@stubber/form-fields 1.4.5 → 1.5.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 +61 -295
- package/dist/fields/components/Signature.svelte +9 -5
- package/dist/fields2/FieldLabel.svelte +8 -0
- package/dist/fields2/FieldLabel.svelte.d.ts +20 -0
- package/dist/fields2/FieldMessage.svelte +16 -0
- package/dist/fields2/FieldMessage.svelte.d.ts +20 -0
- package/dist/fields2/Form.svelte +29 -0
- package/dist/fields2/Form.svelte.d.ts +23 -0
- package/dist/fields2/fileserver.d.ts +15 -0
- package/dist/fields2/fileserver.js +52 -0
- package/dist/fields2/form-field.svelte +10 -0
- package/dist/fields2/form-field.svelte.d.ts +20 -0
- package/dist/fields2/interfaces.d.ts +207 -0
- package/dist/fields2/interfaces.js +82 -0
- package/dist/fields2/sub/array-builder-field.svelte +110 -0
- package/dist/fields2/sub/array-builder-field.svelte.d.ts +27 -0
- package/dist/fields2/sub/checkbox-autocomplete.svelte +56 -0
- package/dist/fields2/sub/checkbox-autocomplete.svelte.d.ts +27 -0
- package/dist/fields2/sub/checkbox-field.svelte +41 -0
- package/dist/fields2/sub/checkbox-field.svelte.d.ts +28 -0
- package/dist/fields2/sub/code-field.svelte +146 -0
- package/dist/fields2/sub/code-field.svelte.d.ts +27 -0
- package/dist/fields2/sub/contact-selector-field.svelte +84 -0
- package/dist/fields2/sub/contact-selector-field.svelte.d.ts +30 -0
- package/dist/fields2/sub/currency-field.svelte +197 -0
- package/dist/fields2/sub/currency-field.svelte.d.ts +29 -0
- package/dist/fields2/sub/data-indication-field.svelte +19 -0
- package/dist/fields2/sub/data-indication-field.svelte.d.ts +23 -0
- package/dist/fields2/sub/date-field.svelte +31 -0
- package/dist/fields2/sub/date-field.svelte.d.ts +23 -0
- package/dist/fields2/sub/date-time-field.svelte +31 -0
- package/dist/fields2/sub/date-time-field.svelte.d.ts +23 -0
- package/dist/fields2/sub/email-field.svelte +40 -0
- package/dist/fields2/sub/email-field.svelte.d.ts +23 -0
- package/dist/fields2/sub/field-builder-field.svelte +525 -0
- package/dist/fields2/sub/field-builder-field.svelte.d.ts +23 -0
- package/dist/fields2/sub/file-field.svelte +150 -0
- package/dist/fields2/sub/file-field.svelte.d.ts +27 -0
- package/dist/fields2/sub/grid-field.svelte +54 -0
- package/dist/fields2/sub/grid-field.svelte.d.ts +30 -0
- package/dist/fields2/sub/heading-field.svelte +28 -0
- package/dist/fields2/sub/heading-field.svelte.d.ts +28 -0
- package/dist/fields2/sub/hidden-field.svelte +142 -0
- package/dist/fields2/sub/hidden-field.svelte.d.ts +37 -0
- package/dist/fields2/sub/hidden-location-field.svelte +23 -0
- package/dist/fields2/sub/hidden-location-field.svelte.d.ts +23 -0
- package/dist/fields2/sub/html-field.svelte +22 -0
- package/dist/fields2/sub/html-field.svelte.d.ts +27 -0
- package/dist/fields2/sub/json-editor-bound.svelte +17 -0
- package/dist/fields2/sub/json-editor-bound.svelte.d.ts +65 -0
- package/dist/fields2/sub/jsoneditor-field.svelte +23 -0
- package/dist/fields2/sub/jsoneditor-field.svelte.d.ts +27 -0
- package/dist/fields2/sub/map-field.svelte +144 -0
- package/dist/fields2/sub/map-field.svelte.d.ts +28 -0
- package/dist/fields2/sub/multi-checkbox-field.svelte +83 -0
- package/dist/fields2/sub/multi-checkbox-field.svelte.d.ts +34 -0
- package/dist/fields2/sub/multistep-field.svelte +70 -0
- package/dist/fields2/sub/multistep-field.svelte.d.ts +24 -0
- package/dist/fields2/sub/note-field.svelte +18 -0
- package/dist/fields2/sub/note-field.svelte.d.ts +23 -0
- package/dist/fields2/sub/number-field.svelte +77 -0
- package/dist/fields2/sub/number-field.svelte.d.ts +29 -0
- package/dist/fields2/sub/object-builder-field.svelte +123 -0
- package/dist/fields2/sub/object-builder-field.svelte.d.ts +28 -0
- package/dist/fields2/sub/qr-code-scanner-field.svelte +86 -0
- package/dist/fields2/sub/qr-code-scanner-field.svelte.d.ts +23 -0
- package/dist/fields2/sub/radio-field.svelte +69 -0
- package/dist/fields2/sub/radio-field.svelte.d.ts +30 -0
- package/dist/fields2/sub/screenrecorder-field.svelte +182 -0
- package/dist/fields2/sub/screenrecorder-field.svelte.d.ts +27 -0
- package/dist/fields2/sub/screenshot-field.svelte +165 -0
- package/dist/fields2/sub/screenshot-field.svelte.d.ts +26 -0
- package/dist/fields2/sub/scroll-and-read-display-field.svelte +92 -0
- package/dist/fields2/sub/scroll-and-read-display-field.svelte.d.ts +29 -0
- package/dist/fields2/sub/section-field.svelte +27 -0
- package/dist/fields2/sub/section-field.svelte.d.ts +26 -0
- package/dist/fields2/sub/select-field.svelte +138 -0
- package/dist/fields2/sub/select-field.svelte.d.ts +34 -0
- package/dist/fields2/sub/selectresource-field.svelte +69 -0
- package/dist/fields2/sub/selectresource-field.svelte.d.ts +29 -0
- package/dist/fields2/sub/signature-field.svelte +84 -0
- package/dist/fields2/sub/signature-field.svelte.d.ts +23 -0
- package/dist/fields2/sub/slider-field.svelte +28 -0
- package/dist/fields2/sub/slider-field.svelte.d.ts +28 -0
- package/dist/fields2/sub/smart-text-field.svelte +245 -0
- package/dist/fields2/sub/smart-text-field.svelte.d.ts +36 -0
- package/dist/fields2/sub/telephone-field.svelte +68 -0
- package/dist/fields2/sub/telephone-field.svelte.d.ts +26 -0
- package/dist/fields2/sub/text-field.svelte +46 -0
- package/dist/fields2/sub/text-field.svelte.d.ts +27 -0
- package/dist/fields2/sub/voicenote-field.svelte +161 -0
- package/dist/fields2/sub/voicenote-field.svelte.d.ts +26 -0
- package/dist/fields2/utils.d.ts +9 -0
- package/dist/fields2/utils.js +116 -0
- package/dist/fields2/validations/validate_field.d.ts +11 -0
- package/dist/fields2/validations/validate_field.js +121 -0
- package/package.json +6 -9
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
<script context="module">import {} from "../interfaces";
|
|
2
|
+
</script>
|
|
3
|
+
|
|
4
|
+
<script>import { Textarea } from "@stubber/ui/textarea";
|
|
5
|
+
import { Button } from "@stubber/ui/button";
|
|
6
|
+
import SignaturePad from "signature_pad";
|
|
7
|
+
import FieldLabel from "../FieldLabel.svelte";
|
|
8
|
+
import FieldMessage from "../FieldMessage.svelte";
|
|
9
|
+
import { onMount } from "svelte";
|
|
10
|
+
import { append_attachment, remove_attachment, uploadFiles } from "../fileserver";
|
|
11
|
+
import { debounce, snakeCase } from "lodash-es";
|
|
12
|
+
export let fieldStore;
|
|
13
|
+
let canvasContainer;
|
|
14
|
+
let pad;
|
|
15
|
+
let signaturePad;
|
|
16
|
+
onMount(() => {
|
|
17
|
+
signaturePad = new SignaturePad(pad);
|
|
18
|
+
signaturePad.addEventListener("endStroke", handleStroke);
|
|
19
|
+
if ($fieldStore.value?.data) {
|
|
20
|
+
setTimeout(() => {
|
|
21
|
+
signaturePad.fromData($fieldStore.value?.data);
|
|
22
|
+
}, 0);
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
function clear() {
|
|
26
|
+
signaturePad.clear();
|
|
27
|
+
if ($fieldStore.value) {
|
|
28
|
+
$fieldStore.value = {};
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function handleStroke() {
|
|
32
|
+
const data = signaturePad.toData();
|
|
33
|
+
if (!$fieldStore.value) {
|
|
34
|
+
$fieldStore.value = {};
|
|
35
|
+
}
|
|
36
|
+
$fieldStore.value = {
|
|
37
|
+
...$fieldStore.value,
|
|
38
|
+
data
|
|
39
|
+
};
|
|
40
|
+
is_uploading = true;
|
|
41
|
+
debounced_uploadFile();
|
|
42
|
+
}
|
|
43
|
+
let is_uploading = false;
|
|
44
|
+
$: canvasWidth = canvasContainer?.clientWidth;
|
|
45
|
+
async function uploadFile() {
|
|
46
|
+
const fileURI = signaturePad.toDataURL();
|
|
47
|
+
const fileBlob = await (await fetch(fileURI)).blob();
|
|
48
|
+
const file = new File([fileBlob], `${snakeCase($fieldStore.label)}.png`, { type: "image/png" });
|
|
49
|
+
const upload_res = await uploadFiles([file], $fieldStore.formDependencies);
|
|
50
|
+
const { uploaded_files = [] } = upload_res || {};
|
|
51
|
+
if (uploaded_files?.length) {
|
|
52
|
+
const prev_file = $fieldStore.value?.file;
|
|
53
|
+
if (prev_file && prev_file.fileuuid) {
|
|
54
|
+
remove_attachment(prev_file.fileuuid, $fieldStore.attachmentsStore);
|
|
55
|
+
}
|
|
56
|
+
$fieldStore.value = {
|
|
57
|
+
...$fieldStore.value,
|
|
58
|
+
file: uploaded_files[0]
|
|
59
|
+
};
|
|
60
|
+
append_attachment(uploaded_files[0], $fieldStore.attachmentsStore);
|
|
61
|
+
}
|
|
62
|
+
is_uploading = false;
|
|
63
|
+
}
|
|
64
|
+
const debounced_uploadFile = debounce(uploadFile, 1e3);
|
|
65
|
+
</script>
|
|
66
|
+
|
|
67
|
+
<FieldLabel {fieldStore} />
|
|
68
|
+
<div bind:this={canvasContainer}>
|
|
69
|
+
<canvas
|
|
70
|
+
bind:this={pad}
|
|
71
|
+
id="signature-pad"
|
|
72
|
+
class="signature-pad mt-2 rounded-md border"
|
|
73
|
+
width={canvasWidth}
|
|
74
|
+
height={200}
|
|
75
|
+
/>
|
|
76
|
+
<div class="mt-1 flex items-center justify-between">
|
|
77
|
+
<Button variant="ghost" on:click={clear} type="button">Clear</Button>
|
|
78
|
+
|
|
79
|
+
{#if is_uploading}
|
|
80
|
+
<i class="fa fa-pulse fa-spinner text-surface-500" />
|
|
81
|
+
{/if}
|
|
82
|
+
</div>
|
|
83
|
+
</div>
|
|
84
|
+
<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 ISignatureField extends IBaseField<{}> {
|
|
5
|
+
fieldtype: "signature";
|
|
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 SignatureFieldProps = typeof __propDef.props;
|
|
19
|
+
export type SignatureFieldEvents = typeof __propDef.events;
|
|
20
|
+
export type SignatureFieldSlots = typeof __propDef.slots;
|
|
21
|
+
export default class SignatureField extends SvelteComponent<SignatureFieldProps, SignatureFieldEvents, SignatureFieldSlots> {
|
|
22
|
+
}
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<script context="module"></script>
|
|
2
|
+
|
|
3
|
+
<script>import FieldLabel from "../FieldLabel.svelte";
|
|
4
|
+
import FieldMessage from "../FieldMessage.svelte";
|
|
5
|
+
export let fieldStore;
|
|
6
|
+
$: min = $fieldStore.min ?? 0;
|
|
7
|
+
$: max = $fieldStore.max ?? 100;
|
|
8
|
+
$: step = $fieldStore.step ?? 1;
|
|
9
|
+
</script>
|
|
10
|
+
|
|
11
|
+
<FieldLabel {fieldStore} />
|
|
12
|
+
<div class="relative">
|
|
13
|
+
<div class="flex justify-between items-end text-sm text-surface-300">
|
|
14
|
+
<div>{min}</div>
|
|
15
|
+
<div class="text-md text-surface-700">{$fieldStore.value || ""}</div>
|
|
16
|
+
<div>{max}</div>
|
|
17
|
+
</div>
|
|
18
|
+
<input
|
|
19
|
+
class="block w-full text-field rounded-md border-0 mb-2 focus:outline-none"
|
|
20
|
+
bind:value={$fieldStore.value}
|
|
21
|
+
{min}
|
|
22
|
+
{max}
|
|
23
|
+
{step}
|
|
24
|
+
type="range"
|
|
25
|
+
aria-invalid={$fieldStore.validation_result?.type == "error" ? true : undefined}
|
|
26
|
+
/>
|
|
27
|
+
</div>
|
|
28
|
+
<FieldMessage {fieldStore} />
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { SvelteComponent } from "svelte";
|
|
2
|
+
import type { Writable } from "svelte/store";
|
|
3
|
+
import type { IBaseField, IBuiltField } from "../interfaces";
|
|
4
|
+
interface INumberParams {
|
|
5
|
+
min?: number;
|
|
6
|
+
max?: number;
|
|
7
|
+
step?: number;
|
|
8
|
+
}
|
|
9
|
+
export interface ISliderField extends IBaseField<INumberParams> {
|
|
10
|
+
fieldtype: "slider";
|
|
11
|
+
}
|
|
12
|
+
declare const __propDef: {
|
|
13
|
+
props: {
|
|
14
|
+
fieldStore: Writable<IBuiltField>;
|
|
15
|
+
};
|
|
16
|
+
events: {
|
|
17
|
+
[evt: string]: CustomEvent<any>;
|
|
18
|
+
};
|
|
19
|
+
slots: {};
|
|
20
|
+
exports?: {} | undefined;
|
|
21
|
+
bindings?: string | undefined;
|
|
22
|
+
};
|
|
23
|
+
export type SliderFieldProps = typeof __propDef.props;
|
|
24
|
+
export type SliderFieldEvents = typeof __propDef.events;
|
|
25
|
+
export type SliderFieldSlots = typeof __propDef.slots;
|
|
26
|
+
export default class SliderField extends SvelteComponent<SliderFieldProps, SliderFieldEvents, SliderFieldSlots> {
|
|
27
|
+
}
|
|
28
|
+
export {};
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
<script context="module">import {} from "../interfaces";
|
|
2
|
+
export const smart_text_field_param_spec = {
|
|
3
|
+
spec: {
|
|
4
|
+
fields: {
|
|
5
|
+
parse_string: {
|
|
6
|
+
fieldtype: "checkbox",
|
|
7
|
+
without_value_details: true
|
|
8
|
+
},
|
|
9
|
+
code_language: {
|
|
10
|
+
fieldtype: "select",
|
|
11
|
+
without_value_details: true,
|
|
12
|
+
params: {
|
|
13
|
+
options: [
|
|
14
|
+
{ label: "Handlebars", value: "handlebars" },
|
|
15
|
+
{ label: "None", value: "none" }
|
|
16
|
+
]
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
auto_completions: {
|
|
20
|
+
fieldtype: "section",
|
|
21
|
+
fields: {
|
|
22
|
+
match_before: {
|
|
23
|
+
fieldtype: "text"
|
|
24
|
+
},
|
|
25
|
+
explicit: {
|
|
26
|
+
fieldtype: "checkbox",
|
|
27
|
+
without_value_details: true
|
|
28
|
+
},
|
|
29
|
+
options: {
|
|
30
|
+
fieldtype: "arraybuilder",
|
|
31
|
+
params: {
|
|
32
|
+
new_entry_field: {
|
|
33
|
+
fieldtype: "section",
|
|
34
|
+
fields: {
|
|
35
|
+
label: {
|
|
36
|
+
fieldtype: "text"
|
|
37
|
+
},
|
|
38
|
+
apply: {
|
|
39
|
+
fieldtype: "text"
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
</script>
|
|
51
|
+
|
|
52
|
+
<script>import {
|
|
53
|
+
acceptCompletion,
|
|
54
|
+
autocompletion,
|
|
55
|
+
CompletionContext,
|
|
56
|
+
completionKeymap
|
|
57
|
+
} from "@codemirror/autocomplete";
|
|
58
|
+
import { history } from "@codemirror/commands";
|
|
59
|
+
import { EditorState, StateField } from "@codemirror/state";
|
|
60
|
+
import {
|
|
61
|
+
Decoration,
|
|
62
|
+
EditorView,
|
|
63
|
+
keymap,
|
|
64
|
+
MatchDecorator,
|
|
65
|
+
placeholder,
|
|
66
|
+
ViewPlugin,
|
|
67
|
+
ViewUpdate
|
|
68
|
+
} from "@codemirror/view";
|
|
69
|
+
import { find } from "lodash-es";
|
|
70
|
+
import FieldLabel from "../FieldLabel.svelte";
|
|
71
|
+
import FieldMessage from "../FieldMessage.svelte";
|
|
72
|
+
export let fieldStore;
|
|
73
|
+
let editor_view;
|
|
74
|
+
$: validation_result = $fieldStore.validation_result;
|
|
75
|
+
$: type = validation_result?.type;
|
|
76
|
+
$: isValid = type !== "error";
|
|
77
|
+
$: is_object = typeof $fieldStore.value === "object";
|
|
78
|
+
$: parse_string = $fieldStore.params?.parse_string;
|
|
79
|
+
$: auto_completions = $fieldStore.params?.auto_completions || [];
|
|
80
|
+
$: code_language = $fieldStore.params?.code_language;
|
|
81
|
+
const setup_editor = (element) => {
|
|
82
|
+
const extensions = [
|
|
83
|
+
history({ newGroupDelay: 150 }),
|
|
84
|
+
EditorView.lineWrapping,
|
|
85
|
+
contentField,
|
|
86
|
+
autocompletion({ override: [myCompletions], defaultKeymap: false }),
|
|
87
|
+
tab_accept_completion,
|
|
88
|
+
placeholder($fieldStore.label),
|
|
89
|
+
EditorView.contentAttributes.of({
|
|
90
|
+
spellcheck: "true"
|
|
91
|
+
})
|
|
92
|
+
];
|
|
93
|
+
if (code_language === "handlebars") {
|
|
94
|
+
extensions.push(fake_handlebars_lang());
|
|
95
|
+
}
|
|
96
|
+
editor_view = new EditorView({
|
|
97
|
+
state: EditorState.create({
|
|
98
|
+
doc: $fieldStore.value,
|
|
99
|
+
extensions
|
|
100
|
+
}),
|
|
101
|
+
parent: element
|
|
102
|
+
});
|
|
103
|
+
};
|
|
104
|
+
const tab_accept_completion = keymap.of(
|
|
105
|
+
completionKeymap.filter((binding) => binding.key != "Enter").concat([
|
|
106
|
+
{
|
|
107
|
+
key: "Enter",
|
|
108
|
+
run: () => {
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
key: "Tab",
|
|
114
|
+
run: acceptCompletion
|
|
115
|
+
}
|
|
116
|
+
])
|
|
117
|
+
);
|
|
118
|
+
const contentField = StateField.define({
|
|
119
|
+
create() {
|
|
120
|
+
return "";
|
|
121
|
+
},
|
|
122
|
+
update(value, transaction) {
|
|
123
|
+
if (transaction.docChanged) {
|
|
124
|
+
$fieldStore.value = parse_string ? parse_string_value(transaction.newDoc.toString()) : transaction.newDoc.toString();
|
|
125
|
+
return transaction.newDoc.toString();
|
|
126
|
+
}
|
|
127
|
+
return value;
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
function fake_handlebars_lang() {
|
|
131
|
+
const curly_decorator = new MatchDecorator({
|
|
132
|
+
regexp: /(\{\{[^}]*\}\})|(~~[^\s]*)/g,
|
|
133
|
+
decoration: Decoration.mark({ class: "curly-braces-highlight" })
|
|
134
|
+
});
|
|
135
|
+
return ViewPlugin.fromClass(
|
|
136
|
+
class {
|
|
137
|
+
// blocks;
|
|
138
|
+
constructor(view) {
|
|
139
|
+
this.curlies = curly_decorator.createDeco(view);
|
|
140
|
+
}
|
|
141
|
+
update(update) {
|
|
142
|
+
this.curlies = curly_decorator.updateDeco(update, this.curlies);
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
decorations: (instance) => instance.curlies
|
|
147
|
+
}
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
function myCompletions(context) {
|
|
151
|
+
for (let completion of auto_completions) {
|
|
152
|
+
if (!completion.match_before) continue;
|
|
153
|
+
let before = context.matchBefore(new RegExp(completion.match_before));
|
|
154
|
+
if (!before) continue;
|
|
155
|
+
return {
|
|
156
|
+
from: before.from,
|
|
157
|
+
options: completion.options,
|
|
158
|
+
validFor: /^.*$/
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
let explicit_completions = find(auto_completions, { explicit: true });
|
|
162
|
+
if (explicit_completions && context.explicit) {
|
|
163
|
+
return {
|
|
164
|
+
from: context.pos,
|
|
165
|
+
options: explicit_completions.options,
|
|
166
|
+
validFor: /^.*$/
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
return null;
|
|
170
|
+
}
|
|
171
|
+
function parse_string_value(value) {
|
|
172
|
+
if (value === "true") return true;
|
|
173
|
+
if (value === "false") return false;
|
|
174
|
+
if (!isNaN(value) && value !== "") {
|
|
175
|
+
return Number(value);
|
|
176
|
+
}
|
|
177
|
+
return value;
|
|
178
|
+
}
|
|
179
|
+
</script>
|
|
180
|
+
|
|
181
|
+
<FieldLabel {fieldStore} />
|
|
182
|
+
{#if !is_object}
|
|
183
|
+
<div
|
|
184
|
+
use:setup_editor
|
|
185
|
+
class=" stubber-cm text-sm {isValid ? 'stubber-valid' : 'stubber-invalid'}"
|
|
186
|
+
/>
|
|
187
|
+
{:else}
|
|
188
|
+
<p class="text-surface-400">The value of this field is not a string.</p>
|
|
189
|
+
{/if}
|
|
190
|
+
<FieldMessage {fieldStore} />
|
|
191
|
+
|
|
192
|
+
<style>
|
|
193
|
+
.stubber-cm :global(.cm-editor) {
|
|
194
|
+
/* Base styles */
|
|
195
|
+
background-color: rgba(255, 255, 255, 0.85);
|
|
196
|
+
border-radius: 0.375rem;
|
|
197
|
+
--tw-border-opacity: 1;
|
|
198
|
+
border-color: hsl(var(--input) / var(--tw-border-opacity, 1));
|
|
199
|
+
border-width: 1px;
|
|
200
|
+
border-style: solid;
|
|
201
|
+
width: 100%;
|
|
202
|
+
color: rgb(31 41 51);
|
|
203
|
+
|
|
204
|
+
/* Top inset shadow only */
|
|
205
|
+
box-shadow: inset 0px 16px 16px -16px rgba(0, 0, 0, 0.1333);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
.stubber-cm :global(.cm-editor.cm-focused) {
|
|
209
|
+
outline: none;
|
|
210
|
+
border-width: 1px;
|
|
211
|
+
border-color: hsl(var(--input) / var(--tw-border-opacity, 1));
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
.stubber-cm.stubber-valid :global(.cm-editor.cm-focused) {
|
|
215
|
+
border-color: rgb(170, 170, 170, 0.5);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
.stubber-cm.stubber-invalid :global(.cm-editor) {
|
|
219
|
+
border-color: rgb(225 45 57);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
.stubber-cm :global(.cm-editor .cm-scroller) {
|
|
223
|
+
font-family: inherit;
|
|
224
|
+
line-height: inherit;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
.stubber-cm :global(.cm-editor .cm-content) {
|
|
228
|
+
padding: 0;
|
|
229
|
+
padding-top: 0.5rem;
|
|
230
|
+
padding-bottom: 0.5rem;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
.stubber-cm :global(.cm-editor .cm-line) {
|
|
234
|
+
padding: 0;
|
|
235
|
+
padding-left: 0.75rem;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
.stubber-cm :global(.cm-editor .cm-placeholder) {
|
|
239
|
+
color: hsl(var(--muted-foreground) / var(--tw-text-opacity, 1));
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
.stubber-cm :global(.curly-braces-highlight) {
|
|
243
|
+
color: rgb(9 103 210);
|
|
244
|
+
}
|
|
245
|
+
</style>
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { SvelteComponent } from "svelte";
|
|
2
|
+
import type { Writable } from "svelte/store";
|
|
3
|
+
import { type IBaseField, type IBuiltField, type IInitialForm } from "../interfaces";
|
|
4
|
+
export interface ISmartTextFieldParams {
|
|
5
|
+
parse_string?: boolean;
|
|
6
|
+
auto_completions?: Array<{
|
|
7
|
+
match_before?: string;
|
|
8
|
+
explicit?: boolean;
|
|
9
|
+
options: Array<{
|
|
10
|
+
label: string;
|
|
11
|
+
apply?: string;
|
|
12
|
+
}>;
|
|
13
|
+
}>;
|
|
14
|
+
code_language?: string;
|
|
15
|
+
}
|
|
16
|
+
export declare const smart_text_field_param_spec: IInitialForm;
|
|
17
|
+
export interface ISmartTextField extends IBaseField<ISmartTextFieldParams> {
|
|
18
|
+
fieldtype: "smart_text";
|
|
19
|
+
}
|
|
20
|
+
declare const __propDef: {
|
|
21
|
+
props: {
|
|
22
|
+
fieldStore: Writable<IBuiltField<ISmartTextFieldParams>>;
|
|
23
|
+
};
|
|
24
|
+
events: {
|
|
25
|
+
[evt: string]: CustomEvent<any>;
|
|
26
|
+
};
|
|
27
|
+
slots: {};
|
|
28
|
+
exports?: {} | undefined;
|
|
29
|
+
bindings?: string | undefined;
|
|
30
|
+
};
|
|
31
|
+
export type SmartTextFieldProps = typeof __propDef.props;
|
|
32
|
+
export type SmartTextFieldEvents = typeof __propDef.events;
|
|
33
|
+
export type SmartTextFieldSlots = typeof __propDef.slots;
|
|
34
|
+
export default class SmartTextField extends SvelteComponent<SmartTextFieldProps, SmartTextFieldEvents, SmartTextFieldSlots> {
|
|
35
|
+
}
|
|
36
|
+
export {};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
<script context="module">import {} from "../interfaces";
|
|
2
|
+
</script>
|
|
3
|
+
|
|
4
|
+
<script>import intlTelInput from "intl-tel-input";
|
|
5
|
+
import "intl-tel-input/build/css/intlTelInput.css";
|
|
6
|
+
import FieldLabel from "../FieldLabel.svelte";
|
|
7
|
+
import FieldMessage from "../FieldMessage.svelte";
|
|
8
|
+
import { set_value_details } from "../utils";
|
|
9
|
+
export let fieldStore;
|
|
10
|
+
let iti;
|
|
11
|
+
function setupInput(input_element) {
|
|
12
|
+
iti = intlTelInput(input_element, {
|
|
13
|
+
initialCountry: "auto",
|
|
14
|
+
geoIpLookup: (callback) => {
|
|
15
|
+
fetch("https://ipapi.co/json").then((res) => res.json()).then((data) => callback(data.country_code)).catch(() => callback("us"));
|
|
16
|
+
},
|
|
17
|
+
utilsScript: "https://cdn.jsdelivr.net/npm/intl-tel-input@18.2.1/build/js/utils.js"
|
|
18
|
+
});
|
|
19
|
+
const itis = document.querySelectorAll("div.iti");
|
|
20
|
+
itis.forEach((iti2) => {
|
|
21
|
+
iti2.style["width"] = "100%";
|
|
22
|
+
});
|
|
23
|
+
input_element.addEventListener("countrychange", () => set_number_details());
|
|
24
|
+
set_number_details();
|
|
25
|
+
}
|
|
26
|
+
$: if ($fieldStore.value) set_number_details();
|
|
27
|
+
let last_set_value = null;
|
|
28
|
+
function set_number_details(force = false) {
|
|
29
|
+
if (!iti) return;
|
|
30
|
+
if (!force && last_set_value === $fieldStore.value) return;
|
|
31
|
+
last_set_value = $fieldStore.value;
|
|
32
|
+
const formatted_number = iti.getNumber();
|
|
33
|
+
const is_valid = iti.isValidNumber();
|
|
34
|
+
const country_data = iti.getSelectedCountryData();
|
|
35
|
+
delete country_data?.node;
|
|
36
|
+
if (is_valid && (force || formatted_number !== $fieldStore.value)) {
|
|
37
|
+
$fieldStore.value = formatted_number;
|
|
38
|
+
}
|
|
39
|
+
if ($fieldStore.value) {
|
|
40
|
+
set_value_details($fieldStore, "details", {
|
|
41
|
+
is_valid_number: is_valid,
|
|
42
|
+
selected_country: country_data
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
if ($fieldStore.value) {
|
|
47
|
+
setTimeout(() => {
|
|
48
|
+
$fieldStore.value = $fieldStore.value || "";
|
|
49
|
+
set_number_details(true);
|
|
50
|
+
}, 100);
|
|
51
|
+
}
|
|
52
|
+
</script>
|
|
53
|
+
|
|
54
|
+
<FieldLabel {fieldStore} />
|
|
55
|
+
<div
|
|
56
|
+
class="w-full bg-surface-100 flex space-x-4 focus:outline-primary-400 relative mt-2 rounded-md"
|
|
57
|
+
>
|
|
58
|
+
<input
|
|
59
|
+
use:setupInput
|
|
60
|
+
bind:value={$fieldStore.value}
|
|
61
|
+
type="tel"
|
|
62
|
+
id={$fieldStore.id}
|
|
63
|
+
class="border-input bg-background selection:bg-primary dark:bg-input/30 selection:text-primary-foreground ring-offset-background placeholder:text-muted-foreground shadow-xs flex h-9 w-full min-w-0 rounded-md border px-3 py-1 text-base outline-none transition-[color,box-shadow] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-[invalid]:border-destructive aria-[invalid]:ring-destructive/50 aria-[invalid]:focus-visible:ring-destructive/50"
|
|
64
|
+
aria-invalid={$fieldStore.validation_result?.type == "error" ? true : undefined}
|
|
65
|
+
aria-describedby="message-{$fieldStore.id}"
|
|
66
|
+
/>
|
|
67
|
+
</div>
|
|
68
|
+
<FieldMessage {fieldStore} />
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { SvelteComponent } from "svelte";
|
|
2
|
+
import type { Writable } from "svelte/store";
|
|
3
|
+
import { type IBaseField, type IBuiltField } from "../interfaces";
|
|
4
|
+
export interface ITelephoneFieldParams {
|
|
5
|
+
}
|
|
6
|
+
export interface ITelephoneField extends IBaseField<ITelephoneFieldParams> {
|
|
7
|
+
fieldtype: "telephone";
|
|
8
|
+
}
|
|
9
|
+
import "intl-tel-input/build/css/intlTelInput.css";
|
|
10
|
+
declare const __propDef: {
|
|
11
|
+
props: {
|
|
12
|
+
fieldStore: Writable<IBuiltField<ITelephoneFieldParams>>;
|
|
13
|
+
};
|
|
14
|
+
events: {
|
|
15
|
+
[evt: string]: CustomEvent<any>;
|
|
16
|
+
};
|
|
17
|
+
slots: {};
|
|
18
|
+
exports?: {} | undefined;
|
|
19
|
+
bindings?: string | undefined;
|
|
20
|
+
};
|
|
21
|
+
export type TelephoneFieldProps = typeof __propDef.props;
|
|
22
|
+
export type TelephoneFieldEvents = typeof __propDef.events;
|
|
23
|
+
export type TelephoneFieldSlots = typeof __propDef.slots;
|
|
24
|
+
export default class TelephoneField extends SvelteComponent<TelephoneFieldProps, TelephoneFieldEvents, TelephoneFieldSlots> {
|
|
25
|
+
}
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
<script context="module">import {} from "../interfaces";
|
|
2
|
+
export const text_field_param_spec = {
|
|
3
|
+
spec: {
|
|
4
|
+
fields: {
|
|
5
|
+
parse_string: {
|
|
6
|
+
fieldtype: "checkbox",
|
|
7
|
+
without_value_details: true
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<script>import { Input } from "@stubber/ui/input";
|
|
15
|
+
import FieldLabel from "../FieldLabel.svelte";
|
|
16
|
+
import FieldMessage from "../FieldMessage.svelte";
|
|
17
|
+
export let fieldStore;
|
|
18
|
+
function parse_string_value(value) {
|
|
19
|
+
if (value === "true") return true;
|
|
20
|
+
if (value === "false") return false;
|
|
21
|
+
if (value !== "" && !isNaN(Number(value))) {
|
|
22
|
+
return Number(value);
|
|
23
|
+
}
|
|
24
|
+
return value;
|
|
25
|
+
}
|
|
26
|
+
function on_input(e) {
|
|
27
|
+
const new_value = e.target.value;
|
|
28
|
+
if ($fieldStore.params?.parse_string) {
|
|
29
|
+
const parsed_value = parse_string_value(new_value);
|
|
30
|
+
$fieldStore.value = parsed_value;
|
|
31
|
+
} else {
|
|
32
|
+
$fieldStore.value = new_value;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
</script>
|
|
36
|
+
|
|
37
|
+
<FieldLabel {fieldStore} />
|
|
38
|
+
<Input
|
|
39
|
+
id={$fieldStore.id}
|
|
40
|
+
value={$fieldStore.value}
|
|
41
|
+
placeholder={$fieldStore.label}
|
|
42
|
+
on:input={on_input}
|
|
43
|
+
aria-invalid={$fieldStore.validation_result?.type == "error" ? true : undefined}
|
|
44
|
+
aria-describedby="message-{$fieldStore.id}"
|
|
45
|
+
/>
|
|
46
|
+
<FieldMessage {fieldStore} />
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { SvelteComponent } from "svelte";
|
|
2
|
+
import type { Writable } from "svelte/store";
|
|
3
|
+
import { type IBaseField, type IBuiltField, type IInitialForm } from "../interfaces";
|
|
4
|
+
export interface ITextFieldParams {
|
|
5
|
+
parse_string?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export interface ITextField extends IBaseField<ITextFieldParams> {
|
|
8
|
+
fieldtype: "text";
|
|
9
|
+
}
|
|
10
|
+
export declare const text_field_param_spec: IInitialForm;
|
|
11
|
+
declare const __propDef: {
|
|
12
|
+
props: {
|
|
13
|
+
fieldStore: Writable<IBuiltField<ITextFieldParams>>;
|
|
14
|
+
};
|
|
15
|
+
events: {
|
|
16
|
+
[evt: string]: CustomEvent<any>;
|
|
17
|
+
};
|
|
18
|
+
slots: {};
|
|
19
|
+
exports?: {} | undefined;
|
|
20
|
+
bindings?: string | undefined;
|
|
21
|
+
};
|
|
22
|
+
export type TextFieldProps = typeof __propDef.props;
|
|
23
|
+
export type TextFieldEvents = typeof __propDef.events;
|
|
24
|
+
export type TextFieldSlots = typeof __propDef.slots;
|
|
25
|
+
export default class TextField extends SvelteComponent<TextFieldProps, TextFieldEvents, TextFieldSlots> {
|
|
26
|
+
}
|
|
27
|
+
export {};
|