@narrative.io/jsonforms-provider-protocols 3.0.0-beta.2 → 3.0.0-beta.21

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 (124) hide show
  1. package/dist/core/initFormData.d.ts +17 -0
  2. package/dist/core/initFormData.d.ts.map +1 -0
  3. package/dist/core/initFormData.js +99 -0
  4. package/dist/core/initFormData.js.map +1 -0
  5. package/dist/core/projection.d.ts +4 -0
  6. package/dist/core/projection.d.ts.map +1 -1
  7. package/dist/core/projection.js +17 -14
  8. package/dist/core/projection.js.map +1 -1
  9. package/dist/core/refs.d.ts +58 -0
  10. package/dist/core/refs.d.ts.map +1 -0
  11. package/dist/core/refs.js +70 -0
  12. package/dist/core/refs.js.map +1 -0
  13. package/dist/core/resolveScope.d.ts +6 -0
  14. package/dist/core/resolveScope.d.ts.map +1 -1
  15. package/dist/core/resolveScope.js +14 -8
  16. package/dist/core/resolveScope.js.map +1 -1
  17. package/dist/core/transforms.d.ts.map +1 -1
  18. package/dist/core/transforms.js +3 -1
  19. package/dist/core/transforms.js.map +1 -1
  20. package/dist/core/types.d.ts +1 -0
  21. package/dist/core/types.d.ts.map +1 -1
  22. package/dist/index.d.ts +3 -0
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +6 -1
  25. package/dist/index.js.map +1 -1
  26. package/dist/jsonforms-provider-protocols.css +2 -2
  27. package/dist/no-eval-ajv.d.ts +70 -0
  28. package/dist/no-eval-ajv.d.ts.map +1 -0
  29. package/dist/no-eval-ajv.js +247 -0
  30. package/dist/no-eval-ajv.js.map +1 -0
  31. package/dist/vue/components/ProviderAutocomplete.vue.d.ts.map +1 -1
  32. package/dist/vue/components/ProviderAutocomplete.vue.js +10 -6
  33. package/dist/vue/components/ProviderAutocomplete.vue.js.map +1 -1
  34. package/dist/vue/components/ProviderMultiSelect.vue.d.ts.map +1 -1
  35. package/dist/vue/components/ProviderMultiSelect.vue.js +1 -1
  36. package/dist/vue/components/ProviderMultiSelect.vue2.js +17 -9
  37. package/dist/vue/components/ProviderMultiSelect.vue2.js.map +1 -1
  38. package/dist/vue/components/ProviderSelect.vue.d.ts.map +1 -1
  39. package/dist/vue/components/ProviderSelect.vue.js +1 -1
  40. package/dist/vue/components/ProviderSelect.vue2.js +19 -9
  41. package/dist/vue/components/ProviderSelect.vue2.js.map +1 -1
  42. package/dist/vue/composables/useDataLayer.d.ts +1 -0
  43. package/dist/vue/composables/useDataLayer.d.ts.map +1 -1
  44. package/dist/vue/composables/useDataLayer.js +1 -0
  45. package/dist/vue/composables/useDataLayer.js.map +1 -1
  46. package/dist/vue/composables/useDerive.d.ts +1 -1
  47. package/dist/vue/composables/useDerive.d.ts.map +1 -1
  48. package/dist/vue/composables/useDerive.js +19 -2
  49. package/dist/vue/composables/useDerive.js.map +1 -1
  50. package/dist/vue/composables/useDeriveInitialValue.d.ts +36 -0
  51. package/dist/vue/composables/useDeriveInitialValue.d.ts.map +1 -0
  52. package/dist/vue/composables/useDeriveInitialValue.js +125 -0
  53. package/dist/vue/composables/useDeriveInitialValue.js.map +1 -0
  54. package/dist/vue/composables/useDirtyValidation.d.ts +3 -3
  55. package/dist/vue/composables/useDirtyValidation.d.ts.map +1 -1
  56. package/dist/vue/composables/useDirtyValidation.js +2 -2
  57. package/dist/vue/composables/useDirtyValidation.js.map +1 -1
  58. package/dist/vue/composables/useProjection.d.ts +7 -0
  59. package/dist/vue/composables/useProjection.d.ts.map +1 -1
  60. package/dist/vue/composables/useProjection.js +87 -4
  61. package/dist/vue/composables/useProjection.js.map +1 -1
  62. package/dist/vue/composables/useProvider.d.ts +2 -2
  63. package/dist/vue/composables/useProvider.d.ts.map +1 -1
  64. package/dist/vue/composables/useProvider.js +14 -10
  65. package/dist/vue/composables/useProvider.js.map +1 -1
  66. package/dist/vue/index.d.ts +2 -0
  67. package/dist/vue/index.d.ts.map +1 -1
  68. package/dist/vue/index.js +30 -10
  69. package/dist/vue/index.js.map +1 -1
  70. package/dist/vue/primevue/JfBoolean.vue.d.ts.map +1 -1
  71. package/dist/vue/primevue/JfBoolean.vue.js +17 -6
  72. package/dist/vue/primevue/JfBoolean.vue.js.map +1 -1
  73. package/dist/vue/primevue/JfEnum.vue.d.ts.map +1 -1
  74. package/dist/vue/primevue/JfEnum.vue.js +22 -10
  75. package/dist/vue/primevue/JfEnum.vue.js.map +1 -1
  76. package/dist/vue/primevue/JfEnumArray.vue.d.ts.map +1 -1
  77. package/dist/vue/primevue/JfEnumArray.vue.js +20 -10
  78. package/dist/vue/primevue/JfEnumArray.vue.js.map +1 -1
  79. package/dist/vue/primevue/JfNumber.vue.d.ts.map +1 -1
  80. package/dist/vue/primevue/JfNumber.vue.js +18 -10
  81. package/dist/vue/primevue/JfNumber.vue.js.map +1 -1
  82. package/dist/vue/primevue/JfText.vue.d.ts.map +1 -1
  83. package/dist/vue/primevue/JfText.vue.js +27 -12
  84. package/dist/vue/primevue/JfText.vue.js.map +1 -1
  85. package/dist/vue/primevue/JfTextArea.vue.d.ts.map +1 -1
  86. package/dist/vue/primevue/JfTextArea.vue.js +15 -9
  87. package/dist/vue/primevue/JfTextArea.vue.js.map +1 -1
  88. package/dist/vue/primevue/index.d.ts.map +1 -1
  89. package/dist/vue/primevue/index.js +93 -16
  90. package/dist/vue/primevue/index.js.map +1 -1
  91. package/dist/vue/utils/autoSelect.js.map +1 -1
  92. package/dist/vue/utils/placeholder.d.ts +17 -0
  93. package/dist/vue/utils/placeholder.d.ts.map +1 -0
  94. package/dist/vue/utils/placeholder.js +17 -0
  95. package/dist/vue/utils/placeholder.js.map +1 -0
  96. package/package.json +10 -2
  97. package/src/core/initFormData.ts +208 -0
  98. package/src/core/projection.ts +33 -22
  99. package/src/core/refs.ts +166 -0
  100. package/src/core/resolveScope.ts +23 -8
  101. package/src/core/transforms.ts +33 -6
  102. package/src/core/types.ts +1 -0
  103. package/src/index.ts +14 -2
  104. package/src/no-eval-ajv.ts +381 -0
  105. package/src/vue/components/ProviderAutocomplete.vue +9 -7
  106. package/src/vue/components/ProviderMultiSelect.vue +20 -15
  107. package/src/vue/components/ProviderSelect.vue +21 -14
  108. package/src/vue/composables/useDataLayer.ts +1 -1
  109. package/src/vue/composables/useDerive.ts +46 -3
  110. package/src/vue/composables/useDeriveInitialValue.ts +195 -0
  111. package/src/vue/composables/useDirtyValidation.ts +8 -3
  112. package/src/vue/composables/useProjection.ts +172 -1
  113. package/src/vue/composables/useProvider.ts +28 -11
  114. package/src/vue/index.ts +28 -9
  115. package/src/vue/primevue/JfBoolean.vue +10 -5
  116. package/src/vue/primevue/JfEnum.vue +23 -14
  117. package/src/vue/primevue/JfEnumArray.vue +22 -17
  118. package/src/vue/primevue/JfNumber.vue +20 -12
  119. package/src/vue/primevue/JfText.vue +31 -16
  120. package/src/vue/primevue/JfTextArea.vue +15 -13
  121. package/src/vue/primevue/index.ts +104 -23
  122. package/src/vue/styles.css +26 -1
  123. package/src/vue/utils/autoSelect.ts +2 -2
  124. package/src/vue/utils/placeholder.ts +42 -0
