(forms) add FieldVariant enum and classic variant tokens

- Add FieldVariant enum with Floating and Classic values
- Add design tokens for classic variant (height, label styles)
- Regenerate cunningham-tokens files

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Nathan Panchout
2026-01-26 20:07:23 +01:00
parent f3f59ce064
commit 5b522e34f3
7 changed files with 76 additions and 4 deletions

View File

@@ -0,0 +1,57 @@
import React from "react";
import classNames from "classnames";
export interface ClassicLabelProps {
label?: string;
hideLabel?: boolean;
disabled?: boolean;
className?: string;
disabledClassName?: string;
htmlFor?: string;
id?: string;
onClick?: () => void;
}
/**
* Renders a label for the "classic" field variant.
* - When hideLabel is false: renders a visible label with the given className.
* - When hideLabel is true: renders an offscreen label for accessibility.
* - When label is falsy: renders nothing.
*/
export const ClassicLabel = ({
label,
hideLabel,
disabled,
className,
disabledClassName,
htmlFor,
id,
onClick,
}: ClassicLabelProps) => {
if (!label) {
return null;
}
if (hideLabel) {
return (
// eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions
<label className="c__offscreen" htmlFor={htmlFor} onClick={onClick}>
{label}
</label>
);
}
return (
// eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions
<label
className={classNames(className, {
[disabledClassName ?? ""]: disabled && disabledClassName,
})}
htmlFor={htmlFor}
id={id}
onClick={onClick}
>
{label}
</label>
);
};

View File

@@ -7,4 +7,7 @@ export const tokens = (defaults: DefaultTokens) => ({
defaults.contextuals.content.semantic.neutral.secondary,
"label-color--big--disabled":
defaults.contextuals.content.semantic.neutral.secondary,
// Classic variant tokens
"classic-label-margin-bottom": defaults.globals.spacings.xs,
"classic-label-font-size": defaults.globals.font.sizes.s,
});

View File

@@ -0,0 +1,6 @@
/**
* Field variant determines how the label and placeholder are displayed.
* - "floating": Label serves as placeholder when empty, animates above value when focused/filled (default)
* - "classic": Label is always above the field, placeholder is native HTML placeholder
*/
export type FieldVariant = "floating" | "classic";