[NO-JIRA][BpkLayout] Expand layout component API with opacity, as, dir, and Stack aliases#4505
[NO-JIRA][BpkLayout] Expand layout component API with opacity, as, dir, and Stack aliases#4505Faye (Faye-Xiao) wants to merge 13 commits into
Conversation
Exposes `opacity` (CSS opacity value), `as` (polymorphic element type), and `dir` (text direction for RTL/LTR) as first-class props on all Backpack layout components, unblocking microsite adoption where these props are in active use. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ariants Exposes `alignItems` and `justifyContent` as semantic aliases for the Chakra shorthands `align` and `justify` on BpkStack, BpkHStack, and BpkVStack. When both forms are provided, `align`/`justify` take precedence. Explicit aliases have been in active use in carhire-homepage. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…hen not provided Only spread resolved align/justify into processedProps when they have a value. Previously, passing align: undefined explicitly overrode HStack's built-in align="center" default, breaking the default layout. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…kBox Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
c129a46 to
14f11fa
Compare
|
Visit https://backpack.github.io/storybook-prs/4505 to see this build running in a browser. |
…ack aliases Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Visit https://backpack.github.io/storybook-prs/4505 to see this build running in a browser. |
…document level Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Visit https://backpack.github.io/storybook-prs/4505 to see this build running in a browser. |
There was a problem hiding this comment.
Pull request overview
This PR expands Backpack’s layout component API to formally support previously pass-through Chakra props (as, opacity) and adds semantic aliases (alignItems, justifyContent) for Stack alignment props to ease adoption/migration.
Changes:
- Adds
as?: ElementTypeandopacity?: numbertoBpkCommonLayoutProps. - Adds
alignItems/justifyContentaliases toBpkStack/BpkHStack/BpkVStack, with canonicalalign/justifytaking precedence. - Updates Storybook stories and unit tests to demonstrate and validate the new props/aliases.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/backpack-web/src/bpk-component-layout/src/types.ts | Extends BpkStack prop types with alignItems/justifyContent aliases. |
| packages/backpack-web/src/bpk-component-layout/src/commonProps.ts | Adds as and opacity to common layout props. |
| packages/backpack-web/src/bpk-component-layout/src/BpkStack.tsx | Resolves alias props into canonical Chakra Stack props before processing. |
| packages/backpack-web/src/bpk-component-layout/src/BpkStack.stories.tsx | Adds Storybook example demonstrating Stack alias props. |
| packages/backpack-web/src/bpk-component-layout/src/BpkStack-test.tsx | Adds tests for alias behavior and precedence. |
| packages/backpack-web/src/bpk-component-layout/src/BpkBox.stories.tsx | Adds Storybook examples for opacity and polymorphic as. |
| packages/backpack-web/src/bpk-component-layout/src/BpkBox-test.tsx | Adds tests covering opacity and as rendering. |
Comments suppressed due to low confidence (2)
packages/backpack-web/src/bpk-component-layout/src/BpkStack.tsx:61
- Same ref typing issue as
BpkStack:BpkHStacksupportsasvia common props, soforwardRef<HTMLDivElement, ...>can become incorrect when consumers render e.g.as="nav". Consider widening the ref element type or using polymorphic typing.
export const BpkHStack = forwardRef<HTMLDivElement, BpkStackProps>(({ align, alignItems, backgroundColor, children, color, justify, justifyContent, ...props }, ref) => {
const resolvedAlign = align ?? alignItems;
const resolvedJustify = justify ?? justifyContent;
packages/backpack-web/src/bpk-component-layout/src/BpkStack.tsx:86
- Same ref typing issue as
BpkStack:BpkVStacksupportsasvia common props, soforwardRef<HTMLDivElement, ...>can become incorrect when consumers render a different element. Consider widening the ref element type or using polymorphic typing.
export const BpkVStack = forwardRef<HTMLDivElement, BpkStackProps>(({ align, alignItems, backgroundColor, children, color, justify, justifyContent, ...props }, ref) => {
const resolvedAlign = align ?? alignItems;
const resolvedJustify = justify ?? justifyContent;
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…pacity tests - Widen ref type from HTMLDivElement to HTMLElement on BpkBox, BpkFlex, BpkStack, BpkHStack, BpkVStack — the `as` prop allows rendering any HTML element so HTMLDivElement was too narrow - Replace opacity smoke tests with class-comparison assertions that verify the prop is actually forwarded to Chakra (different opacity values produce different rendered output) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Visit https://backpack.github.io/storybook-prs/4505 to see this build running in a browser. |
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Visit https://backpack.github.io/storybook-prs/4505 to see this build running in a browser. |
|
Visit https://backpack.github.io/storybook-prs/4505 to see this build running in a browser. |
…passing to Chakra forwardRef<HTMLElement> is correct externally (as prop can render any element) but Chakra's Box/Flex/Stack/HStack/VStack ref props expect HTMLDivElement. Cast internally to satisfy Chakra's types without narrowing the public API. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
| alignItems?: BpkStackOptions['align']; | ||
| /** Alias for `justify`. Maps to CSS `justify-content`. */ | ||
| justifyContent?: BpkStackOptions['justify']; | ||
| } |
There was a problem hiding this comment.
Chakra uses the align and justify for the alignItems and justifyContent. We support both for the development-friendly
| opacity?: number; | ||
|
|
||
| // Text direction — for embedding bidirectional content within a page | ||
| dir?: 'ltr' | 'rtl' | 'auto'; |
|
Visit https://backpack.github.io/storybook-prs/4505 to see this build running in a browser. |
…gical props marginInline/paddingInline (horizontal) were already supported; marginBlock/ paddingBlock (vertical) were missing. Adding them completes the logical properties set and provides a RTL-safe alternative to marginTop+marginBottom. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Visit https://backpack.github.io/storybook-prs/4505 to see this build running in a browser. |
|
Visit https://backpack.github.io/storybook-prs/4505 to see this build running in a browser. |
HTMLElement caused a breaking change for consumers using useRef<HTMLDivElement>(). HTMLDivElement is the correct default (components render a div by default), matching Chakra's own typing for Box/Stack/Flex. Also removes the now-unnecessary Ref<HTMLDivElement> casts introduced to work around the mismatch. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Visit https://backpack.github.io/storybook-prs/4505 to see this build running in a browser. |


Summary
During Backpack adoption in [carhire-homepage], an audit of layout component usage revealed props that were silently passing through Chakra but were not formally declared in the Backpack layout API. This PR adds official support for those props.
Changes
BpkCommonLayoutProps(all layout components):opacity?: number— CSS opacity value (0–1), used for fade/disabled effectsas?: ElementType— polymorphic rendering, allows changing the underlying HTML element (e.g.as="section",as="nav")dir?: 'ltr' | 'rtl' | 'auto'— text direction, for embedding bidirectional content within an LTR pageBpkStack/BpkHStack/BpkVStack:alignItems— semantic alias foralign(maps to CSSalign-items)justifyContent— semantic alias forjustify(maps to CSSjustify-content)align/justify) takes precedenceforwardReftype:HTMLDivElementtoHTMLElementon BpkBox, BpkFlex, BpkStack, BpkHStack, and BpkVStack — necessary now that theasprop allows rendering any HTML elementMotivation
Consumer feedback from carhire-homepage:
alignItems/justifyContentare more semantically clear thanalign/justify(which can be confused with text-align). Supporting both forms reduces friction for teams migrating to Backpack layout primitives.README.md(If you have created a new component)README.md