@stubber/form-fields 2.2.6 → 3.0.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 (126) hide show
  1. package/README.md +63 -25
  2. package/dist/form-fields/Autocomplete.svelte +261 -0
  3. package/dist/form-fields/Autocomplete.svelte.d.ts +43 -0
  4. package/dist/form-fields/CollapsibleSection.svelte +127 -0
  5. package/dist/form-fields/CollapsibleSection.svelte.d.ts +26 -0
  6. package/dist/form-fields/FieldLabel.svelte +18 -3
  7. package/dist/form-fields/FieldLabel.svelte.d.ts +1 -0
  8. package/dist/form-fields/FieldMessage.svelte +20 -9
  9. package/dist/form-fields/Form.svelte +19 -2
  10. package/dist/form-fields/Form.svelte.d.ts +2 -0
  11. package/dist/form-fields/UploadStatus.svelte +76 -0
  12. package/dist/form-fields/UploadStatus.svelte.d.ts +18 -0
  13. package/dist/form-fields/fields/_field-builder-reorder.svelte +35 -0
  14. package/dist/form-fields/fields/_field-builder-reorder.svelte.d.ts +22 -0
  15. package/dist/form-fields/{sub → fields}/array-builder-field.svelte +104 -38
  16. package/dist/form-fields/fields/checkbox-autocomplete.svelte +153 -0
  17. package/dist/form-fields/fields/checkbox-field.svelte +69 -0
  18. package/dist/form-fields/{sub → fields}/contact-selector-field.svelte +9 -6
  19. package/dist/form-fields/{sub → fields}/currency-field.svelte +108 -70
  20. package/dist/form-fields/fields/data-indication-field.svelte +39 -0
  21. package/dist/form-fields/fields/date-field.svelte +31 -0
  22. package/dist/form-fields/fields/date-time-field.svelte +31 -0
  23. package/dist/form-fields/{sub → fields}/email-field.svelte +25 -11
  24. package/dist/form-fields/fields/field-builder-field.svelte +568 -0
  25. package/dist/form-fields/fields/file-field.svelte +284 -0
  26. package/dist/form-fields/{sub → fields}/file-field.svelte.d.ts +2 -0
  27. package/dist/form-fields/fields/grid-field.svelte +152 -0
  28. package/dist/form-fields/{sub → fields}/heading-field.svelte +7 -4
  29. package/dist/form-fields/{sub → fields}/html-field.svelte +6 -4
  30. package/dist/form-fields/{sub → fields}/map-field.svelte +121 -78
  31. package/dist/form-fields/{sub → fields}/multi-checkbox-field.svelte +35 -20
  32. package/dist/form-fields/fields/multistep-field.svelte +135 -0
  33. package/dist/form-fields/fields/note-field.svelte +35 -0
  34. package/dist/form-fields/{sub → fields}/number-field.svelte +29 -14
  35. package/dist/form-fields/fields/object-builder-field.svelte +176 -0
  36. package/dist/form-fields/fields/qr-code-scanner-field.svelte +203 -0
  37. package/dist/form-fields/fields/radio-field.svelte +82 -0
  38. package/dist/form-fields/{sub → fields}/radio-field.svelte.d.ts +1 -1
  39. package/dist/form-fields/fields/screenrecorder-field.svelte +255 -0
  40. package/dist/form-fields/{sub → fields}/screenshot-field.svelte +101 -40
  41. package/dist/form-fields/{sub → fields}/scroll-and-read-display-field.svelte +43 -27
  42. package/dist/form-fields/fields/section-field.svelte +73 -0
  43. package/dist/form-fields/fields/select-field.svelte +104 -0
  44. package/dist/form-fields/{sub → fields}/signature-field.svelte +78 -22
  45. package/dist/form-fields/fields/slider-field.svelte +53 -0
  46. package/dist/form-fields/{sub → fields}/smart-text-field.svelte +62 -82
  47. package/dist/form-fields/fields/telephone-field.svelte +108 -0
  48. package/dist/form-fields/{sub → fields}/telephone-field.svelte.d.ts +1 -1
  49. package/dist/form-fields/{sub → fields}/text-field.svelte +28 -11
  50. package/dist/form-fields/{sub → fields}/voicenote-field.svelte +117 -46
  51. package/dist/form-fields/file_creation_options.d.ts +1 -1
  52. package/dist/form-fields/form-field.svelte +8 -1
  53. package/dist/form-fields/icons/ChevronDownIcon.svelte +21 -0
  54. package/dist/form-fields/icons/ChevronDownIcon.svelte.d.ts +20 -0
  55. package/dist/form-fields/icons/QrCodeScannerIcon.svelte +25 -0
  56. package/dist/form-fields/icons/QrCodeScannerIcon.svelte.d.ts +19 -0
  57. package/dist/form-fields/icons/ScreenRecordingIcon.svelte +21 -0
  58. package/dist/form-fields/icons/ScreenRecordingIcon.svelte.d.ts +19 -0
  59. package/dist/form-fields/icons/ScreenshotIcon.svelte +22 -0
  60. package/dist/form-fields/icons/ScreenshotIcon.svelte.d.ts +19 -0
  61. package/dist/form-fields/index.d.ts +5 -1
  62. package/dist/form-fields/index.js +3 -1
  63. package/dist/form-fields/interfaces.d.ts +63 -63
  64. package/dist/form-fields/interfaces.js +42 -39
  65. package/dist/form-fields/intl-tel-input.css +1 -0
  66. package/dist/form-fields/styles.d.ts +17 -0
  67. package/dist/form-fields/styles.js +4 -0
  68. package/package.json +2 -4
  69. package/dist/form-fields/sub/checkbox-autocomplete.svelte +0 -56
  70. package/dist/form-fields/sub/checkbox-field.svelte +0 -42
  71. package/dist/form-fields/sub/data-indication-field.svelte +0 -19
  72. package/dist/form-fields/sub/date-field.svelte +0 -31
  73. package/dist/form-fields/sub/date-time-field.svelte +0 -31
  74. package/dist/form-fields/sub/field-builder-field.svelte +0 -657
  75. package/dist/form-fields/sub/file-field.svelte +0 -159
  76. package/dist/form-fields/sub/grid-field.svelte +0 -69
  77. package/dist/form-fields/sub/multistep-field.svelte +0 -70
  78. package/dist/form-fields/sub/note-field.svelte +0 -18
  79. package/dist/form-fields/sub/object-builder-field.svelte +0 -134
  80. package/dist/form-fields/sub/qr-code-scanner-field.svelte +0 -84
  81. package/dist/form-fields/sub/radio-field.svelte +0 -69
  82. package/dist/form-fields/sub/screenrecorder-field.svelte +0 -178
  83. package/dist/form-fields/sub/section-field.svelte +0 -50
  84. package/dist/form-fields/sub/select-field.svelte +0 -150
  85. package/dist/form-fields/sub/slider-field.svelte +0 -28
  86. package/dist/form-fields/sub/telephone-field.svelte +0 -64
  87. /package/dist/form-fields/{sub → fields}/array-builder-field.svelte.d.ts +0 -0
  88. /package/dist/form-fields/{sub → fields}/checkbox-autocomplete.svelte.d.ts +0 -0
  89. /package/dist/form-fields/{sub → fields}/checkbox-field.svelte.d.ts +0 -0
  90. /package/dist/form-fields/{sub → fields}/code-field.svelte +0 -0
  91. /package/dist/form-fields/{sub → fields}/code-field.svelte.d.ts +0 -0
  92. /package/dist/form-fields/{sub → fields}/contact-selector-field.svelte.d.ts +0 -0
  93. /package/dist/form-fields/{sub → fields}/currency-field.svelte.d.ts +0 -0
  94. /package/dist/form-fields/{sub → fields}/data-indication-field.svelte.d.ts +0 -0
  95. /package/dist/form-fields/{sub → fields}/date-field.svelte.d.ts +0 -0
  96. /package/dist/form-fields/{sub → fields}/date-time-field.svelte.d.ts +0 -0
  97. /package/dist/form-fields/{sub → fields}/email-field.svelte.d.ts +0 -0
  98. /package/dist/form-fields/{sub → fields}/field-builder-field.svelte.d.ts +0 -0
  99. /package/dist/form-fields/{sub → fields}/grid-field.svelte.d.ts +0 -0
  100. /package/dist/form-fields/{sub → fields}/heading-field.svelte.d.ts +0 -0
  101. /package/dist/form-fields/{sub → fields}/hidden-field.svelte +0 -0
  102. /package/dist/form-fields/{sub → fields}/hidden-field.svelte.d.ts +0 -0
  103. /package/dist/form-fields/{sub → fields}/hidden-location-field.svelte +0 -0
  104. /package/dist/form-fields/{sub → fields}/hidden-location-field.svelte.d.ts +0 -0
  105. /package/dist/form-fields/{sub → fields}/html-field.svelte.d.ts +0 -0
  106. /package/dist/form-fields/{sub → fields}/jsoneditor-field.svelte +0 -0
  107. /package/dist/form-fields/{sub → fields}/jsoneditor-field.svelte.d.ts +0 -0
  108. /package/dist/form-fields/{sub → fields}/map-field.svelte.d.ts +0 -0
  109. /package/dist/form-fields/{sub → fields}/multi-checkbox-field.svelte.d.ts +0 -0
  110. /package/dist/form-fields/{sub → fields}/multistep-field.svelte.d.ts +0 -0
  111. /package/dist/form-fields/{sub → fields}/note-field.svelte.d.ts +0 -0
  112. /package/dist/form-fields/{sub → fields}/number-field.svelte.d.ts +0 -0
  113. /package/dist/form-fields/{sub → fields}/object-builder-field.svelte.d.ts +0 -0
  114. /package/dist/form-fields/{sub → fields}/qr-code-scanner-field.svelte.d.ts +0 -0
  115. /package/dist/form-fields/{sub → fields}/screenrecorder-field.svelte.d.ts +0 -0
  116. /package/dist/form-fields/{sub → fields}/screenshot-field.svelte.d.ts +0 -0
  117. /package/dist/form-fields/{sub → fields}/scroll-and-read-display-field.svelte.d.ts +0 -0
  118. /package/dist/form-fields/{sub → fields}/section-field.svelte.d.ts +0 -0
  119. /package/dist/form-fields/{sub → fields}/select-field.svelte.d.ts +0 -0
  120. /package/dist/form-fields/{sub → fields}/selectresource-field.svelte +0 -0
  121. /package/dist/form-fields/{sub → fields}/selectresource-field.svelte.d.ts +0 -0
  122. /package/dist/form-fields/{sub → fields}/signature-field.svelte.d.ts +0 -0
  123. /package/dist/form-fields/{sub → fields}/slider-field.svelte.d.ts +0 -0
  124. /package/dist/form-fields/{sub → fields}/smart-text-field.svelte.d.ts +0 -0
  125. /package/dist/form-fields/{sub → fields}/text-field.svelte.d.ts +0 -0
  126. /package/dist/form-fields/{sub → fields}/voicenote-field.svelte.d.ts +0 -0
