@stubber/form-fields 2.2.5 → 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.
- package/README.md +63 -25
- package/dist/form-fields/Autocomplete.svelte +261 -0
- package/dist/form-fields/Autocomplete.svelte.d.ts +43 -0
- package/dist/form-fields/CollapsibleSection.svelte +127 -0
- package/dist/form-fields/CollapsibleSection.svelte.d.ts +26 -0
- package/dist/form-fields/FieldLabel.svelte +18 -3
- package/dist/form-fields/FieldLabel.svelte.d.ts +1 -0
- package/dist/form-fields/FieldMessage.svelte +20 -9
- package/dist/form-fields/Form.svelte +19 -2
- package/dist/form-fields/Form.svelte.d.ts +2 -0
- package/dist/form-fields/UploadStatus.svelte +76 -0
- package/dist/form-fields/UploadStatus.svelte.d.ts +18 -0
- package/dist/form-fields/fields/_field-builder-reorder.svelte +35 -0
- package/dist/form-fields/fields/_field-builder-reorder.svelte.d.ts +22 -0
- package/dist/form-fields/{sub → fields}/array-builder-field.svelte +104 -38
- package/dist/form-fields/fields/checkbox-autocomplete.svelte +153 -0
- package/dist/form-fields/fields/checkbox-field.svelte +69 -0
- package/dist/form-fields/{sub → fields}/contact-selector-field.svelte +9 -6
- package/dist/form-fields/{sub → fields}/currency-field.svelte +108 -70
- package/dist/form-fields/fields/data-indication-field.svelte +39 -0
- package/dist/form-fields/fields/date-field.svelte +31 -0
- package/dist/form-fields/fields/date-time-field.svelte +31 -0
- package/dist/form-fields/{sub → fields}/email-field.svelte +25 -11
- package/dist/form-fields/fields/field-builder-field.svelte +568 -0
- package/dist/form-fields/fields/file-field.svelte +284 -0
- package/dist/form-fields/{sub → fields}/file-field.svelte.d.ts +2 -0
- package/dist/form-fields/fields/grid-field.svelte +152 -0
- package/dist/form-fields/{sub → fields}/heading-field.svelte +7 -4
- package/dist/form-fields/{sub → fields}/html-field.svelte +6 -4
- package/dist/form-fields/{sub → fields}/map-field.svelte +122 -78
- package/dist/form-fields/{sub → fields}/multi-checkbox-field.svelte +35 -20
- package/dist/form-fields/fields/multistep-field.svelte +135 -0
- package/dist/form-fields/fields/note-field.svelte +35 -0
- package/dist/form-fields/{sub → fields}/number-field.svelte +29 -14
- package/dist/form-fields/fields/object-builder-field.svelte +176 -0
- package/dist/form-fields/fields/qr-code-scanner-field.svelte +203 -0
- package/dist/form-fields/fields/radio-field.svelte +82 -0
- package/dist/form-fields/{sub → fields}/radio-field.svelte.d.ts +1 -1
- package/dist/form-fields/fields/screenrecorder-field.svelte +255 -0
- package/dist/form-fields/{sub → fields}/screenshot-field.svelte +101 -40
- package/dist/form-fields/{sub → fields}/scroll-and-read-display-field.svelte +43 -27
- package/dist/form-fields/fields/section-field.svelte +73 -0
- package/dist/form-fields/fields/select-field.svelte +104 -0
- package/dist/form-fields/{sub → fields}/signature-field.svelte +78 -22
- package/dist/form-fields/fields/slider-field.svelte +53 -0
- package/dist/form-fields/{sub → fields}/smart-text-field.svelte +62 -82
- package/dist/form-fields/fields/telephone-field.svelte +108 -0
- package/dist/form-fields/{sub → fields}/telephone-field.svelte.d.ts +1 -1
- package/dist/form-fields/{sub → fields}/text-field.svelte +28 -11
- package/dist/form-fields/{sub → fields}/voicenote-field.svelte +117 -46
- package/dist/form-fields/file_creation_options.d.ts +1 -1
- package/dist/form-fields/form-field.svelte +8 -1
- package/dist/form-fields/icons/ChevronDownIcon.svelte +21 -0
- package/dist/form-fields/icons/ChevronDownIcon.svelte.d.ts +20 -0
- package/dist/form-fields/icons/QrCodeScannerIcon.svelte +25 -0
- package/dist/form-fields/icons/QrCodeScannerIcon.svelte.d.ts +19 -0
- package/dist/form-fields/icons/ScreenRecordingIcon.svelte +21 -0
- package/dist/form-fields/icons/ScreenRecordingIcon.svelte.d.ts +19 -0
- package/dist/form-fields/icons/ScreenshotIcon.svelte +22 -0
- package/dist/form-fields/icons/ScreenshotIcon.svelte.d.ts +19 -0
- package/dist/form-fields/index.d.ts +5 -1
- package/dist/form-fields/index.js +3 -1
- package/dist/form-fields/interfaces.d.ts +63 -63
- package/dist/form-fields/interfaces.js +42 -39
- package/dist/form-fields/intl-tel-input.css +1 -0
- package/dist/form-fields/styles.d.ts +17 -0
- package/dist/form-fields/styles.js +4 -0
- package/package.json +2 -4
- package/dist/form-fields/sub/checkbox-autocomplete.svelte +0 -56
- package/dist/form-fields/sub/checkbox-field.svelte +0 -42
- package/dist/form-fields/sub/data-indication-field.svelte +0 -19
- package/dist/form-fields/sub/date-field.svelte +0 -31
- package/dist/form-fields/sub/date-time-field.svelte +0 -31
- package/dist/form-fields/sub/field-builder-field.svelte +0 -657
- package/dist/form-fields/sub/file-field.svelte +0 -159
- package/dist/form-fields/sub/grid-field.svelte +0 -69
- package/dist/form-fields/sub/multistep-field.svelte +0 -70
- package/dist/form-fields/sub/note-field.svelte +0 -18
- package/dist/form-fields/sub/object-builder-field.svelte +0 -134
- package/dist/form-fields/sub/qr-code-scanner-field.svelte +0 -84
- package/dist/form-fields/sub/radio-field.svelte +0 -69
- package/dist/form-fields/sub/screenrecorder-field.svelte +0 -178
- package/dist/form-fields/sub/section-field.svelte +0 -50
- package/dist/form-fields/sub/select-field.svelte +0 -150
- package/dist/form-fields/sub/slider-field.svelte +0 -28
- package/dist/form-fields/sub/telephone-field.svelte +0 -64
- /package/dist/form-fields/{sub → fields}/array-builder-field.svelte.d.ts +0 -0
- /package/dist/form-fields/{sub → fields}/checkbox-autocomplete.svelte.d.ts +0 -0
- /package/dist/form-fields/{sub → fields}/checkbox-field.svelte.d.ts +0 -0
- /package/dist/form-fields/{sub → fields}/code-field.svelte +0 -0
- /package/dist/form-fields/{sub → fields}/code-field.svelte.d.ts +0 -0
- /package/dist/form-fields/{sub → fields}/contact-selector-field.svelte.d.ts +0 -0
- /package/dist/form-fields/{sub → fields}/currency-field.svelte.d.ts +0 -0
- /package/dist/form-fields/{sub → fields}/data-indication-field.svelte.d.ts +0 -0
- /package/dist/form-fields/{sub → fields}/date-field.svelte.d.ts +0 -0
- /package/dist/form-fields/{sub → fields}/date-time-field.svelte.d.ts +0 -0
- /package/dist/form-fields/{sub → fields}/email-field.svelte.d.ts +0 -0
- /package/dist/form-fields/{sub → fields}/field-builder-field.svelte.d.ts +0 -0
- /package/dist/form-fields/{sub → fields}/grid-field.svelte.d.ts +0 -0
- /package/dist/form-fields/{sub → fields}/heading-field.svelte.d.ts +0 -0
- /package/dist/form-fields/{sub → fields}/hidden-field.svelte +0 -0
- /package/dist/form-fields/{sub → fields}/hidden-field.svelte.d.ts +0 -0
- /package/dist/form-fields/{sub → fields}/hidden-location-field.svelte +0 -0
- /package/dist/form-fields/{sub → fields}/hidden-location-field.svelte.d.ts +0 -0
- /package/dist/form-fields/{sub → fields}/html-field.svelte.d.ts +0 -0
- /package/dist/form-fields/{sub → fields}/jsoneditor-field.svelte +0 -0
- /package/dist/form-fields/{sub → fields}/jsoneditor-field.svelte.d.ts +0 -0
- /package/dist/form-fields/{sub → fields}/map-field.svelte.d.ts +0 -0
- /package/dist/form-fields/{sub → fields}/multi-checkbox-field.svelte.d.ts +0 -0
- /package/dist/form-fields/{sub → fields}/multistep-field.svelte.d.ts +0 -0
- /package/dist/form-fields/{sub → fields}/note-field.svelte.d.ts +0 -0
- /package/dist/form-fields/{sub → fields}/number-field.svelte.d.ts +0 -0
- /package/dist/form-fields/{sub → fields}/object-builder-field.svelte.d.ts +0 -0
- /package/dist/form-fields/{sub → fields}/qr-code-scanner-field.svelte.d.ts +0 -0
- /package/dist/form-fields/{sub → fields}/screenrecorder-field.svelte.d.ts +0 -0
- /package/dist/form-fields/{sub → fields}/screenshot-field.svelte.d.ts +0 -0
- /package/dist/form-fields/{sub → fields}/scroll-and-read-display-field.svelte.d.ts +0 -0
- /package/dist/form-fields/{sub → fields}/section-field.svelte.d.ts +0 -0
- /package/dist/form-fields/{sub → fields}/select-field.svelte.d.ts +0 -0
- /package/dist/form-fields/{sub → fields}/selectresource-field.svelte +0 -0
- /package/dist/form-fields/{sub → fields}/selectresource-field.svelte.d.ts +0 -0
- /package/dist/form-fields/{sub → fields}/signature-field.svelte.d.ts +0 -0
- /package/dist/form-fields/{sub → fields}/slider-field.svelte.d.ts +0 -0
- /package/dist/form-fields/{sub → fields}/smart-text-field.svelte.d.ts +0 -0
- /package/dist/form-fields/{sub → fields}/text-field.svelte.d.ts +0 -0
- /package/dist/form-fields/{sub → fields}/voicenote-field.svelte.d.ts +0 -0
|
@@ -2,6 +2,7 @@ import { SvelteComponent } from "svelte";
|
|
|
2
2
|
import type { Writable } from "svelte/store";
|
|
3
3
|
import type { UploadedFile } from "./fileserver";
|
|
4
4
|
import type { IFormDependencies, IInitialForm } from "./interfaces";
|
|
5
|
+
import { type FormFieldStyles } from "./styles";
|
|
5
6
|
declare const __propDef: {
|
|
6
7
|
props: {
|
|
7
8
|
initial_form: IInitialForm;
|
|
@@ -10,6 +11,7 @@ declare const __propDef: {
|
|
|
10
11
|
dependencies?: IFormDependencies | undefined;
|
|
11
12
|
form_valid?: boolean;
|
|
12
13
|
dynamic_field_type?: boolean;
|
|
14
|
+
styles?: FormFieldStyles | undefined;
|
|
13
15
|
};
|
|
14
16
|
events: {
|
|
15
17
|
[evt: string]: CustomEvent<any>;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
<script>export let status;
|
|
2
|
+
$: label = status === "uploaded" ? "Uploaded" : status === "failed" ? "Upload failed" : "Uploading";
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
<span class="upload-status upload-status-{status}" aria-label={label} role="status">
|
|
6
|
+
{#if status === "uploaded"}
|
|
7
|
+
<svg viewBox="0 0 24 24" aria-hidden="true">
|
|
8
|
+
<path d="m6.75 12.25 3.25 3.25 7.25-7.25" />
|
|
9
|
+
</svg>
|
|
10
|
+
{:else if status === "failed"}
|
|
11
|
+
<svg viewBox="0 0 24 24" aria-hidden="true">
|
|
12
|
+
<path d="M12 7.5v5.25M12 16.5h.01" />
|
|
13
|
+
</svg>
|
|
14
|
+
{:else}
|
|
15
|
+
<span class="upload-spinner" aria-hidden="true" />
|
|
16
|
+
{/if}
|
|
17
|
+
</span>
|
|
18
|
+
|
|
19
|
+
<style>
|
|
20
|
+
.upload-status {
|
|
21
|
+
display: inline-grid;
|
|
22
|
+
box-sizing: border-box;
|
|
23
|
+
width: var(--form-upload-status-size, 1.75rem);
|
|
24
|
+
height: var(--form-upload-status-size, 1.75rem);
|
|
25
|
+
flex: none;
|
|
26
|
+
place-items: center;
|
|
27
|
+
border-radius: 999px;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.upload-status-uploaded {
|
|
31
|
+
color: var(--form-upload-success-color, #15803d);
|
|
32
|
+
background: var(--form-upload-success-background, #dcfce7);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.upload-status-failed {
|
|
36
|
+
color: var(--form-upload-failure-color, #b91c1c);
|
|
37
|
+
background: var(--form-upload-failure-background, #fee2e2);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.upload-status-uploading {
|
|
41
|
+
color: var(--form-upload-progress-color, #2563eb);
|
|
42
|
+
background: var(--form-upload-progress-background, #dbeafe);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
svg {
|
|
46
|
+
width: 1.2rem;
|
|
47
|
+
height: 1.2rem;
|
|
48
|
+
fill: none;
|
|
49
|
+
stroke: currentColor;
|
|
50
|
+
stroke-width: 2.5;
|
|
51
|
+
stroke-linecap: round;
|
|
52
|
+
stroke-linejoin: round;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.upload-spinner {
|
|
56
|
+
box-sizing: border-box;
|
|
57
|
+
width: 1rem;
|
|
58
|
+
height: 1rem;
|
|
59
|
+
border: 2px solid currentColor;
|
|
60
|
+
border-right-color: transparent;
|
|
61
|
+
border-radius: 999px;
|
|
62
|
+
animation: upload-spin 0.7s linear infinite;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
@keyframes upload-spin {
|
|
66
|
+
to {
|
|
67
|
+
transform: rotate(360deg);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
@media (prefers-reduced-motion: reduce) {
|
|
72
|
+
.upload-spinner {
|
|
73
|
+
animation-duration: 1.5s;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
</style>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { SvelteComponent } from "svelte";
|
|
2
|
+
declare const __propDef: {
|
|
3
|
+
props: {
|
|
4
|
+
status: "uploading" | "uploaded" | "failed";
|
|
5
|
+
};
|
|
6
|
+
events: {
|
|
7
|
+
[evt: string]: CustomEvent<any>;
|
|
8
|
+
};
|
|
9
|
+
slots: {};
|
|
10
|
+
exports?: {} | undefined;
|
|
11
|
+
bindings?: string | undefined;
|
|
12
|
+
};
|
|
13
|
+
export type UploadStatusProps = typeof __propDef.props;
|
|
14
|
+
export type UploadStatusEvents = typeof __propDef.events;
|
|
15
|
+
export type UploadStatusSlots = typeof __propDef.slots;
|
|
16
|
+
export default class UploadStatus extends SvelteComponent<UploadStatusProps, UploadStatusEvents, UploadStatusSlots> {
|
|
17
|
+
}
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
<script>import { getContext } from "svelte";
|
|
2
|
+
import { STYLES_CONTEXT } from "../styles";
|
|
3
|
+
export let item;
|
|
4
|
+
export let first;
|
|
5
|
+
export let last;
|
|
6
|
+
export let moveUp;
|
|
7
|
+
export let moveDown;
|
|
8
|
+
const styles = getContext(STYLES_CONTEXT);
|
|
9
|
+
</script>
|
|
10
|
+
|
|
11
|
+
<div class="field-builder-reorder">
|
|
12
|
+
<button
|
|
13
|
+
type="button"
|
|
14
|
+
class="field-builder-reorder-up {$styles.button ?? ''}"
|
|
15
|
+
data-size="icon"
|
|
16
|
+
disabled={first}
|
|
17
|
+
on:click={moveUp}
|
|
18
|
+
aria-label="Move {item} up">↑</button
|
|
19
|
+
>
|
|
20
|
+
<button
|
|
21
|
+
type="button"
|
|
22
|
+
class="field-builder-reorder-down {$styles.button ?? ''}"
|
|
23
|
+
data-size="icon"
|
|
24
|
+
disabled={last}
|
|
25
|
+
on:click={moveDown}
|
|
26
|
+
aria-label="Move {item} down">↓</button
|
|
27
|
+
>
|
|
28
|
+
</div>
|
|
29
|
+
|
|
30
|
+
<style>
|
|
31
|
+
.field-builder-reorder {
|
|
32
|
+
display: flex;
|
|
33
|
+
flex: none;
|
|
34
|
+
}
|
|
35
|
+
</style>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { SvelteComponent } from "svelte";
|
|
2
|
+
declare const __propDef: {
|
|
3
|
+
props: {
|
|
4
|
+
item: string;
|
|
5
|
+
first: boolean;
|
|
6
|
+
last: boolean;
|
|
7
|
+
moveUp: () => void;
|
|
8
|
+
moveDown: () => void;
|
|
9
|
+
};
|
|
10
|
+
events: {
|
|
11
|
+
[evt: string]: CustomEvent<any>;
|
|
12
|
+
};
|
|
13
|
+
slots: {};
|
|
14
|
+
exports?: {} | undefined;
|
|
15
|
+
bindings?: string | undefined;
|
|
16
|
+
};
|
|
17
|
+
export type FieldBuilderReorderProps = typeof __propDef.props;
|
|
18
|
+
export type FieldBuilderReorderEvents = typeof __propDef.events;
|
|
19
|
+
export type FieldBuilderReorderSlots = typeof __propDef.slots;
|
|
20
|
+
export default class FieldBuilderReorder extends SvelteComponent<FieldBuilderReorderProps, FieldBuilderReorderEvents, FieldBuilderReorderSlots> {
|
|
21
|
+
}
|
|
22
|
+
export {};
|
|
@@ -10,16 +10,17 @@
|
|
|
10
10
|
};
|
|
11
11
|
</script>
|
|
12
12
|
|
|
13
|
-
<script>import {
|
|
14
|
-
import * as Collapsible from "@stubber/ui/collapsible";
|
|
15
|
-
import { Label } from "@stubber/ui/label";
|
|
13
|
+
<script>import { getContext } from "svelte";
|
|
16
14
|
import { get as get_store_value } from "svelte/store";
|
|
17
15
|
import FieldExprToggle from "../FieldExprToggle.svelte";
|
|
18
16
|
import FieldMessage from "../FieldMessage.svelte";
|
|
19
17
|
import FormField from "../form-field.svelte";
|
|
18
|
+
import CollapsibleSection from "../CollapsibleSection.svelte";
|
|
19
|
+
import { STYLES_CONTEXT } from "../styles";
|
|
20
20
|
import { build_field } from "../utils";
|
|
21
21
|
import { validate_field } from "../validations/validate_field";
|
|
22
22
|
export let fieldStore;
|
|
23
|
+
const styles = getContext(STYLES_CONTEXT);
|
|
23
24
|
const new_entry_field = $fieldStore?.params?.new_entry_field || {
|
|
24
25
|
fieldtype: "text"
|
|
25
26
|
};
|
|
@@ -95,45 +96,110 @@ const validate_sub_fields = async (field) => {
|
|
|
95
96
|
};
|
|
96
97
|
</script>
|
|
97
98
|
|
|
98
|
-
<
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
99
|
+
<div
|
|
100
|
+
class="array-builder-field"
|
|
101
|
+
class:array-builder-field-invalid={section_has_errors}
|
|
102
|
+
aria-invalid={section_has_errors ? true : undefined}
|
|
103
|
+
>
|
|
104
|
+
<CollapsibleSection
|
|
105
|
+
title={$fieldStore.label}
|
|
106
|
+
bind:open
|
|
107
|
+
contentId="content-{$fieldStore.id}"
|
|
108
|
+
labelledBy="label-{$fieldStore.id}"
|
|
109
|
+
>
|
|
110
|
+
<div slot="heading" class="array-builder-heading">
|
|
111
|
+
<span id="label-{$fieldStore.id}" class="array-builder-label">
|
|
112
|
+
{$fieldStore.label}
|
|
113
|
+
</span>
|
|
102
114
|
<FieldMessage {fieldStore} />
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
{:else}
|
|
108
|
-
<i class="fa fa-caret-right pr-1" />
|
|
109
|
-
{/if}
|
|
110
|
-
<FieldExprToggle {fieldStore} />
|
|
111
|
-
</div>
|
|
112
|
-
</Button>
|
|
113
|
-
</Collapsible.Trigger>
|
|
114
|
-
<Collapsible.Content class="flex flex-col gap-y-1 pl-2">
|
|
115
|
+
</div>
|
|
116
|
+
<div slot="actions" class="array-builder-header-actions">
|
|
117
|
+
<FieldExprToggle {fieldStore} />
|
|
118
|
+
</div>
|
|
115
119
|
{#each $fieldStore.sub_fields || [] as sub_field, index (get_store_value(sub_field).id)}
|
|
116
|
-
<div class="
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
<Button variant="ghost" class="h-6 w-6 p-2" on:click={() => move_value_up(index)}>
|
|
120
|
-
<i class="fa fa-chevron-up" />
|
|
121
|
-
</Button>
|
|
122
|
-
<Button variant="ghost" class="h-6 w-6 p-2" on:click={() => move_value_down(index)}>
|
|
123
|
-
<i class="fa fa-chevron-down" />
|
|
124
|
-
</Button>
|
|
120
|
+
<div class="array-builder-item">
|
|
121
|
+
<div class="array-builder-value">
|
|
122
|
+
<FormField fieldStore={sub_field} />
|
|
125
123
|
</div>
|
|
126
|
-
<
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
124
|
+
<button
|
|
125
|
+
type="button"
|
|
126
|
+
class={$styles.button}
|
|
127
|
+
data-size="icon"
|
|
128
|
+
disabled={index === 0}
|
|
129
|
+
aria-label="Move {$fieldStore.label} item {index + 1} up"
|
|
130
|
+
on:click={() => move_value_up(index)}
|
|
131
|
+
>
|
|
132
|
+
<span aria-hidden="true">↑</span>
|
|
133
|
+
</button>
|
|
134
|
+
<button
|
|
135
|
+
type="button"
|
|
136
|
+
class={$styles.button}
|
|
137
|
+
data-size="icon"
|
|
138
|
+
disabled={index === array_value.length - 1}
|
|
139
|
+
aria-label="Move {$fieldStore.label} item {index + 1} down"
|
|
140
|
+
on:click={() => move_value_down(index)}
|
|
141
|
+
>
|
|
142
|
+
<span aria-hidden="true">↓</span>
|
|
143
|
+
</button>
|
|
144
|
+
<button
|
|
145
|
+
type="button"
|
|
146
|
+
class={$styles.button}
|
|
147
|
+
data-variant="destructive"
|
|
148
|
+
data-size="icon"
|
|
149
|
+
aria-label="Remove {$fieldStore.label} item {index + 1}"
|
|
150
|
+
on:click={() => remove_value(index)}
|
|
151
|
+
>
|
|
152
|
+
<span aria-hidden="true">×</span>
|
|
153
|
+
</button>
|
|
130
154
|
</div>
|
|
131
155
|
{/each}
|
|
132
|
-
<div class="
|
|
133
|
-
<
|
|
134
|
-
|
|
135
|
-
|
|
156
|
+
<div class="array-builder-footer">
|
|
157
|
+
<button
|
|
158
|
+
type="button"
|
|
159
|
+
class={$styles.button}
|
|
160
|
+
data-variant="primary"
|
|
161
|
+
aria-label="Add {$fieldStore.label} item"
|
|
162
|
+
on:click={add_value}
|
|
163
|
+
>
|
|
164
|
+
<span aria-hidden="true">+</span>
|
|
165
|
+
<span>Add item</span>
|
|
166
|
+
</button>
|
|
136
167
|
<FieldExprToggle {fieldStore} />
|
|
137
168
|
</div>
|
|
138
|
-
</
|
|
139
|
-
</
|
|
169
|
+
</CollapsibleSection>
|
|
170
|
+
</div>
|
|
171
|
+
|
|
172
|
+
<style>
|
|
173
|
+
.array-builder-field,
|
|
174
|
+
.array-builder-item,
|
|
175
|
+
.array-builder-value {
|
|
176
|
+
box-sizing: border-box;
|
|
177
|
+
width: 100%;
|
|
178
|
+
min-width: 0;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
.array-builder-header-actions,
|
|
182
|
+
.array-builder-reorder-actions,
|
|
183
|
+
.array-builder-footer {
|
|
184
|
+
display: flex;
|
|
185
|
+
align-items: center;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
.array-builder-heading,
|
|
189
|
+
.array-builder-value {
|
|
190
|
+
flex: 1;
|
|
191
|
+
min-width: 0;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
.array-builder-header-actions,
|
|
195
|
+
.array-builder-reorder-actions,
|
|
196
|
+
.array-builder-remove {
|
|
197
|
+
flex: none;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
.array-builder-item {
|
|
201
|
+
display: flex;
|
|
202
|
+
align-items: center;
|
|
203
|
+
gap: 0.5rem;
|
|
204
|
+
}
|
|
205
|
+
</style>
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
<script context="module"></script>
|
|
2
|
+
|
|
3
|
+
<script>import { getContext } from "svelte";
|
|
4
|
+
import ChevronDownIcon from "../icons/ChevronDownIcon.svelte";
|
|
5
|
+
import { STYLES_CONTEXT, classNames } from "../styles";
|
|
6
|
+
import CheckboxField, {} from "./checkbox-field.svelte";
|
|
7
|
+
import SmartTextField, {} from "./smart-text-field.svelte";
|
|
8
|
+
import { isEqual } from "lodash-es";
|
|
9
|
+
export let fieldStore;
|
|
10
|
+
const styles = getContext(STYLES_CONTEXT);
|
|
11
|
+
$fieldStore.without_value_details = true;
|
|
12
|
+
let selected_option = $fieldStore.value === void 0 || typeof $fieldStore.value === "boolean" || isEqual($fieldStore.value, $fieldStore.params?.checkedvalue || true) ? "Checkbox" : "Smart Text";
|
|
13
|
+
const options = ["Checkbox", "Smart Text"];
|
|
14
|
+
let open = false;
|
|
15
|
+
function select_option(new_option) {
|
|
16
|
+
selected_option = new_option;
|
|
17
|
+
switch (selected_option) {
|
|
18
|
+
case "Checkbox":
|
|
19
|
+
$fieldStore.value = false;
|
|
20
|
+
break;
|
|
21
|
+
case "Smart Text":
|
|
22
|
+
$fieldStore.value = "";
|
|
23
|
+
break;
|
|
24
|
+
default:
|
|
25
|
+
break;
|
|
26
|
+
}
|
|
27
|
+
open = false;
|
|
28
|
+
}
|
|
29
|
+
function handle_focusout(event) {
|
|
30
|
+
const nextTarget = event.relatedTarget;
|
|
31
|
+
const currentTarget = event.currentTarget;
|
|
32
|
+
if (!(nextTarget instanceof Node) || !currentTarget.contains(nextTarget)) open = false;
|
|
33
|
+
}
|
|
34
|
+
function handle_keydown(event) {
|
|
35
|
+
if (event.key === "Escape" && open) {
|
|
36
|
+
event.preventDefault();
|
|
37
|
+
open = false;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function preserve_mouse_focus(node) {
|
|
41
|
+
const prevent_default = (event) => event.preventDefault();
|
|
42
|
+
node.addEventListener("mousedown", prevent_default);
|
|
43
|
+
return {
|
|
44
|
+
destroy: () => node.removeEventListener("mousedown", prevent_default)
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
</script>
|
|
48
|
+
|
|
49
|
+
<svelte:window on:keydown={handle_keydown} />
|
|
50
|
+
|
|
51
|
+
<div class="checkbox-autocomplete">
|
|
52
|
+
<div class="popover" on:focusout={handle_focusout}>
|
|
53
|
+
<button
|
|
54
|
+
type="button"
|
|
55
|
+
class={classNames("trigger", $styles.button)}
|
|
56
|
+
data-size="icon"
|
|
57
|
+
aria-label="Choose input type"
|
|
58
|
+
aria-haspopup="dialog"
|
|
59
|
+
aria-expanded={open}
|
|
60
|
+
aria-controls="checkbox-autocomplete-menu-{$fieldStore.id}"
|
|
61
|
+
on:click={() => (open = !open)}
|
|
62
|
+
>
|
|
63
|
+
<span class:indicator-open={open} class="indicator" aria-hidden="true">
|
|
64
|
+
<ChevronDownIcon />
|
|
65
|
+
</span>
|
|
66
|
+
</button>
|
|
67
|
+
{#if open}
|
|
68
|
+
<div
|
|
69
|
+
id="checkbox-autocomplete-menu-{$fieldStore.id}"
|
|
70
|
+
class={classNames("popup", $styles.popover)}
|
|
71
|
+
role="dialog"
|
|
72
|
+
aria-label="Choose input type"
|
|
73
|
+
use:preserve_mouse_focus
|
|
74
|
+
>
|
|
75
|
+
<div class="option-list" role="radiogroup">
|
|
76
|
+
{#each options as option}
|
|
77
|
+
<label
|
|
78
|
+
class={classNames("option", $styles.option)}
|
|
79
|
+
data-selected={selected_option === option ? true : undefined}
|
|
80
|
+
>
|
|
81
|
+
<input
|
|
82
|
+
class={$styles.choice}
|
|
83
|
+
type="radio"
|
|
84
|
+
name="checkbox-autocomplete-mode-{$fieldStore.id}"
|
|
85
|
+
value={option}
|
|
86
|
+
checked={selected_option === option}
|
|
87
|
+
on:change={() => select_option(option)}
|
|
88
|
+
/>
|
|
89
|
+
<span>{option}</span>
|
|
90
|
+
</label>
|
|
91
|
+
{/each}
|
|
92
|
+
</div>
|
|
93
|
+
</div>
|
|
94
|
+
{/if}
|
|
95
|
+
</div>
|
|
96
|
+
{#if selected_option === "Smart Text"}
|
|
97
|
+
<div class="mode-field">
|
|
98
|
+
<SmartTextField {fieldStore} />
|
|
99
|
+
</div>
|
|
100
|
+
{:else}
|
|
101
|
+
<div class="mode-field">
|
|
102
|
+
<CheckboxField {fieldStore} />
|
|
103
|
+
</div>
|
|
104
|
+
{/if}
|
|
105
|
+
</div>
|
|
106
|
+
|
|
107
|
+
<style>
|
|
108
|
+
.checkbox-autocomplete {
|
|
109
|
+
display: flex;
|
|
110
|
+
align-items: flex-start;
|
|
111
|
+
min-width: 0;
|
|
112
|
+
width: 100%;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.popover {
|
|
116
|
+
position: relative;
|
|
117
|
+
flex: none;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
.trigger {
|
|
121
|
+
display: inline-flex;
|
|
122
|
+
align-items: center;
|
|
123
|
+
justify-content: center;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.indicator {
|
|
127
|
+
display: inline-flex;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
.popup {
|
|
131
|
+
position: absolute;
|
|
132
|
+
z-index: 20;
|
|
133
|
+
top: calc(100% + 0.25rem);
|
|
134
|
+
left: 0;
|
|
135
|
+
min-width: 10rem;
|
|
136
|
+
overflow: hidden;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
.option-list {
|
|
140
|
+
display: flex;
|
|
141
|
+
flex-direction: column;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.option {
|
|
145
|
+
display: flex;
|
|
146
|
+
align-items: center;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
.mode-field {
|
|
150
|
+
flex: 1;
|
|
151
|
+
min-width: 0;
|
|
152
|
+
}
|
|
153
|
+
</style>
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
<script context="module">export const checkbox_field_param_spec = {
|
|
2
|
+
spec: {
|
|
3
|
+
fields: {
|
|
4
|
+
checkedvalue: {
|
|
5
|
+
fieldtype: "jsoneditor",
|
|
6
|
+
initvalue: { has_default: true, default: true }
|
|
7
|
+
},
|
|
8
|
+
uncheckedvalue: {
|
|
9
|
+
fieldtype: "jsoneditor",
|
|
10
|
+
initvalue: { has_default: true, default: false }
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
</script>
|
|
16
|
+
|
|
17
|
+
<script>import { isEqual } from "lodash-es";
|
|
18
|
+
import { getContext } from "svelte";
|
|
19
|
+
import FieldLabel from "../FieldLabel.svelte";
|
|
20
|
+
import FieldMessage from "../FieldMessage.svelte";
|
|
21
|
+
import { STYLES_CONTEXT } from "../styles";
|
|
22
|
+
import { set_value_details } from "../utils";
|
|
23
|
+
export let fieldStore;
|
|
24
|
+
const styles = getContext(STYLES_CONTEXT);
|
|
25
|
+
set_value_details($fieldStore, "label", $fieldStore.label);
|
|
26
|
+
$: checked = isEqual($fieldStore.value, $fieldStore.params?.checkedvalue ?? true);
|
|
27
|
+
const on_change = (event) => {
|
|
28
|
+
const new_value = event.currentTarget.checked;
|
|
29
|
+
const checked_value = $fieldStore.params?.checkedvalue ?? true;
|
|
30
|
+
const unchecked_value = $fieldStore.params?.uncheckedvalue ?? false;
|
|
31
|
+
if (new_value) {
|
|
32
|
+
$fieldStore.value = checked_value;
|
|
33
|
+
} else {
|
|
34
|
+
$fieldStore.value = unchecked_value;
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
</script>
|
|
38
|
+
|
|
39
|
+
<div class="checkbox-field">
|
|
40
|
+
<div
|
|
41
|
+
class="checkbox-line"
|
|
42
|
+
aria-invalid={$fieldStore.validation_result?.type === "error" ? true : undefined}
|
|
43
|
+
>
|
|
44
|
+
<input
|
|
45
|
+
class={$styles.choice}
|
|
46
|
+
id={$fieldStore.id}
|
|
47
|
+
type="checkbox"
|
|
48
|
+
{checked}
|
|
49
|
+
aria-invalid={$fieldStore.validation_result?.type === "error" ? true : undefined}
|
|
50
|
+
aria-describedby="message-{$fieldStore.id}"
|
|
51
|
+
on:change={on_change}
|
|
52
|
+
/>
|
|
53
|
+
<FieldLabel {fieldStore} with_margin={false} />
|
|
54
|
+
</div>
|
|
55
|
+
<FieldMessage {fieldStore} />
|
|
56
|
+
</div>
|
|
57
|
+
|
|
58
|
+
<style>
|
|
59
|
+
.checkbox-field {
|
|
60
|
+
display: flex;
|
|
61
|
+
flex-direction: column;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.checkbox-line {
|
|
65
|
+
display: flex;
|
|
66
|
+
align-items: center;
|
|
67
|
+
gap: 0.5rem;
|
|
68
|
+
}
|
|
69
|
+
</style>
|
|
@@ -14,10 +14,12 @@
|
|
|
14
14
|
};
|
|
15
15
|
</script>
|
|
16
16
|
|
|
17
|
-
<script>import {
|
|
17
|
+
<script>import { getContext } from "svelte";
|
|
18
|
+
import { STYLES_CONTEXT, classNames } from "../styles";
|
|
18
19
|
import SelectField, {
|
|
19
20
|
} from "./select-field.svelte";
|
|
20
21
|
export let fieldStore;
|
|
22
|
+
const styles = getContext(STYLES_CONTEXT);
|
|
21
23
|
const params = $fieldStore.params || {};
|
|
22
24
|
const dependencies = $fieldStore.formDependencies;
|
|
23
25
|
const createWantToModal = dependencies?.createWantToModal;
|
|
@@ -69,12 +71,13 @@ const load_options = async (search_term) => {
|
|
|
69
71
|
</script>
|
|
70
72
|
|
|
71
73
|
<SelectField {fieldStore} {load_options}>
|
|
72
|
-
<
|
|
74
|
+
<button
|
|
75
|
+
type="button"
|
|
76
|
+
class={$styles.button}
|
|
77
|
+
data-variant="primary"
|
|
73
78
|
on:click={show_create_contact_modal}
|
|
74
|
-
variant="ghost"
|
|
75
|
-
class="ml-auto text-sm text-surface-500 hover:text-surface-700"
|
|
76
79
|
>
|
|
77
|
-
<
|
|
80
|
+
<span aria-hidden="true">+</span>
|
|
78
81
|
Create new contact
|
|
79
|
-
</
|
|
82
|
+
</button>
|
|
80
83
|
</SelectField>
|