import React from "react"; import { ChoiceGroup, ChoiceOption } from "./ChoiceGroup"; /** * Named-color preset chips. Picking a chip fills the associated color input * with that color's hex. Sourced from the shared NamedColorPalette (PHP) via * the localized payload, so the same presets back the term editor, the * product-panel color picker, and the bulk setup wizard. * * Semantics: these are an exclusive choice over the presets, so they render as * a radiogroup rather than a row of toggle buttons. A custom hex that matches * no preset is legal — the group then has zero checked radios (permitted by * ARIA) and the roving tab stop falls to the first chip, so the group stays * keyboard reachable and never traps a tab stop per chip. * * Free-side only: lives outside src/admin/extension/ and imports nothing premium. */ export interface NamedColor { name: string; hex: string; } export interface ColorSwatchChipsProps { colors: NamedColor[]; activeHex?: string; onPick: (hex: string) => void; label?: string; } const normalizeHex = (hex: string): string => hex.trim().toLowerCase(); export function ColorSwatchChips({ colors, activeHex, onPick, label = "Color presets", }: ColorSwatchChipsProps): React.ReactElement | null { if (!colors || colors.length === 0) { return null; } const active = activeHex ? normalizeHex(activeHex) : ""; // "" when the active hex is custom — a radiogroup with nothing checked. const selectedValue = colors.find((color) => normalizeHex(color.hex) === active)?.hex ?? ""; return ( color.hex)} onChange={onPick} className="b3-wvs-color-presets bwvs:flex bwvs:flex-wrap bwvs:gap-1.5" > {colors.map((color) => { const isActive = color.hex === selectedValue; return ( ); })} ); }