@veltra/desktop 1.2.7 → 1.2.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/dist/components/action/action-group.vue.d.ts +2 -2
  2. package/dist/components/action/action.vue.d.ts +1 -1
  3. package/dist/components/auto-complete/auto-complete.vue.d.ts +2 -2
  4. package/dist/components/batch-edit/batch-edit-form.js +41 -79
  5. package/dist/components/batch-edit/batch-edit-form.js.map +1 -1
  6. package/dist/components/batch-edit/batch-edit-list.js +17 -29
  7. package/dist/components/batch-edit/batch-edit-list.js.map +1 -1
  8. package/dist/components/batch-edit/batch-edit.js +34 -60
  9. package/dist/components/batch-edit/batch-edit.js.map +1 -1
  10. package/dist/components/batch-edit/batch-edit.vue.d.ts +3 -14
  11. package/dist/components/batch-edit/di.js.map +1 -1
  12. package/dist/components/batch-edit/form-action-header.js +25 -0
  13. package/dist/components/batch-edit/form-action-header.js.map +1 -0
  14. package/dist/components/batch-edit/style2.css +0 -13
  15. package/dist/components/batch-edit/use-edit-state.js +40 -0
  16. package/dist/components/batch-edit/use-edit-state.js.map +1 -0
  17. package/dist/components/batch-edit/use-handlers.js +146 -0
  18. package/dist/components/batch-edit/use-handlers.js.map +1 -0
  19. package/dist/components/batch-edit/use-shortcut-key.js +44 -0
  20. package/dist/components/batch-edit/use-shortcut-key.js.map +1 -0
  21. package/dist/components/cascade/cascade.vue.d.ts +4 -4
  22. package/dist/components/checkbox/checkbox-button.vue.d.ts +2 -2
  23. package/dist/components/checkbox/checkbox.vue.d.ts +1 -1
  24. package/dist/components/checkbox-group/checkbox-group.vue.d.ts +2 -2
  25. package/dist/components/code-editor/code-editor.vue.d.ts +1 -1
  26. package/dist/components/date-panel/date-panel.vue.d.ts +1 -1
  27. package/dist/components/date-picker/date-picker.vue.d.ts +2 -2
  28. package/dist/components/date-range-picker/date-range-picker.vue.d.ts +2 -2
  29. package/dist/components/empty/empty.vue.d.ts +1 -1
  30. package/dist/components/file-picker/file-picker.vue.d.ts +1 -1
  31. package/dist/components/form/form.js.map +1 -1
  32. package/dist/components/form/form.vue.d.ts +5 -1
  33. package/dist/components/form/form.vue_vue_type_script_setup_true_lang.js +8 -2
  34. package/dist/components/form/form.vue_vue_type_script_setup_true_lang.js.map +1 -1
  35. package/dist/components/form-item/form-item.js.map +1 -1
  36. package/dist/components/form-item/form-item.vue_vue_type_script_setup_true_lang.js +3 -2
  37. package/dist/components/form-item/form-item.vue_vue_type_script_setup_true_lang.js.map +1 -1
  38. package/dist/components/input/input.vue.d.ts +8 -8
  39. package/dist/components/multi-select/multi-select.vue.d.ts +3 -3
  40. package/dist/components/multi-tree-select/multi-tree-select.vue.d.ts +6 -6
  41. package/dist/components/number-input/number-input.vue.d.ts +4 -4
  42. package/dist/components/number-range-input/number-range-input.vue.d.ts +2 -2
  43. package/dist/components/palette/palette.vue.d.ts +1 -1
  44. package/dist/components/password-input/password-input.vue.d.ts +2 -2
  45. package/dist/components/pop-confirm/pop-confirm.vue.d.ts +1 -1
  46. package/dist/components/progress-nodes/progress-nodes.vue.d.ts +1 -1
  47. package/dist/components/radio-group/radio-group.vue.d.ts +2 -2
  48. package/dist/components/rich-text-editor/rich-text-editor.vue.d.ts +2 -2
  49. package/dist/components/scroll/scroll.vue.d.ts +2 -2
  50. package/dist/components/select/select.vue.d.ts +2 -2
  51. package/dist/components/steps/steps.vue.d.ts +3 -3
  52. package/dist/components/switch/switch.vue.d.ts +1 -1
  53. package/dist/components/tabs/tabs-horizontal.vue.d.ts +2 -2
  54. package/dist/components/tabs/tabs-vertical.vue.d.ts +2 -2
  55. package/dist/components/tabs/tabs.vue.d.ts +2 -2
  56. package/dist/components/textarea/textarea.vue.d.ts +4 -4
  57. package/dist/components/tip/tip.vue.d.ts +1 -1
  58. package/dist/components/tree/tree.vue.d.ts +1 -1
  59. package/dist/components/tree-select/tree-select.vue.d.ts +6 -6
  60. package/dist/index.d.ts +4 -4
  61. package/dist/types/batch-edit.d.ts +38 -12
  62. package/dist/types/form.d.ts +4 -1
  63. package/dist/types/index.d.ts +3 -3
  64. package/package.json +6 -6
  65. package/src/components/batch-edit/batch-edit-form.vue +40 -86
  66. package/src/components/batch-edit/batch-edit-list.vue +13 -29
  67. package/src/components/batch-edit/batch-edit.vue +27 -92
  68. package/src/components/batch-edit/di.ts +6 -5
  69. package/src/components/batch-edit/form-action-header.ts +21 -0
  70. package/src/components/batch-edit/style.scss +0 -14
  71. package/src/components/batch-edit/use-dialog-effect.ts +21 -0
  72. package/src/components/batch-edit/use-edit-state.ts +55 -0
  73. package/src/components/batch-edit/use-handlers.ts +226 -0
  74. package/src/components/batch-edit/use-shortcut-key.ts +58 -0
  75. package/src/components/form/form.vue +10 -3
  76. package/src/components/form-item/form-item.vue +4 -2
  77. package/src/types/batch-edit.ts +43 -22
  78. package/src/types/form.ts +4 -0
  79. package/dist/components/batch-edit/use-edit.js +0 -215
  80. package/dist/components/batch-edit/use-edit.js.map +0 -1
  81. package/src/components/batch-edit/use-edit.ts +0 -343
@@ -1,13 +1,29 @@
1
1
  import { ActionProps } from "./action.js";
2
- import { TableColumn, TableEmits, TableProps, TableRow } from "./table.js";
2
+ import { TableColumn, TableColumnSlotsScope, TableEmits, TableProps, TableRow } from "./table.js";
3
3
  import { DeconstructValue } from "@veltra/utils";
