@narrative.io/jsonforms-provider-protocols 3.0.0-beta.3 → 3.0.0-beta.5

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/core/projection.d.ts.map +1 -1
  2. package/dist/core/projection.js.map +1 -1
  3. package/dist/core/transforms.d.ts.map +1 -1
  4. package/dist/core/transforms.js +3 -1
  5. package/dist/core/transforms.js.map +1 -1
  6. package/dist/jsonforms-provider-protocols.css +2 -2
  7. package/dist/vue/components/ProviderAutocomplete.vue.d.ts.map +1 -1
  8. package/dist/vue/components/ProviderAutocomplete.vue.js +8 -5
  9. package/dist/vue/components/ProviderAutocomplete.vue.js.map +1 -1
  10. package/dist/vue/components/ProviderMultiSelect.vue.d.ts.map +1 -1
  11. package/dist/vue/components/ProviderMultiSelect.vue.js +1 -1
  12. package/dist/vue/components/ProviderMultiSelect.vue2.js +8 -5
  13. package/dist/vue/components/ProviderMultiSelect.vue2.js.map +1 -1
  14. package/dist/vue/components/ProviderSelect.vue.d.ts.map +1 -1
  15. package/dist/vue/components/ProviderSelect.vue.js +1 -1
  16. package/dist/vue/components/ProviderSelect.vue2.js +10 -5
  17. package/dist/vue/components/ProviderSelect.vue2.js.map +1 -1
  18. package/dist/vue/composables/useDerive.d.ts +1 -1
  19. package/dist/vue/composables/useDerive.d.ts.map +1 -1
  20. package/dist/vue/composables/useDerive.js +5 -1
  21. package/dist/vue/composables/useDerive.js.map +1 -1
  22. package/dist/vue/composables/useDeriveInitialValue.d.ts +36 -0
  23. package/dist/vue/composables/useDeriveInitialValue.d.ts.map +1 -0
  24. package/dist/vue/composables/useDeriveInitialValue.js +125 -0
  25. package/dist/vue/composables/useDeriveInitialValue.js.map +1 -0
  26. package/dist/vue/composables/useProjection.d.ts.map +1 -1
  27. package/dist/vue/composables/useProjection.js +1 -3
  28. package/dist/vue/composables/useProjection.js.map +1 -1
  29. package/dist/vue/index.d.ts +2 -0
  30. package/dist/vue/index.d.ts.map +1 -1
  31. package/dist/vue/index.js +12 -2
  32. package/dist/vue/index.js.map +1 -1
  33. package/dist/vue/primevue/JfBoolean.vue.d.ts.map +1 -1
  34. package/dist/vue/primevue/JfBoolean.vue.js +14 -3
  35. package/dist/vue/primevue/JfBoolean.vue.js.map +1 -1
  36. package/dist/vue/primevue/JfEnum.vue.d.ts.map +1 -1
  37. package/dist/vue/primevue/JfEnum.vue.js +12 -5
  38. package/dist/vue/primevue/JfEnum.vue.js.map +1 -1
  39. package/dist/vue/primevue/JfEnumArray.vue.d.ts.map +1 -1
  40. package/dist/vue/primevue/JfEnumArray.vue.js +10 -5
  41. package/dist/vue/primevue/JfEnumArray.vue.js.map +1 -1
  42. package/dist/vue/primevue/JfNumber.vue.d.ts.map +1 -1
  43. package/dist/vue/primevue/JfNumber.vue.js +11 -6
  44. package/dist/vue/primevue/JfNumber.vue.js.map +1 -1
  45. package/dist/vue/primevue/JfText.vue.d.ts.map +1 -1
  46. package/dist/vue/primevue/JfText.vue.js +13 -6
  47. package/dist/vue/primevue/JfText.vue.js.map +1 -1
  48. package/dist/vue/primevue/JfTextArea.vue.d.ts.map +1 -1
  49. package/dist/vue/primevue/JfTextArea.vue.js +10 -5
  50. package/dist/vue/primevue/JfTextArea.vue.js.map +1 -1
  51. package/dist/vue/primevue/index.d.ts.map +1 -1
  52. package/dist/vue/primevue/index.js +93 -16
  53. package/dist/vue/primevue/index.js.map +1 -1
  54. package/dist/vue/utils/autoSelect.js.map +1 -1
  55. package/package.json +1 -1
  56. package/src/core/projection.ts +5 -5
  57. package/src/core/transforms.ts +33 -6
  58. package/src/vue/components/ProviderAutocomplete.vue +8 -5
  59. package/src/vue/components/ProviderMultiSelect.vue +12 -7
  60. package/src/vue/components/ProviderSelect.vue +13 -6
  61. package/src/vue/composables/useDerive.ts +16 -3
  62. package/src/vue/composables/useDeriveInitialValue.ts +195 -0
  63. package/src/vue/composables/useProjection.ts +6 -12
  64. package/src/vue/index.ts +12 -4
  65. package/src/vue/primevue/JfBoolean.vue +8 -3
  66. package/src/vue/primevue/JfEnum.vue +15 -8
  67. package/src/vue/primevue/JfEnumArray.vue +15 -12
  68. package/src/vue/primevue/JfNumber.vue +11 -8
  69. package/src/vue/primevue/JfText.vue +15 -8
  70. package/src/vue/primevue/JfTextArea.vue +10 -7
  71. package/src/vue/primevue/index.ts +104 -23
  72. package/src/vue/styles.css +26 -1
  73. package/src/vue/utils/autoSelect.ts +2 -2
