@narrative.io/jsonforms-provider-protocols 1.0.3 → 1.1.0-beta.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 (73) hide show
  1. package/dist/jsonforms-provider-protocols.css +6 -2
  2. package/dist/protocols/rest_api.d.ts.map +1 -1
  3. package/dist/protocols/rest_api.js +5 -1
  4. package/dist/protocols/rest_api.js.map +1 -1
  5. package/dist/vue/components/ProviderAutocomplete.vue.d.ts.map +1 -1
  6. package/dist/vue/components/ProviderAutocomplete.vue.js +36 -23
  7. package/dist/vue/components/ProviderAutocomplete.vue.js.map +1 -1
  8. package/dist/vue/components/ProviderSelect.vue.d.ts.map +1 -1
  9. package/dist/vue/components/ProviderSelect.vue.js +1 -1
  10. package/dist/vue/components/ProviderSelect.vue2.js +34 -28
  11. package/dist/vue/components/ProviderSelect.vue2.js.map +1 -1
  12. package/dist/vue/composables/useProvider.d.ts +10 -2
  13. package/dist/vue/composables/useProvider.d.ts.map +1 -1
  14. package/dist/vue/composables/useProvider.js +4 -2
  15. package/dist/vue/composables/useProvider.js.map +1 -1
  16. package/dist/vue/index.d.ts +2 -0
  17. package/dist/vue/index.d.ts.map +1 -1
  18. package/dist/vue/index.js +18 -2
  19. package/dist/vue/index.js.map +1 -1
  20. package/dist/vue/primevue/JfBoolean.vue.d.ts +75 -0
  21. package/dist/vue/primevue/JfBoolean.vue.d.ts.map +1 -0
  22. package/dist/vue/primevue/JfBoolean.vue.js +36 -0
  23. package/dist/vue/primevue/JfBoolean.vue.js.map +1 -0
  24. package/dist/vue/primevue/JfBoolean.vue2.js +5 -0
  25. package/dist/vue/primevue/JfBoolean.vue2.js.map +1 -0
  26. package/dist/vue/primevue/JfEnum.vue.d.ts +75 -0
  27. package/dist/vue/primevue/JfEnum.vue.d.ts.map +1 -0
  28. package/dist/vue/primevue/JfEnum.vue.js +8 -0
  29. package/dist/vue/primevue/JfEnum.vue.js.map +1 -0
  30. package/dist/vue/primevue/JfEnum.vue2.js +65 -0
  31. package/dist/vue/primevue/JfEnum.vue2.js.map +1 -0
  32. package/dist/vue/primevue/JfEnumArray.vue.d.ts +75 -0
  33. package/dist/vue/primevue/JfEnumArray.vue.d.ts.map +1 -0
  34. package/dist/vue/primevue/JfEnumArray.vue.js +84 -0
  35. package/dist/vue/primevue/JfEnumArray.vue.js.map +1 -0
  36. package/dist/vue/primevue/JfEnumArray.vue2.js +5 -0
  37. package/dist/vue/primevue/JfEnumArray.vue2.js.map +1 -0
  38. package/dist/vue/primevue/JfNumber.vue.d.ts +75 -0
  39. package/dist/vue/primevue/JfNumber.vue.d.ts.map +1 -0
  40. package/dist/vue/primevue/JfNumber.vue.js +50 -0
  41. package/dist/vue/primevue/JfNumber.vue.js.map +1 -0
  42. package/dist/vue/primevue/JfNumber.vue2.js +5 -0
  43. package/dist/vue/primevue/JfNumber.vue2.js.map +1 -0
  44. package/dist/vue/primevue/JfText.vue.d.ts +75 -0
  45. package/dist/vue/primevue/JfText.vue.d.ts.map +1 -0
  46. package/dist/vue/primevue/JfText.vue.js +56 -0
  47. package/dist/vue/primevue/JfText.vue.js.map +1 -0
  48. package/dist/vue/primevue/JfText.vue2.js +5 -0
  49. package/dist/vue/primevue/JfText.vue2.js.map +1 -0
  50. package/dist/vue/primevue/JfTextArea.vue.d.ts +75 -0
  51. package/dist/vue/primevue/JfTextArea.vue.d.ts.map +1 -0
  52. package/dist/vue/primevue/JfTextArea.vue.js +55 -0
  53. package/dist/vue/primevue/JfTextArea.vue.js.map +1 -0
  54. package/dist/vue/primevue/JfTextArea.vue2.js +5 -0
  55. package/dist/vue/primevue/JfTextArea.vue2.js.map +1 -0
  56. package/dist/vue/primevue/index.d.ts +83 -0
  57. package/dist/vue/primevue/index.d.ts.map +1 -0
  58. package/dist/vue/primevue/index.js +71 -0
  59. package/dist/vue/primevue/index.js.map +1 -0
  60. package/package.json +7 -2
  61. package/src/protocols/rest_api.ts +8 -1
  62. package/src/vue/components/ProviderAutocomplete.vue +31 -12
  63. package/src/vue/components/ProviderSelect.vue +40 -21
  64. package/src/vue/composables/useProvider.ts +3 -2
  65. package/src/vue/index.ts +7 -2
  66. package/src/vue/primevue/JfBoolean.vue +26 -0
  67. package/src/vue/primevue/JfEnum.vue +67 -0
  68. package/src/vue/primevue/JfEnumArray.vue +85 -0
  69. package/src/vue/primevue/JfNumber.vue +42 -0
  70. package/src/vue/primevue/JfText.vue +47 -0
  71. package/src/vue/primevue/JfTextArea.vue +46 -0
  72. package/src/vue/primevue/index.ts +99 -0
  73. package/src/vue/styles.css +15 -0
