Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
10d85dd
spec(AST-094, AST-057): gestures work on the web for every pointer (F…
cixzhang Oct 27, 2026
c037c2f
spec(AST-094): the fine-pointer press paints through the press contro…
cixzhang Oct 27, 2026
ff18a21
Merge remote-tracking branch 'origin/main' into spec/gestures-on-web
cixzhang Oct 27, 2026
0329096
spec: gestures on web — useMenuPress, user-states, buttons follow eve…
cixzhang Oct 27, 2026
91bc491
spec(AST-057, AST-094): a trackpad's horizontal scroll swipes a row; …
cixzhang Oct 27, 2026
874ee55
Merge main (AST-094 FR19 scroll-edge exception) into spec/gestures-on…
cixzhang Oct 27, 2026
848021a
Merge main into spec/gestures-on-web
cixzhang Oct 27, 2026
1bb6eb7
Merge main into spec/gestures-on-web
cixzhang Oct 27, 2026
06fa181
Merge remote-tracking branch 'origin/main' into spec/gestures-on-web
cixzhang Oct 27, 2026
a3f189c
Merge main into spec/gestures-on-web
cixzhang Oct 27, 2026
c46ace4
spec(AST-057): DEC-4 names horizontal wheel input
cixzhang Oct 27, 2026
c7c4091
Merge main into spec/gestures-on-web
cixzhang Oct 27, 2026
8e6c9ef
Merge main into spec/gestures-on-web
cixzhang Oct 27, 2026
459c961
Merge main into spec/gestures-on-web
cixzhang Oct 27, 2026
7270894
Merge remote-tracking branch 'origin/main' into spec/gestures-on-web
cixzhang Oct 27, 2026
d5aee72
Merge main into spec/gestures-on-web
cixzhang Oct 27, 2026
7a823e3
Merge remote-tracking branch 'origin/main' into spec/gestures-on-web
cixzhang Oct 27, 2026
da36283
Merge main into spec/gestures-on-web
cixzhang Oct 27, 2026
4fb6ea2
spec(AST-057): intent names the pen
cixzhang Oct 27, 2026
4084b67
Merge main into spec/gestures-on-web
cixzhang Oct 27, 2026
4e3f644
Merge remote-tracking branch 'origin/main' into spec/gestures-on-web
cixzhang Oct 27, 2026
18da5ed
Merge main into spec/gestures-on-web
cixzhang Oct 27, 2026
b61be38
Merge main into spec/gestures-on-web
cixzhang Oct 27, 2026
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
32 changes: 16 additions & 16 deletions docs/architecture/react-component-runtime.md

Large diffs are not rendered by default.

7 changes: 4 additions & 3 deletions docs/design/reduced-motion.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,9 @@ Content that moves with the person's own pointer or finger during a drag
follows it as direct manipulation and is not a DR1 transition, and neither is
the momentum that continues a throw (DR2). A transition a
component starts when a touch drag is released, such as a swiped row sliding
out or returning (`spec:AST-057` FR5), cross-fades as DR2 says, because a
finger started it. Any other transition, such as one sheet handing off to
out or returning after a finger's swipe (`spec:AST-057` FR5), cross-fades as
DR2 says, because a finger started it; one a trackpad started follows DR2 on
a coarse primary pointer and DR3 otherwise. Any other transition, such as one sheet handing off to
another (`component:BottomSheetSwitcher` FR3), follows DR2 on a coarse primary
pointer and DR3 otherwise.

Expand All @@ -113,7 +114,7 @@ No normative assets are included.

## Component contract links

- `spec:AST-057` FR5 implements DR2 for a swiped row's slide out,
- `spec:AST-057` FR5 implements DR2 and DR3 for a swiped row's slide out,
spring back, and hold-out.
- `component:BottomSheetSwitcher` FR3 and ORD1 implement DR2 and DR3 for a
handoff between sheets.
Expand Down
4 changes: 2 additions & 2 deletions docs/design/user-states.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,12 @@ surface.
- **DR1 — Press the manipulated surface.** During pointer hold or drag, each
enabled surface in the matrix below MUST paint `--color-overlay-pressed` on
the named visual part. The overlay is transient and MUST clear when the press
or drag ends. Under a finger, the overlay's timing follows `spec:AST-094` FR11's press profiles.
or drag ends. The overlay's timing follows `spec:AST-094` FR11's press profiles under every pointer.
- **DR2 — Disabled means no response.** A disabled control in the matrix MUST
remain inoperable and MUST NOT gain a pressed visual treatment.
- **DR3 — Persistent selection wins.** A selected SegmentedControl item MUST
keep its raised selected surface during pointer hold; only an unselected item
receives the pressed overlay. Under a finger the item keeps that surface, and its press timing follows
receives the pressed overlay. Under every pointer the item keeps that surface, and its press timing follows
`spec:AST-094` FR11.

## Anatomy and hierarchy
Expand Down
18 changes: 9 additions & 9 deletions docs/families/buttons.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,15 +93,15 @@ Membership follows public responsibility, not an import of Button or a rendered

## Canonical concepts

| Concept | Values or states | Default semantics | Stability |
| ---------------- | ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------- |
| activation model | momentary action, navigation, persistent press | Button and IconButton activate once; ToggleButton represents retained pressed state | shipped distinction |
| content mode | visible label, custom visible content, icon-only | every control has a required accessible `label`; icon-only hides it visually | shipped family rule |
| size | `sm`, `md`, `lg` | `md`; explicit member size wins over an inherited group size | shipped family axis |
| visual state | rest, hover, focus, active, disabled, loading; pressed where applicable | states preserve control geometry and accessible purpose; under a finger, press feedback follows `spec:AST-094` FR11's control profile | shipped family rule |
| async action | absent, fire-once, interruptible persistent action | ordinary actions deduplicate while pending; persistent toggles remain reversible | shipped family distinction |
| elevation | `none`, `low`, `med`, `high` | `none`; the element painting the visible surface owns the shadow | shipped family axis; ToggleButton adoption approved |
| grouping | standalone, spaced set, connected surface | semantics and painted containment decide ownership; grouping alone does not | family rule |
| Concept | Values or states | Default semantics | Stability |
| ---------------- | ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------- |
| activation model | momentary action, navigation, persistent press | Button and IconButton activate once; ToggleButton represents retained pressed state | shipped distinction |
| content mode | visible label, custom visible content, icon-only | every control has a required accessible `label`; icon-only hides it visually | shipped family rule |
| size | `sm`, `md`, `lg` | `md`; explicit member size wins over an inherited group size | shipped family axis |
| visual state | rest, hover, focus, active, disabled, loading; pressed where applicable | states preserve control geometry and accessible purpose; press feedback follows `spec:AST-094` FR11's control profile under a finger and its fine-pointer profile under a mouse or a pen (not implemented: a mouse press still paints `:active`) | shipped family rule |
| async action | absent, fire-once, interruptible persistent action | ordinary actions deduplicate while pending; persistent toggles remain reversible | shipped family distinction |
| elevation | `none`, `low`, `med`, `high` | `none`; the element painting the visible surface owns the shadow | shipped family axis; ToggleButton adoption approved |
| grouping | standalone, spaced set, connected surface | semantics and painted containment decide ownership; grouping alone does not | family rule |

## Cross-component invariants

Expand Down
8 changes: 4 additions & 4 deletions docs/specs/AST-055-caller-rendered-trigger/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ INV2), so the decision lives here and those records cite it.
| FR3 | A caller-supplied control MUST NOT be taken as a `ReactNode` slot that the component renders inside an interactive element of its own. Callers routinely pass an interactive component, and that shape nests one interactive element inside another (AR2). A content slot rendered inside a component-owned control remains valid for non-interactive content and is unchanged. | DEC-1; AR2 | Accepted; jsdom evidence pending |
| FR4 | The caller's control MUST own a box. A component MUST NOT render it inside a wrapper with no box of its own (`display: contents`), and MUST NOT depend on such a wrapper where it paints or offsets a focus indicator on the trigger, or positions the overlay against the trigger's rect: there is no rect to anchor to and no box on which to paint. FR1 removes the need for any wrapper. | DEC-2; `architecture:layer-runtime` anchor contract | Accepted; real-browser evidence required |
| FR5 | Hover, pressed, and every other pointer paint on the caller's control MUST remain the caller's own CSS. The component MUST NOT write paint onto an element it does not render. The component MUST publish the overlay's open state on the handed-back props as `aria-expanded`, so a caller styles the open state from the rendered attribute and no additional public API is added for it. | DEC-3; `spec:AST-002` FR1, FR2 | Accepted; jsdom evidence pending |
| FR6 | The prop's consumer documentation MUST show styling the open state from `aria-expanded` on the caller's control, and MUST state that a pressed look keyed to `:active` is not a substitute, because `:active` does not behave the same under a coarse pointer — `module:DropdownMenu/useMenuPress` FR6 drops coarse-pointer `:active` paint on menu rows for that reason. | DEC-3; no current core component styles off `aria-expanded`, so callers have no example to copy | Accepted; documentation evidence pending |
| FR6 | The prop's consumer documentation MUST show styling the open state from `aria-expanded` on the caller's control, and MUST state that a pressed look keyed to `:active` is not a substitute, because `:active` does not behave the same under a finger, and press paint follows `spec:AST-094` FR11's profiles instead. | DEC-3; no current core component styles off `aria-expanded`, so callers have no example to copy | Accepted; documentation evidence pending |
| FR7 | Where a component offers both a built-in control and this prop, exactly one control MUST render. The caller's control MUST win, identically in every presentation the component supports, and a development warning MUST fire; the component's own chrome for the replaced control MUST NOT render. Silently ignoring a supplied prop, or rendering both, is rejected. | `spec:AST-002` FR15 (never silently render a broken state); `architecture:public-component-api` INV3 | Accepted; jsdom evidence pending |
| FR8 | A hook that returns props for a trigger — `triggerProps` and `getTriggerProps` on `useLightbox`, `usePopover`, `useMenuHover`, and `useHoverCard` — follows hook conventions and is unchanged by this record. Those return-value names are NOT precedent for a component prop's name or shape. This record does not require a hook to grow a render prop, nor a component to republish its trigger props as a hook return. | DEC-4 | Settled by DEC-4; no code change |

Expand Down Expand Up @@ -287,9 +287,9 @@ reaches CSS through the rendered attribute instead of through new public API.
Because no current core component styles off `aria-expanded` — every current use
only emits the attribute — the route has no in-repo example to copy, so FR6
requires it to be documented on the prop. The same documentation states that
`:active` is not a substitute: it does not behave the same under a coarse
pointer, which is why `module:DropdownMenu/useMenuPress` FR6 drops coarse-pointer
`:active` paint on menu rows.
`:active` is not a substitute: it does not behave the same under a finger,
which is why press paint follows `spec:AST-094` FR11's profiles instead of
`:active`.

### DEC-4 — Hook trigger props are a different convention

Expand Down
Loading
Loading