@@ -0,0 +1,568 @@
1
+ <script context="module">import { writable } from "svelte/store";
2
+ import {
3
+ fields,
4
+ validation_types
5
+ } from "../interfaces";
6
+ import { text_field_param_spec } from "./text-field.svelte";
7
+ const field_params_spec_lookup = {
8
+ text: text_field_param_spec,
9
+ checkbox: checkbox_field_param_spec,
10
+ smart_text: smart_text_field_param_spec,
11
+ file: file_field_param_spec,
12
+ heading: heading_field_param_spec,
13
+ hidden: hidden_field_param_spec,
14
+ html: html_field_param_spec,
15
+ map: map_field_param_spec,
16
+ checkbox_autocomplete: merge({}, checkbox_field_param_spec, smart_text_field_param_spec),
17
+ code: code_field_param_spec,
18
+ currency: currency_field_param_spec,
19
+ dataindication: null,
20
+ telephone: null,
21
+ email: null,
22
+ arraybuilder: array_builder_field_param_spec,
23
+ contactselector: contact_selector_field_param_spec,
24
+ date: null,
25
+ datetime: null,
26
+ fieldbuilder: null,
27
+ grid: grid_field_param_spec,
28
+ hiddenlocation: null,
29
+ jsoneditor: jsoneditor_field_param_spec,
30
+ multicheckbox: multi_checkbox_field_param_spec,
31
+ multistep: null,
32
+ // todo: fields for multistep
33
+ note: null,
34
+ number: number_field_param_spec,
35
+ objectbuilder: object_builder_field_param_spec,
36
+ qrcodescanner: null,
37
+ radio: radio_field_param_spec,
38
+ screenrecorder: basic_files_field_param_spec,
39
+ screenshot: basic_files_field_param_spec,
40
+ voicenote: basic_files_field_param_spec,
41
+ signature: signature_field_param_spec,
42
+ scrollandreaddisplay: scroll_and_read_display_field_param_spec,
43
+ section: null,
44
+ // todo: fields for section
45
+ select: select_field_param_spec,
46
+ slider: number_field_param_spec,
47
+ selectresource: select_resource_field_param_spec,
48
+ unknown: null
49
+ };
50
+ </script>
51
+
52
+ <script>import Form from "../Form.svelte";
53
+ import { cloneDeep, isEmpty, isEqual, isUndefined, merge, omitBy } from "lodash-es";
54
+ import { getContext } from "svelte";
55
+ import Autocomplete, {} from "../Autocomplete.svelte";
56
+ import FieldLabel from "../FieldLabel.svelte";
57
+ import FieldMessage from "../FieldMessage.svelte";
58
+ import { checkbox_field_param_spec } from "./checkbox-field.svelte";
59
+ import { file_field_param_spec } from "./file-field.svelte";
60
+ import { heading_field_param_spec } from "./heading-field.svelte";
61
+ import { hidden_field_param_spec } from "./hidden-field.svelte";
62
+ import { html_field_param_spec } from "./html-field.svelte";
63
+ import { map_field_param_spec } from "./map-field.svelte";
64
+ import { smart_text_field_param_spec } from "./smart-text-field.svelte";
65
+ import { code_field_param_spec } from "./code-field.svelte";
66
+ import { currency_field_param_spec } from "./currency-field.svelte";
67
+ import { array_builder_field_param_spec } from "./array-builder-field.svelte";
68
+ import { contact_selector_field_param_spec } from "./contact-selector-field.svelte";
69
+ import { grid_field_param_spec } from "./grid-field.svelte";
70
+ import { jsoneditor_field_param_spec } from "./jsoneditor-field.svelte";
71
+ import { multi_checkbox_field_param_spec } from "./multi-checkbox-field.svelte";
72
+ import { number_field_param_spec } from "./number-field.svelte";
73
+ import { object_builder_field_param_spec } from "./object-builder-field.svelte";
74
+ import { radio_field_param_spec } from "./radio-field.svelte";
75
+ import { scroll_and_read_display_field_param_spec } from "./scroll-and-read-display-field.svelte";
76
+ import { select_field_param_spec } from "./select-field.svelte";
77
+ import { select_resource_field_param_spec } from "./selectresource-field.svelte";
78
+ import { handle_editor_change_setter, handle_store_change } from "../../utils/json-editor-sync";
79
+ import { basic_files_field_param_spec } from "../file_creation_options";
80
+ import { signature_field_param_spec } from "./signature-field.svelte";
81
+ import { STYLES_CONTEXT, classNames } from "../styles";
82
+ import CollapsibleSection from "../CollapsibleSection.svelte";
83
+ import FieldBuilderReorder from "./_field-builder-reorder.svelte";
84
+ export let fieldStore;
85
+ const styles = getContext(STYLES_CONTEXT);
86
+ let value = cloneDeep($fieldStore.value) || {
87
+ details: {},
88
+ initvalue: {}
89
+ };
90
+ if (!value.details) {
91
+ value.details = {};
92
+ }
93
+ if (!value.initvalue) {
94
+ value.initvalue = {};
95
+ }
96
+ let default_initvalue_editor;
97
+ let override_initvalue_editor;
98
+ $: update_fieldStore(value);
99
+ function update_fieldStore(new_value) {
100
+ const cleaned_value = omitBy(
101
+ cloneDeep(new_value),
102
+ (v) => isUndefined(v) || typeof v === "object" && isEmpty(v)
103
+ );
104
+ if (!isEqual($fieldStore, cleaned_value)) {
105
+ $fieldStore.value = cleaned_value;
106
+ }
107
+ }
108
+ $: update_value($fieldStore.value);
109
+ function update_value(new_value) {
110
+ if (!isEqual(value, new_value)) {
111
+ value = {
112
+ details: {},
113
+ initvalue: {},
114
+ ...cloneDeep(new_value)
115
+ };
116
+ update_params_from_value(value.params);
117
+ update_subfields_from_value(value.fields);
118
+ handle_store_change(value.initvalue.default, default_initvalue_editor);
119
+ handle_store_change(value.initvalue.override, override_initvalue_editor);
120
+ }
121
+ }
122
+ const field_types = Object.keys(fields).map((key) => ({
123
+ label: key,
124
+ value: key
125
+ }));
126
+ function add_condition() {
127
+ if (!value.conditions) {
128
+ value.conditions = [];
129
+ }
130
+ value.conditions = [...value.conditions, ""];
131
+ }
132
+ function move_condition_up(index) {
133
+ if (index > 0 && value.conditions) {
134
+ const temp = value.conditions[index];
135
+ value.conditions[index] = value.conditions[index - 1];
136
+ value.conditions[index - 1] = temp;
137
+ value.conditions = [...value.conditions];
138
+ }
139
+ }
140
+ function move_condition_down(index) {
141
+ if (value.conditions && index < value.conditions.length - 1) {
142
+ const temp = value.conditions[index];
143
+ value.conditions[index] = value.conditions[index + 1];
144
+ value.conditions[index + 1] = temp;
145
+ value.conditions = [...value.conditions];
146
+ }
147
+ }
148
+ function remove_condition(index) {
149
+ if (value.conditions) {
150
+ value.conditions = value.conditions.filter((_, i) => i !== index);
151
+ }
152
+ }
153
+ function add_validation() {
154
+ if (!value.validations) {
155
+ value.validations = [];
156
+ }
157
+ value.validations = [...value.validations, { validationtype: "required", invalid_message: "" }];
158
+ }
159
+ function move_validation_up(index) {
160
+ if (index > 0 && value.validations) {
161
+ const temp = value.validations[index];
162
+ value.validations[index] = value.validations[index - 1];
163
+ value.validations[index - 1] = temp;
164
+ value.validations = [...value.validations];
165
+ }
166
+ }
167
+ function move_validation_down(index) {
168
+ if (value.validations && index < value.validations.length - 1) {
169
+ const temp = value.validations[index];
170
+ value.validations[index] = value.validations[index + 1];
171
+ value.validations[index + 1] = temp;
172
+ value.validations = [...value.validations];
173
+ }
174
+ }
175
+ function remove_validation(index) {
176
+ if (value.validations) {
177
+ value.validations = value.validations.filter((_, i) => i !== index);
178
+ }
179
+ }
180
+ function handle_validation_selected(validationtype, index) {
181
+ if (value.validations) {
182
+ let current_validation;
183
+ let prev_validation = value.validations[index];
184
+ if (validationtype === "required") {
185
+ current_validation = {
186
+ validationtype: "required",
187
+ invalid_message: prev_validation.invalid_message
188
+ };
189
+ } else if (validationtype === "regex") {
190
+ current_validation = {
191
+ validationtype: "regex",
192
+ invalid_message: prev_validation.invalid_message,
193
+ params: { regex: prev_validation.params?.regex ?? "" }
194
+ };
195
+ } else {
196
+ current_validation = {
197
+ validationtype: "jsonata",
198
+ invalid_message: prev_validation.invalid_message,
199
+ params: { jsonata: prev_validation.params?.jsonata ?? "" }
200
+ };
201
+ }
202
+ value.validations[index] = current_validation;
203
+ }
204
+ }
205
+ function handle_validation_change(event, index) {
206
+ handle_validation_selected(
207
+ event.currentTarget.value,
208
+ index
209
+ );
210
+ }
211
+ const params_store = writable({});
212
+ $: update_params($params_store);
213
+ function update_params(new_params) {
214
+ const cloned_new_params = cloneDeep(new_params);
215
+ if (!isEqual(value.params, cloned_new_params) && !isEmpty(cloned_new_params)) {
216
+ value.params = cloned_new_params;
217
+ update_fieldStore(value);
218
+ }
219
+ }
220
+ function update_params_from_value(new_value) {
221
+ if (!isEqual(new_value, $params_store)) {
222
+ params_store.set(cloneDeep(new_value) || {});
223
+ }
224
+ }
225
+ function select_field_type(newValue) {
226
+ value.fieldtype = newValue;
227
+ field_param_spec = cloneDeep(field_params_spec_lookup[value.fieldtype ?? "unknown"]);
228
+ }
229
+ function handle_fieldtype_select(event) {
230
+ select_field_type(event.detail.value);
231
+ }
232
+ let field_param_spec = cloneDeep(field_params_spec_lookup[value.fieldtype ?? "unknown"]);
233
+ const subfields_store = writable({});
234
+ $: update_subfields($subfields_store.fields);
235
+ function update_subfields(new_subfields) {
236
+ const cloned_new_subfields = cloneDeep(new_subfields);
237
+ if (!isEqual(value.fields, cloned_new_subfields) && !isEmpty(cloned_new_subfields)) {
238
+ value.fields = cloned_new_subfields;
239
+ update_fieldStore(value);
240
+ }
241
+ }
242
+ function update_subfields_from_value(new_value) {
243
+ if (!isEqual(new_value, $subfields_store)) {
244
+ subfields_store.set({ fields: cloneDeep(new_value) || {} });
245
+ }
246
+ }
247
+ </script>
248
+
249
+ <div class="field-builder-field">
250
+ <FieldLabel {fieldStore} />
251
+ <!-- fieldtype picker -->
252
+ <Autocomplete
253
+ id={$fieldStore.id}
254
+ options={field_types}
255
+ value={value.fieldtype}
256
+ placeholder="Select a fieldtype"
257
+ emptyMessage="No fieldtype found."
258
+ invalid={$fieldStore.validation_result?.type === "error"}
259
+ ariaDescribedby="message-{$fieldStore.id}"
260
+ on:select={handle_fieldtype_select}
261
+ />
262
+ <!-- basic props -->
263
+ <CollapsibleSection title="Basic Info" open>
264
+ <div class="field-builder-property">
265
+ <label class={classNames("field-builder-label", $styles.label)} for="{$fieldStore.id}-title"
266
+ >Title</label
267
+ >
268
+ <input
269
+ class={classNames("field-builder-input", $styles.input)}
270
+ id="{$fieldStore.id}-title"
271
+ placeholder="Optional custom title for the field"
272
+ bind:value={value.title}
273
+ />
274
+ </div>
275
+ <div class="field-builder-checkbox">
276
+ <input
277
+ id="{$fieldStore.id}-without-value-details"
278
+ class={$styles.choice}
279
+ type="checkbox"
280
+ bind:checked={value.without_value_details}
281
+ />
282
+ <label
283
+ class={classNames("field-builder-label", $styles.label)}
284
+ for="{$fieldStore.id}-without-value-details">Without Value Details</label
285
+ >
286
+ </div>
287
+ <div class="field-builder-checkbox">
288
+ <input
289
+ id="{$fieldStore.id}-hide-label"
290
+ class={$styles.choice}
291
+ type="checkbox"
292
+ bind:checked={value.hide_label}
293
+ />
294
+ <label
295
+ class={classNames("field-builder-label", $styles.label)}
296
+ for="{$fieldStore.id}-hide-label">Hide Label</label
297
+ >
298
+ </div>
299
+ <div class="field-builder-property">
300
+ <label class={classNames("field-builder-label", $styles.label)} for="{$fieldStore.id}-help"
301
+ >Help</label
302
+ >
303
+ <textarea
304
+ class={classNames("field-builder-input", "field-builder-textarea", $styles.input)}
305
+ id="{$fieldStore.id}-help"
306
+ placeholder="Optional help text for the field"
307
+ bind:value={value.help}
308
+ />
309
+ </div>
310
+ </CollapsibleSection>
311
+ <!-- subfields -->
312
+ {#if value.fieldtype === "section" || value.fieldtype === "multistep"}
313
+ <CollapsibleSection title="Fields" open>
314
+ <Form
315
+ form={subfields_store}
316
+ initial_form={{
317
+ spec: {
318
+ fields: {
319
+ fields: {
320
+ hide_label: true,
321
+ fieldtype: "objectbuilder",
322
+ help: "Fields within this section/multistep",
323
+ params: {
324
+ value_field_spec: {
325
+ fieldtype: "fieldbuilder",
326
+ initvalue: {
327
+ has_default: true,
328
+ default: {
329
+ fieldtype: "text",
330
+ },
331
+ },
332
+ },
333
+ },
334
+ },
335
+ },
336
+ },
337
+ }}
338
+ />
339
+ </CollapsibleSection>
340
+ {/if}
341
+
342
+ <!-- params -->
343
+ <CollapsibleSection title="Params">
344
+ {#if field_param_spec}
345
+ {#key value.fieldtype}
346
+ <Form
347
+ initial_form={field_param_spec}
348
+ form={params_store}
349
+ attachments={$fieldStore.attachmentsStore}
350
+ />
351
+ {/key}
352
+ {:else}
353
+ <span class="field-builder-status">No params available for this fieldtype.</span>
354
+ {/if}
355
+ </CollapsibleSection>
356
+ <!-- details -->
357
+ <CollapsibleSection title="Details">
358
+ <div class="field-builder-property">
359
+ <label class={classNames("field-builder-label", $styles.label)} for="{$fieldStore.id}-keyname"
360
+ >Keyname</label
361
+ >
362
+ <input
363
+ class={classNames("field-builder-input", $styles.input)}
364
+ id="{$fieldStore.id}-keyname"
365
+ placeholder="Custom key underwhich to store the value"
366
+ bind:value={value.details.keyname}
367
+ />
368
+ </div>
369
+ <div class="field-builder-property">
370
+ <label
371
+ class={classNames("field-builder-label", $styles.label)}
372
+ for="{$fieldStore.id}-datapath">Data Path</label
373
+ >
374
+ <input
375
+ class={classNames("field-builder-input", $styles.input)}
376
+ id="{$fieldStore.id}-datapath"
377
+ placeholder="Optional custom data path for the field"
378
+ bind:value={value.details.datapath}
379
+ />
380
+ </div>
381
+ </CollapsibleSection>
382
+ <!-- initial value -->
383
+ <CollapsibleSection title="Initial Value">
384
+ <div class="field-builder-property">
385
+ <div class="field-builder-checkbox">
386
+ <input
387
+ id="{$fieldStore.id}-has-default"
388
+ class={$styles.choice}
389
+ type="checkbox"
390
+ bind:checked={value.initvalue.has_default}
391
+ />
392
+ <label
393
+ class={classNames("field-builder-label", $styles.label)}
394
+ for="{$fieldStore.id}-has-default">Has Default</label
395
+ >
396
+ </div>
397
+ {#await import("svelte-jsoneditor") then JSONEditorModule}
398
+ <JSONEditorModule.JSONEditor
399
+ bind:this={default_initvalue_editor}
400
+ onChange={(content) =>
401
+ handle_editor_change_setter(content, (new_val) => (value.initvalue.default = new_val))}
402
+ />
403
+ {/await}
404
+ </div>
405
+ <div class="field-builder-property">
406
+ <div class="field-builder-checkbox">
407
+ <input
408
+ id="{$fieldStore.id}-has-override"
409
+ class={$styles.choice}
410
+ type="checkbox"
411
+ bind:checked={value.initvalue.has_override}
412
+ />
413
+ <label
414
+ class={classNames("field-builder-label", $styles.label)}
415
+ for="{$fieldStore.id}-has-override">Has Override</label
416
+ >
417
+ </div>
418
+ {#await import("svelte-jsoneditor") then JSONEditorModule}
419
+ <JSONEditorModule.JSONEditor
420
+ bind:this={override_initvalue_editor}
421
+ onChange={(content) =>
422
+ handle_editor_change_setter(content, (new_val) => (value.initvalue.override = new_val))}
423
+ />
424
+ {/await}
425
+ </div>
426
+ </CollapsibleSection>
427
+ <!-- conditions -->
428
+ <CollapsibleSection title="Conditions">
429
+ <button
430
+ type="button"
431
+ class={classNames("field-builder-add", $styles.button)}
432
+ data-variant="primary"
433
+ on:click={add_condition}>Add condition</button
434
+ >
435
+
436
+ {#if value.conditions && value.conditions.length > 0}
437
+ {#each value.conditions as condition, index}
438
+ <div class="field-builder-item">
439
+ <!-- up and down sort buttons -->
440
+ <FieldBuilderReorder
441
+ item="condition"
442
+ first={index === 0}
443
+ last={index === value.conditions.length - 1}
444
+ moveUp={() => move_condition_up(index)}
445
+ moveDown={() => move_condition_down(index)}
446
+ />
447
+ <input
448
+ class={classNames("field-builder-input", $styles.input)}
449
+ placeholder="JSONata condition"
450
+ bind:value={value.conditions[index]}
451
+ />
452
+ <button
453
+ type="button"
454
+ class={classNames("field-builder-remove", $styles.button)}
455
+ data-variant="destructive"
456
+ data-size="icon"
457
+ on:click={() => remove_condition(index)}
458
+ aria-label="Remove condition">×</button
459
+ >
460
+ </div>
461
+ {/each}
462
+ {/if}
463
+ </CollapsibleSection>
464
+ <!-- validations -->
465
+ <CollapsibleSection title="Validations">
466
+ <button
467
+ type="button"
468
+ class={classNames("field-builder-add", $styles.button)}
469
+ data-variant="primary"
470
+ on:click={add_validation}>Add validation</button
471
+ >
472
+
473
+ {#if value.validations && value.validations.length > 0}
474
+ {#each value.validations as validation, index}
475
+ <div class="field-builder-item">
476
+ <!-- up and down sort buttons -->
477
+ <FieldBuilderReorder
478
+ item="validation"
479
+ first={index === 0}
480
+ last={index === value.validations.length - 1}
481
+ moveUp={() => move_validation_up(index)}
482
+ moveDown={() => move_validation_down(index)}
483
+ />
484
+ <div class="field-builder-validation-fields">
485
+ <select
486
+ class={classNames("field-builder-input", $styles.input)}
487
+ aria-label="Validation type"
488
+ value={value.validations[index].validationtype}
489
+ on:change={(event) => handle_validation_change(event, index)}
490
+ >
491
+ {#each validation_types as vt}<option value={vt}>{vt}</option>{/each}
492
+ </select>
493
+ <input
494
+ class={classNames("field-builder-input", $styles.input)}
495
+ placeholder="Invalid Message"
496
+ bind:value={value.validations[index].invalid_message}
497
+ />
498
+ {#if value.validations[index].validationtype === "regex"}
499
+ <input
500
+ class={classNames("field-builder-input", $styles.input)}
501
+ placeholder="Regex Pattern"
502
+ bind:value={value.validations[index].params.regex}
503
+ />
504
+ {/if}
505
+ {#if value.validations[index].validationtype === "jsonata"}
506
+ <input
507
+ class={classNames("field-builder-input", $styles.input)}
508
+ placeholder="JSONata Expression"
509
+ bind:value={value.validations[index].params.jsonata}
510
+ />
511
+ {/if}
512
+ </div>
513
+ <button
514
+ type="button"
515
+ class={classNames("field-builder-remove", $styles.button)}
516
+ data-variant="destructive"
517
+ data-size="icon"
518
+ on:click={() => remove_validation(index)}
519
+ aria-label="Remove validation">×</button
520
+ >
521
+ </div>
522
+ {/each}
523
+ {/if}
524
+ </CollapsibleSection>
525
+ <FieldMessage {fieldStore} />
526
+ </div>
527
+
528
+ <style>
529
+ .field-builder-field,
530
+ :where(.field-builder-input),
531
+ :where(.field-builder-textarea),
532
+ .field-builder-validation-fields {
533
+ box-sizing: border-box;
534
+ width: 100%;
535
+ min-width: 0;
536
+ }
537
+
538
+ .field-builder-field {
539
+ display: flex;
540
+ flex-direction: column;
541
+ gap: 0.75rem;
542
+ }
543
+
544
+ .field-builder-property,
545
+ .field-builder-validation-fields {
546
+ display: flex;
547
+ flex-direction: column;
548
+ gap: 0.25rem;
549
+ }
550
+
551
+ .field-builder-checkbox,
552
+ .field-builder-item {
553
+ display: flex;
554
+ align-items: center;
555
+ gap: 0.5rem;
556
+ min-width: 0;
557
+ }
558
+
559
+ .field-builder-item > .field-builder-input,
560
+ .field-builder-validation-fields {
561
+ flex: 1;
562
+ min-width: 0;
563
+ }
564
+
565
+ .field-builder-remove {
566
+ flex: none;
567
+ }
568
+ </style>