Skip to content

Commit

Permalink
Refactor(web-react): Separate HelperText and ValidationText subcompon…
Browse files Browse the repository at this point in the history
…ents

- moved from Field component to their own subcomponents
- updated imports and exports
  • Loading branch information
pavelklibani committed Feb 4, 2025
1 parent c1bfd89 commit bae6ed3
Show file tree
Hide file tree
Showing 27 changed files with 60 additions and 106 deletions.
5 changes: 3 additions & 2 deletions packages/web-react/src/components/Checkbox/Checkbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import classNames from 'classnames';
import React, { ForwardedRef, forwardRef } from 'react';
import { useStyleProps } from '../../hooks';
import { SpiritCheckboxProps } from '../../types';
import { HelperText, ValidationText, useAriaIds } from '../Field';
import { useValidationTextRole } from '../Field/useValidationTextRole';
import { useAriaIds } from '../Field';
import { HelperText } from '../HelperText';
import { Label } from '../Label';
import { useValidationTextRole, ValidationText } from '../ValidationText';
import { useCheckboxStyleProps } from './useCheckboxStyleProps';

/* We need an exception for components exported with forwardRef */
Expand Down
65 changes: 0 additions & 65 deletions packages/web-react/src/components/Field/README.md
Original file line number Diff line number Diff line change
@@ -1,66 +1 @@
# Field

## ValidationText

The ValidationText subcomponent displays validation texts for Field components like TextField, TextArea, Checkbox, FileUploader, etc.

```jsx
import { ValidationText } from '@lmc-eu/spirit-web-react/components';
```

Basic example usage:

```jsx
<ValidationText className="Component__validationText" validationText="Danger validation text" />
```

Advanced example:

```jsx
<ValidationText
id="component__validationText"
className="Component__validationText"
elementType="span"
validationText="Danger validation text"
role="alert"
/>
```

## Role Attribute

When displaying text dynamically, set [`role="alert"`][aria-alert-role] on the `ValidationText` component to improve accessibility. This will help screen readers notify users about content updates.

### API

| Name | Type | Default | Required | Description |
| ---------------- | ------------------------------- | ------- | -------- | ---------------------------------------------------------------------------------------------- |
| `className` | `string` ||| Wrapper custom class name |
| `elementType` | \[`span` \| `div`] | `div` || Type of element used as main wrapper (applied only for single validation text, otherwise `ul`) |
| `id` | `string` ||| Component id |
| `role` | `string` | - || The role attribute that describes the role of an element |
| `validationText` | \[`ReactNode` \| `ReactNode[]`] ||| Validation text, only visible if validationState is set |

## HelperText

The HelperText subcomponent displays helper texts for Field components like TextField, TextArea, Checkbox, FileUploader, etc.

```jsx
<HelperText className="Component__helperText" helperText="Helper text" />
```

Advanced example:

```jsx
<HelperText id="component__helperText" className="Component__helperText" elementType="span" helperText="Helper text" />
```

### API

| Name | Type | Default | Required | Description |
| ------------- | ------------------------------- | ------- | -------- | ---------------------------------------------------------------------------------------------- |
| `className` | `string` ||| Wrapper custom class name |
| `elementType` | \[`span` \| `div`] | `div` || Type of element used as main wrapper (applied only for single validation text, otherwise `ul`) |
| `helperText` | \[`ReactNode` \| `ReactNode[]`] ||| Validation text, only visible if validationState is |
| `id` | `string` ||| Component id |

[aria-alert-role]: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/alert_role
2 changes: 0 additions & 2 deletions packages/web-react/src/components/Field/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
'use client';

export { default as HelperText } from './HelperText';
export { default as useAriaIds } from './useAriaIds';
export { default as ValidationText } from './ValidationText';
export * from './useAriaIds';
9 changes: 1 addition & 8 deletions packages/web-react/src/components/Field/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { ElementType, JSXElementConstructor, ReactNode } from 'react';
import { ValidationTextProp } from '../../types';
import { ElementType, JSXElementConstructor } from 'react';
import { RegisterType } from './useAriaIds';

export interface FieldElementTypeProps<T extends ElementType = 'div'> {
Expand All @@ -16,9 +15,3 @@ export interface FieldProps<T extends ElementType = 'div'> extends FieldElementT
id?: string;
registerAria?: RegisterType;
}

export interface HelperTextProps<T extends ElementType = 'div'> extends FieldProps<T> {
helperText: ReactNode;
}