@@ -1 +1 @@
1
- {"version":3,"file":"useProjection.js","sources":["../../../src/vue/composables/useProjection.ts"],"sourcesContent":["import { computed, type ComputedRef, type Ref } from \"vue\";\nimport {\n getProjectedValue,\n setProjectedValue,\n getProjectedSchema,\n} from \"../../core/projection\";\n\ninterface ProjectionControl {\n data: unknown;\n path: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n schema: Record<string, any>;\n uischema: { options?: { projection?: string; [key: string]: unknown } };\n}\n\nexport interface ProjectionResult {\n /** The value at the projected path (for rendering) */\n projectedData: ComputedRef<unknown>;\n /** The schema at the projected path (for renderer selection) */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n projectedSchema: ComputedRef<Record<string, any>>;\n /** Wrapped handleChange that writes through the projection */\n handleProjectedChange: (path: string, value: unknown) => void;\n /** Whether projection is active */\n hasProjection: boolean;\n}\n\n/**\n * Composable that wraps a JSON Forms control with projection support.\n *\n * When `options.projection` is set on the uischema, this composable:\n * - Reads the projected sub-value from the control data\n * - Resolves the projected sub-schema for renderer type resolution\n * - Wraps handleChange to write back through the projection path (preserving siblings)\n *\n * When no projection is set, it passes through control data/schema/handleChange unchanged.\n */\nexport function useProjection(\n control: Ref<ProjectionControl>,\n handleChange: (path: string, value: unknown) => void,\n): ProjectionResult {\n const projection = control.value.uischema?.options?.projection as\n | string\n | undefined;\n\n if (!projection) {\n return {\n projectedData: computed(() => control.value.data),\n projectedSchema: computed(() => control.value.schema),\n handleProjectedChange: handleChange,\n hasProjection: false,\n };\n }\n\n const projectedData = computed(() =>\n getProjectedValue(control.value.data, projection),\n );\n\n const projectedSchema = computed(() =>\n getProjectedSchema(control.value.schema, projection),\n );\n\n const handleProjectedChange = (path: string, value: unknown) => {\n const fullValue = setProjectedValue(control.value.data, projection, value);\n handleChange(path, fullValue);\n };\n\n return {\n projectedData,\n projectedSchema,\n handleProjectedChange,\n hasProjection: true,\n };\n}\n"],"names":[],"mappings":";;AAqCO,SAAS,cACd,SACA,cACkB;AAClB,QAAM,aAAa,QAAQ,MAAM,UAAU,SAAS;AAIpD,MAAI,CAAC,YAAY;AACf,WAAO;AAAA,MACL,eAAe,SAAS,MAAM,QAAQ,MAAM,IAAI;AAAA,MAChD,iBAAiB,SAAS,MAAM,QAAQ,MAAM,MAAM;AAAA,MACpD,uBAAuB;AAAA,MACvB,eAAe;AAAA,IAAA;AAAA,EAEnB;AAEA,QAAM,gBAAgB;AAAA,IAAS,MAC7B,kBAAkB,QAAQ,MAAM,MAAM,UAAU;AAAA,EAAA;AAGlD,QAAM,kBAAkB;AAAA,IAAS,MAC/B,mBAAmB,QAAQ,MAAM,QAAQ,UAAU;AAAA,EAAA;AAGrD,QAAM,wBAAwB,CAAC,MAAc,UAAmB;AAC9D,UAAM,YAAY,kBAAkB,QAAQ,MAAM,MAAM,YAAY,KAAK;AACzE,iBAAa,MAAM,SAAS;AAAA,EAC9B;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,eAAe;AAAA,EAAA;AAEnB;"}
1
+ {"version":3,"file":"useProjection.js","sources":["../../../src/vue/composables/useProjection.ts"],"sourcesContent":["import { computed, inject, type ComputedRef, type Ref } from \"vue\";\nimport {\n getProjectedValue,\n setProjectedValue,\n getProjectedSchema,\n parseProjectionPath,\n} from \"../../core/projection\";\nimport { deref } from \"../../core/refs\";\n\ninterface ProjectionControl {\n data: unknown;\n path: string;\n errors: string;\n label?: string;\n required?: boolean;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n schema: Record<string, any>;\n uischema: { options?: { projection?: string; [key: string]: unknown } };\n}\n\n// Minimal AJV ErrorObject shape for filtering\ninterface ErrorLike {\n instancePath?: string;\n keyword?: string;\n message?: string;\n params?: { missingProperty?: string };\n}\n\n/**\n * Resolve the display label for a control.\n * Priority: uischema options.label → schemaTitle (projected sub-schema) → control.label.\n * Appends a trailing asterisk when the control is for a required property.\n */\nfunction resolveLabel(\n ctrl: ProjectionControl,\n schemaTitle?: string,\n required?: boolean,\n): string {\n const base =\n (ctrl.uischema?.options?.label as string) ??\n schemaTitle ??\n ctrl.label ??\n \"\";\n if (!base) return base;\n return required ? `${base} *` : base;\n}\n\n/**\n * Determine whether the leaf of a projection path is listed in its parent\n * schema's `required` array. Numeric leaf segments (array indices) are not\n * considered \"required properties\".\n *\n * Dereferences `$ref` at every step against `root` (defaulting to `schema`)\n * so that schemas like `items: { $ref: '#/$defs/Foo' }` resolve correctly.\n */\nfunction isProjectedFieldRequired(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n schema: Record<string, any>,\n path: string,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n root?: Record<string, any>,\n): boolean {\n const segments = parseProjectionPath(path);\n if (segments.length === 0) return false;\n const rootSchema = root ?? schema;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let current: Record<string, any> | undefined = deref(schema, rootSchema);\n for (let i = 0; i < segments.length - 1; i++) {\n const seg = segments[i]!;\n if (typeof seg === \"number\") {\n current = deref(current?.items, rootSchema);\n } else {\n current = deref(current?.properties?.[seg], rootSchema);\n }\n if (!current) return false;\n }\n const last = segments[segments.length - 1];\n if (typeof last !== \"string\") return false;\n current = deref(current, rootSchema);\n return Array.isArray(current?.required) && current.required.includes(last);\n}\n\n/**\n * Normalize AJV error message fragments into user-friendly text.\n * e.g. \"is a required property\" → \"is required\"\n */\nfunction normalizeErrors(errors: string): string {\n if (!errors) return errors;\n return errors\n .replace(/is a required property/g, \"is required\")\n .replace(/must have required property '[^']*'/g, \"is required\");\n}\n\n/**\n * Prefix each error message line with the field label so that AJV fragments\n * like \"is required\" become \"Name is required\".\n */\nfunction prefixErrors(label: string, errors: string): string {\n if (!label || !errors) return errors;\n return errors\n .split(\"\\n\")\n .map((line) => `${label} ${line}`)\n .join(\"\\n\");\n}\n\n/**\n * Convert an AJV ErrorObject's instancePath to a dot-separated control path.\n * Replicates the logic from @jsonforms/core getControlPath.\n */\nfunction getErrorPath(error: ErrorLike): string {\n let p = (error.instancePath || \"\").replace(/\\//g, \".\").replace(/^\\./, \"\");\n if (error.keyword === \"required\" && error.params?.missingProperty) {\n p = p\n ? p + \".\" + error.params.missingProperty\n : error.params.missingProperty;\n }\n return p;\n}\n\nexport interface ProjectionResult {\n /** The value at the projected path (for rendering) */\n projectedData: ComputedRef<unknown>;\n /** The schema at the projected path (for renderer selection) */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n projectedSchema: ComputedRef<Record<string, any>>;\n /** Wrapped handleChange that writes through the projection */\n handleProjectedChange: (path: string, value: unknown) => void;\n /** Whether projection is active */\n hasProjection: boolean;\n /** Resolved display label (options.label → projected schema title → control.label) */\n projectedLabel: ComputedRef<string>;\n /** Error string combining base-path and projected sub-path errors */\n projectedErrors: ComputedRef<string>;\n}\n\n/**\n * Composable that wraps a JSON Forms control with projection support.\n *\n * When `options.projection` is set on the uischema, this composable:\n * - Reads the projected sub-value from the control data\n * - Resolves the projected sub-schema for renderer type resolution\n * - Wraps handleChange to write back through the projection path (preserving siblings)\n *\n * When no projection is set, it passes through control data/schema/handleChange unchanged.\n */\nexport function useProjection(\n control: Ref<ProjectionControl>,\n handleChange: (path: string, value: unknown) => void,\n): ProjectionResult {\n const projection = control.value.uischema?.options?.projection as\n | string\n | undefined;\n\n if (!projection) {\n const label = computed(() =>\n resolveLabel(control.value, undefined, control.value.required),\n );\n return {\n projectedData: computed(() => control.value.data),\n projectedSchema: computed(() => control.value.schema),\n handleProjectedChange: handleChange,\n hasProjection: false,\n projectedLabel: label,\n projectedErrors: computed(() =>\n prefixErrors(\n label.value.replace(/\\*$/, \"\").trim(),\n normalizeErrors(control.value.errors),\n ),\n ),\n };\n }\n\n // Inject JSONForms state to access raw AJV errors for projected sub-paths,\n // and the root schema so that `$ref` resolution inside the projected slice\n // can find `$defs` (which live at the root, not on the control's schema).\n const jsonforms = inject<{\n core?: {\n errors?: ErrorLike[];\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n schema?: Record<string, any>;\n };\n } | null>(\"jsonforms\", null);\n\n const fullProjectedPath = control.value.path + \".\" + projection;\n\n const projectedData = computed(() =>\n getProjectedValue(control.value.data, projection),\n );\n\n const projectedSchema = computed(() =>\n getProjectedSchema(control.value.schema, projection),\n );\n\n const projectedRequired = computed(() =>\n isProjectedFieldRequired(\n control.value.schema,\n projection,\n jsonforms?.core?.schema ?? control.value.schema,\n ),\n );\n\n const label = computed(() =>\n resolveLabel(\n control.value,\n projectedSchema.value?.title,\n projectedRequired.value,\n ),\n );\n\n const projectedErrors = computed(() => {\n const baseErrors = normalizeErrors(control.value.errors || \"\");\n\n const rawErrors = jsonforms?.core?.errors ?? ([] as ErrorLike[]);\n const matching = rawErrors.filter(\n (err) => getErrorPath(err) === fullProjectedPath,\n );\n\n let errStr: string;\n if (matching.length === 0) {\n errStr = baseErrors;\n } else {\n const projMsg = matching\n .map((e) => (e.keyword === \"required\" ? \"is required\" : e.message))\n .filter(Boolean)\n .join(\"\\n\");\n errStr = [baseErrors, projMsg].filter(Boolean).join(\"\\n\");\n }\n\n return prefixErrors(label.value.replace(/\\*$/, \"\").trim(), errStr);\n });\n\n const handleProjectedChange = (path: string, value: unknown) => {\n const fullValue = setProjectedValue(control.value.data, projection, value);\n handleChange(path, fullValue);\n };\n\n return {\n projectedData,\n projectedSchema,\n handleProjectedChange,\n hasProjection: true,\n projectedLabel: label,\n projectedErrors,\n };\n}\n"],"names":["label"],"mappings":"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"}
@@ -3,8 +3,8 @@ import type { ProviderBinding, ProviderItem } from "../../core/types";
3
3
  export declare function useProvider(binding: ProviderBinding | Ref<ProviderBinding> | ComputedRef<ProviderBinding>, ctxBits: {
4
4
  data: unknown | Ref<unknown> | ComputedRef<unknown>;
5
5
  path: string;
6
- dependsOnValues?: unknown[];
7
- uiQuery?: string;
6
+ dependsOnValues?: unknown[] | Ref<unknown[]> | ComputedRef<unknown[]>;
7
+ uiQuery?: string | Ref<string | undefined> | ComputedRef<string | undefined>;
8
8
  }): {
9
9
  items: Ref<{
10
10
  label: string;
@@ -1 +1 @@
1
- {"version":3,"file":"useProvider.d.ts","sourceRoot":"","sources":["../../../src/vue/composables/useProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,WAAW,EAIhB,KAAK,GAAG,EAIT,MAAM,KAAK,CAAC;AAGb,OAAO,KAAK,EAEV,eAAe,EACf,YAAY,EAEb,MAAM,kBAAkB,CAAC;AAE1B,wBAAgB,WAAW,CACzB,OAAO,EACH,eAAe,GACf,GAAG,CAAC,eAAe,CAAC,GACpB,WAAW,CAAC,eAAe,CAAC,EAChC,OAAO,EAAE;IACP,IAAI,EAAE,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;IACpD,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,CAAC,EAAE,OAAO,EAAE,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;;;;;;;;;;;;;EAsEF"}
1
+ {"version":3,"file":"useProvider.d.ts","sourceRoot":"","sources":["../../../src/vue/composables/useProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,WAAW,EAIhB,KAAK,GAAG,EAIT,MAAM,KAAK,CAAC;AAIb,OAAO,KAAK,EAEV,eAAe,EACf,YAAY,EAEb,MAAM,kBAAkB,CAAC;AAE1B,wBAAgB,WAAW,CACzB,OAAO,EACH,eAAe,GACf,GAAG,CAAC,eAAe,CAAC,GACpB,WAAW,CAAC,eAAe,CAAC,EAChC,OAAO,EAAE;IACP,IAAI,EAAE,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;IACpD,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,CAAC,EAAE,OAAO,EAAE,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC,GAAG,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC;IACtE,OAAO,CAAC,EACJ,MAAM,GACN,GAAG,CAAC,MAAM,GAAG,SAAS,CAAC,GACvB,WAAW,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;CACrC;;;;;;;;;;;;;EAmFF"}
@@ -1,6 +1,7 @@
1
1
  import { inject, ref, computed, unref, onBeforeUnmount, watch } from "vue";
2
2
  import { cache } from "../../core/cache.js";
3
3
  import { registry } from "../../core/registry.js";
4
+ import { renderObj } from "../../core/templating.js";
4
5
  function useProvider(binding, ctxBits) {
5
6
  const registry$1 = inject("providerRegistry", registry);
6
7
  const cache$1 = inject("providerCache", cache);
@@ -9,15 +10,18 @@ function useProvider(binding, ctxBits) {
9
10
  const loading = ref(false);
10
11
  const error = ref(void 0);
11
12
  const ac = new AbortController();
12
- const cacheKey = computed(
13
- () => JSON.stringify({
14
- b: unref(binding),
15
- d: ctxBits.dependsOnValues ?? [],
16
- q: ctxBits.uiQuery ?? "",
17
- data: unref(ctxBits.data)
18
- // Include data in cache key for reactivity
19
- })
20
- );
13
+ const cacheKey = computed(() => {
14
+ const b = unref(binding);
15
+ const renderedBinding = b ? {
16
+ ...b,
17
+ config: renderObj(b.config ?? {}, { data: unref(ctxBits.data) })
18
+ } : b;
19
+ return JSON.stringify({
20
+ b: renderedBinding,
21
+ d: unref(ctxBits.dependsOnValues) ?? [],
22
+ q: unref(ctxBits.uiQuery) ?? ""
23
+ });
24
+ });
21
25
  async function load() {
22
26
  const bindingValue = unref(binding);
23
27
  if (!bindingValue) return;
@@ -39,7 +43,7 @@ function useProvider(binding, ctxBits) {
39
43
  const out = await driver.resolve(bindingValue.config ?? {}, {
40
44
  data: unref(ctxBits.data),
41
45
  path: ctxBits.path,
42
- ui: { query: ctxBits.uiQuery },
46
+ ui: { query: unref(ctxBits.uiQuery) },
43
47
  signal: ac.signal,
44
48
  auth: resolveAuth(bindingValue.auth, auth)
45
49
  });
@@ -1 +1 @@
1
- {"version":3,"file":"useProvider.js","sources":["../../../src/vue/composables/useProvider.ts"],"sourcesContent":["import {\n type ComputedRef,\n computed,\n inject,\n onBeforeUnmount,\n type Ref,\n ref,\n unref,\n watch,\n} from \"vue\";\nimport { cache as globalCache } from \"../../core/cache\";\nimport { registry as globalRegistry } from \"../../core/registry\";\nimport type {\n AuthConfig,\n ProviderBinding,\n ProviderItem,\n ProviderOutput,\n} from \"../../core/types\";\n\nexport function useProvider(\n binding:\n | ProviderBinding\n | Ref<ProviderBinding>\n | ComputedRef<ProviderBinding>,\n ctxBits: {\n data: unknown | Ref<unknown> | ComputedRef<unknown>;\n path: string;\n dependsOnValues?: unknown[];\n uiQuery?: string;\n },\n) {\n const registry = inject(\"providerRegistry\", globalRegistry);\n const cache = inject(\"providerCache\", globalCache);\n const auth = inject(\"providerAuth\", {}) as Record<\n string,\n (() => string) | string\n >;\n\n const items = ref<ProviderItem[]>([]);\n const loading = ref(false);\n const error = ref<string | undefined>(undefined);\n const ac = new AbortController();\n\n const cacheKey = computed(() =>\n JSON.stringify({\n b: unref(binding),\n d: ctxBits.dependsOnValues ?? [],\n q: ctxBits.uiQuery ?? \"\",\n data: unref(ctxBits.data), // Include data in cache key for reactivity\n }),\n );\n\n async function load() {\n const bindingValue = unref(binding);\n if (!bindingValue) return;\n loading.value = true;\n error.value = undefined;\n const hit = cache.get(cacheKey.value) as ProviderOutput | undefined;\n if (hit) {\n items.value = hit.items;\n loading.value = false;\n return;\n }\n try {\n const driver = registry.get(bindingValue.protocol);\n if (!driver) {\n throw new Error(\n `No provider registered for protocol: ${bindingValue.protocol}`,\n );\n }\n const out = await driver.resolve(bindingValue.config ?? {}, {\n data: unref(ctxBits.data),\n path: ctxBits.path,\n ui: { query: ctxBits.uiQuery },\n signal: ac.signal,\n auth: resolveAuth(bindingValue.auth, auth),\n });\n items.value = out.items;\n cache.set(cacheKey.value, out, bindingValue.cacheTTL ?? out.ttl ?? 0);\n } catch (e) {\n error.value = (e as Error)?.message ?? String(e);\n items.value = [];\n } finally {\n loading.value = false;\n }\n }\n\n onBeforeUnmount(() => ac.abort());\n watch(\n [cacheKey],\n () => {\n const bindingValue = unref(binding);\n if (bindingValue?.load === \"mount\" || bindingValue?.load === \"query\")\n load();\n },\n { immediate: unref(binding)?.load === \"mount\" },\n );\n\n return { items, loading, error, reload: load };\n}\n\nfunction resolveAuth(\n spec: AuthConfig | undefined,\n authBag: Record<string, (() => string) | string>,\n): AuthConfig {\n if (!spec) return {};\n if (spec.use && typeof authBag[spec.use] === \"function\") {\n const authFunc = authBag[spec.use] as () => string;\n return { [spec.use]: authFunc() };\n }\n return spec;\n}\n"],"names":["registry","globalRegistry","cache","globalCache"],"mappings":";;;AAmBO,SAAS,YACd,SAIA,SAMA;AACA,QAAMA,aAAW,OAAO,oBAAoBC,QAAc;AAC1D,QAAMC,UAAQ,OAAO,iBAAiBC,KAAW;AACjD,QAAM,OAAO,OAAO,gBAAgB,EAAE;AAKtC,QAAM,QAAQ,IAAoB,EAAE;AACpC,QAAM,UAAU,IAAI,KAAK;AACzB,QAAM,QAAQ,IAAwB,MAAS;AAC/C,QAAM,KAAK,IAAI,gBAAA;AAEf,QAAM,WAAW;AAAA,IAAS,MACxB,KAAK,UAAU;AAAA,MACb,GAAG,MAAM,OAAO;AAAA,MAChB,GAAG,QAAQ,mBAAmB,CAAA;AAAA,MAC9B,GAAG,QAAQ,WAAW;AAAA,MACtB,MAAM,MAAM,QAAQ,IAAI;AAAA;AAAA,IAAA,CACzB;AAAA,EAAA;AAGH,iBAAe,OAAO;AACpB,UAAM,eAAe,MAAM,OAAO;AAClC,QAAI,CAAC,aAAc;AACnB,YAAQ,QAAQ;AAChB,UAAM,QAAQ;AACd,UAAM,MAAMD,QAAM,IAAI,SAAS,KAAK;AACpC,QAAI,KAAK;AACP,YAAM,QAAQ,IAAI;AAClB,cAAQ,QAAQ;AAChB;AAAA,IACF;AACA,QAAI;AACF,YAAM,SAASF,WAAS,IAAI,aAAa,QAAQ;AACjD,UAAI,CAAC,QAAQ;AACX,cAAM,IAAI;AAAA,UACR,wCAAwC,aAAa,QAAQ;AAAA,QAAA;AAAA,MAEjE;AACA,YAAM,MAAM,MAAM,OAAO,QAAQ,aAAa,UAAU,IAAI;AAAA,QAC1D,MAAM,MAAM,QAAQ,IAAI;AAAA,QACxB,MAAM,QAAQ;AAAA,QACd,IAAI,EAAE,OAAO,QAAQ,QAAA;AAAA,QACrB,QAAQ,GAAG;AAAA,QACX,MAAM,YAAY,aAAa,MAAM,IAAI;AAAA,MAAA,CAC1C;AACD,YAAM,QAAQ,IAAI;AAClBE,cAAM,IAAI,SAAS,OAAO,KAAK,aAAa,YAAY,IAAI,OAAO,CAAC;AAAA,IACtE,SAAS,GAAG;AACV,YAAM,QAAS,GAAa,WAAW,OAAO,CAAC;AAC/C,YAAM,QAAQ,CAAA;AAAA,IAChB,UAAA;AACE,cAAQ,QAAQ;AAAA,IAClB;AAAA,EACF;AAEA,kBAAgB,MAAM,GAAG,OAAO;AAChC;AAAA,IACE,CAAC,QAAQ;AAAA,IACT,MAAM;AACJ,YAAM,eAAe,MAAM,OAAO;AAClC,UAAI,cAAc,SAAS,WAAW,cAAc,SAAS;AAC3D,aAAA;AAAA,IACJ;AAAA,IACA,EAAE,WAAW,MAAM,OAAO,GAAG,SAAS,QAAA;AAAA,EAAQ;AAGhD,SAAO,EAAE,OAAO,SAAS,OAAO,QAAQ,KAAA;AAC1C;AAEA,SAAS,YACP,MACA,SACY;AACZ,MAAI,CAAC,KAAM,QAAO,CAAA;AAClB,MAAI,KAAK,OAAO,OAAO,QAAQ,KAAK,GAAG,MAAM,YAAY;AACvD,UAAM,WAAW,QAAQ,KAAK,GAAG;AACjC,WAAO,EAAE,CAAC,KAAK,GAAG,GAAG,WAAS;AAAA,EAChC;AACA,SAAO;AACT;"}
1
+ {"version":3,"file":"useProvider.js","sources":["../../../src/vue/composables/useProvider.ts"],"sourcesContent":["import {\n type ComputedRef,\n computed,\n inject,\n onBeforeUnmount,\n type Ref,\n ref,\n unref,\n watch,\n} from \"vue\";\nimport { cache as globalCache } from \"../../core/cache\";\nimport { registry as globalRegistry } from \"../../core/registry\";\nimport { renderObj } from \"../../core/templating\";\nimport type {\n AuthConfig,\n ProviderBinding,\n ProviderItem,\n ProviderOutput,\n} from \"../../core/types\";\n\nexport function useProvider(\n binding:\n | ProviderBinding\n | Ref<ProviderBinding>\n | ComputedRef<ProviderBinding>,\n ctxBits: {\n data: unknown | Ref<unknown> | ComputedRef<unknown>;\n path: string;\n dependsOnValues?: unknown[] | Ref<unknown[]> | ComputedRef<unknown[]>;\n uiQuery?:\n | string\n | Ref<string | undefined>\n | ComputedRef<string | undefined>;\n },\n) {\n const registry = inject(\"providerRegistry\", globalRegistry);\n const cache = inject(\"providerCache\", globalCache);\n const auth = inject(\"providerAuth\", {}) as Record<\n string,\n (() => string) | string\n >;\n\n const items = ref<ProviderItem[]>([]);\n const loading = ref(false);\n const error = ref<string | undefined>(undefined);\n const ac = new AbortController();\n\n // Cache key keys on the *rendered* binding config (with template variables\n // substituted) plus dependsOnValues + uiQuery. This means:\n // - `{{data.country}}` in the URL → cache key changes when country changes,\n // auto-refetching without callers having to declare dependsOn.\n // - Unrelated form fields → rendered URL is unchanged → no refetch.\n // The protocol's resolve() still receives the raw config and current data,\n // so per-fetch URL rendering works as before.\n const cacheKey = computed(() => {\n const b = unref(binding);\n const renderedBinding = b\n ? {\n ...b,\n config: renderObj(b.config ?? {}, { data: unref(ctxBits.data) }),\n }\n : b;\n return JSON.stringify({\n b: renderedBinding,\n d: unref(ctxBits.dependsOnValues) ?? [],\n q: unref(ctxBits.uiQuery) ?? \"\",\n });\n });\n\n async function load() {\n const bindingValue = unref(binding);\n if (!bindingValue) return;\n loading.value = true;\n error.value = undefined;\n const hit = cache.get(cacheKey.value) as ProviderOutput | undefined;\n if (hit) {\n items.value = hit.items;\n loading.value = false;\n return;\n }\n try {\n const driver = registry.get(bindingValue.protocol);\n if (!driver) {\n throw new Error(\n `No provider registered for protocol: ${bindingValue.protocol}`,\n );\n }\n const out = await driver.resolve(bindingValue.config ?? {}, {\n data: unref(ctxBits.data),\n path: ctxBits.path,\n ui: { query: unref(ctxBits.uiQuery) },\n signal: ac.signal,\n auth: resolveAuth(bindingValue.auth, auth),\n });\n items.value = out.items;\n cache.set(cacheKey.value, out, bindingValue.cacheTTL ?? out.ttl ?? 0);\n } catch (e) {\n error.value = (e as Error)?.message ?? String(e);\n items.value = [];\n } finally {\n loading.value = false;\n }\n }\n\n onBeforeUnmount(() => ac.abort());\n watch(\n [cacheKey],\n () => {\n const bindingValue = unref(binding);\n if (bindingValue?.load === \"mount\" || bindingValue?.load === \"query\")\n load();\n },\n { immediate: unref(binding)?.load === \"mount\" },\n );\n\n return { items, loading, error, reload: load };\n}\n\nfunction resolveAuth(\n spec: AuthConfig | undefined,\n authBag: Record<string, (() => string) | string>,\n): AuthConfig {\n if (!spec) return {};\n if (spec.use && typeof authBag[spec.use] === \"function\") {\n const authFunc = authBag[spec.use] as () => string;\n return { [spec.use]: authFunc() };\n }\n return spec;\n}\n"],"names":["registry","globalRegistry","cache","globalCache"],"mappings":";;;;AAoBO,SAAS,YACd,SAIA,SASA;AACA,QAAMA,aAAW,OAAO,oBAAoBC,QAAc;AAC1D,QAAMC,UAAQ,OAAO,iBAAiBC,KAAW;AACjD,QAAM,OAAO,OAAO,gBAAgB,EAAE;AAKtC,QAAM,QAAQ,IAAoB,EAAE;AACpC,QAAM,UAAU,IAAI,KAAK;AACzB,QAAM,QAAQ,IAAwB,MAAS;AAC/C,QAAM,KAAK,IAAI,gBAAA;AASf,QAAM,WAAW,SAAS,MAAM;AAC9B,UAAM,IAAI,MAAM,OAAO;AACvB,UAAM,kBAAkB,IACpB;AAAA,MACE,GAAG;AAAA,MACH,QAAQ,UAAU,EAAE,UAAU,CAAA,GAAI,EAAE,MAAM,MAAM,QAAQ,IAAI,EAAA,CAAG;AAAA,IAAA,IAEjE;AACJ,WAAO,KAAK,UAAU;AAAA,MACpB,GAAG;AAAA,MACH,GAAG,MAAM,QAAQ,eAAe,KAAK,CAAA;AAAA,MACrC,GAAG,MAAM,QAAQ,OAAO,KAAK;AAAA,IAAA,CAC9B;AAAA,EACH,CAAC;AAED,iBAAe,OAAO;AACpB,UAAM,eAAe,MAAM,OAAO;AAClC,QAAI,CAAC,aAAc;AACnB,YAAQ,QAAQ;AAChB,UAAM,QAAQ;AACd,UAAM,MAAMD,QAAM,IAAI,SAAS,KAAK;AACpC,QAAI,KAAK;AACP,YAAM,QAAQ,IAAI;AAClB,cAAQ,QAAQ;AAChB;AAAA,IACF;AACA,QAAI;AACF,YAAM,SAASF,WAAS,IAAI,aAAa,QAAQ;AACjD,UAAI,CAAC,QAAQ;AACX,cAAM,IAAI;AAAA,UACR,wCAAwC,aAAa,QAAQ;AAAA,QAAA;AAAA,MAEjE;AACA,YAAM,MAAM,MAAM,OAAO,QAAQ,aAAa,UAAU,IAAI;AAAA,QAC1D,MAAM,MAAM,QAAQ,IAAI;AAAA,QACxB,MAAM,QAAQ;AAAA,QACd,IAAI,EAAE,OAAO,MAAM,QAAQ,OAAO,EAAA;AAAA,QAClC,QAAQ,GAAG;AAAA,QACX,MAAM,YAAY,aAAa,MAAM,IAAI;AAAA,MAAA,CAC1C;AACD,YAAM,QAAQ,IAAI;AAClBE,cAAM,IAAI,SAAS,OAAO,KAAK,aAAa,YAAY,IAAI,OAAO,CAAC;AAAA,IACtE,SAAS,GAAG;AACV,YAAM,QAAS,GAAa,WAAW,OAAO,CAAC;AAC/C,YAAM,QAAQ,CAAA;AAAA,IAChB,UAAA;AACE,cAAQ,QAAQ;AAAA,IAClB;AAAA,EACF;AAEA,kBAAgB,MAAM,GAAG,OAAO;AAChC;AAAA,IACE,CAAC,QAAQ;AAAA,IACT,MAAM;AACJ,YAAM,eAAe,MAAM,OAAO;AAClC,UAAI,cAAc,SAAS,WAAW,cAAc,SAAS;AAC3D,aAAA;AAAA,IACJ;AAAA,IACA,EAAE,WAAW,MAAM,OAAO,GAAG,SAAS,QAAA;AAAA,EAAQ;AAGhD,SAAO,EAAE,OAAO,SAAS,OAAO,QAAQ,KAAA;AAC1C;AAEA,SAAS,YACP,MACA,SACY;AACZ,MAAI,CAAC,KAAM,QAAO,CAAA;AAClB,MAAI,KAAK,OAAO,OAAO,QAAQ,KAAK,GAAG,MAAM,YAAY;AACvD,UAAM,WAAW,QAAQ,KAAK,GAAG;AACjC,WAAO,EAAE,CAAC,KAAK,GAAG,GAAG,WAAS;AAAA,EAChC;AACA,SAAO;AACT;"}
@@ -21,6 +21,8 @@ export { useProjection } from "./composables/useProjection";
21
21
  export type { ProjectionResult } from "./composables/useProjection";
22
22
  export { createDataLayer, useDataLayer } from "./composables/useDataLayer";
23
23
  export type { DataLayer } from "./composables/useDataLayer";
24
+ export { useDeriveInitialValue } from "./composables/useDeriveInitialValue";
25
+ export type { DeriveInitialValueCfg } from "./composables/useDeriveInitialValue";
24
26
  export { useDirtyValidation } from "./composables/useDirtyValidation";
25
27
  export * from "./testers";
26
28
  export { JfText, JfTextArea, JfNumber, JfEnum, JfEnumArray, JfBoolean, } from "./primevue";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/vue/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAUvD,OAAO,oBAAoB,MAAM,uCAAuC,CAAC;AACzE,OAAO,cAAc,MAAM,iCAAiC,CAAC;AAC7D,OAAO,mBAAmB,MAAM,sCAAsC,CAAC;AAqDvE,eAAO,MAAM,iBAAiB;;;;;;;;;;;GAI7B,CAAC;AAGF,OAAO,EAAE,iBAAiB,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;AAG1E,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,mBAAmB,EAAE,CAAC;AACrE,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,YAAY,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC3E,YAAY,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,cAAc,WAAW,CAAC;AAG1B,OAAO,EACL,MAAM,EACN,UAAU,EACV,QAAQ,EACR,MAAM,EACN,WAAW,EACX,SAAS,GACV,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/vue/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAWvD,OAAO,oBAAoB,MAAM,uCAAuC,CAAC;AACzE,OAAO,cAAc,MAAM,iCAAiC,CAAC;AAC7D,OAAO,mBAAmB,MAAM,sCAAsC,CAAC;AAqEvE,eAAO,MAAM,iBAAiB;;;;;;;;;;;GAI7B,CAAC;AAGF,OAAO,EAAE,iBAAiB,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;AAG1E,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,mBAAmB,EAAE,CAAC;AACrE,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,YAAY,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC3E,YAAY,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AAC5E,YAAY,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AACjF,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,cAAc,WAAW,CAAC;AAG1B,OAAO,EACL,MAAM,EACN,UAAU,EACV,QAAQ,EACR,MAAM,EACN,WAAW,EACX,SAAS,GACV,MAAM,YAAY,CAAC"}
package/dist/vue/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { rankWith, and, or, isStringControl, isNumberControl, isControl } from "@jsonforms/core";
1
+ import { rankWith, and, or, isStringControl, isNumberControl, isIntegerControl, isControl } from "@jsonforms/core";
2
2
  import { resolveScopeSchema } from "../core/resolveScope.js";
3
3
  import _sfc_main from "./components/ProviderAutocomplete.vue.js";
4
4
  import ProviderSelect from "./components/ProviderSelect.vue.js";
@@ -7,6 +7,7 @@ import { primevueRenderers, registerPrimevueRenderers } from "./primevue/index.j
7
7
  import { useProvider } from "./composables/useProvider.js";
8
8
  import { useProjection } from "./composables/useProjection.js";
9
9
  import { createDataLayer, useDataLayer } from "./composables/useDataLayer.js";
10
+ import { useDeriveInitialValue } from "./composables/useDeriveInitialValue.js";
10
11
  import { useDirtyValidation } from "./composables/useDirtyValidation.js";
11
12
  import { providerTester } from "./testers.js";
12
13
  import { default as default2 } from "./primevue/JfText.vue.js";
@@ -21,23 +22,37 @@ const hasProvider = (uischema) => {
21
22
  const isIntegerScope = (uischema, schema) => {
22
23
  const ui = uischema;
23
24
  if (ui?.type !== "Control" || !ui?.scope) return false;
24
- const propertySchema = resolveScopeSchema(ui.scope, schema);
25
+ const propertySchema = resolveScopeSchema(
26
+ ui.scope,
27
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
28
+ schema
29
+ );
25
30
  return propertySchema?.type === "integer";
26
31
  };
27
32
  const providerSelectTester = rankWith(
28
- 106,
29
- // Higher than PrimeVue base (100) to ensure providers take precedence
33
+ 107,
34
+ // Higher than PrimeVue JfNumber integer renderer (106) so provider wins
30
35
  and(
31
- or(isStringControl, isNumberControl, and(isControl, isIntegerScope)),
36
+ or(
37
+ isStringControl,
38
+ isNumberControl,
39
+ isIntegerControl,
40
+ and(isControl, isIntegerScope)
41
+ ),
32
42
  hasProvider,
33
43
  (uischema) => !uischema?.options?.autocomplete
34
44
  )
35
45
  );
36
46
  const providerAutocompleteTester = rankWith(
37
- 107,
38
- // Higher than PrimeVue base (100) to ensure providers take precedence
47
+ 108,
48
+ // Higher than providerSelectTester so autocomplete variant wins when flagged
39
49
  and(
40
- or(isStringControl, isNumberControl, and(isControl, isIntegerScope)),
50
+ or(
51
+ isStringControl,
52
+ isNumberControl,
53
+ isIntegerControl,
54
+ and(isControl, isIntegerScope)
55
+ ),
41
56
  hasProvider,
42
57
  (uischema) => uischema?.options?.autocomplete === true
43
58
  )
@@ -47,11 +62,15 @@ const isArrayControl = (uischema, schema) => {
47
62
  if (controlSchema.type !== "Control" || !controlSchema.scope) {
48
63
  return false;
49
64
  }
50
- const propertySchema = resolveScopeSchema(controlSchema.scope, schema);
65
+ const propertySchema = resolveScopeSchema(
66
+ controlSchema.scope,
67
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
68
+ schema
69
+ );
51
70
  return propertySchema?.type === "array";
52
71
  };
53
72
  const providerMultiSelectTester = rankWith(
54
- 108,
73
+ 109,
55
74
  // Highest priority for array controls with providers
56
75
  and(isArrayControl, hasProvider)
57
76
  );
@@ -76,6 +95,7 @@ export {
76
95
  providerTester,
77
96
  registerPrimevueRenderers,
78
97
  useDataLayer,
98
+ useDeriveInitialValue,
79
99
  useDirtyValidation,
80
100
  useProjection,
81
101
  useProvider
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/vue/index.ts"],"sourcesContent":["import type { UISchemaElement } from \"@jsonforms/core\";\nimport {\n and,\n isNumberControl,\n isStringControl,\n or,\n rankWith,\n isControl,\n} from \"@jsonforms/core\";\nimport { resolveScopeSchema } from \"../core/resolveScope\";\nimport ProviderAutocomplete from \"./components/ProviderAutocomplete.vue\";\nimport ProviderSelect from \"./components/ProviderSelect.vue\";\nimport ProviderMultiSelect from \"./components/ProviderMultiSelect.vue\";\n\n// Custom tester that checks if provider option exists (as object or boolean)\nconst hasProvider = (uischema: UISchemaElement) => {\n return uischema?.options?.provider !== undefined;\n};\n\n// Integer fallback tester — handles nested scopes like #/properties/parent/properties/child\nconst isIntegerScope = (uischema: unknown, schema: unknown) => {\n const ui = uischema as { type?: string; scope?: string };\n if (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 return propertySchema?.type === \"integer\";\n};\n\n// Create specific testers for each component type\nconst providerSelectTester = rankWith(\n 106, // Higher than PrimeVue base (100) to ensure providers take precedence\n and(\n or(isStringControl, isNumberControl, and(isControl, isIntegerScope)),\n hasProvider,\n (uischema) => !uischema?.options?.autocomplete,\n ),\n);\n\nconst providerAutocompleteTester = rankWith(\n 107, // Higher than PrimeVue base (100) to ensure providers take precedence\n and(\n or(isStringControl, isNumberControl, and(isControl, isIntegerScope)),\n hasProvider,\n (uischema) => uischema?.options?.autocomplete === true,\n ),\n);\n\n// Custom array tester - supports nested scope paths\nconst isArrayControl = (uischema: UISchemaElement, schema: unknown) => {\n const controlSchema = uischema as { type: string; scope?: string };\n if (controlSchema.type !== \"Control\" || !controlSchema.scope) {\n return false;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const propertySchema = resolveScopeSchema(controlSchema.scope, schema as Record<string, any>);\n return propertySchema?.type === \"array\";\n};\n\nconst providerMultiSelectTester = rankWith(\n 108, // Highest priority for array controls with providers\n and(isArrayControl, hasProvider),\n);\n\nexport const providerRenderers = [\n { tester: providerMultiSelectTester, renderer: ProviderMultiSelect },\n { tester: providerAutocompleteTester, renderer: ProviderAutocomplete },\n { tester: providerSelectTester, renderer: ProviderSelect },\n];\n\n// Export PrimeVue renderers (styles are auto-injected)\nexport { primevueRenderers, registerPrimevueRenderers } from \"./primevue\";\n\n// Export individual components\nexport { ProviderAutocomplete, ProviderSelect, ProviderMultiSelect };\nexport { useProvider } from \"./composables/useProvider\";\nexport { useProjection } from \"./composables/useProjection\";\nexport type { ProjectionResult } from \"./composables/useProjection\";\nexport { createDataLayer, useDataLayer } from \"./composables/useDataLayer\";\nexport type { DataLayer } from \"./composables/useDataLayer\";\nexport { useDirtyValidation } from \"./composables/useDirtyValidation\";\nexport * from \"./testers\";\n\n// Export individual PrimeVue components using lazy evaluation to avoid circular deps\nexport {\n JfText,\n JfTextArea,\n JfNumber,\n JfEnum,\n JfEnumArray,\n JfBoolean,\n} from \"./primevue\";\n"],"names":["ProviderAutocomplete"],"mappings":";;;;;;;;;;;;;;;;;AAeA,MAAM,cAAc,CAAC,aAA8B;AACjD,SAAO,UAAU,SAAS,aAAa;AACzC;AAGA,MAAM,iBAAiB,CAAC,UAAmB,WAAoB;AAC7D,QAAM,KAAK;AACX,MAAI,IAAI,SAAS,aAAa,CAAC,IAAI,MAAO,QAAO;AAGjD,QAAM,iBAAiB,mBAAmB,GAAG,OAAO,MAA6B;AACjF,SAAO,gBAAgB,SAAS;AAClC;AAGA,MAAM,uBAAuB;AAAA,EAC3B;AAAA;AAAA,EACA;AAAA,IACE,GAAG,iBAAiB,iBAAiB,IAAI,WAAW,cAAc,CAAC;AAAA,IACnE;AAAA,IACA,CAAC,aAAa,CAAC,UAAU,SAAS;AAAA,EAAA;AAEtC;AAEA,MAAM,6BAA6B;AAAA,EACjC;AAAA;AAAA,EACA;AAAA,IACE,GAAG,iBAAiB,iBAAiB,IAAI,WAAW,cAAc,CAAC;AAAA,IACnE;AAAA,IACA,CAAC,aAAa,UAAU,SAAS,iBAAiB;AAAA,EAAA;AAEtD;AAGA,MAAM,iBAAiB,CAAC,UAA2B,WAAoB;AACrE,QAAM,gBAAgB;AACtB,MAAI,cAAc,SAAS,aAAa,CAAC,cAAc,OAAO;AAC5D,WAAO;AAAA,EACT;AAGA,QAAM,iBAAiB,mBAAmB,cAAc,OAAO,MAA6B;AAC5F,SAAO,gBAAgB,SAAS;AAClC;AAEA,MAAM,4BAA4B;AAAA,EAChC;AAAA;AAAA,EACA,IAAI,gBAAgB,WAAW;AACjC;AAEO,MAAM,oBAAoB;AAAA,EAC/B,EAAE,QAAQ,2BAA2B,UAAU,oBAAA;AAAA,EAC/C,EAAE,QAAQ,4BAA4B,UAAUA,UAAA;AAAA,EAChD,EAAE,QAAQ,sBAAsB,UAAU,eAAA;AAC5C;"}
1
+ {"version":3,"file":"index.js","sources":["../../src/vue/index.ts"],"sourcesContent":["import type { UISchemaElement } from \"@jsonforms/core\";\nimport {\n and,\n isIntegerControl,\n isNumberControl,\n isStringControl,\n or,\n rankWith,\n isControl,\n} from \"@jsonforms/core\";\nimport { resolveScopeSchema } from \"../core/resolveScope\";\nimport ProviderAutocomplete from \"./components/ProviderAutocomplete.vue\";\nimport ProviderSelect from \"./components/ProviderSelect.vue\";\nimport ProviderMultiSelect from \"./components/ProviderMultiSelect.vue\";\n\n// Custom tester that checks if provider option exists (as object or boolean)\nconst hasProvider = (uischema: UISchemaElement) => {\n return uischema?.options?.provider !== undefined;\n};\n\n// Integer fallback tester — handles nested scopes like #/properties/parent/properties/child\nconst isIntegerScope = (uischema: unknown, schema: unknown) => {\n const ui = uischema as { type?: string; scope?: string };\n if (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 return propertySchema?.type === \"integer\";\n};\n\n// Create specific testers for each component type\nconst providerSelectTester = rankWith(\n 107, // Higher than PrimeVue JfNumber integer renderer (106) so provider wins\n and(\n or(\n isStringControl,\n isNumberControl,\n isIntegerControl,\n and(isControl, isIntegerScope),\n ),\n hasProvider,\n (uischema) => !uischema?.options?.autocomplete,\n ),\n);\n\nconst providerAutocompleteTester = rankWith(\n 108, // Higher than providerSelectTester so autocomplete variant wins when flagged\n and(\n or(\n isStringControl,\n isNumberControl,\n isIntegerControl,\n and(isControl, isIntegerScope),\n ),\n hasProvider,\n (uischema) => uischema?.options?.autocomplete === true,\n ),\n);\n\n// Custom array tester - supports nested scope paths\nconst isArrayControl = (uischema: UISchemaElement, schema: unknown) => {\n const controlSchema = uischema as { type: string; scope?: string };\n if (controlSchema.type !== \"Control\" || !controlSchema.scope) {\n return false;\n }\n\n const propertySchema = resolveScopeSchema(\n controlSchema.scope,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n schema as Record<string, any>,\n );\n return propertySchema?.type === \"array\";\n};\n\nconst providerMultiSelectTester = rankWith(\n 109, // Highest priority for array controls with providers\n and(isArrayControl, hasProvider),\n);\n\nexport const providerRenderers = [\n { tester: providerMultiSelectTester, renderer: ProviderMultiSelect },\n { tester: providerAutocompleteTester, renderer: ProviderAutocomplete },\n { tester: providerSelectTester, renderer: ProviderSelect },\n];\n\n// Export PrimeVue renderers (styles are auto-injected)\nexport { primevueRenderers, registerPrimevueRenderers } from \"./primevue\";\n\n// Export individual components\nexport { ProviderAutocomplete, ProviderSelect, ProviderMultiSelect };\nexport { useProvider } from \"./composables/useProvider\";\nexport { useProjection } from \"./composables/useProjection\";\nexport type { ProjectionResult } from \"./composables/useProjection\";\nexport { createDataLayer, useDataLayer } from \"./composables/useDataLayer\";\nexport type { DataLayer } from \"./composables/useDataLayer\";\nexport { useDeriveInitialValue } from \"./composables/useDeriveInitialValue\";\nexport type { DeriveInitialValueCfg } from \"./composables/useDeriveInitialValue\";\nexport { useDirtyValidation } from \"./composables/useDirtyValidation\";\nexport * from \"./testers\";\n\n// Export individual PrimeVue components using lazy evaluation to avoid circular deps\nexport {\n JfText,\n JfTextArea,\n JfNumber,\n JfEnum,\n JfEnumArray,\n JfBoolean,\n} from \"./primevue\";\n"],"names":["ProviderAutocomplete"],"mappings":";;;;;;;;;;;;;;;;;;AAgBA,MAAM,cAAc,CAAC,aAA8B;AACjD,SAAO,UAAU,SAAS,aAAa;AACzC;AAGA,MAAM,iBAAiB,CAAC,UAAmB,WAAoB;AAC7D,QAAM,KAAK;AACX,MAAI,IAAI,SAAS,aAAa,CAAC,IAAI,MAAO,QAAO;AAEjD,QAAM,iBAAiB;AAAA,IACrB,GAAG;AAAA;AAAA,IAEH;AAAA,EAAA;AAEF,SAAO,gBAAgB,SAAS;AAClC;AAGA,MAAM,uBAAuB;AAAA,EAC3B;AAAA;AAAA,EACA;AAAA,IACE;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA,IAAI,WAAW,cAAc;AAAA,IAAA;AAAA,IAE/B;AAAA,IACA,CAAC,aAAa,CAAC,UAAU,SAAS;AAAA,EAAA;AAEtC;AAEA,MAAM,6BAA6B;AAAA,EACjC;AAAA;AAAA,EACA;AAAA,IACE;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA,IAAI,WAAW,cAAc;AAAA,IAAA;AAAA,IAE/B;AAAA,IACA,CAAC,aAAa,UAAU,SAAS,iBAAiB;AAAA,EAAA;AAEtD;AAGA,MAAM,iBAAiB,CAAC,UAA2B,WAAoB;AACrE,QAAM,gBAAgB;AACtB,MAAI,cAAc,SAAS,aAAa,CAAC,cAAc,OAAO;AAC5D,WAAO;AAAA,EACT;AAEA,QAAM,iBAAiB;AAAA,IACrB,cAAc;AAAA;AAAA,IAEd;AAAA,EAAA;AAEF,SAAO,gBAAgB,SAAS;AAClC;AAEA,MAAM,4BAA4B;AAAA,EAChC;AAAA;AAAA,EACA,IAAI,gBAAgB,WAAW;AACjC;AAEO,MAAM,oBAAoB;AAAA,EAC/B,EAAE,QAAQ,2BAA2B,UAAU,oBAAA;AAAA,EAC/C,EAAE,QAAQ,4BAA4B,UAAUA,UAAA;AAAA,EAChD,EAAE,QAAQ,sBAAsB,UAAU,eAAA;AAC5C;"}
@@ -1 +1 @@
1
- {"version":3,"file":"JfBoolean.vue.d.ts","sourceRoot":"","sources":["../../../src/vue/primevue/JfBoolean.vue"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsFA,wBA4KK"}
1
+ {"version":3,"file":"JfBoolean.vue.d.ts","sourceRoot":"","sources":["../../../src/vue/primevue/JfBoolean.vue"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2FA,wBAoLK"}
@@ -3,8 +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 Checkbox from "primevue/checkbox";
6
- const _hoisted_1 = { class: "flex items-center gap-2" };
7
- const _hoisted_2 = { key: 0 };
6
+ const _hoisted_1 = {
7
+ class: "jf-control",
8
+ style: { "flex-direction": "row", "align-items": "center" }
9
+ };
10
+ const _hoisted_2 = {
11
+ key: 0,
12
+ class: "jf-label"
13
+ };
8
14
  const _hoisted_3 = {
9
15
  key: 1,
10
16
  class: "p-error"
@@ -51,8 +57,13 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
51
57
  const instance = getCurrentInstance();
52
58
  const props = instance.props;
53
59
  const { control, handleChange: rawHandleChange } = useJsonFormsControl(props);
54
- const { projectedData, handleProjectedChange: handleChange } = useProjection(control, rawHandleChange);
55
- const { showErrors, markDirty } = useDirtyValidation(control);
60
+ const {
61
+ projectedData,
62
+ handleProjectedChange: handleChange,
63
+ projectedErrors,
64
+ projectedLabel
65
+ } = useProjection(control, rawHandleChange);
66
+ const { showErrors, markDirty } = useDirtyValidation(control, projectedErrors);
56
67
  const onToggle = (val) => {
57
68
  markDirty();
58
69
  handleChange(control.value.path, val);
@@ -67,8 +78,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
67
78
  "aria-invalid": unref(showErrors) || void 0,
68
79
  "onUpdate:modelValue": onToggle
69
80
  }, null, 8, ["model-value", "disabled", "class", "aria-invalid"]),
70
- unref(control).label ? (openBlock(), createElementBlock("label", _hoisted_2, toDisplayString(unref(control).label), 1)) : createCommentVNode("", true),
71
- unref(showErrors) ? (openBlock(), createElementBlock("small", _hoisted_3, toDisplayString(unref(control).errors), 1)) : createCommentVNode("", true)
81
+ unref(projectedLabel) ? (openBlock(), createElementBlock("label", _hoisted_2, toDisplayString(unref(projectedLabel)), 1)) : createCommentVNode("", true),
82
+ unref(showErrors) ? (openBlock(), createElementBlock("small", _hoisted_3, toDisplayString(unref(projectedErrors)), 1)) : createCommentVNode("", true)
72
83
  ]);
73
84
  };
74
85
  }
@@ -1 +1 @@
1
- {"version":3,"file":"JfBoolean.vue.js","sources":["../../../src/vue/primevue/JfBoolean.vue"],"sourcesContent":["<script lang=\"ts\">\nexport default {\n name: \"JfBoolean\",\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 { getCurrentInstance } from \"vue\";\nimport { useProjection } from \"../composables/useProjection\";\nimport { useDirtyValidation } from \"../composables/useDirtyValidation\";\nimport Checkbox from \"primevue/checkbox\";\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 } = useProjection(control, rawHandleChange);\n\n// Track user interaction — errors only show after first toggle\nconst { showErrors, markDirty } = useDirtyValidation(control);\n\nconst onToggle = (val: boolean) => {\n markDirty();\n handleChange(control.value.path, val);\n};\n</script>\n\n<template>\n <div class=\"flex items-center gap-2\">\n <Checkbox\n :binary=\"true\"\n :model-value=\"!!projectedData\"\n :disabled=\"!control.enabled\"\n :class=\"{ 'p-invalid': showErrors }\"\n :aria-invalid=\"showErrors || undefined\"\n @update:model-value=\"onToggle\"\n />\n <label v-if=\"control.label\">{{ control.label }}</label>\n <small v-if=\"showErrors\" class=\"p-error\">{{ control.errors }}</small>\n </div>\n</template>\n"],"names":["_openBlock","_createElementBlock","_createVNode","_unref","_toDisplayString"],"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,iBAAiB,cAAc,SAAS,eAAe;AAGrG,UAAM,EAAE,YAAY,cAAc,mBAAmB,OAAO;AAE5D,UAAM,WAAW,CAAC,QAAiB;AACjC,gBAAA;AACA,mBAAa,QAAQ,MAAM,MAAM,GAAG;AAAA,IACtC;;AAIE,aAAAA,UAAA,GAAAC,mBAWM,OAXN,YAWM;AAAA,QAVJC,YAOEC,MAAA,QAAA,GAAA;AAAA,UANC,QAAQ;AAAA,UACR,iBAAeA,MAAA,aAAA;AAAA,UACf,UAAQ,CAAGA,MAAA,OAAA,EAAQ;AAAA,UACnB,qCAAsBA,MAAA,UAAA,GAAU;AAAA,UAChC,gBAAcA,MAAA,UAAA,KAAc;AAAA,UAC5B,uBAAoB;AAAA,QAAA;QAEVA,MAAA,OAAA,EAAQ,sBAArBF,mBAAuD,SAAA,YAAAG,gBAAxBD,MAAA,OAAA,EAAQ,KAAK,GAAA,CAAA;QAC/BA,MAAA,UAAA,KAAbH,aAAAC,mBAAqE,SAArE,YAAqEG,gBAAzBD,MAAA,OAAA,EAAQ,MAAM,GAAA,CAAA;;;;;"}
1
+ {"version":3,"file":"JfBoolean.vue.js","sources":["../../../src/vue/primevue/JfBoolean.vue"],"sourcesContent":["<script lang=\"ts\">\nexport default {\n name: \"JfBoolean\",\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 { getCurrentInstance } from \"vue\";\nimport { useProjection } from \"../composables/useProjection\";\nimport { useDirtyValidation } from \"../composables/useDirtyValidation\";\nimport Checkbox from \"primevue/checkbox\";\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// Track user interaction — errors only show after first toggle\nconst { showErrors, markDirty } = useDirtyValidation(control, projectedErrors);\n\nconst onToggle = (val: boolean) => {\n markDirty();\n handleChange(control.value.path, val);\n};\n</script>\n\n<template>\n <div class=\"jf-control\" style=\"flex-direction: row; align-items: center\">\n <Checkbox\n :binary=\"true\"\n :model-value=\"!!projectedData\"\n :disabled=\"!control.enabled\"\n :class=\"{ 'p-invalid': showErrors }\"\n :aria-invalid=\"showErrors || undefined\"\n @update:model-value=\"onToggle\"\n />\n <label v-if=\"projectedLabel\" class=\"jf-label\">{{ projectedLabel }}</label>\n <small v-if=\"showErrors\" class=\"p-error\">{{ projectedErrors }}</small>\n </div>\n</template>\n"],"names":["_openBlock","_createElementBlock","_createVNode","_unref","_toDisplayString"],"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;AAG1C,UAAM,EAAE,YAAY,UAAA,IAAc,mBAAmB,SAAS,eAAe;AAE7E,UAAM,WAAW,CAAC,QAAiB;AACjC,gBAAA;AACA,mBAAa,QAAQ,MAAM,MAAM,GAAG;AAAA,IACtC;;AAIE,aAAAA,UAAA,GAAAC,mBAWM,OAXN,YAWM;AAAA,QAVJC,YAOEC,MAAA,QAAA,GAAA;AAAA,UANC,QAAQ;AAAA,UACR,iBAAeA,MAAA,aAAA;AAAA,UACf,UAAQ,CAAGA,MAAA,OAAA,EAAQ;AAAA,UACnB,qCAAsBA,MAAA,UAAA,GAAU;AAAA,UAChC,gBAAcA,MAAA,UAAA,KAAc;AAAA,UAC5B,uBAAoB;AAAA,QAAA;QAEVA,MAAA,cAAA,kBAAbF,mBAA0E,SAA1E,YAA0EG,gBAAzBD,MAAA,cAAA,CAAc,GAAA,CAAA;QAClDA,MAAA,UAAA,kBAAbF,mBAAsE,SAAtE,YAAsEG,gBAA1BD,MAAA,eAAA,CAAe,GAAA,CAAA;;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"JfEnum.vue.d.ts","sourceRoot":"","sources":["../../../src/vue/primevue/JfEnum.vue"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqNA,wBAoUK"}
1
+ {"version":3,"file":"JfEnum.vue.d.ts","sourceRoot":"","sources":["../../../src/vue/primevue/JfEnum.vue"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgOA,wBAyUK"}
@@ -2,18 +2,20 @@ import { defineComponent, getCurrentInstance, computed, inject, watch, createEle
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 { shouldAutoSelect } from "../utils/autoSelect.js";
9
+ import { resolvePlaceholder } from "../utils/placeholder.js";
8
10
  import Dropdown from "primevue/dropdown";
9
- const _hoisted_1 = { class: "flex flex-column gap-2" };
11
+ const _hoisted_1 = { class: "jf-control" };
10
12
  const _hoisted_2 = {
11
13
  key: 0,
12
- class: "text-color text-left"
14
+ class: "jf-label"
13
15
  };
14
16
  const _hoisted_3 = {
15
17
  key: 1,
16
- class: "text-color-secondary text-left"
18
+ class: "jf-description"
17
19
  };
18
20
  const _hoisted_4 = {
19
21
  key: 2,
@@ -66,7 +68,12 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
66
68
  const instance = getCurrentInstance();
67
69
  const props = instance.props;
68
70
  const { control, handleChange: rawHandleChange } = useJsonFormsControl(props);
69
- const { projectedData, handleProjectedChange: handleChange } = useProjection(control, rawHandleChange);
71
+ const {
72
+ projectedData,
73
+ handleProjectedChange: handleChange,
74
+ projectedErrors,
75
+ projectedLabel
76
+ } = useProjection(control, rawHandleChange);
70
77
  const toOptions = (schema) => {
71
78
  if (!schema) return [];
72
79
  const s = schema;
@@ -113,11 +120,15 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
113
120
  } = useProvider(binding, {
114
121
  data: rootData,
115
122
  path: control.value.path,
116
- dependsOnValues: depValues.value
123
+ dependsOnValues: depValues
117
124
  });
118
125
  const placeholder = computed(() => {
119
126
  if (loading.value) return "Loading…";
120
- return control.value.uischema?.options?.placeholder ?? control.value.description;
127
+ return resolvePlaceholder(
128
+ control.value.uischema,
129
+ projectedLabel.value,
130
+ "select"
131
+ );
121
132
  });
122
133
  const options = computed(() => {
123
134
  if (binding.value && providerItems.value.length > 0) {
@@ -126,6 +137,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
126
137
  return toOptions(control.value.schema);
127
138
  });
128
139
  useDerive({ control, handleChange, data: projectedData });
140
+ useDeriveInitialValue({ control, handleChange });
129
141
  watch(
130
142
  [providerItems, loading],
131
143
  ([items, isLoading]) => {
@@ -141,16 +153,16 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
141
153
  },
142
154
  { immediate: true }
143
155
  );
144
- const { showErrors, markDirty } = useDirtyValidation(control);
156
+ const { showErrors, markDirty } = useDirtyValidation(control, projectedErrors);
145
157
  const onSelect = (val) => {
146
158
  handleChange(control.value.path, val);
147
159
  };
148
160
  return (_ctx, _cache) => {
149
161
  return openBlock(), createElementBlock("div", _hoisted_1, [
150
- unref(control).label ? (openBlock(), createElementBlock("label", _hoisted_2, toDisplayString(unref(control).label), 1)) : createCommentVNode("", true),
162
+ unref(projectedLabel) ? (openBlock(), createElementBlock("label", _hoisted_2, toDisplayString(unref(projectedLabel)), 1)) : createCommentVNode("", true),
151
163
  unref(control).description ? (openBlock(), createElementBlock("div", _hoisted_3, toDisplayString(unref(control).description), 1)) : createCommentVNode("", true),
152
164
  createVNode(unref(Dropdown), {
153
- class: normalizeClass(["w-full", { "p-invalid": unref(showErrors) }]),
165
+ class: normalizeClass(["w-full!", { "p-invalid": unref(showErrors) }]),
154
166
  options: options.value,
155
167
  "option-label": "label",
156
168
  "option-value": "value",
@@ -162,7 +174,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
162
174
  "onUpdate:modelValue": onSelect,
163
175
  onBlur: unref(markDirty)
164
176
  }, null, 8, ["class", "options", "model-value", "placeholder", "disabled", "aria-invalid", "onBlur"]),
165
- unref(error) ? (openBlock(), createElementBlock("small", _hoisted_4, "Failed to load: " + toDisplayString(unref(error)), 1)) : unref(showErrors) ? (openBlock(), createElementBlock("small", _hoisted_5, toDisplayString(unref(control).errors), 1)) : createCommentVNode("", true)
177
+ unref(error) ? (openBlock(), createElementBlock("small", _hoisted_4, "Failed to load: " + toDisplayString(unref(error)), 1)) : unref(showErrors) ? (openBlock(), createElementBlock("small", _hoisted_5, toDisplayString(unref(projectedErrors)), 1)) : createCommentVNode("", true)
166
178
  ]);
167
179
  };
168
180
  }
@@ -1 +1 @@
1
- {"version":3,"file":"JfEnum.vue.js","sources":["../../../src/vue/primevue/JfEnum.vue"],"sourcesContent":["<script lang=\"ts\">\n// Define props manually to avoid any potential circular dependency issues\nexport default {\n name: \"JfEnum\",\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 { JsonSchema } from \"@jsonforms/core\";\nimport type { ControlProps } from \"@jsonforms/vue\";\nimport { useJsonFormsControl } from \"@jsonforms/vue\";\nimport { computed, inject, getCurrentInstance, watch } from \"vue\";\nimport { useProvider } from \"../composables/useProvider\";\nimport { useDerive } from \"../composables/useDerive\";\nimport { useProjection } from \"../composables/useProjection\";\nimport { useDirtyValidation } from \"../composables/useDirtyValidation\";\nimport { shouldAutoSelect } from \"../utils/autoSelect\";\nimport Dropdown from \"primevue/dropdown\";\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 } = useProjection(control, rawHandleChange);\n\ntype Opt = { label: string; value: unknown };\nconst toOptions = (schema?: JsonSchema): Opt[] => {\n if (!schema) return [];\n const s = schema as {\n enum?: unknown[];\n oneOf?: Array<{ title?: string; const: unknown }>;\n };\n if (Array.isArray(s.enum))\n return s.enum.map((v: unknown) => ({ label: String(v), value: v }));\n if (Array.isArray(s.oneOf))\n return s.oneOf.map((o) => ({\n label: o.title ?? String(o.const),\n value: o.const,\n }));\n return [];\n};\n\n// Provider support\nconst binding = computed(() => {\n const provider = control.value.uischema?.options?.provider;\n // Ensure load property is set to 'mount' by default\n if (provider && typeof provider === \"object\" && !provider.load) {\n return { ...provider, load: \"mount\" };\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\n// Use provider if available, otherwise fall back to schema enum/oneOf\nconst {\n items: providerItems,\n loading,\n error,\n} = useProvider(binding, {\n data: rootData,\n path: control.value.path,\n dependsOnValues: depValues.value,\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 options = computed(() => {\n // Use provider items if available, otherwise fall back to schema enum/oneOf\n if (binding.value && providerItems.value.length > 0) {\n return providerItems.value;\n }\n return toOptions(control.value.schema);\n});\n\n// Add derive functionality\nuseDerive({ control, handleChange, data: projectedData });\n\n// Auto-select when provider returns only one item (enabled by default)\nwatch(\n [providerItems, loading],\n ([items, isLoading]) => {\n const valueToSelect = shouldAutoSelect({\n autoSelectSingle:\n control.value.uischema?.options?.autoSelectSingle !== false,\n isLoading,\n items,\n currentValue: projectedData.value,\n });\n\n if (valueToSelect !== null) {\n handleChange(control.value.path, valueToSelect);\n }\n },\n { immediate: true }\n);\n\n// Track user interaction — errors only show after blur\nconst { showErrors, markDirty } = useDirtyValidation(control);\n\nconst onSelect = (val: unknown) => {\n handleChange(control.value.path, val);\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 <Dropdown\n :class=\"['w-full', { 'p-invalid': showErrors }]\"\n :options=\"options\"\n option-label=\"label\"\n option-value=\"value\"\n :model-value=\"projectedData ?? null\"\n :placeholder=\"placeholder\"\n :disabled=\"!control.enabled || loading\"\n :aria-invalid=\"showErrors || undefined\"\n :show-clear=\"true\"\n @update:model-value=\"onSelect\"\n @blur=\"markDirty\"\n />\n <small v-if=\"error\" class=\"p-error\" role=\"alert\"\n >Failed to load: {{ error }}</small\n >\n <small v-else-if=\"showErrors\" class=\"p-error\">{{ control.errors }}</small>\n </div>\n</template>\n"],"names":["_openBlock","_createElementBlock","_unref","_toDisplayString","_createVNode"],"mappings":"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"}
1
+ {"version":3,"file":"JfEnum.vue.js","sources":["../../../src/vue/primevue/JfEnum.vue"],"sourcesContent":["<script lang=\"ts\">\n// Define props manually to avoid any potential circular dependency issues\nexport default {\n name: \"JfEnum\",\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 { JsonSchema } from \"@jsonforms/core\";\nimport type { ControlProps } from \"@jsonforms/vue\";\nimport { useJsonFormsControl } from \"@jsonforms/vue\";\nimport { computed, inject, getCurrentInstance, watch } 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 { shouldAutoSelect } from \"../utils/autoSelect\";\nimport { resolvePlaceholder } from \"../utils/placeholder\";\nimport Dropdown from \"primevue/dropdown\";\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\ntype Opt = { label: string; value: unknown };\nconst toOptions = (schema?: JsonSchema): Opt[] => {\n if (!schema) return [];\n const s = schema as {\n enum?: unknown[];\n oneOf?: Array<{ title?: string; const: unknown }>;\n };\n if (Array.isArray(s.enum))\n return s.enum.map((v: unknown) => ({ label: String(v), value: v }));\n if (Array.isArray(s.oneOf))\n return s.oneOf.map((o) => ({\n label: o.title ?? String(o.const),\n value: o.const,\n }));\n return [];\n};\n\n// Provider support\nconst binding = computed(() => {\n const provider = control.value.uischema?.options?.provider;\n // Ensure load property is set to 'mount' by default\n if (provider && typeof provider === \"object\" && !provider.load) {\n return { ...provider, load: \"mount\" };\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\n// Use provider if available, otherwise fall back to schema enum/oneOf\nconst {\n items: providerItems,\n loading,\n error,\n} = useProvider(binding, {\n data: rootData,\n path: control.value.path,\n dependsOnValues: depValues,\n});\n\nconst placeholder = computed<string | undefined>(() => {\n if (loading.value) return \"Loading…\";\n return resolvePlaceholder(\n control.value.uischema,\n projectedLabel.value,\n \"select\",\n );\n});\n\nconst options = computed(() => {\n // Use provider items if available, otherwise fall back to schema enum/oneOf\n if (binding.value && providerItems.value.length > 0) {\n return providerItems.value;\n }\n return toOptions(control.value.schema);\n});\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// Auto-select when provider returns only one item (enabled by default)\nwatch(\n [providerItems, loading],\n ([items, isLoading]) => {\n const valueToSelect = shouldAutoSelect({\n autoSelectSingle:\n control.value.uischema?.options?.autoSelectSingle !== false,\n isLoading,\n items,\n currentValue: projectedData.value,\n });\n\n if (valueToSelect !== null) {\n handleChange(control.value.path, valueToSelect);\n }\n },\n { immediate: true },\n);\n\n// Track user interaction — errors only show after blur\nconst { showErrors, markDirty } = useDirtyValidation(control, projectedErrors);\n\nconst onSelect = (val: unknown) => {\n handleChange(control.value.path, val);\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 <Dropdown\n :class=\"['w-full!', { 'p-invalid': showErrors }]\"\n :options=\"options\"\n option-label=\"label\"\n option-value=\"value\"\n :model-value=\"projectedData ?? null\"\n :placeholder=\"placeholder\"\n :disabled=\"!control.enabled || loading\"\n :aria-invalid=\"showErrors || undefined\"\n :show-clear=\"true\"\n @update:model-value=\"onSelect\"\n @blur=\"markDirty\"\n />\n <small v-if=\"error\" class=\"p-error\" role=\"alert\"\n >Failed to load: {{ error }}</small\n >\n <small v-else-if=\"showErrors\" class=\"p-error\">{{ projectedErrors }}</small>\n </div>\n</template>\n"],"names":["_openBlock","_createElementBlock","_unref","_toDisplayString","_createVNode"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"JfEnumArray.vue.d.ts","sourceRoot":"","sources":["../../../src/vue/primevue/JfEnumArray.vue"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2OA,wBA8UK"}
1
+ {"version":3,"file":"JfEnumArray.vue.d.ts","sourceRoot":"","sources":["../../../src/vue/primevue/JfEnumArray.vue"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiPA,wBAgVK"}
@@ -5,15 +5,16 @@ import { useDerive } from "../composables/useDerive.js";
5
5
  import { useProjection } from "../composables/useProjection.js";
6
6
  import { useDirtyValidation } from "../composables/useDirtyValidation.js";
7
7
  import { shouldAutoSelectMulti } from "../utils/autoSelect.js";
8
+ import { resolvePlaceholder } from "../utils/placeholder.js";
8
9
  import MultiSelect from "primevue/multiselect";
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: 2,
@@ -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 } = useProjection(control, rawHandleChange);
70
+ const {
71
+ projectedData,
72
+ handleProjectedChange: handleChange,
73
+ projectedErrors,
74
+ projectedLabel
75
+ } = useProjection(control, rawHandleChange);
70
76
  const toOptions = (schema) => {
71
77
  if (!schema) return [];
72
78
  const s = schema;
@@ -113,7 +119,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
113
119
  } = useProvider(binding, {
114
120
  data: rootData,
115
121
  path: control.value.path,
116
- dependsOnValues: depValues.value
122
+ dependsOnValues: depValues
117
123
  });
118
124
  const options = computed(() => {
119
125
  if (binding.value && providerItems.value.length > 0) {
@@ -122,7 +128,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
122
128
  return toOptions(control.value.schema?.items);
123
129
  });
124
130
  useDerive({ control, handleChange, data: projectedData });
125
- const { showErrors, markDirty } = useDirtyValidation(control);
131
+ const { showErrors, markDirty } = useDirtyValidation(control, projectedErrors);
126
132
  watch(
127
133
  [providerItems, loading],
128
134
  ([items, isLoading]) => {
@@ -140,7 +146,11 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
140
146
  );
141
147
  const placeholder = computed(() => {
142
148
  if (loading.value) return "Loading…";
143
- return control.value.uischema?.options?.placeholder ?? control.value.description;
149
+ return resolvePlaceholder(
150
+ control.value.uischema,
151
+ projectedLabel.value,
152
+ "select"
153
+ );
144
154
  });
145
155
  const sameSet = (a, b) => {
146
156
  if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length)
@@ -164,12 +174,12 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
164
174
  });
165
175
  return (_ctx, _cache) => {
166
176
  return openBlock(), createElementBlock("div", _hoisted_1, [
167
- unref(control).label ? (openBlock(), createElementBlock("label", _hoisted_2, toDisplayString(unref(control).label), 1)) : createCommentVNode("", true),
177
+ unref(projectedLabel) ? (openBlock(), createElementBlock("label", _hoisted_2, toDisplayString(unref(projectedLabel)), 1)) : createCommentVNode("", true),
168
178
  unref(control).description ? (openBlock(), createElementBlock("div", _hoisted_3, toDisplayString(unref(control).description), 1)) : createCommentVNode("", true),
169
179
  createVNode(unref(MultiSelect), {
170
180
  modelValue: model.value,
171
181
  "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => model.value = $event),
172
- class: normalizeClass(["w-full", { "p-invalid": unref(showErrors) }]),
182
+ class: normalizeClass(["w-full!", { "p-invalid": unref(showErrors) }]),
173
183
  options: options.value,
174
184
  "option-label": "label",
175
185
  "option-value": "value",
@@ -179,7 +189,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
179
189
  "aria-invalid": unref(showErrors) || void 0,
180
190
  placeholder: placeholder.value
181
191
  }, null, 8, ["modelValue", "class", "options", "disabled", "aria-invalid", "placeholder"]),
182
- unref(error) ? (openBlock(), createElementBlock("small", _hoisted_4, "Failed to load: " + toDisplayString(unref(error)), 1)) : unref(showErrors) ? (openBlock(), createElementBlock("small", _hoisted_5, toDisplayString(unref(control).errors), 1)) : createCommentVNode("", true)
192
+ unref(error) ? (openBlock(), createElementBlock("small", _hoisted_4, "Failed to load: " + toDisplayString(unref(error)), 1)) : unref(showErrors) ? (openBlock(), createElementBlock("small", _hoisted_5, toDisplayString(unref(projectedErrors)), 1)) : createCommentVNode("", true)
183
193
  ]);
184
194
  };
185
195
  }