# Adopting Alpha

Read this before replacing an existing component with an Alpha one, whatever it
is being replaced with — a third-party library, an in-house component folder, or
markup written by hand. Alpha does not know how your application is built, so
this document states Alpha's own boundaries and the checks a substitution needs.
It never guesses at an equivalence, and neither should you.

## Alpha publishes exactly what `llms.txt` lists

That index is generated from the package's own registry at build time, so it is
complete for the version you have installed. A component that is not in it is
not Alpha's, and no amount of prop-guessing will make it exist.

## What Alpha does not ship

The rule is total and never goes stale: **Alpha exports exactly the surfaces
`llms.txt` lists.** If what you need is not one of them, Alpha does not ship it
— leave the existing implementation in place, mark it, and do not approximate
it out of other Alpha components.

The ones below are called out because they are the ones most often reached for,
not because the list is complete. It cannot be: the set of things Alpha does
not export is unbounded.

<!-- alpha/absent-exports: Box, Stack, Grid, Typography, Text, Flex, Container, Menu, Table, DataGrid, ThemeProvider, DynamicIcon, Icon, GlobalStyles, CssBaseline -->
<!-- alpha/absent-token-prefixes: space, spacing, gap, size, breakpoint, z, screen -->

- **No layout or typography primitives.** There is no `Box`, `Stack`, `Flex`,
  `Grid`, `Typography` or `Text`. Layout and running text belong to the
  application, in its own stylesheets. Leave them alone.
- **No spacing scale and no breakpoint scale.** Alpha's tokens cover colour,
  radius, elevation, type and one motion curve. Control heights live inside the
  components. Spacing between things is yours.
- **No style escape hatch.** There is no `sx`, no style-object prop and no
  `styled()`. See "The style path" below for what to do instead.
- **No theme provider and no reset.** Theming is a CSS custom property override
  plus `data-mode` on `<html>`; there is no React context to wrap anything in.
  Alpha emits no element selectors, so removing a reset from your app changes
  your app, not Alpha.
- **No table, data grid or menu.** A `Dropdown` is a value picker and a
  `Popover` is a panel holding whatever you put in it; neither is a menu of
  commands carrying its own keyboard contract, and neither is a table.
- **No dynamic icon lookup.** There is no name-keyed map from string to glyph,
  because that map is exactly what would stop a bundler dropping the glyphs an
  application does not use.

## The substitution procedure

1. **Inventory the application before changing it.** Search imports, re-exports,
   path aliases, JSX, local component directories, theme providers and styling
   APIs. Follow each candidate to the module that implements it. The source may
   be a package, a wrapper around one, or markup written directly in the app;
   its import graph, not its folder name, tells you which it is.
2. **Identify the source component by its import, and read it.** One name is
   routinely several components: a `Tooltip` from a third-party library, a
   `Tooltip` in the application's own component folder, and a wrapper around
   the first that exists only to show a hint when text overflows are three
   different things with three different answers — and the third has no Alpha
   equivalent at all. Resolve the import specifier, open the implementation,
   and decide per specifier, never per name.
3. **Choose the migration seam.** When an application-owned wrapper can keep
   the API its callers use while rendering Alpha inside, change that wrapper and
   validate its callers as one contract. When preserving the wrapper would hide
   a behavioural mismatch or keep source-specific props alive, migrate the
   affected call sites instead. Do not bypass an application abstraction merely
   to make the Alpha import visible at every use.
4. **Match on capability, not on name.** A tooltip is a tooltip whichever
   library drew it. A component that shares a name with an Alpha one but does
   something else — a "Dropdown" that is really a positioned panel, a "Card"
   that is really a layout grid — is not a match, and a rename would be a
   regression dressed as a migration.
5. **Read that surface's own document** — `llms.txt` lists one per surface —
   before writing a line of it. Every prop, every accepted value and every
   default is there. Where that table and the package's emitted `.d.ts` ever
   disagree, the `.d.ts` is the contract.
