diff --git a/.agents/references/spacing-radius-usage.md b/.agents/references/spacing-radius-usage.md new file mode 100644 index 0000000..415866c --- /dev/null +++ b/.agents/references/spacing-radius-usage.md @@ -0,0 +1,68 @@ +# Spacing and radius usage + +Use the spacing and radius variables exported by +`packages/components/src/tokens.stylex.ts` in component StyleX styles. Do not +repeat a raw length when the intended value already exists in one of these +scales. + +```tsx +import * as stylex from "@stylexjs/stylex"; + +import { radiusVars, spacingVars } from "../tokens.stylex"; + +const styles = stylex.create({ + root: { + borderRadius: radiusVars.md, + gap: spacingVars["2"], + paddingBlock: spacingVars["3"], + paddingInline: spacingVars["4"], + }, +}); +``` + +## Spacing scale + +The spacing scale uses a 0.25rem base unit. Token names match their multiplier, +including decimal names such as `0.5` and `1.5`. Because the names are numeric, +always access spacing variables with bracket notation. + +| Token | Value | +| ----: | ---------- | +| `0` | `0rem` | +| `0.5` | `0.125rem` | +| `1` | `0.25rem` | +| `1.5` | `0.375rem` | +| `2` | `0.5rem` | +| `3` | `0.75rem` | +| `4` | `1rem` | +| `5` | `1.25rem` | +| `6` | `1.5rem` | +| `7` | `1.75rem` | +| `8` | `2rem` | +| `9` | `2.25rem` | +| `10` | `2.5rem` | +| `11` | `2.75rem` | +| `12` | `3rem` | + +Choose a token by the spacing the layout requires, not by converting the value +to pixels in the component. Add a new scale step only when the design system +needs a reusable spacing value that the existing scale cannot express. + +## Radius scale + +| Token | Value | +| ------ | ---------------------- | +| `xs` | `0.125rem` | +| `sm` | `0.25rem` | +| `md` | `0.375rem` | +| `lg` | `0.5rem` | +| `xl` | `0.75rem` | +| `2xl` | `1rem` | +| `3xl` | `1.5rem` | +| `4xl` | `2rem` | +| `none` | `0` | +| `full` | `calc(infinity * 1px)` | + +Use `none` when a component explicitly requires square corners and `full` for +pills and circles. Use bracket notation for radius names that begin with a +number, such as `radiusVars["2xl"]`. diff --git a/AGENTS.md b/AGENTS.md index e032370..3313d21 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -32,3 +32,15 @@ Before adding or changing component colors, read - Select a scale step according to the documented interaction or content role, not merely because it looks close. - Preserve the established semantic families and their Radix mappings. + +## Spacing and radius + +Before adding or changing component spacing or border radii, read +[`.agents/references/spacing-radius-usage.md`](.agents/references/spacing-radius-usage.md). + +- Use `spacingVars` and `radiusVars` from + `packages/components/src/tokens.stylex.ts` when the intended value exists in + the token scales. +- Keep spacing values in rem and preserve the 0.25rem-based numeric scale. +- Access numeric spacing keys and radius keys that begin with a number using + bracket notation, such as `spacingVars["1.5"]` and `radiusVars["2xl"]`. diff --git a/packages/components/src/tokens.stylex.ts b/packages/components/src/tokens.stylex.ts index c1b44fb..88af6f6 100644 --- a/packages/components/src/tokens.stylex.ts +++ b/packages/components/src/tokens.stylex.ts @@ -1,5 +1,44 @@ import * as stylex from "@stylexjs/stylex"; +/** + * Spacing scale based on a 0.25rem (4px) unit. + */ +export const spacingDefaults = { + "0": "0rem", + "0.5": "0.125rem", + "1": "0.25rem", + "1.5": "0.375rem", + "2": "0.5rem", + "3": "0.75rem", + "4": "1rem", + "5": "1.25rem", + "6": "1.5rem", + "7": "1.75rem", + "8": "2rem", + "9": "2.25rem", + "10": "2.5rem", + "11": "2.75rem", + "12": "3rem", +} as const; +export const spacingVars = stylex.defineVars(spacingDefaults); + +/** + * Border radius scale. + */ +export const radiusDefaults = { + xs: "0.125rem", + sm: "0.25rem", + md: "0.375rem", + lg: "0.5rem", + xl: "0.75rem", + "2xl": "1rem", + "3xl": "1.5rem", + "4xl": "2rem", + none: "0", + full: "calc(infinity * 1px)", +} as const; +export const radiusVars = stylex.defineVars(radiusDefaults); + /** * Semantic color scales backed by Radix Colors 3.0.0. * diff --git a/packages/components/test/tokens.test.ts b/packages/components/test/tokens.test.ts index 0d4ea99..9407bb0 100644 --- a/packages/components/test/tokens.test.ts +++ b/packages/components/test/tokens.test.ts @@ -22,7 +22,46 @@ import { } from "@radix-ui/colors"; import { describe, expect, it } from "vitest"; -import { colorDefaults } from "../src/tokens.stylex"; +import { colorDefaults, radiusDefaults, spacingDefaults } from "../src/tokens.stylex"; + +describe("spacing tokens", () => { + it("defines the selected 0.25rem-based scale", () => { + expect(spacingDefaults).toEqual({ + "0": "0rem", + "0.5": "0.125rem", + "1": "0.25rem", + "1.5": "0.375rem", + "2": "0.5rem", + "3": "0.75rem", + "4": "1rem", + "5": "1.25rem", + "6": "1.5rem", + "7": "1.75rem", + "8": "2rem", + "9": "2.25rem", + "10": "2.5rem", + "11": "2.75rem", + "12": "3rem", + }); + }); +}); + +describe("radius tokens", () => { + it("defines the radius scale", () => { + expect(radiusDefaults).toEqual({ + xs: "0.125rem", + sm: "0.25rem", + md: "0.375rem", + lg: "0.5rem", + xl: "0.75rem", + "2xl": "1rem", + "3xl": "1.5rem", + "4xl": "2rem", + none: "0", + full: "calc(infinity * 1px)", + }); + }); +}); const scales = { neutral: [gray, grayDark, grayA, grayDarkA],