export interface ValidationTextProps<T extends ElementType = 'div'> extends FieldProps<T>, ValidationTextProp {}
5 changes: 3 additions & 2 deletions packages/web-react/src/components/FieldGroup/FieldGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ import classNames from 'classnames';
import React from 'react';
import { useStyleProps } from '../../hooks';
import { SpiritFieldGroupProps } from '../../types';
import { HelperText, ValidationText, useAriaIds } from '../Field';
import { useValidationTextRole } from '../Field/useValidationTextRole';
import { useAriaIds } from '../Field';
import { HelperText } from '../HelperText';
import { useValidationTextRole, ValidationText } from '../ValidationText';
import { VisuallyHidden } from '../VisuallyHidden';
import { useFieldGroupStyleProps } from './useFieldGroupStyleProps';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ import classNames from 'classnames';
import React, { useEffect, useState } from 'react';
import { useStyleProps } from '../../hooks';
import { SpiritFileUploaderInputProps } from '../../types';
import { HelperText, ValidationText, useAriaIds } from '../Field';
import { useValidationTextRole } from '../Field/useValidationTextRole';
import { useAriaIds } from '../Field';
import { HelperText } from '../HelperText';
import { Icon } from '../Icon';
import { Label } from '../Label';
import { useValidationTextRole, ValidationText } from '../ValidationText';
import { DEFAULT_FILE_QUEUE_LIMIT, DEFAULT_FILE_SIZE_LIMIT } from './constants';
import { useFileUploaderInput } from './useFileUploaderInput';
import { useFileUploaderStyleProps } from './useFileUploaderStyleProps';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
'use client';

import React, { ElementType, useEffect } from 'react';
import { HelperTextProps } from './types';
import { SpiritHelperTextProps } from '../../types';

