@stubber/form-fields 1.4.6 → 1.5.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 (98) hide show
  1. package/README.md +61 -295
  2. package/dist/fields2/FieldLabel.svelte +8 -0
  3. package/dist/fields2/FieldLabel.svelte.d.ts +20 -0
  4. package/dist/fields2/FieldMessage.svelte +16 -0
  5. package/dist/fields2/FieldMessage.svelte.d.ts +20 -0
  6. package/dist/fields2/Form.svelte +29 -0
  7. package/dist/fields2/Form.svelte.d.ts +23 -0
  8. package/dist/fields2/fileserver.d.ts +15 -0
  9. package/dist/fields2/fileserver.js +52 -0
  10. package/dist/fields2/form-field.svelte +10 -0
  11. package/dist/fields2/form-field.svelte.d.ts +20 -0
  12. package/dist/fields2/index.d.ts +3 -0
  13. package/dist/fields2/index.js +2 -0
  14. package/dist/fields2/interfaces.d.ts +207 -0
  15. package/dist/fields2/interfaces.js +82 -0
  16. package/dist/fields2/sub/array-builder-field.svelte +110 -0
  17. package/dist/fields2/sub/array-builder-field.svelte.d.ts +27 -0
  18. package/dist/fields2/sub/checkbox-autocomplete.svelte +56 -0
  19. package/dist/fields2/sub/checkbox-autocomplete.svelte.d.ts +27 -0
  20. package/dist/fields2/sub/checkbox-field.svelte +41 -0
  21. package/dist/fields2/sub/checkbox-field.svelte.d.ts +28 -0
  22. package/dist/fields2/sub/code-field.svelte +146 -0
  23. package/dist/fields2/sub/code-field.svelte.d.ts +27 -0
  24. package/dist/fields2/sub/contact-selector-field.svelte +84 -0
  25. package/dist/fields2/sub/contact-selector-field.svelte.d.ts +30 -0
  26. package/dist/fields2/sub/currency-field.svelte +197 -0
  27. package/dist/fields2/sub/currency-field.svelte.d.ts +29 -0
  28. package/dist/fields2/sub/data-indication-field.svelte +19 -0
  29. package/dist/fields2/sub/data-indication-field.svelte.d.ts +23 -0
  30. package/dist/fields2/sub/date-field.svelte +31 -0
  31. package/dist/fields2/sub/date-field.svelte.d.ts +23 -0
  32. package/dist/fields2/sub/date-time-field.svelte +31 -0
  33. package/dist/fields2/sub/date-time-field.svelte.d.ts +23 -0
  34. package/dist/fields2/sub/email-field.svelte +40 -0
  35. package/dist/fields2/sub/email-field.svelte.d.ts +23 -0
  36. package/dist/fields2/sub/field-builder-field.svelte +525 -0
  37. package/dist/fields2/sub/field-builder-field.svelte.d.ts +23 -0
  38. package/dist/fields2/sub/file-field.svelte +150 -0
  39. package/dist/fields2/sub/file-field.svelte.d.ts +27 -0
  40. package/dist/fields2/sub/grid-field.svelte +54 -0
  41. package/dist/fields2/sub/grid-field.svelte.d.ts +30 -0
  42. package/dist/fields2/sub/heading-field.svelte +28 -0
  43. package/dist/fields2/sub/heading-field.svelte.d.ts +28 -0
  44. package/dist/fields2/sub/hidden-field.svelte +142 -0
  45. package/dist/fields2/sub/hidden-field.svelte.d.ts +37 -0
  46. package/dist/fields2/sub/hidden-location-field.svelte +23 -0
  47. package/dist/fields2/sub/hidden-location-field.svelte.d.ts +23 -0
  48. package/dist/fields2/sub/html-field.svelte +22 -0
  49. package/dist/fields2/sub/html-field.svelte.d.ts +27 -0
  50. package/dist/fields2/sub/json-editor-bound.svelte +17 -0
  51. package/dist/fields2/sub/json-editor-bound.svelte.d.ts +65 -0
  52. package/dist/fields2/sub/jsoneditor-field.svelte +23 -0
  53. package/dist/fields2/sub/jsoneditor-field.svelte.d.ts +27 -0
  54. package/dist/fields2/sub/map-field.svelte +144 -0
  55. package/dist/fields2/sub/map-field.svelte.d.ts +28 -0
  56. package/dist/fields2/sub/multi-checkbox-field.svelte +83 -0
  57. package/dist/fields2/sub/multi-checkbox-field.svelte.d.ts +34 -0
  58. package/dist/fields2/sub/multistep-field.svelte +70 -0
  59. package/dist/fields2/sub/multistep-field.svelte.d.ts +24 -0
  60. package/dist/fields2/sub/note-field.svelte +18 -0
  61. package/dist/fields2/sub/note-field.svelte.d.ts +23 -0
  62. package/dist/fields2/sub/number-field.svelte +77 -0
  63. package/dist/fields2/sub/number-field.svelte.d.ts +29 -0
  64. package/dist/fields2/sub/object-builder-field.svelte +123 -0
  65. package/dist/fields2/sub/object-builder-field.svelte.d.ts +28 -0
  66. package/dist/fields2/sub/qr-code-scanner-field.svelte +86 -0
  67. package/dist/fields2/sub/qr-code-scanner-field.svelte.d.ts +23 -0
  68. package/dist/fields2/sub/radio-field.svelte +69 -0
  69. package/dist/fields2/sub/radio-field.svelte.d.ts +30 -0
  70. package/dist/fields2/sub/screenrecorder-field.svelte +182 -0
  71. package/dist/fields2/sub/screenrecorder-field.svelte.d.ts +27 -0
  72. package/dist/fields2/sub/screenshot-field.svelte +165 -0
  73. package/dist/fields2/sub/screenshot-field.svelte.d.ts +26 -0
  74. package/dist/fields2/sub/scroll-and-read-display-field.svelte +92 -0
  75. package/dist/fields2/sub/scroll-and-read-display-field.svelte.d.ts +29 -0
  76. package/dist/fields2/sub/section-field.svelte +27 -0
  77. package/dist/fields2/sub/section-field.svelte.d.ts +26 -0
  78. package/dist/fields2/sub/select-field.svelte +138 -0
  79. package/dist/fields2/sub/select-field.svelte.d.ts +34 -0
  80. package/dist/fields2/sub/selectresource-field.svelte +69 -0
  81. package/dist/fields2/sub/selectresource-field.svelte.d.ts +29 -0
  82. package/dist/fields2/sub/signature-field.svelte +84 -0
  83. package/dist/fields2/sub/signature-field.svelte.d.ts +23 -0
  84. package/dist/fields2/sub/slider-field.svelte +28 -0
  85. package/dist/fields2/sub/slider-field.svelte.d.ts +28 -0
  86. package/dist/fields2/sub/smart-text-field.svelte +245 -0
  87. package/dist/fields2/sub/smart-text-field.svelte.d.ts +36 -0
  88. package/dist/fields2/sub/telephone-field.svelte +68 -0
  89. package/dist/fields2/sub/telephone-field.svelte.d.ts +26 -0
  90. package/dist/fields2/sub/text-field.svelte +46 -0
  91. package/dist/fields2/sub/text-field.svelte.d.ts +27 -0
  92. package/dist/fields2/sub/voicenote-field.svelte +161 -0
  93. package/dist/fields2/sub/voicenote-field.svelte.d.ts +26 -0
  94. package/dist/fields2/utils.d.ts +9 -0
  95. package/dist/fields2/utils.js +116 -0
  96. package/dist/fields2/validations/validate_field.d.ts +11 -0
  97. package/dist/fields2/validations/validate_field.js +121 -0
  98. package/package.json +10 -9
