From 4018df5bafbe7cbd824597d4a9027843dd84a291 Mon Sep 17 00:00:00 2001 From: PelayoFelgueroso Date: Tue, 21 Jul 2026 11:12:31 +0200 Subject: [PATCH 1/4] Fix length error messages --- .../localization/LocalizationPage.tsx | 18 ++++++++++++---- packages/lib/src/common/variables.ts | 3 ++- .../lib/src/text-input/TextInput.test.tsx | 12 +++++------ packages/lib/src/text-input/TextInput.tsx | 5 +++-- packages/lib/src/text-input/utils.ts | 14 +++++++++++++ packages/lib/src/textarea/Textarea.test.tsx | 21 +++++++++++++++---- packages/lib/src/textarea/Textarea.tsx | 17 +++++++++++---- 7 files changed, 69 insertions(+), 21 deletions(-) diff --git a/apps/website/screens/guidelines/localization/LocalizationPage.tsx b/apps/website/screens/guidelines/localization/LocalizationPage.tsx index 81aebdd1c4..1fd05c8cb9 100644 --- a/apps/website/screens/guidelines/localization/LocalizationPage.tsx +++ b/apps/website/screens/guidelines/localization/LocalizationPage.tsx @@ -82,14 +82,24 @@ const sections = [ - lengthErrorMessage + maxLengthErrorMessage - Min length minLength, max length maxLength. + Max length maxLength. - It is a function that receives two parameters (minlength and maxlength) and returns the text with - those parameters. + It is a function that receives a parameter (maxlength) and returns the text with this parameter. + + + + + minLengthErrorMessage + + + Min length minLength. + + + It is a function that receives a parameter (minlength) and returns the text with this parameter. diff --git a/packages/lib/src/common/variables.ts b/packages/lib/src/common/variables.ts index f5a58b3784..e9bf2b0132 100644 --- a/packages/lib/src/common/variables.ts +++ b/packages/lib/src/common/variables.ts @@ -75,7 +75,8 @@ export const defaultTranslatedComponentLabels = { requiredSelectionErrorMessage: "This field is required. Please, choose an option.", requiredValueErrorMessage: "This field is required. Please, enter a value.", formatRequestedErrorMessage: "Please match the format requested.", - lengthErrorMessage: (minLength?: number, maxLength?: number) => `Min length ${minLength}, max length ${maxLength}.`, + minLengthErrorMessage: (minLength: number) => `Min length ${minLength}.`, + maxLengthErrorMessage: (maxLength: number) => `Max length ${maxLength}.`, logoAlternativeText: "Logo", }, header: { diff --git a/packages/lib/src/text-input/TextInput.test.tsx b/packages/lib/src/text-input/TextInput.test.tsx index c8f234ff4e..4d76b0fd73 100644 --- a/packages/lib/src/text-input/TextInput.test.tsx +++ b/packages/lib/src/text-input/TextInput.test.tsx @@ -160,13 +160,13 @@ describe("TextInput component tests", () => { expect(onChange).toHaveBeenCalled(); expect(onChange).toHaveBeenCalledWith({ value: "test", - error: "Min length 5, max length 10.", + error: "Min length 5.", }); fireEvent.blur(input); expect(onBlur).toHaveBeenCalled(); expect(onBlur).toHaveBeenCalledWith({ value: "test", - error: "Min length 5, max length 10.", + error: "Min length 5.", }); userEvent.clear(input); fireEvent.change(input, { target: { value: "length" } }); @@ -198,13 +198,13 @@ describe("TextInput component tests", () => { expect(onChange).toHaveBeenCalled(); expect(onChange).toHaveBeenCalledWith({ value: "test", - error: "Min length 5, max length 10.", + error: "Min length 5.", }); fireEvent.blur(input); expect(onBlur).toHaveBeenCalled(); expect(onBlur).toHaveBeenCalledWith({ value: "test", - error: "Min length 5, max length 10.", + error: "Min length 5.", }); fireEvent.change(input, { target: { value: "tests" } }); expect(onChange).toHaveBeenCalled(); @@ -732,12 +732,12 @@ describe("TextInput component synchronous autosuggest tests", () => { }); expect(onChange).toHaveBeenCalledWith({ value: "Cha", - error: "Min length 5, max length 10.", + error: "Min length 5.", }); fireEvent.blur(input); expect(onBlur).toHaveBeenCalledWith({ value: "Chad", - error: "Min length 5, max length 10.", + error: "Min length 5.", }); }); diff --git a/packages/lib/src/text-input/TextInput.tsx b/packages/lib/src/text-input/TextInput.tsx index 2b29115741..ee0e4602ff 100644 --- a/packages/lib/src/text-input/TextInput.tsx +++ b/packages/lib/src/text-input/TextInput.tsx @@ -24,6 +24,7 @@ import Suggestions from "./Suggestions"; import TextInputPropsType, { AutosuggestWrapperProps, RefType } from "./types"; import { calculateWidth, + getLengthErrorMessage, hasSuggestions, isLengthIncorrect, isNumberIncorrect, @@ -240,7 +241,7 @@ const DxcTextInput = forwardRef( } else if (isLengthIncorrect(formattedValue, minLength, maxLength)) { onChange?.({ value: formattedValue, - error: translatedLabels.formFields.lengthErrorMessage?.(minLength, maxLength), + error: getLengthErrorMessage(formattedValue, minLength, maxLength), }); } else if (patternMismatch(pattern, formattedValue)) { onChange?.({ value: formattedValue, error: translatedLabels.formFields.formatRequestedErrorMessage }); @@ -336,7 +337,7 @@ const DxcTextInput = forwardRef( } else if (isLengthIncorrect(event.target.value, minLength, maxLength)) { onBlur?.({ value: event.target.value, - error: translatedLabels.formFields.lengthErrorMessage?.(minLength, maxLength), + error: getLengthErrorMessage(event.target.value, minLength, maxLength), }); } else if (patternMismatch(pattern, event.target.value)) { onBlur?.({ value: event.target.value, error: translatedLabels.formFields.formatRequestedErrorMessage }); diff --git a/packages/lib/src/text-input/utils.ts b/packages/lib/src/text-input/utils.ts index 202e0f56c0..8ad8518ec0 100644 --- a/packages/lib/src/text-input/utils.ts +++ b/packages/lib/src/text-input/utils.ts @@ -55,6 +55,20 @@ export const isLengthIncorrect = ( ) => value != null && ((minLength != null && value.length < minLength) || (maxLength != null && value.length > maxLength)); +export const getLengthErrorMessage = ( + value: string, + minLength: TextInputPropsType["minLength"], + maxLength: TextInputPropsType["maxLength"] +) => { + if (minLength != null && value.length < minLength) { + return `Min length ${minLength}.`; + } + if (maxLength != null && value.length > maxLength) { + return `Max length ${maxLength}.`; + } + return undefined; +}; + export const isNumberIncorrect = ( value: number, minNumber: TextInputPropsType["minLength"], diff --git a/packages/lib/src/textarea/Textarea.test.tsx b/packages/lib/src/textarea/Textarea.test.tsx index 89a315c53c..e4296d23e5 100644 --- a/packages/lib/src/textarea/Textarea.test.tsx +++ b/packages/lib/src/textarea/Textarea.test.tsx @@ -196,13 +196,26 @@ describe("Textarea component tests", () => { expect(onChange).toHaveBeenCalled(); expect(onChange).toHaveBeenCalledWith({ value: "test", - error: "Min length 5, max length 10.", + error: "Min length 5.", }); fireEvent.blur(textarea); expect(onBlur).toHaveBeenCalled(); expect(onBlur).toHaveBeenCalledWith({ value: "test", - error: "Min length 5, max length 10.", + error: "Min length 5.", + }); + userEvent.clear(textarea); + fireEvent.change(textarea, { target: { value: "this is a longer value" } }); + expect(onChange).toHaveBeenCalled(); + expect(onChange).toHaveBeenCalledWith({ + value: "this is a longer value", + error: "Max length 10.", + }); + fireEvent.blur(textarea); + expect(onBlur).toHaveBeenCalled(); + expect(onBlur).toHaveBeenCalledWith({ + value: "this is a longer value", + error: "Max length 10.", }); userEvent.clear(textarea); fireEvent.change(textarea, { target: { value: "length" } }); @@ -233,13 +246,13 @@ describe("Textarea component tests", () => { expect(onChange).toHaveBeenCalled(); expect(onChange).toHaveBeenCalledWith({ value: "test", - error: "Min length 5, max length 10.", + error: "Min length 5.", }); fireEvent.blur(textarea); expect(onBlur).toHaveBeenCalled(); expect(onBlur).toHaveBeenCalledWith({ value: "test", - error: "Min length 5, max length 10.", + error: "Min length 5.", }); fireEvent.change(textarea, { target: { value: "tests" } }); expect(onChange).toHaveBeenCalled(); diff --git a/packages/lib/src/textarea/Textarea.tsx b/packages/lib/src/textarea/Textarea.tsx index b180dcb387..ed128ab1e7 100644 --- a/packages/lib/src/textarea/Textarea.tsx +++ b/packages/lib/src/textarea/Textarea.tsx @@ -99,8 +99,17 @@ const DxcTextarea = forwardRef( const textareaRef = useRef(null); const prevValueRef = useRef(null); - const isLengthOutOfRange = (value: string) => - value !== "" && minLength && maxLength && (value.length < minLength || value.length > maxLength); + const getLengthErrorMessage = (value: string) => { + if (minLength != null && value.length < minLength) { + return translatedLabels.formFields.minLengthErrorMessage?.(minLength); + } + if (maxLength != null && value.length > maxLength) { + return translatedLabels.formFields.maxLengthErrorMessage?.(maxLength); + } + return undefined; + }; + + const isLengthOutOfRange = (value: string) => getLengthErrorMessage(value) != null; const changeValue = (newValue: string) => { if (value == null) setInnerValue(newValue); @@ -113,7 +122,7 @@ const DxcTextarea = forwardRef( } else if (isLengthOutOfRange(newValue)) { onChange?.({ value: newValue, - error: translatedLabels.formFields.lengthErrorMessage?.(minLength, maxLength), + error: getLengthErrorMessage(newValue), }); } else if (newValue && pattern && !patternMatch(pattern, newValue)) { onChange?.({ @@ -132,7 +141,7 @@ const DxcTextarea = forwardRef( } else if (isLengthOutOfRange(event.target.value)) { onBlur?.({ value: event.target.value, - error: translatedLabels.formFields.lengthErrorMessage?.(minLength, maxLength), + error: getLengthErrorMessage(event.target.value), }); } else if (event.target.value && pattern && !patternMatch(pattern, event.target.value)) { onBlur?.({ From 9fd66fefdea81c1f6b57088e6fb171906436b2bb Mon Sep 17 00:00:00 2001 From: PelayoFelgueroso Date: Thu, 23 Jul 2026 12:47:43 +0200 Subject: [PATCH 2/4] fix based on comments --- .../localization/LocalizationPage.tsx | 10 ++------ packages/lib/src/common/variables.ts | 1 - packages/lib/src/text-input/TextInput.tsx | 24 ++++++++++++++----- packages/lib/src/text-input/utils.ts | 21 ---------------- packages/lib/src/textarea/Textarea.tsx | 16 +++++++------ 5 files changed, 29 insertions(+), 43 deletions(-) diff --git a/apps/website/screens/guidelines/localization/LocalizationPage.tsx b/apps/website/screens/guidelines/localization/LocalizationPage.tsx index 1fd05c8cb9..85f1c8fcd6 100644 --- a/apps/website/screens/guidelines/localization/LocalizationPage.tsx +++ b/apps/website/screens/guidelines/localization/LocalizationPage.tsx @@ -85,7 +85,7 @@ const sections = [ maxLengthErrorMessage - Max length maxLength. + The maximum length maxLength. It is a function that receives a parameter (maxlength) and returns the text with this parameter. @@ -96,18 +96,12 @@ const sections = [ minLengthErrorMessage - Min length minLength. + The minimum length minLength. It is a function that receives a parameter (minlength) and returns the text with this parameter. - - - logoAlternativeText - - Logo - diff --git a/packages/lib/src/common/variables.ts b/packages/lib/src/common/variables.ts index e9bf2b0132..1c0050606a 100644 --- a/packages/lib/src/common/variables.ts +++ b/packages/lib/src/common/variables.ts @@ -77,7 +77,6 @@ export const defaultTranslatedComponentLabels = { formatRequestedErrorMessage: "Please match the format requested.", minLengthErrorMessage: (minLength: number) => `Min length ${minLength}.`, maxLengthErrorMessage: (maxLength: number) => `Max length ${maxLength}.`, - logoAlternativeText: "Logo", }, header: { closeIcon: "Close menu", diff --git a/packages/lib/src/text-input/TextInput.tsx b/packages/lib/src/text-input/TextInput.tsx index ee0e4602ff..f6ff0b4cc2 100644 --- a/packages/lib/src/text-input/TextInput.tsx +++ b/packages/lib/src/text-input/TextInput.tsx @@ -24,9 +24,7 @@ import Suggestions from "./Suggestions"; import TextInputPropsType, { AutosuggestWrapperProps, RefType } from "./types"; import { calculateWidth, - getLengthErrorMessage, hasSuggestions, - isLengthIncorrect, isNumberIncorrect, isRequired, makeCancelable, @@ -161,6 +159,16 @@ const DxcTextInput = forwardRef( setPortalContainer(document?.getElementById(`${inputId}-portal`)); }, []); + const getLengthErrorMessage = (value: string) => { + if (minLength != null && value.length < minLength) { + return translatedLabels.formFields.minLengthErrorMessage(minLength); + } + if (maxLength != null && value.length > maxLength) { + return translatedLabels.formFields.minLengthErrorMessage(maxLength); + } + return undefined; + }; + const autosuggestWrapperFunction = (children: ReactNode) => ( 0 || isSearching || isAutosuggestError)}> ( setInnerValue(formattedValue); } + const lengthError = getLengthErrorMessage(formattedValue); + if (isRequired(formattedValue, optional)) { onChange?.({ value: formattedValue, error: translatedLabels.formFields.requiredValueErrorMessage, }); - } else if (isLengthIncorrect(formattedValue, minLength, maxLength)) { + } else if (lengthError) { onChange?.({ value: formattedValue, - error: getLengthErrorMessage(formattedValue, minLength, maxLength), + error: lengthError, }); } else if (patternMismatch(pattern, formattedValue)) { onChange?.({ value: formattedValue, error: translatedLabels.formFields.formatRequestedErrorMessage }); @@ -332,12 +342,14 @@ const DxcTextInput = forwardRef( const handleInputOnBlur = (event: FocusEvent) => { closeSuggestions(); + const lengthError = getLengthErrorMessage(event.target.value); + if (isRequired(event.target.value, optional)) { onBlur?.({ value: event.target.value, error: translatedLabels.formFields.requiredValueErrorMessage }); - } else if (isLengthIncorrect(event.target.value, minLength, maxLength)) { + } else if (lengthError) { onBlur?.({ value: event.target.value, - error: getLengthErrorMessage(event.target.value, minLength, maxLength), + error: lengthError, }); } else if (patternMismatch(pattern, event.target.value)) { onBlur?.({ value: event.target.value, error: translatedLabels.formFields.formatRequestedErrorMessage }); diff --git a/packages/lib/src/text-input/utils.ts b/packages/lib/src/text-input/utils.ts index 8ad8518ec0..3f0c73b699 100644 --- a/packages/lib/src/text-input/utils.ts +++ b/packages/lib/src/text-input/utils.ts @@ -48,27 +48,6 @@ export const hasSuggestions = (suggestions: TextInputPropsType["suggestions"]) = export const isRequired = (value: string, optional: boolean) => value === "" && !optional; -export const isLengthIncorrect = ( - value: string, - minLength: TextInputPropsType["minLength"], - maxLength: TextInputPropsType["maxLength"] -) => - value != null && ((minLength != null && value.length < minLength) || (maxLength != null && value.length > maxLength)); - -export const getLengthErrorMessage = ( - value: string, - minLength: TextInputPropsType["minLength"], - maxLength: TextInputPropsType["maxLength"] -) => { - if (minLength != null && value.length < minLength) { - return `Min length ${minLength}.`; - } - if (maxLength != null && value.length > maxLength) { - return `Max length ${maxLength}.`; - } - return undefined; -}; - export const isNumberIncorrect = ( value: number, minNumber: TextInputPropsType["minLength"], diff --git a/packages/lib/src/textarea/Textarea.tsx b/packages/lib/src/textarea/Textarea.tsx index ed128ab1e7..39f925e455 100644 --- a/packages/lib/src/textarea/Textarea.tsx +++ b/packages/lib/src/textarea/Textarea.tsx @@ -109,20 +109,20 @@ const DxcTextarea = forwardRef( return undefined; }; - const isLengthOutOfRange = (value: string) => getLengthErrorMessage(value) != null; - const changeValue = (newValue: string) => { if (value == null) setInnerValue(newValue); + const lengthError = getLengthErrorMessage(newValue); + if (newValue === "" && !optional) { onChange?.({ value: newValue, error: translatedLabels.formFields.requiredValueErrorMessage, }); - } else if (isLengthOutOfRange(newValue)) { + } else if (lengthError) { onChange?.({ value: newValue, - error: getLengthErrorMessage(newValue), + error: lengthError, }); } else if (newValue && pattern && !patternMatch(pattern, newValue)) { onChange?.({ @@ -133,15 +133,17 @@ const DxcTextarea = forwardRef( }; const handleOnBlur = (event: FocusEvent) => { - if (event.target.value === "" && !optional) { + const lengthError = getLengthErrorMessage(event.target.value); + + if (value === "" && !optional) { onBlur?.({ value: event.target.value, error: translatedLabels.formFields.requiredValueErrorMessage, }); - } else if (isLengthOutOfRange(event.target.value)) { + } else if (lengthError) { onBlur?.({ value: event.target.value, - error: getLengthErrorMessage(event.target.value), + error: lengthError, }); } else if (event.target.value && pattern && !patternMatch(pattern, event.target.value)) { onBlur?.({ From d223d46cc67ae64a8cb896a3467b576490087c84 Mon Sep 17 00:00:00 2001 From: PelayoFelgueroso Date: Thu, 23 Jul 2026 13:29:52 +0200 Subject: [PATCH 3/4] Fix based on comments --- .../localization/LocalizationPage.tsx | 4 +- packages/lib/src/common/variables.ts | 4 +- .../lib/src/text-input/TextInput.test.tsx | 114 +++++++++++++++--- packages/lib/src/text-input/TextInput.tsx | 2 +- 4 files changed, 102 insertions(+), 22 deletions(-) diff --git a/apps/website/screens/guidelines/localization/LocalizationPage.tsx b/apps/website/screens/guidelines/localization/LocalizationPage.tsx index 85f1c8fcd6..783bf6a94d 100644 --- a/apps/website/screens/guidelines/localization/LocalizationPage.tsx +++ b/apps/website/screens/guidelines/localization/LocalizationPage.tsx @@ -85,7 +85,7 @@ const sections = [ maxLengthErrorMessage - The maximum length maxLength. + The maximum length is maxLength. It is a function that receives a parameter (maxlength) and returns the text with this parameter. @@ -96,7 +96,7 @@ const sections = [ minLengthErrorMessage - The minimum length minLength. + The minimum length is minLength. It is a function that receives a parameter (minlength) and returns the text with this parameter. diff --git a/packages/lib/src/common/variables.ts b/packages/lib/src/common/variables.ts index 1c0050606a..a24536597b 100644 --- a/packages/lib/src/common/variables.ts +++ b/packages/lib/src/common/variables.ts @@ -75,8 +75,8 @@ export const defaultTranslatedComponentLabels = { requiredSelectionErrorMessage: "This field is required. Please, choose an option.", requiredValueErrorMessage: "This field is required. Please, enter a value.", formatRequestedErrorMessage: "Please match the format requested.", - minLengthErrorMessage: (minLength: number) => `Min length ${minLength}.`, - maxLengthErrorMessage: (maxLength: number) => `Max length ${maxLength}.`, + minLengthErrorMessage: (minLength: number) => `The minimum length is ${minLength}.`, + maxLengthErrorMessage: (maxLength: number) => `The maximum length is ${maxLength}.`, }, header: { closeIcon: "Close menu", diff --git a/packages/lib/src/text-input/TextInput.test.tsx b/packages/lib/src/text-input/TextInput.test.tsx index 4d76b0fd73..fdf8f6ae96 100644 --- a/packages/lib/src/text-input/TextInput.test.tsx +++ b/packages/lib/src/text-input/TextInput.test.tsx @@ -2,6 +2,7 @@ import { act, fireEvent, render, waitForElementToBeRemoved } from "@testing-libr import userEvent from "@testing-library/user-event"; import DxcTextInput from "./TextInput"; import MockDOMRect from "../../test/mocks/domRectMock"; +import { HalstackProvider } from "../HalstackContext"; // Mocking DOMRect for Radix Primitive Popover global.DOMRect = MockDOMRect; @@ -157,26 +158,81 @@ describe("TextInput component tests", () => { ); const input = getByRole("textbox"); fireEvent.change(input, { target: { value: "test" } }); - expect(onChange).toHaveBeenCalled(); expect(onChange).toHaveBeenCalledWith({ value: "test", - error: "Min length 5.", + error: "The minimum length is 5.", }); fireEvent.blur(input); - expect(onBlur).toHaveBeenCalled(); expect(onBlur).toHaveBeenCalledWith({ value: "test", - error: "Min length 5.", + error: "The minimum length is 5.", }); - userEvent.clear(input); + + fireEvent.change(input, { target: { value: "test-maximum-length" } }); + expect(onChange).toHaveBeenCalledWith({ + value: "test-maximum-length", + error: "The maximum length is 10.", + }); + fireEvent.blur(input); + expect(onBlur).toHaveBeenCalledWith({ + value: "test-maximum-length", + error: "The maximum length is 10.", + }); + fireEvent.change(input, { target: { value: "length" } }); - expect(onChange).toHaveBeenCalled(); expect(onChange).toHaveBeenCalledWith({ value: "length" }); fireEvent.blur(input); - expect(onBlur).toHaveBeenCalled(); expect(onBlur).toHaveBeenCalledWith({ value: "length" }); }); + test("Maximum and minimum error messages change within HalstackProvider", () => { + const onChange = jest.fn(); + const onBlur = jest.fn(); + const { getByRole } = render( + `Please do not enter more than ${maxLength} characters.`, + minLengthErrorMessage: (minLegth: number) => `Please do not enter less than ${minLegth} characters.`, + }, + }} + > + + + ); + const input = getByRole("textbox"); + fireEvent.change(input, { target: { value: "test" } }); + expect(onChange).toHaveBeenCalledWith({ + value: "test", + error: "Please do not enter less than 5 characters.", + }); + fireEvent.blur(input); + expect(onBlur).toHaveBeenCalledWith({ + value: "test", + error: "Please do not enter less than 5 characters.", + }); + + fireEvent.change(input, { target: { value: "test-maximum-length" } }); + expect(onChange).toHaveBeenCalledWith({ + value: "test-maximum-length", + error: "Please do not enter more than 10 characters.", + }); + fireEvent.blur(input); + expect(onBlur).toHaveBeenCalledWith({ + value: "test-maximum-length", + error: "Please do not enter more than 10 characters.", + }); + }); + test("Pattern and length constraints", () => { const onChange = jest.fn(); const onBlur = jest.fn(); @@ -195,34 +251,38 @@ describe("TextInput component tests", () => { ); const input = getByRole("textbox"); fireEvent.change(input, { target: { value: "test" } }); - expect(onChange).toHaveBeenCalled(); expect(onChange).toHaveBeenCalledWith({ value: "test", - error: "Min length 5.", + error: "The minimum length is 5.", }); fireEvent.blur(input); - expect(onBlur).toHaveBeenCalled(); expect(onBlur).toHaveBeenCalledWith({ value: "test", - error: "Min length 5.", + error: "The minimum length is 5.", + }); + fireEvent.change(input, { target: { value: "test-maximum-length" } }); + expect(onChange).toHaveBeenCalledWith({ + value: "test-maximum-length", + error: "The maximum length is 5.", + }); + fireEvent.blur(input); + expect(onBlur).toHaveBeenCalledWith({ + value: "test-maximum-length", + error: "The maximum length is 5.", }); fireEvent.change(input, { target: { value: "tests" } }); - expect(onChange).toHaveBeenCalled(); expect(onChange).toHaveBeenCalledWith({ value: "tests", error: "Please match the format requested.", }); fireEvent.blur(input); - expect(onBlur).toHaveBeenCalled(); expect(onBlur).toHaveBeenCalledWith({ value: "tests", error: "Please match the format requested.", }); fireEvent.change(input, { target: { value: "tests4&" } }); - expect(onChange).toHaveBeenCalled(); expect(onChange).toHaveBeenCalledWith({ value: "tests4&" }); fireEvent.blur(input); - expect(onBlur).toHaveBeenCalled(); expect(onBlur).toHaveBeenCalledWith({ value: "tests4&" }); }); @@ -732,12 +792,32 @@ describe("TextInput component synchronous autosuggest tests", () => { }); expect(onChange).toHaveBeenCalledWith({ value: "Cha", - error: "Min length 5.", + error: "The minimum length is 5.", }); fireEvent.blur(input); expect(onBlur).toHaveBeenCalledWith({ value: "Chad", - error: "Min length 5.", + error: "The minimum length is 5.", + }); + + userEvent.clear(input); + fireEvent.focus(input); + act(() => { + userEvent.type(input, "Democratic Rep"); + }); + expect(getByText("Democratic Rep")).toBeTruthy(); + expect(getByText("Congo")).toBeTruthy(); + act(() => { + userEvent.click(getByRole("option")); + }); + expect(onChange).toHaveBeenCalledWith({ + value: "Democratic Rep", + error: "The maximum length is 10.", + }); + fireEvent.blur(input); + expect(onBlur).toHaveBeenCalledWith({ + value: "Democratic Republic of the Congo", + error: "The maximum length is 10.", }); }); diff --git a/packages/lib/src/text-input/TextInput.tsx b/packages/lib/src/text-input/TextInput.tsx index f6ff0b4cc2..e8b6c6b3cb 100644 --- a/packages/lib/src/text-input/TextInput.tsx +++ b/packages/lib/src/text-input/TextInput.tsx @@ -164,7 +164,7 @@ const DxcTextInput = forwardRef( return translatedLabels.formFields.minLengthErrorMessage(minLength); } if (maxLength != null && value.length > maxLength) { - return translatedLabels.formFields.minLengthErrorMessage(maxLength); + return translatedLabels.formFields.maxLengthErrorMessage(maxLength); } return undefined; }; From 12b5a051d53e9bbbe033bfe5f052abec0577b5c7 Mon Sep 17 00:00:00 2001 From: PelayoFelgueroso Date: Thu, 23 Jul 2026 21:39:53 +0200 Subject: [PATCH 4/4] fix test errors --- .../lib/src/text-input/TextInput.test.tsx | 105 +++++++++--------- packages/lib/src/textarea/Textarea.test.tsx | 12 +- packages/lib/src/textarea/Textarea.tsx | 2 +- 3 files changed, 58 insertions(+), 61 deletions(-) diff --git a/packages/lib/src/text-input/TextInput.test.tsx b/packages/lib/src/text-input/TextInput.test.tsx index fdf8f6ae96..1aba7d0250 100644 --- a/packages/lib/src/text-input/TextInput.test.tsx +++ b/packages/lib/src/text-input/TextInput.test.tsx @@ -185,54 +185,6 @@ describe("TextInput component tests", () => { expect(onBlur).toHaveBeenCalledWith({ value: "length" }); }); - test("Maximum and minimum error messages change within HalstackProvider", () => { - const onChange = jest.fn(); - const onBlur = jest.fn(); - const { getByRole } = render( - `Please do not enter more than ${maxLength} characters.`, - minLengthErrorMessage: (minLegth: number) => `Please do not enter less than ${minLegth} characters.`, - }, - }} - > - - - ); - const input = getByRole("textbox"); - fireEvent.change(input, { target: { value: "test" } }); - expect(onChange).toHaveBeenCalledWith({ - value: "test", - error: "Please do not enter less than 5 characters.", - }); - fireEvent.blur(input); - expect(onBlur).toHaveBeenCalledWith({ - value: "test", - error: "Please do not enter less than 5 characters.", - }); - - fireEvent.change(input, { target: { value: "test-maximum-length" } }); - expect(onChange).toHaveBeenCalledWith({ - value: "test-maximum-length", - error: "Please do not enter more than 10 characters.", - }); - fireEvent.blur(input); - expect(onBlur).toHaveBeenCalledWith({ - value: "test-maximum-length", - error: "Please do not enter more than 10 characters.", - }); - }); - test("Pattern and length constraints", () => { const onChange = jest.fn(); const onBlur = jest.fn(); @@ -263,12 +215,12 @@ describe("TextInput component tests", () => { fireEvent.change(input, { target: { value: "test-maximum-length" } }); expect(onChange).toHaveBeenCalledWith({ value: "test-maximum-length", - error: "The maximum length is 5.", + error: "The maximum length is 10.", }); fireEvent.blur(input); expect(onBlur).toHaveBeenCalledWith({ value: "test-maximum-length", - error: "The maximum length is 5.", + error: "The maximum length is 10.", }); fireEvent.change(input, { target: { value: "tests" } }); expect(onChange).toHaveBeenCalledWith({ @@ -802,11 +754,8 @@ describe("TextInput component synchronous autosuggest tests", () => { userEvent.clear(input); fireEvent.focus(input); - act(() => { - userEvent.type(input, "Democratic Rep"); - }); + fireEvent.change(input, { target: { value: "Democratic Rep" } }); expect(getByText("Democratic Rep")).toBeTruthy(); - expect(getByText("Congo")).toBeTruthy(); act(() => { userEvent.click(getByRole("option")); }); @@ -1236,4 +1185,52 @@ describe("TextInput component asynchronous autosuggest tests", () => { await waitForElementToBeRemoved(() => getByText("Searching...")); expect(getByText("Error fetching data")).toBeTruthy(); }); + + test("Maximum and minimum error messages change within HalstackProvider", () => { + const onChange = jest.fn(); + const onBlur = jest.fn(); + const { getByRole } = render( + `Please do not enter more than ${maxLength} characters.`, + minLengthErrorMessage: (minLegth: number) => `Please do not enter less than ${minLegth} characters.`, + }, + }} + > + + + ); + const input = getByRole("textbox"); + fireEvent.change(input, { target: { value: "test" } }); + expect(onChange).toHaveBeenCalledWith({ + value: "test", + error: "Please do not enter less than 5 characters.", + }); + fireEvent.blur(input); + expect(onBlur).toHaveBeenCalledWith({ + value: "test", + error: "Please do not enter less than 5 characters.", + }); + + fireEvent.change(input, { target: { value: "test-maximum-length" } }); + expect(onChange).toHaveBeenCalledWith({ + value: "test-maximum-length", + error: "Please do not enter more than 10 characters.", + }); + fireEvent.blur(input); + expect(onBlur).toHaveBeenCalledWith({ + value: "test-maximum-length", + error: "Please do not enter more than 10 characters.", + }); + }); }); diff --git a/packages/lib/src/textarea/Textarea.test.tsx b/packages/lib/src/textarea/Textarea.test.tsx index e4296d23e5..71c320b3c5 100644 --- a/packages/lib/src/textarea/Textarea.test.tsx +++ b/packages/lib/src/textarea/Textarea.test.tsx @@ -196,26 +196,26 @@ describe("Textarea component tests", () => { expect(onChange).toHaveBeenCalled(); expect(onChange).toHaveBeenCalledWith({ value: "test", - error: "Min length 5.", + error: "The minimum length is 5.", }); fireEvent.blur(textarea); expect(onBlur).toHaveBeenCalled(); expect(onBlur).toHaveBeenCalledWith({ value: "test", - error: "Min length 5.", + error: "The minimum length is 5.", }); userEvent.clear(textarea); fireEvent.change(textarea, { target: { value: "this is a longer value" } }); expect(onChange).toHaveBeenCalled(); expect(onChange).toHaveBeenCalledWith({ value: "this is a longer value", - error: "Max length 10.", + error: "The maximum length is 10.", }); fireEvent.blur(textarea); expect(onBlur).toHaveBeenCalled(); expect(onBlur).toHaveBeenCalledWith({ value: "this is a longer value", - error: "Max length 10.", + error: "The maximum length is 10.", }); userEvent.clear(textarea); fireEvent.change(textarea, { target: { value: "length" } }); @@ -246,13 +246,13 @@ describe("Textarea component tests", () => { expect(onChange).toHaveBeenCalled(); expect(onChange).toHaveBeenCalledWith({ value: "test", - error: "Min length 5.", + error: "The minimum length is 5.", }); fireEvent.blur(textarea); expect(onBlur).toHaveBeenCalled(); expect(onBlur).toHaveBeenCalledWith({ value: "test", - error: "Min length 5.", + error: "The minimum length is 5.", }); fireEvent.change(textarea, { target: { value: "tests" } }); expect(onChange).toHaveBeenCalled(); diff --git a/packages/lib/src/textarea/Textarea.tsx b/packages/lib/src/textarea/Textarea.tsx index 39f925e455..639daf9330 100644 --- a/packages/lib/src/textarea/Textarea.tsx +++ b/packages/lib/src/textarea/Textarea.tsx @@ -135,7 +135,7 @@ const DxcTextarea = forwardRef( const handleOnBlur = (event: FocusEvent) => { const lengthError = getLengthErrorMessage(event.target.value); - if (value === "" && !optional) { + if (event.target.value === "" && !optional) { onBlur?.({ value: event.target.value, error: translatedLabels.formFields.requiredValueErrorMessage,