@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
|
@@ -9,9 +9,9 @@ declare const __VLS_export: _$vue.DefineComponent<DatePickerProps, {}, {}, {}, {
|
|
|
9
9
|
}>, {
|
|
10
10
|
type: "date" | "month" | "year";
|
|
11
11
|
disabled: boolean;
|
|
12
|
+
readonly: boolean;
|
|
12
13
|
placeholder: string;
|
|
13
14
|
clearable: boolean;
|
|
14
|
-
readonly: boolean;
|
|
15
15
|
}, {}, {}, {}, string, _$vue.ComponentProvideOptions, false, {}, any>;
|
|
16
16
|
declare const _default: typeof __VLS_export;
|
|
17
17
|
//#endregion
|
|
@@ -4,7 +4,7 @@ import _sfc_main$3 from "../date-panel/date-panel.js";
|
|
|
4
4
|
import { Fragment, Transition, computed, createBlock, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, normalizeClass, openBlock, shallowRef, toDisplayString, unref, watch, withCtx, withModifiers } from "vue";
|
|
5
5
|
import { date } from "@cat-kit/core";
|
|
6
6
|
import { FORM_EMPTY_CONTENT, bem } from "@veltra/utils";
|
|
7
|
-
import { useFormComponent, useFormFallbackProps,
|
|
7
|
+
import { useFormComponent, useFormFallbackProps, useUserAction } from "@veltra/compositions";
|
|
8
8
|
import { Calendar, Close } from "@veltra/icons/normal";
|
|
9
9
|
//#region src/components/date-range-picker/date-range-picker.vue
|
|
10
10
|
const _hoisted_1 = ["value", "placeholder"];
|
|
@@ -56,7 +56,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
56
56
|
readonly: false
|
|
57
57
|
});
|
|
58
58
|
const dropdownRef = shallowRef();
|
|
59
|
-
const {
|
|
59
|
+
const { userAction, isUserActive } = useUserAction();
|
|
60
60
|
const currentRangeDate = shallowRef();
|
|
61
61
|
const displayedOfStart = computed(() => {
|
|
62
62
|
return props.modelValue?.[0];
|
|
@@ -73,15 +73,15 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
73
73
|
return "yyyy-MM-dd";
|
|
74
74
|
});
|
|
75
75
|
watch(() => props.modelValue, (val) => {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
});
|
|
76
|
+
if (isUserActive()) return;
|
|
77
|
+
if (val?.length === 2) currentRangeDate.value = [date(val[0]), date(val[1])];
|
|
79
78
|
}, { immediate: true });
|
|
79
|
+
const commitSelectedRange = userAction((rangeDate) => {
|
|
80
|
+
currentRangeDate.value = rangeDate;
|
|
81
|
+
emit("update:modelValue", rangeDate?.map((d) => d.format(formatStr.value)));
|
|
82
|
+
});
|
|
80
83
|
async function handleSelect(rangeDate) {
|
|
81
|
-
await
|
|
82
|
-
currentRangeDate.value = rangeDate;
|
|
83
|
-
emit("update:modelValue", rangeDate?.map((d) => d.format(formatStr.value)));
|
|
84
|
-
});
|
|
84
|
+
await commitSelectedRange(rangeDate);
|
|
85
85
|
dropdownRef.value?.close();
|
|
86
86
|
}
|
|
87
87
|
const hovered = shallowRef(false);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"date-range-picker.js","names":[],"sources":["../../../src/components/date-range-picker/date-range-picker.vue"],"sourcesContent":["<template>\n <u-dropdown\n :class=\"className\"\n trigger=\"click\"\n :content-class=\"[cls.e('panel'), cls.em('panel', size)]\"\n width=\"auto\"\n ref=\"dropdownRef\"\n :disabled=\"disabled\"\n @mouseenter.native=\"hovered = true\"\n @mouseleave.native=\"hovered = false\"\n v-if=\"!readonly\"\n >\n <template #trigger>\n <input\n type=\"text\"\n :class=\"cls.e('input')\"\n :value=\"displayedOfStart\"\n :placeholder=\"placeholder[0]\"\n readonly\n />\n <span :class=\"cls.e('separator')\">至</span>\n <input\n type=\"text\"\n :class=\"cls.e('input')\"\n :value=\"displayedOfEnd\"\n :placeholder=\"placeholder[1]\"\n readonly\n />\n\n <Transition name=\"zoom-in\" mode=\"out-in\">\n <UIcon\n v-if=\"clearable && modelValue && hovered && !disabled\"\n :class=\"[cls.e('icon'), cls.e('clear')]\"\n title=\"清除\"\n @click.stop=\"handleClear\"\n >\n <Close />\n </UIcon>\n\n <u-icon :class=\"cls.e('icon')\" v-else><Calendar /></u-icon>\n </Transition>\n </template>\n\n <template #content>\n <UDatePanel\n range\n :type\n :disabled-date\n :size\n :range-date=\"currentRangeDate\"\n @select:range-date=\"handleSelect\"\n />\n </template>\n </u-dropdown>\n\n <template v-else>\n {{ displayedOfStart || FORM_EMPTY_CONTENT }} 至\n {{ displayedOfEnd || FORM_EMPTY_CONTENT }}\n </template>\n</template>\n\n<script lang=\"ts\" setup>\nimport { date, type Dater } from '@cat-kit/core'\nimport { useFormComponent, useFormFallbackProps
|
|
1
|
+
{"version":3,"file":"date-range-picker.js","names":[],"sources":["../../../src/components/date-range-picker/date-range-picker.vue"],"sourcesContent":["<template>\n <u-dropdown\n :class=\"className\"\n trigger=\"click\"\n :content-class=\"[cls.e('panel'), cls.em('panel', size)]\"\n width=\"auto\"\n ref=\"dropdownRef\"\n :disabled=\"disabled\"\n @mouseenter.native=\"hovered = true\"\n @mouseleave.native=\"hovered = false\"\n v-if=\"!readonly\"\n >\n <template #trigger>\n <input\n type=\"text\"\n :class=\"cls.e('input')\"\n :value=\"displayedOfStart\"\n :placeholder=\"placeholder[0]\"\n readonly\n />\n <span :class=\"cls.e('separator')\">至</span>\n <input\n type=\"text\"\n :class=\"cls.e('input')\"\n :value=\"displayedOfEnd\"\n :placeholder=\"placeholder[1]\"\n readonly\n />\n\n <Transition name=\"zoom-in\" mode=\"out-in\">\n <UIcon\n v-if=\"clearable && modelValue && hovered && !disabled\"\n :class=\"[cls.e('icon'), cls.e('clear')]\"\n title=\"清除\"\n @click.stop=\"handleClear\"\n >\n <Close />\n </UIcon>\n\n <u-icon :class=\"cls.e('icon')\" v-else><Calendar /></u-icon>\n </Transition>\n </template>\n\n <template #content>\n <UDatePanel\n range\n :type\n :disabled-date\n :size\n :range-date=\"currentRangeDate\"\n @select:range-date=\"handleSelect\"\n />\n </template>\n </u-dropdown>\n\n <template v-else>\n {{ displayedOfStart || FORM_EMPTY_CONTENT }} 至\n {{ displayedOfEnd || FORM_EMPTY_CONTENT }}\n </template>\n</template>\n\n<script lang=\"ts\" setup>\nimport { date, type Dater } from '@cat-kit/core'\nimport { useFormComponent, useFormFallbackProps, useUserAction } from '@veltra/compositions'\nimport { Calendar, Close } from '@veltra/icons/normal'\nimport { bem, FORM_EMPTY_CONTENT } from '@veltra/utils'\nimport { computed, shallowRef, watch } from 'vue'\n\nimport type { DateRangePickerEmits, DateRangePickerProps, DropdownExposed } from '../../types'\nimport { UDatePanel } from '../date-panel'\nimport { UDropdown } from '../dropdown'\nimport { UIcon } from '../icon'\n\ndefineOptions({\n name: 'DateRangePicker'\n})\n\nconst props = withDefaults(defineProps<DateRangePickerProps>(), {\n placeholder: () => ['起始日期', '结束日期'],\n type: 'date',\n disabled: undefined,\n readonly: undefined,\n clearable: true\n})\n\nconst emit = defineEmits<DateRangePickerEmits>()\n\nconst cls = bem('date-range-picker')\n\nconst className = computed(() => {\n return [cls.b, cls.m(size.value), bem.is('disabled', disabled.value)]\n})\n\nconst { formProps } = useFormComponent()\n\nconst { size, disabled, readonly } = useFormFallbackProps([formProps ?? {}, props], {\n size: 'default',\n disabled: false,\n readonly: false\n})\n\nconst dropdownRef = shallowRef<DropdownExposed>()\n\nconst { userAction, isUserActive } = useUserAction()\n\nconst currentRangeDate = shallowRef<[Dater, Dater]>()\n\nconst displayedOfStart = computed(() => {\n return props.modelValue?.[0]\n})\n\nconst displayedOfEnd = computed(() => {\n return props.modelValue?.[1]\n})\n\nconst formatStr = computed(() => {\n const { format, type } = props\n if (format) return format\n if (type === 'date') return 'yyyy-MM-dd'\n if (type === 'month') return 'yyyy-MM'\n if (type === 'year') return 'yyyy'\n return 'yyyy-MM-dd'\n})\n\nwatch(\n () => props.modelValue,\n (val) => {\n if (isUserActive()) return\n if (val?.length === 2) {\n currentRangeDate.value = [date(val[0]), date(val[1])]\n }\n },\n { immediate: true }\n)\n\nconst commitSelectedRange = userAction((rangeDate: [Dater, Dater] | undefined) => {\n currentRangeDate.value = rangeDate\n emit('update:modelValue', rangeDate?.map((d) => d.format(formatStr.value)) as [string, string])\n})\n\nasync function handleSelect(rangeDate: [Dater, Dater] | undefined) {\n await commitSelectedRange(rangeDate)\n dropdownRef.value?.close()\n}\n\nconst hovered = shallowRef(false)\n\nfunction handleClear() {\n currentRangeDate.value = undefined\n emit('update:modelValue', undefined)\n}\n</script>\n"],"mappings":"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"}
|
|
@@ -9,9 +9,9 @@ declare const __VLS_export: _$vue.DefineComponent<DateRangePickerProps, {}, {},
|
|
|
9
9
|
}>, {
|
|
10
10
|
type: "date" | "month" | "year";
|
|
11
11
|
disabled: boolean;
|
|
12
|
+
readonly: boolean;
|
|
12
13
|
placeholder: [string, string];
|
|
13
14
|
clearable: boolean;
|
|
14
|
-
readonly: boolean;
|
|
15
15
|
}, {}, {}, {}, string, _$vue.ComponentProvideOptions, false, {}, any>;
|
|
16
16
|
declare const _default: typeof __VLS_export;
|
|
17
17
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"drawer.js","names":["$attrs"],"sources":["../../../src/components/drawer/drawer.vue"],"sourcesContent":["<template>\n <Teleport to=\"body\">\n <transition name=\"fade\" mode=\"out-in\" @enter=\"onEnter\">\n <div v-if=\"overlayVisible\" :class=\"overlayCls.b\" :style=\"{ zIndex: zIndex() }\" @click=\"close\">\n <transition :name=\"transitionName\" appear @after-leave=\"onAfterDrawerLeave\">\n <div\n v-bind=\"$attrs\"\n v-if=\"drawerVisible\"\n :class=\"drawerClass\"\n :style=\"drawerStyle\"\n @click.stop\n >\n <span :class=\"cls.e('close')\" @click=\"close\" v-if=\"showClose\">\n <u-icon><Close /></u-icon>\n </span>\n <slot />\n </div>\n </transition>\n </div>\n </transition>\n </Teleport>\n</template>\n\n<script lang=\"ts\" setup>\nimport { Close } from '@veltra/icons/normal'\nimport { bem, zIndex } from '@veltra/utils'\nimport { computed, shallowRef } from 'vue'\n\nimport type { DrawerProps, DrawerEmits } from '../../types'\nimport { UIcon } from '../icon'\n\ndefineOptions({\n name: 'Drawer',\n inheritAttrs: false\n})\n\nconst props = withDefaults(defineProps<DrawerProps>(), {\n direction: 'right',\n closable: true\n})\n\nconst emit = defineEmits<DrawerEmits>()\n\nconst cls = bem('drawer')\nconst overlayCls = bem('drawer-overlay')\n\nconst overlayVisible = defineModel<boolean>({\n default: false\n})\n\nconst drawerVisible = shallowRef(false)\n\n// 根据方向计算过渡动画名称\nconst transitionName = computed(() => {\n return `drawer-slide-${props.direction}`\n})\n\n// 计算抽屉样式类\nconst drawerClass = computed(() => {\n return [cls.b, bem.is(props.direction)]\n})\n\n// 计算抽屉样式\nconst drawerStyle = computed(() => {\n const style: Record<string, string> = {}\n\n return style\n})\n\nconst onEnter = () => {\n drawerVisible.value = true\n}\n\nconst onAfterDrawerLeave = () => {\n overlayVisible.value = false\n}\n\n// 关闭抽屉\nconst close = () => {\n drawerVisible.value = false\n emit('close')\n}\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;EAoCA,MAAM,QAAQ;EAKd,MAAM,OAAO;EAEb,MAAM,MAAM,IAAI,SAAQ;EACxB,MAAM,aAAa,IAAI,iBAAgB;EAEvC,MAAM,iBAAiB,SAAoB,SAAA,aAE1C;EAED,MAAM,gBAAgB,WAAW,MAAK;EAGtC,MAAM,iBAAiB,eAAe;AACpC,UAAO,gBAAgB,MAAM;IAC9B;EAGD,MAAM,cAAc,eAAe;AACjC,UAAO,CAAC,IAAI,GAAG,IAAI,GAAG,MAAM,UAAU,CAAA;IACvC;EAGD,MAAM,cAAc,eAAe;AAGjC,
|
|
1
|
+
{"version":3,"file":"drawer.js","names":["$attrs"],"sources":["../../../src/components/drawer/drawer.vue"],"sourcesContent":["<template>\n <Teleport to=\"body\">\n <transition name=\"fade\" mode=\"out-in\" @enter=\"onEnter\">\n <div v-if=\"overlayVisible\" :class=\"overlayCls.b\" :style=\"{ zIndex: zIndex() }\" @click=\"close\">\n <transition :name=\"transitionName\" appear @after-leave=\"onAfterDrawerLeave\">\n <div\n v-bind=\"$attrs\"\n v-if=\"drawerVisible\"\n :class=\"drawerClass\"\n :style=\"drawerStyle\"\n @click.stop\n >\n <span :class=\"cls.e('close')\" @click=\"close\" v-if=\"showClose\">\n <u-icon><Close /></u-icon>\n </span>\n <slot />\n </div>\n </transition>\n </div>\n </transition>\n </Teleport>\n</template>\n\n<script lang=\"ts\" setup>\nimport { Close } from '@veltra/icons/normal'\nimport { bem, zIndex } from '@veltra/utils'\nimport { computed, shallowRef } from 'vue'\n\nimport type { DrawerProps, DrawerEmits } from '../../types'\nimport { UIcon } from '../icon'\n\ndefineOptions({\n name: 'Drawer',\n inheritAttrs: false\n})\n\nconst props = withDefaults(defineProps<DrawerProps>(), {\n direction: 'right',\n closable: true\n})\n\nconst emit = defineEmits<DrawerEmits>()\n\nconst cls = bem('drawer')\nconst overlayCls = bem('drawer-overlay')\n\nconst overlayVisible = defineModel<boolean>({\n default: false\n})\n\nconst drawerVisible = shallowRef(false)\n\n// 根据方向计算过渡动画名称\nconst transitionName = computed(() => {\n return `drawer-slide-${props.direction}`\n})\n\n// 计算抽屉样式类\nconst drawerClass = computed(() => {\n return [cls.b, bem.is(props.direction)]\n})\n\n// 计算抽屉样式\nconst drawerStyle = computed(() => {\n const style: Record<string, string> = {}\n\n return style\n})\n\nconst onEnter = () => {\n drawerVisible.value = true\n}\n\nconst onAfterDrawerLeave = () => {\n overlayVisible.value = false\n}\n\n// 关闭抽屉\nconst close = () => {\n drawerVisible.value = false\n emit('close')\n}\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;EAoCA,MAAM,QAAQ;EAKd,MAAM,OAAO;EAEb,MAAM,MAAM,IAAI,SAAQ;EACxB,MAAM,aAAa,IAAI,iBAAgB;EAEvC,MAAM,iBAAiB,SAAoB,SAAA,aAE1C;EAED,MAAM,gBAAgB,WAAW,MAAK;EAGtC,MAAM,iBAAiB,eAAe;AACpC,UAAO,gBAAgB,MAAM;IAC9B;EAGD,MAAM,cAAc,eAAe;AACjC,UAAO,CAAC,IAAI,GAAG,IAAI,GAAG,MAAM,UAAU,CAAA;IACvC;EAGD,MAAM,cAAc,eAAe;AAGjC,UAAO,EAAA;IACR;EAED,MAAM,gBAAgB;AACpB,iBAAc,QAAQ;;EAGxB,MAAM,2BAA2B;AAC/B,kBAAe,QAAQ;;EAIzB,MAAM,cAAc;AAClB,iBAAc,QAAQ;AACtB,QAAK,QAAO;;;uBA/EZ,YAmBW,UAAA,EAnBD,IAAG,QAAM,EAAA,CACjB,YAiBa,YAAA;IAjBD,MAAK;IAAO,MAAK;IAAiB;;2BAgBtC,CAfK,eAAA,SAAA,WAAA,EAAX,mBAeM,OAAA;;KAfsB,OAAK,eAAE,MAAA,WAAU,CAAC,EAAC;KAAG,OAAK,eAAA,EAAA,QAAY,MAAA,OAAM,EAAA,EAAA,CAAA;KAAO,SAAO;QACrF,YAaa,YAAA;KAbA,MAAM,eAAA;KAAgB,QAAA;KAAQ,cAAa;;4BAYhD,CATE,cAAA,SAAA,WAAA,EAFR,mBAWM,OAXN,WAWM,EAAA,KAAA,GAAA,EAVIA,KAAAA,QAAM;MAEb,OAAO,YAAA;MACP,OAAO,YAAA;MACP,SAAK,OAAA,OAAA,OAAA,KAAA,oBAAN,IAAW,CAAA,OAAA,CAAA;UAEwC,QAAA,aAAA,WAAA,EAAnD,mBAEO,QAAA;;MAFA,OAAK,eAAE,MAAA,IAAG,CAAC,EAAC,QAAA,CAAA;MAAY,SAAO;SACpC,YAA0B,MAAA,YAAA,EAAA,MAAA;6BAAT,CAAT,YAAS,MAAA,MAAA,CAAA,CAAA,CAAA;;kDAEnB,WAAQ,KAAA,QAAA,UAAA,CAAA,EAAA,GAAA,IAAA,mBAAA,QAAA,KAAA,CAAA,CAAA"}
|
|
@@ -3,8 +3,8 @@ import * as _$vue from "vue";
|
|
|
3
3
|
|
|
4
4
|
//#region src/components/empty/empty.vue.d.ts
|
|
5
5
|
declare const __VLS_export: _$vue.DefineComponent<EmptyProps, {}, {}, {}, {}, _$vue.ComponentOptionsMixin, _$vue.ComponentOptionsMixin, {}, string, _$vue.PublicProps, Readonly<EmptyProps> & Readonly<{}>, {
|
|
6
|
-
text: string;
|
|
7
6
|
size: number;
|
|
7
|
+
text: string;
|
|
8
8
|
}, {}, {}, {}, string, _$vue.ComponentProvideOptions, false, {}, any>;
|
|
9
9
|
declare const _default: typeof __VLS_export;
|
|
10
10
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"expression-editor.js","names":[],"sources":["../../../src/components/expression-editor/expression-editor.vue"],"sourcesContent":["<template>\n <div :class=\"className\">\n <!-- 编辑容器 -->\n <div\n :class=\"cls.e('container')\"\n ref=\"container\"\n :contenteditable=\"!readonly && !disabled\"\n ></div>\n\n <div v-if=\"showFallbackControls\" :class=\"cls.e('fallback')\">\n <div\n v-for=\"(item, index) in fallbackVariables\"\n :key=\"item.key\"\n :class=\"cls.e('fallback-item')\"\n >\n <span :class=\"cls.e('fallback-label')\">\n {{ item.label || item.variable }}\n </span>\n <div :class=\"cls.e('fallback-actions')\">\n <button\n type=\"button\"\n :class=\"cls.e('fallback-button')\"\n :disabled=\"disabled || readonly || index === 0\"\n @click=\"moveVariable(item.key, -1)\"\n >\n 上移\n </button>\n <button\n type=\"button\"\n :class=\"cls.e('fallback-button')\"\n :disabled=\"disabled || readonly || index === fallbackVariables.length - 1\"\n @click=\"moveVariable(item.key, 1)\"\n >\n 下移\n </button>\n </div>\n </div>\n </div>\n\n <div :class=\"cls.e('placeholder')\" v-if=\"showPlaceholder\">\n {{ placeholder }}\n </div>\n\n <!-- 渲染装饰器节点,内部通过Vue的Teleport组件渲染至节点中 -->\n <Decorators :decorators=\"decorators\" />\n\n <!-- 变量选择器 -->\n <VariablePicker\n v-model:visible=\"contextVisible\"\n :trigger-dom=\"contextTriggerDom\"\n :filterable=\"true\"\n :register-picker-key-handler=\"registerPickerKeyHandler\"\n @select=\"handleVariableSelect\"\n />\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { useFormComponent, useFormFallbackProps } from '@veltra/compositions'\nimport { bem } from '@veltra/utils'\nimport { $getRoot } from 'lexical'\nimport { useTemplateRef, provide, computed, onBeforeUnmount, shallowRef, type VNode } from 'vue'\n\nimport type { ExpressionEditorProps, VariableItem } from '../../types'\nimport VariablePicker from './components/variable-picker.vue'\nimport { ExpressionEditorDIKey, createVariableMap } from './di'\nimport { createExpressionEditorRuntime } from './internal/editor-runtime'\nimport { moveVariableByDirection } from './internal/features/drag-drop/drag-drop-service'\nimport { insertVariableAtTrigger } from './internal/features/insertion/insertion-service'\nimport { $isVariableNode } from './nodes/variable-node'\nimport { registerPlainText } from './plain-text'\nimport { useContext } from './use-context'\nimport { useDecorators } from './use-decorators'\nimport { collectVariableNodeDescriptors, supportsNativeDnD } from './use-expression-drag-drop'\n\ndefineOptions({\n name: 'ExpressionEditor'\n})\n\nconst props = withDefaults(defineProps<ExpressionEditorProps>(), {\n placeholder: '请输入表达式,输入 @ 可插入变量'\n})\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: string): void\n}>()\n\nconst showPlaceholder = computed(() => !props.modelValue || props.modelValue.trim() === '')\n\nconst cls = bem('expression-editor')\n\nconst { formProps } = useFormComponent()\n\nconst { size, disabled, readonly } = useFormFallbackProps([formProps ?? {}, props])\n\nconst className = computed(() => {\n return [\n cls.b,\n cls.m(size.value),\n bem.is('disabled', disabled.value),\n bem.is('readonly', readonly.value)\n ]\n})\n\nconst containerRef = useTemplateRef('container')\n\nconst { editor } = createExpressionEditorRuntime({\n disabled,\n readonly,\n cls,\n container: containerRef,\n props,\n emit\n})\n\nconst {\n contextVisible,\n contextTriggerDom,\n textNode,\n charPosition,\n registerPickerKeyHandler,\n registerContextCommands\n} = useContext(editor)\n\nregisterPlainText(editor, {\n getContextCommands: registerContextCommands\n})\n\nconst decorators = useDecorators(editor)\nconst nativeDnDSupported = supportsNativeDnD()\nconst fallbackVariables = shallowRef(collectVariableNodeDescriptors(editor))\nconst showFallbackControls = computed(\n () => !nativeDnDSupported && fallbackVariables.value.length > 1\n)\n\nconst removeFallbackSync = editor.registerUpdateListener(() => {\n fallbackVariables.value = collectVariableNodeDescriptors(editor)\n})\n\nonBeforeUnmount(() => {\n removeFallbackSync()\n})\n\n// 创建变量映射表\nconst variableMap = computed(() => createVariableMap(props.variables))\n\nfunction Decorators(props: { decorators: VNode[] }) {\n return props.decorators\n}\n\nfunction moveVariable(variableKey: string, direction: -1 | 1) {\n if (disabled.value || readonly.value) return\n\n moveVariableByDirection(editor, variableKey, direction, true)\n}\n\n// 处理变量选择\nfunction handleVariableSelect(variable: VariableItem) {\n if (disabled.value || readonly.value) return\n\n const nodeKey = textNode.value?.getKey()\n if (!nodeKey) return\n\n insertVariableAtTrigger(editor, {\n nodeKey,\n charPosition: charPosition.value,\n variable: {\n value: variable.value,\n label: variable.label,\n type: variable.type\n }\n })\n}\n\n// 更新变量节点的函数\nfunction updateVariableNode(oldValue: string, newValue: string, newLabel?: string) {\n editor.update(() => {\n const root = $getRoot()\n\n // 如果没有提供 label 或 type,从映射表中查找\n const variable = variableMap.value.get(newValue)\n const label = newLabel ?? variable?.label ?? newValue\n const type = variable?.type\n\n // 递归遍历所有节点\n function traverse(node: any) {\n if ($isVariableNode(node)) {\n if (node.getVariable() === oldValue) {\n node.updateVariable(newValue, label, type)\n }\n }\n\n // 如果节点有 getChildren 方法,继续遍历\n if (typeof node.getChildren === 'function') {\n const children = node.getChildren()\n children.forEach((child: any) => traverse(child))\n }\n }\n\n traverse(root)\n })\n}\n\nprovide(ExpressionEditorDIKey, {\n cls,\n editorProps: props,\n editor,\n updateVariableNode,\n variableMap\n})\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+EA,MAAM,QAAQ;EAId,MAAM,OAAO;EAIb,MAAM,kBAAkB,eAAe,CAAC,MAAM,cAAc,MAAM,WAAW,MAAM,KAAK,GAAE;EAE1F,MAAM,MAAM,IAAI,oBAAmB;EAEnC,MAAM,EAAE,cAAc,kBAAiB;EAEvC,MAAM,EAAE,MAAM,UAAU,aAAa,qBAAqB,CAAC,aAAa,EAAE,EAAE,MAAM,CAAA;EAElF,MAAM,YAAY,eAAe;AAC/B,UAAO;IACL,IAAI;IACJ,IAAI,EAAE,KAAK,MAAM;IACjB,IAAI,GAAG,YAAY,SAAS,MAAM;IAClC,IAAI,GAAG,YAAY,SAAS,MAAK;IACnC;IACD;EAID,MAAM,EAAE,WAAW,8BAA8B;GAC/C;GACA;GACA;GACA,WANmB,eAAe,
|
|
1
|
+
{"version":3,"file":"expression-editor.js","names":[],"sources":["../../../src/components/expression-editor/expression-editor.vue"],"sourcesContent":["<template>\n <div :class=\"className\">\n <!-- 编辑容器 -->\n <div\n :class=\"cls.e('container')\"\n ref=\"container\"\n :contenteditable=\"!readonly && !disabled\"\n ></div>\n\n <div v-if=\"showFallbackControls\" :class=\"cls.e('fallback')\">\n <div\n v-for=\"(item, index) in fallbackVariables\"\n :key=\"item.key\"\n :class=\"cls.e('fallback-item')\"\n >\n <span :class=\"cls.e('fallback-label')\">\n {{ item.label || item.variable }}\n </span>\n <div :class=\"cls.e('fallback-actions')\">\n <button\n type=\"button\"\n :class=\"cls.e('fallback-button')\"\n :disabled=\"disabled || readonly || index === 0\"\n @click=\"moveVariable(item.key, -1)\"\n >\n 上移\n </button>\n <button\n type=\"button\"\n :class=\"cls.e('fallback-button')\"\n :disabled=\"disabled || readonly || index === fallbackVariables.length - 1\"\n @click=\"moveVariable(item.key, 1)\"\n >\n 下移\n </button>\n </div>\n </div>\n </div>\n\n <div :class=\"cls.e('placeholder')\" v-if=\"showPlaceholder\">\n {{ placeholder }}\n </div>\n\n <!-- 渲染装饰器节点,内部通过Vue的Teleport组件渲染至节点中 -->\n <Decorators :decorators=\"decorators\" />\n\n <!-- 变量选择器 -->\n <VariablePicker\n v-model:visible=\"contextVisible\"\n :trigger-dom=\"contextTriggerDom\"\n :filterable=\"true\"\n :register-picker-key-handler=\"registerPickerKeyHandler\"\n @select=\"handleVariableSelect\"\n />\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { useFormComponent, useFormFallbackProps } from '@veltra/compositions'\nimport { bem } from '@veltra/utils'\nimport { $getRoot } from 'lexical'\nimport { useTemplateRef, provide, computed, onBeforeUnmount, shallowRef, type VNode } from 'vue'\n\nimport type { ExpressionEditorProps, VariableItem } from '../../types'\nimport VariablePicker from './components/variable-picker.vue'\nimport { ExpressionEditorDIKey, createVariableMap } from './di'\nimport { createExpressionEditorRuntime } from './internal/editor-runtime'\nimport { moveVariableByDirection } from './internal/features/drag-drop/drag-drop-service'\nimport { insertVariableAtTrigger } from './internal/features/insertion/insertion-service'\nimport { $isVariableNode } from './nodes/variable-node'\nimport { registerPlainText } from './plain-text'\nimport { useContext } from './use-context'\nimport { useDecorators } from './use-decorators'\nimport { collectVariableNodeDescriptors, supportsNativeDnD } from './use-expression-drag-drop'\n\ndefineOptions({\n name: 'ExpressionEditor'\n})\n\nconst props = withDefaults(defineProps<ExpressionEditorProps>(), {\n placeholder: '请输入表达式,输入 @ 可插入变量'\n})\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: string): void\n}>()\n\nconst showPlaceholder = computed(() => !props.modelValue || props.modelValue.trim() === '')\n\nconst cls = bem('expression-editor')\n\nconst { formProps } = useFormComponent()\n\nconst { size, disabled, readonly } = useFormFallbackProps([formProps ?? {}, props])\n\nconst className = computed(() => {\n return [\n cls.b,\n cls.m(size.value),\n bem.is('disabled', disabled.value),\n bem.is('readonly', readonly.value)\n ]\n})\n\nconst containerRef = useTemplateRef('container')\n\nconst { editor } = createExpressionEditorRuntime({\n disabled,\n readonly,\n cls,\n container: containerRef,\n props,\n emit\n})\n\nconst {\n contextVisible,\n contextTriggerDom,\n textNode,\n charPosition,\n registerPickerKeyHandler,\n registerContextCommands\n} = useContext(editor)\n\nregisterPlainText(editor, {\n getContextCommands: registerContextCommands\n})\n\nconst decorators = useDecorators(editor)\nconst nativeDnDSupported = supportsNativeDnD()\nconst fallbackVariables = shallowRef(collectVariableNodeDescriptors(editor))\nconst showFallbackControls = computed(\n () => !nativeDnDSupported && fallbackVariables.value.length > 1\n)\n\nconst removeFallbackSync = editor.registerUpdateListener(() => {\n fallbackVariables.value = collectVariableNodeDescriptors(editor)\n})\n\nonBeforeUnmount(() => {\n removeFallbackSync()\n})\n\n// 创建变量映射表\nconst variableMap = computed(() => createVariableMap(props.variables))\n\nfunction Decorators(props: { decorators: VNode[] }) {\n return props.decorators\n}\n\nfunction moveVariable(variableKey: string, direction: -1 | 1) {\n if (disabled.value || readonly.value) return\n\n moveVariableByDirection(editor, variableKey, direction, true)\n}\n\n// 处理变量选择\nfunction handleVariableSelect(variable: VariableItem) {\n if (disabled.value || readonly.value) return\n\n const nodeKey = textNode.value?.getKey()\n if (!nodeKey) return\n\n insertVariableAtTrigger(editor, {\n nodeKey,\n charPosition: charPosition.value,\n variable: {\n value: variable.value,\n label: variable.label,\n type: variable.type\n }\n })\n}\n\n// 更新变量节点的函数\nfunction updateVariableNode(oldValue: string, newValue: string, newLabel?: string) {\n editor.update(() => {\n const root = $getRoot()\n\n // 如果没有提供 label 或 type,从映射表中查找\n const variable = variableMap.value.get(newValue)\n const label = newLabel ?? variable?.label ?? newValue\n const type = variable?.type\n\n // 递归遍历所有节点\n function traverse(node: any) {\n if ($isVariableNode(node)) {\n if (node.getVariable() === oldValue) {\n node.updateVariable(newValue, label, type)\n }\n }\n\n // 如果节点有 getChildren 方法,继续遍历\n if (typeof node.getChildren === 'function') {\n const children = node.getChildren()\n children.forEach((child: any) => traverse(child))\n }\n }\n\n traverse(root)\n })\n}\n\nprovide(ExpressionEditorDIKey, {\n cls,\n editorProps: props,\n editor,\n updateVariableNode,\n variableMap\n})\n</script>\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-runtime.js","names":[],"sources":["../../../../../src/components/expression-editor/internal/editor-runtime/create-runtime.ts"],"sourcesContent":["import type { BEM } from '@veltra/utils'\nimport { createEditor } from 'lexical'\nimport { watchEffect, computed, type Ref, type ShallowRef } from 'vue'\n\nimport type { ExpressionEditorEmits, ExpressionEditorProps } from '../../../../types'\nimport { createVariableMap } from '../../di'\nimport { VariableNode } from '../../nodes/variable-node'\nimport type { EditorMutationGateway, ExpressionEditorRuntime } from '../contracts/editor-runtime'\nimport { createModelSync } from './model-sync'\n\nexport interface CreateExpressionEditorRuntimeOptions {\n disabled: Ref<boolean>\n readonly: Ref<boolean>\n props: ExpressionEditorProps\n cls: BEM<'expression-editor'>\n emit: ExpressionEditorEmits\n container: ShallowRef<HTMLElement | null>\n}\n\nfunction createDefaultMutationGateway(\n editor: ExpressionEditorRuntime['editor']\n): EditorMutationGateway {\n return {\n runUpdate(updater) {\n editor.update(() => {\n updater()\n })\n }\n }\n}\n\nfunction resolveEditable(disabled: Ref<boolean>, readonly: Ref<boolean>) {\n return !disabled.value && !readonly.value\n}\n\nexport function createExpressionEditorRuntime(\n options: CreateExpressionEditorRuntimeOptions\n): ExpressionEditorRuntime {\n const { disabled, readonly, container, props, emit, cls } = options\n const editor = createEditor({\n namespace: 'ExpressionEditor',\n nodes: [VariableNode],\n onError: console.error,\n editable: resolveEditable(disabled, readonly),\n theme: { paragraph: cls.e('paragraph') }\n })\n\n watchEffect(() => {\n editor.setEditable(resolveEditable(disabled, readonly))\n })\n\n watchEffect(() => {\n container.value && editor.setRootElement(container.value)\n })\n\n const variableMap = computed(() => createVariableMap(props.variables))\n const sync = createModelSync({ editor, props, emit, variableMap })\n\n return {\n editor,\n mutations: createDefaultMutationGateway(editor),\n syncFromModelValue: sync.syncFromModelValue\n }\n}\n"],"mappings":";;;;;;AAmBA,SAAS,6BACP,QACuB;AACvB,QAAO,EACL,UAAU,SAAS;AACjB,SAAO,aAAa;AAClB,YAAS;IACT;IAEL;;AAGH,SAAS,gBAAgB,UAAwB,UAAwB;AACvE,QAAO,CAAC,SAAS,SAAS,CAAC,SAAS;;AAGtC,SAAgB,8BACd,SACyB;CACzB,MAAM,EAAE,UAAU,UAAU,WAAW,OAAO,MAAM,QAAQ;CAC5D,MAAM,SAAS,aAAa;EAC1B,WAAW;EACX,OAAO,CAAC,aAAa;EACrB,SAAS,QAAQ;EACjB,UAAU,gBAAgB,UAAU,SAAS;EAC7C,OAAO,EAAE,WAAW,IAAI,EAAE,YAAY,EAAE;EACzC,CAAC;AAEF,mBAAkB;AAChB,SAAO,YAAY,gBAAgB,UAAU,SAAS,CAAC;GACvD;AAEF,mBAAkB;AAChB,YAAU,SAAS,OAAO,eAAe,UAAU,MAAM;GACzD;CAGF,MAAM,OAAO,gBAAgB;EAAE;EAAQ;EAAO;EAAM,aADhC,eAAe,kBAAkB,MAAM,UAAU,
|
|
1
|
+
{"version":3,"file":"create-runtime.js","names":[],"sources":["../../../../../src/components/expression-editor/internal/editor-runtime/create-runtime.ts"],"sourcesContent":["import type { BEM } from '@veltra/utils'\nimport { createEditor } from 'lexical'\nimport { watchEffect, computed, type Ref, type ShallowRef } from 'vue'\n\nimport type { ExpressionEditorEmits, ExpressionEditorProps } from '../../../../types'\nimport { createVariableMap } from '../../di'\nimport { VariableNode } from '../../nodes/variable-node'\nimport type { EditorMutationGateway, ExpressionEditorRuntime } from '../contracts/editor-runtime'\nimport { createModelSync } from './model-sync'\n\nexport interface CreateExpressionEditorRuntimeOptions {\n disabled: Ref<boolean>\n readonly: Ref<boolean>\n props: ExpressionEditorProps\n cls: BEM<'expression-editor'>\n emit: ExpressionEditorEmits\n container: ShallowRef<HTMLElement | null>\n}\n\nfunction createDefaultMutationGateway(\n editor: ExpressionEditorRuntime['editor']\n): EditorMutationGateway {\n return {\n runUpdate(updater) {\n editor.update(() => {\n updater()\n })\n }\n }\n}\n\nfunction resolveEditable(disabled: Ref<boolean>, readonly: Ref<boolean>) {\n return !disabled.value && !readonly.value\n}\n\nexport function createExpressionEditorRuntime(\n options: CreateExpressionEditorRuntimeOptions\n): ExpressionEditorRuntime {\n const { disabled, readonly, container, props, emit, cls } = options\n const editor = createEditor({\n namespace: 'ExpressionEditor',\n nodes: [VariableNode],\n onError: console.error,\n editable: resolveEditable(disabled, readonly),\n theme: { paragraph: cls.e('paragraph') }\n })\n\n watchEffect(() => {\n editor.setEditable(resolveEditable(disabled, readonly))\n })\n\n watchEffect(() => {\n container.value && editor.setRootElement(container.value)\n })\n\n const variableMap = computed(() => createVariableMap(props.variables))\n const sync = createModelSync({ editor, props, emit, variableMap })\n\n return {\n editor,\n mutations: createDefaultMutationGateway(editor),\n syncFromModelValue: sync.syncFromModelValue\n }\n}\n"],"mappings":";;;;;;AAmBA,SAAS,6BACP,QACuB;AACvB,QAAO,EACL,UAAU,SAAS;AACjB,SAAO,aAAa;AAClB,YAAS;IACT;IAEL;;AAGH,SAAS,gBAAgB,UAAwB,UAAwB;AACvE,QAAO,CAAC,SAAS,SAAS,CAAC,SAAS;;AAGtC,SAAgB,8BACd,SACyB;CACzB,MAAM,EAAE,UAAU,UAAU,WAAW,OAAO,MAAM,QAAQ;CAC5D,MAAM,SAAS,aAAa;EAC1B,WAAW;EACX,OAAO,CAAC,aAAa;EACrB,SAAS,QAAQ;EACjB,UAAU,gBAAgB,UAAU,SAAS;EAC7C,OAAO,EAAE,WAAW,IAAI,EAAE,YAAY,EAAE;EACzC,CAAC;AAEF,mBAAkB;AAChB,SAAO,YAAY,gBAAgB,UAAU,SAAS,CAAC;GACvD;AAEF,mBAAkB;AAChB,YAAU,SAAS,OAAO,eAAe,UAAU,MAAM;GACzD;CAGF,MAAM,OAAO,gBAAgB;EAAE;EAAQ;EAAO;EAAM,aADhC,eAAe,kBAAkB,MAAM,UAAU,CACN;EAAE,CAAC;AAElE,QAAO;EACL;EACA,WAAW,6BAA6B,OAAO;EAC/C,oBAAoB,KAAK;EAC1B"}
|
package/dist/components/expression-editor/internal/features/commands/register-command-packs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register-command-packs.js","names":[],"sources":["../../../../../../src/components/expression-editor/internal/features/commands/register-command-packs.ts"],"sourcesContent":["import { $getHtmlContent, $insertDataTransferForPlainText } from '@lexical/clipboard'\nimport {\n CAN_USE_BEFORE_INPUT,\n IS_APPLE_WEBKIT,\n IS_IOS,\n IS_SAFARI,\n mergeRegister,\n objectKlassEquals\n} from '@lexical/utils'\nimport type { CommandPayloadType, LexicalEditor } from 'lexical'\nimport {\n $getSelection,\n $isRangeSelection,\n $selectAll,\n COMMAND_PRIORITY_EDITOR,\n CONTROLLED_TEXT_INSERTION_COMMAND,\n COPY_COMMAND,\n CUT_COMMAND,\n DELETE_CHARACTER_COMMAND,\n DELETE_LINE_COMMAND,\n DELETE_WORD_COMMAND,\n DRAGSTART_COMMAND,\n DRAGOVER_COMMAND,\n DROP_COMMAND,\n INSERT_LINE_BREAK_COMMAND,\n INSERT_PARAGRAPH_COMMAND,\n KEY_ARROW_LEFT_COMMAND,\n KEY_ARROW_RIGHT_COMMAND,\n KEY_BACKSPACE_COMMAND,\n KEY_DELETE_COMMAND,\n KEY_ENTER_COMMAND,\n PASTE_COMMAND,\n PASTE_TAG,\n REMOVE_TEXT_COMMAND,\n SELECT_ALL_COMMAND\n} from 'lexical'\n\nimport { EXPRESSION_VARIABLE_DRAG_TYPE } from '../../../constants'\nimport {\n autoScrollWhenNearEdge,\n beginDragVisualState,\n clearDropIndicator,\n clearDragVisualState,\n ensureDropScopeId,\n getActiveInternalDragPayload,\n readDragSourceKey,\n readInternalDragPayload,\n resolveDropSlot,\n showDropIndicator,\n writeInternalDragPayload\n} from '../../../use-expression-drag-drop'\nimport { reorderVariable } from '../drag-drop/drag-drop-service'\n\nfunction onCopyForPlainText(\n event: CommandPayloadType<typeof COPY_COMMAND>,\n editor: LexicalEditor\n): void {\n editor.update(() => {\n if (event !== null) {\n const clipboardData = objectKlassEquals(event, KeyboardEvent) ? null : event.clipboardData\n const selection = $getSelection()\n\n if (selection !== null && clipboardData != null) {\n event.preventDefault()\n const htmlString = $getHtmlContent(editor)\n\n if (htmlString !== null) {\n clipboardData.setData('text/html', htmlString)\n }\n\n clipboardData.setData('text/plain', selection.getTextContent())\n }\n }\n })\n}\n\nfunction onPasteForPlainText(\n event: CommandPayloadType<typeof PASTE_COMMAND>,\n editor: LexicalEditor\n): void {\n event.preventDefault()\n editor.update(\n () => {\n const selection = $getSelection()\n const clipboardData = objectKlassEquals(event, ClipboardEvent) ? event.clipboardData : null\n if (clipboardData != null && $isRangeSelection(selection)) {\n $insertDataTransferForPlainText(clipboardData, selection)\n }\n },\n { tag: PASTE_TAG }\n )\n}\n\nfunction onCutForPlainText(\n event: CommandPayloadType<typeof CUT_COMMAND>,\n editor: LexicalEditor\n): void {\n onCopyForPlainText(event, editor)\n editor.update(() => {\n const selection = $getSelection()\n\n if ($isRangeSelection(selection)) {\n selection.removeText()\n }\n })\n}\n\nfunction registerTextEditingCommands(editor: LexicalEditor): () => void {\n return mergeRegister(\n editor.registerCommand<boolean>(\n DELETE_CHARACTER_COMMAND,\n (isBackward) => {\n const selection = $getSelection()\n\n if (!$isRangeSelection(selection)) {\n return false\n }\n\n selection.deleteCharacter(isBackward)\n return true\n },\n COMMAND_PRIORITY_EDITOR\n ),\n editor.registerCommand<boolean>(\n DELETE_WORD_COMMAND,\n (isBackward) => {\n const selection = $getSelection()\n\n if (!$isRangeSelection(selection)) {\n return false\n }\n\n selection.deleteWord(isBackward)\n return true\n },\n COMMAND_PRIORITY_EDITOR\n ),\n editor.registerCommand<boolean>(\n DELETE_LINE_COMMAND,\n (isBackward) => {\n const selection = $getSelection()\n\n if (!$isRangeSelection(selection)) {\n return false\n }\n\n selection.deleteLine(isBackward)\n return true\n },\n COMMAND_PRIORITY_EDITOR\n ),\n\n editor.registerCommand<InputEvent | string>(\n CONTROLLED_TEXT_INSERTION_COMMAND,\n (eventOrText) => {\n const selection = $getSelection()\n\n if (!$isRangeSelection(selection)) {\n return false\n }\n\n if (typeof eventOrText === 'string') {\n selection.insertText(eventOrText)\n } else {\n const dataTransfer = eventOrText.dataTransfer\n\n if (dataTransfer != null) {\n $insertDataTransferForPlainText(dataTransfer, selection)\n } else {\n const data = eventOrText.data\n\n if (data) {\n selection.insertText(data)\n }\n }\n }\n\n return true\n },\n COMMAND_PRIORITY_EDITOR\n ),\n editor.registerCommand(\n REMOVE_TEXT_COMMAND,\n () => {\n const selection = $getSelection()\n\n if (!$isRangeSelection(selection)) {\n return false\n }\n\n selection.removeText()\n return true\n },\n COMMAND_PRIORITY_EDITOR\n ),\n editor.registerCommand<boolean>(\n INSERT_LINE_BREAK_COMMAND,\n (selectStart) => {\n const selection = $getSelection()\n\n if (!$isRangeSelection(selection)) {\n return false\n }\n\n selection.insertLineBreak(selectStart)\n return true\n },\n COMMAND_PRIORITY_EDITOR\n ),\n editor.registerCommand(\n INSERT_PARAGRAPH_COMMAND,\n () => {\n const selection = $getSelection()\n\n if (!$isRangeSelection(selection)) {\n return false\n }\n\n selection.insertLineBreak()\n return true\n },\n COMMAND_PRIORITY_EDITOR\n ),\n editor.registerCommand<KeyboardEvent>(\n KEY_ARROW_LEFT_COMMAND,\n () => {\n const selection = $getSelection()\n\n if (!$isRangeSelection(selection)) {\n return false\n }\n\n return false\n },\n COMMAND_PRIORITY_EDITOR\n ),\n editor.registerCommand<KeyboardEvent>(\n KEY_ARROW_RIGHT_COMMAND,\n () => {\n const selection = $getSelection()\n\n if (!$isRangeSelection(selection)) {\n return false\n }\n\n return false\n },\n COMMAND_PRIORITY_EDITOR\n ),\n editor.registerCommand<KeyboardEvent>(\n KEY_BACKSPACE_COMMAND,\n (event) => {\n const selection = $getSelection()\n\n if (!$isRangeSelection(selection)) {\n return false\n }\n\n if (IS_IOS && navigator.language === 'ko-KR') {\n return false\n }\n\n event.preventDefault()\n return editor.dispatchCommand(DELETE_CHARACTER_COMMAND, true)\n },\n COMMAND_PRIORITY_EDITOR\n ),\n editor.registerCommand<KeyboardEvent>(\n KEY_DELETE_COMMAND,\n (event) => {\n const selection = $getSelection()\n\n if (!$isRangeSelection(selection)) {\n return false\n }\n\n event.preventDefault()\n return editor.dispatchCommand(DELETE_CHARACTER_COMMAND, false)\n },\n COMMAND_PRIORITY_EDITOR\n ),\n editor.registerCommand<KeyboardEvent | null>(\n KEY_ENTER_COMMAND,\n (event) => {\n const selection = $getSelection()\n\n if (!$isRangeSelection(selection)) {\n return false\n }\n\n if (event !== null) {\n if ((IS_IOS || IS_SAFARI || IS_APPLE_WEBKIT) && CAN_USE_BEFORE_INPUT) {\n return false\n }\n\n event.preventDefault()\n }\n\n return editor.dispatchCommand(INSERT_LINE_BREAK_COMMAND, false)\n },\n COMMAND_PRIORITY_EDITOR\n ),\n editor.registerCommand(\n SELECT_ALL_COMMAND,\n () => {\n $selectAll()\n\n return true\n },\n COMMAND_PRIORITY_EDITOR\n )\n )\n}\n\nfunction registerClipboardCommands(editor: LexicalEditor): () => void {\n return mergeRegister(\n editor.registerCommand(\n COPY_COMMAND,\n (event) => {\n const selection = $getSelection()\n\n if (!$isRangeSelection(selection)) {\n return false\n }\n\n onCopyForPlainText(event, editor)\n return true\n },\n COMMAND_PRIORITY_EDITOR\n ),\n editor.registerCommand(\n CUT_COMMAND,\n (event) => {\n const selection = $getSelection()\n\n if (!$isRangeSelection(selection)) {\n return false\n }\n\n onCutForPlainText(event, editor)\n return true\n },\n COMMAND_PRIORITY_EDITOR\n ),\n editor.registerCommand(\n PASTE_COMMAND,\n (event) => {\n const selection = $getSelection()\n\n if (!$isRangeSelection(selection)) {\n return false\n }\n\n onPasteForPlainText(event, editor)\n return true\n },\n COMMAND_PRIORITY_EDITOR\n )\n )\n}\n\nfunction registerDragDropCommands(editor: LexicalEditor): () => void {\n return mergeRegister(\n editor.registerCommand<DragEvent>(\n DRAGSTART_COMMAND,\n (event) => {\n if (!editor.isEditable()) {\n return false\n }\n\n const sourceKey = readDragSourceKey(event.target)\n if (!sourceKey) {\n return false\n }\n\n const rootElement = editor.getRootElement()\n if (!rootElement || !(event.target instanceof Node)) {\n return false\n }\n if (!rootElement.contains(event.target)) {\n return false\n }\n\n const scopeId = ensureDropScopeId(editor)\n if (!scopeId || !event.dataTransfer) {\n return false\n }\n\n event.dataTransfer.effectAllowed = 'move'\n writeInternalDragPayload(event.dataTransfer, {\n action: 'move-variable',\n sourceKey,\n scopeId\n })\n event.dataTransfer.setData('text/plain', '{move-variable}')\n\n const sourceElement = rootElement.querySelector<HTMLElement>(\n `[data-ultra-expression-variable-key=\"${sourceKey}\"]`\n )\n beginDragVisualState(editor, sourceElement, { action: 'move-variable', sourceKey, scopeId })\n\n return true\n },\n COMMAND_PRIORITY_EDITOR\n ),\n editor.registerCommand<DragEvent>(\n DRAGOVER_COMMAND,\n (event) => {\n const rootElement = editor.getRootElement()\n if (!rootElement || !(event.target instanceof Node)) {\n return false\n }\n if (!rootElement.contains(event.target)) {\n return false\n }\n\n const payload =\n readInternalDragPayload(event.dataTransfer) ?? getActiveInternalDragPayload(editor)\n if (!payload) {\n clearDropIndicator(editor)\n return false\n }\n\n const scopeId = ensureDropScopeId(editor)\n if (payload.scopeId !== scopeId) {\n clearDropIndicator(editor)\n return false\n }\n\n const dropSlot = resolveDropSlot(editor, event)\n if (dropSlot === null) {\n clearDropIndicator(editor)\n return false\n }\n\n event.preventDefault()\n if (event.dataTransfer) {\n event.dataTransfer.dropEffect = 'move'\n }\n\n showDropIndicator(editor, dropSlot)\n autoScrollWhenNearEdge(rootElement, event.clientY)\n return true\n },\n COMMAND_PRIORITY_EDITOR\n ),\n editor.registerCommand<DragEvent>(\n DROP_COMMAND,\n (event) => {\n const payload =\n readInternalDragPayload(event.dataTransfer) ?? getActiveInternalDragPayload(editor)\n if (!payload) {\n return false\n }\n\n event.preventDefault()\n\n const rootElement = editor.getRootElement()\n const scopeId = ensureDropScopeId(editor)\n if (!rootElement || !scopeId || !(event.target instanceof Node)) {\n clearDragVisualState(editor)\n return true\n }\n if (!rootElement.contains(event.target)) {\n clearDragVisualState(editor)\n return true\n }\n\n const dropSlot = resolveDropSlot(editor, event)\n if (dropSlot === null) {\n clearDragVisualState(editor)\n return true\n }\n\n const payloadText =\n event.dataTransfer?.getData(EXPRESSION_VARIABLE_DRAG_TYPE) ?? JSON.stringify(payload)\n\n reorderVariable(editor, {\n payloadText,\n scopeId,\n targetSlot: dropSlot,\n focusMovedNode: true\n })\n\n clearDragVisualState(editor)\n return true\n },\n COMMAND_PRIORITY_EDITOR\n )\n )\n}\n\nexport interface RegisterCommandPacksOptions {\n /** Optional context-key commands registration (e.g. from use-context). Merged when provided. */\n getContextCommands?: () => () => void\n}\n\n/**\n * Registers all capability command packs for the expression editor.\n * Packs: text-editing, clipboard, drag-drop, and optionally context-keys.\n */\nexport function registerCommandPacks(\n editor: LexicalEditor,\n options?: RegisterCommandPacksOptions\n): () => void {\n const packs: Array<() => void> = [\n registerTextEditingCommands(editor),\n registerClipboardCommands(editor),\n registerDragDropCommands(editor)\n ]\n\n if (options?.getContextCommands) {\n packs.push(options.getContextCommands())\n }\n\n return mergeRegister(...packs)\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"register-command-packs.js","names":[],"sources":["../../../../../../src/components/expression-editor/internal/features/commands/register-command-packs.ts"],"sourcesContent":["import { $getHtmlContent, $insertDataTransferForPlainText } from '@lexical/clipboard'\nimport {\n CAN_USE_BEFORE_INPUT,\n IS_APPLE_WEBKIT,\n IS_IOS,\n IS_SAFARI,\n mergeRegister,\n objectKlassEquals\n} from '@lexical/utils'\nimport type { CommandPayloadType, LexicalEditor } from 'lexical'\nimport {\n $getSelection,\n $isRangeSelection,\n $selectAll,\n COMMAND_PRIORITY_EDITOR,\n CONTROLLED_TEXT_INSERTION_COMMAND,\n COPY_COMMAND,\n CUT_COMMAND,\n DELETE_CHARACTER_COMMAND,\n DELETE_LINE_COMMAND,\n DELETE_WORD_COMMAND,\n DRAGSTART_COMMAND,\n DRAGOVER_COMMAND,\n DROP_COMMAND,\n INSERT_LINE_BREAK_COMMAND,\n INSERT_PARAGRAPH_COMMAND,\n KEY_ARROW_LEFT_COMMAND,\n KEY_ARROW_RIGHT_COMMAND,\n KEY_BACKSPACE_COMMAND,\n KEY_DELETE_COMMAND,\n KEY_ENTER_COMMAND,\n PASTE_COMMAND,\n PASTE_TAG,\n REMOVE_TEXT_COMMAND,\n SELECT_ALL_COMMAND\n} from 'lexical'\n\nimport { EXPRESSION_VARIABLE_DRAG_TYPE } from '../../../constants'\nimport {\n autoScrollWhenNearEdge,\n beginDragVisualState,\n clearDropIndicator,\n clearDragVisualState,\n ensureDropScopeId,\n getActiveInternalDragPayload,\n readDragSourceKey,\n readInternalDragPayload,\n resolveDropSlot,\n showDropIndicator,\n writeInternalDragPayload\n} from '../../../use-expression-drag-drop'\nimport { reorderVariable } from '../drag-drop/drag-drop-service'\n\nfunction onCopyForPlainText(\n event: CommandPayloadType<typeof COPY_COMMAND>,\n editor: LexicalEditor\n): void {\n editor.update(() => {\n if (event !== null) {\n const clipboardData = objectKlassEquals(event, KeyboardEvent) ? null : event.clipboardData\n const selection = $getSelection()\n\n if (selection !== null && clipboardData != null) {\n event.preventDefault()\n const htmlString = $getHtmlContent(editor)\n\n if (htmlString !== null) {\n clipboardData.setData('text/html', htmlString)\n }\n\n clipboardData.setData('text/plain', selection.getTextContent())\n }\n }\n })\n}\n\nfunction onPasteForPlainText(\n event: CommandPayloadType<typeof PASTE_COMMAND>,\n editor: LexicalEditor\n): void {\n event.preventDefault()\n editor.update(\n () => {\n const selection = $getSelection()\n const clipboardData = objectKlassEquals(event, ClipboardEvent) ? event.clipboardData : null\n if (clipboardData != null && $isRangeSelection(selection)) {\n $insertDataTransferForPlainText(clipboardData, selection)\n }\n },\n { tag: PASTE_TAG }\n )\n}\n\nfunction onCutForPlainText(\n event: CommandPayloadType<typeof CUT_COMMAND>,\n editor: LexicalEditor\n): void {\n onCopyForPlainText(event, editor)\n editor.update(() => {\n const selection = $getSelection()\n\n if ($isRangeSelection(selection)) {\n selection.removeText()\n }\n })\n}\n\nfunction registerTextEditingCommands(editor: LexicalEditor): () => void {\n return mergeRegister(\n editor.registerCommand<boolean>(\n DELETE_CHARACTER_COMMAND,\n (isBackward) => {\n const selection = $getSelection()\n\n if (!$isRangeSelection(selection)) {\n return false\n }\n\n selection.deleteCharacter(isBackward)\n return true\n },\n COMMAND_PRIORITY_EDITOR\n ),\n editor.registerCommand<boolean>(\n DELETE_WORD_COMMAND,\n (isBackward) => {\n const selection = $getSelection()\n\n if (!$isRangeSelection(selection)) {\n return false\n }\n\n selection.deleteWord(isBackward)\n return true\n },\n COMMAND_PRIORITY_EDITOR\n ),\n editor.registerCommand<boolean>(\n DELETE_LINE_COMMAND,\n (isBackward) => {\n const selection = $getSelection()\n\n if (!$isRangeSelection(selection)) {\n return false\n }\n\n selection.deleteLine(isBackward)\n return true\n },\n COMMAND_PRIORITY_EDITOR\n ),\n\n editor.registerCommand<InputEvent | string>(\n CONTROLLED_TEXT_INSERTION_COMMAND,\n (eventOrText) => {\n const selection = $getSelection()\n\n if (!$isRangeSelection(selection)) {\n return false\n }\n\n if (typeof eventOrText === 'string') {\n selection.insertText(eventOrText)\n } else {\n const dataTransfer = eventOrText.dataTransfer\n\n if (dataTransfer != null) {\n $insertDataTransferForPlainText(dataTransfer, selection)\n } else {\n const data = eventOrText.data\n\n if (data) {\n selection.insertText(data)\n }\n }\n }\n\n return true\n },\n COMMAND_PRIORITY_EDITOR\n ),\n editor.registerCommand(\n REMOVE_TEXT_COMMAND,\n () => {\n const selection = $getSelection()\n\n if (!$isRangeSelection(selection)) {\n return false\n }\n\n selection.removeText()\n return true\n },\n COMMAND_PRIORITY_EDITOR\n ),\n editor.registerCommand<boolean>(\n INSERT_LINE_BREAK_COMMAND,\n (selectStart) => {\n const selection = $getSelection()\n\n if (!$isRangeSelection(selection)) {\n return false\n }\n\n selection.insertLineBreak(selectStart)\n return true\n },\n COMMAND_PRIORITY_EDITOR\n ),\n editor.registerCommand(\n INSERT_PARAGRAPH_COMMAND,\n () => {\n const selection = $getSelection()\n\n if (!$isRangeSelection(selection)) {\n return false\n }\n\n selection.insertLineBreak()\n return true\n },\n COMMAND_PRIORITY_EDITOR\n ),\n editor.registerCommand<KeyboardEvent>(\n KEY_ARROW_LEFT_COMMAND,\n () => {\n const selection = $getSelection()\n\n if (!$isRangeSelection(selection)) {\n return false\n }\n\n return false\n },\n COMMAND_PRIORITY_EDITOR\n ),\n editor.registerCommand<KeyboardEvent>(\n KEY_ARROW_RIGHT_COMMAND,\n () => {\n const selection = $getSelection()\n\n if (!$isRangeSelection(selection)) {\n return false\n }\n\n return false\n },\n COMMAND_PRIORITY_EDITOR\n ),\n editor.registerCommand<KeyboardEvent>(\n KEY_BACKSPACE_COMMAND,\n (event) => {\n const selection = $getSelection()\n\n if (!$isRangeSelection(selection)) {\n return false\n }\n\n if (IS_IOS && navigator.language === 'ko-KR') {\n return false\n }\n\n event.preventDefault()\n return editor.dispatchCommand(DELETE_CHARACTER_COMMAND, true)\n },\n COMMAND_PRIORITY_EDITOR\n ),\n editor.registerCommand<KeyboardEvent>(\n KEY_DELETE_COMMAND,\n (event) => {\n const selection = $getSelection()\n\n if (!$isRangeSelection(selection)) {\n return false\n }\n\n event.preventDefault()\n return editor.dispatchCommand(DELETE_CHARACTER_COMMAND, false)\n },\n COMMAND_PRIORITY_EDITOR\n ),\n editor.registerCommand<KeyboardEvent | null>(\n KEY_ENTER_COMMAND,\n (event) => {\n const selection = $getSelection()\n\n if (!$isRangeSelection(selection)) {\n return false\n }\n\n if (event !== null) {\n if ((IS_IOS || IS_SAFARI || IS_APPLE_WEBKIT) && CAN_USE_BEFORE_INPUT) {\n return false\n }\n\n event.preventDefault()\n }\n\n return editor.dispatchCommand(INSERT_LINE_BREAK_COMMAND, false)\n },\n COMMAND_PRIORITY_EDITOR\n ),\n editor.registerCommand(\n SELECT_ALL_COMMAND,\n () => {\n $selectAll()\n\n return true\n },\n COMMAND_PRIORITY_EDITOR\n )\n )\n}\n\nfunction registerClipboardCommands(editor: LexicalEditor): () => void {\n return mergeRegister(\n editor.registerCommand(\n COPY_COMMAND,\n (event) => {\n const selection = $getSelection()\n\n if (!$isRangeSelection(selection)) {\n return false\n }\n\n onCopyForPlainText(event, editor)\n return true\n },\n COMMAND_PRIORITY_EDITOR\n ),\n editor.registerCommand(\n CUT_COMMAND,\n (event) => {\n const selection = $getSelection()\n\n if (!$isRangeSelection(selection)) {\n return false\n }\n\n onCutForPlainText(event, editor)\n return true\n },\n COMMAND_PRIORITY_EDITOR\n ),\n editor.registerCommand(\n PASTE_COMMAND,\n (event) => {\n const selection = $getSelection()\n\n if (!$isRangeSelection(selection)) {\n return false\n }\n\n onPasteForPlainText(event, editor)\n return true\n },\n COMMAND_PRIORITY_EDITOR\n )\n )\n}\n\nfunction registerDragDropCommands(editor: LexicalEditor): () => void {\n return mergeRegister(\n editor.registerCommand<DragEvent>(\n DRAGSTART_COMMAND,\n (event) => {\n if (!editor.isEditable()) {\n return false\n }\n\n const sourceKey = readDragSourceKey(event.target)\n if (!sourceKey) {\n return false\n }\n\n const rootElement = editor.getRootElement()\n if (!rootElement || !(event.target instanceof Node)) {\n return false\n }\n if (!rootElement.contains(event.target)) {\n return false\n }\n\n const scopeId = ensureDropScopeId(editor)\n if (!scopeId || !event.dataTransfer) {\n return false\n }\n\n event.dataTransfer.effectAllowed = 'move'\n writeInternalDragPayload(event.dataTransfer, {\n action: 'move-variable',\n sourceKey,\n scopeId\n })\n event.dataTransfer.setData('text/plain', '{move-variable}')\n\n const sourceElement = rootElement.querySelector<HTMLElement>(\n `[data-ultra-expression-variable-key=\"${sourceKey}\"]`\n )\n beginDragVisualState(editor, sourceElement, { action: 'move-variable', sourceKey, scopeId })\n\n return true\n },\n COMMAND_PRIORITY_EDITOR\n ),\n editor.registerCommand<DragEvent>(\n DRAGOVER_COMMAND,\n (event) => {\n const rootElement = editor.getRootElement()\n if (!rootElement || !(event.target instanceof Node)) {\n return false\n }\n if (!rootElement.contains(event.target)) {\n return false\n }\n\n const payload =\n readInternalDragPayload(event.dataTransfer) ?? getActiveInternalDragPayload(editor)\n if (!payload) {\n clearDropIndicator(editor)\n return false\n }\n\n const scopeId = ensureDropScopeId(editor)\n if (payload.scopeId !== scopeId) {\n clearDropIndicator(editor)\n return false\n }\n\n const dropSlot = resolveDropSlot(editor, event)\n if (dropSlot === null) {\n clearDropIndicator(editor)\n return false\n }\n\n event.preventDefault()\n if (event.dataTransfer) {\n event.dataTransfer.dropEffect = 'move'\n }\n\n showDropIndicator(editor, dropSlot)\n autoScrollWhenNearEdge(rootElement, event.clientY)\n return true\n },\n COMMAND_PRIORITY_EDITOR\n ),\n editor.registerCommand<DragEvent>(\n DROP_COMMAND,\n (event) => {\n const payload =\n readInternalDragPayload(event.dataTransfer) ?? getActiveInternalDragPayload(editor)\n if (!payload) {\n return false\n }\n\n event.preventDefault()\n\n const rootElement = editor.getRootElement()\n const scopeId = ensureDropScopeId(editor)\n if (!rootElement || !scopeId || !(event.target instanceof Node)) {\n clearDragVisualState(editor)\n return true\n }\n if (!rootElement.contains(event.target)) {\n clearDragVisualState(editor)\n return true\n }\n\n const dropSlot = resolveDropSlot(editor, event)\n if (dropSlot === null) {\n clearDragVisualState(editor)\n return true\n }\n\n const payloadText =\n event.dataTransfer?.getData(EXPRESSION_VARIABLE_DRAG_TYPE) ?? JSON.stringify(payload)\n\n reorderVariable(editor, {\n payloadText,\n scopeId,\n targetSlot: dropSlot,\n focusMovedNode: true\n })\n\n clearDragVisualState(editor)\n return true\n },\n COMMAND_PRIORITY_EDITOR\n )\n )\n}\n\nexport interface RegisterCommandPacksOptions {\n /** Optional context-key commands registration (e.g. from use-context). Merged when provided. */\n getContextCommands?: () => () => void\n}\n\n/**\n * Registers all capability command packs for the expression editor.\n * Packs: text-editing, clipboard, drag-drop, and optionally context-keys.\n */\nexport function registerCommandPacks(\n editor: LexicalEditor,\n options?: RegisterCommandPacksOptions\n): () => void {\n const packs: Array<() => void> = [\n registerTextEditingCommands(editor),\n registerClipboardCommands(editor),\n registerDragDropCommands(editor)\n ]\n\n if (options?.getContextCommands) {\n packs.push(options.getContextCommands())\n }\n\n return mergeRegister(...packs)\n}\n"],"mappings":"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"}
|
package/dist/components/expression-editor/internal/features/insertion/insertion-service.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"insertion-service.js","names":[],"sources":["../../../../../../src/components/expression-editor/internal/features/insertion/insertion-service.ts"],"sourcesContent":["import {\n $createTextNode,\n $getNodeByKey,\n $getSelection,\n $isRangeSelection,\n type LexicalEditor\n} from 'lexical'\n\nimport { $createVariableNode } from '../../../nodes/variable-node'\n\nexport interface InsertVariableInput {\n nodeKey: string\n charPosition: number\n variable: { value: string; label: string; type?: string }\n}\n\n/**\n * Typed mutation gateway for variable insertion at @ trigger.\n * Must be called inside editor.update or via a gateway that runs updates.\n */\nexport function insertVariableAtTrigger(\n editor: LexicalEditor,\n input: InsertVariableInput\n): boolean {\n let result = false\n\n editor.update(() => {\n const targetNode = $getNodeByKey(input.nodeKey)\n if (!targetNode) return\n\n const selection = $getSelection()\n if (!$isRangeSelection(selection)) return\n\n const focusNode = selection.focus.getNode()\n if (focusNode.getKey() !== targetNode.getKey()) return\n\n const textContent = targetNode.getTextContent()\n if (!textContent?.includes('@')) return\n\n const pos = input.charPosition\n const newNode = $createVariableNode(\n input.variable.value,\n input.variable.label,\n input.variable.type\n )\n const nodeBefore = $createTextNode(textContent.slice(0, pos - 1))\n const nodeAfter = $createTextNode(textContent.slice(pos))\n targetNode.replace(nodeBefore)\n nodeBefore.insertAfter(newNode)\n newNode.insertAfter(nodeAfter)\n newNode.selectEnd()\n result = true\n })\n\n return result\n}\n"],"mappings":";;;;;;;AAoBA,SAAgB,wBACd,QACA,OACS;CACT,IAAI,SAAS;AAEb,QAAO,aAAa;EAClB,MAAM,aAAa,cAAc,MAAM,QAAQ;AAC/C,MAAI,CAAC,WAAY;EAEjB,MAAM,YAAY,eAAe;AACjC,MAAI,CAAC,kBAAkB,UAAU,CAAE;AAGnC,MADkB,UAAU,MAAM,
|
|
1
|
+
{"version":3,"file":"insertion-service.js","names":[],"sources":["../../../../../../src/components/expression-editor/internal/features/insertion/insertion-service.ts"],"sourcesContent":["import {\n $createTextNode,\n $getNodeByKey,\n $getSelection,\n $isRangeSelection,\n type LexicalEditor\n} from 'lexical'\n\nimport { $createVariableNode } from '../../../nodes/variable-node'\n\nexport interface InsertVariableInput {\n nodeKey: string\n charPosition: number\n variable: { value: string; label: string; type?: string }\n}\n\n/**\n * Typed mutation gateway for variable insertion at @ trigger.\n * Must be called inside editor.update or via a gateway that runs updates.\n */\nexport function insertVariableAtTrigger(\n editor: LexicalEditor,\n input: InsertVariableInput\n): boolean {\n let result = false\n\n editor.update(() => {\n const targetNode = $getNodeByKey(input.nodeKey)\n if (!targetNode) return\n\n const selection = $getSelection()\n if (!$isRangeSelection(selection)) return\n\n const focusNode = selection.focus.getNode()\n if (focusNode.getKey() !== targetNode.getKey()) return\n\n const textContent = targetNode.getTextContent()\n if (!textContent?.includes('@')) return\n\n const pos = input.charPosition\n const newNode = $createVariableNode(\n input.variable.value,\n input.variable.label,\n input.variable.type\n )\n const nodeBefore = $createTextNode(textContent.slice(0, pos - 1))\n const nodeAfter = $createTextNode(textContent.slice(pos))\n targetNode.replace(nodeBefore)\n nodeBefore.insertAfter(newNode)\n newNode.insertAfter(nodeAfter)\n newNode.selectEnd()\n result = true\n })\n\n return result\n}\n"],"mappings":";;;;;;;AAoBA,SAAgB,wBACd,QACA,OACS;CACT,IAAI,SAAS;AAEb,QAAO,aAAa;EAClB,MAAM,aAAa,cAAc,MAAM,QAAQ;AAC/C,MAAI,CAAC,WAAY;EAEjB,MAAM,YAAY,eAAe;AACjC,MAAI,CAAC,kBAAkB,UAAU,CAAE;AAGnC,MADkB,UAAU,MAAM,SACrB,CAAC,QAAQ,KAAK,WAAW,QAAQ,CAAE;EAEhD,MAAM,cAAc,WAAW,gBAAgB;AAC/C,MAAI,CAAC,aAAa,SAAS,IAAI,CAAE;EAEjC,MAAM,MAAM,MAAM;EAClB,MAAM,UAAU,oBACd,MAAM,SAAS,OACf,MAAM,SAAS,OACf,MAAM,SAAS,KAChB;EACD,MAAM,aAAa,gBAAgB,YAAY,MAAM,GAAG,MAAM,EAAE,CAAC;EACjE,MAAM,YAAY,gBAAgB,YAAY,MAAM,IAAI,CAAC;AACzD,aAAW,QAAQ,WAAW;AAC9B,aAAW,YAAY,QAAQ;AAC/B,UAAQ,YAAY,UAAU;AAC9B,UAAQ,WAAW;AACnB,WAAS;GACT;AAEF,QAAO"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-decorators.js","names":["LexicalEditor","DefineComponent","VNode","Teleport","computed","onBeforeUnmount","shallowRef","ComputedRef","isVNode","_isVNode","createVNode","_createVNode","_isSlot","s","Object","prototype","toString","call","useDecorators","editor","decorators","getDecorators","removeListener","registerDecoratorListener","nextDecorators","value","decoratedTeleports","decoratorKeys","keys","forEach","nodeKey","node","element","getElementByKey","push","default"],"sources":["../../../src/components/expression-editor/use-decorators.tsx"],"sourcesContent":["import type { LexicalEditor } from 'lexical'\nimport type { DefineComponent, VNode } from 'vue'\nimport { Teleport, computed, onBeforeUnmount, shallowRef, type ComputedRef } from 'vue'\n\nexport function useDecorators(editor: LexicalEditor): ComputedRef<VNode[]> {\n const decorators = shallowRef(editor.getDecorators<DefineComponent>())\n\n const removeListener = editor.registerDecoratorListener<DefineComponent>((nextDecorators) => {\n decorators.value = nextDecorators\n })\n\n onBeforeUnmount(() => {\n removeListener()\n })\n\n return computed(() => {\n const decoratedTeleports: VNode[] = []\n const decoratorKeys = Object.keys(decorators.value)\n decoratorKeys.forEach((nodeKey) => {\n const node = decorators.value[nodeKey]!\n const element = editor.getElementByKey(nodeKey)\n if (element !== null) {\n decoratedTeleports.push(<Teleport to={element}>{node}</Teleport>)\n }\n })\n\n return decoratedTeleports\n })\n}\n"],"mappings":";;AAEuF,SAAAY,QAAAC,GAAA;AAAA,QAAA,OAAAA,MAAA,cAAAC,OAAAC,UAAAC,SAAAC,KAAAJ,EAAA,KAAA,qBAAA,CAAAJ,QAAAI,EAAA;;AAEvF,SAAgBK,cAAcC,QAA6C;CACzE,MAAMC,aAAad,WAAWa,OAAOE,eAAgC,CAAC;CAEtE,MAAMC,iBAAiBH,OAAOI,2BAA4CC,mBAAmB;AAC3FJ,aAAWK,QAAQD;GACnB;AAEFnB,uBAAsB;AACpBiB,kBAAgB;GAChB;AAEF,QAAOlB,eAAe;EACpB,MAAMsB,qBAA8B,EAAE;AAChBZ,SAAOc,KAAKR,WAAWK,
|
|
1
|
+
{"version":3,"file":"use-decorators.js","names":["LexicalEditor","DefineComponent","VNode","Teleport","computed","onBeforeUnmount","shallowRef","ComputedRef","isVNode","_isVNode","createVNode","_createVNode","_isSlot","s","Object","prototype","toString","call","useDecorators","editor","decorators","getDecorators","removeListener","registerDecoratorListener","nextDecorators","value","decoratedTeleports","decoratorKeys","keys","forEach","nodeKey","node","element","getElementByKey","push","default"],"sources":["../../../src/components/expression-editor/use-decorators.tsx"],"sourcesContent":["import type { LexicalEditor } from 'lexical'\nimport type { DefineComponent, VNode } from 'vue'\nimport { Teleport, computed, onBeforeUnmount, shallowRef, type ComputedRef } from 'vue'\n\nexport function useDecorators(editor: LexicalEditor): ComputedRef<VNode[]> {\n const decorators = shallowRef(editor.getDecorators<DefineComponent>())\n\n const removeListener = editor.registerDecoratorListener<DefineComponent>((nextDecorators) => {\n decorators.value = nextDecorators\n })\n\n onBeforeUnmount(() => {\n removeListener()\n })\n\n return computed(() => {\n const decoratedTeleports: VNode[] = []\n const decoratorKeys = Object.keys(decorators.value)\n decoratorKeys.forEach((nodeKey) => {\n const node = decorators.value[nodeKey]!\n const element = editor.getElementByKey(nodeKey)\n if (element !== null) {\n decoratedTeleports.push(<Teleport to={element}>{node}</Teleport>)\n }\n })\n\n return decoratedTeleports\n })\n}\n"],"mappings":";;AAEuF,SAAAY,QAAAC,GAAA;AAAA,QAAA,OAAAA,MAAA,cAAAC,OAAAC,UAAAC,SAAAC,KAAAJ,EAAA,KAAA,qBAAA,CAAAJ,QAAAI,EAAA;;AAEvF,SAAgBK,cAAcC,QAA6C;CACzE,MAAMC,aAAad,WAAWa,OAAOE,eAAgC,CAAC;CAEtE,MAAMC,iBAAiBH,OAAOI,2BAA4CC,mBAAmB;AAC3FJ,aAAWK,QAAQD;GACnB;AAEFnB,uBAAsB;AACpBiB,kBAAgB;GAChB;AAEF,QAAOlB,eAAe;EACpB,MAAMsB,qBAA8B,EAAE;AAChBZ,SAAOc,KAAKR,WAAWK,MAChC,CAACI,SAASC,YAAY;GACjC,MAAMC,OAAOX,WAAWK,MAAMK;GAC9B,MAAME,UAAUb,OAAOc,gBAAgBH,QAAQ;AAC/C,OAAIE,YAAY,KACdN,oBAAmBQ,KAAIvB,YAAAR,UAAA,EAAA,MAAe6B,SAAO,EAAApB,QAAGmB,KAAI,GAAJA,OAAI,EAAAI,eAAA,CAAJJ,KAAI,EAAA,CAAY,CAAC;IAEnE;AAEF,SAAOL;GACP"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-expression-drag-drop.js","names":[],"sources":["../../../src/components/expression-editor/use-expression-drag-drop.ts"],"sourcesContent":["import { $getNodeByKey, $getRoot, type LexicalEditor, type LexicalNode } from 'lexical'\n\nimport {\n EXPRESSION_DROP_SCOPE_ATTR,\n EXPRESSION_VARIABLE_DRAG_KEY_ATTR,\n EXPRESSION_VARIABLE_DRAG_MARKER_ATTR,\n EXPRESSION_VARIABLE_DRAG_TYPE\n} from './constants'\nimport { VariableNode } from './nodes/variable-node'\n\ntype Direction = -1 | 1\n\ninterface DragVisualState {\n indicatorEl: HTMLDivElement | null\n sourceEl: HTMLElement | null\n cleanupDragEnd: (() => void) | null\n activePayload: InternalDragPayload | null\n}\n\ninterface DropAnchor {\n x: number\n y: number\n height: number\n}\n\nexport interface VariableNodeDescriptor {\n key: string\n variable: string\n label: string\n}\n\nexport interface InternalDragPayload {\n sourceKey: string\n scopeId: string\n action: 'move-variable'\n}\n\nexport interface ApplyDropReorderOptions {\n payloadText: string | null\n scopeId: string\n targetSlot: number\n focusMovedNode?: boolean\n}\n\nconst DROP_INDICATOR_CLASS = 'expression-editor__drop-indicator'\nconst DRAG_SOURCE_CLASS = 'is-dragging'\n\nconst dragVisualStateMap = new WeakMap<LexicalEditor, DragVisualState>()\n\nfunction getDragVisualState(editor: LexicalEditor): DragVisualState {\n const existing = dragVisualStateMap.get(editor)\n if (existing) return existing\n\n const created: DragVisualState = {\n indicatorEl: null,\n sourceEl: null,\n cleanupDragEnd: null,\n activePayload: null\n }\n dragVisualStateMap.set(editor, created)\n return created\n}\n\nfunction isHTMLElement(target: EventTarget | null): target is HTMLElement {\n return target instanceof HTMLElement\n}\n\nfunction hasChildren(\n node: LexicalNode\n): node is LexicalNode & { getChildren: () => LexicalNode[] } {\n return typeof (node as { getChildren?: unknown }).getChildren === 'function'\n}\n\nfunction traverseVariableNodes(node: LexicalNode, collector: VariableNodeDescriptor[]): void {\n if (node instanceof VariableNode) {\n collector.push({ key: node.getKey(), variable: node.getVariable(), label: node.getLabel() })\n return\n }\n\n if (!hasChildren(node)) return\n node.getChildren().forEach((child) => traverseVariableNodes(child, collector))\n}\n\nfunction $collectVariableNodeDescriptors(): VariableNodeDescriptor[] {\n const collector: VariableNodeDescriptor[] = []\n const root = $getRoot()\n traverseVariableNodes(root, collector)\n return collector\n}\n\nfunction getDropIndicator(rootElement: HTMLElement): HTMLDivElement {\n const existing = rootElement.querySelector<HTMLDivElement>(`.${DROP_INDICATOR_CLASS}`)\n if (existing) return existing\n\n const indicator = document.createElement('div')\n indicator.className = DROP_INDICATOR_CLASS\n indicator.style.opacity = '0'\n rootElement.appendChild(indicator)\n return indicator\n}\n\nfunction getDropAnchors(editor: LexicalEditor): DropAnchor[] {\n const descriptors = collectVariableNodeDescriptors(editor)\n if (descriptors.length === 0) return []\n\n const rects = descriptors\n .map((descriptor) => editor.getElementByKey(descriptor.key))\n .filter((element): element is HTMLElement => element instanceof HTMLElement)\n .map((element) => element.getBoundingClientRect())\n\n if (rects.length === 0) return []\n\n const anchors: DropAnchor[] = []\n const first = rects[0]!\n anchors.push({ x: first.left, y: first.top, height: first.height })\n\n for (let index = 0; index < rects.length - 1; index++) {\n const currentRect = rects[index]!\n const nextRect = rects[index + 1]!\n anchors.push({\n x: (currentRect.right + nextRect.left) / 2,\n y: (currentRect.top + nextRect.top) / 2,\n height: Math.max(currentRect.height, nextRect.height)\n })\n }\n\n const last = rects[rects.length - 1]!\n anchors.push({ x: last.right, y: last.top, height: last.height })\n\n return anchors\n}\n\nfunction getDistance(pointerX: number, pointerY: number, anchor: DropAnchor): number {\n const dx = pointerX - anchor.x\n const dy = pointerY - (anchor.y + anchor.height / 2)\n return dx * dx + dy * dy\n}\n\nexport function supportsNativeDnD(): boolean {\n if (typeof window === 'undefined') return false\n\n const probe = document.createElement('span')\n const hasDragApi = 'draggable' in probe && typeof DataTransfer !== 'undefined'\n const coarsePointer = window.matchMedia?.('(pointer: coarse)').matches ?? false\n\n return hasDragApi && !coarsePointer\n}\n\nexport function collectVariableNodeDescriptors(editor: LexicalEditor): VariableNodeDescriptor[] {\n let descriptors: VariableNodeDescriptor[] = []\n editor.getEditorState().read(() => {\n descriptors = $collectVariableNodeDescriptors()\n })\n return descriptors\n}\n\nexport function ensureDropScopeId(editor: LexicalEditor): string {\n const rootElement = editor.getRootElement()\n if (!rootElement) return ''\n\n const existing = rootElement.getAttribute(EXPRESSION_DROP_SCOPE_ATTR)\n if (existing) return existing\n\n const generated = `scope-${Math.random().toString(36).slice(2)}`\n rootElement.setAttribute(EXPRESSION_DROP_SCOPE_ATTR, generated)\n return generated\n}\n\nexport function findVariableDragSource(target: EventTarget | null): HTMLElement | null {\n if (!isHTMLElement(target)) return null\n\n return target.closest<HTMLElement>(`[${EXPRESSION_VARIABLE_DRAG_MARKER_ATTR}=\"true\"]`)\n}\n\nexport function readDragSourceKey(target: EventTarget | null): string | null {\n const source = findVariableDragSource(target)\n if (!source) return null\n\n return source.getAttribute(EXPRESSION_VARIABLE_DRAG_KEY_ATTR)\n}\n\nexport function createInternalDragPayload(payload: InternalDragPayload): string {\n return JSON.stringify(payload)\n}\n\nexport function writeInternalDragPayload(\n dataTransfer: DataTransfer | null,\n payload: InternalDragPayload\n): void {\n if (!dataTransfer) return\n dataTransfer.setData(EXPRESSION_VARIABLE_DRAG_TYPE, createInternalDragPayload(payload))\n}\n\nexport function parseInternalDragPayload(payloadText: string | null): InternalDragPayload | null {\n if (!payloadText) return null\n\n try {\n const parsed = JSON.parse(payloadText) as Partial<InternalDragPayload>\n if (\n parsed.action !== 'move-variable' ||\n typeof parsed.scopeId !== 'string' ||\n parsed.scopeId.length === 0 ||\n typeof parsed.sourceKey !== 'string' ||\n parsed.sourceKey.length === 0\n ) {\n return null\n }\n\n return { action: parsed.action, scopeId: parsed.scopeId, sourceKey: parsed.sourceKey }\n } catch {\n return null\n }\n}\n\nexport function readInternalDragPayload(\n dataTransfer: DataTransfer | null\n): InternalDragPayload | null {\n if (!dataTransfer) return null\n return parseInternalDragPayload(dataTransfer.getData(EXPRESSION_VARIABLE_DRAG_TYPE))\n}\n\nexport function beginDragVisualState(\n editor: LexicalEditor,\n sourceEl: HTMLElement | null,\n payload?: InternalDragPayload\n): void {\n const state = getDragVisualState(editor)\n clearDragVisualState(editor)\n state.activePayload = payload ?? null\n\n if (!sourceEl) return\n sourceEl.classList.add(DRAG_SOURCE_CLASS)\n state.sourceEl = sourceEl\n\n const onDragEnd = () => {\n clearDragVisualState(editor)\n }\n window.addEventListener('dragend', onDragEnd, true)\n state.cleanupDragEnd = () => {\n window.removeEventListener('dragend', onDragEnd, true)\n }\n}\n\nexport function getActiveInternalDragPayload(editor: LexicalEditor): InternalDragPayload | null {\n return getDragVisualState(editor).activePayload\n}\n\nexport function showDropIndicator(editor: LexicalEditor, slot: number): void {\n const rootElement = editor.getRootElement()\n if (!rootElement) return\n\n const anchors = getDropAnchors(editor)\n if (slot < 0 || slot >= anchors.length) {\n clearDropIndicator(editor)\n return\n }\n\n const anchor = anchors[slot]!\n const indicator = getDropIndicator(rootElement)\n const rootRect = rootElement.getBoundingClientRect()\n\n indicator.style.left = `${anchor.x - rootRect.left}px`\n indicator.style.top = `${anchor.y - rootRect.top}px`\n indicator.style.height = `${anchor.height}px`\n indicator.style.opacity = '1'\n\n const state = getDragVisualState(editor)\n state.indicatorEl = indicator\n}\n\nexport function clearDropIndicator(editor: LexicalEditor): void {\n const state = getDragVisualState(editor)\n if (!state.indicatorEl) return\n state.indicatorEl.style.opacity = '0'\n}\n\nexport function clearDragVisualState(editor: LexicalEditor): void {\n const state = getDragVisualState(editor)\n\n if (state.sourceEl) {\n state.sourceEl.classList.remove(DRAG_SOURCE_CLASS)\n state.sourceEl = null\n }\n\n if (state.indicatorEl) {\n state.indicatorEl.style.opacity = '0'\n state.indicatorEl = null\n }\n\n if (state.cleanupDragEnd) {\n state.cleanupDragEnd()\n state.cleanupDragEnd = null\n }\n\n state.activePayload = null\n}\n\nexport function autoScrollWhenNearEdge(container: HTMLElement, pointerY: number): void {\n const rect = container.getBoundingClientRect()\n const threshold = 24\n const step = 10\n\n if (pointerY < rect.top + threshold) {\n container.scrollBy({ top: -step, behavior: 'auto' })\n return\n }\n\n if (pointerY > rect.bottom - threshold) {\n container.scrollBy({ top: step, behavior: 'auto' })\n }\n}\n\nexport function resolveDropSlot(editor: LexicalEditor, event: DragEvent): number | null {\n const rootElement = editor.getRootElement()\n if (!rootElement || !isHTMLElement(event.target)) return null\n if (!rootElement.contains(event.target)) return null\n\n const anchors = getDropAnchors(editor)\n if (anchors.length === 0) return null\n\n let nearestSlot = 0\n let nearestDistance = Number.POSITIVE_INFINITY\n for (let slot = 0; slot < anchors.length; slot++) {\n const anchor = anchors[slot]!\n const distance = getDistance(event.clientX, event.clientY, anchor)\n if (distance < nearestDistance) {\n nearestDistance = distance\n nearestSlot = slot\n }\n }\n\n return nearestSlot\n}\n\nexport function reorderVariableNode(\n sourceKey: string,\n targetSlot: number,\n focusMovedNode = true\n): boolean {\n const nodes = $collectVariableNodeDescriptors()\n if (nodes.length <= 1) return false\n\n const sourceIndex = nodes.findIndex((item) => item.key === sourceKey)\n if (sourceIndex < 0) return false\n if (targetSlot < 0 || targetSlot > nodes.length) return false\n if (targetSlot === sourceIndex || targetSlot === sourceIndex + 1) return false\n\n const sourceNode = $getNodeByKey(sourceKey)\n if (!(sourceNode instanceof VariableNode)) return false\n\n const remaining = nodes.filter((item) => item.key !== sourceKey)\n const insertionIndex = targetSlot > sourceIndex ? targetSlot - 1 : targetSlot\n const reference = remaining[insertionIndex]\n\n if (reference) {\n const referenceNode = $getNodeByKey(reference.key)\n if (!(referenceNode instanceof VariableNode)) return false\n referenceNode.insertBefore(sourceNode)\n } else {\n const last = remaining[remaining.length - 1]\n if (!last) return false\n const lastNode = $getNodeByKey(last.key)\n if (!(lastNode instanceof VariableNode)) return false\n lastNode.insertAfter(sourceNode)\n }\n\n if (focusMovedNode) {\n sourceNode.selectEnd()\n }\n\n return true\n}\n\nexport function moveVariableByDirection(\n sourceKey: string,\n direction: Direction,\n focusMovedNode = true\n): boolean {\n const nodes = $collectVariableNodeDescriptors()\n const sourceIndex = nodes.findIndex((item) => item.key === sourceKey)\n if (sourceIndex < 0) return false\n\n const targetIndex = sourceIndex + direction\n if (targetIndex < 0 || targetIndex >= nodes.length) return false\n\n const targetSlot = direction === -1 ? targetIndex : targetIndex + 1\n return reorderVariableNode(sourceKey, targetSlot, focusMovedNode)\n}\n\nexport function applyDropReorder(options: ApplyDropReorderOptions): boolean {\n const payload = parseInternalDragPayload(options.payloadText)\n if (!payload) return false\n if (payload.scopeId !== options.scopeId) return false\n\n return reorderVariableNode(payload.sourceKey, options.targetSlot, options.focusMovedNode ?? true)\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"use-expression-drag-drop.js","names":[],"sources":["../../../src/components/expression-editor/use-expression-drag-drop.ts"],"sourcesContent":["import { $getNodeByKey, $getRoot, type LexicalEditor, type LexicalNode } from 'lexical'\n\nimport {\n EXPRESSION_DROP_SCOPE_ATTR,\n EXPRESSION_VARIABLE_DRAG_KEY_ATTR,\n EXPRESSION_VARIABLE_DRAG_MARKER_ATTR,\n EXPRESSION_VARIABLE_DRAG_TYPE\n} from './constants'\nimport { VariableNode } from './nodes/variable-node'\n\ntype Direction = -1 | 1\n\ninterface DragVisualState {\n indicatorEl: HTMLDivElement | null\n sourceEl: HTMLElement | null\n cleanupDragEnd: (() => void) | null\n activePayload: InternalDragPayload | null\n}\n\ninterface DropAnchor {\n x: number\n y: number\n height: number\n}\n\nexport interface VariableNodeDescriptor {\n key: string\n variable: string\n label: string\n}\n\nexport interface InternalDragPayload {\n sourceKey: string\n scopeId: string\n action: 'move-variable'\n}\n\nexport interface ApplyDropReorderOptions {\n payloadText: string | null\n scopeId: string\n targetSlot: number\n focusMovedNode?: boolean\n}\n\nconst DROP_INDICATOR_CLASS = 'expression-editor__drop-indicator'\nconst DRAG_SOURCE_CLASS = 'is-dragging'\n\nconst dragVisualStateMap = new WeakMap<LexicalEditor, DragVisualState>()\n\nfunction getDragVisualState(editor: LexicalEditor): DragVisualState {\n const existing = dragVisualStateMap.get(editor)\n if (existing) return existing\n\n const created: DragVisualState = {\n indicatorEl: null,\n sourceEl: null,\n cleanupDragEnd: null,\n activePayload: null\n }\n dragVisualStateMap.set(editor, created)\n return created\n}\n\nfunction isHTMLElement(target: EventTarget | null): target is HTMLElement {\n return target instanceof HTMLElement\n}\n\nfunction hasChildren(\n node: LexicalNode\n): node is LexicalNode & { getChildren: () => LexicalNode[] } {\n return typeof (node as { getChildren?: unknown }).getChildren === 'function'\n}\n\nfunction traverseVariableNodes(node: LexicalNode, collector: VariableNodeDescriptor[]): void {\n if (node instanceof VariableNode) {\n collector.push({ key: node.getKey(), variable: node.getVariable(), label: node.getLabel() })\n return\n }\n\n if (!hasChildren(node)) return\n node.getChildren().forEach((child) => traverseVariableNodes(child, collector))\n}\n\nfunction $collectVariableNodeDescriptors(): VariableNodeDescriptor[] {\n const collector: VariableNodeDescriptor[] = []\n const root = $getRoot()\n traverseVariableNodes(root, collector)\n return collector\n}\n\nfunction getDropIndicator(rootElement: HTMLElement): HTMLDivElement {\n const existing = rootElement.querySelector<HTMLDivElement>(`.${DROP_INDICATOR_CLASS}`)\n if (existing) return existing\n\n const indicator = document.createElement('div')\n indicator.className = DROP_INDICATOR_CLASS\n indicator.style.opacity = '0'\n rootElement.appendChild(indicator)\n return indicator\n}\n\nfunction getDropAnchors(editor: LexicalEditor): DropAnchor[] {\n const descriptors = collectVariableNodeDescriptors(editor)\n if (descriptors.length === 0) return []\n\n const rects = descriptors\n .map((descriptor) => editor.getElementByKey(descriptor.key))\n .filter((element): element is HTMLElement => element instanceof HTMLElement)\n .map((element) => element.getBoundingClientRect())\n\n if (rects.length === 0) return []\n\n const anchors: DropAnchor[] = []\n const first = rects[0]!\n anchors.push({ x: first.left, y: first.top, height: first.height })\n\n for (let index = 0; index < rects.length - 1; index++) {\n const currentRect = rects[index]!\n const nextRect = rects[index + 1]!\n anchors.push({\n x: (currentRect.right + nextRect.left) / 2,\n y: (currentRect.top + nextRect.top) / 2,\n height: Math.max(currentRect.height, nextRect.height)\n })\n }\n\n const last = rects[rects.length - 1]!\n anchors.push({ x: last.right, y: last.top, height: last.height })\n\n return anchors\n}\n\nfunction getDistance(pointerX: number, pointerY: number, anchor: DropAnchor): number {\n const dx = pointerX - anchor.x\n const dy = pointerY - (anchor.y + anchor.height / 2)\n return dx * dx + dy * dy\n}\n\nexport function supportsNativeDnD(): boolean {\n if (typeof window === 'undefined') return false\n\n const probe = document.createElement('span')\n const hasDragApi = 'draggable' in probe && typeof DataTransfer !== 'undefined'\n const coarsePointer = window.matchMedia?.('(pointer: coarse)').matches ?? false\n\n return hasDragApi && !coarsePointer\n}\n\nexport function collectVariableNodeDescriptors(editor: LexicalEditor): VariableNodeDescriptor[] {\n let descriptors: VariableNodeDescriptor[] = []\n editor.getEditorState().read(() => {\n descriptors = $collectVariableNodeDescriptors()\n })\n return descriptors\n}\n\nexport function ensureDropScopeId(editor: LexicalEditor): string {\n const rootElement = editor.getRootElement()\n if (!rootElement) return ''\n\n const existing = rootElement.getAttribute(EXPRESSION_DROP_SCOPE_ATTR)\n if (existing) return existing\n\n const generated = `scope-${Math.random().toString(36).slice(2)}`\n rootElement.setAttribute(EXPRESSION_DROP_SCOPE_ATTR, generated)\n return generated\n}\n\nexport function findVariableDragSource(target: EventTarget | null): HTMLElement | null {\n if (!isHTMLElement(target)) return null\n\n return target.closest<HTMLElement>(`[${EXPRESSION_VARIABLE_DRAG_MARKER_ATTR}=\"true\"]`)\n}\n\nexport function readDragSourceKey(target: EventTarget | null): string | null {\n const source = findVariableDragSource(target)\n if (!source) return null\n\n return source.getAttribute(EXPRESSION_VARIABLE_DRAG_KEY_ATTR)\n}\n\nexport function createInternalDragPayload(payload: InternalDragPayload): string {\n return JSON.stringify(payload)\n}\n\nexport function writeInternalDragPayload(\n dataTransfer: DataTransfer | null,\n payload: InternalDragPayload\n): void {\n if (!dataTransfer) return\n dataTransfer.setData(EXPRESSION_VARIABLE_DRAG_TYPE, createInternalDragPayload(payload))\n}\n\nexport function parseInternalDragPayload(payloadText: string | null): InternalDragPayload | null {\n if (!payloadText) return null\n\n try {\n const parsed = JSON.parse(payloadText) as Partial<InternalDragPayload>\n if (\n parsed.action !== 'move-variable' ||\n typeof parsed.scopeId !== 'string' ||\n parsed.scopeId.length === 0 ||\n typeof parsed.sourceKey !== 'string' ||\n parsed.sourceKey.length === 0\n ) {\n return null\n }\n\n return { action: parsed.action, scopeId: parsed.scopeId, sourceKey: parsed.sourceKey }\n } catch {\n return null\n }\n}\n\nexport function readInternalDragPayload(\n dataTransfer: DataTransfer | null\n): InternalDragPayload | null {\n if (!dataTransfer) return null\n return parseInternalDragPayload(dataTransfer.getData(EXPRESSION_VARIABLE_DRAG_TYPE))\n}\n\nexport function beginDragVisualState(\n editor: LexicalEditor,\n sourceEl: HTMLElement | null,\n payload?: InternalDragPayload\n): void {\n const state = getDragVisualState(editor)\n clearDragVisualState(editor)\n state.activePayload = payload ?? null\n\n if (!sourceEl) return\n sourceEl.classList.add(DRAG_SOURCE_CLASS)\n state.sourceEl = sourceEl\n\n const onDragEnd = () => {\n clearDragVisualState(editor)\n }\n window.addEventListener('dragend', onDragEnd, true)\n state.cleanupDragEnd = () => {\n window.removeEventListener('dragend', onDragEnd, true)\n }\n}\n\nexport function getActiveInternalDragPayload(editor: LexicalEditor): InternalDragPayload | null {\n return getDragVisualState(editor).activePayload\n}\n\nexport function showDropIndicator(editor: LexicalEditor, slot: number): void {\n const rootElement = editor.getRootElement()\n if (!rootElement) return\n\n const anchors = getDropAnchors(editor)\n if (slot < 0 || slot >= anchors.length) {\n clearDropIndicator(editor)\n return\n }\n\n const anchor = anchors[slot]!\n const indicator = getDropIndicator(rootElement)\n const rootRect = rootElement.getBoundingClientRect()\n\n indicator.style.left = `${anchor.x - rootRect.left}px`\n indicator.style.top = `${anchor.y - rootRect.top}px`\n indicator.style.height = `${anchor.height}px`\n indicator.style.opacity = '1'\n\n const state = getDragVisualState(editor)\n state.indicatorEl = indicator\n}\n\nexport function clearDropIndicator(editor: LexicalEditor): void {\n const state = getDragVisualState(editor)\n if (!state.indicatorEl) return\n state.indicatorEl.style.opacity = '0'\n}\n\nexport function clearDragVisualState(editor: LexicalEditor): void {\n const state = getDragVisualState(editor)\n\n if (state.sourceEl) {\n state.sourceEl.classList.remove(DRAG_SOURCE_CLASS)\n state.sourceEl = null\n }\n\n if (state.indicatorEl) {\n state.indicatorEl.style.opacity = '0'\n state.indicatorEl = null\n }\n\n if (state.cleanupDragEnd) {\n state.cleanupDragEnd()\n state.cleanupDragEnd = null\n }\n\n state.activePayload = null\n}\n\nexport function autoScrollWhenNearEdge(container: HTMLElement, pointerY: number): void {\n const rect = container.getBoundingClientRect()\n const threshold = 24\n const step = 10\n\n if (pointerY < rect.top + threshold) {\n container.scrollBy({ top: -step, behavior: 'auto' })\n return\n }\n\n if (pointerY > rect.bottom - threshold) {\n container.scrollBy({ top: step, behavior: 'auto' })\n }\n}\n\nexport function resolveDropSlot(editor: LexicalEditor, event: DragEvent): number | null {\n const rootElement = editor.getRootElement()\n if (!rootElement || !isHTMLElement(event.target)) return null\n if (!rootElement.contains(event.target)) return null\n\n const anchors = getDropAnchors(editor)\n if (anchors.length === 0) return null\n\n let nearestSlot = 0\n let nearestDistance = Number.POSITIVE_INFINITY\n for (let slot = 0; slot < anchors.length; slot++) {\n const anchor = anchors[slot]!\n const distance = getDistance(event.clientX, event.clientY, anchor)\n if (distance < nearestDistance) {\n nearestDistance = distance\n nearestSlot = slot\n }\n }\n\n return nearestSlot\n}\n\nexport function reorderVariableNode(\n sourceKey: string,\n targetSlot: number,\n focusMovedNode = true\n): boolean {\n const nodes = $collectVariableNodeDescriptors()\n if (nodes.length <= 1) return false\n\n const sourceIndex = nodes.findIndex((item) => item.key === sourceKey)\n if (sourceIndex < 0) return false\n if (targetSlot < 0 || targetSlot > nodes.length) return false\n if (targetSlot === sourceIndex || targetSlot === sourceIndex + 1) return false\n\n const sourceNode = $getNodeByKey(sourceKey)\n if (!(sourceNode instanceof VariableNode)) return false\n\n const remaining = nodes.filter((item) => item.key !== sourceKey)\n const insertionIndex = targetSlot > sourceIndex ? targetSlot - 1 : targetSlot\n const reference = remaining[insertionIndex]\n\n if (reference) {\n const referenceNode = $getNodeByKey(reference.key)\n if (!(referenceNode instanceof VariableNode)) return false\n referenceNode.insertBefore(sourceNode)\n } else {\n const last = remaining[remaining.length - 1]\n if (!last) return false\n const lastNode = $getNodeByKey(last.key)\n if (!(lastNode instanceof VariableNode)) return false\n lastNode.insertAfter(sourceNode)\n }\n\n if (focusMovedNode) {\n sourceNode.selectEnd()\n }\n\n return true\n}\n\nexport function moveVariableByDirection(\n sourceKey: string,\n direction: Direction,\n focusMovedNode = true\n): boolean {\n const nodes = $collectVariableNodeDescriptors()\n const sourceIndex = nodes.findIndex((item) => item.key === sourceKey)\n if (sourceIndex < 0) return false\n\n const targetIndex = sourceIndex + direction\n if (targetIndex < 0 || targetIndex >= nodes.length) return false\n\n const targetSlot = direction === -1 ? targetIndex : targetIndex + 1\n return reorderVariableNode(sourceKey, targetSlot, focusMovedNode)\n}\n\nexport function applyDropReorder(options: ApplyDropReorderOptions): boolean {\n const payload = parseInternalDragPayload(options.payloadText)\n if (!payload) return false\n if (payload.scopeId !== options.scopeId) return false\n\n return reorderVariableNode(payload.sourceKey, options.targetSlot, options.focusMovedNode ?? true)\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-picker.js","names":[],"sources":["../../../src/components/file-picker/file-picker.vue"],"sourcesContent":["<template>\n <component\n :is=\"tag\"\n :class=\"cls.b\"\n @click.stop=\"handleClickPicker\"\n @dragover.prevent=\"handleDragover\"\n @dragleave=\"handleDragLeave\"\n @drop.prevent=\"handleDrop\"\n >\n <input\n :multiple=\"multiple\"\n :class=\"cls.e('native')\"\n type=\"file\"\n :accept=\"accept\"\n hidden\n placeholder=\"选择文件\"\n ref=\"fileRef\"\n @change=\"handleChange\"\n capture=\"environment\"\n />\n <slot :is-dragover=\"isDragover\" />\n </component>\n</template>\n\n<script lang=\"ts\" setup>\nimport { bem } from '@veltra/utils'\nimport { shallowRef, ref } from 'vue'\n\nimport type { UploaderProps, UploaderEmits } from '../../types'\nimport { matchAccept } from './helper'\n\ndefineOptions({\n name: 'FilePicker'\n})\n\nconst props = withDefaults(defineProps<UploaderProps>(), {\n tag: 'div',\n multiple: false\n})\n\nconst emit = defineEmits<UploaderEmits>()\n\nconst cls = bem('file-picker')\n\nconst fileRef = shallowRef<HTMLInputElement>()\nconst isDragover = ref(false)\n\nconst processFiles = (files: File[]) => {\n const filteredFiles = files.filter((file) => matchAccept(file, props.accept))\n emit('pick', filteredFiles)\n}\n\nconst handleChange = (e: Event) => {\n const target = e.target as HTMLInputElement\n const files = Array.from(target.files || [])\n processFiles(files)\n target.value = ''\n}\n\nconst handleDragover = (e: DragEvent) => {\n if (props.disabled) return\n isDragover.value = true\n}\n\nconst handleDragLeave = (e: DragEvent) => {\n if (props.disabled) return\n const currentTarget = e.currentTarget as HTMLElement\n const relatedTarget = e.relatedTarget as HTMLElement | null\n\n if (currentTarget.contains(relatedTarget)) return\n isDragover.value = false\n}\n\nconst handleDrop = (e: DragEvent) => {\n if (props.disabled) return\n isDragover.value = false\n const files = Array.from(e.dataTransfer?.files || [])\n processFiles(files)\n}\n\nfunction handleClickPicker() {\n if (props.disabled) return\n fileRef.value?.click()\n}\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;EAmCA,MAAM,QAAQ;EAKd,MAAM,OAAO;EAEb,MAAM,MAAM,IAAI,cAAa;EAE7B,MAAM,UAAU,YAA6B;EAC7C,MAAM,aAAa,IAAI,MAAK;EAE5B,MAAM,gBAAgB,UAAkB;AAEtC,QAAK,QADiB,MAAM,QAAQ,SAAS,YAAY,MAAM,MAAM,OAAO,
|
|
1
|
+
{"version":3,"file":"file-picker.js","names":[],"sources":["../../../src/components/file-picker/file-picker.vue"],"sourcesContent":["<template>\n <component\n :is=\"tag\"\n :class=\"cls.b\"\n @click.stop=\"handleClickPicker\"\n @dragover.prevent=\"handleDragover\"\n @dragleave=\"handleDragLeave\"\n @drop.prevent=\"handleDrop\"\n >\n <input\n :multiple=\"multiple\"\n :class=\"cls.e('native')\"\n type=\"file\"\n :accept=\"accept\"\n hidden\n placeholder=\"选择文件\"\n ref=\"fileRef\"\n @change=\"handleChange\"\n capture=\"environment\"\n />\n <slot :is-dragover=\"isDragover\" />\n </component>\n</template>\n\n<script lang=\"ts\" setup>\nimport { bem } from '@veltra/utils'\nimport { shallowRef, ref } from 'vue'\n\nimport type { UploaderProps, UploaderEmits } from '../../types'\nimport { matchAccept } from './helper'\n\ndefineOptions({\n name: 'FilePicker'\n})\n\nconst props = withDefaults(defineProps<UploaderProps>(), {\n tag: 'div',\n multiple: false\n})\n\nconst emit = defineEmits<UploaderEmits>()\n\nconst cls = bem('file-picker')\n\nconst fileRef = shallowRef<HTMLInputElement>()\nconst isDragover = ref(false)\n\nconst processFiles = (files: File[]) => {\n const filteredFiles = files.filter((file) => matchAccept(file, props.accept))\n emit('pick', filteredFiles)\n}\n\nconst handleChange = (e: Event) => {\n const target = e.target as HTMLInputElement\n const files = Array.from(target.files || [])\n processFiles(files)\n target.value = ''\n}\n\nconst handleDragover = (e: DragEvent) => {\n if (props.disabled) return\n isDragover.value = true\n}\n\nconst handleDragLeave = (e: DragEvent) => {\n if (props.disabled) return\n const currentTarget = e.currentTarget as HTMLElement\n const relatedTarget = e.relatedTarget as HTMLElement | null\n\n if (currentTarget.contains(relatedTarget)) return\n isDragover.value = false\n}\n\nconst handleDrop = (e: DragEvent) => {\n if (props.disabled) return\n isDragover.value = false\n const files = Array.from(e.dataTransfer?.files || [])\n processFiles(files)\n}\n\nfunction handleClickPicker() {\n if (props.disabled) return\n fileRef.value?.click()\n}\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;EAmCA,MAAM,QAAQ;EAKd,MAAM,OAAO;EAEb,MAAM,MAAM,IAAI,cAAa;EAE7B,MAAM,UAAU,YAA6B;EAC7C,MAAM,aAAa,IAAI,MAAK;EAE5B,MAAM,gBAAgB,UAAkB;AAEtC,QAAK,QADiB,MAAM,QAAQ,SAAS,YAAY,MAAM,MAAM,OAAO,CAC/D,CAAa;;EAG5B,MAAM,gBAAgB,MAAa;GACjC,MAAM,SAAS,EAAE;AAEjB,gBADc,MAAM,KAAK,OAAO,SAAS,EAAE,CAC9B,CAAK;AAClB,UAAO,QAAQ;;EAGjB,MAAM,kBAAkB,MAAiB;AACvC,OAAI,MAAM,SAAU;AACpB,cAAW,QAAQ;;EAGrB,MAAM,mBAAmB,MAAiB;AACxC,OAAI,MAAM,SAAU;GACpB,MAAM,gBAAgB,EAAE;GACxB,MAAM,gBAAgB,EAAE;AAExB,OAAI,cAAc,SAAS,cAAc,CAAE;AAC3C,cAAW,QAAQ;;EAGrB,MAAM,cAAc,MAAiB;AACnC,OAAI,MAAM,SAAU;AACpB,cAAW,QAAQ;AAEnB,gBADc,MAAM,KAAK,EAAE,cAAc,SAAS,EAAE,CACvC,CAAK;;EAGpB,SAAS,oBAAoB;AAC3B,OAAI,MAAM,SAAU;AACpB,WAAQ,OAAO,OAAM;;;uBAjFrB,YAoBY,wBAnBL,QAAA,IAAG,EAAA;IACP,OAAK,eAAE,MAAA,IAAG,CAAC,EAAC;IACZ,SAAK,cAAO,mBAAiB,CAAA,OAAA,CAAA;IAC7B,YAAQ,cAAU,gBAAc,CAAA,UAAA,CAAA;IAChC,aAAW;IACX,QAAI,cAAU,YAAU,CAAA,UAAA,CAAA;;2BAYvB,CAVF,mBAUE,SAAA;KATC,UAAU,QAAA;KACV,OAAK,eAAE,MAAA,IAAG,CAAC,EAAC,SAAA,CAAA;KACb,MAAK;KACJ,QAAQ,QAAA;KACT,QAAA;KACA,aAAY;cACR;KAAJ,KAAI;KACH,UAAQ;KACT,SAAQ;8BAEV,WAAkC,KAAA,QAAA,WAAA,EAA3B,YAAa,WAAA,OAAU,CAAA,CAAA,CAAA"}
|
|
@@ -13,8 +13,8 @@ declare const __VLS_base: _$vue.DefineComponent<UploaderProps, {}, {}, {}, {}, _
|
|
|
13
13
|
}, string, _$vue.PublicProps, Readonly<UploaderProps> & Readonly<{
|
|
14
14
|
onPick?: ((files: File[]) => any) | undefined;
|
|
15
15
|
}>, {
|
|
16
|
-
multiple: boolean;
|
|
17
16
|
tag: string;
|
|
17
|
+
multiple: boolean;
|
|
18
18
|
}, {}, {}, {}, string, _$vue.ComponentProvideOptions, false, {}, any>;
|
|
19
19
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
20
20
|
declare const _default: typeof __VLS_export;
|
|
@@ -1,17 +1,29 @@
|
|
|
1
1
|
//#region src/components/file-picker/helper.ts
|
|
2
2
|
/**
|
|
3
|
-
* 校验文件是否匹配 accept
|
|
4
|
-
*
|
|
5
|
-
*
|
|
3
|
+
* 校验文件是否匹配 accept 字符串(支持 MIME 类型与通配符)。
|
|
4
|
+
*
|
|
5
|
+
* 支持的形式:
|
|
6
|
+
* - `*` / `*\/*`:接受所有文件
|
|
7
|
+
* - `image/*`:MIME 类型组匹配
|
|
8
|
+
* - `application/pdf`:精确 MIME 类型
|
|
9
|
+
* - `.pdf` / `.docx`:扩展名匹配(不区分大小写)
|
|
10
|
+
*
|
|
11
|
+
* 多个值以逗号分隔,命中任一即视为匹配。
|
|
6
12
|
*/
|
|
7
13
|
function matchAccept(file, accept) {
|
|
8
14
|
if (!accept) return true;
|
|
9
15
|
const fileType = file.type.toLowerCase();
|
|
10
|
-
|
|
16
|
+
const fileName = file.name.toLowerCase();
|
|
17
|
+
const acceptList = accept.split(",").map((item) => item.trim().toLowerCase()).filter(Boolean);
|
|
18
|
+
if (!acceptList.length) return true;
|
|
19
|
+
return acceptList.some((item) => {
|
|
20
|
+
if (item === "*" || item === "*/*") return true;
|
|
21
|
+
if (item.startsWith(".")) return fileName.endsWith(item);
|
|
11
22
|
if (item.endsWith("/*")) {
|
|
12
|
-
const group = item.
|
|
13
|
-
return fileType.startsWith(group);
|
|
14
|
-
}
|
|
23
|
+
const group = item.slice(0, -2);
|
|
24
|
+
return fileType.startsWith(`${group}/`);
|
|
25
|
+
}
|
|
26
|
+
return fileType === item;
|
|
15
27
|
});
|
|
16
28
|
}
|
|
17
29
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helper.js","names":[],"sources":["../../../src/components/file-picker/helper.ts"],"sourcesContent":["/**\n * 校验文件是否匹配 accept
|
|
1
|
+
{"version":3,"file":"helper.js","names":[],"sources":["../../../src/components/file-picker/helper.ts"],"sourcesContent":["/**\n * 校验文件是否匹配 accept 字符串(支持 MIME 类型与通配符)。\n *\n * 支持的形式:\n * - `*` / `*\\/*`:接受所有文件\n * - `image/*`:MIME 类型组匹配\n * - `application/pdf`:精确 MIME 类型\n * - `.pdf` / `.docx`:扩展名匹配(不区分大小写)\n *\n * 多个值以逗号分隔,命中任一即视为匹配。\n */\nexport function matchAccept(file: File, accept?: string): boolean {\n if (!accept) return true\n\n const fileType = file.type.toLowerCase()\n const fileName = file.name.toLowerCase()\n const acceptList = accept\n .split(',')\n .map((item) => item.trim().toLowerCase())\n .filter(Boolean)\n\n if (!acceptList.length) return true\n\n return acceptList.some((item) => {\n if (item === '*' || item === '*/*') return true\n if (item.startsWith('.')) return fileName.endsWith(item)\n if (item.endsWith('/*')) {\n const group = item.slice(0, -2)\n return fileType.startsWith(`${group}/`)\n }\n return fileType === item\n })\n}\n"],"mappings":";;;;;;;;;;;;AAWA,SAAgB,YAAY,MAAY,QAA0B;AAChE,KAAI,CAAC,OAAQ,QAAO;CAEpB,MAAM,WAAW,KAAK,KAAK,aAAa;CACxC,MAAM,WAAW,KAAK,KAAK,aAAa;CACxC,MAAM,aAAa,OAChB,MAAM,IAAI,CACV,KAAK,SAAS,KAAK,MAAM,CAAC,aAAa,CAAC,CACxC,OAAO,QAAQ;AAElB,KAAI,CAAC,WAAW,OAAQ,QAAO;AAE/B,QAAO,WAAW,MAAM,SAAS;AAC/B,MAAI,SAAS,OAAO,SAAS,MAAO,QAAO;AAC3C,MAAI,KAAK,WAAW,IAAI,CAAE,QAAO,SAAS,SAAS,KAAK;AACxD,MAAI,KAAK,SAAS,KAAK,EAAE;GACvB,MAAM,QAAQ,KAAK,MAAM,GAAG,GAAG;AAC/B,UAAO,SAAS,WAAW,GAAG,MAAM,GAAG;;AAEzC,SAAO,aAAa;GACpB"}
|