@@ -0,0 +1,75 @@
1
+ import type { ControlElement } from "@jsonforms/core";
2
+ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
3
+ schema: {
4
+ required: true;
5
+ type: import("vue").PropType<import("@jsonforms/core").JsonSchema>;
6
+ };
7
+ uischema: {
8
+ required: true;
9
+ type: import("vue").PropType<ControlElement>;
10
+ };
11
+ path: {
12
+ required: true;
13
+ type: StringConstructor;
14
+ };
15
+ enabled: {
16
+ required: false;
17
+ type: BooleanConstructor;
18
+ default: undefined;
19
+ };
20
+ renderers: {
21
+ required: boolean;
22
+ type: import("vue").PropType<import("@jsonforms/core").JsonFormsRendererRegistryEntry[]>;
23
+ default: undefined;
24
+ };
25
+ cells: {
26
+ required: boolean;
27
+ type: import("vue").PropType<import("@jsonforms/core").JsonFormsCellRendererRegistryEntry[]>;
28
+ default: undefined;
29
+ };
30
+ config: {
31
+ required: boolean;
32
+ type: ObjectConstructor;
33
+ default: undefined;
34
+ };
35
+ }>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
36
+ schema: {
37
+ required: true;
38
+ type: import("vue").PropType<import("@jsonforms/core").JsonSchema>;
39
+ };
40
+ uischema: {
41
+ required: true;
42
+ type: import("vue").PropType<ControlElement>;
43
+ };
44
+ path: {
45
+ required: true;
46
+ type: StringConstructor;
47
+ };
48
+ enabled: {
49
+ required: false;
50
+ type: BooleanConstructor;
51
+ default: undefined;
52
+ };
53
+ renderers: {
54
+ required: boolean;
55
+ type: import("vue").PropType<import("@jsonforms/core").JsonFormsRendererRegistryEntry[]>;
56
+ default: undefined;
57
+ };
58
+ cells: {
59
+ required: boolean;
60
+ type: import("vue").PropType<import("@jsonforms/core").JsonFormsCellRendererRegistryEntry[]>;
61
+ default: undefined;
62
+ };
63
+ config: {
64
+ required: boolean;
65
+ type: ObjectConstructor;
66
+ default: undefined;
67
+ };
68
+ }>> & Readonly<{}>, {
69
+ enabled: boolean;
70
+ renderers: import("@jsonforms/core").JsonFormsRendererRegistryEntry[];
71
+ cells: import("@jsonforms/core").JsonFormsCellRendererRegistryEntry[];
72
+ config: Record<string, any>;
73
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
74
+ export default _default;
75
+ //# sourceMappingURL=JfTextArea.vue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JfTextArea.vue.d.ts","sourceRoot":"","sources":["../../../src/vue/primevue/JfTextArea.vue"],"names":[],"mappings":"AAgDA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiItD,wBAEG"}
@@ -0,0 +1,55 @@
1
+ import { defineComponent, computed, createElementBlock, openBlock, createCommentVNode, createVNode, unref, toDisplayString } from "vue";
2
+ import { rendererProps, useJsonFormsControl } from "@jsonforms/vue";
3
+ import Textarea from "primevue/textarea";
4
+ const _hoisted_1 = { class: "flex flex-column gap-2" };
5
+ const _hoisted_2 = {
6
+ key: 0,
7
+ class: "text-color text-left"
8
+ };
9
+ const _hoisted_3 = {
10
+ key: 1,
11
+ class: "text-color-secondary text-left"
12
+ };
13
+ const _hoisted_4 = {
14
+ key: 2,
15
+ class: "p-error"
16
+ };
17
+ const _sfc_main = /* @__PURE__ */ defineComponent({
18
+ ...{ name: "JfTextArea" },
19
+ __name: "JfTextArea",
20
+ props: rendererProps(),
21
+ setup(__props) {
22
+ const props = __props;
23
+ const { control, handleChange } = useJsonFormsControl(props);
24
+ const placeholder = computed(
25
+ () => control.value.uischema?.options?.placeholder ?? control.value.description
26
+ );
27
+ function onInput(val) {
28
+ const newValue = val ?? "";
29
+ if ((control.value.data ?? "") !== newValue) {
30
+ handleChange(control.value.path, newValue);
31
+ }
32
+ }
33
+ return (_ctx, _cache) => {
34
+ return openBlock(), createElementBlock("div", _hoisted_1, [
35
+ unref(control).label ? (openBlock(), createElementBlock("label", _hoisted_2, toDisplayString(unref(control).label), 1)) : createCommentVNode("", true),
36
+ unref(control).description ? (openBlock(), createElementBlock("div", _hoisted_3, toDisplayString(unref(control).description), 1)) : createCommentVNode("", true),
37
+ createVNode(unref(Textarea), {
38
+ class: "w-full",
39
+ "model-value": unref(control).data ?? "",
40
+ disabled: !unref(control).enabled,
41
+ "aria-invalid": !!unref(control).errors || void 0,
42
+ placeholder: placeholder.value,
43
+ rows: 4,
44
+ "auto-resize": true,
45
+ "onUpdate:modelValue": onInput
46
+ }, null, 8, ["model-value", "disabled", "aria-invalid", "placeholder"]),
47
+ unref(control).errors ? (openBlock(), createElementBlock("small", _hoisted_4, toDisplayString(unref(control).errors), 1)) : createCommentVNode("", true)
48
+ ]);
49
+ };
50
+ }
51
+ });
52
+ export {
53
+ _sfc_main as default
54
+ };
55
+ //# sourceMappingURL=JfTextArea.vue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JfTextArea.vue.js","sources":["../../../src/vue/primevue/JfTextArea.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { ControlElement } from \"@jsonforms/core\";\nimport { rendererProps, useJsonFormsControl } from \"@jsonforms/vue\";\nimport { computed } from \"vue\";\nimport Textarea from \"primevue/textarea\";\n\ndefineOptions({ name: \"JfTextArea\" });\n\nconst props = defineProps(rendererProps<ControlElement>());\nconst { control, handleChange } = useJsonFormsControl(props);\n\nconst placeholder = computed<string | undefined>(\n () =>\n (control.value.uischema as { options?: { placeholder?: string } })?.options\n ?.placeholder ?? control.value.description,\n);\n\nfunction onInput(val: string | undefined) {\n const newValue = val ?? \"\";\n if ((control.value.data ?? \"\") !== newValue) {\n handleChange(control.value.path, newValue);\n }\n}\n</script>\n\n<template>\n <div class=\"flex flex-column gap-2\">\n <label v-if=\"control.label\" class=\"text-color text-left\">{{\n control.label\n }}</label>\n <div v-if=\"control.description\" class=\"text-color-secondary text-left\">\n {{ control.description }}\n </div>\n <Textarea\n class=\"w-full\"\n :model-value=\"control.data ?? ''\"\n :disabled=\"!control.enabled\"\n :aria-invalid=\"!!control.errors || undefined\"\n :placeholder=\"placeholder\"\n :rows=\"4\"\n :auto-resize=\"true\"\n @update:model-value=\"onInput\"\n />\n <small v-if=\"control.errors\" class=\"p-error\">{{ control.errors }}</small>\n </div>\n</template>\n"],"names":["_openBlock","_createElementBlock","_unref","_toDisplayString","_createVNode"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAQA,UAAM,QAAQ;AACd,UAAM,EAAE,SAAS,iBAAiB,oBAAoB,KAAK;AAE3D,UAAM,cAAc;AAAA,MAClB,MACG,QAAQ,MAAM,UAAqD,SAChE,eAAe,QAAQ,MAAM;AAAA,IAAA;AAGrC,aAAS,QAAQ,KAAyB;AACxC,YAAM,WAAW,OAAO;AACxB,WAAK,QAAQ,MAAM,QAAQ,QAAQ,UAAU;AAC3C,qBAAa,QAAQ,MAAM,MAAM,QAAQ;AAAA,MAC3C;AAAA,IACF;;AAIE,aAAAA,UAAA,GAAAC,mBAkBM,OAlBN,YAkBM;AAAA,QAjBSC,MAAA,OAAA,EAAQ,SAArBF,UAAA,GAAAC,mBAEU,SAFV,YAEUE,gBADRD,MAAA,OAAA,EAAQ,KAAK,GAAA,CAAA;QAEJA,MAAA,OAAA,EAAQ,eAAnBF,UAAA,GAAAC,mBAEM,OAFN,YAEME,gBADDD,MAAA,OAAA,EAAQ,WAAW,GAAA,CAAA;QAExBE,YASEF,MAAA,QAAA,GAAA;AAAA,UARA,OAAM;AAAA,UACL,eAAaA,MAAA,OAAA,EAAQ,QAAI;AAAA,UACzB,UAAQ,CAAGA,MAAA,OAAA,EAAQ;AAAA,UACnB,gBAAY,CAAA,CAAIA,MAAA,OAAA,EAAQ,UAAU;AAAA,UAClC,aAAa,YAAA;AAAA,UACb,MAAM;AAAA,UACN,eAAa;AAAA,UACb,uBAAoB;AAAA,QAAA;QAEVA,MAAA,OAAA,EAAQ,UAArBF,UAAA,GAAAC,mBAAyE,SAAzE,YAAyEE,gBAAzBD,MAAA,OAAA,EAAQ,MAAM,GAAA,CAAA;;;;;"}
@@ -0,0 +1,5 @@
1
+ import _sfc_main from "./JfTextArea.vue.js";
2
+ export {
3
+ _sfc_main as default
4
+ };
5
+ //# sourceMappingURL=JfTextArea.vue2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JfTextArea.vue2.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
@@ -0,0 +1,83 @@
1
+ import JfText from "./JfText.vue";
2
+ import JfTextArea from "./JfTextArea.vue";
3
+ import JfNumber from "./JfNumber.vue";
4
+ import JfEnum from "./JfEnum.vue";
5
+ import JfEnumArray from "./JfEnumArray.vue";
6
+ import JfBoolean from "./JfBoolean.vue";
7
+ export declare const primevueRenderers: {
8
+ tester: (uischema: import("@jsonforms/core").UISchemaElement, schema: import("@jsonforms/core").JsonSchema, context: import("@jsonforms/core").TesterContext) => number;
9
+ renderer: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
10
+ schema: {
11
+ required: true;
12
+ type: import("vue").PropType<import("@jsonforms/core").JsonSchema>;
13
+ };
14
+ uischema: {
15
+ required: true;
16
+ type: import("vue").PropType<import("@jsonforms/core").ControlElement>;
17
+ };
18
+ path: {
19
+ required: true;
20
+ type: StringConstructor;
21
+ };
22
+ enabled: {
23
+ required: false;
24
+ type: BooleanConstructor;
25
+ default: undefined;
26
+ };
27
+ renderers: {
28
+ required: boolean;
29
+ type: import("vue").PropType<import("@jsonforms/core").JsonFormsRendererRegistryEntry[]>;
30
+ default: undefined;
31
+ };
32
+ cells: {
33
+ required: boolean;
34
+ type: import("vue").PropType<import("@jsonforms/core").JsonFormsCellRendererRegistryEntry[]>;
35
+ default: undefined;
36
+ };
37
+ config: {
38
+ required: boolean;
39
+ type: ObjectConstructor;
40
+ default: undefined;
41
+ };
42
+ }>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
43
+ schema: {
44
+ required: true;
45
+ type: import("vue").PropType<import("@jsonforms/core").JsonSchema>;
46
+ };
47
+ uischema: {
48
+ required: true;
49
+ type: import("vue").PropType<import("@jsonforms/core").ControlElement>;
50
+ };
51
+ path: {
52
+ required: true;
53
+ type: StringConstructor;
54
+ };
55
+ enabled: {
56
+ required: false;
57
+ type: BooleanConstructor;
58
+ default: undefined;
59
+ };
60
+ renderers: {
61
+ required: boolean;
62
+ type: import("vue").PropType<import("@jsonforms/core").JsonFormsRendererRegistryEntry[]>;
63
+ default: undefined;
64
+ };
65
+ cells: {
66
+ required: boolean;
67
+ type: import("vue").PropType<import("@jsonforms/core").JsonFormsCellRendererRegistryEntry[]>;
68
+ default: undefined;
69
+ };
70
+ config: {
71
+ required: boolean;
72
+ type: ObjectConstructor;
73
+ default: undefined;
74
+ };
75
+ }>> & Readonly<{}>, {
76
+ enabled: boolean;
77
+ renderers: import("@jsonforms/core").JsonFormsRendererRegistryEntry[];
78
+ cells: import("@jsonforms/core").JsonFormsCellRendererRegistryEntry[];
79
+ config: Record<string, any>;
80
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
81
+ }[];
82
+ export { JfText, JfTextArea, JfNumber, JfEnum, JfEnumArray, JfBoolean };
83
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/vue/primevue/index.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,cAAc,CAAC;AAClC,OAAO,UAAU,MAAM,kBAAkB,CAAC;AAC1C,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,MAAM,MAAM,cAAc,CAAC;AAClC,OAAO,WAAW,MAAM,mBAAmB,CAAC;AAC5C,OAAO,SAAS,MAAM,iBAAiB,CAAC;AA0ExC,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiB7B,CAAC;AAEF,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,CAAC"}
@@ -0,0 +1,71 @@
1
+ import _sfc_main$1 from "./JfText.vue.js";
2
+ import _sfc_main from "./JfTextArea.vue.js";
3
+ import _sfc_main$2 from "./JfNumber.vue.js";
4
+ import JfEnum from "./JfEnum.vue.js";
5
+ import _sfc_main$3 from "./JfEnumArray.vue.js";
6
+ import _sfc_main$4 from "./JfBoolean.vue.js";
7
+ import { rankWith, isStringControl, or, isNumberControl, isIntegerControl, and, isControl, schemaMatches, isBooleanControl } from "@jsonforms/core";
8
+ const injectLayoutStyles = () => {
9
+ if (typeof window !== "undefined" && typeof document !== "undefined") {
10
+ if (!document.getElementById("jsonforms-primevue-styles")) {
11
+ const style = document.createElement("style");
12
+ style.id = "jsonforms-primevue-styles";
13
+ style.textContent = `
14
+ /* JSONForms PrimeVue Provider Protocols Layout Styles */
15
+ .vertical-layout {
16
+ display: flex;
17
+ flex-direction: column;
18
+ align-items: flex-start;
19
+ gap: 1rem;
20
+ width: 100%;
21
+ }
22
+
23
+ .vertical-layout-item {
24
+ width: 100%;
25
+ }
26
+ `;
27
+ document.head.appendChild(style);
28
+ }
29
+ }
30
+ };
31
+ injectLayoutStyles();
32
+ const isScalarEnum = (s) => {
33
+ const schema = s;
34
+ return schema && schema.type !== "array" && (Array.isArray(schema.enum) || Array.isArray(schema.oneOf));
35
+ };
36
+ const isEnumArray = (s) => {
37
+ const schema = s;
38
+ return schema?.type === "array" && (Array.isArray(schema.items?.enum) || Array.isArray(schema.items?.oneOf));
39
+ };
40
+ const isMultilineString = (uischema, schema) => {
41
+ return isStringControl(uischema, schema, {}) && uischema?.options?.multi === true;
42
+ };
43
+ const PRIME = 100;
44
+ const primevueRenderers = [
45
+ // Multiline text has higher priority than regular text
46
+ { tester: rankWith(PRIME + 4, isMultilineString), renderer: _sfc_main },
47
+ { tester: rankWith(PRIME + 3, isStringControl), renderer: _sfc_main$1 },
48
+ {
49
+ tester: rankWith(PRIME + 4, or(isNumberControl, isIntegerControl)),
50
+ renderer: _sfc_main$2
51
+ },
52
+ {
53
+ tester: rankWith(PRIME + 5, and(isControl, schemaMatches(isScalarEnum))),
54
+ renderer: JfEnum
55
+ },
56
+ {
57
+ tester: rankWith(PRIME + 6, and(isControl, schemaMatches(isEnumArray))),
58
+ renderer: _sfc_main$3
59
+ },
60
+ { tester: rankWith(PRIME + 3, isBooleanControl), renderer: _sfc_main$4 }
61
+ ];
62
+ export {
63
+ _sfc_main$4 as JfBoolean,
64
+ JfEnum,
65
+ _sfc_main$3 as JfEnumArray,
66
+ _sfc_main$2 as JfNumber,
67
+ _sfc_main$1 as JfText,
68
+ _sfc_main as JfTextArea,
69
+ primevueRenderers
70
+ };
71
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../../../src/vue/primevue/index.ts"],"sourcesContent":["import JfText from \"./JfText.vue\";\nimport JfTextArea from \"./JfTextArea.vue\";\nimport JfNumber from \"./JfNumber.vue\";\nimport JfEnum from \"./JfEnum.vue\";\nimport JfEnumArray from \"./JfEnumArray.vue\";\nimport JfBoolean from \"./JfBoolean.vue\";\n\n// Auto-inject layout styles\nconst injectLayoutStyles = () => {\n if (typeof window !== \"undefined\" && typeof document !== \"undefined\") {\n if (!document.getElementById(\"jsonforms-primevue-styles\")) {\n const style = document.createElement(\"style\");\n style.id = \"jsonforms-primevue-styles\";\n style.textContent = `\n/* JSONForms PrimeVue Provider Protocols Layout Styles */\n.vertical-layout {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 1rem;\n width: 100%;\n}\n\n.vertical-layout-item {\n width: 100%;\n}\n `;\n document.head.appendChild(style);\n }\n }\n};\n\n// Inject styles when this module is imported\ninjectLayoutStyles();\n\nimport {\n rankWith,\n isStringControl,\n or,\n isNumberControl,\n isIntegerControl,\n and,\n isControl,\n schemaMatches,\n isBooleanControl,\n} from \"@jsonforms/core\";\n\n// helpers for enum detection\nconst isScalarEnum = (s?: object) => {\n const schema = s as { type?: string; enum?: unknown[]; oneOf?: unknown[] };\n return (\n schema &&\n schema.type !== \"array\" &&\n (Array.isArray(schema.enum) || Array.isArray(schema.oneOf))\n );\n};\n\nconst isEnumArray = (s?: object) => {\n const schema = s as {\n type?: string;\n items?: { enum?: unknown[]; oneOf?: unknown[] };\n };\n return (\n schema?.type === \"array\" &&\n (Array.isArray(schema.items?.enum) || Array.isArray(schema.items?.oneOf))\n );\n};\n\n// helper for multiline detection\nconst isMultilineString = (uischema: unknown, schema: unknown) => {\n return (\n isStringControl(uischema as never, schema as never, {} as never) &&\n (uischema as { options?: { multi?: boolean } })?.options?.multi === true\n );\n};\n\n// Give PrimeVue renderers a high base rank; vanilla commonly uses small ranks (2–5)\nconst PRIME = 100;\n\nexport const primevueRenderers = [\n // Multiline text has higher priority than regular text\n { tester: rankWith(PRIME + 4, isMultilineString), renderer: JfTextArea },\n { tester: rankWith(PRIME + 3, isStringControl), renderer: JfText },\n {\n tester: rankWith(PRIME + 4, or(isNumberControl, isIntegerControl)),\n renderer: JfNumber,\n },\n {\n tester: rankWith(PRIME + 5, and(isControl, schemaMatches(isScalarEnum))),\n renderer: JfEnum,\n },\n {\n tester: rankWith(PRIME + 6, and(isControl, schemaMatches(isEnumArray))),\n renderer: JfEnumArray,\n },\n { tester: rankWith(PRIME + 3, isBooleanControl), renderer: JfBoolean },\n];\n\nexport { JfText, JfTextArea, JfNumber, JfEnum, JfEnumArray, JfBoolean };\n"],"names":["JfTextArea","JfText","JfNumber","JfEnumArray","JfBoolean"],"mappings":";;;;;;;AAQA,MAAM,qBAAqB,MAAM;AAC/B,MAAI,OAAO,WAAW,eAAe,OAAO,aAAa,aAAa;AACpE,QAAI,CAAC,SAAS,eAAe,2BAA2B,GAAG;AACzD,YAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,YAAM,KAAK;AACX,YAAM,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAcpB,eAAS,KAAK,YAAY,KAAK;AAAA,IACjC;AAAA,EACF;AACF;AAGA,mBAAA;AAeA,MAAM,eAAe,CAAC,MAAe;AACnC,QAAM,SAAS;AACf,SACE,UACA,OAAO,SAAS,YACf,MAAM,QAAQ,OAAO,IAAI,KAAK,MAAM,QAAQ,OAAO,KAAK;AAE7D;AAEA,MAAM,cAAc,CAAC,MAAe;AAClC,QAAM,SAAS;AAIf,SACE,QAAQ,SAAS,YAChB,MAAM,QAAQ,OAAO,OAAO,IAAI,KAAK,MAAM,QAAQ,OAAO,OAAO,KAAK;AAE3E;AAGA,MAAM,oBAAoB,CAAC,UAAmB,WAAoB;AAChE,SACE,gBAAgB,UAAmB,QAAiB,CAAA,CAAW,KAC9D,UAAgD,SAAS,UAAU;AAExE;AAGA,MAAM,QAAQ;AAEP,MAAM,oBAAoB;AAAA;AAAA,EAE/B,EAAE,QAAQ,SAAS,QAAQ,GAAG,iBAAiB,GAAG,UAAUA,UAAA;AAAA,EAC5D,EAAE,QAAQ,SAAS,QAAQ,GAAG,eAAe,GAAG,UAAUC,YAAA;AAAA,EAC1D;AAAA,IACE,QAAQ,SAAS,QAAQ,GAAG,GAAG,iBAAiB,gBAAgB,CAAC;AAAA,IACjE,UAAUC;AAAAA,EAAA;AAAA,EAEZ;AAAA,IACE,QAAQ,SAAS,QAAQ,GAAG,IAAI,WAAW,cAAc,YAAY,CAAC,CAAC;AAAA,IACvE,UAAU;AAAA,EAAA;AAAA,EAEZ;AAAA,IACE,QAAQ,SAAS,QAAQ,GAAG,IAAI,WAAW,cAAc,WAAW,CAAC,CAAC;AAAA,IACtE,UAAUC;AAAAA,EAAA;AAAA,EAEZ,EAAE,QAAQ,SAAS,QAAQ,GAAG,gBAAgB,GAAG,UAAUC,YAAA;AAC7D;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@narrative.io/jsonforms-provider-protocols",
3
- "version": "1.0.3",
3
+ "version": "1.1.0-beta.0",
4
4
  "description": "Dynamic data provider capabilities for JSONForms with Vue 3 integration",
