@dou-ui/form-builder 0.0.0-stage → 0.1.0-alpha.0

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 (182) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +10 -2
  3. package/dist/builder/canvas.js +695 -0
  4. package/dist/builder/canvas.js.map +1 -0
  5. package/dist/builder/completion.js +49 -0
  6. package/dist/builder/completion.js.map +1 -0
  7. package/dist/builder/condition-editor.js +6 -0
  8. package/dist/builder/condition-editor.js.map +1 -0
  9. package/dist/builder/condition-editor.vue_vue_type_script_setup_true_lang.js +410 -0
  10. package/dist/builder/condition-editor.vue_vue_type_script_setup_true_lang.js.map +1 -0
  11. package/dist/builder/condition.js +159 -0
  12. package/dist/builder/condition.js.map +1 -0
  13. package/dist/builder/context.js +477 -0
  14. package/dist/builder/context.js.map +1 -0
  15. package/dist/builder/core/commands.js +373 -0
  16. package/dist/builder/core/commands.js.map +1 -0
  17. package/dist/builder/core/history.js +76 -0
  18. package/dist/builder/core/history.js.map +1 -0
  19. package/dist/builder/core/transaction.js +298 -0
  20. package/dist/builder/core/transaction.js.map +1 -0
  21. package/dist/builder/drag.js +466 -0
  22. package/dist/builder/drag.js.map +1 -0
  23. package/dist/builder/expression-box.js +19 -0
  24. package/dist/builder/expression-box.js.map +1 -0
  25. package/dist/builder/expression-input.js +6 -0
  26. package/dist/builder/expression-input.js.map +1 -0
  27. package/dist/builder/expression-input.vue_vue_type_script_setup_true_lang.js +117 -0
  28. package/dist/builder/expression-input.vue_vue_type_script_setup_true_lang.js.map +1 -0
  29. package/dist/builder/extension.js +47 -0
  30. package/dist/builder/extension.js.map +1 -0
  31. package/dist/builder/form-builder.js +6 -0
  32. package/dist/builder/form-builder.js.map +1 -0
  33. package/dist/builder/form-builder.vue_vue_type_script_setup_true_lang.js +450 -0
  34. package/dist/builder/form-builder.vue_vue_type_script_setup_true_lang.js.map +1 -0
  35. package/dist/builder/index.js +22 -0
  36. package/dist/builder/index.js.map +1 -0
  37. package/dist/builder/inspector.js +6 -0
  38. package/dist/builder/inspector.js.map +1 -0
  39. package/dist/builder/inspector.vue_vue_type_script_setup_true_lang.js +442 -0
  40. package/dist/builder/inspector.vue_vue_type_script_setup_true_lang.js.map +1 -0
  41. package/dist/builder/json-dialog.js +6 -0
  42. package/dist/builder/json-dialog.js.map +1 -0
  43. package/dist/builder/json-dialog.vue_vue_type_script_setup_true_lang.js +281 -0
  44. package/dist/builder/json-dialog.vue_vue_type_script_setup_true_lang.js.map +1 -0
  45. package/dist/builder/locale.js +1271 -0
  46. package/dist/builder/locale.js.map +1 -0
  47. package/dist/builder/logic-fields.js +18 -0
  48. package/dist/builder/logic-fields.js.map +1 -0
  49. package/dist/builder/logic.js +332 -0
  50. package/dist/builder/logic.js.map +1 -0
  51. package/dist/builder/menu.js +92 -0
  52. package/dist/builder/menu.js.map +1 -0
  53. package/dist/builder/outline-row.js +6 -0
  54. package/dist/builder/outline-row.js.map +1 -0
  55. package/dist/builder/outline-row.vue_vue_type_script_setup_true_lang.js +88 -0
  56. package/dist/builder/outline-row.vue_vue_type_script_setup_true_lang.js.map +1 -0
  57. package/dist/builder/outline.js +6 -0
  58. package/dist/builder/outline.js.map +1 -0
  59. package/dist/builder/outline.vue_vue_type_script_setup_true_lang.js +111 -0
  60. package/dist/builder/outline.vue_vue_type_script_setup_true_lang.js.map +1 -0
  61. package/dist/builder/palette.js +6 -0
  62. package/dist/builder/palette.js.map +1 -0
  63. package/dist/builder/palette.vue_vue_type_script_setup_true_lang.js +96 -0
  64. package/dist/builder/palette.vue_vue_type_script_setup_true_lang.js.map +1 -0
  65. package/dist/builder/preview.js +6 -0
  66. package/dist/builder/preview.js.map +1 -0
  67. package/dist/builder/preview.vue_vue_type_script_setup_true_lang.js +111 -0
  68. package/dist/builder/preview.vue_vue_type_script_setup_true_lang.js.map +1 -0
  69. package/dist/builder/settings-binding.js +57 -0
  70. package/dist/builder/settings-binding.js.map +1 -0
  71. package/dist/builder/settings.js +487 -0
  72. package/dist/builder/settings.js.map +1 -0
  73. package/dist/builder/span-field.js +104 -0
  74. package/dist/builder/span-field.js.map +1 -0
  75. package/dist/code/expression-input.js +6 -0
  76. package/dist/code/expression-input.js.map +1 -0
  77. package/dist/code/expression-input.vue_vue_type_script_setup_true_lang.js +88 -0
  78. package/dist/code/expression-input.vue_vue_type_script_setup_true_lang.js.map +1 -0
  79. package/dist/code/extension.js +202 -0
  80. package/dist/code/extension.js.map +1 -0
  81. package/dist/code/index.js +19 -0
  82. package/dist/code/index.js.map +1 -0
  83. package/dist/code/language.js +43 -0
  84. package/dist/code/language.js.map +1 -0
  85. package/dist/collaboration/index.js +382 -0
  86. package/dist/collaboration/index.js.map +1 -0
  87. package/dist/collaboration/order.js +88 -0
  88. package/dist/collaboration/order.js.map +1 -0
  89. package/dist/core/check.js +314 -0
  90. package/dist/core/check.js.map +1 -0
  91. package/dist/core/document.js +112 -0
  92. package/dist/core/document.js.map +1 -0
  93. package/dist/core/expression.js +854 -0
  94. package/dist/core/expression.js.map +1 -0
  95. package/dist/core/formulas.js +242 -0
  96. package/dist/core/formulas.js.map +1 -0
  97. package/dist/core/rules.js +83 -0
  98. package/dist/core/rules.js.map +1 -0
  99. package/dist/core/values.js +80 -0
  100. package/dist/core/values.js.map +1 -0
  101. package/dist/fields/builtin.js +167 -0
  102. package/dist/fields/builtin.js.map +1 -0
  103. package/dist/fields/components.js +155 -0
  104. package/dist/fields/components.js.map +1 -0
  105. package/dist/fields/define.js +44 -0
  106. package/dist/fields/define.js.map +1 -0
  107. package/dist/fields/format.js +125 -0
  108. package/dist/fields/format.js.map +1 -0
  109. package/dist/fields/options.js +54 -0
  110. package/dist/fields/options.js.map +1 -0
  111. package/dist/index.js +20 -0
  112. package/dist/locale.js +161 -0
  113. package/dist/locale.js.map +1 -0
  114. package/dist/renderer/containers.js +430 -0
  115. package/dist/renderer/containers.js.map +1 -0
  116. package/dist/renderer/context.js +21 -0
  117. package/dist/renderer/context.js.map +1 -0
  118. package/dist/renderer/form-renderer.js +6 -0
  119. package/dist/renderer/form-renderer.js.map +1 -0
  120. package/dist/renderer/form-renderer.vue_vue_type_script_setup_true_lang.js +272 -0
  121. package/dist/renderer/form-renderer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  122. package/dist/renderer/index.js +19 -0
  123. package/dist/renderer/index.js.map +1 -0
  124. package/dist/renderer/node-view.js +385 -0
  125. package/dist/renderer/node-view.js.map +1 -0
  126. package/dist/style.css +1 -0
  127. package/dist/style.d.ts +1 -0
  128. package/dist/style.js +27 -0
  129. package/dist/types/builder/canvas.d.ts +5 -0
  130. package/dist/types/builder/completion.d.ts +35 -0
  131. package/dist/types/builder/condition-editor.vue.d.ts +17 -0
  132. package/dist/types/builder/condition.d.ts +37 -0
  133. package/dist/types/builder/context.d.ts +149 -0
  134. package/dist/types/builder/core/commands.d.ts +74 -0
  135. package/dist/types/builder/core/history.d.ts +23 -0
  136. package/dist/types/builder/core/transaction.d.ts +108 -0
  137. package/dist/types/builder/drag.d.ts +52 -0
  138. package/dist/types/builder/expression-box.d.ts +8 -0
  139. package/dist/types/builder/expression-input.vue.d.ts +29 -0
  140. package/dist/types/builder/extension.d.ts +149 -0
  141. package/dist/types/builder/form-builder.vue.d.ts +24 -0
  142. package/dist/types/builder/index.d.ts +76 -0
  143. package/dist/types/builder/inspector.vue.d.ts +3 -0
  144. package/dist/types/builder/json-dialog.vue.d.ts +10 -0
  145. package/dist/types/builder/locale.d.ts +195 -0
  146. package/dist/types/builder/logic-fields.d.ts +2 -0
  147. package/dist/types/builder/logic.d.ts +57 -0
  148. package/dist/types/builder/menu.d.ts +23 -0
  149. package/dist/types/builder/outline-row.vue.d.ts +19 -0
  150. package/dist/types/builder/outline.vue.d.ts +3 -0
  151. package/dist/types/builder/palette.vue.d.ts +3 -0
  152. package/dist/types/builder/preview.vue.d.ts +3 -0
  153. package/dist/types/builder/settings-binding.d.ts +23 -0
  154. package/dist/types/builder/settings.d.ts +49 -0
  155. package/dist/types/builder/span-field.d.ts +4 -0
  156. package/dist/types/builder/types.d.ts +59 -0
  157. package/dist/types/code/expression-input.vue.d.ts +23 -0
  158. package/dist/types/code/extension.d.ts +45 -0
  159. package/dist/types/code/index.d.ts +12 -0
  160. package/dist/types/code/language.d.ts +6 -0
  161. package/dist/types/collaboration/index.d.ts +64 -0
  162. package/dist/types/collaboration/order.d.ts +20 -0
  163. package/dist/types/core/check.d.ts +68 -0
  164. package/dist/types/core/document.d.ts +36 -0
  165. package/dist/types/core/expression.d.ts +175 -0
  166. package/dist/types/core/formulas.d.ts +44 -0
  167. package/dist/types/core/rules.d.ts +23 -0
  168. package/dist/types/core/types.d.ts +211 -0
  169. package/dist/types/core/values.d.ts +22 -0
  170. package/dist/types/fields/builtin.d.ts +9 -0
  171. package/dist/types/fields/components.d.ts +177 -0
  172. package/dist/types/fields/define.d.ts +93 -0
  173. package/dist/types/fields/format.d.ts +76 -0
  174. package/dist/types/fields/options.d.ts +11 -0
  175. package/dist/types/index.d.ts +3 -0
  176. package/dist/types/locale.d.ts +45 -0
  177. package/dist/types/renderer/containers.d.ts +20 -0
  178. package/dist/types/renderer/context.d.ts +186 -0
  179. package/dist/types/renderer/form-renderer.vue.d.ts +25 -0
  180. package/dist/types/renderer/index.d.ts +81 -0
  181. package/dist/types/renderer/node-view.d.ts +56 -0
  182. package/package.json +88 -4
