@texaryn/vue 0.0.0 → 0.1.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 (64) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/LICENSE +190 -0
  3. package/README.md +91 -0
  4. package/dist/components/FormRoot.d.ts +17 -0
  5. package/dist/components/FormRoot.d.ts.map +1 -0
  6. package/dist/components/FormRoot.js +24 -0
  7. package/dist/components/FormRoot.js.map +1 -0
  8. package/dist/components/NodeRenderer.d.ts +22 -0
  9. package/dist/components/NodeRenderer.d.ts.map +1 -0
  10. package/dist/components/NodeRenderer.js +24 -0
  11. package/dist/components/NodeRenderer.js.map +1 -0
  12. package/dist/context.d.ts +29 -0
  13. package/dist/context.d.ts.map +1 -0
  14. package/dist/context.js +43 -0
  15. package/dist/context.js.map +1 -0
  16. package/dist/field-props.d.ts +29 -0
  17. package/dist/field-props.d.ts.map +1 -0
  18. package/dist/field-props.js +26 -0
  19. package/dist/field-props.js.map +1 -0
  20. package/dist/index.d.ts +20 -0
  21. package/dist/index.d.ts.map +1 -0
  22. package/dist/index.js +14 -0
  23. package/dist/index.js.map +1 -0
  24. package/dist/use-field-array.d.ts +20 -0
  25. package/dist/use-field-array.d.ts.map +1 -0
  26. package/dist/use-field-array.js +43 -0
  27. package/dist/use-field-array.js.map +1 -0
  28. package/dist/use-field-widget.d.ts +33 -0
  29. package/dist/use-field-widget.d.ts.map +1 -0
  30. package/dist/use-field-widget.js +66 -0
  31. package/dist/use-field-widget.js.map +1 -0
  32. package/dist/use-field.d.ts +28 -0
  33. package/dist/use-field.d.ts.map +1 -0
  34. package/dist/use-field.js +47 -0
  35. package/dist/use-field.js.map +1 -0
  36. package/dist/use-form.d.ts +26 -0
  37. package/dist/use-form.d.ts.map +1 -0
  38. package/dist/use-form.js +36 -0
  39. package/dist/use-form.js.map +1 -0
  40. package/dist/use-store.d.ts +19 -0
  41. package/dist/use-store.d.ts.map +1 -0
  42. package/dist/use-store.js +29 -0
  43. package/dist/use-store.js.map +1 -0
  44. package/dist/widget.d.ts +11 -0
  45. package/dist/widget.d.ts.map +1 -0
  46. package/dist/widget.js +2 -0
  47. package/dist/widget.js.map +1 -0
  48. package/dist/widgets/FieldErrors.d.ts +24 -0
  49. package/dist/widgets/FieldErrors.d.ts.map +1 -0
  50. package/dist/widgets/FieldErrors.js +16 -0
  51. package/dist/widgets/FieldErrors.js.map +1 -0
  52. package/dist/widgets/containers.d.ts +29 -0
  53. package/dist/widgets/containers.d.ts.map +1 -0
  54. package/dist/widgets/containers.js +50 -0
  55. package/dist/widgets/containers.js.map +1 -0
  56. package/dist/widgets/default-registry.d.ts +9 -0
  57. package/dist/widgets/default-registry.d.ts.map +1 -0
  58. package/dist/widgets/default-registry.js +46 -0
  59. package/dist/widgets/default-registry.js.map +1 -0
  60. package/dist/widgets/inputs.d.ts +68 -0
  61. package/dist/widgets/inputs.d.ts.map +1 -0
  62. package/dist/widgets/inputs.js +94 -0
  63. package/dist/widgets/inputs.js.map +1 -0
  64. package/package.json +50 -3
