Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/docs/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ do's & don'ts). Read both before any UI/design work here. In short:

- **Register:** product · **Platform:** web. A developer **reference tool**, not a
marketing surface: design serves the task of looking up, copying, and correctly
using components. Closest kin: Radix / Base UI, Stripe, and Tailwind / shadcn docs.
using components. Closest kin: a dense, copy-first API reference, not a product tour.
- **Audience:** internal-first — Plane's own engineers and designers adopting propel,
then external `@makeplane/propel` consumers.
- **Success:** a developer can use any component correctly **without reading the
Expand Down
4 changes: 2 additions & 2 deletions apps/docs/PRODUCT.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ Show the real thing, twice. Every component appears as a live, interactive insta
_and_ as its exact source, together — never a screenshot, never a paraphrase. What
the reader sees working is what they can copy.

Earned familiarity. Navigation, layout, and interaction follow the conventions a
developer fluent in Radix, Stripe, and Tailwind docs already knows. No invented
Earned familiarity. Navigation, layout, and interaction follow the conventions any
developer who reads component-library docs already knows. No invented
affordances for standard tasks; the interface disappears into the lookup.

Practice what it documents. The site is built from propel's own tokens and honors
Expand Down
33 changes: 17 additions & 16 deletions packages/propel/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,12 +167,11 @@ An identical styled element shared across families is a single `internal/` primi
does not re-export it (rule 4a).

6b. **A style/layout prop only reuses a native attribute name when it IS that concept.** `variant`
and `size` are the two standard axes (propel follows [Kumo](https://kumo-ui.com)'s vocabulary) and
are used as such; `width`, `height` and `color` stay off-limits (an `elements` part is
render-capable, so those would collide with the element's own attribute for no gain). Genuine native
attributes (`type`, `disabled`, `href`, `aria-*`) pass through untouched, and a part that declares
its own `type`/`value`/`placeholder` on top of the native one is fine — that is a real, documentable
prop.
and `size` are the two standard axes and are used as such; `width`, `height` and `color` stay
off-limits (an `elements` part is render-capable, so those would collide with the element's own
attribute for no gain). Genuine native attributes (`type`, `disabled`, `href`, `aria-*`) pass
through untouched, and a part that declares its own `type`/`value`/`placeholder` on top of the
native one is fine — that is a real, documentable prop.

Where the axis and a real native attribute genuinely collide, the **styling axis wins** and the
native attribute is omitted from the props type:
Expand All @@ -192,11 +191,11 @@ stays `stretch: "auto" | "full"` (mirroring CSS `width`'s own vocabulary), never
elements.** One `variant` prop carries the component's look — including its color weight, which is
NOT a second axis (a destructive button is `variant="danger"`, not `prominence="secondary"` ×
`tone="danger"`). A single `variant` union may mix semantic values with decorative ones: `Badge`
takes `variant="danger"` and `variant="crimson"` from the same axis, exactly as Kumo's Badge does.
Do not split such a union into `variant` + `color`; `color` is reserved for the rare case where the
value set is _only_ a surface choice. Reach for a different axis name only when a component carries
a **second, orthogonal** visual dimension that `variant` already occupies (`density`, `stretch`,
`sizing`, `surface`, `elevation`, `placement`, `layout`, `visibility`, `orientation`, `side`).
takes `variant="danger"` and `variant="crimson"` from the same axis. Do not split such a union into
`variant` + `color`; `color` is reserved for the rare case where the value set is _only_ a surface
choice. Reach for a different axis name only when a component carries a **second, orthogonal**
visual dimension that `variant` already occupies (`density`, `stretch`, `sizing`, `surface`,
`elevation`, `placement`, `layout`, `visibility`, `orientation`, `side`).

If the values would render a **different element or semantics** (e.g. `<button>`
vs `<a>`), or carry an axis that only applies to one value, that's not a variant — it's a
Expand Down Expand Up @@ -283,8 +282,8 @@ you actually wrap or transform it.

Every styling/layout prop names the **concept** it controls — one name system-wide, with consistent
value spellings. Pick only the axes that apply to a component. **`variant` and `size` are the two
standard axes**, matching [Kumo](https://kumo-ui.com); reach for a more specific name only when the
component genuinely controls something neither of those covers.
standard axes**; reach for a more specific name only when the component genuinely controls
something neither of those covers.

| Axis | Controls | Example values |
| ------------- | ------------------------------------------------ | ------------------------------------------------------------------------------------------- |
Expand All @@ -309,9 +308,11 @@ component genuinely controls something neither of those covers.
`tone` grid whose combinations mostly do not exist. Splitting them made impossible states
representable and forced every call site to pass two props. This replaced the earlier
`prominence`/`tone` split (Button, 2026-07; Menu and the rest follow).
2. **A `variant` union may mix semantic and decorative values.** Kumo's Badge does exactly this, and
propel's Badge follows: `danger`/`crimson`, `success`/`emerald`, `info`/`indigo` live on one axis.
Don't split hues into a separate `color` prop (6c).
2. **A `variant` union may mix semantic and decorative values.** Badge puts `danger`/`crimson`,
`success`/`emerald` and `info`/`indigo` on one axis. A caller picks exactly one look, so a
separate `color` prop would only make contradictory pairs representable (`variant="danger"`
`color="emerald"`) — the same failure as the `prominence`/`tone` split above. Don't split hues
into a separate `color` prop (6c).
3. **`size`, not `magnitude`.** The familiar name wins: it matches what every other library and
every designer calls it. It does collide with the native `size` attribute on `input`-shaped
parts, which is resolved by omitting the native prop (6b) — not by renaming the axis.
Expand Down
Loading