@stubber/form-fields 1.3.0 → 1.4.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.
- package/dist/fields/components/Code.svelte +117 -0
- package/dist/fields/components/Code.svelte.d.ts +18 -0
- package/dist/fields/components/index.d.ts +2 -0
- package/dist/fields/components/index.js +2 -0
- package/dist/fields/definitions/code.json +15 -0
- package/dist/fields/definitions/index.d.ts +10 -8
- package/dist/fields/definitions/index.js +12 -11
- package/package.json +8 -5
- /package/dist/fields/definitions/{_all.json → all.json} +0 -0
- /package/dist/fields/definitions/{_placeholder.json → placeholder.json} +0 -0
- /package/dist/fields/definitions/{smart_text.json → smarttext.json} +0 -0
- /package/dist/fields/definitions/{_valid_fieldtype.json → validfieldtype.json} +0 -0
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
<script>import { acceptCompletion, CompletionContext } from "@codemirror/autocomplete";
|
|
2
|
+
import { javascript, javascriptLanguage } from "@codemirror/lang-javascript";
|
|
3
|
+
import { EditorState } from "@codemirror/state";
|
|
4
|
+
import { EditorView, keymap } from "@codemirror/view";
|
|
5
|
+
import { Label } from "@stubber/ui/label";
|
|
6
|
+
import { basicSetup } from "codemirror";
|
|
7
|
+
export let field;
|
|
8
|
+
let value = $field.data.base || "";
|
|
9
|
+
let params = $field.spec?.params || {};
|
|
10
|
+
let globals = params?.globals || {};
|
|
11
|
+
let editor_view;
|
|
12
|
+
$: state_key = $field.state?.state_key;
|
|
13
|
+
$: label = $field.spec?.title;
|
|
14
|
+
$: hide_label = $field.spec?.hide_label;
|
|
15
|
+
$: isValid = !$field.state?.validation || $field.state?.validation?.valid;
|
|
16
|
+
$: validationMessage = $field.state?.validation?.message;
|
|
17
|
+
const tab_accept_completion = keymap.of([
|
|
18
|
+
{
|
|
19
|
+
key: "Tab",
|
|
20
|
+
run: acceptCompletion
|
|
21
|
+
}
|
|
22
|
+
]);
|
|
23
|
+
function keysFor(obj) {
|
|
24
|
+
return Object.keys(obj ?? {});
|
|
25
|
+
}
|
|
26
|
+
function globalCompletions(ctx) {
|
|
27
|
+
const m = ctx.matchBefore(/[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*)*\.?/);
|
|
28
|
+
if (!m && !ctx.explicit) return null;
|
|
29
|
+
const text = m?.text ?? "";
|
|
30
|
+
const trailingDot = text.endsWith(".");
|
|
31
|
+
const parts = (trailingDot ? text.slice(0, -1) : text).split(".").filter(Boolean);
|
|
32
|
+
let container = globals;
|
|
33
|
+
for (let i = 0; i < Math.max(0, parts.length - (trailingDot ? 0 : 1)); i++) {
|
|
34
|
+
container = container?.[parts[i]];
|
|
35
|
+
if (!container) break;
|
|
36
|
+
}
|
|
37
|
+
const last = trailingDot ? "" : parts[parts.length - 1] ?? "";
|
|
38
|
+
const from = ctx.pos - last.length;
|
|
39
|
+
return {
|
|
40
|
+
from,
|
|
41
|
+
options: keysFor(container).map((key) => ({
|
|
42
|
+
label: key,
|
|
43
|
+
type: "property"
|
|
44
|
+
// 👈 simplified
|
|
45
|
+
})),
|
|
46
|
+
validFor: /^\w*$/
|
|
47
|
+
// keep suggestions stable while typing
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
const stubber_completions = javascriptLanguage.data.of({
|
|
51
|
+
autocomplete: globalCompletions
|
|
52
|
+
});
|
|
53
|
+
function bind_codemirror(el) {
|
|
54
|
+
const min_height_editor = EditorView.theme({
|
|
55
|
+
".cm-content, .cm-gutter": { minHeight: "200px" },
|
|
56
|
+
"&": { maxHeight: "300px" },
|
|
57
|
+
".cm-scroller": { overflow: "auto" }
|
|
58
|
+
});
|
|
59
|
+
editor_view = new EditorView({
|
|
60
|
+
state: EditorState.create({
|
|
61
|
+
doc: value,
|
|
62
|
+
extensions: [
|
|
63
|
+
basicSetup,
|
|
64
|
+
javascript(),
|
|
65
|
+
stubber_completions,
|
|
66
|
+
tab_accept_completion,
|
|
67
|
+
min_height_editor,
|
|
68
|
+
update_listener
|
|
69
|
+
]
|
|
70
|
+
}),
|
|
71
|
+
parent: el
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
const update_listener = EditorView.updateListener.of((update) => {
|
|
75
|
+
if (update.docChanged) {
|
|
76
|
+
const new_value = update.state.doc.toString();
|
|
77
|
+
if (new_value !== value) {
|
|
78
|
+
value = new_value;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
$: sync_field_to_editor(value);
|
|
83
|
+
const sync_field_to_editor = (new_value) => {
|
|
84
|
+
if (editor_view && editor_view.state.doc.toString() !== new_value) {
|
|
85
|
+
editor_view.dispatch({
|
|
86
|
+
changes: {
|
|
87
|
+
from: 0,
|
|
88
|
+
to: editor_view.state.doc.length,
|
|
89
|
+
insert: new_value
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
if ($field.data.base !== new_value) {
|
|
94
|
+
$field.data.base = new_value;
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
$: sync_field_to_value($field.data.base);
|
|
98
|
+
const sync_field_to_value = (new_value) => {
|
|
99
|
+
if (new_value !== value) {
|
|
100
|
+
value = new_value;
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
</script>
|
|
104
|
+
|
|
105
|
+
<div class="flex flex-col w-full my-2">
|
|
106
|
+
<Label for="input_{state_key}" class="block py-2 {hide_label ? 'hidden' : ''}">
|
|
107
|
+
{label}
|
|
108
|
+
</Label>
|
|
109
|
+
<div class="relative rounded-md">
|
|
110
|
+
<div use:bind_codemirror />
|
|
111
|
+
</div>
|
|
112
|
+
{#if validationMessage}
|
|
113
|
+
<Label class="mt-1.5 {!isValid ? `text-danger-500` : `text-success-500`}"
|
|
114
|
+
>{validationMessage}</Label
|
|
115
|
+
>
|
|
116
|
+
{/if}
|
|
117
|
+
</div>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { SvelteComponent } from "svelte";
|
|
2
|
+
declare const __propDef: {
|
|
3
|
+
props: {
|
|
4
|
+
field: any;
|
|
5
|
+
};
|
|
6
|
+
events: {
|
|
7
|
+
[evt: string]: CustomEvent<any>;
|
|
8
|
+
};
|
|
9
|
+
slots: {};
|
|
10
|
+
exports?: {} | undefined;
|
|
11
|
+
bindings?: string | undefined;
|
|
12
|
+
};
|
|
13
|
+
export type CodeProps = typeof __propDef.props;
|
|
14
|
+
export type CodeEvents = typeof __propDef.events;
|
|
15
|
+
export type CodeSlots = typeof __propDef.slots;
|
|
16
|
+
export default class Code extends SvelteComponent<CodeProps, CodeEvents, CodeSlots> {
|
|
17
|
+
}
|
|
18
|
+
export {};
|
|
@@ -2,6 +2,7 @@ export namespace components {
|
|
|
2
2
|
export { Arraybuilder as arraybuilder };
|
|
3
3
|
export { Checkbox as checkbox };
|
|
4
4
|
export { CheckboxAutocomplete as checkbox_autocomplete };
|
|
5
|
+
export { Code as code };
|
|
5
6
|
export { Contactselector as contactselector };
|
|
6
7
|
export { Currency as currency };
|
|
7
8
|
export { Dataindication as dataindication };
|
|
@@ -44,6 +45,7 @@ export namespace components {
|
|
|
44
45
|
import Arraybuilder from "./Arraybuilder.svelte";
|
|
45
46
|
import Checkbox from "./Checkbox.svelte";
|
|
46
47
|
import CheckboxAutocomplete from "./CheckboxAutocomplete.svelte";
|
|
48
|
+
import Code from "./Code.svelte";
|
|
47
49
|
import Contactselector from "./Contactselector.svelte";
|
|
48
50
|
import Currency from "./Currency.svelte";
|
|
49
51
|
import Dataindication from "./Dataindication.svelte";
|
|
@@ -37,11 +37,13 @@ import Text from "./Text.svelte";
|
|
|
37
37
|
import Voicenote from "./Voicenote.svelte";
|
|
38
38
|
import SmartText from "./SmartText.svelte";
|
|
39
39
|
import CheckboxAutocomplete from "./CheckboxAutocomplete.svelte";
|
|
40
|
+
import Code from "./Code.svelte";
|
|
40
41
|
|
|
41
42
|
export const components = {
|
|
42
43
|
arraybuilder: Arraybuilder,
|
|
43
44
|
checkbox: Checkbox,
|
|
44
45
|
checkbox_autocomplete: CheckboxAutocomplete,
|
|
46
|
+
code: Code,
|
|
45
47
|
contactselector: Contactselector,
|
|
46
48
|
currency: Currency,
|
|
47
49
|
dataindication: Dataindication,
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"fieldtype": "code",
|
|
3
|
+
"description": "Code Editing Field",
|
|
4
|
+
"settings_form": {
|
|
5
|
+
"fields": {
|
|
6
|
+
"text_description": {
|
|
7
|
+
"fieldtype": "heading",
|
|
8
|
+
"params": {
|
|
9
|
+
"subheading_text": "Write code with syntax highlighting"
|
|
10
|
+
},
|
|
11
|
+
"__order": 0
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
export namespace definitions {
|
|
2
|
-
export { _all };
|
|
3
|
-
export { _valid_fieldtype };
|
|
2
|
+
export { all as _all };
|
|
3
|
+
export { validfieldtype as _valid_fieldtype };
|
|
4
|
+
export { placeholder as _placeholder };
|
|
4
5
|
export { arraybuilder };
|
|
5
6
|
export { checkbox };
|
|
7
|
+
export { code };
|
|
6
8
|
export { contactselector };
|
|
7
9
|
export { currency };
|
|
8
10
|
export { dataindication };
|
|
@@ -35,20 +37,21 @@ export namespace definitions {
|
|
|
35
37
|
export { selectresource };
|
|
36
38
|
export { signature };
|
|
37
39
|
export { slider };
|
|
38
|
-
export { smart_text };
|
|
40
|
+
export { smarttext as smart_text };
|
|
39
41
|
export { telephone };
|
|
40
42
|
export { text };
|
|
41
43
|
export { voicenote };
|
|
42
|
-
export { _placeholder };
|
|
43
44
|
}
|
|
44
45
|
export const selectableFieldtypes: ({
|
|
45
46
|
label: string;
|
|
46
47
|
value: string;
|
|
47
48
|
} | null)[];
|
|
48
|
-
import
|
|
49
|
-
import
|
|
49
|
+
import all from "./all.json";
|
|
50
|
+
import validfieldtype from "./validfieldtype.json";
|
|
51
|
+
import placeholder from "./placeholder.json";
|
|
50
52
|
import arraybuilder from "./arraybuilder.json";
|
|
51
53
|
import checkbox from "./checkbox.json";
|
|
54
|
+
import code from "./code.json";
|
|
52
55
|
import contactselector from "./contactselector.json";
|
|
53
56
|
import currency from "./currency.json";
|
|
54
57
|
import dataindication from "./dataindication.json";
|
|
@@ -81,8 +84,7 @@ import select from "./select.json";
|
|
|
81
84
|
import selectresource from "./selectresource.json";
|
|
82
85
|
import signature from "./signature.json";
|
|
83
86
|
import slider from "./slider.json";
|
|
84
|
-
import
|
|
87
|
+
import smarttext from "./smarttext.json";
|
|
85
88
|
import telephone from "./telephone.json";
|
|
86
89
|
import text from "./text.json";
|
|
87
90
|
import voicenote from "./voicenote.json";
|
|
88
|
-
import _placeholder from "./_placeholder.json";
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
//
|
|
2
|
-
import
|
|
3
|
-
import
|
|
1
|
+
// special non-field definitions
|
|
2
|
+
import all from "./all.json";
|
|
3
|
+
import validfieldtype from "./validfieldtype.json";
|
|
4
|
+
import placeholder from "./placeholder.json";
|
|
5
|
+
|
|
4
6
|
import arraybuilder from "./arraybuilder.json";
|
|
5
7
|
import checkbox from "./checkbox.json";
|
|
8
|
+
import code from "./code.json";
|
|
6
9
|
import contactselector from "./contactselector.json";
|
|
7
10
|
import currency from "./currency.json";
|
|
8
11
|
import dataindication from "./dataindication.json";
|
|
@@ -27,7 +30,6 @@ import objectbuilder from "./objectbuilder.json";
|
|
|
27
30
|
import qrcodescanner from "./qrcodescanner.json";
|
|
28
31
|
import radio from "./radio.json";
|
|
29
32
|
import renderfield from "./renderfield.json";
|
|
30
|
-
// import richtext from "./richtext.json";
|
|
31
33
|
import screenrecorder from "./screenrecorder.json";
|
|
32
34
|
import screenshot from "./screenshot.json";
|
|
33
35
|
import scrollandreaddisplay from "./scrollandreaddisplay.json";
|
|
@@ -36,17 +38,18 @@ import select from "./select.json";
|
|
|
36
38
|
import selectresource from "./selectresource.json";
|
|
37
39
|
import signature from "./signature.json";
|
|
38
40
|
import slider from "./slider.json";
|
|
39
|
-
import
|
|
41
|
+
import smarttext from "./smarttext.json";
|
|
40
42
|
import telephone from "./telephone.json";
|
|
41
43
|
import text from "./text.json";
|
|
42
44
|
import voicenote from "./voicenote.json";
|
|
43
|
-
import _placeholder from "./_placeholder.json";
|
|
44
45
|
|
|
45
46
|
export const definitions = {
|
|
46
|
-
_all,
|
|
47
|
-
_valid_fieldtype,
|
|
47
|
+
_all: all,
|
|
48
|
+
_valid_fieldtype: validfieldtype,
|
|
49
|
+
_placeholder: placeholder,
|
|
48
50
|
arraybuilder,
|
|
49
51
|
checkbox,
|
|
52
|
+
code,
|
|
50
53
|
contactselector,
|
|
51
54
|
currency,
|
|
52
55
|
dataindication,
|
|
@@ -71,7 +74,6 @@ export const definitions = {
|
|
|
71
74
|
qrcodescanner,
|
|
72
75
|
radio,
|
|
73
76
|
renderfield,
|
|
74
|
-
// richtext,
|
|
75
77
|
screenrecorder,
|
|
76
78
|
screenshot,
|
|
77
79
|
scrollandreaddisplay,
|
|
@@ -80,11 +82,10 @@ export const definitions = {
|
|
|
80
82
|
selectresource,
|
|
81
83
|
signature,
|
|
82
84
|
slider,
|
|
83
|
-
smart_text,
|
|
85
|
+
smart_text: smarttext,
|
|
84
86
|
telephone,
|
|
85
87
|
text,
|
|
86
88
|
voicenote,
|
|
87
|
-
_placeholder,
|
|
88
89
|
};
|
|
89
90
|
|
|
90
91
|
export const selectableFieldtypes = Object.entries(definitions)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stubber/form-fields",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.1",
|
|
4
4
|
"description": "An automatic form builder based on field specifications",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"components",
|
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
"@sveltejs/kit": "^2.0.0",
|
|
37
37
|
"@sveltejs/package": "^2.2.2",
|
|
38
38
|
"@sveltejs/vite-plugin-svelte": "^3.0.0",
|
|
39
|
+
"@types/codemirror": "^5.60.16",
|
|
39
40
|
"autoprefixer": "^10.4.15",
|
|
40
41
|
"chalk": "^5.3.0",
|
|
41
42
|
"eslint": "^8.28.0",
|
|
@@ -55,13 +56,15 @@
|
|
|
55
56
|
"type": "module",
|
|
56
57
|
"dependencies": {
|
|
57
58
|
"@beyonk/svelte-mapbox": "^11.0.0",
|
|
58
|
-
"@codemirror/autocomplete": "^6.
|
|
59
|
-
"@codemirror/commands": "^6.
|
|
60
|
-
"@codemirror/
|
|
61
|
-
"@codemirror/
|
|
59
|
+
"@codemirror/autocomplete": "^6.19.0",
|
|
60
|
+
"@codemirror/commands": "^6.8.1",
|
|
61
|
+
"@codemirror/lang-javascript": "^6.2.4",
|
|
62
|
+
"@codemirror/state": "^6.5.2",
|
|
63
|
+
"@codemirror/view": "^6.38.4",
|
|
62
64
|
"@stubber/ui": "^1.12.3",
|
|
63
65
|
"ag-grid-community": "^31.0.2",
|
|
64
66
|
"ag-grid-enterprise": "^31.0.2",
|
|
67
|
+
"codemirror": "^6.0.2",
|
|
65
68
|
"currency-symbol-map": "^5.1.0",
|
|
66
69
|
"currency.js": "^2.0.4",
|
|
67
70
|
"dotenv": "^16.3.1",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|