From 261ab1bd9a892bde970ca94a6f844c1dec400995 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20G=C3=B3mez=20Pinta?= <44321109+GomezIvann@users.noreply.github.com> Date: Thu, 20 Mar 2025 15:17:06 +0100 Subject: [PATCH 1/7] Textarea redesign --- packages/lib/src/select/Select.tsx | 11 +- .../lib/src/textarea/Textarea.stories.tsx | 64 +-- packages/lib/src/textarea/Textarea.tsx | 398 ++++++++---------- packages/lib/src/textarea/types.ts | 129 +++--- 4 files changed, 260 insertions(+), 342 deletions(-) diff --git a/packages/lib/src/select/Select.tsx b/packages/lib/src/select/Select.tsx index 40693d4220..278a7feaf6 100644 --- a/packages/lib/src/select/Select.tsx +++ b/packages/lib/src/select/Select.tsx @@ -72,11 +72,11 @@ const Label = styled.label<{ `; const HelperText = styled.span<{ disabled: SelectPropsType["disabled"] }>` - margin-bottom: var(--spacing-gap-xs); color: ${({ disabled }) => (disabled ? "var(--color-fg-neutral-medium)" : "var(--color-fg-neutral-stronger)")}; font-family: var(--typography-font-family); font-size: var(--typography-helper-text-s); font-weight: var(--typography-helper-text-regular); + margin-bottom: var(--spacing-gap-xs); `; const Select = styled.div<{ @@ -102,6 +102,7 @@ const Select = styled.div<{ border-color: ${error ? "var(--border-color-error-strong)" : "var(--border-color-primary-strong)"}; } &:focus-within { + border-color: transparent; outline-offset: -2px; outline: var(--border-width-m) var(--border-style-default) var(--border-color-secondary-medium); } @@ -204,13 +205,13 @@ const SearchInput = styled.input` font-weight: var(--typography-label-regular); `; -const Error = styled.span` +const ErrorMessage = styled.span` display: flex; align-items: center; gap: var(--spacing-gap-xs); color: var(--color-fg-error-medium); font-size: var(--typography-helper-text-s); - font-weight: var(--typography-helper-text-regular, 400); + font-weight: var(--typography-helper-text-regular); margin-top: var(--spacing-gap-xs); /* Error icon */ @@ -621,10 +622,10 @@ const DxcSelect = forwardRef( {!disabled && typeof error === "string" && ( - + {error && } {error} - + )} ); diff --git a/packages/lib/src/textarea/Textarea.stories.tsx b/packages/lib/src/textarea/Textarea.stories.tsx index 21d037dd09..b009a5364f 100644 --- a/packages/lib/src/textarea/Textarea.stories.tsx +++ b/packages/lib/src/textarea/Textarea.stories.tsx @@ -1,7 +1,6 @@ import { Meta, StoryObj } from "@storybook/react"; import ExampleContainer from "../../.storybook/components/ExampleContainer"; import Title from "../../.storybook/components/Title"; -import { HalstackProvider } from "../HalstackContext"; import DxcTextarea from "./Textarea"; export default { @@ -9,13 +8,6 @@ export default { component: DxcTextarea, } as Meta; -const opinionatedTheme = { - textarea: { - fontColor: "#000000", - hoverBorderColor: "#a46ede", - }, -}; - const TextArea = () => ( <> @@ -69,11 +61,11 @@ const TextArea = () => ( - + <Title title="With scroll" theme="light" level={4} /> <DxcTextarea label="Manual vertical grow" verticalGrow="manual" - defaultValue="Long textttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt" + defaultValue="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." /> </ExampleContainer> <Title title="Sizes" theme="light" level={2} /> @@ -118,58 +110,6 @@ const TextArea = () => ( <Title title="Xxlarge margin" theme="light" level={4} /> <DxcTextarea label="Xxlarge" margin="xxlarge" /> </ExampleContainer> - <Title title="Opinionated theme" theme="light" level={2} /> - <ExampleContainer pseudoState="pseudo-hover"> - <Title title="Hovered" theme="light" level={4} /> - <HalstackProvider theme={opinionatedTheme}> - <DxcTextarea label="Hovered" helperText="Sample text" placeholder="Placeholder" /> - </HalstackProvider> - </ExampleContainer> - <ExampleContainer pseudoState="pseudo-focus"> - <Title title="Focused" theme="light" level={4} /> - <HalstackProvider theme={opinionatedTheme}> - <DxcTextarea label="Focused" helperText="Sample text" /> - </HalstackProvider> - </ExampleContainer> - <ExampleContainer> - <Title title="Disabled" theme="light" level={4} /> - <HalstackProvider theme={opinionatedTheme}> - <DxcTextarea - label="Disabled" - optional - helperText="Sample text" - placeholder="Enter your text here..." - disabled - /> - </HalstackProvider> - </ExampleContainer> - <ExampleContainer> - <Title title="Disabled with value" theme="light" level={4} /> - <HalstackProvider theme={opinionatedTheme}> - <DxcTextarea label="Disabled" helperText="Sample text" defaultValue="Example text" disabled /> - </HalstackProvider> - </ExampleContainer> - <ExampleContainer> - <Title title="With error" theme="light" level={4} /> - <HalstackProvider theme={opinionatedTheme}> - <DxcTextarea - label="Textarea with error" - helperText="Helper text" - placeholder="Enter your text here..." - error="Error message." - /> - </HalstackProvider> - </ExampleContainer> - <ExampleContainer> - <Title title="Grow manual" theme="light" level={4} />{" "} - <HalstackProvider theme={opinionatedTheme}> - <DxcTextarea - label="Manual vertical grow" - verticalGrow="manual" - defaultValue="Long textttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt" - /> - </HalstackProvider> - </ExampleContainer> </> ); diff --git a/packages/lib/src/textarea/Textarea.tsx b/packages/lib/src/textarea/Textarea.tsx index 3cacf607b5..ec2e367a24 100644 --- a/packages/lib/src/textarea/Textarea.tsx +++ b/packages/lib/src/textarea/Textarea.tsx @@ -1,66 +1,178 @@ import { ChangeEvent, FocusEvent, forwardRef, useContext, useEffect, useId, useRef, useState } from "react"; -import styled, { ThemeProvider } from "styled-components"; +import styled from "styled-components"; import { getMargin } from "../common/utils"; import { spaces } from "../common/variables"; -import HalstackContext, { HalstackLanguageContext } from "../HalstackContext"; +import { HalstackLanguageContext } from "../HalstackContext"; import TextareaPropsType, { RefType } from "./types"; +import { scrollbarStyles } from "../styles/scroll"; +import DxcIcon from "../icon/Icon"; + +const sizes = { + small: "240px", + medium: "360px", + large: "480px", + fillParent: "100%", +}; + +const calculateWidth = (margin: TextareaPropsType["margin"], size: TextareaPropsType["size"]) => + size === "fillParent" + ? `calc(${sizes[size]} - ${getMargin(margin, "left")} - ${getMargin(margin, "right")})` + : size && sizes[size]; + +const TextareaContainer = styled.div<{ + margin: TextareaPropsType["margin"]; + size: TextareaPropsType["size"]; +}>` + display: flex; + flex-direction: column; + width: ${({ margin, size }) => calculateWidth(margin, size)}; + margin: ${({ margin }) => (margin && typeof margin !== "object" ? spaces[margin] : "0px")}; + margin-top: ${({ margin }) => (margin && typeof margin === "object" && margin.top ? spaces[margin.top] : "")}; + margin-right: ${({ margin }) => (margin && typeof margin === "object" && margin.right ? spaces[margin.right] : "")}; + margin-bottom: ${({ margin }) => + margin && typeof margin === "object" && margin.bottom ? spaces[margin.bottom] : ""}; + margin-left: ${({ margin }) => (margin && typeof margin === "object" && margin.left ? spaces[margin.left] : "")}; +`; + +const Label = styled.label<{ + disabled: TextareaPropsType["disabled"]; + helperText: TextareaPropsType["helperText"]; +}>` + color: ${({ disabled }) => (disabled ? "var(--color-fg-neutral-medium)" : "var(--color-fg-neutral-dark)")}; + font-family: var(--typography-font-family); + font-size: var(--typography-label-m); + font-weight: var(--typography-label-semibold); + ${({ helperText }) => !helperText && "margin-bottom: var(--spacing-gap-xs);"} + + /* Optional text */ + > span { + color: ${({ disabled }) => (disabled ? "var(--color-fg-neutral-medium)" : "var(--color-fg-neutral-stronger)")}; + font-weight: var(--typography-label-regular); + } +`; + +const HelperText = styled.span<{ disabled: TextareaPropsType["disabled"] }>` + color: ${({ disabled }) => (disabled ? "var(--color-fg-neutral-medium)" : "var(--color-fg-neutral-stronger)")}; + font-family: var(--typography-font-family); + font-size: var(--typography-helper-text-s); + font-weight: var(--typography-helper-text-regular); + margin-bottom: var(--spacing-gap-xs); +`; + +const Textarea = styled.textarea<{ + error: TextareaPropsType["error"]; + verticalGrow: TextareaPropsType["verticalGrow"]; +}>` + ${({ verticalGrow }) => { + if (verticalGrow === "none") return "resize: none;"; + else if (verticalGrow === "auto") return `resize: none; overflow: hidden;`; + else if (verticalGrow === "manual") return "resize: vertical;"; + else return `resize: none;`; + }}; + ${scrollbarStyles} + padding: var(--spacing-padding-xs) var(--spacing-padding-xs) var(--spacing-padding-xxxs) var(--spacing-padding-xs); + background-color: ${({ disabled }) => (disabled ? `var(--color-bg-neutral-lighter)` : `transparent`)}; + border-radius: var(--border-radius-s); + border: ${({ disabled, error }) => (!disabled && error ? "var(--border-width-m)" : "var(--border-width-s)")} + var(--border-style-default) + ${(props) => { + if (props.disabled) return "var(--border-color-neutral-strong)"; + else if (props.error) return "var(--border-color-error-medium)"; + else if (props.readOnly) return "var(--border-color-neutral-strong)"; + else return "var(--border-color-neutral-dark)"; + }}; + + ${(props) => + !props.disabled + ? `&:hover { + border-color: ${ + props.error + ? "var(--border-color-error-strong)" + : props.readOnly + ? "var(--border-color-neutral-stronger)" + : "var(--border-color-primary-strong)" + }; + } + &:focus, &:focus-within { + border-color: transparent; + outline-offset: -2px; + outline: var(--border-width-m) var(--border-style-default) var(--border-color-secondary-medium); + }` + : "cursor: not-allowed;"}; + + color: ${({ disabled }) => (disabled ? "var(--color-fg-neutral-medium)" : "var(--color-fg-neutral-dark)")}; + font-family: var(--typography-font-family); + font-size: var(--typography-label-m); + font-weight: var(--typography-label-regular); + ::placeholder { + color: ${({ disabled }) => (disabled ? "var(--color-fg-neutral-medium)" : "var(--color-fg-neutral-strong)")}; + } +`; + +const ErrorMessage = styled.span` + display: flex; + align-items: center; + color: var(--color-fg-error-medium); + font-family: var(--typography-font-family); + font-size: var(--typography-helper-text-s); + font-weight: var(--typography-helper-text-regular); + margin-top: var(--spacing-gap-xs); + + /* Error icon */ + > span[role="img"] { + font-size: var(--height-xxs); + } +`; const patternMatch = (pattern: string, value: string) => new RegExp(pattern).test(value); +const isLengthOutOfRange = (value: string, minLength?: number, maxLength?: number) => + value !== "" && minLength && maxLength && (value.length < minLength || value.length > maxLength); + const DxcTextarea = forwardRef<RefType, TextareaPropsType>( ( { - label, - name = "", + ariaLabel = "Text area", + autocomplete = "off", defaultValue = "", - value, - helperText, - placeholder = "", disabled = false, - readOnly = false, - optional = false, - verticalGrow = "auto", - rows = 4, - onChange, - onBlur, error, - pattern, - minLength, - maxLength, - autocomplete = "off", + helperText, + label, margin, + maxLength, + minLength, + name, + onBlur, + onChange, + optional = false, + pattern, + placeholder, + readOnly = false, + rows = 4, size = "medium", tabIndex = 0, - ariaLabel = "Text area", + value, + verticalGrow = "auto", }, ref ) => { const [innerValue, setInnerValue] = useState(defaultValue); const textareaId = `textarea-${useId()}`; - - const colorsTheme = useContext(HalstackContext); + const errorId = `error-${textareaId}`; const translatedLabels = useContext(HalstackLanguageContext); - const textareaRef = useRef<HTMLTextAreaElement | null>(null); const prevValueRef = useRef<string | null>(null); - const errorId = `error-${textareaId}`; - - const isNotOptional = (value: string) => value === "" && !optional; - - const isLengthIncorrect = (value: string) => - value !== "" && minLength && maxLength && (value.length < minLength || value.length > maxLength); const changeValue = (newValue: string) => { - if (value == null) { - setInnerValue(newValue); - } + if (value == null) setInnerValue(newValue); - if (isNotOptional(newValue)) { + if (newValue === "" && !optional) { onChange?.({ value: newValue, error: translatedLabels.formFields.requiredValueErrorMessage, }); - } else if (isLengthIncorrect(newValue)) { + } else if (isLengthOutOfRange(newValue)) { onChange?.({ value: newValue, error: translatedLabels.formFields.lengthErrorMessage?.(minLength, maxLength), @@ -70,18 +182,16 @@ const DxcTextarea = forwardRef<RefType, TextareaPropsType>( value: newValue, error: translatedLabels.formFields.formatRequestedErrorMessage, }); - } else { - onChange?.({ value: newValue }); - } + } else onChange?.({ value: newValue }); }; const handleOnBlur = (event: FocusEvent<HTMLTextAreaElement>) => { - if (isNotOptional(event.target.value)) { + if (event.target.value === "" && !optional) { onBlur?.({ value: event.target.value, error: translatedLabels.formFields.requiredValueErrorMessage, }); - } else if (isLengthIncorrect(event.target.value)) { + } else if (isLengthOutOfRange(event.target.value)) { onBlur?.({ value: event.target.value, error: translatedLabels.formFields.lengthErrorMessage?.(minLength, maxLength), @@ -91,9 +201,7 @@ const DxcTextarea = forwardRef<RefType, TextareaPropsType>( value: event.target.value, error: translatedLabels.formFields.formatRequestedErrorMessage, }); - } else { - onBlur?.({ value: event.target.value }); - } + } else onBlur?.({ value: event.target.value }); }; const handleOnChange = (event: ChangeEvent<HTMLTextAreaElement>) => { @@ -103,186 +211,54 @@ const DxcTextarea = forwardRef<RefType, TextareaPropsType>( useEffect(() => { if (verticalGrow === "auto" && prevValueRef.current !== (value ?? innerValue) && textareaRef.current) { const computedStyle = window.getComputedStyle(textareaRef.current); - const textareaLineHeight = parseInt(computedStyle.lineHeight || "0", 10); - const textareaPaddingTopBottom = parseInt(computedStyle.paddingTop || "0", 10) * 2; + const textareaLineHeight = parseInt(computedStyle.lineHeight ?? "0", 10); + const textareaPaddingTopBottom = parseInt(computedStyle.paddingTop ?? "0", 10) * 2; textareaRef.current.style.height = `${textareaLineHeight * rows}px`; const newHeight = (textareaRef.current.scrollHeight ?? 0) - textareaPaddingTopBottom; textareaRef.current.style.height = `${newHeight}px`; prevValueRef.current = value ?? innerValue; } - }, [verticalGrow, value, innerValue, rows]); + }, [innerValue, rows, value, verticalGrow]); return ( - <ThemeProvider theme={colorsTheme.textarea}> - <TextareaContainer margin={margin} size={size} ref={ref}> - {label && ( - <Label htmlFor={textareaId} disabled={disabled} helperText={helperText}> - {label} {optional && <OptionalLabel>{translatedLabels.formFields.optionalLabel}</OptionalLabel>} - </Label> - )} - {helperText && <HelperText disabled={disabled}>{helperText}</HelperText>} - <Textarea - id={textareaId} - name={name} - value={value ?? innerValue} - placeholder={placeholder} - verticalGrow={verticalGrow} - rows={rows} - onChange={handleOnChange} - onBlur={handleOnBlur} - disabled={disabled} - readOnly={readOnly} - error={error} - minLength={minLength} - maxLength={maxLength} - autoComplete={autocomplete} - ref={textareaRef} - tabIndex={tabIndex} - aria-invalid={!!error} - aria-errormessage={error ? errorId : undefined} - aria-required={!disabled && !optional} - aria-label={label ? undefined : ariaLabel} - /> - {!disabled && typeof error === "string" && ( - <ErrorMessageContainer id={errorId} role="alert" aria-live={error ? "assertive" : "off"}> - {error} - </ErrorMessageContainer> - )} - </TextareaContainer> - </ThemeProvider> + <TextareaContainer margin={margin} size={size} ref={ref}> + {label && ( + <Label htmlFor={textareaId} disabled={disabled} helperText={helperText}> + {label} {optional && <span>{translatedLabels.formFields.optionalLabel}</span>} + </Label> + )} + {helperText && <HelperText disabled={disabled}>{helperText}</HelperText>} + <Textarea + id={textareaId} + name={name} + value={value ?? innerValue} + placeholder={placeholder} + verticalGrow={verticalGrow} + rows={rows} + onChange={handleOnChange} + onBlur={handleOnBlur} + disabled={disabled} + readOnly={readOnly} + error={error} + minLength={minLength} + maxLength={maxLength} + autoComplete={autocomplete} + ref={textareaRef} + tabIndex={tabIndex} + aria-invalid={!!error} + aria-errormessage={error ? errorId : undefined} + aria-required={!disabled && !optional} + aria-label={label ? undefined : ariaLabel} + /> + {!disabled && typeof error === "string" && ( + <ErrorMessage id={errorId} role="alert" aria-live={error ? "assertive" : "off"}> + {error && <DxcIcon icon="filled_error" />} + {error} + </ErrorMessage> + )} + </TextareaContainer> ); } ); -const sizes = { - small: "240px", - medium: "360px", - large: "480px", - fillParent: "100%", -}; - -const calculateWidth = (margin: TextareaPropsType["margin"], size: TextareaPropsType["size"]) => - size === "fillParent" - ? `calc(${sizes[size]} - ${getMargin(margin, "left")} - ${getMargin(margin, "right")})` - : size && sizes[size]; - -const TextareaContainer = styled.div<{ - margin: TextareaPropsType["margin"]; - size: TextareaPropsType["size"]; -}>` - display: flex; - flex-direction: column; - width: ${(props) => calculateWidth(props.margin, props.size)}; - margin: ${(props) => (props.margin && typeof props.margin !== "object" ? spaces[props.margin] : "0px")}; - margin-top: ${(props) => - props.margin && typeof props.margin === "object" && props.margin.top ? spaces[props.margin.top] : ""}; - margin-right: ${(props) => - props.margin && typeof props.margin === "object" && props.margin.right ? spaces[props.margin.right] : ""}; - margin-bottom: ${(props) => - props.margin && typeof props.margin === "object" && props.margin.bottom ? spaces[props.margin.bottom] : ""}; - margin-left: ${(props) => - props.margin && typeof props.margin === "object" && props.margin.left ? spaces[props.margin.left] : ""}; -`; - -const Label = styled.label<{ - disabled: TextareaPropsType["disabled"]; - helperText: TextareaPropsType["helperText"]; -}>` - color: ${(props) => (props.disabled ? props.theme.disabledLabelFontColor : props.theme.labelFontColor)}; - - font-family: ${(props) => props.theme.fontFamily}; - font-size: ${(props) => props.theme.labelFontSize}; - font-style: ${(props) => props.theme.labelFontStyle}; - font-weight: ${(props) => props.theme.labelFontWeight}; - line-height: ${(props) => props.theme.labelLineHeight}; - ${(props) => !props.helperText && `margin-bottom: 0.25rem`} -`; - -const OptionalLabel = styled.span` - font-weight: ${(props) => props.theme.optionalLabelFontWeight}; -`; - -const HelperText = styled.span<{ disabled: TextareaPropsType["disabled"] }>` - color: ${(props) => (props.disabled ? props.theme.disabledHelperTextFontColor : props.theme.helperTextFontColor)}; - - font-family: ${(props) => props.theme.fontFamily}; - font-size: ${(props) => props.theme.helperTextFontSize}; - font-style: ${(props) => props.theme.helperTextFontStyle}; - font-weight: ${(props) => props.theme.helperTextFontWeight}; - line-height: ${(props) => props.theme.helperTextLineHeight}; - margin-bottom: 0.25rem; -`; - -const Textarea = styled.textarea<{ - verticalGrow: TextareaPropsType["verticalGrow"]; - error: TextareaPropsType["error"]; -}>` - ${({ verticalGrow }) => { - if (verticalGrow === "none") return "resize: none;"; - else if (verticalGrow === "auto") return `resize: none; overflow: hidden;`; - else if (verticalGrow === "manual") return "resize: vertical;"; - else return `resize: none;`; - }}; - - ${(props) => - props.disabled ? `background-color: ${props.theme.disabledContainerFillColor};` : `background-color: transparent;`} - - padding: 0.5rem 1rem; - box-shadow: 0 0 0 2px transparent; - border-radius: 0.25rem; - border: 1px solid - ${(props) => { - if (props.disabled) return props.theme.disabledBorderColor; - else if (props.error) return "transparent"; - else if (props.readOnly) return props.theme.readOnlyBorderColor; - else return props.theme.enabledBorderColor; - }}; - - ${(props) => - props.error && - !props.disabled && - `box-shadow: 0 0 0 2px ${props.theme.errorBorderColor}; - `} - - ${(props) => - !props.disabled - ? `&:hover { - border-color: ${ - props.error - ? "transparent" - : props.readOnly - ? props.theme.hoverReadOnlyBorderColor - : props.theme.hoverBorderColor - }; - ${props.error && `box-shadow: 0 0 0 2px ${props.theme.hoverErrorBorderColor};`} - } - &:focus, &:focus-within { - outline: none; - border-color: transparent; - box-shadow: 0 0 0 2px ${props.theme.focusBorderColor}; - }` - : "cursor: not-allowed;"}; - - color: ${(props) => (props.disabled ? props.theme.disabledValueFontColor : props.theme.valueFontColor)}; - font-family: ${(props) => props.theme.fontFamily}; - font-size: ${(props) => props.theme.valueFontSize}; - font-style: ${(props) => props.theme.valueFontStyle}; - font-weight: ${(props) => props.theme.valueFontWeight}; - line-height: 1.5em; - - ::placeholder { - color: ${(props) => (props.disabled ? props.theme.disabledPlaceholderFontColor : props.theme.placeholderFontColor)}; - } -`; - -const ErrorMessageContainer = styled.span` - color: ${(props) => props.theme.errorMessageColor}; - font-family: ${(props) => props.theme.fontFamily}; - font-size: 0.75rem; - font-weight: 400; - min-height: 1.5em; - line-height: 1.5em; - margin-top: 0.25rem; -`; - export default DxcTextarea; diff --git a/packages/lib/src/textarea/types.ts b/packages/lib/src/textarea/types.ts index 5fff2da46b..b1c9d3c6a8 100644 --- a/packages/lib/src/textarea/types.ts +++ b/packages/lib/src/textarea/types.ts @@ -2,55 +2,75 @@ import { Margin, Space } from "../common/utils"; type Props = { /** - * Text to be placed above the textarea. + * Specifies a string to be used as the name for the textarea element when no `label` is provided. */ - label?: string; + ariaLabel?: string; /** - * Name attribute of the textarea element. + * HTML autocomplete attribute. Lets the user specify if any permission the user agent has to provide automated assistance in filling out the textarea value. + * Its value must be one of all the possible values of the HTML autocomplete attribute: 'on', 'off', 'email', 'username', 'new-password', ... */ - name?: string; + autocomplete?: string; + /** + * If true, the component will be disabled. + */ + disabled?: boolean; /** * Initial value of the textarea, only when it is uncontrolled. */ defaultValue?: string; /** - * Value of the textarea. If undefined, the component will be uncontrolled and the value will be managed internally. + * If it is a defined value and also a truthy string, the component will + * change its appearance, showing the error below the textarea. If the + * defined value is an empty string, it will reserve a space below the + * component for a future error, but it would not change its look. In + * case of being undefined or null, both the appearance and the space for + * the error message would not be modified. */ - value?: string; + error?: string; /** * Helper text to be placed above the textarea. */ helperText?: string; /** - * Text to be put as placeholder of the textarea. + * Text to be placed above the textarea. */ - placeholder?: string; + label?: string; /** - * If true, the component will be disabled. + * Specifies the maximum length allowed by the textarea. + * This will be checked both when the textarea loses the + * focus and while typing within it. If the string entered does not + * comply the maximum length, the onBlur and onChange functions will be called + * with the current value and an internal error informing that the value + * length does not comply the specified range. If a valid length is + * reached, the error parameter of both events will not be defined. */ - disabled?: boolean; + maxLength?: number; /** - * If true, the component will not be mutable, meaning the user can not edit the control. + * Size of the margin to be applied to the component ('xxsmall' | 'xsmall' | 'small' | 'medium' | 'large' | 'xlarge' | 'xxlarge'). + * You can pass an object with 'top', 'bottom', 'left' and 'right' properties in order to specify different margin sizes. */ - readOnly?: boolean; + margin?: Space | Margin; /** - * If true, the textarea will be optional, showing '(Optional)' - * next to the label. Otherwise, the field will be considered required - * and an error will be passed as a parameter to the OnBlur and onChange functions - * when it has not been filled. + * Specifies the minimum length allowed by the textarea. + * This will be checked both when the textarea loses the + * focus and while typing within it. If the string entered does not + * comply the minimum length, the onBlur and onChange functions will be called + * with the current value and an internal error informing that the value + * length does not comply the specified range. If a valid length is + * reached, the error parameter of both events will not be defined. */ - optional?: boolean; + minLength?: number; /** - * Defines the textarea's ability to resize vertically. It can be: - * - 'auto': The textarea grows or shrinks automatically in order to fit the content. - * - 'manual': The height of the textarea is enabled to be manually modified. - * - 'none': The textarea has a fixed height and can't be modified. + * Name attribute of the textarea element. */ - verticalGrow?: "auto" | "manual" | "none"; + name?: string; /** - * Number of rows of the textarea. + * This function will be called when the textarea loses the focus. An + * object including the textarea value and the error (if the value entered + * is not valid) will be passed to this function. If there is no error, + * error will not be defined. */ - rows?: number; + onBlur?: (val: { value: string; error?: string }) => void; /** * This function will be called when the user types within the textarea. * An object including the current value and the error (if the value @@ -59,21 +79,12 @@ type Props = { */ onChange?: (val: { value: string; error?: string }) => void; /** - * This function will be called when the textarea loses the focus. An - * object including the textarea value and the error (if the value entered - * is not valid) will be passed to this function. If there is no error, - * error will not be defined. - */ - onBlur?: (val: { value: string; error?: string }) => void; - /** - * If it is a defined value and also a truthy string, the component will - * change its appearance, showing the error below the textarea. If the - * defined value is an empty string, it will reserve a space below the - * component for a future error, but it would not change its look. In - * case of being undefined or null, both the appearance and the space for - * the error message would not be modified. + * If true, the textarea will be optional, showing '(Optional)' + * next to the label. Otherwise, the field will be considered required + * and an error will be passed as a parameter to the OnBlur and onChange functions + * when it has not been filled. */ - error?: string; + optional?: boolean; /** * Regular expression that defines the valid format allowed by the * textarea. This will be checked both when the textarea loses the focus @@ -85,35 +96,17 @@ type Props = { */ pattern?: string; /** - * Specifies the minimum length allowed by the textarea. - * This will be checked both when the textarea loses the - * focus and while typing within it. If the string entered does not - * comply the minimum length, the onBlur and onChange functions will be called - * with the current value and an internal error informing that the value - * length does not comply the specified range. If a valid length is - * reached, the error parameter of both events will not be defined. - */ - minLength?: number; - /** - * Specifies the maximum length allowed by the textarea. - * This will be checked both when the textarea loses the - * focus and while typing within it. If the string entered does not - * comply the maximum length, the onBlur and onChange functions will be called - * with the current value and an internal error informing that the value - * length does not comply the specified range. If a valid length is - * reached, the error parameter of both events will not be defined. + * Text to be put as placeholder of the textarea. */ - maxLength?: number; + placeholder?: string; /** - * HTML autocomplete attribute. Lets the user specify if any permission the user agent has to provide automated assistance in filling out the textarea value. - * Its value must be one of all the possible values of the HTML autocomplete attribute: 'on', 'off', 'email', 'username', 'new-password', ... + * If true, the component will not be mutable, meaning the user can not edit the control. */ - autocomplete?: string; + readOnly?: boolean; /** - * Size of the margin to be applied to the component ('xxsmall' | 'xsmall' | 'small' | 'medium' | 'large' | 'xlarge' | 'xxlarge'). - * You can pass an object with 'top', 'bottom', 'left' and 'right' properties in order to specify different margin sizes. + * Number of rows of the textarea. */ - margin?: Space | Margin; + rows?: number; /** * Size of the component. */ @@ -123,10 +116,18 @@ type Props = { */ tabIndex?: number; /** - * Specifies a string to be used as the name for the textarea element when no `label` is provided. + * Value of the textarea. If undefined, the component will be uncontrolled and the value will be managed internally. */ - ariaLabel?: string; + value?: string; + /** + * Defines the textarea's ability to resize vertically. It can be: + * - 'auto': The textarea grows or shrinks automatically in order to fit the content. + * - 'manual': The height of the textarea is enabled to be manually modified. + * - 'none': The textarea has a fixed height and can't be modified. + */ + verticalGrow?: "auto" | "manual" | "none"; }; + /** * Reference to the component. */ From cbf4167a03103e76d0925f9e12f7c7a52dd0c0cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20G=C3=B3mez=20Pinta?= <44321109+GomezIvann@users.noreply.github.com> Date: Thu, 20 Mar 2025 16:14:49 +0100 Subject: [PATCH 2/7] Textarea docs structure updated --- .../pages/components/textarea/code.tsx | 17 ++ .../pages/components/textarea/index.tsx | 24 +- .../components/textarea/specifications.tsx | 21 -- .../pages/components/textarea/usage.tsx | 21 -- .../textarea/TextareaPageLayout.tsx | 7 +- .../textarea/code/TextareaCodePage.tsx | 238 +++++++++--------- .../overview/TextareaOverviewPage.tsx | 26 ++ .../textarea/specs/TextareaSpecsPage.tsx | 203 --------------- .../specs/images/textarea_anatomy.png | Bin 19468 -> 0 bytes .../textarea/specs/images/textarea_specs.png | Bin 23168 -> 0 bytes .../textarea/specs/images/textarea_states.png | Bin 40118 -> 0 bytes .../textarea/usage/TextareaUsagePage.tsx | 33 --- 12 files changed, 174 insertions(+), 416 deletions(-) create mode 100644 apps/website/pages/components/textarea/code.tsx delete mode 100644 apps/website/pages/components/textarea/specifications.tsx delete mode 100644 apps/website/pages/components/textarea/usage.tsx create mode 100644 apps/website/screens/components/textarea/overview/TextareaOverviewPage.tsx delete mode 100644 apps/website/screens/components/textarea/specs/TextareaSpecsPage.tsx delete mode 100644 apps/website/screens/components/textarea/specs/images/textarea_anatomy.png delete mode 100644 apps/website/screens/components/textarea/specs/images/textarea_specs.png delete mode 100644 apps/website/screens/components/textarea/specs/images/textarea_states.png delete mode 100644 apps/website/screens/components/textarea/usage/TextareaUsagePage.tsx diff --git a/apps/website/pages/components/textarea/code.tsx b/apps/website/pages/components/textarea/code.tsx new file mode 100644 index 0000000000..2347321b98 --- /dev/null +++ b/apps/website/pages/components/textarea/code.tsx @@ -0,0 +1,17 @@ +import Head from "next/head"; +import type { ReactElement } from "react"; +import TextareaPageLayout from "screens/components/textarea/TextareaPageLayout"; +import TextareaCodePage from "screens/components/textarea/code/TextareaCodePage"; + +const Code = () => ( + <> + <Head> + <title>Textarea code — Halstack Design System + + + +); + +Code.getLayout = (page: ReactElement) => {page}; + +export default Code; diff --git a/apps/website/pages/components/textarea/index.tsx b/apps/website/pages/components/textarea/index.tsx index cc62fdc95f..96d811ca23 100644 --- a/apps/website/pages/components/textarea/index.tsx +++ b/apps/website/pages/components/textarea/index.tsx @@ -1,21 +1,17 @@ import Head from "next/head"; import type { ReactElement } from "react"; -import TextareaCodePage from "screens/components/textarea/code/TextareaCodePage"; +import TextareaOverviewPage from "screens/components/textarea/overview/TextareaOverviewPage"; import TextareaPageLayout from "screens/components/textarea/TextareaPageLayout"; -const Index = () => { - return ( - <> - - Textarea — Halstack Design System - - - - ); -}; +const Index = () => ( + <> + + Textarea — Halstack Design System + + + +); -Index.getLayout = function getLayout(page: ReactElement) { - return {page}; -}; +Index.getLayout = (page: ReactElement) => {page}; export default Index; diff --git a/apps/website/pages/components/textarea/specifications.tsx b/apps/website/pages/components/textarea/specifications.tsx deleted file mode 100644 index caffc46119..0000000000 --- a/apps/website/pages/components/textarea/specifications.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import Head from "next/head"; -import type { ReactElement } from "react"; -import TextareaSpecsPage from "screens/components/textarea/specs/TextareaSpecsPage"; -import TextareaPageLayout from "screens/components/textarea/TextareaPageLayout"; - -const Specifications = () => { - return ( - <> - - Textarea Specs — Halstack Design System - - - - ); -}; - -Specifications.getLayout = function getLayout(page: ReactElement) { - return {page}; -}; - -export default Specifications; diff --git a/apps/website/pages/components/textarea/usage.tsx b/apps/website/pages/components/textarea/usage.tsx deleted file mode 100644 index eb2d70ccad..0000000000 --- a/apps/website/pages/components/textarea/usage.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import Head from "next/head"; -import type { ReactElement } from "react"; -import TextareaPageLayout from "screens/components/textarea/TextareaPageLayout"; -import TextareaUsagePage from "screens/components/textarea/usage/TextareaUsagePage"; - -const Usage = () => { - return ( - <> - - Textarea Usage — Halstack Design System - - - - ); -}; - -Usage.getLayout = function getLayout(page: ReactElement) { - return {page}; -}; - -export default Usage; diff --git a/apps/website/screens/components/textarea/TextareaPageLayout.tsx b/apps/website/screens/components/textarea/TextareaPageLayout.tsx index 245469b840..fab3c09a40 100644 --- a/apps/website/screens/components/textarea/TextareaPageLayout.tsx +++ b/apps/website/screens/components/textarea/TextareaPageLayout.tsx @@ -6,9 +6,8 @@ import { ReactNode } from "react"; const TextareaPageHeading = ({ children }: { children: ReactNode }) => { const tabs = [ - { label: "Code", path: "/components/textarea" }, - { label: "Usage", path: "/components/textarea/usage" }, - { label: "Specifications", path: "/components/textarea/specifications" }, + { label: "Overview", path: "/components/textarea" }, + { label: "Code", path: "/components/textarea/code" }, ]; return ( @@ -17,7 +16,7 @@ const TextareaPageHeading = ({ children }: { children: ReactNode }) => { A textarea allows the users enter a multi-line, free-form text. - + {children} diff --git a/apps/website/screens/components/textarea/code/TextareaCodePage.tsx b/apps/website/screens/components/textarea/code/TextareaCodePage.tsx index aa6a5e8f65..cc55aad6f8 100644 --- a/apps/website/screens/components/textarea/code/TextareaCodePage.tsx +++ b/apps/website/screens/components/textarea/code/TextareaCodePage.tsx @@ -24,38 +24,60 @@ const sections = [ - defaultValue + ariaLabel string - Initial value of the textarea, only when it is uncontrolled. - - + + Specifies a string to be used as the name for the textarea element when no label is provided. + + 'Text area' - value + autocomplete string - Value of the textarea. If undefined, the component will be uncontrolled and the value will be managed - internally. + HTML autocomplete attribute. Lets the user specify if any permission the user agent has to + provide automated assistance in filling out the input value. Its value must be one of all the possible + values of the HTML autocomplete attribute. See{" "} + MDN{" "} + for further information. + + + 'off' - - - label + defaultValue string - Text to be placed above the textarea. + Initial value of the textarea, only when it is uncontrolled. - - name + disabled + + boolean + + If true, the component will be disabled. + + false + + + + error string - Name attribute of the textarea element. + + If it is a defined value and also a truthy string, the component will change its appearance, showing the + error below the textarea. If the defined value is an empty string, it will reserve a space below the + component for a future error, but it would not change its look. In case of being undefined or null, both + the appearance and the space for the error message would not be modified. + - @@ -67,79 +89,71 @@ const sections = [ - - placeholder + label string - Text to be put as placeholder of the textarea. + Text to be placed above the textarea. - - disabled + margin - boolean + 'xxsmall' | 'xsmall' | 'small' | 'medium' | 'large' | 'xlarge' | 'xxlarge' | Margin - If true, the component will be disabled. - false + Size of the margin to be applied to the component. You can pass an object with 'top', 'bottom', 'left' and + 'right' properties in order to specify different margin sizes. + - - optional - - boolean - + maxLength - If true, the textarea will be optional, showing '(Optional)' next to the label. Otherwise, the field will - be considered required and an error will be passed as a parameter to the onBlur and{" "} - onChange functions when it has not been filled. + number - false + Specifies the maximum length allowed by the textarea. This will be checked both when the input element + loses the focus and while typing within it. If the string entered does not comply the maximum length, the{" "} + onBlur and onChange functions will be called with the current value and an + internal error informing that the value length does not comply the specified range. If a valid length is + reached, the error parameter of both events will not be defined. + - - readOnly + minLength - boolean + number - If true, the component will not be mutable, meaning the user can not edit the control. - false + Specifies the minimum length allowed by the textarea. This will be checked both when the input element + loses the focus and while typing within it. If the string entered does not comply the minimum length, the{" "} + onBlur and onChange functions will be called with the current value and an + internal error informing that the value length does not comply the specified range. If a valid length is + reached, the error parameter of both events will not be defined. + - - verticalGrow - - 'auto' | 'manual' | 'none' - - - Defines the textarea's ability to resize vertically. It can be: -
    -
  • - 'auto': The textarea grows or shrinks automatically in order to fit the content. -
  • -
  • - 'manual': The height of the textarea is enabled to be manually modified. -
  • -
  • - 'none': The textarea has a fixed height and can't be modified. -
  • -
- + name - 'auto' + string + Name attribute of the textarea element. + - - rows + onBlur - number + {"(val: { value: string; error?: string }) => void"} - Number of rows of the textarea. - 4 + This function will be called when the textarea loses the focus. An object including the textarea value and + the error (if the value entered is not valid) will be passed to this function. If there is no error,{" "} + error will not be defined. + - onChange @@ -154,29 +168,18 @@ const sections = [ - - onBlur - - {"(val: { value: string; error?: string }) => void"} - + optional - This function will be called when the textarea loses the focus. An object including the textarea value and - the error (if the value entered is not valid) will be passed to this function. If there is no error,{" "} - error will not be defined. + boolean - - - - - error - string + If true, the textarea will be optional, showing '(Optional)' next to the label. Otherwise, the field will + be considered required and an error will be passed as a parameter to the onBlur and{" "} + onChange functions when it has not been filled. - If it is a defined value and also a truthy string, the component will change its appearance, showing the - error below the textarea. If the defined value is an empty string, it will reserve a space below the - component for a future error, but it would not change its look. In case of being undefined or null, both - the appearance and the space for the error message would not be modified. + false - - pattern @@ -193,59 +196,40 @@ const sections = [ - - minLength - - number - + placeholder - Specifies the minimum length allowed by the textarea. This will be checked both when the input element - loses the focus and while typing within it. If the string entered does not comply the minimum length, the{" "} - onBlur and onChange functions will be called with the current value and an - internal error informing that the value length does not comply the specified range. If a valid length is - reached, the error parameter of both events will not be defined. + string + Text to be put as placeholder of the textarea. - - maxLength + readOnly - number + boolean + If true, the component will not be mutable, meaning the user can not edit the control. - Specifies the maximum length allowed by the textarea. This will be checked both when the input element - loses the focus and while typing within it. If the string entered does not comply the maximum length, the{" "} - onBlur and onChange functions will be called with the current value and an - internal error informing that the value length does not comply the specified range. If a valid length is - reached, the error parameter of both events will not be defined. + false - - - autocomplete - - string - - - HTML autocomplete attribute. Lets the user specify if any permission the user agent has to - provide automated assistance in filling out the input value. Its value must be one of all the possible - values of the HTML autocomplete attribute. See{" "} - MDN{" "} - for further information. - + ref - 'off' + {"React.Ref"} + Reference to the component. + - - margin + rows - 'xxsmall' | 'xsmall' | 'small' | 'medium' | 'large' | 'xlarge' | 'xxlarge' | Margin + number + Number of rows of the textarea. - Size of the margin to be applied to the component. You can pass an object with 'top', 'bottom', 'left' and - 'right' properties in order to specify different margin sizes. + 4 - - size @@ -270,22 +254,38 @@ const sections = [ - ref + value - {"React.Ref"} + string + + + Value of the textarea. If undefined, the component will be uncontrolled and the value will be managed + internally. - Reference to the component. - - ariaLabel + verticalGrow - string + 'auto' | 'manual' | 'none' - Specifies a string to be used as the name for the textarea element when no label is provided. + Defines the textarea's ability to resize vertically. It can be: +
    +
  • + 'auto': The textarea grows or shrinks automatically in order to fit the content. +
  • +
  • + 'manual': The height of the textarea is enabled to be manually modified. +
  • +
  • + 'none': The textarea has a fixed height and can't be modified. +
  • +
+ + + 'auto' - 'Text area' @@ -310,15 +310,13 @@ const sections = [ }, ]; -const TextareaCodePage = () => { - return ( - - - - - - - ); -}; +const TextareaCodePage = () => ( + + + + + + +); export default TextareaCodePage; diff --git a/apps/website/screens/components/textarea/overview/TextareaOverviewPage.tsx b/apps/website/screens/components/textarea/overview/TextareaOverviewPage.tsx new file mode 100644 index 0000000000..013659c158 --- /dev/null +++ b/apps/website/screens/components/textarea/overview/TextareaOverviewPage.tsx @@ -0,0 +1,26 @@ +import { DxcBulletedList, DxcFlex, DxcParagraph } from "@dxc-technology/halstack-react"; +import QuickNavContainer from "@/common/QuickNavContainer"; +import QuickNavContainerLayout from "@/common/QuickNavContainerLayout"; +import DocFooter from "@/common/DocFooter"; + +const sections = [ + { + title: "Introduction", + content: ( + + The textarea component is a form component that allows the user to enter a multi-line, free-form text. + + ), + }, +]; + +const TextareaOverviewPage = () => ( + + + + + + +); + +export default TextareaOverviewPage; diff --git a/apps/website/screens/components/textarea/specs/TextareaSpecsPage.tsx b/apps/website/screens/components/textarea/specs/TextareaSpecsPage.tsx deleted file mode 100644 index 035b428f85..0000000000 --- a/apps/website/screens/components/textarea/specs/TextareaSpecsPage.tsx +++ /dev/null @@ -1,203 +0,0 @@ -import { DxcLink, DxcBulletedList, DxcFlex, DxcTable, DxcParagraph } from "@dxc-technology/halstack-react"; -import Figure from "@/common/Figure"; -import QuickNavContainer from "@/common/QuickNavContainer"; -import QuickNavContainerLayout from "@/common/QuickNavContainerLayout"; -import Image from "@/common/Image"; -import Code from "@/common/Code"; -import DocFooter from "@/common/DocFooter"; -import Link from "next/link"; -import specsImage from "./images/textarea_specs.png"; -import statesImage from "./images/textarea_states.png"; -import anatomyImage from "./images/textarea_anatomy.png"; - -const sections = [ - { - title: "Specifications", - content: ( - <> -
- Textarea design specifications -
- - The textarea color, typography, border, width and{" "} - margin specifications are inherited from the text input, for reference check the{" "} - - text input - {" "} - component documentation. - - - The textarea doesn't have the following text-input elements, therefore, their listed styles don't - apply: - - - Action - Prefix / Suffix - Error indicator - - - ), - }, - { - title: "States", - content: ( - <> - - States: enabled, hover, focus, error and{" "} - disabled. - -
- Textarea states -
- - ), - }, - { - title: "Anatomy", - content: ( - <> - Textarea anatomy - - Label - - Helper text (Optional) - - Placeholder/Value - Container - Resizer - Error message - - - ), - }, - { - title: "Design tokens", - subSections: [ - { - title: "Spacing", - content: ( - - - - Property - Element - Core token - Value - - - - - - padding-left - - Texarea container - - spacing-8 - - 1rem / 16px - - - - padding-right - - Texarea container - - spacing-8 - - 1rem / 16px - - - - margin-top - - Texarea container - - spacing-4 - - 0.5rem / 8px - - - - margin-bottom - - Texarea container - - spacing-4 - - 0.5rem / 8px - - - - ), - }, - ], - }, - { - title: "Accessibility", - subSections: [ - { - title: "WCAG", - content: ( - - - Understanding WCAG 2.2 -{" "} - - 1.3.1: Information and Relationships - - - - Understanding WCAG 2.2 -{" "} - - 3.3.1: Error Identification - - - - Understanding WCAG 2.2 -{" "} - - 3.3.2: Labels and Instructions - - - - Understanding WCAG 2.2 -{" "} - - 3.3.3: Error Suggestion - - - - Understanding WCAG 2.2 -{" "} - - 4.1.2: Name, Role, Value - - - - ), - }, - { - title: "WAI-ARIA", - content: ( - - - WAI-ARIA Accessible Rich Internet Applications 1.2 -{" "} - - textbox role - - - - ), - }, - ], - }, -]; - -const TextareaSpecsPage = () => { - return ( - - - - - - - ); -}; - -export default TextareaSpecsPage; diff --git a/apps/website/screens/components/textarea/specs/images/textarea_anatomy.png b/apps/website/screens/components/textarea/specs/images/textarea_anatomy.png deleted file mode 100644 index 1042a81ce3507fb8ebc7c03a290a7749dc69192d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19468 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 P{Ap|IUd+94`@#PKT^8Iy diff --git a/apps/website/screens/components/textarea/specs/images/textarea_specs.png b/apps/website/screens/components/textarea/specs/images/textarea_specs.png deleted file mode 100644 index 73e26ab5e4581e38b2c06f02b263cc188293e895..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23168 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 BV!QwV diff --git a/apps/website/screens/components/textarea/specs/images/textarea_states.png b/apps/website/screens/components/textarea/specs/images/textarea_states.png deleted file mode 100644 index 7e85e7c0a3d9423389ea7b3ce70ffa27e17f6ac5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40118 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 RZ7lGghMJD*ql4BL{|`m?044wc diff --git a/apps/website/screens/components/textarea/usage/TextareaUsagePage.tsx b/apps/website/screens/components/textarea/usage/TextareaUsagePage.tsx deleted file mode 100644 index d3f36bdc13..0000000000 --- a/apps/website/screens/components/textarea/usage/TextareaUsagePage.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import { DxcBulletedList, DxcFlex } from "@dxc-technology/halstack-react"; -import QuickNavContainer from "@/common/QuickNavContainer"; -import QuickNavContainerLayout from "@/common/QuickNavContainerLayout"; -import DocFooter from "@/common/DocFooter"; - -const sections = [ - { - title: "Usage", - content: ( - - - Use the textarea when users need to enter text longer than a single line. - - - Avoid using the textarea when complex questions can break up in simpler ones. - - - ), - }, -]; - -const TextareaUsagePage = () => { - return ( - - - - - - - ); -}; - -export default TextareaUsagePage; From 4b6ba7b6abd763ab4e0b062eee5a3cc4e99cfbe6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20G=C3=B3mez=20Pinta?= <44321109+GomezIvann@users.noreply.github.com> Date: Thu, 20 Mar 2025 17:12:37 +0100 Subject: [PATCH 3/7] Fix Textarea tests --- packages/lib/src/textarea/Textarea.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/lib/src/textarea/Textarea.tsx b/packages/lib/src/textarea/Textarea.tsx index ec2e367a24..78a113596f 100644 --- a/packages/lib/src/textarea/Textarea.tsx +++ b/packages/lib/src/textarea/Textarea.tsx @@ -126,9 +126,6 @@ const ErrorMessage = styled.span` const patternMatch = (pattern: string, value: string) => new RegExp(pattern).test(value); -const isLengthOutOfRange = (value: string, minLength?: number, maxLength?: number) => - value !== "" && minLength && maxLength && (value.length < minLength || value.length > maxLength); - const DxcTextarea = forwardRef( ( { @@ -164,6 +161,9 @@ 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 changeValue = (newValue: string) => { if (value == null) setInnerValue(newValue); From 301c37c50446ac62988c9a23cb007ffc44fe4f26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20G=C3=B3mez=20Pinta?= <44321109+GomezIvann@users.noreply.github.com> Date: Wed, 23 Apr 2025 11:00:01 +0200 Subject: [PATCH 4/7] Textarea: doc and component updates --- .../textarea/code/examples/controlled.ts | 1 + .../overview/TextareaOverviewPage.tsx | 204 +++++++++++++++++- .../overview/images/textarea_anatomy.png | Bin 0 -> 36423 bytes .../src/styles/forms/inputStylesByState.tsx | 1 + packages/lib/src/textarea/Textarea.tsx | 125 +++-------- 5 files changed, 233 insertions(+), 98 deletions(-) create mode 100644 apps/website/screens/components/textarea/overview/images/textarea_anatomy.png diff --git a/apps/website/screens/components/textarea/code/examples/controlled.ts b/apps/website/screens/components/textarea/code/examples/controlled.ts index 0bc5de8c4b..f4a11bc67b 100644 --- a/apps/website/screens/components/textarea/code/examples/controlled.ts +++ b/apps/website/screens/components/textarea/code/examples/controlled.ts @@ -14,6 +14,7 @@ const code = `() => { - The textarea component is a form component that allows the user to enter a multi-line, free-form text. - + <> + + Text areas are essential UI components that allow users to enter and interact with{" "} + multi-line text-based information. They are commonly used in forms to collect feedback, + comments, descriptions, and longer messages where a single-line input is not sufficient. Text areas support a + wide range of use cases—from support forms and user profiles to product reviews and detailed reports. + + + Providing clear labels, helpful guidance, and proper formatting improves the user's ability to input + information accurately and comfortably. Enhancing usability through accessibility, validation, and responsive + behavior leads to a more intuitive and effective user experience. + + + ), + }, + { + title: "Anatomy", + content: ( + <> + Textarea's anatomy + + + Label (Optional): a descriptive text that helps users understand what information + is expected in the input field. It should be clear, concise, and placed near the input for better + readability. + + + Optional indicator (Optional): a small indicator that signals the input field is + not mandatory. It helps users know they can leave the field empty without causing validation errors. + readability. + + + Placeholder/Value: a short hint displayed inside the input field before any text is + entered, offering a brief example or instruction on what type of data is expected. It disappears when the + user starts typing. + + + Helper text (Optional): additional text placed below the input label that provides + guidance, examples, or explanations to assist users in filling out the field correctly. + + + Container: the visual wrapper around the input field that provides structure, ensures + accessibility, and helps differentiate the input from other UI elements. + + + Resizer (Optional): allows users to manually expand or shrink the textarea if + resizing is enabled. + + + + ), + }, + { + title: "Form inputs", + content: ( + <> + + Form inputs are essential UI elements that allow users to interact with digital products by{" "} + entering or selecting data. Choosing the right input type and structure is key to designing + efficient, user-friendly forms that support task completion and data accuracy. + + + A form input (also known as a form field) is used to capture user data. Common input types include text + fields, date pickers, number fields, radio buttons, checkboxes, toggles, and dropdowns. Forms should always + include a submission method —such as a submit button, link, or keyboard trigger— to complete the interaction. + + + ), + subSections: [ + { + title: "Shared input characteristics", + content: ( + <> + + Although input fields vary in type and purpose, they often share a common set of features: + + + + Placeholder: a short hint displayed inside the input field that describes its expected + value or purpose. + + + Size and max length: inputs can have both a visual size (width of the field) and a + character limit that defines how much text can be entered. + + + Prefix or suffix: some inputs include a visual element before or after the user input + —like currency symbols or units— to help clarify the expected data. + + + Helper text: additional information displayed below the field to guide the user in + providing the correct input. + + + Optional label: inputs that are not mandatory can be marked with an "Optional" tag to + set clear expectations. + + + + ), + }, + { + title: "Common input states", + content: ( + <> + Most inputs can also present standard interactive or informative states: + + + Disabled: this state prevents users from interacting with the field. It's typically + used when a value is not applicable or editable under certain conditions or roles. + + + Error: when a user enters invalid or incomplete data, the input shows an error state, + often accompanied by a helpful message to guide corrections. + + + Read-only: the input is visible, focusable, and hoverable, but not editable. This is + ideal for fields with auto-calculated values. Unlike disabled fields, read-only inputs can still be + submitted with the form and are part of the form data. + + + + ), + }, + ], + }, + { + title: "Using text areas", + content: ( + <> + + While{" "} + + text inputs + {" "} + are ideal for short, single-line entries—such as names, email addresses, or search queries—text areas are + specifically designed to handle multi-line, freeform text. They offer users more space and + flexibility, making them the right choice for collecting messages, feedback, descriptions, or any content that + may extend beyond a sentence or two. + + + Choosing between a text input and a text area depends on the nature of the content you're asking for. For + instance, a "Job Title" field should use a standard text input, while a "Cover Letter" or "Project + Description" clearly benefits from a textarea. In some cases, even radio buttons, dropdowns, or checkboxes may + be more effective if the expected input can be predefined or simplified. + + + Understanding the user's intent and the expected length and complexity of the response is key to choosing the + right input type. Misusing a text area for short, simple answers can overwhelm users, while using a text input + for extended responses can result in frustration or poor usability. + + + ), + }, + { + title: "Best practices", + content: ( + + + Use the textarea for extended input: provide a textarea when users need to enter responses + longer than a single line, such as comments, messages, or descriptions. + + + Break down complex inputs: avoid using a textarea when a long question can be broken into + multiple, simpler fields. This helps reduce cognitive load and improves response quality. + + + Allow resizing only when beneficial: enable textarea resizing if the user may benefit from + adjusting the visible input area—especially for writing long or detailed content. + + + Avoid auto-expanding fields excessively: dynamic resizing can enhance usability, but ensure + it doesn't disrupt page layout or push key UI elements out of view. + + + + Provide error messages for clarity: + {" "} + use the error prop to surface validation messages. Make sure these are clear and actionable. + + + + Apply placeholder for hints, not instructions: + {" "} + use placeholder to provide example content or expected format (e.g., "Write your feedback + here…"). Avoid using it as a replacement for the label. + + + + Leverage helperText to guide users: + {" "} + add context, tips to help users complete the input accurately (e.g., "Avoid including personal information + like passwords or credit card numbers."). + + ), }, ]; diff --git a/apps/website/screens/components/textarea/overview/images/textarea_anatomy.png b/apps/website/screens/components/textarea/overview/images/textarea_anatomy.png new file mode 100644 index 0000000000000000000000000000000000000000..4a96b3a1a0743ebe65c27da6a39fd9b9fc3eb4ed GIT binary patch literal 36423 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 css` + background-color: ${disabled ? `var(--color-bg-neutral-lighter)` : `transparent`}; border-radius: var(--border-radius-s); border: ${!disabled && error ? "var(--border-width-m)" : "var(--border-width-s)"} var(--border-style-default) ${(() => { diff --git a/packages/lib/src/textarea/Textarea.tsx b/packages/lib/src/textarea/Textarea.tsx index 78a113596f..b1bd6d491a 100644 --- a/packages/lib/src/textarea/Textarea.tsx +++ b/packages/lib/src/textarea/Textarea.tsx @@ -5,7 +5,10 @@ import { spaces } from "../common/variables"; import { HalstackLanguageContext } from "../HalstackContext"; import TextareaPropsType, { RefType } from "./types"; import { scrollbarStyles } from "../styles/scroll"; -import DxcIcon from "../icon/Icon"; +import ErrorMessage from "../styles/forms/ErrorMessage"; +import Label from "../styles/forms/Label"; +import HelperText from "../styles/forms/HelperText"; +import { inputStylesByState } from "../styles/forms/inputStylesByState"; const sizes = { small: "240px", @@ -34,33 +37,10 @@ const TextareaContainer = styled.div<{ margin-left: ${({ margin }) => (margin && typeof margin === "object" && margin.left ? spaces[margin.left] : "")}; `; -const Label = styled.label<{ - disabled: TextareaPropsType["disabled"]; - helperText: TextareaPropsType["helperText"]; -}>` - color: ${({ disabled }) => (disabled ? "var(--color-fg-neutral-medium)" : "var(--color-fg-neutral-dark)")}; - font-family: var(--typography-font-family); - font-size: var(--typography-label-m); - font-weight: var(--typography-label-semibold); - ${({ helperText }) => !helperText && "margin-bottom: var(--spacing-gap-xs);"} - - /* Optional text */ - > span { - color: ${({ disabled }) => (disabled ? "var(--color-fg-neutral-medium)" : "var(--color-fg-neutral-stronger)")}; - font-weight: var(--typography-label-regular); - } -`; - -const HelperText = styled.span<{ disabled: TextareaPropsType["disabled"] }>` - color: ${({ disabled }) => (disabled ? "var(--color-fg-neutral-medium)" : "var(--color-fg-neutral-stronger)")}; - font-family: var(--typography-font-family); - font-size: var(--typography-helper-text-s); - font-weight: var(--typography-helper-text-regular); - margin-bottom: var(--spacing-gap-xs); -`; - const Textarea = styled.textarea<{ - error: TextareaPropsType["error"]; + disabled: Required["disabled"]; + error: boolean; + readOnly: Required["readOnly"]; verticalGrow: TextareaPropsType["verticalGrow"]; }>` ${({ verticalGrow }) => { @@ -69,61 +49,19 @@ const Textarea = styled.textarea<{ else if (verticalGrow === "manual") return "resize: vertical;"; else return `resize: none;`; }}; - ${scrollbarStyles} padding: var(--spacing-padding-xs) var(--spacing-padding-xs) var(--spacing-padding-xxxs) var(--spacing-padding-xs); - background-color: ${({ disabled }) => (disabled ? `var(--color-bg-neutral-lighter)` : `transparent`)}; - border-radius: var(--border-radius-s); - border: ${({ disabled, error }) => (!disabled && error ? "var(--border-width-m)" : "var(--border-width-s)")} - var(--border-style-default) - ${(props) => { - if (props.disabled) return "var(--border-color-neutral-strong)"; - else if (props.error) return "var(--border-color-error-medium)"; - else if (props.readOnly) return "var(--border-color-neutral-strong)"; - else return "var(--border-color-neutral-dark)"; - }}; - - ${(props) => - !props.disabled - ? `&:hover { - border-color: ${ - props.error - ? "var(--border-color-error-strong)" - : props.readOnly - ? "var(--border-color-neutral-stronger)" - : "var(--border-color-primary-strong)" - }; - } - &:focus, &:focus-within { - border-color: transparent; - outline-offset: -2px; - outline: var(--border-width-m) var(--border-style-default) var(--border-color-secondary-medium); - }` - : "cursor: not-allowed;"}; - + ${({ disabled, error, readOnly }) => inputStylesByState(disabled, error, readOnly)} color: ${({ disabled }) => (disabled ? "var(--color-fg-neutral-medium)" : "var(--color-fg-neutral-dark)")}; font-family: var(--typography-font-family); font-size: var(--typography-label-m); font-weight: var(--typography-label-regular); + line-height: 1.36; + ${scrollbarStyles} ::placeholder { color: ${({ disabled }) => (disabled ? "var(--color-fg-neutral-medium)" : "var(--color-fg-neutral-strong)")}; } `; -const ErrorMessage = styled.span` - display: flex; - align-items: center; - color: var(--color-fg-error-medium); - font-family: var(--typography-font-family); - font-size: var(--typography-helper-text-s); - font-weight: var(--typography-helper-text-regular); - margin-top: var(--spacing-gap-xs); - - /* Error icon */ - > span[role="img"] { - font-size: var(--height-xxs); - } -`; - const patternMatch = (pattern: string, value: string) => new RegExp(pattern).test(value); const DxcTextarea = forwardRef( @@ -223,39 +161,38 @@ const DxcTextarea = forwardRef( return ( {label && ( -