@stubber/form-fields 1.4.6 → 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.
Files changed (96) 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/interfaces.d.ts +207 -0
  13. package/dist/fields2/interfaces.js +82 -0
  14. package/dist/fields2/sub/array-builder-field.svelte +110 -0
  15. package/dist/fields2/sub/array-builder-field.svelte.d.ts +27 -0
  16. package/dist/fields2/sub/checkbox-autocomplete.svelte +56 -0
  17. package/dist/fields2/sub/checkbox-autocomplete.svelte.d.ts +27 -0
  18. package/dist/fields2/sub/checkbox-field.svelte +41 -0
  19. package/dist/fields2/sub/checkbox-field.svelte.d.ts +28 -0
  20. package/dist/fields2/sub/code-field.svelte +146 -0
  21. package/dist/fields2/sub/code-field.svelte.d.ts +27 -0
  22. package/dist/fields2/sub/contact-selector-field.svelte +84 -0
  23. package/dist/fields2/sub/contact-selector-field.svelte.d.ts +30 -0
  24. package/dist/fields2/sub/currency-field.svelte +197 -0
  25. package/dist/fields2/sub/currency-field.svelte.d.ts +29 -0
  26. package/dist/fields2/sub/data-indication-field.svelte +19 -0
  27. package/dist/fields2/sub/data-indication-field.svelte.d.ts +23 -0
  28. package/dist/fields2/sub/date-field.svelte +31 -0
  29. package/dist/fields2/sub/date-field.svelte.d.ts +23 -0
  30. package/dist/fields2/sub/date-time-field.svelte +31 -0
  31. package/dist/fields2/sub/date-time-field.svelte.d.ts +23 -0
  32. package/dist/fields2/sub/email-field.svelte +40 -0
  33. package/dist/fields2/sub/email-field.svelte.d.ts +23 -0
  34. package/dist/fields2/sub/field-builder-field.svelte +525 -0
  35. package/dist/fields2/sub/field-builder-field.svelte.d.ts +23 -0
  36. package/dist/fields2/sub/file-field.svelte +150 -0
  37. package/dist/fields2/sub/file-field.svelte.d.ts +27 -0
  38. package/dist/fields2/sub/grid-field.svelte +54 -0
  39. package/dist/fields2/sub/grid-field.svelte.d.ts +30 -0
  40. package/dist/fields2/sub/heading-field.svelte +28 -0
  41. package/dist/fields2/sub/heading-field.svelte.d.ts +28 -0
  42. package/dist/fields2/sub/hidden-field.svelte +142 -0
  43. package/dist/fields2/sub/hidden-field.svelte.d.ts +37 -0
  44. package/dist/fields2/sub/hidden-location-field.svelte +23 -0
  45. package/dist/fields2/sub/hidden-location-field.svelte.d.ts +23 -0
  46. package/dist/fields2/sub/html-field.svelte +22 -0
  47. package/dist/fields2/sub/html-field.svelte.d.ts +27 -0
  48. package/dist/fields2/sub/json-editor-bound.svelte +17 -0
  49. package/dist/fields2/sub/json-editor-bound.svelte.d.ts +65 -0
  50. package/dist/fields2/sub/jsoneditor-field.svelte +23 -0
  51. package/dist/fields2/sub/jsoneditor-field.svelte.d.ts +27 -0
  52. package/dist/fields2/sub/map-field.svelte +144 -0
  53. package/dist/fields2/sub/map-field.svelte.d.ts +28 -0
  54. package/dist/fields2/sub/multi-checkbox-field.svelte +83 -0
  55. package/dist/fields2/sub/multi-checkbox-field.svelte.d.ts +34 -0
  56. package/dist/fields2/sub/multistep-field.svelte +70 -0
  57. package/dist/fields2/sub/multistep-field.svelte.d.ts +24 -0
  58. package/dist/fields2/sub/note-field.svelte +18 -0
  59. package/dist/fields2/sub/note-field.svelte.d.ts +23 -0
  60. package/dist/fields2/sub/number-field.svelte +77 -0
  61. package/dist/fields2/sub/number-field.svelte.d.ts +29 -0
  62. package/dist/fields2/sub/object-builder-field.svelte +123 -0
  63. package/dist/fields2/sub/object-builder-field.svelte.d.ts +28 -0
  64. package/dist/fields2/sub/qr-code-scanner-field.svelte +86 -0
  65. package/dist/fields2/sub/qr-code-scanner-field.svelte.d.ts +23 -0
  66. package/dist/fields2/sub/radio-field.svelte +69 -0
  67. package/dist/fields2/sub/radio-field.svelte.d.ts +30 -0
  68. package/dist/fields2/sub/screenrecorder-field.svelte +182 -0
  69. package/dist/fields2/sub/screenrecorder-field.svelte.d.ts +27 -0
  70. package/dist/fields2/sub/screenshot-field.svelte +165 -0
  71. package/dist/fields2/sub/screenshot-field.svelte.d.ts +26 -0
  72. package/dist/fields2/sub/scroll-and-read-display-field.svelte +92 -0
  73. package/dist/fields2/sub/scroll-and-read-display-field.svelte.d.ts +29 -0
  74. package/dist/fields2/sub/section-field.svelte +27 -0
  75. package/dist/fields2/sub/section-field.svelte.d.ts +26 -0
  76. package/dist/fields2/sub/select-field.svelte +138 -0
  77. package/dist/fields2/sub/select-field.svelte.d.ts +34 -0
  78. package/dist/fields2/sub/selectresource-field.svelte +69 -0
  79. package/dist/fields2/sub/selectresource-field.svelte.d.ts +29 -0
  80. package/dist/fields2/sub/signature-field.svelte +84 -0
  81. package/dist/fields2/sub/signature-field.svelte.d.ts +23 -0
  82. package/dist/fields2/sub/slider-field.svelte +28 -0
  83. package/dist/fields2/sub/slider-field.svelte.d.ts +28 -0
  84. package/dist/fields2/sub/smart-text-field.svelte +245 -0
  85. package/dist/fields2/sub/smart-text-field.svelte.d.ts +36 -0
  86. package/dist/fields2/sub/telephone-field.svelte +68 -0
  87. package/dist/fields2/sub/telephone-field.svelte.d.ts +26 -0
  88. package/dist/fields2/sub/text-field.svelte +46 -0
  89. package/dist/fields2/sub/text-field.svelte.d.ts +27 -0
  90. package/dist/fields2/sub/voicenote-field.svelte +161 -0
  91. package/dist/fields2/sub/voicenote-field.svelte.d.ts +26 -0
  92. package/dist/fields2/utils.d.ts +9 -0
  93. package/dist/fields2/utils.js +116 -0
  94. package/dist/fields2/validations/validate_field.d.ts +11 -0
  95. package/dist/fields2/validations/validate_field.js +121 -0
  96. package/package.json +6 -9
