@qxs-bns/components 0.0.52 → 0.0.54

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/es/index.mjs +1 -1
  2. package/es/index.mjs.map +1 -1
  3. package/es/node_modules/.pnpm/@iconify_vue@5.0.0_vue@3.5.13_typescript@5.8.2_/node_modules/@iconify/vue/dist/iconify.mjs +2 -0
  4. package/es/node_modules/.pnpm/@iconify_vue@5.0.0_vue@3.5.13_typescript@5.8.2_/node_modules/@iconify/vue/dist/iconify.mjs.map +1 -0
  5. package/es/package.json.mjs +1 -1
  6. package/es/src/components.mjs +1 -1
  7. package/es/src/icon/index.mjs +2 -0
  8. package/es/src/icon/index.mjs.map +1 -0
  9. package/es/src/icon/src/icon.vue.mjs +2 -0
  10. package/es/src/icon/src/icon.vue.mjs.map +1 -0
  11. package/es/src/icon/src/icon.vue2.mjs +2 -0
  12. package/es/src/icon/src/icon.vue2.mjs.map +1 -0
  13. package/es/src/image-upload/src/image-upload.vue.mjs +1 -1
  14. package/es/src/image-upload/src/image-upload.vue.mjs.map +1 -1
  15. package/es/src/photo-crop-tool/src/photo-crop-tool.vue.mjs +1 -1
  16. package/es/src/photo-crop-tool/src/photo-crop-tool.vue.mjs.map +1 -1
  17. package/es/src/tiny-mce-editor/src/tiny-mce-editor.vue.mjs +1 -1
  18. package/es/src/tiny-mce-editor/src/tiny-mce-editor.vue.mjs.map +1 -1
  19. package/lib/index.cjs +1 -1
  20. package/lib/index.cjs.map +1 -1
  21. package/lib/node_modules/.pnpm/@iconify_vue@5.0.0_vue@3.5.13_typescript@5.8.2_/node_modules/@iconify/vue/dist/iconify.cjs +2 -0
  22. package/lib/node_modules/.pnpm/@iconify_vue@5.0.0_vue@3.5.13_typescript@5.8.2_/node_modules/@iconify/vue/dist/iconify.cjs.map +1 -0
  23. package/lib/package.json.cjs +1 -1
  24. package/lib/src/components.cjs +1 -1
  25. package/lib/src/icon/index.cjs +2 -0
  26. package/lib/src/icon/index.cjs.map +1 -0
  27. package/lib/src/icon/src/icon.vue.cjs +2 -0
  28. package/lib/src/icon/src/icon.vue.cjs.map +1 -0
  29. package/lib/src/icon/src/icon.vue2.cjs +2 -0
  30. package/lib/src/icon/src/icon.vue2.cjs.map +1 -0
  31. package/lib/src/image-upload/src/image-upload.vue.cjs +1 -1
  32. package/lib/src/image-upload/src/image-upload.vue.cjs.map +1 -1
  33. package/lib/src/photo-crop-tool/src/photo-crop-tool.vue.cjs +1 -1
  34. package/lib/src/photo-crop-tool/src/photo-crop-tool.vue.cjs.map +1 -1
  35. package/lib/src/tiny-mce-editor/src/tiny-mce-editor.vue.cjs +1 -1
  36. package/lib/src/tiny-mce-editor/src/tiny-mce-editor.vue.cjs.map +1 -1
  37. package/package.json +6 -4
  38. package/theme-chalk/index.css +1 -1
  39. package/theme-chalk/index.scss +1 -0
  40. package/theme-chalk/src/icon.css +1 -0
  41. package/theme-chalk/src/icon.scss +19 -0
  42. package/theme-chalk/src/image-upload.css +1 -1
  43. package/theme-chalk/src/image-upload.scss +33 -111
  44. package/theme-chalk/src/photo-crop-tool.css +1 -1
  45. package/theme-chalk/src/photo-crop-tool.scss +17 -3
  46. package/types/src/components.d.ts +1 -0
  47. package/types/src/components.d.ts.map +1 -1
  48. package/types/src/icon/index.d.ts +4 -0
  49. package/types/src/icon/index.d.ts.map +1 -0
  50. package/types/src/icon/src/icon.vue.d.ts +11 -0
  51. package/types/src/icon/src/icon.vue.d.ts.map +1 -0
  52. package/types/src/icon/style/index.d.ts +3 -0
  53. package/types/src/icon/style/index.d.ts.map +1 -0
  54. package/types/src/image-upload/index.d.ts +43 -6
  55. package/types/src/image-upload/index.d.ts.map +1 -1
  56. package/types/src/image-upload/src/image-upload.vue.d.ts +103 -4
  57. package/types/src/image-upload/src/image-upload.vue.d.ts.map +1 -1
  58. package/types/src/image-upload/style/index.d.ts +1 -1
  59. package/types/src/image-upload/style/index.d.ts.map +1 -1
  60. package/types/src/photo-crop-tool/src/photo-crop-tool.vue.d.ts.map +1 -1
  61. package/types/src/tiny-mce-editor/index.d.ts.map +1 -1
  62. package/types/src/tiny-mce-editor/src/tiny-mce-editor.vue.d.ts.map +1 -1
  63. package/types/tsconfig.tsbuildinfo +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"image-upload.vue.cjs","sources":["../../../../../../packages/components/src/image-upload/src/image-upload.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { UploadFile, UploadFiles, UploadProps } from 'element-plus'\nimport { Delete, Plus, ZoomIn } from '@element-plus/icons-vue'\nimport { useNamespace } from '@qxs-bns/hooks'\nimport { useNamespace as useElNamespace } from 'element-plus'\n\n// 类型定义\nexport interface ImageUploadProps {\n action: UploadProps['action']\n headers?: UploadProps['headers']\n data?: UploadProps['data']\n name?: UploadProps['name']\n url?: string\n size?: number\n width?: number\n accept?: string\n height?: number\n placeholder?: string\n notip?: boolean\n tipText?: string\n beforeUpload?: UploadProps['beforeUpload']\n}\n\ninterface UploadProgress {\n preview: string\n percent: number\n}\n\n// 组件名称\ndefineOptions({\n name: 'QxsImageUpload',\n})\n\n// Props 定义\nconst {\n name = 'file',\n url = '',\n size = 20,\n width = 160,\n height = 90,\n placeholder = '点击上传图片',\n notip = false,\n accept = 'image/jpeg,image/jpg,image/png,image/gif',\n beforeUpload,\n tipText = '',\n} = defineProps<ImageUploadProps>()\n\n// Emits 定义\nconst emits = defineEmits<{\n 'update:url': [url: string]\n 'onSuccess': [res: any, uploadFile: UploadFile, uploadFiles: UploadFiles]\n}>()\n\n// 命名空间\nconst ns = useNamespace('image-upload')\nconst nsEl = useElNamespace('upload')\n\n// 响应式数据\nconst uploadData = ref<{\n imageViewerVisible: boolean\n progress: UploadProgress\n}>({\n imageViewerVisible: false,\n progress: {\n preview: '',\n percent: 0,\n },\n})\n\n// 计算属性\nconst exts = computed(() =>\n accept.split(',').map(ext => ext.split('/').pop()),\n)\n\nconst imageStyle = computed(() => ({\n width: `${width}px`,\n height: `${height}px`,\n}))\n\nconst progressSize = computed(() => Math.min(width, height) * 0.8)\n\nconst tipMessage = computed(\n () =>\n tipText\n || `上传图片支持 ${exts.value.join(\n ' / ',\n )} 格式,且图片大小不超过 ${size}MB,建议图片尺寸为 ${width}*${height}`,\n)\n\n// 方法\nfunction preview(e: Event) {\n e.preventDefault()\n uploadData.value.imageViewerVisible = true\n}\n\nfunction previewClose() {\n uploadData.value.imageViewerVisible = false\n}\n\nfunction remove(e: Event) {\n e.preventDefault()\n emits('update:url', '')\n}\n\nconst handleBeforeUpload: UploadProps['beforeUpload'] = (file) => {\n const fileExt = file.name.split('.').pop() ?? ''\n const isTypeOk = exts.value.includes(fileExt)\n const isSizeOk = file.size / 1024 / 1024 < size\n\n if (!isTypeOk) {\n ElMessage.error(`上传图片只支持${exts.value.join(' / ')}格式!`)\n return false\n }\n\n if (!isSizeOk) {\n ElMessage.error(`上传图片大小不能超过 ${size}MB!`)\n return false\n }\n\n uploadData.value.progress.preview = URL.createObjectURL(file)\n\n return beforeUpload ? beforeUpload(file) : true\n}\n\nconst onProgress: UploadProps['onProgress'] = (evt) => {\n uploadData.value.progress.percent = Math.floor(evt.percent)\n}\n\nconst onSuccess: UploadProps['onSuccess'] = (...args) => {\n uploadData.value.progress = {\n preview: '',\n percent: 0,\n }\n emits('onSuccess', ...args)\n}\n</script>\n\n<template>\n <div :class=\"ns.e('container')\">\n <el-upload\n drag\n :show-file-list=\"false\"\n :headers=\"headers\"\n :action=\"action\"\n :data=\"data\"\n :name=\"name\"\n :accept=\"accept\"\n :class=\"ns.e('control')\"\n :before-upload=\"handleBeforeUpload\"\n :on-progress=\"onProgress\"\n :on-success=\"onSuccess\"\n >\n <template v-if=\"url === ''\">\n <el-image\n :style=\"imageStyle\"\n :src=\"placeholder\"\n fit=\"fill\"\n >\n <template #error>\n <div\n class=\"image-slot\"\n :style=\"imageStyle\"\n >\n <el-icon><Plus /></el-icon>\n <p>{{ placeholder }}</p>\n </div>\n </template>\n </el-image>\n </template>\n\n <template v-else>\n <div class=\"image\">\n <el-image\n :src=\"url\"\n :style=\"imageStyle\"\n fit=\"fill\"\n />\n <div class=\"mask\">\n <div class=\"actions\">\n <span\n title=\"预览\"\n @click.stop=\"preview\"\n >\n <el-icon><ZoomIn /></el-icon>\n </span>\n <span\n title=\"移除\"\n @click.stop=\"remove\"\n >\n <el-icon><Delete /></el-icon>\n </span>\n </div>\n </div>\n </div>\n </template>\n\n <div\n v-show=\"url === '' && uploadData.progress.percent\"\n class=\"progress\"\n :style=\"imageStyle\"\n >\n <el-image\n :src=\"uploadData.progress.preview\"\n :style=\"imageStyle\"\n fit=\"fill\"\n />\n <el-progress\n v-if=\"uploadData.progress.percent !== 100\"\n type=\"circle\"\n :width=\"progressSize\"\n :percentage=\"uploadData.progress.percent\"\n />\n </div>\n </el-upload>\n\n <div\n v-if=\"!notip\"\n :class=\"`${nsEl.namespace.value}-upload__tip-text`\"\n >\n <div class=\"tip-content\">\n {{ tipMessage }}\n </div>\n </div>\n\n <el-image-viewer\n v-if=\"uploadData.imageViewerVisible\"\n :url-list=\"[url]\"\n teleported\n @close=\"previewClose\"\n />\n </div>\n</template>\n"],"names":["emits","__emit","ns","useNamespace","nsEl","useElNamespace","uploadData","ref","imageViewerVisible","progress","preview","percent","exts","computed","__props","split","map","ext","pop","imageStyle","width","height","progressSize","Math","min","tipMessage","tipText","value","join","size","e","preventDefault","previewClose","remove","handleBeforeUpload","file","fileExt","name","isTypeOk","includes","isSizeOk","URL","createObjectURL","beforeUpload","ElMessage","error","onProgress","evt","floor","onSuccess","args"],"mappings":"m4CAgDA,MAAMA,EAAQC,EAMRC,EAAKC,eAAa,gBAClBC,EAAOC,eAAe,UAGtBC,EAAaC,EAAAA,IAGhB,CACDC,oBAAoB,EACpBC,SAAU,CACRC,QAAS,GACTC,QAAS,KAKPC,EAAOC,EAAAA,UAAS,IACpBC,SAAOC,MAAM,KAAKC,KAAIC,GAAOA,EAAIF,MAAM,KAAKG,UAGxCC,EAAaN,EAAAA,UAAS,KAAO,CACjCO,MAAO,GAAGN,EAAAM,UACVC,OAAQ,GAAGP,EAAAO,eAGPC,EAAeT,EAAAA,UAAS,IAAgC,GAA1BU,KAAKC,IAAIV,EAAKM,MAAEN,EAAAO,UAE9CI,EAAaZ,EAAAA,UACjB,IACEC,EAAAY,SACG,UAAUd,EAAKe,MAAMC,KACtB,sBACed,EAAAe,kBAAkBf,WAASA,EAAAO,WAIhD,SAASX,EAAQoB,GACfA,EAAEC,iBACFzB,EAAWqB,MAAMnB,oBAAqB,CAAA,CAGxC,SAASwB,IACP1B,EAAWqB,MAAMnB,oBAAqB,CAAA,CAGxC,SAASyB,EAAOH,GACdA,EAAEC,iBACF/B,EAAM,aAAc,GAAE,CAGlB,MAAAkC,EAAmDC,IACvD,MAAMC,EAAUD,EAAKE,KAAKtB,MAAM,KAAKG,OAAS,GACxCoB,EAAW1B,EAAKe,MAAMY,SAASH,GAC/BI,EAAWL,EAAKN,KAAO,KAAO,KAAOf,EAAAe,KAE3C,OAAKS,EAKAE,GAKLlC,EAAWqB,MAAMlB,SAASC,QAAU+B,IAAIC,gBAAgBP,IAEjDrB,EAAY6B,cAAG7B,eAAaqB,KANjCS,EAAAA,UAAUC,MAAM,cAAc/B,EAAAe,YACvB,IANPe,YAAUC,MAAM,UAAUjC,EAAKe,MAAMC,KAAK,cACnC,EAUkC,EAGvCkB,EAAyCC,IAC7CzC,EAAWqB,MAAMlB,SAASE,QAAUY,KAAKyB,MAAMD,EAAIpC,QAAO,EAGtDsC,EAAsC,IAAIC,KAC9C5C,EAAWqB,MAAMlB,SAAW,CAC1BC,QAAS,GACTC,QAAS,GAELX,EAAA,eAAgBkD,EAAI"}
