(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, defaults.contextuals.content.semantic.neutral.secondary,
"label-color--big--disabled": "label-color--big--disabled":
defaults.contextuals.content.semantic.neutral.secondary, 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";

View File

@@ -616,10 +616,13 @@
--c--components--forms-select--multi-pill-border-radius: 2px; --c--components--forms-select--multi-pill-border-radius: 2px;
--c--components--forms-select--multi-pill-max-width: 68%; --c--components--forms-select--multi-pill-max-width: 68%;
--c--components--forms-select--multi-pill-font-size: var(--c--globals--font--sizes--md); --c--components--forms-select--multi-pill-font-size: var(--c--globals--font--sizes--md);
--c--components--forms-select--placeholder-color: var(--c--contextuals--content--semantic--neutral--secondary);
--c--components--forms-labelledbox--label-color--small: var(--c--contextuals--content--semantic--neutral--tertiary); --c--components--forms-labelledbox--label-color--small: var(--c--contextuals--content--semantic--neutral--tertiary);
--c--components--forms-labelledbox--label-color--big: var(--c--contextuals--content--semantic--neutral--primary); --c--components--forms-labelledbox--label-color--big: var(--c--contextuals--content--semantic--neutral--primary);
--c--components--forms-labelledbox--label-color--small--disabled: var(--c--contextuals--content--semantic--neutral--secondary); --c--components--forms-labelledbox--label-color--small--disabled: var(--c--contextuals--content--semantic--neutral--secondary);
--c--components--forms-labelledbox--label-color--big--disabled: var(--c--contextuals--content--semantic--neutral--secondary); --c--components--forms-labelledbox--label-color--big--disabled: var(--c--contextuals--content--semantic--neutral--secondary);
--c--components--forms-labelledbox--classic-label-margin-bottom: var(--c--globals--spacings--xs);
--c--components--forms-labelledbox--classic-label-font-size: var(--c--globals--font--sizes--s);
--c--components--forms-input--font-weight: var(--c--globals--font--weights--regular); --c--components--forms-input--font-weight: var(--c--globals--font--weights--regular);
--c--components--forms-input--font-size: var(--c--globals--font--sizes--md); --c--components--forms-input--font-size: var(--c--globals--font--sizes--md);
--c--components--forms-input--border-radius: 8px; --c--components--forms-input--border-radius: 8px;

File diff suppressed because one or more lines are too long

View File

@@ -766,14 +766,17 @@ $themes: (
'multi-pill-background-color': #F0F1F2, 'multi-pill-background-color': #F0F1F2,
'multi-pill-border-radius': 2px, 'multi-pill-border-radius': 2px,
'multi-pill-max-width': 68%, 'multi-pill-max-width': 68%,
'multi-pill-font-size': 1rem 'multi-pill-font-size': 1rem,
'placeholder-color': #5C5F63
), ),
'forms-radio': (), 'forms-radio': (),
'forms-labelledbox': ( 'forms-labelledbox': (
'label-color--small': #686B6F, 'label-color--small': #686B6F,
'label-color--big': #252627, 'label-color--big': #252627,
'label-color--small--disabled': #5C5F63, 'label-color--small--disabled': #5C5F63,
'label-color--big--disabled': #5C5F63 'label-color--big--disabled': #5C5F63,
'classic-label-margin-bottom': 0.5rem,
'classic-label-font-size': 0.75rem
), ),
'forms-input': ( 'forms-input': (
'font-weight': 400, 'font-weight': 400,

File diff suppressed because one or more lines are too long