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

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,487 @@
1
+ import { markRaw } from "vue";
2
+ import { CalendarIcon, CheckSquareIcon, ChevronDownSquareIcon, ClockIcon, HashIcon, InfoSquareIcon, LayoutIcon, LayoutListIcon, ListChecksIcon, ListTreeIcon, OtpIcon, PaletteIcon, RadioIcon, SegmentedControlIcon, SeparatorHorizontalIcon, SlidersIcon, SquareDashedIcon, StarIcon, StepsIcon, TabsIcon, TagsIcon, TextAlignLeftIcon, TextCursorIcon, ToggleRightIcon, TreeStructureIcon, TypeIcon, UploadIcon } from "@dou-ui/icons";
3
+ // src/builder/settings.ts
4
+ /** The palette groups in the order they are listed; groups of other names follow. */
5
+ var paletteGroups = [
6
+ "input",
7
+ "choice",
8
+ "more",
9
+ "display",
10
+ "layout"
11
+ ];
12
+ var raw = (icon) => markRaw(icon);
13
+ /** Icons and groups of the built-in types, kept out of the renderer's entry. */
14
+ var builtinLooks = {
15
+ input: {
16
+ icon: raw(TextCursorIcon),
17
+ group: "input"
18
+ },
19
+ textarea: {
20
+ icon: raw(TextAlignLeftIcon),
21
+ group: "input"
22
+ },
23
+ "input-number": {
24
+ icon: raw(HashIcon),
25
+ group: "input"
26
+ },
27
+ "input-tag": {
28
+ icon: raw(TagsIcon),
29
+ group: "input"
30
+ },
31
+ "input-otp": {
32
+ icon: raw(OtpIcon),
33
+ group: "input"
34
+ },
35
+ select: {
36
+ icon: raw(ChevronDownSquareIcon),
37
+ group: "choice"
38
+ },
39
+ "radio-group": {
40
+ icon: raw(RadioIcon),
41
+ group: "choice"
42
+ },
43
+ "checkbox-group": {
44
+ icon: raw(ListChecksIcon),
45
+ group: "choice"
46
+ },
47
+ checkbox: {
48
+ icon: raw(CheckSquareIcon),
49
+ group: "choice"
50
+ },
51
+ switch: {
52
+ icon: raw(ToggleRightIcon),
53
+ group: "choice"
54
+ },
55
+ "segmented-control": {
56
+ icon: raw(SegmentedControlIcon),
57
+ group: "choice"
58
+ },
59
+ cascader: {
60
+ icon: raw(ListTreeIcon),
61
+ group: "choice"
62
+ },
63
+ "tree-select": {
64
+ icon: raw(TreeStructureIcon),
65
+ group: "choice"
66
+ },
67
+ slider: {
68
+ icon: raw(SlidersIcon),
69
+ group: "more"
70
+ },
71
+ rate: {
72
+ icon: raw(StarIcon),
73
+ group: "more"
74
+ },
75
+ "date-picker": {
76
+ icon: raw(CalendarIcon),
77
+ group: "more"
78
+ },
79
+ "time-picker": {
80
+ icon: raw(ClockIcon),
81
+ group: "more"
82
+ },
83
+ "color-picker": {
84
+ icon: raw(PaletteIcon),
85
+ group: "more"
86
+ },
87
+ upload: {
88
+ icon: raw(UploadIcon),
89
+ group: "more"
90
+ },
91
+ text: {
92
+ icon: raw(TypeIcon),
93
+ group: "display"
94
+ },
95
+ divider: {
96
+ icon: raw(SeparatorHorizontalIcon),
97
+ group: "display"
98
+ },
99
+ alert: {
100
+ icon: raw(InfoSquareIcon),
101
+ group: "display"
102
+ },
103
+ section: {
104
+ icon: raw(SquareDashedIcon),
105
+ group: "layout"
106
+ },
107
+ tabs: {
108
+ icon: raw(TabsIcon),
109
+ group: "layout"
110
+ },
111
+ steps: {
112
+ icon: raw(StepsIcon),
113
+ group: "layout"
114
+ },
115
+ list: {
116
+ icon: raw(LayoutListIcon),
117
+ group: "layout"
118
+ },
119
+ page: {
120
+ icon: raw(LayoutIcon),
121
+ group: "layout"
122
+ }
123
+ };
124
+ /** The containers the palette offers, after the field types. */
125
+ var containerTypes = [
126
+ "section",
127
+ "tabs",
128
+ "steps",
129
+ "list"
130
+ ];
131
+ /** A type's icon: its own, else the built-in one, else a plain box. */
132
+ function iconOf(type, spec) {
133
+ return spec?.icon ?? builtinLooks[type]?.icon ?? builtinLooks.section.icon;
134
+ }
135
+ function groupOf(type, spec) {
136
+ return spec?.group ?? builtinLooks[type]?.group ?? "more";
137
+ }
138
+ /** A type's name for people: its own `label`, else the locale's. */
139
+ function labelOf(type, spec, messages) {
140
+ return spec?.label ?? messages.types[type] ?? type;
141
+ }
142
+ /** What a node is called in the outline and the inspector's heading. */
143
+ function nodeTitle(node, fields, messages) {
144
+ const record = node;
145
+ const own = record.label ?? record.title;
146
+ if (own) return own;
147
+ if ("name" in node && node.name) return node.name;
148
+ return labelOf(node.type, fields.get(node.type), messages);
149
+ }
150
+ var field = (type, name, label, extra = {}) => ({
151
+ id: `setting-${name}`,
152
+ type,
153
+ name,
154
+ label,
155
+ ...extra
156
+ });
157
+ var sw = (name, label, extra = {}) => field("switch", name, label, extra);
158
+ var text = (name, label, extra = {}) => field("input", name, label, {
159
+ ...extra,
160
+ props: {
161
+ clearable: true,
162
+ ...extra.props
163
+ }
164
+ });
165
+ var number = (name, label, props = {}, extra = {}) => field("input-number", name, label, {
166
+ ...extra,
167
+ props: {
168
+ controls: false,
169
+ ...props
170
+ }
171
+ });
172
+ function choices(messages, key, values) {
173
+ const labels = messages.choices[key] ?? {};
174
+ return values.map((value) => ({
175
+ value,
176
+ label: labels[String(value)] ?? String(value)
177
+ }));
178
+ }
179
+ var segmented = (messages, name, values, fallback, extra = {}, key = name) => field("segmented-control", name, messages.settings[key] ?? name, {
180
+ default: fallback,
181
+ props: {
182
+ options: choices(messages, key, values),
183
+ block: true
184
+ },
185
+ ...extra
186
+ });
187
+ function optionList(messages, name = "options") {
188
+ const s = messages.settings;
189
+ return {
190
+ id: `setting-${name}`,
191
+ type: "list",
192
+ name,
193
+ label: s.options,
194
+ columns: 12,
195
+ children: [field("input", "label", s.optionLabel, { span: 6 }), field("input", "value", s.optionValue, { span: 6 })]
196
+ };
197
+ }
198
+ /** Settings of the built-in types, edited in a node's `props`. */
199
+ function builtinSettings(type, messages) {
200
+ const s = messages.settings;
201
+ const placeholder = text("placeholder", s.placeholder);
202
+ const clearable = sw("clearable", s.clearable);
203
+ const multiple = sw("multiple", s.multiple);
204
+ const filterable = sw("filterable", s.filterable);
205
+ const options = optionList(messages);
206
+ const direction = segmented(messages, "direction", ["horizontal", "vertical"], "horizontal");
207
+ switch (type) {
208
+ case "input": return [
209
+ placeholder,
210
+ clearable,
211
+ number("maxlength", s.maxlength, { min: 1 }),
212
+ sw("showCount", s.showCount)
213
+ ];
214
+ case "textarea": return [
215
+ placeholder,
216
+ number("rows", s.rows, {
217
+ min: 1,
218
+ placeholder: "3"
219
+ }),
220
+ sw("autosize", s.autosize),
221
+ number("maxlength", s.maxlength, { min: 1 }),
222
+ sw("showCount", s.showCount)
223
+ ];
224
+ case "input-number": return [
225
+ placeholder,
226
+ number("min", s.min, {}, { span: 6 }),
227
+ number("max", s.max, {}, { span: 6 }),
228
+ number("step", s.step, {
229
+ min: 0,
230
+ placeholder: "1"
231
+ }, { span: 6 }),
232
+ number("precision", s.precision, {
233
+ min: 0,
234
+ precision: 0
235
+ }, { span: 6 }),
236
+ sw("controls", s.controls, { default: true })
237
+ ];
238
+ case "select": return [
239
+ options,
240
+ placeholder,
241
+ multiple,
242
+ filterable,
243
+ clearable
244
+ ];
245
+ case "radio-group":
246
+ case "checkbox-group": return [options, direction];
247
+ case "segmented-control": return [options];
248
+ case "checkbox": return [text("text", s.text)];
249
+ case "slider": return [
250
+ number("min", s.min, {}, {
251
+ span: 6,
252
+ default: 0
253
+ }),
254
+ number("max", s.max, {}, {
255
+ span: 6,
256
+ default: 100
257
+ }),
258
+ number("step", s.step, { min: 0 }, { default: 1 }),
259
+ sw("range", s.range)
260
+ ];
261
+ case "rate": return [number("max", s.count, {
262
+ min: 1,
263
+ max: 10,
264
+ precision: 0
265
+ }, { default: 5 }), sw("allowHalf", s.allowHalf)];
266
+ case "date-picker": return [
267
+ field("select", "type", s.dateType, {
268
+ default: "date",
269
+ props: { options: choices(messages, "dateType", [
270
+ "date",
271
+ "week",
272
+ "month",
273
+ "quarter",
274
+ "year",
275
+ "datetime"
276
+ ]) }
277
+ }),
278
+ sw("range", s.range, { visibleWhen: "values.type != 'week'" }),
279
+ placeholder,
280
+ clearable
281
+ ];
282
+ case "time-picker": return [
283
+ sw("range", s.range),
284
+ placeholder,
285
+ clearable
286
+ ];
287
+ case "color-picker": return [sw("showAlpha", s.showAlpha), clearable];
288
+ case "cascader":
289
+ case "tree-select": return [
290
+ placeholder,
291
+ multiple,
292
+ filterable,
293
+ clearable
294
+ ];
295
+ case "input-tag": return [
296
+ placeholder,
297
+ number("max", s.maxTags, {
298
+ min: 1,
299
+ precision: 0
300
+ }),
301
+ clearable
302
+ ];
303
+ case "input-otp": return [number("length", s.length, {
304
+ min: 1,
305
+ max: 12,
306
+ precision: 0
307
+ }, { default: 6 }), sw("mask", s.mask)];
308
+ case "upload": return [
309
+ text("accept", s.accept, { props: { placeholder: "image/*, .pdf" } }),
310
+ multiple,
311
+ number("maxCount", s.maxCount, {
312
+ min: 1,
313
+ precision: 0
314
+ }),
315
+ sw("dropzone", s.dropzone)
316
+ ];
317
+ case "text": return [field("textarea", "content", s.content, { props: { autosize: {
318
+ minRows: 2,
319
+ maxRows: 8
320
+ } } }), segmented(messages, "variant", [
321
+ "title",
322
+ "body",
323
+ "caption"
324
+ ], "body")];
325
+ case "divider": return [text("text", s.content), sw("dashed", s.dashed)];
326
+ case "alert": return [
327
+ field("select", "tone", s.tone, {
328
+ default: "neutral",
329
+ props: { options: choices(messages, "tone", [
330
+ "neutral",
331
+ "primary",
332
+ "success",
333
+ "warning",
334
+ "danger"
335
+ ]) }
336
+ }),
337
+ text("title", s.title),
338
+ field("textarea", "content", s.content, { props: { autosize: {
339
+ minRows: 2,
340
+ maxRows: 8
341
+ } } })
342
+ ];
343
+ default: return [];
344
+ }
345
+ }
346
+ /** The builder's own type for a node's width: a number of columns, or one per breakpoint. */
347
+ var SPAN_TYPE = "dou-builder-span";
348
+ /** The builder's own type for expression text, with completions and problems. */
349
+ var EXPRESSION_TYPE = "dou-builder-expression";
350
+ /** The builder's own type for a condition, edited as rows or as text. */
351
+ var CONDITION_TYPE = "dou-builder-condition";
352
+ function spanSetting(context) {
353
+ const node = field(SPAN_TYPE, "span", "", {
354
+ default: context.columns,
355
+ props: { columns: context.columns }
356
+ });
357
+ delete node.label;
358
+ return node;
359
+ }
360
+ /** The settings of a node itself, besides its type's: name, label, width and so on. */
361
+ function nodeSettings(node, context) {
362
+ const s = context.messages.settings;
363
+ const span = spanSetting(context);
364
+ const name = text("name", context.inItem ? s.itemName : s.name, {
365
+ help: context.inItem ? s.itemNameHelp : s.nameHelp,
366
+ props: { clearable: false }
367
+ });
368
+ const columns = number("columns", s.columns, {
369
+ min: 1,
370
+ max: 24,
371
+ precision: 0,
372
+ placeholder: String(context.columns)
373
+ });
374
+ switch (node.type) {
375
+ case "section": return [
376
+ text("title", s.title),
377
+ field("textarea", "description", s.description, { props: { autosize: {
378
+ minRows: 1,
379
+ maxRows: 6
380
+ } } }),
381
+ sw("bordered", s.bordered),
382
+ columns,
383
+ span
384
+ ];
385
+ case "page": return [
386
+ text("title", s.title),
387
+ field("textarea", "description", s.description, { props: { autosize: {
388
+ minRows: 1,
389
+ maxRows: 6
390
+ } } }),
391
+ columns
392
+ ];
393
+ case "tabs":
394
+ case "steps": return [span];
395
+ case "list": return [
396
+ name,
397
+ text("label", s.label),
398
+ text("help", s.help),
399
+ span,
400
+ number("min", s.minItems, {
401
+ min: 0,
402
+ precision: 0
403
+ }, { span: 6 }),
404
+ number("max", s.maxItems, {
405
+ min: 1,
406
+ precision: 0
407
+ }, { span: 6 }),
408
+ text("addText", s.addText),
409
+ sw("sortable", s.sortable, { default: true }),
410
+ sw("required", s.required),
411
+ columns
412
+ ];
413
+ default: {
414
+ const type = context.type;
415
+ if (type?.kind === "display") return [span];
416
+ const own = node;
417
+ const result = [
418
+ name,
419
+ text("label", s.label),
420
+ text("help", s.help),
421
+ span
422
+ ];
423
+ if (type && own.type !== "upload") result.push({
424
+ id: "setting-default",
425
+ type: own.type,
426
+ name: "default",
427
+ label: s.default,
428
+ props: own.props
429
+ });
430
+ result.push(sw("required", s.required));
431
+ return result;
432
+ }
433
+ }
434
+ }
435
+ /** The settings of the document itself. */
436
+ function documentSettings(messages) {
437
+ const s = messages.settings;
438
+ const horizontal = "values.layout == 'horizontal'";
439
+ return [
440
+ segmented(messages, "layout", [
441
+ "vertical",
442
+ "horizontal",
443
+ "inline"
444
+ ], "vertical"),
445
+ segmented(messages, "labelAlign", ["start", "end"], "start", { visibleWhen: horizontal }),
446
+ number("labelWidth", s.labelWidth, {
447
+ min: 40,
448
+ max: 400,
449
+ step: 8,
450
+ precision: 0
451
+ }, {
452
+ default: 96,
453
+ visibleWhen: horizontal
454
+ }),
455
+ segmented(messages, "size", [
456
+ "sm",
457
+ "md",
458
+ "lg"
459
+ ], "md"),
460
+ field("radio-group", "requiredMark", s.requiredMark, {
461
+ default: true,
462
+ props: { options: choices(messages, "requiredMark", [
463
+ true,
464
+ "optional",
465
+ false
466
+ ]) }
467
+ }),
468
+ number("columns", s.columns, {
469
+ min: 1,
470
+ max: 24,
471
+ precision: 0
472
+ }, { default: 12 })
473
+ ];
474
+ }
475
+ /** A settings form: the nodes in a vertical, compact document. */
476
+ function settingsDocument(nodes) {
477
+ return {
478
+ version: 1,
479
+ size: "sm",
480
+ columns: 12,
481
+ requiredMark: false,
482
+ nodes
483
+ };
484
+ }
485
+ export { CONDITION_TYPE, EXPRESSION_TYPE, SPAN_TYPE, builtinSettings, choices, containerTypes, documentSettings, field, groupOf, iconOf, labelOf, nodeSettings, nodeTitle, number, paletteGroups, segmented, settingsDocument, text };
486
+
487
+ //# sourceMappingURL=settings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings.js","names":[],"sources":["../../src/builder/settings.ts"],"sourcesContent":["import {\n CalendarIcon,\n CheckSquareIcon,\n ChevronDownSquareIcon,\n ClockIcon,\n HashIcon,\n InfoSquareIcon,\n LayoutIcon,\n LayoutListIcon,\n ListChecksIcon,\n ListTreeIcon,\n OtpIcon,\n PaletteIcon,\n RadioIcon,\n SegmentedControlIcon,\n SeparatorHorizontalIcon,\n SlidersIcon,\n SquareDashedIcon,\n StarIcon,\n StepsIcon,\n TabsIcon,\n TagsIcon,\n TextAlignLeftIcon,\n TextCursorIcon,\n ToggleRightIcon,\n TreeStructureIcon,\n TypeIcon,\n UploadIcon,\n} from '@dou-ui/icons'\nimport { markRaw } from 'vue'\nimport type { Component } from 'vue'\nimport type { FormDocument, FormFieldNode, FormListNode, FormNode } from '../core/types'\nimport type { FormFieldType } from '../fields/define'\nimport type { FormBuilderMessages } from './locale'\n\n/** The palette groups in the order they are listed; groups of other names follow. */\nexport const paletteGroups = ['input', 'choice', 'more', 'display', 'layout']\n\nconst raw = (icon: Component) => markRaw(icon)\n\n/** Icons and groups of the built-in types, kept out of the renderer's entry. */\nconst builtinLooks: Record<string, { icon: Component; group: string }> = {\n input: { icon: raw(TextCursorIcon), group: 'input' },\n textarea: { icon: raw(TextAlignLeftIcon), group: 'input' },\n 'input-number': { icon: raw(HashIcon), group: 'input' },\n 'input-tag': { icon: raw(TagsIcon), group: 'input' },\n 'input-otp': { icon: raw(OtpIcon), group: 'input' },\n select: { icon: raw(ChevronDownSquareIcon), group: 'choice' },\n 'radio-group': { icon: raw(RadioIcon), group: 'choice' },\n 'checkbox-group': { icon: raw(ListChecksIcon), group: 'choice' },\n checkbox: { icon: raw(CheckSquareIcon), group: 'choice' },\n switch: { icon: raw(ToggleRightIcon), group: 'choice' },\n 'segmented-control': { icon: raw(SegmentedControlIcon), group: 'choice' },\n cascader: { icon: raw(ListTreeIcon), group: 'choice' },\n 'tree-select': { icon: raw(TreeStructureIcon), group: 'choice' },\n slider: { icon: raw(SlidersIcon), group: 'more' },\n rate: { icon: raw(StarIcon), group: 'more' },\n 'date-picker': { icon: raw(CalendarIcon), group: 'more' },\n 'time-picker': { icon: raw(ClockIcon), group: 'more' },\n 'color-picker': { icon: raw(PaletteIcon), group: 'more' },\n upload: { icon: raw(UploadIcon), group: 'more' },\n text: { icon: raw(TypeIcon), group: 'display' },\n divider: { icon: raw(SeparatorHorizontalIcon), group: 'display' },\n alert: { icon: raw(InfoSquareIcon), group: 'display' },\n section: { icon: raw(SquareDashedIcon), group: 'layout' },\n tabs: { icon: raw(TabsIcon), group: 'layout' },\n steps: { icon: raw(StepsIcon), group: 'layout' },\n list: { icon: raw(LayoutListIcon), group: 'layout' },\n page: { icon: raw(LayoutIcon), group: 'layout' },\n}\n\n/** The containers the palette offers, after the field types. */\nexport const containerTypes = ['section', 'tabs', 'steps', 'list']\n\n/** A type's icon: its own, else the built-in one, else a plain box. */\nexport function iconOf(type: string, spec?: FormFieldType): Component {\n return spec?.icon ?? builtinLooks[type]?.icon ?? builtinLooks.section!.icon\n}\n\nexport function groupOf(type: string, spec?: FormFieldType): string {\n return spec?.group ?? builtinLooks[type]?.group ?? 'more'\n}\n\n/** A type's name for people: its own `label`, else the locale's. */\nexport function labelOf(\n type: string,\n spec: FormFieldType | undefined,\n messages: FormBuilderMessages,\n) {\n return spec?.label ?? messages.types[type] ?? type\n}\n\n/** What a node is called in the outline and the inspector's heading. */\nexport function nodeTitle(\n node: FormNode,\n fields: ReadonlyMap<string, FormFieldType>,\n messages: FormBuilderMessages,\n): string {\n const record = node as unknown as Record<string, unknown>\n const own = (record.label ?? record.title) as string | undefined\n if (own) return own\n if ('name' in node && node.name) return node.name\n return labelOf(node.type, fields.get(node.type), messages)\n}\n\n// Settings ----------------------------------------------------------------------\n\ntype Setting = Record<string, unknown>\n\nexport const field = (type: string, name: string, label: string, extra: Setting = {}): FormNode =>\n ({ id: `setting-${name}`, type, name, label, ...extra }) as FormFieldNode\n\nconst sw = (name: string, label: string, extra: Setting = {}) => field('switch', name, label, extra)\nexport const text = (name: string, label: string, extra: Setting = {}) =>\n field('input', name, label, { ...extra, props: { clearable: true, ...(extra.props as Setting) } })\nexport const number = (name: string, label: string, props: Setting = {}, extra: Setting = {}) =>\n field('input-number', name, label, { ...extra, props: { controls: false, ...props } })\n\nexport function choices(\n messages: FormBuilderMessages,\n key: string,\n values: readonly (string | boolean)[],\n): { value: string | boolean; label: string }[] {\n const labels = messages.choices[key] ?? {}\n return values.map((value) => ({ value, label: labels[String(value)] ?? String(value) }))\n}\n\nexport const segmented = (\n messages: FormBuilderMessages,\n name: string,\n values: readonly string[],\n fallback: string,\n extra: Setting = {},\n key = name,\n) =>\n field('segmented-control', name, messages.settings[key] ?? name, {\n default: fallback,\n props: { options: choices(messages, key, values), block: true },\n ...extra,\n })\n\nfunction optionList(messages: FormBuilderMessages, name = 'options'): FormListNode {\n const s = messages.settings\n return {\n id: `setting-${name}`,\n type: 'list',\n name,\n label: s.options,\n columns: 12,\n children: [\n field('input', 'label', s.optionLabel!, { span: 6 }),\n field('input', 'value', s.optionValue!, { span: 6 }),\n ],\n }\n}\n\n/** Settings of the built-in types, edited in a node's `props`. */\nexport function builtinSettings(type: string, messages: FormBuilderMessages): FormNode[] {\n const s = messages.settings as Record<string, string>\n const placeholder = text('placeholder', s.placeholder!)\n const clearable = sw('clearable', s.clearable!)\n const multiple = sw('multiple', s.multiple!)\n const filterable = sw('filterable', s.filterable!)\n const options = optionList(messages)\n const direction = segmented(messages, 'direction', ['horizontal', 'vertical'], 'horizontal')\n switch (type) {\n case 'input':\n return [\n placeholder,\n clearable,\n number('maxlength', s.maxlength!, { min: 1 }),\n sw('showCount', s.showCount!),\n ]\n case 'textarea':\n return [\n placeholder,\n number('rows', s.rows!, { min: 1, placeholder: '3' }),\n sw('autosize', s.autosize!),\n number('maxlength', s.maxlength!, { min: 1 }),\n sw('showCount', s.showCount!),\n ]\n case 'input-number':\n return [\n placeholder,\n number('min', s.min!, {}, { span: 6 }),\n number('max', s.max!, {}, { span: 6 }),\n number('step', s.step!, { min: 0, placeholder: '1' }, { span: 6 }),\n number('precision', s.precision!, { min: 0, precision: 0 }, { span: 6 }),\n sw('controls', s.controls!, { default: true }),\n ]\n case 'select':\n return [options, placeholder, multiple, filterable, clearable]\n case 'radio-group':\n case 'checkbox-group':\n return [options, direction]\n case 'segmented-control':\n return [options]\n case 'checkbox':\n return [text('text', s.text!)]\n case 'slider':\n return [\n number('min', s.min!, {}, { span: 6, default: 0 }),\n number('max', s.max!, {}, { span: 6, default: 100 }),\n number('step', s.step!, { min: 0 }, { default: 1 }),\n sw('range', s.range!),\n ]\n case 'rate':\n return [\n number('max', s.count!, { min: 1, max: 10, precision: 0 }, { default: 5 }),\n sw('allowHalf', s.allowHalf!),\n ]\n case 'date-picker':\n return [\n field('select', 'type', s.dateType!, {\n default: 'date',\n props: {\n options: choices(messages, 'dateType', [\n 'date',\n 'week',\n 'month',\n 'quarter',\n 'year',\n 'datetime',\n ]),\n },\n }),\n sw('range', s.range!, { visibleWhen: \"values.type != 'week'\" }),\n placeholder,\n clearable,\n ]\n case 'time-picker':\n return [sw('range', s.range!), placeholder, clearable]\n case 'color-picker':\n return [sw('showAlpha', s.showAlpha!), clearable]\n case 'cascader':\n case 'tree-select':\n return [placeholder, multiple, filterable, clearable]\n case 'input-tag':\n return [placeholder, number('max', s.maxTags!, { min: 1, precision: 0 }), clearable]\n case 'input-otp':\n return [\n number('length', s.length!, { min: 1, max: 12, precision: 0 }, { default: 6 }),\n sw('mask', s.mask!),\n ]\n case 'upload':\n return [\n text('accept', s.accept!, { props: { placeholder: 'image/*, .pdf' } }),\n multiple,\n number('maxCount', s.maxCount!, { min: 1, precision: 0 }),\n sw('dropzone', s.dropzone!),\n ]\n case 'text':\n return [\n field('textarea', 'content', s.content!, {\n props: { autosize: { minRows: 2, maxRows: 8 } },\n }),\n segmented(messages, 'variant', ['title', 'body', 'caption'], 'body'),\n ]\n case 'divider':\n return [text('text', s.content!), sw('dashed', s.dashed!)]\n case 'alert':\n return [\n field('select', 'tone', s.tone!, {\n default: 'neutral',\n props: {\n options: choices(messages, 'tone', [\n 'neutral',\n 'primary',\n 'success',\n 'warning',\n 'danger',\n ]),\n },\n }),\n text('title', s.title!),\n field('textarea', 'content', s.content!, {\n props: { autosize: { minRows: 2, maxRows: 8 } },\n }),\n ]\n default:\n return []\n }\n}\n\n/** What the node-level settings of a node depend on. */\nexport interface NodeSettingsContext {\n messages: FormBuilderMessages\n /** Columns of the grid the node sits on. */\n columns: number\n /** Whether the node sits in a list item, so its name is a key of the item. */\n inItem: boolean\n /** The node's type, for a field. */\n type?: FormFieldType\n}\n\n/** The builder's own type for a node's width: a number of columns, or one per breakpoint. */\nexport const SPAN_TYPE = 'dou-builder-span'\n/** The builder's own type for expression text, with completions and problems. */\nexport const EXPRESSION_TYPE = 'dou-builder-expression'\n/** The builder's own type for a condition, edited as rows or as text. */\nexport const CONDITION_TYPE = 'dou-builder-condition'\n\nfunction spanSetting(context: NodeSettingsContext): FormNode {\n // The field draws its own label, with the \"by form width\" switch on the same row.\n const node = field(SPAN_TYPE, 'span', '', {\n default: context.columns,\n props: { columns: context.columns },\n }) as FormFieldNode\n delete node.label\n return node\n}\n\n/** The settings of a node itself, besides its type's: name, label, width and so on. */\nexport function nodeSettings(node: FormNode, context: NodeSettingsContext): FormNode[] {\n const s = context.messages.settings as Record<string, string>\n const span = spanSetting(context)\n const name = text('name', context.inItem ? s.itemName! : s.name!, {\n help: context.inItem ? s.itemNameHelp : s.nameHelp,\n props: { clearable: false },\n })\n const columns = number('columns', s.columns!, {\n min: 1,\n max: 24,\n precision: 0,\n placeholder: String(context.columns),\n })\n switch (node.type) {\n case 'section':\n return [\n text('title', s.title!),\n field('textarea', 'description', s.description!, {\n props: { autosize: { minRows: 1, maxRows: 6 } },\n }),\n sw('bordered', s.bordered!),\n columns,\n span,\n ]\n case 'page':\n return [\n text('title', s.title!),\n field('textarea', 'description', s.description!, {\n props: { autosize: { minRows: 1, maxRows: 6 } },\n }),\n columns,\n ]\n case 'tabs':\n case 'steps':\n return [span]\n case 'list':\n return [\n name,\n text('label', s.label!),\n text('help', s.help!),\n span,\n number('min', s.minItems!, { min: 0, precision: 0 }, { span: 6 }),\n number('max', s.maxItems!, { min: 1, precision: 0 }, { span: 6 }),\n text('addText', s.addText!),\n sw('sortable', s.sortable!, { default: true }),\n sw('required', s.required!),\n columns,\n ]\n default: {\n const type = context.type\n if (type?.kind === 'display') return [span]\n const own = node as FormFieldNode\n const result: FormNode[] = [name, text('label', s.label!), text('help', s.help!), span]\n if (type && own.type !== 'upload')\n result.push({\n id: 'setting-default',\n type: own.type,\n name: 'default',\n label: s.default,\n props: own.props,\n } as FormFieldNode)\n result.push(sw('required', s.required!))\n return result\n }\n }\n}\n\n/** The settings of the document itself. */\nexport function documentSettings(messages: FormBuilderMessages): FormNode[] {\n const s = messages.settings as Record<string, string>\n const horizontal = \"values.layout == 'horizontal'\"\n return [\n segmented(messages, 'layout', ['vertical', 'horizontal', 'inline'], 'vertical'),\n segmented(messages, 'labelAlign', ['start', 'end'], 'start', { visibleWhen: horizontal }),\n number(\n 'labelWidth',\n s.labelWidth!,\n { min: 40, max: 400, step: 8, precision: 0 },\n { default: 96, visibleWhen: horizontal },\n ),\n segmented(messages, 'size', ['sm', 'md', 'lg'], 'md'),\n field('radio-group', 'requiredMark', s.requiredMark!, {\n default: true,\n props: { options: choices(messages, 'requiredMark', [true, 'optional', false]) },\n }),\n number('columns', s.columns!, { min: 1, max: 24, precision: 0 }, { default: 12 }),\n ]\n}\n\n/** A settings form: the nodes in a vertical, compact document. */\nexport function settingsDocument(nodes: FormNode[]): FormDocument {\n return { version: 1, size: 'sm', columns: 12, requiredMark: false, nodes }\n}\n"],"mappings":"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"}
@@ -0,0 +1,104 @@
1
+ import { defineFormField } from "../fields/define.js";
2
+ import { SPAN_TYPE } from "./settings.js";
3
+ import { useBuilderState } from "./context.js";
4
+ import { DouCheckbox, DouInputNumber } from "dou-ui";
5
+ import { computed, defineComponent, h, useId } from "vue";
6
+ // src/builder/span-field.ts
7
+ var breakpoints = [
8
+ "base",
9
+ "sm",
10
+ "md",
11
+ "lg",
12
+ "xl"
13
+ ];
14
+ /**
15
+ * A node's width in columns: one number, or one per form width when
16
+ * "by form width" is on. A width left empty takes the next narrower one.
17
+ */
18
+ var SpanInput = defineComponent({
19
+ name: "DouFormBuilderSpan",
20
+ props: {
21
+ modelValue: {
22
+ type: [Number, Object],
23
+ default: void 0
24
+ },
25
+ columns: {
26
+ type: Number,
27
+ default: 12
28
+ },
29
+ disabled: Boolean
30
+ },
31
+ emits: { "update:modelValue": (_value) => true },
32
+ setup(props, { emit }) {
33
+ const state = useBuilderState();
34
+ const labelId = `dou-form-builder-span-${useId()}`;
35
+ const responsive = computed(() => typeof props.modelValue === "object" && props.modelValue !== null);
36
+ const whole = computed(() => {
37
+ const value = props.modelValue;
38
+ if (typeof value === "number") return value;
39
+ if (value && typeof value === "object") return value.base ?? props.columns;
40
+ return props.columns;
41
+ });
42
+ const clamp = (value) => Math.min(Math.max(1, Math.round(value)), props.columns);
43
+ function setOne(value) {
44
+ emit("update:modelValue", value === null ? props.columns : clamp(value));
45
+ }
46
+ function setAt(key, value) {
47
+ const current = { ...props.modelValue };
48
+ if (value === null) delete current[key];
49
+ else current[key] = clamp(value);
50
+ emit("update:modelValue", current);
51
+ }
52
+ function toggle(on) {
53
+ emit("update:modelValue", on ? { base: whole.value } : whole.value);
54
+ }
55
+ return () => {
56
+ const messages = state.messages;
57
+ const choices = messages.choices.breakpoint ?? {};
58
+ const input = (value, set, label, placeholder) => h(DouInputNumber, {
59
+ modelValue: value ?? null,
60
+ min: 1,
61
+ max: props.columns,
62
+ precision: 0,
63
+ size: "sm",
64
+ controls: false,
65
+ disabled: props.disabled,
66
+ placeholder,
67
+ "aria-label": label,
68
+ "onUpdate:modelValue": set
69
+ });
70
+ const rows = responsive.value ? breakpoints.map((key, index) => {
71
+ const value = props.modelValue[key];
72
+ let inherited;
73
+ for (let at = index - 1; at >= 0 && inherited === void 0; at--) inherited = props.modelValue[breakpoints[at]];
74
+ return h("label", {
75
+ key,
76
+ class: "dou-form-builder__span-row"
77
+ }, [h("span", { class: "dou-form-builder__span-label" }, choices[key] ?? key), input(value, (next) => setAt(key, next), choices[key] ?? key, String(inherited ?? props.columns))]);
78
+ }) : [h("div", { class: "dou-form-builder__span-row" }, [input(whole.value, setOne, messages.settings.span ?? "span"), h("span", { class: "dou-form-builder__span-label" }, `/ ${props.columns}`)])];
79
+ return h("div", {
80
+ class: "dou-form-builder__span",
81
+ role: "group",
82
+ "aria-labelledby": labelId
83
+ }, [h("div", { class: "dou-form-builder__span-head" }, [h("div", {
84
+ id: labelId,
85
+ class: "dou-form-item__label"
86
+ }, h("span", { class: "dou-form-item__label-text" }, messages.settings.span)), h(DouCheckbox, {
87
+ modelValue: responsive.value,
88
+ disabled: props.disabled,
89
+ size: "sm",
90
+ class: "dou-form-builder__span-toggle",
91
+ "onUpdate:modelValue": (on) => toggle(on === true)
92
+ }, () => messages.settings.spanResponsive)]), ...rows]);
93
+ };
94
+ }
95
+ });
96
+ /** The width setting of the inspector, a field type of the builder's own. */
97
+ var spanField = defineFormField({
98
+ type: SPAN_TYPE,
99
+ component: SpanInput,
100
+ empty: (props) => props.columns ?? 12
101
+ });
102
+ export { spanField };
103
+
104
+ //# sourceMappingURL=span-field.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"span-field.js","names":[],"sources":["../../src/builder/span-field.ts"],"sourcesContent":["import { computed, defineComponent, h, useId } from 'vue'\nimport type { PropType } from 'vue'\nimport { DouCheckbox, DouInputNumber } from 'dou-ui'\nimport type { FormResponsive } from '../core/types'\nimport { defineFormField } from '../fields/define'\nimport { useBuilderState } from './context'\nimport { SPAN_TYPE } from './settings'\n\nconst breakpoints = ['base', 'sm', 'md', 'lg', 'xl'] as const\ntype Breakpoint = (typeof breakpoints)[number]\ntype Span = FormResponsive<number>\n\n/**\n * A node's width in columns: one number, or one per form width when\n * \"by form width\" is on. A width left empty takes the next narrower one.\n */\nconst SpanInput = defineComponent({\n name: 'DouFormBuilderSpan',\n props: {\n modelValue: { type: [Number, Object] as PropType<Span | null>, default: undefined },\n columns: { type: Number, default: 12 },\n disabled: Boolean,\n },\n emits: { 'update:modelValue': (_value: Span) => true },\n setup(props, { emit }) {\n const state = useBuilderState()\n const labelId = `dou-form-builder-span-${useId()}`\n const responsive = computed(\n () => typeof props.modelValue === 'object' && props.modelValue !== null,\n )\n const whole = computed(() => {\n const value = props.modelValue\n if (typeof value === 'number') return value\n if (value && typeof value === 'object') return value.base ?? props.columns\n return props.columns\n })\n const clamp = (value: number) => Math.min(Math.max(1, Math.round(value)), props.columns)\n\n function setOne(value: number | null) {\n emit('update:modelValue', value === null ? props.columns : clamp(value))\n }\n function setAt(key: Breakpoint, value: number | null) {\n const current = { ...(props.modelValue as Partial<Record<Breakpoint, number>>) }\n if (value === null) delete current[key]\n else current[key] = clamp(value)\n emit('update:modelValue', current)\n }\n function toggle(on: boolean) {\n emit('update:modelValue', on ? { base: whole.value } : whole.value)\n }\n\n return () => {\n const messages = state.messages\n const choices = messages.choices.breakpoint ?? {}\n const input = (\n value: number | null | undefined,\n set: (value: number | null) => void,\n label: string,\n placeholder?: string,\n ) =>\n h(DouInputNumber, {\n modelValue: value ?? null,\n min: 1,\n max: props.columns,\n precision: 0,\n size: 'sm',\n controls: false,\n disabled: props.disabled,\n placeholder,\n 'aria-label': label,\n 'onUpdate:modelValue': set,\n })\n const rows = responsive.value\n ? breakpoints.map((key, index) => {\n const value = (props.modelValue as Partial<Record<Breakpoint, number>>)[key]\n // An empty width shows the one it takes over from.\n let inherited: number | undefined\n for (let at = index - 1; at >= 0 && inherited === undefined; at--)\n inherited = (props.modelValue as Partial<Record<Breakpoint, number>>)[\n breakpoints[at]!\n ]\n return h('label', { key, class: 'dou-form-builder__span-row' }, [\n h('span', { class: 'dou-form-builder__span-label' }, choices[key] ?? key),\n input(\n value,\n (next) => setAt(key, next),\n choices[key] ?? key,\n String(inherited ?? props.columns),\n ),\n ])\n })\n : [\n h('div', { class: 'dou-form-builder__span-row' }, [\n input(whole.value, setOne, messages.settings.span ?? 'span'),\n h('span', { class: 'dou-form-builder__span-label' }, `/ ${props.columns}`),\n ]),\n ]\n return h(\n 'div',\n { class: 'dou-form-builder__span', role: 'group', 'aria-labelledby': labelId },\n [\n h('div', { class: 'dou-form-builder__span-head' }, [\n h(\n 'div',\n { id: labelId, class: 'dou-form-item__label' },\n h('span', { class: 'dou-form-item__label-text' }, messages.settings.span),\n ),\n h(\n DouCheckbox,\n {\n modelValue: responsive.value,\n disabled: props.disabled,\n size: 'sm',\n class: 'dou-form-builder__span-toggle',\n 'onUpdate:modelValue': (on: unknown) => toggle(on === true),\n },\n () => messages.settings.spanResponsive,\n ),\n ]),\n ...rows,\n ],\n )\n }\n },\n})\n\n/** The width setting of the inspector, a field type of the builder's own. */\nexport const spanField = defineFormField({\n type: SPAN_TYPE,\n component: SpanInput,\n empty: (props: { columns?: number }) => props.columns ?? 12,\n})\n"],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import expression_input_vue_vue_type_script_setup_true_lang_default from "./expression-input.vue_vue_type_script_setup_true_lang.js";
2
+ // src/code/expression-input.vue
3
+ var expression_input_default = expression_input_vue_vue_type_script_setup_true_lang_default;
4
+ export { expression_input_default as default };
5
+
6
+ //# sourceMappingURL=expression-input.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expression-input.js","names":["_sfc_main"],"sources":["../../src/code/expression-input.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { DouCodeInput } from '@dou-ui/code'\nimport { computed, useId } from 'vue'\nimport { builtinFunctions, checkExpression } from '../core/expression'\nimport { formatMessage } from '../locale'\nimport { useBuilderState } from '../builder/context'\nimport { expressionCodeExtension } from './extension'\nimport type { ExpressionName } from './extension'\nimport { formExpression } from './language'\n\n/**\n * The builder's expression box as a code input: colored, with completions\n * of field paths and functions, parameter hints, and problems underlined\n * as well as written under it.\n */\ndefineOptions({ name: 'DouFormBuilderCodeExpression', inheritAttrs: false })\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: string | null\n names?: ExpressionName[]\n itemNames?: ExpressionName[]\n readsValue?: boolean\n placeholder?: string\n disabled?: boolean\n /** Shown and selectable, but not changed; also when the form around is read-only. */\n readonly?: boolean\n }>(),\n { modelValue: '', names: () => [], itemNames: undefined, placeholder: undefined },\n)\nconst emit = defineEmits<{ 'update:modelValue': [value: string] }>()\n\nconst state = useBuilderState()\nconst errorId = `dou-form-builder-expression-${useId()}`\nconst words = computed(() => state.messages.expression)\n\nconst problemMessage = (problem: { code: string; message: string; text: string }) =>\n formatMessage(words.value.problems[problem.code] ?? problem.message, { text: problem.text })\n\nconst extensions = [\n expressionCodeExtension({\n names: () => props.names,\n itemNames: () => props.itemNames,\n readsValue: () => !!props.readsValue,\n functions: () => state.functionNames.value,\n functionInfo: () => words.value.functions,\n labels: () => words.value,\n problemMessage,\n }),\n]\n\nconst text = computed(() => props.modelValue ?? '')\n\n// The first problem in words too, for screen readers and at a glance.\nconst problem = computed(() => {\n if (!text.value.trim()) return undefined\n const found = checkExpression(text.value, {\n fields: props.names.map((name) => name.path),\n itemFields: props.itemNames ? props.itemNames.map((name) => name.path) : [],\n functions: [...new Set([...Object.keys(builtinFunctions), ...state.functionNames.value])],\n })[0]\n return found && problemMessage(found)\n})\n</script>\n\n<template>\n <div class=\"dou-form-builder__expression\">\n <DouCodeInput\n v-bind=\"$attrs\"\n :model-value=\"text\"\n :language=\"formExpression\"\n :extensions=\"extensions\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n :readonly=\"readonly\"\n :invalid=\"!!problem\"\n :aria-describedby=\"problem ? errorId : undefined\"\n multiline\n :autosize=\"{ maxRows: 4 }\"\n size=\"sm\"\n class=\"dou-form-builder__expression-input\"\n @update:model-value=\"emit('update:modelValue', $event)\"\n />\n <div v-if=\"problem\" :id=\"errorId\" class=\"dou-form-builder__expression-error\">\n {{ problem }}\n </div>\n </div>\n</template>\n"],"mappings":""}