Skip to content

Commit 1d4f2d5

Browse files
authored
feat: Implementation of the Alert component Style API (#3688)
1 parent bb84fa6 commit 1d4f2d5

File tree

8 files changed

+538
-3
lines changed

8 files changed

+538
-3
lines changed
Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
import React, { useRef } from 'react';
4+
5+
import { useCurrentMode } from '@cloudscape-design/component-toolkit/internal';
6+
7+
import { Alert as CloudscapeAlert, Button, SpaceBetween } from '~components';
8+
9+
import { palette } from '../app/themes/style-api';
10+
import ScreenshotArea from '../utils/screenshot-area';
11+
import { i18nStrings } from './common';
12+
13+
export default function CustomAlertTypes() {
14+
return (
15+
<ScreenshotArea>
16+
<h1>Custom Alert Types</h1>
17+
<SpaceBetween direction="vertical" size="m">
18+
<CustomAlert type="info" dismissible={true}>
19+
Info
20+
</CustomAlert>
21+
<CustomAlert type="success">Success</CustomAlert>
22+
<CustomAlert type="error" dismissible={true}>
23+
Error
24+
</CustomAlert>
25+
<CustomAlert
26+
type="error"
27+
action={
28+
<Button
29+
style={{
30+
root: {
31+
background: {
32+
default: palette.blue90,
33+
hover: palette.green90,
34+
active: palette.blue90,
35+
},
36+
borderColor: {
37+
default: palette.neutral10,
38+
hover: palette.neutral10,
39+
active: palette.neutral10,
40+
},
41+
color: {
42+
default: palette.neutral10,
43+
hover: palette.neutral10,
44+
active: palette.neutral10,
45+
},
46+
paddingBlock: '4px',
47+
paddingInline: '12px',
48+
},
49+
}}
50+
>
51+
Retry
52+
</Button>
53+
}
54+
>
55+
With Button
56+
</CustomAlert>
57+
<CustomAlert type="warning">Warning</CustomAlert>
58+
</SpaceBetween>
59+
</ScreenshotArea>
60+
);
61+
}
62+
63+
interface CustomAlertProps {
64+
children?: React.ReactNode;
65+
type: 'info' | 'success' | 'error' | 'warning';
66+
dismissible?: boolean;
67+
action?: React.ReactNode;
68+
}
69+
70+
function CustomAlert({ children, type, dismissible, action }: CustomAlertProps) {
71+
const mode = useCurrentMode(useRef(document.body));
72+
const background = backgrounds[mode][type];
73+
const borderColor = borderColors[mode][type];
74+
const borderWidth = borderWidths[type];
75+
const color = colors[mode];
76+
return (
77+
<CloudscapeAlert
78+
dismissible={dismissible}
79+
type={type}
80+
action={action}
81+
i18nStrings={i18nStrings}
82+
style={{
83+
root: {
84+
background,
85+
borderColor,
86+
borderRadius: '8px',
87+
borderWidth,
88+
color,
89+
focusRing: {
90+
borderColor: palette.red60,
91+
borderRadius: '4px',
92+
borderWidth: '2px',
93+
},
94+
},
95+
dismissButton: {
96+
color: {
97+
default: dismissButtonColors[mode][type].default,
98+
hover: dismissButtonColors[mode][type].hover,
99+
active: dismissButtonColors[mode][type].active,
100+
},
101+
focusRing: {
102+
borderColor: palette.red60,
103+
borderRadius: '4px',
104+
borderWidth: '2px',
105+
},
106+
},
107+
}}
108+
>
109+
<span style={{ fontSize: '16px' }}>{children}</span>
110+
</CloudscapeAlert>
111+
);
112+
}
113+
114+
const backgrounds = {
115+
light: {
116+
info: palette.blue80,
117+
success: palette.green80,
118+
error: palette.red80,
119+
warning: palette.teal90,
120+
},
121+
dark: {
122+
info: palette.blue40,
123+
success: palette.green20,
124+
error: palette.red30,
125+
warning: palette.teal20,
126+
},
127+
};
128+
129+
const colors = {
130+
light: palette.neutral10,
131+
dark: palette.neutral100,
132+
};
133+
134+
const borderColors = {
135+
light: {
136+
info: palette.neutral80,
137+
success: palette.green80,
138+
error: palette.blue90,
139+
warning: palette.orange80,
140+
},
141+
dark: {
142+
info: palette.neutral20,
143+
success: palette.green30,
144+
error: palette.red60,
145+
warning: palette.orange40,
146+
},
147+
};
148+
149+
const borderWidths = {
150+
info: '4px',
151+
success: '0px',
152+
error: '6px',
153+
warning: '0px',
154+
};
155+
156+
const dismissButtonColors = {
157+
light: {
158+
info: {
159+
default: palette.green60,
160+
hover: palette.neutral80,
161+
active: palette.neutral90,
162+
},
163+
success: {
164+
default: palette.green60,
165+
hover: palette.green80,
166+
active: palette.green90,
167+
},
168+
error: {
169+
default: palette.red60,
170+
hover: palette.red60,
171+
active: palette.red80,
172+
},
173+
warning: {
174+
default: palette.orange60,
175+
hover: palette.orange80,
176+
active: palette.orange90,
177+
},
178+
},
179+
dark: {
180+
info: {
181+
default: palette.neutral40,
182+
hover: palette.neutral20,
183+
active: palette.neutral10,
184+
},
185+
success: {
186+
default: palette.green30,
187+
hover: palette.green20,
188+
active: palette.green10,
189+
},
190+
error: {
191+
default: palette.red60,
192+
hover: palette.red20,
193+
active: palette.red10,
194+
},
195+
warning: {
196+
default: palette.orange40,
197+
hover: palette.orange20,
198+
active: palette.orange10,
199+
},
200+
},
201+
};

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

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,161 @@ If the label is assigned via the \`i18nStrings\` property, this label will be ig
180180
"optional": true,
181181
"type": "string",
182182
},
183+
{
184+
"description": "Specifies an object of selectors and properties that are used to apply custom styles.
185+
186+
- \`root.background\` - (string) (Optional) Background for alert.
187+
- \`root.borderColor\` - (string) (Optional) Border color for alert.
188+
- \`root.borderRadius\` (string) - (Optional) Alert border radius.
189+
- \`root.borderWidth\` (string) - (Optional) Alert border width.
190+
- \`root.color\` - (string) (Optional) Text color for alert.
191+
- \`root.focusRing.borderColor\` - (string) (Optional) Alert focus ring border color.
192+
- \`root.focusRing.borderRadius\` (string) - (Optional) Alert button focus ring border radius.
193+
- \`root.focusRing.borderWidth\` (string) - (Optional) Alert button focus ring border width.
194+
- \`dismissButton.color.active\` - (string) (Optional) Color for dismiss button active state.
195+
- \`dismissButton.color.default\` - (string) (Optional) Color for dismiss button default state.
196+
- \`dismissButton.color.hover\` - (string) (Optional) Color for dismiss button hover state.
197+
- \`dismissButton.focusRing.borderColor\` - (string) (Optional) Dismiss button focus ring border color.
198+
- \`dismissButton.focusRing.borderRadius\` (string) - (Optional) Dismiss button focus ring border radius.
199+
- \`dismissButton.focusRing.borderWidth\` (string) - (Optional) Dismiss button focus ring border width.",
200+
"inlineType": {
201+
"name": "AlertProps.Style",
202+
"properties": [
203+
{
204+
"inlineType": {
205+
"name": "object",
206+
"properties": [
207+
{
208+
"inlineType": {
209+
"name": "{ active?: string | undefined; default?: string | undefined; hover?: string | undefined; }",
210+
"properties": [
211+
{
212+
"name": "active",
213+
"optional": true,
214+
"type": "string",
215+
},
216+
{
217+
"name": "default",
218+
"optional": true,
219+
"type": "string",
220+
},
221+
{
222+
"name": "hover",
223+
"optional": true,
224+
"type": "string",
225+
},
226+
],
227+
"type": "object",
228+
},
229+
"name": "color",
230+
"optional": true,
231+
"type": "{ active?: string | undefined; default?: string | undefined; hover?: string | undefined; }",
232+
},
233+
{
234+
"inlineType": {
235+
"name": "object",
236+
"properties": [
237+
{
238+
"name": "borderColor",
239+
"optional": true,
240+
"type": "string",
241+
},
242+
{
243+
"name": "borderRadius",
244+
"optional": true,
245+
"type": "string",
246+
},
247+
{
248+
"name": "borderWidth",
249+
"optional": true,
250+
"type": "string",
251+
},
252+
],
253+
"type": "object",
254+
},
255+
"name": "focusRing",
256+
"optional": true,
257+
"type": "{ borderColor?: string | undefined; borderRadius?: string | undefined; borderWidth?: string | undefined; }",
258+
},
259+
],
260+
"type": "object",
261+
},
262+
"name": "dismissButton",
263+
"optional": true,
264+
"type": "{ color?: { active?: string | undefined; default?: string | undefined; hover?: string | undefined; } | undefined; focusRing?: { borderColor?: string | undefined; borderRadius?: string | undefined; borderWidth?: string | undefined; } | undefined; }",
265+
},
266+
{
267+
"inlineType": {
268+
"name": "object",
269+
"properties": [
270+
{
271+
"name": "background",
272+
"optional": true,
273+
"type": "string",
274+
},
275+
{
276+
"name": "borderColor",
277+
"optional": true,
278+
"type": "string",
279+
},
280+
{
281+
"name": "borderRadius",
282+
"optional": true,
283+
"type": "string",
284+
},
285+
{
286+
"name": "borderWidth",
287+
"optional": true,
288+
"type": "string",
289+
},
290+
{
291+
"name": "color",
292+
"optional": true,
293+
"type": "string",
294+
},
295+
{
296+
"inlineType": {
297+
"name": "object",
298+
"properties": [
299+
{
300+
"name": "borderColor",
301+
"optional": true,
302+
"type": "string",
303+
},
304+
{
305+
"name": "borderRadius",
306+
"optional": true,
307+
"type": "string",
308+
},
309+
{
310+
"name": "borderWidth",
311+
"optional": true,
312+
"type": "string",
313+
},
314+
],
315+
"type": "object",
316+
},
317+
"name": "focusRing",
318+
"optional": true,
319+
"type": "{ borderColor?: string | undefined; borderRadius?: string | undefined; borderWidth?: string | undefined; }",
320+
},
321+
],
322+
"type": "object",
323+
},
324+
"name": "root",
325+
"optional": true,
326+
"type": "{ background?: string | undefined; borderColor?: string | undefined; borderRadius?: string | undefined; borderWidth?: string | undefined; color?: string | undefined; focusRing?: { ...; } | undefined; }",
327+
},
328+
],
329+
"type": "object",
330+
},
331+
"name": "style",
332+
"optional": true,
333+
"systemTags": [
334+
"core",
335+
],
336+
"type": "AlertProps.Style",
337+
},
183338
{
184339
"defaultValue": "'info'",
185340
"description": "Specifies the type of message you want to display.",

0 commit comments

Comments
 (0)