diff --git a/example/app.mpx b/example/app.mpx index 31ac28e..3804c4d 100644 --- a/example/app.mpx +++ b/example/app.mpx @@ -49,7 +49,8 @@ "./pages/switch/index", "./pages/loading/index", "./pages/input/index", - "./pages/action-sheet/index" + "./pages/action-sheet/index", + "./pages/upload/index" ] } diff --git a/example/common/config.ts b/example/common/config.ts index 51b4910..1bfaa57 100644 --- a/example/common/config.ts +++ b/example/common/config.ts @@ -61,7 +61,8 @@ export default { 'date-picker', 'time-picker', 'rate', - 'switch' + 'switch', + 'upload', ] }, { diff --git a/example/pages/upload/index.mpx b/example/pages/upload/index.mpx new file mode 100644 index 0000000..99ea107 --- /dev/null +++ b/example/pages/upload/index.mpx @@ -0,0 +1,28 @@ + + + + + + + \ No newline at end of file diff --git a/packages/mpx-cube-ui/lib/common/stylus/theme/components/upload.styl b/packages/mpx-cube-ui/lib/common/stylus/theme/components/upload.styl new file mode 100644 index 0000000..ecc515f --- /dev/null +++ b/packages/mpx-cube-ui/lib/common/stylus/theme/components/upload.styl @@ -0,0 +1 @@ +$upload-background-color := #FFF; \ No newline at end of file diff --git a/packages/mpx-cube-ui/lib/components/upload/css.styl b/packages/mpx-cube-ui/lib/components/upload/css.styl new file mode 100644 index 0000000..b96559d --- /dev/null +++ b/packages/mpx-cube-ui/lib/components/upload/css.styl @@ -0,0 +1,133 @@ +@require "../../common/stylus/variable.styl" +@require "../../common/stylus/theme/components/upload.styl"; +.uploader-wrapper + display flex + flex-wrap wrap + gap 20rpx +.card-container + position relative +.card-container .close-icon + display flex + align-items center + justify-content center + position absolute + top 10rpx + right 10rpx + width 24rpx + height 24rpx + cursor pointer +.card + width 167rpx + height 167rpx + border-radius 16rpx + overflow hidden + position relative + background-color $var(upload-background-color) + box-sizing border-box + font-family PingFangSC-Regular + font-size 18rpx + color #E8C5AA + letter-spacing 0 + text-align center + font-weight 400 +.thumb + width 100% + height 100% + object-fit cover +.preview-icon + position absolute + top 0 + right 0 + bottom 0 + left 0 + display flex + align-items center + justify-content center + background-color rgba(0, 0, 0, 0.5) + color #fff + font-size 24rpx + padding 4rpx 8rpx + border-radius 8rpx + opacity 0 + transition opacity 0.2s +.uploading + position absolute + top 0 + display flex + flex-direction column + align-items center + justify-content center + background-color rgba(0, 0, 0, 0.5) +.uploading-text + margin-bottom 10rpx +@keyframes spin + 0% + transform rotate(0deg) + 100% + transform rotate(360deg) +.progress + width 30rpx + height 30rpx + margin-bottom 7rpx + &.loading + animation spin 1s linear infinite +.progress-bar + height 100% + background-color #3b82f6 + transition width 0.3s +.upload-btn + display flex + flex-direction column + align-items center + justify-content center + border-style dashed + border-color #cbd5e1 + color #666 +.plus + width 30rpx + height 30rpx +.text + font-size 22rpx +.error + position absolute + top 0 + display flex + align-content center + justify-content center + flex-direction column +.error-icon + font-size 30rpx + margin-bottom 5rpx +.preview-mask + position fixed + top 0 + left 0 + right 0 + bottom 0 + background-color rgba(0, 0, 0, 0.9) + z-index 999 + display flex + align-items center + justify-content center + .close-icon + position absolute + top 114rpx + left 32rpx + width 36rpx + height 36rpx + .indicator + position absolute + top 114rpx + left 50% + transform translateX(-50%) + color #fff + font-size 24rpx +.preview-img + width 100% + height 60% + border-radius 12rpx +.mpx-image + width 100% + height 100% + background-size contain + background-repeat no-repeat \ No newline at end of file diff --git a/packages/mpx-cube-ui/lib/components/upload/hooks.js b/packages/mpx-cube-ui/lib/components/upload/hooks.js new file mode 100644 index 0000000..3862738 --- /dev/null +++ b/packages/mpx-cube-ui/lib/components/upload/hooks.js @@ -0,0 +1,19 @@ +import { onUnmounted, ref } from "@mpxjs/core"; +// 节流hooks +export const useDebounceFn = (fn, delay) => { + const timer = ref(); + onUnmounted(() => { + clearTimeout(timer.value); + }); + return { + run: (...args) => { + if (timer.value) { + clearTimeout(timer.value); + } + timer.value = setTimeout(() => { + fn(...args); + timer.value = undefined; + }, delay); + } + }; +}; diff --git a/packages/mpx-cube-ui/lib/components/upload/index.mpx b/packages/mpx-cube-ui/lib/components/upload/index.mpx new file mode 100644 index 0000000..345ba6e --- /dev/null +++ b/packages/mpx-cube-ui/lib/components/upload/index.mpx @@ -0,0 +1,427 @@ + + + + + diff --git a/packages/mpx-cube-ui/lib/components/upload/utils.js b/packages/mpx-cube-ui/lib/components/upload/utils.js new file mode 100644 index 0000000..64593f5 --- /dev/null +++ b/packages/mpx-cube-ui/lib/components/upload/utils.js @@ -0,0 +1,16 @@ +export function getByPath(obj, path) { + return path.split('.').reduce((prev, curr) => prev && prev[curr], obj); +} +/** + * 对请求的返回结构做目标转化 + * @param source + * @param target + * @returns + */ +export function transformRes(source, target) { + target = { ...target }; + for (const key in target) { + target[key] = getByPath(source, target[key]); + } + return target; +} diff --git a/packages/mpx-cube-ui/src/common/stylus/theme/components/upload.styl b/packages/mpx-cube-ui/src/common/stylus/theme/components/upload.styl new file mode 100644 index 0000000..ecc515f --- /dev/null +++ b/packages/mpx-cube-ui/src/common/stylus/theme/components/upload.styl @@ -0,0 +1 @@ +$upload-background-color := #FFF; \ No newline at end of file diff --git a/packages/mpx-cube-ui/src/components/upload/css.styl b/packages/mpx-cube-ui/src/components/upload/css.styl new file mode 100644 index 0000000..b96559d --- /dev/null +++ b/packages/mpx-cube-ui/src/components/upload/css.styl @@ -0,0 +1,133 @@ +@require "../../common/stylus/variable.styl" +@require "../../common/stylus/theme/components/upload.styl"; +.uploader-wrapper + display flex + flex-wrap wrap + gap 20rpx +.card-container + position relative +.card-container .close-icon + display flex + align-items center + justify-content center + position absolute + top 10rpx + right 10rpx + width 24rpx + height 24rpx + cursor pointer +.card + width 167rpx + height 167rpx + border-radius 16rpx + overflow hidden + position relative + background-color $var(upload-background-color) + box-sizing border-box + font-family PingFangSC-Regular + font-size 18rpx + color #E8C5AA + letter-spacing 0 + text-align center + font-weight 400 +.thumb + width 100% + height 100% + object-fit cover +.preview-icon + position absolute + top 0 + right 0 + bottom 0 + left 0 + display flex + align-items center + justify-content center + background-color rgba(0, 0, 0, 0.5) + color #fff + font-size 24rpx + padding 4rpx 8rpx + border-radius 8rpx + opacity 0 + transition opacity 0.2s +.uploading + position absolute + top 0 + display flex + flex-direction column + align-items center + justify-content center + background-color rgba(0, 0, 0, 0.5) +.uploading-text + margin-bottom 10rpx +@keyframes spin + 0% + transform rotate(0deg) + 100% + transform rotate(360deg) +.progress + width 30rpx + height 30rpx + margin-bottom 7rpx + &.loading + animation spin 1s linear infinite +.progress-bar + height 100% + background-color #3b82f6 + transition width 0.3s +.upload-btn + display flex + flex-direction column + align-items center + justify-content center + border-style dashed + border-color #cbd5e1 + color #666 +.plus + width 30rpx + height 30rpx +.text + font-size 22rpx +.error + position absolute + top 0 + display flex + align-content center + justify-content center + flex-direction column +.error-icon + font-size 30rpx + margin-bottom 5rpx +.preview-mask + position fixed + top 0 + left 0 + right 0 + bottom 0 + background-color rgba(0, 0, 0, 0.9) + z-index 999 + display flex + align-items center + justify-content center + .close-icon + position absolute + top 114rpx + left 32rpx + width 36rpx + height 36rpx + .indicator + position absolute + top 114rpx + left 50% + transform translateX(-50%) + color #fff + font-size 24rpx +.preview-img + width 100% + height 60% + border-radius 12rpx +.mpx-image + width 100% + height 100% + background-size contain + background-repeat no-repeat \ No newline at end of file diff --git a/packages/mpx-cube-ui/src/components/upload/hooks.ts b/packages/mpx-cube-ui/src/components/upload/hooks.ts new file mode 100644 index 0000000..045235e --- /dev/null +++ b/packages/mpx-cube-ui/src/components/upload/hooks.ts @@ -0,0 +1,21 @@ +import { onUnmounted, ref } from '@mpxjs/core' + +// 节流hooks +export const useDebounceFn = (fn, delay) => { + const timer = ref() + + onUnmounted(() => { + clearTimeout(timer.value) + }) + return { + run: (...args) => { + if (timer.value) { + clearTimeout(timer.value) + } + timer.value = setTimeout(() => { + fn(...args) + timer.value = undefined + }, delay) + } + } +} diff --git a/packages/mpx-cube-ui/src/components/upload/index.mpx b/packages/mpx-cube-ui/src/components/upload/index.mpx new file mode 100644 index 0000000..c3a5dd2 --- /dev/null +++ b/packages/mpx-cube-ui/src/components/upload/index.mpx @@ -0,0 +1,431 @@ + + + + + diff --git a/packages/mpx-cube-ui/src/components/upload/utils.ts b/packages/mpx-cube-ui/src/components/upload/utils.ts new file mode 100644 index 0000000..4893e56 --- /dev/null +++ b/packages/mpx-cube-ui/src/components/upload/utils.ts @@ -0,0 +1,36 @@ +/** + * 根据 path 获取对象数据 + */ +type Prev = [never, 0, 1, 2, 3, 4, 5] +type Join = T extends string | number ? P extends string | number ? `${T}.${P}` : never : never +type Paths = + Depth extends never ? + never + : T extends object + ? { + [K in keyof T & (string | number)]: + T[K] extends object + ? `${K}` | Join> + : `${K}` + }[keyof T & (string | number)] + : never + +export function getByPath>(obj: T, path: K) { + return path.split('.').reduce((prev, curr) => prev && prev[curr], obj) +} + +/** + * 对请求的返回结构做目标转化 + * @param source + * @param target + * @returns + */ +export function transformRes(source, target) { + target = { ...target } + const result = {} + for (const key in target) { + const path = target[key] + result[key] = getByPath(source, path) + } + return result +} diff --git a/packages/website-build/src/compiler/compile-src-code-md.ts b/packages/website-build/src/compiler/compile-src-code-md.ts index 86f4833..d925c1c 100644 --- a/packages/website-build/src/compiler/compile-src-code-md.ts +++ b/packages/website-build/src/compiler/compile-src-code-md.ts @@ -9,6 +9,29 @@ import { parser } from '@mpxjs/vuese-parser' import { Render } from '@mpxjs/vuese-markdown-render' import { renderOptions } from '../common/options.js' +/** + * 将字符串的对象转为可读的markdown格式 + * @param str + * @returns + */ +export function convertObjectStringToMarkdownHtml(str) { + if (!str) return + return ( + '
' +
+    str
+      .split('\n')
+      .map((line, idx) => {
+        // 第一行和最后一行是{},将括号的前后空白字符去除,只保留属性的
+        if (!(idx !== 0 && idx !== str.split('\n').length - 1)) {
+          line = line.replace(/\s+/g, '').replace(//g, '>')
+        }
+        return line
+      }) // 防止HTML标签注入
+      .join('
') + + '
' + ) +} + /** * 解析 cube-ui src 文件夹下的组件,生成md文档 * @@ -44,6 +67,9 @@ const genSrcCodeMd = function (srcDir: string, component: string, fnMixins) { item.type = item.type.replace(/\n/g, '
') item.type = item.type.replace(new RegExp(optionalMark, 'g'), '?') }) + text.props?.forEach(item => { + item.default = convertObjectStringToMarkdownHtml(item.default) + }) const render = new Render(text, Object.assign({ name: component } as any, renderOptions))