@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.
@@ -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 "./_all.json";
49
- import _valid_fieldtype from "./_valid_fieldtype.json";
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 "./smart_text.json";
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 "./_placeholder.json";
90
+ import _placeholder from "$lib/fields/definitions/_placeholder.json";
@@ -1,8 +1,9 @@
1
1
  // import _ from "lodash-es";
2
- import _all from "./_all.json";
3
- import _valid_fieldtype from "./_valid_fieldtype.json";
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 "./smart_text.json";
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 "./_placeholder.json";
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.0",
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.18.1",
59
- "@codemirror/commands": "^6.7.1",
60
- "@codemirror/state": "^6.4.1",
61
- "@codemirror/view": "^6.34.1",
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",