@@ -0,0 +1,43 @@
1
+ import { computed, toValue } from 'vue';
2
+ import { useFormRuntime } from './context.js';
3
+ import { useStore } from './use-store.js';
4
+ export function useFieldArray(nodeId) {
5
+ const runtime = useFormRuntime();
6
+ const document = useStore(runtime.document, runtime.document.getSnapshot());
7
+ const container = computed(() => {
8
+ const node = document.value.nodes[toValue(nodeId)];
9
+ return node?.type === 'container' && node.containerType === 'array'
10
+ ? node
11
+ : undefined;
12
+ });
13
+ const items = computed(() => {
14
+ const meta = container.value?.arrayMeta;
15
+ if (!meta)
16
+ return [];
17
+ return meta.itemIds.map((id, index) => ({
18
+ id,
19
+ nodeId: container.value?.children[index],
20
+ }));
21
+ });
22
+ return {
23
+ items,
24
+ canAdd: computed(() => container.value?.arrayMeta?.canAdd ?? false),
25
+ canRemove: computed(() => container.value?.arrayMeta?.canRemove ?? false),
26
+ canReorder: computed(() => container.value?.arrayMeta?.canReorder ?? false),
27
+ add: (value) => {
28
+ runtime.dispatch({
29
+ type: 'InsertItem',
30
+ containerId: toValue(nodeId),
31
+ index: items.value.length,
32
+ value,
33
+ });
34
+ },
35
+ remove: (index) => {
36
+ runtime.dispatch({ type: 'RemoveItem', containerId: toValue(nodeId), index });
37
+ },
38
+ move: (from, to) => {
39
+ runtime.dispatch({ type: 'MoveItem', containerId: toValue(nodeId), from, to });
40
+ },
41
+ };
42
+ }
43
+ //# sourceMappingURL=use-field-array.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-field-array.js","sourceRoot":"","sources":["../src/use-field-array.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,KAAK,CAAA;AAGvC,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAoBzC,MAAM,UAAU,aAAa,CAAC,MAAgC;IAC5D,MAAM,OAAO,GAAG,cAAc,EAAE,CAAA;IAChC,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAA;IAE3E,MAAM,SAAS,GAAG,QAAQ,CAAC,GAAG,EAAE;QAC9B,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAA;QAClD,OAAO,IAAI,EAAE,IAAI,KAAK,WAAW,IAAI,IAAI,CAAC,aAAa,KAAK,OAAO;YACjE,CAAC,CAAE,IAAsB;YACzB,CAAC,CAAC,SAAS,CAAA;IACf,CAAC,CAAC,CAAA;IAEF,MAAM,KAAK,GAAG,QAAQ,CAAmB,GAAG,EAAE;QAC5C,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,EAAE,SAAS,CAAA;QACvC,IAAI,CAAC,IAAI;YAAE,OAAO,EAAE,CAAA;QACpB,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;YACtC,EAAE;YACF,MAAM,EAAE,SAAS,CAAC,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC;SACzC,CAAC,CAAC,CAAA;IACL,CAAC,CAAC,CAAA;IAEF,OAAO;QACL,KAAK;QACL,MAAM,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,IAAI,KAAK,CAAC;QACnE,SAAS,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,KAAK,EAAE,SAAS,EAAE,SAAS,IAAI,KAAK,CAAC;QACzE,UAAU,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,KAAK,EAAE,SAAS,EAAE,UAAU,IAAI,KAAK,CAAC;QAC3E,GAAG,EAAE,CAAC,KAAe,EAAE,EAAE;YACvB,OAAO,CAAC,QAAQ,CAAC;gBACf,IAAI,EAAE,YAAY;gBAClB,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC;gBAC5B,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM;gBACzB,KAAK;aACN,CAAC,CAAA;QACJ,CAAC;QACD,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;YACxB,OAAO,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,CAAA;QAC/E,CAAC;QACD,IAAI,EAAE,CAAC,IAAY,EAAE,EAAU,EAAE,EAAE;YACjC,OAAO,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAA;QAChF,CAAC;KACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,33 @@
1
+ import type { ComputedRef, MaybeRefOrGetter, Ref } from 'vue';
2
+ import type { FieldNode, ValidationError } from '@texaryn/core';
3
+ import type { FieldAria } from './field-props.js';
4
+ export type FieldKind = 'enum' | 'boolean' | 'number' | 'string';
5
+ export declare function fieldKind(node: FieldNode): FieldKind;
6
+ export declare function displayValue(kind: FieldKind, value: unknown): string | number;
7
+ export declare function coerce(kind: FieldKind, node: FieldNode, raw: string): unknown;
8
+ export interface FieldWidget {
9
+ node: ComputedRef<FieldNode>;
10
+ kind: ComputedRef<FieldKind>;
11
+ value: Ref<unknown>;
12
+ display: ComputedRef<string | number>;
13
+ label: ComputedRef<string>;
14
+ description: ComputedRef<string | undefined>;
15
+ descriptionId: ComputedRef<string>;
16
+ errorId: ComputedRef<string>;
17
+ labelFor: ComputedRef<string>;
18
+ aria: ComputedRef<FieldAria>;
19
+ /** Visible errors only: empty until the display policy says to show them. */
20
+ errors: ComputedRef<readonly ValidationError[]>;
21
+ invalid: ComputedRef<boolean>;
22
+ setRaw(raw: string): void;
23
+ setValue(value: unknown): void;
24
+ onBlur(): void;
25
+ }
26
+ /**
27
+ * Everything a native widget needs, derived from a node that is allowed to
28
+ * change under it. The node arrives as a getter for the same reason the node
29
+ * id does in useField: an array move hands a widget a different node while
30
+ * keeping its component instance.
31
+ */
32
+ export declare function useFieldWidget(nodeSource: MaybeRefOrGetter<FieldNode>): FieldWidget;
33
+ //# sourceMappingURL=use-field-widget.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-field-widget.d.ts","sourceRoot":"","sources":["../src/use-field-widget.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,GAAG,EAAE,MAAM,KAAK,CAAA;AAE7D,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAG/D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAIjD,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAA;AAGhE,wBAAgB,SAAS,CAAC,IAAI,EAAE,SAAS,GAAG,SAAS,CAKpD;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAI7E;AAED,wBAAgB,MAAM,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAO7E;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,WAAW,CAAC,SAAS,CAAC,CAAA;IAC5B,IAAI,EAAE,WAAW,CAAC,SAAS,CAAC,CAAA;IAC5B,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IACnB,OAAO,EAAE,WAAW,CAAC,MAAM,GAAG,MAAM,CAAC,CAAA;IACrC,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IAC1B,WAAW,EAAE,WAAW,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;IAC5C,aAAa,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IAClC,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IAC5B,QAAQ,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IAC7B,IAAI,EAAE,WAAW,CAAC,SAAS,CAAC,CAAA;IAC5B,6EAA6E;IAC7E,MAAM,EAAE,WAAW,CAAC,SAAS,eAAe,EAAE,CAAC,CAAA;IAC/C,OAAO,EAAE,WAAW,CAAC,OAAO,CAAC,CAAA;IAC7B,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAA;IAC9B,MAAM,IAAI,IAAI,CAAA;CACf;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,gBAAgB,CAAC,SAAS,CAAC,GAAG,WAAW,CA+BnF"}
@@ -0,0 +1,66 @@
1
+ import { computed } from 'vue';
2
+ import { toValue } from 'vue';
3
+ import { useField } from './use-field.js';
4
+ import { fieldAria, fieldLabel, makeId } from './field-props.js';
5
+ const NO_ERRORS = Object.freeze([]);
6
+ // Mirrors the default registry's ranking: enum outranks the primitive kind.
7
+ export function fieldKind(node) {
8
+ if (node.enumValues != null && node.enumValues.length > 0)
9
+ return 'enum';
10
+ if (node.fieldType === 'boolean')
11
+ return 'boolean';
12
+ if (node.fieldType === 'number' || node.fieldType === 'integer')
13
+ return 'number';
14
+ return 'string';
15
+ }
16
+ export function displayValue(kind, value) {
17
+ if (kind === 'number' && typeof value === 'number')
18
+ return value;
19
+ if (kind === 'string' && typeof value === 'string')
20
+ return value;
21
+ return value == null ? '' : String(value);
22
+ }
23
+ export function coerce(kind, node, raw) {
24
+ if (kind === 'number')
25
+ return raw === '' ? undefined : Number(raw);
26
+ if (kind === 'enum') {
27
+ const option = (node.enumValues ?? []).find((o) => String(o.value) === raw);
28
+ return option ? option.value : raw;
29
+ }
30
+ return raw;
31
+ }
32
+ /**
33
+ * Everything a native widget needs, derived from a node that is allowed to
34
+ * change under it. The node arrives as a getter for the same reason the node
35
+ * id does in useField: an array move hands a widget a different node while
36
+ * keeping its component instance.
37
+ */
38
+ export function useFieldWidget(nodeSource) {
39
+ const node = computed(() => toValue(nodeSource));
40
+ const field = useField(() => node.value.id);
41
+ const kind = computed(() => fieldKind(node.value));
42
+ const errors = computed(() => (field.showErrors.value ? field.errors.value : NO_ERRORS));
43
+ const invalid = computed(() => errors.value.length > 0);
44
+ return {
45
+ node,
46
+ kind,
47
+ value: field.value,
48
+ display: computed(() => displayValue(kind.value, field.value.value)),
49
+ label: computed(() => fieldLabel(node.value)),
50
+ description: computed(() => node.value.helpText ?? node.value.annotations.description),
51
+ descriptionId: computed(() => makeId(node.value.id, 'description')),
52
+ errorId: computed(() => makeId(node.value.id, 'error')),
53
+ labelFor: computed(() => makeId(node.value.id, 'input')),
54
+ aria: computed(() => fieldAria(node.value, {
55
+ disabled: field.disabled.value,
56
+ showErrors: field.showErrors.value,
57
+ errors: field.errors.value,
58
+ })),
59
+ errors,
60
+ invalid,
61
+ setRaw: (raw) => { field.onChange(coerce(kind.value, node.value, raw)); },
62
+ setValue: field.onChange,
63
+ onBlur: field.onBlur,
64
+ };
65
+ }
66
+ //# sourceMappingURL=use-field-widget.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-field-widget.js","sourceRoot":"","sources":["../src/use-field-widget.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import type { MaybeRefOrGetter, Ref } from 'vue';
2
+ import type { NodeId, ValidationError } from '@texaryn/core';
3
+ export interface UseFieldReturn {
4
+ value: Ref<unknown>;
5
+ errors: Ref<ValidationError[]>;
6
+ dirty: Ref<boolean>;
7
+ touched: Ref<boolean>;
8
+ visible: Ref<boolean>;
9
+ disabled: Ref<boolean>;
10
+ showErrors: Ref<boolean>;
11
+ onChange(value: unknown): void;
12
+ onBlur(): void;
13
+ }
14
+ /**
15
+ * The node id is accepted as a ref or getter, not a value, and that is load
16
+ * bearing rather than a convenience.
17
+ *
18
+ * Node ids are assigned by traversal order, so an array item's id follows its
19
+ * position. Item identity is carried separately, by `StableItemId`, and a
20
+ * widget keyed on that correctly survives a move with its component instance
21
+ * intact while the id underneath it changes. React re-reads the id on every
22
+ * render, so it follows along for free. A Vue composable that captured the id
23
+ * in `setup` would keep subscribing to the old position and, worse, keep
24
+ * dispatching to it: typing into a moved row would write to the row that took
25
+ * its place.
26
+ */
27
+ export declare function useField(nodeId: MaybeRefOrGetter<NodeId>): UseFieldReturn;
28
+ //# sourceMappingURL=use-field.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-field.d.ts","sourceRoot":"","sources":["../src/use-field.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,GAAG,EAAE,MAAM,KAAK,CAAA;AAChD,OAAO,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAI5D,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IACnB,MAAM,EAAE,GAAG,CAAC,eAAe,EAAE,CAAC,CAAA;IAC9B,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IACnB,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IACrB,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IACrB,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IACtB,UAAU,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IACxB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAA;IAC9B,MAAM,IAAI,IAAI,CAAA;CACf;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC,MAAM,CAAC,GAAG,cAAc,CA+BzE"}
@@ -0,0 +1,47 @@
1
+ import { computed, toValue } from 'vue';
2
+ import { useFormRuntime } from './context.js';
3
+ import { useStore } from './use-store.js';
4
+ /**
5
+ * The node id is accepted as a ref or getter, not a value, and that is load
6
+ * bearing rather than a convenience.
7
+ *
8
+ * Node ids are assigned by traversal order, so an array item's id follows its
9
+ * position. Item identity is carried separately, by `StableItemId`, and a
10
+ * widget keyed on that correctly survives a move with its component instance
11
+ * intact while the id underneath it changes. React re-reads the id on every
12
+ * render, so it follows along for free. A Vue composable that captured the id
13
+ * in `setup` would keep subscribing to the old position and, worse, keep
14
+ * dispatching to it: typing into a moved row would write to the row that took
15
+ * its place.
16
+ */
17
+ export function useField(nodeId) {
18
+ const runtime = useFormRuntime();
19
+ const document = useStore(runtime.document, runtime.document.getSnapshot());
20
+ // `getNodeState` is a map lookup, so nothing about it is reactive on its
21
+ // own. Reading the document ref here is what makes a recompile re-resolve
22
+ // the bundle: a node id that disappeared and came back is a different
23
+ // bundle, and without this the field would hold the discarded one.
24
+ const state = computed(() => {
25
+ void document.value;
26
+ return runtime.getNodeState(toValue(nodeId));
27
+ });
28
+ return {
29
+ value: useStore(() => state.value?.value, undefined),
30
+ errors: useStore(() => state.value?.errors, []),
31
+ dirty: useStore(() => state.value?.dirty, false),
32
+ touched: useStore(() => state.value?.touched, false),
33
+ visible: useStore(() => state.value?.visible, true),
34
+ disabled: useStore(() => state.value?.disabled, false),
35
+ showErrors: useStore(() => state.value?.showErrors, false),
36
+ // Read at call time, never captured. Subscriptions following the id is
37
+ // only half of it: a dispatch carrying a stale id writes to the wrong
38
+ // data pointer, and no amount of correct reading would show it.
39
+ onChange: (value) => {
40
+ runtime.dispatch({ type: 'SetValue', nodeId: toValue(nodeId), value });
41
+ },
42
+ onBlur: () => {
43
+ runtime.dispatch({ type: 'SetTouched', nodeId: toValue(nodeId) });
44
+ },
45
+ };
46
+ }
47
+ //# sourceMappingURL=use-field.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-field.js","sourceRoot":"","sources":["../src/use-field.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,KAAK,CAAA;AAGvC,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAczC;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,QAAQ,CAAC,MAAgC;IACvD,MAAM,OAAO,GAAG,cAAc,EAAE,CAAA;IAChC,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAA;IAE3E,yEAAyE;IACzE,0EAA0E;IAC1E,sEAAsE;IACtE,mEAAmE;IACnE,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,EAAE;QAC1B,KAAK,QAAQ,CAAC,KAAK,CAAA;QACnB,OAAO,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAA;IAC9C,CAAC,CAAC,CAAA;IAEF,OAAO;QACL,KAAK,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,CAAC;QACpD,MAAM,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,EAAuB,CAAC;QACpE,KAAK,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;QAChD,OAAO,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,CAAC;QACpD,OAAO,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC;QACnD,QAAQ,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC;QACtD,UAAU,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,CAAC;QAC1D,uEAAuE;QACvE,sEAAsE;QACtE,gEAAgE;QAChE,QAAQ,EAAE,CAAC,KAAc,EAAE,EAAE;YAC3B,OAAO,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,CAAA;QACxE,CAAC;QACD,MAAM,EAAE,GAAG,EAAE;YACX,OAAO,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;QACnE,CAAC;KACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,26 @@
1
+ import type { Ref } from 'vue';
2
+ import type { Command, FormRuntime, FormRuntimeOptions, NodeId, NodeState, SchemaEvaluationPort, SubmissionState, UIDocument, VisibleError } from '@texaryn/core';
3
+ export interface UseFormReturn {
4
+ runtime: FormRuntime;
5
+ document: Ref<UIDocument>;
6
+ data: Ref<unknown>;
7
+ submission: Ref<SubmissionState>;
8
+ visibleErrors: Ref<VisibleError[]>;
9
+ dispatch(command: Command): void;
10
+ getNodeState(nodeId: NodeId): NodeState | undefined;
11
+ }
12
+ /**
13
+ * Creates the runtime once and ties its lifetime to the calling scope.
14
+ *
15
+ * React needs a ref plus an effect to avoid recreating the runtime on every
16
+ * render. `setup` runs once, so the runtime is simply a local, and the whole
17
+ * question disappears rather than being solved differently. What replaces it
18
+ * is the requirement of a scope: the runtime's lifetime is the scope's.
19
+ *
20
+ * Providing is deliberately not folded in here. React's equivalent is a
21
+ * component in the template, `<FormProvider value={form.runtime}>`, and Vue's
22
+ * is a setup call, so `provideFormRuntime` stays the caller's explicit second
23
+ * step rather than a side effect of construction.
24
+ */
25
+ export declare function useForm(port: SchemaEvaluationPort, options?: FormRuntimeOptions): UseFormReturn;
26
+ //# sourceMappingURL=use-form.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-form.d.ts","sourceRoot":"","sources":["../src/use-form.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,KAAK,CAAA;AAE9B,OAAO,KAAK,EACV,OAAO,EACP,WAAW,EACX,kBAAkB,EAClB,MAAM,EACN,SAAS,EACT,oBAAoB,EACpB,eAAe,EACf,UAAU,EACV,YAAY,EACb,MAAM,eAAe,CAAA;AAGtB,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,WAAW,CAAA;IACpB,QAAQ,EAAE,GAAG,CAAC,UAAU,CAAC,CAAA;IACzB,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IAClB,UAAU,EAAE,GAAG,CAAC,eAAe,CAAC,CAAA;IAChC,aAAa,EAAE,GAAG,CAAC,YAAY,EAAE,CAAC,CAAA;IAClC,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAA;IAChC,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAAA;CACpD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,oBAAoB,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,aAAa,CAsB/F"}
@@ -0,0 +1,36 @@
1
+ import { getCurrentScope, onScopeDispose } from 'vue';
2
+ import { createFormRuntime } from '@texaryn/core';
3
+ import { useStore } from './use-store.js';
4
+ /**
5
+ * Creates the runtime once and ties its lifetime to the calling scope.
6
+ *
7
+ * React needs a ref plus an effect to avoid recreating the runtime on every
8
+ * render. `setup` runs once, so the runtime is simply a local, and the whole
9
+ * question disappears rather than being solved differently. What replaces it
10
+ * is the requirement of a scope: the runtime's lifetime is the scope's.
11
+ *
12
+ * Providing is deliberately not folded in here. React's equivalent is a
13
+ * component in the template, `<FormProvider value={form.runtime}>`, and Vue's
14
+ * is a setup call, so `provideFormRuntime` stays the caller's explicit second
15
+ * step rather than a side effect of construction.
16
+ */
17
+ export function useForm(port, options) {
18
+ // Before the runtime exists, so a misuse cannot leak one. A FormRuntime
19
+ // holds validation timers and subscriptions and is only released by
20
+ // `destroy`, so an owner that will eventually call it is a requirement.
21
+ if (!getCurrentScope()) {
22
+ throw new Error('useForm must be called inside setup() or an active effectScope, which owns the runtime');
23
+ }
24
+ const runtime = createFormRuntime(port, options);
25
+ onScopeDispose(() => { runtime.destroy(); });
26
+ return {
27
+ runtime,
28
+ document: useStore(runtime.document, runtime.document.getSnapshot()),
29
+ data: useStore(runtime.data, undefined),
30
+ submission: useStore(runtime.submission, runtime.submission.getSnapshot()),
31
+ visibleErrors: useStore(runtime.visibleErrors, []),
32
+ dispatch: (command) => { runtime.dispatch(command); },
33
+ getNodeState: (nodeId) => runtime.getNodeState(nodeId),
34
+ };
35
+ }
36
+ //# sourceMappingURL=use-form.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-form.js","sourceRoot":"","sources":["../src/use-form.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,KAAK,CAAA;AAErD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AAYjD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAYzC;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,OAAO,CAAC,IAA0B,EAAE,OAA4B;IAC9E,wEAAwE;IACxE,oEAAoE;IACpE,wEAAwE;IACxE,IAAI,CAAC,eAAe,EAAE,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CACb,wFAAwF,CACzF,CAAA;IACH,CAAC;IAED,MAAM,OAAO,GAAG,iBAAiB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;IAChD,cAAc,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,CAAA,CAAC,CAAC,CAAC,CAAA;IAE3C,OAAO;QACL,OAAO;QACP,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;QACpE,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC;QACvC,UAAU,EAAE,QAAQ,CAAC,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC;QAC1E,aAAa,EAAE,QAAQ,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC;QAClD,QAAQ,EAAE,CAAC,OAAgB,EAAE,EAAE,GAAG,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA,CAAC,CAAC;QAC7D,YAAY,EAAE,CAAC,MAAc,EAAE,EAAE,CAAC,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC;KAC/D,CAAA;AACH,CAAC"}
@@ -0,0 +1,19 @@
1
+ import type { Ref } from 'vue';
2
+ import type { Store } from '@texaryn/core';
3
+ /**
4
+ * A Texaryn store, read as a Vue ref.
5
+ *
6
+ * This is where the two bindings genuinely diverge rather than differ in
7
+ * spelling. React's `useStore` re-runs on every render, so it re-reads the
8
+ * store expression each time and `useSyncExternalStore` swaps subscriptions
9
+ * for free. A Vue composable runs once in `setup`, so the subscription has to
10
+ * be managed: accepting a getter and watching it is what replaces the
11
+ * re-render.
12
+ *
13
+ * `shallowRef` rather than `ref`: snapshots are plain data owned by the
14
+ * runtime, and deep reactive conversion would both cost a proxy walk per
15
+ * update and hand callers a mutable view of state they do not own.
16
+ */
17
+ export declare function useStore<T>(source: Store<T> | (() => Store<T> | undefined), fallback: T): Ref<T>;
18
+ export declare function useStore<T>(source: Store<T> | (() => Store<T> | undefined)): Ref<T | undefined>;
19
+ //# sourceMappingURL=use-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-store.d.ts","sourceRoot":"","sources":["../src/use-store.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,KAAK,CAAA;AAC9B,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAE1C;;;;;;;;;;;;;GAaG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAA;AACjG,wBAAgB,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,SAAS,CAAC,CAAA"}
@@ -0,0 +1,29 @@
1
+ import { getCurrentScope, onScopeDispose, shallowRef, watch } from 'vue';
2
+ export function useStore(source, fallback) {
3
+ // Checked before anything is created, so a misuse cannot leak the thing it
4
+ // was about to subscribe to. This composable owns a subscription it never
5
+ // hands back, so an owner that will eventually stop it is a requirement
6
+ // rather than a convention: without a scope there is nobody to unsubscribe.
7
+ if (!getCurrentScope()) {
8
+ throw new Error('useStore must be called inside setup() or an active effectScope, which owns its subscription');
9
+ }
10
+ const getStore = typeof source === 'function' ? source : () => source;
11
+ // Presence of a store decides the fallback, never the snapshot's value. A
12
+ // field holding null or undefined is a real value, not an absent store.
13
+ const initial = getStore();
14
+ const state = shallowRef(initial ? initial.getSnapshot() : fallback);
15
+ const stop = watch(getStore, (store, _previous, onCleanup) => {
16
+ if (!store) {
17
+ state.value = fallback;
18
+ return;
19
+ }
20
+ // Between the previous read and this subscribe the store may already
21
+ // have moved, so seed from the snapshot rather than waiting for a
22
+ // notification that has been and gone.
23
+ state.value = store.getSnapshot();
24
+ onCleanup(store.subscribe(() => { state.value = store.getSnapshot(); }));
25
+ }, { immediate: true });
26
+ onScopeDispose(stop);
27
+ return state;
28
+ }
29
+ //# sourceMappingURL=use-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-store.js","sourceRoot":"","sources":["../src/use-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,KAAK,CAAA;AAoBxE,MAAM,UAAU,QAAQ,CACtB,MAA+C,EAC/C,QAAY;IAEZ,2EAA2E;IAC3E,0EAA0E;IAC1E,wEAAwE;IACxE,4EAA4E;IAC5E,IAAI,CAAC,eAAe,EAAE,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CACb,8FAA8F,CAC/F,CAAA;IACH,CAAC;IAED,MAAM,QAAQ,GAAG,OAAO,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,MAAM,CAAA;IACrE,0EAA0E;IAC1E,wEAAwE;IACxE,MAAM,OAAO,GAAG,QAAQ,EAAE,CAAA;IAC1B,MAAM,KAAK,GAAG,UAAU,CAAgB,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAA;IAEnF,MAAM,IAAI,GAAG,KAAK,CAChB,QAAQ,EACR,CAAC,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE;QAC9B,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,KAAK,CAAC,KAAK,GAAG,QAAQ,CAAA;YACtB,OAAM;QACR,CAAC;QACD,qEAAqE;QACrE,kEAAkE;QAClE,uCAAuC;QACvC,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,WAAW,EAAE,CAAA;QACjC,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,WAAW,EAAE,CAAA,CAAC,CAAC,CAAC,CAAC,CAAA;IACzE,CAAC,EACD,EAAE,SAAS,EAAE,IAAI,EAAE,CACpB,CAAA;IAED,cAAc,CAAC,IAAI,CAAC,CAAA;IAEpB,OAAO,KAAK,CAAA;AACd,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { Component } from 'vue';
2
+ import type { UINode } from '@texaryn/core';
3
+ /**
4
+ * A widget receives only the node it renders, matching React's contract,
5
+ * because `RendererRegistry<T>` fixes the widget prop shape. Everything else
6
+ * a container needs (the document, the registry) arrives through inject.
7
+ */
8
+ export type WidgetComponent = Component<{
9
+ node: UINode;
10
+ }>;
11
+ //# sourceMappingURL=widget.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"widget.d.ts","sourceRoot":"","sources":["../src/widget.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,KAAK,CAAA;AACpC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AAE3C;;;;GAIG;AACH,MAAM,MAAM,eAAe,GAAG,SAAS,CAAC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAAA"}
package/dist/widget.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=widget.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"widget.js","sourceRoot":"","sources":["../src/widget.ts"],"names":[],"mappings":""}
@@ -0,0 +1,24 @@
1
+ import type { PropType } from 'vue';
2
+ import type { ValidationError } from '@texaryn/core';
3
+ export declare const FieldErrors: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
4
+ id: {
5
+ type: StringConstructor;
6
+ required: true;
7
+ };
8
+ errors: {
9
+ type: PropType<readonly ValidationError[]>;
10
+ required: true;
11
+ };
12
+ }>, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
13
+ [key: string]: any;
14
+ }> | null, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
15
+ id: {
16
+ type: StringConstructor;
17
+ required: true;
18
+ };
19
+ errors: {
20
+ type: PropType<readonly ValidationError[]>;
21
+ required: true;
22
+ };
23
+ }>> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
24
+ //# sourceMappingURL=FieldErrors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FieldErrors.d.ts","sourceRoot":"","sources":["../../src/widgets/FieldErrors.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAA;AACnC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAEpD,eAAO,MAAM,WAAW;;;;;;cAIK,QAAQ,CAAC,SAAS,eAAe,EAAE,CAAC;;;;;;;;;;;cAApC,QAAQ,CAAC,SAAS,eAAe,EAAE,CAAC;;;iGAe/D,CAAA"}
@@ -0,0 +1,16 @@
1
+ import { defineComponent, h } from 'vue';
2
+ export const FieldErrors = defineComponent({
3
+ name: 'FieldErrors',
4
+ props: {
5
+ id: { type: String, required: true },
6
+ errors: { type: Array, required: true },
7
+ },
8
+ setup(props) {
9
+ return () => {
10
+ if (props.errors.length === 0)
11
+ return null;
12
+ return h('div', { id: props.id, role: 'alert' }, props.errors.map((error, index) => h('div', { key: `${error.instancePointer}:${error.keyword}:${index}` }, error.message ?? error.keyword)));
13
+ };
14
+ },
15
+ });
16
+ //# sourceMappingURL=FieldErrors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FieldErrors.js","sourceRoot":"","sources":["../../src/widgets/FieldErrors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAIxC,MAAM,CAAC,MAAM,WAAW,GAAG,eAAe,CAAC;IACzC,IAAI,EAAE,aAAa;IACnB,KAAK,EAAE;QACL,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE;QACpC,MAAM,EAAE,EAAE,IAAI,EAAE,KAA6C,EAAE,QAAQ,EAAE,IAAI,EAAE;KAChF;IACD,KAAK,CAAC,KAAK;QACT,OAAO,GAAG,EAAE;YACV,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO,IAAI,CAAA;YAC1C,OAAO,CAAC,CACN,KAAK,EACL,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAC/B,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAChC,CAAC,CAAC,KAAK,EAAE,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC,eAAe,IAAI,KAAK,CAAC,OAAO,IAAI,KAAK,EAAE,EAAE,EACpE,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,CAClC,CACF,CAAA;QACH,CAAC,CAAA;IACH,CAAC;CACF,CAAC,CAAA"}
@@ -0,0 +1,29 @@
1
+ import type { PropType } from 'vue';
2
+ import type { UINode } from '@texaryn/core';
3
+ export declare const ObjectLayout: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
4
+ readonly node: {
5
+ readonly type: PropType<UINode>;
6
+ readonly required: true;
7
+ };
8
+ }>, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
9
+ [key: string]: any;
10
+ }>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
11
+ readonly node: {
12
+ readonly type: PropType<UINode>;
13
+ readonly required: true;
14
+ };
15
+ }>> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
16
+ export declare const ArrayControl: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
17
+ readonly node: {
18
+ readonly type: PropType<UINode>;
19
+ readonly required: true;
20
+ };
21
+ }>, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
22
+ [key: string]: any;
23
+ }>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
24
+ readonly node: {
25
+ readonly type: PropType<UINode>;
26
+ readonly required: true;
27
+ };
28
+ }>> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
29
+ //# sourceMappingURL=containers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"containers.d.ts","sourceRoot":"","sources":["../../src/widgets/containers.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAA;AACnC,OAAO,KAAK,EAAiB,MAAM,EAAE,MAAM,eAAe,CAAA;AAQ1D,eAAO,MAAM,YAAY;;uBAFkB,QAAQ,CAAC,MAAM,CAAC;;;;;;;uBAAhB,QAAQ,CAAC,MAAM,CAAC;;;iGAoBzD,CAAA;AAEF,eAAO,MAAM,YAAY;;uBAtBkB,QAAQ,CAAC,MAAM,CAAC;;;;;;;uBAAhB,QAAQ,CAAC,MAAM,CAAC;;;iGAyDzD,CAAA"}
@@ -0,0 +1,50 @@
1
+ import { computed, defineComponent, h } from 'vue';
2
+ import { useFormRuntime } from '../context.js';
3
+ import { useStore } from '../use-store.js';
4
+ import { useFieldArray } from '../use-field-array.js';
5
+ import { NodeRenderer } from '../components/NodeRenderer.js';
6
+ const nodeProp = { node: { type: Object, required: true } };
7
+ export const ObjectLayout = defineComponent({
8
+ name: 'ObjectLayout',
9
+ props: nodeProp,
10
+ setup(props) {
11
+ const runtime = useFormRuntime();
12
+ const document = useStore(runtime.document, runtime.document.getSnapshot());
13
+ const children = computed(() => props.node.children
14
+ .map((id) => document.value.nodes[id])
15
+ .filter((child) => child != null));
16
+ return () => h('div', children.value.map((child) => h(NodeRenderer, { key: child.id, node: child })));
17
+ },
18
+ });
19
+ export const ArrayControl = defineComponent({
20
+ name: 'ArrayControl',
21
+ props: nodeProp,
22
+ setup(props) {
23
+ const runtime = useFormRuntime();
24
+ const document = useStore(runtime.document, runtime.document.getSnapshot());
25
+ const array = useFieldArray(() => props.node.id);
26
+ return () => h('div', [
27
+ ...array.items.value.map((item, index) => {
28
+ const child = item.nodeId ? document.value.nodes[item.nodeId] : undefined;
29
+ return h('div',
30
+ // Keyed by the stable item id, never the positional node id. That
31
+ // is what makes a move preserve the row's component instance and
32
+ // its DOM, and it is also what hands the surviving instance a
33
+ // different node than the one it mounted with.
34
+ { key: item.id }, [
35
+ child ? h(NodeRenderer, { node: child }) : null,
36
+ array.canRemove.value
37
+ ? h('button', { type: 'button', onClick: () => array.remove(index) }, 'Remove')
38
+ : null,
39
+ array.canReorder.value && index > 0
40
+ ? h('button', { type: 'button', onClick: () => array.move(index, index - 1) }, 'Up')
41
+ : null,
42
+ ]);
43
+ }),
44
+ array.canAdd.value
45
+ ? h('button', { type: 'button', onClick: () => array.add() }, 'Add')
46
+ : null,
47
+ ]);
48
+ },
49
+ });
50
+ //# sourceMappingURL=containers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"containers.js","sourceRoot":"","sources":["../../src/widgets/containers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { RendererRegistry } from '@texaryn/core';
2
+ import type { WidgetComponent } from '../widget.js';
3
+ /**
4
+ * The same tests and ranks as the React default registry, on purpose. If the
5
+ * two ever disagree about which widget a node resolves to, the difference is
6
+ * a renderer's opinion leaking into what the document means.
7
+ */
8
+ export declare function createDefaultRegistry(): RendererRegistry<WidgetComponent>;
9
+ //# sourceMappingURL=default-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"default-registry.d.ts","sourceRoot":"","sources":["../../src/widgets/default-registry.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAa,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAChE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAInD;;;;GAIG;AACH,wBAAgB,qBAAqB,IAAI,gBAAgB,CAAC,eAAe,CAAC,CAoEzE"}
@@ -0,0 +1,46 @@
1
+ import { createRendererRegistry } from '@texaryn/core';
2
+ import { Checkbox, NumberInput, Select, Textarea, TextInput } from './inputs.js';
3
+ import { ArrayControl, ObjectLayout } from './containers.js';
4
+ /**
5
+ * The same tests and ranks as the React default registry, on purpose. If the
6
+ * two ever disagree about which widget a node resolves to, the difference is
7
+ * a renderer's opinion leaking into what the document means.
8
+ */
9
+ export function createDefaultRegistry() {
10
+ const registry = createRendererRegistry();
11
+ registry.register({
12
+ test: (node) => node.type === 'field' &&
13
+ node.fieldType === 'string' &&
14
+ node.enumValues == null,
15
+ rank: 1,
16
+ }, TextInput);
17
+ registry.register({
18
+ test: (node) => node.type === 'field' &&
19
+ (node.fieldType === 'number' || node.fieldType === 'integer'),
20
+ rank: 1,
21
+ }, NumberInput);
22
+ registry.register({
23
+ test: (node) => node.type === 'field' && node.fieldType === 'boolean',
24
+ rank: 1,
25
+ }, Checkbox);
26
+ registry.register({
27
+ test: (node) => node.type === 'field' &&
28
+ node.enumValues != null &&
29
+ node.enumValues.length > 0,
30
+ rank: 2,
31
+ }, Select);
32
+ registry.register({
33
+ test: (node) => node.type === 'field' && node.widget === 'textarea',
34
+ rank: 5,
35
+ }, Textarea);
36
+ registry.register({
37
+ test: (node) => node.type === 'container' && node.containerType === 'object',
38
+ rank: 1,
39
+ }, ObjectLayout);
40
+ registry.register({
41
+ test: (node) => node.type === 'container' && node.containerType === 'array',
42
+ rank: 1,
43
+ }, ArrayControl);
44
+ return registry;
45
+ }
46
+ //# sourceMappingURL=default-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"default-registry.js","sourceRoot":"","sources":["../../src/widgets/default-registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAA;AAGtD,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAChF,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAE5D;;;;GAIG;AACH,MAAM,UAAU,qBAAqB;IACnC,MAAM,QAAQ,GAAG,sBAAsB,EAAmB,CAAA;IAE1D,QAAQ,CAAC,QAAQ,CACf;QACE,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CACb,IAAI,CAAC,IAAI,KAAK,OAAO;YACpB,IAAkB,CAAC,SAAS,KAAK,QAAQ;YACzC,IAAkB,CAAC,UAAU,IAAI,IAAI;QACxC,IAAI,EAAE,CAAC;KACR,EACD,SAAS,CACV,CAAA;IAED,QAAQ,CAAC,QAAQ,CACf;QACE,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CACb,IAAI,CAAC,IAAI,KAAK,OAAO;YACrB,CAAE,IAAkB,CAAC,SAAS,KAAK,QAAQ,IAAK,IAAkB,CAAC,SAAS,KAAK,SAAS,CAAC;QAC7F,IAAI,EAAE,CAAC;KACR,EACD,WAAW,CACZ,CAAA;IAED,QAAQ,CAAC,QAAQ,CACf;QACE,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,OAAO,IAAK,IAAkB,CAAC,SAAS,KAAK,SAAS;QACpF,IAAI,EAAE,CAAC;KACR,EACD,QAAQ,CACT,CAAA;IAED,QAAQ,CAAC,QAAQ,CACf;QACE,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CACb,IAAI,CAAC,IAAI,KAAK,OAAO;YACpB,IAAkB,CAAC,UAAU,IAAI,IAAI;YACrC,IAAkB,CAAC,UAAW,CAAC,MAAM,GAAG,CAAC;QAC5C,IAAI,EAAE,CAAC;KACR,EACD,MAAM,CACP,CAAA;IAED,QAAQ,CAAC,QAAQ,CACf;QACE,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,OAAO,IAAK,IAAkB,CAAC,MAAM,KAAK,UAAU;QAClF,IAAI,EAAE,CAAC;KACR,EACD,QAAQ,CACT,CAAA;IAED,QAAQ,CAAC,QAAQ,CACf;QACE,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,WAAW,IAAI,IAAI,CAAC,aAAa,KAAK,QAAQ;QAC5E,IAAI,EAAE,CAAC;KACR,EACD,YAAY,CACb,CAAA;IAED,QAAQ,CAAC,QAAQ,CACf;QACE,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,WAAW,IAAI,IAAI,CAAC,aAAa,KAAK,OAAO;QAC3E,IAAI,EAAE,CAAC;KACR,EACD,YAAY,CACb,CAAA;IAED,OAAO,QAAQ,CAAA;AACjB,CAAC"}