@veltra/desktop 1.0.9 → 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/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/style.js +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/cascade/cascade.vue.d.ts +5 -5
- 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/drawer/drawer.js.map +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-viewer/previewers/sheet-previewer.js.map +1 -1
- 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/input/input.vue.d.ts +2 -2
- 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.js.map +1 -1
- package/dist/components/multi-select/multi-select.vue.d.ts +3 -3
- package/dist/components/multi-tree-select/multi-tree-select.vue.d.ts +5 -5
- package/dist/components/notification/index.js.map +1 -1
- package/dist/components/number-input/number-input.js.map +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/palette-sv.js.map +1 -1
- package/dist/components/pop-confirm/pop-confirm.vue.d.ts +1 -1
- 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/progress-nodes/progress-nodes.vue.d.ts +3 -3
- 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.vue.d.ts +2 -2
- package/dist/components/slider/slider-thumb.js.map +1 -1
- package/dist/components/table/di.js.map +1 -1
- package/dist/components/table/style.js +1 -1
- package/dist/components/table/table-row.js +1 -2
- package/dist/components/table/table-row.js.map +1 -1
- package/dist/components/table/table.js +1 -2
- 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-table.js +25 -0
- package/dist/components/table/use-table.js.map +1 -1
- package/dist/components/tabs/style2.css +3 -2
- package/dist/components/tabs/tabs-horizontal.js +2 -2
- package/dist/components/tabs/tabs-horizontal.js.map +1 -1
- package/dist/components/tabs/tabs-horizontal.vue.d.ts +14 -3
- package/dist/components/tabs/tabs-vertical.js +2 -2
- package/dist/components/tabs/tabs-vertical.js.map +1 -1
- package/dist/components/tabs/tabs-vertical.vue.d.ts +13 -3
- package/dist/components/tabs/tabs.vue.d.ts +2 -2
- 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 +3 -3
- package/dist/components/theme/theme.js.map +1 -1
- package/dist/components/tip/tip.vue.d.ts +1 -1
- package/dist/components/tree/tree-node2.js.map +1 -1
- package/dist/components/tree/tree.vue.d.ts +4 -4
- package/dist/components/tree/use-tree-nodes.js.map +1 -1
- package/dist/components/tree-select/tree-select.vue.d.ts +5 -5
- package/dist/components/watermark/watermark.vue.d.ts +1 -1
- package/package.json +11 -11
- package/src/components/progress/progress.vue +1 -1
- package/src/components/table/di.ts +51 -53
- package/src/components/table/table.vue +0 -1
- package/src/components/tabs/style.scss +7 -4
- package/src/components/tabs/tabs-horizontal.vue +10 -7
- package/src/components/tabs/tabs-vertical.vue +3 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"batch-edit.js","names":[],"sources":["../../../src/components/batch-edit/batch-edit.vue"],"sourcesContent":["<template>\n <u-layout :class=\"cls.b\" :cols=\"cols\" rows=\"100%\" gap=\"8px\" resizable @keyup.esc=\"handleClose\">\n <!-- 编辑列表 -->\n <BatchEditList :slots=\"slots\" />\n\n <!-- 编辑表单 -->\n <BatchEditForm v-slot=\"scoped\">\n <!-- @vue-ignore -->\n <slot name=\"form\" v-bind=\"scoped\" />\n </BatchEditForm>\n </u-layout>\n</template>\n\n<script lang=\"ts\" setup generic=\"Model extends FormModel\">\nimport { bem } from '@veltra/utils'\nimport { computed, inject, provide, shallowRef, watch } from 'vue'\n\nimport type {\n BatchEditEmits,\n BatchEditFeature,\n BatchEditProps,\n TableColumnSlotsScope,\n TableExposed,\n TableRow\n} from '../../types'\nimport { DialogDIKey } from '../dialog/di'\nimport type { FormModel } from '../form'\nimport { ULayout } from '../layout'\nimport BatchEditForm from './batch-edit-form.vue'\nimport BatchEditList from './batch-edit-list.vue'\nimport { BatchEditDIKey } from './di'\nimport { useEdit } from './use-edit'\n\ndefineOptions({ name: 'BatchEdit' })\n\nconst props = withDefaults(defineProps<BatchEditProps<Model>>(), {\n cols: () => ['1fr', '400px'],\n mode: 'normal'\n})\n\nconst emit = defineEmits<BatchEditEmits>()\n\nconst staticFeatures = computed(() => {\n const { features } = props\n\n if (Array.isArray(features)) {\n return new Set(features)\n }\n\n const defaultFeatures = new Set<BatchEditFeature>(['create', 'delete', 'update', 'createChild'])\n\n if (!features) {\n return defaultFeatures\n }\n\n // 排除函数和false的部分\n Object.entries(features).forEach(([key, value]) => {\n if (typeof value === 'function' || value === false) {\n defaultFeatures.delete(key as BatchEditFeature)\n }\n })\n return defaultFeatures\n})\n\nconst dynamicFeatures = computed<\n Record<BatchEditFeature, ((row?: TableRow) => boolean) | undefined>\n>(() => {\n const { features } = props\n if (!Array.isArray(features) && typeof features === 'object') {\n const ret = Object.entries(features)\n .filter(([_, value]) => {\n return typeof value === 'function'\n })\n .reduce(\n (acc, [key, value]) => {\n acc[key] = value\n return acc\n },\n {} as Record<BatchEditFeature, (row?: TableRow) => boolean>\n )\n return ret\n }\n\n return {} as Record<BatchEditFeature, ((row?: TableRow) => boolean) | undefined>\n})\n\nconst slots = defineSlots<\n {\n form?: (props: {\n /** 表单数据 */\n data: Model['data']\n /** 表单模型 */\n model: Model\n /** 当前编辑的层级 */\n depth?: number\n /** 当前编辑的行 */\n row?: TableRow\n /** 当前编辑的行索引 */\n index?: number\n /** 操作的目标行索引路径 */\n indexes?: number[]\n }) => any\n\n header?: () => any\n } & Partial<{\n [key: `column:${string}`]: (props: TableColumnSlotsScope) => any\n }>\n>()\n\nconst cls = bem('batch-edit')\n\nconst tableRef = shallowRef<TableExposed>()\n\nconst editCtx = useEdit({ props, emit, tableRef })\n\nconst { state, handleClose } = editCtx\n\nprovide(BatchEditDIKey, {\n cls,\n props,\n emit,\n tableRef,\n staticFeatures,\n dynamicFeatures,\n ...editCtx\n})\n\nconst dialogCtx = inject(DialogDIKey, undefined)\n\n// 如果在dialog上下文中\ndialogCtx &&\n watch(dialogCtx.visible, (visible) => {\n !visible && editCtx.handleClose()\n })\n\nconst cols = computed(() => {\n return !!state.row || state.visible ? props.cols : undefined\n})\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmCA,MAAM,QAAQ;EAKd,MAAM,OAAO;EAEb,MAAM,iBAAiB,eAAe;GACpC,MAAM,EAAE,aAAa;AAErB,OAAI,MAAM,QAAQ,SAAS,CACzB,QAAO,IAAI,IAAI,SAAQ;GAGzB,MAAM,kBAAkB,IAAI,IAAsB;IAAC;IAAU;IAAU;IAAU;IAAc,CAAA;AAE/F,OAAI,CAAC,SACH,QAAO;AAIT,UAAO,QAAQ,SAAS,CAAC,SAAS,CAAC,KAAK,WAAW;AACjD,QAAI,OAAO,UAAU,cAAc,UAAU,MAC3C,iBAAgB,OAAO,IAAuB;KAEjD;AACD,UAAO;IACR;EAED,MAAM,kBAAkB,eAEhB;GACN,MAAM,EAAE,aAAa;AACrB,OAAI,CAAC,MAAM,QAAQ,SAAS,IAAI,OAAO,aAAa,SAYlD,QAXY,OAAO,QAAQ,SAAQ,CAChC,QAAQ,CAAC,GAAG,WAAW;AACtB,WAAO,OAAO,UAAU;KACzB,CACA,QACE,KAAK,CAAC,KAAK,WAAW;AACrB,QAAI,OAAO;AACX,WAAO;MAET,EAAE,
|
|
1
|
+
{"version":3,"file":"batch-edit.js","names":[],"sources":["../../../src/components/batch-edit/batch-edit.vue"],"sourcesContent":["<template>\n <u-layout :class=\"cls.b\" :cols=\"cols\" rows=\"100%\" gap=\"8px\" resizable @keyup.esc=\"handleClose\">\n <!-- 编辑列表 -->\n <BatchEditList :slots=\"slots\" />\n\n <!-- 编辑表单 -->\n <BatchEditForm v-slot=\"scoped\">\n <!-- @vue-ignore -->\n <slot name=\"form\" v-bind=\"scoped\" />\n </BatchEditForm>\n </u-layout>\n</template>\n\n<script lang=\"ts\" setup generic=\"Model extends FormModel\">\nimport { bem } from '@veltra/utils'\nimport { computed, inject, provide, shallowRef, watch } from 'vue'\n\nimport type {\n BatchEditEmits,\n BatchEditFeature,\n BatchEditProps,\n TableColumnSlotsScope,\n TableExposed,\n TableRow\n} from '../../types'\nimport { DialogDIKey } from '../dialog/di'\nimport type { FormModel } from '../form'\nimport { ULayout } from '../layout'\nimport BatchEditForm from './batch-edit-form.vue'\nimport BatchEditList from './batch-edit-list.vue'\nimport { BatchEditDIKey } from './di'\nimport { useEdit } from './use-edit'\n\ndefineOptions({ name: 'BatchEdit' })\n\nconst props = withDefaults(defineProps<BatchEditProps<Model>>(), {\n cols: () => ['1fr', '400px'],\n mode: 'normal'\n})\n\nconst emit = defineEmits<BatchEditEmits>()\n\nconst staticFeatures = computed(() => {\n const { features } = props\n\n if (Array.isArray(features)) {\n return new Set(features)\n }\n\n const defaultFeatures = new Set<BatchEditFeature>(['create', 'delete', 'update', 'createChild'])\n\n if (!features) {\n return defaultFeatures\n }\n\n // 排除函数和false的部分\n Object.entries(features).forEach(([key, value]) => {\n if (typeof value === 'function' || value === false) {\n defaultFeatures.delete(key as BatchEditFeature)\n }\n })\n return defaultFeatures\n})\n\nconst dynamicFeatures = computed<\n Record<BatchEditFeature, ((row?: TableRow) => boolean) | undefined>\n>(() => {\n const { features } = props\n if (!Array.isArray(features) && typeof features === 'object') {\n const ret = Object.entries(features)\n .filter(([_, value]) => {\n return typeof value === 'function'\n })\n .reduce(\n (acc, [key, value]) => {\n acc[key] = value\n return acc\n },\n {} as Record<BatchEditFeature, (row?: TableRow) => boolean>\n )\n return ret\n }\n\n return {} as Record<BatchEditFeature, ((row?: TableRow) => boolean) | undefined>\n})\n\nconst slots = defineSlots<\n {\n form?: (props: {\n /** 表单数据 */\n data: Model['data']\n /** 表单模型 */\n model: Model\n /** 当前编辑的层级 */\n depth?: number\n /** 当前编辑的行 */\n row?: TableRow\n /** 当前编辑的行索引 */\n index?: number\n /** 操作的目标行索引路径 */\n indexes?: number[]\n }) => any\n\n header?: () => any\n } & Partial<{\n [key: `column:${string}`]: (props: TableColumnSlotsScope) => any\n }>\n>()\n\nconst cls = bem('batch-edit')\n\nconst tableRef = shallowRef<TableExposed>()\n\nconst editCtx = useEdit({ props, emit, tableRef })\n\nconst { state, handleClose } = editCtx\n\nprovide(BatchEditDIKey, {\n cls,\n props,\n emit,\n tableRef,\n staticFeatures,\n dynamicFeatures,\n ...editCtx\n})\n\nconst dialogCtx = inject(DialogDIKey, undefined)\n\n// 如果在dialog上下文中\ndialogCtx &&\n watch(dialogCtx.visible, (visible) => {\n !visible && editCtx.handleClose()\n })\n\nconst cols = computed(() => {\n return !!state.row || state.visible ? props.cols : undefined\n})\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmCA,MAAM,QAAQ;EAKd,MAAM,OAAO;EAEb,MAAM,iBAAiB,eAAe;GACpC,MAAM,EAAE,aAAa;AAErB,OAAI,MAAM,QAAQ,SAAS,CACzB,QAAO,IAAI,IAAI,SAAQ;GAGzB,MAAM,kBAAkB,IAAI,IAAsB;IAAC;IAAU;IAAU;IAAU;IAAc,CAAA;AAE/F,OAAI,CAAC,SACH,QAAO;AAIT,UAAO,QAAQ,SAAS,CAAC,SAAS,CAAC,KAAK,WAAW;AACjD,QAAI,OAAO,UAAU,cAAc,UAAU,MAC3C,iBAAgB,OAAO,IAAuB;KAEjD;AACD,UAAO;IACR;EAED,MAAM,kBAAkB,eAEhB;GACN,MAAM,EAAE,aAAa;AACrB,OAAI,CAAC,MAAM,QAAQ,SAAS,IAAI,OAAO,aAAa,SAYlD,QAXY,OAAO,QAAQ,SAAQ,CAChC,QAAQ,CAAC,GAAG,WAAW;AACtB,WAAO,OAAO,UAAU;KACzB,CACA,QACE,KAAK,CAAC,KAAK,WAAW;AACrB,QAAI,OAAO;AACX,WAAO;MAET,EAAE,CAEC;AAGT,UAAO,EAAE;IACV;EAED,MAAM,QAAQ,UAAA;EAuBd,MAAM,MAAM,IAAI,aAAY;EAE5B,MAAM,WAAW,YAAyB;EAE1C,MAAM,UAAU,QAAQ;GAAE;GAAO;GAAM;GAAU,CAAA;EAEjD,MAAM,EAAE,OAAO,gBAAgB;AAE/B,UAAQ,gBAAgB;GACtB;GACA;GACA;GACA;GACA;GACA;GACA,GAAG;GACJ,CAAA;EAED,MAAM,YAAY,OAAO,aAAa,KAAA,EAAS;AAG/C,eACE,MAAM,UAAU,UAAU,YAAY;AACpC,IAAC,WAAW,QAAQ,aAAY;IACjC;EAEH,MAAM,OAAO,eAAe;AAC1B,UAAO,CAAC,CAAC,MAAM,OAAO,MAAM,UAAU,MAAM,OAAO,KAAA;IACpD;;uBAxIC,YASW,MAAA,YAAA,EAAA;IATA,OAAK,eAAE,MAAA,IAAG,CAAC,EAAC;IAAG,MAAM,KAAA;IAAM,MAAK;IAAO,KAAI;IAAM,WAAA;IAAW,SAAK,SAAM,MAAA,YAAW,EAAA,CAAA,MAAA,CAAA;;2BAC9E;KAAb,mBAAA,SAAa;KACb,YAAgC,aAAA,EAAT,OAAK,CAAA;KAE5B,mBAAA,SAAa;KACb,YAGgB,aAAA,MAAA;wBAHO,WAAM,CAC3B,mBAAA,gBAAoB,EACpB,WAAoC,KAAA,QAAA,QAAA,eAAA,mBAAV,OAAM,CAAA,CAAA,CAAA,CAAA"}
|
|
@@ -7,9 +7,9 @@ import * as _$_cat_kit_core0 from "@cat-kit/core";
|
|
|
7
7
|
//#region src/components/batch-edit/batch-edit.vue.d.ts
|
|
8
8
|
declare const __VLS_export: <Model extends FormModel>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
|
|
9
9
|
props: _$vue.PublicProps & __VLS_PrettifyLocal<BatchEditProps<Model> & {
|
|
10
|
-
"onUpdate:data"?: ((value: Record<string, any>[]) => any) | undefined;
|
|
11
|
-
"onUpdate:checked"?: ((value: Record<string, any>[]) => any) | undefined;
|
|
12
10
|
"onUpdate:selected"?: ((value: Record<string, any> | undefined) => any) | undefined;
|
|
11
|
+
"onUpdate:checked"?: ((value: Record<string, any>[]) => any) | undefined;
|
|
12
|
+
"onUpdate:data"?: ((value: Record<string, any>[]) => any) | undefined;
|
|
13
13
|
"onUpdate:rows"?: ((rows: TableRow[]) => any) | undefined;
|
|
14
14
|
"onUpdate:forest"?: ((rows?: _$_cat_kit_core0.Forest<Record<string, unknown>, any> | undefined) => any) | undefined;
|
|
15
15
|
"onUpdate:current"?: ((row?: TableRow | undefined) => any) | undefined;
|
|
@@ -2,11 +2,11 @@ import "../button/style.js";
|
|
|
2
2
|
import "../tip/style.js";
|
|
3
3
|
import "../action/style.js";
|
|
4
4
|
import "../scroll/style.js";
|
|
5
|
-
import "../card/style.js";
|
|
6
|
-
import "../checkbox/style.js";
|
|
7
5
|
import "../layout/style.js";
|
|
8
6
|
import "../form/style.js";
|
|
7
|
+
import "../checkbox/style.js";
|
|
9
8
|
import "../table/style.js";
|
|
9
|
+
import "../card/style.js";
|
|
10
10
|
import "./style2.css";
|
|
11
11
|
import "@veltra/directives/ripple/style.js";
|
|
12
12
|
import "@veltra/styles/anime/fade.scss";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-edit.js","names":[],"sources":["../../../src/components/batch-edit/use-edit.ts"],"sourcesContent":["import { last, o, safeRun } from '@cat-kit/core'\nimport { computed, nextTick, shallowReactive, shallowRef, watch, type ShallowRef } from 'vue'\n\nimport type { TableRow, BatchEditEmits, BatchEditProps, TableExposed } from '../../types'\n\n/** 按索引路径在原始数据树中定位节点(等价于历史 Forest.visit 路径访问) */\nfunction visitDataByIndexPath<T extends Record<string, unknown>>(\n roots: T[],\n indexPath: number[],\n childrenKey: string\n): T | undefined {\n if (!indexPath.length) return undefined\n let currentList: T[] | undefined = roots\n let node: T | undefined\n for (let i = 0; i < indexPath.length; i++) {\n const idx = indexPath[i]!\n if (!currentList) return undefined\n node = currentList[idx]\n if (node === undefined) return undefined\n if (i < indexPath.length - 1) {\n const next = node[childrenKey]\n currentList = Array.isArray(next) ? (next as T[]) : undefined\n }\n }\n return node\n}\n\ninterface Options {\n props: BatchEditProps\n emit: BatchEditEmits\n tableRef: ShallowRef<TableExposed | undefined>\n}\n\nexport interface BatchEditStates {\n /** 层级 */\n depth?: number\n visible: boolean\n type: 'create' | 'update'\n loading: boolean\n row?: TableRow\n /** 父级,只在添加子级时会有值 */\n parentRow?: TableRow\n /** 数据是否已更新 */\n dataUpdated: boolean\n}\n\nexport interface EditReturned {\n state: BatchEditStates\n insertIndexes: ShallowRef<number[]>\n handleSave: () => Promise<void>\n handleClose: () => void\n handleCreate: () => void\n handleDelete: (row: TableRow) => Promise<void>\n handleInsertToNext: (row: TableRow) => void\n handleInsertToPrev: (row: TableRow) => void\n handleInsertChild: (row: TableRow) => void\n}\n\nexport function useEdit(options: Options): EditReturned {\n const { props, emit, tableRef } = options\n\n /** 组件状态 */\n const state = shallowReactive<BatchEditStates>({\n depth: undefined,\n visible: false,\n type: 'create',\n loading: false,\n dataUpdated: false\n })\n\n const insertIndexes = shallowRef<number[]>([])\n\n watch(\n () => state.visible,\n (v) => {\n if (!v) {\n state.dataUpdated = false\n }\n }\n )\n\n /** 是否是用户输入产生的值变更 */\n let changedByUserInput = true\n\n watch(\n () => state.row,\n (row) => {\n props.model?.resetData()\n if (row) {\n state.type = 'update'\n state.visible = true\n changedByUserInput = false\n props.model?.setData(row.data)\n nextTick(() => {\n changedByUserInput = true\n })\n } else {\n state.visible = false\n }\n }\n )\n\n const changeCb = (_field: string, _val: any) => {\n // 检测到为用户变更时,为数据添加一个已更改状态从而显示修改按钮\n if (changedByUserInput) {\n state.dataUpdated = true\n }\n }\n\n watch(\n () => props.model,\n (model, oldModel) => {\n if (oldModel) {\n oldModel.offChange(changeCb)\n }\n if (model) {\n model.onChange(changeCb)\n }\n },\n { immediate: true }\n )\n\n const childrenKey = computed(() => {\n return typeof props.tree === 'string' ? props.tree : 'children'\n })\n\n /**\n * 插入数据\n * @param item 数据\n */\n function insert(item: Record<string, any>) {\n const data = [...(props.data ?? [])]\n\n const parent = visitDataByIndexPath(\n data ?? [],\n insertIndexes.value.slice(0, -1),\n childrenKey.value\n )\n\n if (parent) {\n const children = parent[childrenKey.value]\n if (!children) {\n parent[childrenKey.value] = [item]\n } else {\n children.splice(last(insertIndexes.value), 0, item)\n }\n } else {\n data.splice(last(insertIndexes.value), 0, item)\n }\n\n emit('update:data', data)\n\n return item\n }\n\n function getInsertData(): Record<string, any> {\n return safeRun(() => JSON.parse(JSON.stringify(props.model?.data ?? {})), {})\n }\n\n async function runCreate(cb: () => void) {\n state.parentRow = undefined\n if (state.row) {\n state.row.isCurrent = false\n }\n state.row = undefined\n state.type = 'create'\n props.model?.resetData()\n cb()\n\n let item: Record<string, any> | undefined = undefined\n\n await nextTick()\n\n state.visible = true\n\n if (item) {\n const row = tableRef.value?.getRowByData(item)\n if (row) {\n state.row = row\n }\n }\n }\n\n /**\n * 点击新增按钮\n */\n function handleCreate() {\n const { data } = props\n runCreate(() => {\n state.depth = 1\n insertIndexes.value = [data?.length ?? 0]\n })\n }\n\n function handleInsertToPrev(row: TableRow) {\n runCreate(() => {\n state.depth = row.depth\n insertIndexes.value = [...row.indexes]\n })\n }\n\n function handleInsertToNext(row: TableRow) {\n runCreate(() => {\n state.depth = row.depth\n insertIndexes.value = [...row.indexes.slice(0, -1), row.index + 1]\n })\n }\n\n function handleInsertChild(row: TableRow) {\n runCreate(() => {\n state.parentRow = row\n state.depth = row.depth + 1\n row.expanded = true\n\n insertIndexes.value = [...row.indexes, row.children?.length ?? 0]\n })\n }\n\n function runWithLoading<Arg extends any[]>(fn: (...args: Arg) => Promise<void> | void) {\n return async (...args: Arg) => {\n state.loading = true\n if (state.row) {\n state.row.operating = true\n }\n try {\n await fn.apply(null, args)\n } catch (error) {\n console.error(error)\n }\n state.loading = false\n if (state.row) {\n state.row.operating = false\n }\n }\n }\n\n /** 保存 */\n const handleSave = runWithLoading(async () => {\n const { model, saveMethod } = props\n\n if (!model) return\n\n model.clearValidate()\n const valid = await model.validate()\n\n if (!valid) return\n\n let item = getInsertData()\n if (saveMethod) {\n const result = await saveMethod(item, state.type, state.parentRow)\n if (result) {\n item = result\n }\n }\n\n state.dataUpdated = false\n\n // 新增\n if (state.type === 'create') {\n insert(item)\n\n return model?.resetData()\n }\n // 更新\n if (state.type === 'update') {\n const { row } = state\n row &&\n model.allKeys.forEach((key) => {\n o(row.data).set(key, o(item).get(key))\n })\n }\n })\n\n const handleDelete = runWithLoading(async (row: TableRow) => {\n const { deleteMethod } = props\n\n if (deleteMethod) {\n await deleteMethod([row.data])\n }\n\n const data = [...(props.data ?? [])]\n\n const parent = visitDataByIndexPath(data, row.indexes.slice(0, -1), childrenKey.value)\n\n if (parent) {\n const children = parent[childrenKey.value]\n if (children) {\n children.splice(row.index, 1)\n } else {\n console.error('行路径不正确')\n }\n } else {\n data.splice(row.index, 1)\n }\n\n if (state.row === row) {\n state.row = undefined\n state.depth = undefined\n }\n\n emit('update:data', data)\n })\n\n function handleClose() {\n state.visible = false\n if (state.row) {\n state.row.isCurrent = false\n }\n state.row = undefined\n state.parentRow = undefined\n state.depth = undefined\n props.model?.resetData()\n insertIndexes.value = []\n }\n\n return {\n state,\n insertIndexes,\n handleDelete,\n handleInsertChild,\n handleInsertToNext,\n handleInsertToPrev,\n handleCreate,\n handleClose,\n handleSave\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"use-edit.js","names":[],"sources":["../../../src/components/batch-edit/use-edit.ts"],"sourcesContent":["import { last, o, safeRun } from '@cat-kit/core'\nimport { computed, nextTick, shallowReactive, shallowRef, watch, type ShallowRef } from 'vue'\n\nimport type { TableRow, BatchEditEmits, BatchEditProps, TableExposed } from '../../types'\n\n/** 按索引路径在原始数据树中定位节点(等价于历史 Forest.visit 路径访问) */\nfunction visitDataByIndexPath<T extends Record<string, unknown>>(\n roots: T[],\n indexPath: number[],\n childrenKey: string\n): T | undefined {\n if (!indexPath.length) return undefined\n let currentList: T[] | undefined = roots\n let node: T | undefined\n for (let i = 0; i < indexPath.length; i++) {\n const idx = indexPath[i]!\n if (!currentList) return undefined\n node = currentList[idx]\n if (node === undefined) return undefined\n if (i < indexPath.length - 1) {\n const next = node[childrenKey]\n currentList = Array.isArray(next) ? (next as T[]) : undefined\n }\n }\n return node\n}\n\ninterface Options {\n props: BatchEditProps\n emit: BatchEditEmits\n tableRef: ShallowRef<TableExposed | undefined>\n}\n\nexport interface BatchEditStates {\n /** 层级 */\n depth?: number\n visible: boolean\n type: 'create' | 'update'\n loading: boolean\n row?: TableRow\n /** 父级,只在添加子级时会有值 */\n parentRow?: TableRow\n /** 数据是否已更新 */\n dataUpdated: boolean\n}\n\nexport interface EditReturned {\n state: BatchEditStates\n insertIndexes: ShallowRef<number[]>\n handleSave: () => Promise<void>\n handleClose: () => void\n handleCreate: () => void\n handleDelete: (row: TableRow) => Promise<void>\n handleInsertToNext: (row: TableRow) => void\n handleInsertToPrev: (row: TableRow) => void\n handleInsertChild: (row: TableRow) => void\n}\n\nexport function useEdit(options: Options): EditReturned {\n const { props, emit, tableRef } = options\n\n /** 组件状态 */\n const state = shallowReactive<BatchEditStates>({\n depth: undefined,\n visible: false,\n type: 'create',\n loading: false,\n dataUpdated: false\n })\n\n const insertIndexes = shallowRef<number[]>([])\n\n watch(\n () => state.visible,\n (v) => {\n if (!v) {\n state.dataUpdated = false\n }\n }\n )\n\n /** 是否是用户输入产生的值变更 */\n let changedByUserInput = true\n\n watch(\n () => state.row,\n (row) => {\n props.model?.resetData()\n if (row) {\n state.type = 'update'\n state.visible = true\n changedByUserInput = false\n props.model?.setData(row.data)\n nextTick(() => {\n changedByUserInput = true\n })\n } else {\n state.visible = false\n }\n }\n )\n\n const changeCb = (_field: string, _val: any) => {\n // 检测到为用户变更时,为数据添加一个已更改状态从而显示修改按钮\n if (changedByUserInput) {\n state.dataUpdated = true\n }\n }\n\n watch(\n () => props.model,\n (model, oldModel) => {\n if (oldModel) {\n oldModel.offChange(changeCb)\n }\n if (model) {\n model.onChange(changeCb)\n }\n },\n { immediate: true }\n )\n\n const childrenKey = computed(() => {\n return typeof props.tree === 'string' ? props.tree : 'children'\n })\n\n /**\n * 插入数据\n * @param item 数据\n */\n function insert(item: Record<string, any>) {\n const data = [...(props.data ?? [])]\n\n const parent = visitDataByIndexPath(\n data ?? [],\n insertIndexes.value.slice(0, -1),\n childrenKey.value\n )\n\n if (parent) {\n const children = parent[childrenKey.value]\n if (!children) {\n parent[childrenKey.value] = [item]\n } else {\n children.splice(last(insertIndexes.value), 0, item)\n }\n } else {\n data.splice(last(insertIndexes.value), 0, item)\n }\n\n emit('update:data', data)\n\n return item\n }\n\n function getInsertData(): Record<string, any> {\n return safeRun(() => JSON.parse(JSON.stringify(props.model?.data ?? {})), {})\n }\n\n async function runCreate(cb: () => void) {\n state.parentRow = undefined\n if (state.row) {\n state.row.isCurrent = false\n }\n state.row = undefined\n state.type = 'create'\n props.model?.resetData()\n cb()\n\n let item: Record<string, any> | undefined = undefined\n\n await nextTick()\n\n state.visible = true\n\n if (item) {\n const row = tableRef.value?.getRowByData(item)\n if (row) {\n state.row = row\n }\n }\n }\n\n /**\n * 点击新增按钮\n */\n function handleCreate() {\n const { data } = props\n runCreate(() => {\n state.depth = 1\n insertIndexes.value = [data?.length ?? 0]\n })\n }\n\n function handleInsertToPrev(row: TableRow) {\n runCreate(() => {\n state.depth = row.depth\n insertIndexes.value = [...row.indexes]\n })\n }\n\n function handleInsertToNext(row: TableRow) {\n runCreate(() => {\n state.depth = row.depth\n insertIndexes.value = [...row.indexes.slice(0, -1), row.index + 1]\n })\n }\n\n function handleInsertChild(row: TableRow) {\n runCreate(() => {\n state.parentRow = row\n state.depth = row.depth + 1\n row.expanded = true\n\n insertIndexes.value = [...row.indexes, row.children?.length ?? 0]\n })\n }\n\n function runWithLoading<Arg extends any[]>(fn: (...args: Arg) => Promise<void> | void) {\n return async (...args: Arg) => {\n state.loading = true\n if (state.row) {\n state.row.operating = true\n }\n try {\n await fn.apply(null, args)\n } catch (error) {\n console.error(error)\n }\n state.loading = false\n if (state.row) {\n state.row.operating = false\n }\n }\n }\n\n /** 保存 */\n const handleSave = runWithLoading(async () => {\n const { model, saveMethod } = props\n\n if (!model) return\n\n model.clearValidate()\n const valid = await model.validate()\n\n if (!valid) return\n\n let item = getInsertData()\n if (saveMethod) {\n const result = await saveMethod(item, state.type, state.parentRow)\n if (result) {\n item = result\n }\n }\n\n state.dataUpdated = false\n\n // 新增\n if (state.type === 'create') {\n insert(item)\n\n return model?.resetData()\n }\n // 更新\n if (state.type === 'update') {\n const { row } = state\n row &&\n model.allKeys.forEach((key) => {\n o(row.data).set(key, o(item).get(key))\n })\n }\n })\n\n const handleDelete = runWithLoading(async (row: TableRow) => {\n const { deleteMethod } = props\n\n if (deleteMethod) {\n await deleteMethod([row.data])\n }\n\n const data = [...(props.data ?? [])]\n\n const parent = visitDataByIndexPath(data, row.indexes.slice(0, -1), childrenKey.value)\n\n if (parent) {\n const children = parent[childrenKey.value]\n if (children) {\n children.splice(row.index, 1)\n } else {\n console.error('行路径不正确')\n }\n } else {\n data.splice(row.index, 1)\n }\n\n if (state.row === row) {\n state.row = undefined\n state.depth = undefined\n }\n\n emit('update:data', data)\n })\n\n function handleClose() {\n state.visible = false\n if (state.row) {\n state.row.isCurrent = false\n }\n state.row = undefined\n state.parentRow = undefined\n state.depth = undefined\n props.model?.resetData()\n insertIndexes.value = []\n }\n\n return {\n state,\n insertIndexes,\n handleDelete,\n handleInsertChild,\n handleInsertToNext,\n handleInsertToPrev,\n handleCreate,\n handleClose,\n handleSave\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"button.js","names":[],"sources":["../../../src/components/button/button.vue"],"sourcesContent":["<template>\n <button\n :class=\"classList\"\n type=\"button\"\n aria-label=\"button\"\n ref=\"buttonRef\"\n v-ripple=\"ripple\"\n @click=\"handleClick\"\n >\n <!-- 加载图标 -->\n <u-icon v-if=\"loading\" :class=\"[bem.is('loading')]\" :size=\"iconSize\">\n <component :is=\"loadingIcon\" />\n </u-icon>\n\n <!-- 左侧图标 -->\n <u-icon v-if=\"!!icon && iconPosition === 'left' && !loading\" :size=\"iconSize\">\n <component :is=\"icon\" />\n </u-icon>\n\n <slot />\n\n <!-- 右侧图标 -->\n <u-icon v-if=\"!!icon && iconPosition === 'right'\" :size=\"iconSize\">\n <component :is=\"icon\" />\n </u-icon>\n </button>\n</template>\n\n<script lang=\"ts\" setup>\nimport { useFallbackProps } from '@veltra/compositions'\nimport { vRipple } from '@veltra/directives'\nimport { Loading } from '@veltra/icons'\nimport { bem } from '@veltra/utils'\nimport { computed, shallowRef } from 'vue'\n\nimport type { ButtonEmits, ButtonProps, _ButtonExposed, ComponentSize } from '../../types'\nimport { UIcon } from '../icon'\n\ndefineOptions({\n name: 'Button'\n})\n\nconst props = withDefaults(defineProps<ButtonProps>(), {\n iconPosition: 'left',\n loadingIcon: () => Loading,\n disabled: false,\n propagate: true\n})\n\nconst { size } = useFallbackProps([props], {\n size: 'default' as ComponentSize\n})\n\nconst emit = defineEmits<ButtonEmits>()\n\nconst cls = bem('button')\n\nconst classList = computed(() => {\n return [\n cls.b,\n cls.m(size.value),\n props.type && cls.m('color-' + props.type),\n bem.is('circle', props.circle),\n bem.is('disabled', props.disabled),\n bem.is('loading', props.loading),\n bem.is('plain', props.plain),\n bem.is('text', props.text)\n ]\n})\n\nconst ripple = computed(() => {\n if (props.disabled || props.loading) return false\n if ((props.plain || props.text) && props.type) {\n return bem.is(`ripple-${props.type}`)\n }\n return true\n})\n\nconst handleClick = (e: MouseEvent) => {\n if (props.disabled || props.loading) {\n e.stopPropagation()\n return\n }\n\n !props.propagate && e.stopPropagation()\n\n emit('click', e)\n}\n\nconst buttonRef = shallowRef<HTMLButtonElement>()\n\nconst exposed: _ButtonExposed = {\n el: buttonRef\n}\n\ndefineExpose(exposed)\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0CA,MAAM,QAAQ;EAOd,MAAM,EAAE,SAAS,iBAAiB,CAAC,MAAM,EAAE,EACzC,MAAM,WACP,CAAA;EAED,MAAM,OAAO;EAEb,MAAM,MAAM,IAAI,SAAQ;EAExB,MAAM,YAAY,eAAe;AAC/B,UAAO;IACL,IAAI;IACJ,IAAI,EAAE,KAAK,MAAM;IACjB,MAAM,QAAQ,IAAI,EAAE,WAAW,MAAM,KAAK;IAC1C,IAAI,GAAG,UAAU,MAAM,OAAO;IAC9B,IAAI,GAAG,YAAY,MAAM,SAAS;IAClC,IAAI,GAAG,WAAW,MAAM,QAAQ;IAChC,IAAI,GAAG,SAAS,MAAM,MAAM;IAC5B,IAAI,GAAG,QAAQ,MAAM,KAAI;IAC3B;IACD;EAED,MAAM,SAAS,eAAe;AAC5B,OAAI,MAAM,YAAY,MAAM,QAAS,QAAO;AAC5C,QAAK,MAAM,SAAS,MAAM,SAAS,MAAM,KACvC,QAAO,IAAI,GAAG,UAAU,MAAM,OAAM;AAEtC,UAAO;IACR;EAED,MAAM,eAAe,MAAkB;AACrC,OAAI,MAAM,YAAY,MAAM,SAAS;AACnC,MAAE,iBAAgB;AAClB;;AAGF,IAAC,MAAM,aAAa,EAAE,iBAAgB;AAEtC,QAAK,SAAS,EAAC;;EAGjB,MAAM,YAAY,YAA8B;AAMhD,
|
|
1
|
+
{"version":3,"file":"button.js","names":[],"sources":["../../../src/components/button/button.vue"],"sourcesContent":["<template>\n <button\n :class=\"classList\"\n type=\"button\"\n aria-label=\"button\"\n ref=\"buttonRef\"\n v-ripple=\"ripple\"\n @click=\"handleClick\"\n >\n <!-- 加载图标 -->\n <u-icon v-if=\"loading\" :class=\"[bem.is('loading')]\" :size=\"iconSize\">\n <component :is=\"loadingIcon\" />\n </u-icon>\n\n <!-- 左侧图标 -->\n <u-icon v-if=\"!!icon && iconPosition === 'left' && !loading\" :size=\"iconSize\">\n <component :is=\"icon\" />\n </u-icon>\n\n <slot />\n\n <!-- 右侧图标 -->\n <u-icon v-if=\"!!icon && iconPosition === 'right'\" :size=\"iconSize\">\n <component :is=\"icon\" />\n </u-icon>\n </button>\n</template>\n\n<script lang=\"ts\" setup>\nimport { useFallbackProps } from '@veltra/compositions'\nimport { vRipple } from '@veltra/directives'\nimport { Loading } from '@veltra/icons'\nimport { bem } from '@veltra/utils'\nimport { computed, shallowRef } from 'vue'\n\nimport type { ButtonEmits, ButtonProps, _ButtonExposed, ComponentSize } from '../../types'\nimport { UIcon } from '../icon'\n\ndefineOptions({\n name: 'Button'\n})\n\nconst props = withDefaults(defineProps<ButtonProps>(), {\n iconPosition: 'left',\n loadingIcon: () => Loading,\n disabled: false,\n propagate: true\n})\n\nconst { size } = useFallbackProps([props], {\n size: 'default' as ComponentSize\n})\n\nconst emit = defineEmits<ButtonEmits>()\n\nconst cls = bem('button')\n\nconst classList = computed(() => {\n return [\n cls.b,\n cls.m(size.value),\n props.type && cls.m('color-' + props.type),\n bem.is('circle', props.circle),\n bem.is('disabled', props.disabled),\n bem.is('loading', props.loading),\n bem.is('plain', props.plain),\n bem.is('text', props.text)\n ]\n})\n\nconst ripple = computed(() => {\n if (props.disabled || props.loading) return false\n if ((props.plain || props.text) && props.type) {\n return bem.is(`ripple-${props.type}`)\n }\n return true\n})\n\nconst handleClick = (e: MouseEvent) => {\n if (props.disabled || props.loading) {\n e.stopPropagation()\n return\n }\n\n !props.propagate && e.stopPropagation()\n\n emit('click', e)\n}\n\nconst buttonRef = shallowRef<HTMLButtonElement>()\n\nconst exposed: _ButtonExposed = {\n el: buttonRef\n}\n\ndefineExpose(exposed)\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0CA,MAAM,QAAQ;EAOd,MAAM,EAAE,SAAS,iBAAiB,CAAC,MAAM,EAAE,EACzC,MAAM,WACP,CAAA;EAED,MAAM,OAAO;EAEb,MAAM,MAAM,IAAI,SAAQ;EAExB,MAAM,YAAY,eAAe;AAC/B,UAAO;IACL,IAAI;IACJ,IAAI,EAAE,KAAK,MAAM;IACjB,MAAM,QAAQ,IAAI,EAAE,WAAW,MAAM,KAAK;IAC1C,IAAI,GAAG,UAAU,MAAM,OAAO;IAC9B,IAAI,GAAG,YAAY,MAAM,SAAS;IAClC,IAAI,GAAG,WAAW,MAAM,QAAQ;IAChC,IAAI,GAAG,SAAS,MAAM,MAAM;IAC5B,IAAI,GAAG,QAAQ,MAAM,KAAI;IAC3B;IACD;EAED,MAAM,SAAS,eAAe;AAC5B,OAAI,MAAM,YAAY,MAAM,QAAS,QAAO;AAC5C,QAAK,MAAM,SAAS,MAAM,SAAS,MAAM,KACvC,QAAO,IAAI,GAAG,UAAU,MAAM,OAAM;AAEtC,UAAO;IACR;EAED,MAAM,eAAe,MAAkB;AACrC,OAAI,MAAM,YAAY,MAAM,SAAS;AACnC,MAAE,iBAAgB;AAClB;;AAGF,IAAC,MAAM,aAAa,EAAE,iBAAgB;AAEtC,QAAK,SAAS,EAAC;;EAGjB,MAAM,YAAY,YAA8B;AAMhD,WAAa,EAHX,IAAI,WAGO,CAAO;;uCA9FlB,mBAwBS,UAAA;IAvBN,OAAK,eAAE,UAAA,MAAS;IACjB,MAAK;IACL,cAAW;aACP;IAAJ,KAAI;IAEH,SAAO;;IAER,mBAAA,SAAa;IACC,QAAA,WAAA,WAAA,EAAd,YAES,MAAA,YAAA,EAAA;;KAFe,OAAK,eAAA,CAAG,MAAA,IAAG,CAAC,GAAE,UAAA,CAAA,CAAA;KAAe,MAAM,QAAA;;4BAC1B,EAAA,WAAA,EAA/B,YAA+B,wBAAf,QAAA,YAAW,CAAA,EAAA,CAAA;;;IAG7B,mBAAA,SAAa;MACG,QAAA,QAAQ,QAAA,iBAAY,UAAA,CAAgB,QAAA,WAAA,WAAA,EAApD,YAES,MAAA,YAAA,EAAA;;KAFqD,MAAM,QAAA;;4BAC1C,EAAA,WAAA,EAAxB,YAAwB,wBAAR,QAAA,KAAI,CAAA,EAAA,CAAA;;;IAGtB,WAAQ,KAAA,QAAA,UAAA;IAER,mBAAA,SAAa;MACG,QAAA,QAAQ,QAAA,iBAAY,WAAA,WAAA,EAApC,YAES,MAAA,YAAA,EAAA;;KAF0C,MAAM,QAAA;;4BAC/B,EAAA,WAAA,EAAxB,YAAwB,wBAAR,QAAA,KAAI,CAAA,EAAA,CAAA;;;6BAjBZ,OAAA,MAAM,CAAA,CAAA"}
|
|
@@ -4,18 +4,18 @@ import * as _$vue from "vue";
|
|
|
4
4
|
//#region src/components/cascade/cascade.vue.d.ts
|
|
5
5
|
declare const __VLS_export: _$vue.DefineComponent<CascadeProps, {}, {}, {}, {}, _$vue.ComponentOptionsMixin, _$vue.ComponentOptionsMixin, {} & {
|
|
6
6
|
"update:modelValue": (value?: string | string[] | undefined) => any;
|
|
7
|
-
clear: () => any;
|
|
8
7
|
change: (...args: [value?: string | undefined, label?: string | undefined, item?: Record<string, any> | undefined] | [value: string[], label: string[], data: Record<string, any>[]]) => any;
|
|
8
|
+
clear: () => any;
|
|
9
9
|
}, string, _$vue.PublicProps, Readonly<CascadeProps> & Readonly<{
|
|
10
10
|
"onUpdate:modelValue"?: ((value?: string | string[] | undefined) => any) | undefined;
|
|
11
|
-
onClear?: (() => any) | undefined;
|
|
12
11
|
onChange?: ((...args: [value?: string | undefined, label?: string | undefined, item?: Record<string, any> | undefined] | [value: string[], label: string[], data: Record<string, any>[]]) => any) | undefined;
|
|
12
|
+
onClear?: (() => any) | undefined;
|
|
13
13
|
}>, {
|
|
14
|
-
separator: string;
|
|
15
|
-
disabled: boolean;
|
|
16
|
-
readonly: boolean;
|
|
17
14
|
labelKey: string;
|
|
18
15
|
valueKey: string;
|
|
16
|
+
disabled: boolean;
|
|
17
|
+
readonly: boolean;
|
|
18
|
+
separator: string;
|
|
19
19
|
placeholder: string;
|
|
20
20
|
clearable: boolean;
|
|
21
21
|
data: Record<string, any>[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-select.js","names":[],"sources":["../../../src/components/cascade/use-select.ts"],"sourcesContent":["import { Forest } from '@cat-kit/core'\nimport { createIncrease } from '@veltra/utils'\nimport {\n computed,\n nextTick,\n shallowRef,\n triggerRef,\n watch,\n type ComputedRef,\n type Ref,\n type ShallowRef\n} from 'vue'\n\nimport type {\n CascadeProps,\n CascadeEmits,\n CascadeNode,\n DropdownExposed,\n PanelItem\n} from '../../types'\n\ninterface SelectOptions {\n props: CascadeProps\n emit: CascadeEmits\n isUserActive: () => boolean\n forest: Ref<Forest<Record<string, unknown>, any>>\n dataMap: Ref<Map<string, CascadeNode>>\n dropdownRef: Ref<DropdownExposed | undefined>\n}\n\ninterface UseSelectReturned {\n displayedValue: ComputedRef<string | undefined>\n selectItem: (panelIndex: number, item: CascadeNode) => void\n selectedNodeKeys: ShallowRef<string[]>\n updateSingleValue: () => void\n initSingleSelect: () => void\n panelItemList: ShallowRef<PanelItem[]>\n getPanelItemList: (data?: CascadeNode[]) => void\n setPanelItem: (panelIndex: number, panelData?: CascadeNode[]) => void\n createPanelItem: (nodes: CascadeNode[]) => PanelItem\n}\n\nexport function useSelect(options: SelectOptions): UseSelectReturned {\n const { props, emit, dataMap, isUserActive, dropdownRef, forest } = options\n\n /** 选中的节点key */\n const selectedNodeKeys = shallowRef<string[]>([])\n\n const currentItem = shallowRef<Record<string, any>>()\n\n /** 面板数据 */\n const panelItemList = shallowRef<PanelItem[]>([])\n const uid = createIncrease()\n function createPanelItem(nodes: CascadeNode[]): PanelItem {\n return { key: uid(), nodes: nodes.filter((node) => node.visible) }\n }\n\n const displayedValue = computed(() => {\n const { modelValue, separator } = props\n const valueNodes =\n modelValue && typeof modelValue === 'string' ? modelValue.split(separator!) : undefined\n return valueNodes\n ?.map((v) => {\n const node = dataMap.value.get(v)\n return node?.label ?? v\n })\n .join(props.separator)\n })\n\n function getPanelItemList(data?: CascadeNode[]) {\n const _panelItemList: Array<PanelItem> = []\n if (!data?.length) return panelItemList\n _panelItemList.push(createPanelItem(data))\n\n selectedNodeKeys.value.slice(0, -1).forEach((key) => {\n const node = dataMap.value.get(key)\n node?.children?.length && _panelItemList.push(createPanelItem(node.children))\n })\n\n panelItemList.value = _panelItemList\n }\n\n function setPanelItem(panelIndex: number, panelData?: CascadeNode[]) {\n if (panelData?.length) {\n panelItemList.value[panelIndex + 1] = createPanelItem(panelData)\n panelItemList.value.splice(panelIndex + 2)\n } else {\n panelItemList.value.splice(panelIndex + 1)\n }\n\n triggerRef(panelItemList)\n }\n\n function updateSingleValue() {\n const { separator } = props\n\n const targetValue = selectedNodeKeys.value.length\n ? selectedNodeKeys.value.join(separator!)\n : undefined\n\n const targetLabel = selectedNodeKeys.value\n .map((key) => {\n const node = dataMap.value.get(key)\n return node?.label\n })\n .filter(Boolean)\n .join(separator!)\n\n emit('update:modelValue', targetValue)\n emit('change', targetValue, targetLabel, currentItem.value!)\n }\n\n /**\n * 单选选择\n *\n * @param panelIndex 面板索引\n * @param item 选中的节点\n */\n function selectItem(panelIndex: number, item: CascadeNode) {\n // 设置选中的节点\n currentItem.value = item\n selectedNodeKeys.value[panelIndex] = item.value\n selectedNodeKeys.value.splice(panelIndex + 1)\n triggerRef(selectedNodeKeys)\n\n // 展开子级面板\n setPanelItem(panelIndex, item.children)\n\n nextTick(() => {\n dropdownRef.value?.updateDropdown()\n })\n\n if (!item.children?.length && !props.multiple) {\n dropdownRef.value?.close()\n }\n }\n\n function initSingleSelect() {\n const { modelValue, separator } = props\n\n if (modelValue && typeof modelValue === 'string') {\n const nodes = modelValue.split(separator!)\n selectedNodeKeys.value = nodes\n getPanelItemList(forest.value.roots)\n } else {\n selectedNodeKeys.value = []\n getPanelItemList(forest.value.roots)\n }\n }\n\n watch(\n [() => props.multiple, () => props.modelValue, forest],\n ([multiple]) => {\n if (multiple || isUserActive()) return\n initSingleSelect()\n },\n { immediate: true }\n )\n\n return {\n displayedValue,\n selectItem,\n selectedNodeKeys,\n updateSingleValue,\n initSingleSelect,\n panelItemList,\n getPanelItemList,\n setPanelItem,\n createPanelItem\n }\n}\n"],"mappings":";;;;AA0CA,SAAgB,UAAU,SAA2C;CACnE,MAAM,EAAE,OAAO,MAAM,SAAS,cAAc,aAAa,WAAW;;CAGpE,MAAM,mBAAmB,WAAqB,EAAE,CAAC;CAEjD,MAAM,cAAc,YAAiC;;CAGrD,MAAM,gBAAgB,WAAwB,EAAE,CAAC;CACjD,MAAM,MAAM,gBAAgB;CAC5B,SAAS,gBAAgB,OAAiC;AACxD,SAAO;GAAE,KAAK,KAAK;GAAE,OAAO,MAAM,QAAQ,SAAS,KAAK,QAAQ;GAAE;;CAGpE,MAAM,iBAAiB,eAAe;EACpC,MAAM,EAAE,YAAY,cAAc;AAGlC,UADE,cAAc,OAAO,eAAe,WAAW,WAAW,MAAM,UAAW,GAAG,KAAA,IAE5E,KAAK,MAAM;AAEX,UADa,QAAQ,MAAM,IAAI,EAAE,
|
|
1
|
+
{"version":3,"file":"use-select.js","names":[],"sources":["../../../src/components/cascade/use-select.ts"],"sourcesContent":["import { Forest } from '@cat-kit/core'\nimport { createIncrease } from '@veltra/utils'\nimport {\n computed,\n nextTick,\n shallowRef,\n triggerRef,\n watch,\n type ComputedRef,\n type Ref,\n type ShallowRef\n} from 'vue'\n\nimport type {\n CascadeProps,\n CascadeEmits,\n CascadeNode,\n DropdownExposed,\n PanelItem\n} from '../../types'\n\ninterface SelectOptions {\n props: CascadeProps\n emit: CascadeEmits\n isUserActive: () => boolean\n forest: Ref<Forest<Record<string, unknown>, any>>\n dataMap: Ref<Map<string, CascadeNode>>\n dropdownRef: Ref<DropdownExposed | undefined>\n}\n\ninterface UseSelectReturned {\n displayedValue: ComputedRef<string | undefined>\n selectItem: (panelIndex: number, item: CascadeNode) => void\n selectedNodeKeys: ShallowRef<string[]>\n updateSingleValue: () => void\n initSingleSelect: () => void\n panelItemList: ShallowRef<PanelItem[]>\n getPanelItemList: (data?: CascadeNode[]) => void\n setPanelItem: (panelIndex: number, panelData?: CascadeNode[]) => void\n createPanelItem: (nodes: CascadeNode[]) => PanelItem\n}\n\nexport function useSelect(options: SelectOptions): UseSelectReturned {\n const { props, emit, dataMap, isUserActive, dropdownRef, forest } = options\n\n /** 选中的节点key */\n const selectedNodeKeys = shallowRef<string[]>([])\n\n const currentItem = shallowRef<Record<string, any>>()\n\n /** 面板数据 */\n const panelItemList = shallowRef<PanelItem[]>([])\n const uid = createIncrease()\n function createPanelItem(nodes: CascadeNode[]): PanelItem {\n return { key: uid(), nodes: nodes.filter((node) => node.visible) }\n }\n\n const displayedValue = computed(() => {\n const { modelValue, separator } = props\n const valueNodes =\n modelValue && typeof modelValue === 'string' ? modelValue.split(separator!) : undefined\n return valueNodes\n ?.map((v) => {\n const node = dataMap.value.get(v)\n return node?.label ?? v\n })\n .join(props.separator)\n })\n\n function getPanelItemList(data?: CascadeNode[]) {\n const _panelItemList: Array<PanelItem> = []\n if (!data?.length) return panelItemList\n _panelItemList.push(createPanelItem(data))\n\n selectedNodeKeys.value.slice(0, -1).forEach((key) => {\n const node = dataMap.value.get(key)\n node?.children?.length && _panelItemList.push(createPanelItem(node.children))\n })\n\n panelItemList.value = _panelItemList\n }\n\n function setPanelItem(panelIndex: number, panelData?: CascadeNode[]) {\n if (panelData?.length) {\n panelItemList.value[panelIndex + 1] = createPanelItem(panelData)\n panelItemList.value.splice(panelIndex + 2)\n } else {\n panelItemList.value.splice(panelIndex + 1)\n }\n\n triggerRef(panelItemList)\n }\n\n function updateSingleValue() {\n const { separator } = props\n\n const targetValue = selectedNodeKeys.value.length\n ? selectedNodeKeys.value.join(separator!)\n : undefined\n\n const targetLabel = selectedNodeKeys.value\n .map((key) => {\n const node = dataMap.value.get(key)\n return node?.label\n })\n .filter(Boolean)\n .join(separator!)\n\n emit('update:modelValue', targetValue)\n emit('change', targetValue, targetLabel, currentItem.value!)\n }\n\n /**\n * 单选选择\n *\n * @param panelIndex 面板索引\n * @param item 选中的节点\n */\n function selectItem(panelIndex: number, item: CascadeNode) {\n // 设置选中的节点\n currentItem.value = item\n selectedNodeKeys.value[panelIndex] = item.value\n selectedNodeKeys.value.splice(panelIndex + 1)\n triggerRef(selectedNodeKeys)\n\n // 展开子级面板\n setPanelItem(panelIndex, item.children)\n\n nextTick(() => {\n dropdownRef.value?.updateDropdown()\n })\n\n if (!item.children?.length && !props.multiple) {\n dropdownRef.value?.close()\n }\n }\n\n function initSingleSelect() {\n const { modelValue, separator } = props\n\n if (modelValue && typeof modelValue === 'string') {\n const nodes = modelValue.split(separator!)\n selectedNodeKeys.value = nodes\n getPanelItemList(forest.value.roots)\n } else {\n selectedNodeKeys.value = []\n getPanelItemList(forest.value.roots)\n }\n }\n\n watch(\n [() => props.multiple, () => props.modelValue, forest],\n ([multiple]) => {\n if (multiple || isUserActive()) return\n initSingleSelect()\n },\n { immediate: true }\n )\n\n return {\n displayedValue,\n selectItem,\n selectedNodeKeys,\n updateSingleValue,\n initSingleSelect,\n panelItemList,\n getPanelItemList,\n setPanelItem,\n createPanelItem\n }\n}\n"],"mappings":";;;;AA0CA,SAAgB,UAAU,SAA2C;CACnE,MAAM,EAAE,OAAO,MAAM,SAAS,cAAc,aAAa,WAAW;;CAGpE,MAAM,mBAAmB,WAAqB,EAAE,CAAC;CAEjD,MAAM,cAAc,YAAiC;;CAGrD,MAAM,gBAAgB,WAAwB,EAAE,CAAC;CACjD,MAAM,MAAM,gBAAgB;CAC5B,SAAS,gBAAgB,OAAiC;AACxD,SAAO;GAAE,KAAK,KAAK;GAAE,OAAO,MAAM,QAAQ,SAAS,KAAK,QAAQ;GAAE;;CAGpE,MAAM,iBAAiB,eAAe;EACpC,MAAM,EAAE,YAAY,cAAc;AAGlC,UADE,cAAc,OAAO,eAAe,WAAW,WAAW,MAAM,UAAW,GAAG,KAAA,IAE5E,KAAK,MAAM;AAEX,UADa,QAAQ,MAAM,IAAI,EACpB,EAAE,SAAS;IACtB,CACD,KAAK,MAAM,UAAU;GACxB;CAEF,SAAS,iBAAiB,MAAsB;EAC9C,MAAM,iBAAmC,EAAE;AAC3C,MAAI,CAAC,MAAM,OAAQ,QAAO;AAC1B,iBAAe,KAAK,gBAAgB,KAAK,CAAC;AAE1C,mBAAiB,MAAM,MAAM,GAAG,GAAG,CAAC,SAAS,QAAQ;GACnD,MAAM,OAAO,QAAQ,MAAM,IAAI,IAAI;AACnC,SAAM,UAAU,UAAU,eAAe,KAAK,gBAAgB,KAAK,SAAS,CAAC;IAC7E;AAEF,gBAAc,QAAQ;;CAGxB,SAAS,aAAa,YAAoB,WAA2B;AACnE,MAAI,WAAW,QAAQ;AACrB,iBAAc,MAAM,aAAa,KAAK,gBAAgB,UAAU;AAChE,iBAAc,MAAM,OAAO,aAAa,EAAE;QAE1C,eAAc,MAAM,OAAO,aAAa,EAAE;AAG5C,aAAW,cAAc;;CAG3B,SAAS,oBAAoB;EAC3B,MAAM,EAAE,cAAc;EAEtB,MAAM,cAAc,iBAAiB,MAAM,SACvC,iBAAiB,MAAM,KAAK,UAAW,GACvC,KAAA;EAEJ,MAAM,cAAc,iBAAiB,MAClC,KAAK,QAAQ;AAEZ,UADa,QAAQ,MAAM,IAAI,IACpB,EAAE;IACb,CACD,OAAO,QAAQ,CACf,KAAK,UAAW;AAEnB,OAAK,qBAAqB,YAAY;AACtC,OAAK,UAAU,aAAa,aAAa,YAAY,MAAO;;;;;;;;CAS9D,SAAS,WAAW,YAAoB,MAAmB;AAEzD,cAAY,QAAQ;AACpB,mBAAiB,MAAM,cAAc,KAAK;AAC1C,mBAAiB,MAAM,OAAO,aAAa,EAAE;AAC7C,aAAW,iBAAiB;AAG5B,eAAa,YAAY,KAAK,SAAS;AAEvC,iBAAe;AACb,eAAY,OAAO,gBAAgB;IACnC;AAEF,MAAI,CAAC,KAAK,UAAU,UAAU,CAAC,MAAM,SACnC,aAAY,OAAO,OAAO;;CAI9B,SAAS,mBAAmB;EAC1B,MAAM,EAAE,YAAY,cAAc;AAElC,MAAI,cAAc,OAAO,eAAe,UAAU;AAEhD,oBAAiB,QADH,WAAW,MAAM,UACD;AAC9B,oBAAiB,OAAO,MAAM,MAAM;SAC/B;AACL,oBAAiB,QAAQ,EAAE;AAC3B,oBAAiB,OAAO,MAAM,MAAM;;;AAIxC,OACE;QAAO,MAAM;QAAgB,MAAM;EAAY;EAAO,GACrD,CAAC,cAAc;AACd,MAAI,YAAY,cAAc,CAAE;AAChC,oBAAkB;IAEpB,EAAE,WAAW,MAAM,CACpB;AAED,QAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checkbox-group.js","names":[],"sources":["../../../src/components/checkbox-group/checkbox-group.vue"],"sourcesContent":["<template>\n <div :class=\"[cls.b, cls.m(size), bem.is('block', block)]\" v-if=\"!readonly\">\n <u-checkbox\n v-for=\"item of items\"\n :key=\"item[valueKey]\"\n :model-value=\"getCheckStatus(item)\"\n @update:model-value=\"handleUpdate($event, item)\"\n :disabled=\"disabled\"\n :size=\"size\"\n >\n {{ item[labelKey] }}\n </u-checkbox>\n </div>\n\n <div v-else-if=\"model?.length\" :class=\"[cls.m(size), cls.e('readonly-tags')]\">\n <div :class=\"cls.e('tags')\">\n <u-tag v-for=\"tag of model\" :key=\"tag\">\n {{ getLabel(tag) }}\n </u-tag>\n </div>\n </div>\n\n <template v-else>\n {{ FORM_EMPTY_CONTENT }}\n </template>\n</template>\n\n<script lang=\"ts\" setup>\nimport { useFormComponent, useFormFallbackProps } from '@veltra/compositions'\nimport { bem, FORM_EMPTY_CONTENT } from '@veltra/utils'\n\nimport type { CheckboxGroupProps, CheckboxGroupEmits } from '../../types'\nimport { UCheckbox } from '../checkbox'\nimport { UTag } from '../tag'\n\ndefineOptions({\n name: 'CheckboxGroup'\n})\n\nconst props = withDefaults(defineProps<CheckboxGroupProps>(), {\n labelKey: 'label',\n valueKey: 'value',\n disabled: undefined,\n readonly: undefined\n})\n\ndefineEmits<CheckboxGroupEmits>()\n\nconst model = defineModel<any[]>()\n\nconst cls = bem('checkbox-group')\n\nconst { formProps } = useFormComponent()\n\nconst { size, disabled, readonly } = useFormFallbackProps([formProps ?? {}, props], {\n size: 'default',\n disabled: false,\n readonly: false\n})\n\n/**\n * 获取checkbox的选中状态\n * @param item - 模型对象\n * @returns 模型值是否存在于model.value中\n */\nconst getCheckStatus = (item: Record<string, string | number>): boolean => {\n const { valueKey } = props\n const value = item[valueKey]\n if (!value || !model.value) return false\n return model.value.includes(value)\n}\n\n/**\n * 处理更新操作\n * @param checked - 指示是否选中\n * @param item - 更新的项\n */\nconst handleUpdate = (checked: boolean, item: Record<string, string | number>) => {\n const { valueKey } = props\n const value = item[valueKey]\n if (!value) return\n if (checked) {\n model.value = [...(model.value ?? []), value]\n } else {\n model.value = model.value?.filter((v) => v !== value)\n }\n}\n\nconst getLabel = (value: string | number) => {\n const { items, valueKey, labelKey } = props\n const item = items.find((item) => item[valueKey] === value)\n return item?.[labelKey]\n}\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuCA,MAAM,QAAQ;EASd,MAAM,QAAQ,SAAkB,SAAA,aAAC;EAEjC,MAAM,MAAM,IAAI,iBAAgB;EAEhC,MAAM,EAAE,cAAc,kBAAiB;EAEvC,MAAM,EAAE,MAAM,UAAU,aAAa,qBAAqB,CAAC,aAAa,EAAE,EAAE,MAAM,EAAE;GAClF,MAAM;GACN,UAAU;GACV,UAAU;GACX,CAAA;;;;;;EAOD,MAAM,kBAAkB,SAAmD;GACzE,MAAM,EAAE,aAAa;GACrB,MAAM,QAAQ,KAAK;AACnB,OAAI,CAAC,SAAS,CAAC,MAAM,MAAO,QAAO;AACnC,UAAO,MAAM,MAAM,SAAS,MAAK;;;;;;;EAQnC,MAAM,gBAAgB,SAAkB,SAA0C;GAChF,MAAM,EAAE,aAAa;GACrB,MAAM,QAAQ,KAAK;AACnB,OAAI,CAAC,MAAO;AACZ,OAAI,QACF,OAAM,QAAQ,CAAC,GAAI,MAAM,SAAS,EAAE,EAAG,MAAK;OAE5C,OAAM,QAAQ,MAAM,OAAO,QAAQ,MAAM,MAAM,MAAK;;EAIxD,MAAM,YAAY,UAA2B;GAC3C,MAAM,EAAE,OAAO,UAAU,aAAa;AAEtC,UADa,MAAM,MAAM,SAAS,KAAK,cAAc,
|
|
1
|
+
{"version":3,"file":"checkbox-group.js","names":[],"sources":["../../../src/components/checkbox-group/checkbox-group.vue"],"sourcesContent":["<template>\n <div :class=\"[cls.b, cls.m(size), bem.is('block', block)]\" v-if=\"!readonly\">\n <u-checkbox\n v-for=\"item of items\"\n :key=\"item[valueKey]\"\n :model-value=\"getCheckStatus(item)\"\n @update:model-value=\"handleUpdate($event, item)\"\n :disabled=\"disabled\"\n :size=\"size\"\n >\n {{ item[labelKey] }}\n </u-checkbox>\n </div>\n\n <div v-else-if=\"model?.length\" :class=\"[cls.m(size), cls.e('readonly-tags')]\">\n <div :class=\"cls.e('tags')\">\n <u-tag v-for=\"tag of model\" :key=\"tag\">\n {{ getLabel(tag) }}\n </u-tag>\n </div>\n </div>\n\n <template v-else>\n {{ FORM_EMPTY_CONTENT }}\n </template>\n</template>\n\n<script lang=\"ts\" setup>\nimport { useFormComponent, useFormFallbackProps } from '@veltra/compositions'\nimport { bem, FORM_EMPTY_CONTENT } from '@veltra/utils'\n\nimport type { CheckboxGroupProps, CheckboxGroupEmits } from '../../types'\nimport { UCheckbox } from '../checkbox'\nimport { UTag } from '../tag'\n\ndefineOptions({\n name: 'CheckboxGroup'\n})\n\nconst props = withDefaults(defineProps<CheckboxGroupProps>(), {\n labelKey: 'label',\n valueKey: 'value',\n disabled: undefined,\n readonly: undefined\n})\n\ndefineEmits<CheckboxGroupEmits>()\n\nconst model = defineModel<any[]>()\n\nconst cls = bem('checkbox-group')\n\nconst { formProps } = useFormComponent()\n\nconst { size, disabled, readonly } = useFormFallbackProps([formProps ?? {}, props], {\n size: 'default',\n disabled: false,\n readonly: false\n})\n\n/**\n * 获取checkbox的选中状态\n * @param item - 模型对象\n * @returns 模型值是否存在于model.value中\n */\nconst getCheckStatus = (item: Record<string, string | number>): boolean => {\n const { valueKey } = props\n const value = item[valueKey]\n if (!value || !model.value) return false\n return model.value.includes(value)\n}\n\n/**\n * 处理更新操作\n * @param checked - 指示是否选中\n * @param item - 更新的项\n */\nconst handleUpdate = (checked: boolean, item: Record<string, string | number>) => {\n const { valueKey } = props\n const value = item[valueKey]\n if (!value) return\n if (checked) {\n model.value = [...(model.value ?? []), value]\n } else {\n model.value = model.value?.filter((v) => v !== value)\n }\n}\n\nconst getLabel = (value: string | number) => {\n const { items, valueKey, labelKey } = props\n const item = items.find((item) => item[valueKey] === value)\n return item?.[labelKey]\n}\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuCA,MAAM,QAAQ;EASd,MAAM,QAAQ,SAAkB,SAAA,aAAC;EAEjC,MAAM,MAAM,IAAI,iBAAgB;EAEhC,MAAM,EAAE,cAAc,kBAAiB;EAEvC,MAAM,EAAE,MAAM,UAAU,aAAa,qBAAqB,CAAC,aAAa,EAAE,EAAE,MAAM,EAAE;GAClF,MAAM;GACN,UAAU;GACV,UAAU;GACX,CAAA;;;;;;EAOD,MAAM,kBAAkB,SAAmD;GACzE,MAAM,EAAE,aAAa;GACrB,MAAM,QAAQ,KAAK;AACnB,OAAI,CAAC,SAAS,CAAC,MAAM,MAAO,QAAO;AACnC,UAAO,MAAM,MAAM,SAAS,MAAK;;;;;;;EAQnC,MAAM,gBAAgB,SAAkB,SAA0C;GAChF,MAAM,EAAE,aAAa;GACrB,MAAM,QAAQ,KAAK;AACnB,OAAI,CAAC,MAAO;AACZ,OAAI,QACF,OAAM,QAAQ,CAAC,GAAI,MAAM,SAAS,EAAE,EAAG,MAAK;OAE5C,OAAM,QAAQ,MAAM,OAAO,QAAQ,MAAM,MAAM,MAAK;;EAIxD,MAAM,YAAY,UAA2B;GAC3C,MAAM,EAAE,OAAO,UAAU,aAAa;AAEtC,UADa,MAAM,MAAM,SAAS,KAAK,cAAc,MAC9C,GAAO;;;WA1FoD,MAAA,SAAQ,IAAA,WAAA,EAA1E,mBAWM,OAAA;;IAXA,OAAK,eAAA;KAAG,MAAA,IAAG,CAAC;KAAG,MAAA,IAAG,CAAC,EAAE,MAAA,KAAI,CAAA;KAAG,MAAA,IAAG,CAAC,GAAE,SAAU,QAAA,MAAK;KAAA,CAAA;yBACrD,mBASa,UAAA,MAAA,WARI,QAAA,QAAR,SAAI;wBADb,YASa,MAAA,YAAA,EAAA;KAPV,KAAK,KAAK,QAAA;KACV,eAAa,eAAe,KAAI;KAChC,wBAAkB,WAAE,aAAa,QAAQ,KAAI;KAC7C,UAAU,MAAA,SAAQ;KAClB,MAAM,MAAA,KAAI;;4BAES,CAAA,gBAAA,gBAAjB,KAAK,QAAA,UAAQ,EAAA,EAAA,CAAA,CAAA;;;;;;;;qBAIJ,MAAA,OAAO,UAAA,WAAA,EAAvB,mBAMM,OAAA;;IAN0B,OAAK,eAAA,CAAG,MAAA,IAAG,CAAC,EAAE,MAAA,KAAI,CAAA,EAAG,MAAA,IAAG,CAAC,EAAC,gBAAA,CAAA,CAAA;OACxD,mBAIM,OAAA,EAJA,OAAK,eAAE,MAAA,IAAG,CAAC,EAAC,OAAA,CAAA,EAAA,EAAA,EAAA,UAAA,KAAA,EAChB,mBAEQ,UAAA,MAAA,WAFa,MAAA,QAAP,QAAG;wBAAjB,YAEQ,MAAA,YAAA,EAAA,EAFqB,KAAK,KAAG,EAAA;4BAChB,CAAA,gBAAA,gBAAhB,SAAS,IAAG,CAAA,EAAA,EAAA,CAAA,CAAA;;;wCAKrB,mBAEW,UAAA,EAAA,KAAA,GAAA,EAAA,CAAA,gBAAA,gBADN,MAAA,mBAAkB,CAAA,EAAA,EAAA,CAAA,EAAA,GAAA"}
|
|
@@ -14,10 +14,10 @@ declare const __VLS_export: _$vue.DefineComponent<__VLS_PublicProps, {}, {}, {},
|
|
|
14
14
|
}, string, _$vue.PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
15
15
|
"onUpdate:modelValue"?: ((value: any[]) => any) | undefined;
|
|
16
16
|
}>, {
|
|
17
|
-
disabled: boolean;
|
|
18
|
-
readonly: boolean;
|
|
19
17
|
labelKey: string;
|
|
20
18
|
valueKey: string;
|
|
19
|
+
disabled: boolean;
|
|
20
|
+
readonly: boolean;
|
|
21
21
|
}, {}, {}, {}, string, _$vue.ComponentProvideOptions, false, {}, any>;
|
|
22
22
|
declare const _default: typeof __VLS_export;
|
|
23
23
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"date-panel.js","names":[],"sources":["../../../src/components/date-panel/date-panel.vue"],"sourcesContent":["<template>\n <div :class=\"[cls.b, cls.m(props.size)]\">\n <template v-if=\"panelType === 'day'\">\n <DayHeader />\n <DayPanel />\n </template>\n\n <template v-else-if=\"panelType === 'year'\">\n <YearHeader />\n <YearPanel />\n </template>\n\n <template v-else-if=\"panelType === 'month'\">\n <MonthHeader />\n <MonthPanel />\n </template>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport type { DatePanelEmits, DatePanelProps } from '../../types'\nimport DayHeader from './headers/day.vue'\nimport MonthHeader from './headers/month.vue'\nimport YearHeader from './headers/year.vue'\nimport DayPanel from './panels/day.vue'\nimport MonthPanel from './panels/month.vue'\nimport YearPanel from './panels/year.vue'\nimport { usePanel } from './use-panel'\n\ndefineOptions({\n name: 'DatePanel'\n})\n\nconst props = withDefaults(defineProps<DatePanelProps>(), {\n size: 'default',\n type: 'date'\n})\n\nconst emit = defineEmits<DatePanelEmits>()\n\nconst { cls, panelType } = usePanel({\n props,\n emit\n})\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;EAiCA,MAAM,QAAQ;EAOd,MAAM,EAAE,KAAK,cAAc,SAAS;GAClC;GACA,
|
|
1
|
+
{"version":3,"file":"date-panel.js","names":[],"sources":["../../../src/components/date-panel/date-panel.vue"],"sourcesContent":["<template>\n <div :class=\"[cls.b, cls.m(props.size)]\">\n <template v-if=\"panelType === 'day'\">\n <DayHeader />\n <DayPanel />\n </template>\n\n <template v-else-if=\"panelType === 'year'\">\n <YearHeader />\n <YearPanel />\n </template>\n\n <template v-else-if=\"panelType === 'month'\">\n <MonthHeader />\n <MonthPanel />\n </template>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport type { DatePanelEmits, DatePanelProps } from '../../types'\nimport DayHeader from './headers/day.vue'\nimport MonthHeader from './headers/month.vue'\nimport YearHeader from './headers/year.vue'\nimport DayPanel from './panels/day.vue'\nimport MonthPanel from './panels/month.vue'\nimport YearPanel from './panels/year.vue'\nimport { usePanel } from './use-panel'\n\ndefineOptions({\n name: 'DatePanel'\n})\n\nconst props = withDefaults(defineProps<DatePanelProps>(), {\n size: 'default',\n type: 'date'\n})\n\nconst emit = defineEmits<DatePanelEmits>()\n\nconst { cls, panelType } = usePanel({\n props,\n emit\n})\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;EAiCA,MAAM,QAAQ;EAOd,MAAM,EAAE,KAAK,cAAc,SAAS;GAClC;GACA,MAAA;GACD,CAAA;;uBA1CC,mBAeM,OAAA,EAfA,OAAK,eAAA,CAAG,MAAA,IAAG,CAAC,GAAG,MAAA,IAAG,CAAC,EAAE,MAAM,KAAI,CAAA,CAAA,EAAA,EAAA,CACnB,MAAA,UAAS,KAAA,SAAA,WAAA,EAAzB,mBAGW,UAAA,EAAA,KAAA,GAAA,EAAA,CAFT,YAAa,YAAA,EACb,YAAY,YAAA,CAAA,EAAA,GAAA,IAGO,MAAA,UAAS,KAAA,UAAA,WAAA,EAA9B,mBAGW,UAAA,EAAA,KAAA,GAAA,EAAA,CAFT,YAAc,YAAA,EACd,YAAa,YAAA,CAAA,EAAA,GAAA,IAGM,MAAA,UAAS,KAAA,WAAA,WAAA,EAA9B,mBAGW,UAAA,EAAA,KAAA,GAAA,EAAA,CAFT,YAAe,YAAA,EACf,YAAc,YAAA,CAAA,EAAA,GAAA,IAAA,mBAAA,QAAA,KAAA,CAAA,EAAA,EAAA"}
|
|
@@ -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"}
|
|
@@ -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":";;;;;;;AAqDA,SAAS,mBACP,OACA,QACM;AACN,QAAO,aAAa;AAClB,MAAI,UAAU,MAAM;GAClB,MAAM,gBAAgB,kBAAkB,OAAO,cAAc,GAAG,OAAO,MAAM;GAC7E,MAAM,YAAY,eAAe;AAEjC,OAAI,cAAc,QAAQ,iBAAiB,MAAM;AAC/C,UAAM,gBAAgB;IACtB,MAAM,aAAa,gBAAgB,OAAO;AAE1C,QAAI,eAAe,KACjB,eAAc,QAAQ,aAAa,WAAW;AAGhD,kBAAc,QAAQ,cAAc,UAAU,gBAAgB,CAAC;;;GAGnE;;AAGJ,SAAS,oBACP,OACA,QACM;AACN,OAAM,gBAAgB;AACtB,QAAO,aACC;EACJ,MAAM,YAAY,eAAe;EACjC,MAAM,gBAAgB,kBAAkB,OAAO,eAAe,GAAG,MAAM,gBAAgB;AACvF,MAAI,iBAAiB,QAAQ,kBAAkB,UAAU,CACvD,iCAAgC,eAAe,UAAU;IAG7D,EAAE,KAAK,WAAW,CACnB;;AAGH,SAAS,kBACP,OACA,QACM;AACN,oBAAmB,OAAO,OAAO;AACjC,QAAO,aAAa;EAClB,MAAM,YAAY,eAAe;AAEjC,MAAI,kBAAkB,UAAU,CAC9B,WAAU,YAAY;GAExB;;AAGJ,SAAS,4BAA4B,QAAmC;AACtE,QAAO,cACL,OAAO,gBACL,2BACC,eAAe;EACd,MAAM,YAAY,eAAe;AAEjC,MAAI,CAAC,kBAAkB,UAAU,CAC/B,QAAO;AAGT,YAAU,gBAAgB,WAAW;AACrC,SAAO;IAET,wBACD,EACD,OAAO,gBACL,sBACC,eAAe;EACd,MAAM,YAAY,eAAe;AAEjC,MAAI,CAAC,kBAAkB,UAAU,CAC/B,QAAO;AAGT,YAAU,WAAW,WAAW;AAChC,SAAO;IAET,wBACD,EACD,OAAO,gBACL,sBACC,eAAe;EACd,MAAM,YAAY,eAAe;AAEjC,MAAI,CAAC,kBAAkB,UAAU,CAC/B,QAAO;AAGT,YAAU,WAAW,WAAW;AAChC,SAAO;IAET,wBACD,EAED,OAAO,gBACL,oCACC,gBAAgB;EACf,MAAM,YAAY,eAAe;AAEjC,MAAI,CAAC,kBAAkB,UAAU,CAC/B,QAAO;AAGT,MAAI,OAAO,gBAAgB,SACzB,WAAU,WAAW,YAAY;OAC5B;GACL,MAAM,eAAe,YAAY;AAEjC,OAAI,gBAAgB,KAClB,iCAAgC,cAAc,UAAU;QACnD;IACL,MAAM,OAAO,YAAY;AAEzB,QAAI,KACF,WAAU,WAAW,KAAK;;;AAKhC,SAAO;IAET,wBACD,EACD,OAAO,gBACL,2BACM;EACJ,MAAM,YAAY,eAAe;AAEjC,MAAI,CAAC,kBAAkB,UAAU,CAC/B,QAAO;AAGT,YAAU,YAAY;AACtB,SAAO;IAET,wBACD,EACD,OAAO,gBACL,4BACC,gBAAgB;EACf,MAAM,YAAY,eAAe;AAEjC,MAAI,CAAC,kBAAkB,UAAU,CAC/B,QAAO;AAGT,YAAU,gBAAgB,YAAY;AACtC,SAAO;IAET,wBACD,EACD,OAAO,gBACL,gCACM;EACJ,MAAM,YAAY,eAAe;AAEjC,MAAI,CAAC,kBAAkB,UAAU,CAC/B,QAAO;AAGT,YAAU,iBAAiB;AAC3B,SAAO;IAET,wBACD,EACD,OAAO,gBACL,8BACM;AAGJ,MAAI,CAAC,kBAFa,eAEc,CAAC,CAC/B,QAAO;AAGT,SAAO;IAET,wBACD,EACD,OAAO,gBACL,+BACM;AAGJ,MAAI,CAAC,kBAFa,eAEc,CAAC,CAC/B,QAAO;AAGT,SAAO;IAET,wBACD,EACD,OAAO,gBACL,wBACC,UAAU;AAGT,MAAI,CAAC,kBAFa,eAEc,CAAC,CAC/B,QAAO;AAGT,MAAI,UAAU,UAAU,aAAa,QACnC,QAAO;AAGT,QAAM,gBAAgB;AACtB,SAAO,OAAO,gBAAgB,0BAA0B,KAAK;IAE/D,wBACD,EACD,OAAO,gBACL,qBACC,UAAU;AAGT,MAAI,CAAC,kBAFa,eAEc,CAAC,CAC/B,QAAO;AAGT,QAAM,gBAAgB;AACtB,SAAO,OAAO,gBAAgB,0BAA0B,MAAM;IAEhE,wBACD,EACD,OAAO,gBACL,oBACC,UAAU;AAGT,MAAI,CAAC,kBAFa,eAEc,CAAC,CAC/B,QAAO;AAGT,MAAI,UAAU,MAAM;AAClB,QAAK,UAAU,aAAa,oBAAoB,qBAC9C,QAAO;AAGT,SAAM,gBAAgB;;AAGxB,SAAO,OAAO,gBAAgB,2BAA2B,MAAM;IAEjE,wBACD,EACD,OAAO,gBACL,0BACM;AACJ,cAAY;AAEZ,SAAO;IAET,wBACD,CACF;;AAGH,SAAS,0BAA0B,QAAmC;AACpE,QAAO,cACL,OAAO,gBACL,eACC,UAAU;AAGT,MAAI,CAAC,kBAFa,eAEc,CAAC,CAC/B,QAAO;AAGT,qBAAmB,OAAO,OAAO;AACjC,SAAO;IAET,wBACD,EACD,OAAO,gBACL,cACC,UAAU;AAGT,MAAI,CAAC,kBAFa,eAEc,CAAC,CAC/B,QAAO;AAGT,oBAAkB,OAAO,OAAO;AAChC,SAAO;IAET,wBACD,EACD,OAAO,gBACL,gBACC,UAAU;AAGT,MAAI,CAAC,kBAFa,eAEc,CAAC,CAC/B,QAAO;AAGT,sBAAoB,OAAO,OAAO;AAClC,SAAO;IAET,wBACD,CACF;;AAGH,SAAS,yBAAyB,QAAmC;AACnE,QAAO,cACL,OAAO,gBACL,oBACC,UAAU;AACT,MAAI,CAAC,OAAO,YAAY,CACtB,QAAO;EAGT,MAAM,YAAY,kBAAkB,MAAM,OAAO;AACjD,MAAI,CAAC,UACH,QAAO;EAGT,MAAM,cAAc,OAAO,gBAAgB;AAC3C,MAAI,CAAC,eAAe,EAAE,MAAM,kBAAkB,MAC5C,QAAO;AAET,MAAI,CAAC,YAAY,SAAS,MAAM,OAAO,CACrC,QAAO;EAGT,MAAM,UAAU,kBAAkB,OAAO;AACzC,MAAI,CAAC,WAAW,CAAC,MAAM,aACrB,QAAO;AAGT,QAAM,aAAa,gBAAgB;AACnC,2BAAyB,MAAM,cAAc;GAC3C,QAAQ;GACR;GACA;GACD,CAAC;AACF,QAAM,aAAa,QAAQ,cAAc,kBAAkB;AAK3D,uBAAqB,QAHC,YAAY,cAChC,wCAAwC,UAAU,IAEV,EAAE;GAAE,QAAQ;GAAiB;GAAW;GAAS,CAAC;AAE5F,SAAO;IAET,wBACD,EACD,OAAO,gBACL,mBACC,UAAU;EACT,MAAM,cAAc,OAAO,gBAAgB;AAC3C,MAAI,CAAC,eAAe,EAAE,MAAM,kBAAkB,MAC5C,QAAO;AAET,MAAI,CAAC,YAAY,SAAS,MAAM,OAAO,CACrC,QAAO;EAGT,MAAM,UACJ,wBAAwB,MAAM,aAAa,IAAI,6BAA6B,OAAO;AACrF,MAAI,CAAC,SAAS;AACZ,sBAAmB,OAAO;AAC1B,UAAO;;EAGT,MAAM,UAAU,kBAAkB,OAAO;AACzC,MAAI,QAAQ,YAAY,SAAS;AAC/B,sBAAmB,OAAO;AAC1B,UAAO;;EAGT,MAAM,WAAW,gBAAgB,QAAQ,MAAM;AAC/C,MAAI,aAAa,MAAM;AACrB,sBAAmB,OAAO;AAC1B,UAAO;;AAGT,QAAM,gBAAgB;AACtB,MAAI,MAAM,aACR,OAAM,aAAa,aAAa;AAGlC,oBAAkB,QAAQ,SAAS;AACnC,yBAAuB,aAAa,MAAM,QAAQ;AAClD,SAAO;IAET,wBACD,EACD,OAAO,gBACL,eACC,UAAU;EACT,MAAM,UACJ,wBAAwB,MAAM,aAAa,IAAI,6BAA6B,OAAO;AACrF,MAAI,CAAC,QACH,QAAO;AAGT,QAAM,gBAAgB;EAEtB,MAAM,cAAc,OAAO,gBAAgB;EAC3C,MAAM,UAAU,kBAAkB,OAAO;AACzC,MAAI,CAAC,eAAe,CAAC,WAAW,EAAE,MAAM,kBAAkB,OAAO;AAC/D,wBAAqB,OAAO;AAC5B,UAAO;;AAET,MAAI,CAAC,YAAY,SAAS,MAAM,OAAO,EAAE;AACvC,wBAAqB,OAAO;AAC5B,UAAO;;EAGT,MAAM,WAAW,gBAAgB,QAAQ,MAAM;AAC/C,MAAI,aAAa,MAAM;AACrB,wBAAqB,OAAO;AAC5B,UAAO;;AAMT,kBAAgB,QAAQ;GACtB,aAHA,MAAM,cAAc,QAAA,0CAAsC,IAAI,KAAK,UAAU,QAAQ;GAIrF;GACA,YAAY;GACZ,gBAAgB;GACjB,CAAC;AAEF,uBAAqB,OAAO;AAC5B,SAAO;IAET,wBACD,CACF;;;;;;AAYH,SAAgB,qBACd,QACA,SACY;CACZ,MAAM,QAA2B;EAC/B,4BAA4B,OAAO;EACnC,0BAA0B,OAAO;EACjC,yBAAyB,OAAO;EACjC;AAED,KAAI,SAAS,mBACX,OAAM,KAAK,QAAQ,oBAAoB,CAAC;AAG1C,QAAO,cAAc,GAAG,MAAM"}
|
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"}
|