@@ -0,0 +1,146 @@
1
+ <script context="module">import {} from "../interfaces";
2
+ export const code_field_param_spec = {
3
+ spec: {
4
+ fields: {
5
+ globals: {
6
+ fieldtype: "jsoneditor",
7
+ help: "Global variables available in the code editor."
8
+ }
9
+ }
10
+ }
11
+ };
12
+ </script>
13
+
14
+ <script>import { Textarea } from "@stubber/ui/textarea";
15
+ import FieldLabel from "../FieldLabel.svelte";
16
+ import FieldMessage from "../FieldMessage.svelte";
17
+ import {
18
+ acceptCompletion,
19
+ autocompletion,
20
+ CompletionContext,
21
+ completionKeymap,
22
+ startCompletion
23
+ } from "@codemirror/autocomplete";
24
+ import { javascript, javascriptLanguage } from "@codemirror/lang-javascript";
25
+ import { EditorState } from "@codemirror/state";
26
+ import { EditorView, keymap } from "@codemirror/view";
27
+ import { basicSetup } from "codemirror";
28
+ export let fieldStore;
29
+ let value = $fieldStore.value || "";
30
+ let editor_view;
31
+ const custom_completion_keymap = completionKeymap.filter((binding) => binding.key != "Enter").concat([
32
+ {
33
+ key: "Enter",
34
+ run: () => {
35
+ return false;
36
+ }
37
+ },
38
+ {
39
+ key: "Tab",
40
+ run: acceptCompletion
41
+ },
42
+ {
43
+ key: "Ctrl-Space",
44
+ run: startCompletion,
45
+ stopPropagation: true
46
+ }
47
+ ]);
48
+ function keysFor(obj) {
49
+ return Object.keys(obj ?? {});
50
+ }
51
+ function globalCompletions(ctx) {
52
+ const m = ctx.matchBefore(/[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*)*\.?/);
53
+ if (!m && !ctx.explicit) return null;
54
+ const text = m?.text ?? "";
55
+ const trailingDot = text.endsWith(".");
56
+ const parts = (trailingDot ? text.slice(0, -1) : text).split(".").filter(Boolean);
57
+ let container = $fieldStore.params?.globals || {};
58
+ for (let i = 0; i < Math.max(0, parts.length - (trailingDot ? 0 : 1)); i++) {
59
+ container = container?.[parts[i]];
60
+ if (!container) break;
61
+ }
62
+ const last = trailingDot ? "" : parts[parts.length - 1] ?? "";
63
+ const from = ctx.pos - last.length;
64
+ return {
65
+ from,
66
+ options: keysFor(container).map((key) => ({
67
+ label: key,
68
+ type: "property"
69
+ // 👈 simplified
70
+ })),
71
+ validFor: /^\w*$/
72
+ // keep suggestions stable while typing
73
+ };
74
+ }
75
+ const stubber_completions = javascriptLanguage.data.of({
76
+ autocomplete: globalCompletions
77
+ });
78
+ function bind_codemirror(el) {
79
+ const min_height_editor = EditorView.theme({
80
+ ".cm-content, .cm-gutter": { minHeight: "200px" },
81
+ "&": { maxHeight: "300px" },
82
+ ".cm-scroller": { overflow: "auto" }
83
+ });
84
+ editor_view = new EditorView({
85
+ state: EditorState.create({
86
+ doc: value,
87
+ extensions: [
88
+ basicSetup,
89
+ javascript(),
90
+ stubber_completions,
91
+ autocompletion({ defaultKeymap: false }),
92
+ keymap.of(custom_completion_keymap),
93
+ min_height_editor,
94
+ update_listener
95
+ ]
96
+ }),
97
+ parent: el
98
+ });
99
+ }
100
+ const update_listener = EditorView.updateListener.of((update) => {
101
+ if (update.docChanged) {
102
+ const new_value = update.state.doc.toString();
103
+ if (new_value !== value) {
104
+ value = new_value;
105
+ }
106
+ }
107
+ });
108
+ $: sync_field_to_editor(value);
109
+ const sync_field_to_editor = (new_value) => {
110
+ if (editor_view && editor_view.state.doc.toString() !== new_value) {
111
+ editor_view.dispatch({
112
+ changes: {
113
+ from: 0,
114
+ to: editor_view.state.doc.length,
115
+ insert: new_value
116
+ }
117
+ });
118
+ }
119
+ if ($fieldStore.value !== new_value) {
120
+ $fieldStore.value = new_value;
121
+ }
122
+ };
123
+ $: sync_field_to_value($fieldStore.value);
124
+ const sync_field_to_value = (new_value) => {
125
+ if (new_value !== value) {
126
+ value = new_value;
127
+ if (editor_view?.state.doc.toString() !== new_value) {
128
+ editor_view.dispatch({
129
+ changes: {
130
+ from: 0,
131
+ to: editor_view.state.doc.length,
132
+ insert: new_value
133
+ }
134
+ });
135
+ }
136
+ }
137
+ };
138
+ </script>
139
+
140
+ <div class="flex flex-col w-full my-2">
141
+ <FieldLabel {fieldStore} />
142
+ <div class="relative rounded-md">
143
+ <div use:bind_codemirror />
144
+ </div>
145
+ <FieldMessage {fieldStore} />
146
+ </div>
@@ -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
+ interface ICodeFieldParams {
5
+ globals?: Record<string, any>;
6
+ }
7
+ export declare const code_field_param_spec: IInitialForm;
8
+ export interface ICodeField extends IBaseField<ICodeFieldParams> {
9
+ fieldtype: "code";
10
+ }
11
+ declare const __propDef: {
12
+ props: {
13
+ fieldStore: Writable<IBuiltField<ICodeFieldParams>>;
14
+ };
15
+ events: {
16
+ [evt: string]: CustomEvent<any>;
17
+ };
18
+ slots: {};
19
+ exports?: {} | undefined;
20
+ bindings?: string | undefined;
21
+ };
22
+ export type CodeFieldProps = typeof __propDef.props;
23
+ export type CodeFieldEvents = typeof __propDef.events;
24
+ export type CodeFieldSlots = typeof __propDef.slots;
25
+ export default class CodeField extends SvelteComponent<CodeFieldProps, CodeFieldEvents, CodeFieldSlots> {
26
+ }
27
+ export {};
@@ -0,0 +1,84 @@
1
+ <script context="module">export const contact_selector_field_param_spec = {
2
+ spec: {
3
+ fields: {
4
+ label: {
5
+ fieldtype: "text",
6
+ help: "The contact field to use as the label in the dropdown options."
7
+ },
8
+ limit: {
9
+ fieldtype: "number",
10
+ help: "Limit the number of contacts returned."
11
+ }
12
+ }
13
+ }
14
+ };
15
+ </script>
16
+
17
+ <script>import { Button } from "@stubber/ui/button";
18
+ import SelectField, {} from "./select-field.svelte";
19
+ export let fieldStore;
20
+ const params = $fieldStore.params || {};
21
+ const dependencies = $fieldStore.formDependencies;
22
+ const createWantToModal = dependencies?.createWantToModal;
23
+ const show_create_contact_modal = () => {
24
+ const stubref = dependencies?.stubber?.stubref;
25
+ const orguuid = dependencies?.stubber?.orguuid;
26
+ createWantToModal("_create_new_contact", stubref, orguuid);
27
+ };
28
+ const field = $fieldStore;
29
+ if (field.params) {
30
+ field.params.load_options = async (search_term) => {
31
+ const socket = dependencies?.clienthub?.socket;
32
+ const orguuid = dependencies?.stubber?.orguuid;
33
+ const stubref = dependencies?.stubber?.stubref;
34
+ if (!socket || !orguuid || !stubref) {
35
+ console.error("ClientHub socket or stubber details not available.");
36
+ return [];
37
+ }
38
+ const details = {
39
+ resource_name: "contacts"
40
+ };
41
+ details.params = $fieldStore.params || {};
42
+ details.params.orguuid = orguuid;
43
+ details.params.stubref = stubref;
44
+ details.params.input = search_term;
45
+ if (details.params.limit === void 0) {
46
+ details.params.limit = 50;
47
+ }
48
+ console.log("Loading contacts with details:", details);
49
+ return new Promise((resolve, reject) => {
50
+ socket.emit("request", { type: "resource", details }, (res) => {
51
+ if (res.success) {
52
+ console.log("Contacts loaded:", res);
53
+ const contacts = res.payload?.contacts || [];
54
+ const result = contacts.map((contact) => {
55
+ let label = contact._default_label;
56
+ if (params.label && contact[params.label]) {
57
+ label = contact[params.label];
58
+ }
59
+ return {
60
+ value: contact,
61
+ label
62
+ };
63
+ });
64
+ resolve(result);
65
+ } else {
66
+ console.error("Failed to load contacts:", res);
67
+ resolve([]);
68
+ }
69
+ });
70
+ });
71
+ };
72
+ }
73
+ </script>
74
+
75
+ <SelectField {fieldStore}>
76
+ <Button
77
+ on:click={show_create_contact_modal}
78
+ variant="ghost"
79
+ class="ml-auto text-surface-500 text-sm hover:text-surface-700"
80
+ >
81
+ <i class="fa-regular fa-plus" />
82
+ Create new contact
83
+ </Button>
84
+ </SelectField>
@@ -0,0 +1,30 @@
1
+ import { SvelteComponent } from "svelte";
2
+ import type { Writable } from "svelte/store";
3
+ import type { IBaseField, IBuiltField, IInitialForm } from "../interfaces";
4
+ export interface IContactSelectorFieldParams {
5
+ label?: string;
6
+ limit?: number;
7
+ load_options?: (search_term: string) => Promise<ISelectFieldOption[]>;
8
+ }
9
+ export declare const contact_selector_field_param_spec: IInitialForm;
10
+ export interface IContactSelectorField extends IBaseField<IContactSelectorFieldParams> {
11
+ fieldtype: "contactselector";
12
+ }
13
+ import { type ISelectFieldOption } from "./select-field.svelte";
14
+ declare const __propDef: {
15
+ props: {
16
+ fieldStore: Writable<IBuiltField<IContactSelectorFieldParams>>;
17
+ };
18
+ events: {
19
+ [evt: string]: CustomEvent<any>;
20
+ };
21
+ slots: {};
22
+ exports?: {} | undefined;
23
+ bindings?: string | undefined;
24
+ };
25
+ export type ContactSelectorFieldProps = typeof __propDef.props;
26
+ export type ContactSelectorFieldEvents = typeof __propDef.events;
27
+ export type ContactSelectorFieldSlots = typeof __propDef.slots;
28
+ export default class ContactSelectorField extends SvelteComponent<ContactSelectorFieldProps, ContactSelectorFieldEvents, ContactSelectorFieldSlots> {
29
+ }
30
+ export {};
@@ -0,0 +1,197 @@
1
+ <script context="module">const currency_codes = Intl.supportedValuesOf("currency");
2
+ const currency_code_options = currency_codes.map((code) => ({
3
+ label: code,
4
+ value: code
5
+ }));
6
+ export const currency_field_param_spec = {
7
+ spec: {
8
+ fields: {
9
+ currency: {
10
+ fieldtype: "select",
11
+ without_value_details: true,
12
+ params: {
13
+ options: currency_code_options
14
+ }
15
+ },
16
+ currency_whitelist: {
17
+ fieldtype: "arraybuilder",
18
+ params: {
19
+ new_entry_field: {
20
+ fieldtype: "select",
21
+ without_value_details: true,
22
+ params: {
23
+ options: currency_code_options
24
+ }
25
+ }
26
+ },
27
+ help: "List of allowed currency codes (ISO 4217)"
28
+ },
29
+ currency_blacklist: {
30
+ fieldtype: "arraybuilder",
31
+ help: "List of disallowed currency codes (ISO 4217)",
32
+ params: {
33
+ new_entry_field: {
34
+ fieldtype: "select",
35
+ without_value_details: true,
36
+ params: {
37
+ options: currency_code_options
38
+ }
39
+ }
40
+ }
41
+ }
42
+ }
43
+ }
44
+ };
45
+ </script>
46
+
47
+ <script>import * as utils from "../../utils/index.js";
48
+ import { Button } from "@stubber/ui/button";
49
+ import * as Command from "@stubber/ui/command";
50
+ import * as Popover from "@stubber/ui/popover";
51
+ import getSymbolFromCurrency from "currency-symbol-map";
52
+ import currency from "currency.js";
53
+ import { get } from "lodash-es";
54
+ import { get as get_store_value } from "svelte/store";
55
+ import FieldLabel from "../FieldLabel.svelte";
56
+ import FieldMessage from "../FieldMessage.svelte";
57
+ import { set_value_details } from "../utils";
58
+ export let fieldStore;
59
+ let field = $fieldStore;
60
+ let params = field.params;
61
+ const currencyRegex = /^([0-9]+(\.?[0-9]?[0-9]?)?)$/;
62
+ const currencyName = new Intl.DisplayNames("en-US", {
63
+ type: "currency"
64
+ });
65
+ let { inputRegexMask } = utils;
66
+ let initial_ui_value = $fieldStore.value || "";
67
+ let currency_list = [];
68
+ const build_currency_list_from_codes = (codes) => {
69
+ const currencies = [];
70
+ for (const code of codes) {
71
+ try {
72
+ const name = currencyName.of(code);
73
+ if (!name) continue;
74
+ const symbol = getSymbolFromCurrency(code);
75
+ if (!symbol) continue;
76
+ currencies.push({
77
+ value: code,
78
+ symbol,
79
+ name
80
+ });
81
+ } catch (err) {
82
+ console.warn(err);
83
+ continue;
84
+ }
85
+ }
86
+ return currencies;
87
+ };
88
+ if (params?.currency_whitelist && params.currency_whitelist.length > 0) {
89
+ currency_list = build_currency_list_from_codes(params.currency_whitelist);
90
+ } else if (params?.currency_blacklist && params.currency_blacklist.length > 0) {
91
+ const filtered_currencies = currency_codes.filter(
92
+ (c) => !params.currency_blacklist?.includes(c)
93
+ );
94
+ currency_list = build_currency_list_from_codes(filtered_currencies);
95
+ } else {
96
+ currency_list = build_currency_list_from_codes(currency_codes);
97
+ }
98
+ const details_data_path = field.data_path + "_details";
99
+ let current_details = get(get_store_value(field.formStore), details_data_path);
100
+ if (!current_details) {
101
+ current_details = {
102
+ cents: 0,
103
+ amount: 0,
104
+ currencycode: params?.currency || "USD",
105
+ currencysymbol: getSymbolFromCurrency(params?.currency || "USD") || "$"
106
+ };
107
+ }
108
+ const on_input = (e) => {
109
+ const input = e.target;
110
+ const new_value = input.value;
111
+ const currencycode_valid = current_details?.currencycode && currency_list.some((c) => c.value === current_details.currencycode);
112
+ if (!currencycode_valid) {
113
+ if (params?.currency && currency_list.some((c) => c.value === params.currency)) {
114
+ current_details.currencycode = params.currency;
115
+ } else if (currency_list.length > 0) {
116
+ current_details.currencycode = currency_list[0].value;
117
+ } else {
118
+ current_details.currencycode = "USD";
119
+ }
120
+ }
121
+ current_details.currencysymbol = getSymbolFromCurrency(current_details.currencycode) || current_details.currencysymbol || "USD";
122
+ current_details.cents = currency(new_value).intValue;
123
+ current_details.amount = currency(new_value).value;
124
+ field.value = current_details.amount ? current_details.amount.toFixed(2).toString() : "";
125
+ set_value_details(field, "details", current_details);
126
+ };
127
+ let open = false;
128
+ $: selectedValue = currency_list.find((c) => c.value === current_details?.currencycode)?.value || "Select Currency...";
129
+ </script>
130
+
131
+ <FieldLabel {fieldStore} />
132
+ <div
133
+ class="flex-row items-center gap-2 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"
134
+ >
135
+ <!-- currency indicator front left -->
136
+ <div class="pointer-events-none text-gray-500">
137
+ {#if current_details?.currencysymbol}
138
+ {current_details.currencysymbol}
139
+ {:else if params?.currency}
140
+ {getSymbolFromCurrency(params.currency) || params.currency}
141
+ {:else}
142
+ $
143
+ {/if}
144
+ </div>
145
+ <input
146
+ class="w-full focus-within:outline-none bg-transparent"
147
+ use:inputRegexMask={currencyRegex}
148
+ value={initial_ui_value}
149
+ inputmode="decimal"
150
+ aria-invalid={$fieldStore.validation_result?.type == "error" ? true : undefined}
151
+ on:input={on_input}
152
+ />
153
+
154
+ <!-- currency selector back right -->
155
+ {#if currency_list.length > 1 && !params?.currency}
156
+ <Popover.Root bind:open let:ids>
157
+ <Popover.Trigger asChild let:builder>
158
+ <Button
159
+ builders={[builder]}
160
+ variant="outline"
161
+ role="combobox"
162
+ aria-expanded={open}
163
+ class="w-28 border-none bg-transparent px-1 justify-between"
164
+ >
165
+ {selectedValue}
166
+ <i class="fas fa-sort ml-2 h-4 w-4 shrink-0 opacity-50" />
167
+ </Button>
168
+ </Popover.Trigger>
169
+ <Popover.Content class="p-0 max-h-[50vh] overflow-y-scroll">
170
+ <Command.Root>
171
+ <Command.Input placeholder="Search currencies..." />
172
+ <Command.Empty>No currency found.</Command.Empty>
173
+ <Command.Group>
174
+ {#each currency_list as c}
175
+ <Command.Item
176
+ value={c.value}
177
+ onSelect={(currentValue) => {
178
+ current_details = {
179
+ ...current_details,
180
+ currencycode: currentValue,
181
+ currencysymbol: getSymbolFromCurrency(currentValue) || "",
182
+ };
183
+ set_value_details($fieldStore, "details", current_details);
184
+ open = false;
185
+ }}
186
+ class={selectedValue === c.value ? "bg-primary-100" : ""}
187
+ >
188
+ {c.value} - {c.name} ({c.symbol})
189
+ </Command.Item>
190
+ {/each}
191
+ </Command.Group>
192
+ </Command.Root>
193
+ </Popover.Content>
194
+ </Popover.Root>
195
+ {/if}
196
+ </div>
197
+ <FieldMessage {fieldStore} />
@@ -0,0 +1,29 @@
1
+ import { SvelteComponent } from "svelte";
2
+ import type { IBaseField, IBuiltField, IInitialForm } from "../interfaces";
3
+ export interface ICurrencyFieldParams {
4
+ currency?: string;
5
+ currency_whitelist?: string[];
6
+ currency_blacklist?: string[];
7
+ }
8
+ export declare const currency_field_param_spec: IInitialForm;
9
+ export interface ICurrencyField extends IBaseField<ICurrencyFieldParams> {
10
+ fieldtype: "currency";
11
+ }
12
+ import { type Writable } from "svelte/store";
13
+ declare const __propDef: {
14
+ props: {
15
+ fieldStore: Writable<IBuiltField<ICurrencyFieldParams>>;
16
+ };
17
+ events: {
18
+ [evt: string]: CustomEvent<any>;
19
+ };
20
+ slots: {};
21
+ exports?: {} | undefined;
22
+ bindings?: string | undefined;
23
+ };
24
+ export type CurrencyFieldProps = typeof __propDef.props;
25
+ export type CurrencyFieldEvents = typeof __propDef.events;
26
+ export type CurrencyFieldSlots = typeof __propDef.slots;
27
+ export default class CurrencyField extends SvelteComponent<CurrencyFieldProps, CurrencyFieldEvents, CurrencyFieldSlots> {
28
+ }
29
+ export {};
@@ -0,0 +1,19 @@
1
+ <script context="module"></script>
2
+
3
+ <script>import { isString } from "lodash-es";
4
+ import FieldLabel from "../FieldLabel.svelte";
5
+ import FieldMessage from "../FieldMessage.svelte";
6
+ export let fieldStore;
7
+ let value;
8
+ $: {
9
+ const new_value = $fieldStore.value;
10
+ const is_string = isString(new_value);
11
+ value = is_string ? new_value : JSON.stringify(new_value, null, 2);
12
+ }
13
+ </script>
14
+
15
+ <FieldLabel {fieldStore} />
16
+ <div class="relative mt-2 rounded-md bg-surface-100 p-2">
17
+ <pre class="rounded-md">{value ?? ""}</pre>
18
+ </div>
19
+ <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 IDataIndicationField extends IBaseField<{}> {
5
+ fieldtype: "dataindication";
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 DataIndicationFieldProps = typeof __propDef.props;
19
+ export type DataIndicationFieldEvents = typeof __propDef.events;
20
+ export type DataIndicationFieldSlots = typeof __propDef.slots;
21
+ export default class DataIndicationField extends SvelteComponent<DataIndicationFieldProps, DataIndicationFieldEvents, DataIndicationFieldSlots> {
22
+ }
23
+ export {};
@@ -0,0 +1,31 @@
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
+ export let fieldStore;
7
+ </script>
8
+
9
+ <FieldLabel {fieldStore} />
10
+ <Input
11
+ id={$fieldStore.id}
12
+ bind:value={$fieldStore.value}
13
+ type="date"
14
+ aria-invalid={$fieldStore.validation_result?.type == "error" ? true : undefined}
15
+ class="w-full date-input {!$fieldStore.value ? 'text-muted-foreground' : ''}"
16
+ aria-describedby="message-{$fieldStore.id}"
17
+ />
18
+ <FieldMessage {fieldStore} />
19
+
20
+ <style>
21
+ :global(input[type="date"].date-input) {
22
+ position: relative;
23
+ padding-right: 2rem;
24
+ }
25
+
26
+ :global(input[type="date"].date-input::-webkit-calendar-picker-indicator) {
27
+ position: absolute;
28
+ right: 0.5rem;
29
+ cursor: pointer;
30
+ }
31
+ </style>
@@ -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 IDateField extends IBaseField<{}> {
5
+ fieldtype: "date";
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 DateFieldProps = typeof __propDef.props;
19
+ export type DateFieldEvents = typeof __propDef.events;
20
+ export type DateFieldSlots = typeof __propDef.slots;
21
+ export default class DateField extends SvelteComponent<DateFieldProps, DateFieldEvents, DateFieldSlots> {
22
+ }
23
+ export {};
@@ -0,0 +1,31 @@
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
+ export let fieldStore;
7
+ </script>
8
+
9
+ <FieldLabel {fieldStore} />
10
+ <Input
11
+ id={$fieldStore.id}
12
+ bind:value={$fieldStore.value}
13
+ type="datetime-local"
14
+ aria-invalid={$fieldStore.validation_result?.type == "error" ? true : undefined}
15
+ class="w-full date-input {!$fieldStore.value ? 'text-muted-foreground' : ''}"
16
+ aria-describedby="message-{$fieldStore.id}"
17
+ />
18
+ <FieldMessage {fieldStore} />
19
+
20
+ <style>
21
+ :global(input[type="datetime-local"].date-input) {
22
+ position: relative;
23
+ padding-right: 2rem;
24
+ }
25
+
26
+ :global(input[type="datetime-local"].date-input::-webkit-calendar-picker-indicator) {
27
+ position: absolute;
28
+ right: 0.5rem;
29
+ cursor: pointer;
30
+ }
31
+ </style>
@@ -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 IDateTimeField extends IBaseField<{}> {
5
+ fieldtype: "datetime";
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 DateTimeFieldProps = typeof __propDef.props;
19
+ export type DateTimeFieldEvents = typeof __propDef.events;
20
+ export type DateTimeFieldSlots = typeof __propDef.slots;
21
+ export default class DateTimeField extends SvelteComponent<DateTimeFieldProps, DateTimeFieldEvents, DateTimeFieldSlots> {
22
+ }
23
+ export {};