Skip to content

Commit f99e671

Browse files
Merge branch 'develop' into feat/require-heading-level
2 parents c03f8db + ec53af7 commit f99e671

File tree

10 files changed

+114
-115
lines changed

10 files changed

+114
-115
lines changed

packages/css/src/components/alert/README.md

+13-15
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,19 @@
44

55
An Alert informs the user of a significant or time-sensitive message without interrupting their task.
66

7-
## Specifications
8-
9-
There are four types of notifications:
10-
11-
- **Warning** (orange) when action is needed to prevent damage.
12-
- **Error** (red) indicates an error has occurred.
13-
- **Confirmation** (green) to reassure that a process is complete.
14-
- **Notification** (blue) to bring attention to a message.
15-
167
## Guidelines
178

18-
- Place an orange Alert directly below the Header for important and urgent information.
9+
- Use an Alert if the message’s purpose matches one of the following:
10+
- **Information** to bring attention to a message.
11+
This variation is blue and it is the default.
12+
- **Success** to reassure that a process is complete.
13+
This variation is green.
14+
- **Warning** when action is needed to prevent damage.
15+
This variation is orange.
16+
- **Error** indicates an error has occurred.
17+
This variation is red.
18+
- Place the Alert in a Grid Cell to create enough white space around it.
19+
- Important and urgent information is to be placed directly below the Header.
1920
Examples: system outage or changes in the opening hours of a City Office.
20-
- Ensure sufficient white space around the Alert.
21-
The grid’s white space is a good reference – place the Alert in its own cell.
22-
- By default, the Alert cannot be closed.
23-
This functionality can be added optionally.
24-
- Optionally, the heading can be omitted.
21+
This can be applied to the entire application or to a part of it.
22+
- Add a close button if the user should be able to dismiss the Alert.

packages/css/src/components/alert/alert.scss

+29-13
Original file line numberDiff line numberDiff line change
@@ -4,36 +4,52 @@
44
*/
55

66
.ams-alert {
7-
align-items: flex-start;
87
background-color: var(--ams-alert-background-color);
9-
border-style: var(--ams-alert-border-style);
10-
border-width: var(--ams-alert-border-width);
8+
box-shadow: var(--ams-alert-box-shadow);
119
display: flex;
12-
gap: var(--ams-alert-gap);
13-
justify-content: space-between;
14-
padding-block: var(--ams-alert-padding-block);
15-
padding-inline: var(--ams-alert-padding-inline);
10+
11+
@media (forced-colors: active) {
12+
border-style: solid;
13+
border-width: var(--ams-alert-forced-colors-border-width);
14+
}
15+
}
16+
17+
.ams-alert__severity-indicator {
18+
background-color: var(--ams-alert-severity-indicator-background-color);
19+
flex: none;
20+
padding-block: var(--ams-alert-severity-indicator-padding-block);
21+
padding-inline: var(--ams-alert-severity-indicator-padding-inline);
1622
}
1723

1824
.ams-alert__content {
1925
display: flex;
2026
flex: auto;
2127
flex-direction: column;
2228
gap: var(--ams-alert-content-gap);
29+
padding-block: var(--ams-alert-content-padding-block);
30+
padding-inline: var(--ams-alert-content-padding-inline);
2331
}
2432

2533
.ams-alert--error {
26-
border-color: var(--ams-alert-error-border-color);
27-
}
34+
box-shadow: var(--ams-alert-error-box-shadow);
2835

29-
.ams-alert--info {
30-
border-color: var(--ams-alert-info-border-color);
36+
> .ams-alert__severity-indicator {
37+
background-color: var(--ams-alert-error-severity-indicator-background-color);
38+
}
3139
}
3240

3341
.ams-alert--success {
34-
border-color: var(--ams-alert-success-border-color);
42+
box-shadow: var(--ams-alert-success-box-shadow);
43+
44+
> .ams-alert__severity-indicator {
45+
background-color: var(--ams-alert-success-severity-indicator-background-color);
46+
}
3547
}
3648

3749
.ams-alert--warning {
38-
border-color: var(--ams-alert-warning-border-color);
50+
box-shadow: var(--ams-alert-warning-box-shadow);
51+
52+
> .ams-alert__severity-indicator {
53+
background-color: var(--ams-alert-warning-severity-indicator-background-color);
54+
}
3955
}

packages/react/src/Alert/Alert.test.tsx

+8-8
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ import '@testing-library/jest-dom'
55