const defaultProps: Partial<HelperTextProps> = {
const defaultProps: Partial<SpiritHelperTextProps> = {
className: undefined,
elementType: 'div',
id: undefined,
registerAria: undefined,
};

const HelperText = <T extends ElementType = 'div'>(props: HelperTextProps<T>) => {
const HelperText = <T extends ElementType = 'div'>(props: SpiritHelperTextProps<T>) => {
const propsWithDefaults = { ...defaultProps, ...props };
const {
helperText,
Expand Down
3 changes: 3 additions & 0 deletions packages/web-react/src/components/HelperText/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
'use client';

export { default as HelperText } from './HelperText';
2 changes: 1 addition & 1 deletion packages/web-react/src/components/Item/Item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import classNames from 'classnames';
import React, { ElementType } from 'react';
import { useStyleProps } from '../../hooks';
import { SpiritItemProps } from '../../types';
import { HelperText } from '../Field';
import { HelperText } from '../HelperText';
import { Icon } from '../Icon';
import { useItemStyleProps } from './useItemStyleProps';

Expand Down
3 changes: 2 additions & 1 deletion packages/web-react/src/components/Radio/Radio.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import classNames from 'classnames';
import React, { ForwardedRef, forwardRef } from 'react';
import { useStyleProps } from '../../hooks';
import { SpiritRadioProps } from '../../types';
import { HelperText, useAriaIds } from '../Field';
import { useAriaIds } from '../Field';
import { HelperText } from '../HelperText';
import { Label } from '../Label';
import { useRadioStyleProps } from './useRadioStyleProps';

Expand Down
5 changes: 3 additions & 2 deletions packages/web-react/src/components/Select/Select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ import classNames from 'classnames';
import React, { ForwardedRef, forwardRef } from 'react';
import { useStyleProps } from '../../hooks';
import { SpiritSelectProps } from '../../types';
import { HelperText, ValidationText, useAriaIds } from '../Field';
import { useValidationTextRole } from '../Field/useValidationTextRole';
import { useAriaIds } from '../Field';
import { HelperText } from '../HelperText';
import { Icon } from '../Icon';
import { Label } from '../Label';
import { useValidationTextRole, ValidationText } from '../ValidationText';
import { useSelectStyleProps } from './useSelectStyleProps';

/* We need an exception for components exported with forwardRef */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import classNames from 'classnames';
import React, { ForwardedRef, forwardRef } from 'react';
import { useStyleProps } from '../../hooks';
import { SpiritTextFieldBaseProps, TextFieldBasePasswordToggleProps } from '../../types';
import { HelperText, ValidationText, useAriaIds } from '../Field';
import { useValidationTextRole } from '../Field/useValidationTextRole';
import { useAriaIds } from '../Field';
import { HelperText } from '../HelperText';
import { Label } from '../Label';
import { useValidationTextRole, ValidationText } from '../ValidationText';
import TextFieldBaseInput from './TextFieldBaseInput';
import { useTextFieldBaseStyleProps } from './useTextFieldBaseStyleProps';
import withPasswordToggle from './withPasswordToggle';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
'use client';

import classNames from 'classnames';
import React, { CSSProperties, ChangeEvent, FormEvent, ForwardedRef, forwardRef } from 'react';
import React, { ChangeEvent, CSSProperties, FormEvent, ForwardedRef, forwardRef } from 'react';
import { useStyleProps } from '../../hooks';
import { SpiritSliderProps } from '../../types';
import { HelperText, ValidationText, useAriaIds } from '../Field';
import { useValidationTextRole } from '../Field/useValidationTextRole';
import { useAriaIds } from '../Field';
import { HelperText } from '../HelperText';
import { Label } from '../Label';
import { useValidationTextRole, ValidationText } from '../ValidationText';
import { SLIDER_DEFAULT_PROPS } from './constants';
import { useSliderStyleProps } from './useSliderStyleProps';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import classNames from 'classnames';
import React, { ForwardedRef, forwardRef, useState } from 'react';
import { useStyleProps } from '../../hooks';
import { SpiritToggleProps } from '../../types';
import { HelperText, useAriaIds, ValidationText } from '../Field';
import { useValidationTextRole } from '../Field/useValidationTextRole';
import { useAriaIds } from '../Field';
import { HelperText } from '../HelperText';
import { Label } from '../Label';
import { useValidationTextRole, ValidationText } from '../ValidationText';
import { useToggleStyleProps } from './useToggleStyleProps';

/* We need an exception for components exported with forwardRef */
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
'use client';

import React, { ElementType, useEffect } from 'react';
import { ValidationTextProps } from './types';
import { SpiritValidationTextProps } from '../../types/validationText';

const defaultProps: Partial<ValidationTextProps> = {
const defaultProps: Partial<SpiritValidationTextProps> = {
className: undefined,
elementType: 'div',
id: undefined,
registerAria: undefined,
role: undefined,
};

const ValidationText = <T extends ElementType = 'div'>(props: ValidationTextProps<T>) => {
const ValidationText = <T extends ElementType = 'div'>(props: SpiritValidationTextProps<T>) => {
const propsWithDefaults = { ...defaultProps, ...props };
const {
className,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import '@testing-library/jest-dom';
import { render, screen } from '@testing-library/react';
import React, { ElementType } from 'react';
import { ValidationTextProps } from 'src/types/validationText';
import { A11Y_ALERT_ROLE } from '../constants';
import { ValidationTextProps } from '../types';
import ValidationText from '../ValidationText';

const renderValidationText = <T extends ElementType = 'div'>(props: Partial<ValidationTextProps<T>>) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const A11Y_ALERT_ROLE = 'alert';
4 changes: 4 additions & 0 deletions packages/web-react/src/components/ValidationText/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
'use client';

export { default as ValidationText } from './ValidationText';
export { useValidationTextRole } from './useValidationTextRole';
4 changes: 2 additions & 2 deletions packages/web-react/src/types/checkbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
RequiredProps,
SpiritInputElementPropsWithRef,
Validation,
ValidationTextProp,
ValidationTextProps,
} from './shared';

export type CheckboxElementBaseProps = SpiritInputElementPropsWithRef;
Expand All @@ -20,7 +20,7 @@ export interface CheckboxProps
ItemProps,
InputBaseProps,
Validation,
ValidationTextProp,
ValidationTextProps,
RequiredProps,
HelperTextProps {
/** Whether the checkbox is indeterminate */
Expand Down
5 changes: 5 additions & 0 deletions packages/web-react/src/types/helperText.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { ElementType } from 'react';
import { FieldProps } from 'src/components/Field/types';
import { HelperTextProps } from './shared';

export interface SpiritHelperTextProps<T extends ElementType = 'div'> extends FieldProps<T>, HelperTextProps {}
2 changes: 2 additions & 0 deletions packages/web-react/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export * from './footer';
export * from './grid';
export * from './header';
export * from './heading';
export * from './helperText';
export * from './icon';
export * from './item';
export * from './label';
Expand All @@ -41,4 +42,5 @@ export * from './textFieldBase';
export * from './toast';
export * from './toggle';
export * from './tooltip';
export * from './validationText';
export * from './visuallyHidden';
2 changes: 1 addition & 1 deletion packages/web-react/src/types/shared/inputs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export interface HelperTextProps {
helperText?: ReactNode;
}

export interface ValidationTextProp {
export interface ValidationTextProps {
/** The role for validation text element */
role?: AriaRole;
/** The validation text to display. */
Expand Down
4 changes: 2 additions & 2 deletions packages/web-react/src/types/textArea.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
SpiritTextAreaElementPropsWithRef,
TextInputProps,
Validation,
ValidationTextProp,
ValidationTextProps,
} from './shared';

export type TextAreaElementBaseProps = SpiritTextAreaElementPropsWithRef;
Expand All @@ -19,7 +19,7 @@ export interface TextAreaProps
ChildrenProps,
LabelProps,
HelperTextProps,
ValidationTextProp,
ValidationTextProps,
TextInputProps,
RequiredProps,
Validation {
Expand Down
4 changes: 2 additions & 2 deletions packages/web-react/src/types/textField.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
SpiritInputElementPropsWithRef,
TextInputProps,
Validation,
ValidationTextProp,
ValidationTextProps,
} from './shared';

export type TextFieldType = 'email' | 'number' | 'password' | 'search' | 'tel' | 'text' | 'url';
Expand All @@ -23,7 +23,7 @@ export interface TextFieldProps
ChildrenProps,
LabelProps,
HelperTextProps,
ValidationTextProp,
ValidationTextProps,
TextInputProps,
RequiredProps,
Validation {
Expand Down
5 changes: 5 additions & 0 deletions packages/web-react/src/types/validationText.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { ElementType } from 'react';
import { FieldProps } from 'src/components/Field/types';
import { ValidationTextProps } from './shared';

export interface SpiritValidationTextProps<T extends ElementType = 'div'> extends FieldProps<T>, ValidationTextProps {}

0 comments on commit bae6ed3

Please sign in to comment.