6. **Check the shape hazards.** This is where a mechanical rename compiles and
   then misbehaves, so check every one of these each time:
   - **A prop Alpha does not own becomes a DOM attribute.** Alpha components
     spread the native props of the element they render, so an unrecognised
     prop is not an error — it lands on the element. The costly case is a name
     that collides with a real HTML attribute: if the source component used
     `type` for its visual variant, then `type="primary"` on an Alpha button is
     a valid React prop, renders no variant, and gives the element an invalid
     `type` — which a browser treats as `submit`, so the button now submits the
     form it sits in. Rename by attribute name, never by value, and include the
     computed ones (`type={x ? 'a' : 'b'}`).
   - **A value outside a closed union fails silently.** The variant tables are
     exhaustive, and a value that is not in one produces no class: the
     component renders unstyled, with the attribute set to your bad value. In
     TypeScript that is a compile error. In plain JavaScript nothing tells you.
   - **The handler's name and its argument.** A field that called
     `onChange(nextValue)` with a bare string does not survive being pointed at
     a handler that receives a DOM event, and nothing will tell you: the code
     compiles and the value arrives as `[object Object]` or `undefined`.
   - **Controlled versus uncontrolled.** An explicitly passed `false` is a
     controlled closed component, which is not the same thing as an
     uncontrolled one that happens to be closed.
   - **Defaults differ, so dropping a prop is not a no-op.** Omitting a prop
     takes Alpha's default, which is rarely the source's — a size that was
     implicit before can come out visibly smaller. Spell out what the old
     default gave you rather than letting both defaults apply.
   - **Two source booleans may be one Alpha axis.** Where the source expressed
     something with independent flags and Alpha expresses it as a single union,
     some combinations are not expressible at all. The source resolved them by
     CSS rule order; Alpha makes you choose, and that choice is a decision to
     record rather than to guess.
   - **Where the content goes.** Whether the label is the children, a prop, or
     nothing at all because the element is void.
7. **Geometry is Alpha's.** Sizes are fixed axes with named values, and there is
   nothing between them or below the smallest. If the surrounding layout cannot
   absorb the size Alpha offers, that is a design decision for a person to
   take — adjust the container, or leave the existing control in place.
   Re-specifying a height through CSS is re-implementing the axis Alpha
   deliberately withheld.
8. **Take the style path.** In order of preference:
   - **A token override** for anything about appearance. Alpha's custom
     properties are unprefixed, so they are ordinary globals — if your
     application already declares one of these names, one of you will lose.
     Override in the same two-block shape the package uses, or a bare `:root`
     rule will land on both modes at once.
   - **`className` on a component root, for layout only** — width, flex, grid
     position, margin. Never for appearance.
   - **`[data-slot="…"]`** for a contextual override that belongs to one place
     in your layout. See `slots.md`: it is the only selector into a component
     that Alpha supports, and overlays are portalled, which defeats the
     descendant selector everyone reaches for first.
   - **Never** the hashed class names. They are content-addressed and change
     between builds.
9. **Icons are one static import per glyph**, by name, from the `/icons`
   subpath. If no Alpha glyph matches the drawing you are replacing, keep the
   existing icon — an approximate glyph is a silent visual change. Sizes are
   the named steps only, never a number, and an icon is never a control: the
   handler and the accessible name belong to the thing around it.
10. **Leave what you cannot resolve, and say so.** Where the mapping is
    genuinely ambiguous — a size with no counterpart, a prop with no
    equivalent, a layout that would have to change — do not pick the closest
    thing. Leave the existing code in place and mark it:

```
// TODO(alpha): <what is ambiguous, and what a person has to decide>
```

A file that migrates eight of ten call sites and flags two is a good
result. A file that migrates ten by guessing at two is a bad one, and the
guesses are the expensive part to find later.

## Keep a migration ledger

For work that spans files or sessions, create `alpha-migration.md` in the
consuming application's root and update it as part of every batch. Use one row
per resolved source export or application-owned wrapper, not one row per name:

| Source             | Resolved implementation | Call sites      | Capability   | Alpha target      | Status                                                 | Blocker           | Validation |
| ------------------ | ----------------------- | --------------- | ------------ | ----------------- | ------------------------------------------------------ | ----------------- | ---------- |
| `specifier#export` | `path`                  | paths or search | what it does | surface or `none` | `unreviewed`, `ready`, `migrated`, `blocked` or `keep` | decision required | checks run |

The ledger is discovery state, not permission to broaden the migration. Add
newly found call sites before editing them, record why an item stays, and mark a
row migrated only after its validation passes. A source dependency, provider,
reset or stylesheet can be removed only when searches show no remaining code
or configuration that needs it.

## Validate in batches

Use the consuming application's own gates: typecheck, lint, tests and its visual
harness where one exists. Also search for the source import and wrapper after
each batch. TypeScript cannot prove that focus returns to the trigger, that an
event still carries the same value, that a portal is styled in its new location,
or that a default size did not change; exercise those behaviours directly.
