Repository navigation
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
AI review status for this pull request.
|
PR Analysis Report🔎 Preview ·
|
| Component | Size | LoC | Visual · A11y · RTL |
|---|---|---|---|
| LayerProvider | 4.2 kB (0) · 20 B CSS (0) | — | ✓ · ✓ · ✗ |
| Lightbox · Storybook | 🔴 135.3 kB (+16.0 kB) · 11.0 kB CSS (+511 B) | 4,184 (+810) | ✓ · ✓ · ✓ |
| Timer | 13.4 kB (+121 B) · 6.0 kB CSS (0) | — | — · — · — |
101 more components
| Component | Size | LoC | Visual · A11y · RTL |
|---|---|---|---|
| ListItem | 68.8 kB (+109 B) · 11.3 kB CSS (0) | — | — · — · — |
| ChatToolCalls | 31.5 kB (+107 B) · 8.3 kB CSS (0) | — | — · — · — |
| TextInput | 66.7 kB (+106 B) · 11.1 kB CSS (0) | — | — · — · — |
| Timestamp | 32.4 kB (+106 B) · 10.2 kB CSS (0) | — | — · — · — |
| ChatMessageList | 27.6 kB (+105 B) · 7.0 kB CSS (0) | — | — · — · — |
| BreadcrumbItem | 83.5 kB (+102 B) · 12.1 kB CSS (0) | — | — · — · — |
| CommandPaletteInput | 31.1 kB (+102 B) · 7.5 kB CSS (0) | — | — · — · — |
| Spinner | 24.2 kB (+102 B) · 6.2 kB CSS (0) | — | — · — · — |
| AppShell | 89.7 kB (+99 B) · 13.5 kB CSS (0) | — | — · — · — |
| DateTimeInput | 204.8 kB (+98 B) · 18.6 kB CSS (0) | — | — · — · — |
| Heading | 11.9 kB (+97 B) · 5.4 kB CSS (0) | — | — · — · — |
| Table | 116.5 kB (+97 B) · 17.9 kB CSS (0) | — | — · — · — |
| Text · Storybook | 11.3 kB (+97 B) · 5.4 kB CSS (0) | 758 (+44) | ✓ · ✓ · — |
| CheckboxListItem | 69.9 kB (+95 B) · 11.3 kB CSS (0) | — | — · — · — |
| TextArea | 61.2 kB (+95 B) · 9.3 kB CSS (0) | — | — · — · — |
| FileInput | 68.1 kB (+93 B) · 10.9 kB CSS (0) | — | — · — · — |
| DropdownMenu | 95.8 kB (+91 B) · 17.3 kB CSS (0) | — | — · — · — |
| DateRangeInput | 91.2 kB (+90 B) · 12.4 kB CSS (0) | — | — · — · — |
| Markdown | 179.6 kB (+90 B) · 20.3 kB CSS (0) | — | — · — · — |
| Carousel | 68.7 kB (+89 B) · 10.9 kB CSS (0) | — | — · — · — |
| MoreMenu | 96.1 kB (+89 B) · 17.3 kB CSS (0) | — | — · — · — |
| MultiSelector | 93.6 kB (+89 B) · 16.8 kB CSS (0) | — | — · — · — |
| RadioListItem | 66.2 kB (+89 B) · 10.1 kB CSS (0) | — | — · — · — |
| CheckboxInput | 63.3 kB (+88 B) · 9.1 kB CSS (0) | — | — · — · — |
| CheckboxList | 68.1 kB (+88 B) · 8.1 kB CSS (0) | — | — · — · — |
| ComplexSelector | 69.8 kB (+88 B) · 11.8 kB CSS (0) | — | — · — · — |
| CommandPalette | 72.5 kB (+87 B) · 12.5 kB CSS (0) | — | — · — · — |
| ContextMenu | 106.4 kB (+87 B) · 17.2 kB CSS (0) | — | — · — · — |
| TableSelectionToolbar | 69.5 kB (+87 B) · 13.2 kB CSS (0) | — | — · — · — |
| DateInput | 183.1 kB (+86 B) · 16.9 kB CSS (0) | — | — · — · — |
| BaseTypeahead | 70.1 kB (+85 B) · 10.9 kB CSS (0) | — | — · — · — |
| Calendar | 70.3 kB (+85 B) · 10.5 kB CSS (0) | — | — · — · — |
| MobileNav | 69.6 kB (+85 B) · 10.6 kB CSS (0) | — | — · — · — |
| NumberInput | 70.7 kB (+85 B) · 11.4 kB CSS (0) | — | — · — · — |
| RadioList | 55.2 kB (+85 B) · 7.2 kB CSS (0) | — | — · — · — |
| TabMenu | 70.8 kB (+85 B) · 11.1 kB CSS (0) | — | — · — · — |
| TopNavMenu | 73.5 kB (+84 B) · 11.2 kB CSS (0) | — | — · — · — |
| AlertDialog | 104.3 kB (+83 B) · 14.4 kB CSS (0) | — | — · — · — |
| ToggleButton | 85.7 kB (+83 B) · 10.0 kB CSS (0) | — | — · — · — |
| MobileNavToggle | 59.6 kB (+82 B) · 9.9 kB CSS (0) | — | — · — · — |
| Stepper | 60.9 kB (+82 B) · 10.1 kB CSS (0) | — | — · — · — |
| TableHeaderCell | 107.2 kB (+82 B) · 17.4 kB CSS (0) | — | — · — · — |
| ChatLayout | 79.5 kB (+80 B) · 10.5 kB CSS (0) | — | — · — · — |
| Thumbnail | 63.6 kB (+80 B) · 11.5 kB CSS (0) | — | — · — · — |
| TopNav | 71.3 kB (+80 B) · 10.9 kB CSS (0) | — | — · — · — |
| TopNavMegaMenu | 68.7 kB (+80 B) · 11.8 kB CSS (0) | — | — · — · — |
| DropdownMenuSubMenu | 69.1 kB (+79 B) · 9.7 kB CSS (0) | — | — · — · — |
| Slider | 106.2 kB (+79 B) · 8.8 kB CSS (0) | — | — · — · — |
| Typeahead | 78.6 kB (+79 B) · 12.4 kB CSS (0) | — | — · — · — |
| IconButton | 59.3 kB (+78 B) · 9.9 kB CSS (0) | — | — · — · — |
| ChatSendButton | 59.7 kB (+77 B) · 9.9 kB CSS (0) | — | — · — · — |
| InputGroup | 55.5 kB (+77 B) · 7.8 kB CSS (0) | — | — · — · — |
| ChatComposer | 76.9 kB (+76 B) · 12.0 kB CSS (0) | — | — · — · — |
| ChatDictationButton | 59.8 kB (+76 B) · 10.0 kB CSS (0) | — | — · — · — |
| CodeBlock | 73.9 kB (+76 B) · 11.2 kB CSS (0) | — | — · — · — |
| DrawerHeader | 62.3 kB (+76 B) · 12.9 kB CSS (0) | — | — · — · — |
| Field | 53.8 kB (+76 B) · 7.2 kB CSS (0) | — | — · — · — |
| PowerSearch | 282.8 kB (+76 B) · 23.8 kB CSS (0) | — | — · — · — |
| TableCell | 107.6 kB (+76 B) · 17.6 kB CSS (0) | — | — · — · — |
| Toast | 97.1 kB (+76 B) · 10.2 kB CSS (0) | — | — · — · — |
| DialogHeader | 62.1 kB (+75 B) · 11.5 kB CSS (0) | — | — · — · — |
| Popover | 88.0 kB (+75 B) · 14.1 kB CSS (0) | — | — · — · — |
| SideNavCollapseButton | 60.1 kB (+75 B) · 10.0 kB CSS (0) | — | — · — · — |
| TopNavHeading | 73.9 kB (+75 B) · 11.0 kB CSS (0) | — | — · — · — |
| SideNavHeading | 74.5 kB (+74 B) · 11.2 kB CSS (0) | — | — · — · — |
| ChatComposerTokenElement | 74.6 kB (+73 B) · 11.2 kB CSS (0) | — | — · — · — |
| ChatLayoutScrollButton | 59.8 kB (+73 B) · 10.1 kB CSS (0) | — | — · — · — |
| ChatComposerInput | 74.6 kB (+72 B) · 11.2 kB CSS (0) | — | — · — · — |
| Switch | 100.7 kB (+72 B) · 9.9 kB CSS (0) | — | — · — · — |
| Tokenizer | 90.3 kB (+71 B) · 18.6 kB CSS (0) | — | — · — · — |
| Link | 52.1 kB (+70 B) · 7.0 kB CSS (0) | — | — · — · — |
| Banner | 61.3 kB (+69 B) · 10.5 kB CSS (0) | — | — · — · — |
| Button | 59.2 kB (+69 B) · 9.9 kB CSS (0) | — | — · — · — |
| Pagination | 108.5 kB (+69 B) · 17.7 kB CSS (0) | — | — · — · — |
| SideNavItem | 69.4 kB (+69 B) · 11.1 kB CSS (0) | — | — · — · — |
| Selector | 98.4 kB (+68 B) · 17.3 kB CSS (0) | — | — · — · — |
| TimeInput | 158.7 kB (+66 B) · 15.9 kB CSS (0) | — | — · — · — |
| SideNav | 111.0 kB (+62 B) · 11.3 kB CSS (0) | — | — · — · — |
| charts/Chart | 198.0 kB (new) · 494 B CSS (new) | — | — · — · — |
| charts/ChartLegend | 48.6 kB (new) · 224 B CSS (new) | — | — · — · — |
| charts/ChartTooltip | 175.2 kB (new) · 423 B CSS (new) | — | — · — · — |
| layer | — | — | — · ✓ · — |
| Layer | — | — | ✓ · ✓ · — |
| lab/ChatEmojiPicker | 102.5 kB (new) · 773 B CSS (new) | — | — · — · — |
| lab/ChatReactionBar | 103.7 kB (new) · 1.1 kB CSS (new) | — | — · — · — |
| lab/CommentComposer | 147.4 kB (new) · 1.9 kB CSS (new) | — | — · — · — |
| lab/Comments | 343.1 kB (new) · 2.5 kB CSS (new) | — | — · — · — |
| lab/CommentThread | 336.6 kB (new) · 2.4 kB CSS (new) | — | — · — · — |
| lab/DialogHeroHeader | 81.9 kB (new) · 372 B CSS (new) | — | — · — · — |
| lab/DiffViewer | 85.7 kB (new) · 2.1 kB CSS (new) | — | — · — · — |
| lab/EmojiPicker | 85.3 kB (new) · 751 B CSS (new) | — | — · — · — |
| lab/LineClamp | 13.4 kB (new) · 168 B CSS (new) | — | — · — · — |
| lab/ListInput | 100.6 kB (new) · 1.6 kB CSS (new) | — | — · — · — |
| lab/Schedule | 104.7 kB (new) · 3.9 kB CSS (new) | — | — · — · — |
| lab/SelectableCardGroup | 63.2 kB (new) · 162 B CSS (new) | — | — · — · — |
| lab/TourStep | 94.3 kB (new) · 590 B CSS (new) | — | — · — · — |
| lab/TransferList | 106.5 kB (new) · 1.7 kB CSS (new) | — | — · — · — |
| lab/TransferListSelector | 113.2 kB (new) · 1.9 kB CSS (new) | — | — · — · — |
| richtext/RichTextEditor | 295.7 kB (new) · 2.6 kB CSS (new) | — | — · — · — |
| richtext/RichTextEditorToolbar | 276.2 kB (new) · 454 B CSS (new) | — | — · — · — |
| richtext/RichTextView | 275.0 kB (new) · 2.3 kB CSS (new) | — | — · — · — |
Package size: measured; main has no measurement of the merge base to compare yet.
API changes: cli +22 · ~7 · −0 (against the merge base's committed report); theme-butter +1 · ~0 · −0 (against the merge base's committed report); theme-y2k +1 · ~0 · −0 (against the merge base's committed report)
Committed API report behind this build: cli 29 rows, core 35 rows, theme-butter 1 row, theme-y2k 1 row; run pnpm api:report.
31 API changes (advisory)
| Package | Where | Signature | Usage | |
|---|---|---|---|---|
| + | cli |
./api · Functions · function exportSearchIndex |
function exportSearchIndex @experimental: (options?: { cwd?: string | undefined; package?: string | undefined }) => Promise<SearchIndex> |
import {exportSearchIndex} from '@astryxdesign/cli/api'; exportSearchIndex(…) |
| + | cli |
./api · Functions · function rankSearchIndex |
function rankSearchIndex @experimental: (query: string, indexes: SearchIndex | SearchIndex[], options?: { type?: SearchDomain | undefined; limit?: number | undefined }) => Promise<SearchResponse> |
import {rankSearchIndex} from '@astryxdesign/cli/api'; rankSearchIndex(…) |
| + | cli |
./api · Types · type DocsListChild |
type DocsListChild = DocsNodeChild & { topic: string; description: string; children?: DocsListChild[]; childCount?: number } |
import type {DocsListChild} from '@astryxdesign/cli/api' |
| + | cli |
./api · Types · type DocsListNamespace |
childCount?: number | undefined |
import type {DocsListNamespace} from '@astryxdesign/cli/api'; const x: DocsListNamespace = {childCount: …} |
| + | cli |
./api · Types · type DocsListNamespace |
children?: DocsListChild[] | undefined |
import type {DocsListNamespace} from '@astryxdesign/cli/api'; const x: DocsListNamespace = {children: …} |
| + | cli |
./api · Types · type SearchIndex |
type SearchIndex |
import type {SearchIndex} from '@astryxdesign/cli/api' |
| + | cli |
./api · Types · type SearchResultEntry |
deprecated?: ComponentDeprecation | undefined |
import type {SearchResultEntry} from '@astryxdesign/cli/api'; const x: SearchResultEntry = {deprecated: …} |
| + | cli |
./authoring · Types · interface ComponentDeprecation |
interface ComponentDeprecation |
import type {ComponentDeprecation} from '@astryxdesign/cli/authoring' |
| + | cli |
./authoring · Types · interface ComponentIconSlotDoc |
interface ComponentIconSlotDoc |
import type {ComponentIconSlotDoc} from '@astryxdesign/cli/authoring' |
| + | cli |
./authoring · Types · interface ComponentIconSlotStateDoc |
interface ComponentIconSlotStateDoc |
import type {ComponentIconSlotStateDoc} from '@astryxdesign/cli/authoring' |
| + | cli |
./authoring · Types · interface MultiComponentDoc |
deprecated?: ComponentDeprecation |
import type {MultiComponentDoc} from '@astryxdesign/cli/authoring'; const x: MultiComponentDoc = {deprecated: …} |
| + | cli |
./authoring · Types · interface SingleComponentDoc |
deprecated?: ComponentDeprecation |
import type {SingleComponentDoc} from '@astryxdesign/cli/authoring'; const x: SingleComponentDoc = {deprecated: …} |
| + | cli |
./doc · Types · interface ComponentBaseDoc |
deprecated?: ComponentDeprecation |
import type {ComponentBaseDoc} from '@astryxdesign/cli/doc'; const x: ComponentBaseDoc = {deprecated: …} |
| + | cli |
./doc · Types · interface SubComponentDoc |
deprecated?: ComponentDeprecation |
import type {SubComponentDoc} from '@astryxdesign/cli/doc'; const x: SubComponentDoc = {deprecated: …} |
| + | cli |
./doc · Also exported from an earlier entry point · ComponentDeprecation |
ComponentDeprecation (./authoring) |
import {ComponentDeprecation} from '@astryxdesign/cli/doc' |
| + | cli |
./doc · Also exported from an earlier entry point · ComponentIconSlotDoc |
ComponentIconSlotDoc (./authoring) |
import {ComponentIconSlotDoc} from '@astryxdesign/cli/doc' |
| + | cli |
./doc · Also exported from an earlier entry point · ComponentIconSlotStateDoc |
ComponentIconSlotStateDoc (./authoring) |
import {ComponentIconSlotStateDoc} from '@astryxdesign/cli/doc' |
| + | cli |
./json · Also exported from an earlier entry point · DocsListChild |
DocsListChild (./api) |
import {DocsListChild} from '@astryxdesign/cli/json' |
| + | cli |
./json · Also exported from an earlier entry point · SearchIndex |
SearchIndex (./api) |
import {SearchIndex} from '@astryxdesign/cli/json' |
| + | cli |
./template · Also exported from an earlier entry point · ComponentDeprecation |
ComponentDeprecation (./authoring) |
import {ComponentDeprecation} from '@astryxdesign/cli/template' |
| + | cli |
./template · Also exported from an earlier entry point · ComponentIconSlotDoc |
ComponentIconSlotDoc (./authoring) |
import {ComponentIconSlotDoc} from '@astryxdesign/cli/template' |
| + | cli |
./template · Also exported from an earlier entry point · ComponentIconSlotStateDoc |
ComponentIconSlotStateDoc (./authoring) |
import {ComponentIconSlotStateDoc} from '@astryxdesign/cli/template' |
| ~ | cli |
./api · Functions · function search |
function search: (query: string, options?: { cwd?: string | undefined; type?: "template" | "component" | "hook" | "theme" | "doc" | undefined; limit?: number | undefined }) => Promise<SearchResponse> → function search: (query: string, options?: { cwd?: string | undefined; type?: "template" | "component" | "doc" | "theme" | "hook" | undefined; limit?: number | undefined }) => Promise<SearchResponse> |
import {search} from '@astryxdesign/cli/api'; search(…) |
| ~ | cli |
./api · Types · type SwizzleCopyResponse |
data: { component: string; package: string; outputDir: string; filesCopied: number; files: string[]; usesStyleX: boolean; feedback?: SwizzleFeedback | undefined } → data: { component: string; package: string; outputDir: string; filesCopied: number; files: string[]; usesStyleX: boolean; dependencies: Record<string, string>; marker … #84d9505b |
import type {SwizzleCopyResponse} from '@astryxdesign/cli/api'; const x: SwizzleCopyResponse = {data: …} |
| ~ | cli |
./authoring · Types · interface MultiComponentDoc |
theming?: { container?: boolean; targets: ComponentThemingTarget[]; vars?: ComponentThemingVar[]; derived?: ComponentThemingDerivedVar[] } → theming?: { container?: boolean; targets: ComponentThemingTarget[]; vars?: ComponentThemingVar[]; derived?: ComponentThemingDerivedVar[]; componentIcons?: ComponentIconSlotDoc[] } |
import type {MultiComponentDoc} from '@astryxdesign/cli/authoring'; const x: MultiComponentDoc = {theming: …} |
| ~ | cli |
./authoring · Types · interface SingleComponentDoc |
theming?: { container?: boolean; targets: ComponentThemingTarget[]; vars?: ComponentThemingVar[]; derived?: ComponentThemingDerivedVar[] } → theming?: { container?: boolean; targets: ComponentThemingTarget[]; vars?: ComponentThemingVar[]; derived?: ComponentThemingDerivedVar[]; componentIcons?: ComponentIconSlotDoc[] } |
import type {SingleComponentDoc} from '@astryxdesign/cli/authoring'; const x: SingleComponentDoc = {theming: …} |
| ~ | cli |
./authoring · Types · type TemplateCategory |
type TemplateCategory = | 'Dashboard - Analytics' | 'Dashboard - Comparison' | 'Dashboard - KPI Summary' | 'Dashboard - Monitoring' | 'Dashboard - Executive Summary' | 'Dashboard - Sco … #e7c18378 → type TemplateCategory = | 'Dashboard - Analytics' | 'Dashboard - Comparison' | 'Dashboard - KPI Summary' | 'Dashboard - Monitoring' | 'Dashboard - Executive Summary' | 'Dashboard - Sco … #a8be998f |
import type {TemplateCategory} from '@astryxdesign/cli/authoring' |
| ~ | cli |
./doc · Types · interface ComponentBaseDoc |
theming?: { container?: boolean; targets: ComponentThemingTarget[]; vars?: ComponentThemingVar[]; derived?: ComponentThemingDerivedVar[] } → theming?: { container?: boolean; targets: ComponentThemingTarget[]; vars?: ComponentThemingVar[]; derived?: ComponentThemingDerivedVar[]; componentIcons?: ComponentIconSlotDoc[] } |
import type {ComponentBaseDoc} from '@astryxdesign/cli/doc'; const x: ComponentBaseDoc = {theming: …} |
| ~ | cli |
./doc · Types · interface SubComponentDoc |
theming?: { container?: boolean; targets: ComponentThemingTarget[]; vars?: ComponentThemingVar[]; derived?: ComponentThemingDerivedVar[] } → theming?: { container?: boolean; targets: ComponentThemingTarget[]; vars?: ComponentThemingVar[]; derived?: ComponentThemingDerivedVar[]; componentIcons?: ComponentIconSlotDoc[] } |
import type {SubComponentDoc} from '@astryxdesign/cli/doc'; const x: SubComponentDoc = {theming: …} |
| + | theme-butter |
Public attributes · attr data-astryx-pressable |
attr data-astryx-pressable (public data attribute) |
[data-astryx-pressable] { … } |
| + | theme-y2k |
Public attributes · attr data-astryx-pressable |
attr data-astryx-pressable (public data attribute) |
[data-astryx-pressable] { … } |
Touched components checked; add ci:run-visual or ci:run-rtl to run the full suites.
Accessibility: 1 violation(s)
Accessibility Audit
Status: 1 accessibility violation(s) found — 1 serious.
Text - 1 issue(s)
- 🟠 serious: Ensure the contrast between foreground and background colors meets WCAG 2 AA minimum contrast ratio thresholds
- Rule:
color-contrast· Affects 1/24 stories · Learn more - WCAG: 1.4.3 (Level AA)
- Rule:
Generated by PR Enrichment workflow | View full report
There was a problem hiding this comment.
This pull request needs an owner decision on its Lightbox spec changes, and it has two blocking findings that need changes either way.
- A single zoomed photo no longer pans on a drag that starts at its side edge, because
useZoomStage.ts(lines 214–227) refuses that pan for every Lightbox rather than only for a gallery whose pager can take it, so please hand the drag off at an edge only in a gallery and add a single-photo test that drags out from an edge. - Against
mainthis pull request is 5,488 changed lines, and since itsStack:line does not match the one in #8197 and #9810 (neither lists this pull request) the stack size exemption does not apply, so please give all three descriptions one identicalStack:line, bottom first with this pull request last, or split the change.
The head adds requirements the current records do not state: the gallery caption-band sentences in component:Lightbox FR1, the new FR17 media-surface rule, and a rewrite of the spec:AST-038 Lightbox row that currently keeps centred large captions. Approval needs an engineering owner to approve or reject those record changes by commenting /approve-spec <full head SHA> on this pull request, and the author can do that as an engineering owner. The review shows before and after captures for both findings.
[Automated review]
1370140 to
702b595
Compare
There was a problem hiding this comment.
This pull request needs an engineering owner's decision on its Lightbox spec changes, and it has two blocking findings that need changes either way.
Approval waits on an engineering owner approving or rejecting three spec changes, as written at this head: component:Lightbox FR1's gallery caption-band sentences (the two-line band, the "more"/"less" button for every pointer, the full caption as the accessible description); the new FR17 media-surface row, which also restyles a single photo's caption as body text on a dark plate; and spec:AST-038's rewritten Lightbox row, which drops the "Centered large captions … remain intentional" guidance. An engineering owner records the decision by commenting /approve-spec <full head SHA> on this pull request; the author may do so if they are an engineering owner.
Blocking findings:
.changeset/pager-settle-tempo.mdsays aCarouselwithhasSnapnow settles at the theme'stempo, but onlyhasSnap={useSnapPaging()}runs the pager (plainhasSnapkeeps CSS scroll snap), so it should read "in aCarouselgivenhasSnap={useSnapPaging()}".- The diff is 5,947 authored lines with no size exemption, because the
Stack:line is not the one #8147 and #8148 carry and it lists #8215, which this head does not contain; give every listed pull request one identical linear line of pull requests that each contain the one below (for example #8197 → #9810 → #10284), or split the change.
Non-blocking: spec:AST-094's FR45 verification row still lists the pager's tempo gap, and the proposed FR1 does not yet state the toggle's expanded state or where focus goes when paging removes it. The single zoomed photo's drag from its edge pans again, as on main.
[Automated review]
702b595 to
2b845bc
Compare
There was a problem hiding this comment.
This stack is waiting on one engineering-owner decision: #8197 and #9810 are approved, and #10284 needs its new Lightbox spec line approved.
#8197
Approved at its current head, with no blocking findings.
#9810
Approved at its current head, with no blocking findings.
#10284
Approval waits on an engineering owner approving or rejecting component:Lightbox FR1b and its verification row, as written at this head: a single photo presents its caption the same way a gallery page does (the two-line band at the bottom of the viewer on the caption's backing, the inline "more"/"less" for every pointer, the photo centred above it, no band without a caption), with no paging controls and the zoomed photo's rubber band as its exceptions. No current record states this. An engineering owner records the decision by commenting /approve-spec <full head SHA> on this pull request; the author may do so if they are an engineering owner. There are no blocking findings beyond that decision.
Non-blocking: the record's "Captioned media" state still says the caption follows the photo in a centred group, FR1b's exception should say a gallery's touch pager takes the edge drag, and the description should say this pull request also carries #8197's busy-proof test rewrite and a merge of main.
Whole stack
No blocking issue across the three pull requests, and the head merges cleanly with main. Each pull request lands only when it and every pull request below it are approved; CI has not run on these drafts yet.
[Automated review]
2b845bc to
e902d9a
Compare
There was a problem hiding this comment.
This stack waits on engineering-owner approvals for #9810 and #10284, and #8197 needs one fix. Each pull request lands only when it and every pull request below it are approved.
#8197
Changes needed:
- Regression: this head conflicts with
main, because the v0.7.10 release deleted.changeset/lightbox-every-pointer.mdand this pull request still edits one line of it; mergemainhere and drop that edit (the merge already in #9810's history does exactly this), then have the record approval re-stamped at the new head.
#9810
No blocking findings. Its own changes are identical to the approved head, but the new head merges #8197 and main, so the record approval no longer applies: an engineering owner re-approves its unchanged record text by commenting /approve-spec <full head SHA> on #9810.
#10284
Approval waits on an engineering owner approving or rejecting component:Lightbox FR1b and its verification row as written: a single photo presents its caption the same way a gallery page does (the two-line band at the bottom of the viewer on the caption's backing, the inline "more"/"less" for every pointer, the photo centred above it, no band without a caption), with no paging controls and the zoomed photo's rubber band as its exceptions. No current record states this. An engineering owner records the decision by commenting /approve-spec <full head SHA> on this pull request; the author may do so if they are an engineering owner. There are no other blocking findings.
Non-blocking: the translator notes for "more" and "less" in en.json still say they follow a gallery caption (Miss), the record's "Captioned media" state still describes the old centred group, and FR1b's exception should say a gallery's touch pager takes the edge drag.
Whole stack
No blocking issue in the combined change: it merges cleanly with main, its records agree with each other, and the touched unit suites pass. CI has not run on these drafts yet.
[Automated review]
|
/approve-spec e902d9a |
There was a problem hiding this comment.
Changes needed before this can land; one rebase fixes all three blocking findings. This pull request is reviewed on its own against main, because #8197 and #9810 no longer list it in their Stack: line and this head does not contain their current heads; its record changes, component:Lightbox FR1b included, carry an engineering owner's /approve-spec for this head, so no spec decision is pending.
- Regression: the stack exemption no longer covers this branch's 6,681 authored lines, so rebase it onto #9810's current head and give #8197, #9810 and #10284 one identical
Stack: #8197 → #9810 → #10284line. - Regression: merging this head into
mainstops on a conflict inpackages/core/src/Lightbox/__tests__/LightboxZoom.interaction.browser.spec.ts, which #9810's current head already resolves. - Miss:
onSettleinLightbox.tsxresets only photos outside the page marked current, so when a swipe's render lands after the settle ends the photo left behind keeps its zoom; #8197's current head fixes this by skipping only the page the pager reports as settled.
Non-blocking: the "more"/"less" translator notes in en.json still say "gallery caption", and the record's "Captioned media" state still describes the old centred caption. The rebased head will need a fresh /approve-spec.
[Automated review]
e902d9a to
fcf9c27
Compare
|
/approve-spec b565bdc |
Main's Lightbox record now has FR17, an index past either end, and FR18, a paged-away video. This branch's media-surface requirement, also numbered FR17, becomes FR19, with its verification row and its Current-state entry.
The caption band now carries main's FR17 and FR18, and its media-surface requirement is FR19. This branch's verification row for it follows as FR19, and the single photo's caption-contrast gap stays removed: this branch fixes it.
The owner's message reads differently from the sentence FR1b quoted. FR1b now keeps only her exact fragment, "they really should be consistent", and says the rest in plain prose.
There was a problem hiding this comment.
Changes requested: one blocking finding, in #9810's record and carried into #10284; the record text itself is owner-approved and the Stack: line now holds.
#9810: request changes
- Regression:
mainnow defines its owncomponent:LightboxFR17 (the nearest valid item for an out-of-rangeindex) and FR18 (a paged-away video), so this pull request's media-surface FR17 row and its verification row collide with them and GitHub reports a merge conflict indocs/specs/components/Lightbox/Lightbox.spec.md; please rebase ontomainand renumber the media-surface requirement to FR19 wherever the record cites it.
#10284: request changes
- Regression: this pull request edits the same media-surface FR17 verification row and removes #9810's FR17 gap, so it conflicts with
mainthe same way; please rebase it onto #9810 once the row is renumbered.
Whole stack
The stack fails until that rebase, though the code itself merges with main, typechecks and passes the Lightbox, Text and Layer unit tests. A pull request lands only when it and every pull request below it are approved, and after the rebase an engineering owner records the spec approval again by commenting /approve-spec <full head SHA> on each pull request, which the author may do as an engineering owner.
- Non-blocking: FR1b names a single captioned video, but its exceptions, its verification row and the changeset speak only of a single photo, and no test pins the video's caption in the band.
[Automated review]
Main now judges the double-tap zoom's busy proof on the photo's top edge instead of its height, which this branch's last run failed on.
The caption band now carries main's busy-proof fix for the double-tap zoom; this branch changes nothing there.
|
/approve-spec 801fa11 |
There was a problem hiding this comment.
Changes requested. The record text now has an engineering owner's approval at this head, and two blocking findings remain.
- Regression: since this branch was written,
mainmade a labelledButton's size a minimum height, so once merged the caption's "more"/"less" button, whosecaptionTogglestyle setsblockSize: '1lh'(Lightbox.tsx:400-405), grows to 28 px and sits 4 px above the caption's last line on a desktop (2 px on a phone); addingminBlockSize: 0tocaptionTogglekeeps it one line tall. - Regression: #9810 has moved to a new head that this branch does not contain, so the
Stack: #9810 → #10284line no longer holds and this 3,870-line pull request is reviewed alone, without the stack's size exemption; merging #9810's current head, with the toggle fix, into this branch restores the stack.
Non-blocking: FR1b names a single captioned video, but its exceptions, its verification row and the changeset speak only of a single photo, and no test pins the video's band. After the push, an engineering owner records /approve-spec <full head SHA> for the new head; the author may do so as an engineering owner.
[Automated review]
|
/approve-spec 785873b |
There was a problem hiding this comment.
Changes requested on both pull requests in this stack; the record text is approved for each head.
#9810: request changes
- Regression:
main'sButtonnow takes its size as a minimum height, socaptionToggle(Lightbox.tsx:400-405) renders "more"/"less" 28 px tall on a 20 px caption line and 4 px above the caption's last line (2 px on a phone), which fails five of the stack's own browser specs (LightboxViewport×4 andLightboxPaging"…ends the last"); addingminBlockSize: 0tocaptionTogglebrings it back to one line. - Regression:
mainnow includes #8215 (drag a photo down to close), and this branch no longer merges with it:Lightbox.tsxandLightboxEveryPointer.interaction.browser.spec.tsconflict, including #8215's new layer around the controls, which this branch wraps inMediaTheme, and its caption fade, which needs to reach the new band.
#10284: request changes
- Regression: this head also conflicts with #8215 in
Lightbox.tsx, including the stage style it rewrites for a single photo; merge #9810 here once #9810 has takenmain.
#10284 also shows #9810's lifted "more" on a single long caption until it merges that fix. Whole stack: fails; a pull request lands only when it and every pull request below it are approved. Non-blocking: FR1b now covers a single captioned video, but no test pins that case.
[Automated review]
Main's drag to close and this branch both change Lightbox.tsx, and the merge keeps both. The controls sit in the drag's click-through layers inside the media surface, and each takes its own clicks. A page's photo box keeps its row in the band's grid and takes the dismissal's overflow and stacking. The every-pointer spec keeps a new case from each side. Main's new fine-pointer case counts the media surface too.
Main's drag to close fades the controls and the caption with its travel. In a gallery the caption's backing is its band, which stayed opaque over the fading backdrop. The band now fades in the caption's place, once.
The caption's toggle was a ghost Button with a size of its own. It is now Link's button form: a native button in the caption's own font and line height, underlined, at the end of the caption's last line. It keeps aria-expanded and aria-controls, and the shared hit area still grows its tap toward 44 px under a finger. Lightbox's record, docs and changeset say so.
The caption band now carries main's drag to close, and shows "more" and "less" as an inline link. On this branch every item is a page of the track, a single photo too. So the drag to close moves each page's photo box, and the track takes its touches. After a cancelled drag, the stage's own tap beside the photo still closes the viewer. The zoom core drops its fit callback, which only placed the old single caption. Main's cases that read that caption read its band instead.
The caption's "more" and "less" grew their touch target through their own copy of the shared hit area: a watch and a band of their own. They now use Core's touch hit area and its layer, as other controls do, with a growth that never reaches up into the caption's line above. Lightbox's record marks FR19's single-photo gap, and the contrast case adds the black photo its verification row names.
The caption band's "more" and "less" now take their touch target from Core's touch hit area, growing toward 44 px down and to each side but never up. A single photo's caption uses the same toggle, so it gets the fix too. FR19 stays settled here, since this branch closes the single photo's contrast gap the caption band's record lists.
Main now plays the drag to close at the theme's tempo, and Lightbox's record says so in FR5 and its Motion section. The merge keeps main's FR5 row, Motion paragraph and verification row, and this branch's FR1 and FR19 rows. The dismissal spec keeps both sides' new cases.
The caption band now carries main's tempo for the drag to close, and its record's FR5 row and Motion section. Every item here is a page of the track, so a single photo's drag to close plays at that tempo too.
|
/approve-spec 2b0b009 |
There was a problem hiding this comment.
Approved: both pull requests in this stack. The Lightbox record changes carry an engineering owner's approval at each head, and the stack merges cleanly with main.
#9810: approve. No blocking findings. The caption's "more"/"less" is now one caption line tall, and the merge with the drag to close keeps the band fading with it.
#10284: approve. No blocking findings. A single captioned photo now shows its caption exactly as a gallery page does.
Whole stack: passes. A pull request lands only when it and every pull request below it are approved.
Non-blocking: FR1b's single-video half has no test, and FR19's verification row here drops the black photo that #9810's contrast loop now runs (inline note).
[Automated review]
| | FR16 | Touch tests closing by Close, Escape, platform close, and a tap beside the photo with the controls shown; Reduce Motion | With and without `experimental`; controls shown and hidden | A touch close without the exit, a literal timing, input reaching the viewer during the exit, or a tap beside the photo that closes while the controls are hidden fails. | `audit:Lightbox/touch` | | ||
| | FR17 | `Lightbox.test.tsx` index cases | An index below 0 and past the end, controlled and default | An index past either end that opens an empty viewer, or any item but the nearest, fails. | `audit:Lightbox/anatomy` | | ||
| | FR18 | `Lightbox.test.tsx` video paging cases (pause, keep, autoplay) | A playing video paged away from and back to | A neighbouring video that unmounts, keeps playing, or starts again from its beginning fails. | `audit:Lightbox/anatomy` | | ||
| | FR19 | Unit: `Lightbox.test.tsx` media surface cases; browser: `LightboxPaging` and `LightboxZoom` interaction specs, Chromium and WebKit | Gallery with captions, with and without zoom; a single photo's caption; over a white and a mid-grey photo (body 14.7:1 over white) | A viewer outside `MediaTheme`, a Lightbox-set text color, a caption or counter that is not `Text`, a toggle that is not Link's button form, two start edges, or a caption under 4.5:1 fails. | `audit:Lightbox/theming` | |
There was a problem hiding this comment.
Non-blocking: #9810 now runs the contrast case over a black photo too (LightboxZoom.interaction.browser.spec.ts:469), so this row names less than the stack tests. Keeping "over a white, a mid-grey and a black photo" here would match the tests.
Batch: B7 Lightbox
Stack: #9810 → #10284
Stacked on #9810, which adds a gallery's caption band. This head merges #9810's main merge, vjeux@9a9b0f7, where #9810's media-surface requirement became FR19, and FR1b now quotes only the owner's exact words, vjeux@801fa11. It then merges #9810's second main merge, which brings main's fix to the double-tap zoom's busy proof; the caption's backing is unchanged: vjeux@785873b. It then merges #9810's head for this round, which carries main's drag to close and shows "more" and "less" as an inline link: vjeux@c6efc6e. On this branch every item is a page of the track, a single photo too. So the drag to close moves each page's photo box, and the track takes its touches. Main's cases that read the old single caption read its band, and the zoom core drops the fit callback that placed that caption. A single photo's "more" is the same inline link as a gallery's. It then merges two more #9810 commits. One takes the toggle's touch target from Core's touch hit area, and one merges main for the drag to close's tempo: vjeux@2b0b009. FR19 stays settled here, since this branch closes the single photo's contrast gap. This pull request has four commits on #9810's 232f499, the same four as before (each patch unchanged): the earlier single-photo plate, vjeux@d2e76e4, the rework that replaces it with the gallery's band, vjeux@d398515, the notes and records that now cover a single photo, vjeux@50875b6, and FR1b's scope for a single captioned video, vjeux@b565bdc. Review them together: vjeux/astryx@232f499...b565bdc
User impact
A single photo and a set of photos now show their caption the same way. Before, a single photo's caption sat under the photo, centred with it, on a plate as wide as its text. A gallery's caption sits in a band at the bottom of the viewer: two lines tall, with "more" for a longer caption, and no band when no photo has a caption. The two looked like different components. Now a single photo uses the gallery's band, so a caption, its backing and the photo's place are the same whether the viewer holds one photo or many.
The caption keeps 4.5:1 contrast over any page behind the viewer, on the band's backing, as the earlier version of this pull request did with its plate.
Problem and solution fit
The fix renders a single photo through the gallery's own page code. A single photo is the one page of the viewer's track, with the gallery's photo box and caption band. Only paging stays a gallery's.
Expected behavior and authority
component:LightboxFR1b, as the record states it:Named exceptions, in the same row:
FR1b sits beside FR1 as its own row, because FR1's cell has 37 characters of slack and a longer FR1 would re-pad the whole table. The owners can fold it into FR1 if they prefer. Edits to the owners' line, for their re-stamp: a card id a reader can't resolve is dropped, and the citation keeps their "Owner direction" but quotes only Cindy's exact words, "they really should be consistent", with the rest in plain prose. FR19's verification row drops a black photo that no contrast case ran, and FR19 stays
settled: this pull request removes the Current-state gap #9810 names.What changed
Lightbox.tsx: a single photo renders as the one page of the track, with the gallery'spageMediabox (the zoom target) and caption band. The single photo's own wrapper, its plate style, the caption's lift under a fitted photo and the fit callback are removed.isGallerynow gates only the pager, Previous/Next, the counter and the arrow keys. A single photo attaches no pager.Lightbox.doc.mjs: the caption prop says it shows in the band at the bottom of the viewer for every viewer.Lightbox.spec.md: the "Captioned media" state says the caption shows in the band under the active page, for one photo or a gallery, and FR1b's exception names the touch pager.en.json: the "more" and "less" translator notes cover a single photo too.Lightbox.spec.md, in the spec owners' scope: FR1b's first sentence covers a single captioned item, a photo or a video, and the "Captioned media" state says "for one item or a gallery". The code already shows a single video's caption in the band.What stays different, and why: the two exceptions above. Nothing else.
Evidence
Side by side: a single photo beside a gallery's first page, with the same photo and caption, at 390 px and on a desktop, in light and dark. The band, the text, "more" and the photo's box match; only the gallery's counter and Previous/Next differ.
A short caption sits centred in the same band:
iPhone 17 Pro simulator (iOS 26.2, Safari): a single photo, a gallery's first page with the same photo and caption, and the single photo's caption opened by "more":
Zoomed by a pinch, the photo fills its box and the band stays put; with no caption, the photo box fills the viewer:
Red first: the new
LightboxSingleCaptionspec (band shape against a gallery's, "more" and "less", no band with no caption, no paging controls) fails 8/8 on fix(Lightbox): a single photo's caption sits on the caption's backing #10284's previous build in Chromium, and passes at this head in Chromium and WebKit, 24/24 each over three repeats.Gallery unchanged: a pixel diff of every state of "Gallery with captions" (clamped, open, each page) at 1440, 402 and 360 px, LTR and RTL, against the previous build: 30/30 identical in Chromium.
Scope
Writing rubric results
Testing
At 2b0b009, on #9810's d038a4b, core
tscis clean. The Lightbox, motion, Text, Layer and Link unit files pass 1,891/1,891.pnpm check:knowledge,pnpm check:changesets, the motion role table check and CI's Changeset coverage step pass. In a 4-CPU container the Lightbox interaction specs pass 132 in Chromium (4 skips) and 125 in WebKit (11 skips). The Lightbox a11y specs pass 44 of 44 in Chromium and 42 in WebKit (2 skips), the toggle's touch target case included. Against #9810's head, this pull request's own diff changes in two places only. It re-indents #9810's new toggle lines, as it does the rest of that block, and FR19's state stays "settled".At c6efc6e, on #9810's 5c56c40, core
tscis clean and strict ESLint is clean on the changed Lightbox files. The Lightbox, motion, Text, Layer and Link unit files pass 1,890/1,890.pnpm check:knowledge,pnpm check:changesets, the motion role table check and CI's Changeset coverage step pass. In a 4-CPU container the Lightbox interaction specs pass 130 in Chromium (4 skips) and 123 in WebKit (11 skips). The Lightbox a11y specs pass 43 of 43 in Chromium and 41 in WebKit (2 skips). Main's drag to close cases that read the old single caption read its band now. Held sideways, a dragged photo draws above the band. Without the photo box's z-index while dragged, that case fails in both engines: vjeux@37e5124 (not for landing). This head differs from 15ca3b9 only in one comment's line wrapping. The unit files and browser specs above ran at 15ca3b9. The Lightbox unit files pass again here, 159/159. Before and after stills of a single photo and a gallery, phone and desktop, from a sandbox page: https://github.com/vjeux/astryx/tree/000b3c2965f46b456998e6095c8a78ecf6730022/lightbox-caption-link-r8At 785873b: core
tscis clean; the Lightbox, motion, Text and Layer unit files pass 1,740/1,740;pnpm check:knowledgepasses.At 801fa11, on #9810's 18d4bb5: core
tscis clean; the Lightbox, motion, Text and Layer unit files pass 1,740/1,740;pnpm check:knowledgepasses. Before the merge, at b565bdc on #9810's 232f499 and main 88ba279: coretscis clean; the Lightbox, motion, Text and Layer unit files pass 1,730/1,730;pnpm check:knowledgepasses; the Lightbox interaction specs pass 100 in Chromium (3 skips) and 94 in WebKit in a 4-CPU container (9 skips); the Lightbox a11y specs pass 41 of 41 in Chromium.At bd721e6, which merges #9810's e60fcca (the caption band joins the surfaces that read the device's safe-area insets themselves): this pull request's own diff is unchanged (the same patch-id);
layerViewportInset.test.tsand the Text and Lightbox unit files pass 204/204; coretscis clean.At d56431d, which changes only the record's two lines:
pnpm check:knowledgepasses.At fcf9c27, on #9810's dd85656 (main 5c1b7d4): core
tsc0; Text and Lightbox units 198/198;pnpm check:knowledgeandpnpm check:changesetspass. Lightbox a11y specs: 41/41 in Chromium, 39 in WebKit (2 skips). Lightbox interaction specs: 100 in Chromium (3 skips) and 94 in WebKit in a 4-CPU container, the CI profile (9 skips), the new spec among them. The rework's one conflict with #9810's later caption measurement, inLightbox.tsx, keeps both: this pull request's single track, with the band's always-mounted toggle and #8197's settled-page index.At 2b845bc, on a Storybook build of that head (this head replays its two commits on #9810's d036f15 with the same patches, after main's v0.7.10 release):
tsc0; strict ESLint 0 on the changed files; Prettier clean; comment sentence lengths 0 over;pnpm check:knowledgeandpnpm check:changesetspass;usePagerwith them, 270/270;LightboxFinePointer,LightboxViewportandLightboxKeyboard38 passed, 2 skips;On a Storybook build of 74bbab3, which differs from this head only by the zoom core's unused fit callback, a comment, the changeset's wording and FR1b's two edits: the gallery's pixels, every state of "Gallery with captions" (clamped, open, each page) at 1440, 402 and 360 px, LTR and RTL, match #10284's earlier build 1b7ae73, 30/30 identical in Chromium; and the new spec passes 24/24 in Chromium and 24/24 in WebKit (CI profile) over three repeats.