From 49fa0ee7357115e399f22bc842cb8dd90b4e2408 Mon Sep 17 00:00:00 2001 From: Michal Gold Date: Thu, 20 Feb 2025 12:28:04 +0200 Subject: [PATCH] Wizard: Refactor HookValidatedInput component This commit splits the HookValidatedInput component into three separate functions to improve modularity and readability: - `getValidationState`: Calculates the validation state ('default', 'success', 'error') based on whether the input is pristine and if there is an error message. - `ValidatedInputAndTextArea`: Renders the TextInput or TextArea component, utilizing the `getValidationState` output. - `ErrorMessage`: Displays validation error messages. This refactoring enhances code maintainability and testability, and the updated structure is now implemented for the username field. --- .../CreateImageWizard/ValidatedInput.tsx | 98 ++++++++++++++++++- .../steps/Users/component/UserInfo.tsx | 3 +- .../utilities/useValidation.tsx | 10 +- .../CreateImageWizard/validators.ts | 1 - 4 files changed, 101 insertions(+), 11 deletions(-) diff --git a/src/Components/CreateImageWizard/ValidatedInput.tsx b/src/Components/CreateImageWizard/ValidatedInput.tsx index 4b77a3a4..873755c9 100644 --- a/src/Components/CreateImageWizard/ValidatedInput.tsx +++ b/src/Components/CreateImageWizard/ValidatedInput.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { useEffect, useState } from 'react'; import { HelperText, @@ -15,7 +15,7 @@ import { EyeIcon, EyeSlashIcon } from '@patternfly/react-icons'; import type { StepValidation } from './utilities/useValidation'; -interface ValidatedTextInputPropTypes extends TextInputProps { +type ValidatedTextInputPropTypes = TextInputProps & { dataTestId?: string | undefined; ouiaId?: string; ariaLabel: string | undefined; @@ -23,7 +23,7 @@ interface ValidatedTextInputPropTypes extends TextInputProps { validator: (value: string | undefined) => boolean; value: string; placeholder?: string; -} +}; type HookValidatedInputPropTypes = TextInputProps & TextAreaProps & { @@ -38,6 +38,26 @@ type HookValidatedInputPropTypes = TextInputProps & inputType?: 'textInput' | 'textArea'; }; +type ValidationInputProp = TextInputProps & + TextAreaProps & { + value: string; + placeholder: string; + stepValidation: StepValidation; + fieldName: string; + inputType?: 'textInput' | 'textArea'; + ariaLabel: string; + onChange: ( + event: React.FormEvent, + value: string + ) => void; + }; + +type ErrorMessageProps = { + errorMessage: string; +}; + +type ValidationResult = 'default' | 'success' | 'error'; + export const HookPasswordValidatedInput = ({ ariaLabel, placeholder, @@ -89,6 +109,78 @@ export const HookPasswordValidatedInput = ({ ); }; +export const ValidatedInputAndTextArea = ({ + value, + stepValidation, + fieldName, + placeholder, + onChange, + ariaLabel, + inputType = 'textInput', +}: ValidationInputProp) => { + const errorMessage = stepValidation.errors[fieldName]; + const hasError = errorMessage !== ''; + + const [isPristine, setIsPristine] = useState(!value); + const validated = getValidationState(isPristine, errorMessage); + + const handleBlur = () => { + if (value) { + setIsPristine(false); + } + }; + + useEffect(() => { + if (!value) { + setIsPristine(true); + } + }, [value, setIsPristine]); + + return ( + <> + {inputType === 'textArea' ? ( +