@@ -0,0 +1,40 @@
1
+ <script context="module"></script>
2
+
3
+ <script>import { Input } from "@stubber/ui/input";
4
+ import FieldLabel from "../FieldLabel.svelte";
5
+ import FieldMessage from "../FieldMessage.svelte";
6
+ import { set_value_details } from "../utils";
7
+ export let fieldStore;
8
+ const field = $fieldStore;
9
+ const formStore = field.formStore;
10
+ $: value = $fieldStore.value;
11
+ $: {
12
+ const regex = /^(([^<>()[\]\.,;:\s@\"]+(\.[^<>()[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i;
13
+ const is_valid_email = regex.test(value);
14
+ const username = is_valid_email ? value.split("@")[0] : null;
15
+ const domain = is_valid_email ? value.split("@")[1] : null;
16
+ const email_details = {
17
+ is_valid_email,
18
+ username,
19
+ domain,
20
+ raw: value
21
+ };
22
+ if (value) set_value_details(field, "details", email_details);
23
+ }
24
+ function on_input(event) {
25
+ const input = event.target;
26
+ const new_value = input.value.trim().toLowerCase();
27
+ field.value = new_value;
28
+ }
29
+ </script>
30
+
31
+ <FieldLabel {fieldStore} />
32
+ <Input
33
+ id={$fieldStore.id}
34
+ {value}
35
+ placeholder={$fieldStore.label}
36
+ on:input={on_input}
37
+ aria-invalid={$fieldStore.validation_result?.type == "error" ? true : undefined}
38
+ aria-describedby="message-{$fieldStore.id}"
39
+ />
40
+ <FieldMessage {fieldStore} />
@@ -0,0 +1,23 @@
1
+ import { SvelteComponent } from "svelte";
2
+ import type { Writable } from "svelte/store";
3
+ import type { IBaseField, IBuiltField } from "../interfaces";
4
+ export interface IEmailField extends IBaseField<{}> {
5
+ fieldtype: "email";
6
+ }
7
+ declare const __propDef: {
8
+ props: {
9
+ fieldStore: Writable<IBuiltField>;
10
+ };
11
+ events: {
12
+ [evt: string]: CustomEvent<any>;
13
+ };
14
+ slots: {};
15
+ exports?: {} | undefined;
16
+ bindings?: string | undefined;
17
+ };
18
+ export type EmailFieldProps = typeof __propDef.props;
19
+ export type EmailFieldEvents = typeof __propDef.events;
20
+ export type EmailFieldSlots = typeof __propDef.slots;
21
+ export default class EmailField extends SvelteComponent<EmailFieldProps, EmailFieldEvents, EmailFieldSlots> {
22
+ }
23
+ export {};
@@ -0,0 +1,525 @@
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: max_files_param_spec,
39
+ screenshot: max_files_param_spec,
40
+ voicenote: max_files_param_spec,
41
+ signature: null,
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 { Button } from "@stubber/ui/button";
54
+ import { Checkbox } from "@stubber/ui/checkbox";
55
+ import * as Collapsible from "@stubber/ui/collapsible";
56
+ import * as Command from "@stubber/ui/command";
57
+ import { Input } from "@stubber/ui/input";
58
+ import { Label } from "@stubber/ui/label";
59
+ import * as Popover from "@stubber/ui/popover";
60
+ import * as Select from "@stubber/ui/select";
61
+ import { Textarea } from "@stubber/ui/textarea";
62
+ import { cloneDeep, isEmpty, isEqual, isUndefined, merge, omitBy } from "lodash-es";
63
+ import { tick } from "svelte";
64
+ import FieldLabel from "../FieldLabel.svelte";
65
+ import FieldMessage from "../FieldMessage.svelte";
66
+ import { checkbox_field_param_spec } from "./checkbox-field.svelte";
67
+ import { file_field_param_spec } from "./file-field.svelte";
68
+ import { heading_field_param_spec } from "./heading-field.svelte";
69
+ import { hidden_field_param_spec } from "./hidden-field.svelte";
70
+ import { html_field_param_spec } from "./html-field.svelte";
71
+ import JsonEditorBound from "./json-editor-bound.svelte";
72
+ import { map_field_param_spec } from "./map-field.svelte";
73
+ import { smart_text_field_param_spec } from "./smart-text-field.svelte";
74
+ import { code_field_param_spec } from "./code-field.svelte";
75
+ import { currency_field_param_spec } from "./currency-field.svelte";
76
+ import { array_builder_field_param_spec } from "./array-builder-field.svelte";
77
+ import { contact_selector_field_param_spec } from "./contact-selector-field.svelte";
78
+ import { grid_field_param_spec } from "./grid-field.svelte";
79
+ import { jsoneditor_field_param_spec } from "./jsoneditor-field.svelte";
80
+ import { multi_checkbox_field_param_spec } from "./multi-checkbox-field.svelte";
81
+ import { number_field_param_spec } from "./number-field.svelte";
82
+ import { object_builder_field_param_spec } from "./object-builder-field.svelte";
83
+ import { radio_field_param_spec } from "./radio-field.svelte";
84
+ import { max_files_param_spec } from "./screenrecorder-field.svelte";
85
+ import { scroll_and_read_display_field_param_spec } from "./scroll-and-read-display-field.svelte";
86
+ import { select_field_param_spec } from "./select-field.svelte";
87
+ import { select_resource_field_param_spec } from "./selectresource-field.svelte";
88
+ export let fieldStore;
89
+ let value = cloneDeep($fieldStore.value) || {
90
+ details: {},
91
+ initvalue: {}
92
+ };
93
+ if (!value.details) {
94
+ value.details = {};
95
+ }
96
+ if (!value.initvalue) {
97
+ value.initvalue = {};
98
+ }
99
+ $: update_fieldStore(value);
100
+ function update_fieldStore(new_value) {
101
+ const cleaned_value = omitBy(
102
+ cloneDeep(new_value),
103
+ (v) => isUndefined(v) || typeof v === "object" && isEmpty(v)
104
+ );
105
+ if (!isEqual($fieldStore, cleaned_value)) {
106
+ $fieldStore.value = cleaned_value;
107
+ }
108
+ }
109
+ $: update_value($fieldStore.value);
110
+ function update_value(new_value) {
111
+ if (!isEqual(value, new_value)) {
112
+ value = {
113
+ details: {},
114
+ initvalue: {},
115
+ ...cloneDeep(new_value)
116
+ };
117
+ update_params_from_value(value.params);
118
+ }
119
+ }
120
+ const field_types = Object.keys(fields).map((key) => ({
121
+ label: key,
122
+ value: key
123
+ }));
124
+ let open = false;
125
+ $: selectedValue = field_types.find((f) => f.value === value.fieldtype)?.label ?? "Select a fieldtype";
126
+ function closeAndFocusTrigger(trigger_id) {
127
+ open = false;
128
+ tick().then(() => {
129
+ document.getElementById(trigger_id)?.focus();
130
+ });
131
+ }
132
+ function add_condition() {
133
+ if (!value.conditions) {
134
+ value.conditions = [];
135
+ }
136
+ value.conditions = [...value.conditions, ""];
137
+ }
138
+ function move_condition_up(index) {
139
+ if (index > 0 && value.conditions) {
140
+ const temp = value.conditions[index];
141
+ value.conditions[index] = value.conditions[index - 1];
142
+ value.conditions[index - 1] = temp;
143
+ value.conditions = [...value.conditions];
144
+ }
145
+ }
146
+ function move_condition_down(index) {
147
+ if (value.conditions && index < value.conditions.length - 1) {
148
+ const temp = value.conditions[index];
149
+ value.conditions[index] = value.conditions[index + 1];
150
+ value.conditions[index + 1] = temp;
151
+ value.conditions = [...value.conditions];
152
+ }
153
+ }
154
+ function remove_condition(index) {
155
+ if (value.conditions) {
156
+ value.conditions = value.conditions.filter((_, i) => i !== index);
157
+ }
158
+ }
159
+ function add_validation() {
160
+ if (!value.validations) {
161
+ value.validations = [];
162
+ }
163
+ value.validations = [...value.validations, { validationtype: "required", invalid_message: "" }];
164
+ }
165
+ function move_validation_up(index) {
166
+ if (index > 0 && value.validations) {
167
+ const temp = value.validations[index];
168
+ value.validations[index] = value.validations[index - 1];
169
+ value.validations[index - 1] = temp;
170
+ value.validations = [...value.validations];
171
+ }
172
+ }
173
+ function move_validation_down(index) {
174
+ if (value.validations && index < value.validations.length - 1) {
175
+ const temp = value.validations[index];
176
+ value.validations[index] = value.validations[index + 1];
177
+ value.validations[index + 1] = temp;
178
+ value.validations = [...value.validations];
179
+ }
180
+ }
181
+ function remove_validation(index) {
182
+ if (value.validations) {
183
+ value.validations = value.validations.filter((_, i) => i !== index);
184
+ }
185
+ }
186
+ function handle_validation_selected(val, index) {
187
+ if (val && value.validations) {
188
+ let current_validation;
189
+ let prev_validation = value.validations[index];
190
+ if (val.value === "required") {
191
+ current_validation = {
192
+ validationtype: "required",
193
+ invalid_message: prev_validation.invalid_message
194
+ };
195
+ } else if (val.value === "regex") {
196
+ current_validation = {
197
+ validationtype: "regex",
198
+ invalid_message: prev_validation.invalid_message,
199
+ params: { regex: prev_validation.params?.regex ?? "" }
200
+ };
201
+ } else {
202
+ current_validation = {
203
+ validationtype: "jsonata",
204
+ invalid_message: prev_validation.invalid_message,
205
+ params: { jsonata: prev_validation.params?.jsonata ?? "" }
206
+ };
207
+ }
208
+ value.validations[index] = current_validation;
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, trigger) {
226
+ value.fieldtype = newValue;
227
+ closeAndFocusTrigger(trigger);
228
+ }
229
+ </script>
230
+
231
+ <FieldLabel {fieldStore} />
232
+ <div class="flex flex-col gap-y-2">
233
+ <!-- fieldtype picker -->
234
+ <Popover.Root bind:open let:ids>
235
+ <Popover.Trigger asChild let:builder>
236
+ <Button
237
+ builders={[builder]}
238
+ variant="outline"
239
+ role="combobox"
240
+ aria-expanded={open}
241
+ class="w-full border-input bg-white bg-opacity-[15] ring-offset-background placeholder:text-muted-foreground focus-visible:ring-ring flex h-10 rounded-md border px-3 py-2 text-sm file:border-0 file:bg-transparent file:text-sm file:font-medium focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 justify-between"
242
+ >
243
+ {selectedValue}
244
+ <i class="fas fa-sort ml-2 h-4 w-4 shrink-0 opacity-50" />
245
+ </Button>
246
+ </Popover.Trigger>
247
+ <Popover.Content class="p-0" sameWidth>
248
+ <Command.Root>
249
+ <Command.Input placeholder="Search framework..." />
250
+ <Command.Empty>No fieldtype found.</Command.Empty>
251
+ <Command.Group>
252
+ {#each field_types as fieldtype_item}
253
+ <Command.Item
254
+ value={fieldtype_item.value}
255
+ onSelect={(newValue) => select_field_type(newValue, ids.trigger)}
256
+ class={value.fieldtype === fieldtype_item.value ? "bg-primary-100" : ""}
257
+ >
258
+ {fieldtype_item.label}
259
+ </Command.Item>
260
+ {/each}
261
+ </Command.Group>
262
+ </Command.Root>
263
+ </Popover.Content>
264
+ </Popover.Root>
265
+ <!-- basic props -->
266
+ <Collapsible.Root open={true} class="w-full">
267
+ <Collapsible.Trigger asChild let:builder>
268
+ <Button builders={[builder]} variant="ghost" class="w-full justify-between pl-0">
269
+ <Label>Basic Info</Label>
270
+
271
+ <i class="fa fa-sort" />
272
+ </Button>
273
+ </Collapsible.Trigger>
274
+
275
+ <Collapsible.Content class="flex flex-col gap-y-2 pl-2">
276
+ <div>
277
+ <Label for="title">Title</Label>
278
+ <Input
279
+ id="title"
280
+ placeholder="Optional custom title for the field"
281
+ bind:value={value.title}
282
+ />
283
+ </div>
284
+ <div class="w-full flex items-center space-x-2">
285
+ <Checkbox id="without_value_details" bind:checked={value.without_value_details} />
286
+ <Label for="without_value_details">Without Value Details</Label>
287
+ </div>
288
+ <div class="w-full flex items-center space-x-2">
289
+ <Checkbox id="hide_label" bind:checked={value.hide_label} />
290
+ <Label for="hide_label">Hide Label</Label>
291
+ </div>
292
+ <div>
293
+ <Label for="help">Help</Label>
294
+ <Textarea
295
+ id="help"
296
+ placeholder="Optional help text for the field"
297
+ bind:value={value.help}
298
+ />
299
+ </div>
300
+ </Collapsible.Content>
301
+ </Collapsible.Root>
302
+ <hr />
303
+ <!-- params -->
304
+ <Collapsible.Root open={true} class="w-full">
305
+ <Collapsible.Trigger asChild let:builder>
306
+ <Button builders={[builder]} variant="ghost" class="w-full justify-between pl-0">
307
+ <Label>Params</Label>
308
+
309
+ <i class="fa fa-sort" />
310
+ </Button>
311
+ </Collapsible.Trigger>
312
+
313
+ <Collapsible.Content class="flex flex-col gap-y-2 pl-2 pt-2">
314
+ {@const field_param_spec = field_params_spec_lookup[value.fieldtype ?? "unknown"]}
315
+ {#if field_param_spec}
316
+ <Form
317
+ initial_form={field_param_spec}
318
+ form={params_store}
319
+ attachments={$fieldStore.attachmentsStore}
320
+ />
321
+ {:else}
322
+ <span class="text-muted-foreground text-xs">No params available for this fieldtype.</span>
323
+ {/if}
324
+ </Collapsible.Content>
325
+ </Collapsible.Root>
326
+ <hr />
327
+ <!-- details -->
328
+ <Collapsible.Root open={false} class="w-full">
329
+ <Collapsible.Trigger asChild let:builder>
330
+ <Button builders={[builder]} variant="ghost" class="w-full justify-between pl-0">
331
+ <Label>Details</Label>
332
+
333
+ <i class="fa fa-sort" />
334
+ </Button>
335
+ </Collapsible.Trigger>
336
+
337
+ <Collapsible.Content class="flex flex-col gap-y-2 pl-2">
338
+ <div>
339
+ <Label for="keyname">Keyname</Label>
340
+ <Input
341
+ id="keyname"
342
+ placeholder="Custom key underwhich to store the value"
343
+ bind:value={value.details.keyname}
344
+ />
345
+ </div>
346
+ <div>
347
+ <Label for="data_path">Data Path</Label>
348
+ <Input
349
+ id="data_path"
350
+ placeholder="Optional custom data path for the field"
351
+ bind:value={value.details.data_path}
352
+ />
353
+ </div>
354
+ </Collapsible.Content>
355
+ </Collapsible.Root>
356
+ <hr />
357
+ <!-- initial value -->
358
+ <Collapsible.Root open={false} class="w-full">
359
+ <Collapsible.Trigger asChild let:builder>
360
+ <Button builders={[builder]} variant="ghost" class="w-full justify-between pl-0">
361
+ <Label>Initial Value</Label>
362
+
363
+ <i class="fa fa-sort" />
364
+ </Button>
365
+ </Collapsible.Trigger>
366
+
367
+ <Collapsible.Content class="flex flex-col gap-y-2 pl-2">
368
+ <div>
369
+ <div class="w-full flex items-center space-x-2">
370
+ <Checkbox id="has_default" bind:checked={value.initvalue.has_default} />
371
+ <Label for="has_default">Has Default</Label>
372
+ </div>
373
+ <JsonEditorBound bind:value={value.initvalue.default} />
374
+ </div>
375
+ <div>
376
+ <div class="w-full flex items-center space-x-2">
377
+ <Checkbox id="has_override" bind:checked={value.initvalue.has_override} />
378
+ <Label for="has_override">Has Override</Label>
379
+ </div>
380
+ <JsonEditorBound bind:value={value.initvalue.override} />
381
+ </div>
382
+ </Collapsible.Content>
383
+ </Collapsible.Root>
384
+ <hr />
385
+ <!-- conditions -->
386
+ <Collapsible.Root open={false} class="w-full">
387
+ <Collapsible.Trigger asChild let:builder>
388
+ <Button builders={[builder]} variant="ghost" class="w-full justify-between pl-0">
389
+ <Label>Conditions</Label>
390
+
391
+ <i class="fa fa-sort" />
392
+ </Button>
393
+ </Collapsible.Trigger>
394
+
395
+ <Collapsible.Content class="flex flex-col gap-y-2 pl-2">
396
+ <Button variant="outline" size="icon" class="self-start" on:click={add_condition}>
397
+ <i class="fa fa-plus" />
398
+ </Button>
399
+
400
+ {#if value.conditions && value.conditions.length > 0}
401
+ {#each value.conditions as condition, index}
402
+ <div class="flex items-center space-x-2 w-full">
403
+ <!-- up and down sort buttons -->
404
+ <div class="flex flex-col items-center">
405
+ <Button
406
+ variant="ghost"
407
+ class="h-5 w-5 p-2"
408
+ disabled={index === 0}
409
+ on:click={() => move_condition_up(index)}
410
+ >
411
+ <i class="fa fa-chevron-up" />
412
+ </Button>
413
+ <Button
414
+ variant="ghost"
415
+ class="h-5 w-5 p-2"
416
+ disabled={index === value.conditions.length - 1}
417
+ on:click={() => move_condition_down(index)}
418
+ >
419
+ <i class="fa fa-chevron-down" />
420
+ </Button>
421
+ </div>
422
+ <Input
423
+ placeholder="JSONata condition"
424
+ class="w-full"
425
+ bind:value={value.conditions[index]}
426
+ />
427
+ <Button
428
+ variant="destructive"
429
+ class="h-5 w-5 p-2"
430
+ on:click={() => remove_condition(index)}
431
+ >
432
+ <i class="fa fa-trash" />
433
+ </Button>
434
+ </div>
435
+ {/each}
436
+ {/if}
437
+ </Collapsible.Content>
438
+ </Collapsible.Root>
439
+ <hr />
440
+ <!-- validations -->
441
+ <Collapsible.Root open={false} class="w-full">
442
+ <Collapsible.Trigger asChild let:builder>
443
+ <Button builders={[builder]} variant="ghost" class="w-full justify-between pl-0">
444
+ <Label>Validations</Label>
445
+
446
+ <i class="fa fa-sort" />
447
+ </Button>
448
+ </Collapsible.Trigger>
449
+
450
+ <Collapsible.Content class="flex flex-col gap-y-2 pl-2">
451
+ <Button variant="outline" size="icon" class="self-start" on:click={add_validation}>
452
+ <i class="fa fa-plus" />
453
+ </Button>
454
+
455
+ {#if value.validations && value.validations.length > 0}
456
+ {#each value.validations as validation, index}
457
+ <div class="flex items-start space-x-2 w-full">
458
+ <!-- up and down sort buttons -->
459
+ <div class="flex flex-col items-center">
460
+ <Button
461
+ variant="ghost"
462
+ class="h-5 w-5 p-2"
463
+ disabled={index === 0}
464
+ on:click={() => move_validation_up(index)}
465
+ >
466
+ <i class="fa fa-chevron-up" />
467
+ </Button>
468
+ <Button
469
+ variant="ghost"
470
+ class="h-5 w-5 p-2"
471
+ disabled={index === value.validations.length - 1}
472
+ on:click={() => move_validation_down(index)}
473
+ >
474
+ <i class="fa fa-chevron-down" />
475
+ </Button>
476
+ </div>
477
+ <div class="w-full flex flex-col items-stretch gap-1">
478
+ <Select.Root
479
+ selected={{
480
+ label: value.validations[index].validationtype,
481
+ value: value.validations[index].validationtype,
482
+ }}
483
+ onSelectedChange={(v) => handle_validation_selected(v, index)}
484
+ >
485
+ <Select.Trigger class="w-full">
486
+ <Select.Value placeholder="Validation Type" />
487
+ </Select.Trigger>
488
+ <Select.Content>
489
+ {#each validation_types as vt}
490
+ <Select.Item value={vt}>{vt}</Select.Item>
491
+ {/each}
492
+ </Select.Content>
493
+ </Select.Root>
494
+ <Input
495
+ placeholder="Invalid Message"
496
+ bind:value={value.validations[index].invalid_message}
497
+ />
498
+ {#if value.validations[index].validationtype === "regex"}
499
+ <Input
500
+ placeholder="Regex Pattern"
501
+ bind:value={value.validations[index].params.regex}
502
+ />
503
+ {/if}
504
+ {#if value.validations[index].validationtype === "jsonata"}
505
+ <Input
506
+ placeholder="JSONata Expression"
507
+ bind:value={value.validations[index].params.jsonata}
508
+ />
509
+ {/if}
510
+ </div>
511
+ <Button
512
+ variant="destructive"
513
+ class="h-5 w-5 p-2"
514
+ on:click={() => remove_validation(index)}
515
+ >
516
+ <i class="fa fa-trash" />
517
+ </Button>
518
+ </div>
519
+ {/each}
520
+ {/if}
521
+ </Collapsible.Content>
522
+ </Collapsible.Root>
523
+ <hr />
524
+ </div>
525
+ <FieldMessage {fieldStore} />
@@ -0,0 +1,23 @@
1
+ import { SvelteComponent } from "svelte";
2
+ import { type Writable } from "svelte/store";
3
+ import { type IBaseField, type IBuiltField } from "../interfaces";
4
+ export interface IFieldBuilderField extends IBaseField<{}> {
5
+ fieldtype: "fieldbuilder";
6
+ }
7
+ declare const __propDef: {
8
+ props: {
9
+ fieldStore: Writable<IBuiltField>;
10
+ };
11
+ events: {
12
+ [evt: string]: CustomEvent<any>;
13
+ };
14
+ slots: {};
15
+ exports?: {} | undefined;
16
+ bindings?: string | undefined;
17
+ };
18
+ export type FieldBuilderFieldProps = typeof __propDef.props;
19
+ export type FieldBuilderFieldEvents = typeof __propDef.events;
20
+ export type FieldBuilderFieldSlots = typeof __propDef.slots;
21
+ export default class FieldBuilderField extends SvelteComponent<FieldBuilderFieldProps, FieldBuilderFieldEvents, FieldBuilderFieldSlots> {
22
+ }
23
+ export {};