5
5
  "type": "module",
6
6
  "author": "Narrative I/O",
@@ -64,7 +64,11 @@
64
64
  "test:watch": "bun test --watch",
65
65
  "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix",
66
66
  "lint:check": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts",
67
- "format": "prettier --write src/"
67
+ "format": "prettier --write src/",
68
+ "demo": "cd demo && npm start",
69
+ "demo:install": "cd demo && npm install",
70
+ "demo:dev": "cd demo && npm run dev",
71
+ "demo:api": "cd demo && npm run api"
68
72
  },
69
73
  "devDependencies": {
70
74
  "@commitlint/config-conventional": "^19.8.1",
@@ -83,6 +87,7 @@
83
87
  "eslint-plugin-vue": "^10.4.0",
84
88
  "globals": "^16.3.0",
85
89
  "prettier": "^3.6.2",
90
+ "primevue": "^4.3.8",
86
91
  "typescript": "^5.9.2",
87
92
  "typescript-eslint": "^8.41.0",
88
93
  "vite": "^7.1.3",
@@ -83,7 +83,14 @@ export const RestApiProtocol = (): Protocol<RestApiCfg> => ({
83
83
  let cursor: unknown = null;
84
84
  let page = 0;
85
85
  do {
86
- const url = new URL(renderTpl(cfg.url, { data: ctx.data, ui: ctx.ui }));
86
+ const renderedUrl = renderTpl(cfg.url, { data: ctx.data, ui: ctx.ui });
87
+
88
+ // Check if URL has unresolved template variables (empty string after template rendering)
89
+ if (cfg.url.includes("{{") && renderedUrl.endsWith("/")) {
90
+ return { items: [], ttl: 0 };
91
+ }
92
+
93
+ const url = new URL(renderedUrl);
87
94
  const q = renderObj(cfg.query ?? {}, {
88
95
  data: ctx.data,
89
96
  ui: ctx.ui,
@@ -3,6 +3,7 @@ import type { ControlElement, JsonSchema } from "@jsonforms/core";
3
3
  import { useJsonFormsControl } from "@jsonforms/vue";
4
4
  import { computed, ref, watch } from "vue";
5
5
  import { useProvider } from "../composables/useProvider";
6
+ import AutoComplete from "primevue/autocomplete";
6
7
 
7
8
  const props = defineProps<{
8
9
  uischema: ControlElement;
@@ -19,6 +20,7 @@ const binding = computed(() => {
19
20
  }
20
21
  return provider;
21
22
  });
23
+
22
24
  const query = ref("");
23
25
  const { items, loading, error, reload } = useProvider(binding, {
24
26
  data: control.value.data,
@@ -34,21 +36,38 @@ const value = computed({
34
36
  get: () => control.value.data,
35
37
  set: (v) => handleChange(control.value.path, v),
36
38
  });
39
+
40
+ const placeholder = computed(() =>
41
+ loading.value ? "Loading…" : "Type to search…",
42
+ );
43
+
44
+ const onComplete = (event: { query: string }) => {
45
+ query.value = event.query;
46
+ };
47
+
48
+ const onSelect = (event: { value?: { value?: unknown } | unknown }) => {
49
+ value.value = (event.value as { value?: unknown })?.value ?? event.value;
50
+ };
37
51
  </script>
38
52
 
39
53
  <template>
40
- <div class="provider-autocomplete">
41
- <label>{{ control.schema.title }}</label>
42
- <input
43
- v-model="query"
44
- :placeholder="loading ? 'Loading…' : 'Type to search…'"
45
- type="text"
54
+ <div class="flex flex-column gap-1">
55
+ <label v-if="control.schema.title" class="text-color text-left">{{
56
+ control.schema.title
57
+ }}</label>
58
+ <div v-if="control.description" class="text-color-secondary text-left">
59
+ {{ control.description }}
60
+ </div>
61
+ <AutoComplete
62
+ v-model="value"
63
+ class="w-full"
64
+ :suggestions="items"
65
+ option-label="label"
66
+ :placeholder="placeholder"
67
+ :disabled="!control.enabled"
68
+ @complete="onComplete"
69
+ @item-select="onSelect"
46
70
  />
47
- <ul v-if="items.length">
48
- <li v-for="it in items" :key="String(it.value)" @click="value = it.value">
49
- {{ it.label }}
50
- </li>
51
- </ul>
52
- <small v-if="error" role="alert">Failed: {{ error }}</small>
71
+ <small v-if="error" class="p-error" role="alert">Failed: {{ error }}</small>
53
72
  </div>
54
73
  </template>
@@ -1,8 +1,9 @@
1
1
  <script setup lang="ts">
2
2
  import type { ControlElement, JsonSchema } from "@jsonforms/core";
3
3
  import { useJsonFormsControl } from "@jsonforms/vue";
4
- import { computed, watch } from "vue";
4
+ import { computed, inject } from "vue";
5
5
  import { useProvider } from "../composables/useProvider";
6
+ import Dropdown from "primevue/dropdown";
6
7
 
7
8
  const props = defineProps<{
8
9
  uischema: ControlElement;
@@ -30,41 +31,59 @@ const deps = computed(
30
31
  );
31
32
  const depValues = computed(() => deps.value.map(() => null)); // you can resolve actual values via control.value.data & pointers
32
33
 
33
- const { items, loading, error, reload } = useProvider(binding, {
34
- data: control.value.data,
34
+ // Get the root form data from JSONForms context for template URL resolution
35
+ const injectedFormData = inject<{ value: unknown }>("formData", { value: {} });
36
+ const rootData = computed(() => injectedFormData.value || {});
37
+
38
+ const { items, loading, error } = useProvider(binding, {
39
+ data: rootData, // Pass the reactive reference
35
40
  path: control.value.path,
36
41
  dependsOnValues: depValues.value,
37
42
  });
38
43
 
39
- watch(
40
- () => control.value.data,
41
- () => {
42
- // if dependsOn changed → reload
43
- reload();
44
- },
45
- );
44
+ // Provider will automatically reload when rootData changes due to reactive cache key
46
45
 
47
46
  const value = computed({
48
47
  get: () => control.value.data,
49
48
  set: (v) => handleChange(control.value.path, v),
50
49
  });
50
+
51
+ const placeholder = computed(() => {
52
+ if (loading.value) return "Loading…";
53
+ // Check for placeholder in uischema options
54
+ const uischemaPlaceholder = (
55
+ control.value.uischema as { options?: { placeholder?: string } }
56
+ )?.options?.placeholder;
57
+ return uischemaPlaceholder || "Select…";
58
+ });
51
59
  </script>
52
60
 
53
61
  <template>
54
- <div class="provider-select">
55
- <label>{{ control.schema.title }}</label>
56
- <select v-model="value">
57
- <option value="" disabled>{{ loading ? "Loading…" : "Select…" }}</option>
58
- <option v-for="it in items" :key="String(it.value)" :value="it.value">
59
- {{ it.label }}
60
- </option>
61
- </select>
62
- <small v-if="error" role="alert">Failed to load: {{ error }}</small>
62
+ <div class="flex flex-column gap-2">
63
+ <label v-if="control.schema.title" class="text-color text-left">{{
64
+ control.schema.title
65
+ }}</label>
66
+ <div v-if="control.description" class="text-color-secondary text-left">
67
+ {{ control.description }}
68
+ </div>
69
+ <Dropdown
70
+ v-model="value"
71
+ class="w-full"
72
+ :options="items"
73
+ option-label="label"
74
+ option-value="value"
75
+ :placeholder="placeholder"
76
+ :disabled="!control.enabled || loading"
77
+ :show-clear="true"
78
+ />
79
+ <small v-if="error" class="p-error" role="alert"
80
+ >Failed to load: {{ error }}</small
81
+ >
63
82
  </div>
64
83
  </template>
65
84
 
66
85
  <style scoped>
67
- .provider-select select {
68
- min-width: 16rem;
86
+ :deep(.p-dropdown-label) {
87
+ text-align: left;
69
88
  }
70
89
  </style>
@@ -23,7 +23,7 @@ export function useProvider(
23
23
  | Ref<ProviderBinding>
24
24
  | ComputedRef<ProviderBinding>,
25
25
  ctxBits: {
26
- data: unknown;
26
+ data: unknown | Ref<unknown> | ComputedRef<unknown>;
27
27
  path: string;
28
28
  dependsOnValues?: unknown[];
29
29
  uiQuery?: string;
@@ -46,6 +46,7 @@ export function useProvider(
46
46
  b: unref(binding),
47
47
  d: ctxBits.dependsOnValues ?? [],
48
48
  q: ctxBits.uiQuery ?? "",
49
+ data: unref(ctxBits.data), // Include data in cache key for reactivity
49
50
  }),
50
51
  );
51
52
 
@@ -68,7 +69,7 @@ export function useProvider(
68
69
  );
69
70
  }
70
71
  const out = await driver.resolve(bindingValue.config ?? {}, {
71
- data: ctxBits.data,
72
+ data: unref(ctxBits.data),
72
73
  path: ctxBits.path,
73
74
  ui: { query: ctxBits.uiQuery },
74
75
  signal: ac.signal,
package/src/vue/index.ts CHANGED
@@ -17,7 +17,7 @@ const hasProvider = (uischema: UISchemaElement) => {
17
17
 
18
18
  // Create specific testers for each component type
19
19
  const providerSelectTester = rankWith(
20
- 6,
20
+ 106, // Higher than PrimeVue base (100) to ensure providers take precedence
21
21
  and(
22
22
  or(isStringControl, isNumberControl, isIntegerControl),
23
23
  hasProvider,
@@ -26,7 +26,7 @@ const providerSelectTester = rankWith(
26
26
  );
27
27
 
28
28
  const providerAutocompleteTester = rankWith(
29
- 7,
29
+ 107, // Higher than PrimeVue base (100) to ensure providers take precedence
30
30
  and(
31
31
  or(isStringControl, isNumberControl, isIntegerControl),
32
32
  hasProvider,
@@ -39,6 +39,11 @@ export const providerRenderers = [
39
39
  { tester: providerAutocompleteTester, renderer: ProviderAutocomplete },
40
40
  ];
41
41
 
42
+ // Export PrimeVue renderers (styles are auto-injected)
43
+ export { primevueRenderers } from "./primevue";
44
+
45
+ // Export individual components
42
46
  export { ProviderAutocomplete, ProviderSelect };
43
47
  export { useProvider } from "./composables/useProvider";
44
48
  export * from "./testers";
49
+ export * from "./primevue";
@@ -0,0 +1,26 @@
1
+ <script setup lang="ts">
2
+ import type { ControlElement } from "@jsonforms/core";
3
+ import { rendererProps, useJsonFormsControl } from "@jsonforms/vue";
4
+ import Checkbox from "primevue/checkbox";
5
+
6
+ defineOptions({ name: "JfBoolean" });
7
+
8
+ const props = defineProps(rendererProps<ControlElement>());
9
+ const { control, handleChange } = useJsonFormsControl(props);
10
+
11
+ const onToggle = (val: boolean) => handleChange(control.value.path, val);
12
+ </script>
13
+
14
+ <template>
15
+ <div class="flex items-center gap-2">
16
+ <Checkbox
17
+ :binary="true"
18
+ :model-value="!!control.data"
19
+ :disabled="!control.enabled"
20
+ :aria-invalid="!!control.errors || undefined"
21
+ @update:model-value="onToggle"
22
+ />
23
+ <label v-if="control.label">{{ control.label }}</label>
24
+ <small v-if="control.errors" class="p-error">{{ control.errors }}</small>
25
+ </div>
26
+ </template>