Skip to content
Merged
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
5 changes: 5 additions & 0 deletions .changeset/flush-banner.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@primer/react": minor
---

Banner: Add `flush` prop for use within confined spaces, such as dialogs, tables, cards, or boxes where available space is limited.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions e2e/components/Banner.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ const stories: Array<{title: string; id: string; viewports?: Array<keyof typeof
title: 'ActionsStacked',
id: 'components-banner-features--actions-layout-stacked',
},
{
title: 'FlushInsideDialog',
id: 'components-banner-features--flush-inside-dialog',
},
]

test.describe('Banner', () => {
Expand Down
8 changes: 7 additions & 1 deletion packages/react/src/Banner/Banner.docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,12 @@
"name": "actionsLayout",
"type": "'default' | 'inline' | 'stacked'",
"description": "Override the responsive layout of the action buttons. 'inline' layout will display the buttons inline with the title and description, while 'stacked' layout will always render the buttons in a new row."
},
{
"name": "flush",
"type": "boolean",
"defaultValue": "false",
"description": "Full width banner specifically for use within confined spaces, such as dialogs, tables, cards, or boxes where available space is limited."
Copy link
Member

Choose a reason for hiding this comment

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

(you might be onto this already) Should we also plan to add some guidance around when flush is acceptable to our docs? 👀

Copy link
Member Author

Choose a reason for hiding this comment

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

yep! Lukas has a PR open

}
],
"subcomponents": [
Expand Down Expand Up @@ -157,4 +163,4 @@
}
}
]
}
}
17 changes: 13 additions & 4 deletions packages/react/src/Banner/Banner.features.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -262,19 +262,28 @@ export const CustomIcon = () => {
)
}

export const InsideDialog = () => {
export const FlushInsideDialog = () => {
const onDialogClose = React.useCallback(() => {}, [])

return (
<Dialog title="Add issue fields" onClose={onDialogClose} width="small">
<Dialog
title="Add issue fields"
onClose={onDialogClose}
height="small"
renderBody={({children}) => {
// custom renderBody to remove default padding from body and move it to the child after banner
return <div style={{padding: 0}}>{children}</div>
}}
>
<Banner
title="Something went wrong adding fields."
hideTitle
title="Something went wrong loading custom fields."
description="Please try again."
variant="critical"
actionsLayout="inline"
primaryAction={<Banner.PrimaryAction onClick={action('Try again')}>Try again</Banner.PrimaryAction>}
flush
/>
<div style={{padding: 'var(--base-size-16)'}}>rest of the dialog content goes here</div>
</Dialog>
)
}
Expand Down
6 changes: 6 additions & 0 deletions packages/react/src/Banner/Banner.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@
padding: var(--base-size-4);
}

&[data-flush] {
border-left: none;
border-right: none;
border-radius: 0;
}

&[data-variant='critical'] {
--banner-bgColor: var(--bgColor-danger-muted);
--banner-borderColor: var(--borderColor-danger-muted);
Expand Down
10 changes: 10 additions & 0 deletions packages/react/src/Banner/Banner.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,16 @@ describe('Banner', () => {
expect(container.firstChild).toHaveAttribute('data-actions-layout', 'default')
})

it('should render data-flush attribute when flush is true', () => {
const {container} = render(<Banner title="test" flush />)
expect(container.firstChild).toHaveAttribute('data-flush')
})

it('should not render data-flush attribute when flush is false', () => {
const {container} = render(<Banner title="test" />)
expect(container.firstChild).not.toHaveAttribute('data-flush')
})

describe('Banner.Title', () => {
it('should render as a h2 element by default', () => {
render(
Expand Down
7 changes: 7 additions & 0 deletions packages/react/src/Banner/Banner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,11 @@ export type BannerProps = React.ComponentPropsWithoutRef<'section'> & {
* Override the default actions layout behavior
*/
actionsLayout?: 'inline' | 'stacked' | 'default'

/**
* Full width banner specifically for use within confined spaces, such as dialogs, tables, cards, or boxes where available space is limited.
*/
flush?: boolean
}

const iconForVariant: Record<BannerVariant, React.ReactNode> = {
Expand Down Expand Up @@ -114,6 +119,7 @@ export const Banner = React.forwardRef<HTMLElement, BannerProps>(function Banner
title,
variant = 'info',
actionsLayout = 'default',
flush = false,
...rest
},
forwardRef,
Expand Down Expand Up @@ -161,6 +167,7 @@ export const Banner = React.forwardRef<HTMLElement, BannerProps>(function Banner
tabIndex={-1}
ref={ref}
data-layout={rest.layout || 'default'}
data-flush={flush ? '' : undefined}
>
<div className={classes.BannerIcon}>{visual && supportsCustomIcon ? visual : iconForVariant[variant]}</div>
<div className={classes.BannerContainer}>
Expand Down
Loading