Skip to content

feat(lab): DialogHeroHeader - #10108

Draft
cixzhang wants to merge 3 commits into
mainfrom
carry/dialog-hero-header
Draft

cixzhang wants to merge 3 commits into
mainfrom
carry/dialog-hero-header

Conversation

@cixzhang

@cixzhang cixzhang commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

Part 2 of 3 of the carry that supersedes #5105 (jiunshinn's DialogHeroHeader). It stacks on #10105 (the Core carry: Dialog initial-focus order and the internal dialog-context entry). It carries jiunshinn's Lab component, tests, doc and story on a team branch so it can get CI, with a Co-authored-by trailer. Part 3 adds the Lab showcase and the CLI package-index entries.

User impact

A builder of a Lab experience can open a Dialog with a hero header: media above a title. The header names the dialog and takes initial focus on its title the way DialogHeader does. An explicit data-autofocus request in the dialog still wins (component:Dialog FR2, from #10105).

What is in this PR

  • packages/lab/src/DialogHeroHeader/: the component, its index, DialogHeroHeader.doc.mjs, and 34 tests.
  • packages/lab/src/index.ts: exports DialogHeroHeader, DialogHeroHeaderProps and DialogHeroHeaderMediaMode.
  • apps/storybook/stories/DialogHeroHeader.stories.tsx, with the story-play-guard.js entries its play stories need.
  • internal/shadcn-registry/routes.lock.json: the component route.
  • The content is jiunshinn's as of feat(lab): DialogHeroHeader #5105's head f97e24a, including the handshake fix: the rendered heading drives the handshake, so a re-render keeps focus and a late heading still names the dialog.

Authority

Lab under the design owner's Lab grant. The Core parts it reads are in #10105.

Testing

  • vitest run packages/lab/src/DialogHeroHeader: 34 pass.
  • eslint on the changed files is clean.
  • Size: 8 files, +1,878.

@vercel

vercel Bot commented Nov 5, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
astryx Ready Ready Preview Nov 6, 2026 5:19am UTC

Request Review

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Meta Open Source bot. label Nov 5, 2026
@astracat-bot

astracat-bot Bot commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

AI review status for this pull request.

Review status Updated
🟢 Reviewed (for maintainers only) Nov 6, 2026, 5:26 AM UTC

@cixzhang

cixzhang commented Nov 5, 2026

Copy link
Copy Markdown
Contributor Author

/approve-spec 9a05f56

@astracat-bot astracat-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approval waits on an engineering-owner decision and two fixes.

No current spec governs DialogHeroHeader, and because this pull request also changes the story, the story-play guard and the route lock, the Lab exemption does not cover it. An engineering owner needs to accept these behaviors for Lab, or identify the spec that governs them: the title names the Dialog and takes its default initial focus, the media bleeds to the dialog's edges, and the close button sits over the media with mediaMode. They record that by commenting /approve-spec with the full head commit SHA, which the author may do as an engineering owner.

  • apps/storybook/stories/DialogHeroHeader.stories.tsx:32 imports packages/lab/blocks/DialogHeroHeaderShowcase, which this pull request does not add, so none of the 10 stories load (both new story-play guard targets included): move the Showcase story to the pull request that adds the block, or add the block here.
  • packages/cli/assets/discover/official-packages.json is stale because the new doc adds a DialogHeroHeader discover item, so scripts/check-cli-official-packages.test.mjs now fails: run pnpm bundle:cli-official-packages and commit the result, or move the doc together with that entry.

[Automated review]

import {Heading} from '@astryxdesign/core/Heading';
import {Icon} from '@astryxdesign/core/Icon';
import {Text} from '@astryxdesign/core/Text';
import DialogHeroHeaderShowcase from '../../../packages/lab/blocks/DialogHeroHeaderShowcase';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

packages/lab/blocks/DialogHeroHeaderShowcase is not in this pull request, so this import fails and the whole story file does not load: every story shows "Failed to fetch dynamically imported module", including the two story-play guard targets. Move the Showcase story and this import to the pull request that adds the block, or add the block here.

/** @type {import('@astryxdesign/cli/authoring').ComponentDoc} */

export const docs = {
name: 'DialogHeroHeader',

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doc adds a DialogHeroHeader discover item, so packages/cli/assets/discover/official-packages.json needs a matching {"kind": "component", "name": "DialogHeroHeader"} entry. scripts/check-cli-official-packages.test.mjs fails until you run pnpm bundle:cli-official-packages and commit the result.

Comment on lines +5 to +46
/**
* @file DialogHeroHeader.tsx
* @input Uses React, StyleX, theme tokens, LayoutHeader, Button, Icon,
* Heading, MediaTheme, VisuallyHidden, useDialogContext, useTranslator
* @output Exports DialogHeroHeader component, DialogHeroHeaderProps, and
* DialogHeroHeaderMediaMode
* @position Lab implementation; consumed by index.ts, tested by
* DialogHeroHeader.test.tsx, demonstrated in Storybook
*
* Hero-style header for Dialog. The high-emphasis sibling of DialogHeader: a
* full-bleed media slot sits above the title, and the close button overlays
* the media's top-trailing corner.
*
* The media bleeds to the dialog's edges by cancelling the surrounding
* LayoutHeader padding with negative margins driven by the
* `--container-padding-*` custom properties (the same container-compensation
* contract Section uses), so it tracks theme and per-dialog padding
* automatically. Corner rounding comes free from the Dialog inner wrapper's
* `overflow: hidden` + inherited radius.
*
* Content overlaid on the media (the close button) can't rely on ambient
* theme tokens for contrast; `mediaMode` describes the media's luminance and
* composes MediaTheme under the hood so the overlay picks up inverted tokens
* (including its focus ring) when the media is dark.
*
* The title alone carries Dialog's title id. A visible title declares default
* focus intent; Dialog applies it after opening, with explicit descendant
* focus requests taking priority. Hidden, inline, and standalone headers do
* not request focus. A caller-provided heading receives the same handshake on
* its own rendered element (never on a wrapper, so the focus target keeps its
* heading role); attributes the caller already set are left untouched. The
* handshake follows the rendered heading node, so a re-render keeps focus on
* it, and a heading that renders later or is replaced still names the dialog.
* MediaTheme stays mounted across media-mode changes so the close button
* retains DOM identity and keyboard focus.
*
* SYNC: When modified, update these files to stay in sync:
* - /packages/lab/src/DialogHeroHeader/DialogHeroHeader.doc.mjs (props, usage)
* - /packages/lab/src/DialogHeroHeader/DialogHeroHeader.test.tsx (behavior)
* - /packages/lab/src/DialogHeroHeader/index.ts (exports if types change)
* - /apps/storybook/stories/DialogHeroHeader.stories.tsx (examples)
*/

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-blocking: this header is 42 lines, and its prose repeats the component JSDoc below. The repository's comment rule keeps a header to about 12 lines of @file/@input/@output/@position/SYNC:. Suggest dropping the prose paragraphs.

@astracat-bot astracat-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The earlier Showcase-import and official-list blockers are fixed; approval now waits on an engineering-owner decision at this head and two fixes.

No current spec governs DialogHeroHeader, and because this pull request also changes the story, the story-play guard, the route lock and the CLI official-packages list, the Lab exemption does not cover it. An engineering owner needs to accept these behaviors for Lab, or identify the spec that governs them: the title names the Dialog and is its default initial-focus target, the media bleeds to the dialog's inline and block-start edges, and the close button sits over the media with mediaMode colours. They record that by commenting /approve-spec <full head SHA> for the current head, which the author may do as an engineering owner; the earlier /approve-spec names the previous head, and the new commit supersedes it.

  • Miss: the description's User impact says the header puts "media above a title and description", but DialogHeroHeader has no description or subtitle slot, so please say "media above a title" in the description and the commit message.
  • packages/cli/assets/discover/official-packages.json now adds DialogHeroHeader to the list the published @astryxdesign/cli ships, so please add a '@astryxdesign/cli': patch [feat] Changeset here, as #9723 did for CircleCheckIndicator, and drop the matching entry and Changeset from #10109.

[Automated review]

Comment on lines +131 to +134
{
"kind": "component",
"name": "DialogHeroHeader"
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This entry ships in the published @astryxdesign/cli (its files include assets), so astryx discover on a canary CLI now lists DialogHeroHeader. Lab is private, but the CLI is not, so this needs a Changeset, as #9723 added for CircleCheckIndicator:

---
'@astryxdesign/cli': patch
---

[feat] `astryx discover` lists the experimental DialogHeroHeader component from `@astryxdesign/lab`.

#10109 adds the same entry and Changeset, so drop them there.

@cixzhang
cixzhang force-pushed the carry/dialog-hero-header branch from 71eff45 to 786ed9e Compare November 6, 2026 05:02
@cixzhang
cixzhang changed the base branch from carry/dialog-autofocus-fallthrough to main November 6, 2026 05:02
@cixzhang

cixzhang commented Nov 6, 2026

Copy link
Copy Markdown
Contributor Author

/approve-spec 786ed9e

cixzhang and others added 3 commits November 5, 2026 21:11
A hero-style Dialog header for Lab: media above a title,
composed inside an Astryx Dialog, naming the dialog and requesting title
focus through the internal Dialog context. Carries jiunshinn's component,
tests, doc and story from #5105, as of its handshake fix (the rendered
heading drives the handshake, so a re-render keeps focus and a late
heading still names the dialog).

Co-authored-by: jiunshinn <jiun.dev@gmail.com>
@cixzhang
cixzhang force-pushed the carry/dialog-hero-header branch from 786ed9e to 25a3e5d Compare November 6, 2026 05:12
cixzhang added a commit that referenced this pull request Nov 6, 2026
@cixzhang

cixzhang commented Nov 6, 2026

Copy link
Copy Markdown
Contributor Author

/approve-spec 25a3e5d

@github-actions

github-actions Bot commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

PR Analysis Report

Current run: The current CI run concluded skipped. Current analysis is unavailable.


Generated by PR Enrichment workflow | View current CI run

@astracat-bot astracat-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved pending CI: CI has not run on this head yet. The pull request is a draft, and CI runs once it is marked ready for review.

An engineering owner's /approve-spec for this head settles the behaviors no spec records for this Lab component: the title names the dialog and takes default focus, the media bleeds to the dialog's edges, and the close button sits over the media with mediaMode colours. The earlier findings are fixed: the description now says "media above a title", and the CLI discover entry has its @astryxdesign/cli patch Changeset.

Optional, non-blocking: trim the 42-line header in DialogHeroHeader.tsx to its @file, @input, @output, @position and SYNC: lines, and update the description's file list and size (10 files, +1,882).

[Automated review]

This branch was successfully deployed

1 active deployment
Preview — 25a3e5d4 Deployed Nov 6, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Meta Open Source bot.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant