@veltra/desktop 1.0.8 → 1.0.10
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/dist/components/action/action-group.vue.d.ts +2 -2
- package/dist/components/action/action.vue.d.ts +3 -3
- package/dist/components/auto-complete/auto-complete.vue.d.ts +1 -1
- package/dist/components/batch-edit/batch-edit.js.map +1 -1
- package/dist/components/batch-edit/batch-edit.vue.d.ts +2 -2
- package/dist/components/batch-edit/use-edit.js.map +1 -1
- package/dist/components/button/button.js.map +1 -1
- package/dist/components/button/button.vue.d.ts +1 -1
- package/dist/components/cascade/cascade.js +15 -13
- package/dist/components/cascade/cascade.js.map +1 -1
- package/dist/components/cascade/cascade.vue.d.ts +7 -7
- package/dist/components/cascade/node.js.map +1 -1
- package/dist/components/cascade/use-check.js +3 -2
- package/dist/components/cascade/use-check.js.map +1 -1
- package/dist/components/cascade/use-select.js +3 -3
- package/dist/components/cascade/use-select.js.map +1 -1
- package/dist/components/checkbox-group/checkbox-group.js.map +1 -1
- package/dist/components/checkbox-group/checkbox-group.vue.d.ts +2 -2
- package/dist/components/date-panel/date-panel.js.map +1 -1
- package/dist/components/date-panel/date-panel.vue.d.ts +1 -1
- package/dist/components/date-picker/date-picker.js +9 -9
- package/dist/components/date-picker/date-picker.js.map +1 -1
- package/dist/components/date-picker/date-picker.vue.d.ts +1 -1
- package/dist/components/date-range-picker/date-range-picker.js +9 -9
- package/dist/components/date-range-picker/date-range-picker.js.map +1 -1
- package/dist/components/date-range-picker/date-range-picker.vue.d.ts +1 -1
- package/dist/components/drawer/drawer.js.map +1 -1
- package/dist/components/empty/empty.vue.d.ts +1 -1
- package/dist/components/expression-editor/expression-editor.js.map +1 -1
- package/dist/components/expression-editor/internal/editor-runtime/create-runtime.js.map +1 -1
- package/dist/components/expression-editor/internal/features/commands/register-command-packs.js.map +1 -1
- package/dist/components/expression-editor/internal/features/insertion/insertion-service.js.map +1 -1
- package/dist/components/expression-editor/use-decorators.js.map +1 -1
- package/dist/components/expression-editor/use-expression-drag-drop.js.map +1 -1
- package/dist/components/file-picker/file-picker.js.map +1 -1
- package/dist/components/file-picker/file-picker.vue.d.ts +1 -1
- package/dist/components/file-picker/helper.js +19 -7
- package/dist/components/file-picker/helper.js.map +1 -1
- package/dist/components/file-viewer/file-viewer.js +294 -0
- package/dist/components/file-viewer/file-viewer.js.map +1 -0
- package/dist/components/file-viewer/file-viewer.vue.d.ts +42 -0
- package/dist/components/file-viewer/helper.js +185 -0
- package/dist/components/file-viewer/helper.js.map +1 -0
- package/dist/components/file-viewer/index.d.ts +1 -0
- package/dist/components/file-viewer/previewers/docx-previewer.js +76 -0
- package/dist/components/file-viewer/previewers/docx-previewer.js.map +1 -0
- package/dist/components/file-viewer/previewers/image-previewer.js +64 -0
- package/dist/components/file-viewer/previewers/image-previewer.js.map +1 -0
- package/dist/components/file-viewer/previewers/pdf-previewer.js +90 -0
- package/dist/components/file-viewer/previewers/pdf-previewer.js.map +1 -0
- package/dist/components/file-viewer/previewers/sheet-previewer.js +175 -0
- package/dist/components/file-viewer/previewers/sheet-previewer.js.map +1 -0
- package/dist/components/file-viewer/previewers/text-previewer.js +74 -0
- package/dist/components/file-viewer/previewers/text-previewer.js.map +1 -0
- package/dist/components/file-viewer/previewers/video-previewer.js +62 -0
- package/dist/components/file-viewer/previewers/video-previewer.js.map +1 -0
- package/dist/components/file-viewer/style.d.ts +1 -0
- package/dist/components/file-viewer/style.js +4 -0
- package/dist/components/file-viewer/style2.css +445 -0
- package/dist/components/form/form-model.js +2 -1
- package/dist/components/form/form-model.js.map +1 -1
- package/dist/components/grid/grid.js.map +1 -1
- package/dist/components/grid/use-responsive.js.map +1 -1
- package/dist/components/grid-input/grid-input.vue.d.ts +1 -1
- package/dist/components/index.d.ts +12 -9
- package/dist/components/input/input.vue.d.ts +3 -3
- package/dist/components/list/list.js.map +1 -1
- package/dist/components/loading/directive.js.map +1 -1
- package/dist/components/menu/menu-item.js.map +1 -1
- package/dist/components/message/message2.js.map +1 -1
- package/dist/components/multi-select/multi-select-option.js +14 -10
- package/dist/components/multi-select/multi-select-option.js.map +1 -1
- package/dist/components/multi-select/multi-select.js +16 -19
- package/dist/components/multi-select/multi-select.js.map +1 -1
- package/dist/components/multi-select/multi-select.vue.d.ts +4 -4
- package/dist/components/multi-tree-select/multi-tree-select.vue.d.ts +7 -7
- package/dist/components/notification/index.js.map +1 -1
- package/dist/components/notification/notification.vue.d.ts +1 -1
- package/dist/components/number-input/number-input.js.map +1 -1
- package/dist/components/number-input/number-input.vue.d.ts +1 -1
- package/dist/components/number-range-input/number-range-input.vue.d.ts +1 -1
- package/dist/components/palette/color-transform.js.map +1 -1
- package/dist/components/palette/di.js.map +1 -1
- package/dist/components/palette/palette-alpha.js +7 -10
- package/dist/components/palette/palette-alpha.js.map +1 -1
- package/dist/components/palette/palette-hue.js +5 -7
- package/dist/components/palette/palette-hue.js.map +1 -1
- package/dist/components/palette/palette-sv.js +8 -10
- package/dist/components/palette/palette-sv.js.map +1 -1
- package/dist/components/palette/palette.js +22 -24
- package/dist/components/palette/palette.js.map +1 -1
- package/dist/components/password-input/password-input.vue.d.ts +1 -1
- package/dist/components/pop-confirm/pop-confirm.vue.d.ts +2 -2
- package/dist/components/progress/progress.js +1 -1
- package/dist/components/progress/progress.js.map +1 -1
- package/dist/components/progress-nodes/progress-nodes.js.map +1 -1
- package/dist/components/radio-group/radio-group.vue.d.ts +2 -2
- package/dist/components/rich-text-editor/rich-text-editor.js.map +1 -1
- package/dist/components/rich-text-editor/rich-text-editor.vue.d.ts +1 -1
- package/dist/components/rich-text-editor/toolbar.js.map +1 -1
- package/dist/components/scroll/scroll.js.map +1 -1
- package/dist/components/select/select.js +14 -12
- package/dist/components/select/select.js.map +1 -1
- package/dist/components/select/select.vue.d.ts +3 -3
- package/dist/components/slider/slider-thumb.js +10 -13
- package/dist/components/slider/slider-thumb.js.map +1 -1
- package/dist/components/slider/slider.js +12 -15
- package/dist/components/slider/slider.js.map +1 -1
- package/dist/components/table/di.js.map +1 -1
- package/dist/components/table/node/row.d.ts +10 -1
- package/dist/components/table/node/row.js +9 -0
- package/dist/components/table/node/row.js.map +1 -1
- package/dist/components/table/table-body.js +25 -26
- package/dist/components/table/table-body.js.map +1 -1
- package/dist/components/table/table-cell.js +16 -9
- package/dist/components/table/table-cell.js.map +1 -1
- package/dist/components/table/table-row.js +77 -19
- package/dist/components/table/table-row.js.map +1 -1
- package/dist/components/table/table.js +75 -34
- package/dist/components/table/table.js.map +1 -1
- package/dist/components/table/table.vue.d.ts +2 -2
- package/dist/components/table/use-columns.js +4 -0
- package/dist/components/table/use-columns.js.map +1 -1
- package/dist/components/table/use-fixed-columns.js +27 -8
- package/dist/components/table/use-fixed-columns.js.map +1 -1
- package/dist/components/table/use-rows.js +2 -2
- package/dist/components/table/use-rows.js.map +1 -1
- package/dist/components/table/use-table.js +50 -3
- package/dist/components/table/use-table.js.map +1 -1
- package/dist/components/tabs/index.d.ts +3 -1
- package/dist/components/tabs/style2.css +170 -107
- package/dist/components/tabs/tabs-horizontal.js +133 -0
- package/dist/components/tabs/tabs-horizontal.js.map +1 -0
- package/dist/components/tabs/tabs-horizontal.vue.d.ts +40 -0
- package/dist/components/tabs/tabs-vertical.js +89 -0
- package/dist/components/tabs/tabs-vertical.js.map +1 -0
- package/dist/components/tabs/tabs-vertical.vue.d.ts +38 -0
- package/dist/components/tabs/tabs.js +75 -105
- package/dist/components/tabs/tabs.js.map +1 -1
- package/dist/components/tabs/tabs.vue.d.ts +9 -23
- package/dist/components/tabs/use-tabs-bar.js +105 -0
- package/dist/components/tabs/use-tabs-bar.js.map +1 -0
- package/dist/components/text/text.js.map +1 -1
- package/dist/components/textarea/textarea.js.map +1 -1
- package/dist/components/textarea/textarea.vue.d.ts +4 -4
- package/dist/components/theme/theme.js.map +1 -1
- package/dist/components/tip/tip.vue.d.ts +1 -1
- package/dist/components/tree/style2.css +45 -23
- package/dist/components/tree/tree-node.js +50 -35
- package/dist/components/tree/tree-node.js.map +1 -1
- package/dist/components/tree/tree-node2.js.map +1 -1
- package/dist/components/tree/tree.js +27 -20
- package/dist/components/tree/tree.js.map +1 -1
- package/dist/components/tree/tree.vue.d.ts +5 -5
- package/dist/components/tree/use-check.js +52 -14
- package/dist/components/tree/use-check.js.map +1 -1
- package/dist/components/tree/use-tree-nodes.js +51 -24
- package/dist/components/tree/use-tree-nodes.js.map +1 -1
- package/dist/components/tree-select/tree-select.vue.d.ts +7 -7
- package/dist/index.d.ts +57 -53
- package/dist/index.js +51 -48
- package/dist/types/file-viewer.d.ts +71 -0
- package/dist/types/index.d.ts +3 -2
- package/dist/types/tabs.d.ts +106 -14
- package/dist/types/tree.d.ts +6 -1
- package/package.json +32 -31
- package/src/components/cascade/cascade.vue +18 -18
- package/src/components/cascade/node.ts +4 -1
- package/src/components/cascade/use-check.ts +5 -4
- package/src/components/cascade/use-select.ts +4 -5
- package/src/components/date-picker/date-picker.vue +10 -9
- package/src/components/date-range-picker/date-range-picker.vue +12 -12
- package/src/components/file-picker/helper.ts +21 -10
- package/src/components/file-viewer/file-viewer.vue +311 -0
- package/src/components/file-viewer/helper.ts +193 -0
- package/src/components/file-viewer/index.ts +1 -0
- package/src/components/file-viewer/previewers/docx-previewer.vue +78 -0
- package/src/components/file-viewer/previewers/image-previewer.vue +64 -0
- package/src/components/file-viewer/previewers/pdf-previewer.vue +90 -0
- package/src/components/file-viewer/previewers/sheet-previewer.vue +210 -0
- package/src/components/file-viewer/previewers/text-previewer.vue +76 -0
- package/src/components/file-viewer/previewers/video-previewer.vue +72 -0
- package/src/components/file-viewer/style.scss +504 -0
- package/src/components/file-viewer/style.ts +4 -0
- package/src/components/index.ts +2 -0
- package/src/components/multi-select/multi-select-option.vue +16 -3
- package/src/components/multi-select/multi-select.vue +17 -9
- package/src/components/palette/di.ts +5 -3
- package/src/components/palette/palette-alpha.vue +7 -10
- package/src/components/palette/palette-hue.vue +5 -7
- package/src/components/palette/palette-sv.vue +12 -14
- package/src/components/palette/palette.vue +19 -21
- package/src/components/progress/progress.vue +1 -1
- package/src/components/select/select.vue +21 -19
- package/src/components/slider/slider-thumb.vue +11 -14
- package/src/components/slider/slider.vue +15 -15
- package/src/components/table/di.ts +58 -43
- package/src/components/table/node/row.ts +10 -1
- package/src/components/table/table-body.vue +28 -33
- package/src/components/table/table-cell.vue +17 -9
- package/src/components/table/table-row.tsx +83 -17
- package/src/components/table/table.vue +72 -45
- package/src/components/table/use-fixed-columns.ts +46 -12
- package/src/components/table/use-rows.ts +14 -3
- package/src/components/table/use-table.ts +27 -3
- package/src/components/tabs/index.ts +2 -0
- package/src/components/tabs/style.scss +219 -133
- package/src/components/tabs/tabs-horizontal.vue +128 -0
- package/src/components/tabs/tabs-vertical.vue +77 -0
- package/src/components/tabs/tabs.vue +56 -127
- package/src/components/tabs/use-tabs-bar.ts +119 -0
- package/src/components/tree/style.scss +74 -29
- package/src/components/tree/tree-node.vue +10 -4
- package/src/components/tree/tree.vue +39 -12
- package/src/components/tree/use-check.ts +79 -23
- package/src/components/tree/use-tree-nodes.ts +85 -34
- package/src/types/file-viewer.ts +69 -0
- package/src/types/index.ts +1 -0
- package/src/types/tabs.ts +113 -19
- package/src/types/tree.ts +6 -1
|
@@ -6,7 +6,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
6
6
|
name: "PaletteHue",
|
|
7
7
|
__name: "palette-hue",
|
|
8
8
|
setup(__props, { expose: __expose }) {
|
|
9
|
-
const { cls, updateHue, HSV,
|
|
9
|
+
const { cls, updateHue, HSV, userAction } = inject(PaletteDIKey);
|
|
10
10
|
const hueRef = shallowRef();
|
|
11
11
|
const transformX = shallowRef(0);
|
|
12
12
|
let sliderWidth = 0;
|
|
@@ -18,12 +18,10 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
18
18
|
sliderWidth = hueRef.value?.offsetWidth ?? 0;
|
|
19
19
|
rangeX[1] = sliderWidth;
|
|
20
20
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
});
|
|
26
|
-
}
|
|
21
|
+
const updateOffsetX = userAction((offsetX) => {
|
|
22
|
+
transformX.value = offsetX;
|
|
23
|
+
updateHue(Math.round(offsetX / sliderWidth * 360));
|
|
24
|
+
});
|
|
27
25
|
const sliderDragger = useDrag({
|
|
28
26
|
target: hueRef,
|
|
29
27
|
rangeX,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"palette-hue.js","names":[],"sources":["../../../src/components/palette/palette-hue.vue"],"sourcesContent":["<template>\n <div :class=\"cls.e('hue')\" ref=\"hueRef\">\n <span :class=\"cls.e('hue-thumb')\" @click.stop :style=\"hueThumbStyle\"></span>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { useDrag } from '@veltra/compositions'\nimport { inject, onMounted } from 'vue'\nimport { shallowRef, computed } from 'vue'\n\nimport { PaletteDIKey } from './di'\n\ndefineOptions({\n name: 'PaletteHue'\n})\n\nconst { cls, updateHue, HSV,
|
|
1
|
+
{"version":3,"file":"palette-hue.js","names":[],"sources":["../../../src/components/palette/palette-hue.vue"],"sourcesContent":["<template>\n <div :class=\"cls.e('hue')\" ref=\"hueRef\">\n <span :class=\"cls.e('hue-thumb')\" @click.stop :style=\"hueThumbStyle\"></span>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { useDrag } from '@veltra/compositions'\nimport { inject, onMounted } from 'vue'\nimport { shallowRef, computed } from 'vue'\n\nimport { PaletteDIKey } from './di'\n\ndefineOptions({\n name: 'PaletteHue'\n})\n\nconst { cls, updateHue, HSV, userAction } = inject(PaletteDIKey)!\n\nconst hueRef = shallowRef<HTMLElement>()\n\nconst transformX = shallowRef(0)\nlet sliderWidth = 0\n\nconst hueThumbStyle = computed(() => {\n return { transform: `translateX(${transformX.value}px)` }\n})\n\nconst rangeX = [0, 0] as [number, number]\n\nfunction getSliderWidth() {\n sliderWidth = hueRef.value?.offsetWidth ?? 0\n rangeX[1] = sliderWidth\n}\n\nconst updateOffsetX = userAction((offsetX: number) => {\n transformX.value = offsetX\n updateHue(Math.round((offsetX / sliderWidth) * 360))\n})\n\nconst sliderDragger = useDrag({\n target: hueRef,\n rangeX,\n onDrag({ offsetX }) {\n updateOffsetX(offsetX)\n },\n onDragStart(e) {\n getSliderWidth()\n\n sliderDragger.update({ offsetX: e.offsetX })\n\n updateOffsetX(e.offsetX)\n }\n})\n\nfunction init(): void {\n getSliderWidth()\n transformX.value = (sliderWidth * HSV.h) / 360\n}\n\nonMounted(() => {\n init()\n})\n\ndefineExpose({\n init\n})\n</script>\n"],"mappings":";;;;;;;;EAiBA,MAAM,EAAE,KAAK,WAAW,KAAK,eAAe,OAAO,aAAa;EAEhE,MAAM,SAAS,YAAwB;EAEvC,MAAM,aAAa,WAAW,EAAC;EAC/B,IAAI,cAAc;EAElB,MAAM,gBAAgB,eAAe;AACnC,UAAO,EAAE,WAAW,cAAc,WAAW,MAAM,MAAK;IACzD;EAED,MAAM,SAAS,CAAC,GAAG,EAAE;EAErB,SAAS,iBAAiB;AACxB,iBAAc,OAAO,OAAO,eAAe;AAC3C,UAAO,KAAK;;EAGd,MAAM,gBAAgB,YAAY,YAAoB;AACpD,cAAW,QAAQ;AACnB,aAAU,KAAK,MAAO,UAAU,cAAe,IAAI,CAAA;IACpD;EAED,MAAM,gBAAgB,QAAQ;GAC5B,QAAQ;GACR;GACA,OAAO,EAAE,WAAW;AAClB,kBAAc,QAAO;;GAEvB,YAAY,GAAG;AACb,oBAAe;AAEf,kBAAc,OAAO,EAAE,SAAS,EAAE,SAAS,CAAA;AAE3C,kBAAc,EAAE,QAAO;;GAE1B,CAAA;EAED,SAAS,OAAa;AACpB,mBAAe;AACf,cAAW,QAAS,cAAc,IAAI,IAAK;;AAG7C,kBAAgB;AACd,SAAK;IACN;AAED,WAAa,EACX,MACD,CAAA;;uBAjEC,mBAEM,OAAA;IAFA,OAAK,eAAE,MAAA,IAAG,CAAC,EAAC,MAAA,CAAA;aAAa;IAAJ,KAAI;OAC7B,mBAA4E,QAAA;IAArE,OAAK,eAAE,MAAA,IAAG,CAAC,EAAC,YAAA,CAAA;IAAgB,SAAK,OAAA,OAAA,OAAA,KAAA,oBAAN,IAAW,CAAA,OAAA,CAAA;IAAE,OAAK,eAAE,cAAA,MAAa"}
|
|
@@ -6,7 +6,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
6
6
|
name: "PaletteSV",
|
|
7
7
|
__name: "palette-sv",
|
|
8
8
|
setup(__props, { expose: __expose }) {
|
|
9
|
-
const { cls, hueRGB, HSV, updateSV,
|
|
9
|
+
const { cls, hueRGB, HSV, updateSV, userAction } = inject(PaletteDIKey);
|
|
10
10
|
const svRef = shallowRef();
|
|
11
11
|
const canvasSize = {
|
|
12
12
|
width: 0,
|
|
@@ -29,16 +29,14 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
29
29
|
const svThumbStyle = computed(() => {
|
|
30
30
|
return { transform: `translate(${transform.x}px, ${transform.y}px)` };
|
|
31
31
|
});
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
v: Math.max(0, Math.min(1, 1 - offsetY / canvasSize.height))
|
|
39
|
-
});
|
|
32
|
+
const updateThumb = userAction((offsetX, offsetY) => {
|
|
33
|
+
transform.x = offsetX;
|
|
34
|
+
transform.y = offsetY;
|
|
35
|
+
updateSV({
|
|
36
|
+
s: Math.max(0, Math.min(1, offsetX / canvasSize.width)),
|
|
37
|
+
v: Math.max(0, Math.min(1, 1 - offsetY / canvasSize.height))
|
|
40
38
|
});
|
|
41
|
-
}
|
|
39
|
+
});
|
|
42
40
|
const svDragger = useDrag({
|
|
43
41
|
target: svRef,
|
|
44
42
|
rangeX,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"palette-sv.js","names":[],"sources":["../../../src/components/palette/palette-sv.vue"],"sourcesContent":["<template>\n <!-- 调色画布 -->\n <div :class=\"cls.e('sv')\" ref=\"svRef\">\n <div :class=\"cls.e('sv-s')\" :style=\"{ backgroundImage: canvasBackground }\"></div>\n <div :class=\"cls.e('sv-v')\">{{}}</div>\n\n <div\n :class=\"cls.e('sv-thumb')\"\n ref=\"svThumbRef\"\n @click.stop\n @mousedown.stop\n :style=\"svThumbStyle\"\n ></div>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { useDrag } from '@veltra/compositions'\nimport { computed, inject, reactive, shallowRef, onMounted } from 'vue'\n\nimport { PaletteDIKey } from './di'\n\ndefineOptions({\n name: 'PaletteSV'\n})\n\nconst { cls, hueRGB, HSV, updateSV,
|
|
1
|
+
{"version":3,"file":"palette-sv.js","names":[],"sources":["../../../src/components/palette/palette-sv.vue"],"sourcesContent":["<template>\n <!-- 调色画布 -->\n <div :class=\"cls.e('sv')\" ref=\"svRef\">\n <div :class=\"cls.e('sv-s')\" :style=\"{ backgroundImage: canvasBackground }\"></div>\n <div :class=\"cls.e('sv-v')\">{{}}</div>\n\n <div\n :class=\"cls.e('sv-thumb')\"\n ref=\"svThumbRef\"\n @click.stop\n @mousedown.stop\n :style=\"svThumbStyle\"\n ></div>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { useDrag } from '@veltra/compositions'\nimport { computed, inject, reactive, shallowRef, onMounted } from 'vue'\n\nimport { PaletteDIKey } from './di'\n\ndefineOptions({\n name: 'PaletteSV'\n})\n\nconst { cls, hueRGB, HSV, updateSV, userAction } = inject(PaletteDIKey)!\n\nconst svRef = shallowRef<HTMLDivElement>()\n\nconst canvasSize = {\n width: 0,\n height: 0\n}\n\nconst rangeX = [0, 0] as [number, number]\nconst rangeY = [0, 0] as [number, number]\n\nconst getCanvasSize = () => {\n if (!svRef.value) return\n const { offsetHeight, offsetWidth } = svRef.value!\n\n canvasSize.width = offsetWidth\n rangeX[1] = offsetWidth\n\n canvasSize.height = offsetHeight\n rangeY[1] = offsetHeight\n}\n\nconst transform = reactive({\n x: 0,\n y: 0\n})\n\nconst svThumbStyle = computed(() => {\n return {\n transform: `translate(${transform.x}px, ${transform.y}px)`\n }\n})\n\nconst updateThumb = userAction((offsetX: number, offsetY: number) => {\n transform.x = offsetX\n transform.y = offsetY\n\n // 根据画布位置计算饱和度和亮度\n // 水平方向表示饱和度,从左到右饱和度逐渐增高\n // 垂直方向表示亮度,上亮下暗\n const s = Math.max(0, Math.min(1, offsetX / canvasSize.width))\n const v = Math.max(0, Math.min(1, 1 - offsetY / canvasSize.height))\n\n // 更新饱和度和亮度\n updateSV({ s, v })\n})\n\nconst svDragger = useDrag({\n target: svRef,\n rangeX,\n rangeY,\n\n onDrag({ offsetX, offsetY }) {\n updateThumb(offsetX, offsetY)\n },\n onDragStart(e) {\n getCanvasSize()\n\n const { offsetX, offsetY } = e\n\n updateThumb(offsetX, offsetY)\n\n svDragger.update({ offsetX, offsetY })\n }\n})\n\nconst canvasBackground = computed(() => {\n const { r, g, b } = hueRGB.value\n return `linear-gradient(to right, rgb(255, 255, 255), rgb(${r}, ${g}, ${b}))`\n})\n\nfunction init(): void {\n getCanvasSize()\n transform.x = canvasSize.width * HSV.s\n transform.y = canvasSize.height * (1 - HSV.v)\n}\n\nonMounted(() => {\n init()\n})\n\ndefineExpose({\n init\n})\n</script>\n"],"mappings":";;;;;;;;EA0BA,MAAM,EAAE,KAAK,QAAQ,KAAK,UAAU,eAAe,OAAO,aAAa;EAEvE,MAAM,QAAQ,YAA2B;EAEzC,MAAM,aAAa;GACjB,OAAO;GACP,QAAQ;GACV;EAEA,MAAM,SAAS,CAAC,GAAG,EAAE;EACrB,MAAM,SAAS,CAAC,GAAG,EAAE;EAErB,MAAM,sBAAsB;AAC1B,OAAI,CAAC,MAAM,MAAO;GAClB,MAAM,EAAE,cAAc,gBAAgB,MAAM;AAE5C,cAAW,QAAQ;AACnB,UAAO,KAAK;AAEZ,cAAW,SAAS;AACpB,UAAO,KAAK;;EAGd,MAAM,YAAY,SAAS;GACzB,GAAG;GACH,GAAG;GACJ,CAAA;EAED,MAAM,eAAe,eAAe;AAClC,UAAO,EACL,WAAW,aAAa,UAAU,EAAE,MAAM,UAAU,EAAE,MACxD;IACD;EAED,MAAM,cAAc,YAAY,SAAiB,YAAoB;AACnE,aAAU,IAAI;AACd,aAAU,IAAI;AASd,YAAS;IAAE,GAJD,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,UAAU,WAAW,MAAM,CAIlD;IAAG,GAHJ,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,IAAI,UAAU,WAAW,OAAO,CAGpD;IAAG,CAAA;IAClB;EAED,MAAM,YAAY,QAAQ;GACxB,QAAQ;GACR;GACA;GAEA,OAAO,EAAE,SAAS,WAAW;AAC3B,gBAAY,SAAS,QAAO;;GAE9B,YAAY,GAAG;AACb,mBAAc;IAEd,MAAM,EAAE,SAAS,YAAY;AAE7B,gBAAY,SAAS,QAAO;AAE5B,cAAU,OAAO;KAAE;KAAS;KAAS,CAAA;;GAExC,CAAA;EAED,MAAM,mBAAmB,eAAe;GACtC,MAAM,EAAE,GAAG,GAAG,MAAM,OAAO;AAC3B,UAAO,qDAAqD,EAAE,IAAI,EAAE,IAAI,EAAE;IAC3E;EAED,SAAS,OAAa;AACpB,kBAAc;AACd,aAAU,IAAI,WAAW,QAAQ,IAAI;AACrC,aAAU,IAAI,WAAW,UAAU,IAAI,IAAI;;AAG7C,kBAAgB;AACd,SAAK;IACN;AAED,WAAa,EACX,MACD,CAAA;;2DA7GC,mBAAA,SAAa,EACb,mBAWM,OAAA;IAXA,OAAK,eAAE,MAAA,IAAG,CAAC,EAAC,KAAA,CAAA;aAAY;IAAJ,KAAI;;IAC5B,mBAAiF,OAAA;KAA3E,OAAK,eAAE,MAAA,IAAG,CAAC,EAAC,OAAA,CAAA;KAAW,OAAK,eAAA,EAAA,iBAAqB,iBAAA,OAAgB,CAAA;;IACvE,mBAAsC,OAAA,EAAhC,OAAK,eAAE,MAAA,IAAG,CAAC,EAAC,OAAA,CAAA,EAAA,EAAA,iBAAA,EAAA,EAAA;IAElB,mBAMO,OAAA;KALJ,OAAK,eAAE,MAAA,IAAG,CAAC,EAAC,WAAA,CAAA;KACb,KAAI;KACH,SAAK,OAAA,OAAA,OAAA,KAAA,oBAAN,IAAW,CAAA,OAAA,CAAA;KACV,aAAS,OAAA,OAAA,OAAA,KAAA,oBAAV,IAAe,CAAA,OAAA,CAAA;KACd,OAAK,eAAE,aAAA,MAAY"}
|
|
@@ -8,7 +8,7 @@ import _sfc_main$5 from "./palette-sv.js";
|
|
|
8
8
|
import { useHSV } from "./use-hsv.js";
|
|
9
9
|
import { computed, createBlock, createCommentVNode, createElementVNode, createVNode, defineComponent, mergeModels, normalizeClass, normalizeStyle, openBlock, provide, shallowRef, unref, useModel, useTemplateRef, watch, withCtx } from "vue";
|
|
10
10
|
import { bem } from "@veltra/utils";
|
|
11
|
-
import { useFormComponent, useFormFallbackProps,
|
|
11
|
+
import { useFormComponent, useFormFallbackProps, useUserAction } from "@veltra/compositions";
|
|
12
12
|
//#region src/components/palette/palette.vue
|
|
13
13
|
const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
14
14
|
name: "Palette",
|
|
@@ -48,43 +48,41 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
48
48
|
const { HSV, alpha, ...rest } = useHSV();
|
|
49
49
|
const color = useModel(__props, "modelValue");
|
|
50
50
|
const RGB = computed(() => HSV2RGB(HSV));
|
|
51
|
-
const
|
|
51
|
+
const { userAction, isUserActive } = useUserAction();
|
|
52
52
|
watch([alpha, RGB], ([alpha, RGB]) => {
|
|
53
53
|
color.value = `#${RGB2HEX(RGB, alpha)}`;
|
|
54
54
|
});
|
|
55
55
|
const visible = shallowRef(false);
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
});
|
|
62
|
-
}
|
|
56
|
+
const handleClear = userAction(() => {
|
|
57
|
+
color.value = "";
|
|
58
|
+
rest.updateAlpha(1);
|
|
59
|
+
visible.value = false;
|
|
60
|
+
});
|
|
63
61
|
const paletteSVRef = useTemplateRef("palette-sv");
|
|
64
62
|
const paletteHueRef = useTemplateRef("palette-hue");
|
|
65
63
|
const paletteAlphaRef = useTemplateRef("palette-alpha");
|
|
66
64
|
watch(color, (color) => {
|
|
67
65
|
if (!color) return;
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
});
|
|
76
|
-
rest.updateAlpha(alpha);
|
|
77
|
-
paletteSVRef.value?.init();
|
|
78
|
-
paletteHueRef.value?.init();
|
|
79
|
-
paletteAlphaRef.value?.init();
|
|
66
|
+
if (isUserActive()) return;
|
|
67
|
+
const { RGB, alpha } = HEX2RGBA(color);
|
|
68
|
+
const hsv = RGB2HSV(RGB);
|
|
69
|
+
rest.updateHue(hsv.h);
|
|
70
|
+
rest.updateSV({
|
|
71
|
+
s: hsv.s,
|
|
72
|
+
v: hsv.v
|
|
80
73
|
});
|
|
74
|
+
rest.updateAlpha(alpha);
|
|
75
|
+
paletteSVRef.value?.init();
|
|
76
|
+
paletteHueRef.value?.init();
|
|
77
|
+
paletteAlphaRef.value?.init();
|
|
81
78
|
}, { immediate: true });
|
|
82
79
|
provide(PaletteDIKey, {
|
|
83
80
|
cls,
|
|
84
81
|
HSV,
|
|
85
82
|
RGB,
|
|
86
83
|
alpha,
|
|
87
|
-
|
|
84
|
+
userAction,
|
|
85
|
+
isUserActive,
|
|
88
86
|
...rest
|
|
89
87
|
});
|
|
90
88
|
return (_ctx, _cache) => {
|
|
@@ -106,8 +104,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
106
104
|
createVNode(_sfc_main$3, {
|
|
107
105
|
color: color.value,
|
|
108
106
|
"onUpdate:color": _cache[0] || (_cache[0] = ($event) => color.value = $event),
|
|
109
|
-
onClear: handleClear
|
|
110
|
-
}, null, 8, ["color"])
|
|
107
|
+
onClear: unref(handleClear)
|
|
108
|
+
}, null, 8, ["color", "onClear"])
|
|
111
109
|
]),
|
|
112
110
|
default: withCtx(() => [createElementVNode("span", {
|
|
113
111
|
class: normalizeClass(className.value),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"palette.js","names":[],"sources":["../../../src/components/palette/palette.vue"],"sourcesContent":["<template>\n <u-tip\n trigger=\"click\"\n :class=\"cls.e('panel')\"\n v-model:visible=\"visible\"\n :disabled=\"disabled || readonly\"\n >\n <span :class=\"className\" :style=\"{ backgroundColor: color }\"> </span>\n\n <template #content>\n <!-- 饱和度和亮度 -->\n <PaletteSV ref=\"palette-sv\" />\n\n <!-- 色相 -->\n <PaletteHue ref=\"palette-hue\" />\n\n <!-- 透明度 -->\n <PaletteAlpha ref=\"palette-alpha\" />\n\n <!-- 颜色切换 -->\n <PaletteColorSwitch v-model:color=\"color\" @clear=\"handleClear\" />\n </template>\n </u-tip>\n</template>\n\n<script lang=\"ts\" setup>\nimport { useFormComponent, useFormFallbackProps,
|
|
1
|
+
{"version":3,"file":"palette.js","names":[],"sources":["../../../src/components/palette/palette.vue"],"sourcesContent":["<template>\n <u-tip\n trigger=\"click\"\n :class=\"cls.e('panel')\"\n v-model:visible=\"visible\"\n :disabled=\"disabled || readonly\"\n >\n <span :class=\"className\" :style=\"{ backgroundColor: color }\"> </span>\n\n <template #content>\n <!-- 饱和度和亮度 -->\n <PaletteSV ref=\"palette-sv\" />\n\n <!-- 色相 -->\n <PaletteHue ref=\"palette-hue\" />\n\n <!-- 透明度 -->\n <PaletteAlpha ref=\"palette-alpha\" />\n\n <!-- 颜色切换 -->\n <PaletteColorSwitch v-model:color=\"color\" @clear=\"handleClear\" />\n </template>\n </u-tip>\n</template>\n\n<script lang=\"ts\" setup>\nimport { useFormComponent, useFormFallbackProps, useUserAction } from '@veltra/compositions'\nimport { bem } from '@veltra/utils'\nimport { computed, provide, shallowRef, useTemplateRef, watch } from 'vue'\n\nimport type { PaletteProps } from '../../types'\nimport { UTip } from '../tip'\nimport { HSV2RGB, RGB2HEX, HEX2RGBA, RGB2HSV } from './color-transform'\nimport { PaletteDIKey } from './di'\nimport PaletteAlpha from './palette-alpha.vue'\nimport PaletteColorSwitch from './palette-color-switch.vue'\nimport PaletteHue from './palette-hue.vue'\nimport PaletteSV from './palette-sv.vue'\nimport { useHSV } from './use-hsv'\n\ndefineOptions({\n name: 'Palette'\n})\n\nconst props = withDefaults(defineProps<PaletteProps>(), {\n disabled: undefined,\n readonly: undefined\n})\n\nconst { formProps } = useFormComponent()\n\nconst { size, disabled, readonly } = useFormFallbackProps([formProps ?? {}, props])\n\nconst cls = bem('palette')\n\nconst className = computed(() => {\n return [cls.b, cls.m(size.value), bem.is('no-color', !color.value)]\n})\n\nconst { HSV, alpha, ...rest } = useHSV()\n\nconst color = defineModel<string>()\nconst RGB = computed(() => HSV2RGB(HSV))\nconst { userAction, isUserActive } = useUserAction()\n\nwatch([alpha, RGB], ([alpha, RGB]) => {\n color.value = `#${RGB2HEX(RGB, alpha)}`\n})\n\nconst visible = shallowRef(false)\n\nconst handleClear = userAction(() => {\n color.value = ''\n rest.updateAlpha(1)\n visible.value = false\n})\n\nconst paletteSVRef = useTemplateRef('palette-sv')\nconst paletteHueRef = useTemplateRef('palette-hue')\nconst paletteAlphaRef = useTemplateRef('palette-alpha')\n\nwatch(\n color,\n (color) => {\n if (!color) return\n if (isUserActive()) return\n\n const { RGB, alpha } = HEX2RGBA(color)\n const hsv = RGB2HSV(RGB)\n rest.updateHue(hsv.h)\n rest.updateSV({ s: hsv.s, v: hsv.v })\n rest.updateAlpha(alpha)\n\n paletteSVRef.value?.init()\n paletteHueRef.value?.init()\n paletteAlphaRef.value?.init()\n },\n { immediate: true }\n)\n\nprovide(PaletteDIKey, {\n cls,\n HSV,\n RGB,\n alpha,\n userAction,\n isUserActive,\n ...rest\n})\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4CA,MAAM,QAAQ;EAKd,MAAM,EAAE,cAAc,kBAAiB;EAEvC,MAAM,EAAE,MAAM,UAAU,aAAa,qBAAqB,CAAC,aAAa,EAAE,EAAE,MAAM,CAAA;EAElF,MAAM,MAAM,IAAI,UAAS;EAEzB,MAAM,YAAY,eAAe;AAC/B,UAAO;IAAC,IAAI;IAAG,IAAI,EAAE,KAAK,MAAM;IAAE,IAAI,GAAG,YAAY,CAAC,MAAM,MAAM;IAAA;IACnE;EAED,MAAM,EAAE,KAAK,OAAO,GAAG,SAAS,QAAO;EAEvC,MAAM,QAAQ,SAAmB,SAAA,aAAC;EAClC,MAAM,MAAM,eAAe,QAAQ,IAAI,CAAA;EACvC,MAAM,EAAE,YAAY,iBAAiB,eAAc;AAEnD,QAAM,CAAC,OAAO,IAAI,GAAG,CAAC,OAAO,SAAS;AACpC,SAAM,QAAQ,IAAI,QAAQ,KAAK,MAAM;IACtC;EAED,MAAM,UAAU,WAAW,MAAK;EAEhC,MAAM,cAAc,iBAAiB;AACnC,SAAM,QAAQ;AACd,QAAK,YAAY,EAAC;AAClB,WAAQ,QAAQ;IACjB;EAED,MAAM,eAAe,eAAe,aAAY;EAChD,MAAM,gBAAgB,eAAe,cAAa;EAClD,MAAM,kBAAkB,eAAe,gBAAe;AAEtD,QACE,QACC,UAAU;AACT,OAAI,CAAC,MAAO;AACZ,OAAI,cAAc,CAAE;GAEpB,MAAM,EAAE,KAAK,UAAU,SAAS,MAAK;GACrC,MAAM,MAAM,QAAQ,IAAG;AACvB,QAAK,UAAU,IAAI,EAAC;AACpB,QAAK,SAAS;IAAE,GAAG,IAAI;IAAG,GAAG,IAAI;IAAG,CAAA;AACpC,QAAK,YAAY,MAAK;AAEtB,gBAAa,OAAO,MAAK;AACzB,iBAAc,OAAO,MAAK;AAC1B,mBAAgB,OAAO,MAAK;KAE9B,EAAE,WAAW,MAAK,CACpB;AAEA,UAAQ,cAAc;GACpB;GACA;GACA;GACA;GACA;GACA;GACA,GAAG;GACJ,CAAA;;uBA3GC,YAqBQ,MAAA,YAAA,EAAA;IApBN,SAAQ;IACP,OAAK,eAAE,MAAA,IAAG,CAAC,EAAC,QAAA,CAAA;IACL,SAAS,QAAA;8DAAA,QAAO,QAAA;IACvB,UAAU,MAAA,SAAQ,IAAI,MAAA,SAAQ;;IAIpB,SAAO,cACD;KAAf,mBAAA,WAAe;KACf,YAA8B,aAAA,EAAnB,KAAI,cAAY,EAAA,MAAA,IAAA;KAE3B,mBAAA,OAAW;KACX,YAAgC,aAAA,EAApB,KAAI,eAAa,EAAA,MAAA,IAAA;KAE7B,mBAAA,QAAY;KACZ,YAAoC,aAAA,EAAtB,KAAI,iBAAe,EAAA,MAAA,IAAA;KAEjC,mBAAA,SAAa;KACb,YAAiE,aAAA;MAArC,OAAO,MAAA;8DAAA,MAAK,QAAA;MAAG,SAAO,MAAA,YAAW;;;2BAbM,CAArE,mBAAqE,QAAA;KAA9D,OAAK,eAAE,UAAA,MAAS;KAAG,OAAK,eAAA,EAAA,iBAAqB,MAAA,OAAK,CAAA"}
|
|
@@ -16,8 +16,8 @@ declare const __VLS_base: _$vue.DefineComponent<__VLS_PublicProps, {}, {}, {}, {
|
|
|
16
16
|
"onUpdate:modelValue"?: ((value: string | undefined) => any) | undefined;
|
|
17
17
|
}>, {
|
|
18
18
|
disabled: boolean;
|
|
19
|
-
clearable: boolean;
|
|
20
19
|
readonly: boolean;
|
|
20
|
+
clearable: boolean;
|
|
21
21
|
}, {}, {}, {}, string, _$vue.ComponentProvideOptions, false, {}, any>;
|
|
22
22
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
23
23
|
declare const _default: typeof __VLS_export;
|
|
@@ -14,9 +14,9 @@ declare const __VLS_base: _$vue.DefineComponent<PopConfirmProps, {}, {}, {}, {},
|
|
|
14
14
|
onConfirm?: (() => any) | undefined;
|
|
15
15
|
onCancel?: (() => any) | undefined;
|
|
16
16
|
}>, {
|
|
17
|
-
icon: _$vue.Component;
|
|
18
|
-
direction: TipDirection;
|
|
19
17
|
trigger: "hover" | "click";
|
|
18
|
+
direction: TipDirection;
|
|
19
|
+
icon: _$vue.Component;
|
|
20
20
|
iconColor: string;
|
|
21
21
|
confirmText: string;
|
|
22
22
|
cancelText: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"progress.js","names":[],"sources":["../../../src/components/progress/progress.vue"],"sourcesContent":["<template>\n <div :class=\"className\">\n <!-- 条形进度条 -->\n <div :class=\"cls.e('bar-wrap')\" v-if=\"!circle\">\n <div :class=\"cls.e('bar')\" :style=\"{ width: percentage + '%' }\">\n <slot v-bind=\"{ percentage, type }\">{{ percentage }}%</slot>\n </div>\n </div>\n\n <!-- 环形进度条 -->\n <div\n v-else\n :class=\"cls.e('circle')\"\n :style=\"{ height: withUnit(size, 'px'), width: withUnit(size, 'px') }\"\n >\n <svg viewBox=\"0 0 100 100\">\n <circle cx=\"50\" cy=\"50\" :r=\"r\" fill=\"none\" stroke=\"#f5f8fa\" stroke-width=\"8\" />\n <circle\n :class=\"cls.e('circle-ring')\"\n cx=\"50\"\n cy=\"50\"\n :r=\"r\"\n fill=\"none\"\n :stroke=\"stroke\"\n stroke-width=\"8\"\n :stroke-dasharray=\"dashArray\"\n :stroke-dashoffset=\"offset\"\n :stroke-linecap=\"percentage === 0 ? undefined : 'round'\"\n />\n </svg>\n\n <div :class=\"cls.e('circle-content')\">\n <slot v-bind=\"{ percentage, type }\"> {{ percentage }}% </slot>\n </div>\n </div>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { n } from '@cat-kit/core'\nimport { bem, withUnit } from '@veltra/utils'\nimport { computed } from 'vue'\n\nimport type { ProgressProps, ColorType } from '../../types'\n\ndefineOptions({\n name: 'Progress'\n})\n\nconst props = withDefaults(defineProps<ProgressProps>(), {\n type: 'primary',\n circle: false\n})\n\ndefineSlots<{\n default: (props: {\n /** 进度百分比 */\n percentage: number\n /** 样式类型 */\n type: ColorType\n }) => any\n}>()\n\nconst cls = bem('progress')\n\nconst percentage = computed(() => {\n return n(props.percentage ?? 0).range(0, 100)\n})\n\nconst type = computed<ColorType>(() => {\n const { type } = props\n return typeof type === 'function' ? type(percentage.value) : type\n})\n\nconst className = computed(() => {\n return [cls.b, bem.is('circle', props.circle), cls.m(type.value)]\n})\n\n/** 描边 */\nconst stroke = computed(() => {\n return `var(--color-${type.value})`\n})\n\nconst r = 44\nconst c = 2 * Math.PI * r\nconst offset = c / 4\n\n/** 圆周 */\nconst dashArray = computed(() => {\n const dashLen = (c * percentage.value) / 100\n return `${dashLen}, ${c - dashLen}`\n})\n</script>\n"],"mappings":";;;;;;;;;;AAmFA,MAAM,IAAI;;;;;;;;;;;;;;;;;EAlCV,MAAM,QAAQ;EAcd,MAAM,MAAM,IAAI,WAAU;EAE1B,MAAM,aAAa,eAAe;AAChC,UAAO,EAAE,MAAM,cAAc,EAAE,CAAC,MAAM,GAAG,IAAG;IAC7C;EAED,MAAM,OAAO,eAA0B;GACrC,MAAM,EAAE,SAAS;AACjB,UAAO,OAAO,SAAS,aAAa,KAAK,WAAW,MAAM,GAAG;IAC9D;EAED,MAAM,YAAY,eAAe;AAC/B,UAAO;IAAC,IAAI;IAAG,IAAI,GAAG,UAAU,MAAM,OAAO;IAAE,IAAI,EAAE,KAAK,MAAM;IAAA;IACjE;;EAGD,MAAM,SAAS,eAAe;AAC5B,UAAO,
|
|
1
|
+
{"version":3,"file":"progress.js","names":[],"sources":["../../../src/components/progress/progress.vue"],"sourcesContent":["<template>\n <div :class=\"className\">\n <!-- 条形进度条 -->\n <div :class=\"cls.e('bar-wrap')\" v-if=\"!circle\">\n <div :class=\"cls.e('bar')\" :style=\"{ width: percentage + '%' }\">\n <slot v-bind=\"{ percentage, type }\">{{ percentage }}%</slot>\n </div>\n </div>\n\n <!-- 环形进度条 -->\n <div\n v-else\n :class=\"cls.e('circle')\"\n :style=\"{ height: withUnit(size, 'px'), width: withUnit(size, 'px') }\"\n >\n <svg viewBox=\"0 0 100 100\">\n <circle cx=\"50\" cy=\"50\" :r=\"r\" fill=\"none\" stroke=\"#f5f8fa\" stroke-width=\"8\" />\n <circle\n :class=\"cls.e('circle-ring')\"\n cx=\"50\"\n cy=\"50\"\n :r=\"r\"\n fill=\"none\"\n :stroke=\"stroke\"\n stroke-width=\"8\"\n :stroke-dasharray=\"dashArray\"\n :stroke-dashoffset=\"offset\"\n :stroke-linecap=\"percentage === 0 ? undefined : 'round'\"\n />\n </svg>\n\n <div :class=\"cls.e('circle-content')\">\n <slot v-bind=\"{ percentage, type }\"> {{ percentage }}% </slot>\n </div>\n </div>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { n } from '@cat-kit/core'\nimport { bem, withUnit } from '@veltra/utils'\nimport { computed } from 'vue'\n\nimport type { ProgressProps, ColorType } from '../../types'\n\ndefineOptions({\n name: 'Progress'\n})\n\nconst props = withDefaults(defineProps<ProgressProps>(), {\n type: 'primary',\n circle: false\n})\n\ndefineSlots<{\n default: (props: {\n /** 进度百分比 */\n percentage: number\n /** 样式类型 */\n type: ColorType\n }) => any\n}>()\n\nconst cls = bem('progress')\n\nconst percentage = computed(() => {\n return n(props.percentage ?? 0).range(0, 100)\n})\n\nconst type = computed<ColorType>(() => {\n const { type } = props\n return typeof type === 'function' ? type(percentage.value) : type\n})\n\nconst className = computed(() => {\n return [cls.b, bem.is('circle', props.circle), cls.m(type.value)]\n})\n\n/** 描边 */\nconst stroke = computed(() => {\n return `var(--u-color-${type.value})`\n})\n\nconst r = 44\nconst c = 2 * Math.PI * r\nconst offset = c / 4\n\n/** 圆周 */\nconst dashArray = computed(() => {\n const dashLen = (c * percentage.value) / 100\n return `${dashLen}, ${c - dashLen}`\n})\n</script>\n"],"mappings":";;;;;;;;;;AAmFA,MAAM,IAAI;;;;;;;;;;;;;;;;;EAlCV,MAAM,QAAQ;EAcd,MAAM,MAAM,IAAI,WAAU;EAE1B,MAAM,aAAa,eAAe;AAChC,UAAO,EAAE,MAAM,cAAc,EAAE,CAAC,MAAM,GAAG,IAAG;IAC7C;EAED,MAAM,OAAO,eAA0B;GACrC,MAAM,EAAE,SAAS;AACjB,UAAO,OAAO,SAAS,aAAa,KAAK,WAAW,MAAM,GAAG;IAC9D;EAED,MAAM,YAAY,eAAe;AAC/B,UAAO;IAAC,IAAI;IAAG,IAAI,GAAG,UAAU,MAAM,OAAO;IAAE,IAAI,EAAE,KAAK,MAAM;IAAA;IACjE;;EAGD,MAAM,SAAS,eAAe;AAC5B,UAAO,iBAAiB,KAAK,MAAM;IACpC;EAGD,MAAM,IAAI,IAAI,KAAK,KAAK;EACxB,MAAM,SAAS,IAAI;;EAGnB,MAAM,YAAY,eAAe;GAC/B,MAAM,UAAW,IAAI,WAAW,QAAS;AACzC,UAAO,GAAG,QAAQ,IAAI,IAAI;IAC3B;;uBA1FC,mBAkCM,OAAA,EAlCA,OAAK,eAAE,UAAA,MAAS,EAAA,EAAA,CACpB,mBAAA,UAAc,EAAA,CACyB,QAAA,UAAA,WAAA,EAAvC,mBAIM,OAAA;;IAJA,OAAK,eAAE,MAAA,IAAG,CAAC,EAAC,WAAA,CAAA;OAChB,mBAEM,OAAA;IAFA,OAAK,eAAE,MAAA,IAAG,CAAC,EAAC,MAAA,CAAA;IAAU,OAAK,eAAA,EAAA,OAAW,WAAA,QAAU,KAAA,CAAA;OACpD,WAA4D,KAAA,QAAA,WAAA,eAAA,mBAAA;IAAA,YAA5C,WAAA;IAAU,MAAE,KAAA;IAAI,CAAA,CAAA,QAA4B,CAAA,gBAAA,gBAArB,WAAA,MAAU,GAAG,KAAC,EAAA,CAAA,CAAA,CAAA,EAAA,EAAA,CAAA,EAAA,EAAA,KAAA,WAAA,EAKzD,mBAwBM,UAAA,EAAA,KAAA,GAAA,EAAA,CAzBN,mBAAA,UAAc,EACd,mBAwBM,OAAA;IAtBH,OAAK,eAAE,MAAA,IAAG,CAAC,EAAC,SAAA,CAAA;IACZ,OAAK,eAAA;KAAA,QAAY,MAAA,SAAQ,CAAC,QAAA,MAAI,KAAA;KAAA,OAAgB,MAAA,SAAQ,CAAC,QAAA,MAAI,KAAA;KAAA,CAAA;qBAE5D,mBAcM,OAdN,YAcM,CAbJ,mBAA+E,UAAA;IAAvE,IAAG;IAAK,IAAG;IAAS;IAAG,MAAK;IAAO,QAAO;IAAU,gBAAa;OACzE,mBAWE,UAAA;IAVC,OAAK,eAAE,MAAA,IAAG,CAAC,EAAC,cAAA,CAAA;IACb,IAAG;IACH,IAAG;IACC;IACJ,MAAK;IACJ,QAAQ,OAAA;IACT,gBAAa;IACZ,oBAAkB,UAAA;IAClB,qBAAmB;IACnB,kBAAgB,WAAA,UAAU,IAAS,KAAA,IAAS;gCAIjD,mBAEM,OAAA,EAFA,OAAK,eAAE,MAAA,IAAG,CAAC,EAAC,iBAAA,CAAA,EAAA,EAAA,CAChB,WAA8D,KAAA,QAAA,WAAA,eAAA,mBAAA;IAAA,YAA9C,WAAA;IAAU,MAAE,KAAA;IAAI,CAAA,CAAA,QAA8B,CAAA,gBAAA,gBAAtB,WAAA,MAAU,GAAG,MAAE,EAAA,CAAA,CAAA,CAAA,EAAA,EAAA,CAAA,EAAA,EAAA,CAAA,EAAA,KAAA,EAAA,EAAA,EAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"progress-nodes.js","names":[],"sources":["../../../src/components/progress-nodes/progress-nodes.vue"],"sourcesContent":["<template>\n <div ref=\"container\" :class=\"className\" :style=\"containerStyle\" @scroll=\"checkScroll\">\n <ul :class=\"cls.e('list')\">\n <li\n v-for=\"(node, index) in nodes\"\n :key=\"node.key ?? index\"\n :class=\"[\n cls.e('item'),\n bem.is('checked', isChecked(node, index)),\n bem.is('active', isActive(node))\n ]\"\n @click=\"handleClick(node, index)\"\n >\n <div :class=\"cls.e('node')\">\n <!-- 虚线连接 -->\n <div v-if=\"index !== nodes.length - 1\" :class=\"cls.e('link')\"></div>\n\n <!-- 节点圆点 -->\n <span :class=\"cls.e('dot')\">\n <slot name=\"icon\" :node=\"node\" :index=\"index\" />\n </span>\n </div>\n\n <div :class=\"cls.e('label')\">\n <slot :node=\"node\" :index=\"index\">\n {{ getLabel(node) }}\n </slot>\n </div>\n </li>\n </ul>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { o } from '@cat-kit/core'\nimport { useDrag, useResizeObserver } from '@veltra/compositions'\nimport { bem } from '@veltra/utils'\nimport { computed, shallowRef, toRefs, useTemplateRef, watch, nextTick } from 'vue'\n\nimport type { ProgressNodesProps, ProgressNodesEmits } from '../../types'\n\ndefineOptions({\n name: 'ProgressNodes'\n})\n\nconst props = withDefaults(defineProps<ProgressNodesProps>(), {\n colorType: 'primary',\n labelKey: 'label',\n valueKey: 'value'\n})\n\nconst emit = defineEmits<ProgressNodesEmits>()\n\nconst { nodes } = toRefs(props)\n\nconst cls = bem('progress-nodes')\nconst containerRef = useTemplateRef('container')\nconst isDragging = shallowRef(false)\nconst isScrollable = shallowRef(false)\nconst showMaskStart = shallowRef(false)\nconst showMaskEnd = shallowRef(false)\n\nconst className = computed(() => [\n cls.b,\n cls.m(props.colorType),\n bem.is('scrollable', isScrollable.value),\n bem.is('dragging', isDragging.value),\n bem.is('mask-start', showMaskStart.value),\n bem.is('mask-end', showMaskEnd.value)\n])\n\nconst containerStyle = computed(() => {\n const style: Record<string, string> = {}\n const maxWidth = toCssSize(props.maxWidth)\n if (maxWidth) style.maxWidth = maxWidth\n return style\n})\n\nlet startScrollLeft = 0\n\nuseDrag({\n target: containerRef,\n onDragStart() {\n if (!isScrollable.value) return\n const container = containerRef.value\n if (!container) return\n isDragging.value = true\n startScrollLeft = container.scrollLeft\n },\n onDrag({ x }) {\n if (!isScrollable.value) return\n const container = containerRef.value\n if (!container) return\n container.scrollLeft = startScrollLeft - x\n },\n onDragEnd() {\n isDragging.value = false\n }\n})\n\nuseResizeObserver({\n targets: containerRef,\n onResize: checkScroll\n})\n\nwatch(\n nodes,\n () => {\n nextTick(checkScroll)\n },\n { deep: true }\n)\n\nfunction checkScroll() {\n const container = containerRef.value\n if (!container) return\n\n const { scrollLeft, scrollWidth, clientWidth } = container\n isScrollable.value = scrollWidth > clientWidth + 1\n showMaskStart.value = scrollLeft > 0\n showMaskEnd.value = scrollLeft + clientWidth < scrollWidth - 1\n}\n\nfunction isChecked(node: Record<string, any>, index: number) {\n return props.check?.(node, index) ?? false\n}\n\nfunction isActive(node: Record<string, any>) {\n const value = o(node).get(props.valueKey)\n return props.modelValue === value\n}\n\nfunction getLabel(node: Record<string, any>) {\n return o(node).get(props.labelKey)\n}\n\nfunction handleClick(node: Record<string, any>, index: number) {\n const value = o(node).get(props.valueKey)\n emit('update:modelValue', value)\n emit('click', node, index)\n}\n\nfunction toCssSize(value?: number | string) {\n if (value === undefined) return undefined\n return typeof value === 'number' ? `${value}px` : value\n}\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;EA6CA,MAAM,QAAQ;EAMd,MAAM,OAAO;EAEb,MAAM,EAAE,UAAU,OAAO,MAAK;EAE9B,MAAM,MAAM,IAAI,iBAAgB;EAChC,MAAM,eAAe,eAAe,YAAW;EAC/C,MAAM,aAAa,WAAW,MAAK;EACnC,MAAM,eAAe,WAAW,MAAK;EACrC,MAAM,gBAAgB,WAAW,MAAK;EACtC,MAAM,cAAc,WAAW,MAAK;EAEpC,MAAM,YAAY,eAAe;GAC/B,IAAI;GACJ,IAAI,EAAE,MAAM,UAAU;GACtB,IAAI,GAAG,cAAc,aAAa,MAAM;GACxC,IAAI,GAAG,YAAY,WAAW,MAAM;GACpC,IAAI,GAAG,cAAc,cAAc,MAAM;GACzC,IAAI,GAAG,YAAY,YAAY,MAAK;GACrC,CAAA;EAED,MAAM,iBAAiB,eAAe;GACpC,MAAM,QAAgC,EAAC;GACvC,MAAM,WAAW,UAAU,MAAM,SAAQ;AACzC,OAAI,SAAU,OAAM,WAAW;AAC/B,UAAO;IACR;EAED,IAAI,kBAAkB;AAEtB,UAAQ;GACN,QAAQ;GACR,cAAc;AACZ,QAAI,CAAC,aAAa,MAAO;IACzB,MAAM,YAAY,aAAa;AAC/B,QAAI,CAAC,UAAW;AAChB,eAAW,QAAQ;AACnB,sBAAkB,UAAU;;GAE9B,OAAO,EAAE,KAAK;AACZ,QAAI,CAAC,aAAa,MAAO;IACzB,MAAM,YAAY,aAAa;AAC/B,QAAI,CAAC,UAAW;AAChB,cAAU,aAAa,kBAAkB;;GAE3C,YAAY;AACV,eAAW,QAAQ;;GAEtB,CAAA;AAED,oBAAkB;GAChB,SAAS;GACT,UAAU;GACX,CAAA;AAED,QACE,aACM;AACJ,YAAS,YAAW;KAEtB,EAAE,MAAM,MAAK,CACf;EAEA,SAAS,cAAc;GACrB,MAAM,YAAY,aAAa;AAC/B,OAAI,CAAC,UAAW;GAEhB,MAAM,EAAE,YAAY,aAAa,gBAAgB;AACjD,gBAAa,QAAQ,cAAc,cAAc;AACjD,iBAAc,QAAQ,aAAa;AACnC,eAAY,QAAQ,aAAa,cAAc,cAAc;;EAG/D,SAAS,UAAU,MAA2B,OAAe;AAC3D,UAAO,MAAM,QAAQ,MAAM,MAAM,IAAI;;EAGvC,SAAS,SAAS,MAA2B;GAC3C,MAAM,QAAQ,EAAE,KAAK,CAAC,IAAI,MAAM,SAAQ;AACxC,UAAO,MAAM,eAAe;;EAG9B,SAAS,SAAS,MAA2B;AAC3C,UAAO,EAAE,KAAK,CAAC,IAAI,MAAM,SAAQ;;EAGnC,SAAS,YAAY,MAA2B,OAAe;AAE7D,QAAK,qBADS,EAAE,KAAK,CAAC,IAAI,MAAM,
|
|
1
|
+
{"version":3,"file":"progress-nodes.js","names":[],"sources":["../../../src/components/progress-nodes/progress-nodes.vue"],"sourcesContent":["<template>\n <div ref=\"container\" :class=\"className\" :style=\"containerStyle\" @scroll=\"checkScroll\">\n <ul :class=\"cls.e('list')\">\n <li\n v-for=\"(node, index) in nodes\"\n :key=\"node.key ?? index\"\n :class=\"[\n cls.e('item'),\n bem.is('checked', isChecked(node, index)),\n bem.is('active', isActive(node))\n ]\"\n @click=\"handleClick(node, index)\"\n >\n <div :class=\"cls.e('node')\">\n <!-- 虚线连接 -->\n <div v-if=\"index !== nodes.length - 1\" :class=\"cls.e('link')\"></div>\n\n <!-- 节点圆点 -->\n <span :class=\"cls.e('dot')\">\n <slot name=\"icon\" :node=\"node\" :index=\"index\" />\n </span>\n </div>\n\n <div :class=\"cls.e('label')\">\n <slot :node=\"node\" :index=\"index\">\n {{ getLabel(node) }}\n </slot>\n </div>\n </li>\n </ul>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { o } from '@cat-kit/core'\nimport { useDrag, useResizeObserver } from '@veltra/compositions'\nimport { bem } from '@veltra/utils'\nimport { computed, shallowRef, toRefs, useTemplateRef, watch, nextTick } from 'vue'\n\nimport type { ProgressNodesProps, ProgressNodesEmits } from '../../types'\n\ndefineOptions({\n name: 'ProgressNodes'\n})\n\nconst props = withDefaults(defineProps<ProgressNodesProps>(), {\n colorType: 'primary',\n labelKey: 'label',\n valueKey: 'value'\n})\n\nconst emit = defineEmits<ProgressNodesEmits>()\n\nconst { nodes } = toRefs(props)\n\nconst cls = bem('progress-nodes')\nconst containerRef = useTemplateRef('container')\nconst isDragging = shallowRef(false)\nconst isScrollable = shallowRef(false)\nconst showMaskStart = shallowRef(false)\nconst showMaskEnd = shallowRef(false)\n\nconst className = computed(() => [\n cls.b,\n cls.m(props.colorType),\n bem.is('scrollable', isScrollable.value),\n bem.is('dragging', isDragging.value),\n bem.is('mask-start', showMaskStart.value),\n bem.is('mask-end', showMaskEnd.value)\n])\n\nconst containerStyle = computed(() => {\n const style: Record<string, string> = {}\n const maxWidth = toCssSize(props.maxWidth)\n if (maxWidth) style.maxWidth = maxWidth\n return style\n})\n\nlet startScrollLeft = 0\n\nuseDrag({\n target: containerRef,\n onDragStart() {\n if (!isScrollable.value) return\n const container = containerRef.value\n if (!container) return\n isDragging.value = true\n startScrollLeft = container.scrollLeft\n },\n onDrag({ x }) {\n if (!isScrollable.value) return\n const container = containerRef.value\n if (!container) return\n container.scrollLeft = startScrollLeft - x\n },\n onDragEnd() {\n isDragging.value = false\n }\n})\n\nuseResizeObserver({\n targets: containerRef,\n onResize: checkScroll\n})\n\nwatch(\n nodes,\n () => {\n nextTick(checkScroll)\n },\n { deep: true }\n)\n\nfunction checkScroll() {\n const container = containerRef.value\n if (!container) return\n\n const { scrollLeft, scrollWidth, clientWidth } = container\n isScrollable.value = scrollWidth > clientWidth + 1\n showMaskStart.value = scrollLeft > 0\n showMaskEnd.value = scrollLeft + clientWidth < scrollWidth - 1\n}\n\nfunction isChecked(node: Record<string, any>, index: number) {\n return props.check?.(node, index) ?? false\n}\n\nfunction isActive(node: Record<string, any>) {\n const value = o(node).get(props.valueKey)\n return props.modelValue === value\n}\n\nfunction getLabel(node: Record<string, any>) {\n return o(node).get(props.labelKey)\n}\n\nfunction handleClick(node: Record<string, any>, index: number) {\n const value = o(node).get(props.valueKey)\n emit('update:modelValue', value)\n emit('click', node, index)\n}\n\nfunction toCssSize(value?: number | string) {\n if (value === undefined) return undefined\n return typeof value === 'number' ? `${value}px` : value\n}\n</script>\n"],"mappings":"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"}
|
|
@@ -16,10 +16,10 @@ declare const __VLS_export: _$vue.DefineComponent<__VLS_PublicProps, {}, {}, {},
|
|
|
16
16
|
"onUpdate:modelValue"?: ((value: any) => any) | undefined;
|
|
17
17
|
onChange?: ((item: Record<string, any>) => any) | undefined;
|
|
18
18
|
}>, {
|
|
19
|
-
disabled: boolean;
|
|
20
|
-
readonly: boolean;
|
|
21
19
|
labelKey: string;
|
|
22
20
|
valueKey: string;
|
|
21
|
+
disabled: boolean;
|
|
22
|
+
readonly: boolean;
|
|
23
23
|
}, {}, {}, {}, string, _$vue.ComponentProvideOptions, false, {}, any>;
|
|
24
24
|
declare const _default: typeof __VLS_export;
|
|
25
25
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rich-text-editor.js","names":[],"sources":["../../../src/components/rich-text-editor/rich-text-editor.vue"],"sourcesContent":["<template>\n <div :class=\"className\">\n <toolbar\n v-if=\"!isReadonly && toolbarItems.length > 0\"\n :editor=\"editor\"\n :toolbar=\"toolbarItems\"\n :disabled=\"isDisabled\"\n />\n <div :class=\"cls.e('content')\">\n <div\n ref=\"editorContainer\"\n :class=\"cls.e('editable')\"\n :contenteditable=\"!isDisabled && !isReadonly\"\n ></div>\n <div v-if=\"showPlaceholder\" :class=\"cls.e('placeholder')\">\n {{ placeholder }}\n </div>\n </div>\n </div>\n</template>\n\n<script lang=\"ts\">\nimport type { ToolbarItem } from '../../types'\n\nconst LEXICAL_THEME = {\n paragraph: 'u-rte-paragraph',\n heading: {\n h1: 'u-rte-h1',\n h2: 'u-rte-h2',\n h3: 'u-rte-h3',\n h4: 'u-rte-h4',\n h5: 'u-rte-h5',\n h6: 'u-rte-h6'\n },\n text: {\n bold: 'u-rte-bold',\n italic: 'u-rte-italic',\n underline: 'u-rte-underline',\n strikethrough: 'u-rte-strikethrough'\n },\n list: {\n ul: 'u-rte-ul',\n ol: 'u-rte-ol',\n listitem: 'u-rte-li',\n nested: { listitem: 'u-rte-li--nested' }\n },\n quote: 'u-rte-blockquote',\n\n link: 'u-rte-link',\n image: 'u-rte-image'\n}\n\nconst DEFAULT_TOOLBAR: ToolbarItem[] = [\n 'undo',\n 'redo',\n '|',\n 'heading',\n '|',\n 'bold',\n 'italic',\n 'underline',\n 'strikethrough',\n '|',\n 'bullet-list',\n 'ordered-list',\n '|',\n 'blockquote',\n '|',\n 'link'\n]\n</script>\n\n<script lang=\"ts\" setup>\nimport { registerHistory, createEmptyHistoryState } from '@lexical/history'\nimport { $generateHtmlFromNodes, $generateNodesFromDOM } from '@lexical/html'\nimport { LinkNode, AutoLinkNode } from '@lexical/link'\nimport { ListNode, ListItemNode, registerList } from '@lexical/list'\nimport { registerRichText } from '@lexical/rich-text'\nimport { HeadingNode, QuoteNode } from '@lexical/rich-text'\nimport { useFormComponent, useFormFallbackProps } from '@veltra/compositions'\nimport { bem } from '@veltra/utils'\nimport { createEditor, $getRoot, $createParagraphNode, type LexicalEditor } from 'lexical'\nimport { computed, onBeforeUnmount, onMounted, ref, shallowRef, useTemplateRef, watch } from 'vue'\n\nimport type { RichTextEditorProps } from '../../types'\nimport Toolbar from './toolbar.vue'\n\nconst props = withDefaults(defineProps<RichTextEditorProps>(), {\n disabled: undefined,\n readonly: undefined,\n format: 'html',\n toolbar: () => DEFAULT_TOOLBAR,\n placeholder: ''\n})\n\nconst model = defineModel<string>()\n\nconst cls = bem('rich-text-editor')\n\nconst { formProps } = useFormComponent()\n\nconst { size, disabled, readonly } = useFormFallbackProps([formProps ?? {}, props])\n\nconst isDisabled = computed(() => !!disabled.value)\nconst isReadonly = computed(() => !!readonly.value)\n\nconst className = computed<string[]>(() => {\n return [\n cls.b,\n cls.m(size.value),\n bem.is('disabled', isDisabled.value),\n bem.is('readonly', isReadonly.value)\n ]\n})\n\nconst toolbarItems = computed<ToolbarItem[]>(() => {\n return props.toolbar ?? DEFAULT_TOOLBAR\n})\n\nconst editorContainer = useTemplateRef('editorContainer')\nconst editor = shallowRef<LexicalEditor | null>(null)\nconst showPlaceholder = ref(true)\nlet isComposing = false\nlet cleanupFns: (() => void)[] = []\n\nfunction initEditor() {\n if (!editorContainer.value) return\n\n const editorInstance = createEditor({\n namespace: 'URichTextEditor',\n theme: LEXICAL_THEME,\n nodes: [HeadingNode, QuoteNode, ListNode, ListItemNode, LinkNode, AutoLinkNode],\n editable: !isDisabled.value && !isReadonly.value,\n onError: (error: Error) => {\n console.error('Lexical error:', error)\n }\n })\n\n editorInstance.setRootElement(editorContainer.value)\n\n // Register plugins\n cleanupFns.push(registerRichText(editorInstance))\n cleanupFns.push(registerList(editorInstance))\n cleanupFns.push(registerHistory(editorInstance, createEmptyHistoryState(), 300))\n\n // Set initial value\n if (model.value) {\n setEditorContent(editorInstance, model.value)\n }\n\n // Listen for content changes\n cleanupFns.push(\n editorInstance.registerUpdateListener(({ editorState }) => {\n editorState.read(() => {\n const root = $getRoot()\n const textContent = root.getTextContent()\n showPlaceholder.value = textContent.trim().length === 0\n\n if (isComposing) return\n\n let value: string\n if (props.format === 'json') {\n value = JSON.stringify(editorState.toJSON())\n } else {\n value = $generateHtmlFromNodes(editorInstance)\n }\n\n // Avoid circular updates: only emit if content really changed\n if (value !== model.value) {\n isComposing = true\n model.value = value\n // Use microtask to reset after Vue processes the update\n queueMicrotask(() => {\n isComposing = false\n })\n }\n })\n })\n )\n\n // Composing event listeners for IME\n const rootElement = editorInstance.getRootElement()\n if (rootElement) {\n const onCompositionStart = () => {\n isComposing = true\n }\n const onCompositionEnd = () => {\n isComposing = false\n }\n rootElement.addEventListener('compositionstart', onCompositionStart)\n rootElement.addEventListener('compositionend', onCompositionEnd)\n cleanupFns.push(() => {\n rootElement.removeEventListener('compositionstart', onCompositionStart)\n rootElement.removeEventListener('compositionend', onCompositionEnd)\n })\n }\n\n editor.value = editorInstance\n}\n\nfunction setEditorContent(editorInstance: LexicalEditor, value: string) {\n editorInstance.update(() => {\n const root = $getRoot()\n root.clear()\n\n if (props.format === 'json') {\n try {\n const parsedState = editorInstance.parseEditorState(value)\n editorInstance.setEditorState(parsedState)\n } catch {\n // If JSON parse fails, treat as empty\n root.append($createParagraphNode())\n }\n } else {\n // HTML format\n const parser = new DOMParser()\n const dom = parser.parseFromString(value, 'text/html')\n const nodes = $generateNodesFromDOM(editorInstance, dom)\n root.append(...nodes)\n }\n })\n}\n\n// Watch external model changes\nwatch(model, (newVal) => {\n if (!editor.value || isComposing) return\n\n const editorInstance = editor.value\n\n // Compare current content to avoid circular updates\n editorInstance.getEditorState().read(() => {\n let currentValue: string\n if (props.format === 'json') {\n currentValue = JSON.stringify(editorInstance.getEditorState().toJSON())\n } else {\n currentValue = $generateHtmlFromNodes(editorInstance)\n }\n\n if (currentValue !== newVal) {\n isComposing = true\n setEditorContent(editorInstance, newVal ?? '')\n queueMicrotask(() => {\n isComposing = false\n })\n }\n })\n})\n\n// Watch disabled/readonly changes\nwatch([isDisabled, isReadonly], () => {\n if (editor.value) {\n editor.value.setEditable(!isDisabled.value && !isReadonly.value)\n }\n})\n\nonMounted(() => {\n initEditor()\n})\n\nonBeforeUnmount(() => {\n cleanupFns.forEach((fn) => fn())\n cleanupFns = []\n editor.value = null\n})\n</script>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"rich-text-editor.js","names":[],"sources":["../../../src/components/rich-text-editor/rich-text-editor.vue"],"sourcesContent":["<template>\n <div :class=\"className\">\n <toolbar\n v-if=\"!isReadonly && toolbarItems.length > 0\"\n :editor=\"editor\"\n :toolbar=\"toolbarItems\"\n :disabled=\"isDisabled\"\n />\n <div :class=\"cls.e('content')\">\n <div\n ref=\"editorContainer\"\n :class=\"cls.e('editable')\"\n :contenteditable=\"!isDisabled && !isReadonly\"\n ></div>\n <div v-if=\"showPlaceholder\" :class=\"cls.e('placeholder')\">\n {{ placeholder }}\n </div>\n </div>\n </div>\n</template>\n\n<script lang=\"ts\">\nimport type { ToolbarItem } from '../../types'\n\nconst LEXICAL_THEME = {\n paragraph: 'u-rte-paragraph',\n heading: {\n h1: 'u-rte-h1',\n h2: 'u-rte-h2',\n h3: 'u-rte-h3',\n h4: 'u-rte-h4',\n h5: 'u-rte-h5',\n h6: 'u-rte-h6'\n },\n text: {\n bold: 'u-rte-bold',\n italic: 'u-rte-italic',\n underline: 'u-rte-underline',\n strikethrough: 'u-rte-strikethrough'\n },\n list: {\n ul: 'u-rte-ul',\n ol: 'u-rte-ol',\n listitem: 'u-rte-li',\n nested: { listitem: 'u-rte-li--nested' }\n },\n quote: 'u-rte-blockquote',\n\n link: 'u-rte-link',\n image: 'u-rte-image'\n}\n\nconst DEFAULT_TOOLBAR: ToolbarItem[] = [\n 'undo',\n 'redo',\n '|',\n 'heading',\n '|',\n 'bold',\n 'italic',\n 'underline',\n 'strikethrough',\n '|',\n 'bullet-list',\n 'ordered-list',\n '|',\n 'blockquote',\n '|',\n 'link'\n]\n</script>\n\n<script lang=\"ts\" setup>\nimport { registerHistory, createEmptyHistoryState } from '@lexical/history'\nimport { $generateHtmlFromNodes, $generateNodesFromDOM } from '@lexical/html'\nimport { LinkNode, AutoLinkNode } from '@lexical/link'\nimport { ListNode, ListItemNode, registerList } from '@lexical/list'\nimport { registerRichText } from '@lexical/rich-text'\nimport { HeadingNode, QuoteNode } from '@lexical/rich-text'\nimport { useFormComponent, useFormFallbackProps } from '@veltra/compositions'\nimport { bem } from '@veltra/utils'\nimport { createEditor, $getRoot, $createParagraphNode, type LexicalEditor } from 'lexical'\nimport { computed, onBeforeUnmount, onMounted, ref, shallowRef, useTemplateRef, watch } from 'vue'\n\nimport type { RichTextEditorProps } from '../../types'\nimport Toolbar from './toolbar.vue'\n\nconst props = withDefaults(defineProps<RichTextEditorProps>(), {\n disabled: undefined,\n readonly: undefined,\n format: 'html',\n toolbar: () => DEFAULT_TOOLBAR,\n placeholder: ''\n})\n\nconst model = defineModel<string>()\n\nconst cls = bem('rich-text-editor')\n\nconst { formProps } = useFormComponent()\n\nconst { size, disabled, readonly } = useFormFallbackProps([formProps ?? {}, props])\n\nconst isDisabled = computed(() => !!disabled.value)\nconst isReadonly = computed(() => !!readonly.value)\n\nconst className = computed<string[]>(() => {\n return [\n cls.b,\n cls.m(size.value),\n bem.is('disabled', isDisabled.value),\n bem.is('readonly', isReadonly.value)\n ]\n})\n\nconst toolbarItems = computed<ToolbarItem[]>(() => {\n return props.toolbar ?? DEFAULT_TOOLBAR\n})\n\nconst editorContainer = useTemplateRef('editorContainer')\nconst editor = shallowRef<LexicalEditor | null>(null)\nconst showPlaceholder = ref(true)\nlet isComposing = false\nlet cleanupFns: (() => void)[] = []\n\nfunction initEditor() {\n if (!editorContainer.value) return\n\n const editorInstance = createEditor({\n namespace: 'URichTextEditor',\n theme: LEXICAL_THEME,\n nodes: [HeadingNode, QuoteNode, ListNode, ListItemNode, LinkNode, AutoLinkNode],\n editable: !isDisabled.value && !isReadonly.value,\n onError: (error: Error) => {\n console.error('Lexical error:', error)\n }\n })\n\n editorInstance.setRootElement(editorContainer.value)\n\n // Register plugins\n cleanupFns.push(registerRichText(editorInstance))\n cleanupFns.push(registerList(editorInstance))\n cleanupFns.push(registerHistory(editorInstance, createEmptyHistoryState(), 300))\n\n // Set initial value\n if (model.value) {\n setEditorContent(editorInstance, model.value)\n }\n\n // Listen for content changes\n cleanupFns.push(\n editorInstance.registerUpdateListener(({ editorState }) => {\n editorState.read(() => {\n const root = $getRoot()\n const textContent = root.getTextContent()\n showPlaceholder.value = textContent.trim().length === 0\n\n if (isComposing) return\n\n let value: string\n if (props.format === 'json') {\n value = JSON.stringify(editorState.toJSON())\n } else {\n value = $generateHtmlFromNodes(editorInstance)\n }\n\n // Avoid circular updates: only emit if content really changed\n if (value !== model.value) {\n isComposing = true\n model.value = value\n // Use microtask to reset after Vue processes the update\n queueMicrotask(() => {\n isComposing = false\n })\n }\n })\n })\n )\n\n // Composing event listeners for IME\n const rootElement = editorInstance.getRootElement()\n if (rootElement) {\n const onCompositionStart = () => {\n isComposing = true\n }\n const onCompositionEnd = () => {\n isComposing = false\n }\n rootElement.addEventListener('compositionstart', onCompositionStart)\n rootElement.addEventListener('compositionend', onCompositionEnd)\n cleanupFns.push(() => {\n rootElement.removeEventListener('compositionstart', onCompositionStart)\n rootElement.removeEventListener('compositionend', onCompositionEnd)\n })\n }\n\n editor.value = editorInstance\n}\n\nfunction setEditorContent(editorInstance: LexicalEditor, value: string) {\n editorInstance.update(() => {\n const root = $getRoot()\n root.clear()\n\n if (props.format === 'json') {\n try {\n const parsedState = editorInstance.parseEditorState(value)\n editorInstance.setEditorState(parsedState)\n } catch {\n // If JSON parse fails, treat as empty\n root.append($createParagraphNode())\n }\n } else {\n // HTML format\n const parser = new DOMParser()\n const dom = parser.parseFromString(value, 'text/html')\n const nodes = $generateNodesFromDOM(editorInstance, dom)\n root.append(...nodes)\n }\n })\n}\n\n// Watch external model changes\nwatch(model, (newVal) => {\n if (!editor.value || isComposing) return\n\n const editorInstance = editor.value\n\n // Compare current content to avoid circular updates\n editorInstance.getEditorState().read(() => {\n let currentValue: string\n if (props.format === 'json') {\n currentValue = JSON.stringify(editorInstance.getEditorState().toJSON())\n } else {\n currentValue = $generateHtmlFromNodes(editorInstance)\n }\n\n if (currentValue !== newVal) {\n isComposing = true\n setEditorContent(editorInstance, newVal ?? '')\n queueMicrotask(() => {\n isComposing = false\n })\n }\n })\n})\n\n// Watch disabled/readonly changes\nwatch([isDisabled, isReadonly], () => {\n if (editor.value) {\n editor.value.setEditable(!isDisabled.value && !isReadonly.value)\n }\n})\n\nonMounted(() => {\n initEditor()\n})\n\nonBeforeUnmount(() => {\n cleanupFns.forEach((fn) => fn())\n cleanupFns = []\n editor.value = null\n})\n</script>\n"],"mappings":"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"}
|
|
@@ -13,8 +13,8 @@ declare const __VLS_export: _$vue.DefineComponent<RichTextEditorProps & {
|
|
|
13
13
|
"onUpdate:modelValue"?: ((value: string | undefined) => any) | undefined;
|
|
14
14
|
}>, {
|
|
15
15
|
disabled: boolean;
|
|
16
|
-
placeholder: string;
|
|
17
16
|
readonly: boolean;
|
|
17
|
+
placeholder: string;
|
|
18
18
|
format: RichTextFormat;
|
|
19
19
|
toolbar: ToolbarItem[];
|
|
20
20
|
}, {}, {}, {}, string, _$vue.ComponentProvideOptions, false, {}, any>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toolbar.js","names":[],"sources":["../../../src/components/rich-text-editor/toolbar.vue"],"sourcesContent":["<template>\n <div :class=\"cls.e('toolbar')\">\n <template v-for=\"(item, index) in toolbar\" :key=\"index\">\n <div v-if=\"item === '|'\" :class=\"cls.e('separator')\"></div>\n\n <div v-else-if=\"item === 'heading'\" :class=\"[cls.e('toolbar-dropdown')]\">\n <select\n :class=\"[cls.e('heading-select'), { 'is-disabled': disabled }]\"\n :value=\"activeHeading\"\n :disabled=\"disabled\"\n @change=\"onHeadingChange\"\n >\n <option value=\"paragraph\">正文</option>\n <option value=\"h1\">Heading 1</option>\n <option value=\"h2\">Heading 2</option>\n <option value=\"h3\">Heading 3</option>\n <option value=\"h4\">Heading 4</option>\n <option value=\"h5\">Heading 5</option>\n <option value=\"h6\">Heading 6</option>\n </select>\n </div>\n\n <button\n v-else\n type=\"button\"\n :class=\"[\n cls.e('toolbar-btn'),\n { 'is-active': isActive(item) },\n { 'is-disabled': disabled }\n ]\"\n :disabled=\"disabled\"\n :title=\"getTitle(item)\"\n @click=\"onToolbarAction(item)\"\n >\n <span :class=\"cls.e('toolbar-icon')\" v-html=\"getIcon(item)\"></span>\n </button>\n </template>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { $isLinkNode, TOGGLE_LINK_COMMAND } from '@lexical/link'\nimport { INSERT_ORDERED_LIST_COMMAND, INSERT_UNORDERED_LIST_COMMAND, ListNode } from '@lexical/list'\nimport { $createHeadingNode, $isHeadingNode, type HeadingTagType } from '@lexical/rich-text'\nimport { $isQuoteNode, $createQuoteNode } from '@lexical/rich-text'\nimport { $setBlocksType } from '@lexical/selection'\nimport { $getNearestNodeOfType } from '@lexical/utils'\nimport { bem } from '@veltra/utils'\nimport {\n $getSelection,\n $isRangeSelection,\n FORMAT_TEXT_COMMAND,\n UNDO_COMMAND,\n REDO_COMMAND,\n type LexicalEditor,\n $createParagraphNode,\n type RangeSelection\n} from 'lexical'\nimport { ref, onBeforeUnmount, watch } from 'vue'\n\nimport type { ToolbarItem } from '../../types'\n\nconst props = defineProps<{\n editor: LexicalEditor | null\n toolbar: ToolbarItem[]\n disabled: boolean\n}>()\n\nconst cls = bem('rich-text-editor')\n\n// Active states\nconst isBold = ref(false)\nconst isItalic = ref(false)\nconst isUnderline = ref(false)\nconst isStrikethrough = ref(false)\nconst isLink = ref(false)\nconst isBulletList = ref(false)\nconst isOrderedList = ref(false)\nconst isBlockquote = ref(false)\nconst activeHeading = ref('paragraph')\n\nlet cleanupListener: (() => void) | null = null\n\nfunction setupListener(editorInstance: LexicalEditor) {\n cleanupListener?.()\n cleanupListener = editorInstance.registerUpdateListener(({ editorState }) => {\n editorState.read(() => {\n const selection = $getSelection()\n if (!$isRangeSelection(selection)) return\n\n updateToolbarState(selection)\n })\n })\n}\n\nfunction updateToolbarState(selection: RangeSelection) {\n isBold.value = selection.hasFormat('bold')\n isItalic.value = selection.hasFormat('italic')\n isUnderline.value = selection.hasFormat('underline')\n isStrikethrough.value = selection.hasFormat('strikethrough')\n\n // Check block type\n const anchorNode = selection.anchor.getNode()\n let element = anchorNode.getKey() === 'root' ? anchorNode : anchorNode.getTopLevelElementOrThrow()\n\n if ($isHeadingNode(element)) {\n activeHeading.value = (element as any).getTag()\n } else {\n activeHeading.value = 'paragraph'\n }\n\n // Check list\n const parentList = $getNearestNodeOfType(anchorNode, ListNode)\n if (parentList) {\n const listType = (parentList as any).getListType()\n isBulletList.value = listType === 'bullet'\n isOrderedList.value = listType === 'number'\n } else {\n isBulletList.value = false\n isOrderedList.value = false\n }\n\n // Check blockquote\n isBlockquote.value = $isQuoteNode(element)\n\n // Check link\n const parent = anchorNode.getParent()\n isLink.value = $isLinkNode(parent)\n}\n\nwatch(\n () => props.editor,\n (editorInstance) => {\n if (editorInstance) {\n setupListener(editorInstance)\n }\n },\n { immediate: true }\n)\n\nfunction isActive(item: ToolbarItem): boolean {\n switch (item) {\n case 'bold':\n return isBold.value\n case 'italic':\n return isItalic.value\n case 'underline':\n return isUnderline.value\n case 'strikethrough':\n return isStrikethrough.value\n case 'bullet-list':\n return isBulletList.value\n case 'ordered-list':\n return isOrderedList.value\n case 'blockquote':\n return isBlockquote.value\n case 'link':\n return isLink.value\n default:\n return false\n }\n}\n\nfunction onToolbarAction(item: ToolbarItem) {\n const editorInstance = props.editor\n if (!editorInstance || props.disabled) return\n\n switch (item) {\n case 'bold':\n editorInstance.dispatchCommand(FORMAT_TEXT_COMMAND, 'bold')\n break\n case 'italic':\n editorInstance.dispatchCommand(FORMAT_TEXT_COMMAND, 'italic')\n break\n case 'underline':\n editorInstance.dispatchCommand(FORMAT_TEXT_COMMAND, 'underline')\n break\n case 'strikethrough':\n editorInstance.dispatchCommand(FORMAT_TEXT_COMMAND, 'strikethrough')\n break\n case 'code':\n editorInstance.dispatchCommand(FORMAT_TEXT_COMMAND, 'code')\n break\n case 'bullet-list':\n editorInstance.dispatchCommand(INSERT_UNORDERED_LIST_COMMAND, undefined)\n break\n case 'ordered-list':\n editorInstance.dispatchCommand(INSERT_ORDERED_LIST_COMMAND, undefined)\n break\n case 'blockquote':\n editorInstance.update(() => {\n const selection = $getSelection()\n if ($isRangeSelection(selection)) {\n if (isBlockquote.value) {\n $setBlocksType(selection, () => $createParagraphNode())\n } else {\n $setBlocksType(selection, () => $createQuoteNode())\n }\n }\n })\n break\n case 'link':\n toggleLink(editorInstance)\n break\n case 'undo':\n editorInstance.dispatchCommand(UNDO_COMMAND, undefined)\n break\n case 'redo':\n editorInstance.dispatchCommand(REDO_COMMAND, undefined)\n break\n }\n\n // Keep focus on editor\n editorInstance.focus()\n}\n\nfunction onHeadingChange(event: Event) {\n const editorInstance = props.editor\n if (!editorInstance || props.disabled) return\n\n const value = (event.target as HTMLSelectElement).value\n\n editorInstance.update(() => {\n const selection = $getSelection()\n if ($isRangeSelection(selection)) {\n if (value === 'paragraph') {\n $setBlocksType(selection, () => $createParagraphNode())\n } else {\n $setBlocksType(selection, () => $createHeadingNode(value as HeadingTagType))\n }\n }\n })\n\n editorInstance.focus()\n}\n\nfunction toggleLink(editorInstance: LexicalEditor) {\n editorInstance.getEditorState().read(() => {\n const selection = $getSelection()\n if (!$isRangeSelection(selection)) return\n\n const anchorNode = selection.anchor.getNode()\n const parent = anchorNode.getParent()\n\n if ($isLinkNode(parent)) {\n // Remove link\n editorInstance.dispatchCommand(TOGGLE_LINK_COMMAND, null)\n } else {\n // Insert link with prompt\n const url = prompt('请输入链接地址:', 'https://')\n if (url && url !== 'https://') {\n editorInstance.dispatchCommand(TOGGLE_LINK_COMMAND, url)\n }\n }\n })\n}\n\nfunction getTitle(item: ToolbarItem): string {\n const titles: Record<string, string> = {\n bold: '加粗',\n italic: '斜体',\n underline: '下划线',\n strikethrough: '删除线',\n code: '行内代码',\n 'bullet-list': '无序列表',\n 'ordered-list': '有序列表',\n blockquote: '引用',\n 'code-block': '代码块',\n link: '链接',\n undo: '撤销',\n redo: '重做'\n }\n return titles[item] ?? item\n}\n\nfunction getIcon(item: ToolbarItem): string {\n const icons: Record<string, string> = {\n bold: '<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M6 4h8a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z\"/><path d=\"M6 12h9a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z\"/></svg>',\n italic:\n '<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"19\" y1=\"4\" x2=\"10\" y2=\"4\"/><line x1=\"14\" y1=\"20\" x2=\"5\" y2=\"20\"/><line x1=\"15\" y1=\"4\" x2=\"9\" y2=\"20\"/></svg>',\n underline:\n '<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M6 3v7a6 6 0 0 0 6 6 6 6 0 0 0 6-6V3\"/><line x1=\"4\" y1=\"21\" x2=\"20\" y2=\"21\"/></svg>',\n strikethrough:\n '<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M16 4H9a3 3 0 0 0-2.83 4\"/><path d=\"M14 12a4 4 0 0 1 0 8H6\"/><line x1=\"4\" y1=\"12\" x2=\"20\" y2=\"12\"/></svg>',\n code: '<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"16 18 22 12 16 6\"/><polyline points=\"8 6 2 12 8 18\"/></svg>',\n 'bullet-list':\n '<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"8\" y1=\"6\" x2=\"21\" y2=\"6\"/><line x1=\"8\" y1=\"12\" x2=\"21\" y2=\"12\"/><line x1=\"8\" y1=\"18\" x2=\"21\" y2=\"18\"/><line x1=\"3\" y1=\"6\" x2=\"3.01\" y2=\"6\"/><line x1=\"3\" y1=\"12\" x2=\"3.01\" y2=\"12\"/><line x1=\"3\" y1=\"18\" x2=\"3.01\" y2=\"18\"/></svg>',\n 'ordered-list':\n '<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"10\" y1=\"6\" x2=\"21\" y2=\"6\"/><line x1=\"10\" y1=\"12\" x2=\"21\" y2=\"12\"/><line x1=\"10\" y1=\"18\" x2=\"21\" y2=\"18\"/><path d=\"M4 6h1v4\"/><path d=\"M4 10h2\"/><path d=\"M6 18H4c0-1 2-2 2-3s-1-1.5-2-1\"/></svg>',\n blockquote:\n '<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M3 21c3 0 7-1 7-8V5c0-1.25-.756-2.017-2-2H4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2 1 0 1 0 1 1v1c0 1-1 2-2 2s-1 .008-1 1.031V21z\"/><path d=\"M15 21c3 0 7-1 7-8V5c0-1.25-.757-2.017-2-2h-4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2h.75c0 2.25.25 4-2.75 4v3z\"/></svg>',\n 'code-block':\n '<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"2\" y=\"3\" width=\"20\" height=\"18\" rx=\"2\"/><path d=\"m8 10-3 2 3 2\"/><path d=\"m16 10 3 2-3 2\"/><path d=\"m13 7-2 10\"/></svg>',\n link: '<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71\"/><path d=\"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71\"/></svg>',\n undo: '<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M3 7v6h6\"/><path d=\"M21 17a9 9 0 0 0-9-9 9 9 0 0 0-6 2.3L3 13\"/></svg>',\n redo: '<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M21 7v6h-6\"/><path d=\"M3 17a9 9 0 0 1 9-9 9 9 0 0 1 6 2.3L21 13\"/></svg>'\n }\n return icons[item] ?? ''\n}\n\nonBeforeUnmount(() => {\n cleanupListener?.()\n cleanupListener = null\n})\n</script>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"toolbar.js","names":[],"sources":["../../../src/components/rich-text-editor/toolbar.vue"],"sourcesContent":["<template>\n <div :class=\"cls.e('toolbar')\">\n <template v-for=\"(item, index) in toolbar\" :key=\"index\">\n <div v-if=\"item === '|'\" :class=\"cls.e('separator')\"></div>\n\n <div v-else-if=\"item === 'heading'\" :class=\"[cls.e('toolbar-dropdown')]\">\n <select\n :class=\"[cls.e('heading-select'), { 'is-disabled': disabled }]\"\n :value=\"activeHeading\"\n :disabled=\"disabled\"\n @change=\"onHeadingChange\"\n >\n <option value=\"paragraph\">正文</option>\n <option value=\"h1\">Heading 1</option>\n <option value=\"h2\">Heading 2</option>\n <option value=\"h3\">Heading 3</option>\n <option value=\"h4\">Heading 4</option>\n <option value=\"h5\">Heading 5</option>\n <option value=\"h6\">Heading 6</option>\n </select>\n </div>\n\n <button\n v-else\n type=\"button\"\n :class=\"[\n cls.e('toolbar-btn'),\n { 'is-active': isActive(item) },\n { 'is-disabled': disabled }\n ]\"\n :disabled=\"disabled\"\n :title=\"getTitle(item)\"\n @click=\"onToolbarAction(item)\"\n >\n <span :class=\"cls.e('toolbar-icon')\" v-html=\"getIcon(item)\"></span>\n </button>\n </template>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { $isLinkNode, TOGGLE_LINK_COMMAND } from '@lexical/link'\nimport { INSERT_ORDERED_LIST_COMMAND, INSERT_UNORDERED_LIST_COMMAND, ListNode } from '@lexical/list'\nimport { $createHeadingNode, $isHeadingNode, type HeadingTagType } from '@lexical/rich-text'\nimport { $isQuoteNode, $createQuoteNode } from '@lexical/rich-text'\nimport { $setBlocksType } from '@lexical/selection'\nimport { $getNearestNodeOfType } from '@lexical/utils'\nimport { bem } from '@veltra/utils'\nimport {\n $getSelection,\n $isRangeSelection,\n FORMAT_TEXT_COMMAND,\n UNDO_COMMAND,\n REDO_COMMAND,\n type LexicalEditor,\n $createParagraphNode,\n type RangeSelection\n} from 'lexical'\nimport { ref, onBeforeUnmount, watch } from 'vue'\n\nimport type { ToolbarItem } from '../../types'\n\nconst props = defineProps<{\n editor: LexicalEditor | null\n toolbar: ToolbarItem[]\n disabled: boolean\n}>()\n\nconst cls = bem('rich-text-editor')\n\n// Active states\nconst isBold = ref(false)\nconst isItalic = ref(false)\nconst isUnderline = ref(false)\nconst isStrikethrough = ref(false)\nconst isLink = ref(false)\nconst isBulletList = ref(false)\nconst isOrderedList = ref(false)\nconst isBlockquote = ref(false)\nconst activeHeading = ref('paragraph')\n\nlet cleanupListener: (() => void) | null = null\n\nfunction setupListener(editorInstance: LexicalEditor) {\n cleanupListener?.()\n cleanupListener = editorInstance.registerUpdateListener(({ editorState }) => {\n editorState.read(() => {\n const selection = $getSelection()\n if (!$isRangeSelection(selection)) return\n\n updateToolbarState(selection)\n })\n })\n}\n\nfunction updateToolbarState(selection: RangeSelection) {\n isBold.value = selection.hasFormat('bold')\n isItalic.value = selection.hasFormat('italic')\n isUnderline.value = selection.hasFormat('underline')\n isStrikethrough.value = selection.hasFormat('strikethrough')\n\n // Check block type\n const anchorNode = selection.anchor.getNode()\n let element = anchorNode.getKey() === 'root' ? anchorNode : anchorNode.getTopLevelElementOrThrow()\n\n if ($isHeadingNode(element)) {\n activeHeading.value = (element as any).getTag()\n } else {\n activeHeading.value = 'paragraph'\n }\n\n // Check list\n const parentList = $getNearestNodeOfType(anchorNode, ListNode)\n if (parentList) {\n const listType = (parentList as any).getListType()\n isBulletList.value = listType === 'bullet'\n isOrderedList.value = listType === 'number'\n } else {\n isBulletList.value = false\n isOrderedList.value = false\n }\n\n // Check blockquote\n isBlockquote.value = $isQuoteNode(element)\n\n // Check link\n const parent = anchorNode.getParent()\n isLink.value = $isLinkNode(parent)\n}\n\nwatch(\n () => props.editor,\n (editorInstance) => {\n if (editorInstance) {\n setupListener(editorInstance)\n }\n },\n { immediate: true }\n)\n\nfunction isActive(item: ToolbarItem): boolean {\n switch (item) {\n case 'bold':\n return isBold.value\n case 'italic':\n return isItalic.value\n case 'underline':\n return isUnderline.value\n case 'strikethrough':\n return isStrikethrough.value\n case 'bullet-list':\n return isBulletList.value\n case 'ordered-list':\n return isOrderedList.value\n case 'blockquote':\n return isBlockquote.value\n case 'link':\n return isLink.value\n default:\n return false\n }\n}\n\nfunction onToolbarAction(item: ToolbarItem) {\n const editorInstance = props.editor\n if (!editorInstance || props.disabled) return\n\n switch (item) {\n case 'bold':\n editorInstance.dispatchCommand(FORMAT_TEXT_COMMAND, 'bold')\n break\n case 'italic':\n editorInstance.dispatchCommand(FORMAT_TEXT_COMMAND, 'italic')\n break\n case 'underline':\n editorInstance.dispatchCommand(FORMAT_TEXT_COMMAND, 'underline')\n break\n case 'strikethrough':\n editorInstance.dispatchCommand(FORMAT_TEXT_COMMAND, 'strikethrough')\n break\n case 'code':\n editorInstance.dispatchCommand(FORMAT_TEXT_COMMAND, 'code')\n break\n case 'bullet-list':\n editorInstance.dispatchCommand(INSERT_UNORDERED_LIST_COMMAND, undefined)\n break\n case 'ordered-list':\n editorInstance.dispatchCommand(INSERT_ORDERED_LIST_COMMAND, undefined)\n break\n case 'blockquote':\n editorInstance.update(() => {\n const selection = $getSelection()\n if ($isRangeSelection(selection)) {\n if (isBlockquote.value) {\n $setBlocksType(selection, () => $createParagraphNode())\n } else {\n $setBlocksType(selection, () => $createQuoteNode())\n }\n }\n })\n break\n case 'link':\n toggleLink(editorInstance)\n break\n case 'undo':\n editorInstance.dispatchCommand(UNDO_COMMAND, undefined)\n break\n case 'redo':\n editorInstance.dispatchCommand(REDO_COMMAND, undefined)\n break\n }\n\n // Keep focus on editor\n editorInstance.focus()\n}\n\nfunction onHeadingChange(event: Event) {\n const editorInstance = props.editor\n if (!editorInstance || props.disabled) return\n\n const value = (event.target as HTMLSelectElement).value\n\n editorInstance.update(() => {\n const selection = $getSelection()\n if ($isRangeSelection(selection)) {\n if (value === 'paragraph') {\n $setBlocksType(selection, () => $createParagraphNode())\n } else {\n $setBlocksType(selection, () => $createHeadingNode(value as HeadingTagType))\n }\n }\n })\n\n editorInstance.focus()\n}\n\nfunction toggleLink(editorInstance: LexicalEditor) {\n editorInstance.getEditorState().read(() => {\n const selection = $getSelection()\n if (!$isRangeSelection(selection)) return\n\n const anchorNode = selection.anchor.getNode()\n const parent = anchorNode.getParent()\n\n if ($isLinkNode(parent)) {\n // Remove link\n editorInstance.dispatchCommand(TOGGLE_LINK_COMMAND, null)\n } else {\n // Insert link with prompt\n const url = prompt('请输入链接地址:', 'https://')\n if (url && url !== 'https://') {\n editorInstance.dispatchCommand(TOGGLE_LINK_COMMAND, url)\n }\n }\n })\n}\n\nfunction getTitle(item: ToolbarItem): string {\n const titles: Record<string, string> = {\n bold: '加粗',\n italic: '斜体',\n underline: '下划线',\n strikethrough: '删除线',\n code: '行内代码',\n 'bullet-list': '无序列表',\n 'ordered-list': '有序列表',\n blockquote: '引用',\n 'code-block': '代码块',\n link: '链接',\n undo: '撤销',\n redo: '重做'\n }\n return titles[item] ?? item\n}\n\nfunction getIcon(item: ToolbarItem): string {\n const icons: Record<string, string> = {\n bold: '<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M6 4h8a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z\"/><path d=\"M6 12h9a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z\"/></svg>',\n italic:\n '<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"19\" y1=\"4\" x2=\"10\" y2=\"4\"/><line x1=\"14\" y1=\"20\" x2=\"5\" y2=\"20\"/><line x1=\"15\" y1=\"4\" x2=\"9\" y2=\"20\"/></svg>',\n underline:\n '<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M6 3v7a6 6 0 0 0 6 6 6 6 0 0 0 6-6V3\"/><line x1=\"4\" y1=\"21\" x2=\"20\" y2=\"21\"/></svg>',\n strikethrough:\n '<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M16 4H9a3 3 0 0 0-2.83 4\"/><path d=\"M14 12a4 4 0 0 1 0 8H6\"/><line x1=\"4\" y1=\"12\" x2=\"20\" y2=\"12\"/></svg>',\n code: '<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"16 18 22 12 16 6\"/><polyline points=\"8 6 2 12 8 18\"/></svg>',\n 'bullet-list':\n '<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"8\" y1=\"6\" x2=\"21\" y2=\"6\"/><line x1=\"8\" y1=\"12\" x2=\"21\" y2=\"12\"/><line x1=\"8\" y1=\"18\" x2=\"21\" y2=\"18\"/><line x1=\"3\" y1=\"6\" x2=\"3.01\" y2=\"6\"/><line x1=\"3\" y1=\"12\" x2=\"3.01\" y2=\"12\"/><line x1=\"3\" y1=\"18\" x2=\"3.01\" y2=\"18\"/></svg>',\n 'ordered-list':\n '<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"10\" y1=\"6\" x2=\"21\" y2=\"6\"/><line x1=\"10\" y1=\"12\" x2=\"21\" y2=\"12\"/><line x1=\"10\" y1=\"18\" x2=\"21\" y2=\"18\"/><path d=\"M4 6h1v4\"/><path d=\"M4 10h2\"/><path d=\"M6 18H4c0-1 2-2 2-3s-1-1.5-2-1\"/></svg>',\n blockquote:\n '<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M3 21c3 0 7-1 7-8V5c0-1.25-.756-2.017-2-2H4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2 1 0 1 0 1 1v1c0 1-1 2-2 2s-1 .008-1 1.031V21z\"/><path d=\"M15 21c3 0 7-1 7-8V5c0-1.25-.757-2.017-2-2h-4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2h.75c0 2.25.25 4-2.75 4v3z\"/></svg>',\n 'code-block':\n '<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"2\" y=\"3\" width=\"20\" height=\"18\" rx=\"2\"/><path d=\"m8 10-3 2 3 2\"/><path d=\"m16 10 3 2-3 2\"/><path d=\"m13 7-2 10\"/></svg>',\n link: '<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71\"/><path d=\"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71\"/></svg>',\n undo: '<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M3 7v6h6\"/><path d=\"M21 17a9 9 0 0 0-9-9 9 9 0 0 0-6 2.3L3 13\"/></svg>',\n redo: '<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M21 7v6h-6\"/><path d=\"M3 17a9 9 0 0 1 9-9 9 9 0 0 1 6 2.3L21 13\"/></svg>'\n }\n return icons[item] ?? ''\n}\n\nonBeforeUnmount(() => {\n cleanupListener?.()\n cleanupListener = null\n})\n</script>\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scroll.js","names":[],"sources":["../../../src/components/scroll/scroll.vue"],"sourcesContent":["<template>\n <div :class=\"className\" :style=\"style\" ref=\"scrollRef\">\n <div\n ref=\"containerRef\"\n :class=\"[cls.e('container'), containerClass]\"\n @scroll.passive=\"handleScroll\"\n :style=\"containerStyle\"\n >\n <component\n ref=\"contentRef\"\n :style=\"contentStyle\"\n :class=\"[cls.e('content'), contentClass]\"\n :is=\"tag\"\n >\n <slot />\n </component>\n </div>\n\n <u-scroll-bar type=\"y\" :class=\"cls.e('bar-y')\" @drag=\"handleDragY\" ref=\"barY\" />\n <u-scroll-bar type=\"x\" :class=\"cls.e('bar-x')\" @drag=\"handleDragX\" ref=\"barX\" />\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { debounce } from '@cat-kit/core'\nimport { useResizeObserver } from '@veltra/compositions'\nimport { bem, withUnit } from '@veltra/utils'\nimport { type CSSProperties, computed, provide, shallowRef } from 'vue'\n\nimport type { ScrollPosition, _ScrollExposed, ScrollProps, ScrollEmits } from '../../types'\nimport { ScrollDIKey } from './di'\nimport UScrollBar from './scroll-bar.vue'\n\ndefineOptions({\n name: 'Scroll'\n})\n\nconst props = withDefaults(defineProps<ScrollProps>(), {\n tag: 'div'\n})\n\nconst emit = defineEmits<ScrollEmits>()\n\ndefineSlots<{\n /** 默认插槽 */\n default(): any\n /** 内容插槽 */\n content(): any\n}>()\n\nconst cls = bem('scroll')\nconst className = computed(() => {\n return [cls.b, bem.is('always', props.always)]\n})\n\n// 样式-------------------------------------------------------------\nconst style = computed<CSSProperties>(() => {\n return {\n height: withUnit(props.height, 'px')\n }\n})\n\n// 模板引用------------------------------------------------\n/** 内容引用 */\nconst contentRef = shallowRef<HTMLElement>()\n/** 滚动根元素引用 */\nconst scrollRef = shallowRef<HTMLElement>()\n/** 容器引用 */\nconst containerRef = shallowRef<HTMLElement>()\nconst barX = shallowRef<InstanceType<typeof UScrollBar>>()\nconst barY = shallowRef<InstanceType<typeof UScrollBar>>()\nconst minSize = 20\n\nconst trackSize = {\n width: 0,\n height: 0\n}\n\nuseResizeObserver({\n targets: [contentRef, scrollRef],\n onResize: (entries) => {\n if (entries.length && scrollRef.value) {\n const { clientHeight, clientWidth } = scrollRef.value\n\n trackSize.width = clientWidth\n trackSize.height = clientHeight\n\n barX.value?.setTrackSize(trackSize.width)\n barY.value?.setTrackSize(trackSize.height)\n updateBar()\n\n emit(\n 'resize',\n entries.map((entry) => entry.target as HTMLElement)\n )\n }\n }\n})\n\n// 更新滚动条\nconst updateBar = () => {\n if (!containerRef.value) return\n\n const {\n scrollHeight,\n clientHeight,\n scrollTop,\n\n scrollWidth,\n clientWidth,\n scrollLeft\n } = containerRef.value\n\n emit('scroll', {\n x: scrollLeft,\n y: scrollTop,\n sw: scrollWidth,\n sh: scrollHeight,\n cw: clientWidth,\n ch: clientHeight\n })\n\n if (scrollHeight !== clientHeight) {\n const barYHeight = Math.max((clientHeight / scrollHeight) * trackSize.height, minSize)\n\n const barYTop = (scrollTop / (scrollHeight - clientHeight)) * (trackSize.height - barYHeight)\n\n barY.value?.update(barYHeight, barYTop)\n } else {\n barY.value?.update(0, 0)\n }\n\n if (scrollWidth !== clientWidth) {\n const barXWidth = Math.max((clientWidth / scrollWidth) * trackSize.width, minSize)\n\n const barXLeft = (scrollLeft / (scrollWidth - clientWidth)) * (trackSize.width - barXWidth)\n\n barX.value?.update(barXWidth, barXLeft)\n } else {\n barX.value?.update(0, 0)\n }\n}\n\n// 滚动条拖拽\nconst handleDragX = debounce(\n (offset: number, size: number) => {\n const container = containerRef.value!\n const { clientWidth, scrollWidth } = container\n\n container.scrollLeft = (offset / (trackSize.width - size)) * (scrollWidth - clientWidth)\n },\n props.dragDebounce ?? 0,\n false\n)\n\nconst handleDragY = debounce(\n (offset: number, size: number) => {\n const container = containerRef.value!\n const { clientHeight, scrollHeight } = container\n container.scrollTop = (offset / (trackSize.height - size)) * (scrollHeight - clientHeight)\n },\n props.dragDebounce ?? 0,\n false\n)\n\n// 滚动事件\nconst handleScroll = (e) => {\n updateBar()\n}\n\n// 滚动至------------------------------------------------\nconst scrollToLeft = (left: number) => {\n const container = containerRef.value\n if (!container) return\n\n container.scrollTo({\n left\n })\n}\n\nconst scrollToTop = (top: number) => {\n const container = containerRef.value\n if (!container) return\n\n container.scrollTo({\n top\n })\n}\n\nconst scrollTo = (position: ScrollPosition) => {\n if (position.x !== undefined) scrollToLeft(position.x)\n if (position.y !== undefined) scrollToTop(position.y)\n}\n\nprovide(ScrollDIKey, {\n cls\n})\n\nconst exposed: _ScrollExposed = {\n el: scrollRef,\n contentRef,\n containerRef,\n scrollTo,\n update: updateBar\n}\n\ndefineExpose(exposed)\n</script>\n"],"mappings":";;;;;;;AAuEA,MAAM,UAAU;;;;;;;;;;;;;;;;EAlChB,MAAM,QAAQ;EAId,MAAM,OAAO;EASb,MAAM,MAAM,IAAI,SAAQ;EACxB,MAAM,YAAY,eAAe;AAC/B,UAAO,CAAC,IAAI,GAAG,IAAI,GAAG,UAAU,MAAM,OAAO,CAAA;IAC9C;EAGD,MAAM,QAAQ,eAA8B;AAC1C,UAAO,EACL,QAAQ,SAAS,MAAM,QAAQ,KAAI,EACrC;IACD;;EAID,MAAM,aAAa,YAAwB;;EAE3C,MAAM,YAAY,YAAwB;;EAE1C,MAAM,eAAe,YAAwB;EAC7C,MAAM,OAAO,YAA4C;EACzD,MAAM,OAAO,YAA4C;EAGzD,MAAM,YAAY;GAChB,OAAO;GACP,QAAQ;GACV;AAEA,oBAAkB;GAChB,SAAS,CAAC,YAAY,UAAU;GAChC,WAAW,YAAY;AACrB,QAAI,QAAQ,UAAU,UAAU,OAAO;KACrC,MAAM,EAAE,cAAc,gBAAgB,UAAU;AAEhD,eAAU,QAAQ;AAClB,eAAU,SAAS;AAEnB,UAAK,OAAO,aAAa,UAAU,MAAK;AACxC,UAAK,OAAO,aAAa,UAAU,OAAM;AACzC,gBAAU;AAEV,UACE,UACA,QAAQ,KAAK,UAAU,MAAM,OAAqB,CACpD;;;GAGL,CAAA;EAGD,MAAM,kBAAkB;AACtB,OAAI,CAAC,aAAa,MAAO;GAEzB,MAAM,EACJ,cACA,cACA,WAEA,aACA,aACA,eACE,aAAa;AAEjB,QAAK,UAAU;IACb,GAAG;IACH,GAAG;IACH,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACL,CAAA;AAED,OAAI,iBAAiB,cAAc;IACjC,MAAM,aAAa,KAAK,IAAK,eAAe,eAAgB,UAAU,QAAQ,QAAO;IAErF,MAAM,UAAW,aAAa,eAAe,iBAAkB,UAAU,SAAS;AAElF,SAAK,OAAO,OAAO,YAAY,QAAO;SAEtC,MAAK,OAAO,OAAO,GAAG,EAAC;AAGzB,OAAI,gBAAgB,aAAa;IAC/B,MAAM,YAAY,KAAK,IAAK,cAAc,cAAe,UAAU,OAAO,QAAO;IAEjF,MAAM,WAAY,cAAc,cAAc,gBAAiB,UAAU,QAAQ;AAEjF,SAAK,OAAO,OAAO,WAAW,SAAQ;SAEtC,MAAK,OAAO,OAAO,GAAG,EAAC;;EAK3B,MAAM,cAAc,UACjB,QAAgB,SAAiB;GAChC,MAAM,YAAY,aAAa;GAC/B,MAAM,EAAE,aAAa,gBAAgB;AAErC,aAAU,aAAc,UAAU,UAAU,QAAQ,SAAU,cAAc;KAE9E,MAAM,gBAAgB,GACtB,MACF;EAEA,MAAM,cAAc,UACjB,QAAgB,SAAiB;GAChC,MAAM,YAAY,aAAa;GAC/B,MAAM,EAAE,cAAc,iBAAiB;AACvC,aAAU,YAAa,UAAU,UAAU,SAAS,SAAU,eAAe;KAE/E,MAAM,gBAAgB,GACtB,MACF;EAGA,MAAM,gBAAgB,MAAM;AAC1B,cAAU;;EAIZ,MAAM,gBAAgB,SAAiB;GACrC,MAAM,YAAY,aAAa;AAC/B,OAAI,CAAC,UAAW;AAEhB,aAAU,SAAS,EACjB,MACD,CAAA;;EAGH,MAAM,eAAe,QAAgB;GACnC,MAAM,YAAY,aAAa;AAC/B,OAAI,CAAC,UAAW;AAEhB,aAAU,SAAS,EACjB,KACD,CAAA;;EAGH,MAAM,YAAY,aAA6B;AAC7C,OAAI,SAAS,MAAM,KAAA,EAAW,cAAa,SAAS,EAAC;AACrD,OAAI,SAAS,MAAM,KAAA,EAAW,aAAY,SAAS,EAAC;;AAGtD,UAAQ,aAAa,EACnB,KACD,CAAA;AAUD,
|
|
1
|
+
{"version":3,"file":"scroll.js","names":[],"sources":["../../../src/components/scroll/scroll.vue"],"sourcesContent":["<template>\n <div :class=\"className\" :style=\"style\" ref=\"scrollRef\">\n <div\n ref=\"containerRef\"\n :class=\"[cls.e('container'), containerClass]\"\n @scroll.passive=\"handleScroll\"\n :style=\"containerStyle\"\n >\n <component\n ref=\"contentRef\"\n :style=\"contentStyle\"\n :class=\"[cls.e('content'), contentClass]\"\n :is=\"tag\"\n >\n <slot />\n </component>\n </div>\n\n <u-scroll-bar type=\"y\" :class=\"cls.e('bar-y')\" @drag=\"handleDragY\" ref=\"barY\" />\n <u-scroll-bar type=\"x\" :class=\"cls.e('bar-x')\" @drag=\"handleDragX\" ref=\"barX\" />\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { debounce } from '@cat-kit/core'\nimport { useResizeObserver } from '@veltra/compositions'\nimport { bem, withUnit } from '@veltra/utils'\nimport { type CSSProperties, computed, provide, shallowRef } from 'vue'\n\nimport type { ScrollPosition, _ScrollExposed, ScrollProps, ScrollEmits } from '../../types'\nimport { ScrollDIKey } from './di'\nimport UScrollBar from './scroll-bar.vue'\n\ndefineOptions({\n name: 'Scroll'\n})\n\nconst props = withDefaults(defineProps<ScrollProps>(), {\n tag: 'div'\n})\n\nconst emit = defineEmits<ScrollEmits>()\n\ndefineSlots<{\n /** 默认插槽 */\n default(): any\n /** 内容插槽 */\n content(): any\n}>()\n\nconst cls = bem('scroll')\nconst className = computed(() => {\n return [cls.b, bem.is('always', props.always)]\n})\n\n// 样式-------------------------------------------------------------\nconst style = computed<CSSProperties>(() => {\n return {\n height: withUnit(props.height, 'px')\n }\n})\n\n// 模板引用------------------------------------------------\n/** 内容引用 */\nconst contentRef = shallowRef<HTMLElement>()\n/** 滚动根元素引用 */\nconst scrollRef = shallowRef<HTMLElement>()\n/** 容器引用 */\nconst containerRef = shallowRef<HTMLElement>()\nconst barX = shallowRef<InstanceType<typeof UScrollBar>>()\nconst barY = shallowRef<InstanceType<typeof UScrollBar>>()\nconst minSize = 20\n\nconst trackSize = {\n width: 0,\n height: 0\n}\n\nuseResizeObserver({\n targets: [contentRef, scrollRef],\n onResize: (entries) => {\n if (entries.length && scrollRef.value) {\n const { clientHeight, clientWidth } = scrollRef.value\n\n trackSize.width = clientWidth\n trackSize.height = clientHeight\n\n barX.value?.setTrackSize(trackSize.width)\n barY.value?.setTrackSize(trackSize.height)\n updateBar()\n\n emit(\n 'resize',\n entries.map((entry) => entry.target as HTMLElement)\n )\n }\n }\n})\n\n// 更新滚动条\nconst updateBar = () => {\n if (!containerRef.value) return\n\n const {\n scrollHeight,\n clientHeight,\n scrollTop,\n\n scrollWidth,\n clientWidth,\n scrollLeft\n } = containerRef.value\n\n emit('scroll', {\n x: scrollLeft,\n y: scrollTop,\n sw: scrollWidth,\n sh: scrollHeight,\n cw: clientWidth,\n ch: clientHeight\n })\n\n if (scrollHeight !== clientHeight) {\n const barYHeight = Math.max((clientHeight / scrollHeight) * trackSize.height, minSize)\n\n const barYTop = (scrollTop / (scrollHeight - clientHeight)) * (trackSize.height - barYHeight)\n\n barY.value?.update(barYHeight, barYTop)\n } else {\n barY.value?.update(0, 0)\n }\n\n if (scrollWidth !== clientWidth) {\n const barXWidth = Math.max((clientWidth / scrollWidth) * trackSize.width, minSize)\n\n const barXLeft = (scrollLeft / (scrollWidth - clientWidth)) * (trackSize.width - barXWidth)\n\n barX.value?.update(barXWidth, barXLeft)\n } else {\n barX.value?.update(0, 0)\n }\n}\n\n// 滚动条拖拽\nconst handleDragX = debounce(\n (offset: number, size: number) => {\n const container = containerRef.value!\n const { clientWidth, scrollWidth } = container\n\n container.scrollLeft = (offset / (trackSize.width - size)) * (scrollWidth - clientWidth)\n },\n props.dragDebounce ?? 0,\n false\n)\n\nconst handleDragY = debounce(\n (offset: number, size: number) => {\n const container = containerRef.value!\n const { clientHeight, scrollHeight } = container\n container.scrollTop = (offset / (trackSize.height - size)) * (scrollHeight - clientHeight)\n },\n props.dragDebounce ?? 0,\n false\n)\n\n// 滚动事件\nconst handleScroll = (e) => {\n updateBar()\n}\n\n// 滚动至------------------------------------------------\nconst scrollToLeft = (left: number) => {\n const container = containerRef.value\n if (!container) return\n\n container.scrollTo({\n left\n })\n}\n\nconst scrollToTop = (top: number) => {\n const container = containerRef.value\n if (!container) return\n\n container.scrollTo({\n top\n })\n}\n\nconst scrollTo = (position: ScrollPosition) => {\n if (position.x !== undefined) scrollToLeft(position.x)\n if (position.y !== undefined) scrollToTop(position.y)\n}\n\nprovide(ScrollDIKey, {\n cls\n})\n\nconst exposed: _ScrollExposed = {\n el: scrollRef,\n contentRef,\n containerRef,\n scrollTo,\n update: updateBar\n}\n\ndefineExpose(exposed)\n</script>\n"],"mappings":"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"}
|