66
describe('Alert', () => {
77
it('renders', () => {
8-
const { container } = render(<Alert headingLevel={2} />)
8+
const { container } = render(<Alert heading="Let op!" headingLevel={2} />)
99

1010
const component = container.querySelector(':only-child')
11-
const icon = component?.querySelector('.ams-alert__icon')
11+
const icon = component?.querySelector('.ams-alert__severity-indicator > .ams-icon')
1212

1313
expect(component).toBeInTheDocument()
1414
expect(component).toBeVisible()
@@ -17,15 +17,15 @@ describe('Alert', () => {
1717
})
1818

1919
it('renders a design system BEM class name', () => {
20-
const { container } = render(<Alert headingLevel={2} />)
20+
const { container } = render(<Alert heading="Let op!" headingLevel={2} />)
2121

2222
const component = container.querySelector(':only-child')
2323

2424
expect(component).toHaveClass('ams-alert')
2525
})
2626

2727
it('renders an additional class name', () => {
28-
const { container } = render(<Alert className="extra" headingLevel={2} />)
28+
const { container } = render(<Alert className="extra" heading="Let op!" headingLevel={2} />)
2929

3030
const component = container.querySelector(':only-child')
3131

@@ -35,7 +35,7 @@ describe('Alert', () => {
3535
it('supports ForwardRef in React', () => {
3636
const ref = createRef<HTMLDivElement>()
3737

38-
const { container } = render(<Alert ref={ref} headingLevel={2} />)
38+
const { container } = render(<Alert heading="Let op!" headingLevel={2} ref={ref} />)
3939

4040
const component = container.querySelector(':only-child')
4141

@@ -53,7 +53,7 @@ describe('Alert', () => {
5353
})
5454

5555
it('renders the close button', () => {
56-
const { container } = render(<Alert closeable={true} headingLevel={2} />)
56+
const { container } = render(<Alert closeable heading="Let op!" headingLevel={2} />)
5757

5858
const component = container.querySelector(':only-child')
5959
const closeButton = component?.querySelector('.ams-icon-button')
@@ -63,7 +63,7 @@ describe('Alert', () => {
6363
})
6464

6565
it('renders the close button with a label', () => {
66-
render(<Alert closeable={true} closeButtonLabel="Close" headingLevel={2} />)
66+
render(<Alert closeable closeButtonLabel="Close" heading="Let op!" headingLevel={2} />)
6767

6868
const closeButton = screen.getByRole('button', { name: 'Close' })
6969

@@ -72,7 +72,7 @@ describe('Alert', () => {
7272

7373
it('fires the onClose event when the close button is clicked', () => {
7474
const onClose = jest.fn()
75-
const { container } = render(<Alert closeable={true} onClose={onClose} headingLevel={2} />)
75+
const { container } = render(<Alert closeable onClose={onClose} heading="Let op!" headingLevel={2} />)
7676

7777
const component = container.querySelector(':only-child')
7878
const closeButton = component?.querySelector('.ams-icon-button')

packages/react/src/Alert/Alert.tsx

+15-14
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,17 @@ import { Heading } from '../Heading'
1111
import type { HeadingProps } from '../Heading'
1212
import { Icon } from '../Icon'
1313
import { IconButton } from '../IconButton'
14+
import { Row } from '../Row'
15+
16+
type Severity = 'error' | 'success' | 'warning'
1417

1518
export type AlertProps = {
1619
/** Whether the user can dismiss the Alert. Adds a button to its top right. */
1720
closeable?: boolean
1821
/** The label for the button that dismisses the Alert. */
1922
closeButtonLabel?: string
2023
/** The text for the Heading. */
21-
heading?: string
24+
heading: string
2225
/**
2326
* The hierarchical level of the Alert’s Heading within the document.
2427
* There is no default value; determine the correct level for each instance.
@@ -28,12 +31,11 @@ export type AlertProps = {
2831
/** A function to run when dismissing. */
2932
onClose?: () => void
3033
/** The significance of the message conveyed. */
31-
severity?: 'error' | 'info' | 'success' | 'warning'
34+
severity?: Severity
3235
} & PropsWithChildren<HTMLAttributes<HTMLDivElement>>
3336

34-
const iconSvgBySeverity = {
37+
const iconSvgBySeverity: Record<Severity, Function> = {
3538
error: AlertIcon,
36-
info: InfoIcon,
3739
success: CheckmarkIcon,
3840
warning: AlertIcon,
3941
}
@@ -48,29 +50,28 @@ export const Alert = forwardRef(
4850
heading,
4951
headingLevel,
5052
onClose,
51-
severity = 'warning',
53+
severity,
5254
...restProps
5355
}: AlertProps,
5456
ref: ForwardedRef<HTMLDivElement>,
5557
) => {
56-
const alertSize = heading ? 'level-4' : 'level-5'
57-
const Tag = heading ? 'section' : 'div'
58+
const SeverityIcon = severity ? iconSvgBySeverity[severity] : InfoIcon
5859

5960
return (
60-
<Tag {...restProps} ref={ref} className={clsx('ams-alert', severity && `ams-alert--${severity}`, className)}>
61-
<div className="ams-alert__icon">
62-
<Icon size={alertSize} svg={iconSvgBySeverity[severity]} />
61+
<section {...restProps} ref={ref} className={clsx('ams-alert', severity && `ams-alert--${severity}`, className)}>
62+
<div className="ams-alert__severity-indicator">
63+
<Icon inverseColor size="level-4" svg={SeverityIcon} />
6364
</div>
6465
<div className="ams-alert__content">
65-
{heading && (
66+
<Row align="between" alignVertical="start">
6667
<Heading level={headingLevel} size="level-4">
6768
{heading}
6869
</Heading>
69-
)}
70+
{closeable && <IconButton label={closeButtonLabel} onClick={onClose} size="level-4" />}
71+
</Row>
7072
{children}
7173
</div>
72-
{closeable && <IconButton label={closeButtonLabel} size={alertSize} onClick={onClose} />}
73-
</Tag>
74+
</section>
7475
)
7576
},
7677
)

packages/react/src/Avatar/Avatar.tsx

+1-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import clsx from 'clsx'
88
import { forwardRef } from 'react'
99
import type { ForwardedRef, HTMLAttributes } from 'react'
1010
import { Icon } from '../Icon'
11-
import { Image } from '../Image'
1211

1312
export const avatarColors = [
1413
'black',
@@ -36,7 +35,7 @@ type AvatarContentProps = {
3635

3736
const AvatarContent = ({ imageSrc, initials }: AvatarContentProps) => {
3837
if (imageSrc) {
39-
return <Image alt="" src={imageSrc} />
38+
return <img alt="" src={imageSrc} />
4039
}
4140

4241
if (initials.length) {

proprietary/tokens/src/components/ams/alert.tokens.json

+26-14
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,37 @@
22
"ams": {
33
"alert": {
44
"background-color": { "value": "{ams.color.primary-white}" },
5-
"border-width": { "value": "{ams.border.width.xl}" },
6-
"border-style": { "value": "solid" },
7-
"gap": { "value": "{ams.space.sm}" },
8-
"padding-block": { "value": "{ams.space.md}" },
9-
"padding-inline": { "value": "{ams.space.lg}" },
10-
"error": {
11-
"border-color": { "value": "{ams.color.primary-red}" }
5+
"box-shadow": { "value": "inset 0 0 0 {ams.border.width.xl} {ams.color.blue}" },
6+
"forced-colors": {
7+
"border-width": { "value": "{ams.border.width.xl}" }
8+
},
9+
"severity-indicator": {
10+
"background-color": { "value": "{ams.color.blue}" },
11+
"padding-block": { "value": "{ams.space.md}" },
12+
"padding-inline": { "value": "{ams.space.xs}" }
1213
},
13-
"info": {
14-
"border-color": { "value": "{ams.color.blue}" }
14+
"content": {
15+
"gap": { "value": "{ams.space.sm}" },
16+
"padding-block": { "value": "{ams.space.md}" },
17+
"padding-inline": { "value": "{ams.space.md}" }
18+
},
19+
"error": {
20+
"box-shadow": { "value": "inset 0 0 0 {ams.border.width.xl} {ams.color.primary-red}" },
21+
"severity-indicator": {
22+
"background-color": { "value": "{ams.color.primary-red}" }
23+
}
1524
},
1625
"success": {
17-
"border-color": { "value": "{ams.color.dark-green}" }
26+
"box-shadow": { "value": "inset 0 0 0 {ams.border.width.xl} {ams.color.dark-green}" },
27+
"severity-indicator": {
28+
"background-color": { "value": "{ams.color.dark-green}" }
29+
}
1830
},
1931
"warning": {
20-
"border-color": { "value": "{ams.color.orange}" }
21-
},
22-
"content": {
23-
"gap": { "value": "{ams.space.sm}" }
32+
"box-shadow": { "value": "inset 0 0 0 {ams.border.width.xl} {ams.color.orange}" },
33+
"severity-indicator": {
34+
"background-color": { "value": "{ams.color.orange}" }
35+
}
2436
}
2537
}
2638
}

storybook/src/components/Alert/Alert.docs.mdx

+1-15
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import README from "../../../../packages/css/src/components/alert/README.md?raw"
1717
### Warning
1818

1919
Display a warning when user action is required.
20-
This is the default severity.
2120

2221
<Canvas of={AlertStories.Warning} />
2322

@@ -34,7 +33,7 @@ Announce the success of a significant action.
3433

3534
<Canvas of={AlertStories.Success} />
3635

37-
### Info
36+
### Information
3837

3938
An informative message can emphasize matters that are useful to follow.
4039

@@ -45,16 +44,3 @@ An informative message can emphasize matters that are useful to follow.
4544
Include an inline link in the text to guide the user.
4645

4746
<Canvas of={AlertStories.WithInlineLink} />
48-
49-
### With list
50-
51-
For clarification, formatted text can be included in the alert.
52-
53-
<Canvas of={AlertStories.WithList} />
54-
55-
### Without heading
56-
57-
Sometimes, a heading is unnecessary.
58-
The icon automatically becomes slightly smaller.
59-
60-
<Canvas of={AlertStories.WithoutHeading} />

0 commit comments

Comments
 (0)