@narrative.io/jsonforms-provider-protocols 3.0.0-beta.13 → 3.0.0-beta.16
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.
- package/dist/core/initFormData.js +12 -8
- package/dist/core/initFormData.js.map +1 -1
- package/dist/jsonforms-provider-protocols.css +2 -2
- package/dist/vue/components/ProviderAutocomplete.vue.d.ts.map +1 -1
- package/dist/vue/components/ProviderAutocomplete.vue.js +6 -5
- package/dist/vue/components/ProviderAutocomplete.vue.js.map +1 -1
- package/dist/vue/components/ProviderMultiSelect.vue.d.ts.map +1 -1
- package/dist/vue/components/ProviderMultiSelect.vue.js +1 -1
- package/dist/vue/components/ProviderMultiSelect.vue2.js +12 -7
- package/dist/vue/components/ProviderMultiSelect.vue2.js.map +1 -1
- package/dist/vue/components/ProviderSelect.vue.d.ts.map +1 -1
- package/dist/vue/components/ProviderSelect.vue.js +1 -1
- package/dist/vue/components/ProviderSelect.vue2.js +12 -7
- package/dist/vue/components/ProviderSelect.vue2.js.map +1 -1
- package/dist/vue/primevue/JfEnum.vue.d.ts.map +1 -1
- package/dist/vue/primevue/JfEnum.vue.js +6 -1
- package/dist/vue/primevue/JfEnum.vue.js.map +1 -1
- package/dist/vue/primevue/JfEnumArray.vue.d.ts.map +1 -1
- package/dist/vue/primevue/JfEnumArray.vue.js +6 -1
- package/dist/vue/primevue/JfEnumArray.vue.js.map +1 -1
- package/dist/vue/primevue/JfNumber.vue.d.ts.map +1 -1
- package/dist/vue/primevue/JfNumber.vue.js +2 -1
- package/dist/vue/primevue/JfNumber.vue.js.map +1 -1
- package/dist/vue/primevue/JfText.vue.d.ts.map +1 -1
- package/dist/vue/primevue/JfText.vue.js +10 -2
- package/dist/vue/primevue/JfText.vue.js.map +1 -1
- package/dist/vue/primevue/JfTextArea.vue.d.ts.map +1 -1
- package/dist/vue/primevue/JfTextArea.vue.js +2 -1
- package/dist/vue/primevue/JfTextArea.vue.js.map +1 -1
- package/dist/vue/utils/placeholder.d.ts +17 -0
- package/dist/vue/utils/placeholder.d.ts.map +1 -0
- package/dist/vue/utils/placeholder.js +17 -0
- package/dist/vue/utils/placeholder.js.map +1 -0
- package/package.json +1 -1
- package/src/core/initFormData.ts +32 -14
- package/src/vue/components/ProviderAutocomplete.vue +6 -7
- package/src/vue/components/ProviderMultiSelect.vue +12 -12
- package/src/vue/components/ProviderSelect.vue +12 -12
- package/src/vue/primevue/JfEnum.vue +5 -3
- package/src/vue/primevue/JfEnumArray.vue +5 -3
- package/src/vue/primevue/JfNumber.vue +3 -2
- package/src/vue/primevue/JfText.vue +13 -5
- package/src/vue/primevue/JfTextArea.vue +3 -4
- package/src/vue/utils/placeholder.ts +42 -0
|
@@ -45,7 +45,8 @@ function initProperty(property, root, seed, required) {
|
|
|
45
45
|
}
|
|
46
46
|
const resolved = resolveRef(property, root);
|
|
47
47
|
const type = resolved.type;
|
|
48
|
-
|
|
48
|
+
const isOneOf = Array.isArray(resolved.oneOf);
|
|
49
|
+
if (seed !== void 0 && seed !== null && type !== "object" && !isOneOf) {
|
|
49
50
|
return seed;
|
|
50
51
|
}
|
|
51
52
|
if ("const" in resolved) {
|
|
@@ -57,9 +58,12 @@ function initProperty(property, root, seed, required) {
|
|
|
57
58
|
if ("default" in resolved) {
|
|
58
59
|
return resolved.default;
|
|
59
60
|
}
|
|
60
|
-
if (
|
|
61
|
-
|
|
62
|
-
|
|
61
|
+
if (isOneOf) {
|
|
62
|
+
const value = initOneOf(resolved, root, seed, required);
|
|
63
|
+
if (!required && (value === void 0 || value !== null && typeof value === "object" && !Array.isArray(value) && Object.keys(value).length === 0)) {
|
|
64
|
+
return void 0;
|
|
65
|
+
}
|
|
66
|
+
return value;
|
|
63
67
|
}
|
|
64
68
|
if (type === "object") {
|
|
65
69
|
const obj = initObject(
|
|
@@ -104,13 +108,13 @@ function initObject(schema, root, seed, parentRequired) {
|
|
|
104
108
|
}
|
|
105
109
|
return result;
|
|
106
110
|
}
|
|
107
|
-
function initOneOf(schema, root, seed) {
|
|
111
|
+
function initOneOf(schema, root, seed, required) {
|
|
108
112
|
const variants = schema.oneOf;
|
|
109
|
-
if (!variants || variants.length === 0) return null;
|
|
113
|
+
if (!variants || variants.length === 0) return required ? null : void 0;
|
|
110
114
|
const first = variants[0];
|
|
111
|
-
if (!first) return null;
|
|
115
|
+
if (!first) return required ? null : void 0;
|
|
112
116
|
const firstVariant = resolveRef(first, root);
|
|
113
|
-
return initProperty(firstVariant, root, seed,
|
|
117
|
+
return initProperty(firstVariant, root, seed, required);
|
|
114
118
|
}
|
|
115
119
|
export {
|
|
116
120
|
initFormDataFromSchema
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"initFormData.js","sources":["../../src/core/initFormData.ts"],"sourcesContent":["/**\n * Initialize a form data object from a JSON Schema.\n * Resolves $ref, const, default, oneOf/discriminator, and typed empty values.\n *\n * Optional fields (not listed in the parent schema's `required` array) that\n * have no `const`, no single-value `enum`, and no `default` are omitted\n * entirely from the result. This avoids seeding values (e.g. `null` for\n * `type: \"integer\"`) that fail AJV's type check and surface spurious errors\n * on untouched fields. Required fields retain legacy typed-empty seeding\n * (`\"\"`, `null`, `false`, `[]`) so that \"is required\" surfaces cleanly.\n *\n * @param schema - The full JSON Schema (must include $defs if $refs are used)\n * @param seed - Optional existing data to merge (seed values take priority)\n * @returns A data object with schema-defined fields initialized\n */\nexport function initFormDataFromSchema(\n schema: Record<string, unknown>,\n seed?: Record<string, unknown>,\n): Record<string, unknown> {\n const result = initProperty(schema, schema, seed, true) as\n | Record<string, unknown>\n | undefined;\n\n const base =\n result && typeof result === \"object\" && !Array.isArray(result)\n ? result\n : {};\n\n // Preserve seed keys not described by the schema's properties.\n if (seed && typeof seed === \"object\") {\n const schemaKeys = new Set(\n Object.keys(\n (resolveRef(schema, schema) as Record<string, unknown>)?.properties ??\n {},\n ),\n );\n for (const key of Object.keys(seed)) {\n if (!schemaKeys.has(key) && !(key in base)) {\n base[key] = seed[key];\n }\n }\n }\n\n return base;\n}\n\n/**\n * Resolve a $ref pointer against the root schema's $defs.\n * Supports nested $ref chains.\n */\nfunction resolveRef(\n property: Record<string, unknown>,\n root: Record<string, unknown>,\n seen?: Set<string>,\n): Record<string, unknown> {\n if (!property || typeof property !== \"object\") return property;\n\n const ref = property.$ref as string | undefined;\n if (!ref) return property;\n\n const visited = seen ?? new Set<string>();\n if (visited.has(ref)) return property;\n visited.add(ref);\n\n const resolved = resolvePointer(root, ref);\n if (!resolved) return property;\n\n return resolveRef(resolved as Record<string, unknown>, root, visited);\n}\n\n/**\n * Resolve a JSON pointer like \"#/$defs/Price\" against an object.\n */\nfunction resolvePointer(\n obj: Record<string, unknown>,\n pointer: string,\n): unknown {\n if (!pointer.startsWith(\"#/\")) return undefined;\n const parts = pointer.slice(2).split(\"/\");\n let current: unknown = obj;\n for (const part of parts) {\n if (current && typeof current === \"object\" && part in current) {\n current = (current as Record<string, unknown>)[part];\n } else {\n return undefined;\n }\n }\n return current;\n}\n\n/**\n * Initialize a single property value based on its schema definition.\n * Returns `undefined` when the property is optional and has nothing\n * concrete to seed — the caller then omits the key from its result.\n */\nfunction initProperty(\n property: Record<string, unknown>,\n root: Record<string, unknown>,\n seed: unknown,\n required: boolean,\n): unknown {\n if (!property || typeof property !== \"object\") {\n return required ? null : undefined;\n }\n\n const resolved = resolveRef(property, root);\n const type = resolved.type as string | undefined;\n\n // Priority 1: seed wins for non-object types.\n if (seed !== undefined && seed !== null && type !== \"object\") {\n return seed;\n }\n\n // Priority 2: const (schema-invariant — always set).\n if (\"const\" in resolved) {\n return resolved.const;\n }\n\n // Priority 3: single-value enum (same reasoning — only one valid value).\n if (\n Array.isArray(resolved.enum) &&\n (resolved.enum as unknown[]).length === 1\n ) {\n return (resolved.enum as unknown[])[0];\n }\n\n // Priority 4: default (explicit author intent — always honored).\n if (\"default\" in resolved) {\n return resolved.default;\n }\n\n // Priority 5: oneOf. For required fields, materialize the first variant\n // so the discriminator and shape are present. For optional fields, leave\n // undefined so the user isn't forced into a variant they haven't chosen.\n if (Array.isArray(resolved.oneOf)) {\n if (!required) return undefined;\n return initOneOf(resolved, root, seed);\n }\n\n // Priority 6: objects recurse. The `required` flag propagates downward:\n // inside an optional ancestor, nested required primitives also collapse,\n // so an optional object with nested required fields stays absent instead\n // of materializing a shell that AJV would flag.\n if (type === \"object\") {\n const obj = initObject(\n resolved,\n root,\n seed as Record<string, unknown>,\n required,\n );\n if (!required && Object.keys(obj).length === 0) return undefined;\n return obj;\n }\n\n // Priority 7: optional primitives — omit.\n if (!required) return undefined;\n\n // Priority 8: required primitives — legacy typed empty.\n switch (type) {\n case \"array\":\n return seed !== undefined && seed !== null ? seed : [];\n case \"string\":\n return \"\";\n case \"boolean\":\n return false;\n case \"number\":\n case \"integer\":\n default:\n return null;\n }\n}\n\n/**\n * Initialize an object type by recursing into its properties.\n * Keys whose initialization returns `undefined` are omitted.\n *\n * `parentRequired` controls how schema.required propagates: a child is\n * treated as required only if both its parent is required AND it appears in\n * the parent's required array. Inside an optional ancestor the whole\n * subtree collapses (except for author-forced values: const, default,\n * single-value enum, or seeded values).\n */\nfunction initObject(\n schema: Record<string, unknown>,\n root: Record<string, unknown>,\n seed: Record<string, unknown> | undefined,\n parentRequired: boolean,\n): Record<string, unknown> {\n const properties = schema.properties as\n | Record<string, Record<string, unknown>>\n | undefined;\n if (!properties) {\n return seed && typeof seed === \"object\" ? { ...seed } : {};\n }\n\n const requiredSet = new Set<string>(\n Array.isArray(schema.required) ? (schema.required as string[]) : [],\n );\n\n const result: Record<string, unknown> = {};\n\n for (const [key, propSchema] of Object.entries(properties)) {\n const seedValue = seed && typeof seed === \"object\" ? seed[key] : undefined;\n const effectiveRequired = parentRequired && requiredSet.has(key);\n const value = initProperty(propSchema, root, seedValue, effectiveRequired);\n if (value !== undefined) {\n result[key] = value;\n }\n }\n\n return result;\n}\n\n/**\n * Handle oneOf schemas — pick the first variant and initialize it.\n * The variant is treated as required so its own required discriminator\n * and structure seed cleanly.\n */\nfunction initOneOf(\n schema: Record<string, unknown>,\n root: Record<string, unknown>,\n seed?: unknown,\n): unknown {\n const variants = schema.oneOf as Record<string, unknown>[];\n if (!variants || variants.length === 0) return null;\n\n const first = variants[0];\n if (!first) return null;\n\n const firstVariant = resolveRef(first, root);\n return initProperty(firstVariant, root, seed, true);\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"initFormData.js","sources":["../../src/core/initFormData.ts"],"sourcesContent":["/**\n * Initialize a form data object from a JSON Schema.\n * Resolves $ref, const, default, oneOf/discriminator, and typed empty values.\n *\n * Optional fields (not listed in the parent schema's `required` array) that\n * have no `const`, no single-value `enum`, and no `default` are omitted\n * entirely from the result. This avoids seeding values (e.g. `null` for\n * `type: \"integer\"`) that fail AJV's type check and surface spurious errors\n * on untouched fields. Required fields retain legacy typed-empty seeding\n * (`\"\"`, `null`, `false`, `[]`) so that \"is required\" surfaces cleanly.\n *\n * @param schema - The full JSON Schema (must include $defs if $refs are used)\n * @param seed - Optional existing data to merge (seed values take priority)\n * @returns A data object with schema-defined fields initialized\n */\nexport function initFormDataFromSchema(\n schema: Record<string, unknown>,\n seed?: Record<string, unknown>,\n): Record<string, unknown> {\n const result = initProperty(schema, schema, seed, true) as\n | Record<string, unknown>\n | undefined;\n\n const base =\n result && typeof result === \"object\" && !Array.isArray(result)\n ? result\n : {};\n\n // Preserve seed keys not described by the schema's properties.\n if (seed && typeof seed === \"object\") {\n const schemaKeys = new Set(\n Object.keys(\n (resolveRef(schema, schema) as Record<string, unknown>)?.properties ??\n {},\n ),\n );\n for (const key of Object.keys(seed)) {\n if (!schemaKeys.has(key) && !(key in base)) {\n base[key] = seed[key];\n }\n }\n }\n\n return base;\n}\n\n/**\n * Resolve a $ref pointer against the root schema's $defs.\n * Supports nested $ref chains.\n */\nfunction resolveRef(\n property: Record<string, unknown>,\n root: Record<string, unknown>,\n seen?: Set<string>,\n): Record<string, unknown> {\n if (!property || typeof property !== \"object\") return property;\n\n const ref = property.$ref as string | undefined;\n if (!ref) return property;\n\n const visited = seen ?? new Set<string>();\n if (visited.has(ref)) return property;\n visited.add(ref);\n\n const resolved = resolvePointer(root, ref);\n if (!resolved) return property;\n\n return resolveRef(resolved as Record<string, unknown>, root, visited);\n}\n\n/**\n * Resolve a JSON pointer like \"#/$defs/Price\" against an object.\n */\nfunction resolvePointer(\n obj: Record<string, unknown>,\n pointer: string,\n): unknown {\n if (!pointer.startsWith(\"#/\")) return undefined;\n const parts = pointer.slice(2).split(\"/\");\n let current: unknown = obj;\n for (const part of parts) {\n if (current && typeof current === \"object\" && part in current) {\n current = (current as Record<string, unknown>)[part];\n } else {\n return undefined;\n }\n }\n return current;\n}\n\n/**\n * Initialize a single property value based on its schema definition.\n * Returns `undefined` when the property is optional and has nothing\n * concrete to seed — the caller then omits the key from its result.\n */\nfunction initProperty(\n property: Record<string, unknown>,\n root: Record<string, unknown>,\n seed: unknown,\n required: boolean,\n): unknown {\n if (!property || typeof property !== \"object\") {\n return required ? null : undefined;\n }\n\n const resolved = resolveRef(property, root);\n const type = resolved.type as string | undefined;\n const isOneOf = Array.isArray(resolved.oneOf);\n\n // Priority 1: seed wins for non-object, non-oneOf types. For oneOf we still\n // descend so that a partial seed (e.g. `{value: 5}` missing the\n // discriminator) picks up the variant's const/default for untouched fields.\n if (seed !== undefined && seed !== null && type !== \"object\" && !isOneOf) {\n return seed;\n }\n\n // Priority 2: const (schema-invariant — always set).\n if (\"const\" in resolved) {\n return resolved.const;\n }\n\n // Priority 3: single-value enum (same reasoning — only one valid value).\n if (\n Array.isArray(resolved.enum) &&\n (resolved.enum as unknown[]).length === 1\n ) {\n return (resolved.enum as unknown[])[0];\n }\n\n // Priority 4: default (explicit author intent — always honored).\n if (\"default\" in resolved) {\n return resolved.default;\n }\n\n // Priority 5: oneOf. Recurse into the first variant, propagating the\n // `required` flag so that the variant's own schema-declared required fields\n // only get typed-empty seeding when the container is required. For optional\n // containers, the variant's const / default / single-value enum still seed\n // (author intent is unconditional) but typed-empty placeholders do not.\n // If recursion yields nothing forced, we collapse back to undefined.\n if (isOneOf) {\n const value = initOneOf(resolved, root, seed, required);\n if (\n !required &&\n (value === undefined ||\n (value !== null &&\n typeof value === \"object\" &&\n !Array.isArray(value) &&\n Object.keys(value as Record<string, unknown>).length === 0))\n ) {\n return undefined;\n }\n return value;\n }\n\n // Priority 6: objects recurse. The `required` flag propagates downward:\n // inside an optional ancestor, nested required primitives also collapse,\n // so an optional object with nested required fields stays absent instead\n // of materializing a shell that AJV would flag.\n if (type === \"object\") {\n const obj = initObject(\n resolved,\n root,\n seed as Record<string, unknown>,\n required,\n );\n if (!required && Object.keys(obj).length === 0) return undefined;\n return obj;\n }\n\n // Priority 7: optional primitives — omit.\n if (!required) return undefined;\n\n // Priority 8: required primitives — legacy typed empty.\n switch (type) {\n case \"array\":\n return seed !== undefined && seed !== null ? seed : [];\n case \"string\":\n return \"\";\n case \"boolean\":\n return false;\n case \"number\":\n case \"integer\":\n default:\n return null;\n }\n}\n\n/**\n * Initialize an object type by recursing into its properties.\n * Keys whose initialization returns `undefined` are omitted.\n *\n * `parentRequired` controls how schema.required propagates: a child is\n * treated as required only if both its parent is required AND it appears in\n * the parent's required array. Inside an optional ancestor the whole\n * subtree collapses (except for author-forced values: const, default,\n * single-value enum, or seeded values).\n */\nfunction initObject(\n schema: Record<string, unknown>,\n root: Record<string, unknown>,\n seed: Record<string, unknown> | undefined,\n parentRequired: boolean,\n): Record<string, unknown> {\n const properties = schema.properties as\n | Record<string, Record<string, unknown>>\n | undefined;\n if (!properties) {\n return seed && typeof seed === \"object\" ? { ...seed } : {};\n }\n\n const requiredSet = new Set<string>(\n Array.isArray(schema.required) ? (schema.required as string[]) : [],\n );\n\n const result: Record<string, unknown> = {};\n\n for (const [key, propSchema] of Object.entries(properties)) {\n const seedValue = seed && typeof seed === \"object\" ? seed[key] : undefined;\n const effectiveRequired = parentRequired && requiredSet.has(key);\n const value = initProperty(propSchema, root, seedValue, effectiveRequired);\n if (value !== undefined) {\n result[key] = value;\n }\n }\n\n return result;\n}\n\n/**\n * Handle oneOf schemas — pick the first variant and initialize it.\n * `required` propagates: if the outer oneOf is required, the variant is\n * materialized with typed-empty seeding for its required fields; if optional,\n * only author-forced values (const / default / single-enum / seed) survive.\n */\nfunction initOneOf(\n schema: Record<string, unknown>,\n root: Record<string, unknown>,\n seed: unknown,\n required: boolean,\n): unknown {\n const variants = schema.oneOf as Record<string, unknown>[];\n if (!variants || variants.length === 0) return required ? null : undefined;\n\n const first = variants[0];\n if (!first) return required ? null : undefined;\n\n const firstVariant = resolveRef(first, root);\n return initProperty(firstVariant, root, seed, required);\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProviderAutocomplete.vue.d.ts","sourceRoot":"","sources":["../../../src/vue/components/ProviderAutocomplete.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ProviderAutocomplete.vue.d.ts","sourceRoot":"","sources":["../../../src/vue/components/ProviderAutocomplete.vue"],"names":[],"mappings":"AA+EA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAOlE,KAAK,WAAW,GAAG;IACjB,QAAQ,EAAE,cAAc,CAAC;IACzB,MAAM,EAAE,UAAU,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;;AA2JF,wBAEG"}
|
|
@@ -27,10 +27,11 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
27
27
|
setup(__props) {
|
|
28
28
|
const props = __props;
|
|
29
29
|
const { control, handleChange: rawHandleChange } = useJsonFormsControl(props);
|
|
30
|
-
const {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
30
|
+
const {
|
|
31
|
+
projectedData,
|
|
32
|
+
projectedLabel,
|
|
33
|
+
handleProjectedChange: handleChange
|
|
34
|
+
} = useProjection(control, rawHandleChange);
|
|
34
35
|
const binding = computed(() => {
|
|
35
36
|
const provider = control.value.uischema?.options?.provider;
|
|
36
37
|
if (provider && typeof provider === "object" && !provider.load) {
|
|
@@ -62,7 +63,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
62
63
|
};
|
|
63
64
|
return (_ctx, _cache) => {
|
|
64
65
|
return openBlock(), createElementBlock("div", _hoisted_1, [
|
|
65
|
-
unref(
|
|
66
|
+
unref(projectedLabel) ? (openBlock(), createElementBlock("label", _hoisted_2, toDisplayString(unref(projectedLabel)), 1)) : createCommentVNode("", true),
|
|
66
67
|
unref(control).description ? (openBlock(), createElementBlock("div", _hoisted_3, toDisplayString(unref(control).description), 1)) : createCommentVNode("", true),
|
|
67
68
|
createVNode(unref(AutoComplete), {
|
|
68
69
|
modelValue: value.value,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProviderAutocomplete.vue.js","sources":["../../../src/vue/components/ProviderAutocomplete.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { ControlElement, JsonSchema } from \"@jsonforms/core\";\nimport { useJsonFormsControl } from \"@jsonforms/vue\";\nimport { computed, ref, watch } from \"vue\";\nimport { useProvider } from \"../composables/useProvider\";\nimport { useProjection } from \"../composables/useProjection\";\nimport AutoComplete from \"primevue/autocomplete\";\n\nconst props = defineProps<{\n uischema: ControlElement;\n schema: JsonSchema;\n path: string;\n}>();\nconst { control, handleChange: rawHandleChange } = useJsonFormsControl(props);\nconst {
|
|
1
|
+
{"version":3,"file":"ProviderAutocomplete.vue.js","sources":["../../../src/vue/components/ProviderAutocomplete.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { ControlElement, JsonSchema } from \"@jsonforms/core\";\nimport { useJsonFormsControl } from \"@jsonforms/vue\";\nimport { computed, ref, watch } from \"vue\";\nimport { useProvider } from \"../composables/useProvider\";\nimport { useProjection } from \"../composables/useProjection\";\nimport AutoComplete from \"primevue/autocomplete\";\n\nconst props = defineProps<{\n uischema: ControlElement;\n schema: JsonSchema;\n path: string;\n}>();\nconst { control, handleChange: rawHandleChange } = useJsonFormsControl(props);\nconst {\n projectedData,\n projectedLabel,\n handleProjectedChange: handleChange,\n} = useProjection(control, rawHandleChange);\n\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 query = ref(\"\");\nconst { items, loading, error, reload } = useProvider(binding, {\n data: control.value.data,\n path: control.value.path,\n uiQuery: query.value,\n});\n\nwatch(query, () => {\n if (binding.value?.load === \"query\") reload();\n});\n\nconst value = computed({\n get: () => projectedData.value,\n set: (v) => handleChange(control.value.path, v),\n});\n\nconst placeholder = computed(() =>\n loading.value ? \"Loading…\" : \"Type to search…\",\n);\n\nconst onComplete = (event: { query: string }) => {\n query.value = event.query;\n};\n\nconst onSelect = (event: { value?: { value?: unknown } | unknown }) => {\n value.value = (event.value as { value?: unknown })?.value ?? event.value;\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-model=\"value\"\n class=\"w-full!\"\n :suggestions=\"items\"\n option-label=\"label\"\n :placeholder=\"placeholder\"\n :disabled=\"!control.enabled\"\n @complete=\"onComplete\"\n @item-select=\"onSelect\"\n />\n <small v-if=\"error\" class=\"p-error\" role=\"alert\">Failed: {{ error }}</small>\n </div>\n</template>\n"],"names":["_openBlock","_createElementBlock","_unref","_toDisplayString","_createVNode"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAQA,UAAM,QAAQ;AAKd,UAAM,EAAE,SAAS,cAAc,gBAAA,IAAoB,oBAAoB,KAAK;AAC5E,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA,uBAAuB;AAAA,IAAA,IACrB,cAAc,SAAS,eAAe;AAE1C,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,QAAQ,IAAI,EAAE;AACpB,UAAM,EAAE,OAAO,SAAS,OAAO,OAAA,IAAW,YAAY,SAAS;AAAA,MAC7D,MAAM,QAAQ,MAAM;AAAA,MACpB,MAAM,QAAQ,MAAM;AAAA,MACpB,SAAS,MAAM;AAAA,IAAA,CAChB;AAED,UAAM,OAAO,MAAM;AACjB,UAAI,QAAQ,OAAO,SAAS,QAAS,QAAA;AAAA,IACvC,CAAC;AAED,UAAM,QAAQ,SAAS;AAAA,MACrB,KAAK,MAAM,cAAc;AAAA,MACzB,KAAK,CAAC,MAAM,aAAa,QAAQ,MAAM,MAAM,CAAC;AAAA,IAAA,CAC/C;AAED,UAAM,cAAc;AAAA,MAAS,MAC3B,QAAQ,QAAQ,aAAa;AAAA,IAAA;AAG/B,UAAM,aAAa,CAAC,UAA6B;AAC/C,YAAM,QAAQ,MAAM;AAAA,IACtB;AAEA,UAAM,WAAW,CAAC,UAAqD;AACrE,YAAM,QAAS,MAAM,OAA+B,SAAS,MAAM;AAAA,IACrE;;AAIE,aAAAA,UAAA,GAAAC,mBAgBM,OAhBN,YAgBM;AAAA,QAfSC,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,YASEF,MAAA,YAAA,GAAA;AAAA,sBARS,MAAA;AAAA,uEAAA,MAAK,QAAA;AAAA,UACd,OAAM;AAAA,UACL,aAAaA,MAAA,KAAA;AAAA,UACd,gBAAa;AAAA,UACZ,aAAa,YAAA;AAAA,UACb,UAAQ,CAAGA,MAAA,OAAA,EAAQ;AAAA,UACnB;AAAA,UACA,cAAa;AAAA,QAAA;QAEHA,MAAA,KAAA,KAAbF,aAAAC,mBAA4E,SAA5E,YAAiD,6BAAWC,MAAA,KAAA,CAAK,GAAA,CAAA;;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProviderMultiSelect.vue.d.ts","sourceRoot":"","sources":["../../../src/vue/components/ProviderMultiSelect.vue"],"names":[],"mappings":"AAyIA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"ProviderMultiSelect.vue.d.ts","sourceRoot":"","sources":["../../../src/vue/components/ProviderMultiSelect.vue"],"names":[],"mappings":"AAyIA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AASlE,KAAK,WAAW,GAAG;IACjB,QAAQ,EAAE,cAAc,CAAC;IACzB,MAAM,EAAE,UAAU,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;;AAuMF,wBAEG"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import _sfc_main from "./ProviderMultiSelect.vue2.js";
|
|
2
2
|
/* empty css */
|
|
3
3
|
import _export_sfc from "../../_virtual/_plugin-vue_export-helper.js";
|
|
4
|
-
const ProviderMultiSelect = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-
|
|
4
|
+
const ProviderMultiSelect = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-0d0d0f03"]]);
|
|
5
5
|
export {
|
|
6
6
|
ProviderMultiSelect as default
|
|
7
7
|
};
|
|
@@ -3,6 +3,7 @@ import { useJsonFormsControl } from "@jsonforms/vue";
|
|
|
3
3
|
import { useProvider } from "../composables/useProvider.js";
|
|
4
4
|
import { useProjection } from "../composables/useProjection.js";
|
|
5
5
|
import { shouldAutoSelectMulti } from "../utils/autoSelect.js";
|
|
6
|
+
import { resolvePlaceholder } from "../utils/placeholder.js";
|
|
6
7
|
import MultiSelect from "primevue/multiselect";
|
|
7
8
|
const _hoisted_1 = { class: "jf-control" };
|
|
8
9
|
const _hoisted_2 = {
|
|
@@ -28,10 +29,11 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
28
29
|
setup(__props) {
|
|
29
30
|
const props = __props;
|
|
30
31
|
const { control, handleChange: rawHandleChange } = useJsonFormsControl(props);
|
|
31
|
-
const {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
const {
|
|
33
|
+
projectedData,
|
|
34
|
+
projectedLabel,
|
|
35
|
+
handleProjectedChange: handleChange
|
|
36
|
+
} = useProjection(control, rawHandleChange);
|
|
35
37
|
const binding = computed(() => {
|
|
36
38
|
const provider = control.value.uischema?.options?.provider;
|
|
37
39
|
if (provider && typeof provider === "object" && !provider.load) {
|
|
@@ -85,12 +87,15 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
85
87
|
});
|
|
86
88
|
const placeholder = computed(() => {
|
|
87
89
|
if (loading.value) return "Loading…";
|
|
88
|
-
|
|
89
|
-
|
|
90
|
+
return resolvePlaceholder(
|
|
91
|
+
control.value.uischema,
|
|
92
|
+
projectedLabel.value,
|
|
93
|
+
"select"
|
|
94
|
+
);
|
|
90
95
|
});
|
|
91
96
|
return (_ctx, _cache) => {
|
|
92
97
|
return openBlock(), createElementBlock("div", _hoisted_1, [
|
|
93
|
-
unref(
|
|
98
|
+
unref(projectedLabel) ? (openBlock(), createElementBlock("label", _hoisted_2, toDisplayString(unref(projectedLabel)), 1)) : createCommentVNode("", true),
|
|
94
99
|
unref(control).description ? (openBlock(), createElementBlock("div", _hoisted_3, toDisplayString(unref(control).description), 1)) : createCommentVNode("", true),
|
|
95
100
|
createVNode(unref(MultiSelect), {
|
|
96
101
|
modelValue: value.value,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProviderMultiSelect.vue2.js","sources":["../../../src/vue/components/ProviderMultiSelect.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { ControlElement, JsonSchema } from \"@jsonforms/core\";\nimport { useJsonFormsControl } from \"@jsonforms/vue\";\nimport { computed, inject, watch } from \"vue\";\nimport { useProvider } from \"../composables/useProvider\";\nimport { useProjection } from \"../composables/useProjection\";\nimport { shouldAutoSelectMulti } from \"../utils/autoSelect\";\nimport MultiSelect from \"primevue/multiselect\";\n\nconst props = defineProps<{\n uischema: ControlElement;\n schema: JsonSchema;\n path: string;\n}>();\nconst { control, handleChange: rawHandleChange } = useJsonFormsControl(props);\nconst {
|
|
1
|
+
{"version":3,"file":"ProviderMultiSelect.vue2.js","sources":["../../../src/vue/components/ProviderMultiSelect.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { ControlElement, JsonSchema } from \"@jsonforms/core\";\nimport { useJsonFormsControl } from \"@jsonforms/vue\";\nimport { computed, inject, watch } from \"vue\";\nimport { useProvider } from \"../composables/useProvider\";\nimport { useProjection } from \"../composables/useProjection\";\nimport { shouldAutoSelectMulti } from \"../utils/autoSelect\";\nimport { resolvePlaceholder } from \"../utils/placeholder\";\nimport MultiSelect from \"primevue/multiselect\";\n\nconst props = defineProps<{\n uischema: ControlElement;\n schema: JsonSchema;\n path: string;\n}>();\nconst { control, handleChange: rawHandleChange } = useJsonFormsControl(props);\nconst {\n projectedData,\n projectedLabel,\n handleProjectedChange: handleChange,\n} = useProjection(control, rawHandleChange);\n\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(() => deps.value.map(() => null)); // you can resolve actual values via control.value.data & pointers\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 { items, loading, error } = useProvider(binding, {\n data: rootData, // Pass the reactive reference\n path: control.value.path,\n dependsOnValues: depValues,\n});\n\n// Provider will automatically reload when rootData changes due to reactive cache key\n\n// Auto-select when provider returns only one item (opt-in for multiselect)\nwatch(\n [items, loading],\n ([newItems, isLoading]) => {\n const valueToSelect = shouldAutoSelectMulti({\n autoSelectSingle:\n control.value.uischema?.options?.autoSelectSingle === true,\n isLoading,\n items: newItems,\n currentValue: Array.isArray(projectedData.value)\n ? projectedData.value\n : [],\n });\n\n if (valueToSelect !== null) {\n handleChange(control.value.path, valueToSelect);\n }\n },\n { immediate: true },\n);\n\n// order-insensitive shallow equality for primitive arrays\nconst sameSet = (a: unknown[], b: unknown[]) => {\n if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length)\n return false;\n const s = new Set(b);\n return a.every((v) => s.has(v));\n};\n\n// v-model with guard to avoid recursive updates\nconst value = computed({\n get() {\n const curr = Array.isArray(projectedData.value) ? projectedData.value : [];\n // return a fresh copy so MultiSelect can't mutate JSONForms' array in place\n return [...curr];\n },\n set(val) {\n const next = Array.isArray(val) ? [...val] : [];\n const curr = Array.isArray(projectedData.value) ? projectedData.value : [];\n if (!sameSet(curr, next)) handleChange(control.value.path, next);\n },\n});\n\nconst placeholder = computed(() => {\n if (loading.value) return \"Loading…\";\n return resolvePlaceholder(\n control.value.uischema,\n projectedLabel.value,\n \"select\",\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 <MultiSelect\n v-model=\"value\"\n class=\"w-full!\"\n :options=\"items\"\n option-label=\"label\"\n option-value=\"value\"\n data-key=\"value\"\n display=\"chip\"\n :placeholder=\"placeholder\"\n :disabled=\"!control.enabled || loading\"\n :show-clear=\"true\"\n />\n <small v-if=\"error\" class=\"p-error\" role=\"alert\"\n >Failed to load: {{ error }}</small\n >\n </div>\n</template>\n\n<style scoped>\n:deep(.p-multiselect-label) {\n text-align: left;\n}\n</style>\n"],"names":["_openBlock","_createElementBlock","_unref","_toDisplayString","_createVNode"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProviderSelect.vue.d.ts","sourceRoot":"","sources":["../../../src/vue/components/ProviderSelect.vue"],"names":[],"mappings":"AAwHA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"ProviderSelect.vue.d.ts","sourceRoot":"","sources":["../../../src/vue/components/ProviderSelect.vue"],"names":[],"mappings":"AAwHA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAUlE,KAAK,WAAW,GAAG;IACjB,QAAQ,EAAE,cAAc,CAAC;IACzB,MAAM,EAAE,UAAU,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;;AAmLF,wBAEG"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import _sfc_main from "./ProviderSelect.vue2.js";
|
|
2
2
|
/* empty css */
|
|
3
3
|
import _export_sfc from "../../_virtual/_plugin-vue_export-helper.js";
|
|
4
|
-
const ProviderSelect = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-
|
|
4
|
+
const ProviderSelect = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-cbb98bc4"]]);
|
|
5
5
|
export {
|
|
6
6
|
ProviderSelect as default
|
|
7
7
|
};
|
|
@@ -4,6 +4,7 @@ import { useProvider } from "../composables/useProvider.js";
|
|
|
4
4
|
import { useDeriveInitialValue } from "../composables/useDeriveInitialValue.js";
|
|
5
5
|
import { useProjection } from "../composables/useProjection.js";
|
|
6
6
|
import { shouldAutoSelect } from "../utils/autoSelect.js";
|
|
7
|
+
import { resolvePlaceholder } from "../utils/placeholder.js";
|
|
7
8
|
import Dropdown from "primevue/dropdown";
|
|
8
9
|
const _hoisted_1 = { class: "jf-control" };
|
|
9
10
|
const _hoisted_2 = {
|
|
@@ -29,10 +30,11 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
29
30
|
setup(__props) {
|
|
30
31
|
const props = __props;
|
|
31
32
|
const { control, handleChange: rawHandleChange } = useJsonFormsControl(props);
|
|
32
|
-
const {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
const {
|
|
34
|
+
projectedData,
|
|
35
|
+
projectedLabel,
|
|
36
|
+
handleProjectedChange: handleChange
|
|
37
|
+
} = useProjection(control, rawHandleChange);
|
|
36
38
|
const binding = computed(() => {
|
|
37
39
|
const provider = control.value.uischema?.options?.provider;
|
|
38
40
|
if (provider && typeof provider === "object" && !provider.load) {
|
|
@@ -74,12 +76,15 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
74
76
|
});
|
|
75
77
|
const placeholder = computed(() => {
|
|
76
78
|
if (loading.value) return "Loading…";
|
|
77
|
-
|
|
78
|
-
|
|
79
|
+
return resolvePlaceholder(
|
|
80
|
+
control.value.uischema,
|
|
81
|
+
projectedLabel.value,
|
|
82
|
+
"select"
|
|
83
|
+
);
|
|
79
84
|
});
|
|
80
85
|
return (_ctx, _cache) => {
|
|
81
86
|
return openBlock(), createElementBlock("div", _hoisted_1, [
|
|
82
|
-
unref(
|
|
87
|
+
unref(projectedLabel) ? (openBlock(), createElementBlock("label", _hoisted_2, toDisplayString(unref(projectedLabel)), 1)) : createCommentVNode("", true),
|
|
83
88
|
unref(control).description ? (openBlock(), createElementBlock("div", _hoisted_3, toDisplayString(unref(control).description), 1)) : createCommentVNode("", true),
|
|
84
89
|
createVNode(unref(Dropdown), {
|
|
85
90
|
modelValue: value.value,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProviderSelect.vue2.js","sources":["../../../src/vue/components/ProviderSelect.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { ControlElement, JsonSchema } from \"@jsonforms/core\";\nimport { useJsonFormsControl } from \"@jsonforms/vue\";\nimport { computed, inject, watch } from \"vue\";\nimport { useProvider } from \"../composables/useProvider\";\nimport { useDeriveInitialValue } from \"../composables/useDeriveInitialValue\";\nimport { useProjection } from \"../composables/useProjection\";\nimport { shouldAutoSelect } from \"../utils/autoSelect\";\nimport Dropdown from \"primevue/dropdown\";\n\nconst props = defineProps<{\n uischema: ControlElement;\n schema: JsonSchema;\n path: string;\n}>();\nconst { control, handleChange: rawHandleChange } = useJsonFormsControl(props);\nconst {
|
|
1
|
+
{"version":3,"file":"ProviderSelect.vue2.js","sources":["../../../src/vue/components/ProviderSelect.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { ControlElement, JsonSchema } from \"@jsonforms/core\";\nimport { useJsonFormsControl } from \"@jsonforms/vue\";\nimport { computed, inject, watch } from \"vue\";\nimport { useProvider } from \"../composables/useProvider\";\nimport { useDeriveInitialValue } from \"../composables/useDeriveInitialValue\";\nimport { useProjection } from \"../composables/useProjection\";\nimport { shouldAutoSelect } from \"../utils/autoSelect\";\nimport { resolvePlaceholder } from \"../utils/placeholder\";\nimport Dropdown from \"primevue/dropdown\";\n\nconst props = defineProps<{\n uischema: ControlElement;\n schema: JsonSchema;\n path: string;\n}>();\nconst { control, handleChange: rawHandleChange } = useJsonFormsControl(props);\nconst {\n projectedData,\n projectedLabel,\n handleProjectedChange: handleChange,\n} = useProjection(control, rawHandleChange);\n\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(() => deps.value.map(() => null)); // you can resolve actual values via control.value.data & pointers\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 { items, loading, error } = useProvider(binding, {\n data: rootData, // Pass the reactive reference\n path: control.value.path,\n dependsOnValues: depValues,\n});\n\n// Provider will automatically reload when rootData changes due to reactive cache key\n\n// 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 [items, loading],\n ([newItems, isLoading]) => {\n const valueToSelect = shouldAutoSelect({\n autoSelectSingle:\n control.value.uischema?.options?.autoSelectSingle !== false,\n isLoading,\n items: newItems,\n currentValue: projectedData.value,\n });\n\n if (valueToSelect !== null) {\n handleChange(control.value.path, valueToSelect);\n }\n },\n { immediate: true },\n);\n\nconst value = computed({\n get: () => projectedData.value,\n set: (v) => handleChange(control.value.path, v),\n});\n\nconst placeholder = computed(() => {\n if (loading.value) return \"Loading…\";\n return resolvePlaceholder(\n control.value.uischema,\n projectedLabel.value,\n \"select\",\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 <Dropdown\n v-model=\"value\"\n class=\"w-full!\"\n :options=\"items\"\n option-label=\"label\"\n option-value=\"value\"\n :placeholder=\"placeholder\"\n :disabled=\"!control.enabled || loading\"\n :show-clear=\"true\"\n />\n <small v-if=\"error\" class=\"p-error\" role=\"alert\"\n >Failed to load: {{ error }}</small\n >\n </div>\n</template>\n\n<style scoped>\n:deep(.p-dropdown-label) {\n text-align: left;\n}\n</style>\n"],"names":["_openBlock","_createElementBlock","_unref","_toDisplayString","_createVNode"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAWA,UAAM,QAAQ;AAKd,UAAM,EAAE,SAAS,cAAc,gBAAA,IAAoB,oBAAoB,KAAK;AAC5E,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA,uBAAuB;AAAA,IAAA,IACrB,cAAc,SAAS,eAAe;AAE1C,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,KAAK,MAAM,IAAI,MAAM,IAAI,CAAC;AAG3D,UAAM,mBAAmB,OAA2B,YAAY,EAAE,OAAO,CAAA,GAAI;AAC7E,UAAM,WAAW,SAAS,MAAM,iBAAiB,SAAS,CAAA,CAAE;AAE5D,UAAM,EAAE,OAAO,SAAS,MAAA,IAAU,YAAY,SAAS;AAAA,MACrD,MAAM;AAAA;AAAA,MACN,MAAM,QAAQ,MAAM;AAAA,MACpB,iBAAiB;AAAA,IAAA,CAClB;AAKD,0BAAsB,EAAE,SAAS,cAAc;AAG/C;AAAA,MACE,CAAC,OAAO,OAAO;AAAA,MACf,CAAC,CAAC,UAAU,SAAS,MAAM;AACzB,cAAM,gBAAgB,iBAAiB;AAAA,UACrC,kBACE,QAAQ,MAAM,UAAU,SAAS,qBAAqB;AAAA,UACxD;AAAA,UACA,OAAO;AAAA,UACP,cAAc,cAAc;AAAA,QAAA,CAC7B;AAED,YAAI,kBAAkB,MAAM;AAC1B,uBAAa,QAAQ,MAAM,MAAM,aAAa;AAAA,QAChD;AAAA,MACF;AAAA,MACA,EAAE,WAAW,KAAA;AAAA,IAAK;AAGpB,UAAM,QAAQ,SAAS;AAAA,MACrB,KAAK,MAAM,cAAc;AAAA,MACzB,KAAK,CAAC,MAAM,aAAa,QAAQ,MAAM,MAAM,CAAC;AAAA,IAAA,CAC/C;AAED,UAAM,cAAc,SAAS,MAAM;AACjC,UAAI,QAAQ,MAAO,QAAO;AAC1B,aAAO;AAAA,QACL,QAAQ,MAAM;AAAA,QACd,eAAe;AAAA,QACf;AAAA,MAAA;AAAA,IAEJ,CAAC;;AAIC,aAAAA,UAAA,GAAAC,mBAkBM,OAlBN,YAkBM;AAAA,QAjBSC,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,YASEF,MAAA,QAAA,GAAA;AAAA,sBARS,MAAA;AAAA,uEAAA,MAAK,QAAA;AAAA,UACd,OAAM;AAAA,UACL,SAASA,MAAA,KAAA;AAAA,UACV,gBAAa;AAAA,UACb,gBAAa;AAAA,UACZ,aAAa,YAAA;AAAA,UACb,UAAQ,CAAGA,MAAA,OAAA,EAAQ,WAAWA,MAAA,OAAA;AAAA,UAC9B,cAAY;AAAA,QAAA;QAEFA,MAAA,KAAA,KAAbF,aAAAC,mBAEC,SAFD,YACG,qCAAmBC,MAAA,KAAA,CAAK,GAAA,CAAA;;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JfEnum.vue.d.ts","sourceRoot":"","sources":["../../../src/vue/primevue/JfEnum.vue"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"JfEnum.vue.d.ts","sourceRoot":"","sources":["../../../src/vue/primevue/JfEnum.vue"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgOA,wBAyUK"}
|
|
@@ -6,6 +6,7 @@ import { useDeriveInitialValue } from "../composables/useDeriveInitialValue.js";
|
|
|
6
6
|
import { useProjection } from "../composables/useProjection.js";
|
|
7
7
|
import { useDirtyValidation } from "../composables/useDirtyValidation.js";
|
|
8
8
|
import { shouldAutoSelect } from "../utils/autoSelect.js";
|
|
9
|
+
import { resolvePlaceholder } from "../utils/placeholder.js";
|
|
9
10
|
import Dropdown from "primevue/dropdown";
|
|
10
11
|
const _hoisted_1 = { class: "jf-control" };
|
|
11
12
|
const _hoisted_2 = {
|
|
@@ -123,7 +124,11 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
123
124
|
});
|
|
124
125
|
const placeholder = computed(() => {
|
|
125
126
|
if (loading.value) return "Loading…";
|
|
126
|
-
return
|
|
127
|
+
return resolvePlaceholder(
|
|
128
|
+
control.value.uischema,
|
|
129
|
+
projectedLabel.value,
|
|
130
|
+
"select"
|
|
131
|
+
);
|
|
127
132
|
});
|
|
128
133
|
const options = computed(() => {
|
|
129
134
|
if (binding.value && providerItems.value.length > 0) {
|
|
@@ -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 { useDeriveInitialValue } from \"../composables/useDeriveInitialValue\";\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 {\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 (\n
|
|
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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"JfEnumArray.vue.d.ts","sourceRoot":"","sources":["../../../src/vue/primevue/JfEnumArray.vue"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiPA,wBAgVK"}
|
|
@@ -5,6 +5,7 @@ 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
10
|
const _hoisted_1 = { class: "jf-control" };
|
|
10
11
|
const _hoisted_2 = {
|
|
@@ -145,7 +146,11 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
145
146
|
);
|
|
146
147
|
const placeholder = computed(() => {
|
|
147
148
|
if (loading.value) return "Loading…";
|
|
148
|
-
return
|
|
149
|
+
return resolvePlaceholder(
|
|
150
|
+
control.value.uischema,
|
|
151
|
+
projectedLabel.value,
|
|
152
|
+
"select"
|
|
153
|
+
);
|
|
149
154
|
});
|
|
150
155
|
const sameSet = (a, b) => {
|
|
151
156
|
if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JfEnumArray.vue.js","sources":["../../../src/vue/primevue/JfEnumArray.vue"],"sourcesContent":["<script lang=\"ts\">\nexport default {\n name: \"JfEnumArray\",\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 { shouldAutoSelectMulti } from \"../utils/autoSelect\";\nimport MultiSelect from \"primevue/multiselect\";\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 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 as { items?: JsonSchema })?.items);\n});\n\n// Add derive functionality\nuseDerive({ control, handleChange, data: projectedData });\n\n// Track user interaction — errors only show after first change\nconst { showErrors, markDirty } = useDirtyValidation(control, projectedErrors);\n\n// Auto-select when provider returns only one item (opt-in for multiselect)\nwatch(\n [providerItems, loading],\n ([items, isLoading]) => {\n const valueToSelect = shouldAutoSelectMulti({\n autoSelectSingle:\n control.value.uischema?.options?.autoSelectSingle === true,\n isLoading,\n items,\n currentValue: Array.isArray(projectedData.value)\n ? projectedData.value\n : [],\n });\n\n if (valueToSelect !== null) {\n handleChange(control.value.path, valueToSelect);\n }\n },\n { immediate: true },\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\n// order-insensitive shallow equality for primitive enums\nconst sameSet = (a: unknown[], b: unknown[]) => {\n if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length)\n return false;\n const s = new Set(b);\n return a.every((v) => s.has(v));\n};\n\n// v-model with guard to avoid recursive updates\nconst model = computed<unknown[]>({\n get() {\n const curr = Array.isArray(projectedData.value) ? projectedData.value : [];\n // return a fresh copy so PrimeMultiSelect can't mutate JSONForms' array in place\n return [...curr];\n },\n set(val) {\n const next = Array.isArray(val) ? [...val] : [];\n const curr = Array.isArray(projectedData.value) ? projectedData.value : [];\n if (!sameSet(curr, next)) {\n markDirty();\n handleChange(control.value.path, next);\n }\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\n <MultiSelect\n v-model=\"model\"\n :class=\"['w-full!', { 'p-invalid': showErrors }]\"\n :options=\"options\"\n option-label=\"label\"\n option-value=\"value\"\n data-key=\"value\"\n display=\"chip\"\n :disabled=\"!control.enabled || loading\"\n :aria-invalid=\"showErrors || undefined\"\n :placeholder=\"placeholder\"\n />\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
|
+
{"version":3,"file":"JfEnumArray.vue.js","sources":["../../../src/vue/primevue/JfEnumArray.vue"],"sourcesContent":["<script lang=\"ts\">\nexport default {\n name: \"JfEnumArray\",\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 { shouldAutoSelectMulti } from \"../utils/autoSelect\";\nimport { resolvePlaceholder } from \"../utils/placeholder\";\nimport MultiSelect from \"primevue/multiselect\";\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 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 as { items?: JsonSchema })?.items);\n});\n\n// Add derive functionality\nuseDerive({ control, handleChange, data: projectedData });\n\n// Track user interaction — errors only show after first change\nconst { showErrors, markDirty } = useDirtyValidation(control, projectedErrors);\n\n// Auto-select when provider returns only one item (opt-in for multiselect)\nwatch(\n [providerItems, loading],\n ([items, isLoading]) => {\n const valueToSelect = shouldAutoSelectMulti({\n autoSelectSingle:\n control.value.uischema?.options?.autoSelectSingle === true,\n isLoading,\n items,\n currentValue: Array.isArray(projectedData.value)\n ? projectedData.value\n : [],\n });\n\n if (valueToSelect !== null) {\n handleChange(control.value.path, valueToSelect);\n }\n },\n { immediate: true },\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\n// order-insensitive shallow equality for primitive enums\nconst sameSet = (a: unknown[], b: unknown[]) => {\n if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length)\n return false;\n const s = new Set(b);\n return a.every((v) => s.has(v));\n};\n\n// v-model with guard to avoid recursive updates\nconst model = computed<unknown[]>({\n get() {\n const curr = Array.isArray(projectedData.value) ? projectedData.value : [];\n // return a fresh copy so PrimeMultiSelect can't mutate JSONForms' array in place\n return [...curr];\n },\n set(val) {\n const next = Array.isArray(val) ? [...val] : [];\n const curr = Array.isArray(projectedData.value) ? projectedData.value : [];\n if (!sameSet(curr, next)) {\n markDirty();\n handleChange(control.value.path, next);\n }\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\n <MultiSelect\n v-model=\"model\"\n :class=\"['w-full!', { 'p-invalid': showErrors }]\"\n :options=\"options\"\n option-label=\"label\"\n option-value=\"value\"\n data-key=\"value\"\n display=\"chip\"\n :disabled=\"!control.enabled || loading\"\n :aria-invalid=\"showErrors || undefined\"\n :placeholder=\"placeholder\"\n />\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":"JfNumber.vue.d.ts","sourceRoot":"","sources":["../../../src/vue/primevue/JfNumber.vue"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"JfNumber.vue.d.ts","sourceRoot":"","sources":["../../../src/vue/primevue/JfNumber.vue"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8JA,wBA0QK"}
|
|
@@ -4,6 +4,7 @@ import { useDerive } from "../composables/useDerive.js";
|
|
|
4
4
|
import { useDeriveInitialValue } from "../composables/useDeriveInitialValue.js";
|
|
5
5
|
import { useProjection } from "../composables/useProjection.js";
|
|
6
6
|
import { useDirtyValidation } from "../composables/useDirtyValidation.js";
|
|
7
|
+
import { resolvePlaceholder } from "../utils/placeholder.js";
|
|
7
8
|
import InputNumber from "primevue/inputnumber";
|
|
8
9
|
const _hoisted_1 = { class: "jf-control" };
|
|
9
10
|
const _hoisted_2 = {
|
|
@@ -70,7 +71,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
70
71
|
() => control.value.uischema?.options ?? {}
|
|
71
72
|
);
|
|
72
73
|
const placeholder = computed(
|
|
73
|
-
() =>
|
|
74
|
+
() => resolvePlaceholder(control.value.uischema, projectedLabel.value, "input")
|
|
74
75
|
);
|
|
75
76
|
useDerive({ control, handleChange, data: projectedData });
|
|
76
77
|
useDeriveInitialValue({ control, handleChange });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JfNumber.vue.js","sources":["../../../src/vue/primevue/JfNumber.vue"],"sourcesContent":["<script lang=\"ts\">\nexport default {\n name: \"JfNumber\",\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 { useDerive } from \"../composables/useDerive\";\nimport { useDeriveInitialValue } from \"../composables/useDeriveInitialValue\";\nimport { useProjection } from \"../composables/useProjection\";\nimport { useDirtyValidation } from \"../composables/useDirtyValidation\";\nimport InputNumber from \"primevue/inputnumber\";\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 options = computed(\n () =>\n (control.value.uischema as { options?: Record<string, unknown> })\n ?.options ?? {},\n);\n\nconst placeholder = computed<string | undefined>(
|
|
1
|
+
{"version":3,"file":"JfNumber.vue.js","sources":["../../../src/vue/primevue/JfNumber.vue"],"sourcesContent":["<script lang=\"ts\">\nexport default {\n name: \"JfNumber\",\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 { useDerive } from \"../composables/useDerive\";\nimport { useDeriveInitialValue } from \"../composables/useDeriveInitialValue\";\nimport { useProjection } from \"../composables/useProjection\";\nimport { useDirtyValidation } from \"../composables/useDirtyValidation\";\nimport { resolvePlaceholder } from \"../utils/placeholder\";\nimport InputNumber from \"primevue/inputnumber\";\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 options = computed(\n () =>\n (control.value.uischema as { options?: Record<string, unknown> })\n ?.options ?? {},\n);\n\nconst placeholder = computed<string | undefined>(() =>\n resolvePlaceholder(control.value.uischema, projectedLabel.value, \"input\"),\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// Currency and decimal configuration\nconst mode = computed(() => {\n if (options.value.currency) return \"currency\";\n if (options.value.decimal || typeof options.value.precision === \"number\")\n return \"decimal\";\n return undefined;\n});\n\nconst currency = computed(() =>\n typeof options.value.currency === \"string\" ? options.value.currency : \"USD\",\n);\n\nconst minFractionDigits = computed(() => {\n // For integer types, no fractional digits\n if (control.value.schema?.type === \"integer\") return 0;\n if (mode.value === \"currency\") return 2;\n if (typeof options.value.precision === \"number\")\n return options.value.precision;\n return undefined;\n});\n\nconst maxFractionDigits = computed(() => {\n // For integer types, no fractional digits\n if (control.value.schema?.type === \"integer\") return 0;\n if (mode.value === \"currency\") return 2;\n if (typeof options.value.precision === \"number\")\n return options.value.precision;\n return undefined;\n});\n\nconst useGrouping = computed(() => {\n // Enable grouping for currency by default, or if explicitly set\n if (mode.value === \"currency\") return true;\n return options.value.useGrouping === true;\n});\n\n// Track user interaction — errors only show after blur\nconst { showErrors, markDirty } = useDirtyValidation(control, projectedErrors);\n\nconst onNumber = (val: number | null) => {\n handleChange(control.value.path, val ?? undefined);\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 <InputNumber\n :class=\"['w-full!', { 'p-invalid': showErrors }]\"\n :input-class=\"['w-full!', { 'p-invalid': showErrors }]\"\n :use-grouping=\"useGrouping\"\n :mode=\"mode\"\n :currency=\"currency\"\n :min-fraction-digits=\"minFractionDigits\"\n :max-fraction-digits=\"maxFractionDigits\"\n :model-value=\"typeof projectedData === 'number' ? projectedData : null\"\n :placeholder=\"placeholder\"\n :disabled=\"!control.enabled\"\n :aria-invalid=\"showErrors || undefined\"\n @update:model-value=\"onNumber\"\n @blur=\"markDirty\"\n />\n <small v-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":"JfText.vue.d.ts","sourceRoot":"","sources":["../../../src/vue/primevue/JfText.vue"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"JfText.vue.d.ts","sourceRoot":"","sources":["../../../src/vue/primevue/JfText.vue"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4NA,wBAsXK"}
|
|
@@ -5,6 +5,7 @@ import { useDerive } from "../composables/useDerive.js";
|
|
|
5
5
|
import { useDeriveInitialValue } from "../composables/useDeriveInitialValue.js";
|
|
6
6
|
import { useProjection } from "../composables/useProjection.js";
|
|
7
7
|
import { useDirtyValidation } from "../composables/useDirtyValidation.js";
|
|
8
|
+
import { resolvePlaceholder } from "../utils/placeholder.js";
|
|
8
9
|
import InputText from "primevue/inputtext";
|
|
9
10
|
import AutoComplete from "primevue/autocomplete";
|
|
10
11
|
const _hoisted_1 = { class: "jf-control" };
|
|
@@ -110,11 +111,18 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
110
111
|
watch(query, () => {
|
|
111
112
|
if (binding.value?.load === "query") reload();
|
|
112
113
|
});
|
|
114
|
+
const isAutocomplete = computed(() => !!binding.value);
|
|
113
115
|
const placeholder = computed(() => {
|
|
114
116
|
if (loading.value) return "Loading…";
|
|
115
|
-
|
|
117
|
+
const explicit = control.value.uischema?.options?.placeholder;
|
|
118
|
+
if (explicit) return explicit;
|
|
119
|
+
if (isAutocomplete.value) return "Type to search…";
|
|
120
|
+
return resolvePlaceholder(
|
|
121
|
+
control.value.uischema,
|
|
122
|
+
projectedLabel.value,
|
|
123
|
+
"input"
|
|
124
|
+
);
|
|
116
125
|
});
|
|
117
|
-
const isAutocomplete = computed(() => !!binding.value);
|
|
118
126
|
useDerive({ control, handleChange, data: projectedData });
|
|
119
127
|
useDeriveInitialValue({ control, handleChange });
|
|
120
128
|
const { showErrors, markDirty } = useDirtyValidation(control, projectedErrors);
|
|
@@ -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 { 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,\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
|
+
{"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 { resolvePlaceholder } from \"../utils/placeholder\";\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,\n});\n\nwatch(query, () => {\n if (binding.value?.load === \"query\") reload();\n});\n\nconst isAutocomplete = computed(() => !!binding.value);\n\nconst placeholder = computed<string | undefined>(() => {\n if (loading.value) return \"Loading…\";\n const explicit = (\n control.value.uischema as { options?: { placeholder?: string } }\n )?.options?.placeholder;\n if (explicit) return explicit;\n // In autocomplete mode the input is really a search box — use matching UX.\n if (isAutocomplete.value) return \"Type to search…\";\n return resolvePlaceholder(\n control.value.uischema,\n projectedLabel.value,\n \"input\",\n );\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// 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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmHA,
|
|
1
|
+
{"version":3,"file":"JfTextArea.vue.d.ts","sourceRoot":"","sources":["../../../src/vue/primevue/JfTextArea.vue"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmHA,wBA0NK"}
|
|
@@ -2,6 +2,7 @@ import { defineComponent, getCurrentInstance, computed, createElementBlock, open
|
|
|
2
2
|
import { useJsonFormsControl } from "@jsonforms/vue";
|
|
3
3
|
import { useProjection } from "../composables/useProjection.js";
|
|
4
4
|
import { useDirtyValidation } from "../composables/useDirtyValidation.js";
|
|
5
|
+
import { resolvePlaceholder } from "../utils/placeholder.js";
|
|
5
6
|
import Textarea from "primevue/textarea";
|
|
6
7
|
const _hoisted_1 = { class: "jf-control" };
|
|
7
8
|
const _hoisted_2 = {
|
|
@@ -65,7 +66,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
65
66
|
projectedLabel
|
|
66
67
|
} = useProjection(control, rawHandleChange);
|
|
67
68
|
const placeholder = computed(
|
|
68
|
-
() => control.value.uischema
|
|
69
|
+
() => resolvePlaceholder(control.value.uischema, projectedLabel.value, "input")
|
|
69
70
|
);
|
|
70
71
|
const { showErrors, markDirty } = useDirtyValidation(control, projectedErrors);
|
|
71
72
|
function onInput(val) {
|
|
@@ -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 {\n projectedData,\n handleProjectedChange: handleChange,\n projectedErrors,\n projectedLabel,\n} = useProjection(control, rawHandleChange);\n\nconst placeholder = computed<string | undefined>(
|
|
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 { resolvePlaceholder } from \"../utils/placeholder\";\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 resolvePlaceholder(control.value.uischema, projectedLabel.value, \"input\"),\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;;;;AAaA,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,MAA6B,MAC/C,mBAAmB,QAAQ,MAAM,UAAU,eAAe,OAAO,OAAO;AAAA,IAAA;AAI1E,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;;;;;"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Placeholder resolution for form controls.
|
|
3
|
+
*
|
|
4
|
+
* Precedence:
|
|
5
|
+
* 1. `uischema.options.placeholder` (explicit author intent — always wins)
|
|
6
|
+
* 2. `Select ${label}` or `Enter ${label}` when a label is resolvable
|
|
7
|
+
* 3. Kind-appropriate bare fallback
|
|
8
|
+
*
|
|
9
|
+
* Never falls back to `schema.description` — descriptions are rendered as
|
|
10
|
+
* prose above the field by our renderers, so re-using them as placeholder
|
|
11
|
+
* produces a duplicated, truncated string inside the input.
|
|
12
|
+
*/
|
|
13
|
+
export type PlaceholderKind = "select" | "input";
|
|
14
|
+
export declare function resolvePlaceholder(uischema: {
|
|
15
|
+
options?: unknown;
|
|
16
|
+
} | undefined, resolvedLabel: string | undefined, kind: PlaceholderKind): string | undefined;
|
|
17
|
+
//# sourceMappingURL=placeholder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"placeholder.d.ts","sourceRoot":"","sources":["../../../src/vue/utils/placeholder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,OAAO,CAAC;AAUjD,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,SAAS,EAC3C,aAAa,EAAE,MAAM,GAAG,SAAS,EACjC,IAAI,EAAE,eAAe,GACpB,MAAM,GAAG,SAAS,CAcpB"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
function stripRequiredMarker(label) {
|
|
2
|
+
return label.replace(/\s*\*\s*$/, "").trim();
|
|
3
|
+
}
|
|
4
|
+
function resolvePlaceholder(uischema, resolvedLabel, kind) {
|
|
5
|
+
const options = uischema?.options;
|
|
6
|
+
const explicit = options && typeof options === "object" ? options.placeholder : void 0;
|
|
7
|
+
if (typeof explicit === "string" && explicit.length > 0) return explicit;
|
|
8
|
+
const label = resolvedLabel ? stripRequiredMarker(resolvedLabel) : "";
|
|
9
|
+
if (label) {
|
|
10
|
+
return kind === "select" ? `Select ${label}` : `Enter ${label}`;
|
|
11
|
+
}
|
|
12
|
+
return kind === "select" ? "Select…" : void 0;
|
|
13
|
+
}
|
|
14
|
+
export {
|
|
15
|
+
resolvePlaceholder
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=placeholder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"placeholder.js","sources":["../../../src/vue/utils/placeholder.ts"],"sourcesContent":["/**\n * Placeholder resolution for form controls.\n *\n * Precedence:\n * 1. `uischema.options.placeholder` (explicit author intent — always wins)\n * 2. `Select ${label}` or `Enter ${label}` when a label is resolvable\n * 3. Kind-appropriate bare fallback\n *\n * Never falls back to `schema.description` — descriptions are rendered as\n * prose above the field by our renderers, so re-using them as placeholder\n * produces a duplicated, truncated string inside the input.\n */\n\nexport type PlaceholderKind = \"select\" | \"input\";\n\n/**\n * Strip a trailing required-indicator asterisk (\" *\" or \"*\") that `resolveLabel`\n * appends for required fields, so composed placeholders read naturally.\n */\nfunction stripRequiredMarker(label: string): string {\n return label.replace(/\\s*\\*\\s*$/, \"\").trim();\n}\n\nexport function resolvePlaceholder(\n uischema: { options?: unknown } | undefined,\n resolvedLabel: string | undefined,\n kind: PlaceholderKind,\n): string | undefined {\n const options = uischema?.options;\n const explicit =\n options && typeof options === \"object\"\n ? (options as Record<string, unknown>).placeholder\n : undefined;\n if (typeof explicit === \"string\" && explicit.length > 0) return explicit;\n\n const label = resolvedLabel ? stripRequiredMarker(resolvedLabel) : \"\";\n if (label) {\n return kind === \"select\" ? `Select ${label}` : `Enter ${label}`;\n }\n\n return kind === \"select\" ? \"Select…\" : undefined;\n}\n"],"names":[],"mappings":"AAmBA,SAAS,oBAAoB,OAAuB;AAClD,SAAO,MAAM,QAAQ,aAAa,EAAE,EAAE,KAAA;AACxC;AAEO,SAAS,mBACd,UACA,eACA,MACoB;AACpB,QAAM,UAAU,UAAU;AAC1B,QAAM,WACJ,WAAW,OAAO,YAAY,WACzB,QAAoC,cACrC;AACN,MAAI,OAAO,aAAa,YAAY,SAAS,SAAS,EAAG,QAAO;AAEhE,QAAM,QAAQ,gBAAgB,oBAAoB,aAAa,IAAI;AACnE,MAAI,OAAO;AACT,WAAO,SAAS,WAAW,UAAU,KAAK,KAAK,SAAS,KAAK;AAAA,EAC/D;AAEA,SAAO,SAAS,WAAW,YAAY;AACzC;"}
|
package/package.json
CHANGED
package/src/core/initFormData.ts
CHANGED
|
@@ -105,9 +105,12 @@ function initProperty(
|
|
|
105
105
|
|
|
106
106
|
const resolved = resolveRef(property, root);
|
|
107
107
|
const type = resolved.type as string | undefined;
|
|
108
|
+
const isOneOf = Array.isArray(resolved.oneOf);
|
|
108
109
|
|
|
109
|
-
// Priority 1: seed wins for non-object types.
|
|
110
|
-
|
|
110
|
+
// Priority 1: seed wins for non-object, non-oneOf types. For oneOf we still
|
|
111
|
+
// descend so that a partial seed (e.g. `{value: 5}` missing the
|
|
112
|
+
// discriminator) picks up the variant's const/default for untouched fields.
|
|
113
|
+
if (seed !== undefined && seed !== null && type !== "object" && !isOneOf) {
|
|
111
114
|
return seed;
|
|
112
115
|
}
|
|
113
116
|
|
|
@@ -129,12 +132,25 @@ function initProperty(
|
|
|
129
132
|
return resolved.default;
|
|
130
133
|
}
|
|
131
134
|
|
|
132
|
-
// Priority 5: oneOf.
|
|
133
|
-
//
|
|
134
|
-
//
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
135
|
+
// Priority 5: oneOf. Recurse into the first variant, propagating the
|
|
136
|
+
// `required` flag so that the variant's own schema-declared required fields
|
|
137
|
+
// only get typed-empty seeding when the container is required. For optional
|
|
138
|
+
// containers, the variant's const / default / single-value enum still seed
|
|
139
|
+
// (author intent is unconditional) but typed-empty placeholders do not.
|
|
140
|
+
// If recursion yields nothing forced, we collapse back to undefined.
|
|
141
|
+
if (isOneOf) {
|
|
142
|
+
const value = initOneOf(resolved, root, seed, required);
|
|
143
|
+
if (
|
|
144
|
+
!required &&
|
|
145
|
+
(value === undefined ||
|
|
146
|
+
(value !== null &&
|
|
147
|
+
typeof value === "object" &&
|
|
148
|
+
!Array.isArray(value) &&
|
|
149
|
+
Object.keys(value as Record<string, unknown>).length === 0))
|
|
150
|
+
) {
|
|
151
|
+
return undefined;
|
|
152
|
+
}
|
|
153
|
+
return value;
|
|
138
154
|
}
|
|
139
155
|
|
|
140
156
|
// Priority 6: objects recurse. The `required` flag propagates downward:
|
|
@@ -213,20 +229,22 @@ function initObject(
|
|
|
213
229
|
|
|
214
230
|
/**
|
|
215
231
|
* Handle oneOf schemas — pick the first variant and initialize it.
|
|
216
|
-
*
|
|
217
|
-
*
|
|
232
|
+
* `required` propagates: if the outer oneOf is required, the variant is
|
|
233
|
+
* materialized with typed-empty seeding for its required fields; if optional,
|
|
234
|
+
* only author-forced values (const / default / single-enum / seed) survive.
|
|
218
235
|
*/
|
|
219
236
|
function initOneOf(
|
|
220
237
|
schema: Record<string, unknown>,
|
|
221
238
|
root: Record<string, unknown>,
|
|
222
|
-
seed
|
|
239
|
+
seed: unknown,
|
|
240
|
+
required: boolean,
|
|
223
241
|
): unknown {
|
|
224
242
|
const variants = schema.oneOf as Record<string, unknown>[];
|
|
225
|
-
if (!variants || variants.length === 0) return null;
|
|
243
|
+
if (!variants || variants.length === 0) return required ? null : undefined;
|
|
226
244
|
|
|
227
245
|
const first = variants[0];
|
|
228
|
-
if (!first) return null;
|
|
246
|
+
if (!first) return required ? null : undefined;
|
|
229
247
|
|
|
230
248
|
const firstVariant = resolveRef(first, root);
|
|
231
|
-
return initProperty(firstVariant, root, seed,
|
|
249
|
+
return initProperty(firstVariant, root, seed, required);
|
|
232
250
|
}
|
|
@@ -12,10 +12,11 @@ const props = defineProps<{
|
|
|
12
12
|
path: string;
|
|
13
13
|
}>();
|
|
14
14
|
const { control, handleChange: rawHandleChange } = useJsonFormsControl(props);
|
|
15
|
-
const {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
const {
|
|
16
|
+
projectedData,
|
|
17
|
+
projectedLabel,
|
|
18
|
+
handleProjectedChange: handleChange,
|
|
19
|
+
} = useProjection(control, rawHandleChange);
|
|
19
20
|
|
|
20
21
|
const binding = computed(() => {
|
|
21
22
|
const provider = control.value.uischema?.options?.provider;
|
|
@@ -57,9 +58,7 @@ const onSelect = (event: { value?: { value?: unknown } | unknown }) => {
|
|
|
57
58
|
|
|
58
59
|
<template>
|
|
59
60
|
<div class="jf-control">
|
|
60
|
-
<label v-if="
|
|
61
|
-
control.schema.title
|
|
62
|
-
}}</label>
|
|
61
|
+
<label v-if="projectedLabel" class="jf-label">{{ projectedLabel }}</label>
|
|
63
62
|
<div v-if="control.description" class="jf-description">
|
|
64
63
|
{{ control.description }}
|
|
65
64
|
</div>
|
|
@@ -5,6 +5,7 @@ import { computed, inject, watch } from "vue";
|
|
|
5
5
|
import { useProvider } from "../composables/useProvider";
|
|
6
6
|
import { useProjection } from "../composables/useProjection";
|
|
7
7
|
import { shouldAutoSelectMulti } from "../utils/autoSelect";
|
|
8
|
+
import { resolvePlaceholder } from "../utils/placeholder";
|
|
8
9
|
import MultiSelect from "primevue/multiselect";
|
|
9
10
|
|
|
10
11
|
const props = defineProps<{
|
|
@@ -13,10 +14,11 @@ const props = defineProps<{
|
|
|
13
14
|
path: string;
|
|
14
15
|
}>();
|
|
15
16
|
const { control, handleChange: rawHandleChange } = useJsonFormsControl(props);
|
|
16
|
-
const {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
const {
|
|
18
|
+
projectedData,
|
|
19
|
+
projectedLabel,
|
|
20
|
+
handleProjectedChange: handleChange,
|
|
21
|
+
} = useProjection(control, rawHandleChange);
|
|
20
22
|
|
|
21
23
|
const binding = computed(() => {
|
|
22
24
|
const provider = control.value.uischema?.options?.provider;
|
|
@@ -94,19 +96,17 @@ const value = computed({
|
|
|
94
96
|
|
|
95
97
|
const placeholder = computed(() => {
|
|
96
98
|
if (loading.value) return "Loading…";
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
99
|
+
return resolvePlaceholder(
|
|
100
|
+
control.value.uischema,
|
|
101
|
+
projectedLabel.value,
|
|
102
|
+
"select",
|
|
103
|
+
);
|
|
102
104
|
});
|
|
103
105
|
</script>
|
|
104
106
|
|
|
105
107
|
<template>
|
|
106
108
|
<div class="jf-control">
|
|
107
|
-
<label v-if="
|
|
108
|
-
control.schema.title
|
|
109
|
-
}}</label>
|
|
109
|
+
<label v-if="projectedLabel" class="jf-label">{{ projectedLabel }}</label>
|
|
110
110
|
<div v-if="control.description" class="jf-description">
|
|
111
111
|
{{ control.description }}
|
|
112
112
|
</div>
|
|
@@ -6,6 +6,7 @@ import { useProvider } from "../composables/useProvider";
|
|
|
6
6
|
import { useDeriveInitialValue } from "../composables/useDeriveInitialValue";
|
|
7
7
|
import { useProjection } from "../composables/useProjection";
|
|
8
8
|
import { shouldAutoSelect } from "../utils/autoSelect";
|
|
9
|
+
import { resolvePlaceholder } from "../utils/placeholder";
|
|
9
10
|
import Dropdown from "primevue/dropdown";
|
|
10
11
|
|
|
11
12
|
const props = defineProps<{
|
|
@@ -14,10 +15,11 @@ const props = defineProps<{
|
|
|
14
15
|
path: string;
|
|
15
16
|
}>();
|
|
16
17
|
const { control, handleChange: rawHandleChange } = useJsonFormsControl(props);
|
|
17
|
-
const {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
const {
|
|
19
|
+
projectedData,
|
|
20
|
+
projectedLabel,
|
|
21
|
+
handleProjectedChange: handleChange,
|
|
22
|
+
} = useProjection(control, rawHandleChange);
|
|
21
23
|
|
|
22
24
|
const binding = computed(() => {
|
|
23
25
|
const provider = control.value.uischema?.options?.provider;
|
|
@@ -79,19 +81,17 @@ const value = computed({
|
|
|
79
81
|
|
|
80
82
|
const placeholder = computed(() => {
|
|
81
83
|
if (loading.value) return "Loading…";
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
84
|
+
return resolvePlaceholder(
|
|
85
|
+
control.value.uischema,
|
|
86
|
+
projectedLabel.value,
|
|
87
|
+
"select",
|
|
88
|
+
);
|
|
87
89
|
});
|
|
88
90
|
</script>
|
|
89
91
|
|
|
90
92
|
<template>
|
|
91
93
|
<div class="jf-control">
|
|
92
|
-
<label v-if="
|
|
93
|
-
control.schema.title
|
|
94
|
-
}}</label>
|
|
94
|
+
<label v-if="projectedLabel" class="jf-label">{{ projectedLabel }}</label>
|
|
95
95
|
<div v-if="control.description" class="jf-description">
|
|
96
96
|
{{ control.description }}
|
|
97
97
|
</div>
|
|
@@ -49,6 +49,7 @@ import { useDeriveInitialValue } from "../composables/useDeriveInitialValue";
|
|
|
49
49
|
import { useProjection } from "../composables/useProjection";
|
|
50
50
|
import { useDirtyValidation } from "../composables/useDirtyValidation";
|
|
51
51
|
import { shouldAutoSelect } from "../utils/autoSelect";
|
|
52
|
+
import { resolvePlaceholder } from "../utils/placeholder";
|
|
52
53
|
import Dropdown from "primevue/dropdown";
|
|
53
54
|
|
|
54
55
|
// Access props from the component instance
|
|
@@ -131,9 +132,10 @@ const {
|
|
|
131
132
|
|
|
132
133
|
const placeholder = computed<string | undefined>(() => {
|
|
133
134
|
if (loading.value) return "Loading…";
|
|
134
|
-
return (
|
|
135
|
-
|
|
136
|
-
|
|
135
|
+
return resolvePlaceholder(
|
|
136
|
+
control.value.uischema,
|
|
137
|
+
projectedLabel.value,
|
|
138
|
+
"select",
|
|
137
139
|
);
|
|
138
140
|
});
|
|
139
141
|
|
|
@@ -47,6 +47,7 @@ import { useDerive } from "../composables/useDerive";
|
|
|
47
47
|
import { useProjection } from "../composables/useProjection";
|
|
48
48
|
import { useDirtyValidation } from "../composables/useDirtyValidation";
|
|
49
49
|
import { shouldAutoSelectMulti } from "../utils/autoSelect";
|
|
50
|
+
import { resolvePlaceholder } from "../utils/placeholder";
|
|
50
51
|
import MultiSelect from "primevue/multiselect";
|
|
51
52
|
|
|
52
53
|
// Access props from the component instance
|
|
@@ -164,9 +165,10 @@ watch(
|
|
|
164
165
|
|
|
165
166
|
const placeholder = computed<string | undefined>(() => {
|
|
166
167
|
if (loading.value) return "Loading…";
|
|
167
|
-
return (
|
|
168
|
-
|
|
169
|
-
|
|
168
|
+
return resolvePlaceholder(
|
|
169
|
+
control.value.uischema,
|
|
170
|
+
projectedLabel.value,
|
|
171
|
+
"select",
|
|
170
172
|
);
|
|
171
173
|
});
|
|
172
174
|
|
|
@@ -45,6 +45,7 @@ import { useDerive } from "../composables/useDerive";
|
|
|
45
45
|
import { useDeriveInitialValue } from "../composables/useDeriveInitialValue";
|
|
46
46
|
import { useProjection } from "../composables/useProjection";
|
|
47
47
|
import { useDirtyValidation } from "../composables/useDirtyValidation";
|
|
48
|
+
import { resolvePlaceholder } from "../utils/placeholder";
|
|
48
49
|
import InputNumber from "primevue/inputnumber";
|
|
49
50
|
|
|
50
51
|
// Access props from the component instance
|
|
@@ -64,8 +65,8 @@ const options = computed(
|
|
|
64
65
|
?.options ?? {},
|
|
65
66
|
);
|
|
66
67
|
|
|
67
|
-
const placeholder = computed<string | undefined>(
|
|
68
|
-
(
|
|
68
|
+
const placeholder = computed<string | undefined>(() =>
|
|
69
|
+
resolvePlaceholder(control.value.uischema, projectedLabel.value, "input"),
|
|
69
70
|
);
|
|
70
71
|
|
|
71
72
|
// Add derive functionality
|
|
@@ -46,6 +46,7 @@ import { useDerive } from "../composables/useDerive";
|
|
|
46
46
|
import { useDeriveInitialValue } from "../composables/useDeriveInitialValue";
|
|
47
47
|
import { useProjection } from "../composables/useProjection";
|
|
48
48
|
import { useDirtyValidation } from "../composables/useDirtyValidation";
|
|
49
|
+
import { resolvePlaceholder } from "../utils/placeholder";
|
|
49
50
|
import InputText from "primevue/inputtext";
|
|
50
51
|
import AutoComplete from "primevue/autocomplete";
|
|
51
52
|
|
|
@@ -111,16 +112,23 @@ watch(query, () => {
|
|
|
111
112
|
if (binding.value?.load === "query") reload();
|
|
112
113
|
});
|
|
113
114
|
|
|
115
|
+
const isAutocomplete = computed(() => !!binding.value);
|
|
116
|
+
|
|
114
117
|
const placeholder = computed<string | undefined>(() => {
|
|
115
118
|
if (loading.value) return "Loading…";
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
+
const explicit = (
|
|
120
|
+
control.value.uischema as { options?: { placeholder?: string } }
|
|
121
|
+
)?.options?.placeholder;
|
|
122
|
+
if (explicit) return explicit;
|
|
123
|
+
// In autocomplete mode the input is really a search box — use matching UX.
|
|
124
|
+
if (isAutocomplete.value) return "Type to search…";
|
|
125
|
+
return resolvePlaceholder(
|
|
126
|
+
control.value.uischema,
|
|
127
|
+
projectedLabel.value,
|
|
128
|
+
"input",
|
|
119
129
|
);
|
|
120
130
|
});
|
|
121
131
|
|
|
122
|
-
const isAutocomplete = computed(() => !!binding.value);
|
|
123
|
-
|
|
124
132
|
// Add derive functionality
|
|
125
133
|
useDerive({ control, handleChange, data: projectedData });
|
|
126
134
|
|
|
@@ -43,6 +43,7 @@ import { useJsonFormsControl } from "@jsonforms/vue";
|
|
|
43
43
|
import { computed, getCurrentInstance } from "vue";
|
|
44
44
|
import { useProjection } from "../composables/useProjection";
|
|
45
45
|
import { useDirtyValidation } from "../composables/useDirtyValidation";
|
|
46
|
+
import { resolvePlaceholder } from "../utils/placeholder";
|
|
46
47
|
import Textarea from "primevue/textarea";
|
|
47
48
|
|
|
48
49
|
// Access props from the component instance
|
|
@@ -56,10 +57,8 @@ const {
|
|
|
56
57
|
projectedLabel,
|
|
57
58
|
} = useProjection(control, rawHandleChange);
|
|
58
59
|
|
|
59
|
-
const placeholder = computed<string | undefined>(
|
|
60
|
-
()
|
|
61
|
-
(control.value.uischema as { options?: { placeholder?: string } })?.options
|
|
62
|
-
?.placeholder ?? control.value.description,
|
|
60
|
+
const placeholder = computed<string | undefined>(() =>
|
|
61
|
+
resolvePlaceholder(control.value.uischema, projectedLabel.value, "input"),
|
|
63
62
|
);
|
|
64
63
|
|
|
65
64
|
// Track user interaction — errors only show after blur
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Placeholder resolution for form controls.
|
|
3
|
+
*
|
|
4
|
+
* Precedence:
|
|
5
|
+
* 1. `uischema.options.placeholder` (explicit author intent — always wins)
|
|
6
|
+
* 2. `Select ${label}` or `Enter ${label}` when a label is resolvable
|
|
7
|
+
* 3. Kind-appropriate bare fallback
|
|
8
|
+
*
|
|
9
|
+
* Never falls back to `schema.description` — descriptions are rendered as
|
|
10
|
+
* prose above the field by our renderers, so re-using them as placeholder
|
|
11
|
+
* produces a duplicated, truncated string inside the input.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
export type PlaceholderKind = "select" | "input";
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Strip a trailing required-indicator asterisk (" *" or "*") that `resolveLabel`
|
|
18
|
+
* appends for required fields, so composed placeholders read naturally.
|
|
19
|
+
*/
|
|
20
|
+
function stripRequiredMarker(label: string): string {
|
|
21
|
+
return label.replace(/\s*\*\s*$/, "").trim();
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function resolvePlaceholder(
|
|
25
|
+
uischema: { options?: unknown } | undefined,
|
|
26
|
+
resolvedLabel: string | undefined,
|
|
27
|
+
kind: PlaceholderKind,
|
|
28
|
+
): string | undefined {
|
|
29
|
+
const options = uischema?.options;
|
|
30
|
+
const explicit =
|
|
31
|
+
options && typeof options === "object"
|
|
32
|
+
? (options as Record<string, unknown>).placeholder
|
|
33
|
+
: undefined;
|
|
34
|
+
if (typeof explicit === "string" && explicit.length > 0) return explicit;
|
|
35
|
+
|
|
36
|
+
const label = resolvedLabel ? stripRequiredMarker(resolvedLabel) : "";
|
|
37
|
+
if (label) {
|
|
38
|
+
return kind === "select" ? `Select ${label}` : `Enter ${label}`;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return kind === "select" ? "Select…" : undefined;
|
|
42
|
+
}
|