1
+ {"version":3,"file":"image-upload.vue.cjs","sources":["../../../../../../packages/components/src/image-upload/src/image-upload.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { UploadFile, UploadFiles, UploadProps } from 'element-plus'\nimport { Delete, Plus, ZoomIn } from '@element-plus/icons-vue'\nimport { useNamespace } from 'element-plus'\n// import QxsIcon from '../../icon'\n\n// 组件名称\ndefineOptions({\n name: 'QxsImageUpload',\n})\n\n// Props 定义\nconst {\n name = 'file',\n size = 20,\n width = 160,\n height = 90,\n limit = 1,\n placeholder = '上传图片',\n notip = false,\n accept = 'image/jpeg,image/jpg,image/png,image/gif',\n beforeUpload,\n tipText = '',\n disabled = false,\n} = defineProps<ImageUploadProps>()\n\n// Emits 定义\nconst emits = defineEmits<{\n onSuccess: [res: any, uploadFile: UploadFile, uploadFiles: UploadFiles]\n remove: [file: UploadFile]\n}>()\n\n// 类型定义\nexport interface ImageUploadProps {\n action: UploadProps['action']\n headers?: UploadProps['headers']\n data?: UploadProps['data']\n name?: UploadProps['name']\n url?: string\n size?: number\n width?: number\n accept?: string\n height?: number\n placeholder?: string\n notip?: boolean\n tipText?: string\n beforeUpload?: UploadProps['beforeUpload']\n disabled?: boolean\n limit?: number\n}\n\ninterface UploadProgress {\n preview: string\n percent: number\n}\n\nconst attrs = useAttrs()\n\nconst fileList = defineModel('fileList', {\n type: Array as () => UploadFile[],\n default: () => [],\n})\n\n// 命名空间\nconst nsEl = useNamespace('image-upload')\n\nconst initialIndex = ref(0)\n// 响应式数据\nconst uploadData = ref<{\n imageViewerVisible: boolean\n progress: UploadProgress\n}>({\n imageViewerVisible: false,\n progress: {\n preview: '',\n percent: 0,\n },\n})\n\nconst cssVar = computed(() => {\n return nsEl.cssVarBlock({\n ns: nsEl.namespace.value,\n width: `${width || 160}px`,\n height: `${height || 90}px`,\n })\n})\n\n// 计算属性\nconst exts = computed(() =>\n accept.split(',').map(ext => ext.split('/').pop()),\n)\n\nconst tipMessage = computed(\n () =>\n tipText\n || `上传图片支持 ${exts.value.join(\n ' / ',\n )} 格式,且图片大小不超过 ${size}MB${width && height ? `,建议图片尺寸为 ${width}*${height}` : ''}`,\n)\n\n// 方法\nfunction onPreview(file: UploadFile) {\n initialIndex.value = fileList.value.indexOf(file)\n uploadData.value.imageViewerVisible = true\n}\nfunction onRemove(file: UploadFile) {\n fileList.value.splice(fileList.value.indexOf(file), 1)\n}\n\nfunction previewClose() {\n uploadData.value.imageViewerVisible = false\n}\n\nconst handleBeforeUpload: UploadProps['beforeUpload'] = (file) => {\n const fileExt = file.name.split('.').pop() ?? ''\n const isTypeOk = exts.value.includes(fileExt)\n const isSizeOk = file.size / 1024 / 1024 < size\n\n if (!isTypeOk) {\n ElMessage.error(`上传图片只支持${exts.value.join(' / ')}格式!`)\n return false\n }\n\n if (!isSizeOk) {\n ElMessage.error(`上传图片大小不能超过 ${size}MB!`)\n return false\n }\n\n uploadData.value.progress.preview = URL.createObjectURL(file)\n\n return beforeUpload ? beforeUpload(file) : true\n}\n\nconst onProgress: UploadProps['onProgress'] = (evt) => {\n uploadData.value.progress.percent = Math.floor(evt.percent)\n}\n\nconst onSuccess: UploadProps['onSuccess'] = (...args) => {\n uploadData.value.progress = {\n preview: '',\n percent: 0,\n }\n emits('onSuccess', ...args)\n}\n</script>\n\n<template>\n <div\n :class=\"nsEl.e('container')\"\n :style=\"cssVar\"\n >\n <el-upload\n v-bind=\"attrs\"\n v-model:file-list=\"fileList\"\n drag\n :limit=\"limit\"\n list-type=\"picture-card\"\n :headers=\"headers\"\n :action=\"action\"\n :data=\"data\"\n :name=\"name\"\n :accept=\"accept\"\n :before-upload=\"handleBeforeUpload\"\n :on-progress=\"onProgress\"\n :on-preview=\"onPreview\"\n :on-success=\"onSuccess\"\n :class=\"[nsEl.e('control'), limit <= fileList.length ? nsEl.e('more-than-limit') : '']\"\n :on-remove=\"onRemove\"\n >\n <slot>\n <div class=\"image-slot\">\n <el-icon><Plus /></el-icon>\n <p>{{ placeholder }}</p>\n </div>\n </slot>\n <template #file=\"{ file }\">\n <img\n :class=\"`${nsEl.namespace.value}-upload-list__item-thumbnail`\"\n :src=\"file.url\"\n alt=\"\"\n >\n <span :class=\"`${nsEl.namespace.value}-upload-list__item-actions`\">\n <span\n :class=\"`${nsEl.namespace.value}-upload-list__item-preview`\"\n @click=\"onPreview(file)\"\n >\n <el-icon><ZoomIn /></el-icon>\n </span>\n <span\n v-if=\"!disabled\"\n :class=\"`${nsEl.namespace.value}-upload-list__item-delete`\"\n @click=\"onRemove(file)\"\n >\n <el-icon><Delete /></el-icon>\n </span>\n </span>\n </template>\n <template #tip>\n <slot name=\"tip\">\n <div\n v-if=\"!notip\"\n :class=\"`${nsEl.namespace.value}-upload__tip-text`\"\n >\n <div class=\"tip-content\">\n {{ tipMessage }}\n </div>\n </div>\n </slot>\n </template>\n </el-upload>\n\n <el-image-viewer\n v-if=\"uploadData.imageViewerVisible\"\n :url-list=\"fileList.map(item => item.url).filter(v => v !== undefined)\"\n :initial-index=\"initialIndex\"\n teleported\n @close=\"previewClose\"\n />\n </div>\n</template>\n"],"names":["emits","__emit","attrs","useAttrs","fileList","_useModel","__props","nsEl","useNamespace","initialIndex","ref","uploadData","imageViewerVisible","progress","preview","percent","cssVar","computed","cssVarBlock","ns","namespace","value","width","height","exts","split","map","ext","pop","tipMessage","tipText","join","size","onPreview","file","indexOf","onRemove","splice","previewClose","handleBeforeUpload","fileExt","name","isTypeOk","includes","isSizeOk","URL","createObjectURL","beforeUpload","ElMessage","error","onProgress","evt","Math","floor","onSuccess","args"],"mappings":"06CA2BA,MAAMA,EAAQC,EA6BRC,EAAQC,EAAAA,WAERC,EAAWC,EAAAA,SAAYC,EAAA,YAMvBC,EAAOC,eAAa,gBAEpBC,EAAeC,MAAI,GAEnBC,EAAaD,EAAAA,IAGhB,CACDE,oBAAoB,EACpBC,SAAU,CACRC,QAAS,GACTC,QAAS,KAIPC,EAASC,EAAAA,UAAS,IACfV,EAAKW,YAAY,CACtBC,GAAIZ,EAAKa,UAAUC,MACnBC,MAAO,GAAGhB,EAAKgB,OAAI,QACnBC,OAAQ,GAAGjB,EAAAiB,QAAU,WAKnBC,EAAOP,EAAAA,UAAS,IACpBX,SAAOmB,MAAM,KAAKC,KAAIC,GAAOA,EAAIF,MAAM,KAAKG,UAGxCC,EAAaZ,EAAAA,UACjB,IACEX,EAAAwB,SACG,UAAUN,EAAKH,MAAMU,KACtB,sBACezB,EAAI0B,SAAK1B,EAAKgB,OAAIhB,EAAAiB,OAAS,YAAYjB,EAAAgB,SAAShB,EAAMiB,SAAK,OAIhF,SAASU,EAAUC,GACjBzB,EAAaY,MAAQjB,EAASiB,MAAMc,QAAQD,GAC5CvB,EAAWU,MAAMT,oBAAqB,CAAA,CAExC,SAASwB,EAASF,GAChB9B,EAASiB,MAAMgB,OAAOjC,EAASiB,MAAMc,QAAQD,GAAO,EAAC,CAGvD,SAASI,IACP3B,EAAWU,MAAMT,oBAAqB,CAAA,CAGlC,MAAA2B,EAAmDL,IACvD,MAAMM,EAAUN,EAAKO,KAAKhB,MAAM,KAAKG,OAAS,GACxCc,EAAWlB,EAAKH,MAAMsB,SAASH,GAC/BI,EAAWV,EAAKF,KAAO,KAAO,KAAO1B,EAAA0B,KAE3C,OAAKU,EAKAE,GAKLjC,EAAWU,MAAMR,SAASC,QAAU+B,IAAIC,gBAAgBZ,IAEjD5B,EAAYyC,cAAGzC,eAAa4B,KANjCc,EAAAA,UAAUC,MAAM,cAAc3C,EAAA0B,YACvB,IANPgB,YAAUC,MAAM,UAAUzB,EAAKH,MAAMU,KAAK,cACnC,EAUkC,EAGvCmB,EAAyCC,IAC7CxC,EAAWU,MAAMR,SAASE,QAAUqC,KAAKC,MAAMF,EAAIpC,QAAO,EAGtDuC,EAAsC,IAAIC,KAC9C5C,EAAWU,MAAMR,SAAW,CAC1BC,QAAS,GACTC,QAAS,GAELf,EAAA,eAAgBuD,EAAI"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("vue"),t=require("@qxs-bns/hooks"),l=require("./composables.cjs"),a=require("@vueuse/core");const o=["src"];var u=e.defineComponent({name:"QxsPhotoCropTool",__name:"photo-crop-tool",props:{imgFile:{type:Object,default:()=>null},aspectRatio:{type:String,default:()=>"16 / 9"},defaultWidth:{type:Number,default:()=>320},defaultHeight:{type:Number,default:()=>180},zoomType:{type:String,default:()=>"fixed"}},setup(u,{expose:i}){const n=u;let r=0,s=0,v=0,h=0;const c=t.useNamespace("photo-crop-tool"),f=e.ref(null),p=e.ref(null),d=e.ref(null),m=e.ref(""),g=e.ref(""),y=e.ref({x:0,y:0}),w=e.ref({width:n.defaultWidth,height:n.defaultHeight,x:0,y:0}),{width:x,height:b}=a.useElementSize(f),{width:z}=a.useElementSize(d),{x:E,y:N,style:R}=a.useDraggable(f,{containerElement:p,draggingElement:f,disabled:e.computed((()=>!!g.value)),exact:!0,initialValue:y}),k=e.computed((()=>n.imgFile?URL.createObjectURL(n.imgFile):""));e.watch((()=>n.imgFile),(e=>{e&&!e.type.startsWith("image/")?m.value="文件类型错误":m.value=""}));const H=e.computed((()=>(d.value?.naturalWidth||0)/z.value)),C=e.computed((()=>{const e={left:0,top:0};return"bottom-right"===g.value?(e.left=w.value.x,e.top=w.value.y):"top-left"===g.value?(e.left=w.value.x-x.value,e.top=w.value.y-b.value):"top-right"===g.value?(e.top=w.value.y-b.value,e.left=w.value.x):"bottom-left"===g.value&&(e.left=w.value.x-x.value,e.top=w.value.y),e})),T=e.computed((()=>{const{aspectRatio:e}=n,t={width:`${w.value.width||n.defaultWidth}`,height:`${w.value.height||n.defaultHeight}`,"aspect-ratio":e,top:`${C.value.top}px`,left:`${C.value.left}px`};return"free"===n.zoomType?delete t["aspect-ratio"]:"fixed"===n.zoomType&&delete t.height,c.cssVarBlock(t)}));function F(e){return e*H.value}function M(e,t){const l=p.value?.clientWidth||1/0,a=p.value?.clientHeight||1/0;return{width:Math.min(Math.max(e,0),l),height:Math.min(Math.max(t,0),a)}}function W(e){const t=e.clientX-r,l=e.clientY-s;if("bottom-right"===g.value){if("free"===n.zoomType){const{width:e,height:a}=M(v+t,h+l);w.value.width=e,w.value.height=a}else if("fixed"===n.zoomType){const e=Number.parseFloat(n.aspectRatio.split(" / ")[0])/Number.parseFloat(n.aspectRatio.split(" / ")[1]);let l=v+t,a=l/e;const{width:o,height:u}=M(l,a);u>(p.value?.clientHeight||1/0)&&(a=p.value?.clientHeight||1/0,l=a*e),w.value.width=o,w.value.height=u}}else if("top-left"===g.value){if("free"===n.zoomType){const{width:e,height:a}=M(v-t,h-l);w.value.width=e,w.value.height=a}else if("fixed"===n.zoomType){const e=Number.parseFloat(n.aspectRatio.split(" / ")[0])/Number.parseFloat(n.aspectRatio.split(" / ")[1]);let l=v-t,a=l/e;const{width:o,height:u}=M(l,a);u>(p.value?.clientHeight||1/0)&&(a=p.value?.clientHeight||1/0,l=a*e),w.value.width=o,w.value.height=u}E.value=C.value.left,N.value=C.value.top}else if("top-right"===g.value){if("free"===n.zoomType){const{width:e,height:a}=M(v+t,h-l);w.value.width=e,w.value.height=a}else if("fixed"===n.zoomType){const e=Number.parseFloat(n.aspectRatio.split(" / ")[0])/Number.parseFloat(n.aspectRatio.split(" / ")[1]);let l=v+t,a=l/e;const{width:o,height:u}=M(l,a);u>(p.value?.clientHeight||1/0)&&(a=p.value?.clientHeight||1/0,l=a*e),w.value.width=o,w.value.height=u}E.value=C.value.left,N.value=C.value.top}else if("bottom-left"===g.value){if("free"===n.zoomType){const{width:e,height:a}=M(v-t,h+l);w.value.width=e,w.value.height=a}else if("fixed"===n.zoomType){const e=Number.parseFloat(n.aspectRatio.split(" / ")[0])/Number.parseFloat(n.aspectRatio.split(" / ")[1]);let l=v-t,a=l/e;const{width:o,height:u}=M(l,a);u>(p.value?.clientHeight||1/0)&&(a=p.value?.clientHeight||1/0,l=a*e),w.value.width=o,w.value.height=u}E.value=C.value.left,N.value=C.value.top}e.preventDefault(),e.stopPropagation()}function B(e,t){g.value=t,r=e.clientX,s=e.clientY,v=w.value.width,h=w.value.height,"bottom-right"===t?(w.value.x=E.value,w.value.y=N.value):"top-left"===t?(w.value.x=E.value+x.value,w.value.y=N.value+b.value):"top-right"===t?(w.value.x=E.value,w.value.y=N.value+b.value):"bottom-left"===t&&(w.value.x=E.value+x.value,w.value.y=N.value)}function L(){g.value=""}return document.addEventListener("mouseup",L),document.addEventListener("mousemove",W),e.onMounted((()=>{e.nextTick((()=>{y.value.x=(p.value?.offsetWidth||0)/2-w.value.width/2,y.value.y=(p.value?.offsetHeight||0)/2-w.value.height/2}))})),e.onUnmounted((()=>{k.value&&URL.revokeObjectURL(k.value),document.removeEventListener("mouseup",L),document.removeEventListener("mousemove",W)})),i({crop:async function(e=d.value){let t="transparent";p.value&&(t=window.getComputedStyle(p.value).backgroundColor);const a=document.createElement("canvas");a.width=F(p.value?.clientWidth||0),a.height=F(p.value?.clientHeight||0);const{drawImage:o,cropCanvas:u,drawColor:i}=l.useCanvas(a);return i(0,0,a.width,a.height,t),o(e,F(e.offsetLeft),F(e.offsetTop),e.naturalWidth,e.naturalHeight),await u(F(E.value),F(N.value),F(x.value),F(b.value))},resize:function(){w.value.width=n.defaultWidth,w.value.height=n.defaultHeight,E.value=0,N.value=0}}),(t,l)=>(e.openBlock(),e.createElementBlock("div",{ref_key:"containerBoxRef",ref:p,class:e.normalizeClass([e.unref(c).e("img-box")])},[e.unref(m)?(e.openBlock(),e.createElementBlock("div",{key:0,class:e.normalizeClass([e.unref(c).e("error-message")])},e.toDisplayString(e.unref(m)),3)):(e.openBlock(),e.createElementBlock(e.Fragment,{key:1},[e.createElementVNode("img",{ref_key:"imgRef",ref:d,class:e.normalizeClass([e.unref(c).e("image")]),src:e.unref(k)},null,10,o),e.createElementVNode("div",{ref_key:"cropBoxRef",ref:f,class:e.normalizeClass([e.unref(c).e("crop-tool-box")]),style:e.normalizeStyle([e.unref(T),e.unref(g)?`left: ${e.unref(C).left}px;top: ${e.unref(C).top}px`:e.unref(R)])},[e.createElementVNode("div",{class:e.normalizeClass([e.unref(c).e("top-left")]),onMousedown:l[0]||(l[0]=e=>B(e,"top-left"))},null,34),e.createElementVNode("div",{class:e.normalizeClass([e.unref(c).e("top-right")]),onMousedown:l[1]||(l[1]=e=>B(e,"top-right"))},null,34),e.createElementVNode("div",{class:e.normalizeClass([e.unref(c).e("bottom-right")]),onMousedown:l[2]||(l[2]=e=>B(e,"bottom-right"))},null,34),e.createElementVNode("div",{class:e.normalizeClass([e.unref(c).e("bottom-left")]),onMousedown:l[3]||(l[3]=e=>B(e,"bottom-left"))},null,34)],6)],64))],2))}});exports.default=u;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("vue"),t=require("@qxs-bns/hooks"),o=require("./composables.cjs"),l=require("@vueuse/core");const i=["src"];var a=e.defineComponent({name:"QxsPhotoCropTool",__name:"photo-crop-tool",props:{imgFile:{type:Object,default:()=>null},aspectRatio:{type:String,default:()=>"16 / 9"},defaultWidth:{type:Number,default:()=>320},defaultHeight:{type:Number,default:()=>180},zoomType:{type:String,default:()=>"fixed"}},setup(a,{expose:u}){const n=a;let r=0,s=0,v=0,h=0;const c=t.useNamespace("photo-crop-tool"),p=e.ref(null),d=e.ref(null),f=e.ref(null),m=e.ref(""),g=e.ref(""),w=e.ref({x:0,y:0}),y=e.ref({width:n.defaultWidth,height:n.defaultHeight,x:0,y:0}),{width:x,height:b}=l.useElementSize(p),{width:E}=l.useElementSize(f),{x:T,y:M,style:z}=l.useDraggable(p,{containerElement:d,draggingElement:p,disabled:e.computed((()=>!!g.value)),exact:!0,initialValue:w}),N=e.computed((()=>n.imgFile?URL.createObjectURL(n.imgFile):""));e.watch((()=>n.imgFile),(e=>{e&&!e.type.startsWith("image/")?m.value="文件类型错误":m.value=""}));const R=e.computed((()=>(f.value?.naturalWidth||0)/E.value)),k=e.computed((()=>{const e={left:0,top:0};return"bottom-right"===g.value?(e.left=y.value.x,e.top=y.value.y):"top-left"===g.value?(e.left=y.value.x-x.value,e.top=y.value.y-b.value):"top-right"===g.value?(e.top=y.value.y-b.value,e.left=y.value.x):"bottom-left"===g.value&&(e.left=y.value.x-x.value,e.top=y.value.y),e})),H=e.computed((()=>{const{aspectRatio:e}=n,t={width:`${y.value.width||n.defaultWidth}`,height:`${y.value.height||n.defaultHeight}`,"aspect-ratio":e,top:`${k.value.top}px`,left:`${k.value.left}px`};return"free"===n.zoomType?delete t["aspect-ratio"]:"fixed"===n.zoomType&&delete t.height,c.cssVarBlock(t)}));function C(e){return e*R.value}function L(e,t){const o=d.value?.clientWidth||1/0,l=d.value?.clientHeight||1/0;return{width:Math.min(Math.max(e,0),o),height:Math.min(Math.max(t,0),l)}}function F(e){return e instanceof MouseEvent?{clientX:e.clientX,clientY:e.clientY}:e instanceof TouchEvent&&e.touches.length>0?{clientX:e.touches[0].clientX,clientY:e.touches[0].clientY}:{clientX:0,clientY:0}}function W(e,t){const{clientX:o,clientY:l}=F(e);g.value=t,r=o,s=l,v=y.value.width,h=y.value.height,document.addEventListener("touchmove",B,{passive:!1}),document.addEventListener("touchend",V),"bottom-right"===t?(y.value.x=T.value,y.value.y=M.value):"top-left"===t?(y.value.x=T.value+x.value,y.value.y=M.value+b.value):"top-right"===t?(y.value.x=T.value,y.value.y=M.value+b.value):"bottom-left"===t&&(y.value.x=T.value+x.value,y.value.y=M.value),e instanceof TouchEvent&&e.preventDefault()}function B(e){e instanceof TouchEvent&&g.value&&e.preventDefault();const{clientX:t,clientY:o}=F(e),l=t-r,i=o-s;if("bottom-right"===g.value){if("free"===n.zoomType){const{width:e,height:t}=L(v+l,h+i);y.value.width=e,y.value.height=t}else if("fixed"===n.zoomType){const e=Number.parseFloat(n.aspectRatio.split(" / ")[0])/Number.parseFloat(n.aspectRatio.split(" / ")[1]);let t=v+l,o=t/e;const{width:i,height:a}=L(t,o);a>(d.value?.clientHeight||1/0)&&(o=d.value?.clientHeight||1/0,t=o*e),y.value.width=i,y.value.height=a}}else if("top-left"===g.value){if("free"===n.zoomType){const{width:e,height:t}=L(v-l,h-i);y.value.width=e,y.value.height=t}else if("fixed"===n.zoomType){const e=Number.parseFloat(n.aspectRatio.split(" / ")[0])/Number.parseFloat(n.aspectRatio.split(" / ")[1]);let t=v-l,o=t/e;const{width:i,height:a}=L(t,o);a>(d.value?.clientHeight||1/0)&&(o=d.value?.clientHeight||1/0,t=o*e),y.value.width=i,y.value.height=a}T.value=k.value.left,M.value=k.value.top}else if("top-right"===g.value){if("free"===n.zoomType){const{width:e,height:t}=L(v+l,h-i);y.value.width=e,y.value.height=t}else if("fixed"===n.zoomType){const e=Number.parseFloat(n.aspectRatio.split(" / ")[0])/Number.parseFloat(n.aspectRatio.split(" / ")[1]);let t=v+l,o=t/e;const{width:i,height:a}=L(t,o);a>(d.value?.clientHeight||1/0)&&(o=d.value?.clientHeight||1/0,t=o*e),y.value.width=i,y.value.height=a}T.value=k.value.left,M.value=k.value.top}else if("bottom-left"===g.value){if("free"===n.zoomType){const{width:e,height:t}=L(v-l,h+i);y.value.width=e,y.value.height=t}else if("fixed"===n.zoomType){const e=Number.parseFloat(n.aspectRatio.split(" / ")[0])/Number.parseFloat(n.aspectRatio.split(" / ")[1]);let t=v-l,o=t/e;const{width:i,height:a}=L(t,o);a>(d.value?.clientHeight||1/0)&&(o=d.value?.clientHeight||1/0,t=o*e),y.value.width=i,y.value.height=a}T.value=k.value.left,M.value=k.value.top}}function V(){document.removeEventListener("touchmove",B),document.removeEventListener("touchend",V),g.value=""}return e.onMounted((()=>{e.nextTick((()=>{w.value.x=(d.value?.offsetWidth||0)/2-y.value.width/2,w.value.y=(d.value?.offsetHeight||0)/2-y.value.height/2})),document.addEventListener("mouseup",V),document.addEventListener("mousemove",B,{passive:!1}),document.addEventListener("touchmove",B,{passive:!1}),document.addEventListener("touchend",V)})),e.onUnmounted((()=>{N.value&&URL.revokeObjectURL(N.value),document.removeEventListener("mouseup",V),document.removeEventListener("mousemove",B)})),u({crop:async function(e=f.value){let t="transparent";d.value&&(t=window.getComputedStyle(d.value).backgroundColor);const l=document.createElement("canvas");l.width=C(d.value?.clientWidth||0),l.height=C(d.value?.clientHeight||0);const{drawImage:i,cropCanvas:a,drawColor:u}=o.useCanvas(l);return u(0,0,l.width,l.height,t),i(e,C(e.offsetLeft),C(e.offsetTop),e.naturalWidth,e.naturalHeight),await a(C(T.value),C(M.value),C(x.value),C(b.value))},resize:function(){y.value.width=n.defaultWidth,y.value.height=n.defaultHeight,T.value=0,M.value=0}}),(t,o)=>(e.openBlock(),e.createElementBlock("div",{ref_key:"containerBoxRef",ref:d,class:e.normalizeClass([e.unref(c).e("img-box")])},[e.unref(m)?(e.openBlock(),e.createElementBlock("div",{key:0,class:e.normalizeClass([e.unref(c).e("error-message")])},e.toDisplayString(e.unref(m)),3)):(e.openBlock(),e.createElementBlock(e.Fragment,{key:1},[e.createElementVNode("img",{ref_key:"imgRef",ref:f,class:e.normalizeClass([e.unref(c).e("image")]),src:e.unref(N)},null,10,i),e.createElementVNode("div",{ref_key:"cropBoxRef",ref:p,class:e.normalizeClass([e.unref(c).e("crop-tool-box")]),style:e.normalizeStyle([e.unref(H),e.unref(g)?`left: ${e.unref(k).left}px;top: ${e.unref(k).top}px`:e.unref(z)]),onTouchstart:o[8]||(o[8]=e.withModifiers((()=>{}),["stop","prevent"])),onTouchend:e.withModifiers(V,["stop","prevent"])},[e.createElementVNode("div",{class:e.normalizeClass([e.unref(c).e("top-left")]),onMousedown:o[0]||(o[0]=e.withModifiers((e=>W(e,"top-left")),["stop","prevent"])),onTouchstart:o[1]||(o[1]=e.withModifiers((e=>W(e,"top-left")),["stop","prevent"])),onTouchend:e.withModifiers(V,["stop","prevent"])},null,34),e.createElementVNode("div",{class:e.normalizeClass([e.unref(c).e("top-right")]),onMousedown:o[2]||(o[2]=e.withModifiers((e=>W(e,"top-right")),["stop","prevent"])),onTouchstart:o[3]||(o[3]=e.withModifiers((e=>W(e,"top-right")),["stop","prevent"])),onTouchend:e.withModifiers(V,["stop","prevent"])},null,34),e.createElementVNode("div",{class:e.normalizeClass([e.unref(c).e("bottom-right")]),onMousedown:o[4]||(o[4]=e.withModifiers((e=>W(e,"bottom-right")),["stop","prevent"])),onTouchstart:o[5]||(o[5]=e.withModifiers((e=>W(e,"bottom-right")),["stop","prevent"])),onTouchend:e.withModifiers(V,["stop","prevent"])},null,34),e.createElementVNode("div",{class:e.normalizeClass([e.unref(c).e("bottom-left")]),onMousedown:o[6]||(o[6]=e.withModifiers((e=>W(e,"bottom-left")),["stop","prevent"])),onTouchstart:o[7]||(o[7]=e.withModifiers((e=>W(e,"bottom-left")),["stop","prevent"])),onTouchend:e.withModifiers(V,["stop","prevent"])},null,34)],38)],64))],2))}});exports.default=a;
2
2
  //# sourceMappingURL=photo-crop-tool.vue.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"photo-crop-tool.vue.cjs","sources":["../../../../../../packages/components/src/photo-crop-tool/src/photo-crop-tool.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { PropType } from 'vue'\nimport { useNamespace } from '@qxs-bns/hooks'\nimport { useCanvas } from './composables'\n\ndefineOptions({\n name: 'QxsPhotoCropTool',\n})\n\nconst props = defineProps({\n imgFile: {\n type: Object as PropType<File>,\n default: () => null,\n },\n aspectRatio: {\n type: String,\n default: () => '16 / 9',\n },\n defaultWidth: {\n type: Number,\n default: () => 320,\n },\n defaultHeight: {\n type: Number,\n default: () => 180,\n },\n /**\n * free 自由缩放\n * fixed 固定比例缩放\n */\n zoomType: {\n type: String,\n default: () => 'fixed',\n },\n})\nlet startX = 0\nlet startY = 0\nlet startWidth = 0\nlet startHeight = 0\n\nconst ns = useNamespace('photo-crop-tool')\n\nconst cropBoxRef = ref<HTMLElement | null>(null)\nconst containerBoxRef = ref<HTMLElement | null>(null)\nconst imgRef = ref<HTMLImageElement | null>(null)\nconst errorMessage = ref('')\nconst dargPoint = ref('')\nconst initialValue = ref({\n x: 0,\n y: 0,\n})\nconst cropInfo = ref({\n width: props.defaultWidth,\n height: props.defaultHeight,\n x: 0,\n y: 0,\n})\n\nconst { width, height } = useElementSize(cropBoxRef)\nconst { width: imgWidth } = useElementSize(imgRef)\n\nconst { x, y, style } = useDraggable(cropBoxRef, {\n containerElement: containerBoxRef,\n draggingElement: cropBoxRef,\n disabled: computed(() => !!dargPoint.value),\n exact: true,\n initialValue,\n})\n\nconst imageUrl = computed(() => {\n if (!props.imgFile) {\n return ''\n }\n return URL.createObjectURL(props.imgFile)\n})\n\nwatch(\n () => props.imgFile,\n (newFile: File | null) => {\n if (newFile && !newFile.type.startsWith('image/')) {\n errorMessage.value = '文件类型错误'\n }\n else {\n errorMessage.value = ''\n }\n },\n)\n\nconst ratio = computed(() => {\n return (imgRef.value?.naturalWidth || 0) / imgWidth.value\n})\n\nconst customStyle = computed(() => {\n const position = {\n left: 0,\n top: 0,\n }\n if (dargPoint.value === 'bottom-right') {\n position.left = cropInfo.value.x\n position.top = cropInfo.value.y\n }\n else if (dargPoint.value === 'top-left') {\n position.left = cropInfo.value.x - width.value\n position.top = cropInfo.value.y - height.value\n }\n else if (dargPoint.value === 'top-right') {\n position.top = cropInfo.value.y - height.value\n position.left = cropInfo.value.x\n }\n else if (dargPoint.value === 'bottom-left') {\n position.left = cropInfo.value.x - width.value\n position.top = cropInfo.value.y\n }\n return position\n})\n\nconst sizeStyle = computed(() => {\n const { aspectRatio } = props\n\n const style: {\n 'height'?: string\n 'width': string\n 'aspect-ratio'?: string\n 'top': string\n 'left': string\n } = {\n 'width': `${cropInfo.value.width || props.defaultWidth}`,\n 'height': `${cropInfo.value.height || props.defaultHeight}`,\n 'aspect-ratio': aspectRatio,\n 'top': `${customStyle.value.top}px`,\n 'left': `${customStyle.value.left}px`,\n }\n if (props.zoomType === 'free') {\n delete style['aspect-ratio']\n }\n else if (props.zoomType === 'fixed') {\n delete style.height\n }\n return ns.cssVarBlock(style)\n})\n\nfunction zoom(pixel: number) {\n return pixel * ratio.value\n}\nasync function crop(img: HTMLImageElement = imgRef.value!) {\n let backgroundColor = 'transparent'\n if (containerBoxRef.value) {\n backgroundColor = window.getComputedStyle(\n containerBoxRef.value,\n ).backgroundColor\n }\n const canvas = document.createElement('canvas')\n canvas.width = zoom(containerBoxRef.value?.clientWidth || 0)\n canvas.height = zoom(containerBoxRef.value?.clientHeight || 0)\n const { drawImage, cropCanvas, drawColor } = useCanvas(canvas)\n drawColor(0, 0, canvas.width, canvas.height, backgroundColor)\n drawImage(\n img,\n zoom(img.offsetLeft),\n zoom(img.offsetTop),\n img.naturalWidth,\n img.naturalHeight,\n )\n return await cropCanvas(\n zoom(x.value),\n zoom(y.value),\n zoom(width.value),\n zoom(height.value),\n )\n}\n\nfunction checkBoundaries(\n newWidth: number,\n newHeight: number,\n): { width: number, height: number } {\n const maxWidth = containerBoxRef.value?.clientWidth || Infinity\n const maxHeight = containerBoxRef.value?.clientHeight || Infinity\n\n return {\n width: Math.min(Math.max(newWidth, 0), maxWidth),\n height: Math.min(Math.max(newHeight, 0), maxHeight),\n }\n}\n\nfunction mousemove(e: MouseEvent) {\n const deltaX = e.clientX - startX\n const deltaY = e.clientY - startY\n\n if (dargPoint.value === 'bottom-right') {\n if (props.zoomType === 'free') {\n const { width, height } = checkBoundaries(\n startWidth + deltaX,\n startHeight + deltaY,\n )\n cropInfo.value.width = width\n cropInfo.value.height = height\n }\n else if (props.zoomType === 'fixed') {\n const aspectRatio\n = Number.parseFloat(props.aspectRatio.split(' / ')[0])\n / Number.parseFloat(props.aspectRatio.split(' / ')[1])\n let newWidth = startWidth + deltaX\n let newHeight = newWidth / aspectRatio\n const { width, height } = checkBoundaries(newWidth, newHeight)\n if (height > (containerBoxRef.value?.clientHeight || Infinity)) {\n newHeight = containerBoxRef.value?.clientHeight || Infinity\n newWidth = newHeight * aspectRatio\n }\n cropInfo.value.width = width\n cropInfo.value.height = height\n }\n }\n else if (dargPoint.value === 'top-left') {\n if (props.zoomType === 'free') {\n const { width, height } = checkBoundaries(\n startWidth - deltaX,\n startHeight - deltaY,\n )\n cropInfo.value.width = width\n cropInfo.value.height = height\n }\n else if (props.zoomType === 'fixed') {\n const aspectRatio\n = Number.parseFloat(props.aspectRatio.split(' / ')[0])\n / Number.parseFloat(props.aspectRatio.split(' / ')[1])\n let newWidth = startWidth - deltaX\n let newHeight = newWidth / aspectRatio\n const { width, height } = checkBoundaries(newWidth, newHeight)\n if (height > (containerBoxRef.value?.clientHeight || Infinity)) {\n newHeight = containerBoxRef.value?.clientHeight || Infinity\n newWidth = newHeight * aspectRatio\n }\n cropInfo.value.width = width\n cropInfo.value.height = height\n }\n x.value = customStyle.value.left\n y.value = customStyle.value.top\n }\n else if (dargPoint.value === 'top-right') {\n if (props.zoomType === 'free') {\n const { width, height } = checkBoundaries(\n startWidth + deltaX,\n startHeight - deltaY,\n )\n cropInfo.value.width = width\n cropInfo.value.height = height\n }\n else if (props.zoomType === 'fixed') {\n const aspectRatio\n = Number.parseFloat(props.aspectRatio.split(' / ')[0])\n / Number.parseFloat(props.aspectRatio.split(' / ')[1])\n let newWidth = startWidth + deltaX\n let newHeight = newWidth / aspectRatio\n const { width, height } = checkBoundaries(newWidth, newHeight)\n if (height > (containerBoxRef.value?.clientHeight || Infinity)) {\n newHeight = containerBoxRef.value?.clientHeight || Infinity\n newWidth = newHeight * aspectRatio\n }\n cropInfo.value.width = width\n cropInfo.value.height = height\n }\n x.value = customStyle.value.left\n y.value = customStyle.value.top\n }\n else if (dargPoint.value === 'bottom-left') {\n if (props.zoomType === 'free') {\n const { width, height } = checkBoundaries(\n startWidth - deltaX,\n startHeight + deltaY,\n )\n cropInfo.value.width = width\n cropInfo.value.height = height\n }\n else if (props.zoomType === 'fixed') {\n const aspectRatio\n = Number.parseFloat(props.aspectRatio.split(' / ')[0])\n / Number.parseFloat(props.aspectRatio.split(' / ')[1])\n let newWidth = startWidth - deltaX\n let newHeight = newWidth / aspectRatio\n const { width, height } = checkBoundaries(newWidth, newHeight)\n if (height > (containerBoxRef.value?.clientHeight || Infinity)) {\n newHeight = containerBoxRef.value?.clientHeight || Infinity\n newWidth = newHeight * aspectRatio\n }\n cropInfo.value.width = width\n cropInfo.value.height = height\n }\n x.value = customStyle.value.left\n y.value = customStyle.value.top\n }\n e.preventDefault()\n e.stopPropagation()\n}\n\nfunction mousedown(e: MouseEvent, point: string) {\n dargPoint.value = point\n startX = e.clientX\n startY = e.clientY\n startWidth = cropInfo.value.width\n startHeight = cropInfo.value.height\n\n if (point === 'bottom-right') {\n cropInfo.value.x = x.value\n cropInfo.value.y = y.value\n }\n else if (point === 'top-left') {\n cropInfo.value.x = x.value + width.value\n cropInfo.value.y = y.value + height.value\n }\n else if (point === 'top-right') {\n cropInfo.value.x = x.value\n cropInfo.value.y = y.value + height.value\n }\n else if (point === 'bottom-left') {\n cropInfo.value.x = x.value + width.value\n cropInfo.value.y = y.value\n }\n}\n\nfunction mouseup() {\n dargPoint.value = ''\n}\n\nfunction resize() {\n cropInfo.value.width = props.defaultWidth\n cropInfo.value.height = props.defaultHeight\n x.value = 0\n y.value = 0\n}\n\ndocument.addEventListener('mouseup', mouseup)\ndocument.addEventListener('mousemove', mousemove)\n\nonMounted(() => {\n nextTick(() => {\n // 初始化位置\n initialValue.value.x\n = (containerBoxRef.value?.offsetWidth || 0) / 2 - cropInfo.value.width / 2\n initialValue.value.y\n = (containerBoxRef.value?.offsetHeight || 0) / 2\n - cropInfo.value.height / 2\n })\n})\n\nonUnmounted(() => {\n if (imageUrl.value) {\n URL.revokeObjectURL(imageUrl.value)\n }\n document.removeEventListener('mouseup', mouseup)\n document.removeEventListener('mousemove', mousemove)\n})\n\ndefineExpose({\n crop,\n resize,\n})\n</script>\n\n<template>\n <div\n ref=\"containerBoxRef\"\n :class=\"[ns.e('img-box')]\"\n >\n <div\n v-if=\"errorMessage\"\n :class=\"[ns.e('error-message')]\"\n >\n {{ errorMessage }}\n </div>\n <template v-else>\n <img\n ref=\"imgRef\"\n :class=\"[ns.e('image')]\"\n :src=\"imageUrl\"\n >\n <div\n ref=\"cropBoxRef\"\n :class=\"[ns.e('crop-tool-box')]\"\n :style=\"[\n sizeStyle,\n dargPoint\n ? `left: ${customStyle.left}px;top: ${customStyle.top}px`\n : style,\n ]\"\n >\n <div\n :class=\"[ns.e('top-left')]\"\n @mousedown=\"mousedown($event, 'top-left')\"\n />\n <div\n :class=\"[ns.e('top-right')]\"\n @mousedown=\"mousedown($event, 'top-right')\"\n />\n <div\n :class=\"[ns.e('bottom-right')]\"\n @mousedown=\"mousedown($event, 'bottom-right')\"\n />\n <div\n :class=\"[ns.e('bottom-left')]\"\n @mousedown=\"mousedown($event, 'bottom-left')\"\n />\n </div>\n </template>\n </div>\n</template>\n"],"names":["props","__props","startX","startY","startWidth","startHeight","ns","useNamespace","cropBoxRef","ref","containerBoxRef","imgRef","errorMessage","dargPoint","initialValue","x","y","cropInfo","width","defaultWidth","height","defaultHeight","useElementSize","imgWidth","style","useDraggable","containerElement","draggingElement","disabled","computed","value","exact","imageUrl","imgFile","URL","createObjectURL","watch","newFile","type","startsWith","ratio","naturalWidth","customStyle","position","left","top","sizeStyle","aspectRatio","zoomType","cssVarBlock","zoom","pixel","checkBoundaries","newWidth","newHeight","maxWidth","clientWidth","Infinity","maxHeight","clientHeight","Math","min","max","mousemove","e","deltaX","clientX","deltaY","clientY","Number","parseFloat","split","preventDefault","stopPropagation","mousedown","point","mouseup","document","addEventListener","onMounted","nextTick","offsetWidth","offsetHeight","onUnmounted","revokeObjectURL","removeEventListener","__expose","crop","async","img","backgroundColor","window","getComputedStyle","canvas","createElement","drawImage","cropCanvas","drawColor","useCanvas","offsetLeft","offsetTop","naturalHeight","resize"],"mappings":"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"}
1
+ {"version":3,"file":"photo-crop-tool.vue.cjs","sources":["../../../../../../packages/components/src/photo-crop-tool/src/photo-crop-tool.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { PropType } from 'vue'\nimport { useNamespace } from '@qxs-bns/hooks'\nimport { useCanvas } from './composables'\n\ndefineOptions({\n name: 'QxsPhotoCropTool',\n})\n\nconst props = defineProps({\n imgFile: {\n type: Object as PropType<File>,\n default: () => null,\n },\n aspectRatio: {\n type: String,\n default: () => '16 / 9',\n },\n defaultWidth: {\n type: Number,\n default: () => 320,\n },\n defaultHeight: {\n type: Number,\n default: () => 180,\n },\n /**\n * free 自由缩放\n * fixed 固定比例缩放\n */\n zoomType: {\n type: String,\n default: () => 'fixed',\n },\n})\nlet startX = 0\nlet startY = 0\nlet startWidth = 0\nlet startHeight = 0\n\nconst ns = useNamespace('photo-crop-tool')\n\nconst cropBoxRef = ref<HTMLElement | null>(null)\nconst containerBoxRef = ref<HTMLElement | null>(null)\nconst imgRef = ref<HTMLImageElement | null>(null)\nconst errorMessage = ref('')\nconst dargPoint = ref('')\nconst initialValue = ref({\n x: 0,\n y: 0,\n})\nconst cropInfo = ref({\n width: props.defaultWidth,\n height: props.defaultHeight,\n x: 0,\n y: 0,\n})\n\nconst { width, height } = useElementSize(cropBoxRef)\nconst { width: imgWidth } = useElementSize(imgRef)\n\nconst { x, y, style } = useDraggable(cropBoxRef, {\n containerElement: containerBoxRef,\n draggingElement: cropBoxRef,\n disabled: computed(() => !!dargPoint.value),\n exact: true,\n initialValue,\n})\n\nconst imageUrl = computed(() => {\n if (!props.imgFile) {\n return ''\n }\n return URL.createObjectURL(props.imgFile)\n})\n\nwatch(\n () => props.imgFile,\n (newFile: File | null) => {\n if (newFile && !newFile.type.startsWith('image/')) {\n errorMessage.value = '文件类型错误'\n }\n else {\n errorMessage.value = ''\n }\n },\n)\n\nconst ratio = computed(() => {\n return (imgRef.value?.naturalWidth || 0) / imgWidth.value\n})\n\nconst customStyle = computed(() => {\n const position = {\n left: 0,\n top: 0,\n }\n if (dargPoint.value === 'bottom-right') {\n position.left = cropInfo.value.x\n position.top = cropInfo.value.y\n }\n else if (dargPoint.value === 'top-left') {\n position.left = cropInfo.value.x - width.value\n position.top = cropInfo.value.y - height.value\n }\n else if (dargPoint.value === 'top-right') {\n position.top = cropInfo.value.y - height.value\n position.left = cropInfo.value.x\n }\n else if (dargPoint.value === 'bottom-left') {\n position.left = cropInfo.value.x - width.value\n position.top = cropInfo.value.y\n }\n return position\n})\n\nconst sizeStyle = computed(() => {\n const { aspectRatio } = props\n\n const style: {\n 'height'?: string\n 'width': string\n 'aspect-ratio'?: string\n 'top': string\n 'left': string\n } = {\n 'width': `${cropInfo.value.width || props.defaultWidth}`,\n 'height': `${cropInfo.value.height || props.defaultHeight}`,\n 'aspect-ratio': aspectRatio,\n 'top': `${customStyle.value.top}px`,\n 'left': `${customStyle.value.left}px`,\n }\n if (props.zoomType === 'free') {\n delete style['aspect-ratio']\n }\n else if (props.zoomType === 'fixed') {\n delete style.height\n }\n return ns.cssVarBlock(style)\n})\n\nfunction zoom(pixel: number) {\n return pixel * ratio.value\n}\nasync function crop(img: HTMLImageElement = imgRef.value!) {\n let backgroundColor = 'transparent'\n if (containerBoxRef.value) {\n backgroundColor = window.getComputedStyle(\n containerBoxRef.value,\n ).backgroundColor\n }\n const canvas = document.createElement('canvas')\n canvas.width = zoom(containerBoxRef.value?.clientWidth || 0)\n canvas.height = zoom(containerBoxRef.value?.clientHeight || 0)\n const { drawImage, cropCanvas, drawColor } = useCanvas(canvas)\n drawColor(0, 0, canvas.width, canvas.height, backgroundColor)\n drawImage(\n img,\n zoom(img.offsetLeft),\n zoom(img.offsetTop),\n img.naturalWidth,\n img.naturalHeight,\n )\n return await cropCanvas(\n zoom(x.value),\n zoom(y.value),\n zoom(width.value),\n zoom(height.value),\n )\n}\n\nfunction checkBoundaries(\n newWidth: number,\n newHeight: number,\n): { width: number, height: number } {\n const maxWidth = containerBoxRef.value?.clientWidth || Infinity\n const maxHeight = containerBoxRef.value?.clientHeight || Infinity\n\n return {\n width: Math.min(Math.max(newWidth, 0), maxWidth),\n height: Math.min(Math.max(newHeight, 0), maxHeight),\n }\n}\n\nfunction getClientPos(e: MouseEvent | TouchEvent): { clientX: number, clientY: number } {\n if (e instanceof MouseEvent) {\n return { clientX: e.clientX, clientY: e.clientY }\n }\n else if (e instanceof TouchEvent && e.touches.length > 0) {\n return { clientX: e.touches[0].clientX, clientY: e.touches[0].clientY }\n }\n return { clientX: 0, clientY: 0 }\n}\n\nfunction handleStart(e: MouseEvent | TouchEvent, point: string) {\n const { clientX, clientY } = getClientPos(e)\n dargPoint.value = point\n startX = clientX\n startY = clientY\n startWidth = cropInfo.value.width\n startHeight = cropInfo.value.height\n\n // 添加移动端事件监听\n document.addEventListener('touchmove', handleMove, { passive: false })\n document.addEventListener('touchend', handleEnd)\n\n if (point === 'bottom-right') {\n cropInfo.value.x = x.value\n cropInfo.value.y = y.value\n }\n else if (point === 'top-left') {\n cropInfo.value.x = x.value + width.value\n cropInfo.value.y = y.value + height.value\n }\n else if (point === 'top-right') {\n cropInfo.value.x = x.value\n cropInfo.value.y = y.value + height.value\n }\n else if (point === 'bottom-left') {\n cropInfo.value.x = x.value + width.value\n cropInfo.value.y = y.value\n }\n\n // Prevent touch scrolling\n if (e instanceof TouchEvent) {\n e.preventDefault()\n }\n}\n\nfunction handleMove(e: MouseEvent | TouchEvent) {\n // Only prevent default if we're in a drag operation\n if (e instanceof TouchEvent && dargPoint.value) {\n e.preventDefault()\n }\n\n const { clientX, clientY } = getClientPos(e)\n const deltaX = clientX - startX\n const deltaY = clientY - startY\n\n if (dargPoint.value === 'bottom-right') {\n if (props.zoomType === 'free') {\n const { width, height } = checkBoundaries(\n startWidth + deltaX,\n startHeight + deltaY,\n )\n cropInfo.value.width = width\n cropInfo.value.height = height\n }\n else if (props.zoomType === 'fixed') {\n const aspectRatio\n = Number.parseFloat(props.aspectRatio.split(' / ')[0])\n / Number.parseFloat(props.aspectRatio.split(' / ')[1])\n let newWidth = startWidth + deltaX\n let newHeight = newWidth / aspectRatio\n const { width, height } = checkBoundaries(newWidth, newHeight)\n if (height > (containerBoxRef.value?.clientHeight || Infinity)) {\n newHeight = containerBoxRef.value?.clientHeight || Infinity\n newWidth = newHeight * aspectRatio\n }\n cropInfo.value.width = width\n cropInfo.value.height = height\n }\n }\n else if (dargPoint.value === 'top-left') {\n if (props.zoomType === 'free') {\n const { width, height } = checkBoundaries(\n startWidth - deltaX,\n startHeight - deltaY,\n )\n cropInfo.value.width = width\n cropInfo.value.height = height\n }\n else if (props.zoomType === 'fixed') {\n const aspectRatio\n = Number.parseFloat(props.aspectRatio.split(' / ')[0])\n / Number.parseFloat(props.aspectRatio.split(' / ')[1])\n let newWidth = startWidth - deltaX\n let newHeight = newWidth / aspectRatio\n const { width, height } = checkBoundaries(newWidth, newHeight)\n if (height > (containerBoxRef.value?.clientHeight || Infinity)) {\n newHeight = containerBoxRef.value?.clientHeight || Infinity\n newWidth = newHeight * aspectRatio\n }\n cropInfo.value.width = width\n cropInfo.value.height = height\n }\n x.value = customStyle.value.left\n y.value = customStyle.value.top\n }\n else if (dargPoint.value === 'top-right') {\n if (props.zoomType === 'free') {\n const { width, height } = checkBoundaries(\n startWidth + deltaX,\n startHeight - deltaY,\n )\n cropInfo.value.width = width\n cropInfo.value.height = height\n }\n else if (props.zoomType === 'fixed') {\n const aspectRatio\n = Number.parseFloat(props.aspectRatio.split(' / ')[0])\n / Number.parseFloat(props.aspectRatio.split(' / ')[1])\n let newWidth = startWidth + deltaX\n let newHeight = newWidth / aspectRatio\n const { width, height } = checkBoundaries(newWidth, newHeight)\n if (height > (containerBoxRef.value?.clientHeight || Infinity)) {\n newHeight = containerBoxRef.value?.clientHeight || Infinity\n newWidth = newHeight * aspectRatio\n }\n cropInfo.value.width = width\n cropInfo.value.height = height\n }\n x.value = customStyle.value.left\n y.value = customStyle.value.top\n }\n else if (dargPoint.value === 'bottom-left') {\n if (props.zoomType === 'free') {\n const { width, height } = checkBoundaries(\n startWidth - deltaX,\n startHeight + deltaY,\n )\n cropInfo.value.width = width\n cropInfo.value.height = height\n }\n else if (props.zoomType === 'fixed') {\n const aspectRatio\n = Number.parseFloat(props.aspectRatio.split(' / ')[0])\n / Number.parseFloat(props.aspectRatio.split(' / ')[1])\n let newWidth = startWidth - deltaX\n let newHeight = newWidth / aspectRatio\n const { width, height } = checkBoundaries(newWidth, newHeight)\n if (height > (containerBoxRef.value?.clientHeight || Infinity)) {\n newHeight = containerBoxRef.value?.clientHeight || Infinity\n newWidth = newHeight * aspectRatio\n }\n cropInfo.value.width = width\n cropInfo.value.height = height\n }\n x.value = customStyle.value.left\n y.value = customStyle.value.top\n }\n}\n\nfunction handleEnd() {\n // 移除移动端事件监听\n document.removeEventListener('touchmove', handleMove)\n document.removeEventListener('touchend', handleEnd)\n\n dargPoint.value = ''\n}\n\nfunction resize() {\n cropInfo.value.width = props.defaultWidth\n cropInfo.value.height = props.defaultHeight\n x.value = 0\n y.value = 0\n}\n\nonMounted(() => {\n nextTick(() => {\n // 初始化位置\n initialValue.value.x\n = (containerBoxRef.value?.offsetWidth || 0) / 2 - cropInfo.value.width / 2\n initialValue.value.y\n = (containerBoxRef.value?.offsetHeight || 0) / 2\n - cropInfo.value.height / 2\n })\n\n // 只添加鼠标事件监听\n document.addEventListener('mouseup', handleEnd)\n document.addEventListener('mousemove', handleMove, { passive: false })\n document.addEventListener('touchmove', handleMove, { passive: false })\n document.addEventListener('touchend', handleEnd)\n})\n\nonUnmounted(() => {\n if (imageUrl.value) {\n URL.revokeObjectURL(imageUrl.value)\n }\n // 确保移除所有事件监听\n document.removeEventListener('mouseup', handleEnd)\n document.removeEventListener('mousemove', handleMove)\n})\n\ndefineExpose({\n crop,\n resize,\n})\n</script>\n\n<template>\n <div\n ref=\"containerBoxRef\"\n :class=\"[ns.e('img-box')]\"\n >\n <div\n v-if=\"errorMessage\"\n :class=\"[ns.e('error-message')]\"\n >\n {{ errorMessage }}\n </div>\n <template v-else>\n <img\n ref=\"imgRef\"\n :class=\"[ns.e('image')]\"\n :src=\"imageUrl\"\n >\n <div\n ref=\"cropBoxRef\"\n :class=\"[ns.e('crop-tool-box')]\"\n :style=\"[\n sizeStyle,\n dargPoint\n ? `left: ${customStyle.left}px;top: ${customStyle.top}px`\n : style,\n ]\"\n @touchstart.stop.prevent\n @touchend.stop.prevent=\"handleEnd\"\n >\n <div\n :class=\"[ns.e('top-left')]\"\n @mousedown.stop.prevent=\"handleStart($event, 'top-left')\"\n @touchstart.stop.prevent=\"handleStart($event, 'top-left')\"\n @touchend.stop.prevent=\"handleEnd\"\n />\n <div\n :class=\"[ns.e('top-right')]\"\n @mousedown.stop.prevent=\"handleStart($event, 'top-right')\"\n @touchstart.stop.prevent=\"handleStart($event, 'top-right')\"\n @touchend.stop.prevent=\"handleEnd\"\n />\n <div\n :class=\"[ns.e('bottom-right')]\"\n @mousedown.stop.prevent=\"handleStart($event, 'bottom-right')\"\n @touchstart.stop.prevent=\"handleStart($event, 'bottom-right')\"\n @touchend.stop.prevent=\"handleEnd\"\n />\n <div\n :class=\"[ns.e('bottom-left')]\"\n @mousedown.stop.prevent=\"handleStart($event, 'bottom-left')\"\n @touchstart.stop.prevent=\"handleStart($event, 'bottom-left')\"\n @touchend.stop.prevent=\"handleEnd\"\n />\n </div>\n </template>\n </div>\n</template>\n"],"names":["props","__props","startX","startY","startWidth","startHeight","ns","useNamespace","cropBoxRef","ref","containerBoxRef","imgRef","errorMessage","dargPoint","initialValue","x","y","cropInfo","width","defaultWidth","height","defaultHeight","useElementSize","imgWidth","style","useDraggable","containerElement","draggingElement","disabled","computed","value","exact","imageUrl","imgFile","URL","createObjectURL","watch","newFile","type","startsWith","ratio","naturalWidth","customStyle","position","left","top","sizeStyle","aspectRatio","zoomType","cssVarBlock","zoom","pixel","checkBoundaries","newWidth","newHeight","maxWidth","clientWidth","Infinity","maxHeight","clientHeight","Math","min","max","getClientPos","e","MouseEvent","clientX","clientY","TouchEvent","touches","length","handleStart","point","document","addEventListener","handleMove","passive","handleEnd","preventDefault","deltaX","deltaY","Number","parseFloat","split","removeEventListener","onMounted","nextTick","offsetWidth","offsetHeight","onUnmounted","revokeObjectURL","__expose","crop","async","img","backgroundColor","window","getComputedStyle","canvas","createElement","drawImage","cropCanvas","drawColor","useCanvas","offsetLeft","offsetTop","naturalHeight","resize"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("vue"),n=require("@qxs-bns/hooks"),i=require("lodash-es"),t=require("tinymce/tinymce");require("tinymce/themes/silver/theme"),require("tinymce/icons/default/icons"),require("tinymce/models/dom"),require("tinymce/plugins/autolink"),require("tinymce/plugins/autoresize"),require("tinymce/plugins/fullscreen"),require("tinymce/plugins/image"),require("tinymce/plugins/insertdatetime"),require("tinymce/plugins/link"),require("tinymce/plugins/lists"),require("tinymce/plugins/media"),require("tinymce/plugins/preview"),require("tinymce/plugins/table"),require("tinymce/plugins/wordcount"),require("tinymce/plugins/code"),require("tinymce/plugins/searchreplace"),require("tinymce/plugins/nonbreaking");const r=["id","name"];var l=e.defineComponent({name:"QxsTinyMceEditor",__name:"tiny-mce-editor",props:{modelValue:{type:String,required:!0,default:""},config:{type:Object,required:!1,default:()=>({})},assetsBasePath:{type:String,required:!1,default:""}},emits:["update:modelValue"],setup(l,{emit:a}){const u=a,s=n.useNamespace("tiny-mce-editor"),o=l.assetsBasePath||"node_modules/",m=e.shallowRef(null),c=e.ref(`tiny-mce-textarea-${Date.now()}-${Math.random().toString(36).substr(2,9)}`),d=e.computed({get:()=>l.modelValue,set(e){u("update:modelValue",e)}}),g={selector:`textarea#${c.value}`,promotion:!1,license_key:"gpl",elementpath:!1,language:"zh-Hans",language_url:`${o}tinymce/langs/zh-Hans.js`,skin_url:`${o}tinymce/skins/ui/oxide`,content_css:`${o}tinymce/skins/content/default/content.min.css`,min_height:300,max_height:700,plugins:"autolink autoresize fullscreen image insertdatetime link lists media preview table wordcount code searchreplace nonbreaking",toolbar:"undo redo | bold italic underline strikethrough | blocks | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | forecolor backcolor removeformat | link image media table insertdatetime searchreplace | preview code",branding:!1,autoresize:!0,menubar:!1,nonbreaking_force_tab:!0,toolbar_mode:"sliding",insertdatetime_formats:["%Y年%m月%d日","%H点%M分%S秒","%Y-%m-%d","%H:%M:%S"],setup:e=>{m.value=e,e.on("input change undo redo",(()=>{d.value=e.getContent()})),e.on("init",(()=>{e.setContent(d.value)})),l.config?.expandSetup?.(e)}},p=e.computed((()=>{const e=g;return l.config.images_upload_handler||("string"==typeof e.plugins?e.plugins=e.plugins.replace("image",""):Array.isArray(e.plugins)&&(e.plugins=e.plugins.filter((e=>"image"!==e)))),i.merge(e,l.config)}));return e.watch((()=>l.modelValue),(e=>{m.value&&e!==m.value.getContent()&&m.value.setContent(e)}),{immediate:!0}),e.onMounted((async()=>{"undefined"!=typeof window&&t.init(p.value)})),e.onBeforeUnmount((()=>{m.value&&(m.value.destroy(),m.value=null)})),(n,i)=>(e.openBlock(),e.createElementBlock("div",{class:e.normalizeClass(e.unref(s).e("tiny-mce"))},[e.createCommentVNode(" 使用动态生成的 id "),e.withDirectives(e.createElementVNode("textarea",{id:e.unref(c),"onUpdate:modelValue":i[0]||(i[0]=n=>e.isRef(d)?d.value=n:null),name:e.unref(c)},null,8,r),[[e.vModelText,e.unref(d)]])],2))}});exports.default=l;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("vue"),n=require("@qxs-bns/hooks"),i=require("lodash-es"),t=require("tinymce/tinymce");require("tinymce/themes/silver/theme"),require("tinymce/icons/default/icons"),require("tinymce/models/dom"),require("tinymce/plugins/autolink"),require("tinymce/plugins/autoresize"),require("tinymce/plugins/fullscreen"),require("tinymce/plugins/image"),require("tinymce/plugins/insertdatetime"),require("tinymce/plugins/link"),require("tinymce/plugins/lists"),require("tinymce/plugins/media"),require("tinymce/plugins/preview"),require("tinymce/plugins/table"),require("tinymce/plugins/wordcount"),require("tinymce/plugins/code"),require("tinymce/plugins/searchreplace"),require("tinymce/plugins/nonbreaking");const r=["id","name"];var l=e.defineComponent({name:"QxsTinyMceEditor",__name:"tiny-mce-editor",props:{modelValue:{type:String,required:!0,default:""},config:{type:Object,required:!1,default:()=>({})},assetsBasePath:{type:String,required:!1,default:""}},emits:["update:modelValue"],setup(l,{emit:a}){const u=a,o=n.useNamespace("tiny-mce-editor"),s=l.assetsBasePath||"node_modules/",c=e.shallowRef(null),m=e.ref(`tiny-mce-textarea-${Date.now()}-${Math.random().toString(36).substr(2,9)}`),d=e.computed({get:()=>l.modelValue,set(e){u("update:modelValue",e)}}),g={selector:`textarea#${m.value}`,promotion:!1,license_key:"gpl",elementpath:!1,language:"zh-Hans",language_url:`${s}tinymce/langs/zh-Hans.js`,skin_url:`${s}tinymce/skins/ui/oxide`,content_css:`${s}tinymce/skins/content/default/content.min.css`,min_height:300,max_height:700,plugins:"autolink autoresize fullscreen image insertdatetime link lists media preview table wordcount code searchreplace nonbreaking",toolbar:"undo redo | bold italic underline strikethrough | blocks | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | forecolor backcolor removeformat | link image media table insertdatetime searchreplace | preview code",branding:!1,autoresize:!0,menubar:!1,nonbreaking_force_tab:!0,toolbar_mode:"sliding",insertdatetime_formats:["%Y年%m月%d日","%H点%M分%S秒","%Y-%m-%d","%H:%M:%S"],setup:e=>{e.on("init",(()=>{c.value=e,e.setContent(d.value)})),e.on("input change undo redo",(()=>{d.value=e.getContent()})),l.config?.expandSetup?.(e)}},p=e.computed((()=>{const e=g;return l.config.images_upload_handler||("string"==typeof e.plugins?e.plugins=e.plugins.replace("image",""):Array.isArray(e.plugins)&&(e.plugins=e.plugins.filter((e=>"image"!==e)))),i.merge(e,l.config)}));return e.watch((()=>l.modelValue),(e=>{try{c.value&&e!==c.value?.getContent()&&c.value.setContent(e)}catch(e){console.error("设置编辑器内容时出错:",e)}})),e.onMounted((async()=>{"undefined"!=typeof window&&t.init(p.value)})),e.onBeforeUnmount((()=>{c.value&&(c.value.destroy(),c.value=null)})),(n,i)=>(e.openBlock(),e.createElementBlock("div",{class:e.normalizeClass(e.unref(o).e("tiny-mce"))},[e.createCommentVNode(" 使用动态生成的 id "),e.withDirectives(e.createElementVNode("textarea",{id:e.unref(m),"onUpdate:modelValue":i[0]||(i[0]=n=>e.isRef(d)?d.value=n:null),name:e.unref(m)},null,8,r),[[e.vModelText,e.unref(d)]])],2))}});exports.default=l;
2
2
  //# sourceMappingURL=tiny-mce-editor.vue.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"tiny-mce-editor.vue.cjs","sources":["../../../../../../packages/components/src/tiny-mce-editor/src/tiny-mce-editor.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { Editor, RawEditorOptions } from 'tinymce/tinymce'\nimport { useNamespace } from '@qxs-bns/hooks'\nimport { merge } from 'lodash-es'\nimport tinymce from 'tinymce/tinymce'\n\n// 导入核心功能\nimport 'tinymce/themes/silver/theme'\nimport 'tinymce/icons/default/icons'\nimport 'tinymce/models/dom'\n\nimport 'tinymce/plugins/autolink'\nimport 'tinymce/plugins/autoresize'\nimport 'tinymce/plugins/fullscreen'\nimport 'tinymce/plugins/image'\nimport 'tinymce/plugins/insertdatetime'\nimport 'tinymce/plugins/link'\nimport 'tinymce/plugins/lists'\nimport 'tinymce/plugins/media'\nimport 'tinymce/plugins/preview'\nimport 'tinymce/plugins/table'\nimport 'tinymce/plugins/wordcount'\nimport 'tinymce/plugins/code'\nimport 'tinymce/plugins/searchreplace'\nimport 'tinymce/plugins/nonbreaking'\n// 导入语言包\n\ndefineOptions({\n name: 'QxsTinyMceEditor',\n})\n\nconst {\n modelValue = '',\n config = {},\n assetsBasePath = '',\n} = defineProps<{\n modelValue: string\n config?: RawEditorOptions & {\n expandSetup?: RawEditorOptions['setup']\n }\n assetsBasePath?: string\n}>()\n\nconst emit = defineEmits(['update:modelValue'])\n\nconst ns = useNamespace('tiny-mce-editor')\n\nconst colorScheme = 'light'\nconst basePath = assetsBasePath || 'node_modules/'\n// 存储编辑器实例的引用\nconst editorInstance = shallowRef<Editor | null>(null)\n// 生成唯一的 id\nconst uniqueId = ref(\n `tiny-mce-textarea-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,\n)\n\nconst content = computed({\n get() {\n return modelValue\n },\n set(val) {\n emit('update:modelValue', val)\n },\n})\n\nconst defaultSetting: RawEditorOptions = {\n // 使用动态生成的 id\n selector: `textarea#${uniqueId.value}`,\n promotion: false, // 禁用推广信息\n license_key: 'gpl',\n elementpath: false,\n language: 'zh-Hans',\n language_url: `${basePath}tinymce/langs/zh-Hans.js`,\n skin_url: `${basePath}${\n colorScheme === 'light' ? 'tinymce/skins/ui/oxide' : 'tinymce/skins/ui/oxide-dark'\n }`,\n content_css: `${basePath}${\n colorScheme === 'light'\n ? 'tinymce/skins/content/default/content.min.css'\n : 'tinymce/skins/content/dark/content.min.css'\n }`,\n min_height: 300,\n max_height: 700,\n plugins:\n 'autolink autoresize fullscreen image insertdatetime link lists media preview table wordcount code searchreplace nonbreaking',\n toolbar:\n 'undo redo | bold italic underline strikethrough | blocks | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | forecolor backcolor removeformat | link image media table insertdatetime searchreplace | preview code',\n branding: false,\n autoresize: true,\n menubar: false,\n nonbreaking_force_tab: true,\n toolbar_mode: 'sliding',\n insertdatetime_formats: [\n '%Y年%m月%d日',\n '%H点%M分%S秒',\n '%Y-%m-%d',\n '%H:%M:%S',\n ],\n // https://www.tiny.cloud/docs/tinymce/6/file-image-upload/#images_upload_handler\n // images_upload_handler: async (blobInfo: any, progress: any) => {\n // // blobInfo, succFun, failFun, progress\n // const files = blobInfo.blob()\n // const formData = new FormData()\n // formData.append('image', files)\n\n // const { res, error } = await useApi({\n // // ...commonUrls.uploadImage,\n // params: {\n // bucketType: classify,\n // },\n // data: formData,\n // onUploadProgress: (e: any) => {\n // progress((e.loaded / e.total) * 100)\n // },\n // })\n // if (res) {\n // const { normal } = res\n // console.log('normal: ', res)\n // return normal\n // }\n // if (error) {\n // console.log(error.message)\n // return Promise.reject(error.message)\n // }\n // },\n setup: (editor: Editor) => {\n // 保存编辑器实例\n editorInstance.value = editor\n\n // 监听编辑器内容变化\n editor.on('input change undo redo', () => {\n content.value = editor.getContent()\n })\n\n // 编辑器初始化完成后设置内容\n editor.on('init', () => {\n editor.setContent(content.value)\n })\n\n config?.expandSetup?.(editor)\n },\n}\n\nconst initSetting = computed(() => {\n const dealDefaultSetting = defaultSetting\n if (!config.images_upload_handler) {\n // 删除 image 图片 plugin\n if (typeof dealDefaultSetting.plugins === 'string') {\n dealDefaultSetting.plugins = dealDefaultSetting.plugins.replace(\n 'image',\n '',\n )\n }\n else if (Array.isArray(dealDefaultSetting.plugins)) {\n dealDefaultSetting.plugins = dealDefaultSetting.plugins.filter(\n plugin => plugin !== 'image',\n )\n }\n }\n return merge(dealDefaultSetting, config)\n})\n\n// 监听 modelValue 的变化\nwatch(() => modelValue, (newVal) => {\n // 确保编辑器已初始化且内容确实发生变化\n if (editorInstance.value && newVal !== editorInstance.value.getContent()) {\n editorInstance.value.setContent(newVal)\n }\n}, { immediate: true })\n\nonMounted(async () => {\n if (typeof window !== 'undefined') {\n tinymce.init(initSetting.value)\n }\n})\n\n// 组件卸载时清理\nonBeforeUnmount(() => {\n if (editorInstance.value) {\n editorInstance.value.destroy()\n editorInstance.value = null\n }\n})\n</script>\n\n<template>\n <div :class=\"ns.e('tiny-mce')\">\n <!-- 使用动态生成的 id -->\n <textarea\n :id=\"uniqueId\"\n v-model=\"content\"\n :name=\"uniqueId\"\n />\n </div>\n</template>\n"],"names":["emit","__emit","ns","useNamespace","basePath","__props","assetsBasePath","editorInstance","shallowRef","uniqueId","ref","Date","now","Math","random","toString","substr","content","computed","get","modelValue","set","val","defaultSetting","selector","value","promotion","license_key","elementpath","language","language_url","skin_url","content_css","min_height","max_height","plugins","toolbar","branding","autoresize","menubar","nonbreaking_force_tab","toolbar_mode","insertdatetime_formats","setup","editor","on","getContent","setContent","config","expandSetup","initSetting","dealDefaultSetting","images_upload_handler","replace","Array","isArray","filter","plugin","merge","watch","newVal","immediate","onMounted","async","window","tinymce","init","onBeforeUnmount","destroy"],"mappings":"ujCA2CA,MAAMA,EAAOC,EAEPC,EAAKC,eAAa,mBAGlBC,EAAWC,EAAAC,gBAAkB,gBAE7BC,EAAiBC,aAA0B,MAE3CC,EAAWC,EAAAA,IACf,qBAAqBC,KAAKC,SAASC,KAAKC,SAASC,SAAS,IAAIC,OAAO,EAAG,MAGpEC,EAAUC,EAAAA,SAAS,CACvBC,IAAM,IACGd,EAAAe,WAET,GAAAC,CAAIC,GACFtB,EAAK,oBAAqBsB,EAAG,IAI3BC,EAAmC,CAEvCC,SAAU,YAAYf,EAASgB,QAC/BC,WAAW,EACXC,YAAa,MACbC,aAAa,EACbC,SAAU,UACVC,aAAc,GAAG1B,4BACjB2B,SAAU,GAAG3B,0BAGb4B,YAAa,GAAG5B,iDAKhB6B,WAAY,IACZC,WAAY,IACZC,QACE,8HACFC,QACE,oPACFC,UAAU,EACVC,YAAY,EACZC,SAAS,EACTC,uBAAuB,EACvBC,aAAc,UACdC,uBAAwB,CACtB,YACA,YACA,WACA,YA6BFC,MAAQC,IAENrC,EAAekB,MAAQmB,EAGhBA,EAAAC,GAAG,0BAA0B,KAC1B5B,EAAAQ,MAAQmB,EAAOE,YAAW,IAI7BF,EAAAC,GAAG,QAAQ,KACTD,EAAAG,WAAW9B,EAAQQ,MAAK,IAG3BpB,EAAA2C,QAAEC,cAAcL,EAAM,GAI1BM,EAAchC,EAAAA,UAAS,KAC3B,MAAMiC,EAAqB5B,EAepB,OAdFlB,EAAM2C,OAACI,wBAEgC,iBAA/BD,EAAmBhB,QACTgB,EAAAhB,QAAUgB,EAAmBhB,QAAQkB,QACtD,QACA,IAGKC,MAAMC,QAAQJ,EAAmBhB,WACrBgB,EAAAhB,QAAUgB,EAAmBhB,QAAQqB,WACjC,UAAXC,MAITC,QAAMP,EAAoB9C,EAAM2C,OAAA,WAIzCW,EAAAA,OAAM,IAAMtD,EAAAe,aAAawC,IAEnBrD,EAAekB,OAASmC,IAAWrD,EAAekB,MAAMqB,cAC3CvC,EAAAkB,MAAMsB,WAAWa,EAAM,GAEvC,CAAEC,WAAW,IAEhBC,EAAAA,WAAUC,UACc,oBAAXC,QACDC,EAAAC,KAAKhB,EAAYzB,MAAK,IAKlC0C,EAAAA,iBAAgB,KACV5D,EAAekB,QACjBlB,EAAekB,MAAM2C,UACrB7D,EAAekB,MAAQ,KAAA"}
1
+ {"version":3,"file":"tiny-mce-editor.vue.cjs","sources":["../../../../../../packages/components/src/tiny-mce-editor/src/tiny-mce-editor.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { Editor, RawEditorOptions } from 'tinymce/tinymce'\nimport { useNamespace } from '@qxs-bns/hooks'\nimport { merge } from 'lodash-es'\nimport tinymce from 'tinymce/tinymce'\n\n// 导入核心功能\nimport 'tinymce/themes/silver/theme'\nimport 'tinymce/icons/default/icons'\nimport 'tinymce/models/dom'\n\nimport 'tinymce/plugins/autolink'\nimport 'tinymce/plugins/autoresize'\nimport 'tinymce/plugins/fullscreen'\nimport 'tinymce/plugins/image'\nimport 'tinymce/plugins/insertdatetime'\nimport 'tinymce/plugins/link'\nimport 'tinymce/plugins/lists'\nimport 'tinymce/plugins/media'\nimport 'tinymce/plugins/preview'\nimport 'tinymce/plugins/table'\nimport 'tinymce/plugins/wordcount'\nimport 'tinymce/plugins/code'\nimport 'tinymce/plugins/searchreplace'\nimport 'tinymce/plugins/nonbreaking'\n// 导入语言包\n\ndefineOptions({\n name: 'QxsTinyMceEditor',\n})\n\nconst {\n modelValue = '',\n config = {},\n assetsBasePath = '',\n} = defineProps<{\n modelValue: string\n config?: RawEditorOptions & {\n expandSetup?: RawEditorOptions['setup']\n }\n assetsBasePath?: string\n}>()\n\nconst emit = defineEmits(['update:modelValue'])\n\nconst ns = useNamespace('tiny-mce-editor')\n\nconst colorScheme = 'light'\nconst basePath = assetsBasePath || 'node_modules/'\n// 存储编辑器实例的引用\nconst editorInstance = shallowRef<Editor | null>(null)\n// 生成唯一的 id\nconst uniqueId = ref(\n `tiny-mce-textarea-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,\n)\n\nconst content = computed({\n get() {\n return modelValue\n },\n set(val) {\n emit('update:modelValue', val)\n },\n})\n\nconst defaultSetting: RawEditorOptions = {\n // 使用动态生成的 id\n selector: `textarea#${uniqueId.value}`,\n promotion: false, // 禁用推广信息\n license_key: 'gpl',\n elementpath: false,\n language: 'zh-Hans',\n language_url: `${basePath}tinymce/langs/zh-Hans.js`,\n skin_url: `${basePath}${\n colorScheme === 'light' ? 'tinymce/skins/ui/oxide' : 'tinymce/skins/ui/oxide-dark'\n }`,\n content_css: `${basePath}${\n colorScheme === 'light'\n ? 'tinymce/skins/content/default/content.min.css'\n : 'tinymce/skins/content/dark/content.min.css'\n }`,\n min_height: 300,\n max_height: 700,\n plugins:\n 'autolink autoresize fullscreen image insertdatetime link lists media preview table wordcount code searchreplace nonbreaking',\n toolbar:\n 'undo redo | bold italic underline strikethrough | blocks | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | forecolor backcolor removeformat | link image media table insertdatetime searchreplace | preview code',\n branding: false,\n autoresize: true,\n menubar: false,\n nonbreaking_force_tab: true,\n toolbar_mode: 'sliding',\n insertdatetime_formats: [\n '%Y年%m月%d日',\n '%H点%M分%S秒',\n '%Y-%m-%d',\n '%H:%M:%S',\n ],\n // https://www.tiny.cloud/docs/tinymce/6/file-image-upload/#images_upload_handler\n // images_upload_handler: async (blobInfo: any, progress: any) => {\n // // blobInfo, succFun, failFun, progress\n // const files = blobInfo.blob()\n // const formData = new FormData()\n // formData.append('image', files)\n\n // const { res, error } = await useApi({\n // // ...commonUrls.uploadImage,\n // params: {\n // bucketType: classify,\n // },\n // data: formData,\n // onUploadProgress: (e: any) => {\n // progress((e.loaded / e.total) * 100)\n // },\n // })\n // if (res) {\n // const { normal } = res\n // console.log('normal: ', res)\n // return normal\n // }\n // if (error) {\n // console.log(error.message)\n // return Promise.reject(error.message)\n // }\n // },\n setup: (editor: Editor) => {\n // 编辑器初始化完成后设置内容\n editor.on('init', () => {\n // 保存编辑器实例\n editorInstance.value = editor\n editor.setContent(content.value)\n })\n\n // 监听编辑器内容变化\n editor.on('input change undo redo', () => {\n content.value = editor.getContent()\n })\n\n config?.expandSetup?.(editor)\n },\n}\n\nconst initSetting = computed(() => {\n const dealDefaultSetting = defaultSetting\n if (!config.images_upload_handler) {\n // 删除 image 图片 plugin\n if (typeof dealDefaultSetting.plugins === 'string') {\n dealDefaultSetting.plugins = dealDefaultSetting.plugins.replace(\n 'image',\n '',\n )\n }\n else if (Array.isArray(dealDefaultSetting.plugins)) {\n dealDefaultSetting.plugins = dealDefaultSetting.plugins.filter(\n plugin => plugin !== 'image',\n )\n }\n }\n return merge(dealDefaultSetting, config)\n})\n\n// 监听 modelValue 的变化\nwatch(() => modelValue, (newVal) => {\n try {\n // 确保编辑器已初始化且内容确实发生变化\n if (editorInstance.value && newVal !== editorInstance.value?.getContent()) {\n editorInstance.value.setContent(newVal)\n }\n }\n catch (error) {\n console.error('设置编辑器内容时出错:', error)\n }\n})\n\nonMounted(async () => {\n if (typeof window !== 'undefined') {\n tinymce.init(initSetting.value)\n }\n})\n\n// 组件卸载时清理\nonBeforeUnmount(() => {\n if (editorInstance.value) {\n editorInstance.value.destroy()\n editorInstance.value = null\n }\n})\n</script>\n\n<template>\n <div :class=\"ns.e('tiny-mce')\">\n <!-- 使用动态生成的 id -->\n <textarea\n :id=\"uniqueId\"\n v-model=\"content\"\n :name=\"uniqueId\"\n />\n </div>\n</template>\n"],"names":["emit","__emit","ns","useNamespace","basePath","__props","assetsBasePath","editorInstance","shallowRef","uniqueId","ref","Date","now","Math","random","toString","substr","content","computed","get","modelValue","set","val","defaultSetting","selector","value","promotion","license_key","elementpath","language","language_url","skin_url","content_css","min_height","max_height","plugins","toolbar","branding","autoresize","menubar","nonbreaking_force_tab","toolbar_mode","insertdatetime_formats","setup","editor","on","setContent","getContent","config","expandSetup","initSetting","dealDefaultSetting","images_upload_handler","replace","Array","isArray","filter","plugin","merge","watch","newVal","error","console","onMounted","async","window","tinymce","init","onBeforeUnmount","destroy"],"mappings":"ujCA2CA,MAAMA,EAAOC,EAEPC,EAAKC,eAAa,mBAGlBC,EAAWC,EAAAC,gBAAkB,gBAE7BC,EAAiBC,aAA0B,MAE3CC,EAAWC,EAAAA,IACf,qBAAqBC,KAAKC,SAASC,KAAKC,SAASC,SAAS,IAAIC,OAAO,EAAG,MAGpEC,EAAUC,EAAAA,SAAS,CACvBC,IAAM,IACGd,EAAAe,WAET,GAAAC,CAAIC,GACFtB,EAAK,oBAAqBsB,EAAG,IAI3BC,EAAmC,CAEvCC,SAAU,YAAYf,EAASgB,QAC/BC,WAAW,EACXC,YAAa,MACbC,aAAa,EACbC,SAAU,UACVC,aAAc,GAAG1B,4BACjB2B,SAAU,GAAG3B,0BAGb4B,YAAa,GAAG5B,iDAKhB6B,WAAY,IACZC,WAAY,IACZC,QACE,8HACFC,QACE,oPACFC,UAAU,EACVC,YAAY,EACZC,SAAS,EACTC,uBAAuB,EACvBC,aAAc,UACdC,uBAAwB,CACtB,YACA,YACA,WACA,YA6BFC,MAAQC,IAECA,EAAAC,GAAG,QAAQ,KAEhBtC,EAAekB,MAAQmB,EAChBA,EAAAE,WAAW7B,EAAQQ,MAAK,IAI1BmB,EAAAC,GAAG,0BAA0B,KAC1B5B,EAAAQ,MAAQmB,EAAOG,YAAW,IAG9B1C,EAAA2C,QAAEC,cAAcL,EAAM,GAI1BM,EAAchC,EAAAA,UAAS,KAC3B,MAAMiC,EAAqB5B,EAepB,OAdFlB,EAAM2C,OAACI,wBAEgC,iBAA/BD,EAAmBhB,QACTgB,EAAAhB,QAAUgB,EAAmBhB,QAAQkB,QACtD,QACA,IAGKC,MAAMC,QAAQJ,EAAmBhB,WACrBgB,EAAAhB,QAAUgB,EAAmBhB,QAAQqB,WACjC,UAAXC,MAITC,QAAMP,EAAoB9C,EAAM2C,OAAA,WAIzCW,EAAAA,OAAM,IAAMtD,EAAAe,aAAawC,IACnB,IAEErD,EAAekB,OAASmC,IAAWrD,EAAekB,OAAOsB,cAC5CxC,EAAAkB,MAAMqB,WAAWc,SAG7BC,GACGC,QAAAD,MAAM,cAAeA,EAAK,KAItCE,EAAAA,WAAUC,UACc,oBAAXC,QACDC,EAAAC,KAAKjB,EAAYzB,MAAK,IAKlC2C,EAAAA,iBAAgB,KACV7D,EAAekB,QACjBlB,EAAekB,MAAM4C,UACrB9D,EAAekB,MAAQ,KAAA"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@qxs-bns/components",
3
3
  "type": "module",
4
- "version": "0.0.52",
4
+ "version": "0.0.54",
5
5
  "description": "Vue 3 Component Library",
6
6
  "license": "MIT",
7
7
  "homepage": "https://trry-hub.github.io/qxs-bns/",
@@ -41,9 +41,11 @@
41
41
  },
42
42
  "dependencies": {
43
43
  "@amap/amap-jsapi-loader": "^1.0.1",
44
- "@qxs-bns/directives": "0.0.18",
45
- "@qxs-bns/hooks": "0.0.4",
46
- "@qxs-bns/utils": "0.0.24",
44
+ "@iconify/vue": "^5.0.0",
45
+ "@qxs-bns/directives": "0.0.19",
46
+ "@qxs-bns/hooks": "0.0.5",
47
+ "@qxs-bns/icon": "0.0.0",
48
+ "@qxs-bns/utils": "0.0.26",
47
49
  "@vueuse/core": "^11.3.0",
48
50
  "echarts": "^5.5.1",
49
51
  "lodash-es": "^4.17.21",
@@ -1 +1 @@
1
- :root [data-fixed-calc-width]{position:fixed;right:0;left:0%}:root [data-mode=mobile] [data-fixed-calc-width]{width:100% !important}.qxs-data-chart__table{box-sizing:border-box;display:flex;flex-direction:column}.qxs-data-chart__table .title{display:flex;align-items:center;justify-content:space-between;padding:0 5px;margin-top:2px;margin-bottom:7px;font-family:sans-serif;font-size:14px;font-weight:bolder;color:#464646}.qxs-data-chart__table>div[class*=-table]{position:relative;display:flex;flex:1;flex-direction:column;overflow:hidden;background-color:rgba(0,0,0,0);border-top-left-radius:4px;border-top-right-radius:4px}.qxs-data-chart__table>div[class*=-table] [class*=-table__body-wrapper] [class*=-table__cell]{border-right:0}.qxs-data-chart__table>div[class*=-table] [class*=-table__body-wrapper] [class$=table__empty-text]{line-height:unset}.qxs-data-chart__empty{display:flex;align-items:center;justify-content:center;height:100%}.qxs-data-chart__empty-content{display:flex;flex-direction:column;align-items:center;pointer-events:none;margin-top:-2px}.qxs-data-chart__empty-description{font-size:14px;color:#74767e;margin-left:1px}.qxs-data-chart__wrapper{height:100%}.qxs-fixed-action-bar__actionbar{bottom:0;z-index:10;padding:var(--qxs-fixed-action-bar-actionbar-padding);padding-bottom:calc(env(safe-area-inset-bottom) + var(--qxs-fixed-action-bar-actionbar-padding-bottom));text-align:center;background-color:var(--qxs-bg-color, #fff);box-shadow:0 0 1px 0 var(--qxs-border-color, #f3f3f2);transition:box-shadow .3s,var(--qxs-transition-box-shadow, #f3f3f2)}.qxs-fixed-action-bar__actionbar.is-shadow{box-shadow:0 0 1px 0 var(--qxs-border-color, #f3f3f2)}.qxs-photo-crop-tool__img-box{position:relative;display:flex;align-items:center;justify-content:center;width:100%;height:100%;overflow:hidden;background-color:#fafafa}.qxs-photo-crop-tool__error-message{color:red}.qxs-photo-crop-tool__image{max-width:100%;max-height:100%;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;user-select:none;-o-object-fit:contain;object-fit:contain;-webkit-user-drag:none}.qxs-photo-crop-tool__crop-tool-box{position:absolute;width:calc(var(--qxs-photo-crop-tool-width)*1px);max-width:100%;height:calc(var(--qxs-photo-crop-tool-height)*1px);max-height:100%;aspect-ratio:var(--qxs-photo-crop-tool-aspect-ratio);overflow:hidden;cursor:move;border:1px dashed #fff;box-shadow:0 0 0 9999px rgba(0,0,0,.4)}.qxs-photo-crop-tool__crop-tool-box>div{position:absolute;z-index:3;width:30%;aspect-ratio:1/1;background-color:rgba(2,2,2,.01);border-radius:50%;transition:all .3s}.qxs-photo-crop-tool__crop-tool-box>div:hover,.qxs-photo-crop-tool__crop-tool-box>div:active{background-color:rgba(2,2,2,.5)}.qxs-photo-crop-tool__top-left{top:0;left:0;cursor:nwse-resize;transform:translate3d(-50%, -50%, 0)}.qxs-photo-crop-tool__top-right{top:0;right:0;cursor:nesw-resize;transform:translate3d(50%, -50%, 0)}.qxs-photo-crop-tool__bottom-right{right:0;bottom:0;cursor:nwse-resize;transform:translate3d(50%, 50%, 0)}.qxs-photo-crop-tool__bottom-left{bottom:0;left:0;cursor:nesw-resize;transform:translate3d(-50%, 50%, 0)}.qxs-image-upload__container{line-height:initial}.qxs-image-upload__control{display:inline-block;vertical-align:top}.qxs-image-upload__control .image{position:relative;overflow:hidden;border-radius:6px}.qxs-image-upload__control .image .mask{position:absolute;top:0;width:100%;height:100%;background-color:var(--qxs-overlay-color-lighter);opacity:0;transition:opacity .3s}.qxs-image-upload__control .image .mask .actions{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;width:100px;height:100px;position:absolute;top:50%;left:50%;transform:translateX(-50%) translateY(-50%)}.qxs-image-upload__control .image .mask .actions span{width:50%;color:var(--qxs-color-white);text-align:center;cursor:pointer;transition:color .1s,transform .1s}.qxs-image-upload__control .image .mask .actions span:hover{transform:scale(1.5)}.qxs-image-upload__control .image .mask .actions span [class=qxs-icon]{font-size:24px}.qxs-image-upload__control .image:hover .mask{opacity:1}.qxs-image-upload__control .is-drag{display:inline-block !important;font-size:0}.qxs-image-upload__control .is-drag [class$=-upload-dragger]{display:inline-block;padding:0;font-size:0}.qxs-image-upload__control .is-drag [class$=-upload-dragger] [class$=-image]{display:block}.qxs-image-upload__control .is-drag [class$=-upload-dragger].is-dragover{border-width:1px}.qxs-image-upload__control .is-drag [class$=-upload-dragger] .image-slot{display:flex;flex-direction:column;align-items:center;justify-content:center;width:100%;height:100%;font-size:14px;color:var(--qxs-text-color-placeholder);background-color:#f5f5f5;transition:all .3s}.qxs-image-upload__control .is-drag [class$=-upload-dragger] .image-slot:hover{background-color:#eee}.qxs-image-upload__control .is-drag [class$=-upload-dragger] .image-slot [class$=-icon]{font-size:28px}.qxs-image-upload__control .is-drag [class$=-upload-dragger] .image-slot p{margin-top:10px;margin-bottom:0;line-height:1em;color:#5a5a5a}.qxs-image-upload__control .is-drag [class$=-upload-dragger] .progress{position:absolute;top:0}.qxs-image-upload__control .is-drag [class$=-upload-dragger] .progress::after{position:absolute;top:0;left:0;width:100%;height:100%;content:"";background-color:var(--qxs-overlay-color-lighter)}.qxs-image-upload__control .is-drag [class$=-upload-dragger] .progress [class$=-progress]{z-index:1;position:absolute;top:50%;left:50%;transform:translateX(-50%) translateY(-50%)}.qxs-image-upload__control .is-drag [class$=-upload-dragger] .progress [class$=-progress] [class$=-progress__text]{color:var(--qxs-text-color-placeholder)}.qxs-image-upload__container [class$=-upload__tip-text]{font-size:14px;line-height:32px;color:#c8c8c8}.qxs-file-upload__control .is-drag{display:inline-block !important}.qxs-file-upload__control .is-drag [class$=-upload-dragger]{padding:0}.qxs-file-upload__control .is-drag [class$=-upload-dragger] [class$=-icon--upload]{margin-bottom:0;font-size:40px}.qxs-file-upload__control .is-drag [class$=-upload-dragger] [class$=-upload__text]{padding:0 6px;font-size:14px;line-height:1.5}.qxs-file-upload__control .is-drag.is-dragover{border-width:1px}.qxs-file-upload__control .is-drag .slot{width:160px;height:90px}.qxs-tiny-mce-editor__tiny-mce .tox-tinymce{border-width:1px;border-radius:var(--qxs-border-radius-base, 4px)}.qxs-tiny-mce-editor__tiny-mce .tox-tinymce:not(.tox-tinymce-inline) .tox-editor-header{box-shadow:0 2px 2px -2px rgba(34,47,62,.1),0 4px 4px -4px rgba(34,47,62,.07)}.qxs-tiny-mce-editor__tiny-mce .tox-tinymce .tox-sidebar-wrap{overflow-y:auto}.qxs-tiny-mce-editor__tiny-mce .tox-tinymce .tox-sidebar-wrap .tox-edit-area::before{border-width:1px;border-radius:0}.qxs-tiny-mce-editor .tox-tinymce-aux{z-index:2500 !important}.qxs-subject-list__list-exam .flex{display:flex;align-items:center}.qxs-subject-list__list-exam .flex-items-center{display:flex;align-items:center}.qxs-subject-list__list-exam .flex-justify-between{display:flex;justify-content:space-between}.qxs-subject-list__list-exam .flex-justify-center{display:flex;justify-content:center}.qxs-subject-list__list-exam .flex-justify-end{display:flex;justify-content:flex-end}.qxs-subject-list__list-exam .margin-left-10{margin-left:10px}.qxs-subject-list__list-exam .label{min-width:50px}.qxs-subject-list__list-exam .flex-1{flex:1}.qxs-subject-list__list-exam .subject-list-wrapper{width:100%;margin-bottom:20px}.qxs-subject-list__list-exam .margin-bottom{margin-bottom:20px}.qxs-subject-list__list-exam .auto-line{flex:1;height:1px;margin:0 15px;background-color:#c8c8c8}.qxs-subject-list__list-exam .title{font-size:14px;font-weight:500}.qxs-subject-list__list-exam .rich-text img{max-width:100%}.qxs-subject-single__single-exam .preview-answer{display:flex;flex-direction:column;margin-bottom:10px}.qxs-subject-single__single-exam .flex{display:flex;align-items:center}.qxs-subject-single__single-exam .margin-bottom{margin-bottom:20px}.qxs-subject-single__single-exam .answer-list .answer-item{margin-top:15px}.qxs-subject-single__single-exam .answer-list .answer-item .input{width:300px}.qxs-subject-single__single-exam .answer-list .answer-item .input [class$=-input]{font-weight:bold}.qxs-subject-single__single-exam .answer-list .answer-item .correct{margin:0 10px}.qxs-subject-single__single-exam .answer-list .answer-item .correct:hover{color:#3d61e3;cursor:pointer}.qxs-subject-single__single-exam .answer-list .answer-item .is-correct{color:#67c23a}.qxs-subject-single__single-exam .answer-list .answer-item .icon{margin-left:10px;font-size:18px;color:#a3a3a3;cursor:pointer}.qxs-subject-single__single-exam .answer-list .answer-item .disabled{color:#c0c4cc;cursor:not-allowed}.qxs-subject-single__single-exam .preview .answer-radio{padding-left:10px}.qxs-subject-single__single-exam .preview .answer-radio .radio{margin-top:10px}.qxs-subject-blank-fill__blank-fill-exam .flex{display:flex;align-items:center}.qxs-subject-blank-fill__blank-fill-exam .label{min-width:50px;margin-right:10px}.qxs-subject-blank-fill__blank-fill-exam .margin-bottom{margin-bottom:20px}.qxs-subject-blank-fill__blank-fill-exam .answer-list .answer-item{width:100%;margin-top:15px}.qxs-subject-blank-fill__blank-fill-exam .answer-list .answer-item .answer-tags{flex:1;padding:5px 15px;border:1px solid #eee;border-radius:4px}.qxs-subject-blank-fill__blank-fill-exam .answer-list .answer-item .answer-tags [class$=-tag]{margin-right:10px}.qxs-subject-blank-fill__blank-fill-exam .preview .content{min-height:100px;padding-top:10px;background-color:#fff}.qxs-subject-text-fill__text-fill-exam .flex{display:flex;align-items:center}.qxs-subject-text-fill__text-fill-exam .label{min-width:50px;margin-right:10px}.qxs-subject-text-fill__text-fill-exam .margin-bottom{margin-bottom:20px}.qxs-subject-text-fill__text-fill-exam .answer-list .answer-item{width:100%;margin-top:15px}.qxs-subject-text-fill__text-fill-exam .answer-list .answer-item .answer-tags{flex:1;padding:5px 15px;border:1px solid #eee;border-radius:4px}.qxs-subject-text-fill__text-fill-exam .answer-list .answer-item .operation .icon{margin-left:10px;font-size:16px;color:#a3a3a3;cursor:pointer}.qxs-subject-text-fill__text-fill-exam .answer-list .answer-item .operation .disabled{color:#c0c4cc;cursor:not-allowed}.qxs-subject-text-fill__text-fill-exam .preview .content{min-height:100px;margin-top:10px}.qxs-subject-scale__scale-exam .flex{display:flex;align-items:center}.qxs-subject-scale__scale-exam .label{min-width:50px}.qxs-subject-scale__scale-exam .margin-bottom{margin-bottom:20px}.qxs-subject-scale__scale-exam .answer{margin:20px 0}.qxs-subject-scale__scale-exam .answer .answer-list{margin-left:40px}.qxs-subject-scale__scale-exam .answer .answer-list .answer-item{margin-bottom:20px}.qxs-subject-scale__scale-exam .answer .answer-list .answer-item .order{width:16px;margin-right:10px}.qxs-subject-scale__scale-exam .answer .answer-list .answer-item .icon{margin-left:10px;font-size:16px;color:#a3a3a3;cursor:pointer}.qxs-subject-scale__scale-exam .answer .answer-list .answer-item .disabled{color:#c0c4cc;cursor:not-allowed}.qxs-subject-scale__scale-exam .preview .answer-radio .radio-item .qxs-radio-wrapper{margin-inline-end:0}.qxs-subject-layout__layout-exam{padding:10px;font-size:12px;color:#5a5a5a}.qxs-subject-layout__layout-exam .edit{position:relative;padding:20px 10px;padding-bottom:10px;margin-top:20px;background-color:#f6f7fb}.qxs-subject-layout__layout-exam .edit .triangle-up{position:absolute;top:-20px;left:100px;width:0;height:0;border-right:20px solid rgba(0,0,0,0);border-bottom:20px solid #f6f7fb;border-left:20px solid rgba(0,0,0,0)}.qxs-subject-action__action-exam .action{padding:20px 0}.qxs-subject-action__action-exam .active{padding-right:10px;padding-left:10px;background-color:#f6f7fb}.qxs-subject-action__action-exam .btn-margin{margin-right:10px}.qxs-subject-action__action-exam .has-set{display:flex;align-items:center;font-size:12px;color:#bbb}.qxs-subject-action__action-exam .vertical-radio-group{display:flex;flex-direction:column;align-items:flex-start;margin-left:20px}.qxs-subject-action__action-exam .vertical-radio-group ::v-deep(.qxs-radio){display:block;margin-right:0}.qxs-subject-type__type-list .type-item{margin-bottom:20px}.qxs-subject-type__type-list .base-subject{display:flex;flex-wrap:wrap;align-items:center}.qxs-subject-type__type-list .base-subject .item{width:50px;height:22px;margin-top:10px;margin-right:10px;font-size:14px;color:#5a5a5a;text-align:center;cursor:pointer;background:#fafafa}.qxs-subject-type__type-list .base-subject .item:hover{color:#3d61e3;background:rgba(61,97,227,.12)}
1
+ :root [data-fixed-calc-width]{position:fixed;right:0;left:0%}:root [data-mode=mobile] [data-fixed-calc-width]{width:100% !important}.qxs-data-chart__table{box-sizing:border-box;display:flex;flex-direction:column}.qxs-data-chart__table .title{display:flex;align-items:center;justify-content:space-between;padding:0 5px;margin-top:2px;margin-bottom:7px;font-family:sans-serif;font-size:14px;font-weight:bolder;color:#464646}.qxs-data-chart__table>div[class*=-table]{position:relative;display:flex;flex:1;flex-direction:column;overflow:hidden;background-color:rgba(0,0,0,0);border-top-left-radius:4px;border-top-right-radius:4px}.qxs-data-chart__table>div[class*=-table] [class*=-table__body-wrapper] [class*=-table__cell]{border-right:0}.qxs-data-chart__table>div[class*=-table] [class*=-table__body-wrapper] [class$=table__empty-text]{line-height:unset}.qxs-data-chart__empty{display:flex;align-items:center;justify-content:center;height:100%}.qxs-data-chart__empty-content{display:flex;flex-direction:column;align-items:center;pointer-events:none;margin-top:-2px}.qxs-data-chart__empty-description{font-size:14px;color:#74767e;margin-left:1px}.qxs-data-chart__wrapper{height:100%}.qxs-fixed-action-bar__actionbar{bottom:0;z-index:10;padding:var(--qxs-fixed-action-bar-actionbar-padding);padding-bottom:calc(env(safe-area-inset-bottom) + var(--qxs-fixed-action-bar-actionbar-padding-bottom));text-align:center;background-color:var(--qxs-bg-color, #fff);box-shadow:0 0 1px 0 var(--qxs-border-color, #f3f3f2);transition:box-shadow .3s,var(--qxs-transition-box-shadow, #f3f3f2)}.qxs-fixed-action-bar__actionbar.is-shadow{box-shadow:0 0 1px 0 var(--qxs-border-color, #f3f3f2)}.qxs-photo-crop-tool__img-box{position:relative;display:flex;align-items:center;justify-content:center;width:100%;height:100%;overflow:hidden;background-color:#fafafa}.qxs-photo-crop-tool__error-message{color:red}.qxs-photo-crop-tool__image{max-width:100%;max-height:100%;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;user-select:none;-o-object-fit:contain;object-fit:contain;-webkit-user-drag:none}.qxs-photo-crop-tool__crop-tool-box{position:absolute;width:calc(var(--qxs-photo-crop-tool-width)*1px);max-width:100%;height:calc(var(--qxs-photo-crop-tool-height)*1px);max-height:100%;aspect-ratio:var(--qxs-photo-crop-tool-aspect-ratio);overflow:hidden;cursor:move;border:1px dashed #fff;box-shadow:0 0 0 9999px rgba(0,0,0,.4)}.qxs-photo-crop-tool__crop-tool-box>div{position:absolute;z-index:3;width:30%;aspect-ratio:1/1;background-color:rgba(2,2,2,.01);border-radius:50%;transition:all .3s}.qxs-photo-crop-tool__crop-tool-box>div:after{content:"";position:absolute;width:10px;height:10px;top:50%;left:50%;transform:translate3d(-50%, -50%, 0);border-radius:50%;background-color:var(--qxs-color-primary, #3d61e3)}.qxs-photo-crop-tool__crop-tool-box>div:hover,.qxs-photo-crop-tool__crop-tool-box>div:active{background-color:rgba(2,2,2,.5)}.qxs-photo-crop-tool__top-left{top:0;left:0;cursor:nwse-resize;transform:translate3d(-50%, -50%, 0)}.qxs-photo-crop-tool__top-right{top:0;right:0;cursor:nesw-resize;transform:translate3d(50%, -50%, 0)}.qxs-photo-crop-tool__bottom-right{right:0;bottom:0;cursor:nwse-resize;transform:translate3d(50%, 50%, 0)}.qxs-photo-crop-tool__bottom-left{bottom:0;left:0;cursor:nesw-resize;transform:translate3d(-50%, 50%, 0)}.el-image-upload__container{line-height:initial}.el-image-upload__control>.el-upload-list--picture-card .el-upload-list__item{width:var(--el-image-upload-width);height:var(--el-image-upload-height)}.el-image-upload__control>.el-upload-list--picture-card .el-upload-list__item [role=progressbar]{width:calc(min(var(--el-image-upload-width),var(--el-image-upload-height))/4*3) !important}.el-image-upload__control>.el-upload-list--picture-card .el-upload-list__item [role=progressbar] .el-progress-circle{width:calc(min(var(--el-image-upload-width),var(--el-image-upload-height))/4*3) !important;height:calc(min(var(--el-image-upload-width),var(--el-image-upload-height))/4*3) !important}.el-image-upload__control>.el-upload-list--picture-card .is-drag{width:var(--el-image-upload-width);height:var(--el-image-upload-height)}.el-image-upload__control>.el-upload-list--picture-card .is-drag .el-upload-dragger{border:unset;background-color:unset;width:100%;height:100%;display:flex;justify-content:center;align-items:center}.el-image-upload__control>.el-upload-list--picture-card .is-drag .el-upload-dragger .image-slot [class$=-icon]{font-size:28px;margin-bottom:10px}.el-image-upload__more-than-limit .is-drag{display:none}.el-image-upload__container .el-upload__tip-text{font-size:14px;line-height:32px;color:#c8c8c8}.qxs-file-upload__control .is-drag{display:inline-block !important}.qxs-file-upload__control .is-drag [class$=-upload-dragger]{padding:0}.qxs-file-upload__control .is-drag [class$=-upload-dragger] [class$=-icon--upload]{margin-bottom:0;font-size:40px}.qxs-file-upload__control .is-drag [class$=-upload-dragger] [class$=-upload__text]{padding:0 6px;font-size:14px;line-height:1.5}.qxs-file-upload__control .is-drag.is-dragover{border-width:1px}.qxs-file-upload__control .is-drag .slot{width:160px;height:90px}.qxs-tiny-mce-editor__tiny-mce .tox-tinymce{border-width:1px;border-radius:var(--qxs-border-radius-base, 4px)}.qxs-tiny-mce-editor__tiny-mce .tox-tinymce:not(.tox-tinymce-inline) .tox-editor-header{box-shadow:0 2px 2px -2px rgba(34,47,62,.1),0 4px 4px -4px rgba(34,47,62,.07)}.qxs-tiny-mce-editor__tiny-mce .tox-tinymce .tox-sidebar-wrap{overflow-y:auto}.qxs-tiny-mce-editor__tiny-mce .tox-tinymce .tox-sidebar-wrap .tox-edit-area::before{border-width:1px;border-radius:0}.qxs-tiny-mce-editor .tox-tinymce-aux{z-index:2500 !important}.qxs-subject-list__list-exam .flex{display:flex;align-items:center}.qxs-subject-list__list-exam .flex-items-center{display:flex;align-items:center}.qxs-subject-list__list-exam .flex-justify-between{display:flex;justify-content:space-between}.qxs-subject-list__list-exam .flex-justify-center{display:flex;justify-content:center}.qxs-subject-list__list-exam .flex-justify-end{display:flex;justify-content:flex-end}.qxs-subject-list__list-exam .margin-left-10{margin-left:10px}.qxs-subject-list__list-exam .label{min-width:50px}.qxs-subject-list__list-exam .flex-1{flex:1}.qxs-subject-list__list-exam .subject-list-wrapper{width:100%;margin-bottom:20px}.qxs-subject-list__list-exam .margin-bottom{margin-bottom:20px}.qxs-subject-list__list-exam .auto-line{flex:1;height:1px;margin:0 15px;background-color:#c8c8c8}.qxs-subject-list__list-exam .title{font-size:14px;font-weight:500}.qxs-subject-list__list-exam .rich-text img{max-width:100%}.qxs-subject-single__single-exam .preview-answer{display:flex;flex-direction:column;margin-bottom:10px}.qxs-subject-single__single-exam .flex{display:flex;align-items:center}.qxs-subject-single__single-exam .margin-bottom{margin-bottom:20px}.qxs-subject-single__single-exam .answer-list .answer-item{margin-top:15px}.qxs-subject-single__single-exam .answer-list .answer-item .input{width:300px}.qxs-subject-single__single-exam .answer-list .answer-item .input [class$=-input]{font-weight:bold}.qxs-subject-single__single-exam .answer-list .answer-item .correct{margin:0 10px}.qxs-subject-single__single-exam .answer-list .answer-item .correct:hover{color:#3d61e3;cursor:pointer}.qxs-subject-single__single-exam .answer-list .answer-item .is-correct{color:#67c23a}.qxs-subject-single__single-exam .answer-list .answer-item .icon{margin-left:10px;font-size:18px;color:#a3a3a3;cursor:pointer}.qxs-subject-single__single-exam .answer-list .answer-item .disabled{color:#c0c4cc;cursor:not-allowed}.qxs-subject-single__single-exam .preview .answer-radio{padding-left:10px}.qxs-subject-single__single-exam .preview .answer-radio .radio{margin-top:10px}.qxs-subject-blank-fill__blank-fill-exam .flex{display:flex;align-items:center}.qxs-subject-blank-fill__blank-fill-exam .label{min-width:50px;margin-right:10px}.qxs-subject-blank-fill__blank-fill-exam .margin-bottom{margin-bottom:20px}.qxs-subject-blank-fill__blank-fill-exam .answer-list .answer-item{width:100%;margin-top:15px}.qxs-subject-blank-fill__blank-fill-exam .answer-list .answer-item .answer-tags{flex:1;padding:5px 15px;border:1px solid #eee;border-radius:4px}.qxs-subject-blank-fill__blank-fill-exam .answer-list .answer-item .answer-tags [class$=-tag]{margin-right:10px}.qxs-subject-blank-fill__blank-fill-exam .preview .content{min-height:100px;padding-top:10px;background-color:#fff}.qxs-subject-text-fill__text-fill-exam .flex{display:flex;align-items:center}.qxs-subject-text-fill__text-fill-exam .label{min-width:50px;margin-right:10px}.qxs-subject-text-fill__text-fill-exam .margin-bottom{margin-bottom:20px}.qxs-subject-text-fill__text-fill-exam .answer-list .answer-item{width:100%;margin-top:15px}.qxs-subject-text-fill__text-fill-exam .answer-list .answer-item .answer-tags{flex:1;padding:5px 15px;border:1px solid #eee;border-radius:4px}.qxs-subject-text-fill__text-fill-exam .answer-list .answer-item .operation .icon{margin-left:10px;font-size:16px;color:#a3a3a3;cursor:pointer}.qxs-subject-text-fill__text-fill-exam .answer-list .answer-item .operation .disabled{color:#c0c4cc;cursor:not-allowed}.qxs-subject-text-fill__text-fill-exam .preview .content{min-height:100px;margin-top:10px}.qxs-subject-scale__scale-exam .flex{display:flex;align-items:center}.qxs-subject-scale__scale-exam .label{min-width:50px}.qxs-subject-scale__scale-exam .margin-bottom{margin-bottom:20px}.qxs-subject-scale__scale-exam .answer{margin:20px 0}.qxs-subject-scale__scale-exam .answer .answer-list{margin-left:40px}.qxs-subject-scale__scale-exam .answer .answer-list .answer-item{margin-bottom:20px}.qxs-subject-scale__scale-exam .answer .answer-list .answer-item .order{width:16px;margin-right:10px}.qxs-subject-scale__scale-exam .answer .answer-list .answer-item .icon{margin-left:10px;font-size:16px;color:#a3a3a3;cursor:pointer}.qxs-subject-scale__scale-exam .answer .answer-list .answer-item .disabled{color:#c0c4cc;cursor:not-allowed}.qxs-subject-scale__scale-exam .preview .answer-radio .radio-item .qxs-radio-wrapper{margin-inline-end:0}.qxs-subject-layout__layout-exam{padding:10px;font-size:12px;color:#5a5a5a}.qxs-subject-layout__layout-exam .edit{position:relative;padding:20px 10px;padding-bottom:10px;margin-top:20px;background-color:#f6f7fb}.qxs-subject-layout__layout-exam .edit .triangle-up{position:absolute;top:-20px;left:100px;width:0;height:0;border-right:20px solid rgba(0,0,0,0);border-bottom:20px solid #f6f7fb;border-left:20px solid rgba(0,0,0,0)}.qxs-subject-action__action-exam .action{padding:20px 0}.qxs-subject-action__action-exam .active{padding-right:10px;padding-left:10px;background-color:#f6f7fb}.qxs-subject-action__action-exam .btn-margin{margin-right:10px}.qxs-subject-action__action-exam .has-set{display:flex;align-items:center;font-size:12px;color:#bbb}.qxs-subject-action__action-exam .vertical-radio-group{display:flex;flex-direction:column;align-items:flex-start;margin-left:20px}.qxs-subject-action__action-exam .vertical-radio-group ::v-deep(.qxs-radio){display:block;margin-right:0}.qxs-subject-type__type-list .type-item{margin-bottom:20px}.qxs-subject-type__type-list .base-subject{display:flex;flex-wrap:wrap;align-items:center}.qxs-subject-type__type-list .base-subject .item{width:50px;height:22px;margin-top:10px;margin-right:10px;font-size:14px;color:#5a5a5a;text-align:center;cursor:pointer;background:#fafafa}.qxs-subject-type__type-list .base-subject .item:hover{color:#3d61e3;background:rgba(61,97,227,.12)}.qxs-icon{position:relative;display:inline-flex;align-items:center;justify-content:center;width:1em;height:1em;font-size:1em;line-height:1em;vertical-align:-2px;fill:currentcolor}.qxs-icon svg{width:100%;height:100%}
@@ -11,3 +11,4 @@
11
11
  @use "./src/subject-layout";
12
12
  @use "./src/subject-action";
13
13
  @use "./src/subject-type";
14
+ @use './src/icon';
@@ -0,0 +1 @@
1
+ .qxs-icon{position:relative;display:inline-flex;align-items:center;justify-content:center;width:1em;height:1em;font-size:1em;line-height:1em;vertical-align:-2px;fill:currentcolor}.qxs-icon svg{width:100%;height:100%}
@@ -0,0 +1,19 @@
1
+ @use "mixins/mixins" as *;
2
+
3
+ @include b(icon) {
4
+ position: relative;
5
+ display: inline-flex;
6
+ align-items: center;
7
+ justify-content: center;
8
+ width: 1em;
9
+ height: 1em;
10
+ font-size: 1em;
11
+ line-height: 1em;
12
+ vertical-align: -2px;
13
+ fill: currentcolor;
14
+
15
+ svg {
16
+ width: 100%;
17
+ height: 100%;
18
+ }
19
+ }
@@ -1 +1 @@
1
- .qxs-image-upload__container{line-height:initial}.qxs-image-upload__control{display:inline-block;vertical-align:top}.qxs-image-upload__control .image{position:relative;overflow:hidden;border-radius:6px}.qxs-image-upload__control .image .mask{position:absolute;top:0;width:100%;height:100%;background-color:var(--qxs-overlay-color-lighter);opacity:0;transition:opacity .3s}.qxs-image-upload__control .image .mask .actions{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;width:100px;height:100px;position:absolute;top:50%;left:50%;transform:translateX(-50%) translateY(-50%)}.qxs-image-upload__control .image .mask .actions span{width:50%;color:var(--qxs-color-white);text-align:center;cursor:pointer;transition:color .1s,transform .1s}.qxs-image-upload__control .image .mask .actions span:hover{transform:scale(1.5)}.qxs-image-upload__control .image .mask .actions span [class=qxs-icon]{font-size:24px}.qxs-image-upload__control .image:hover .mask{opacity:1}.qxs-image-upload__control .is-drag{display:inline-block !important;font-size:0}.qxs-image-upload__control .is-drag [class$=-upload-dragger]{display:inline-block;padding:0;font-size:0}.qxs-image-upload__control .is-drag [class$=-upload-dragger] [class$=-image]{display:block}.qxs-image-upload__control .is-drag [class$=-upload-dragger].is-dragover{border-width:1px}.qxs-image-upload__control .is-drag [class$=-upload-dragger] .image-slot{display:flex;flex-direction:column;align-items:center;justify-content:center;width:100%;height:100%;font-size:14px;color:var(--qxs-text-color-placeholder);background-color:#f5f5f5;transition:all .3s}.qxs-image-upload__control .is-drag [class$=-upload-dragger] .image-slot:hover{background-color:#eee}.qxs-image-upload__control .is-drag [class$=-upload-dragger] .image-slot [class$=-icon]{font-size:28px}.qxs-image-upload__control .is-drag [class$=-upload-dragger] .image-slot p{margin-top:10px;margin-bottom:0;line-height:1em;color:#5a5a5a}.qxs-image-upload__control .is-drag [class$=-upload-dragger] .progress{position:absolute;top:0}.qxs-image-upload__control .is-drag [class$=-upload-dragger] .progress::after{position:absolute;top:0;left:0;width:100%;height:100%;content:"";background-color:var(--qxs-overlay-color-lighter)}.qxs-image-upload__control .is-drag [class$=-upload-dragger] .progress [class$=-progress]{z-index:1;position:absolute;top:50%;left:50%;transform:translateX(-50%) translateY(-50%)}.qxs-image-upload__control .is-drag [class$=-upload-dragger] .progress [class$=-progress] [class$=-progress__text]{color:var(--qxs-text-color-placeholder)}.qxs-image-upload__container [class$=-upload__tip-text]{font-size:14px;line-height:32px;color:#c8c8c8}
1
+ .el-image-upload__container{line-height:initial}.el-image-upload__control>.el-upload-list--picture-card .el-upload-list__item{width:var(--el-image-upload-width);height:var(--el-image-upload-height)}.el-image-upload__control>.el-upload-list--picture-card .el-upload-list__item [role=progressbar]{width:calc(min(var(--el-image-upload-width),var(--el-image-upload-height))/4*3) !important}.el-image-upload__control>.el-upload-list--picture-card .el-upload-list__item [role=progressbar] .el-progress-circle{width:calc(min(var(--el-image-upload-width),var(--el-image-upload-height))/4*3) !important;height:calc(min(var(--el-image-upload-width),var(--el-image-upload-height))/4*3) !important}.el-image-upload__control>.el-upload-list--picture-card .is-drag{width:var(--el-image-upload-width);height:var(--el-image-upload-height)}.el-image-upload__control>.el-upload-list--picture-card .is-drag .el-upload-dragger{border:unset;background-color:unset;width:100%;height:100%;display:flex;justify-content:center;align-items:center}.el-image-upload__control>.el-upload-list--picture-card .is-drag .el-upload-dragger .image-slot [class$=-icon]{font-size:28px;margin-bottom:10px}.el-image-upload__more-than-limit .is-drag{display:none}.el-image-upload__container .el-upload__tip-text{font-size:14px;line-height:32px;color:#c8c8c8}
@@ -1,134 +1,56 @@
1
- @use "mixins/mixins" as *;
1
+ @use 'element-plus/theme-chalk/src/mixins/config' as *;
2
+ @use 'element-plus/theme-chalk/src/mixins/mixins' as *;
2
3
 
3
4
  @include b(image-upload) {
5
+
4
6
  @include e(container) {
5
7
  line-height: initial;
6
8
 
7
9
  @include e(control) {
8
- display: inline-block;
9
- vertical-align: top;
10
-
11
- .image {
12
- position: relative;
13
- overflow: hidden;
14
- border-radius: 6px;
15
-
16
- .mask {
17
- position: absolute;
18
- top: 0;
19
- width: 100%;
20
- height: 100%;
21
- background-color: var(--#{$namespace}-overlay-color-lighter);
22
- opacity: 0;
23
- transition: opacity 0.3s;
24
-
25
- .actions {
26
- display: flex;
27
- flex-wrap: wrap;
28
- align-items: center;
29
- justify-content: center;
30
- width: 100px;
31
- height: 100px;
32
-
33
- @include position-center(xy);
34
-
35
- span {
36
- width: 50%;
37
- color: var(--#{$namespace}-color-white);
38
- text-align: center;
39
- cursor: pointer;
40
- transition: color 0.1s, transform 0.1s;
41
-
42
- &:hover {
43
- transform: scale(1.5);
44
- }
45
-
46
- [class="#{$namespace}-icon"] {
47
- font-size: 24px;
48
- }
10
+ >.#{$namespace}-upload-list--picture-card {
11
+
12
+ .#{$namespace}-upload-list__item {
13
+ width: getCssVar('image-upload', 'width');
14
+ height: getCssVar('image-upload', 'height');
15
+ [role="progressbar"] {
16
+ width: calc(min(getCssVar('image-upload', 'width'), getCssVar('image-upload', 'height')) / 4 * 3)!important;
17
+
18
+ .#{$namespace}-progress-circle {
19
+ width: calc(min(getCssVar('image-upload', 'width'), getCssVar('image-upload', 'height')) / 4 * 3)!important;
20
+ height: calc(min(getCssVar('image-upload', 'width'), getCssVar('image-upload', 'height')) / 4 * 3)!important;
49
21
  }
50
22
  }
51
23
  }
52
24
 
53
- &:hover .mask {
54
- opacity: 1;
55
- }
56
- }
57
-
58
- .is-drag {
59
- display: inline-block !important;
60
- font-size: 0;
61
-
62
- [class$="-upload-dragger"] {
63
- display: inline-block;
64
- padding: 0;
65
- font-size: 0;
66
-
67
- [class$="-image"] {
68
- display: block;
69
- }
70
-
71
- &.is-dragover {
72
- border-width: 1px;
73
- }
25
+ .is-drag {
26
+ width: getCssVar('image-upload', 'width');
27
+ height: getCssVar('image-upload', 'height');
74
28
 
75
- .image-slot {
76
- display: flex;
77
- flex-direction: column;
78
- align-items: center;
79
- justify-content: center;
29
+ .#{$namespace}-upload-dragger {
30
+ border: unset;
31
+ background-color: unset;
80
32
  width: 100%;
81
33
  height: 100%;
82
- font-size: 14px;
83
- color: var(--#{$namespace}-text-color-placeholder);
84
- background-color: #f5f5f5;
85
- transition: all 0.3s;
86
-
87
- &:hover {
88
- background-color: #eee;
89
- }
90
-
91
- [class$="-icon"] {
92
- font-size: 28px;
93
- }
94
-
95
- p {
96
- margin-top: 10px;
97
- margin-bottom: 0;
98
- line-height: 1em;
99
- color: #5a5a5a;
100
- }
101
- }
102
-
103
- .progress {
104
- position: absolute;
105
- top: 0;
106
-
107
- &::after {
108
- position: absolute;
109
- top: 0;
110
- left: 0;
111
- width: 100%;
112
- height: 100%;
113
- content: "";
114
- background-color: var(--#{$namespace}-overlay-color-lighter);
115
- }
116
-
117
- [class$="-progress"] {
118
- z-index: 1;
119
-
120
- @include position-center(xy);
121
-
122
- [class$="-progress__text"] {
123
- color: var(--#{$namespace}-text-color-placeholder);
34
+ display: flex;
35
+ justify-content: center;
36
+ align-items: center;
37
+ .image-slot {
38
+ [class$="-icon"] {
39
+ font-size: 28px;
40
+ margin-bottom: 10px;
124
41
  }
125
42
  }
126
43
  }
127
44
  }
128
45
  }
129
46
  }
47
+ @include e(more-than-limit) {
48
+ .is-drag {
49
+ display: none;
50
+ }
51
+ }
130
52
 
131
- [class$="-upload__tip-text"] {
53
+ .#{$namespace}-upload__tip-text {
132
54
  font-size: 14px;
133
55
  line-height: 32px;
134
56
  color: #c8c8c8;
@@ -1 +1 @@
1
- .qxs-photo-crop-tool__img-box{position:relative;display:flex;align-items:center;justify-content:center;width:100%;height:100%;overflow:hidden;background-color:#fafafa}.qxs-photo-crop-tool__error-message{color:red}.qxs-photo-crop-tool__image{max-width:100%;max-height:100%;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;user-select:none;-o-object-fit:contain;object-fit:contain;-webkit-user-drag:none}.qxs-photo-crop-tool__crop-tool-box{position:absolute;width:calc(var(--qxs-photo-crop-tool-width)*1px);max-width:100%;height:calc(var(--qxs-photo-crop-tool-height)*1px);max-height:100%;aspect-ratio:var(--qxs-photo-crop-tool-aspect-ratio);overflow:hidden;cursor:move;border:1px dashed #fff;box-shadow:0 0 0 9999px rgba(0,0,0,.4)}.qxs-photo-crop-tool__crop-tool-box>div{position:absolute;z-index:3;width:30%;aspect-ratio:1/1;background-color:rgba(2,2,2,.01);border-radius:50%;transition:all .3s}.qxs-photo-crop-tool__crop-tool-box>div:hover,.qxs-photo-crop-tool__crop-tool-box>div:active{background-color:rgba(2,2,2,.5)}.qxs-photo-crop-tool__top-left{top:0;left:0;cursor:nwse-resize;transform:translate3d(-50%, -50%, 0)}.qxs-photo-crop-tool__top-right{top:0;right:0;cursor:nesw-resize;transform:translate3d(50%, -50%, 0)}.qxs-photo-crop-tool__bottom-right{right:0;bottom:0;cursor:nwse-resize;transform:translate3d(50%, 50%, 0)}.qxs-photo-crop-tool__bottom-left{bottom:0;left:0;cursor:nesw-resize;transform:translate3d(-50%, 50%, 0)}
1
+ .qxs-photo-crop-tool__img-box{position:relative;display:flex;align-items:center;justify-content:center;width:100%;height:100%;overflow:hidden;background-color:#fafafa}.qxs-photo-crop-tool__error-message{color:red}.qxs-photo-crop-tool__image{max-width:100%;max-height:100%;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;user-select:none;-o-object-fit:contain;object-fit:contain;-webkit-user-drag:none}.qxs-photo-crop-tool__crop-tool-box{position:absolute;width:calc(var(--qxs-photo-crop-tool-width)*1px);max-width:100%;height:calc(var(--qxs-photo-crop-tool-height)*1px);max-height:100%;aspect-ratio:var(--qxs-photo-crop-tool-aspect-ratio);overflow:hidden;cursor:move;border:1px dashed #fff;box-shadow:0 0 0 9999px rgba(0,0,0,.4)}.qxs-photo-crop-tool__crop-tool-box>div{position:absolute;z-index:3;width:30%;aspect-ratio:1/1;background-color:rgba(2,2,2,.01);border-radius:50%;transition:all .3s}.qxs-photo-crop-tool__crop-tool-box>div:after{content:"";position:absolute;width:10px;height:10px;top:50%;left:50%;transform:translate3d(-50%, -50%, 0);border-radius:50%;background-color:var(--qxs-color-primary, #3d61e3)}.qxs-photo-crop-tool__crop-tool-box>div:hover,.qxs-photo-crop-tool__crop-tool-box>div:active{background-color:rgba(2,2,2,.5)}.qxs-photo-crop-tool__top-left{top:0;left:0;cursor:nwse-resize;transform:translate3d(-50%, -50%, 0)}.qxs-photo-crop-tool__top-right{top:0;right:0;cursor:nesw-resize;transform:translate3d(50%, -50%, 0)}.qxs-photo-crop-tool__bottom-right{right:0;bottom:0;cursor:nwse-resize;transform:translate3d(50%, 50%, 0)}.qxs-photo-crop-tool__bottom-left{bottom:0;left:0;cursor:nesw-resize;transform:translate3d(-50%, 50%, 0)}