fix: align banner and toast icons - #726
Conversation
commit: |
Docs PreviewCommit: |
|
/bonk review and approve this approach |
There was a problem hiding this comment.
The approach is clean and consistent across both Banner and Toast. Using a line-height-sized flex container with is a modern, minimal way to keep icons aligned to the first line without shrinking when text wraps. Tests cover the new behavior, and the docs preview is a nice addition.
There was a problem hiding this comment.
The approach is clean and consistent across both Banner and Toast. Using a line-height-sized flex container with flex-none is a modern, minimal way to keep icons aligned to the first line without shrinking when text wraps. Tests cover the new behavior, and the docs preview is a nice addition.
|
✅ Approved PR #726 with the following comment:
Summary of the review:
|
| it("aligns icons to the first text line without shrinking", () => { | ||
| render( | ||
| <Banner | ||
| size="sm" | ||
| icon={<svg data-testid="icon" className="custom-icon" />} | ||
| description="A DNS record already exists in this zone and may wrap onto multiple lines." | ||
| />, | ||
| ); | ||
|
|
||
| const icon = screen.getByTestId("icon"); | ||
| const iconClassName = icon.getAttribute("class") ?? ""; | ||
| expect(iconClassName).toContain("size-[1em]"); | ||
| expect(iconClassName).toContain("flex-none"); | ||
| expect(iconClassName).toContain("custom-icon"); | ||
| expect(icon.parentElement?.className).toContain("h-[1lh]"); | ||
| expect(icon.parentElement?.className).toContain("flex-none"); |
There was a problem hiding this comment.
nit: we shouldn't test on the existence of class names, it's brittle
There was a problem hiding this comment.
truth! I will fix this
| ? cloneElement(iconElement, { | ||
| className: cn( | ||
| iconElement.props.className, | ||
| "size-[1em] flex-none leading-snug", |
There was a problem hiding this comment.
I checked downstream Stratus usage and this does have compatibility impact: there are at least 123 Banner usages across 90 files that pass explicit numeric icon sizes, including many 18px, 20px, and 24px icons. Appending size-[1em] overrides those sizes for Phosphor icons (for example, a requested 20px icon becomes the Banner’s inherited 1em size), while custom icon components that do not forward className may retain their original size, so the normalization is inconsistent across the current ReactNode contract.
Is taking ownership of all Banner icon sizing intentional here? If the goal is only alignment/non-shrinking, the outer h-[1lh] flex-none items-center wrapper appears sufficient without cloning or rewriting the supplied node. If normalization is intentional, I think it should be called out as an API/visual behavior change because Stratus currently relies heavily on explicit icon sizing.
There was a problem hiding this comment.
Intentional. Custom sizes downstream is a defect (in my opinion), but point heard about the impact.













































Summary
Tests
Notes
Full docs lint currently fails on unrelated existing issues in TabsDemo.tsx, ToolbarDemo.tsx, and ChartCard.astro.