@qxs-bns/components 0.0.69 → 0.0.71
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.
- package/es/package.json.mjs +1 -1
- package/es/src/data-chart/src/components/area.vue2.mjs +1 -1
- package/es/src/data-chart/src/components/area.vue2.mjs.map +1 -1
- package/es/src/data-chart/src/components/bar.vue2.mjs.map +1 -1
- package/es/src/data-chart/src/components/card.vue2.mjs +1 -1
- package/es/src/data-chart/src/components/card.vue2.mjs.map +1 -1
- package/es/src/data-chart/src/components/funnel.vue2.mjs.map +1 -1
- package/es/src/data-chart/src/components/line.vue2.mjs.map +1 -1
- package/es/src/data-chart/src/components/pie.vue2.mjs.map +1 -1
- package/es/src/data-chart/src/components/radar.vue2.mjs.map +1 -1
- package/es/src/data-chart/src/components/scatter-simple.vue2.mjs.map +1 -1
- package/es/src/data-chart/src/components/scatter.vue2.mjs.map +1 -1
- package/es/src/data-chart/src/components/table.vue.mjs +1 -1
- package/es/src/data-chart/src/components/table.vue.mjs.map +1 -1
- package/es/src/data-chart/src/data-chart.vue.mjs +1 -1
- package/es/src/data-chart/src/data-chart.vue.mjs.map +1 -1
- package/es/src/data-chart/src/utils/config.mjs +1 -1
- package/es/src/data-chart/src/utils/config.mjs.map +1 -1
- package/es/src/data-chart/src/utils/mapData.mjs.map +1 -1
- package/es/src/data-chart/src/utils/useCharts.mjs +1 -1
- package/es/src/data-chart/src/utils/useCharts.mjs.map +1 -1
- package/es/src/file-upload/src/file-upload.vue.mjs +1 -1
- package/es/src/file-upload/src/file-upload.vue.mjs.map +1 -1
- package/es/src/fixed-action-bar/src/fixed-action-bar.vue.mjs +1 -1
- package/es/src/fixed-action-bar/src/fixed-action-bar.vue.mjs.map +1 -1
- package/es/src/icon/index.mjs +1 -1
- package/es/src/icon/index.mjs.map +1 -1
- package/es/src/icon/src/icon.vue.mjs +1 -1
- package/es/src/icon/src/icon.vue.mjs.map +1 -1
- package/es/src/image-upload/src/image-upload.vue.mjs +1 -1
- package/es/src/image-upload/src/image-upload.vue.mjs.map +1 -1
- package/es/src/photo-crop-tool/src/composables.mjs.map +1 -1
- package/es/src/photo-crop-tool/src/photo-crop-tool.vue.mjs +1 -1
- package/es/src/photo-crop-tool/src/photo-crop-tool.vue.mjs.map +1 -1
- package/es/src/subject-action/src/subject-action.vue.mjs +1 -1
- package/es/src/subject-action/src/subject-action.vue.mjs.map +1 -1
- package/es/src/subject-list/src/components/SubjectPageEnd.vue.mjs +1 -1
- package/es/src/subject-list/src/components/SubjectPageEnd.vue.mjs.map +1 -1
- package/es/src/subject-list/src/components/SubjectRichText.vue.mjs +1 -1
- package/es/src/subject-list/src/components/SubjectRichText.vue.mjs.map +1 -1
- package/es/src/subject-list/src/components/subject-blank-fill.vue.mjs +1 -1
- package/es/src/subject-list/src/components/subject-blank-fill.vue.mjs.map +1 -1
- package/es/src/subject-list/src/components/subject-scale.vue.mjs +1 -1
- package/es/src/subject-list/src/components/subject-scale.vue.mjs.map +1 -1
- package/es/src/subject-list/src/components/subject-single.vue.mjs +1 -1
- package/es/src/subject-list/src/components/subject-single.vue.mjs.map +1 -1
- package/es/src/subject-list/src/components/subject-text-fill.vue.mjs +1 -1
- package/es/src/subject-list/src/components/subject-text-fill.vue.mjs.map +1 -1
- package/es/src/subject-list/src/subject-list.vue.mjs +1 -1
- package/es/src/subject-list/src/subject-list.vue.mjs.map +1 -1
- package/es/src/subject-type/src/subject-type.vue.mjs +1 -1
- package/es/src/subject-type/src/subject-type.vue.mjs.map +1 -1
- package/es/src/tiny-mce-editor/src/tiny-mce-editor.vue.mjs +1 -1
- package/es/src/tiny-mce-editor/src/tiny-mce-editor.vue.mjs.map +1 -1
- package/lib/package.json.cjs +1 -1
- package/lib/src/data-chart/src/components/area.vue2.cjs +1 -1
- package/lib/src/data-chart/src/components/area.vue2.cjs.map +1 -1
- package/lib/src/data-chart/src/components/bar.vue2.cjs.map +1 -1
- package/lib/src/data-chart/src/components/card.vue2.cjs +1 -1
- package/lib/src/data-chart/src/components/card.vue2.cjs.map +1 -1
- package/lib/src/data-chart/src/components/funnel.vue2.cjs.map +1 -1
- package/lib/src/data-chart/src/components/line.vue2.cjs.map +1 -1
- package/lib/src/data-chart/src/components/pie.vue2.cjs.map +1 -1
- package/lib/src/data-chart/src/components/radar.vue2.cjs.map +1 -1
- package/lib/src/data-chart/src/components/scatter-simple.vue2.cjs.map +1 -1
- package/lib/src/data-chart/src/components/scatter.vue2.cjs.map +1 -1
- package/lib/src/data-chart/src/components/table.vue.cjs +1 -1
- package/lib/src/data-chart/src/components/table.vue.cjs.map +1 -1
- package/lib/src/data-chart/src/data-chart.vue.cjs +1 -1
- package/lib/src/data-chart/src/data-chart.vue.cjs.map +1 -1
- package/lib/src/data-chart/src/utils/config.cjs +1 -1
- package/lib/src/data-chart/src/utils/config.cjs.map +1 -1
- package/lib/src/data-chart/src/utils/mapData.cjs.map +1 -1
- package/lib/src/data-chart/src/utils/useCharts.cjs +1 -1
- package/lib/src/data-chart/src/utils/useCharts.cjs.map +1 -1
- package/lib/src/file-upload/src/file-upload.vue.cjs +1 -1
- package/lib/src/file-upload/src/file-upload.vue.cjs.map +1 -1
- package/lib/src/fixed-action-bar/src/fixed-action-bar.vue.cjs +1 -1
- package/lib/src/fixed-action-bar/src/fixed-action-bar.vue.cjs.map +1 -1
- package/lib/src/icon/index.cjs +1 -1
- package/lib/src/icon/index.cjs.map +1 -1
- package/lib/src/icon/src/icon.vue.cjs +1 -1
- package/lib/src/icon/src/icon.vue.cjs.map +1 -1
- package/lib/src/image-upload/src/image-upload.vue.cjs +1 -1
- package/lib/src/image-upload/src/image-upload.vue.cjs.map +1 -1
- package/lib/src/photo-crop-tool/src/composables.cjs.map +1 -1
- package/lib/src/photo-crop-tool/src/photo-crop-tool.vue.cjs +1 -1
- package/lib/src/photo-crop-tool/src/photo-crop-tool.vue.cjs.map +1 -1
- package/lib/src/subject-action/src/subject-action.vue.cjs +1 -1
- package/lib/src/subject-action/src/subject-action.vue.cjs.map +1 -1
- package/lib/src/subject-list/src/components/SubjectPageEnd.vue.cjs +1 -1
- package/lib/src/subject-list/src/components/SubjectPageEnd.vue.cjs.map +1 -1
- package/lib/src/subject-list/src/components/SubjectRichText.vue.cjs +1 -1
- package/lib/src/subject-list/src/components/SubjectRichText.vue.cjs.map +1 -1
- package/lib/src/subject-list/src/components/subject-blank-fill.vue.cjs +1 -1
- package/lib/src/subject-list/src/components/subject-blank-fill.vue.cjs.map +1 -1
- package/lib/src/subject-list/src/components/subject-scale.vue.cjs +1 -1
- package/lib/src/subject-list/src/components/subject-scale.vue.cjs.map +1 -1
- package/lib/src/subject-list/src/components/subject-single.vue.cjs +1 -1
- package/lib/src/subject-list/src/components/subject-single.vue.cjs.map +1 -1
- package/lib/src/subject-list/src/components/subject-text-fill.vue.cjs +1 -1
- package/lib/src/subject-list/src/components/subject-text-fill.vue.cjs.map +1 -1
- package/lib/src/subject-list/src/subject-list.vue.cjs +1 -1
- package/lib/src/subject-list/src/subject-list.vue.cjs.map +1 -1
- package/lib/src/subject-type/src/subject-type.vue.cjs +1 -1
- package/lib/src/subject-type/src/subject-type.vue.cjs.map +1 -1
- package/lib/src/tiny-mce-editor/src/tiny-mce-editor.vue.cjs +1 -1
- package/lib/src/tiny-mce-editor/src/tiny-mce-editor.vue.cjs.map +1 -1
- package/package.json +8 -15
- package/theme-chalk/index.css +1 -1
- package/theme-chalk/index.scss +1 -1
- package/theme-chalk/src/common/element-plus.scss +1 -1
- package/theme-chalk/src/data-chart/empty.css +1 -1
- package/theme-chalk/src/data-chart/empty.scss +3 -3
- package/theme-chalk/src/data-chart/index.css +1 -1
- package/theme-chalk/src/icon.css +1 -1
- package/theme-chalk/src/icon.scss +5 -5
- package/theme-chalk/src/image-upload.css +1 -1
- package/theme-chalk/src/image-upload.scss +21 -18
- package/theme-chalk/src/mixins/config.scss +1 -3
- package/theme-chalk/src/mixins/mixins.scss +1 -2
- package/theme-chalk/src/normalize.css +1 -1
- package/theme-chalk/src/normalize.scss +41 -19
- package/theme-chalk/src/photo-crop-tool.css +1 -1
- package/theme-chalk/src/photo-crop-tool.scss +7 -7
- package/theme-chalk/src/subject-action.css +1 -1
- package/theme-chalk/src/subject-action.scss +1 -1
- package/types/src/data-chart/index.d.ts +1 -1
- package/types/src/data-chart/src/components/area.vue.d.ts.map +1 -1
- package/types/src/data-chart/src/components/bar.vue.d.ts.map +1 -1
- package/types/src/data-chart/src/components/card.vue.d.ts +2 -2
- package/types/src/data-chart/src/components/card.vue.d.ts.map +1 -1
- package/types/src/data-chart/src/components/funnel.vue.d.ts.map +1 -1
- package/types/src/data-chart/src/components/line.vue.d.ts.map +1 -1
- package/types/src/data-chart/src/components/pie.vue.d.ts.map +1 -1
- package/types/src/data-chart/src/components/radar.vue.d.ts.map +1 -1
- package/types/src/data-chart/src/components/scatter-simple.vue.d.ts.map +1 -1
- package/types/src/data-chart/src/components/scatter.vue.d.ts.map +1 -1
- package/types/src/data-chart/src/components/table.vue.d.ts +2 -2
- package/types/src/data-chart/src/components/table.vue.d.ts.map +1 -1
- package/types/src/data-chart/src/data-chart.vue.d.ts +2 -2
- package/types/src/data-chart/src/data-chart.vue.d.ts.map +1 -1
- package/types/src/data-chart/src/utils/config.d.ts.map +1 -1
- package/types/src/data-chart/src/utils/mapData.d.ts.map +1 -1
- package/types/src/data-chart/src/utils/useCharts.d.ts.map +1 -1
- package/types/src/file-upload/src/file-upload.vue.d.ts.map +1 -1
- package/types/src/fixed-action-bar/index.d.ts +3 -3
- package/types/src/fixed-action-bar/src/fixed-action-bar.vue.d.ts +2 -2
- package/types/src/fixed-action-bar/src/fixed-action-bar.vue.d.ts.map +1 -1
- package/types/src/icon/index.d.ts +2 -2
- package/types/src/icon/index.d.ts.map +1 -1
- package/types/src/icon/src/icon.vue.d.ts +2 -1
- package/types/src/icon/src/icon.vue.d.ts.map +1 -1
- package/types/src/image-upload/src/image-upload.vue.d.ts.map +1 -1
- package/types/src/photo-crop-tool/index.d.ts +4 -4
- package/types/src/photo-crop-tool/src/composables.d.ts.map +1 -1
- package/types/src/photo-crop-tool/src/photo-crop-tool.vue.d.ts +2 -2
- package/types/src/photo-crop-tool/src/photo-crop-tool.vue.d.ts.map +1 -1
- package/types/src/subject-action/index.d.ts +2 -2
- package/types/src/subject-action/src/subject-action.vue.d.ts +2 -2
- package/types/src/subject-action/src/subject-action.vue.d.ts.map +1 -1
- package/types/src/subject-list/index.d.ts +1 -1
- package/types/src/subject-list/src/components/SubjectPageEnd.vue.d.ts.map +1 -1
- package/types/src/subject-list/src/components/SubjectRichText.vue.d.ts.map +1 -1
- package/types/src/subject-list/src/components/subject-blank-fill.vue.d.ts.map +1 -1
- package/types/src/subject-list/src/components/subject-scale.vue.d.ts.map +1 -1
- package/types/src/subject-list/src/components/subject-single.vue.d.ts.map +1 -1
- package/types/src/subject-list/src/components/subject-text-fill.vue.d.ts.map +1 -1
- package/types/src/subject-list/src/subject-list.vue.d.ts +1 -1
- package/types/src/subject-list/src/subject-list.vue.d.ts.map +1 -1
- package/types/src/subject-type/src/subject-type.vue.d.ts.map +1 -1
- package/types/src/tiny-mce-editor/index.d.ts.map +1 -1
- package/types/src/tiny-mce-editor/src/tiny-mce-editor.vue.d.ts.map +1 -1
- package/types/tsconfig.tsbuildinfo +1 -1
@@ -1,2 +1,2 @@
|
|
1
|
-
"use strict";var e=require("
|
1
|
+
"use strict";var e=require("@vueuse/core"),t=require("echarts"),n=require("vue"),i=require("../components/empty.svg.cjs");function r(e){var t=Object.create(null);return e&&Object.keys(e).forEach(function(n){if("default"!==n){var i=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,i.get?i:{enumerable:!0,get:function(){return e[n]}})}}),t.default=e,Object.freeze(t)}var o=r(t),s=Object.defineProperty,a=(e,t,n)=>((e,t,n)=>t in e?s(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n)(e,"symbol"!=typeof t?t+"":t,n);const c=new class{constructor(){a(this,"observer",null),a(this,"callbacks",new Map)}createObserver(){return"undefined"==typeof IntersectionObserver?null:new IntersectionObserver(e=>{for(const t of e)if(t.isIntersecting){const e=this.callbacks.get(t.target);e&&(e(),this.unobserve(t.target))}},{threshold:0,rootMargin:"200px"})}observe(e,t){this.observer||(this.observer=this.createObserver()),this.observer&&(this.callbacks.set(e,t),this.observer.observe(e))}unobserve(e){this.observer&&(this.observer.unobserve(e),this.callbacks.delete(e))}disconnect(){this.observer&&(this.observer.disconnect(),this.callbacks.clear(),this.observer=null)}};function l(t,n){const{width:i,height:r}=e.useElementSize(n);e.watchDebounced([i,r],()=>{if(t&&!t.isDisposed())try{t.resize()}catch(e){console.warn("Error during chart resize:",e)}})}exports.useCharts=function(t){let{chartDOM:r,chartData:s,chartOptions:a,initBefore:u,initAfter:h,lazyLoad:d=!0}=t,f=null,v=!1,b=null,p=[];const g=window.devicePixelRatio||1;function w(){if(f){try{f.isDisposed()||f.dispose()}catch(e){console.warn("Error disposing chart:",e)}f=null}}function y(){if(!f||f.isDisposed()){if(!r.value)return console.warn("[ECharts] DOM element not found"),null;const{clientWidth:e,clientHeight:t}=r.value;if(0===e||0===t)return console.warn("[ECharts] Container has zero size. Width:",e,"Height:",t,". Skipping initialization."),null;f=o.init(r.value,null,{devicePixelRatio:g,renderer:"svg"})}return f}function m(){r.value&&c.unobserve(r.value)}function D(){if(p.length>0)return;const{isOutside:t}=e.useMouseInElement(r),n=e.watchDebounced(t,e=>{"boolean"==typeof e&&f&&!f.isDisposed()&&function(e){if(f&&!f.isDisposed())try{f.setOption({toolbox:{show:e}})}catch(e){console.warn("Error toggling toolbox:",e)}}(!e)},{debounce:200}),i=e.watchDebounced(()=>a.value,async()=>{await async function(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];try{f&&!f.isDisposed()||await O(),f?.showLoading(),s.value?.data?.length?(!0===v&&(t[1]||(t[1]={}),t[1].notMerge=!0),v=!1):t=await k(),f?.setOption(...t)}catch(e){console.log("🚀 ~ renderChart ~ error:",e),f&&!f.isDisposed()&&w(),y(),t=await k("配置项错误"),f?.setOption(...t)}finally{f?.hideLoading()}}(a.value)},{debounce:500,deep:!0,immediate:!0});p.push(n,i)}async function x(){await n.nextTick();const{clientWidth:e,clientHeight:t}=r.value||{clientWidth:0,clientHeight:0};if(e>0&&t>0){y()&&(h&&h(f),f&&!f.isDisposed()&&l(f,r),D()),m()}else!function(){if(!r.value||"undefined"==typeof ResizeObserver)return;b=new ResizeObserver(e=>{for(const t of e){const{width:e,height:n}=t.contentRect;if(e>0&&n>0){y()&&(h&&h(f),f&&!f.isDisposed()&&l(f,r),D()),b?.disconnect(),b=null,m();break}}}),b.observe(r.value)}()}async function O(){return r.value?(await n.nextTick(),d?(r.value&&c.observe(r.value,()=>{x()}),f):(await x(),f)):f}function k(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"暂无数据";return new Promise(t=>{const n=new Image;n.src=i.default,n.onload=()=>{const r=n.width/n.height,o={title:[{text:s.value?.modelName,...a.value.title},{subtext:e,top:"center",left:"center",text:"{a|}",itemGap:-20,subtextStyle:{fontSize:14},textStyle:{align:"center",rich:{a:{height:100/r,width:100,backgroundColor:{image:i.default}}}}}]};v=!0,t([o,{notMerge:!0,replaceMerge:["xAxis","yAxis","series"],lazyUpdate:!1}])}})}return n.onMounted(async()=>{u&&await u(),await n.nextTick(),await O(),f&&!f.isDisposed()&&(h&&h(f),l(f,r),D())}),n.onUnmounted(()=>{if(p.forEach(e=>e()),p=[],b&&(b.disconnect(),b=null),m(),f&&!f.isDisposed())try{f.getZr()?.off("mousemove"),f.getZr()?.off("mouseout"),f.getZr()?.off("click"),f.off("click"),w()}catch(e){console.warn("Error during chart cleanup:",e)}}),{myChart:()=>f}},exports.useDataToExcelJson=function(e){const{desc:{colDesc:t=[],groupByDesc:n=[]}={},data:i=[]}=e,r=[...n.map(e=>e.colDesc),...t].filter(e=>e),o=i.map(e=>r.map(t=>e[t]||""));return[r,...o]},exports.useResize=l;
|
2
2
|
//# sourceMappingURL=useCharts.cjs.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"useCharts.cjs","sources":["../../../../../../../packages/components/src/data-chart/src/utils/useCharts.ts"],"sourcesContent":["import type { ECharts, SetOptionOpts } from 'echarts'\nimport type { Ref } from 'vue'\nimport type { EChartData, EChartsOption, IFormatPublicData } from './types'\nimport * as echarts from 'echarts'\nimport { onMounted, onUnmounted, nextTick } from 'vue'\nimport { useMouseInElement, useElementSize, watchDebounced } from '@vueuse/core'\n\n// 使用别名路径导入 SVG\nimport emptyImg from '../components/empty.svg'\n\n// 全局 IntersectionObserver 管理器\nclass IntersectionObserverManager {\n private observer: IntersectionObserver | null = null\n private callbacks = new Map<Element, () => void>()\n\n private createObserver() {\n if (typeof IntersectionObserver === 'undefined') {\n return null\n }\n\n return new IntersectionObserver(\n (entries) => {\n for (const entry of entries) {\n if (entry.isIntersecting) {\n const callback = this.callbacks.get(entry.target)\n if (callback) {\n callback()\n // 执行回调后移除监听,避免重复初始化\n this.unobserve(entry.target)\n }\n }\n }\n },\n {\n threshold: 0,\n rootMargin: '200px'\n }\n )\n }\n\n observe(element: Element, callback: () => void) {\n if (!this.observer) {\n this.observer = this.createObserver()\n }\n\n if (this.observer) {\n this.callbacks.set(element, callback)\n this.observer.observe(element)\n }\n }\n\n unobserve(element: Element) {\n if (this.observer) {\n this.observer.unobserve(element)\n this.callbacks.delete(element)\n }\n }\n\n disconnect() {\n if (this.observer) {\n this.observer.disconnect()\n this.callbacks.clear()\n this.observer = null\n }\n }\n}\n\n// 全局单例实例\nconst globalIntersectionObserver = new IntersectionObserverManager()\n\nexport function useCharts({ chartDOM, chartData, chartOptions, initBefore, initAfter, lazyLoad = true }: {\n chartDOM: Ref<HTMLElement | null>\n chartData: Ref<IFormatPublicData>\n chartOptions: Ref<EChartsOption>\n initBefore?: () => Promise<void>\n initAfter?: (e: ECharts | null) => void\n lazyLoad?: boolean\n}) {\n // 每个组件实例的独立状态\n let myChart: ECharts | null = null\n let isEmpty = false\n let resizeObserver: ResizeObserver | null = null\n let watchStopHandles: Array<() => void> = [] // 存储 watch 停止函数\n\n // 获取设备像素比\n const dpr = window.devicePixelRatio || 1\n\n function disposeChart() {\n if (myChart) {\n try {\n if (!myChart.isDisposed()) {\n myChart.dispose()\n }\n }\n catch (error) {\n console.warn('Error disposing chart:', error)\n }\n myChart = null\n }\n }\n\n function initChart() {\n if (!(myChart && !myChart.isDisposed())) {\n // 检查 DOM 元素是否存在\n if (!chartDOM.value) {\n console.warn('[ECharts] DOM element not found')\n return null\n }\n\n // 检查容器尺寸\n const { clientWidth, clientHeight } = chartDOM.value\n if (clientWidth === 0 || clientHeight === 0) {\n // 如果容器没有尺寸,返回 null 而不是强制初始化\n console.warn('[ECharts] Container has zero size. Width:', clientWidth, 'Height:', clientHeight, '. Skipping initialization.')\n return null\n }\n\n // 创建 ECharts 实例\n myChart = echarts.init(chartDOM.value, null, {\n devicePixelRatio: dpr,\n renderer: 'svg',\n })\n }\n return myChart\n }\n\n // 清理所有观察器\n function cleanupObservers() {\n // 从全局观察器中移除当前元素\n if (chartDOM.value) {\n globalIntersectionObserver.unobserve(chartDOM.value)\n }\n }\n\n // 初始化 watchDebounced 监听器\n function setupWatchers() {\n if (watchStopHandles.length > 0) {\n return // 已经设置过了,避免重复设置\n }\n\n // 鼠标悬停监听\n const { isOutside: mouseInChart } = useMouseInElement(chartDOM)\n const stopMouseWatch = watchDebounced(mouseInChart, (newVal) => {\n if (typeof newVal !== 'boolean' || (!myChart || myChart.isDisposed())) {\n return\n }\n toggleToolbox(!newVal)\n }, { debounce: 200 })\n\n // 图表选项监听\n const stopOptionsWatch = watchDebounced(\n () => chartOptions.value,\n async () => {\n await renderChart(chartOptions.value)\n },\n { debounce: 500, deep: true, immediate: true },\n )\n\n watchStopHandles.push(stopMouseWatch, stopOptionsWatch)\n }\n\n // 开始初始化流程\n async function startInitialization() {\n // 等待 DOM 渲染完成\n await nextTick()\n\n // 检查容器是否已经有尺寸\n const { clientWidth, clientHeight } = chartDOM.value || { clientWidth: 0, clientHeight: 0 }\n if (clientWidth > 0 && clientHeight > 0) {\n // 直接初始化\n const chart = initChart()\n if (chart) {\n if (initAfter) {\n initAfter(myChart)\n }\n if (myChart && !myChart.isDisposed()) {\n useResize(myChart, chartDOM)\n }\n // 图表初始化成功后,设置监听器\n setupWatchers()\n }\n // 初始化成功后清理观察器\n cleanupObservers()\n } else {\n // 如果没有尺寸,使用 ResizeObserver 等待\n setupResizeObserver()\n }\n }\n\n // 使用全局 IntersectionObserver 监听元素是否进入可视区域\n function setupIntersectionObserver() {\n if (!chartDOM.value) {\n return\n }\n\n // 使用全局观察器,避免重复创建\n globalIntersectionObserver.observe(chartDOM.value, () => {\n startInitialization()\n })\n }\n\n\n\n // 使用 ResizeObserver 监听容器尺寸变化\n function setupResizeObserver() {\n if (!chartDOM.value || typeof ResizeObserver === 'undefined') {\n return\n }\n\n resizeObserver = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const { width, height } = entry.contentRect\n if (width > 0 && height > 0) {\n // 容器有尺寸了,可以安全初始化\n const chart = initChart()\n if (chart) {\n if (initAfter) {\n initAfter(myChart)\n }\n // 设置 resize 监听\n if (myChart && !myChart.isDisposed()) {\n useResize(myChart, chartDOM)\n }\n // 图表初始化成功后,设置监听器\n setupWatchers()\n }\n // 初始化后停止观察并清理其他观察器\n resizeObserver?.disconnect()\n resizeObserver = null\n cleanupObservers()\n break\n }\n }\n })\n\n resizeObserver.observe(chartDOM.value)\n }\n\n // 安全的初始化函数\n async function safeInitChart() {\n if (!chartDOM.value) {\n return myChart\n }\n\n // 等待 DOM 渲染完成\n await nextTick()\n\n // 如果启用了懒加载\n if (lazyLoad) {\n // 直接设置 IntersectionObserver,让它检测元素是否进入可视区域\n setupIntersectionObserver()\n return myChart\n }\n\n // 非懒加载模式,直接开始初始化流程\n await startInitialization()\n\n return myChart\n }\n\n async function renderChart(...opt: [EChartsOption, SetOptionOpts?]) {\n try {\n // 确保图表已初始化\n if (!myChart || myChart.isDisposed()) {\n await safeInitChart()\n }\n\n myChart?.showLoading()\n if (chartData.value?.data?.length) {\n if (isEmpty === true) {\n if (!opt[1]) {\n opt[1] = {}\n }\n opt[1].notMerge = true\n }\n isEmpty = false\n }\n else {\n // 数据为空时保持原有配置\n opt = await setEmpty()\n }\n myChart?.setOption(...opt)\n }\n catch (error) {\n if (myChart && !myChart.isDisposed()) {\n disposeChart()\n }\n // 如果实例已被销毁,重新创建\n initChart()\n opt = await setEmpty('配置项错误')\n myChart?.setOption(...opt)\n } finally {\n myChart?.hideLoading()\n }\n }\n\n function setEmpty(subtext = '暂无数据'): Promise<[EChartsOption, SetOptionOpts]> {\n return new Promise((resolve) => {\n const img = new Image()\n img.src = emptyImg\n\n img.onload = () => {\n const aspectRatio = img.width / img.height\n\n const obj: EChartsOption = {\n title: [{\n text: chartData.value?.modelName,\n ...chartOptions.value.title,\n }, {\n subtext,\n top: 'center',\n left: 'center',\n text: '{a|}',\n itemGap: -20,\n subtextStyle: {\n fontSize: 14,\n },\n textStyle: {\n align: 'center',\n rich: {\n a: {\n height: 100 / aspectRatio,\n width: 100,\n backgroundColor: {\n image: emptyImg,\n },\n },\n },\n },\n }],\n }\n isEmpty = true\n resolve([obj, {\n notMerge: true,\n replaceMerge: ['xAxis', 'yAxis', 'series'],\n lazyUpdate: false,\n }])\n }\n })\n }\n\n function toggleToolbox(show: boolean) {\n // 修改条件判断,移除 isDisposed 检查\n if (myChart && !myChart.isDisposed()) {\n try {\n myChart.setOption({\n toolbox: {\n show,\n },\n })\n }\n catch (error) {\n console.warn('Error toggling toolbox:', error)\n }\n }\n }\n\n // 移除这里的 watchDebounced 调用,改为在图表初始化后调用\n\n onMounted(async () => {\n if (initBefore) {\n await initBefore()\n }\n\n // 等待 DOM 渲染完成\n await nextTick()\n\n // 使用安全的初始化函数\n await safeInitChart()\n\n // 如果图表已经初始化(容器有尺寸),调用 initAfter 和设置 resize\n if (myChart && !myChart.isDisposed()) {\n if (initAfter) {\n initAfter(myChart)\n }\n useResize(myChart, chartDOM)\n // 图表初始化成功后,设置监听器\n setupWatchers()\n }\n })\n\n onUnmounted(() => {\n // 停止所有 watch 监听器\n watchStopHandles.forEach(stop => stop())\n watchStopHandles = []\n\n // 清理 ResizeObserver\n if (resizeObserver) {\n resizeObserver.disconnect()\n resizeObserver = null\n }\n\n // 清理全局 IntersectionObserver 中的当前元素\n cleanupObservers()\n\n if (myChart && !myChart.isDisposed()) {\n try {\n // 清理所有事件监听器\n myChart.getZr()?.off('mousemove')\n myChart.getZr()?.off('mouseout')\n myChart.getZr()?.off('click')\n myChart.off('click')\n disposeChart()\n }\n catch (error) {\n console.warn('Error during chart cleanup:', error)\n }\n }\n })\n\n return {\n myChart: () => myChart,\n }\n}\n\nexport function useResize(myChart: ECharts, chartDOM: Ref<HTMLElement | null>) {\n const { width, height } = useElementSize(chartDOM)\n watchDebounced([width, height], () => {\n if (myChart && !myChart.isDisposed()) {\n try {\n myChart.resize()\n }\n catch (error) {\n console.warn('Error during chart resize:', error)\n }\n }\n })\n}\n\nexport function useDataToExcelJson(dataSource: EChartData) {\n const { desc: { colDesc = [], groupByDesc = [] } = {}, data = [] } = dataSource\n const header = [...groupByDesc.map(item => item.colDesc), ...colDesc].filter(v => v) as string[]\n const json = data.map((item) => {\n return header.map((headerItem) => {\n return item[headerItem as keyof typeof item] || ''\n })\n })\n return [header, ...json]\n}\n"],"names":["globalIntersectionObserver","constructor","__publicField","this","Map","createObserver","IntersectionObserver","entries","entry","isIntersecting","callback","callbacks","get","target","unobserve","threshold","rootMargin","observe","element","observer","set","delete","disconnect","clear","useResize","myChart","chartDOM","width","height","useElementSize","watchDebounced","isDisposed","resize","error","console","warn","_ref","chartData","chartOptions","initBefore","initAfter","lazyLoad","isEmpty","resizeObserver","watchStopHandles","dpr","window","devicePixelRatio","disposeChart","dispose","initChart","value","clientWidth","clientHeight","echarts","init","renderer","cleanupObservers","setupWatchers","length","isOutside","mouseInChart","useMouseInElement","stopMouseWatch","newVal","show","setOption","toolbox","toggleToolbox","debounce","stopOptionsWatch","async","_len","arguments","opt","Array","_key","safeInitChart","showLoading","data","notMerge","setEmpty","hideLoading","renderChart","deep","immediate","push","startInitialization","nextTick","ResizeObserver","contentRect","setupResizeObserver","subtext","Promise","resolve","img","Image","src","emptyImg","onload","aspectRatio","obj","title","text","modelName","top","left","itemGap","subtextStyle","fontSize","textStyle","align","rich","a","backgroundColor","image","replaceMerge","lazyUpdate","onMounted","onUnmounted","forEach","stop","getZr","off","dataSource","desc","colDesc","groupByDesc","header","map","item","filter","v","json","headerItem"],"mappings":"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"}
|
1
|
+
{"version":3,"file":"useCharts.cjs","sources":["../../../../../../../packages/components/src/data-chart/src/utils/useCharts.ts"],"sourcesContent":["import type { ECharts, SetOptionOpts } from 'echarts'\nimport type { Ref } from 'vue'\nimport type { EChartData, EChartsOption, IFormatPublicData } from './types'\nimport { useElementSize, useMouseInElement, watchDebounced } from '@vueuse/core'\nimport * as echarts from 'echarts'\nimport { nextTick, onMounted, onUnmounted } from 'vue'\n\n// 使用别名路径导入 SVG\nimport emptyImg from '../components/empty.svg'\n\n// 全局 IntersectionObserver 管理器\nclass IntersectionObserverManager {\n private observer: IntersectionObserver | null = null\n private callbacks = new Map<Element, () => void>()\n\n private createObserver() {\n if (typeof IntersectionObserver === 'undefined') {\n return null\n }\n\n return new IntersectionObserver(\n (entries) => {\n for (const entry of entries) {\n if (entry.isIntersecting) {\n const callback = this.callbacks.get(entry.target)\n if (callback) {\n callback()\n // 执行回调后移除监听,避免重复初始化\n this.unobserve(entry.target)\n }\n }\n }\n },\n {\n threshold: 0,\n rootMargin: '200px',\n },\n )\n }\n\n observe(element: Element, callback: () => void) {\n if (!this.observer) {\n this.observer = this.createObserver()\n }\n\n if (this.observer) {\n this.callbacks.set(element, callback)\n this.observer.observe(element)\n }\n }\n\n unobserve(element: Element) {\n if (this.observer) {\n this.observer.unobserve(element)\n this.callbacks.delete(element)\n }\n }\n\n disconnect() {\n if (this.observer) {\n this.observer.disconnect()\n this.callbacks.clear()\n this.observer = null\n }\n }\n}\n\n// 全局单例实例\nconst globalIntersectionObserver = new IntersectionObserverManager()\n\nexport function useCharts({ chartDOM, chartData, chartOptions, initBefore, initAfter, lazyLoad = true }: {\n chartDOM: Ref<HTMLElement | null>\n chartData: Ref<IFormatPublicData>\n chartOptions: Ref<EChartsOption>\n initBefore?: () => Promise<void>\n initAfter?: (e: ECharts | null) => void\n lazyLoad?: boolean\n}) {\n // 每个组件实例的独立状态\n let myChart: ECharts | null = null\n let isEmpty = false\n let resizeObserver: ResizeObserver | null = null\n let watchStopHandles: Array<() => void> = [] // 存储 watch 停止函数\n\n // 获取设备像素比\n const dpr = window.devicePixelRatio || 1\n\n function disposeChart() {\n if (myChart) {\n try {\n if (!myChart.isDisposed()) {\n myChart.dispose()\n }\n }\n catch (error) {\n console.warn('Error disposing chart:', error)\n }\n myChart = null\n }\n }\n\n function initChart() {\n if (!(myChart && !myChart.isDisposed())) {\n // 检查 DOM 元素是否存在\n if (!chartDOM.value) {\n console.warn('[ECharts] DOM element not found')\n return null\n }\n\n // 检查容器尺寸\n const { clientWidth, clientHeight } = chartDOM.value\n if (clientWidth === 0 || clientHeight === 0) {\n // 如果容器没有尺寸,返回 null 而不是强制初始化\n console.warn('[ECharts] Container has zero size. Width:', clientWidth, 'Height:', clientHeight, '. Skipping initialization.')\n return null\n }\n\n // 创建 ECharts 实例\n myChart = echarts.init(chartDOM.value, null, {\n devicePixelRatio: dpr,\n renderer: 'svg',\n })\n }\n return myChart\n }\n\n // 清理所有观察器\n function cleanupObservers() {\n // 从全局观察器中移除当前元素\n if (chartDOM.value) {\n globalIntersectionObserver.unobserve(chartDOM.value)\n }\n }\n\n // 初始化 watchDebounced 监听器\n function setupWatchers() {\n if (watchStopHandles.length > 0) {\n return // 已经设置过了,避免重复设置\n }\n\n // 鼠标悬停监听\n const { isOutside: mouseInChart } = useMouseInElement(chartDOM)\n const stopMouseWatch = watchDebounced(mouseInChart, (newVal) => {\n if (typeof newVal !== 'boolean' || (!myChart || myChart.isDisposed())) {\n return\n }\n toggleToolbox(!newVal)\n }, { debounce: 200 })\n\n // 图表选项监听\n const stopOptionsWatch = watchDebounced(\n () => chartOptions.value,\n async () => {\n await renderChart(chartOptions.value)\n },\n { debounce: 500, deep: true, immediate: true },\n )\n\n watchStopHandles.push(stopMouseWatch, stopOptionsWatch)\n }\n\n // 开始初始化流程\n async function startInitialization() {\n // 等待 DOM 渲染完成\n await nextTick()\n\n // 检查容器是否已经有尺寸\n const { clientWidth, clientHeight } = chartDOM.value || { clientWidth: 0, clientHeight: 0 }\n if (clientWidth > 0 && clientHeight > 0) {\n // 直接初始化\n const chart = initChart()\n if (chart) {\n if (initAfter) {\n initAfter(myChart)\n }\n if (myChart && !myChart.isDisposed()) {\n useResize(myChart, chartDOM)\n }\n // 图表初始化成功后,设置监听器\n setupWatchers()\n }\n // 初始化成功后清理观察器\n cleanupObservers()\n }\n else {\n // 如果没有尺寸,使用 ResizeObserver 等待\n setupResizeObserver()\n }\n }\n\n // 使用全局 IntersectionObserver 监听元素是否进入可视区域\n function setupIntersectionObserver() {\n if (!chartDOM.value) {\n return\n }\n\n // 使用全局观察器,避免重复创建\n globalIntersectionObserver.observe(chartDOM.value, () => {\n startInitialization()\n })\n }\n\n // 使用 ResizeObserver 监听容器尺寸变化\n function setupResizeObserver() {\n if (!chartDOM.value || typeof ResizeObserver === 'undefined') {\n return\n }\n\n resizeObserver = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const { width, height } = entry.contentRect\n if (width > 0 && height > 0) {\n // 容器有尺寸了,可以安全初始化\n const chart = initChart()\n if (chart) {\n if (initAfter) {\n initAfter(myChart)\n }\n // 设置 resize 监听\n if (myChart && !myChart.isDisposed()) {\n useResize(myChart, chartDOM)\n }\n // 图表初始化成功后,设置监听器\n setupWatchers()\n }\n // 初始化后停止观察并清理其他观察器\n resizeObserver?.disconnect()\n resizeObserver = null\n cleanupObservers()\n break\n }\n }\n })\n\n resizeObserver.observe(chartDOM.value)\n }\n\n // 安全的初始化函数\n async function safeInitChart() {\n if (!chartDOM.value) {\n return myChart\n }\n\n // 等待 DOM 渲染完成\n await nextTick()\n\n // 如果启用了懒加载\n if (lazyLoad) {\n // 直接设置 IntersectionObserver,让它检测元素是否进入可视区域\n setupIntersectionObserver()\n return myChart\n }\n\n // 非懒加载模式,直接开始初始化流程\n await startInitialization()\n\n return myChart\n }\n\n async function renderChart(...opt: [EChartsOption, SetOptionOpts?]) {\n try {\n // 确保图表已初始化\n if (!myChart || myChart.isDisposed()) {\n await safeInitChart()\n }\n\n myChart?.showLoading()\n if (chartData.value?.data?.length) {\n if (isEmpty === true) {\n if (!opt[1]) {\n opt[1] = {}\n }\n opt[1].notMerge = true\n }\n isEmpty = false\n }\n else {\n // 数据为空时保持原有配置\n opt = await setEmpty()\n }\n myChart?.setOption(...opt)\n }\n catch (error) {\n console.log(`🚀 ~ renderChart ~ error:`, error)\n if (myChart && !myChart.isDisposed()) {\n disposeChart()\n }\n // 如果实例已被销毁,重新创建\n initChart()\n opt = await setEmpty('配置项错误')\n myChart?.setOption(...opt)\n }\n finally {\n myChart?.hideLoading()\n }\n }\n\n function setEmpty(subtext = '暂无数据'): Promise<[EChartsOption, SetOptionOpts]> {\n return new Promise((resolve) => {\n const img = new Image()\n img.src = emptyImg\n\n img.onload = () => {\n const aspectRatio = img.width / img.height\n\n const obj: EChartsOption = {\n title: [{\n text: chartData.value?.modelName,\n ...chartOptions.value.title,\n }, {\n subtext,\n top: 'center',\n left: 'center',\n text: '{a|}',\n itemGap: -20,\n subtextStyle: {\n fontSize: 14,\n },\n textStyle: {\n align: 'center',\n rich: {\n a: {\n height: 100 / aspectRatio,\n width: 100,\n backgroundColor: {\n image: emptyImg,\n },\n },\n },\n },\n }],\n }\n isEmpty = true\n resolve([obj, {\n notMerge: true,\n replaceMerge: ['xAxis', 'yAxis', 'series'],\n lazyUpdate: false,\n }])\n }\n })\n }\n\n function toggleToolbox(show: boolean) {\n // 修改条件判断,移除 isDisposed 检查\n if (myChart && !myChart.isDisposed()) {\n try {\n myChart.setOption({\n toolbox: {\n show,\n },\n })\n }\n catch (error) {\n console.warn('Error toggling toolbox:', error)\n }\n }\n }\n\n // 移除这里的 watchDebounced 调用,改为在图表初始化后调用\n\n onMounted(async () => {\n if (initBefore) {\n await initBefore()\n }\n\n // 等待 DOM 渲染完成\n await nextTick()\n\n // 使用安全的初始化函数\n await safeInitChart()\n\n // 如果图表已经初始化(容器有尺寸),调用 initAfter 和设置 resize\n if (myChart && !myChart.isDisposed()) {\n if (initAfter) {\n initAfter(myChart)\n }\n useResize(myChart, chartDOM)\n // 图表初始化成功后,设置监听器\n setupWatchers()\n }\n })\n\n onUnmounted(() => {\n // 停止所有 watch 监听器\n watchStopHandles.forEach(stop => stop())\n watchStopHandles = []\n\n // 清理 ResizeObserver\n if (resizeObserver) {\n resizeObserver.disconnect()\n resizeObserver = null\n }\n\n // 清理全局 IntersectionObserver 中的当前元素\n cleanupObservers()\n\n if (myChart && !myChart.isDisposed()) {\n try {\n // 清理所有事件监听器\n myChart.getZr()?.off('mousemove')\n myChart.getZr()?.off('mouseout')\n myChart.getZr()?.off('click')\n myChart.off('click')\n disposeChart()\n }\n catch (error) {\n console.warn('Error during chart cleanup:', error)\n }\n }\n })\n\n return {\n myChart: () => myChart,\n }\n}\n\nexport function useResize(myChart: ECharts, chartDOM: Ref<HTMLElement | null>) {\n const { width, height } = useElementSize(chartDOM)\n watchDebounced([width, height], () => {\n if (myChart && !myChart.isDisposed()) {\n try {\n myChart.resize()\n }\n catch (error) {\n console.warn('Error during chart resize:', error)\n }\n }\n })\n}\n\nexport function useDataToExcelJson(dataSource: EChartData) {\n const { desc: { colDesc = [], groupByDesc = [] } = {}, data = [] } = dataSource\n const header = [...groupByDesc.map(item => item.colDesc), ...colDesc].filter(v => v) as string[]\n const json = data.map((item) => {\n return header.map((headerItem) => {\n return item[headerItem as keyof typeof item] || ''\n })\n })\n return [header, ...json]\n}\n"],"names":["globalIntersectionObserver","constructor","__publicField","this","Map","createObserver","IntersectionObserver","entries","entry","isIntersecting","callback","callbacks","get","target","unobserve","threshold","rootMargin","observe","element","observer","set","delete","disconnect","clear","useResize","myChart","chartDOM","width","height","useElementSize","watchDebounced","isDisposed","resize","error","console","warn","_ref","chartData","chartOptions","initBefore","initAfter","lazyLoad","isEmpty","resizeObserver","watchStopHandles","dpr","window","devicePixelRatio","disposeChart","dispose","initChart","value","clientWidth","clientHeight","echarts","init","renderer","cleanupObservers","setupWatchers","length","isOutside","mouseInChart","useMouseInElement","stopMouseWatch","newVal","show","setOption","toolbox","toggleToolbox","debounce","stopOptionsWatch","async","_len","arguments","opt","Array","_key","safeInitChart","showLoading","data","notMerge","setEmpty","log","hideLoading","renderChart","deep","immediate","push","startInitialization","nextTick","ResizeObserver","contentRect","setupResizeObserver","subtext","Promise","resolve","img","Image","src","emptyImg","onload","aspectRatio","obj","title","text","modelName","top","left","itemGap","subtextStyle","fontSize","textStyle","align","rich","a","backgroundColor","image","replaceMerge","lazyUpdate","onMounted","onUnmounted","forEach","stop","getZr","off","dataSource","desc","colDesc","groupByDesc","header","map","item","filter","v","json","headerItem"],"mappings":"4hBAoEA,MAAMA,EAA6B,IAzDnC,MAAAC,WAAAA,GACEC,EAAAC,KAAQ,WAAwC,MAChDD,EAAAC,KAAQ,gBAAgBC,IAAyB,CAEzCC,cAAAA,GACN,MAAoC,oBAAzBC,qBACF,KAGF,IAAIA,qBACRC,IACC,IAAA,MAAWC,KAASD,EAClB,GAAIC,EAAMC,eAAgB,CACxB,MAAMC,EAAWP,KAAKQ,UAAUC,IAAIJ,EAAMK,QACtCH,IACFA,IAEAP,KAAKW,UAAUN,EAAMK,QAEzB,GAGJ,CACEE,UAAW,EACXC,WAAY,SAGlB,CAEAC,OAAAA,CAAQC,EAAkBR,GACnBP,KAAKgB,WACRhB,KAAKgB,SAAWhB,KAAKE,kBAGnBF,KAAKgB,WACPhB,KAAKQ,UAAUS,IAAIF,EAASR,GAC5BP,KAAKgB,SAASF,QAAQC,GAE1B,CAEAJ,SAAAA,CAAUI,GACJf,KAAKgB,WACPhB,KAAKgB,SAASL,UAAUI,GACxBf,KAAKQ,UAAUU,OAAOH,GAE1B,CAEAI,UAAAA,GACMnB,KAAKgB,WACPhB,KAAKgB,SAASG,aACdnB,KAAKQ,UAAUY,QACfpB,KAAKgB,SAAW,KAEpB,GAgWK,SAASK,EAAUC,EAAkBC,GAC1C,MAAMC,MAAEA,EAAAC,OAAOA,GAAWC,EAAAA,eAAeH,GACzCI,EAAAA,eAAe,CAACH,EAAOC,GAAS,KAC9B,GAAIH,IAAYA,EAAQM,aACtB,IACEN,EAAQO,QACV,OACOC,GACLC,QAAQC,KAAK,6BAA8BF,EAC7C,GAGN,mBAtWO,SAASG,GAOb,IAPuBV,SAAEA,EAAAW,UAAUA,EAAAC,aAAWA,aAAcC,EAAAC,UAAYA,EAAAC,SAAWA,GAAW,GAAKL,EAShGX,EAA0B,KAC1BiB,GAAU,EACVC,EAAwC,KACxCC,EAAsC,GAG1C,MAAMC,EAAMC,OAAOC,kBAAoB,EAEvC,SAASC,IACP,GAAIvB,EAAS,CACX,IACOA,EAAQM,cACXN,EAAQwB,SAEZ,OACOhB,GACLC,QAAQC,KAAK,yBAA0BF,EACzC,CACAR,EAAU,IACZ,CACF,CAEA,SAASyB,IACP,IAAMzB,GAAYA,EAAQM,aAAe,CAEvC,IAAKL,EAASyB,MAEZ,OADAjB,QAAQC,KAAK,mCACN,KAIT,MAAMiB,YAAEA,EAAAC,aAAaA,GAAiB3B,EAASyB,MAC/C,GAAoB,IAAhBC,GAAsC,IAAjBC,EAGvB,OADAnB,QAAQC,KAAK,4CAA6CiB,EAAa,UAAWC,EAAc,8BACzF,KAIT5B,EAAU6B,EAAQC,KAAK7B,EAASyB,MAAO,KAAM,CAC3CJ,iBAAkBF,EAClBW,SAAU,OAEd,CACA,OAAO/B,CACT,CAGA,SAASgC,IAEH/B,EAASyB,OACXnD,EAA2Bc,UAAUY,EAASyB,MAElD,CAGA,SAASO,IACP,GAAId,EAAiBe,OAAS,EAC5B,OAIF,MAAQC,UAAWC,GAAiBC,EAAAA,kBAAkBpC,GAChDqC,EAAiBjC,EAAAA,eAAe+B,EAAeG,IAC7B,kBAAXA,GAA0BvC,IAAWA,EAAQM,cAuM5D,SAAuBkC,GAErB,GAAIxC,IAAYA,EAAQM,aACtB,IACEN,EAAQyC,UAAU,CAChBC,QAAS,CACPF,SAGN,OACOhC,GACLC,QAAQC,KAAK,0BAA2BF,EAC1C,CAEJ,CAlNImC,EAAeJ,IACd,CAAEK,SAAU,MAGTC,EAAmBxC,EAAAA,eACvB,IAAMQ,EAAaa,MACnBoB,gBA2GJA,iBAAoE,IAAA,IAAAC,EAAAC,UAAAd,OAAtCe,EAAA,IAAAC,MAAAH,GAAAI,EAAA,EAAAA,EAAAJ,EAAAI,IAAAF,EAAAE,GAAAH,UAAAG,GAC5B,IAEOnD,IAAWA,EAAQM,oBAChB8C,IAGRpD,GAASqD,cACLzC,EAAUc,OAAO4B,MAAMpB,SACT,IAAZjB,IACGgC,EAAI,KACPA,EAAI,GAAK,CAAA,GAEXA,EAAI,GAAGM,UAAW,GAEpBtC,GAAU,GAIVgC,QAAYO,IAEdxD,GAASyC,aAAaQ,EACxB,OACOzC,GACLC,QAAQgD,IAAI,4BAA6BjD,GACrCR,IAAYA,EAAQM,cACtBiB,IAGFE,IACAwB,QAAYO,EAAS,SACrBxD,GAASyC,aAAaQ,EACxB,CAAA,QAEEjD,GAAS0D,aACX,CACF,CA9IYC,CAAY9C,EAAaa,QAEjC,CAAEkB,SAAU,IAAKgB,MAAM,EAAMC,WAAW,IAG1C1C,EAAiB2C,KAAKxB,EAAgBO,EACxC,CAGAC,eAAeiB,UAEPC,aAGN,MAAMrC,YAAEA,EAAAC,aAAaA,GAAiB3B,EAASyB,OAAS,CAAEC,YAAa,EAAGC,aAAc,GACxF,GAAID,EAAc,GAAKC,EAAe,EAAG,CAEzBH,MAERV,GACFA,EAAUf,GAERA,IAAYA,EAAQM,cACtBP,EAAUC,EAASC,GAGrBgC,KAGFD,GACF,MAoBF,WACE,IAAK/B,EAASyB,OAAmC,oBAAnBuC,eAC5B,OAGF/C,EAAiB,IAAI+C,eAAgBnF,IACnC,IAAA,MAAWC,KAASD,EAAS,CAC3B,MAAMoB,MAAEA,EAAAC,OAAOA,GAAWpB,EAAMmF,YAChC,GAAIhE,EAAQ,GAAKC,EAAS,EAAG,CAEbsB,MAERV,GACFA,EAAUf,GAGRA,IAAYA,EAAQM,cACtBP,EAAUC,EAASC,GAGrBgC,KAGFf,GAAgBrB,aAChBqB,EAAiB,KACjBc,IACA,KACF,CACF,IAGFd,EAAe1B,QAAQS,EAASyB,MAClC,CAjDIyC,EAEJ,CAkDArB,eAAeM,IACb,OAAKnD,EAASyB,aAKRsC,aAGFhD,GAvDCf,EAASyB,OAKdnD,EAA2BiB,QAAQS,EAASyB,MAAO,KACjDqC,MAoDO/D,UAIH+D,IAEC/D,IAhBEA,CAiBX,CAwCA,SAASwD,IAAoE,IAA3DY,yDAAU,OAC1B,OAAO,IAAIC,QAASC,IAClB,MAAMC,EAAM,IAAIC,MAChBD,EAAIE,IAAMC,EAAAA,QAEVH,EAAII,OAAS,KACX,MAAMC,EAAcL,EAAIrE,MAAQqE,EAAIpE,OAE9B0E,EAAqB,CACzBC,MAAO,CAAC,CACNC,KAAMnE,EAAUc,OAAOsD,aACpBnE,EAAaa,MAAMoD,OACrB,CACDV,UACAa,IAAK,SACLC,KAAM,SACNH,KAAM,OACNI,SAAS,GACTC,aAAc,CACZC,SAAU,IAEZC,UAAW,CACTC,MAAO,SACPC,KAAM,CACJC,EAAG,CACDtF,OAAQ,IAAMyE,EACd1E,MAAO,IACPwF,gBAAiB,CACfC,MAAOjB,EAAAA,eAOnBzD,GAAU,EACVqD,EAAQ,CAACO,EAAK,CACZtB,UAAU,EACVqC,aAAc,CAAC,QAAS,QAAS,UACjCC,YAAY,OAIpB,CAuEA,OAnDAC,EAAAA,UAAUhD,UACJhC,SACIA,UAIFkD,mBAGAZ,IAGFpD,IAAYA,EAAQM,eAClBS,GACFA,EAAUf,GAEZD,EAAUC,EAASC,GAEnBgC,OAIJ8D,EAAAA,YAAY,KAcV,GAZA5E,EAAiB6E,QAAQC,GAAQA,KACjC9E,EAAmB,GAGfD,IACFA,EAAerB,aACfqB,EAAiB,MAInBc,IAEIhC,IAAYA,EAAQM,aACtB,IAEEN,EAAQkG,SAASC,IAAI,aACrBnG,EAAQkG,SAASC,IAAI,YACrBnG,EAAQkG,SAASC,IAAI,SACrBnG,EAAQmG,IAAI,SACZ5E,GACF,OACOf,GACLC,QAAQC,KAAK,8BAA+BF,EAC9C,IAIG,CACLR,QAASA,IAAMA,EAEnB,6BAgBO,SAA4BoG,GACjC,MAAQC,MAAMC,QAAEA,EAAU,GAACC,YAAGA,EAAc,IAAO,CAAA,EAACjD,KAAGA,EAAO,IAAO8C,EAC/DI,EAAS,IAAID,EAAYE,IAAIC,GAAQA,EAAKJ,YAAaA,GAASK,UAAYC,GAC5EC,EAAOvD,EAAKmD,IAAKC,GACdF,EAAOC,IAAKK,GACVJ,EAAKI,IAAoC,KAGpD,MAAO,CAACN,KAAWK,EACrB"}
|
@@ -1,2 +1,2 @@
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("vue"),a=require("@element-plus/icons-vue"),l=require("@qxs-bns/hooks"),t=require("element-plus");const r={class:"slot"},s={style:{display:"inline-block"}};var o=e.defineComponent({name:"QxsFileUpload",__name:"file-upload",props:{action:{type:String,required:!0},headers:{type:null,required:!1},data:{type:null,required:!1},name:{type:String,required:!1,default:"file"},size:{type:Number,required:!1,default:20},max:{type:Number,required:!1,default:3},accept:{type:String,required:!1,default:"zip,rar"},files:{type:Array,required:!1,default:()=>[]},notip:{type:Boolean,required:!1,default:!1},ext:{type:Array,required:!1}},emits:["onSuccess"],setup(o,{emit:i}){const n=i,u=l.useNamespace("file-upload"),d=t.useNamespace("file-upload"),c=e.computed(()=>o.accept.split(",")),p=e=>{const a=e.name.split(".").at(-1)??"",l=c.value.includes(a),r=e.size/1024/1024<o.size;return l||t.ElMessage.error(`上传文件只支持 ${c.value.join(" / ")} 格式!`),r||t.ElMessage.error(`上传文件大小不能超过 ${o.size}MB!`),l&&r},m=()=>{t.ElMessage.warning("文件上传超过限制")},f=(e,a,l)=>{n("onSuccess",e,a,l)};return(l,t)=>{const o=e.resolveComponent("el-icon"),i=e.resolveComponent("el-alert"),n=e.resolveComponent("el-upload");return e.openBlock(),e.createBlock(n,{headers:l.headers,action:l.action,data:l.data,name:l.name,"before-upload":p,"on-exceed":m,"on-success":f,"file-list":l.files,limit:l.max,drag:"",class:e.normalizeClass(e.unref(u).e("control"))},{tip:e.withCtx(()=>[l.notip?e.createCommentVNode("v-if",!0):(e.openBlock(),e.createElementBlock("div",{key:0,class:e.normalizeClass(`${e.unref(d).namespace.value}-upload__tip`)},[e.createElementVNode("div",s,[e.createVNode(i,{title:`上传文件支持 ${c.value.join(" / ")} 格式,单个文件大小不超过 ${l.size}MB,且文件数量不超过 ${l.max} 个`,type:"info","show-icon":"",closable:!1},null,8,["title"])])],2))]),default:e.withCtx(()=>[e.createElementVNode("div",r,[e.createVNode(o,{class:e.normalizeClass(`${e.unref(d).namespace.value}-icon--upload`)},{default:e.withCtx(()=>[e.createVNode(e.unref(a.UploadFilled))]),_:1},8,["class"]),e.createElementVNode("div",{class:e.normalizeClass(`${e.unref(d).namespace.value}-upload__text`)},t[0]||(t[0]=[e.createTextVNode(" 将文件拖到此处,或",-1),e.createElementVNode("em",null,"点击上传",-1)]),2)])]),_:1},8,["headers","action","data","name","file-list","limit","class"])}}});exports.default=o;
|
2
2
|
//# sourceMappingURL=file-upload.vue.cjs.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"file-upload.vue.cjs","sources":["../../../../../../packages/components/src/file-upload/src/file-upload.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { UploadProps, UploadUserFile } from 'element-plus'\nimport { UploadFilled } from '@element-plus/icons-vue'\nimport { useNamespace } from '@qxs-bns/hooks'\nimport { useNamespace as useElNamespace } from 'element-plus'\n\ndefineOptions({\n name: 'QxsFileUpload',\n})\n\nconst {\n name = 'file',\n size = 20,\n max = 3,\n files = [],\n notip = false,\n accept = 'zip,rar',\n} = defineProps<{\n action: UploadProps['action']\n headers?: UploadProps['headers']\n data?: UploadProps['data']\n name?: UploadProps['name']\n size?: number\n max?: number\n accept?: string\n files?: UploadUserFile[]\n notip?: boolean\n ext?: string[]\n}>()\n\nconst emit = defineEmits(['onSuccess'])\n\nconst ns = useNamespace('file-upload')\nconst nsEl = useElNamespace('file-upload')\n\nconst exts = computed(() => {\n return accept.split(',')\n})\nconst beforeUpload: UploadProps['beforeUpload'] = (file) => {\n const fileName = file.name.split('.')\n const fileExt = fileName.at(-1) ?? ''\n const isTypeOk = exts.value.includes(fileExt)\n const isSizeOk = file.size / 1024 / 1024 < size\n if (!isTypeOk) {\n ElMessage.error(`上传文件只支持 ${exts.value.join(' / ')} 格式!`)\n }\n if (!isSizeOk) {\n ElMessage.error(`上传文件大小不能超过 ${size}MB!`)\n }\n return isTypeOk && isSizeOk\n}\n\nconst onExceed: UploadProps['onExceed'] = () => {\n ElMessage.warning('文件上传超过限制')\n}\n\nconst onSuccess: UploadProps['onSuccess'] = (res, file, fileList) => {\n emit('onSuccess', res, file, fileList)\n}\n</script>\n\n<template>\n <el-upload\n :headers=\"headers\"\n :action=\"action\"\n :data=\"data\"\n :name=\"name\"\n :before-upload=\"beforeUpload\"\n :on-exceed=\"onExceed\"\n :on-success=\"onSuccess\"\n :file-list=\"files\"\n :limit=\"max\"\n drag\n :class=\"ns.e('control')\"\n >\n <div class=\"slot\">\n <el-icon :class=\"`${nsEl.namespace.value}-icon--upload`\">\n <UploadFilled />\n </el-icon>\n <div :class=\"`${nsEl.namespace.value}-upload__text`\">\n 将文件拖到此处,或<em>点击上传</em>\n </div>\n </div>\n <template #tip>\n <div\n v-if=\"!notip\"\n :class=\"`${nsEl.namespace.value}-upload__tip`\"\n >\n <div style=\"display: inline-block;\">\n <el-alert\n :title=\"`上传文件支持 ${exts.join(\n ' / ',\n )} 格式,单个文件大小不超过 ${size}MB,且文件数量不超过 ${max} 个`\"\n type=\"info\"\n show-icon\n :closable=\"false\"\n />\n </div>\n </div>\n </template>\n </el-upload>\n</template>\n"],"names":["emit","__emit","ns","useNamespace","nsEl","useElNamespace","exts","computed","__props","accept","split","beforeUpload","file","fileExt","name","at","isTypeOk","value","includes","isSizeOk","size","ElMessage","error","join","onExceed","warning","onSuccess","res","fileList","_createBlock","_component_el_upload","headers","action","data","files","limit","max","drag","class","_normalizeClass","_unref","e","tip","notip","_createElementBlock","namespace","_createElementVNode","_hoisted_2","_createVNode","_component_el_alert","title","type","closable","_hoisted_1","_component_el_icon","UploadFilled"],"mappings":"
|
1
|
+
{"version":3,"file":"file-upload.vue.cjs","sources":["../../../../../../packages/components/src/file-upload/src/file-upload.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { UploadProps, UploadUserFile } from 'element-plus'\nimport { UploadFilled } from '@element-plus/icons-vue'\nimport { useNamespace } from '@qxs-bns/hooks'\nimport { ElMessage, useNamespace as useElNamespace } from 'element-plus'\nimport { computed } from 'vue'\n\ndefineOptions({\n name: 'QxsFileUpload',\n})\n\nconst {\n name = 'file',\n size = 20,\n max = 3,\n files = [],\n notip = false,\n accept = 'zip,rar',\n} = defineProps<{\n action: UploadProps['action']\n headers?: UploadProps['headers']\n data?: UploadProps['data']\n name?: UploadProps['name']\n size?: number\n max?: number\n accept?: string\n files?: UploadUserFile[]\n notip?: boolean\n ext?: string[]\n}>()\n\nconst emit = defineEmits(['onSuccess'])\n\nconst ns = useNamespace('file-upload')\nconst nsEl = useElNamespace('file-upload')\n\nconst exts = computed(() => {\n return accept.split(',')\n})\nconst beforeUpload: UploadProps['beforeUpload'] = (file) => {\n const fileName = file.name.split('.')\n const fileExt = fileName.at(-1) ?? ''\n const isTypeOk = exts.value.includes(fileExt)\n const isSizeOk = file.size / 1024 / 1024 < size\n if (!isTypeOk) {\n ElMessage.error(`上传文件只支持 ${exts.value.join(' / ')} 格式!`)\n }\n if (!isSizeOk) {\n ElMessage.error(`上传文件大小不能超过 ${size}MB!`)\n }\n return isTypeOk && isSizeOk\n}\n\nconst onExceed: UploadProps['onExceed'] = () => {\n ElMessage.warning('文件上传超过限制')\n}\n\nconst onSuccess: UploadProps['onSuccess'] = (res, file, fileList) => {\n emit('onSuccess', res, file, fileList)\n}\n</script>\n\n<template>\n <el-upload\n :headers=\"headers\"\n :action=\"action\"\n :data=\"data\"\n :name=\"name\"\n :before-upload=\"beforeUpload\"\n :on-exceed=\"onExceed\"\n :on-success=\"onSuccess\"\n :file-list=\"files\"\n :limit=\"max\"\n drag\n :class=\"ns.e('control')\"\n >\n <div class=\"slot\">\n <el-icon :class=\"`${nsEl.namespace.value}-icon--upload`\">\n <UploadFilled />\n </el-icon>\n <div :class=\"`${nsEl.namespace.value}-upload__text`\">\n 将文件拖到此处,或<em>点击上传</em>\n </div>\n </div>\n <template #tip>\n <div\n v-if=\"!notip\"\n :class=\"`${nsEl.namespace.value}-upload__tip`\"\n >\n <div style=\"display: inline-block;\">\n <el-alert\n :title=\"`上传文件支持 ${exts.join(\n ' / ',\n )} 格式,单个文件大小不超过 ${size}MB,且文件数量不超过 ${max} 个`\"\n type=\"info\"\n show-icon\n :closable=\"false\"\n />\n </div>\n </div>\n </template>\n </el-upload>\n</template>\n"],"names":["emit","__emit","ns","useNamespace","nsEl","useElNamespace","exts","computed","__props","accept","split","beforeUpload","file","fileExt","name","at","isTypeOk","value","includes","isSizeOk","size","ElMessage","error","join","onExceed","warning","onSuccess","res","fileList","_createBlock","_component_el_upload","headers","action","data","files","limit","max","drag","class","_normalizeClass","_unref","e","tip","notip","_createElementBlock","namespace","_createElementVNode","_hoisted_2","_createVNode","_component_el_alert","title","type","closable","_hoisted_1","_component_el_icon","UploadFilled"],"mappings":"uuBA+BA,MAAMA,EAAOC,EAEPC,EAAKC,EAAAA,aAAa,eAClBC,EAAOC,EAAAA,aAAe,eAEtBC,EAAOC,EAAAA,SAAS,IACbC,EAAAC,OAAOC,MAAM,MAEhBC,EAA6CC,IACjD,MACMC,EADWD,EAAKE,KAAKJ,MAAM,KACRK,IAAG,IAAO,GAC7BC,EAAWV,EAAKW,MAAMC,SAASL,GAC/BM,EAAWP,EAAKQ,KAAO,KAAO,KAAOZ,EAAAY,KAO3C,OANKJ,GACHK,YAAUC,MAAM,WAAWhB,EAAKW,MAAMM,KAAK,cAExCJ,GACHE,EAAAA,UAAUC,MAAM,cAAcd,EAAAY,WAEzBJ,GAAYG,GAGfK,EAAoC,KACxCH,EAAAA,UAAUI,QAAQ,aAGdC,EAAsC,CAACC,EAAKf,EAAMgB,KACtD5B,EAAK,YAAa2B,EAAKf,EAAMgB,gJAK7BC,EAAAA,YAsCYC,EAAA,CArCTC,QAASA,EAAAA,QACTC,OAAQA,EAAAA,OACRC,KAAMA,EAAAA,KACNnB,KAAMA,EAAAA,KACN,gBAAeH,EACf,YAAWa,EACX,aAAYE,EACZ,YAAWQ,EAAAA,MACXC,MAAOC,EAAAA,IACRC,KAAA,GACCC,MAAKC,EAAAA,eAAEC,EAAAA,MAAAtC,GAAGuC,EAAC,cAUDC,cACT,IAcM,CAbGC,EAAAA,qDADTC,EAAAA,mBAcM,MAAA,OAZHN,MAAKC,EAAAA,eAAA,GAAKC,EAAAA,MAAApC,GAAKyC,UAAU5B,uBAE1B6B,EAAAA,mBASM,MATNC,EASM,CARJC,EAAAA,YAOEC,EAAA,CANCC,MAAK,UAAY5C,EAAAW,MAAKM,4BAAyDH,EAAAA,mBAAmBgB,EAAAA,QAGnGe,KAAK,OACL,YAAA,GACCC,UAAU,gDApBnB,IAOM,CAPNN,EAAAA,mBAOM,MAPNO,EAOM,CANJL,EAAAA,YAEUM,EAAA,CAFAhB,MAAKC,EAAAA,eAAA,GAAKC,EAAAA,MAAApC,GAAKyC,UAAU5B,0CACjC,IAAgB,CAAhB+B,EAAAA,YAAgBR,EAAAA,MAAAe,qCAElBT,EAAAA,mBAEM,MAAA,CAFAR,MAAKC,EAAAA,eAAA,GAAKC,EAAAA,MAAApC,GAAKyC,UAAU5B,sDAAsB,cAC1C,GAAA6B,EAAAA,mBAAa,UAAT,QAAI"}
|
@@ -1,2 +1,2 @@
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("vue"),t=require("@qxs-bns/hooks"),n=require("@qxs-bns/utils"),
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("vue"),t=require("@qxs-bns/hooks"),n=require("@qxs-bns/utils"),a=require("lodash-es");var r=e.defineComponent({name:"QxsFixedActionBar",props:{padding:{type:Number,default:8},className:{type:String,default:""}},setup(r){const o=r,i=t.useNamespace("fixed-action-bar"),l=e.ref(!1),d=e.ref(null),s=e.ref(null),u=e.ref({width:0,height:0}),c=e.ref(0),p=e.ref(0),m={resize:null,parent:null};function f(e,t,n){const a=new ResizeObserver(e=>{e.forEach(e=>requestAnimationFrame(()=>t(e)))});return a.observe(e,n),a}function v(){if(!d.value||!s.value)return;m.resize=f(d.value,e=>{const t=function(e){const t=getComputedStyle(e);return{x:Number.parseFloat(t.paddingLeft)+Number.parseFloat(t.paddingRight),y:Number.parseFloat(t.paddingTop)+Number.parseFloat(t.paddingBottom)}}(e.target);u.value={width:e.contentRect.width+t.x,height:e.contentRect.height+t.y}},{box:"border-box"});const e=s.value.parentElement;e&&(m.parent=f(e,()=>{const t=e.getBoundingClientRect();c.value=t.width,p.value=t.left}))}const h=a.debounce(()=>{const{scrollY:e}=window,{clientHeight:t,scrollHeight:n}=document.documentElement;l.value=Math.ceil(e+t)>=n},100),g=e.computed(()=>l.value?"":i.is("shadow")),b=e.computed(()=>"Android"===n.getDeviceType()?Math.max(o.padding,20):o.padding),x=e.computed(()=>({width:`${c.value}px`,left:`${p.value}px`,...i.cssVarBlock({"actionbar-padding":`${o.padding}px`,"actionbar-padding-bottom":`${b.value}px`})}));return e.onMounted(()=>{v(),window.addEventListener("scroll",h,{passive:!0})}),e.onUnmounted(()=>{m.resize?.disconnect(),m.parent?.disconnect(),window.removeEventListener("scroll",h)}),(t,n)=>(e.openBlock(),e.createElementBlock("div",{ref_key:"placeholderRef",ref:s,style:e.normalizeStyle({width:"100%",height:`${u.value.height}px`})},[e.createElementVNode("div",{ref_key:"actionbar",ref:d,style:e.normalizeStyle(x.value),class:e.normalizeClass([e.unref(i).e("actionbar"),g.value,r.className]),"data-fixed-calc-width":""},[e.renderSlot(t.$slots,"default")],6)],4))}});exports.default=r;
|
2
2
|
//# sourceMappingURL=fixed-action-bar.vue.cjs.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"fixed-action-bar.vue.cjs","sources":["../../../../../../packages/components/src/fixed-action-bar/src/fixed-action-bar.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { useNamespace } from '@qxs-bns/hooks'\nimport { getDeviceType } from '@qxs-bns/utils'\nimport { debounce } from 'lodash-es'\n\nconst props = defineProps({\n padding: {\n type: Number,\n default: 8,\n },\n className: {\n type: String,\n default: '',\n },\n})\n\ninterface ElementSize { width: number, height: number }\n\nconst ns = useNamespace('fixed-action-bar')\nconst isBottom = ref(false)\nconst actionbar = ref<HTMLElement | null>(null)\nconst placeholderRef = ref<HTMLElement | null>(null)\n\nconst elementSize = ref<ElementSize>({ width: 0, height: 0 })\nconst parentWidth = ref(0)\nconst elementLeft = ref(0)\n\nconst observers = {\n resize: null as ResizeObserver | null,\n parent: null as ResizeObserver | null,\n}\n\nfunction getTotalPadding(el: HTMLElement) {\n const style = getComputedStyle(el)\n return {\n x: Number.parseFloat(style.paddingLeft) + Number.parseFloat(style.paddingRight),\n y: Number.parseFloat(style.paddingTop) + Number.parseFloat(style.paddingBottom),\n }\n}\n\nfunction createResizeObserver(el: HTMLElement,\n callback: (entry: ResizeObserverEntry) => void,\n options?: ResizeObserverOptions) {\n const observer = new ResizeObserver((entries) => {\n entries.forEach(entry => requestAnimationFrame(() => callback(entry)))\n })\n observer.observe(el, options)\n return observer\n}\n\nfunction initObservers() {\n if (!actionbar.value || !placeholderRef.value) {\n return\n }\n\n // 主元素尺寸观察\n observers.resize = createResizeObserver(\n actionbar.value,\n (entry) => {\n const padding = getTotalPadding(entry.target as HTMLElement)\n elementSize.value = {\n width: entry.contentRect.width + padding.x,\n height: entry.contentRect.height + padding.y,\n }\n },\n { box: 'border-box' },\n )\n\n // 父元素观察\n const parent = placeholderRef.value.parentElement\n if (parent) {\n observers.parent = createResizeObserver(parent, () => {\n const rect = parent.getBoundingClientRect()\n parentWidth.value = rect.width\n elementLeft.value = rect.left\n })\n }\n}\n\nconst calculateScrollDetails = debounce(() => {\n const { scrollY } = window\n const { clientHeight, scrollHeight } = document.documentElement\n isBottom.value = Math.ceil(scrollY + clientHeight) >= scrollHeight\n}, 100)\n\nconst shadowClass = computed(() => (!isBottom.value ? ns.is('shadow') : ''))\n\nconst paddingBottom = computed(() =>\n getDeviceType() === 'Android' ? Math.max(props.padding, 20) : props.padding,\n)\n\nconst actionbarStyle = computed(() => ({\n width: `${parentWidth.value}px`,\n left: `${elementLeft.value}px`,\n ...ns.cssVarBlock({\n 'actionbar-padding': `${props.padding}px`,\n 'actionbar-padding-bottom': `${paddingBottom.value}px`,\n }),\n}))\n\nonMounted(() => {\n initObservers()\n window.addEventListener('scroll', calculateScrollDetails, { passive: true })\n})\n\nonUnmounted(() => {\n observers.resize?.disconnect()\n observers.parent?.disconnect()\n window.removeEventListener('scroll', calculateScrollDetails)\n})\n</script>\n\n<script lang=\"ts\">\nexport default {\n name: 'QxsFixedActionBar',\n}\n</script>\n\n<template>\n <div\n ref=\"placeholderRef\"\n :style=\"{ width: '100%', height: `${elementSize.height}px` }\"\n >\n <div\n ref=\"actionbar\"\n :style=\"actionbarStyle\"\n :class=\"[ns.e('actionbar'), shadowClass, className]\"\n data-fixed-calc-width\n >\n <slot />\n </div>\n </div>\n</template>\n"],"names":["name","props","__props","ns","useNamespace","isBottom","ref","actionbar","placeholderRef","elementSize","width","height","parentWidth","elementLeft","observers","resize","parent","createResizeObserver","el","callback","options","observer","ResizeObserver","entries","forEach","entry","requestAnimationFrame","observe","initObservers","value","padding","style","getComputedStyle","x","Number","parseFloat","paddingLeft","paddingRight","y","paddingTop","paddingBottom","getTotalPadding","target","contentRect","box","parentElement","rect","getBoundingClientRect","left","calculateScrollDetails","debounce","scrollY","window","clientHeight","scrollHeight","document","documentElement","Math","ceil","shadowClass","computed","is","getDeviceType","max","actionbarStyle","cssVarBlock","onMounted","addEventListener","passive","onUnmounted","disconnect","removeEventListener","_createElementBlock","_normalizeStyle","
|
1
|
+
{"version":3,"file":"fixed-action-bar.vue.cjs","sources":["../../../../../../packages/components/src/fixed-action-bar/src/fixed-action-bar.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { useNamespace } from '@qxs-bns/hooks'\nimport { getDeviceType } from '@qxs-bns/utils'\nimport { debounce } from 'lodash-es'\nimport { computed, onMounted, onUnmounted, ref } from 'vue'\n\nconst props = defineProps({\n padding: {\n type: Number,\n default: 8,\n },\n className: {\n type: String,\n default: '',\n },\n})\n\ninterface ElementSize { width: number, height: number }\n\nconst ns = useNamespace('fixed-action-bar')\nconst isBottom = ref(false)\nconst actionbar = ref<HTMLElement | null>(null)\nconst placeholderRef = ref<HTMLElement | null>(null)\n\nconst elementSize = ref<ElementSize>({ width: 0, height: 0 })\nconst parentWidth = ref(0)\nconst elementLeft = ref(0)\n\nconst observers = {\n resize: null as ResizeObserver | null,\n parent: null as ResizeObserver | null,\n}\n\nfunction getTotalPadding(el: HTMLElement) {\n const style = getComputedStyle(el)\n return {\n x: Number.parseFloat(style.paddingLeft) + Number.parseFloat(style.paddingRight),\n y: Number.parseFloat(style.paddingTop) + Number.parseFloat(style.paddingBottom),\n }\n}\n\nfunction createResizeObserver(el: HTMLElement,\n callback: (entry: ResizeObserverEntry) => void,\n options?: ResizeObserverOptions) {\n const observer = new ResizeObserver((entries) => {\n entries.forEach(entry => requestAnimationFrame(() => callback(entry)))\n })\n observer.observe(el, options)\n return observer\n}\n\nfunction initObservers() {\n if (!actionbar.value || !placeholderRef.value) {\n return\n }\n\n // 主元素尺寸观察\n observers.resize = createResizeObserver(\n actionbar.value,\n (entry) => {\n const padding = getTotalPadding(entry.target as HTMLElement)\n elementSize.value = {\n width: entry.contentRect.width + padding.x,\n height: entry.contentRect.height + padding.y,\n }\n },\n { box: 'border-box' },\n )\n\n // 父元素观察\n const parent = placeholderRef.value.parentElement\n if (parent) {\n observers.parent = createResizeObserver(parent, () => {\n const rect = parent.getBoundingClientRect()\n parentWidth.value = rect.width\n elementLeft.value = rect.left\n })\n }\n}\n\nconst calculateScrollDetails = debounce(() => {\n const { scrollY } = window\n const { clientHeight, scrollHeight } = document.documentElement\n isBottom.value = Math.ceil(scrollY + clientHeight) >= scrollHeight\n}, 100)\n\nconst shadowClass = computed(() => (!isBottom.value ? ns.is('shadow') : ''))\n\nconst paddingBottom = computed(() =>\n getDeviceType() === 'Android' ? Math.max(props.padding, 20) : props.padding,\n)\n\nconst actionbarStyle = computed(() => ({\n width: `${parentWidth.value}px`,\n left: `${elementLeft.value}px`,\n ...ns.cssVarBlock({\n 'actionbar-padding': `${props.padding}px`,\n 'actionbar-padding-bottom': `${paddingBottom.value}px`,\n }),\n}))\n\nonMounted(() => {\n initObservers()\n window.addEventListener('scroll', calculateScrollDetails, { passive: true })\n})\n\nonUnmounted(() => {\n observers.resize?.disconnect()\n observers.parent?.disconnect()\n window.removeEventListener('scroll', calculateScrollDetails)\n})\n</script>\n\n<script lang=\"ts\">\nexport default {\n name: 'QxsFixedActionBar',\n}\n</script>\n\n<template>\n <div\n ref=\"placeholderRef\"\n :style=\"{ width: '100%', height: `${elementSize.height}px` }\"\n >\n <div\n ref=\"actionbar\"\n :style=\"actionbarStyle\"\n :class=\"[ns.e('actionbar'), shadowClass, className]\"\n data-fixed-calc-width\n >\n <slot />\n </div>\n </div>\n</template>\n"],"names":["name","props","__props","ns","useNamespace","isBottom","ref","actionbar","placeholderRef","elementSize","width","height","parentWidth","elementLeft","observers","resize","parent","createResizeObserver","el","callback","options","observer","ResizeObserver","entries","forEach","entry","requestAnimationFrame","observe","initObservers","value","padding","style","getComputedStyle","x","Number","parseFloat","paddingLeft","paddingRight","y","paddingTop","paddingBottom","getTotalPadding","target","contentRect","box","parentElement","rect","getBoundingClientRect","left","calculateScrollDetails","debounce","scrollY","window","clientHeight","scrollHeight","document","documentElement","Math","ceil","shadowClass","computed","is","getDeviceType","max","actionbarStyle","cssVarBlock","onMounted","addEventListener","passive","onUnmounted","disconnect","removeEventListener","_createElementBlock","_normalizeStyle","_createElementVNode","class","_unref","e","className","_renderSlot","_ctx","$slots"],"mappings":"iMAmHEA,KAAM,wGA7GR,MAAMC,EAAQC,EAaRC,EAAKC,EAAAA,aAAa,oBAClBC,EAAWC,EAAAA,KAAI,GACfC,EAAYD,EAAAA,IAAwB,MACpCE,EAAiBF,EAAAA,IAAwB,MAEzCG,EAAcH,EAAAA,IAAiB,CAAEI,MAAO,EAAGC,OAAQ,IACnDC,EAAcN,EAAAA,IAAI,GAClBO,EAAcP,EAAAA,IAAI,GAElBQ,EAAY,CAChBC,OAAQ,KACRC,OAAQ,MAWV,SAASC,EAAqBC,EAC5BC,EACAC,GACA,MAAMC,EAAW,IAAIC,eAAgBC,IACnCA,EAAQC,QAAQC,GAASC,sBAAsB,IAAMP,EAASM,OAGhE,OADAJ,EAASM,QAAQT,EAAIE,GACdC,CACT,CAEA,SAASO,IACP,IAAKrB,EAAUsB,QAAUrB,EAAeqB,MACtC,OAIFf,EAAUC,OAASE,EACjBV,EAAUsB,MACTJ,IACC,MAAMK,EA3BZ,SAAyBZ,GACvB,MAAMa,EAAQC,iBAAiBd,GAC/B,MAAO,CACLe,EAAGC,OAAOC,WAAWJ,EAAMK,aAAeF,OAAOC,WAAWJ,EAAMM,cAClEC,EAAGJ,OAAOC,WAAWJ,EAAMQ,YAAcL,OAAOC,WAAWJ,EAAMS,eAErE,CAqBsBC,CAAgBhB,EAAMiB,QACtCjC,EAAYoB,MAAQ,CAClBnB,MAAOe,EAAMkB,YAAYjC,MAAQoB,EAAQG,EACzCtB,OAAQc,EAAMkB,YAAYhC,OAASmB,EAAQQ,IAG/C,CAAEM,IAAK,eAIT,MAAM5B,EAASR,EAAeqB,MAAMgB,cAChC7B,IACFF,EAAUE,OAASC,EAAqBD,EAAQ,KAC9C,MAAM8B,EAAO9B,EAAO+B,wBACpBnC,EAAYiB,MAAQiB,EAAKpC,MACzBG,EAAYgB,MAAQiB,EAAKE,OAG/B,CAEA,MAAMC,EAAyBC,EAAAA,SAAS,KACtC,MAAMC,QAAEA,GAAYC,QACdC,aAAEA,EAAAC,aAAcA,GAAiBC,SAASC,gBAChDnD,EAASwB,MAAQ4B,KAAKC,KAAKP,EAAUE,IAAiBC,GACrD,KAEGK,EAAcC,WAAS,IAAQvD,EAASwB,MAA0B,GAAlB1B,EAAG0D,GAAG,WAEtDrB,EAAgBoB,EAAAA,SAAS,IACT,YAApBE,EAAAA,gBAAgCL,KAAKM,IAAI9D,EAAM6B,QAAS,IAAM7B,EAAM6B,SAGhEkC,EAAiBJ,EAAAA,SAAS,KAAA,CAC9BlD,MAAO,GAAGE,EAAYiB,UACtBmB,KAAM,GAAGnC,EAAYgB,aAClB1B,EAAG8D,YAAY,CAChB,oBAAqB,GAAGhE,EAAM6B,YAC9B,2BAA4B,GAAGU,EAAcX,sBAIjDqC,EAAAA,UAAU,KACRtC,IACAwB,OAAOe,iBAAiB,SAAUlB,EAAwB,CAAEmB,SAAS,MAGvEC,EAAAA,YAAY,KACVvD,EAAUC,QAAQuD,aAClBxD,EAAUE,QAAQsD,aAClBlB,OAAOmB,oBAAoB,SAAUtB,2BAWrCuB,EAAAA,mBAYM,MAAA,SAXA,iBAAJlE,IAAIE,EACHuB,MAAK0C,EAAAA,eAAA,CAAA/D,MAAA,OAAAC,OAAA,GAA8BF,EAAAoB,MAAYlB,eAEhD+D,EAAAA,mBAOM,MAAA,SANA,YAAJpE,IAAIC,EACHwB,uBAAOiC,EAAAnC,OACP8C,wBAAQC,EAAAA,MAAAzE,GAAG0E,EAAC,aAAelB,EAAA9B,MAAa3B,EAAA4E,YACzC,wBAAA,KAEAC,aAAQC,EAAAC,OAAA"}
|
package/lib/src/icon/index.cjs
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("vue"),t=require("../withInstall.cjs"),r=require("./src/icon.vue.cjs");const s=t.withInstall(r.default);exports.QxsIcon=s,exports.createQxsIcon=function(t){return t="string"==typeof t?{icon:t}:t,e.defineComponent({setup:()=>()=>e.h(r.default,{...t})})},exports.default=s;
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../../../../../packages/components/src/icon/index.ts"],"sourcesContent":["import {
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../../../../packages/components/src/icon/index.ts"],"sourcesContent":["import type { PropsType } from './src/icon.vue'\nimport { defineComponent, h } from 'vue'\nimport { withInstall } from '../withInstall'\nimport component from './src/icon.vue'\n\nconst QxsIcon = withInstall(component)\n\n// 返回一个组件对象\nfunction createQxsIcon(opt: PropsType | string) {\n opt = typeof opt === 'string' ? { icon: opt } : opt\n return defineComponent({\n setup() {\n return () => h(component, { ...opt })\n },\n })\n}\n\nexport {\n createQxsIcon,\n QxsIcon,\n}\n\nexport default QxsIcon\n"],"names":["QxsIcon","withInstall","component","opt","icon","defineComponent","setup","h"],"mappings":"yJAKA,MAAMA,EAAUC,EAAAA,YAAYC,EAAAA,iDAG5B,SAAuBC,GAErB,OADAA,EAAqB,iBAARA,EAAmB,CAAEC,KAAMD,GAAQA,EACzCE,kBAAgB,CACrBC,MAAAA,IACS,IAAMC,EAAAA,EAAEL,UAAW,IAAKC,KAGrC"}
|
@@ -1,2 +1,2 @@
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("vue"),
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("vue"),o=require("../../../node_modules/.pnpm/@iconify_vue@5.0.0_vue@3.5.18_typescript@5.9.2_/node_modules/@iconify/vue/dist/iconify.cjs"),t=require("@qxs-bns/hooks");const n=["xlink:href"];var r=e.defineComponent({name:"QxsIcon",__name:"icon",props:{icon:{type:null,required:!0},runtime:{type:Boolean,required:!1},flip:{type:null,required:!1,default:""},rotate:{type:Number,required:!1,default:0},color:{type:String,required:!1},size:{type:[String,Number],required:!1},localIconPrefix:{type:String,required:!1,default:"icon-"}},setup(r){const l=e.useAttrs(),u=t.useNamespace("icon"),i=e.computed(()=>"object"==typeof r.icon||"function"==typeof r.icon),s=e.computed(()=>i.value?"component":0===r.icon.indexOf("i-")?r.runtime?"svg":"css":r.icon.includes(":")?"svg":"custom"),c=e.computed(()=>{if(i.value)return"";if(0===r.icon.indexOf("i-")){let e=r.icon;return r.runtime&&(e=e.replace("i-","")),e}return r.icon});const a=e.computed(()=>{const e=[];switch(r.flip){case"horizontal":e.push("rotateY(180deg)");break;case"vertical":e.push("rotateX(180deg)");break;case"both":e.push("rotateX(180deg)"),e.push("rotateY(180deg)")}return r.rotate&&e.push(`rotate(${r.rotate%360}deg)`),`${r.color?`color: ${r.color};`:""}${r.size?`font-size: ${o=r.size,o?"number"==typeof o||/^\d+(?:\.\d+)?$/.test(o)?`${o}px`:o:""};`:""}${e.length?`transform: ${e.join(" ")};`:""}`;var o});return(t,r)=>"component"===s.value?(e.openBlock(),e.createBlock(e.resolveDynamicComponent(t.icon),{key:0,class:e.normalizeClass([e.unref(u).b()]),style:e.normalizeStyle(a.value+(e.unref(l).style||""))},null,8,["class","style"])):"css"===s.value&&c.value?(e.openBlock(),e.createElementBlock("i",{key:1,class:e.normalizeClass([e.unref(u).b(),c.value]),style:e.normalizeStyle(a.value+(e.unref(l).style||""))},null,6)):"svg"===s.value&&c.value?(e.openBlock(),e.createElementBlock("i",{key:2,style:e.normalizeStyle(a.value+(e.unref(l).style||"")),class:e.normalizeClass([e.unref(u).b()])},[e.createVNode(e.unref(o.Icon),{icon:c.value},null,8,["icon"])],6)):c.value?(e.openBlock(),e.createElementBlock("svg",{key:3,"aria-hidden":"true",class:e.normalizeClass([e.unref(u).b()]),style:e.normalizeStyle(a.value+(e.unref(l).style||""))},[e.createElementVNode("use",{"xlink:href":`#${t.localIconPrefix}${c.value}`},null,8,n)],6)):e.createCommentVNode("v-if",!0)}});exports.default=r;
|
2
2
|
//# sourceMappingURL=icon.vue.cjs.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"icon.vue.cjs","sources":["../../../../../../packages/components/src/icon/src/icon.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { Icon } from '@iconify/vue'\nimport { useNamespace } from '@qxs-bns/hooks'\nimport
|
1
|
+
{"version":3,"file":"icon.vue.cjs","sources":["../../../../../../packages/components/src/icon/src/icon.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { Component } from 'vue'\nimport { Icon } from '@iconify/vue'\nimport { useNamespace } from '@qxs-bns/hooks'\nimport { computed, useAttrs } from 'vue'\n\ndefineOptions({\n name: 'QxsIcon',\n})\n\nconst {\n icon,\n flip = '',\n rotate = 0,\n runtime,\n color,\n size,\n localIconPrefix = 'icon-',\n} = defineProps<PropsType>()\n\nconst attrs = useAttrs()\n\nconst ns = useNamespace('icon')\n\nexport interface PropsType {\n icon: string | Component\n runtime?: boolean\n flip?: 'horizontal' | 'vertical' | 'both' | '' | undefined\n rotate?: number\n color?: string\n size?: string | number\n localIconPrefix?: string\n}\n\nconst isComponentName = computed(() => typeof icon === 'object' || typeof icon === 'function')\n\nconst outputType = computed(() => {\n if (isComponentName.value) {\n return 'component'\n }\n if ((icon as string).indexOf('i-') === 0) {\n return runtime ? 'svg' : 'css'\n }\n else if ((icon as string).includes(':')) {\n return 'svg'\n }\n else {\n return 'custom'\n }\n})\n\nconst outputName = computed(() => {\n if (isComponentName.value) {\n return ''\n }\n if ((icon as string).indexOf('i-') === 0) {\n let conversionName = icon as string\n if (runtime) {\n conversionName = conversionName.replace('i-', '')\n }\n return conversionName\n }\n else {\n return icon as string\n }\n})\n\n// 用正则匹配 size 是不是 number 值,再判断是否有 px 结尾的单位,没有则拼接\nfunction formatSize(size: string | number | undefined): string {\n if (!size) {\n return ''\n }\n\n // 如果是数字,直接添加 px\n if (typeof size === 'number') {\n return `${size}px`\n }\n\n // 如果是纯数字字符串,添加 px\n if (/^\\d+(?:\\.\\d+)?$/.test(size)) {\n return `${size}px`\n }\n\n // 如果已经有单位(px、em、rem等)或者不是纯数字,直接返回\n return size\n}\n\n// 统一的样式计算属性,适用于所有图标类型\n// 包含颜色、尺寸和变换(旋转、翻转)\n// Iconify 图标通过外层 i 标签应用这些样式\nconst style = computed(() => {\n const transform = [] as string[]\n switch (flip) {\n case 'horizontal':\n transform.push('rotateY(180deg)')\n break\n case 'vertical':\n transform.push('rotateX(180deg)')\n break\n case 'both':\n transform.push('rotateX(180deg)')\n transform.push('rotateY(180deg)')\n break\n // 对于 '' 和 undefined,不做任何处理\n }\n if (rotate) {\n transform.push(`rotate(${rotate % 360}deg)`)\n }\n return `${color ? `color: ${color};` : ''}${size ? `font-size: ${formatSize(size)};` : ''}${transform.length ? `transform: ${transform.join(' ')};` : ''}`\n})\n</script>\n\n<template>\n <component\n :is=\"icon as any\"\n v-if=\"outputType === 'component'\"\n :class=\"[ns.b()]\"\n :style=\"style + (attrs.style || '')\"\n />\n <i\n v-else-if=\"outputType === 'css' && outputName\"\n :class=\"[ns.b(), outputName]\"\n :style=\"style + (attrs.style || '')\"\n />\n <i\n v-else-if=\"outputType === 'svg' && outputName\"\n :style=\"style + (attrs.style || '')\"\n :class=\"[ns.b()]\"\n >\n <Icon\n :icon=\"outputName\"\n />\n </i>\n <svg\n v-else-if=\"outputName\"\n aria-hidden=\"true\"\n :class=\"[ns.b()]\"\n :style=\"style + (attrs.style || '')\"\n >\n <use :xlink:href=\"`#${localIconPrefix}${outputName}`\" />\n </svg>\n</template>\n"],"names":["attrs","useAttrs","ns","useNamespace","isComponentName","computed","__props","icon","outputType","value","indexOf","runtime","includes","outputName","conversionName","replace","style","transform","flip","push","rotate","color","size","test","length","join","_openBlock","_createBlock","_resolveDynamicComponent","class","_normalizeClass","_unref","b","_normalizeStyle","_createElementBlock","_createVNode","Icon","_createElementVNode","localIconPrefix"],"mappings":"4mBAoBA,MAAMA,EAAQC,EAAAA,WAERC,EAAKC,EAAAA,aAAa,QAYlBC,EAAkBC,WAAS,IAAsB,iBAATC,EAAAC,MAAqC,mBAATD,EAAAC,MAEpEC,EAAaH,EAAAA,SAAS,IACtBD,EAAgBK,MACX,YAE8B,IAAlCH,EAAAC,KAAgBG,QAAQ,MACpBJ,EAAAK,QAAU,MAAQ,MAEjBL,EAAAC,KAAgBK,SAAS,KAC1B,MAGA,UAILC,EAAaR,EAAAA,SAAS,KAC1B,GAAID,EAAgBK,MAClB,MAAO,GAET,GAAuC,IAAlCH,EAAAC,KAAgBG,QAAQ,MAAa,CACxC,IAAII,EAAiBR,EAAAC,KAIrB,OAHID,EAAAK,UACFG,EAAiBA,EAAeC,QAAQ,KAAM,KAEzCD,CACT,CAEE,OAAOR,EAAAC,OA2BX,MAAMS,EAAQX,EAAAA,SAAS,KACrB,MAAMY,EAAY,GAClB,OAAQX,EAAAY,MACN,IAAK,aACHD,EAAUE,KAAK,mBACf,MACF,IAAK,WACHF,EAAUE,KAAK,mBACf,MACF,IAAK,OACHF,EAAUE,KAAK,mBACfF,EAAUE,KAAK,mBAOnB,OAHIb,EAAAc,QACFH,EAAUE,KAAK,UAAUb,SAAS,WAE7B,GAAGA,EAAAe,MAAQ,UAAUf,EAAAe,SAAW,KAAKf,EAAAgB,KAAO,cAxCjCA,EAwC0DhB,OAvCvEgB,EAKe,iBAATA,GAKP,kBAAkBC,KAAKD,GAJlB,GAAGA,MASLA,EAdE,MAsC8E,KAAKL,EAAUO,OAAS,cAAcP,EAAUQ,KAAK,QAAU,KAxCxJ,IAAoBH,iBA+CA,cAAVd,EAAAC,OAFRiB,EAAAA,YAAAC,EAAAA,YAKEC,EAAAA,wBAJKrB,EAAAA,MAAI,OAERsB,MAAKC,EAAAA,eAAA,CAAGC,EAAAA,MAAA7B,GAAG8B,MACXhB,MAAKiB,EAAAA,eAAEjB,EAAAP,OAASsB,EAAAA,MAAA/B,GAAMgB,OAAK,yCAGjBR,EAAAC,OAAwBI,EAAAJ,qBADrCyB,EAAAA,mBAIE,IAAA,OAFCL,MAAKC,EAAAA,eAAA,CAAGC,QAAA7B,GAAG8B,IAAKnB,EAAAJ,QAChBO,MAAKiB,EAAAA,eAAEjB,EAAAP,OAASsB,EAAAA,MAAA/B,GAAMgB,OAAK,uBAGjBR,EAAAC,OAAwBI,EAAAJ,qBADrCyB,EAAAA,mBAQI,IAAA,OANDlB,MAAKiB,EAAAA,eAAEjB,EAAAP,OAASsB,EAAAA,MAAA/B,GAAMgB,OAAK,KAC3Ba,MAAKC,EAAAA,eAAA,CAAGC,EAAAA,MAAA7B,GAAG8B,QAEZG,EAAAA,YAEEJ,EAAAA,MAAAK,QAAA,CADC7B,KAAMM,EAAAJ,OAAU,KAAA,EAAA,CAAA,cAIRI,EAAAJ,qBADbyB,EAAAA,mBAOM,MAAA,OALJ,cAAY,OACXL,MAAKC,EAAAA,eAAA,CAAGC,EAAAA,MAAA7B,GAAG8B,MACXhB,MAAKiB,EAAAA,eAAEjB,EAAAP,OAASsB,EAAAA,MAAA/B,GAAMgB,OAAK,OAE5BqB,EAAAA,mBAAwD,MAAA,CAAlD,aAAU,IAAMC,EAAAA,kBAAkBzB,EAAAJ"}
|
@@ -1,2 +1,2 @@
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("vue"),t=require("@qxs-bns/icons"),l=require("element-plus");const i={class:"image-slot"},a=["src"],r=["onClick"],n=["onClick"],o={class:"tip-content"};var s=e.defineComponent({name:"QxsImageUpload",__name:"image-upload",props:e.mergeModels({action:{type:String,required:!0},headers:{type:null,required:!1},data:{type:null,required:!1},name:{type:String,required:!1,default:"file"},url:{type:String,required:!1},size:{type:Number,required:!1,default:20},width:{type:Number,required:!1,default:160},accept:{type:String,required:!1,default:"image/jpeg,image/jpg,image/png,image/gif"},height:{type:Number,required:!1,default:90},placeholder:{type:String,required:!1,default:"上传图片"},notip:{type:Boolean,required:!1,default:!1},tipText:{type:String,required:!1,default:""},beforeUpload:{type:null,required:!1},disabled:{type:Boolean,required:!1,default:!1},limit:{type:Number,required:!1,default:1}},{fileList:{type:Array,default:()=>[]},fileListModifiers:{}}),emits:e.mergeModels(["onSuccess","remove"],["update:fileList"]),setup(s,{emit:u}){const p=u,c=e.useAttrs(),d=e.useModel(s,"fileList"),m=l.useNamespace("image-upload"),f=e.ref(0),g=e.ref({imageViewerVisible:!1,progress:{preview:"",percent:0}}),v=e.computed(()=>m.cssVarBlock({ns:m.namespace.value,width:`${s.width||160}px`,height:`${s.height||90}px`})),h=e.computed(()=>s.accept.split(",").map(e=>e.split("/").pop())),y=e.computed(()=>s.tipText||`上传图片支持 ${h.value.join(" / ")} 格式,且图片大小不超过 ${s.size}MB${s.width&&s.height?`,建议图片尺寸为 ${s.width}*${s.height}`:""}`);function V(e){f.value=d.value.indexOf(e),g.value.imageViewerVisible=!0}function x(e){d.value.splice(d.value.indexOf(e),1)}function b(){g.value.imageViewerVisible=!1}const q=e=>{const t=e.name.split(".").pop()??"",i=h.value.includes(t),a=e.size/1024/1024<s.size;return i?a?(g.value.progress.preview=URL.createObjectURL(e),!s.beforeUpload||s.beforeUpload(e)):(l.ElMessage.error(`上传图片大小不能超过 ${s.size}MB!`),!1):(l.ElMessage.error(`上传图片只支持${h.value.join(" / ")}格式!`),!1)},w=e=>{g.value.progress.percent=Math.floor(e.percent)},C=(...e)=>{g.value.progress={preview:"",percent:0},p("onSuccess",...e)};return(s,u)=>{const p=e.resolveComponent("QxsIcon");return e.openBlock(),e.createElementBlock("div",{class:e.normalizeClass(e.unref(m).e("container")),style:e.normalizeStyle(v.value)},[e.createVNode(e.unref(l.ElUpload),e.mergeProps(e.unref(c),{"file-list":d.value,"onUpdate:fileList":u[0]||(u[0]=e=>d.value=e),drag:"",limit:s.limit,"list-type":"picture-card",headers:s.headers,action:s.action,data:s.data,name:s.name,accept:s.accept,"before-upload":q,"on-progress":w,"on-preview":V,"on-success":C,class:[e.unref(m).e("control"),s.limit<=d.value.length?e.unref(m).e("more-than-limit"):""],"on-remove":x}),{file:e.withCtx(({file:l})=>[e.createElementVNode("img",{class:e.normalizeClass(`${e.unref(m).namespace.value}-upload-list__item-thumbnail`),src:l.url},null,10,a),e.createElementVNode("span",{class:e.normalizeClass(`${e.unref(m).namespace.value}-upload-list__item-actions`)},[e.createElementVNode("span",{class:e.normalizeClass(`${e.unref(m).namespace.value}-upload-list__item-preview`),onClick:e=>V(l)},[e.createVNode(e.unref(t.ZoomIn),{size:"14px"})],10,r),u[1]||(u[1]=e.createElementVNode("span",{style:{width:"1px",height:"14px","background-color":"rgb(255 255 255 / 50%)"}},null,-1)),s.disabled?e.createCommentVNode("v-if",!0):(e.openBlock(),e.createElementBlock("span",{key:0,class:e.normalizeClass(`${e.unref(m).namespace.value}-upload-list__item-delete`),onClick:e=>x(l)},[e.createVNode(e.unref(t.Delete),{size:"14px"})],10,n))],2)]),tip:e.withCtx(()=>[e.renderSlot(s.$slots,"tip",{},()=>[s.notip?e.createCommentVNode("v-if",!0):(e.openBlock(),e.createElementBlock("div",{key:0,class:e.normalizeClass(`${e.unref(m).namespace.value}-upload__tip-text`)},[e.createElementVNode("div",o,e.toDisplayString(y.value),1)],2))])]),default:e.withCtx(()=>[e.renderSlot(s.$slots,"default",{},()=>[e.createElementVNode("div",i,[e.createVNode(p,{size:"32px",icon:e.unref(t.UploadImage)},null,8,["icon"]),e.createElementVNode("p",null,e.toDisplayString(s.placeholder),1)])])]),_:3},16,["file-list","limit","headers","action","data","name","accept","class"]),g.value.imageViewerVisible?(e.openBlock(),e.createBlock(e.unref(l.ElImageViewer),{key:0,"url-list":d.value.map(e=>e.url).filter(e=>void 0!==e),"initial-index":f.value,teleported:"",onClose:b},null,8,["url-list","initial-index"])):e.createCommentVNode("v-if",!0)],6)}}});exports.default=s;
|
2
2
|
//# sourceMappingURL=image-upload.vue.cjs.map
|
@@ -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 {
|
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, UploadImage, ZoomIn } from '@qxs-bns/icons'\nimport { ElImageViewer, ElMessage, ElUpload, useNamespace } from 'element-plus'\nimport { computed, ref, useAttrs } from 'vue'\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 <ElUpload\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 <QxsIcon\n size=\"32px\"\n :icon=\"UploadImage\"\n />\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 >\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 <ZoomIn size=\"14px\" />\n </span>\n <span style=\"width: 1px; height: 14px; background-color: rgb(255 255 255 / 50%);\" />\n <span\n v-if=\"!disabled\"\n :class=\"`${nsEl.namespace.value}-upload-list__item-delete`\"\n @click=\"onRemove(file)\"\n >\n <Delete size=\"14px\" />\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 </ElUpload>\n\n <ElImageViewer\n v-if=\"uploadData.imageViewerVisible\"\n :url-list=\"fileList.map((item: UploadFile) => item.url).filter((v: string | undefined) => 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","_createElementBlock","class","_normalizeClass","_unref","e","style","_createVNode","ElUpload","_mergeProps","$event","drag","limit","headers","action","data","accept","length","_withCtx","_createElementVNode","src","url","onClick","ZoomIn","disabled","Delete","tip","_renderSlot","_ctx","notip","_hoisted_5","_toDisplayString","_hoisted_1","_component_QxsIcon","icon","UploadImage","placeholder","_createBlock","ElImageViewer","item","filter","v","teleported","onClose"],"mappings":"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"}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"composables.cjs","sources":["../../../../../../packages/components/src/photo-crop-tool/src/composables.ts"],"sourcesContent":["// useCanvas.ts\nimport
|
1
|
+
{"version":3,"file":"composables.cjs","sources":["../../../../../../packages/components/src/photo-crop-tool/src/composables.ts"],"sourcesContent":["import type { Ref } from 'vue'\n// useCanvas.ts\nimport { ref } from 'vue'\n\nexport function useCanvas(canvasElement: HTMLCanvasElement) {\n const context: Ref<CanvasRenderingContext2D | null> = ref(null)\n\n if (canvasElement) {\n context.value = canvasElement.getContext('2d')\n }\n\n const clearCanvas = () => {\n if (context.value) {\n context.value.clearRect(0, 0, canvasElement.width, canvasElement.height)\n }\n }\n\n const drawColor = (x: number, y: number, width: number, height: number, color: string) => {\n if (context.value) {\n context.value.fillStyle = color\n context.value.fillRect(x, y, width, height)\n }\n }\n\n const drawImage = (image: HTMLImageElement, x: number, y: number, width: number, height: number) => {\n context.value!.drawImage(image, x, y, width, height)\n }\n\n const cropCanvas = (x: number, y: number, width: number, height: number): Promise<File | null> => {\n return new Promise((resolve) => {\n if (context.value) {\n const croppedCanvas = document.createElement('canvas')\n croppedCanvas.width = width\n croppedCanvas.height = height\n const croppedContext = croppedCanvas.getContext('2d')\n if (croppedContext) {\n croppedContext.drawImage(canvasElement, x, y, width, height, 0, 0, width, height)\n croppedCanvas.toBlob((blob) => {\n if (blob) {\n const file = new File([blob], 'cropped_image.png', { type: 'image/png' })\n resolve(file)\n }\n else {\n resolve(null)\n }\n }, 'image/png')\n }\n else {\n resolve(null)\n }\n }\n else {\n resolve(null)\n }\n })\n }\n\n return {\n clearCanvas,\n drawColor,\n drawImage,\n cropCanvas,\n }\n}\n"],"names":["canvasElement","context","ref","value","getContext","clearCanvas","clearRect","width","height","drawColor","x","y","color","fillStyle","fillRect","drawImage","image","cropCanvas","Promise","resolve","croppedCanvas","document","createElement","croppedContext","toBlob","blob","file","File","type"],"mappings":"oDAIO,SAAmBA,GACxB,MAAMC,EAAgDC,EAAAA,IAAI,MAoD1D,OAlDIF,IACFC,EAAQE,MAAQH,EAAcI,WAAW,OAiDpC,CACLC,YA/CkBA,KACdJ,EAAQE,OACVF,EAAQE,MAAMG,UAAU,EAAG,EAAGN,EAAcO,MAAOP,EAAcQ,SA8CnEC,UA1CgBA,CAACC,EAAWC,EAAWJ,EAAeC,EAAgBI,KAClEX,EAAQE,QACVF,EAAQE,MAAMU,UAAYD,EAC1BX,EAAQE,MAAMW,SAASJ,EAAGC,EAAGJ,EAAOC,KAwCtCO,UApCgBA,CAACC,EAAyBN,EAAWC,EAAWJ,EAAeC,KAC/EP,EAAQE,MAAOY,UAAUC,EAAON,EAAGC,EAAGJ,EAAOC,IAoC7CS,WAjCiBA,CAACP,EAAWC,EAAWJ,EAAeC,IAChD,IAAIU,QAASC,IAClB,GAAIlB,EAAQE,MAAO,CACjB,MAAMiB,EAAgBC,SAASC,cAAc,UAC7CF,EAAcb,MAAQA,EACtBa,EAAcZ,OAASA,EACvB,MAAMe,EAAiBH,EAAchB,WAAW,MAC5CmB,GACFA,EAAeR,UAAUf,EAAeU,EAAGC,EAAGJ,EAAOC,EAAQ,EAAG,EAAGD,EAAOC,GAC1EY,EAAcI,OAAQC,IACpB,GAAIA,EAAM,CACR,MAAMC,EAAO,IAAIC,KAAK,CAACF,GAAO,oBAAqB,CAAEG,KAAM,cAC3DT,EAAQO,EACV,MAEEP,EAAQ,OAET,cAGHA,EAAQ,KAEZ,MAEEA,EAAQ,QAWhB"}
|
@@ -1,2 +1,2 @@
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("vue"),t=require("@qxs-bns/hooks"),o=require("
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("vue"),t=require("@qxs-bns/hooks"),o=require("@vueuse/core"),l=require("./composables.cjs");const a=["src"];var i=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(i,{expose:u}){const n=i;let s=0,r=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}=o.useElementSize(p),{width:E}=o.useElementSize(f),{x:T,y:M,style:z}=o.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,s=o,r=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-s,a=o-r;if("bottom-right"===g.value){if("free"===n.zoomType){const{width:e,height:t}=L(v+l,h+a);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:a,height:i}=L(t,o);i>(d.value?.clientHeight||1/0)&&(o=d.value?.clientHeight||1/0,t=o*e),y.value.width=a,y.value.height=i}}else if("top-left"===g.value){if("free"===n.zoomType){const{width:e,height:t}=L(v-l,h-a);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:a,height:i}=L(t,o);i>(d.value?.clientHeight||1/0)&&(o=d.value?.clientHeight||1/0,t=o*e),y.value.width=a,y.value.height=i}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-a);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:a,height:i}=L(t,o);i>(d.value?.clientHeight||1/0)&&(o=d.value?.clientHeight||1/0,t=o*e),y.value.width=a,y.value.height=i}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+a);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:a,height:i}=L(t,o);i>(d.value?.clientHeight||1/0)&&(o=d.value?.clientHeight||1/0,t=o*e),y.value.width=a,y.value.height=i}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 o=document.createElement("canvas");o.width=C(d.value?.clientWidth||0),o.height=C(d.value?.clientHeight||0);const{drawImage:a,cropCanvas:i,drawColor:u}=l.useCanvas(o);return u(0,0,o.width,o.height,t),a(e,C(e.offsetLeft),C(e.offsetTop),e.naturalWidth,e.naturalHeight),await i(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")])},[m.value?(e.openBlock(),e.createElementBlock("div",{key:0,class:e.normalizeClass([e.unref(c).e("error-message")])},e.toDisplayString(m.value),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:N.value},null,10,a),e.createElementVNode("div",{ref_key:"cropBoxRef",ref:p,class:e.normalizeClass([e.unref(c).e("crop-tool-box")]),style:e.normalizeStyle([H.value,g.value?`left: ${k.value.left}px;top: ${k.value.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=i;
|
2
2
|
//# sourceMappingURL=photo-crop-tool.vue.cjs.map
|