@@ -0,0 +1,17 @@
1
+ import type { LogicTarget } from './logic';
2
+ type __VLS_Props = {
3
+ modelValue?: string | null;
4
+ /** The fields the rows can read. */
5
+ targets?: LogicTarget[];
6
+ disabled?: boolean;
7
+ };
8
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
9
+ "update:modelValue": (value: string) => any;
10
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
11
+ "onUpdate:modelValue"?: ((value: string) => any) | undefined;
12
+ }>, {
13
+ modelValue: string | null;
14
+ targets: LogicTarget[];
15
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
16
+ declare const _default: typeof __VLS_export;
17
+ export default _default;
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Conditions as the condition editor shows them: rows of "field, how,
3
+ * value", all of which must hold (`and`) or one of which (`or`). They are
4
+ * written to the node as expression text, and read back from it when the
5
+ * text has that shape; other expressions are edited as text.
6
+ */
7
+ export type ConditionOperator = 'eq' | 'ne' | 'gt' | 'ge' | 'lt' | 'le' | 'in' | 'contains' | 'empty' | 'filled';
8
+ export type ConditionLiteral = string | number | boolean | null;
9
+ export interface ConditionRow {
10
+ /** What the row reads: the form's values, or the list item around the node. */
11
+ scope: 'values' | 'item';
12
+ /** The path read, e.g. `contact.phone`; empty while no field is picked. */
13
+ path: string;
14
+ op: ConditionOperator;
15
+ /** A literal, or a list of them for `in`. Unused by `empty` and `filled`. */
16
+ value?: ConditionLiteral | ConditionLiteral[];
17
+ }
18
+ export interface Condition {
19
+ join: 'and' | 'or';
20
+ rows: ConditionRow[];
21
+ }
22
+ /** Operators that need no value. */
23
+ export declare const unaryOperators: ReadonlySet<ConditionOperator>;
24
+ /** A literal as expression text. */
25
+ export declare function literalSource(value: ConditionLiteral): string;
26
+ /** `values.contact.phone`, with brackets for keys that are not plain names. */
27
+ export declare function referenceSource(scope: 'values' | 'item', path: string): string;
28
+ /** Whether a row says enough to be written. */
29
+ export declare function rowComplete(entry: ConditionRow): boolean;
30
+ /** The condition as expression text, leaving out rows that are not filled in; `''` for none. */
31
+ export declare function printCondition(condition: Condition): string;
32
+ /**
33
+ * The condition an expression says, when it is rows joined by one of
34
+ * `&&` and `||`; `undefined` for any other expression, or one that does
35
+ * not parse. Empty text is a condition without rows.
36
+ */
37
+ export declare function parseCondition(source: string | undefined): Condition | undefined;
@@ -0,0 +1,149 @@
1
+ import type { ComputedRef, InjectionKey, Ref } from 'vue';
2
+ import type { FormContainerNode, FormDocument, FormNode, FormPageNode, FormValidator } from '../core/types';
3
+ import type { FormFunction } from '../core/expression';
4
+ import type { FormFieldType } from '../fields/define';
5
+ import type { FormOptionsLoader } from '../renderer/context';
6
+ import type { ResolvedFormBuilderExtensions } from './extension';
7
+ import type { FormBuilderMessages } from './locale';
8
+ import { FormBuilderTransaction } from './core/transaction';
9
+ import type { FormBuilderInsertPlace } from './core/commands';
10
+ import type { DragController } from './drag';
11
+ /** What the builder shows: the canvas to edit on, or the form to fill in as people will. */
12
+ export type FormBuilderMode = 'design' | 'preview';
13
+ /** How a click changes the selection: replace it, add or take away the node, or extend it. */
14
+ export type FormBuilderSelectMode = 'replace' | 'toggle' | 'extend';
15
+ export interface FormBuilderDispatchOptions {
16
+ /** The selection after the change. Defaults to the current one, without nodes that are gone. */
17
+ selection?: readonly string[];
18
+ /** Read out to screen readers once the change is made. */
19
+ announce?: string;
20
+ }
21
+ /**
22
+ * What the builder and its parts share, from `useFormBuilder()` inside a
23
+ * builder, e.g. in a panel of your own or a field type's component.
24
+ */
25
+ export interface FormBuilderContext {
26
+ /** The document as it is now. */
27
+ readonly document: FormDocument;
28
+ /** The ids of the selected nodes, the last one selected last. */
29
+ readonly selection: readonly string[];
30
+ /** Every field type, built-in and given. */
31
+ readonly fields: ReadonlyMap<string, FormFieldType>;
32
+ readonly messages: FormBuilderMessages;
33
+ readonly canUndo: boolean;
34
+ readonly canRedo: boolean;
35
+ /**
36
+ * Whether the builder only shows the form: nodes can be selected and
37
+ * their settings read, but the commands below change nothing. A
38
+ * transaction handed to `dispatch` still applies.
39
+ */
40
+ readonly readonly: boolean;
41
+ readonly mode: FormBuilderMode;
42
+ /** Show the canvas or the preview. */
43
+ setMode: (mode: FormBuilderMode) => void;
44
+ /** A transaction on the document as it is now, to `dispatch`. */
45
+ transaction: () => FormBuilderTransaction;
46
+ /** Make the changes of a transaction, as one undo step (or part of one, by `meta.group`). */
47
+ dispatch: (tr: FormBuilderTransaction, options?: FormBuilderDispatchOptions) => void;
48
+ /** Select nodes; `null` or `[]` selects the form itself. */
49
+ select: (ids: string | readonly string[] | null, mode?: FormBuilderSelectMode) => void;
50
+ /**
51
+ * Add a new node of a type (a field type or `section`, `tabs`, `steps`,
52
+ * `list`) and select it. It goes into the selected container, else
53
+ * after the selected node, else at the end, unless `place` says where.
54
+ * Returns its id.
55
+ */
56
+ add: (type: string, place?: FormBuilderInsertPlace) => string | undefined;
57
+ /** Delete nodes, the selected ones by default. */
58
+ remove: (ids?: readonly string[]) => void;
59
+ /** Put a copy of each node after it, the selected ones by default, and select the copies. */
60
+ duplicate: (ids?: readonly string[]) => void;
61
+ /** Move nodes, the selected ones by default, one place up (`-1`) or down (`1`). */
62
+ moveBy: (delta: -1 | 1, ids?: readonly string[]) => void;
63
+ /**
64
+ * Move nodes, the selected ones by default, into a container (`null`:
65
+ * the top) to start at `index` of its children as they are now.
66
+ */
67
+ moveTo: (place: FormBuilderInsertPlace, ids?: readonly string[]) => void;
68
+ /** Replace the whole form with another, e.g. one imported as JSON, as one undo step. */
69
+ replace: (document: FormDocument) => void;
70
+ /** Put nodes of one container into a new section, the selected ones by default. */
71
+ wrap: (ids?: readonly string[]) => void;
72
+ /** Add a page to tabs or steps (the selected ones, or the ones around the selection). */
73
+ addPage: (id?: string) => void;
74
+ /** Select the container around the last selected node, or the form. */
75
+ selectParent: () => void;
76
+ undo: () => void;
77
+ redo: () => void;
78
+ /** The page of tabs or steps the canvas shows. */
79
+ shownPage: (container: FormContainerNode) => FormPageNode | undefined;
80
+ }
81
+ /** What the builder's own parts read besides the public context. */
82
+ export interface BuilderState extends FormBuilderContext {
83
+ /** The id of a node's element on the canvas or in the outline. */
84
+ domId: (id: string, view: 'canvas' | 'outline') => string;
85
+ announce: (text: string) => void;
86
+ live: Ref<string>;
87
+ /** Keys pressed on the canvas or the outline; `order` is the nodes as they are listed there. */
88
+ keydown: (event: KeyboardEvent, view: BuilderView) => void;
89
+ /** Ask the inspector to focus its first setting. */
90
+ focusInspector: () => void;
91
+ inspector: Ref<HTMLElement | null>;
92
+ /** The canvas's focusable tree, to take focus back. */
93
+ canvas: Ref<HTMLElement | null>;
94
+ /** Taps add to the selection or take from it, for touch screens without Shift or ⌘. */
95
+ tapToggles: Ref<boolean>;
96
+ /**
97
+ * A press on a node in a view: Shift selects the range from the last
98
+ * plain press, ⌘ / Ctrl (or `tapToggles`) adds or removes, else replaces.
99
+ */
100
+ pick: (id: string, event: MouseEvent, view: BuilderView) => void;
101
+ /** Drags on the canvas, set by the canvas once it is mounted. */
102
+ dragger: Ref<DragController | null>;
103
+ /** Opens the menu of the selected nodes at a point of the viewport, set by the canvas. */
104
+ openMenu: Ref<((x: number, y: number) => void) | null>;
105
+ /** The names of the functions given to the builder, for checks and completions. */
106
+ functionNames: ComputedRef<string[]>;
107
+ /** The functions given to the builder, for the preview. */
108
+ functions: () => Record<string, FormFunction> | undefined;
109
+ sources: () => Record<string, FormOptionsLoader> | undefined;
110
+ /** The validators given to the builder, for the preview and the rules editor. */
111
+ validators: () => Record<string, FormValidator> | undefined;
112
+ extensions: () => ResolvedFormBuilderExtensions;
113
+ /** The selection, as a set, for views checking many nodes. */
114
+ selected: ComputedRef<ReadonlySet<string>>;
115
+ /** The node the inspector and the action bar are for: the last selected one. */
116
+ focused: ComputedRef<FormNode | undefined>;
117
+ }
118
+ /** A list of nodes as a view shows them, for the arrow keys. */
119
+ export interface BuilderView {
120
+ name: 'canvas' | 'outline';
121
+ /** The nodes in the order they are listed. */
122
+ order: () => string[];
123
+ /** `ArrowRight` on a node: return `true` when the view handled it, e.g. by expanding it. */
124
+ expand?: (id: string) => boolean;
125
+ collapse?: (id: string) => boolean;
126
+ }
127
+ export declare const builderKey: InjectionKey<BuilderState>;
128
+ /** Inside a builder: its document, selection and commands. */
129
+ export declare function useFormBuilder(): FormBuilderContext;
130
+ export declare function useBuilderState(): BuilderState;
131
+ export interface CreateBuilderOptions {
132
+ uid: string;
133
+ document: () => FormDocument;
134
+ selection: () => readonly string[] | undefined;
135
+ fields: () => Map<string, FormFieldType>;
136
+ messages: () => FormBuilderMessages;
137
+ emitDocument: (document: FormDocument, tr: FormBuilderTransaction) => void;
138
+ emitSelection: (ids: string[]) => void;
139
+ mode: () => FormBuilderMode;
140
+ emitMode: (mode: FormBuilderMode) => void;
141
+ functions: () => Record<string, FormFunction> | undefined;
142
+ sources: () => Record<string, FormOptionsLoader> | undefined;
143
+ validators: () => Record<string, FormValidator> | undefined;
144
+ readonly: () => boolean;
145
+ extensions: () => ResolvedFormBuilderExtensions;
146
+ }
147
+ export declare function createBuilderState(options: CreateBuilderOptions): BuilderState;
148
+ /** Every node in the order the canvas lists them: only the shown page of tabs and steps is open. */
149
+ export declare function canvasOrder(state: BuilderState): string[];
@@ -0,0 +1,74 @@
1
+ import type { FormContainerNode, FormDocument, FormListNode, FormNode, FormPageNode } from '../../core/types';
2
+ import type { FormFieldType } from '../../fields/define';
3
+ import type { FormBuilderMessages } from '../locale';
4
+ import type { FormBuilderTransaction } from './transaction';
5
+ /** Where a new node goes: into a container (`null`: the top) at an index. */
6
+ export interface FormBuilderInsertPlace {
7
+ parent: string | null;
8
+ index: number;
9
+ }
10
+ /** The list a node's name is a key of, or `null` for names at the top of the form. */
11
+ export declare function scopeOf(document: FormDocument, parent: string | null): FormListNode | null;
12
+ /** The names already used in a scope: fields and lists, not the fields of nested lists. */
13
+ export declare function namesIn(document: FormDocument, scope: FormListNode | null): Set<string>;
14
+ /** `select3` after `select` and `select2`: the type in camel case and the first free number. */
15
+ export declare function uniqueName(base: string, taken: ReadonlySet<string>): string;
16
+ /** A new node of a type, with an id, a free name and texts to start from. */
17
+ export declare function createNode(type: string, context: {
18
+ fields: Map<string, FormFieldType>;
19
+ messages: FormBuilderMessages;
20
+ taken: ReadonlySet<string>;
21
+ }): FormNode;
22
+ /** The page of tabs or steps the builder shows, given which ones are open. */
23
+ export type ShownPage = (container: FormContainerNode) => FormPageNode | undefined;
24
+ /**
25
+ * Where a node of `type` goes when added from the palette: inside the
26
+ * last selected container (the shown page of tabs and steps), else after
27
+ * the last selected node, else at the end of the form.
28
+ */
29
+ export declare function insertPlace(document: FormDocument, selection: readonly string[], type: string, shown: ShownPage): FormBuilderInsertPlace;
30
+ /** The selected nodes without the ones inside other selected nodes, in document order. */
31
+ export declare function topmost(document: FormDocument, ids: readonly string[]): string[];
32
+ /** A copy of a node with new ids, and a free name for the copy itself. */
33
+ export declare function copyNode(node: FormNode, taken: Set<string>): FormNode;
34
+ /** What the commands below read besides the document. */
35
+ export interface CommandContext {
36
+ fields: Map<string, FormFieldType>;
37
+ messages: FormBuilderMessages;
38
+ }
39
+ /** Remove nodes; the node to select afterwards: the next one, else the one before, else the parent. */
40
+ export declare function removeNodes(tr: FormBuilderTransaction, ids: readonly string[]): {
41
+ removed: number;
42
+ next: string | undefined;
43
+ };
44
+ /** Put a copy of each node right after it; the ids of the copies. */
45
+ export declare function duplicateNodes(tr: FormBuilderTransaction, ids: readonly string[]): string[];
46
+ /**
47
+ * Move each node one place up (`-1`) or down (`1`) among its siblings.
48
+ * Nodes already at the edge stay, and so do the selected ones next to
49
+ * them, so a selection keeps its shape. Returns whether anything moved.
50
+ */
51
+ export declare function moveNodes(tr: FormBuilderTransaction, ids: readonly string[], delta: -1 | 1): boolean;
52
+ /** Put nodes of one container into a new section where the first of them was; its id. */
53
+ export declare function wrapNodes(tr: FormBuilderTransaction, ids: readonly string[], context: CommandContext): string | undefined;
54
+ /**
55
+ * Move nodes, in document order, into a container (`null`: the top) so
56
+ * that they start at `index` of its children as they are now (the moved
57
+ * nodes counted). Returns whether anything changed.
58
+ */
59
+ export declare function moveNodesTo(tr: FormBuilderTransaction, ids: readonly string[], parent: string | null, index: number): boolean;
60
+ /**
61
+ * Every place nodes can be moved to, in reading order: before each child
62
+ * of each container and at its end. Places inside the moved nodes, in
63
+ * pages not shown, or in containers that cannot hold them are left out.
64
+ */
65
+ export declare function dropPlaces(document: FormDocument, ids: readonly string[], shown: ShownPage): FormBuilderInsertPlace[];
66
+ /**
67
+ * Turn the document into another, e.g. one imported as JSON or one changed
68
+ * by another person, in as few steps as it takes: nodes only the old one
69
+ * has go, nodes only the new one has come in, nodes in both move where the
70
+ * new one has them and take its keys, and the settings follow. Nodes that
71
+ * did not change stay the same objects. As steps of a transaction, so undo
72
+ * brings the old document back.
73
+ */
74
+ export declare function replaceDocument(tr: FormBuilderTransaction, next: FormDocument): void;
@@ -0,0 +1,23 @@
1
+ import type { FormDocument } from '../../core/types';
2
+ import type { FormBuilderTransaction } from './transaction';
3
+ /** Undo and redo of a builder: the steps of each transaction and the selection around it. */
4
+ export declare class FormBuilderHistory {
5
+ private depth;
6
+ private done;
7
+ private undone;
8
+ constructor(depth?: number);
9
+ get canUndo(): boolean;
10
+ get canRedo(): boolean;
11
+ record(tr: FormBuilderTransaction, selectionBefore: string[], selectionAfter: string[], now?: number): void;
12
+ /** End the current group, so the next change starts a new undo step. */
13
+ close(): void;
14
+ undo(document: FormDocument): {
15
+ tr: FormBuilderTransaction;
16
+ selection: string[];
17
+ } | null;
18
+ redo(document: FormDocument): {
19
+ tr: FormBuilderTransaction;
20
+ selection: string[];
21
+ } | null;
22
+ clear(): void;
23
+ }
@@ -0,0 +1,108 @@
1
+ import type { FormContainerNode, FormDocument, FormNode } from '../../core/types';
2
+ /**
3
+ * The settings of a document besides its nodes, e.g. `layout` or
4
+ * `columns`. `undefined` in a patch removes the setting.
5
+ */
6
+ export type FormDocumentPatch = {
7
+ [K in Exclude<keyof FormDocument, 'nodes' | 'version'>]?: FormDocument[K] | undefined;
8
+ };
9
+ /**
10
+ * Keys of a node to set; `undefined` removes the key. `id`, `type` and
11
+ * `children` cannot be set: insert, remove and move nodes instead.
12
+ */
13
+ export type FormNodePatch = Record<string, unknown>;
14
+ /**
15
+ * One change to a document. `parent` is the id of a container, or `null`
16
+ * for the document's own nodes; `index` counts in that list, after the
17
+ * node moved out of its old place.
18
+ */
19
+ export type FormBuilderStep = {
20
+ type: 'insert';
21
+ node: FormNode;
22
+ parent: string | null;
23
+ index: number;
24
+ } | {
25
+ type: 'remove';
26
+ id: string;
27
+ } | {
28
+ type: 'update';
29
+ id: string;
30
+ patch: FormNodePatch;
31
+ } | {
32
+ type: 'move';
33
+ id: string;
34
+ parent: string | null;
35
+ index: number;
36
+ } | {
37
+ type: 'updateDocument';
38
+ patch: FormDocumentPatch;
39
+ };
40
+ export interface FormBuilderTransactionMeta {
41
+ /** `false` keeps the change out of undo, e.g. a change from another person. */
42
+ history?: boolean;
43
+ /**
44
+ * Changes of the same group within a second become one undo step, e.g.
45
+ * the keys typed into one setting.
46
+ */
47
+ group?: string;
48
+ /** Where the change comes from, e.g. `inspector`, `keyboard` or an extension's name. */
49
+ origin?: string;
50
+ [key: string]: unknown;
51
+ }
52
+ /** Where a node sits: its container (`null` at the top) and position. */
53
+ export interface FormNodePlace {
54
+ node: FormNode;
55
+ parent: FormContainerNode | null;
56
+ index: number;
57
+ /** How deep it sits, from 1 for the document's own nodes. */
58
+ depth: number;
59
+ }
60
+ /**
61
+ * Where every node of a document sits, by id. Worked out once per
62
+ * document object, which a transaction replaces on every change.
63
+ */
64
+ export declare function formNodePlaces(document: FormDocument): Map<string, FormNodePlace>;
65
+ /**
66
+ * Whether a container (`null`: the top of the form) can hold `node`:
67
+ * pages go in tabs and steps, and only pages do.
68
+ */
69
+ export declare function canContainFormNode(parent: FormNode | null, node: FormNode): boolean;
70
+ /**
71
+ * Changes to a form document, made step by step. Each step returns a new
72
+ * document that shares every node it did not touch with the one before,
73
+ * so views of untouched nodes do not render again. The builder records
74
+ * the steps for undo; extensions and code dispatch them through
75
+ * `useFormBuilder().dispatch`.
76
+ */
77
+ export declare class FormBuilderTransaction {
78
+ /** The document the transaction starts from. */
79
+ readonly before: FormDocument;
80
+ /** The document after the steps so far. */
81
+ doc: FormDocument;
82
+ readonly steps: FormBuilderStep[];
83
+ /** The steps that undo the ones so far, last one first. */
84
+ readonly inverse: FormBuilderStep[];
85
+ readonly meta: FormBuilderTransactionMeta;
86
+ constructor(
87
+ /** The document the transaction starts from. */
88
+ before: FormDocument);
89
+ /** Whether any step was made. */
90
+ get changed(): boolean;
91
+ /** Apply a step as it is. */
92
+ step(step: FormBuilderStep): this;
93
+ /** Put a node, and what it holds, into a container (`null`: the top), at `index` (the end by default). */
94
+ insert(node: FormNode, parent?: string | null, index?: number): this;
95
+ /** Take a node, and what it holds, out of the document. */
96
+ remove(id: string): this;
97
+ /** Set keys of a node; `undefined` removes a key. */
98
+ update(id: string, patch: FormNodePatch): this;
99
+ /** Move a node into a container (`null`: the top), at `index` of the list without it. */
100
+ move(id: string, parent: string | null, index: number): this;
101
+ /** Change the settings of the document, e.g. `{ layout: 'horizontal' }`. */
102
+ updateDocument(patch: FormDocumentPatch): this;
103
+ setMeta(key: string, value: unknown): this;
104
+ }
105
+ /** Run steps on a document, e.g. ones from undo or from another person. */
106
+ export declare function applyFormSteps(document: FormDocument, steps: readonly FormBuilderStep[]): FormBuilderTransaction;
107
+ /** Merge updates of the same node that follow each other, for steps kept by undo. */
108
+ export declare function compactFormSteps(steps: readonly FormBuilderStep[]): FormBuilderStep[];
@@ -0,0 +1,52 @@
1
+ import type { BuilderState } from './context';
2
+ import type { FormBuilderInsertPlace } from './core/commands';
3
+ /** A rectangle in the coordinates of the canvas's content, so scrolling does not change it. */
4
+ interface Box {
5
+ left: number;
6
+ top: number;
7
+ right: number;
8
+ bottom: number;
9
+ }
10
+ /** Where a drop goes, and how to draw it. */
11
+ export interface DropTarget extends FormBuilderInsertPlace {
12
+ /** The line between nodes, in the canvas's content coordinates. */
13
+ line: {
14
+ left: number;
15
+ top: number;
16
+ length: number;
17
+ vertical: boolean;
18
+ };
19
+ /** The grid the node goes into. */
20
+ holder: Box;
21
+ }
22
+ /** What is being dragged: nodes of the canvas, or a new node of a type from the palette. */
23
+ export type DragSource = {
24
+ kind: 'nodes';
25
+ ids: string[];
26
+ } | {
27
+ kind: 'type';
28
+ type: string;
29
+ };
30
+ /** The parts the canvas draws for a drag; the controller moves them without rendering. */
31
+ export interface DragLayer {
32
+ indicator: HTMLElement | null;
33
+ holder: HTMLElement | null;
34
+ ghost: HTMLElement | null;
35
+ }
36
+ export interface DragController {
37
+ /** A press on a node of the canvas: becomes a drag after a move (mouse) or a rest (touch). */
38
+ pressNode: (event: PointerEvent, id: string) => void;
39
+ /** A press on an entry of the palette. */
40
+ pressType: (event: PointerEvent, type: string, label: string) => void;
41
+ /** Whether the click that ends a drag should be ignored. */
42
+ swallowClick: () => boolean;
43
+ /** Pick up the selected nodes to move them with the keyboard. */
44
+ pickUp: () => boolean;
45
+ /** Keys while nodes are picked up; returns whether the key was used. */
46
+ keydown: (event: KeyboardEvent) => boolean;
47
+ /** Whether nodes are picked up with the keyboard. */
48
+ readonly carrying: boolean;
49
+ stop: () => void;
50
+ }
51
+ export declare function createDragController(state: BuilderState, scroller: () => HTMLElement | null, layer: DragLayer): DragController;
52
+ export {};
@@ -0,0 +1,8 @@
1
+ import ExpressionInput from './expression-input.vue';
2
+ /**
3
+ * The text box for an expression: an extension's `expressionInput`, else the built-in one.
4
+ * It is read-only while the builder is. Everything given to it goes on to that box, so it
5
+ * takes what the built-in one takes.
6
+ */
7
+ declare const _default: typeof ExpressionInput;
8
+ export default _default;
@@ -0,0 +1,29 @@
1
+ interface Name {
2
+ path: string;
3
+ label?: string;
4
+ }
5
+ type __VLS_Props = {
6
+ modelValue?: string | null;
7
+ /** The paths `values` can read. */
8
+ names?: Name[];
9
+ /** The paths `item` can read; left out where there is no list item. */
10
+ itemNames?: Name[];
11
+ /** Whether the expression can read `value`, as a check can. */
12
+ readsValue?: boolean;
13
+ placeholder?: string;
14
+ disabled?: boolean;
15
+ /** Shown and selectable, but not changed; also when the form around is read-only. */
16
+ readonly?: boolean;
17
+ };
18
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
19
+ "update:modelValue": (value: string) => any;
20
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
21
+ "onUpdate:modelValue"?: ((value: string) => any) | undefined;
22
+ }>, {
23
+ modelValue: string | null;
24
+ placeholder: string;
25
+ names: Name[];
26
+ itemNames: Name[];
27
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
28
+ declare const _default: typeof __VLS_export;
29
+ export default _default;
@@ -0,0 +1,149 @@
1
+ import type { Component } from 'vue';
2
+ import type { FormNode } from '../core/types';
3
+ import type { FormFieldType } from '../fields/define';
4
+ import type { FormBuilderContext } from './context';
5
+ import type { FormBuilderTransaction } from './core/transaction';
6
+ /** What an extension's hooks receive; the same as `useFormBuilder()`. */
7
+ export type FormBuilderExtensionContext = FormBuilderContext;
8
+ /**
9
+ * A key handler: return `false` to let the key through to the next handler
10
+ * and the builder's own keys; anything else means it was handled.
11
+ */
12
+ export type FormBuilderKeyHandler = (event: KeyboardEvent) => boolean | void;
13
+ /** A button of the toolbar over the canvas. */
14
+ export interface FormBuilderToolbarItem {
15
+ key: string;
16
+ /** Read out, and shown as the tooltip; shown beside the icon when there is no icon. */
17
+ label: string;
18
+ icon?: Component;
19
+ run: () => void;
20
+ disabled?: boolean;
21
+ /** For a button that turns something on and off: whether it is on. */
22
+ pressed?: boolean;
23
+ /**
24
+ * The key that does the same, as a hotkey like `alt+r`: shown in the
25
+ * tooltip and given to screen readers as `aria-keyshortcuts`. It is only
26
+ * a hint; bind the key with `keymap`.
27
+ */
28
+ shortcut?: string;
29
+ }
30
+ /** An item of a node's menu: its "more" button and the right-click menu. */
31
+ export interface FormBuilderMenuItem {
32
+ key: string;
33
+ label: string;
34
+ icon?: Component;
35
+ run: () => void;
36
+ disabled?: boolean;
37
+ tone?: 'neutral' | 'danger';
38
+ /** The key that does the same, as a hotkey like `alt+r`, shown at the end of the item. */
39
+ shortcut?: string;
40
+ }
41
+ /**
42
+ * A mark on a node of the canvas and the outline, e.g. who else has it
43
+ * selected: an outline in its color and a tag with its label.
44
+ */
45
+ export interface FormBuilderNodeMark {
46
+ key: string;
47
+ label: string;
48
+ /** Any CSS color; the text color when left out. */
49
+ color?: string;
50
+ }
51
+ /** An undo history that replaces the builder's own, e.g. one that only undoes this user's changes. */
52
+ export interface FormBuilderHistoryHandler {
53
+ /** `false` when there was nothing to undo. */
54
+ undo: () => boolean;
55
+ redo: () => boolean;
56
+ canUndo: () => boolean;
57
+ canRedo: () => boolean;
58
+ }
59
+ /** A part of the inspector, under the built-in settings. */
60
+ export interface FormBuilderInspectorSection {
61
+ key: string;
62
+ /** The heading over it. */
63
+ title: string;
64
+ /**
65
+ * Rendered with `props`; it can call `useFormBuilder()`. It is not made
66
+ * read-only for you: read `useFormBuilder().readonly` and do not change
67
+ * the form while it is `true`.
68
+ */
69
+ component: Component;
70
+ props?: Record<string, unknown>;
71
+ }
72
+ /**
73
+ * A piece of the builder: field types, keys, toolbar buttons, menu items,
74
+ * parts of the inspector, and a say in every change.
75
+ */
76
+ export interface FormBuilderExtension {
77
+ name: string;
78
+ /** Higher runs first: its keys and hooks come before others. Defaults to 100. */
79
+ priority?: number;
80
+ /**
81
+ * Field types for the palette, besides the `fields` prop. Give the
82
+ * renderer the same types (`resolveFormBuilderFields` collects them).
83
+ */
84
+ fields?: FormFieldType<any>[];
85
+ /**
86
+ * Replaces the text box for expressions (formulas, checks, conditions
87
+ * written as text), e.g. with the code input of
88
+ * `@dou-ui/form-builder/code`. It gets the built-in box's props:
89
+ * `modelValue`, `names`, `itemNames`, `readsValue`, `placeholder`,
90
+ * `disabled`, `readonly` (the builder's `readonly`), and emits
91
+ * `update:modelValue`. The first one by priority
92
+ * is used.
93
+ */
94
+ expressionInput?: Component;
95
+ /**
96
+ * Keys, written as in `useHotkey` (e.g. `mod+e`, `shift+t`), while the
97
+ * canvas or the outline has focus. They come before the builder's own.
98
+ */
99
+ keymap?: (context: FormBuilderExtensionContext) => Record<string, FormBuilderKeyHandler>;
100
+ /** Buttons after undo and redo, before the `toolbar` slot. */
101
+ toolbar?: (context: FormBuilderExtensionContext) => FormBuilderToolbarItem[];
102
+ /** Items for the menu of the selected nodes, after the built-in ones. */
103
+ menu?: (context: FormBuilderExtensionContext, nodes: FormNode[]) => FormBuilderMenuItem[];
104
+ /**
105
+ * Parts of the inspector for a node, or the form when `node` is
106
+ * `undefined`, after the built-in settings.
107
+ */
108
+ inspector?: (context: FormBuilderExtensionContext, node: FormNode | undefined) => FormBuilderInspectorSection[];
109
+ /**
110
+ * Marks for a node, read while the node renders: reactive state read
111
+ * here updates them.
112
+ */
113
+ marks?: (context: FormBuilderExtensionContext, node: FormNode) => FormBuilderNodeMark[];
114
+ /** Replaces the builder's undo history; the first extension that has one wins. */
115
+ history?: (context: FormBuilderExtensionContext) => FormBuilderHistoryHandler;
116
+ /** Runs once the builder is mounted. Return a function to run when it unmounts. */
117
+ setup?: (context: FormBuilderExtensionContext) => void | (() => void);
118
+ /**
119
+ * Sees every change before it reaches the document, in priority order,
120
+ * and may add steps to it, e.g. to name new fields by a rule of the app.
121
+ * Undo and redo do not come through here: they put back what was there.
122
+ */
123
+ transaction?: (tr: FormBuilderTransaction, context: FormBuilderExtensionContext) => void;
124
+ }
125
+ /** Declares an extension; only gives it a type. */
126
+ export declare function defineFormBuilderExtension(extension: FormBuilderExtension): FormBuilderExtension;
127
+ /** Everything the extensions contribute, gathered once per list. */
128
+ export interface ResolvedFormBuilderExtensions {
129
+ extensions: FormBuilderExtension[];
130
+ fields: FormFieldType<any>[];
131
+ keymaps: NonNullable<FormBuilderExtension['keymap']>[];
132
+ toolbars: NonNullable<FormBuilderExtension['toolbar']>[];
133
+ menus: NonNullable<FormBuilderExtension['menu']>[];
134
+ inspectors: NonNullable<FormBuilderExtension['inspector']>[];
135
+ setups: NonNullable<FormBuilderExtension['setup']>[];
136
+ marks: NonNullable<FormBuilderExtension['marks']>[];
137
+ history: FormBuilderExtension['history'];
138
+ expressionInput: FormBuilderExtension['expressionInput'];
139
+ transactions: NonNullable<FormBuilderExtension['transaction']>[];
140
+ }
141
+ type ExtensionList = readonly (FormBuilderExtension | readonly FormBuilderExtension[])[];
142
+ /** Sorts the extensions by priority and collects what they add. */
143
+ export declare function resolveFormBuilderExtensions(list?: ExtensionList): ResolvedFormBuilderExtensions;
144
+ /**
145
+ * The field types of a builder with extensions, for the renderer that
146
+ * shows its forms: the given ones, then the extensions'.
147
+ */
148
+ export declare function resolveFormBuilderFields(fields?: readonly FormFieldType<any>[], extensions?: ExtensionList): FormFieldType<any>[];
149
+ export {};