Skip to content

Commit 69c8d30

Browse files
authored
feat: Implementation of the Flashbar component Style API. (#3557)
1 parent 9ccb261 commit 69c8d30

File tree

13 files changed

+632
-40
lines changed

13 files changed

+632
-40
lines changed

pages/flashbar/style-custom.page.tsx

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
import React from 'react';
4+
5+
import { Flashbar, FlashbarProps, SpaceBetween } from '~components';
6+
7+
import { palette } from '../app/themes/style-api';
8+
import ScreenshotArea from '../utils/screenshot-area';
9+
import { i18nStrings } from './common';
10+
11+
export default function CustomFlashbar() {
12+
const noop = () => void 0;
13+
14+
const items: FlashbarProps.MessageDefinition[] = [
15+
{
16+
dismissible: true,
17+
onDismiss: noop,
18+
dismissLabel: 'Dismiss',
19+
statusIconAriaLabel: 'Success',
20+
type: 'success',
21+
header: 'This is the test header',
22+
content: 'This is the test content.',
23+
id: 'success',
24+
},
25+
{
26+
dismissible: true,
27+
onDismiss: noop,
28+
dismissLabel: 'Dismiss',
29+
statusIconAriaLabel: 'Warning',
30+
type: 'warning',
31+
header: 'This is the test header',
32+
content: 'This is the test content.',
33+
id: 'warning',
34+
},
35+
{
36+
dismissible: true,
37+
onDismiss: noop,
38+
dismissLabel: 'Dismiss',
39+
statusIconAriaLabel: 'Error',
40+
type: 'error',
41+
header: 'This is the test header',
42+
content: 'This is the test content.',
43+
id: 'error',
44+
},
45+
{
46+
dismissible: true,
47+
onDismiss: noop,
48+
dismissLabel: 'Dismiss',
49+
statusIconAriaLabel: 'Info',
50+
type: 'info',
51+
header: 'This is the test header',
52+
content: 'This is the test content.',
53+
id: 'info',
54+
},
55+
{
56+
dismissible: true,
57+
onDismiss: noop,
58+
dismissLabel: 'Dismiss',
59+
statusIconAriaLabel: 'In Progress',
60+
type: 'in-progress',
61+
header: 'This is the test header',
62+
content: 'This is the test content.',
63+
id: 'in-progress',
64+
},
65+
];
66+
67+
return (
68+
<ScreenshotArea>
69+
<h1>Custom Flashbar</h1>
70+
71+
<SpaceBetween direction="vertical" size="l">
72+
<Flashbar
73+
data-testid="collapsed"
74+
items={items}
75+
stackItems={true}
76+
style={{
77+
item,
78+
notificationBar,
79+
}}
80+
i18nStrings={i18nStrings}
81+
/>
82+
83+
<Flashbar
84+
data-testid="expanded"
85+
items={items}
86+
stackItems={false}
87+
style={{
88+
item,
89+
}}
90+
i18nStrings={i18nStrings}
91+
/>
92+
</SpaceBetween>
93+
</ScreenshotArea>
94+
);
95+
}
96+
97+
const item = {
98+
root: {
99+
background: {
100+
error: palette.red20,
101+
info: palette.blue20,
102+
inProgress: palette.teal20,
103+
success: palette.green20,
104+
warning: palette.orange20,
105+
},
106+
borderColor: {
107+
error: palette.red60,
108+
info: palette.blue60,
109+
inProgress: palette.teal60,
110+
success: palette.green60,
111+
warning: palette.orange60,
112+
},
113+
borderRadius: '4px',
114+
borderWidth: '1px',
115+
color: {
116+
error: palette.red100,
117+
info: palette.blue100,
118+
inProgress: palette.teal100,
119+
success: palette.green100,
120+
warning: palette.orange100,
121+
},
122+
focusRing: {
123+
borderColor: palette.neutral90,
124+
borderRadius: '4px',
125+
borderWidth: '1px',
126+
},
127+
},
128+
dismissButton: {
129+
color: {
130+
active: palette.neutral100,
131+
default: palette.neutral80,
132+
hover: palette.neutral90,
133+
},
134+
focusRing: {
135+
borderColor: palette.neutral90,
136+
borderRadius: '4px',
137+
borderWidth: '1px',
138+
},
139+
},
140+
};
141+
142+
const notificationBar = {
143+
root: {
144+
background: {
145+
active: palette.neutral80,
146+
default: palette.neutral90,
147+
hover: palette.neutral100,
148+
},
149+
borderColor: {
150+
active: palette.neutral100,
151+
default: palette.neutral100,
152+
hover: palette.neutral100,
153+
},
154+
borderRadius: '4px',
155+
borderWidth: '1px',
156+
color: {
157+
active: palette.neutral10,
158+
default: palette.neutral10,
159+
hover: palette.neutral10,
160+
},
161+
},
162+
};

src/__tests__/snapshot-tests/__snapshots__/documenter.test.ts.snap

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9467,6 +9467,30 @@ If the \`action\` property is set, this property is ignored. **Deprecated**, rep
94679467
"optional": true,
94689468
"type": "boolean",
94699469
},
9470+
{
9471+
"inlineType": {
9472+
"name": "FlashbarProps.Style",
9473+
"properties": [
9474+
{
9475+
"name": "item",
9476+
"optional": true,
9477+
"type": "{ root?: { background?: { error?: string | undefined; info?: string | undefined; inProgress?: string | undefined; success?: string | undefined; warning?: string | undefined; } | undefined; ... 4 more ...; focusRing?: { ...; } | undefined; } | undefined; dismissButton?: { ...; } | undefined; }",
9478+
},
9479+
{
9480+
"name": "notificationBar",
9481+
"optional": true,
9482+
"type": "{ root: { background?: { active?: string | undefined; default?: string | undefined; hover?: string | undefined; } | undefined; borderColor?: { active?: string | undefined; default?: string | undefined; hover?: string | undefined; } | undefined; borderRadius?: string | undefined; borderWidth?: string | undefined; col...",
9483+
},
9484+
],
9485+
"type": "object",
9486+
},
9487+
"name": "style",
9488+
"optional": true,
9489+
"systemTags": [
9490+
"core",
9491+
],
9492+
"type": "FlashbarProps.Style",
9493+
},
94709494
],
94719495
"regions": [],
94729496
"releaseStatus": "stable",

src/button/__integ__/button.test.ts

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,6 @@ class ButtonPageObject extends BasePageObject {
1111
getClickMessage() {
1212
return this.getText('#clickMessage');
1313
}
14-
15-
getComputedStyles(selector: string, property: string, pseudoElement: string | null = null) {
16-
return this.browser.execute(
17-
([selector, property, pseudoElement]) => {
18-
return getComputedStyle(document.querySelector(selector)!, pseudoElement).getPropertyValue(property);
19-
},
20-
[selector, property, pseudoElement] as const
21-
);
22-
}
2314
}
2415

2516
describe('Button', () => {
@@ -61,15 +52,19 @@ describe('Button Style API', () => {
6152
useBrowser(async browser => {
6253
await browser.url('#/light/button/style-custom-types');
6354
const page = new ButtonPageObject(browser);
64-
await page.click('[data-testid=default]');
65-
await page.hoverElement('[data-testid=default]');
66-
await expect(await page.getComputedStyles('[data-testid=default]', 'background-color')).toBe('rgb(0, 85, 102)');
55+
const buttonSelector = '[data-testid=default]';
56+
57+
await page.click(buttonSelector);
58+
await page.hoverElement(buttonSelector);
59+
await expect((await browser.$(buttonSelector).getCSSProperty('background-color')).value).toBe('rgba(0,85,102,1)');
60+
6761
await page.buttonDownOnElement('[data-testid=default]');
68-
await expect(await page.getComputedStyles('[data-testid=default]', 'background-color')).toBe('rgb(0, 64, 77)');
62+
await expect((await browser.$(buttonSelector).getCSSProperty('background-color')).value).toBe('rgba(0,64,77,1)');
63+
6964
await page.buttonUp();
7065
await page.keys('a');
71-
await expect(await page.getComputedStyles('[data-testid=default]', 'box-shadow', ':before')).toBe(
72-
'rgb(0, 64, 77) 0px 0px 0px 2px'
66+
await expect((await browser.$(buttonSelector).getCSSProperty('box-shadow', '::before')).value).toBe(
67+
'rgb(0,64,77)0px0px0px2px'
7368
);
7469
})
7570
);

src/button/styles.scss

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,10 @@
9494
(
9595
'vertical': awsui.$space-button-icon-focus-outline-gutter-vertical,
9696
'horizontal': awsui.$space-button-focus-outline-gutter,
97-
)
97+
),
98+
$border-radius:
99+
var(#{custom-props.$styleFocusRingBorderRadius}, awsui.$border-radius-control-default-focus-ring),
100+
$box-shadow: var(#{custom-props.$styleFocusRingBoxShadow})
98101
);
99102
}
100103

src/flashbar/__integ__/collapsible.test.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
22
// SPDX-License-Identifier: Apache-2.0
3+
import useBrowser from '@cloudscape-design/browser-test-tools/use-browser';
4+
35
import { FOCUS_THROTTLE_DELAY } from '../utils';
6+
import { FlashbarBasePage } from './pages/base';
47
import { setupTest } from './pages/interactive-page';
58
import { setupTest as setupStickyFlashbarTest } from './pages/sticky-page';
69

@@ -150,3 +153,40 @@ describe('Collapsible Flashbar', () => {
150153
);
151154
});
152155
});
156+
157+
describe('Flashbar Style API', () => {
158+
test(
159+
'active, hover and focus states',
160+
useBrowser(async browser => {
161+
await browser.url('#/light/flashbar/style-custom');
162+
163+
const page = new FlashbarBasePage(browser);
164+
const dismissButton = page.getDismissButton();
165+
const notificationBar = page.getNotificationBar();
166+
const expandButton = page.getExpandButton();
167+
168+
await page.hoverElement(dismissButton);
169+
await expect((await browser.$(dismissButton).getCSSProperty('color')).value).toBe('rgba(48,64,80,1)');
170+
171+
await page.buttonDownOnElement(dismissButton);
172+
await expect((await browser.$(dismissButton).getCSSProperty('color')).value).toBe('rgba(13,26,38,1)');
173+
174+
await page.click('[data-testid=collapsed]');
175+
await page.keys('Tab');
176+
await expect((await browser.$(dismissButton).getCSSProperty('box-shadow', '::before')).value).toBe(
177+
'rgb(48,64,80)0px0px0px1px'
178+
);
179+
180+
await page.click('[data-testid=collapsed]');
181+
await page.keys(['Shift', 'Tab']);
182+
await expect((await browser.$(expandButton).getCSSProperty('box-shadow', '::before')).value).toBe(
183+
'rgb(249,249,250)0px0px0px2px'
184+
);
185+
186+
await page.buttonDownOnElement(notificationBar);
187+
await expect((await browser.$(notificationBar).getCSSProperty('background-color')).value).toBe(
188+
'rgba(92,102,112,1)'
189+
);
190+
})
191+
);
192+
});

src/flashbar/__integ__/pages/base.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,14 @@ export class FlashbarBasePage extends BasePageObject {
2222
return createWrapper().findFlashbar().findByClassName(selectors['notification-bar']).toSelector();
2323
}
2424

25+
getExpandButton() {
26+
return createWrapper().findFlashbar().findByClassName(selectors.button).toSelector();
27+
}
28+
29+
getDismissButton() {
30+
return createWrapper().findFlashbar().findByClassName(selectors['dismiss-button']).toSelector();
31+
}
32+
2533
isFlashFocused(index: number) {
2634
return this.isFocused(
2735
flashbar.findItems().get(index).findByClassName(selectors['flash-focus-container']).toSelector()

0 commit comments

Comments
 (0)