4
4
 
5
5
  //#region src/types/batch-edit.d.ts
6
6
  /** 批量编辑列 */
7
7
  interface BatchEditColumn extends TableColumn {}
8
- type BatchEditFeature = 'create' | 'update' | 'copy' | 'delete' | 'view' | 'createChild';
9
- /** 批量编辑模式 */
10
- type BatchEditMode = 'normal' | 'quick';
8
+ type BatchEditFeature = 'create' | 'update' | 'delete' | 'view' | 'createChild';
9
+ type BatchEditFormStatus = 'hidden';
10
+ /** 批量编辑状态 */
11
+ interface BatchEditStates {
12
+ /** 层级 */
13
+ depth: number;
14
+ /** 表单可见性 */
15
+ formVisible: boolean;
16
+ /** 表单操作类型 */
17
+ formActionType: 'create' | 'update' | 'view' | 'createChild';
18
+ /** 加载状态 */
19
+ loading: boolean;
20
+ /** 当前编辑行 */
21
+ row?: TableRow;
22
+ /** 当前编辑或者新增的父级行 */
23
+ parentRow?: TableRow;
24
+ /** 行索引路径, */
25
+ indexPath: number[];
26
+ }
11
27
  /** 批量编辑组件属性 */
12
28
  interface BatchEditProps extends TableProps {
13
29
  /**
@@ -24,14 +40,13 @@ interface BatchEditProps extends TableProps {
24
40
  /** 只读模式 */
25
41
  readonly?: boolean;
26
42
  /**
27
- * 编辑模式
28
- * @default 'normal'
29
- * @description `quick` 模式下编辑行时表单直接绑定 `row.data` 实时更新,且不调用 `saveMethod`
43
+ * 开启快速编辑
44
+ * @description 开启后,编辑行时表单实时写回 `row.data`(经 `model` 中转),且不调用 `saveMethod`
30
45
  */
31
- mode?: BatchEditMode;
46
+ quickEdit?: boolean;
32
47
  /**
33
48
  * 新增前的钩子
34
- * @description 仅作用于 create 类操作。`normal` 模式在保存时调用;`quick` 模式在点击新增类按钮时立即调用。可直接修改传入的 draft 对象
49
+ * @description 仅作用于 create 类操作,在保存时调用。可直接修改传入的 draft 对象
35
50
  */
36
51
  beforeCreate?: (data: Record<string, any>, parentData?: Record<string, any>) => void | Promise<void>;
37
52
  /** label的宽度 */
@@ -40,14 +55,14 @@ interface BatchEditProps extends TableProps {
40
55
  deleteMethod?: (data: Record<string, any>[]) => any;
41
56
  /**
42
57
  * 保存方法
43
- * @description 仅在 `normal` 模式下、保存时调用(create / update)
58
+ * @description 保存时调用。`quick` 模式下编辑行时实时写回,不调用此方法;新增时与 `normal` 模式一致
44
59
  * @returns 如果返回一个值,那么这个值会被插入,否则插入的为表单值
45
60
  */
46
61
  saveMethod?: (/** 表单数据 */
47
62
 
48
63
  data: Record<string, any>, /** 操作类型 */
49
64
 
50
- actionType: 'create' | 'update', /** 父级数据 */
65
+ actionType: BatchEditStates['formActionType'], /** 父级数据 */
51
66
 
52
67
  parentData?: Record<string, any>) => any;
53
68
  /**
@@ -84,10 +99,21 @@ interface BatchEditEmits extends TableEmits {
84
99
  /** 更新数据 */
85
100
  (e: 'update:data', value: Record<string, any>[]): void;
86
101
  }
102
+ type BatchEditSlots = {
103
+ form?: (props: {
104
+ /** 当前编辑的层级 */depth?: number; /** 当前编辑的行 */
105
+ row?: TableRow; /** 当前编辑的行索引 */
106
+ index?: number; /** 操作的目标行索引路径 */
107
+ indexes?: number[];
108
+ }) => any;
109
+ header?: () => any;
110
+ } & Partial<{
111
+ [key: `column:${string}`]: (props: TableColumnSlotsScope) => any;
112
+ }>;
87
113
  /** 批量编辑组件暴露的属性和方法(组件内部使用) */
88
114
  interface _BatchEditExposed {}
89
115
  /** 批量编辑组件暴露的属性和方法(组件外部使用, 引用的值会被自动解构) */
90
116
  type BatchEditExposed = DeconstructValue<_BatchEditExposed>;
91
117
  //#endregion
92
- export { BatchEditColumn, BatchEditEmits, BatchEditExposed, BatchEditFeature, BatchEditMode, BatchEditProps, _BatchEditExposed };
118
+ export { BatchEditColumn, BatchEditEmits, BatchEditExposed, BatchEditFeature, BatchEditFormStatus, BatchEditProps, BatchEditSlots, BatchEditStates, _BatchEditExposed };
93
119
  //# sourceMappingURL=batch-edit.d.ts.map
@@ -20,6 +20,9 @@ interface FormProps extends ComponentProps {
20
20
  /** 是否禁用 */
21
21
  disabled?: boolean;
22
22
  }
23
+ interface FormEmits {
24
+ (e: 'field:change', field: string, value: any): void;
25
+ }
23
26
  interface _FormExposed {
24
27
  el: ShallowRef<HTMLElement | null | undefined>;
25
28
  validate: (keys?: string[]) => Promise<boolean>;
@@ -29,5 +32,5 @@ interface _FormExposed {
29
32
  }
30
33
  type FormExposed = DeconstructValue<_FormExposed>;
31
34
  //#endregion
32
- export { FormExposed, FormProps, _FormExposed };
35
+ export { FormEmits, FormExposed, FormProps, _FormExposed };
33
36
  //# sourceMappingURL=form.d.ts.map
@@ -24,7 +24,7 @@ import { DatePanelEmits, DatePanelProps, PanelType } from "./date-panel.js";
24
24
  import { DialogEmits, DialogExposed, DialogProps, DialogTransition, _DialogExposed } from "./dialog.js";
25
25
  import { ActionEmits, ActionExposed, ActionGroupExposed, ActionGroupProps, ActionProps, _ActionExposed, _ActionGroupExposed } from "./action.js";
26
26
  import { TableColumn, TableColumnAlign, TableColumnNode, TableColumnRenderContext, TableColumnSlotsScope, TableEmits, TableExposed, TableProps, TableRow, TableRowSlotsScope, TableSummaryContext, _TableExposed } from "./table.js";
27
- import { BatchEditColumn, BatchEditEmits, BatchEditExposed, BatchEditFeature, BatchEditMode, BatchEditProps, _BatchEditExposed } from "./batch-edit.js";
27
+ import { BatchEditColumn, BatchEditEmits, BatchEditExposed, BatchEditFeature, BatchEditFormStatus, BatchEditProps, BatchEditSlots, BatchEditStates, _BatchEditExposed } from "./batch-edit.js";
28
28
  import { BreadcrumbEmits, BreadcrumbExposed, BreadcrumbItem, BreadcrumbProps, BreadcrumbSlotScope, _BreadcrumbExposed } from "./breadcrumb.js";
29
29
  import { ListEmits, ListExposed, ListProps, _ListExposed } from "./list.js";
30
30
  import { EmptyEmits, EmptyExposed, EmptyProps, _EmptyExposed } from "./empty.js";
@@ -33,7 +33,7 @@ import { FloatButtonEmits, FloatButtonExposed, FloatButtonItem, FloatButtonProps
33
33
  import { CalendarDay, CalendarEmits, CalendarExposed, CalendarMonth, CalendarProps, CalendarYear, _CalendarExposed } from "./calendar.js";
34
34
  import { PaletteColorType, PaletteEmits, PaletteExposed, PaletteHSV, PaletteProps, PaletteRGB, _PaletteExposed } from "./palette.js";
35
35
  import { InputEmits, InputExposed, InputProps, _InputExposed } from "./input.js";
36
- import { FormExposed, FormProps, _FormExposed } from "./form.js";
36
+ import { FormEmits, FormExposed, FormProps, _FormExposed } from "./form.js";
37
37
  import { UploaderEmits, UploaderExposed, UploaderProps, _UploaderExposed } from "./file-picker.js";
38
38
  import { PopEmits, PopExposed, PopProps, _PopExposed } from "./pop.js";
39
39
  import { GridInputEmits, GridInputExposed, GridInputProps, _GridInputExposed } from "./grid-input.js";
@@ -82,7 +82,7 @@ export type * from "@veltra/utils";
82
82
 
83
83
  //#region src/types/index.d.ts
84
84
  declare namespace index_d_exports {
85
- export { ActionEmits, ActionExposed, ActionGroupExposed, ActionGroupProps, ActionProps, AnimationEmits, AnimationExposed, AnimationProps, AutoCompleteEmits, AutoCompleteExposed, AutoCompleteProps, BadgeEmits, BadgeExposed, BadgeProps, BarType, BatchEditColumn, BatchEditEmits, BatchEditExposed, BatchEditFeature, BatchEditMode, BatchEditProps, BreadcrumbEmits, BreadcrumbExposed, BreadcrumbItem, BreadcrumbProps, BreadcrumbSlotScope, BreakCols, Breakpoint, ButtonEmits, ButtonExposed, ButtonProps, ButtonType, CalendarDay, CalendarEmits, CalendarExposed, CalendarMonth, CalendarProps, CalendarYear, CardActionProps, CardContentProps, CardCoverProps, CardEmits, CardExposed, CardProps, CascadeEmits, CascadeExposed, CascadeNode, CascadeProps, CheckTagEmits, CheckTagExposed, CheckTagProps, CheckboxButtonEmits, CheckboxButtonProps, CheckboxEmits, CheckboxExposed, CheckboxGroupEmits, CheckboxGroupExposed, CheckboxGroupProps, CheckboxProps, CodeEditorEmits, CodeEditorExposed, CodeEditorLang, CodeEditorProps, CollapseEmits, CollapseItemProps, CollapseModelValue, CollapseProps, CollapseValue, ConditionConnector, ConditionEditorEmits, ConditionEditorExposed, ConditionEditorProps, ConditionExpression, ConditionField, ConditionGroup, ConditionLeaf, ConditionNode, ConditionValue, ContextmenuEmits, ContextmenuExposed, ContextmenuItem, ContextmenuProps, CssTransitionEmits, CssTransitionExposed, CssTransitionProps, DatePanelEmits, DatePanelProps, DatePickerEmits, DatePickerExposed, DatePickerProps, DateRangePickerEmits, DateRangePickerExposed, DateRangePickerProps, DialogEmits, DialogExposed, DialogProps, DialogTransition, DrawerDirection, DrawerEmits, DrawerExposed, DrawerMode, DrawerProps, DropdownEmits, DropdownExposed, DropdownProps, DualNavEmits, DualNavExposed, DualNavProps, DualNavRootItem, EmptyEmits, EmptyExposed, EmptyProps, ExpressionEditorEmits, ExpressionEditorExposed, ExpressionEditorProps, ExpressionSelectableLevels, FileViewerEmits, FileViewerExposed, FileViewerItem, FileViewerKind, FileViewerProps, FloatButtonEmits, FloatButtonExposed, FloatButtonItem, FloatButtonProps, FormExposed, FormItemEmits, FormItemExposed, FormItemProps, FormProps, GanttChartEmits, GanttChartExposed, GanttChartProps, GridEmits, GridExposed, GridInputEmits, GridInputExposed, GridInputProps, GridItemProps, GridProps, GroupInputEmits, GroupInputExposed, GroupInputProps, IconEmits, IconExposed, IconProps, InputEmits, InputExposed, InputProps, LayoutEmits, LayoutExposed, LayoutProps, ListEmits, ListExposed, ListProps, LoadingEmits, LoadingExposed, LoadingProps, LoadingType, Message, MessageConfirmEmits, MessageConfirmExposed, MessageConfirmProps, MessageEmits, MessageExposed, MessageInstance, MessageOptions, MessageProps, MessageType, MultiAutoCompleteEmits, MultiAutoCompleteExposed, MultiAutoCompleteProps, MultiSelectEmits, MultiSelectExposed, MultiSelectProps, MultiTreeSelectEmits, MultiTreeSelectExposed, MultiTreeSelectProps, NavEmits, NavExposed, NavItem, NavProps, NodeRenderExposed, NodeRenderProps, NotificationEmits, NotificationExposed, NotificationProps, NumberEmits, NumberExposed, NumberInputEmits, NumberInputExposed, NumberInputProps, NumberProps, NumberRangeInputEmits, NumberRangeInputExposed, NumberRangeInputProps, NumberRangeTuple, PaginatorEmits, PaginatorExposed, PaginatorProps, PaletteColorType, PaletteEmits, PaletteExposed, PaletteHSV, PaletteProps, PaletteRGB, PanelItem, PanelType, PasswordInputEmits, PasswordInputExposed, PasswordInputProps, PopConfirmEmits, PopConfirmExposed, PopConfirmProps, PopEmits, PopExposed, PopProps, ProgressEmits, ProgressExposed, ProgressNodesEmits, ProgressNodesExposed, ProgressNodesProps, ProgressProps, QuickBatchEditEmits, QuickBatchEditExposed, QuickBatchEditProps, RadioEmits, RadioExposed, RadioGroupEmits, RadioGroupExposed, RadioGroupProps, RadioProps, RichTextEditorEmits, RichTextEditorExposed, RichTextEditorProps, RichTextFormat, ScrollEmits, ScrollExposed, ScrollPosition, ScrollProps, SelectEmits, SelectExposed, SelectProps, SliderEmits, SliderExposed, SliderProps, StepsEmits, StepsExposed, StepsProps, StepsSlotScope, SwitchEmits, SwitchExposed, SwitchProps, TabItem, TableColumn, TableColumnAlign, TableColumnNode, TableColumnRenderContext, TableColumnSlotsScope, TableEditorEmits, TableEditorExposed, TableEditorProps, TableEmits, TableExposed, TableProps, TableRow, TableRowSlotsScope, TableSummaryContext, TabsEmits, TabsExposed, TabsHorizontalEmits, TabsHorizontalExposed, TabsHorizontalProps, TabsProps, TabsVerticalEmits, TabsVerticalExposed, TabsVerticalProps, TagEmits, TagExposed, TagProps, TextEditorEmits, TextEditorExposed, TextEditorProps, TextEmits, TextExposed, TextProps, TextareaEmits, TextareaExposed, TextareaProps, ThemeExposed, ThemeProps, TipAlign, TipDirection, TipEmits, TipExposed, TipProps, ToolbarItem, TreeEmit, TreeExposed, TreeNode, TreeNodeProps, TreeProps, TreeSelectEmits, TreeSelectExposed, TreeSelectProps, UploaderEmits, UploaderExposed, UploaderProps, VariableItem, WatermarkEmits, WatermarkExposed, WatermarkProps, _ActionExposed, _ActionGroupExposed, _AnimationExposed, _AutoCompleteExposed, _BadgeExposed, _BatchEditExposed, _BreadcrumbExposed, _ButtonExposed, _CalendarExposed, _CardExposed, _CascadeExposed, _CheckTagExposed, _CodeEditorExposed, _ConditionEditorExposed, _ContextmenuExposed, _CssTransitionExposed, _DatePickerExposed, _DateRangePickerExposed, _DialogExposed, _DrawerExposed, _DropdownExposed, _DualNavExposed, _EmptyExposed, _ExpressionEditorExposed, _FileViewerExposed, _FloatButtonExposed, _FormExposed, _GanttChartExposed, _GridExposed, _GridInputExposed, _GroupInputExposed, _InputExposed, _LayoutExposed, _ListExposed, _LoadingExposed, _MessageConfirmExposed, _MessageExposed, _MultiAutoCompleteExposed, _MultiSelectExposed, _MultiTreeSelectExposed, _NavExposed, _NotificationExposed, _PaginatorExposed, _PaletteExposed, _PasswordInputExposed, _PopConfirmExposed, _PopExposed, _ProgressExposed, _ProgressNodesExposed, _QuickBatchEditExposed, _RadioExposed, _RadioGroupExposed, _RichTextEditorExposed, _ScrollExposed, _SelectExposed, _SliderExposed, _StepsExposed, _SwitchExposed, _TableEditorExposed, _TableExposed, _TabsExposed, _TabsHorizontalExposed, _TabsVerticalExposed, _TextEditorExposed, _TextExposed, _TextareaExposed, _ThemeExposed, _TipExposed, _TreeExposed, _TreeSelectExposed, _UploaderExposed, _WatermarkExposed };
85
+ export { ActionEmits, ActionExposed, ActionGroupExposed, ActionGroupProps, ActionProps, AnimationEmits, AnimationExposed, AnimationProps, AutoCompleteEmits, AutoCompleteExposed, AutoCompleteProps, BadgeEmits, BadgeExposed, BadgeProps, BarType, BatchEditColumn, BatchEditEmits, BatchEditExposed, BatchEditFeature, BatchEditFormStatus, BatchEditProps, BatchEditSlots, BatchEditStates, BreadcrumbEmits, BreadcrumbExposed, BreadcrumbItem, BreadcrumbProps, BreadcrumbSlotScope, BreakCols, Breakpoint, ButtonEmits, ButtonExposed, ButtonProps, ButtonType, CalendarDay, CalendarEmits, CalendarExposed, CalendarMonth, CalendarProps, CalendarYear, CardActionProps, CardContentProps, CardCoverProps, CardEmits, CardExposed, CardProps, CascadeEmits, CascadeExposed, CascadeNode, CascadeProps, CheckTagEmits, CheckTagExposed, CheckTagProps, CheckboxButtonEmits, CheckboxButtonProps, CheckboxEmits, CheckboxExposed, CheckboxGroupEmits, CheckboxGroupExposed, CheckboxGroupProps, CheckboxProps, CodeEditorEmits, CodeEditorExposed, CodeEditorLang, CodeEditorProps, CollapseEmits, CollapseItemProps, CollapseModelValue, CollapseProps, CollapseValue, ConditionConnector, ConditionEditorEmits, ConditionEditorExposed, ConditionEditorProps, ConditionExpression, ConditionField, ConditionGroup, ConditionLeaf, ConditionNode, ConditionValue, ContextmenuEmits, ContextmenuExposed, ContextmenuItem, ContextmenuProps, CssTransitionEmits, CssTransitionExposed, CssTransitionProps, DatePanelEmits, DatePanelProps, DatePickerEmits, DatePickerExposed, DatePickerProps, DateRangePickerEmits, DateRangePickerExposed, DateRangePickerProps, DialogEmits, DialogExposed, DialogProps, DialogTransition, DrawerDirection, DrawerEmits, DrawerExposed, DrawerMode, DrawerProps, DropdownEmits, DropdownExposed, DropdownProps, DualNavEmits, DualNavExposed, DualNavProps, DualNavRootItem, EmptyEmits, EmptyExposed, EmptyProps, ExpressionEditorEmits, ExpressionEditorExposed, ExpressionEditorProps, ExpressionSelectableLevels, FileViewerEmits, FileViewerExposed, FileViewerItem, FileViewerKind, FileViewerProps, FloatButtonEmits, FloatButtonExposed, FloatButtonItem, FloatButtonProps, FormEmits, FormExposed, FormItemEmits, FormItemExposed, FormItemProps, FormProps, GanttChartEmits, GanttChartExposed, GanttChartProps, GridEmits, GridExposed, GridInputEmits, GridInputExposed, GridInputProps, GridItemProps, GridProps, GroupInputEmits, GroupInputExposed, GroupInputProps, IconEmits, IconExposed, IconProps, InputEmits, InputExposed, InputProps, LayoutEmits, LayoutExposed, LayoutProps, ListEmits, ListExposed, ListProps, LoadingEmits, LoadingExposed, LoadingProps, LoadingType, Message, MessageConfirmEmits, MessageConfirmExposed, MessageConfirmProps, MessageEmits, MessageExposed, MessageInstance, MessageOptions, MessageProps, MessageType, MultiAutoCompleteEmits, MultiAutoCompleteExposed, MultiAutoCompleteProps, MultiSelectEmits, MultiSelectExposed, MultiSelectProps, MultiTreeSelectEmits, MultiTreeSelectExposed, MultiTreeSelectProps, NavEmits, NavExposed, NavItem, NavProps, NodeRenderExposed, NodeRenderProps, NotificationEmits, NotificationExposed, NotificationProps, NumberEmits, NumberExposed, NumberInputEmits, NumberInputExposed, NumberInputProps, NumberProps, NumberRangeInputEmits, NumberRangeInputExposed, NumberRangeInputProps, NumberRangeTuple, PaginatorEmits, PaginatorExposed, PaginatorProps, PaletteColorType, PaletteEmits, PaletteExposed, PaletteHSV, PaletteProps, PaletteRGB, PanelItem, PanelType, PasswordInputEmits, PasswordInputExposed, PasswordInputProps, PopConfirmEmits, PopConfirmExposed, PopConfirmProps, PopEmits, PopExposed, PopProps, ProgressEmits, ProgressExposed, ProgressNodesEmits, ProgressNodesExposed, ProgressNodesProps, ProgressProps, QuickBatchEditEmits, QuickBatchEditExposed, QuickBatchEditProps, RadioEmits, RadioExposed, RadioGroupEmits, RadioGroupExposed, RadioGroupProps, RadioProps, RichTextEditorEmits, RichTextEditorExposed, RichTextEditorProps, RichTextFormat, ScrollEmits, ScrollExposed, ScrollPosition, ScrollProps, SelectEmits, SelectExposed, SelectProps, SliderEmits, SliderExposed, SliderProps, StepsEmits, StepsExposed, StepsProps, StepsSlotScope, SwitchEmits, SwitchExposed, SwitchProps, TabItem, TableColumn, TableColumnAlign, TableColumnNode, TableColumnRenderContext, TableColumnSlotsScope, TableEditorEmits, TableEditorExposed, TableEditorProps, TableEmits, TableExposed, TableProps, TableRow, TableRowSlotsScope, TableSummaryContext, TabsEmits, TabsExposed, TabsHorizontalEmits, TabsHorizontalExposed, TabsHorizontalProps, TabsProps, TabsVerticalEmits, TabsVerticalExposed, TabsVerticalProps, TagEmits, TagExposed, TagProps, TextEditorEmits, TextEditorExposed, TextEditorProps, TextEmits, TextExposed, TextProps, TextareaEmits, TextareaExposed, TextareaProps, ThemeExposed, ThemeProps, TipAlign, TipDirection, TipEmits, TipExposed, TipProps, ToolbarItem, TreeEmit, TreeExposed, TreeNode, TreeNodeProps, TreeProps, TreeSelectEmits, TreeSelectExposed, TreeSelectProps, UploaderEmits, UploaderExposed, UploaderProps, VariableItem, WatermarkEmits, WatermarkExposed, WatermarkProps, _ActionExposed, _ActionGroupExposed, _AnimationExposed, _AutoCompleteExposed, _BadgeExposed, _BatchEditExposed, _BreadcrumbExposed, _ButtonExposed, _CalendarExposed, _CardExposed, _CascadeExposed, _CheckTagExposed, _CodeEditorExposed, _ConditionEditorExposed, _ContextmenuExposed, _CssTransitionExposed, _DatePickerExposed, _DateRangePickerExposed, _DialogExposed, _DrawerExposed, _DropdownExposed, _DualNavExposed, _EmptyExposed, _ExpressionEditorExposed, _FileViewerExposed, _FloatButtonExposed, _FormExposed, _GanttChartExposed, _GridExposed, _GridInputExposed, _GroupInputExposed, _InputExposed, _LayoutExposed, _ListExposed, _LoadingExposed, _MessageConfirmExposed, _MessageExposed, _MultiAutoCompleteExposed, _MultiSelectExposed, _MultiTreeSelectExposed, _NavExposed, _NotificationExposed, _PaginatorExposed, _PaletteExposed, _PasswordInputExposed, _PopConfirmExposed, _PopExposed, _ProgressExposed, _ProgressNodesExposed, _QuickBatchEditExposed, _RadioExposed, _RadioGroupExposed, _RichTextEditorExposed, _ScrollExposed, _SelectExposed, _SliderExposed, _StepsExposed, _SwitchExposed, _TableEditorExposed, _TableExposed, _TabsExposed, _TabsHorizontalExposed, _TabsVerticalExposed, _TextEditorExposed, _TextExposed, _TextareaExposed, _ThemeExposed, _TipExposed, _TreeExposed, _TreeSelectExposed, _UploaderExposed, _WatermarkExposed };
86
86
  }
87
87
  import * as import__veltra_utils from "@veltra/utils";
88
88
  //#endregion
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@veltra/desktop",
3
- "version": "1.2.7",
3
+ "version": "1.2.9",
4
4
  "files": [
5
5
  "dist",
6
6
  "src"
@@ -68,11 +68,11 @@
68
68
  "@cat-kit/core": ">=1.1.6",
69
69
  "@cat-kit/excel": ">=1.0.0",
70
70
  "@cat-kit/fe": "^1.1.6",
71
- "@veltra/compositions": "1.2.7",
72
- "@veltra/directives": "1.2.7",
73
- "@veltra/icons": "1.2.7",
74
- "@veltra/styles": "1.2.7",
75
- "@veltra/utils": "1.2.7",
71
+ "@veltra/compositions": "1.2.9",
72
+ "@veltra/directives": "1.2.9",
73
+ "@veltra/icons": "1.2.9",
74
+ "@veltra/styles": "1.2.9",
75
+ "@veltra/utils": "1.2.9",
76
76
  "vue": ">=3.5.0"
77
77
  }
78
78
  }
@@ -1,16 +1,13 @@
1
1
  <template>
2
- <aside :class="cls.e('form')" v-if="state.visible && formModel">
2
+ <aside :class="cls.e('form')" v-if="state.formVisible && !!props.model">
3
3
  <header :class="cls.e('form-header')">
4
- <span :class="[cls.e('form-icon'), bem.is(headerInfo.tone)]">
4
+ <span :class="[cls.e('form-icon'), bem.is(state.formActionType)]">
5
5
  <u-icon>
6
6
  <component :is="headerInfo.icon" />
7
7
  </u-icon>
8
8
  </span>
9
9
  <div :class="cls.e('form-title')">
10
10
  <h3 :class="cls.e('form-title-text')">{{ headerInfo.title }}</h3>
11
- <span v-if="headerInfo.chip" :class="cls.e('form-chip')">
12
- {{ headerInfo.chip }}
13
- </span>
14
11
  </div>
15
12
  <u-button
16
13
  :class="cls.e('form-close')"
@@ -27,15 +24,16 @@
27
24
  <transition name="fade" appear mode="out-in">
28
25
  <u-form
29
26
  ref="formComponentRef"
30
- :model="formModel"
27
+ :model="props.model"
31
28
  :readonly="props.readonly"
32
29
  :label-width="props.labelWidth"
30
+ @field:change="handleFieldChange"
33
31
  >
34
32
  <slot
35
33
  v-bind="{
36
34
  row: state.row,
37
35
  depth: state.depth,
38
- indexes: insertIndexes,
36
+ indexes: state.indexPath,
39
37
  index: state.row?.index
40
38
  }"
41
39
  />
@@ -44,27 +42,20 @@
44
42
  </u-scroll>
45
43
 
46
44
  <footer :class="cls.e('form-footer')">
47
- <span :class="cls.e('form-hint')" v-if="props.readonly">只读模式</span>
48
- <span :class="cls.e('form-hint')" v-else-if="isQuickUpdate">
49
- 实时编辑
50
- <span :class="{ [bem.is('concealed')]: !focused }"> · <u-kbd>Esc</u-kbd> 关闭</span>
51
- </span>
52
- <span :class="cls.e('form-hint')" v-else>
45
+ <span :class="cls.e('form-hint')">
46
+ <template v-if="props.readonly"> 只读模式 </template>
47
+
53
48
  <span :class="{ [bem.is('concealed')]: !focused }">
54
- <u-kbd>Ctrl + S</u-kbd> 保存 · <u-kbd>Esc</u-kbd> 关闭
49
+ <template v-if="!(state.formActionType === 'update' && props.quickEdit)">
50
+ <u-kbd>Ctrl + S</u-kbd> 保存 ·
51
+ </template>
52
+ <u-kbd>Esc</u-kbd> 关闭
55
53
  </span>
56
54
  </span>
57
55
 
58
56
  <div :class="cls.e('form-actions')">
59
57
  <u-button text :loading="state.loading" @click="handleClose"> 取消 </u-button>
60
- <u-button
61
- v-if="
62
- !props.readonly && ((isNormal && (creatable || updatable)) || (isQuick && creatable))
63
- "
64
- :type="state.type === 'create' ? 'success' : 'primary'"
65
- :loading="state.loading"
66
- @click="handleSave"
67
- >
58
+ <u-button v-if="showSaveBtn" type="primary" :loading="state.loading" @click="handleSave">
68
59
  保存
69
60
  </u-button>
70
61
  </div>
@@ -73,10 +64,12 @@
73
64
  </template>
74
65
 
75
66
  <script lang="ts" setup>
76
- import { AddChild, Close, EditPen, Plus, View } from '@veltra/icons/normal'
67
+ import { o } from '@cat-kit/core'
68
+ import { Close } from '@veltra/icons/normal'
77
69
  import { bem } from '@veltra/utils'
78
- import { computed, inject, shallowRef, toRef, type Component } from 'vue'
70
+ import { computed, inject, shallowRef, toRef } from 'vue'
79
71
 
72
+ import type { BatchEditSlots } from '../../types'
80
73
  import type { _FormExposed, FormExposed } from '../../types/form'
81
74
  import { UButton } from '../button'
82
75
  import { UForm } from '../form'
@@ -84,21 +77,13 @@ import { UIcon } from '../icon'
84
77
  import { UKbd } from '../kbd'
85
78
  import { UScroll } from '../scroll'
86
79
  import { BatchEditDIKey } from './di'
80
+ import { FORM_ACTION_HEADER_MAP } from './form-action-header'
87
81
 
88
82
  defineOptions({ name: 'BatchEditForm' })
89
83
 
90
84
  const batchEditCtx = inject(BatchEditDIKey)!
91
85
 
92
- const {
93
- cls,
94
- props,
95
- state,
96
- insertIndexes,
97
- handleSave,
98
- handleClose,
99
- staticFeatures,
100
- dynamicFeatures
101
- } = batchEditCtx
86
+ const { cls, props, state, handleClose, handleSave, staticFeatures, dynamicFeatures } = batchEditCtx
102
87
 
103
88
  const focused = toRef(batchEditCtx, 'focused')
104
89
 
@@ -111,68 +96,37 @@ defineExpose<_FormExposed>({
111
96
  reset: () => formComponentRef.value?.reset()
112
97
  })
113
98
 
99
+ function handleFieldChange(field: string, value: any) {
100
+ if (state.row && props.quickEdit) {
101
+ o(state.row.data).set(field, value)
102
+ }
103
+ }
104
+
114
105
  const creatable = computed(() => {
115
- return (
116
- state.type === 'create' &&
117
- (staticFeatures.value.has('create') || dynamicFeatures.value.create?.(state.row))
118
- )
106
+ if (state.formActionType !== 'create') return false
107
+ return staticFeatures.value.has('create') || dynamicFeatures.value.create?.(state.row)
119
108
  })
120
109
 
121
- const updatable = computed(() => {
122
- return (
123
- state.type === 'update' &&
124
- (staticFeatures.value.has('update') || dynamicFeatures.value.update?.(state.row))
125
- )
110
+ const creatableChild = computed(() => {
111
+ if (state.formActionType !== 'createChild') return false
112
+ return staticFeatures.value.has('createChild') || dynamicFeatures.value.createChild?.(state.row)
126
113
  })
127
114
 
128
- const isQuick = computed(() => props.mode === 'quick')
129
- const isNormal = computed(() => props.mode !== 'quick')
130
- const isQuickUpdate = computed(() => isQuick.value && state.type === 'update')
131
-
132
- const formModel = computed(() => {
133
- if (isQuick.value && state.type === 'update' && state.row) {
134
- return state.row.data
135
- }
136
- return props.model
115
+ const updatable = computed(() => {
116
+ if (state.formActionType !== 'update') return false
117
+ return staticFeatures.value.has('update') || dynamicFeatures.value.update?.(state.row)
137
118
  })
138
119
 
139
- interface HeaderInfo {
140
- icon: Component
141
- title: string
142
- chip?: string
143
- tone: 'create' | 'update' | 'view' | 'child'
144
- }
145
-
146
- const headerInfo = computed<HeaderInfo>(() => {
147
- if (props.readonly) {
148
- return {
149
- icon: View,
150
- title: '查看详情',
151
- chip: state.row ? `第 ${state.row.index + 1} 行` : undefined,
152
- tone: 'view'
153
- }
154
- }
155
- if (state.parentRow) {
156
- return {
157
- icon: AddChild,
158
- title: '新增子级',
159
- chip: `归属于第 ${state.parentRow.index + 1} 行`,
160
- tone: 'child'
161
- }
162
- }
163
- if (state.type === 'create') {
164
- return { icon: Plus, title: '新增', tone: 'create' }
165
- }
166
- return {
167
- icon: EditPen,
168
- title: '编辑',
169
- chip: state.row ? `第 ${state.row.index + 1} 行` : undefined,
170
- tone: 'update'
171
- }
120
+ const showSaveBtn = computed(() => {
121
+ if (props.readonly) return false
122
+ if (props.quickEdit && state.formActionType === 'update') return false
123
+ return creatable.value || updatable.value || creatableChild.value
172
124
  })
173
125
 
126
+ const headerInfo = computed(() => FORM_ACTION_HEADER_MAP[state.formActionType])
127
+
174
128
  /** 通过 row 切换 / 类型切换驱动表单内容淡出淡入 */
175
129
  const bodyKey = computed(() => {
176
- return `${state.type}-${state.row?.uid ?? 'create'}-${state.parentRow?.uid ?? 'root'}`
130
+ return `${state.formActionType}-${state.row?.uid ?? 'create'}-${state.parentRow?.uid ?? 'root'}`
177
131
  })
178
132
  </script>
@@ -2,14 +2,13 @@
2
2
  <u-table
3
3
  v-bind="tableProps"
4
4
  :slots="slots"
5
- :class="[cls.e('table'), bem.is('editing', state.visible)]"
5
+ :class="[cls.e('table')]"
6
6
  :columns="columns"
7
7
  highlight-current
8
8
  :current="state.row"
9
9
  @update:current="handleUpdateCurrentRow"
10
10
  @update:checked="emit('update:checked', $event)"
11
11
  @update:selected="emit('update:selected', $event)"
12
- ref="tableRef"
13
12
  >
14
13
  <template #column:__action__="{ row }">
15
14
  <u-action-group :class="cls.e('row-actions')" :max="5" @click.stop circle>
@@ -31,13 +30,6 @@
31
30
  title="添加子级"
32
31
  @run="handleInsertChild(row)"
33
32
  />
34
- <u-action
35
- v-if="allowed('copy', row)"
36
- :icon="Copy"
37
- title="复制此行"
38
- @run="handleCopy(row)"
39
- />
40
-
41
33
  <u-action
42
34
  v-if="canDelete(row)"
43
35
  :icon="Delete"
@@ -49,16 +41,8 @@
49
41
  </u-action-group>
50
42
  </template>
51
43
 
52
- <template #empty v-if="!props.readonly"> {{ null }} </template>
53
-
54
- <template
55
- #append
56
- v-if="
57
- !props.readonly &&
58
- (staticFeatures.has('create') || dynamicFeatures.create?.()) &&
59
- ((state.type === 'create' && !state.visible) || state.type === 'update')
60
- "
61
- >
44
+ <!-- 新增按钮 -->
45
+ <template #append v-if="showCreateBtn">
62
46
  <div :class="cls.e('add')">
63
47
  <u-button
64
48
  :class="cls.e('add-btn')"
@@ -77,8 +61,7 @@
77
61
 
78
62
  <script setup lang="ts">
79
63
  import { o } from '@cat-kit/core'
80
- import { AddChild, Copy, Delete, InsertToNext, InsertToPrev, Plus } from '@veltra/icons/normal'
81
- import { bem } from '@veltra/utils'
64
+ import { AddChild, Delete, InsertToNext, InsertToPrev, Plus } from '@veltra/icons/normal'
82
65
  import { computed, inject, type Slots } from 'vue'
83
66
 
84
67
  import type { BatchEditFeature, TableRow } from '../../types'
@@ -94,13 +77,11 @@ defineProps<{ slots: Slots }>()
94
77
  const {
95
78
  cls,
96
79
  state,
97
- tableRef,
98
80
  props,
99
81
  emit,
100
82
  staticFeatures,
101
83
  dynamicFeatures,
102
84
  handleCreate,
103
- handleCopy,
104
85
  handleDelete,
105
86
  handleInsertToNext,
106
87
  handleInsertToPrev,
@@ -128,8 +109,7 @@ const allowed = (feature: BatchEditFeature, row?: TableRow) => {
128
109
  }
129
110
 
130
111
  const columns = computed(() => {
131
- if (props.readonly || hasNot(['create', 'delete', 'createChild', 'update', 'copy']))
132
- return props.columns
112
+ if (props.readonly || hasNot(['create', 'delete', 'createChild', 'update'])) return props.columns
133
113
 
134
114
  return (props.columns ?? []).concat({
135
115
  name: '操作',
@@ -143,15 +123,19 @@ const columns = computed(() => {
143
123
 
144
124
  function handleUpdateCurrentRow(row?: TableRow) {
145
125
  if (allowed('update', row)) {
146
- if (row) {
147
- state.type = 'update'
148
- }
149
126
  state.row = row
150
- state.depth = row?.depth
151
127
  }
152
128
  }
153
129
 
154
130
  function canDelete(row: TableRow) {
155
131
  return !props.readonly && allowed('delete', row)
156
132
  }
133
+
134
+ const showCreateBtn = computed(() => {
135
+ if (props.readonly) return false
136
+
137
+ const hasFeature = staticFeatures.value.has('create') || dynamicFeatures.value.create?.()
138
+ const createActionVisible = state.formActionType === 'create' && state.formVisible
139
+ return hasFeature && !createActionVisible
140
+ })
157
141
  </script>
@@ -2,7 +2,7 @@
2
2
  <u-layout
3
3
  :class="cls.b"
4
4
  :cols="cols"
5
- rows="minmax(0, 1fr)"
5
+ rows="minmax(0, 1fr) "
6
6
  gap="8px"
7
7
  resizable
8
8
  tabindex="-1"
@@ -11,10 +11,10 @@
11
11
  @keydown.capture="handleKeydown"
12
12
  >
13
13
  <!-- 编辑列表 -->
14
- <BatchEditList :slots="slots" ref="tableRef" />
14
+ <BatchEditList :slots="slots" />
15
15
 
16
16
  <!-- 编辑表单 -->
17
- <BatchEditForm ref="formRef" v-slot="scoped">
17
+ <BatchEditForm ref="form" v-slot="scoped">
18
18
  <slot name="form" v-bind="scoped" />
19
19
  </BatchEditForm>
20
20
  </u-layout>
@@ -22,121 +22,56 @@
22
22
 
23
23
  <script lang="ts" setup>
24
24
  import { bem } from '@veltra/utils'
25
- import { computed, inject, provide, shallowRef, watch } from 'vue'
25
+ import { computed, provide, useTemplateRef } from 'vue'
26
26
 
27
- import type {
28
- BatchEditEmits,
29
- BatchEditProps,
30
- TableColumnSlotsScope,
31
- TableExposed,
32
- TableRow
33
- } from '../../types'
34
- import type { FormExposed } from '../../types/form'
35
- import { DialogDIKey } from '../dialog/di'
27
+ import type { BatchEditEmits, BatchEditProps, BatchEditSlots, FormExposed } from '../../types'
36
28
  import { ULayout } from '../layout'
37
29
  import BatchEditForm from './batch-edit-form.vue'
38
30
  import BatchEditList from './batch-edit-list.vue'
39
31
  import { BatchEditDIKey } from './di'
40
- import { useEdit } from './use-edit'
32
+ import { useEditState } from './use-edit-state'
41
33
  import { useFeatures } from './use-features'
34
+ import { useHandlers } from './use-handlers'
35
+ import { useShortcutKey } from './use-shortcut-key'
42
36
 
43
37
  defineOptions({ name: 'BatchEdit' })
44
38
 
45
- const props = withDefaults(defineProps<BatchEditProps>(), {
46
- cols: () => ['1fr', '420px'],
47
- mode: 'normal'
48
- })
39
+ const props = withDefaults(defineProps<BatchEditProps>(), { cols: () => ['1fr', '420px'] })
49
40
 
50
41
  const emit = defineEmits<BatchEditEmits>()
51
42
 
52
- const slots = defineSlots<
53
- {
54
- form?: (props: {
55
- /** 当前编辑的层级 */
56
- depth?: number
57
- /** 当前编辑的行 */
58
- row?: TableRow
59
- /** 当前编辑的行索引 */
60
- index?: number
61
- /** 操作的目标行索引路径 */
62
- indexes?: number[]
63
- }) => any
64
-
65
- header?: () => any
66
- } & Partial<{ [key: `column:${string}`]: (props: TableColumnSlotsScope) => any }>
67
- >()
43
+ const slots = defineSlots<BatchEditSlots>()
68
44
 
69
45
  const cls = bem('batch-edit')
70
46
 
71
- const tableRef = shallowRef<TableExposed>()
72
- const formRef = shallowRef<FormExposed>()
73
- const focused = shallowRef(false)
47
+ const formRef = useTemplateRef<FormExposed>('form')
48
+
49
+ const { state, resetState } = useEditState({ props })
74
50
 
75
51
  const { staticFeatures, dynamicFeatures } = useFeatures({ props })
76
52
 
77
- const editCtx = useEdit({ props, emit, formRef })
53
+ const handlers = useHandlers({ props, emit, state, resetState, formRef })
54
+
55
+ // 快捷键处理
56
+ const { handleFocusIn, handleFocusOut, handleKeydown, focused } = useShortcutKey({
57
+ props,
58
+ onSave: handlers.handleSave,
59
+ onClose: handlers.handleClose,
60
+ state
61
+ })
78
62
 
79
- const { state, handleClose, handleSave } = editCtx
63
+ const cols = computed(() => {
64
+ return state.formVisible ? props.cols : undefined
65
+ })
80
66
 
81
67
  provide(BatchEditDIKey, {
82
68
  cls,
83
69
  props,
84
70
  emit,
85
- tableRef,
71
+ state,
86
72
  staticFeatures,
87
73
  dynamicFeatures,
88
74
  focused,
89
- ...editCtx
90
- })
91
-
92
- const dialogCtx = inject(DialogDIKey, undefined)
93
-
94
- dialogCtx &&
95
- watch(dialogCtx.visible, (visible) => {
96
- !visible && editCtx.handleClose()
97
- })
98
-
99
- const cols = computed(() => {
100
- return !!state.row || state.visible ? props.cols : undefined
75
+ ...handlers
101
76
  })
102
-
103
- function handleFocusIn() {
104
- focused.value = true
105
- }
106
-
107
- function handleFocusOut(e: FocusEvent) {
108
- const root = e.currentTarget as HTMLElement
109
- if (!root.contains(e.relatedTarget as Node | null)) {
110
- focused.value = false
111
- }
112
- }
113
-
114
- /**
115
- * 键盘快捷键(仅组件获焦时生效):
116
- * - Esc 关闭表单
117
- * - ⌘/Ctrl + S 保存(快速编辑模式下编辑行时除外)
118
- */
119
- function handleKeydown(e: KeyboardEvent) {
120
- if (!focused.value) return
121
- if (props.readonly && e.key !== 'Escape') return
122
-
123
- if (e.key === 'Escape') {
124
- if (state.visible) {
125
- e.preventDefault()
126
- handleClose()
127
- }
128
- return
129
- }
130
-
131
- const meta = e.metaKey || e.ctrlKey
132
- if (!meta) return
133
-
134
- const key = e.key.toLowerCase()
135
-
136
- if (key === 's' && state.visible) {
137
- if (props.mode === 'quick' && state.type === 'update') return
138
- e.preventDefault()
139
- handleSave()
140
- }
141
- }
142
77
  </script>