Skip to content

feat(core): add elevation prop to configurable surfaces#4251

Open
kentonquatman wants to merge 1 commit into
mainfrom
feat/elevation-prop
Open

feat(core): add elevation prop to configurable surfaces#4251
kentonquatman wants to merge 1 commit into
mainfrom
feat/elevation-prop

Conversation

@kentonquatman

Copy link
Copy Markdown
Contributor

Summary

Implements the Elevation prop (configurable surfaces) table from the elevation system proposal (#4146). Adds a single elevation prop to every configurable surface, narrowed per component to the steps it needs.

Component Supported values Default
Card 'none' | 'low' | 'med' | 'high' 'none'
ClickableCard 'none' | 'low' | 'med' | 'high' 'none'
SelectableCard 'none' | 'low' | 'med' | 'high' 'none'
ChatComposer 'none' | 'low' 'low'
Button 'none' | 'low' | 'med' | 'high' 'none'
IconButton 'none' | 'low' | 'med' | 'high' 'none'
Thumbnail 'none' | 'low' | 'med' | 'high' 'none'
ButtonGroup 'none' | 'low' | 'med' | 'high' 'none'
Banner 'none' | 'low' | 'med' | 'high' 'none'

Levels map to the existing --shadow-low/-med/-high tokens; none is the flat box-shadow: none literal. No new tokens.

No breaking changes

Every prop defaults to today's behavior, so nothing changes unless a consumer opts in:

  • Every surface is flat at rest today → defaults to 'none'.
  • ChatComposer is raised today → defaults to 'low' (low at rest, bumping to med on hover / focus, exactly as before). Set elevation="none" to flatten it.
  • Thumbnail keeps its existing hover-only shadow at the 'none' default.

Composition, not clobbering

box-shadow is a single CSS property, so a few surfaces needed care so elevation coexists with an existing shadow rather than overwriting it:

  • Card reads two private shadow slots (--_card-ring, --_card-elevation). SelectableCard now drives its inset selection ring through --_card-ring, so a selected card keeps its resting elevation.
  • Thumbnail routes resting elevation through --_thumbnail-elevation, which the existing :hover → med bump reads, so a raised tile still bumps on hover.
  • Button elevation is skipped inside a ButtonGroup — the group owns the shared surface's shadow (and rounds its wrapper so the shadow follows the connected silhouette).
  • IconButton inherits elevation for free by composing Button; ClickableCard/SelectableCard forward it to Card.

Intrinsic overlays (Dialog, Popover, Tooltip, Toast, HoverCard, DropdownMenu, …) are unchanged — they bake elevation in and expose no prop.

What's included

  • elevation prop on all 9 configurable-surface components, with a shared Elevation type in utils/types.
  • Updated component docs (.doc.mjs — English, 中文, and dense variants) so astryx component <Name> reflects the new prop.
  • Updated the elevation foundation doc to describe the prop layer alongside the token layer.
  • Storybook: elevation controls on each component's stories plus dedicated stories (Card Elevations, Button Elevations, Banner Floating, ChatComposer Flat).
  • Colocated tests for each component (distinct class per level, defaults preserved, and a SelectableCard test proving the ring composes with elevation).
  • Changeset (patch).

Interaction-driven elevation (drag/reorder lift) is intentionally out of scope per the proposal's appendix.

Checks

build, test (154 passing across the touched files), lint / check:repo, core + docs + template-docs + storybook typechecks, sync-exports --check, and check:changesets all pass locally.

Implements the first-PR scope of #4146 (the elevation prop + foundation doc). The proposal's lint/review guard for raw box-shadow is a separate follow-up.

Add an `elevation` prop to the configurable surfaces from the elevation
system proposal (#4146). Card, ClickableCard, SelectableCard, Button,
IconButton, ButtonGroup, Thumbnail, and Banner take the full
`'none' | 'low' | 'med' | 'high'` scale; ChatComposer takes the narrowed
`'none' | 'low'`.

Levels map to the existing `--shadow-low/-med/-high` tokens; `none` is a
flat literal. Defaults preserve today's appearance — `none` everywhere
except ChatComposer, which defaults to `low` to keep its raised look.

Composition is preserved rather than clobbered: Card routes elevation and
SelectableCard's inset selection ring through separate box-shadow slots so
a selected card keeps its shadow, and Thumbnail's resting elevation coexists
with its hover-shadow bump. Button elevation is skipped inside a ButtonGroup,
where the group owns the shared surface's shadow.

Also documents the elevation prop layer in the elevation foundation doc.
@vercel

vercel Bot commented Jul 23, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
astryx Ready Ready Preview, Comment Jul 23, 2026 7:44am

Request Review

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Meta Open Source bot. label Jul 23, 2026
@github-actions github-actions Bot added the needs:code-review High-risk change (new package/component/API) — needs human code review before merge label Jul 23, 2026
github-actions Bot added a commit that referenced this pull request Jul 23, 2026
@github-actions

Copy link
Copy Markdown
Contributor

PR Analysis Report

📚 Storybook Preview

View Storybook for this PR
GitHub Pages may take up to a minute to hydrate after deploy.

🧪 Sandbox Preview

View Sandbox for this PR
GitHub Pages may take up to a minute to hydrate after deploy.

Modified Components

Banner · View in Storybook
Metric Before After Delta
Bundle Size (ESM) N/A N/A N/A
Lines of Code N/A 344 -
Complexity N/A High (24) -
Button · View in Storybook
Metric Before After Delta
Bundle Size (ESM) N/A N/A N/A
Lines of Code N/A 563 -
Complexity N/A Very High (62) -
ButtonGroup · View in Storybook
Metric Before After Delta
Bundle Size (ESM) N/A N/A N/A
Lines of Code N/A 121 -
Complexity N/A Low (3) -
Card · View in Storybook
Metric Before After Delta
Bundle Size (ESM) N/A N/A N/A
Lines of Code N/A 203 -
Complexity N/A High (18) -
Chat · View in Storybook
Metric Before After Delta
Bundle Size (ESM) N/A N/A N/A
Lines of Code N/A 5239 -
Complexity N/A Very High (425) -
ClickableCard · View in Storybook
Metric Before After Delta
Bundle Size (ESM) N/A N/A N/A
Lines of Code N/A 200 -
Complexity N/A Medium (13) -
IconButton · View in Storybook
Metric Before After Delta
Bundle Size (ESM) N/A N/A N/A
Lines of Code N/A 17 -
Complexity N/A Low (1) -
SelectableCard · View in Storybook
Metric Before After Delta
Bundle Size (ESM) N/A N/A N/A
Lines of Code N/A 252 -
Complexity N/A High (25) -
Thumbnail · View in Storybook
Metric Before After Delta
Bundle Size (ESM) N/A N/A N/A
Lines of Code N/A 260 -
Complexity N/A High (25) -

Bundle Size Summary

Package Size (ESM) Size (CJS) Gzipped
@astryxdesign/core N/A 4.7KB 0B

Accessibility Audit

Status: 6 accessibility violation(s) found — 6 serious.

Banner - 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/16 stories · Learn more
    • WCAG: 1.4.3 (Level AA)
Card - 1 issue(s)
  • 🟠 serious: Ensure the contrast between foreground and background colors meets WCAG 2 AA minimum contrast ratio thresholds
    • Rule: color-contrast · Affects 8/14 stories · Learn more
    • WCAG: 1.4.3 (Level AA)
Chat - 1 issue(s)
  • 🟠 serious: Ensure the contrast between foreground and background colors meets WCAG 2 AA minimum contrast ratio thresholds
    • Rule: color-contrast · Affects 2/8 stories · Learn more
    • WCAG: 1.4.3 (Level AA)
ClickableCard - 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/5 stories · Learn more
    • WCAG: 1.4.3 (Level AA)
SelectableCard - 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/4 stories · Learn more
    • WCAG: 1.4.3 (Level AA)
Thumbnail - 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/11 stories · Learn more
    • WCAG: 1.4.3 (Level AA)

Generated by PR Enrichment workflow | Storybook | Sandbox | View full report

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. needs:code-review High-risk change (new package/component/API) — needs human code review before merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant