Update checkbox component

This commit is contained in:
adilallo
2026-02-04 13:31:04 -07:00
parent 0e7985287f
commit 05e403e3c6
5 changed files with 162 additions and 130 deletions
+45 -42
View File
@@ -21,49 +21,59 @@ const CheckboxContainer = memo<CheckboxProps>(
...props
}) => {
const isInverse = mode === "inverse";
const isStandard = mode === "standard";
// Base tokens (rough placeholders leveraging existing CSS variables)
const colorContent = isInverse
? "var(--color-content-inverse-primary)"
: "var(--color-content-default-primary)";
// Generate unique ID for accessibility if not provided
const { id: checkboxId, labelId } = useComponentId("checkbox", id);
// Visual container depending on state
const baseBox = `flex items-center justify-center shrink-0 w-[var(--measures-sizing-024)] h-[var(--measures-sizing-024)] rounded-[var(--measures-radius-medium)] transition-all duration-200 ease-in-out`;
// Base box styles per Figma
const baseBox = `
flex
items-center
justify-center
shrink-0
w-[24px]
h-[24px]
rounded-[4px]
transition-all
duration-200
ease-in-out
`.trim().replace(/\s+/g, " ");
const stateStyles: Record<string, string> = {
default: "",
hover: "",
focus: "",
// Get box styles based on state and checked status per Figma designs
const getBoxStyles = (): string => {
// Standard mode styles
if (isStandard) {
// Default state: tertiary border, with hover and focus states via CSS
// Hover changes border to brand primary color
// Focus removes border and shows shadow (double ring: 2px white inner, 4px dark outer)
return `${baseBox} bg-[var(--color-surface-default-primary)] border border-solid border-[var(--color-border-default-tertiary,#464646)] hover:border-[var(--color-border-default-brand-primary,#fdfaa8)] focus:border-transparent focus:shadow-[0px_0px_0px_2px_var(--color-border-invert-primary,white),0px_0px_0px_4px_var(--color-border-default-primary,#141414)] focus:outline-none`;
}
// Inverse mode styles per Figma
if (isInverse) {
// Inverse: transparent background, white border
// Hover changes border to brand primary color
// Focus shows shadow (2px dark inner, 4px white outer) - note: reversed from standard
return `${baseBox} bg-transparent border border-solid border-[var(--color-border-invert-primary,white)] hover:border-[var(--color-border-default-brand-primary,#fdfaa8)] focus:shadow-[0px_0px_0px_2px_var(--color-border-default-primary,#141414),0px_0px_0px_4px_var(--color-border-invert-primary,white)] focus:outline-none`;
}
return baseBox;
};
// Background behavior:
// - Standard: background does not change on check; only checkmark appears
// - Inverse: transparent background, checkmark appears on check
const backgroundWhenChecked = isInverse
? "var(--color-surface-default-transparent)"
: "var(--color-surface-default-primary)";
const combinedBoxStyles = getBoxStyles();
// Checkmark color per Figma
const checkGlyphColor = checked
? isInverse
? "var(--color-content-inverse-primary)"
: "var(--color-border-default-brand-primary)"
? isStandard
? "var(--color-content-default-brand-primary, #fefcc9)" // Light yellow/cream for standard mode
: "var(--color-content-inverse-primary, #000000)" // Black for inverse mode
: "transparent";
const labelColor = colorContent;
const combinedBoxStyles = `${baseBox} ${stateStyles[state]}`;
// Force visible outline for standard / default / unchecked
// Outline classes instead of inline styles so hover can override
const defaultOutlineClass = isInverse
? "outline outline-1 outline-[var(--color-border-inverse-primary)]"
: "outline outline-1 outline-[var(--color-border-default-tertiary)]";
// Apply brand outline only on actual :hover, and only when standard/unchecked
const conditionalHoverOutlineClass =
"hover:outline hover:outline-1 hover:outline-[var(--color-border-default-brand-primary)]";
// Focus state for standard/unchecked with brand primary color and specific blur/spread
const conditionalFocusClass =
"focus:outline focus:outline-1 focus:outline-[var(--color-border-default-utility-info)] focus:shadow-[0_0_10px_1px_var(--color-surface-inverse-brand-primary)]";
// Label color
const labelColor = isInverse
? "var(--color-content-inverse-primary)"
: "var(--color-content-default-primary)";
const handleToggle = (e: React.MouseEvent | React.KeyboardEvent) => {
if (disabled) return;
@@ -74,9 +84,6 @@ const CheckboxContainer = memo<CheckboxProps>(
});
};
// Generate unique ID for accessibility if not provided
const { id: checkboxId, labelId } = useComponentId("checkbox", id);
const accessibilityProps = {
role: "checkbox" as const,
"aria-checked": checked,
@@ -107,10 +114,6 @@ const CheckboxContainer = memo<CheckboxProps>(
value={value}
className={className}
combinedBoxStyles={combinedBoxStyles}
defaultOutlineClass={defaultOutlineClass}
conditionalHoverOutlineClass={conditionalHoverOutlineClass}
conditionalFocusClass={conditionalFocusClass}
backgroundWhenChecked={backgroundWhenChecked}
checkGlyphColor={checkGlyphColor}
labelColor={labelColor}
accessibilityProps={accessibilityProps}