Add more examples for custom fields

Signed-off-by: Charles de Dreuille <charles.dedreuille@gmail.com>
This commit is contained in:
Charles de Dreuille
2025-06-16 23:41:50 +01:00
parent f071baa582
commit 70416c788f
4 changed files with 33 additions and 5 deletions
@@ -20,14 +20,14 @@ import type { FieldLabelProps } from './types';
/** @public */
export const FieldLabel = forwardRef<HTMLDivElement, FieldLabelProps>(
(props: FieldLabelProps, ref) => {
const { label, secondaryLabel, description } = props;
const { label, secondaryLabel, description, htmlFor, id, ...rest } = props;
if (!label) return null;
return (
<div className="canon-FieldLabel" ref={ref}>
<div className="canon-FieldLabel" {...rest} ref={ref}>
{label && (
<Label className="canon-FieldLabelLabel">
<Label className="canon-FieldLabelLabel" htmlFor={htmlFor} id={id}>
{label}
{secondaryLabel && (
<span
@@ -14,8 +14,10 @@
* limitations under the License.
*/
import type { HTMLAttributes } from 'react';
/** @public */
export interface FieldLabelProps {
export interface FieldLabelProps extends HTMLAttributes<HTMLDivElement> {
/**
* The label of the text field
*/
@@ -30,4 +32,9 @@ export interface FieldLabelProps {
* The description of the text field
*/
description?: string | null;
/**
* The HTML for attribute of the text field
*/
htmlFor?: string;
}
@@ -19,6 +19,7 @@ import { TextField } from './TextField';
import { Form } from 'react-aria-components';
import { Icon } from '../Icon';
import { Flex } from '../Flex';
import { FieldLabel } from '../FieldLabel';
const meta = {
title: 'Forms/TextField',
@@ -125,3 +126,21 @@ export const Validation: Story = {
validate: value => (value === 'admin' ? 'Nice try!' : null),
},
};
export const CustomField: Story = {
render: () => (
<>
<FieldLabel
htmlFor="custom-field"
id="custom-field-label"
label="Custom Field"
/>
<TextField
id="custom-field"
aria-labelledby="custom-field-label"
name="custom-field"
defaultValue="Custom Field"
/>
</>
),
};
@@ -45,7 +45,7 @@ export const TextField = forwardRef<HTMLDivElement, FormInputProps>(
useEffect(() => {
if (!label && !ariaLabel && !ariaLabelledBy) {
console.warn(
'If you do not provide a visible label, you must specify an aria-label or aria-labelledby attribute for accessibility',
'TextField requires either a visible label, aria-label, or aria-labelledby for accessibility',
);
}
}, [label, ariaLabel, ariaLabelledBy]);
@@ -61,6 +61,8 @@ export const TextField = forwardRef<HTMLDivElement, FormInputProps>(
<AriaTextField
className={clsx('canon-TextField', className)}
data-size={responsiveSize}
aria-label={ariaLabel}
aria-labelledby={ariaLabelledBy}
{...rest}
ref={ref}
>