Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/banner-single-line-toggle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@astryxdesign/core': patch
---

[fix] Banner: a title-only collapsible banner now centers its header, as a title-only banner with any other control already does. `isSingleLine` counted `endContent` and the dismiss button but not the collapse toggle, so a banner whose only control was the toggle kept `align-items: flex-start` — leaving its icon and title 4px above the 28px toggle they sit beside, while the same banner with a dismiss button centered correctly.

@freddymeta
40 changes: 40 additions & 0 deletions packages/core/src/Banner/Banner.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -650,4 +650,44 @@ describe('Banner', () => {
expect(getComputedStyle(textColumn).flexBasis).not.toBe('8rem');
});
});
describe('single-line centering', () => {
const headerOf = (ui: React.ReactElement) => {
const {container} = render(ui);
return container.firstElementChild!.firstElementChild!;
};

it('centers a title-only banner that has a dismiss button', () => {
const header = headerOf(
<Banner status="info" title="Deploy finished" isDismissable />,
);
expect(getComputedStyle(header).alignItems).toBe('center');
});

it('centers a title-only banner whose only control is the collapse toggle', () => {
const header = headerOf(
<Banner status="info" title="Deploy finished">
<p>Details</p>
</Banner>,
);
expect(getComputedStyle(header).alignItems).toBe('center');
});

it('keeps a described banner top-aligned, toggle or not', () => {
const header = headerOf(
<Banner status="info" title="Deploy finished" description="Two lines">
<p>Details</p>
</Banner>,
);
expect(getComputedStyle(header).alignItems).toBe('flex-start');
});

it('keeps a banner with no controls at all top-aligned', () => {
const header = headerOf(
<Banner status="info" title="Deploy finished" collapsible={false}>
<p>Details</p>
</Banner>,
);
expect(getComputedStyle(header).alignItems).toBe('flex-start');
});
});
});
7 changes: 5 additions & 2 deletions packages/core/src/Banner/Banner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -534,8 +534,11 @@ export function Banner({
// Show the end area if there are actions, dismiss, or a collapsible toggle
const showEndArea = isRenderable(endContent) || isDismissable || hasToggle;
// Center items vertically when there's only a title (no description)
// and the banner has action buttons
const hasActions = isRenderable(endContent) || isDismissable;
// and the banner has action buttons. The collapse toggle counts: it is the
// same 28px control as a dismiss button and shares the row with it, so a
// collapsible title-only banner is exactly the case this centers — leaving
// it out left the icon and title hanging above the toggle they sit beside.
const hasActions = isRenderable(endContent) || isDismissable || hasToggle;
const isSingleLine = !isRenderable(description) && hasActions;

// Non-collapsible children are always shown; collapsible ones follow the
Expand Down
Loading