-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(AppNotification)!: introduce 2.0 component
- add component with specified design and code API - add in tests and stories - support button alignment in ButtonGroup via new internal value
- Loading branch information
1 parent
2f25f6b
commit b584896
Showing
12 changed files
with
540 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
/*------------------------------------*\ | ||
# APP NOTIFICATION | ||
\*------------------------------------*/ | ||
|
||
/** | ||
* AppNotification | ||
*/ | ||
.app-notification { | ||
padding: 1.5rem; | ||
|
||
&.app-notification--color-dark { | ||
color: var(--eds-theme-color-text-utility-inverse); | ||
background-color: var(--eds-theme-color-background-utility-default-high-emphasis); | ||
} | ||
|
||
&.app-notification--color-light { | ||
color: var(--eds-theme-color-text-utility-default-primary-active); | ||
background-color: var(--eds-theme-color-background-utility-container); | ||
} | ||
|
||
@media (min-width: $eds-bp-sm) { | ||
padding-left: calc(var(--eds-size-6) * 1px); | ||
padding-right: calc(var(--eds-size-6) * 1px); | ||
} | ||
|
||
@media (min-width: $eds-bp-xl) { | ||
.app-notification__content { | ||
margin: 0 auto; | ||
} | ||
} | ||
} | ||
|
||
.app-notification__title { | ||
margin-bottom: 0.5rem; | ||
} | ||
|
||
/* .app-notification__sub-title { | ||
} */ | ||
|
||
.app-notification__actions { | ||
margin-top: 1.5rem; | ||
} | ||
|
||
.app-notification__content { | ||
/* TODO-AH: how to define this magic number */ | ||
max-width: 1320px; | ||
display: flex; | ||
gap: 0.5rem; | ||
} | ||
|
||
.app-notification__close-btn { | ||
flex-shrink: 0; | ||
margin-top: -0.5rem; | ||
margin-right: -0.5rem; | ||
} |
81 changes: 81 additions & 0 deletions
81
src/components/AppNotification/AppNotification.stories.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
import { BADGE } from '@geometricpanda/storybook-addon-badges'; | ||
import type { StoryObj, Meta } from '@storybook/react'; | ||
|
||
import React from 'react'; | ||
|
||
import { AppNotification } from './AppNotification'; | ||
import { ButtonV2 as Button } from '../Button'; | ||
import { ButtonGroupV2 as ButtonGroup } from '../ButtonGroup'; | ||
|
||
export default { | ||
title: 'Components/V2/AppNotification', | ||
component: AppNotification, | ||
parameters: { | ||
badges: [BADGE.BETA, 'intro-2.0', 'current-2.0'], | ||
}, | ||
args: { | ||
title: 'This is an AppNotification title', | ||
subTitle: | ||
'Lorem ipsum dolor sit amet consectetur. At et vitae quis amet felis mollis in vitae. Eget in neque et molestie. Luctus sed id commodo volutpat. In a eu in id molestie consectetur pellentesque.', | ||
}, | ||
argTypes: { | ||
children: { | ||
control: { | ||
type: null, | ||
}, | ||
}, | ||
}, | ||
} as Meta<Args>; | ||
|
||
type Args = React.ComponentProps<typeof AppNotification>; | ||
|
||
export const Default: StoryObj<Args> = { | ||
args: {}, | ||
}; | ||
|
||
export const WithControls: StoryObj<Args> = { | ||
args: { | ||
children: ( | ||
<ButtonGroup buttonLayout="horizontal" className="!flex-row"> | ||
<Button rank="secondary" variant="inverse"> | ||
Call To Action | ||
</Button> | ||
<Button rank="tertiary" variant="inverse"> | ||
Other action | ||
</Button> | ||
</ButtonGroup> | ||
), | ||
}, | ||
}; | ||
|
||
export const LightColor: StoryObj<Args> = { | ||
args: { | ||
color: 'light', | ||
children: ( | ||
<ButtonGroup buttonLayout="horizontal-align-left"> | ||
<Button rank="secondary">Call To Action</Button> | ||
<Button rank="tertiary">Other action</Button> | ||
</ButtonGroup> | ||
), | ||
}, | ||
}; | ||
|
||
export const WithDismissAndControls: StoryObj<Args> = { | ||
args: { | ||
...WithControls.args, | ||
onDismiss: () => { | ||
console.log('dismissing!'); | ||
}, | ||
}, | ||
}; | ||
|
||
export const LightWithDismissAndControls: StoryObj<Args> = { | ||
args: { | ||
...LightColor.args, | ||
onDismiss: () => { | ||
console.log('dismissing!'); | ||
}, | ||
}, | ||
}; | ||
|
||
// TODO-AH: add in responsive tests for each breakpoint to cover layout and spacing |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import { generateSnapshots } from '@chanzuckerberg/story-utils'; | ||
import type { StoryFile } from '@storybook/testing-react'; | ||
|
||
import * as stories from './AppNotification.stories'; | ||
|
||
describe('<AppNotification />', () => { | ||
generateSnapshots(stories as StoryFile); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
import clsx from 'clsx'; | ||
import React from 'react'; | ||
import { ButtonV2 as Button } from '../Button'; | ||
import Text from '../Text'; | ||
import styles from './AppNotification.module.css'; | ||
|
||
export interface Props { | ||
// Design API | ||
/** | ||
* The title/heading of the notification | ||
*/ | ||
title: string; | ||
/** | ||
* Secondary text used to describe the notification in more detail | ||
*/ | ||
subTitle: React.ReactNode; | ||
/** | ||
* Treatment for component (whether it is dark on light text, or light on dark text) | ||
*/ | ||
color: 'dark' | 'light'; | ||
|
||
// Component API | ||
/** | ||
* Contents of the component below the title and sub-title (used mainly for `ButtonGroup`) | ||
*/ | ||
children?: React.ReactNode; | ||
/** | ||
* CSS class names that can be appended to the component. | ||
*/ | ||
className?: string; | ||
/** | ||
* Callback when banner is dismissed. When passed in, renders banner with a close icon in the top right. | ||
*/ | ||
onDismiss?: () => void; | ||
} | ||
|
||
/** | ||
* `import {AppNotification} from "@chanzuckerberg/eds";` | ||
* | ||
* An alert placed at the top of an application which persists across pages. | ||
*/ | ||
export const AppNotification = ({ | ||
className, | ||
children, | ||
color = 'dark', | ||
onDismiss, | ||
subTitle, | ||
title, | ||
...other | ||
}: Props) => { | ||
const componentClassName = clsx( | ||
styles['app-notification'], | ||
color && styles[`app-notification--color-${color}`], | ||
className, | ||
); | ||
|
||
return ( | ||
<div className={componentClassName} role="status" {...other}> | ||
<div className={styles['app-notification__content']}> | ||
<section> | ||
<Text | ||
as="div" | ||
className={styles['app-notification__title']} | ||
preset="headline-sm-bold" | ||
> | ||
{title} | ||
</Text> | ||
<Text | ||
as="p" | ||
className={styles['app-notification__sub-title']} | ||
preset="body-md" | ||
> | ||
{subTitle} | ||
</Text> | ||
<div className={styles['app-notification__actions']}>{children}</div> | ||
</section> | ||
{onDismiss && ( | ||
<Button | ||
aria-label="close" | ||
className={styles['app-notification__close-btn']} | ||
context="default" | ||
icon="close" | ||
iconLayout="icon-only" | ||
onClick={onDismiss} | ||
rank="tertiary" | ||
variant={color === 'dark' ? 'inverse' : 'neutral'} | ||
> | ||
Close | ||
</Button> | ||
)} | ||
</div> | ||
</div> | ||
); | ||
}; |
Oops, something went wrong.