import type { ColorPalette, ControlSize, ControlVariant, FieldSize } from '@/lib'; /** * The axis values every entry and every page draws from. * * These used to be restated in ten places — seven registry files and both * `/buttons` tabs — because the kit did not export its own vocabulary. It does * now (`colorPalettes`, `controlVariants`, `controlHeights`, `fieldHeights` in * `src/lib/cva-presets.ts`, re-exported from `@/lib`), so the lists live here * once and the types below make a drift a compile error rather than a grid with * a missing column. * * They are written out rather than derived with `Object.keys()` for two * reasons: order is meaningful (it is the order of the columns on screen, and * CBAR's canvas order is not alphabetical), and `Object.keys` widens to * `string[]`, which would take the literal types out of every `axes` block. * `satisfies` gives back what `Object.keys` would have cost. */ /** * `true` if `Listed` covers every member of `All`, otherwise a tuple naming what * is missing — which is the text that ends up in the compiler error. * * Exported because `pages/buttons-figma.tsx` keeps its own ordering — CBAR's * canvas order, which is deliberately not the kit's — and needs the same * coverage check over a list this file cannot own. */ export type Complete = Exclude< All, Listed > extends never ? true : ['a value is missing from this list:', Exclude]; /** * What turns {@link Complete} into an actual compile error. * * `Complete<…>` on its own is inert: a type alias resolving to a tuple is a * perfectly legal type, so `type _X = Complete` type-checks whether the * answer is `true` or `['a value is missing from this list:', 'xl']`. Measured * with the kit's own `tsc` — the guards below were silent for exactly that * reason. Passing the answer through a parameter constrained to `true` is what * makes the failing case unassignable, and the tuple is then quoted in the * error. */ export type Assert = T; /** * The seven palettes, minus the deprecated `third` alias of `tertiary`. * * `third` is excluded deliberately: it resolves to the same eight `--ctl-*` * roles, so showing it would draw an identical column twice. */ export const PALETTES = [ 'primary', 'secondary', 'tertiary', 'black', 'red', 'green', 'yellow', ] as const satisfies readonly ColorPalette[]; export type Palette = (typeof PALETTES)[number]; /* Exclude the alias here too, or adding a palette would not be caught. */ export type _PalettesCovered = Assert>; /** * The five fill treatments that compose with a palette. * * Button carries three more (`link`, `destructive`, `secondary-solid`) that pin * their own colour from the semantic roles in theme.css and therefore ignore * `colorPalette`. Those are Button's own business and stay in its entry. */ export const VARIANTS = [ 'solid', 'subtle', 'surface', 'outline', 'ghost', ] as const satisfies readonly ControlVariant[]; export type Variant = (typeof VARIANTS)[number]; export type _VariantsCovered = Assert>; /** Button's height ladder — 32 / 36 / 40 / 48 / 56px. */ export const CONTROL_SIZES = ['xs', 'sm', 'md', 'lg', 'xl'] as const satisfies readonly ControlSize[]; export type ControlSizeValue = (typeof CONTROL_SIZES)[number]; export type _ControlSizesCovered = Assert>; /** * The form-field ladder — 32 / 36 / 44 / 56px. * * Deliberately shorter than {@link CONTROL_SIZES} and deliberately not the same * heights: CBAR draws fields taller than buttons from `md` up. See the note on * `fieldHeights` in `src/lib/cva-presets.ts`. */ export const FIELD_SIZES = ['xs', 'sm', 'md', 'lg'] as const satisfies readonly FieldSize[]; export type FieldSizeValue = (typeof FIELD_SIZES)[number]; export type _FieldSizesCovered = Assert>;