From 36b03bfb40f0c39089df1f7ac55e2bbd13a6d837 Mon Sep 17 00:00:00 2001 From: Luke Bennett Date: Wed, 8 Jul 2026 17:25:49 +1000 Subject: [PATCH] Remove ADRs and update docs --- AGENTS.md | 23 +-- CONTEXT.md | 82 ---------- README.md | 149 ++++-------------- .../docs/components/actions/button.mdx | 13 +- .../docs/components/forms/combobox-field.mdx | 28 +--- .../docs/components/forms/text-field.mdx | 10 +- apps/docs/content/docs/components/meta.json | 2 +- .../docs/components/primitives/button.mdx | 32 ++++ .../docs/components/primitives/combobox.mdx | 128 +++++++++++++++ .../docs/components/primitives/field.mdx | 62 ++++++++ .../docs/components/primitives/meta.json | 4 + .../docs/components/primitives/text-input.mdx | 35 ++++ apps/docs/content/docs/index.mdx | 1 + .../src/examples/loading-skeleton/text.tsx | 9 +- docs/COMPONENTS.md | 58 +++++++ docs/CONVENTIONS.md | 98 ++---------- docs/DOCUMENTATION.md | 82 ++++++++++ docs/STYLING.md | 111 +++++++------ docs/adr/0001-component-tier-taxonomy.md | 47 ------ .../0002-primitive-package-path-convention.md | 38 ----- docs/adr/0003-package-docs-surface.md | 58 ------- docs/adr/0004-styling-utilities-public-api.md | 40 ----- .../0005-component-creation-plan-module.md | 20 --- docs/adr/0006-docs-md-structure-standard.md | 65 -------- docs/adr/0007-docs-moved-to-hosted-app.md | 38 ----- packages/@luke-ui/react/README.md | 21 ++- 26 files changed, 545 insertions(+), 709 deletions(-) delete mode 100644 CONTEXT.md create mode 100644 apps/docs/content/docs/components/primitives/button.mdx create mode 100644 apps/docs/content/docs/components/primitives/combobox.mdx create mode 100644 apps/docs/content/docs/components/primitives/field.mdx create mode 100644 apps/docs/content/docs/components/primitives/meta.json create mode 100644 apps/docs/content/docs/components/primitives/text-input.mdx create mode 100644 docs/COMPONENTS.md create mode 100644 docs/DOCUMENTATION.md delete mode 100644 docs/adr/0001-component-tier-taxonomy.md delete mode 100644 docs/adr/0002-primitive-package-path-convention.md delete mode 100644 docs/adr/0003-package-docs-surface.md delete mode 100644 docs/adr/0004-styling-utilities-public-api.md delete mode 100644 docs/adr/0005-component-creation-plan-module.md delete mode 100644 docs/adr/0006-docs-md-structure-standard.md delete mode 100644 docs/adr/0007-docs-moved-to-hosted-app.md diff --git a/AGENTS.md b/AGENTS.md index b9a6aae7..d15780fa 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,21 +1,22 @@ # Luke UI agent guide -- Use `catalog:` for dependency versions in `package.json`. The catalog lives in - `pnpm-workspace.yaml`. Do not add raw versions. -- Read [docs/CONVENTIONS.md](docs/CONVENTIONS.md), [docs/STYLING.md](docs/STYLING.md), and - [docs/TESTING.md](docs/TESTING.md) before changing code, styles, or tests. +- Use `catalog:` dependency versions in `package.json`. The catalog lives in `pnpm-workspace.yaml`. + Do not add raw versions. +- Read [docs/CONVENTIONS.md](docs/CONVENTIONS.md), [docs/COMPONENTS.md](docs/COMPONENTS.md), + [docs/DOCUMENTATION.md](docs/DOCUMENTATION.md), [docs/STYLING.md](docs/STYLING.md), and + [docs/TESTING.md](docs/TESTING.md) before changing code, styles, docs, or tests. - Run tasks through Turbo from the repo root, for example `pnpm run check` or `pnpm run build`. - Package-local scripts can skip Turbo `generate` dependencies, which may leave generated files + Package-local scripts can skip Turbo `generate` dependencies, which can leave generated files missing. - Scaffold components non-interactively: `pnpm run generate:component --args `. -- When you change code, update or delete the docs that describe it in the same change — comments, - JSDoc, MDX files in `apps/docs/content/docs/`, `README.md`, and `docs/*.md`. See - [docs/CONVENTIONS.md](docs/CONVENTIONS.md#keeping-docs-current). +- When you change code, update or delete the docs that describe it in the same change. This includes + comments, JSDoc, MDX files in `apps/docs/content/docs/`, `README.md`, package READMEs, and files + in `docs/`. See [docs/DOCUMENTATION.md](docs/DOCUMENTATION.md#keeping-docs-current). ## Dev loop -- Run `pnpm run check` from the repo root to verify changes before committing. -- Component prose now lives in MDX files in `apps/docs/content/docs/`, not `.docs.md` files in the - package. Update the relevant MDX page in the same change as the component code. +- Run `pnpm run check` from the repo root before committing. +- Component prose lives in MDX files in `apps/docs/content/docs/`, not `.docs.md` files in the + package. Update the relevant MDX page in the same change as component code. - Do not add or edit `.docs.md` files in `packages/@luke-ui/react/src/`. diff --git a/CONTEXT.md b/CONTEXT.md deleted file mode 100644 index 35e1dd26..00000000 --- a/CONTEXT.md +++ /dev/null @@ -1,82 +0,0 @@ -# Luke UI - -Luke UI is a React design system built on `react-aria-components` and `vanilla-extract`. - -Components use three vocabulary tiers. Those tiers define how code is laid out and how each -component is documented. - -## Language - -**Atom**: A component that presents one conceptual unit, such as one piece of text, one icon, or one -number. It may compose `Text` or other atoms internally, but consumers treat it as a single unit. -App developers use atoms directly. _Examples_: `Text`, `Link`, `Icon`, `LoadingSpinner`, `Heading`, -`Emoji`, `Numeral`. _Avoid_: calling these "primitives" in source comments. That name is reserved. - -**Composed**: A component that combines atoms or primitives into an opinionated, ready-to-drop-in -unit for app developers. _Examples_: `Button`, `IconButton`, `TextField`, `ComboboxField`. - -**Primitive**: A building block for library authors assembling the next composed component. App -developers are not the audience. A primitive may be a single file (e.g. `text-field/primitive`) or a -kit of parts (e.g. `combobox-field/primitive`, `field/primitive`). _Examples_: `TextInput` (via -`text-field/primitive`), `Combobox*` kit (via `combobox-field/primitive`), `button/primitive`, -`field/primitive`, and the composed-but-internal `Field`. _Avoid_: "base" and "raw". Use -**Primitive**. - -**Component creation**: The act of adding the public surface a new Atom or Composed component needs -to exist consistently. That includes source, stories, hosted docs, recipes when needed, and -generated exports. - -## Relationships - -- A **Composed** component is built from one or more **Atoms** or **Primitives**. -- A **Primitive** is documented in the hosted docs app so library authors and agents can find it. It - is omitted from the hosted docs primary navigation and index. -- The composed `Field` is a **Primitive** by audience, even though it composes other components. It - exists for library authors building `TextField`, `ComboboxField`, and similar components. -- An **Atom** or **Composed** component gets a hosted docs page. - -## Hosted docs shape - -Each component docs page at `apps/docs/content/docs/components//.mdx` follows the -section order from [ADR-0006](docs/adr/0006-docs-md-structure-standard.md) (now superseded by -ADR-0007; the section ordering still applies): - -- Usage lead-in with no explicit `## Usage` heading. -- `## Best Practices` table. -- Feature sections ordered by importance to a typical consumer. -- `## Accessibility` when the component has a user-facing accessibility contract. -- Cross-reference sections last. - -All prose is authored in the hosted docs app (`apps/docs/content/docs/`). The package no longer -ships generated docs on npm. Full rationale is in -[ADR-0007](docs/adr/0007-docs-moved-to-hosted-app.md). - -## Docs rule - -The **hosted docs app** (`apps/docs`) is the primary docs surface. It serves both app developers and -library authors. The package README links to it. - -| Tier | Hosted docs? | Notes | -| --------- | ----------------- | ------------------------------------------------ | -| Atom | yes (primary nav) | App-developer-facing | -| Composed | yes (primary nav) | App-developer-facing | -| Primitive | yes (specialist) | Listed in a "Library authors / advanced" section | - -**Specialist, not noise.** Primitive pages exist in the hosted docs so library authors and agents -can find them. They are listed in a separate, de-emphasised "Library authors / advanced" section, -never mixed into the primary index alongside atoms and composed components. The goal is reachability -without crowding the main path. Do not document anything that is not part of the public API. - -Package docs are no longer shipped on npm. - -## Decisions - -- [ADR-0001](docs/adr/0001-component-tier-taxonomy.md): Three-tier taxonomy docs rule -- [ADR-0002](docs/adr/0002-primitive-package-path-convention.md): Primitive kits are exported at - `[composed]/primitive` -- [ADR-0003](docs/adr/0003-package-docs-surface.md): Package docs are a separate AI-native surface - (superseded by ADR-0007) -- [ADR-0004](docs/adr/0004-styling-utilities-public-api.md): Styling utilities public API -- [ADR-0006](docs/adr/0006-docs-md-structure-standard.md): Standard structure for `.docs.md` prose - files (superseded by ADR-0007) -- [ADR-0007](docs/adr/0007-docs-moved-to-hosted-app.md): Docs moved to the hosted docs app diff --git a/README.md b/README.md index 8295dfe8..264e3e35 100644 --- a/README.md +++ b/README.md @@ -1,133 +1,48 @@ -# Luke UI 5 +# Luke UI -React design system using `vanilla-extract`. +React design system built with `react-aria-components` and `vanilla-extract`. ## Setup -- `pnpm install` -- `pnpm dev` - Start dev -- `pnpm build` - Build all -- `pnpm check` - Lint, format, types -- `pnpm test` - Run all tests (unit, Storybook, visual regression) +```sh +pnpm install +pnpm dev +``` -## Stack - -- **Monorepo**: pnpm + Turbo -- **React**: `react-aria-components` base -- **Styling**: `vanilla-extract` (static CSS) -- **Lint/Format**: `oxlint` + `oxfmt` - -## UI Package (`@luke-ui/react`) - -- Tokens: `src/tokens.ts` -- Theme: `src/theme/` -- Styles: `src/styles/` -- Build: `tsdown` -> `dist/stylesheet.css` - -## Contributing - -- Use `pnpm changeset` for versions. -- Run `pnpm check` before committing. - -## CI Setup - -- Test command: `pnpm test` -- Visual regression testing: `docs/VISUAL_TESTING.md` - -## TODO - -- Revise tokens -- Review visual styles (move away from being an EDS clone) -- Make docs more visual -- Review how we do stories - - Kitchen sink stories for broader test coverage - - Include more component states in stories (focus, open menus etc) - - Other examples are for consumers and quick reference +Useful repo commands: -Components to build: +- `pnpm run check`: lint, format, and typecheck. +- `pnpm run build`: build all packages and apps. +- `pnpm run test`: run unit, Storybook, and visual regression tests. -### Core - -- [ ] LinkContextProvider -- [ ] ThemeContext -- [ ] ThemeProvider - -### Accessibility - -- [ ] LiveRegion -- [ ] SkipTo -- [ ] VisuallyHidden - -### Media and visuals - -- [ ] Avatar -- [x] Icon -- [ ] Illustration - -### Typography and content - -- [x] Emoji -- [x] Heading -- [x] Numeral -- [x] Text - -### Feedback and status indicators +## Stack -- [ ] Badge -- [ ] EmptyState -- [x] LoadingSkeleton -- [ ] Notice -- [ ] ShowMore -- [ ] Toast -- [x] LoadingSpinner +- Monorepo: pnpm and Turbo. +- React: `react-aria-components`. +- Styling: `vanilla-extract` static CSS. +- Lint and format: `oxlint` and `oxfmt`. -### Layout and structure +## Package -- [ ] Breadcrumbs -- [ ] Card -- [ ] Divider -- [ ] PageHeader -- [ ] Pagination -- [ ] ScrollWrap -- [ ] Table -- [ ] Tabs -- [ ] Tag -- [x] Link +`@luke-ui/react` contains the public React package. -### Actions +- Tokens: `packages/@luke-ui/react/src/tokens.ts`. +- Theme: `packages/@luke-ui/react/src/theme/`. +- Styles: `packages/@luke-ui/react/src/styles/`. +- Build output: `packages/@luke-ui/react/dist/stylesheet.css`. -- [ ] ActionGroup -- [ ] ActionsDropdown -- [ ] BulkActionBar -- [x] Button -- [x] IconButton +## Docs -### Forms +- [Conventions](docs/CONVENTIONS.md): repo-wide coding conventions. +- [Components](docs/COMPONENTS.md): component tiers, package paths, and generator rules. +- [Documentation](docs/DOCUMENTATION.md): hosted docs ownership, MDX structure, examples, and API + reference. +- [Styling](docs/STYLING.md): cascade layers, recipes, and styling utilities. +- [Testing](docs/TESTING.md): test type, placement, and writing rules. +- [Visual testing](docs/VISUAL_TESTING.md): visual regression workflow. -- [ ] AddressInput -- [ ] AllFiltersButton -- [ ] Checkbox -- [ ] DateDropdown -- [ ] DateInput -- [ ] Field -- [ ] Fieldset -- [ ] FileInput -- [ ] FilterBar -- [ ] PhoneInput -- [ ] Radio -- [ ] RichTextEditor -- [ ] SearchInput -- [ ] SelectDropdown -- [ ] SelectInput -- [ ] TextAreaInput -- [ ] TextInput -- [ ] Toggle +## Contributing -### Overlays +Run `pnpm run check` before committing. -- [ ] Accordion -- [ ] Blanket -- [ ] Menu -- [ ] Modal -- [ ] Popover -- [ ] Tooltip +Use `pnpm changeset` when a change needs a package version entry. diff --git a/apps/docs/content/docs/components/actions/button.mdx b/apps/docs/content/docs/components/actions/button.mdx index 1783d327..cfcd4e54 100644 --- a/apps/docs/content/docs/components/actions/button.mdx +++ b/apps/docs/content/docs/components/actions/button.mdx @@ -86,17 +86,10 @@ The pending spinner is `aria-hidden` and does not announce busy state to screen reader users need to hear the pending state, change the label text itself, for example to "Saving", while `isPending` is set. -## Primitive Button +## Primitive -The lower-level `Button` primitive is available when you need full control over children, such as -custom loading states, render-prop children, or non-standard content. - -```ts -import { Button } from '@luke-ui/react/button/primitive'; -``` - -The primitive renders a single `; +``` + +## When to use + +Use `@luke-ui/react/button/primitive` when you need full control over children layout, render-prop +children, custom loading states, or non-standard button content. + +Use [`Button`](/docs/components/actions/button) for most app actions. + +## Behaviour + +The primitive renders a single `; ``` -### Available properties +## Utility surface The v1 surface covers: -- **Layout**: `display`, `flexDirection`, `justifyContent`, `alignItems` -- **Flex item**: `flexGrow`, `flexShrink`, `flexBasis` -- **Sizing**: `inlineSize`, `blockSize`, `minInlineSize`, `minBlockSize`, `maxInlineSize`, - `maxBlockSize` -- **Gaps**: `gap`, `rowGap`, `columnGap` -- **Padding**: `padding`, `paddingInline`, `paddingBlock`, `paddingInlineStart`, `paddingInlineEnd`, - `paddingBlockStart`, `paddingBlockEnd` -- **Overflow**: `overflow`, `overflowX`, `overflowY`, `textOverflow` -- **Pseudo-state**: `backgroundColor` with `hover` and `focus-visible` +- Layout: `display`, `flexDirection`, `justifyContent`, `alignItems`. +- Flex item: `flexGrow`, `flexShrink`, `flexBasis`. +- Sizing: `inlineSize`, `blockSize`, `minInlineSize`, `minBlockSize`, `maxInlineSize`, + `maxBlockSize`. +- Gaps: `gap`, `rowGap`, `columnGap`. +- Padding: `padding`, `paddingInline`, `paddingBlock`, `paddingInlineStart`, `paddingInlineEnd`, + `paddingBlockStart`, `paddingBlockEnd`. +- Overflow: `overflow`, `overflowX`, `overflowY`, `textOverflow`. +- Pseudo-state colour: `backgroundColor` with `hover` and `focus-visible`. -Margin utilities are excluded from the initial surface. +Margin utilities are not part of the initial surface. -Use CSS-native values throughout, for example `flex-start` instead of `start`. Keep -`@luke-ui/react/styles` separate from `@luke-ui/react/recipes`. Recipes are component-specific -styles. Styles are general layout utilities. +Use CSS-native values throughout, for example `flex-start` instead of `start`. -## Implementation +Styling utilities do not yet read runtime theme context. -- Use CSS logical properties such as `margin-inline-start`, `block-size`, and `inset-inline`. Do not - use physical properties such as `margin-left`, `height`, `left`, or `right`. +## Implementation rules + +- Use CSS logical properties such as `margin-inline-start`, `block-size`, and `inset-inline`. +- Do not use physical properties such as `margin-left`, `height`, `left`, or `right`. - Align variant names with public props, such as `size` and `tone`. - Boolean props use `is*` or `should*`. - -## Limitations - -Styling utilities do not yet have runtime theme context. diff --git a/docs/adr/0001-component-tier-taxonomy.md b/docs/adr/0001-component-tier-taxonomy.md deleted file mode 100644 index f16604b9..00000000 --- a/docs/adr/0001-component-tier-taxonomy.md +++ /dev/null @@ -1,47 +0,0 @@ -# Component tier taxonomy: Atom, Composed, Primitive - -> **Note:** The docs location detail is superseded by [ADR-0007](0007-docs-moved-to-hosted-app.md). -> Primitives are mentioned in prose on their parent component's hosted docs page (see, for example, -> the "Primitive kit" section of the Combobox Field docs), but do not yet have their own generated -> API reference. - -Luke UI classifies components into three tiers: **Atom**, **Composed**, and **Primitive**. The tier -decides whether the component appears in hosted docs and how it is described in source and hosted -docs. - -## Decision - -- **Atoms** present one conceptual unit. App developers use them directly. Examples: `Text`, `Link`, - `Icon`, `LoadingSpinner`, `Heading`, `Emoji`, and `Numeral`. Atoms get hosted docs. -- **Composed** components combine atoms or primitives into a ready-to-drop-in pattern for app - developers. Examples: `Button`, `IconButton`, `TextField`, and `ComboboxField`. Composed - components get hosted docs. -- **Primitives** are building blocks for library authors who are assembling the next composed - component. Examples: `TextInput`, the `Combobox*` kit, `button/primitive`, and the `Field` kit. - Primitives do not get hosted docs, but they are documented in package docs so library authors and - coding agents can find them. - -In one line: hosted docs target app developers. Package docs cover every public export path. - -## Rejected options - -We rejected a two-tier "composed vs primitive" model because it could not classify atoms cleanly. -`Text` was labelled "primitive" in its own JSDoc, but it is nothing like `TextInput` in terms of -audience or use. - -We also rejected treating the composed `Field` as app-developer-facing docs content. It composes -other components, but its audience is library authors. App developers reach it through `TextField`, -`ComboboxField`, and similar wrappers. - -Thin presets of one composed component do not earn a new Composed-tier module. The removed -`CloseButton` only pinned `IconButton`'s `icon` and `aria-label`. It failed the deletion test, so -the pattern belongs in the wrapped component's docs instead. See issue #41. - -## Consequences - -- Source JSDoc should use "atom", "composed", and "primitive" consistently. -- Do not use "primitive" as a generic label for anything that is not a plain HTML element. -- `docs/CONVENTIONS.md` should describe the three-tier taxonomy, not a two-way "primitive and - composed" split. -- Hosted docs stay focused on app-developer-facing atoms and composed components. -- Package docs remain the reachability surface for public primitive exports. diff --git a/docs/adr/0002-primitive-package-path-convention.md b/docs/adr/0002-primitive-package-path-convention.md deleted file mode 100644 index 404d2235..00000000 --- a/docs/adr/0002-primitive-package-path-convention.md +++ /dev/null @@ -1,38 +0,0 @@ -# Primitive kit exports live at `[composed]/primitive` - -When a primitive kit supports a composed component, export it at `[composed]/primitive` instead of a -bare top-level path. - -## Decision - -Use paths like: - -- `@luke-ui/react/text-field/primitive` for `TextInput` -- `@luke-ui/react/combobox-field/primitive` for `ComboboxInput`, `ComboboxControl`, - `ComboboxListBox`, and related parts -- `@luke-ui/react/field/primitive` for `Field`, the primitive field div, `FieldLabel`, `FieldError`, - and `FieldDescription` - -This follows the convention already used by `@luke-ui/react/button/primitive` and -`@luke-ui/react/field/primitive`. - -The path makes the audience visible. `combobox-field/primitive` reads as "the primitive kit that -underpins `ComboboxField`". The API remains public without moving source folders. - -## Rejected options - -We rejected top-level paths such as `./combobox` or `./text-input` because they do not signal -audience. The import line looks the same as an atom or composed component. - -We rejected a source-folder reshuffle such as `primitives/`, `composed/`, and `atoms/` at the -package root. That would churn internal imports without changing the public API shape. - -We rejected making primitives fully internal by removing them from `package.json#exports`. The -package is public, and external consumers may need to assemble their own composed wrappers. - -## Consequences - -- There is intentionally no top-level `./field` export. -- Consumers who need field anatomy import from `./field/primitive`. -- Primitive paths are lower-level escape hatches for library authors. -- New primitive kits must follow the `[composed]/primitive` convention. diff --git a/docs/adr/0003-package-docs-surface.md b/docs/adr/0003-package-docs-surface.md deleted file mode 100644 index 4a6f68ee..00000000 --- a/docs/adr/0003-package-docs-surface.md +++ /dev/null @@ -1,58 +0,0 @@ -# Package docs are a separate AI-native surface - -> **Superseded by [ADR-0007](0007-docs-moved-to-hosted-app.md).** Package docs are no longer shipped -> on npm. The hosted docs app is the primary docs surface. - -`@luke-ui/react` ships per-export documentation under `packages/@luke-ui/react/docs/`. Those docs -are generated from JSDoc, TypeScript types, and authored prose. They are separate from the hosted -Fumadocs site in `apps/docs`. - -## Decision - -Luke UI has two docs surfaces: - -- **Hosted docs** target app developers building UIs. Their navigation and page shape are tuned for - human discovery. -- **Package docs** target anyone reading the package off npm, including library authors and coding - agents. They document every public export path. - -Primitives are documented in package docs, but listed in a de-emphasised "Library authors" section -in `README.md` and `llms.txt`. Hosted docs continue to omit primitives. - -## Rejected options - -We rejected documenting no primitives anywhere. Agents and library authors who reach for -`text-field/primitive` need the type contract without reverse engineering source. - -We rejected one unified docs surface. Navigation tuned for app developers crowds out library-author -content. Navigation tuned for library authors clutters the hosted site. - -## Consequences - -- JSDoc and TypeScript types are authoritative for API tables. -- Co-located prose sources are `*.docs.md` files. They contain prose only. -- Prop tables are generated from types with `ts-morph`. -- Atom and composed component interfaces should re-declare important inherited - `react-aria-components` props with full JSDoc. Long-tail inherited props are covered by a single - "Extends `react-aria-components` ``" pointer. -- Generated files under `packages/@luke-ui/react/docs/` are not committed. They are produced by - `pnpm --filter @luke-ui/react generate:docs`, or by `turbo generate`. -- `dist/docs/llms-full.md` is built output and is not committed. -- CI validates that the generator runs. It does not compare generated files to a committed snapshot. -- Hosted docs embed generated package docs into component MDX pages with Fumadocs ``. - Story-driven interactivity sits above the included Markdown. -- `source.config.ts` strips leading generated titles from included Markdown so the hosted page does - not duplicate its frontmatter title. -- Page shape follows export shape, not tier. Single-export paths render component-style pages. - Multi-export paths render overview pages. -- Tier appears as index labelling, not as a separate page template. -- Full pages cover component-shaped exports. Overview pages cover `recipes`, `theme`, `tokens`, and - `utils`. -- `stylesheet.css`, `spritesheet.svg`, and `package.json` are index-only entries. -- A single `generate:docs` script emits the package README index and `llms.txt`. The hosted app - calls the same shared builder for its `/llms.txt` route. -- The package `README.md` is hand-authored. It is the front door, not a generated enumeration. -- The package `LICENSE` is a hand-committed copy of the workspace MIT license. -- First npm publish is deferred. `version` stays at `0.0.0` until a separate release-engineering - initiative. V1 package readiness is verified with `npm pack --dry-run` against the - `package.json#files` allowlist: `["dist", "docs", "README.md", "LICENSE"]`. diff --git a/docs/adr/0004-styling-utilities-public-api.md b/docs/adr/0004-styling-utilities-public-api.md deleted file mode 100644 index a1c72615..00000000 --- a/docs/adr/0004-styling-utilities-public-api.md +++ /dev/null @@ -1,40 +0,0 @@ -# Styling utilities are public API - -Styling utilities are public API, exported as named exports from `@luke-ui/react/styles`. They -provide token-aware, type-safe layout helpers for cases where component props are too narrow. - -## Decision - -Use Rainbow Sprinkles instead of vanilla-extract Sprinkles. - -Rainbow Sprinkles uses `assignInlineVars` to emit dynamic CSS custom properties at runtime. It does -not generate a static class for every token-value combination. That keeps the generated CSS bundle -small as the token scale grows, because the static utilities layer defines property-level classes -rather than value-level classes. - -The tradeoff is that values are applied through inline `style`, which raises specificity. That is -acceptable because the utilities layer is already the highest-priority escape hatch. - -## Rejected options - -- **Polymorphic `Box` component**: rejected because it introduces the same polymorphism issues that - make React Aria Components' `render` prop preferable. -- **Style props on every component**: rejected because it would bloat component APIs and blur the - boundary between component-specific recipes and consumer layout utilities. -- **Library-author-only API**: rejected because consumers repeatedly need safe layout composition - without writing inline styles. - -## Consequences - -- `@luke-ui/react/styles` exports `createSprinkles()` as a public layout utility. -- The initial surface covers layout, flex-item behaviour, sizing, token-backed gaps, token-backed - padding, overflow, and text overflow. -- Margin utilities are excluded. -- Values are CSS-native. -- Property names are logical where possible. -- Responsive values and pseudo-state conditions (`hover`, `focus-visible`) are in scope for v1. -- Responsive values use object notation. Array notation may be added later. -- Pseudo-states use Rainbow Sprinkles condition syntax. -- Utilities live in the `utilities` cascade layer. -- Layer helpers such as `styleInLayer` and `recipeInLayer` remain internal. -- No React component wrapper is added for this API. diff --git a/docs/adr/0005-component-creation-plan-module.md b/docs/adr/0005-component-creation-plan-module.md deleted file mode 100644 index ec224116..00000000 --- a/docs/adr/0005-component-creation-plan-module.md +++ /dev/null @@ -1,20 +0,0 @@ -# Component creation uses a plan module - -Component creation is modelled as a module that returns a plan for the files and checks needed to -add an Atom or Composed component. - -Turbo and Plop stay as the adapter that applies the plan. They are not where the component creation -rules live. - -## Decision - -Keep Luke UI's component creation rules in a testable plan module. The adapter can stay thin and -replaceable. - -## Rejected options - -- **Keep all logic in the Turbo generator**: rejected because it makes Plop the test surface and - spreads Atom, Composed, docs, story, recipe, and export rules through one shallow script. -- **Create files directly without a plan**: rejected because it makes dry-run tests and fixture - assertions harder. It also hides the exact public surfaces a component creation input should - produce. diff --git a/docs/adr/0006-docs-md-structure-standard.md b/docs/adr/0006-docs-md-structure-standard.md deleted file mode 100644 index 388e3b24..00000000 --- a/docs/adr/0006-docs-md-structure-standard.md +++ /dev/null @@ -1,65 +0,0 @@ -# Standard structure for `.docs.md` prose files - -> **Superseded by [ADR-0007](0007-docs-moved-to-hosted-app.md).** Component prose now lives in -> `apps/docs/content/docs/**/*.mdx`. `.docs.md` files are no longer used. - -Every `src//.docs.md` file follows the same section order. Readers can then -predict where to find usage, props, accessibility notes, and cross-references regardless of which -component they are reading. - -This extends [ADR-0003](0003-package-docs-surface.md), which established the two-surface docs split -and the "prose only" rule for `.docs.md` files. - -## Decision - -Use this section order: - -1. **Usage lead-in**: unheaded prose and minimal code examples. Do not write an explicit `## Usage` - heading. `render-page.ts` injects that heading when it assembles the generated package doc. -2. **`## Best Practices`**: a two-column `| Guidance | Practices |` table. `Guidance` contains plain - `Do` or `Don't`. `Practices` contains the sentence. This is not a paired `| Do | Don't |` table. - Add only rows that carry useful guidance. -3. **Feature sections**: one `##` heading per prop or concept, such as `## Size`, `## Tone`, or - `## Validation`. Order sections by importance to a typical consumer. Do not sort alphabetically - or follow TypeScript declaration order by default. -4. **`## Accessibility`**: include this when the component has user-facing accessibility behaviour - to explain. Delete it when the component has nothing beyond default semantics to call out. -5. **Cross-reference sections**: always last. - -Cross-reference section names: - -- `## Primitive {Name}` for a composed component with a same-subpath, single-component primitive - counterpart. `{Name}` is the primitive export name. Example: `## Primitive TextInput` in - `text-field.docs.md`. -- `## Primitive kit` for a same-subpath primitive kit with multiple exports. Example: - `combobox-field/primitive`. -- `## When to use vs {Name}` for an easily confused sibling component. - -These names apply to component docs in the package: atoms, composed components, and component -utilities documented under the same subpath export. - -## Rejected option - -We rejected leaving the shape as tribal knowledge. "Copy a sibling file" did not catch drift. -`button.docs.md` had no headings while other component docs used one `##` heading per feature, and -nothing flagged the mismatch. - -## Docs are authored in the package - -All component prose is authored in `packages/@luke-ui/react/src//.docs.md`, -next to the component source. - -Hosted docs MDX files under `apps/docs` are wiring only. They contain frontmatter, the interactive -`` demo, and an `` for generated package docs. - -## Consequences - -- The component generator scaffolds `## Best Practices` and `## Accessibility` placeholders for new - component docs. -- Primitives have no `.docs.md` file and no authored `## Usage` heading, per ADR-0003. -- Placeholder content in `.docs.md` must be visible text, not HTML comments. Generated Markdown is - included in Fumadocs MDX and also read as plain Markdown by npm users and agents. -- Visible placeholders are easier to catch than hidden comments. A forgotten hidden comment can - render as an empty section with no clue. -- This standard applies to Atom and Composed component docs. A separate audit can update older files - that do not yet match it. diff --git a/docs/adr/0007-docs-moved-to-hosted-app.md b/docs/adr/0007-docs-moved-to-hosted-app.md deleted file mode 100644 index f3fd01a7..00000000 --- a/docs/adr/0007-docs-moved-to-hosted-app.md +++ /dev/null @@ -1,38 +0,0 @@ -# Docs moved to the hosted docs app - -Component documentation has moved out of `@luke-ui/react` and into the hosted docs app in -`apps/docs`. The hosted docs app is now the primary docs surface. The package README links to it, -and package docs are no longer shipped on npm. - -This supersedes [ADR-0003](0003-package-docs-surface.md), which established a separate package-docs -surface, and [ADR-0006](0006-docs-md-structure-standard.md), which standardised the `.docs.md` prose -format. - -## Decision - -- All component prose lives in `apps/docs/content/docs/**/*.mdx`. -- Component MDX pages are the authoritative docs for app developers and library authors. -- API reference tables are generated from TypeScript types with `fumadocs-typescript`'s - `remarkAutoTypeTable` plugin. -- Interactive examples live in `apps/docs/src/examples//` and render through the - `` component. -- `llms.txt`, `llms-full.txt`, and `.md` per-page routes are provided by Fumadocs built-ins. -- The `@luke-ui/react` package README links to the hosted docs. -- The package no longer ships generated docs under `packages/@luke-ui/react/docs/` or includes them - in the npm `files` allowlist. - -## Rejected options - -We rejected keeping the two-surface split (hosted docs + package docs). Maintaining the package docs -generator, virtual modules, and a separate prose source in `src//.docs.md` -created duplication and tooling overhead without reaching a meaningfully different audience. The -same readers can use the hosted docs, the `llms.txt` index, and the per-page `.md` routes. - -## Consequences - -- Prose is co-located with the docs app instead of the component source. -- Component docs no longer need a `.docs.md` file or an `` of generated package docs. -- The `generate:docs` and `check:docs` scripts in `@luke-ui/react` are removed. -- The `@luke-ui/docs-tools` package and package-docs Vite plugins are removed. -- The hosted docs app type-checks and builds the full docs surface. -- ADR-0003 and ADR-0006 are superseded. diff --git a/packages/@luke-ui/react/README.md b/packages/@luke-ui/react/README.md index 451e49a4..f2ef943a 100644 --- a/packages/@luke-ui/react/README.md +++ b/packages/@luke-ui/react/README.md @@ -28,20 +28,19 @@ Full component documentation, interactive examples, and API reference are at AI agents can fetch documentation at: -- [llms.txt](https://lukebennett88.github.io/luke-ui/llms.txt) — component index -- [llms-full.txt](https://lukebennett88.github.io/luke-ui/llms-full.txt) — full docs -- Append `.md` to any docs URL for per-page markdown +- [llms.txt](https://lukebennett88.github.io/luke-ui/llms.txt): component index. +- [llms-full.txt](https://lukebennett88.github.io/luke-ui/llms-full.txt): full docs. +- Any docs URL with `.md` appended: per-page Markdown. -Components follow the -[three-tier taxonomy](https://github.com/lukebennett88/luke-ui/blob/main/docs/adr/0001-component-tier-taxonomy.md): +Components follow three tiers: -- **Atoms**: single units such as `Text`, `Icon`, and `Heading` -- **Composed**: opinionated combinations such as `Button` and `TextField` -- **Primitives**: building blocks for library authors, such as `button/primitive` and - `field/primitive` +- Atoms: single units such as `Text`, `Icon`, and `Heading`. +- Composed components: opinionated combinations such as `Button` and `TextField`. +- Primitives: lower-level public APIs for library authors, such as `button/primitive` and + `field/primitive`. -Atoms and composed components are app-developer-facing. Primitives are documented under `docs/` for -library authors, but excluded from the primary index. +Atoms and composed components are app-developer-facing. Primitives are documented in hosted docs for +library authors, separate from the primary component path. ## License -- 2.51.2