diff --git a/.changeset/tall-pillows-shake.md b/.changeset/tall-pillows-shake.md new file mode 100644 index 0000000..64337ff --- /dev/null +++ b/.changeset/tall-pillows-shake.md @@ -0,0 +1,12 @@ +--- +'@batik-prototype/core': minor +--- + +Add `Accordion`, a stack of disclosure rows in the same token-driven shape as the rest of +the set: `contained` groups the rows on one surface and divides them with the border token, +`separated` gives each row its own outline. + +It is `
` and `` underneath, so the keyboard, the screen reader and +find-in-page behaviour are the platform's. `exclusive` names the group rather than tracking +which row is open, which is why the rows arrive as an `items` array instead of as children: +nothing has to read the group's name or variant out of React context to render. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 750fa2a..63f0c5b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,6 +19,11 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v5 + with: + # The changeset gate below diffs against `origin/main`, and the default + # shallow clone has neither that ref nor enough history to find where + # this branch left it. Same reason release.yml asks for it. + fetch-depth: 0 # setup-vp installs Vite+, Node and pnpm, and caches package-manager data. # The version is pinned deliberately: the docs call out that the `v1` tag diff --git a/apps/example/src/showcase.tsx b/apps/example/src/showcase.tsx index 8fb64d1..60b0ba4 100644 --- a/apps/example/src/showcase.tsx +++ b/apps/example/src/showcase.tsx @@ -1,6 +1,7 @@ -import { Badge, Button, Card, Input } from '@batik-prototype/core'; +import { Accordion, Badge, Button, Card, Input, type AccordionItem } from '@batik-prototype/core'; import { color } from '@batik-prototype/core/tokens/color.stylex'; import { font } from '@batik-prototype/core/tokens/font.stylex'; +import { radius } from '@batik-prototype/core/tokens/shape.stylex'; import { space } from '@batik-prototype/core/tokens/space.stylex'; import * as stylex from '@stylexjs/stylex'; import { useId, type ReactNode } from 'react'; @@ -33,8 +34,73 @@ const styles = stylex.create({ cardTitle: { fontSize: font.sizeMd, fontWeight: font.weightSemibold, margin: 0 }, cardBody: { color: color.muted, fontSize: font.sizeSm, margin: 0 }, + + code: { + backgroundColor: color.neutralSurface, + borderRadius: radius.sm, + color: color.onNeutralSurface, + fontFamily: font.familyMono, + fontSize: '0.85em', + paddingInline: space.xs, + }, }); +const FAQ: readonly AccordionItem[] = [ + { + id: 'tokens', + title: 'Where do the colours come from?', + content: ( +

+ Every one of them is a StyleX variable declared by{' '} + @batik-prototype/core. A theme overrides the + variable; this row never learns which theme won. +

+ ), + defaultOpen: true, + }, + { + id: 'platform', + title: 'What is this built on?', + content: ( +

+ A <details> and a{' '} + <summary>, so the keyboard and the screen + reader work without a line of JavaScript. Opening one row closes the others because they + share a name, which is a browser feature rather + than a component one. +

+ ), + }, + { + id: 'locked', + title: 'A row that cannot be opened', + content:

Unreachable, by design.

, + disabled: true, + }, +]; + +const SEPARATED: readonly AccordionItem[] = [ + { + id: 'radius', + title: 'Ocean rounds the corners', + content: ( +

+ The radius token moves and every row follows, in both variants at once. +

+ ), + }, + { + id: 'divider', + title: 'Sunset squares them off', + content: ( +

+ In the contained variant the divider between rows is the border token, so a theme that + thickens its outlines thickens these too. +

+ ), + }, +]; + function Section({ title, caption, @@ -172,6 +238,16 @@ export function Showcase() { + +
+
+ + +
+
); } diff --git a/packages/core/README.md b/packages/core/README.md index c43339f..1ef5a86 100644 --- a/packages/core/README.md +++ b/packages/core/README.md @@ -36,14 +36,17 @@ anyway to compile your own StyleX. See [Setting up the compiler](#setting-up-the | `Input` | Three sizes, `invalid`, disabled, themed placeholder | | `Card` | `elevated` / `outlined`, four padding steps | | `Badge` | Five tones: neutral, accent, success, warning, danger | +| `Accordion` | `contained` / `separated`, optional `exclusive` rows | | `ThemeProvider` | Applies a theme, resolves the colour scheme | | `useTheme` / `useColorScheme` | Read the active theme and the resolved scheme | | `usePreferredColorScheme` | The OS preference on its own, kept live | | `defineTheme` / `resolveTheme` | The theme contract, also at `@batik-prototype/core/theme` | -Components are plain elements underneath — `