@astryxdesign/core 0.6.3-canary.ea2f048 → 0.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Chat/ChatLayout.d.ts +0 -19
- package/dist/Chat/ChatLayout.d.ts.map +1 -1
- package/dist/Chat/ChatLayout.js +0 -19
- package/dist/Chat/ChatLayoutScrollButton.d.ts.map +1 -1
- package/dist/Chat/ChatLayoutScrollButton.js +5 -5
- package/dist/astryx.css +2 -2
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -3
- package/package.json +4 -9
- package/src/Chat/ChatLayout.doc.mjs +4 -12
- package/src/Chat/ChatLayout.test.tsx +0 -28
- package/src/Chat/ChatLayout.tsx +0 -19
- package/src/Chat/ChatLayoutScrollButton.test.tsx +0 -31
- package/src/Chat/ChatLayoutScrollButton.tsx +4 -16
- package/src/index.ts +0 -3
- package/src/tailwind-theme.css +6 -0
- package/dist/Timer/Timer.d.ts +0 -49
- package/dist/Timer/Timer.d.ts.map +0 -1
- package/dist/Timer/Timer.js +0 -158
- package/dist/Timer/index.d.ts +0 -9
- package/dist/Timer/index.d.ts.map +0 -1
- package/dist/Timer/index.js +0 -10
- package/src/Chat/ChatLayout.spec.md +0 -271
- package/src/Chat/__tests__/ChatLayoutScrollButton.a11y.chromium.spec.ts +0 -510
- package/src/Timer/Timer.doc.mjs +0 -183
- package/src/Timer/Timer.spec.md +0 -215
- package/src/Timer/Timer.test.tsx +0 -302
- package/src/Timer/Timer.tsx +0 -258
- package/src/Timer/index.ts +0 -11
package/dist/Timer/index.d.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file index.ts
|
|
3
|
-
* @input Imports Timer, TimerProps, and TimerFormat
|
|
4
|
-
* @output Public Timer component barrel
|
|
5
|
-
* @position Component subpath entry point for @astryxdesign/core/Timer
|
|
6
|
-
*/
|
|
7
|
-
export { Timer } from './Timer';
|
|
8
|
-
export type { TimerFormat, TimerProps } from './Timer';
|
|
9
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Timer/index.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AAEH,OAAO,EAAC,KAAK,EAAC,MAAM,SAAS,CAAC;AAC9B,YAAY,EAAC,WAAW,EAAE,UAAU,EAAC,MAAM,SAAS,CAAC"}
|
package/dist/Timer/index.js
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* @file index.ts
|
|
5
|
-
* @input Imports Timer, TimerProps, and TimerFormat
|
|
6
|
-
* @output Public Timer component barrel
|
|
7
|
-
* @position Component subpath entry point for @astryxdesign/core/Timer
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
export { Timer } from "./Timer.js";
|
|
@@ -1,271 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
schema_version: 3
|
|
3
|
-
template_version: 5
|
|
4
|
-
kind: component
|
|
5
|
-
id: component:ChatLayout
|
|
6
|
-
authority: draft
|
|
7
|
-
archive_reason: null
|
|
8
|
-
superseded_by: null
|
|
9
|
-
approved_by: null
|
|
10
|
-
approved_at: null
|
|
11
|
-
owners: [cixzhang]
|
|
12
|
-
review_triggers:
|
|
13
|
-
[public-api, behavior, layout, scrolling, accessibility, theming, testing]
|
|
14
|
-
verified_by:
|
|
15
|
-
[
|
|
16
|
-
packages/core/src/Chat/ChatLayout.test.tsx,
|
|
17
|
-
packages/core/src/Chat/ChatLayoutScrollButton.test.tsx,
|
|
18
|
-
packages/core/src/Chat/useChatStreamScroll.test.tsx,
|
|
19
|
-
packages/core/src/Chat/useChatNewMessages.test.tsx,
|
|
20
|
-
apps/storybook/stories/ChatLayout.stories.tsx,
|
|
21
|
-
]
|
|
22
|
-
modules: []
|
|
23
|
-
families: []
|
|
24
|
-
design_specs: []
|
|
25
|
-
architecture:
|
|
26
|
-
[
|
|
27
|
-
architecture:public-component-api,
|
|
28
|
-
architecture:component-style-authoring,
|
|
29
|
-
architecture:component-theming-surface,
|
|
30
|
-
architecture:theme-tokens,
|
|
31
|
-
architecture:react-component-runtime,
|
|
32
|
-
architecture:component-test-sufficiency,
|
|
33
|
-
architecture:knowledge-contracts,
|
|
34
|
-
]
|
|
35
|
-
contributing: []
|
|
36
|
-
system_specs: [spec:AST-025, spec:AST-029]
|
|
37
|
-
---
|
|
38
|
-
|
|
39
|
-
# ChatLayout component contract
|
|
40
|
-
|
|
41
|
-
This record is an **observational backfill** written during the 2026-09-23
|
|
42
|
-
component audit under `spec:AST-029/FR3–FR4`. Every row below describes behavior
|
|
43
|
-
already shipped on `main` and verified against source, focused tests, and
|
|
44
|
-
consumer docs. It adds, improves, removes and reinterprets nothing. Rows whose
|
|
45
|
-
basis is only current behavior are marked `verify`; unresolved questions stay in
|
|
46
|
-
Open questions rather than being settled here.
|
|
47
|
-
|
|
48
|
-
## Contract at a glance
|
|
49
|
-
|
|
50
|
-
| Area | Contract |
|
|
51
|
-
| ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
52
|
-
| Public contract | `children`, `composer`, `emptyState`, `scrollButton`, `scrollRef`, `density`, plus `BaseProps<HTMLDivElement>` and `ref` on the layout root. |
|
|
53
|
-
| Behavior | The root is a flex column; the message area grows and never shrinks; the dock is sticky when the root scrolls and fixed when `scrollRef` names an outer scroller. |
|
|
54
|
-
| End-user impact | A chat transcript scrolls under a composer that stays reachable, auto-follows streaming output, and offers a scroll-to-bottom affordance when the reader has moved away from the bottom. |
|
|
55
|
-
| Builder impact | None from this record. It documents the shipped surface; `density` becomes discoverable in consumer docs, which previously described an adaptation the component never performed. |
|
|
56
|
-
| Compatibility/readiness | Observational draft. No public API, default, or compatibility promise changes. Authority is `draft` until exact-head owner approval. |
|
|
57
|
-
| Review checks | Reject any row that states unshipped behavior, promises a default this component does not apply, or resolves OQ1 or OQ2 without an owner decision. |
|
|
58
|
-
| Governing rules | `architecture:public-component-api/INV1, INV5–INV6, INV8`; `architecture:component-style-authoring/INV1–INV3, INV5`; `architecture:theme-tokens/INV3`; `spec:AST-025/FR12` (not adopted). |
|
|
59
|
-
|
|
60
|
-
This table is a review projection; the body below is authoritative.
|
|
61
|
-
|
|
62
|
-
## Intent
|
|
63
|
-
|
|
64
|
-
ChatLayout is the structural shell for a chat surface. It owns one job: place a
|
|
65
|
-
scrolling transcript above a docked composer so that short conversations do not
|
|
66
|
-
overflow, long ones scroll, and the composer stays at the bottom edge of
|
|
67
|
-
whichever element actually scrolls. Scroll mechanics live in
|
|
68
|
-
`useChatStreamScroll` and `useChatNewMessages`; this component wires them to the
|
|
69
|
-
DOM it owns and publishes the resulting refs through `ChatLayoutContext`.
|
|
70
|
-
|
|
71
|
-
Consumer usage, prop syntax, and examples belong in `ChatLayout.doc.mjs`.
|
|
72
|
-
|
|
73
|
-
## Compatibility and migration
|
|
74
|
-
|
|
75
|
-
- Released default preserved: yes — `@astryxdesign/core@0.6.2` ships `./Chat`
|
|
76
|
-
with `ChatLayout`, `ChatLayoutProps`, and `ChatLayoutScrollButton`.
|
|
77
|
-
- Compatibility class: no change. This record is descriptive.
|
|
78
|
-
- Controlled/uncontrolled behavior: not applicable; the component holds no
|
|
79
|
-
controllable value.
|
|
80
|
-
- Migration decision: none.
|
|
81
|
-
|
|
82
|
-
## Ownership boundary
|
|
83
|
-
|
|
84
|
-
**Owns**
|
|
85
|
-
|
|
86
|
-
- The layout root: flex column, relative positioning, `container-type:
|
|
87
|
-
inline-size`, and the `chat-layout` theming target with its `density` axis.
|
|
88
|
-
- Which element scrolls: the root itself, or the element named by `scrollRef`.
|
|
89
|
-
- Dock positioning — `sticky` in self-scroll mode, `fixed` in external-scroll
|
|
90
|
-
mode — and the frosted glass layer painted behind it.
|
|
91
|
-
- Density geometry: dock padding, message-column max-width and inline padding,
|
|
92
|
-
and the blur layer's height and mask.
|
|
93
|
-
- Empty-state substitution and its centering box.
|
|
94
|
-
- The default scroll-to-bottom affordance and the visibility signal it receives.
|
|
95
|
-
- Publication of `scrollContainerRef` and `contentRef` through `ChatLayoutContext`.
|
|
96
|
-
|
|
97
|
-
**Does not own / non-goals**
|
|
98
|
-
|
|
99
|
-
- Scroll measurement, spring animation, lock behavior, or new-message detection —
|
|
100
|
-
owned by `useChatStreamScroll` and `useChatNewMessages`.
|
|
101
|
-
- Message presentation, grouping, or sender semantics — owned by
|
|
102
|
-
`component:ChatMessageList` and `component:ChatMessage`.
|
|
103
|
-
- Composer behavior, sizing, or status — owned by `component:ChatComposer`.
|
|
104
|
-
- The scroll-to-bottom control's own presentation — owned by
|
|
105
|
-
`component:ChatLayoutScrollButton`.
|
|
106
|
-
- Page shell, navigation, and landmark assignment — the caller's.
|
|
107
|
-
- The shared effective-axis scroll capability defined by `spec:AST-025`. This
|
|
108
|
-
component predates it and has not adopted it; see OQ1.
|
|
109
|
-
|
|
110
|
-
## Public concepts
|
|
111
|
-
|
|
112
|
-
| Concept | Closed values or states | Meaning | Default | Owner | Stability | Invalid-value behavior |
|
|
113
|
-
| -------------- | -------------------------------------------------------- | ---------------------------------------------------------------------------------- | ----------- | -------------------- | --------- | ------------------------------------------ |
|
|
114
|
-
| `children` | any `ReactNode` | Transcript content placed in the message area. | required | caller | stable | n/a — required |
|
|
115
|
-
| `composer` | any `ReactNode` | Content placed inside the dock. | required | caller | stable | n/a — required |
|
|
116
|
-
| `emptyState` | `ReactNode`; omitted | Rendered centred in place of `children` when `children` is empty. | omitted | caller | stable | omitted renders `children` unchanged |
|
|
117
|
-
| `scrollButton` | `undefined`; `null`; any `ReactNode` | `undefined` selects the wired default, `null` renders nothing, a node replaces it. | `undefined` | component/caller | stable | any node renders as given |
|
|
118
|
-
| `scrollRef` | `RefObject<HTMLElement \| null>`; omitted | Names the scrolling element; omitted makes the root scroll. | omitted | caller | stable | a null `current` leaves scrolling inactive |
|
|
119
|
-
| `density` | `compact`; `balanced`; `spacious` | Selects dock padding, message-column width, and blur-layer size. | `balanced` | component | stable | closed union; rejected by types |
|
|
120
|
-
| root surface | `ref`; DOM/data/ARIA props; `className`/`style`/`xstyle` | Extends the layout root. | omitted | public component API | stable | n/a |
|
|
121
|
-
|
|
122
|
-
`density` is a closed union. It is a documented `visualProps` axis of the
|
|
123
|
-
`chat-layout` target, and it is not theme-extensible: no unavailable custom value
|
|
124
|
-
has a safe theme-independent baseline, so it stays closed under
|
|
125
|
-
`architecture:component-theming-surface/INV14`.
|
|
126
|
-
|
|
127
|
-
## Behavioral and layout contract
|
|
128
|
-
|
|
129
|
-
| ID | Candidate invariant | Basis | Draft review state |
|
|
130
|
-
| --- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------- | ------------------ |
|
|
131
|
-
| FR1 | The root MUST be a flex column, so an in-flow sticky dock's height is part of the root's height rather than added on top of it. | regression fix for the phantom-scrollbar defect; pinned tests | settled |
|
|
132
|
-
| FR2 | The message area MUST grow into leftover space and MUST NOT shrink below its content height, so short transcripts fill the root exactly and long ones overflow it. | same regression fix; pinned tests | settled |
|
|
133
|
-
| FR3 | With no `scrollRef`, the root MUST be the scroll container and the dock MUST be `position: sticky`. | shipped implementation; pinned test | verify |
|
|
134
|
-
| FR4 | With a `scrollRef`, the root MUST NOT become a scroll container and the dock MUST be `position: fixed`. | shipped implementation; pinned test | verify |
|
|
135
|
-
| FR5 | `emptyState` MUST replace `children` exactly when `children` is `null`, `undefined`, `false`, or an empty array, and MUST NOT replace any other children. | shipped `hasVisibleContent`; pinned tests | verify |
|
|
136
|
-
| FR6 | `scrollButton` MUST distinguish three cases: omitted selects the wired default, `null` renders nothing, and a supplied node replaces the default. | shipped implementation; pinned tests | verify |
|
|
137
|
-
| FR7 | `density` MUST reflect on the root as the `chat-layout` target's `data-density`, and MUST select the dock, message-area, dock-inner, and blur-layer geometry together. | shipped implementation; pinned tests; family doc `visualProps` | verify |
|
|
138
|
-
| FR8 | The layout MUST publish its scroll container and message content refs through `ChatLayoutContext` so the message list can register the observed content box. | shipped implementation | verify |
|
|
139
|
-
| FR9 | Accepted `ref`, DOM/data/ARIA props, `className`, `style`, and `xstyle` MUST reach and compose on the layout root. | `architecture:public-component-api/INV5–INV6, INV8` | settled |
|
|
140
|
-
|
|
141
|
-
### Allowed variation
|
|
142
|
-
|
|
143
|
-
- **AV1 — Scroll ownership.** The caller chooses between root-owned and
|
|
144
|
-
externally-owned scrolling; the dock's positioning strategy follows that choice.
|
|
145
|
-
- **AV2 — Scroll affordance.** The caller may keep the wired default, remove it,
|
|
146
|
-
or substitute any node.
|
|
147
|
-
- **AV3 — Transcript content.** Any content is allowed in the message area;
|
|
148
|
-
ChatMessageList is a convention, not a requirement.
|
|
149
|
-
- **AV4 — Density geometry.** Resolved spacing and widths follow the active
|
|
150
|
-
theme's spacing scale; only the relationships between the three steps are fixed.
|
|
151
|
-
|
|
152
|
-
### Representative states
|
|
153
|
-
|
|
154
|
-
| State | Required invariant | Allowed variation |
|
|
155
|
-
| ----------------------------------- | --------------------------------------------------------------- | --------------------------------------------- |
|
|
156
|
-
| Self-scroll, short transcript | Root fills without overflowing; dock sticky at the block end | Empty state may occupy the message area |
|
|
157
|
-
| Self-scroll, overflowing transcript | Root scrolls; message area keeps content height | Scroll affordance becomes visible |
|
|
158
|
-
| External `scrollRef` | Root does not scroll; dock is fixed to the viewport's block end | The named element may be the document element |
|
|
159
|
-
| Empty children with `emptyState` | Centred empty state replaces the transcript | Any node may be the empty state |
|
|
160
|
-
| `scrollButton={null}` | No scroll affordance renders | Auto-scroll behavior is unchanged |
|
|
161
|
-
|
|
162
|
-
### Performance and resources
|
|
163
|
-
|
|
164
|
-
- **PR1 — No layout measurement in the component.** Density is a prop. ChatLayout
|
|
165
|
-
MUST NOT add a `ResizeObserver`, media query, or animation frame of its own for
|
|
166
|
-
presentation the CSS container/flex model already resolves
|
|
167
|
-
(`architecture:component-style-authoring/INV2`).
|
|
168
|
-
- **PR2 — Shared observation only.** Content-size observation reaches the browser
|
|
169
|
-
through the pooled `observeResize` utility used by `useChatNewMessages`, never a
|
|
170
|
-
per-instance observer.
|
|
171
|
-
|
|
172
|
-
## Accessibility contract
|
|
173
|
-
|
|
174
|
-
- **AR1 — The wired default scroll affordance MUST NOT be focusable while it is
|
|
175
|
-
visually hidden.** The hidden pill paints nothing, so focus landing on it would
|
|
176
|
-
have no visible indicator (WCAG 2.2 SC 2.4.7, Level AA). `opacity` and
|
|
177
|
-
`pointer-events` do not remove an element from sequential focus navigation.
|
|
178
|
-
- **AR2 — The scroll affordance MUST remain keyboard reachable and operable while
|
|
179
|
-
visible**, with its accessible name supplied by the catalog and replaced by the
|
|
180
|
-
new-messages label when new messages have arrived.
|
|
181
|
-
- **AR3 — All user-visible and AT-facing strings MUST come from the catalog**:
|
|
182
|
-
`@astryx.chatLayout.newMessages` and
|
|
183
|
-
`@astryx.chatLayoutScrollButton.scrollToBottom`.
|
|
184
|
-
- **AR4 — The layout MUST NOT assign a landmark role or accessible name to the
|
|
185
|
-
caller's regions.** Region semantics stay caller-owned.
|
|
186
|
-
- The self-scroll root carries no `tabIndex`, role, or accessible name of its
|
|
187
|
-
own; the keyboard path into scrolled content comes from whatever `children`
|
|
188
|
-
supplies. Which layer should own that guarantee is unresolved; see OQ1.
|
|
189
|
-
|
|
190
|
-
## Design relationships
|
|
191
|
-
|
|
192
|
-
- The dock paints a `backdrop-filter` blur with a block-start mask so the
|
|
193
|
-
transcript fades out behind the composer rather than ending at a hard edge.
|
|
194
|
-
Blur height and mask distance step with `density`.
|
|
195
|
-
- The scroll affordance is a pill whose height tracks `--size-element-md`, the
|
|
196
|
-
same token that sizes the `md` Button it wraps, so the pill's `overflow: hidden`
|
|
197
|
-
cannot clip that Button under a theme that retunes the element scale
|
|
198
|
-
(`architecture:theme-tokens/INV3`).
|
|
199
|
-
- Spacing, radius, shadow, duration, and easing all resolve from portable
|
|
200
|
-
semantic tokens. Component-local geometry that has no semantic role — the
|
|
201
|
-
message-column and dock-inner caps, the blur heights, and the empty-state
|
|
202
|
-
minimum height — remains a named component design decision.
|
|
203
|
-
- The component declares no portable token and no public custom property.
|
|
204
|
-
|
|
205
|
-
### Theming reachability (observed)
|
|
206
|
-
|
|
207
|
-
Observed dispositions for ChatLayout's five anatomy parts. This record carries no
|
|
208
|
-
`anatomy-theming:v1` block; the block is optional during migration, and see OQ2.
|
|
209
|
-
|
|
210
|
-
| Anatomy part | Disposition |
|
|
211
|
-
| ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
212
|
-
| Message area | `none` — reachability-gap: an internal element with no `themeProps` call. `chat-layout` sits on the scrolling root, so a theme cannot reach the transcript column's own padding or width cap. |
|
|
213
|
-
| Frosted glass dock | `none` — reachability-gap: the dock, its inner column, and the backdrop-filter blur layer paint the component's most distinctive surface and carry no target. |
|
|
214
|
-
| Scroll-to-bottom button | `delegatesTo` the `chat-layout-scroll-button` target, whose canonical owner in the current inventory is `component:Chat`. |
|
|
215
|
-
| Composer | `delegatesTo` the `chat-composer` target, whose canonical owner in the current inventory is `component:Chat`. |
|
|
216
|
-
| Empty state | `none` — reachability-gap: the empty-state box only centres caller content and carries no target. |
|
|
217
|
-
|
|
218
|
-
The `chat-layout` target itself is declared on the Chat family document
|
|
219
|
-
(`Chat.doc.mjs`) rather than on `ChatLayout.doc.mjs`.
|
|
220
|
-
|
|
221
|
-
## Family and system relationships
|
|
222
|
-
|
|
223
|
-
- There is no `family:chat` record. The Chat components share the `Chat.doc.mjs`
|
|
224
|
-
family document and its theming target inventory, which is not a knowledge-record
|
|
225
|
-
family contract.
|
|
226
|
-
- `component:ChatLayoutScrollButton` owns the scroll affordance's presentation,
|
|
227
|
-
label, and focus behavior. ChatLayout owns only when it is visible.
|
|
228
|
-
- `component:ChatMessageList` consumes `ChatLayoutContext.contentRef`.
|
|
229
|
-
- `spec:AST-025` owns the shared effective-axis scroll capability. ChatLayout
|
|
230
|
-
does not adopt it today: it declares `overflow-y: auto` unconditionally in
|
|
231
|
-
self-scroll mode rather than resolving an effective axis, and it assigns no
|
|
232
|
-
keyboard access to the viewport itself. FR12 accepts an existing focusable
|
|
233
|
-
descendant as the keyboard path; see OQ1 for the open ownership question.
|
|
234
|
-
|
|
235
|
-
## Verification map
|
|
236
|
-
|
|
237
|
-
| Contract | Verification | Representative states | Mutation or failure expectation | Audit section |
|
|
238
|
-
| -------- | -------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------- | ------------------------------------------------------------------------------------------------- | --------------------- |
|
|
239
|
-
| FR1, FR2 | `ChatLayout.test.tsx` self-scroll layout contract | self-scroll, short and long transcript | Restoring `min-height: 100%` on the message area re-adds the dock's height and the root overflows | `audit:ChatLayout/§4` |
|
|
240
|
-
| FR3, FR4 | `ChatLayout.test.tsx` dock positioning | no `scrollRef`; external `scrollRef` | Swapping sticky and fixed detaches the dock from the element that actually scrolls | `audit:ChatLayout/§4` |
|
|
241
|
-
| FR5 | `ChatLayout.test.tsx` empty-state cases | empty array; populated children | Treating populated children as empty hides the transcript | `audit:ChatLayout/§4` |
|
|
242
|
-
| FR6 | `ChatLayout.test.tsx` scroll-button cases | default; custom node; `null` | Collapsing `null` into the default renders an affordance the caller removed | `audit:ChatLayout/§4` |
|
|
243
|
-
| FR7 | `ChatLayout.test.tsx` density cases; `themingTargets.test.ts` | compact; balanced; spacious | Dropping the reflected attribute makes the theming axis unselectable | `audit:ChatLayout/§2` |
|
|
244
|
-
| FR8 | `useChatNewMessages.test.tsx`, `useChatStreamScroll.test.tsx` | first fill; streaming growth | Losing the published refs stops auto-scroll from observing content growth | `audit:ChatLayout/§7` |
|
|
245
|
-
| AR1, AR2 | `ChatLayoutScrollButton.test.tsx` and `ChatLayout.test.tsx` tab-order cases; `ChatLayoutScrollButton.a11y.chromium.spec.ts` in real Chromium | hidden at rest; visible; re-hidden after activation | Reverting to `opacity`-only hiding puts an invisible control back in the tab order | `audit:ChatLayout/§1` |
|
|
246
|
-
| PR2 | Source review of `useChatNewMessages` | mounted list | A per-instance `ResizeObserver` replaces the pooled one | `audit:ChatLayout/§7` |
|
|
247
|
-
|
|
248
|
-
## Decision log
|
|
249
|
-
|
|
250
|
-
None. This record settles no decision; it describes shipped behavior.
|
|
251
|
-
|
|
252
|
-
## Open questions
|
|
253
|
-
|
|
254
|
-
- **OQ1 — Which layer owns the keyboard path to scrolled content, and should
|
|
255
|
-
ChatLayout guarantee it?** (`human-api`) In self-scroll mode the root is the
|
|
256
|
-
scroll container and carries no `tabIndex`, role, or accessible name of its
|
|
257
|
-
own. `component:ChatMessageList`, the documented child, carries `role="log"`
|
|
258
|
-
and `tabIndex={0}`, and `spec:AST-025/FR12` accepts such an existing
|
|
259
|
-
focusable descendant instead of a named viewport. `children` is typed
|
|
260
|
-
`ReactNode`, so whether a composition supplying no focusable descendant is
|
|
261
|
-
also covered is unresolved, as is which layer should own the guarantee. This
|
|
262
|
-
record states the arrangement and asserts no defect.
|
|
263
|
-
- **OQ2 — Should the frosted dock be themeable?** (`human-api`) The dock, its
|
|
264
|
-
inner column, and the blur layer paint the component's signature surface, and
|
|
265
|
-
no current target reaches them.
|
|
266
|
-
|
|
267
|
-
## Content boundary
|
|
268
|
-
|
|
269
|
-
This file does not duplicate `ChatLayout.doc.mjs` prop tables or examples, the
|
|
270
|
-
audit's scores and evidence, or the scroll, message, and composer contracts owned
|
|
271
|
-
by their own components and hooks.
|