@stubber/form-fields 1.3.0 → 1.4.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/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 +6 -4
- package/dist/fields/definitions/index.js +6 -4
- package/package.json +8 -5
|
@@ -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
|
+
}
|
|
@@ -3,6 +3,7 @@ export namespace definitions {
|
|
|
3
3
|
export { _valid_fieldtype };
|
|
4
4
|
export { arraybuilder };
|
|
5
5
|
export { checkbox };
|
|
6
|
+
export { code };
|
|
6
7
|
export { contactselector };
|
|
7
8
|
export { currency };
|
|
8
9
|
export { dataindication };
|
|
@@ -45,10 +46,11 @@ export const selectableFieldtypes: ({
|
|
|
45
46
|
label: string;
|
|
46
47
|
value: string;
|
|
47
48
|
} | null)[];
|
|
48
|
-
import _all from "
|
|
49
|
-
import _valid_fieldtype from "
|
|
49
|
+
import _all from "$lib/fields/definitions/_all.json";
|
|
50
|
+
import _valid_fieldtype from "$lib/fields/definitions/_valid_fieldtype.json";
|
|
50
51
|
import arraybuilder from "./arraybuilder.json";
|
|
51
52
|
import checkbox from "./checkbox.json";
|
|
53
|
+
import code from "./code.json";
|
|
52
54
|
import contactselector from "./contactselector.json";
|
|
53
55
|
import currency from "./currency.json";
|
|
54
56
|
import dataindication from "./dataindication.json";
|
|
@@ -81,8 +83,8 @@ import select from "./select.json";
|
|
|
81
83
|
import selectresource from "./selectresource.json";
|
|
82
84
|
import signature from "./signature.json";
|
|
83
85
|
import slider from "./slider.json";
|
|
84
|
-
import smart_text from "
|
|
86
|
+
import smart_text from "$lib/fields/definitions/smart_text.json";
|
|
85
87
|
import telephone from "./telephone.json";
|
|
86
88
|
import text from "./text.json";
|
|
87
89
|
import voicenote from "./voicenote.json";
|
|
88
|
-
import _placeholder from "
|
|
90
|
+
import _placeholder from "$lib/fields/definitions/_placeholder.json";
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
// import _ from "lodash-es";
|
|
2
|
-
import _all from "
|
|
3
|
-
import _valid_fieldtype from "
|
|
2
|
+
import _all from "$lib/fields/definitions/_all.json";
|
|
3
|
+
import _valid_fieldtype from "$lib/fields/definitions/_valid_fieldtype.json";
|
|
4
4
|
import arraybuilder from "./arraybuilder.json";
|
|
5
5
|
import checkbox from "./checkbox.json";
|
|
6
|
+
import code from "./code.json";
|
|
6
7
|
import contactselector from "./contactselector.json";
|
|
7
8
|
import currency from "./currency.json";
|
|
8
9
|
import dataindication from "./dataindication.json";
|
|
@@ -36,17 +37,18 @@ import select from "./select.json";
|
|
|
36
37
|
import selectresource from "./selectresource.json";
|
|
37
38
|
import signature from "./signature.json";
|
|
38
39
|
import slider from "./slider.json";
|
|
39
|
-
import smart_text from "
|
|
40
|
+
import smart_text from "$lib/fields/definitions/smart_text.json";
|
|
40
41
|
import telephone from "./telephone.json";
|
|
41
42
|
import text from "./text.json";
|
|
42
43
|
import voicenote from "./voicenote.json";
|
|
43
|
-
import _placeholder from "
|
|
44
|
+
import _placeholder from "$lib/fields/definitions/_placeholder.json";
|
|
44
45
|
|
|
45
46
|
export const definitions = {
|
|
46
47
|
_all,
|
|
47
48
|
_valid_fieldtype,
|
|
48
49
|
arraybuilder,
|
|
49
50
|
checkbox,
|
|
51
|
+
code,
|
|
50
52
|
contactselector,
|
|
51
53
|
currency,
|
|
52
54
|
dataindication,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stubber/form-fields",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
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",
|