@@ -2,18 +2,19 @@ import { defineComponent, getCurrentInstance, computed, inject, ref, watch, crea
2
2
  import { useJsonFormsControl } from "@jsonforms/vue";
3
3
  import { useProvider } from "../composables/useProvider.js";
4
4
  import { useDerive } from "../composables/useDerive.js";
5
+ import { useDeriveInitialValue } from "../composables/useDeriveInitialValue.js";
5
6
  import { useProjection } from "../composables/useProjection.js";
6
7
  import { useDirtyValidation } from "../composables/useDirtyValidation.js";
7
8
  import InputText from "primevue/inputtext";
8
9
  import AutoComplete from "primevue/autocomplete";
9
- const _hoisted_1 = { class: "flex flex-column gap-2" };
10
+ const _hoisted_1 = { class: "jf-control" };
10
11
  const _hoisted_2 = {
11
12
  key: 0,
12
- class: "text-color text-left"
13
+ class: "jf-label"
13
14
  };
14
15
  const _hoisted_3 = {
15
16
  key: 1,
16
- class: "text-color-secondary text-left"
17
+ class: "jf-description"
17
18
  };
18
19
  const _hoisted_4 = {
19
20
  key: 4,
@@ -66,7 +67,12 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
66
67
  const instance = getCurrentInstance();
67
68
  const props = instance.props;
68
69
  const { control, handleChange: rawHandleChange } = useJsonFormsControl(props);
69
- const { projectedData, handleProjectedChange: handleChange, projectedErrors, projectedLabel } = useProjection(control, rawHandleChange);
70
+ const {
71
+ projectedData,
72
+ handleProjectedChange: handleChange,
73
+ projectedErrors,
74
+ projectedLabel
75
+ } = useProjection(control, rawHandleChange);
70
76
  const binding = computed(() => {
71
77
  const provider = control.value.uischema?.options?.provider;
72
78
  if (provider && typeof provider === "object" && !provider.load) {
@@ -110,6 +116,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
110
116
  });
111
117
  const isAutocomplete = computed(() => !!binding.value);
112
118
  useDerive({ control, handleChange, data: projectedData });
119
+ useDeriveInitialValue({ control, handleChange });
113
120
  const { showErrors, markDirty } = useDirtyValidation(control, projectedErrors);
114
121
  function onInput(val) {
115
122
  const newValue = val && val.trim() !== "" ? val : void 0;
@@ -137,7 +144,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
137
144
  unref(control).description ? (openBlock(), createElementBlock("div", _hoisted_3, toDisplayString(unref(control).description), 1)) : createCommentVNode("", true),
138
145
  isAutocomplete.value ? (openBlock(), createBlock(unref(AutoComplete), {
139
146
  key: 2,
140
- class: normalizeClass(["w-full", { "p-invalid": unref(showErrors) }]),
147
+ class: normalizeClass(["w-full!", { "p-invalid": unref(showErrors) }]),
141
148
  "model-value": unref(projectedData) ?? "",
142
149
  suggestions: unref(items),
143
150
  "option-label": "label",
@@ -150,7 +157,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
150
157
  onBlur
151
158
  }, null, 8, ["class", "model-value", "suggestions", "placeholder", "disabled", "aria-invalid"])) : (openBlock(), createBlock(unref(InputText), {
152
159
  key: 3,
153
- class: normalizeClass(["w-full", { "p-invalid": unref(showErrors) }]),
160
+ class: normalizeClass(["w-full!", { "p-invalid": unref(showErrors) }]),
154
161
  "model-value": unref(projectedData) ?? "",
155
162
  disabled: !unref(control).enabled,
156
163
  "aria-invalid": unref(showErrors) || void 0,
@@ -1 +1 @@
1
- {"version":3,"file":"JfText.vue.js","sources":["../../../src/vue/primevue/JfText.vue"],"sourcesContent":["<script lang=\"ts\">\nexport default {\n name: \"JfText\",\n props: {\n uischema: {\n type: Object,\n required: true,\n },\n schema: {\n type: Object,\n required: true,\n },\n path: {\n type: String,\n required: true,\n },\n enabled: {\n type: Boolean,\n default: undefined,\n },\n renderers: {\n type: Array,\n required: false,\n default: undefined,\n },\n cells: {\n type: Array,\n required: false,\n default: undefined,\n },\n config: {\n type: Object,\n required: false,\n default: undefined,\n },\n },\n};\n</script>\n\n<script setup lang=\"ts\">\nimport type { ControlProps } from \"@jsonforms/vue\";\nimport { useJsonFormsControl } from \"@jsonforms/vue\";\nimport { computed, ref, inject, watch, getCurrentInstance } from \"vue\";\nimport { useProvider } from \"../composables/useProvider\";\nimport { useDerive } from \"../composables/useDerive\";\nimport { useProjection } from \"../composables/useProjection\";\nimport { useDirtyValidation } from \"../composables/useDirtyValidation\";\nimport InputText from \"primevue/inputtext\";\nimport AutoComplete from \"primevue/autocomplete\";\n\n// Access props from the component instance\nconst instance = getCurrentInstance()!;\nconst props = instance.props as unknown as ControlProps;\nconst { control, handleChange: rawHandleChange } = useJsonFormsControl(props);\nconst { projectedData, handleProjectedChange: handleChange, projectedErrors, projectedLabel } = useProjection(control, rawHandleChange);\n\n// Provider support for autocomplete functionality\nconst binding = computed(() => {\n const provider = control.value.uischema?.options?.provider;\n // Ensure load property is set to 'query' by default for autocomplete\n if (provider && typeof provider === \"object\" && !provider.load) {\n return { ...provider, load: \"query\" };\n }\n return provider;\n});\n\nconst deps = computed(\n () =>\n ((\n (control.value.schema as Record<string, unknown>)?.[\n \"x-provider\"\n ] as Record<string, unknown>\n )?.dependsOn as string[]) ?? [],\n);\nconst depValues = computed(() => {\n return deps.value.map((dep) => {\n // Resolve dependency value from form data using JSON pointer-like path\n const path = dep.startsWith(\"#/\") ? dep.slice(2) : dep;\n const keys = path.replace(/\\//g, \".\").split(\".\");\n let value: unknown = rootData.value;\n for (const key of keys) {\n if (value && typeof value === \"object\" && key in value) {\n value = (value as Record<string, unknown>)[key];\n } else {\n return null;\n }\n }\n return value;\n });\n});\n\n// Get the root form data from JSONForms context for template URL resolution\nconst injectedFormData = inject<{ value: unknown }>(\"formData\", { value: {} });\nconst rootData = computed(() => injectedFormData.value || {});\n\nconst query = ref(\"\");\nconst { items, loading, error, reload } = useProvider(binding, {\n data: rootData,\n path: control.value.path,\n uiQuery: query.value,\n dependsOnValues: depValues.value,\n});\n\nwatch(query, () => {\n if (binding.value?.load === \"query\") reload();\n});\n\nconst placeholder = computed<string | undefined>(() => {\n if (loading.value) return \"Loading…\";\n return (\n (control.value.uischema as { options?: { placeholder?: string } })?.options\n ?.placeholder ?? control.value.description\n );\n});\n\nconst isAutocomplete = computed(() => !!binding.value);\n\n// Add derive functionality\nuseDerive({ control, handleChange, data: projectedData });\n\n// Track user interaction — errors only show after blur\nconst { showErrors, markDirty } = useDirtyValidation(control, projectedErrors);\n\nfunction onInput(val: string | undefined) {\n // Convert empty strings to undefined for proper required field validation\n const newValue = val && val.trim() !== \"\" ? val : undefined;\n if (projectedData.value !== newValue) {\n handleChange(control.value.path, newValue);\n }\n}\n\nfunction onBlur() {\n markDirty();\n // Normalize empty strings to undefined so required validation fires\n const val = projectedData.value;\n if (typeof val === \"string\" && val.trim() === \"\") {\n handleChange(control.value.path, undefined);\n }\n}\n\n// Autocomplete specific handlers\nconst onComplete = (event: { query: string }) => {\n query.value = event.query;\n};\n\nconst onSelect = (event: { value?: { value?: unknown } | unknown }) => {\n const newValue = (event.value as { value?: unknown })?.value ?? event.value;\n handleChange(control.value.path, newValue);\n};\n</script>\n\n<template>\n <div class=\"flex flex-column gap-2\">\n <label v-if=\"projectedLabel\" class=\"text-color text-left\">{{\n projectedLabel\n }}</label>\n <div v-if=\"control.description\" class=\"text-color-secondary text-left\">\n {{ control.description }}\n </div>\n <AutoComplete\n v-if=\"isAutocomplete\"\n :class=\"['w-full', { 'p-invalid': showErrors }]\"\n :model-value=\"projectedData ?? ''\"\n :suggestions=\"items\"\n option-label=\"label\"\n :placeholder=\"placeholder\"\n :disabled=\"!control.enabled\"\n :aria-invalid=\"showErrors || undefined\"\n @complete=\"onComplete\"\n @item-select=\"onSelect\"\n @update:model-value=\"onInput\"\n @blur=\"onBlur\"\n />\n <InputText\n v-else\n :class=\"['w-full', { 'p-invalid': showErrors }]\"\n :model-value=\"(projectedData as string) ?? ''\"\n :disabled=\"!control.enabled\"\n :aria-invalid=\"showErrors || undefined\"\n :placeholder=\"placeholder\"\n autocapitalize=\"off\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n @update:model-value=\"onInput\"\n @blur=\"onBlur\"\n />\n <small v-if=\"error\" class=\"p-error\" role=\"alert\">Failed: {{ error }}</small>\n <small v-else-if=\"showErrors\" class=\"p-error\">{{ projectedErrors }}</small>\n </div>\n</template>\n"],"names":["_openBlock","_createElementBlock","_unref","_toDisplayString","_createBlock"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AACA,MAAA,cAAe;AAAA,EACb,MAAM;AAAA,EACN,OAAO;AAAA,IACL,UAAU;AAAA,MACR,MAAM;AAAA,MACN,UAAU;AAAA,IAAA;AAAA,IAEZ,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,UAAU;AAAA,IAAA;AAAA,IAEZ,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,UAAU;AAAA,IAAA;AAAA,IAEZ,SAAS;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,IAAA;AAAA,IAEX,WAAW;AAAA,MACT,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS;AAAA,IAAA;AAAA,IAEX,OAAO;AAAA,MACL,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS;AAAA,IAAA;AAAA,IAEX,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS;AAAA,IAAA;AAAA,EACX;AAEJ;;;;AAeA,UAAM,WAAW,mBAAA;AACjB,UAAM,QAAQ,SAAS;AACvB,UAAM,EAAE,SAAS,cAAc,gBAAA,IAAoB,oBAAoB,KAAK;AAC5E,UAAM,EAAE,eAAe,uBAAuB,cAAc,iBAAiB,mBAAmB,cAAc,SAAS,eAAe;AAGtI,UAAM,UAAU,SAAS,MAAM;AAC7B,YAAM,WAAW,QAAQ,MAAM,UAAU,SAAS;AAElD,UAAI,YAAY,OAAO,aAAa,YAAY,CAAC,SAAS,MAAM;AAC9D,eAAO,EAAE,GAAG,UAAU,MAAM,QAAA;AAAA,MAC9B;AACA,aAAO;AAAA,IACT,CAAC;AAED,UAAM,OAAO;AAAA,MACX,MAEK,QAAQ,MAAM,SACb,YACF,GACC,aAA0B,CAAA;AAAA,IAAC;AAElC,UAAM,YAAY,SAAS,MAAM;AAC/B,aAAO,KAAK,MAAM,IAAI,CAAC,QAAQ;AAE7B,cAAM,OAAO,IAAI,WAAW,IAAI,IAAI,IAAI,MAAM,CAAC,IAAI;AACnD,cAAM,OAAO,KAAK,QAAQ,OAAO,GAAG,EAAE,MAAM,GAAG;AAC/C,YAAI,QAAiB,SAAS;AAC9B,mBAAW,OAAO,MAAM;AACtB,cAAI,SAAS,OAAO,UAAU,YAAY,OAAO,OAAO;AACtD,oBAAS,MAAkC,GAAG;AAAA,UAChD,OAAO;AACL,mBAAO;AAAA,UACT;AAAA,QACF;AACA,eAAO;AAAA,MACT,CAAC;AAAA,IACH,CAAC;AAGD,UAAM,mBAAmB,OAA2B,YAAY,EAAE,OAAO,CAAA,GAAI;AAC7E,UAAM,WAAW,SAAS,MAAM,iBAAiB,SAAS,CAAA,CAAE;AAE5D,UAAM,QAAQ,IAAI,EAAE;AACpB,UAAM,EAAE,OAAO,SAAS,OAAO,OAAA,IAAW,YAAY,SAAS;AAAA,MAC7D,MAAM;AAAA,MACN,MAAM,QAAQ,MAAM;AAAA,MACpB,SAAS,MAAM;AAAA,MACf,iBAAiB,UAAU;AAAA,IAAA,CAC5B;AAED,UAAM,OAAO,MAAM;AACjB,UAAI,QAAQ,OAAO,SAAS,QAAS,QAAA;AAAA,IACvC,CAAC;AAED,UAAM,cAAc,SAA6B,MAAM;AACrD,UAAI,QAAQ,MAAO,QAAO;AAC1B,aACG,QAAQ,MAAM,UAAqD,SAChE,eAAe,QAAQ,MAAM;AAAA,IAErC,CAAC;AAED,UAAM,iBAAiB,SAAS,MAAM,CAAC,CAAC,QAAQ,KAAK;AAGrD,cAAU,EAAE,SAAS,cAAc,MAAM,eAAe;AAGxD,UAAM,EAAE,YAAY,UAAA,IAAc,mBAAmB,SAAS,eAAe;AAE7E,aAAS,QAAQ,KAAyB;AAExC,YAAM,WAAW,OAAO,IAAI,KAAA,MAAW,KAAK,MAAM;AAClD,UAAI,cAAc,UAAU,UAAU;AACpC,qBAAa,QAAQ,MAAM,MAAM,QAAQ;AAAA,MAC3C;AAAA,IACF;AAEA,aAAS,SAAS;AAChB,gBAAA;AAEA,YAAM,MAAM,cAAc;AAC1B,UAAI,OAAO,QAAQ,YAAY,IAAI,KAAA,MAAW,IAAI;AAChD,qBAAa,QAAQ,MAAM,MAAM,MAAS;AAAA,MAC5C;AAAA,IACF;AAGA,UAAM,aAAa,CAAC,UAA6B;AAC/C,YAAM,QAAQ,MAAM;AAAA,IACtB;AAEA,UAAM,WAAW,CAAC,UAAqD;AACrE,YAAM,WAAY,MAAM,OAA+B,SAAS,MAAM;AACtE,mBAAa,QAAQ,MAAM,MAAM,QAAQ;AAAA,IAC3C;;AAIE,aAAAA,UAAA,GAAAC,mBAoCM,OApCN,YAoCM;AAAA,QAnCSC,MAAA,cAAA,kBAAbD,mBAEU,SAFV,YAEUE,gBADRD,MAAA,cAAA,CAAc,GAAA,CAAA;QAELA,MAAA,OAAA,EAAQ,eAAnBF,UAAA,GAAAC,mBAEM,OAFN,YAEME,gBADDD,MAAA,OAAA,EAAQ,WAAW,GAAA,CAAA;QAGhB,eAAA,sBADRE,YAaEF,MAAA,YAAA,GAAA;AAAA;UAXC,gDAAiCA,MAAA,UAAA,EAAA,CAAU,CAAA;AAAA,UAC3C,eAAaA,MAAA,aAAA,KAAa;AAAA,UAC1B,aAAaA,MAAA,KAAA;AAAA,UACd,gBAAa;AAAA,UACZ,aAAa,YAAA;AAAA,UACb,UAAQ,CAAGA,MAAA,OAAA,EAAQ;AAAA,UACnB,gBAAcA,MAAA,UAAA,KAAc;AAAA,UAC5B;AAAA,UACA,cAAa;AAAA,UACb,uBAAoB;AAAA,UACpB;AAAA,QAAA,iHAEHE,YAYEF,MAAA,SAAA,GAAA;AAAA;UAVC,gDAAiCA,MAAA,UAAA,EAAA,CAAU,CAAA;AAAA,UAC3C,eAAcA,MAAA,aAAA,KAAa;AAAA,UAC3B,UAAQ,CAAGA,MAAA,OAAA,EAAQ;AAAA,UACnB,gBAAcA,MAAA,UAAA,KAAc;AAAA,UAC5B,aAAa,YAAA;AAAA,UACd,gBAAe;AAAA,UACf,cAAa;AAAA,UACb,YAAW;AAAA,UACV,uBAAoB;AAAA,UACpB;AAAA,QAAA;QAEUA,MAAA,KAAA,KAAbF,UAAA,GAAAC,mBAA4E,SAA5E,YAAiD,6BAAWC,MAAA,KAAA,CAAK,GAAA,CAAA,KAC/CA,MAAA,UAAA,kBAAlBD,mBAA2E,SAA3E,YAA2EE,gBAA1BD,MAAA,eAAA,CAAe,GAAA,CAAA;;;;;"}
1
+ {"version":3,"file":"JfText.vue.js","sources":["../../../src/vue/primevue/JfText.vue"],"sourcesContent":["<script lang=\"ts\">\nexport default {\n name: \"JfText\",\n props: {\n uischema: {\n type: Object,\n required: true,\n },\n schema: {\n type: Object,\n required: true,\n },\n path: {\n type: String,\n required: true,\n },\n enabled: {\n type: Boolean,\n default: undefined,\n },\n renderers: {\n type: Array,\n required: false,\n default: undefined,\n },\n cells: {\n type: Array,\n required: false,\n default: undefined,\n },\n config: {\n type: Object,\n required: false,\n default: undefined,\n },\n },\n};\n</script>\n\n<script setup lang=\"ts\">\nimport type { ControlProps } from \"@jsonforms/vue\";\nimport { useJsonFormsControl } from \"@jsonforms/vue\";\nimport { computed, ref, inject, watch, getCurrentInstance } from \"vue\";\nimport { useProvider } from \"../composables/useProvider\";\nimport { useDerive } from \"../composables/useDerive\";\nimport { useDeriveInitialValue } from \"../composables/useDeriveInitialValue\";\nimport { useProjection } from \"../composables/useProjection\";\nimport { useDirtyValidation } from \"../composables/useDirtyValidation\";\nimport InputText from \"primevue/inputtext\";\nimport AutoComplete from \"primevue/autocomplete\";\n\n// Access props from the component instance\nconst instance = getCurrentInstance()!;\nconst props = instance.props as unknown as ControlProps;\nconst { control, handleChange: rawHandleChange } = useJsonFormsControl(props);\nconst {\n projectedData,\n handleProjectedChange: handleChange,\n projectedErrors,\n projectedLabel,\n} = useProjection(control, rawHandleChange);\n\n// Provider support for autocomplete functionality\nconst binding = computed(() => {\n const provider = control.value.uischema?.options?.provider;\n // Ensure load property is set to 'query' by default for autocomplete\n if (provider && typeof provider === \"object\" && !provider.load) {\n return { ...provider, load: \"query\" };\n }\n return provider;\n});\n\nconst deps = computed(\n () =>\n ((\n (control.value.schema as Record<string, unknown>)?.[\n \"x-provider\"\n ] as Record<string, unknown>\n )?.dependsOn as string[]) ?? [],\n);\nconst depValues = computed(() => {\n return deps.value.map((dep) => {\n // Resolve dependency value from form data using JSON pointer-like path\n const path = dep.startsWith(\"#/\") ? dep.slice(2) : dep;\n const keys = path.replace(/\\//g, \".\").split(\".\");\n let value: unknown = rootData.value;\n for (const key of keys) {\n if (value && typeof value === \"object\" && key in value) {\n value = (value as Record<string, unknown>)[key];\n } else {\n return null;\n }\n }\n return value;\n });\n});\n\n// Get the root form data from JSONForms context for template URL resolution\nconst injectedFormData = inject<{ value: unknown }>(\"formData\", { value: {} });\nconst rootData = computed(() => injectedFormData.value || {});\n\nconst query = ref(\"\");\nconst { items, loading, error, reload } = useProvider(binding, {\n data: rootData,\n path: control.value.path,\n uiQuery: query.value,\n dependsOnValues: depValues.value,\n});\n\nwatch(query, () => {\n if (binding.value?.load === \"query\") reload();\n});\n\nconst placeholder = computed<string | undefined>(() => {\n if (loading.value) return \"Loading…\";\n return (\n (control.value.uischema as { options?: { placeholder?: string } })?.options\n ?.placeholder ?? control.value.description\n );\n});\n\nconst isAutocomplete = computed(() => !!binding.value);\n\n// Add derive functionality\nuseDerive({ control, handleChange, data: projectedData });\n\n// Add deriveInitialValue — async API-based initial value seeding\nuseDeriveInitialValue({ control, handleChange });\n\n// Track user interaction — errors only show after blur\nconst { showErrors, markDirty } = useDirtyValidation(control, projectedErrors);\n\nfunction onInput(val: string | undefined) {\n // Convert empty strings to undefined for proper required field validation\n const newValue = val && val.trim() !== \"\" ? val : undefined;\n if (projectedData.value !== newValue) {\n handleChange(control.value.path, newValue);\n }\n}\n\nfunction onBlur() {\n markDirty();\n // Normalize empty strings to undefined so required validation fires\n const val = projectedData.value;\n if (typeof val === \"string\" && val.trim() === \"\") {\n handleChange(control.value.path, undefined);\n }\n}\n\n// Autocomplete specific handlers\nconst onComplete = (event: { query: string }) => {\n query.value = event.query;\n};\n\nconst onSelect = (event: { value?: { value?: unknown } | unknown }) => {\n const newValue = (event.value as { value?: unknown })?.value ?? event.value;\n handleChange(control.value.path, newValue);\n};\n</script>\n\n<template>\n <div class=\"jf-control\">\n <label v-if=\"projectedLabel\" class=\"jf-label\">{{ projectedLabel }}</label>\n <div v-if=\"control.description\" class=\"jf-description\">\n {{ control.description }}\n </div>\n <AutoComplete\n v-if=\"isAutocomplete\"\n :class=\"['w-full!', { 'p-invalid': showErrors }]\"\n :model-value=\"projectedData ?? ''\"\n :suggestions=\"items\"\n option-label=\"label\"\n :placeholder=\"placeholder\"\n :disabled=\"!control.enabled\"\n :aria-invalid=\"showErrors || undefined\"\n @complete=\"onComplete\"\n @item-select=\"onSelect\"\n @update:model-value=\"onInput\"\n @blur=\"onBlur\"\n />\n <InputText\n v-else\n :class=\"['w-full!', { 'p-invalid': showErrors }]\"\n :model-value=\"(projectedData as string) ?? ''\"\n :disabled=\"!control.enabled\"\n :aria-invalid=\"showErrors || undefined\"\n :placeholder=\"placeholder\"\n autocapitalize=\"off\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n @update:model-value=\"onInput\"\n @blur=\"onBlur\"\n />\n <small v-if=\"error\" class=\"p-error\" role=\"alert\">Failed: {{ error }}</small>\n <small v-else-if=\"showErrors\" class=\"p-error\">{{ projectedErrors }}</small>\n </div>\n</template>\n"],"names":["_openBlock","_createElementBlock","_unref","_toDisplayString","_createBlock"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"JfTextArea.vue.d.ts","sourceRoot":"","sources":["../../../src/vue/primevue/JfTextArea.vue"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgHA,wBA6NK"}
1
+ {"version":3,"file":"JfTextArea.vue.d.ts","sourceRoot":"","sources":["../../../src/vue/primevue/JfTextArea.vue"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmHA,wBA4NK"}
@@ -3,14 +3,14 @@ import { useJsonFormsControl } from "@jsonforms/vue";
3
3
  import { useProjection } from "../composables/useProjection.js";
4
4
  import { useDirtyValidation } from "../composables/useDirtyValidation.js";
5
5
  import Textarea from "primevue/textarea";
6
- const _hoisted_1 = { class: "flex flex-column gap-2" };
6
+ const _hoisted_1 = { class: "jf-control" };
7
7
  const _hoisted_2 = {
8
8
  key: 0,
9
- class: "text-color text-left"
9
+ class: "jf-label"
10
10
  };
11
11
  const _hoisted_3 = {
12
12
  key: 1,
13
- class: "text-color-secondary text-left"
13
+ class: "jf-description"
14
14
  };
15
15
  const _hoisted_4 = {
16
16
  key: 2,
@@ -58,7 +58,12 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
58
58
  const instance = getCurrentInstance();
59
59
  const props = instance.props;
60
60
  const { control, handleChange: rawHandleChange } = useJsonFormsControl(props);
61
- const { projectedData, handleProjectedChange: handleChange, projectedErrors, projectedLabel } = useProjection(control, rawHandleChange);
61
+ const {
62
+ projectedData,
63
+ handleProjectedChange: handleChange,
64
+ projectedErrors,
65
+ projectedLabel
66
+ } = useProjection(control, rawHandleChange);
62
67
  const placeholder = computed(
63
68
  () => control.value.uischema?.options?.placeholder ?? control.value.description
64
69
  );
@@ -81,7 +86,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
81
86
  unref(projectedLabel) ? (openBlock(), createElementBlock("label", _hoisted_2, toDisplayString(unref(projectedLabel)), 1)) : createCommentVNode("", true),
82
87
  unref(control).description ? (openBlock(), createElementBlock("div", _hoisted_3, toDisplayString(unref(control).description), 1)) : createCommentVNode("", true),
83
88
  createVNode(unref(Textarea), {
84
- class: normalizeClass(["w-full", { "p-invalid": unref(showErrors) }]),
89
+ class: normalizeClass(["w-full!", { "p-invalid": unref(showErrors) }]),
85
90
  "model-value": unref(projectedData) ?? "",
86
91
  disabled: !unref(control).enabled,
87
92
  "aria-invalid": unref(showErrors) || void 0,
@@ -1 +1 @@
1
- {"version":3,"file":"JfTextArea.vue.js","sources":["../../../src/vue/primevue/JfTextArea.vue"],"sourcesContent":["<script lang=\"ts\">\nexport default {\n name: \"JfTextArea\",\n props: {\n uischema: {\n type: Object,\n required: true,\n },\n schema: {\n type: Object,\n required: true,\n },\n path: {\n type: String,\n required: true,\n },\n enabled: {\n type: Boolean,\n default: undefined,\n },\n renderers: {\n type: Array,\n required: false,\n default: undefined,\n },\n cells: {\n type: Array,\n required: false,\n default: undefined,\n },\n config: {\n type: Object,\n required: false,\n default: undefined,\n },\n },\n};\n</script>\n\n<script setup lang=\"ts\">\nimport type { ControlProps } from \"@jsonforms/vue\";\nimport { useJsonFormsControl } from \"@jsonforms/vue\";\nimport { computed, getCurrentInstance } from \"vue\";\nimport { useProjection } from \"../composables/useProjection\";\nimport { useDirtyValidation } from \"../composables/useDirtyValidation\";\nimport Textarea from \"primevue/textarea\";\n\n// Access props from the component instance\nconst instance = getCurrentInstance()!;\nconst props = instance.props as unknown as ControlProps;\nconst { control, handleChange: rawHandleChange } = useJsonFormsControl(props);\nconst { projectedData, handleProjectedChange: handleChange, projectedErrors, projectedLabel } = useProjection(control, rawHandleChange);\n\nconst placeholder = computed<string | undefined>(\n () =>\n (control.value.uischema as { options?: { placeholder?: string } })?.options\n ?.placeholder ?? control.value.description,\n);\n\n// Track user interaction — errors only show after blur\nconst { showErrors, markDirty } = useDirtyValidation(control, projectedErrors);\n\nfunction onInput(val: string | undefined) {\n // Convert empty strings to undefined for proper required field validation\n const newValue = val && val.trim() !== \"\" ? val : undefined;\n if (projectedData.value !== newValue) {\n handleChange(control.value.path, newValue);\n }\n}\n\nfunction onBlur() {\n markDirty();\n // Normalize empty strings to undefined so required validation fires\n const val = projectedData.value;\n if (typeof val === \"string\" && val.trim() === \"\") {\n handleChange(control.value.path, undefined);\n }\n}\n</script>\n\n<template>\n <div class=\"flex flex-column gap-2\">\n <label v-if=\"projectedLabel\" class=\"text-color text-left\">{{\n projectedLabel\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', { 'p-invalid': showErrors }]\"\n :model-value=\"(projectedData as string) ?? ''\"\n :disabled=\"!control.enabled\"\n :aria-invalid=\"showErrors || undefined\"\n :placeholder=\"placeholder\"\n :rows=\"4\"\n :auto-resize=\"true\"\n @update:model-value=\"onInput\"\n @blur=\"onBlur\"\n />\n <small v-if=\"showErrors\" class=\"p-error\">{{ projectedErrors }}</small>\n </div>\n</template>\n"],"names":["_openBlock","_createElementBlock","_unref","_toDisplayString","_createVNode"],"mappings":";;;;;;;;;;;;;;;;;;AACA,MAAA,cAAe;AAAA,EACb,MAAM;AAAA,EACN,OAAO;AAAA,IACL,UAAU;AAAA,MACR,MAAM;AAAA,MACN,UAAU;AAAA,IAAA;AAAA,IAEZ,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,UAAU;AAAA,IAAA;AAAA,IAEZ,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,UAAU;AAAA,IAAA;AAAA,IAEZ,SAAS;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,IAAA;AAAA,IAEX,WAAW;AAAA,MACT,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS;AAAA,IAAA;AAAA,IAEX,OAAO;AAAA,MACL,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS;AAAA,IAAA;AAAA,IAEX,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS;AAAA,IAAA;AAAA,EACX;AAEJ;;;;AAYA,UAAM,WAAW,mBAAA;AACjB,UAAM,QAAQ,SAAS;AACvB,UAAM,EAAE,SAAS,cAAc,gBAAA,IAAoB,oBAAoB,KAAK;AAC5E,UAAM,EAAE,eAAe,uBAAuB,cAAc,iBAAiB,mBAAmB,cAAc,SAAS,eAAe;AAEtI,UAAM,cAAc;AAAA,MAClB,MACG,QAAQ,MAAM,UAAqD,SAChE,eAAe,QAAQ,MAAM;AAAA,IAAA;AAIrC,UAAM,EAAE,YAAY,UAAA,IAAc,mBAAmB,SAAS,eAAe;AAE7E,aAAS,QAAQ,KAAyB;AAExC,YAAM,WAAW,OAAO,IAAI,KAAA,MAAW,KAAK,MAAM;AAClD,UAAI,cAAc,UAAU,UAAU;AACpC,qBAAa,QAAQ,MAAM,MAAM,QAAQ;AAAA,MAC3C;AAAA,IACF;AAEA,aAAS,SAAS;AAChB,gBAAA;AAEA,YAAM,MAAM,cAAc;AAC1B,UAAI,OAAO,QAAQ,YAAY,IAAI,KAAA,MAAW,IAAI;AAChD,qBAAa,QAAQ,MAAM,MAAM,MAAS;AAAA,MAC5C;AAAA,IACF;;AAIE,aAAAA,UAAA,GAAAC,mBAmBM,OAnBN,YAmBM;AAAA,QAlBSC,MAAA,cAAA,kBAAbD,mBAEU,SAFV,YAEUE,gBADRD,MAAA,cAAA,CAAc,GAAA,CAAA;QAELA,MAAA,OAAA,EAAQ,eAAnBF,UAAA,GAAAC,mBAEM,OAFN,YAEME,gBADDD,MAAA,OAAA,EAAQ,WAAW,GAAA,CAAA;QAExBE,YAUEF,MAAA,QAAA,GAAA;AAAA,UATC,gDAAiCA,MAAA,UAAA,EAAA,CAAU,CAAA;AAAA,UAC3C,eAAcA,MAAA,aAAA,KAAa;AAAA,UAC3B,UAAQ,CAAGA,MAAA,OAAA,EAAQ;AAAA,UACnB,gBAAcA,MAAA,UAAA,KAAc;AAAA,UAC5B,aAAa,YAAA;AAAA,UACb,MAAM;AAAA,UACN,eAAa;AAAA,UACb,uBAAoB;AAAA,UACpB;AAAA,QAAA;QAEUA,MAAA,UAAA,kBAAbD,mBAAsE,SAAtE,YAAsEE,gBAA1BD,MAAA,eAAA,CAAe,GAAA,CAAA;;;;;"}
1
+ {"version":3,"file":"JfTextArea.vue.js","sources":["../../../src/vue/primevue/JfTextArea.vue"],"sourcesContent":["<script lang=\"ts\">\nexport default {\n name: \"JfTextArea\",\n props: {\n uischema: {\n type: Object,\n required: true,\n },\n schema: {\n type: Object,\n required: true,\n },\n path: {\n type: String,\n required: true,\n },\n enabled: {\n type: Boolean,\n default: undefined,\n },\n renderers: {\n type: Array,\n required: false,\n default: undefined,\n },\n cells: {\n type: Array,\n required: false,\n default: undefined,\n },\n config: {\n type: Object,\n required: false,\n default: undefined,\n },\n },\n};\n</script>\n\n<script setup lang=\"ts\">\nimport type { ControlProps } from \"@jsonforms/vue\";\nimport { useJsonFormsControl } from \"@jsonforms/vue\";\nimport { computed, getCurrentInstance } from \"vue\";\nimport { useProjection } from \"../composables/useProjection\";\nimport { useDirtyValidation } from \"../composables/useDirtyValidation\";\nimport Textarea from \"primevue/textarea\";\n\n// Access props from the component instance\nconst instance = getCurrentInstance()!;\nconst props = instance.props as unknown as ControlProps;\nconst { control, handleChange: rawHandleChange } = useJsonFormsControl(props);\nconst {\n projectedData,\n handleProjectedChange: handleChange,\n projectedErrors,\n projectedLabel,\n} = useProjection(control, rawHandleChange);\n\nconst placeholder = computed<string | undefined>(\n () =>\n (control.value.uischema as { options?: { placeholder?: string } })?.options\n ?.placeholder ?? control.value.description,\n);\n\n// Track user interaction — errors only show after blur\nconst { showErrors, markDirty } = useDirtyValidation(control, projectedErrors);\n\nfunction onInput(val: string | undefined) {\n // Convert empty strings to undefined for proper required field validation\n const newValue = val && val.trim() !== \"\" ? val : undefined;\n if (projectedData.value !== newValue) {\n handleChange(control.value.path, newValue);\n }\n}\n\nfunction onBlur() {\n markDirty();\n // Normalize empty strings to undefined so required validation fires\n const val = projectedData.value;\n if (typeof val === \"string\" && val.trim() === \"\") {\n handleChange(control.value.path, undefined);\n }\n}\n</script>\n\n<template>\n <div class=\"jf-control\">\n <label v-if=\"projectedLabel\" class=\"jf-label\">{{ projectedLabel }}</label>\n <div v-if=\"control.description\" class=\"jf-description\">\n {{ control.description }}\n </div>\n <Textarea\n :class=\"['w-full!', { 'p-invalid': showErrors }]\"\n :model-value=\"(projectedData as string) ?? ''\"\n :disabled=\"!control.enabled\"\n :aria-invalid=\"showErrors || undefined\"\n :placeholder=\"placeholder\"\n :rows=\"4\"\n :auto-resize=\"true\"\n @update:model-value=\"onInput\"\n @blur=\"onBlur\"\n />\n <small v-if=\"showErrors\" class=\"p-error\">{{ projectedErrors }}</small>\n </div>\n</template>\n"],"names":["_openBlock","_createElementBlock","_unref","_toDisplayString","_createVNode"],"mappings":";;;;;;;;;;;;;;;;;;AACA,MAAA,cAAe;AAAA,EACb,MAAM;AAAA,EACN,OAAO;AAAA,IACL,UAAU;AAAA,MACR,MAAM;AAAA,MACN,UAAU;AAAA,IAAA;AAAA,IAEZ,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,UAAU;AAAA,IAAA;AAAA,IAEZ,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,UAAU;AAAA,IAAA;AAAA,IAEZ,SAAS;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,IAAA;AAAA,IAEX,WAAW;AAAA,MACT,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS;AAAA,IAAA;AAAA,IAEX,OAAO;AAAA,MACL,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS;AAAA,IAAA;AAAA,IAEX,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS;AAAA,IAAA;AAAA,EACX;AAEJ;;;;AAYA,UAAM,WAAW,mBAAA;AACjB,UAAM,QAAQ,SAAS;AACvB,UAAM,EAAE,SAAS,cAAc,gBAAA,IAAoB,oBAAoB,KAAK;AAC5E,UAAM;AAAA,MACJ;AAAA,MACA,uBAAuB;AAAA,MACvB;AAAA,MACA;AAAA,IAAA,IACE,cAAc,SAAS,eAAe;AAE1C,UAAM,cAAc;AAAA,MAClB,MACG,QAAQ,MAAM,UAAqD,SAChE,eAAe,QAAQ,MAAM;AAAA,IAAA;AAIrC,UAAM,EAAE,YAAY,UAAA,IAAc,mBAAmB,SAAS,eAAe;AAE7E,aAAS,QAAQ,KAAyB;AAExC,YAAM,WAAW,OAAO,IAAI,KAAA,MAAW,KAAK,MAAM;AAClD,UAAI,cAAc,UAAU,UAAU;AACpC,qBAAa,QAAQ,MAAM,MAAM,QAAQ;AAAA,MAC3C;AAAA,IACF;AAEA,aAAS,SAAS;AAChB,gBAAA;AAEA,YAAM,MAAM,cAAc;AAC1B,UAAI,OAAO,QAAQ,YAAY,IAAI,KAAA,MAAW,IAAI;AAChD,qBAAa,QAAQ,MAAM,MAAM,MAAS;AAAA,MAC5C;AAAA,IACF;;AAIE,aAAAA,UAAA,GAAAC,mBAiBM,OAjBN,YAiBM;AAAA,QAhBSC,MAAA,cAAA,kBAAbD,mBAA0E,SAA1E,YAA0EE,gBAAzBD,MAAA,cAAA,CAAc,GAAA,CAAA;QACpDA,MAAA,OAAA,EAAQ,eAAnBF,UAAA,GAAAC,mBAEM,OAFN,YAEME,gBADDD,MAAA,OAAA,EAAQ,WAAW,GAAA,CAAA;QAExBE,YAUEF,MAAA,QAAA,GAAA;AAAA,UATC,iDAAkCA,MAAA,UAAA,EAAA,CAAU,CAAA;AAAA,UAC5C,eAAcA,MAAA,aAAA,KAAa;AAAA,UAC3B,UAAQ,CAAGA,MAAA,OAAA,EAAQ;AAAA,UACnB,gBAAcA,MAAA,UAAA,KAAc;AAAA,UAC5B,aAAa,YAAA;AAAA,UACb,MAAM;AAAA,UACN,eAAa;AAAA,UACb,uBAAoB;AAAA,UACpB;AAAA,QAAA;QAEUA,MAAA,UAAA,kBAAbD,mBAAsE,SAAtE,YAAsEE,gBAA1BD,MAAA,eAAA,CAAe,GAAA,CAAA;;;;;"}
@@ -1 +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;AAoCxC,eAAO,MAAM,iBAAiB,EAAE,OAAO,EAAO,CAAC;AAK/C,wBAAgB,yBAAyB,CAAC,aAAa,EAAE,GAAG,GAAG,OAAO,EAAE,CA4GvE;AAED,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,CAAC"}
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;AA6DxC,eAAO,MAAM,iBAAiB,EAAE,OAAO,EAAO,CAAC;AAK/C,wBAAgB,yBAAyB,CAAC,aAAa,EAAE,GAAG,GAAG,OAAO,EAAE,CAoKvE;AAED,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,CAAC"}
@@ -17,13 +17,38 @@ const injectLayoutStyles = () => {
17
17
  display: flex;
18
18
  flex-direction: column;
19
19
  align-items: flex-start;
20
- gap: 1rem;
20
+ gap: 24px;
21
21
  width: 100%;
22
22
  }
23
23
 
24
24
  .vertical-layout-item {
25
25
  width: 100%;
26
26
  }
27
+
28
+ /* Form control wrapper */
29
+ .jf-control {
30
+ display: flex;
31
+ flex-direction: column;
32
+ gap: 12px;
33
+ }
34
+
35
+ /* Form control label typography */
36
+ .jf-label {
37
+ font-weight: 600;
38
+ font-size: 14px;
39
+ line-height: 14px;
40
+ color: #031553;
41
+ text-align: left;
42
+ }
43
+
44
+ /* Form control description typography */
45
+ .jf-description {
46
+ font-weight: 400;
47
+ font-size: 14px;
48
+ line-height: 14px;
49
+ color: #415290;
50
+ text-align: left;
51
+ }
27
52
  `;
28
53
  document.head.appendChild(style);
29
54
  }
@@ -64,39 +89,91 @@ function registerPrimevueRenderers(jsonformsCore) {
64
89
  {}
65
90
  );
66
91
  };
67
- const projectedSchemaMatches = (check) => (uischema, schema) => {
68
- const ui = uischema;
69
- const projection = ui?.options?.projection;
70
- if (!projection || ui?.type !== "Control" || !ui?.scope) return false;
71
- const propertySchema = resolveScopeSchema(ui.scope, schema);
72
- if (!propertySchema) return false;
73
- return check(getProjectedSchema(propertySchema, projection));
74
- };
92
+ const projectedSchemaMatches = (
93
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
94
+ ((check) => (uischema, schema) => {
95
+ const ui = uischema;
96
+ const projection = ui?.options?.projection;
97
+ if (!projection || ui?.type !== "Control" || !ui?.scope) return false;
98
+ const propertySchema = resolveScopeSchema(
99
+ ui.scope,
100
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
101
+ schema
102
+ );
103
+ if (!propertySchema) return false;
104
+ return check(getProjectedSchema(propertySchema, projection));
105
+ })
106
+ );
75
107
  const isMultilineProjection = (uischema, schema) => {
76
108
  const ui = uischema;
77
109
  return ui?.options?.multi === true && projectedSchemaMatches((s) => s?.type === "string")(uischema, schema);
78
110
  };
79
111
  const renderers = [
80
112
  // Multiline text has higher priority than regular text
81
- { tester: rankWith(PRIME + 4, or(isMultilineString, isMultilineProjection)), renderer: _sfc_main },
82
- { tester: rankWith(PRIME + 3, or(isStringControl, projectedSchemaMatches((s) => s?.type === "string"))), renderer: _sfc_main$1 },
83
113
  {
84
- tester: rankWith(PRIME + 6, or(isIntegerControl, projectedSchemaMatches((s) => s?.type === "integer"))),
114
+ tester: rankWith(PRIME + 4, or(isMultilineString, isMultilineProjection)),
115
+ renderer: _sfc_main
116
+ },
117
+ {
118
+ tester: rankWith(
119
+ PRIME + 3,
120
+ or(
121
+ isStringControl,
122
+ projectedSchemaMatches((s) => s?.type === "string")
123
+ )
124
+ ),
125
+ renderer: _sfc_main$1
126
+ },
127
+ {
128
+ tester: rankWith(
129
+ PRIME + 6,
130
+ or(
131
+ isIntegerControl,
132
+ projectedSchemaMatches((s) => s?.type === "integer")
133
+ )
134
+ ),
85
135
  renderer: _sfc_main$2
86
136
  },
87
137
  {
88
- tester: rankWith(PRIME + 4, or(isNumberControl, projectedSchemaMatches((s) => s?.type === "number"))),
138
+ tester: rankWith(
139
+ PRIME + 4,
140
+ or(
141
+ isNumberControl,
142
+ projectedSchemaMatches((s) => s?.type === "number")
143
+ )
144
+ ),
89
145
  renderer: _sfc_main$2
90
146
  },
91
147
  {
92
- tester: rankWith(PRIME + 7, or(and(isControl, schemaMatches(isScalarEnum)), and(isControl, projectedSchemaMatches(isScalarEnum)))),
148
+ tester: rankWith(
149
+ PRIME + 7,
150
+ or(
151
+ and(isControl, schemaMatches(isScalarEnum)),
152
+ and(isControl, projectedSchemaMatches(isScalarEnum))
153
+ )
154
+ ),
93
155
  renderer: _sfc_main$3
94
156
  },
95
157
  {
96
- tester: rankWith(PRIME + 8, or(and(isControl, schemaMatches(isEnumArray)), and(isControl, projectedSchemaMatches(isEnumArray)))),
158
+ tester: rankWith(
159
+ PRIME + 8,
160
+ or(
161
+ and(isControl, schemaMatches(isEnumArray)),
162
+ and(isControl, projectedSchemaMatches(isEnumArray))
163
+ )
164
+ ),
97
165
  renderer: _sfc_main$4
98
166
  },
99
- { tester: rankWith(PRIME + 3, or(isBooleanControl, projectedSchemaMatches((s) => s?.type === "boolean"))), renderer: _sfc_main$5 }
167
+ {
168
+ tester: rankWith(
169
+ PRIME + 3,
170
+ or(
171
+ isBooleanControl,
172
+ projectedSchemaMatches((s) => s?.type === "boolean")
173
+ )
174
+ ),
175
+ renderer: _sfc_main$5
176
+ }
100
177
  ];
101
178
  primevueRenderers.splice(0, primevueRenderers.length, ...renderers);
102
179
  renderersInitialized = true;
@@ -1 +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\";\nimport { getProjectedSchema } from \"../../core/projection\";\nimport { resolveScopeSchema } from \"../../core/resolveScope\";\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\n// Track whether renderers have been registered to avoid duplicate registrations\nlet renderersInitialized = false;\n\n// Return empty renderers array initially\nexport const primevueRenderers: unknown[] = [];\n\n// Export a function that can be called by the consumer to register renderers\n// This should only be called once during application initialization\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function registerPrimevueRenderers(jsonformsCore: any): unknown[] {\n // Prevent duplicate registration which causes AJV schema recompilation\n if (renderersInitialized) {\n return primevueRenderers as unknown[];\n }\n\n const {\n rankWith,\n isStringControl,\n isNumberControl,\n isIntegerControl,\n and,\n or,\n isControl,\n schemaMatches,\n isBooleanControl,\n } = jsonformsCore;\n\n // Give PrimeVue renderers a high base rank; vanilla commonly uses small ranks (2–5)\n const PRIME = 100;\n\n // helpers for enum detection - using simple schema checks instead of JSONForms internal functions\n const isScalarEnum = (s?: object) => {\n const schema = s as {\n type?: string;\n enum?: unknown[];\n oneOf?: unknown[];\n };\n return (\n schema &&\n schema.type !== \"array\" &&\n (Array.isArray(schema.enum) || Array.isArray(schema.oneOf))\n );\n };\n\n const 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\n const isMultilineString = (uischema: unknown, schema: unknown) => {\n const controlUischema = uischema as { options?: { multi?: boolean } };\n return and(isStringControl, () => controlUischema?.options?.multi === true)(\n uischema as Parameters<typeof isStringControl>[0],\n schema as Parameters<typeof isStringControl>[1],\n {} as Parameters<typeof isStringControl>[2],\n );\n };\n\n // Projection-aware schema check: when options.projection is set,\n // resolve the projected schema and test against it instead of the original\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const projectedSchemaMatches = (check: (schema: any) => boolean) =>\n (uischema: unknown, schema: unknown): boolean => {\n const ui = uischema as { type?: string; scope?: string; options?: { projection?: string } };\n const projection = ui?.options?.projection;\n if (!projection || ui?.type !== \"Control\" || !ui?.scope) return false;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const propertySchema = resolveScopeSchema(ui.scope, schema as Record<string, any>);\n if (!propertySchema) return false;\n\n return check(getProjectedSchema(propertySchema, projection));\n };\n\n const isMultilineProjection = (uischema: unknown, schema: unknown) => {\n const ui = uischema as { options?: { multi?: boolean } };\n return ui?.options?.multi === true &&\n projectedSchemaMatches((s) => s?.type === \"string\")(uischema, schema);\n };\n\n const renderers = [\n // Multiline text has higher priority than regular text\n { tester: rankWith(PRIME + 4, or(isMultilineString, isMultilineProjection)), renderer: JfTextArea },\n { tester: rankWith(PRIME + 3, or(isStringControl, projectedSchemaMatches((s) => s?.type === \"string\"))), renderer: JfText },\n {\n tester: rankWith(PRIME + 6, or(isIntegerControl, projectedSchemaMatches((s) => s?.type === \"integer\"))),\n renderer: JfNumber,\n },\n {\n tester: rankWith(PRIME + 4, or(isNumberControl, projectedSchemaMatches((s) => s?.type === \"number\"))),\n renderer: JfNumber,\n },\n {\n tester: rankWith(PRIME + 7, or(and(isControl, schemaMatches(isScalarEnum)), and(isControl, projectedSchemaMatches(isScalarEnum)))),\n renderer: JfEnum,\n },\n {\n tester: rankWith(PRIME + 8, or(and(isControl, schemaMatches(isEnumArray)), and(isControl, projectedSchemaMatches(isEnumArray)))),\n renderer: JfEnumArray,\n },\n { tester: rankWith(PRIME + 3, or(isBooleanControl, projectedSchemaMatches((s) => s?.type === \"boolean\"))), renderer: JfBoolean },\n ];\n\n // Update the exported array\n primevueRenderers.splice(0, primevueRenderers.length, ...renderers);\n\n // Mark as initialized to prevent duplicate registrations\n renderersInitialized = true;\n\n return renderers;\n}\n\nexport { JfText, JfTextArea, JfNumber, JfEnum, JfEnumArray, JfBoolean };\n"],"names":["JfTextArea","JfText","JfNumber","JfEnum","JfEnumArray","JfBoolean"],"mappings":";;;;;;;;AAUA,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;AAGA,IAAI,uBAAuB;AAGpB,MAAM,oBAA+B,CAAA;AAKrC,SAAS,0BAA0B,eAA+B;AAEvE,MAAI,sBAAsB;AACxB,WAAO;AAAA,EACT;AAEA,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,IACE;AAGJ,QAAM,QAAQ;AAGd,QAAM,eAAe,CAAC,MAAe;AACnC,UAAM,SAAS;AAKf,WACE,UACA,OAAO,SAAS,YACf,MAAM,QAAQ,OAAO,IAAI,KAAK,MAAM,QAAQ,OAAO,KAAK;AAAA,EAE7D;AAEA,QAAM,cAAc,CAAC,MAAe;AAClC,UAAM,SAAS;AAIf,WACE,QAAQ,SAAS,YAChB,MAAM,QAAQ,OAAO,OAAO,IAAI,KAAK,MAAM,QAAQ,OAAO,OAAO,KAAK;AAAA,EAE3E;AAGA,QAAM,oBAAoB,CAAC,UAAmB,WAAoB;AAChE,UAAM,kBAAkB;AACxB,WAAO,IAAI,iBAAiB,MAAM,iBAAiB,SAAS,UAAU,IAAI;AAAA,MACxE;AAAA,MACA;AAAA,MACA,CAAA;AAAA,IAAC;AAAA,EAEL;AAKA,QAAM,yBAAyB,CAAC,UAC9B,CAAC,UAAmB,WAA6B;AAC/C,UAAM,KAAK;AACX,UAAM,aAAa,IAAI,SAAS;AAChC,QAAI,CAAC,cAAc,IAAI,SAAS,aAAa,CAAC,IAAI,MAAO,QAAO;AAGhE,UAAM,iBAAiB,mBAAmB,GAAG,OAAO,MAA6B;AACjF,QAAI,CAAC,eAAgB,QAAO;AAE5B,WAAO,MAAM,mBAAmB,gBAAgB,UAAU,CAAC;AAAA,EAC7D;AAEF,QAAM,wBAAwB,CAAC,UAAmB,WAAoB;AACpE,UAAM,KAAK;AACX,WAAO,IAAI,SAAS,UAAU,QAC5B,uBAAuB,CAAC,MAAM,GAAG,SAAS,QAAQ,EAAE,UAAU,MAAM;AAAA,EACxE;AAEA,QAAM,YAAY;AAAA;AAAA,IAEhB,EAAE,QAAQ,SAAS,QAAQ,GAAG,GAAG,mBAAmB,qBAAqB,CAAC,GAAG,UAAUA,UAAA;AAAA,IACvF,EAAE,QAAQ,SAAS,QAAQ,GAAG,GAAG,iBAAiB,uBAAuB,CAAC,MAAM,GAAG,SAAS,QAAQ,CAAC,CAAC,GAAG,UAAUC,YAAA;AAAA,IACnH;AAAA,MACE,QAAQ,SAAS,QAAQ,GAAG,GAAG,kBAAkB,uBAAuB,CAAC,MAAM,GAAG,SAAS,SAAS,CAAC,CAAC;AAAA,MACtG,UAAUC;AAAAA,IAAA;AAAA,IAEZ;AAAA,MACE,QAAQ,SAAS,QAAQ,GAAG,GAAG,iBAAiB,uBAAuB,CAAC,MAAM,GAAG,SAAS,QAAQ,CAAC,CAAC;AAAA,MACpG,UAAUA;AAAAA,IAAA;AAAA,IAEZ;AAAA,MACE,QAAQ,SAAS,QAAQ,GAAG,GAAG,IAAI,WAAW,cAAc,YAAY,CAAC,GAAG,IAAI,WAAW,uBAAuB,YAAY,CAAC,CAAC,CAAC;AAAA,MACjI,UAAUC;AAAAA,IAAA;AAAA,IAEZ;AAAA,MACE,QAAQ,SAAS,QAAQ,GAAG,GAAG,IAAI,WAAW,cAAc,WAAW,CAAC,GAAG,IAAI,WAAW,uBAAuB,WAAW,CAAC,CAAC,CAAC;AAAA,MAC/H,UAAUC;AAAAA,IAAA;AAAA,IAEZ,EAAE,QAAQ,SAAS,QAAQ,GAAG,GAAG,kBAAkB,uBAAuB,CAAC,MAAM,GAAG,SAAS,SAAS,CAAC,CAAC,GAAG,UAAUC,YAAA;AAAA,EAAU;AAIjI,oBAAkB,OAAO,GAAG,kBAAkB,QAAQ,GAAG,SAAS;AAGlE,yBAAuB;AAEvB,SAAO;AACT;"}
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\";\nimport { getProjectedSchema } from \"../../core/projection\";\nimport { resolveScopeSchema } from \"../../core/resolveScope\";\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: 24px;\n width: 100%;\n}\n\n.vertical-layout-item {\n width: 100%;\n}\n\n/* Form control wrapper */\n.jf-control {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n/* Form control label typography */\n.jf-label {\n font-weight: 600;\n font-size: 14px;\n line-height: 14px;\n color: #031553;\n text-align: left;\n}\n\n/* Form control description typography */\n.jf-description {\n font-weight: 400;\n font-size: 14px;\n line-height: 14px;\n color: #415290;\n text-align: left;\n}\n `;\n document.head.appendChild(style);\n }\n }\n};\n\n// Inject styles when this module is imported\ninjectLayoutStyles();\n\n// Track whether renderers have been registered to avoid duplicate registrations\nlet renderersInitialized = false;\n\n// Return empty renderers array initially\nexport const primevueRenderers: unknown[] = [];\n\n// Export a function that can be called by the consumer to register renderers\n// This should only be called once during application initialization\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function registerPrimevueRenderers(jsonformsCore: any): unknown[] {\n // Prevent duplicate registration which causes AJV schema recompilation\n if (renderersInitialized) {\n return primevueRenderers as unknown[];\n }\n\n const {\n rankWith,\n isStringControl,\n isNumberControl,\n isIntegerControl,\n and,\n or,\n isControl,\n schemaMatches,\n isBooleanControl,\n } = jsonformsCore;\n\n // Give PrimeVue renderers a high base rank; vanilla commonly uses small ranks (2–5)\n const PRIME = 100;\n\n // helpers for enum detection - using simple schema checks instead of JSONForms internal functions\n const isScalarEnum = (s?: object) => {\n const schema = s as {\n type?: string;\n enum?: unknown[];\n oneOf?: unknown[];\n };\n return (\n schema &&\n schema.type !== \"array\" &&\n (Array.isArray(schema.enum) || Array.isArray(schema.oneOf))\n );\n };\n\n const 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\n const isMultilineString = (uischema: unknown, schema: unknown) => {\n const controlUischema = uischema as { options?: { multi?: boolean } };\n return and(isStringControl, () => controlUischema?.options?.multi === true)(\n uischema as Parameters<typeof isStringControl>[0],\n schema as Parameters<typeof isStringControl>[1],\n {} as Parameters<typeof isStringControl>[2],\n );\n };\n\n // Projection-aware schema check: when options.projection is set,\n // resolve the projected schema and test against it instead of the original\n\n const projectedSchemaMatches =\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (check: (schema: any) => boolean) =>\n (uischema: unknown, schema: unknown): boolean => {\n const ui = uischema as {\n type?: string;\n scope?: string;\n options?: { projection?: string };\n };\n const projection = ui?.options?.projection;\n if (!projection || ui?.type !== \"Control\" || !ui?.scope) return false;\n\n const propertySchema = resolveScopeSchema(\n ui.scope,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n schema as Record<string, any>,\n );\n if (!propertySchema) return false;\n\n return check(getProjectedSchema(propertySchema, projection));\n };\n\n const isMultilineProjection = (uischema: unknown, schema: unknown) => {\n const ui = uischema as { options?: { multi?: boolean } };\n return (\n ui?.options?.multi === true &&\n projectedSchemaMatches((s) => s?.type === \"string\")(uischema, schema)\n );\n };\n\n const renderers = [\n // Multiline text has higher priority than regular text\n {\n tester: rankWith(PRIME + 4, or(isMultilineString, isMultilineProjection)),\n renderer: JfTextArea,\n },\n {\n tester: rankWith(\n PRIME + 3,\n or(\n isStringControl,\n projectedSchemaMatches((s) => s?.type === \"string\"),\n ),\n ),\n renderer: JfText,\n },\n {\n tester: rankWith(\n PRIME + 6,\n or(\n isIntegerControl,\n projectedSchemaMatches((s) => s?.type === \"integer\"),\n ),\n ),\n renderer: JfNumber,\n },\n {\n tester: rankWith(\n PRIME + 4,\n or(\n isNumberControl,\n projectedSchemaMatches((s) => s?.type === \"number\"),\n ),\n ),\n renderer: JfNumber,\n },\n {\n tester: rankWith(\n PRIME + 7,\n or(\n and(isControl, schemaMatches(isScalarEnum)),\n and(isControl, projectedSchemaMatches(isScalarEnum)),\n ),\n ),\n renderer: JfEnum,\n },\n {\n tester: rankWith(\n PRIME + 8,\n or(\n and(isControl, schemaMatches(isEnumArray)),\n and(isControl, projectedSchemaMatches(isEnumArray)),\n ),\n ),\n renderer: JfEnumArray,\n },\n {\n tester: rankWith(\n PRIME + 3,\n or(\n isBooleanControl,\n projectedSchemaMatches((s) => s?.type === \"boolean\"),\n ),\n ),\n renderer: JfBoolean,\n },\n ];\n\n // Update the exported array\n primevueRenderers.splice(0, primevueRenderers.length, ...renderers);\n\n // Mark as initialized to prevent duplicate registrations\n renderersInitialized = true;\n\n return renderers;\n}\n\nexport { JfText, JfTextArea, JfNumber, JfEnum, JfEnumArray, JfBoolean };\n"],"names":["JfTextArea","JfText","JfNumber","JfEnum","JfEnumArray","JfBoolean"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"autoSelect.js","sources":["../../../src/vue/utils/autoSelect.ts"],"sourcesContent":["import type { ProviderItem } from \"../../core/types\";\n\nexport interface AutoSelectParams {\n autoSelectSingle: boolean;\n isLoading: boolean;\n items: ProviderItem[];\n currentValue: unknown;\n}\n\n/**\n * Determines if auto-select should trigger for single-select dropdowns.\n * Returns null if auto-select should not trigger.\n *\n * Auto-select triggers when:\n * - autoSelectSingle option is enabled (default: true for single-select)\n * - Provider has finished loading\n * - Exactly one item is available\n * - Current value is empty (undefined/null) OR not in the current options\n */\nexport function shouldAutoSelect(params: AutoSelectParams): unknown | null {\n const { autoSelectSingle, isLoading, items, currentValue } = params;\n\n if (!autoSelectSingle || isLoading || items.length !== 1) {\n return null;\n }\n\n const singleItem = items[0];\n if (!singleItem) {\n return null;\n }\n\n const isValueEmpty = currentValue === undefined || currentValue === null;\n const isValueInOptions = items.some((item) => item.value === currentValue);\n\n if (isValueEmpty || !isValueInOptions) {\n return singleItem.value;\n }\n\n return null;\n}\n\nexport interface AutoSelectMultiParams {\n autoSelectSingle: boolean;\n isLoading: boolean;\n items: ProviderItem[];\n currentValue: unknown[];\n}\n\n/**\n * Determines if auto-select should trigger for multiselect dropdowns.\n * Returns null if auto-select should not trigger, otherwise returns an array with the single value.\n *\n * Auto-select triggers when:\n * - autoSelectSingle option is explicitly enabled (default: false for multiselect)\n * - Provider has finished loading\n * - Exactly one item is available\n * - Current value is empty array OR current selection is not in the current options\n */\nexport function shouldAutoSelectMulti(\n params: AutoSelectMultiParams\n): unknown[] | null {\n const { autoSelectSingle, isLoading, items, currentValue } = params;\n\n if (!autoSelectSingle || isLoading || items.length !== 1) {\n return null;\n }\n\n const singleItem = items[0];\n if (!singleItem) {\n return null;\n }\n\n const currentArray = Array.isArray(currentValue) ? currentValue : [];\n const isValueEmpty = currentArray.length === 0;\n const hasValidSelection = currentArray.some((val) =>\n items.some((item) => item.value === val)\n );\n\n if (isValueEmpty || !hasValidSelection) {\n return [singleItem.value];\n }\n\n return null;\n}\n"],"names":[],"mappings":"AAmBO,SAAS,iBAAiB,QAA0C;AACzE,QAAM,EAAE,kBAAkB,WAAW,OAAO,iBAAiB;AAE7D,MAAI,CAAC,oBAAoB,aAAa,MAAM,WAAW,GAAG;AACxD,WAAO;AAAA,EACT;AAEA,QAAM,aAAa,MAAM,CAAC;AAC1B,MAAI,CAAC,YAAY;AACf,WAAO;AAAA,EACT;AAEA,QAAM,eAAe,iBAAiB,UAAa,iBAAiB;AACpE,QAAM,mBAAmB,MAAM,KAAK,CAAC,SAAS,KAAK,UAAU,YAAY;AAEzE,MAAI,gBAAgB,CAAC,kBAAkB;AACrC,WAAO,WAAW;AAAA,EACpB;AAEA,SAAO;AACT;AAmBO,SAAS,sBACd,QACkB;AAClB,QAAM,EAAE,kBAAkB,WAAW,OAAO,iBAAiB;AAE7D,MAAI,CAAC,oBAAoB,aAAa,MAAM,WAAW,GAAG;AACxD,WAAO;AAAA,EACT;AAEA,QAAM,aAAa,MAAM,CAAC;AAC1B,MAAI,CAAC,YAAY;AACf,WAAO;AAAA,EACT;AAEA,QAAM,eAAe,MAAM,QAAQ,YAAY,IAAI,eAAe,CAAA;AAClE,QAAM,eAAe,aAAa,WAAW;AAC7C,QAAM,oBAAoB,aAAa;AAAA,IAAK,CAAC,QAC3C,MAAM,KAAK,CAAC,SAAS,KAAK,UAAU,GAAG;AAAA,EAAA;AAGzC,MAAI,gBAAgB,CAAC,mBAAmB;AACtC,WAAO,CAAC,WAAW,KAAK;AAAA,EAC1B;AAEA,SAAO;AACT;"}
1
+ {"version":3,"file":"autoSelect.js","sources":["../../../src/vue/utils/autoSelect.ts"],"sourcesContent":["import type { ProviderItem } from \"../../core/types\";\n\nexport interface AutoSelectParams {\n autoSelectSingle: boolean;\n isLoading: boolean;\n items: ProviderItem[];\n currentValue: unknown;\n}\n\n/**\n * Determines if auto-select should trigger for single-select dropdowns.\n * Returns null if auto-select should not trigger.\n *\n * Auto-select triggers when:\n * - autoSelectSingle option is enabled (default: true for single-select)\n * - Provider has finished loading\n * - Exactly one item is available\n * - Current value is empty (undefined/null) OR not in the current options\n */\nexport function shouldAutoSelect(params: AutoSelectParams): unknown | null {\n const { autoSelectSingle, isLoading, items, currentValue } = params;\n\n if (!autoSelectSingle || isLoading || items.length !== 1) {\n return null;\n }\n\n const singleItem = items[0];\n if (!singleItem) {\n return null;\n }\n\n const isValueEmpty = currentValue === undefined || currentValue === null;\n const isValueInOptions = items.some((item) => item.value === currentValue);\n\n if (isValueEmpty || !isValueInOptions) {\n return singleItem.value;\n }\n\n return null;\n}\n\nexport interface AutoSelectMultiParams {\n autoSelectSingle: boolean;\n isLoading: boolean;\n items: ProviderItem[];\n currentValue: unknown[];\n}\n\n/**\n * Determines if auto-select should trigger for multiselect dropdowns.\n * Returns null if auto-select should not trigger, otherwise returns an array with the single value.\n *\n * Auto-select triggers when:\n * - autoSelectSingle option is explicitly enabled (default: false for multiselect)\n * - Provider has finished loading\n * - Exactly one item is available\n * - Current value is empty array OR current selection is not in the current options\n */\nexport function shouldAutoSelectMulti(\n params: AutoSelectMultiParams,\n): unknown[] | null {\n const { autoSelectSingle, isLoading, items, currentValue } = params;\n\n if (!autoSelectSingle || isLoading || items.length !== 1) {\n return null;\n }\n\n const singleItem = items[0];\n if (!singleItem) {\n return null;\n }\n\n const currentArray = Array.isArray(currentValue) ? currentValue : [];\n const isValueEmpty = currentArray.length === 0;\n const hasValidSelection = currentArray.some((val) =>\n items.some((item) => item.value === val),\n );\n\n if (isValueEmpty || !hasValidSelection) {\n return [singleItem.value];\n }\n\n return null;\n}\n"],"names":[],"mappings":"AAmBO,SAAS,iBAAiB,QAA0C;AACzE,QAAM,EAAE,kBAAkB,WAAW,OAAO,iBAAiB;AAE7D,MAAI,CAAC,oBAAoB,aAAa,MAAM,WAAW,GAAG;AACxD,WAAO;AAAA,EACT;AAEA,QAAM,aAAa,MAAM,CAAC;AAC1B,MAAI,CAAC,YAAY;AACf,WAAO;AAAA,EACT;AAEA,QAAM,eAAe,iBAAiB,UAAa,iBAAiB;AACpE,QAAM,mBAAmB,MAAM,KAAK,CAAC,SAAS,KAAK,UAAU,YAAY;AAEzE,MAAI,gBAAgB,CAAC,kBAAkB;AACrC,WAAO,WAAW;AAAA,EACpB;AAEA,SAAO;AACT;AAmBO,SAAS,sBACd,QACkB;AAClB,QAAM,EAAE,kBAAkB,WAAW,OAAO,iBAAiB;AAE7D,MAAI,CAAC,oBAAoB,aAAa,MAAM,WAAW,GAAG;AACxD,WAAO;AAAA,EACT;AAEA,QAAM,aAAa,MAAM,CAAC;AAC1B,MAAI,CAAC,YAAY;AACf,WAAO;AAAA,EACT;AAEA,QAAM,eAAe,MAAM,QAAQ,YAAY,IAAI,eAAe,CAAA;AAClE,QAAM,eAAe,aAAa,WAAW;AAC7C,QAAM,oBAAoB,aAAa;AAAA,IAAK,CAAC,QAC3C,MAAM,KAAK,CAAC,SAAS,KAAK,UAAU,GAAG;AAAA,EAAA;AAGzC,MAAI,gBAAgB,CAAC,mBAAmB;AACtC,WAAO,CAAC,WAAW,KAAK;AAAA,EAC1B;AAEA,SAAO;AACT;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@narrative.io/jsonforms-provider-protocols",
3
- "version": "3.0.0-beta.3",
3
+ "version": "3.0.0-beta.5",
4
4
  "description": "Dynamic data provider capabilities for JSONForms with Vue 3 integration",
5
5
  "type": "module",
6
6
  "author": "Narrative I/O",
@@ -26,10 +26,7 @@ export function parseProjectionPath(path: string): ProjectionSegment[] {
26
26
  * Read a value from `data` by following the projection path.
27
27
  * Returns `undefined` if any segment along the path is missing.
28
28
  */
29
- export function getProjectedValue(
30
- data: unknown,
31
- path: string,
32
- ): unknown {
29
+ export function getProjectedValue(data: unknown, path: string): unknown {
33
30
  const segments = parseProjectionPath(path);
34
31
  let current: unknown = data;
35
32
 
@@ -85,7 +82,10 @@ function setAtPath(
85
82
  } else {
86
83
  // Object key — ensure we have an object
87
84
  const obj: Record<string, unknown> =
88
- current !== null && current !== undefined && typeof current === "object" && !Array.isArray(current)
85
+ current !== null &&
86
+ current !== undefined &&
87
+ typeof current === "object" &&
88
+ !Array.isArray(current)
89
89
  ? { ...(current as Record<string, unknown>) }
90
90
  : {};
91
91
  obj[seg] = setAtPath(obj[seg], segments, index + 1, value);
@@ -14,7 +14,16 @@ export interface FlattenTransform extends Transform {
14
14
  labelFormat?: string; // Optional format string like "{parent.name} → {name}"
15
15
  }
16
16
 
17
- export type FilterOperator = "eq" | "neq" | "empty" | "notEmpty" | "gt" | "gte" | "lt" | "lte" | "contains";
17
+ export type FilterOperator =
18
+ | "eq"
19
+ | "neq"
20
+ | "empty"
21
+ | "notEmpty"
22
+ | "gt"
23
+ | "gte"
24
+ | "lt"
25
+ | "lte"
26
+ | "contains";
18
27
 
19
28
  export interface FilterCondition {
20
29
  key: string;
@@ -153,13 +162,29 @@ function evaluateCondition(
153
162
  case "notEmpty":
154
163
  return !isEmpty(value);
155
164
  case "gt":
156
- return typeof value === "number" && condition.values !== undefined && value > (condition.values[0] as number);
165
+ return (
166
+ typeof value === "number" &&
167
+ condition.values !== undefined &&
168
+ value > (condition.values[0] as number)
169
+ );
157
170
  case "gte":
158
- return typeof value === "number" && condition.values !== undefined && value >= (condition.values[0] as number);
171
+ return (
172
+ typeof value === "number" &&
173
+ condition.values !== undefined &&
174
+ value >= (condition.values[0] as number)
175
+ );
159
176
  case "lt":
160
- return typeof value === "number" && condition.values !== undefined && value < (condition.values[0] as number);
177
+ return (
178
+ typeof value === "number" &&
179
+ condition.values !== undefined &&
180
+ value < (condition.values[0] as number)
181
+ );
161
182
  case "lte":
162
- return typeof value === "number" && condition.values !== undefined && value <= (condition.values[0] as number);
183
+ return (
184
+ typeof value === "number" &&
185
+ condition.values !== undefined &&
186
+ value <= (condition.values[0] as number)
187
+ );
163
188
  case "contains":
164
189
  if (typeof value === "string" && condition.values) {
165
190
  return condition.values.some((v) => value.includes(String(v)));
@@ -208,7 +233,9 @@ function filterTransform(items: unknown[], config: Transform): unknown[] {
208
233
  return items.filter((item) => {
209
234
  if (typeof item !== "object" || item === null) return false;
210
235
  const itemObj = item as Record<string, unknown>;
211
- return conditions.every((condition) => evaluateCondition(itemObj, condition));
236
+ return conditions.every((condition) =>
237
+ evaluateCondition(itemObj, condition),
238
+ );
212
239
  });
213
240
  }
214
241
 
@@ -12,7 +12,10 @@ const props = defineProps<{
12
12
  path: string;
13
13
  }>();
14
14
  const { control, handleChange: rawHandleChange } = useJsonFormsControl(props);
15
- const { projectedData, handleProjectedChange: handleChange } = useProjection(control, rawHandleChange);
15
+ const { projectedData, handleProjectedChange: handleChange } = useProjection(
16
+ control,
17
+ rawHandleChange,
18
+ );
16
19
 
17
20
  const binding = computed(() => {
18
21
  const provider = control.value.uischema?.options?.provider;
@@ -53,16 +56,16 @@ const onSelect = (event: { value?: { value?: unknown } | unknown }) => {
53
56
  </script>
54
57
 
55
58
  <template>
56
- <div class="flex flex-column gap-1">
57
- <label v-if="control.schema.title" class="text-color text-left">{{
59
+ <div class="jf-control">
60
+ <label v-if="control.schema.title" class="jf-label">{{
58
61
  control.schema.title
59
62
  }}</label>
60
- <div v-if="control.description" class="text-color-secondary text-left">
63
+ <div v-if="control.description" class="jf-description">
61
64
  {{ control.description }}
62
65
  </div>
63
66
  <AutoComplete
64
67
  v-model="value"
65
- class="w-full"
68
+ class="w-full!"
66
69
  :suggestions="items"
67
70
  option-label="label"
68
71
  :placeholder="placeholder"
@@ -13,7 +13,10 @@ const props = defineProps<{
13
13
  path: string;
14
14
  }>();
15
15
  const { control, handleChange: rawHandleChange } = useJsonFormsControl(props);
16
- const { projectedData, handleProjectedChange: handleChange } = useProjection(control, rawHandleChange);
16
+ const { projectedData, handleProjectedChange: handleChange } = useProjection(
17
+ control,
18
+ rawHandleChange,
19
+ );
17
20
 
18
21
  const binding = computed(() => {
19
22
  const provider = control.value.uischema?.options?.provider;
@@ -55,14 +58,16 @@ watch(
55
58
  control.value.uischema?.options?.autoSelectSingle === true,
56
59
  isLoading,
57
60
  items: newItems,
58
- currentValue: Array.isArray(projectedData.value) ? projectedData.value : [],
61
+ currentValue: Array.isArray(projectedData.value)
62
+ ? projectedData.value
63
+ : [],
59
64
  });
60
65
 
61
66
  if (valueToSelect !== null) {
62
67
  handleChange(control.value.path, valueToSelect);
63
68
  }
64
69
  },
65
- { immediate: true }
70
+ { immediate: true },
66
71
  );
67
72
 
68
73
  // order-insensitive shallow equality for primitive arrays
@@ -98,16 +103,16 @@ const placeholder = computed(() => {
98
103
  </script>
99
104
 
100
105
  <template>
101
- <div class="flex flex-column gap-2">
102
- <label v-if="control.schema.title" class="text-color text-left">{{
106
+ <div class="jf-control">
107
+ <label v-if="control.schema.title" class="jf-label">{{
103
108
  control.schema.title
104
109
  }}</label>
105
- <div v-if="control.description" class="text-color-secondary text-left">
110
+ <div v-if="control.description" class="jf-description">
106
111
  {{ control.description }}
107
112
  </div>
108
113
  <MultiSelect
109
114
  v-model="value"
110
- class="w-full"
115
+ class="w-full!"
111
116
  :options="items"
112
117
  option-label="label"
113
118
  option-value="value"