From 4d156d38b6cd3cff47aee75103eeb5dcb89e5cb9 Mon Sep 17 00:00:00 2001 From: Davide Di Pumpo Date: Tue, 9 Dec 2025 21:22:30 +0100 Subject: [PATCH 1/2] fix: unify number type handling and remove int references across components --- .../components/OmegaForm/OmegaFormStuff.ts | 82 ++++++------------- .../OmegaForm/OmegaInputVuetify.vue | 4 +- .../OmegaForm/OmegaInternalInput.vue | 4 +- .../stories/OmegaForm/SimpleForm.vue | 39 +++++---- 4 files changed, 48 insertions(+), 81 deletions(-) diff --git a/packages/vue-components/src/components/OmegaForm/OmegaFormStuff.ts b/packages/vue-components/src/components/OmegaForm/OmegaFormStuff.ts index 27945aa70..09d1ca3ce 100644 --- a/packages/vue-components/src/components/OmegaForm/OmegaFormStuff.ts +++ b/packages/vue-components/src/components/OmegaForm/OmegaFormStuff.ts @@ -246,11 +246,12 @@ export type StringFieldMeta = BaseFieldMeta & { } export type NumberFieldMeta = BaseFieldMeta & { - type: "number" | "int" + type: "number" minimum?: number maximum?: number exclusiveMinimum?: number exclusiveMaximum?: number + refinement?: "int" } export type SelectFieldMeta = BaseFieldMeta & { @@ -682,7 +683,8 @@ export const createMeta = ( // if this is S.Int (a refinement), set the type and skip following "from" // otherwise we'd lose the "Int" information and get "number" instead if (titleType === "Int" || titleType === "int") { - meta["type"] = "int" + meta["type"] = "number" + meta["refinement"] = "int" // don't follow "from" for Int refinements } else if ("from" in property) { return createMeta({ @@ -888,66 +890,28 @@ export const generateInputStandardSchemaFromFieldMeta = ( } break - case "int": { - // create a custom integer schema with translations - // S.Number with empty message, then S.int with integer message - schema = S - .Number - .annotations({ - message: () => trans("validation.empty") - }) - .pipe( - S.int({ message: (issue) => trans("validation.integer.expected", { actualValue: String(issue.actual) }) }) - ) - if (typeof meta.minimum === "number") { - schema = schema.pipe(S.greaterThanOrEqualTo(meta.minimum)).annotations({ - message: () => - trans(meta.minimum === 0 ? "validation.number.positive" : "validation.number.min", { - minimum: meta.minimum, - isExclusive: true - }) - }) - } - if (typeof meta.maximum === "number") { - schema = schema.pipe(S.lessThanOrEqualTo(meta.maximum)).annotations({ - message: () => - trans("validation.number.max", { - maximum: meta.maximum, - isExclusive: true - }) - }) - } - if (typeof meta.exclusiveMinimum === "number") { - schema = schema.pipe(S.greaterThan(meta.exclusiveMinimum)).annotations({ - message: () => - trans(meta.exclusiveMinimum === 0 ? "validation.number.positive" : "validation.number.min", { - minimum: meta.exclusiveMinimum, - isExclusive: false - }) - }) - } - if (typeof meta.exclusiveMaximum === "number") { - schema = schema.pipe(S.lessThan(meta.exclusiveMaximum)).annotations({ - message: () => - trans("validation.number.max", { - maximum: meta.exclusiveMaximum, - isExclusive: false - }) - }) - } - break - } - case "number": - schema = S.Number.annotations({ - message: () => trans("validation.number.expected", { actualValue: "NaN" }) - }) - - if (meta.required) { - schema.annotations({ - message: () => trans("validation.empty") + if (meta.refinement === "int") { + schema = S + .Number + .annotations({ + message: () => trans("validation.empty") + }) + .pipe( + S.int({ message: (issue) => trans("validation.integer.expected", { actualValue: String(issue.actual) }) }) + ) + } else { + schema = S.Number.annotations({ + message: () => trans("validation.number.expected", { actualValue: "NaN" }) }) + + if (meta.required) { + schema.annotations({ + message: () => trans("validation.empty") + }) + } } + if (typeof meta.minimum === "number") { schema = schema.pipe(S.greaterThanOrEqualTo(meta.minimum)).annotations({ message: () => diff --git a/packages/vue-components/src/components/OmegaForm/OmegaInputVuetify.vue b/packages/vue-components/src/components/OmegaForm/OmegaInputVuetify.vue index 02e7248fe..11c43b95a 100644 --- a/packages/vue-components/src/components/OmegaForm/OmegaInputVuetify.vue +++ b/packages/vue-components/src/components/OmegaForm/OmegaInputVuetify.vue @@ -81,12 +81,12 @@ > = computed(() => ({ required: isRequired.value, minLength: props.meta?.type === "string" && props.meta?.minLength, maxLength: props.meta?.type === "string" && props.meta?.maxLength, - max: (props.meta?.type === "number" || props.meta?.type === "int") + max: (props.meta?.type === "number") && (props.meta?.maximum ?? (typeof props.meta?.exclusiveMaximum === "number" && props.meta.exclusiveMaximum - 1)), - min: (props.meta?.type === "number" || props.meta?.type === "int") + min: (props.meta?.type === "number") && (props.meta?.minimum ?? (typeof props.meta?.exclusiveMinimum === "number" && props.meta.exclusiveMinimum + 1)), errorMessages: errors.value, diff --git a/packages/vue-components/stories/OmegaForm/SimpleForm.vue b/packages/vue-components/stories/OmegaForm/SimpleForm.vue index a083da34a..11e5c5cc3 100644 --- a/packages/vue-components/stories/OmegaForm/SimpleForm.vue +++ b/packages/vue-components/stories/OmegaForm/SimpleForm.vue @@ -1,55 +1,58 @@