@narrative.io/jsonforms-provider-protocols 1.1.0-beta.1 → 1.1.0-beta.3
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/jsonforms-provider-protocols.css +1 -1
- package/dist/vue/primevue/JfEnum.vue.d.ts.map +1 -1
- package/dist/vue/primevue/JfEnum.vue.js +1 -1
- package/dist/vue/primevue/JfEnum.vue2.js +13 -5
- package/dist/vue/primevue/JfEnum.vue2.js.map +1 -1
- package/dist/vue/primevue/JfNumber.vue.d.ts.map +1 -1
- package/dist/vue/primevue/JfNumber.vue.js +48 -8
- 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 +19 -6
- 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 +12 -6
- package/dist/vue/primevue/JfTextArea.vue.js.map +1 -1
- package/package.json +1 -1
- package/src/vue/primevue/JfEnum.vue +17 -4
- package/src/vue/primevue/JfNumber.vue +59 -8
- package/src/vue/primevue/JfText.vue +24 -5
- package/src/vue/primevue/JfTextArea.vue +16 -5
|
@@ -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":"AAkFA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0KlE,wBAEG"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import _sfc_main from "./JfEnum.vue2.js";
|
|
2
2
|
/* empty css */
|
|
3
3
|
import _export_sfc from "../../_virtual/_plugin-vue_export-helper.js";
|
|
4
|
-
const JfEnum = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-
|
|
4
|
+
const JfEnum = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-354307cd"]]);
|
|
5
5
|
export {
|
|
6
6
|
JfEnum as default
|
|
7
7
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { defineComponent, computed, createElementBlock, openBlock, createCommentVNode, createVNode, unref, toDisplayString } from "vue";
|
|
1
|
+
import { defineComponent, computed, ref, createElementBlock, openBlock, createCommentVNode, createVNode, unref, toDisplayString } from "vue";
|
|
2
2
|
import { rendererProps, useJsonFormsControl } from "@jsonforms/vue";
|
|
3
3
|
import Dropdown from "primevue/dropdown";
|
|
4
4
|
const _hoisted_1 = { class: "flex flex-column gap-2" };
|
|
@@ -37,7 +37,14 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
37
37
|
() => control.value.uischema?.options?.placeholder ?? control.value.description
|
|
38
38
|
);
|
|
39
39
|
const options = computed(() => toOptions(control.value.schema));
|
|
40
|
-
const
|
|
40
|
+
const hasInteracted = ref(false);
|
|
41
|
+
const showErrors = computed(() => hasInteracted.value && control.value.errors);
|
|
42
|
+
const onSelect = (val) => {
|
|
43
|
+
handleChange(control.value.path, val);
|
|
44
|
+
};
|
|
45
|
+
const onBlur = () => {
|
|
46
|
+
hasInteracted.value = true;
|
|
47
|
+
};
|
|
41
48
|
return (_ctx, _cache) => {
|
|
42
49
|
return openBlock(), createElementBlock("div", _hoisted_1, [
|
|
43
50
|
unref(control).label ? (openBlock(), createElementBlock("label", _hoisted_2, toDisplayString(unref(control).label), 1)) : createCommentVNode("", true),
|
|
@@ -50,11 +57,12 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
50
57
|
"model-value": unref(control).data ?? null,
|
|
51
58
|
placeholder: placeholder.value,
|
|
52
59
|
disabled: !unref(control).enabled,
|
|
53
|
-
"aria-invalid": !!
|
|
60
|
+
"aria-invalid": !!showErrors.value || void 0,
|
|
54
61
|
"show-clear": true,
|
|
55
|
-
"onUpdate:modelValue": onSelect
|
|
62
|
+
"onUpdate:modelValue": onSelect,
|
|
63
|
+
onBlur
|
|
56
64
|
}, null, 8, ["options", "model-value", "placeholder", "disabled", "aria-invalid"]),
|
|
57
|
-
|
|
65
|
+
showErrors.value ? (openBlock(), createElementBlock("small", _hoisted_4, toDisplayString(unref(control).errors), 1)) : createCommentVNode("", true)
|
|
58
66
|
]);
|
|
59
67
|
};
|
|
60
68
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JfEnum.vue2.js","sources":["../../../src/vue/primevue/JfEnum.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { ControlElement, JsonSchema } from \"@jsonforms/core\";\nimport { rendererProps, useJsonFormsControl } from \"@jsonforms/vue\";\nimport { computed } from \"vue\";\nimport Dropdown from \"primevue/dropdown\";\n\ndefineOptions({ name: \"JfEnum\" });\n\nconst props = defineProps(rendererProps<ControlElement>());\nconst { control, handleChange } = useJsonFormsControl(props);\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\nconst placeholder = computed<string | undefined>(\n () =>\n (control.value.uischema as { options?: { placeholder?: string } })?.options\n ?.placeholder ?? control.value.description,\n);\n\nconst options = computed(() => toOptions(control.value.schema));\nconst onSelect = (val: unknown) => handleChange(control.value.path, val);\n</script>\n\n<template>\n <div class=\"flex flex-column gap-2\">\n <label v-if=\"control.label\" class=\"text-color text-left\">{{\n control.label\n }}</label>\n <div v-if=\"control.description\" class=\"text-color-secondary text-left\">\n {{ control.description }}\n </div>\n <Dropdown\n class=\"w-full\"\n :options=\"options\"\n option-label=\"label\"\n option-value=\"value\"\n :model-value=\"control.data ?? null\"\n :placeholder=\"placeholder\"\n :disabled=\"!control.enabled\"\n :aria-invalid=\"!!
|
|
1
|
+
{"version":3,"file":"JfEnum.vue2.js","sources":["../../../src/vue/primevue/JfEnum.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { ControlElement, JsonSchema } from \"@jsonforms/core\";\nimport { rendererProps, useJsonFormsControl } from \"@jsonforms/vue\";\nimport { computed, ref } from \"vue\";\nimport Dropdown from \"primevue/dropdown\";\n\ndefineOptions({ name: \"JfEnum\" });\n\nconst props = defineProps(rendererProps<ControlElement>());\nconst { control, handleChange } = useJsonFormsControl(props);\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\nconst placeholder = computed<string | undefined>(\n () =>\n (control.value.uischema as { options?: { placeholder?: string } })?.options\n ?.placeholder ?? control.value.description,\n);\n\nconst options = computed(() => toOptions(control.value.schema));\n\n// Track user interaction\nconst hasInteracted = ref(false);\n\nconst showErrors = computed(() => hasInteracted.value && control.value.errors);\n\nconst onSelect = (val: unknown) => {\n handleChange(control.value.path, val);\n};\n\nconst onBlur = () => {\n hasInteracted.value = true;\n};\n</script>\n\n<template>\n <div class=\"flex flex-column gap-2\">\n <label v-if=\"control.label\" class=\"text-color text-left\">{{\n control.label\n }}</label>\n <div v-if=\"control.description\" class=\"text-color-secondary text-left\">\n {{ control.description }}\n </div>\n <Dropdown\n class=\"w-full\"\n :options=\"options\"\n option-label=\"label\"\n option-value=\"value\"\n :model-value=\"control.data ?? null\"\n :placeholder=\"placeholder\"\n :disabled=\"!control.enabled\"\n :aria-invalid=\"!!showErrors || undefined\"\n :show-clear=\"true\"\n @update:model-value=\"onSelect\"\n @blur=\"onBlur\"\n />\n <small v-if=\"showErrors\" class=\"p-error\">{{ control.errors }}</small>\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":";;;;;;;;;;;;;;;;;;;;;AAQA,UAAM,QAAQ;AACd,UAAM,EAAE,SAAS,iBAAiB,oBAAoB,KAAK;AAG3D,UAAM,YAAY,CAAC,WAA+B;AAChD,UAAI,CAAC,OAAQ,QAAO,CAAA;AACpB,YAAM,IAAI;AAIV,UAAI,MAAM,QAAQ,EAAE,IAAI;AACtB,eAAO,EAAE,KAAK,IAAI,CAAC,OAAgB,EAAE,OAAO,OAAO,CAAC,GAAG,OAAO,EAAA,EAAI;AACpE,UAAI,MAAM,QAAQ,EAAE,KAAK;AACvB,eAAO,EAAE,MAAM,IAAI,CAAC,OAAO;AAAA,UACzB,OAAO,EAAE,SAAS,OAAO,EAAE,KAAK;AAAA,UAChC,OAAO,EAAE;AAAA,QAAA,EACT;AACJ,aAAO,CAAA;AAAA,IACT;AAEA,UAAM,cAAc;AAAA,MAClB,MACG,QAAQ,MAAM,UAAqD,SAChE,eAAe,QAAQ,MAAM;AAAA,IAAA;AAGrC,UAAM,UAAU,SAAS,MAAM,UAAU,QAAQ,MAAM,MAAM,CAAC;AAG9D,UAAM,gBAAgB,IAAI,KAAK;AAE/B,UAAM,aAAa,SAAS,MAAM,cAAc,SAAS,QAAQ,MAAM,MAAM;AAE7E,UAAM,WAAW,CAAC,QAAiB;AACjC,mBAAa,QAAQ,MAAM,MAAM,GAAG;AAAA,IACtC;AAEA,UAAM,SAAS,MAAM;AACnB,oBAAc,QAAQ;AAAA,IACxB;;AAIE,aAAAA,UAAA,GAAAC,mBAqBM,OArBN,YAqBM;AAAA,QApBSC,MAAA,OAAA,EAAQ,SAArBF,UAAA,GAAAC,mBAEU,SAFV,YAEUE,gBADRD,MAAA,OAAA,EAAQ,KAAK,GAAA,CAAA;QAEJA,MAAA,OAAA,EAAQ,eAAnBF,UAAA,GAAAC,mBAEM,OAFN,YAEME,gBADDD,MAAA,OAAA,EAAQ,WAAW,GAAA,CAAA;QAExBE,YAYEF,MAAA,QAAA,GAAA;AAAA,UAXA,OAAM;AAAA,UACL,SAAS,QAAA;AAAA,UACV,gBAAa;AAAA,UACb,gBAAa;AAAA,UACZ,eAAaA,MAAA,OAAA,EAAQ,QAAI;AAAA,UACzB,aAAa,YAAA;AAAA,UACb,UAAQ,CAAGA,MAAA,OAAA,EAAQ;AAAA,UACnB,gBAAY,CAAA,CAAI,WAAA,SAAc;AAAA,UAC9B,cAAY;AAAA,UACZ,uBAAoB;AAAA,UACpB;AAAA,QAAA;QAEU,WAAA,SAAbF,UAAA,GAAAC,mBAAqE,SAArE,YAAqEE,gBAAzBD,MAAA,OAAA,EAAQ,MAAM,GAAA,CAAA;;;;;"}
|
|
@@ -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":"AA+FA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+LtD,wBAEG"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { defineComponent, computed, createElementBlock, openBlock, createCommentVNode, createVNode, unref, toDisplayString } from "vue";
|
|
1
|
+
import { defineComponent, computed, ref, createElementBlock, openBlock, createCommentVNode, createVNode, unref, toDisplayString } from "vue";
|
|
2
2
|
import { rendererProps, useJsonFormsControl } from "@jsonforms/vue";
|
|
3
3
|
import InputNumber from "primevue/inputnumber";
|
|
4
4
|
const _hoisted_1 = { class: "flex flex-column gap-2" };
|
|
@@ -21,10 +21,45 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
21
21
|
setup(__props) {
|
|
22
22
|
const props = __props;
|
|
23
23
|
const { control, handleChange } = useJsonFormsControl(props);
|
|
24
|
+
const options = computed(
|
|
25
|
+
() => control.value.uischema?.options ?? {}
|
|
26
|
+
);
|
|
24
27
|
const placeholder = computed(
|
|
25
|
-
() =>
|
|
28
|
+
() => options.value.placeholder ?? control.value.description
|
|
29
|
+
);
|
|
30
|
+
const mode = computed(() => {
|
|
31
|
+
if (options.value.currency) return "currency";
|
|
32
|
+
if (options.value.decimal || typeof options.value.precision === "number")
|
|
33
|
+
return "decimal";
|
|
34
|
+
return void 0;
|
|
35
|
+
});
|
|
36
|
+
const currency = computed(
|
|
37
|
+
() => typeof options.value.currency === "string" ? options.value.currency : "USD"
|
|
26
38
|
);
|
|
27
|
-
const
|
|
39
|
+
const minFractionDigits = computed(() => {
|
|
40
|
+
if (mode.value === "currency") return 2;
|
|
41
|
+
if (typeof options.value.precision === "number")
|
|
42
|
+
return options.value.precision;
|
|
43
|
+
return void 0;
|
|
44
|
+
});
|
|
45
|
+
const maxFractionDigits = computed(() => {
|
|
46
|
+
if (mode.value === "currency") return 2;
|
|
47
|
+
if (typeof options.value.precision === "number")
|
|
48
|
+
return options.value.precision;
|
|
49
|
+
return void 0;
|
|
50
|
+
});
|
|
51
|
+
const useGrouping = computed(() => {
|
|
52
|
+
if (mode.value === "currency") return true;
|
|
53
|
+
return options.value.useGrouping === true;
|
|
54
|
+
});
|
|
55
|
+
const hasInteracted = ref(false);
|
|
56
|
+
const showErrors = computed(() => hasInteracted.value && control.value.errors);
|
|
57
|
+
const onNumber = (val) => {
|
|
58
|
+
handleChange(control.value.path, val ?? void 0);
|
|
59
|
+
};
|
|
60
|
+
const onBlur = () => {
|
|
61
|
+
hasInteracted.value = true;
|
|
62
|
+
};
|
|
28
63
|
return (_ctx, _cache) => {
|
|
29
64
|
return openBlock(), createElementBlock("div", _hoisted_1, [
|
|
30
65
|
unref(control).label ? (openBlock(), createElementBlock("label", _hoisted_2, toDisplayString(unref(control).label), 1)) : createCommentVNode("", true),
|
|
@@ -32,14 +67,19 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
32
67
|
createVNode(unref(InputNumber), {
|
|
33
68
|
class: "w-full",
|
|
34
69
|
"input-class": "w-full",
|
|
35
|
-
"use-grouping":
|
|
70
|
+
"use-grouping": useGrouping.value,
|
|
71
|
+
mode: mode.value,
|
|
72
|
+
currency: currency.value,
|
|
73
|
+
"min-fraction-digits": minFractionDigits.value,
|
|
74
|
+
"max-fraction-digits": maxFractionDigits.value,
|
|
36
75
|
"model-value": typeof unref(control).data === "number" ? unref(control).data : null,
|
|
37
76
|
placeholder: placeholder.value,
|
|
38
77
|
disabled: !unref(control).enabled,
|
|
39
|
-
"aria-invalid": !!
|
|
40
|
-
"onUpdate:modelValue": onNumber
|
|
41
|
-
|
|
42
|
-
|
|
78
|
+
"aria-invalid": !!showErrors.value || void 0,
|
|
79
|
+
"onUpdate:modelValue": onNumber,
|
|
80
|
+
onBlur
|
|
81
|
+
}, null, 8, ["use-grouping", "mode", "currency", "min-fraction-digits", "max-fraction-digits", "model-value", "placeholder", "disabled", "aria-invalid"]),
|
|
82
|
+
showErrors.value ? (openBlock(), createElementBlock("small", _hoisted_4, toDisplayString(unref(control).errors), 1)) : createCommentVNode("", true)
|
|
43
83
|
]);
|
|
44
84
|
};
|
|
45
85
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JfNumber.vue.js","sources":["../../../src/vue/primevue/JfNumber.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { ControlElement } from \"@jsonforms/core\";\nimport { rendererProps, useJsonFormsControl } from \"@jsonforms/vue\";\nimport { computed } from \"vue\";\nimport InputNumber from \"primevue/inputnumber\";\n\ndefineOptions({ name: \"JfNumber\" });\n\nconst props = defineProps(rendererProps<ControlElement>());\nconst { control, handleChange } = useJsonFormsControl(props);\n\nconst
|
|
1
|
+
{"version":3,"file":"JfNumber.vue.js","sources":["../../../src/vue/primevue/JfNumber.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { ControlElement } from \"@jsonforms/core\";\nimport { rendererProps, useJsonFormsControl } from \"@jsonforms/vue\";\nimport { computed, ref } from \"vue\";\nimport InputNumber from \"primevue/inputnumber\";\n\ndefineOptions({ name: \"JfNumber\" });\n\nconst props = defineProps(rendererProps<ControlElement>());\nconst { control, handleChange } = useJsonFormsControl(props);\n\nconst options = computed(\n () =>\n (control.value.uischema as { options?: Record<string, unknown> })\n ?.options ?? {},\n);\n\nconst placeholder = computed<string | undefined>(\n () => (options.value.placeholder as string) ?? control.value.description,\n);\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 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 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\nconst hasInteracted = ref(false);\n\nconst showErrors = computed(() => hasInteracted.value && control.value.errors);\n\nconst onNumber = (val: number | null) => {\n handleChange(control.value.path, val ?? undefined);\n};\n\nconst onBlur = () => {\n hasInteracted.value = true;\n};\n</script>\n\n<template>\n <div class=\"flex flex-column gap-2\">\n <label v-if=\"control.label\" class=\"text-color text-left\">{{\n control.label\n }}</label>\n <div v-if=\"control.description\" class=\"text-color-secondary text-left\">\n {{ control.description }}\n </div>\n <InputNumber\n class=\"w-full\"\n input-class=\"w-full\"\n :use-grouping=\"useGrouping\"\n :mode=\"mode\"\n :currency=\"currency\"\n :min-fraction-digits=\"minFractionDigits\"\n :max-fraction-digits=\"maxFractionDigits\"\n :model-value=\"typeof control.data === 'number' ? control.data : null\"\n :placeholder=\"placeholder\"\n :disabled=\"!control.enabled\"\n :aria-invalid=\"!!showErrors || undefined\"\n @update:model-value=\"onNumber\"\n @blur=\"onBlur\"\n />\n <small v-if=\"showErrors\" class=\"p-error\">{{ control.errors }}</small>\n </div>\n</template>\n"],"names":["_openBlock","_createElementBlock","_unref","_toDisplayString","_createVNode"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAQA,UAAM,QAAQ;AACd,UAAM,EAAE,SAAS,iBAAiB,oBAAoB,KAAK;AAE3D,UAAM,UAAU;AAAA,MACd,MACG,QAAQ,MAAM,UACX,WAAW,CAAA;AAAA,IAAC;AAGpB,UAAM,cAAc;AAAA,MAClB,MAAO,QAAQ,MAAM,eAA0B,QAAQ,MAAM;AAAA,IAAA;AAI/D,UAAM,OAAO,SAAS,MAAM;AAC1B,UAAI,QAAQ,MAAM,SAAU,QAAO;AACnC,UAAI,QAAQ,MAAM,WAAW,OAAO,QAAQ,MAAM,cAAc;AAC9D,eAAO;AACT,aAAO;AAAA,IACT,CAAC;AAED,UAAM,WAAW;AAAA,MAAS,MACxB,OAAO,QAAQ,MAAM,aAAa,WAAW,QAAQ,MAAM,WAAW;AAAA,IAAA;AAGxE,UAAM,oBAAoB,SAAS,MAAM;AACvC,UAAI,KAAK,UAAU,WAAY,QAAO;AACtC,UAAI,OAAO,QAAQ,MAAM,cAAc;AACrC,eAAO,QAAQ,MAAM;AACvB,aAAO;AAAA,IACT,CAAC;AAED,UAAM,oBAAoB,SAAS,MAAM;AACvC,UAAI,KAAK,UAAU,WAAY,QAAO;AACtC,UAAI,OAAO,QAAQ,MAAM,cAAc;AACrC,eAAO,QAAQ,MAAM;AACvB,aAAO;AAAA,IACT,CAAC;AAED,UAAM,cAAc,SAAS,MAAM;AAEjC,UAAI,KAAK,UAAU,WAAY,QAAO;AACtC,aAAO,QAAQ,MAAM,gBAAgB;AAAA,IACvC,CAAC;AAGD,UAAM,gBAAgB,IAAI,KAAK;AAE/B,UAAM,aAAa,SAAS,MAAM,cAAc,SAAS,QAAQ,MAAM,MAAM;AAE7E,UAAM,WAAW,CAAC,QAAuB;AACvC,mBAAa,QAAQ,MAAM,MAAM,OAAO,MAAS;AAAA,IACnD;AAEA,UAAM,SAAS,MAAM;AACnB,oBAAc,QAAQ;AAAA,IACxB;;AAIE,aAAAA,UAAA,GAAAC,mBAuBM,OAvBN,YAuBM;AAAA,QAtBSC,MAAA,OAAA,EAAQ,SAArBF,UAAA,GAAAC,mBAEU,SAFV,YAEUE,gBADRD,MAAA,OAAA,EAAQ,KAAK,GAAA,CAAA;QAEJA,MAAA,OAAA,EAAQ,eAAnBF,UAAA,GAAAC,mBAEM,OAFN,YAEME,gBADDD,MAAA,OAAA,EAAQ,WAAW,GAAA,CAAA;QAExBE,YAcEF,MAAA,WAAA,GAAA;AAAA,UAbA,OAAM;AAAA,UACN,eAAY;AAAA,UACX,gBAAc,YAAA;AAAA,UACd,MAAM,KAAA;AAAA,UACN,UAAU,SAAA;AAAA,UACV,uBAAqB,kBAAA;AAAA,UACrB,uBAAqB,kBAAA;AAAA,UACrB,sBAAoBA,MAAA,OAAA,EAAQ,SAAI,WAAgBA,MAAA,OAAA,EAAQ,OAAI;AAAA,UAC5D,aAAa,YAAA;AAAA,UACb,UAAQ,CAAGA,MAAA,OAAA,EAAQ;AAAA,UACnB,gBAAY,CAAA,CAAI,WAAA,SAAc;AAAA,UAC9B,uBAAoB;AAAA,UACpB;AAAA,QAAA;QAEU,WAAA,SAAbF,UAAA,GAAAC,mBAAqE,SAArE,YAAqEE,gBAAzBD,MAAA,OAAA,EAAQ,MAAM,GAAA,CAAA;;;;;"}
|
|
@@ -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":"AAoEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiKtD,wBAEG"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { defineComponent, computed, createElementBlock, openBlock, createCommentVNode, createVNode, unref, toDisplayString } from "vue";
|
|
1
|
+
import { defineComponent, computed, ref, createElementBlock, openBlock, createCommentVNode, createVNode, unref, toDisplayString } from "vue";
|
|
2
2
|
import { rendererProps, useJsonFormsControl } from "@jsonforms/vue";
|
|
3
3
|
import InputText from "primevue/inputtext";
|
|
4
4
|
const _hoisted_1 = { class: "flex flex-column gap-2" };
|
|
@@ -24,12 +24,23 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
24
24
|
const placeholder = computed(
|
|
25
25
|
() => control.value.uischema?.options?.placeholder ?? control.value.description
|
|
26
26
|
);
|
|
27
|
+
const hasInteracted = ref(false);
|
|
28
|
+
const hasFocused = ref(false);
|
|
29
|
+
const showErrors = computed(() => hasInteracted.value && control.value.errors);
|
|
27
30
|
function onInput(val) {
|
|
28
|
-
const newValue = val
|
|
29
|
-
if (
|
|
31
|
+
const newValue = val && val.trim() !== "" ? val : void 0;
|
|
32
|
+
if (control.value.data !== newValue) {
|
|
30
33
|
handleChange(control.value.path, newValue);
|
|
31
34
|
}
|
|
32
35
|
}
|
|
36
|
+
function onBlur() {
|
|
37
|
+
if (hasFocused.value) {
|
|
38
|
+
hasInteracted.value = true;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function onFocus() {
|
|
42
|
+
hasFocused.value = true;
|
|
43
|
+
}
|
|
33
44
|
return (_ctx, _cache) => {
|
|
34
45
|
return openBlock(), createElementBlock("div", _hoisted_1, [
|
|
35
46
|
unref(control).label ? (openBlock(), createElementBlock("label", _hoisted_2, toDisplayString(unref(control).label), 1)) : createCommentVNode("", true),
|
|
@@ -38,14 +49,16 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
38
49
|
class: "w-full",
|
|
39
50
|
"model-value": unref(control).data ?? "",
|
|
40
51
|
disabled: !unref(control).enabled,
|
|
41
|
-
"aria-invalid": !!
|
|
52
|
+
"aria-invalid": !!showErrors.value || void 0,
|
|
42
53
|
placeholder: placeholder.value,
|
|
43
54
|
autocapitalize: "off",
|
|
44
55
|
autocomplete: "off",
|
|
45
56
|
spellcheck: "false",
|
|
46
|
-
"onUpdate:modelValue": onInput
|
|
57
|
+
"onUpdate:modelValue": onInput,
|
|
58
|
+
onBlur,
|
|
59
|
+
onFocus
|
|
47
60
|
}, null, 8, ["model-value", "disabled", "aria-invalid", "placeholder"]),
|
|
48
|
-
|
|
61
|
+
showErrors.value ? (openBlock(), createElementBlock("small", _hoisted_4, toDisplayString(unref(control).errors), 1)) : createCommentVNode("", true)
|
|
49
62
|
]);
|
|
50
63
|
};
|
|
51
64
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JfText.vue.js","sources":["../../../src/vue/primevue/JfText.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { ControlElement } from \"@jsonforms/core\";\nimport { rendererProps, useJsonFormsControl } from \"@jsonforms/vue\";\nimport { computed } from \"vue\";\nimport InputText from \"primevue/inputtext\";\n\ndefineOptions({ name: \"JfText\" });\n\nconst props = defineProps(rendererProps<ControlElement>());\nconst { control, handleChange } = useJsonFormsControl(props);\n\nconst placeholder = computed<string | undefined>(\n () =>\n (control.value.uischema as { options?: { placeholder?: string } })?.options\n ?.placeholder ?? control.value.description,\n);\n\nfunction onInput(val: string | undefined) {\n const newValue = val
|
|
1
|
+
{"version":3,"file":"JfText.vue.js","sources":["../../../src/vue/primevue/JfText.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { ControlElement } from \"@jsonforms/core\";\nimport { rendererProps, useJsonFormsControl } from \"@jsonforms/vue\";\nimport { computed, ref } from \"vue\";\nimport InputText from \"primevue/inputtext\";\n\ndefineOptions({ name: \"JfText\" });\n\nconst props = defineProps(rendererProps<ControlElement>());\nconst { control, handleChange } = useJsonFormsControl(props);\n\nconst placeholder = computed<string | undefined>(\n () =>\n (control.value.uischema as { options?: { placeholder?: string } })?.options\n ?.placeholder ?? control.value.description,\n);\n\n// Track user interaction\nconst hasInteracted = ref(false);\nconst hasFocused = ref(false);\n\nconst showErrors = computed(() => hasInteracted.value && control.value.errors);\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 (control.value.data !== newValue) {\n handleChange(control.value.path, newValue);\n }\n}\n\nfunction onBlur() {\n if (hasFocused.value) {\n hasInteracted.value = true;\n }\n}\n\nfunction onFocus() {\n hasFocused.value = true;\n}\n</script>\n\n<template>\n <div class=\"flex flex-column gap-2\">\n <label v-if=\"control.label\" class=\"text-color text-left\">{{\n control.label\n }}</label>\n <div v-if=\"control.description\" class=\"text-color-secondary text-left\">\n {{ control.description }}\n </div>\n <InputText\n class=\"w-full\"\n :model-value=\"control.data ?? ''\"\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 @focus=\"onFocus\"\n />\n <small v-if=\"showErrors\" class=\"p-error\">{{ control.errors }}</small>\n </div>\n</template>\n"],"names":["_openBlock","_createElementBlock","_unref","_toDisplayString","_createVNode"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAQA,UAAM,QAAQ;AACd,UAAM,EAAE,SAAS,iBAAiB,oBAAoB,KAAK;AAE3D,UAAM,cAAc;AAAA,MAClB,MACG,QAAQ,MAAM,UAAqD,SAChE,eAAe,QAAQ,MAAM;AAAA,IAAA;AAIrC,UAAM,gBAAgB,IAAI,KAAK;AAC/B,UAAM,aAAa,IAAI,KAAK;AAE5B,UAAM,aAAa,SAAS,MAAM,cAAc,SAAS,QAAQ,MAAM,MAAM;AAE7E,aAAS,QAAQ,KAAyB;AAExC,YAAM,WAAW,OAAO,IAAI,KAAA,MAAW,KAAK,MAAM;AAClD,UAAI,QAAQ,MAAM,SAAS,UAAU;AACnC,qBAAa,QAAQ,MAAM,MAAM,QAAQ;AAAA,MAC3C;AAAA,IACF;AAEA,aAAS,SAAS;AAChB,UAAI,WAAW,OAAO;AACpB,sBAAc,QAAQ;AAAA,MACxB;AAAA,IACF;AAEA,aAAS,UAAU;AACjB,iBAAW,QAAQ;AAAA,IACrB;;AAIE,aAAAA,UAAA,GAAAC,mBAqBM,OArBN,YAqBM;AAAA,QApBSC,MAAA,OAAA,EAAQ,SAArBF,UAAA,GAAAC,mBAEU,SAFV,YAEUE,gBADRD,MAAA,OAAA,EAAQ,KAAK,GAAA,CAAA;QAEJA,MAAA,OAAA,EAAQ,eAAnBF,UAAA,GAAAC,mBAEM,OAFN,YAEME,gBADDD,MAAA,OAAA,EAAQ,WAAW,GAAA,CAAA;QAExBE,YAYEF,MAAA,SAAA,GAAA;AAAA,UAXA,OAAM;AAAA,UACL,eAAaA,MAAA,OAAA,EAAQ,QAAI;AAAA,UACzB,UAAQ,CAAGA,MAAA,OAAA,EAAQ;AAAA,UACnB,gBAAY,CAAA,CAAI,WAAA,SAAc;AAAA,UAC9B,aAAa,YAAA;AAAA,UACd,gBAAe;AAAA,UACf,cAAa;AAAA,UACb,YAAW;AAAA,UACV,uBAAoB;AAAA,UACpB;AAAA,UACA;AAAA,QAAA;QAEU,WAAA,SAAbF,UAAA,GAAAC,mBAAqE,SAArE,YAAqEE,gBAAzBD,MAAA,OAAA,EAAQ,MAAM,GAAA,CAAA;;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JfTextArea.vue.d.ts","sourceRoot":"","sources":["../../../src/vue/primevue/JfTextArea.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"JfTextArea.vue.d.ts","sourceRoot":"","sources":["../../../src/vue/primevue/JfTextArea.vue"],"names":[],"mappings":"AA2DA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkJtD,wBAEG"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { defineComponent, computed, createElementBlock, openBlock, createCommentVNode, createVNode, unref, toDisplayString } from "vue";
|
|
1
|
+
import { defineComponent, computed, ref, createElementBlock, openBlock, createCommentVNode, createVNode, unref, toDisplayString } from "vue";
|
|
2
2
|
import { rendererProps, useJsonFormsControl } from "@jsonforms/vue";
|
|
3
3
|
import Textarea from "primevue/textarea";
|
|
4
4
|
const _hoisted_1 = { class: "flex flex-column gap-2" };
|
|
@@ -24,12 +24,17 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
24
24
|
const placeholder = computed(
|
|
25
25
|
() => control.value.uischema?.options?.placeholder ?? control.value.description
|
|
26
26
|
);
|
|
27
|
+
const hasInteracted = ref(false);
|
|
28
|
+
const showErrors = computed(() => hasInteracted.value && control.value.errors);
|
|
27
29
|
function onInput(val) {
|
|
28
|
-
const newValue = val
|
|
29
|
-
if (
|
|
30
|
+
const newValue = val && val.trim() !== "" ? val : void 0;
|
|
31
|
+
if (control.value.data !== newValue) {
|
|
30
32
|
handleChange(control.value.path, newValue);
|
|
31
33
|
}
|
|
32
34
|
}
|
|
35
|
+
function onBlur() {
|
|
36
|
+
hasInteracted.value = true;
|
|
37
|
+
}
|
|
33
38
|
return (_ctx, _cache) => {
|
|
34
39
|
return openBlock(), createElementBlock("div", _hoisted_1, [
|
|
35
40
|
unref(control).label ? (openBlock(), createElementBlock("label", _hoisted_2, toDisplayString(unref(control).label), 1)) : createCommentVNode("", true),
|
|
@@ -38,13 +43,14 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
38
43
|
class: "w-full",
|
|
39
44
|
"model-value": unref(control).data ?? "",
|
|
40
45
|
disabled: !unref(control).enabled,
|
|
41
|
-
"aria-invalid": !!
|
|
46
|
+
"aria-invalid": !!showErrors.value || void 0,
|
|
42
47
|
placeholder: placeholder.value,
|
|
43
48
|
rows: 4,
|
|
44
49
|
"auto-resize": true,
|
|
45
|
-
"onUpdate:modelValue": onInput
|
|
50
|
+
"onUpdate:modelValue": onInput,
|
|
51
|
+
onBlur
|
|
46
52
|
}, null, 8, ["model-value", "disabled", "aria-invalid", "placeholder"]),
|
|
47
|
-
|
|
53
|
+
showErrors.value ? (openBlock(), createElementBlock("small", _hoisted_4, toDisplayString(unref(control).errors), 1)) : createCommentVNode("", true)
|
|
48
54
|
]);
|
|
49
55
|
};
|
|
50
56
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JfTextArea.vue.js","sources":["../../../src/vue/primevue/JfTextArea.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { ControlElement } from \"@jsonforms/core\";\nimport { rendererProps, useJsonFormsControl } from \"@jsonforms/vue\";\nimport { computed } from \"vue\";\nimport Textarea from \"primevue/textarea\";\n\ndefineOptions({ name: \"JfTextArea\" });\n\nconst props = defineProps(rendererProps<ControlElement>());\nconst { control, handleChange } = useJsonFormsControl(props);\n\nconst placeholder = computed<string | undefined>(\n () =>\n (control.value.uischema as { options?: { placeholder?: string } })?.options\n ?.placeholder ?? control.value.description,\n);\n\nfunction onInput(val: string | undefined) {\n const newValue = val
|
|
1
|
+
{"version":3,"file":"JfTextArea.vue.js","sources":["../../../src/vue/primevue/JfTextArea.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { ControlElement } from \"@jsonforms/core\";\nimport { rendererProps, useJsonFormsControl } from \"@jsonforms/vue\";\nimport { computed, ref } from \"vue\";\nimport Textarea from \"primevue/textarea\";\n\ndefineOptions({ name: \"JfTextArea\" });\n\nconst props = defineProps(rendererProps<ControlElement>());\nconst { control, handleChange } = useJsonFormsControl(props);\n\nconst placeholder = computed<string | undefined>(\n () =>\n (control.value.uischema as { options?: { placeholder?: string } })?.options\n ?.placeholder ?? control.value.description,\n);\n\n// Track user interaction\nconst hasInteracted = ref(false);\n\nconst showErrors = computed(() => hasInteracted.value && control.value.errors);\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 (control.value.data !== newValue) {\n handleChange(control.value.path, newValue);\n }\n}\n\nfunction onBlur() {\n hasInteracted.value = true;\n}\n</script>\n\n<template>\n <div class=\"flex flex-column gap-2\">\n <label v-if=\"control.label\" class=\"text-color text-left\">{{\n control.label\n }}</label>\n <div v-if=\"control.description\" class=\"text-color-secondary text-left\">\n {{ control.description }}\n </div>\n <Textarea\n class=\"w-full\"\n :model-value=\"control.data ?? ''\"\n :disabled=\"!control.enabled\"\n :aria-invalid=\"!!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\">{{ control.errors }}</small>\n </div>\n</template>\n"],"names":["_openBlock","_createElementBlock","_unref","_toDisplayString","_createVNode"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAQA,UAAM,QAAQ;AACd,UAAM,EAAE,SAAS,iBAAiB,oBAAoB,KAAK;AAE3D,UAAM,cAAc;AAAA,MAClB,MACG,QAAQ,MAAM,UAAqD,SAChE,eAAe,QAAQ,MAAM;AAAA,IAAA;AAIrC,UAAM,gBAAgB,IAAI,KAAK;AAE/B,UAAM,aAAa,SAAS,MAAM,cAAc,SAAS,QAAQ,MAAM,MAAM;AAE7E,aAAS,QAAQ,KAAyB;AAExC,YAAM,WAAW,OAAO,IAAI,KAAA,MAAW,KAAK,MAAM;AAClD,UAAI,QAAQ,MAAM,SAAS,UAAU;AACnC,qBAAa,QAAQ,MAAM,MAAM,QAAQ;AAAA,MAC3C;AAAA,IACF;AAEA,aAAS,SAAS;AAChB,oBAAc,QAAQ;AAAA,IACxB;;AAIE,aAAAA,UAAA,GAAAC,mBAmBM,OAnBN,YAmBM;AAAA,QAlBSC,MAAA,OAAA,EAAQ,SAArBF,UAAA,GAAAC,mBAEU,SAFV,YAEUE,gBADRD,MAAA,OAAA,EAAQ,KAAK,GAAA,CAAA;QAEJA,MAAA,OAAA,EAAQ,eAAnBF,UAAA,GAAAC,mBAEM,OAFN,YAEME,gBADDD,MAAA,OAAA,EAAQ,WAAW,GAAA,CAAA;QAExBE,YAUEF,MAAA,QAAA,GAAA;AAAA,UATA,OAAM;AAAA,UACL,eAAaA,MAAA,OAAA,EAAQ,QAAI;AAAA,UACzB,UAAQ,CAAGA,MAAA,OAAA,EAAQ;AAAA,UACnB,gBAAY,CAAA,CAAI,WAAA,SAAc;AAAA,UAC9B,aAAa,YAAA;AAAA,UACb,MAAM;AAAA,UACN,eAAa;AAAA,UACb,uBAAoB;AAAA,UACpB;AAAA,QAAA;QAEU,WAAA,SAAbF,UAAA,GAAAC,mBAAqE,SAArE,YAAqEE,gBAAzBD,MAAA,OAAA,EAAQ,MAAM,GAAA,CAAA;;;;;"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import type { ControlElement, JsonSchema } from "@jsonforms/core";
|
|
3
3
|
import { rendererProps, useJsonFormsControl } from "@jsonforms/vue";
|
|
4
|
-
import { computed } from "vue";
|
|
4
|
+
import { computed, ref } from "vue";
|
|
5
5
|
import Dropdown from "primevue/dropdown";
|
|
6
6
|
|
|
7
7
|
defineOptions({ name: "JfEnum" });
|
|
@@ -33,7 +33,19 @@ const placeholder = computed<string | undefined>(
|
|
|
33
33
|
);
|
|
34
34
|
|
|
35
35
|
const options = computed(() => toOptions(control.value.schema));
|
|
36
|
-
|
|
36
|
+
|
|
37
|
+
// Track user interaction
|
|
38
|
+
const hasInteracted = ref(false);
|
|
39
|
+
|
|
40
|
+
const showErrors = computed(() => hasInteracted.value && control.value.errors);
|
|
41
|
+
|
|
42
|
+
const onSelect = (val: unknown) => {
|
|
43
|
+
handleChange(control.value.path, val);
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const onBlur = () => {
|
|
47
|
+
hasInteracted.value = true;
|
|
48
|
+
};
|
|
37
49
|
</script>
|
|
38
50
|
|
|
39
51
|
<template>
|
|
@@ -52,11 +64,12 @@ const onSelect = (val: unknown) => handleChange(control.value.path, val);
|
|
|
52
64
|
:model-value="control.data ?? null"
|
|
53
65
|
:placeholder="placeholder"
|
|
54
66
|
:disabled="!control.enabled"
|
|
55
|
-
:aria-invalid="!!
|
|
67
|
+
:aria-invalid="!!showErrors || undefined"
|
|
56
68
|
:show-clear="true"
|
|
57
69
|
@update:model-value="onSelect"
|
|
70
|
+
@blur="onBlur"
|
|
58
71
|
/>
|
|
59
|
-
<small v-if="
|
|
72
|
+
<small v-if="showErrors" class="p-error">{{ control.errors }}</small>
|
|
60
73
|
</div>
|
|
61
74
|
</template>
|
|
62
75
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import type { ControlElement } from "@jsonforms/core";
|
|
3
3
|
import { rendererProps, useJsonFormsControl } from "@jsonforms/vue";
|
|
4
|
-
import { computed } from "vue";
|
|
4
|
+
import { computed, ref } from "vue";
|
|
5
5
|
import InputNumber from "primevue/inputnumber";
|
|
6
6
|
|
|
7
7
|
defineOptions({ name: "JfNumber" });
|
|
@@ -9,14 +9,60 @@ defineOptions({ name: "JfNumber" });
|
|
|
9
9
|
const props = defineProps(rendererProps<ControlElement>());
|
|
10
10
|
const { control, handleChange } = useJsonFormsControl(props);
|
|
11
11
|
|
|
12
|
-
const
|
|
12
|
+
const options = computed(
|
|
13
13
|
() =>
|
|
14
|
-
(control.value.uischema as { options?:
|
|
15
|
-
?.
|
|
14
|
+
(control.value.uischema as { options?: Record<string, unknown> })
|
|
15
|
+
?.options ?? {},
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
const placeholder = computed<string | undefined>(
|
|
19
|
+
() => (options.value.placeholder as string) ?? control.value.description,
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
// Currency and decimal configuration
|
|
23
|
+
const mode = computed(() => {
|
|
24
|
+
if (options.value.currency) return "currency";
|
|
25
|
+
if (options.value.decimal || typeof options.value.precision === "number")
|
|
26
|
+
return "decimal";
|
|
27
|
+
return undefined;
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
const currency = computed(() =>
|
|
31
|
+
typeof options.value.currency === "string" ? options.value.currency : "USD",
|
|
16
32
|
);
|
|
17
33
|
|
|
18
|
-
const
|
|
34
|
+
const minFractionDigits = computed(() => {
|
|
35
|
+
if (mode.value === "currency") return 2;
|
|
36
|
+
if (typeof options.value.precision === "number")
|
|
37
|
+
return options.value.precision;
|
|
38
|
+
return undefined;
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
const maxFractionDigits = computed(() => {
|
|
42
|
+
if (mode.value === "currency") return 2;
|
|
43
|
+
if (typeof options.value.precision === "number")
|
|
44
|
+
return options.value.precision;
|
|
45
|
+
return undefined;
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
const useGrouping = computed(() => {
|
|
49
|
+
// Enable grouping for currency by default, or if explicitly set
|
|
50
|
+
if (mode.value === "currency") return true;
|
|
51
|
+
return options.value.useGrouping === true;
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
// Track user interaction
|
|
55
|
+
const hasInteracted = ref(false);
|
|
56
|
+
|
|
57
|
+
const showErrors = computed(() => hasInteracted.value && control.value.errors);
|
|
58
|
+
|
|
59
|
+
const onNumber = (val: number | null) => {
|
|
19
60
|
handleChange(control.value.path, val ?? undefined);
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const onBlur = () => {
|
|
64
|
+
hasInteracted.value = true;
|
|
65
|
+
};
|
|
20
66
|
</script>
|
|
21
67
|
|
|
22
68
|
<template>
|
|
@@ -30,13 +76,18 @@ const onNumber = (val: number | null) =>
|
|
|
30
76
|
<InputNumber
|
|
31
77
|
class="w-full"
|
|
32
78
|
input-class="w-full"
|
|
33
|
-
:use-grouping="
|
|
79
|
+
:use-grouping="useGrouping"
|
|
80
|
+
:mode="mode"
|
|
81
|
+
:currency="currency"
|
|
82
|
+
:min-fraction-digits="minFractionDigits"
|
|
83
|
+
:max-fraction-digits="maxFractionDigits"
|
|
34
84
|
:model-value="typeof control.data === 'number' ? control.data : null"
|
|
35
85
|
:placeholder="placeholder"
|
|
36
86
|
:disabled="!control.enabled"
|
|
37
|
-
:aria-invalid="!!
|
|
87
|
+
:aria-invalid="!!showErrors || undefined"
|
|
38
88
|
@update:model-value="onNumber"
|
|
89
|
+
@blur="onBlur"
|
|
39
90
|
/>
|
|
40
|
-
<small v-if="
|
|
91
|
+
<small v-if="showErrors" class="p-error">{{ control.errors }}</small>
|
|
41
92
|
</div>
|
|
42
93
|
</template>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import type { ControlElement } from "@jsonforms/core";
|
|
3
3
|
import { rendererProps, useJsonFormsControl } from "@jsonforms/vue";
|
|
4
|
-
import { computed } from "vue";
|
|
4
|
+
import { computed, ref } from "vue";
|
|
5
5
|
import InputText from "primevue/inputtext";
|
|
6
6
|
|
|
7
7
|
defineOptions({ name: "JfText" });
|
|
@@ -15,12 +15,29 @@ const placeholder = computed<string | undefined>(
|
|
|
15
15
|
?.placeholder ?? control.value.description,
|
|
16
16
|
);
|
|
17
17
|
|
|
18
|
+
// Track user interaction
|
|
19
|
+
const hasInteracted = ref(false);
|
|
20
|
+
const hasFocused = ref(false);
|
|
21
|
+
|
|
22
|
+
const showErrors = computed(() => hasInteracted.value && control.value.errors);
|
|
23
|
+
|
|
18
24
|
function onInput(val: string | undefined) {
|
|
19
|
-
|
|
20
|
-
|
|
25
|
+
// Convert empty strings to undefined for proper required field validation
|
|
26
|
+
const newValue = val && val.trim() !== "" ? val : undefined;
|
|
27
|
+
if (control.value.data !== newValue) {
|
|
21
28
|
handleChange(control.value.path, newValue);
|
|
22
29
|
}
|
|
23
30
|
}
|
|
31
|
+
|
|
32
|
+
function onBlur() {
|
|
33
|
+
if (hasFocused.value) {
|
|
34
|
+
hasInteracted.value = true;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function onFocus() {
|
|
39
|
+
hasFocused.value = true;
|
|
40
|
+
}
|
|
24
41
|
</script>
|
|
25
42
|
|
|
26
43
|
<template>
|
|
@@ -35,13 +52,15 @@ function onInput(val: string | undefined) {
|
|
|
35
52
|
class="w-full"
|
|
36
53
|
:model-value="control.data ?? ''"
|
|
37
54
|
:disabled="!control.enabled"
|
|
38
|
-
:aria-invalid="!!
|
|
55
|
+
:aria-invalid="!!showErrors || undefined"
|
|
39
56
|
:placeholder="placeholder"
|
|
40
57
|
autocapitalize="off"
|
|
41
58
|
autocomplete="off"
|
|
42
59
|
spellcheck="false"
|
|
43
60
|
@update:model-value="onInput"
|
|
61
|
+
@blur="onBlur"
|
|
62
|
+
@focus="onFocus"
|
|
44
63
|
/>
|
|
45
|
-
<small v-if="
|
|
64
|
+
<small v-if="showErrors" class="p-error">{{ control.errors }}</small>
|
|
46
65
|
</div>
|
|
47
66
|
</template>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import type { ControlElement } from "@jsonforms/core";
|
|
3
3
|
import { rendererProps, useJsonFormsControl } from "@jsonforms/vue";
|
|
4
|
-
import { computed } from "vue";
|
|
4
|
+
import { computed, ref } from "vue";
|
|
5
5
|
import Textarea from "primevue/textarea";
|
|
6
6
|
|
|
7
7
|
defineOptions({ name: "JfTextArea" });
|
|
@@ -15,12 +15,22 @@ const placeholder = computed<string | undefined>(
|
|
|
15
15
|
?.placeholder ?? control.value.description,
|
|
16
16
|
);
|
|
17
17
|
|
|
18
|
+
// Track user interaction
|
|
19
|
+
const hasInteracted = ref(false);
|
|
20
|
+
|
|
21
|
+
const showErrors = computed(() => hasInteracted.value && control.value.errors);
|
|
22
|
+
|
|
18
23
|
function onInput(val: string | undefined) {
|
|
19
|
-
|
|
20
|
-
|
|
24
|
+
// Convert empty strings to undefined for proper required field validation
|
|
25
|
+
const newValue = val && val.trim() !== "" ? val : undefined;
|
|
26
|
+
if (control.value.data !== newValue) {
|
|
21
27
|
handleChange(control.value.path, newValue);
|
|
22
28
|
}
|
|
23
29
|
}
|
|
30
|
+
|
|
31
|
+
function onBlur() {
|
|
32
|
+
hasInteracted.value = true;
|
|
33
|
+
}
|
|
24
34
|
</script>
|
|
25
35
|
|
|
26
36
|
<template>
|
|
@@ -35,12 +45,13 @@ function onInput(val: string | undefined) {
|
|
|
35
45
|
class="w-full"
|
|
36
46
|
:model-value="control.data ?? ''"
|
|
37
47
|
:disabled="!control.enabled"
|
|
38
|
-
:aria-invalid="!!
|
|
48
|
+
:aria-invalid="!!showErrors || undefined"
|
|
39
49
|
:placeholder="placeholder"
|
|
40
50
|
:rows="4"
|
|
41
51
|
:auto-resize="true"
|
|
42
52
|
@update:model-value="onInput"
|
|
53
|
+
@blur="onBlur"
|
|
43
54
|
/>
|
|
44
|
-
<small v-if="
|
|
55
|
+
<small v-if="showErrors" class="p-error">{{ control.errors }}</small>
|
|
45
56
|
</div>
|
|
46
57
|
</template>
|