Skip to content

Commit 0e65b85

Browse files
committed
Make Alerts dismissible (#11)
1 parent 0022a1d commit 0e65b85

File tree

11 files changed

+299
-143
lines changed

11 files changed

+299
-143
lines changed

src/demo/pages/DemoContainer.jsx

Lines changed: 80 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -864,57 +864,90 @@ class DemoContainer extends React.Component {
864864
<Documentation
865865
name="Alert types"
866866
component={(
867-
<div>
868-
<Alert type="success">
869-
<span>
870-
<strong>Success: </strong>
871-
Success message
872-
</span>
873-
</Alert>
874-
<Alert type="warning">
875-
<span>
876-
<strong>Warning: </strong>
877-
Warning message
878-
</span>
879-
</Alert>
880-
<Alert type="error">
881-
<span>
882-
<strong>Error: </strong>
883-
Error message
884-
</span>
885-
</Alert>
886-
<Alert type="info">
887-
<span>
888-
<strong>Info: </strong>
889-
Info message
890-
</span>
891-
</Alert>
892-
<Alert type="help">
893-
<span>
894-
<strong>Help: </strong>
895-
Help message
896-
</span>
897-
</Alert>
898-
<Alert>
899-
<span>
900-
<strong>Note: </strong>
901-
Note message
902-
</span>
903-
</Alert>
904-
</div>
867+
<>
868+
<div className="mb-4">
869+
<Alert type="success">
870+
<span>
871+
<strong>Success: </strong>
872+
Success message
873+
</span>
874+
</Alert>
875+
</div>
876+
<div className="mb-4">
877+
<Alert type="warning">
878+
<span>
879+
<strong>Warning: </strong>
880+
Warning message
881+
</span>
882+
</Alert>
883+
</div>
884+
<div className="mb-4">
885+
<Alert type="error">
886+
<span>
887+
<strong>Error: </strong>
888+
Error message
889+
</span>
890+
</Alert>
891+
</div>
892+
<div className="mb-4">
893+
<Alert type="info">
894+
<span>
895+
<strong>Info: </strong>
896+
Info message
897+
</span>
898+
</Alert>
899+
</div>
900+
<div className="mb-4">
901+
<Alert type="help">
902+
<span>
903+
<strong>Help: </strong>
904+
Help message
905+
</span>
906+
</Alert>
907+
</div>
908+
<div>
909+
<Alert>
910+
<span>
911+
<strong>Note: </strong>
912+
Note message
913+
</span>
914+
</Alert>
915+
</div>
916+
</>
905917
)}
906918
/>
907919
<Documentation
908-
name="Alert with icon"
920+
name="Dismissible alert with icon"
909921
component={(
910-
<div>
911-
<Alert type="success" icon={<Icon icon="success" />}>
912-
<span>
913-
<strong>Success: </strong>
914-
Success message
915-
</span>
916-
</Alert>
917-
</div>
922+
<Alert
923+
closeHandler={loggerClick}
924+
icon={<Icon icon="success" />}
925+
type="success"
926+
>
927+
<span>
928+
<strong>Success: </strong>
929+
Success message
930+
</span>
931+
</Alert>
932+
)}
933+
/>
934+
<Documentation
935+
name="Dismissible alert with long content"
936+
component={(
937+
<Alert
938+
closeHandler={loggerClick}
939+
icon={<Icon icon="success" />}
940+
type="success"
941+
>
942+
<span>
943+
<strong>Success: </strong>
944+
Curabitur sagittis hendrerit ante. Integer pellentesque quam vel velit. Sed vel
945+
lectus. Donec odio tempus molestie, porttitor ut, iaculis quis, sem.
946+
Pellentesque sapien. Ut enim ad minima veniam, quis nostrum exercitationem ullam
947+
corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur?
948+
Maecenas sollicitudin.
949+
</span>
950+
</Alert>
918951
)}
919952
/>
920953
<h3 id="ui-components-badge" className="typography-size-4 mb-6">Badge</h3>

src/lib/components/ui/Alert/Alert.jsx

Lines changed: 60 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,95 @@
11
import PropTypes from 'prop-types';
22
import React from 'react';
3+
import { withTranslationContext } from '../../../translation';
34
import styles from './Alert.scss';
45

56
const Alert = (props) => {
6-
let rootTypeClass = styles.note;
7-
8-
if (props.type) {
9-
if (props.type === 'success') {
10-
rootTypeClass = styles.success;
11-
} else if (props.type === 'error') {
12-
rootTypeClass = styles.error;
13-
} else if (props.type === 'warning') {
14-
rootTypeClass = styles.warning;
15-
} else if (props.type === 'info') {
16-
rootTypeClass = styles.info;
17-
} else if (props.type === 'help') {
18-
rootTypeClass = styles.help;
7+
const {
8+
children,
9+
closeHandler,
10+
icon,
11+
id,
12+
translations,
13+
type,
14+
} = props;
15+
16+
const rootTypeClass = (variant) => {
17+
if (variant === 'success') {
18+
return styles.isRootSuccess;
19+
}
20+
21+
if (variant === 'error') {
22+
return styles.isRootError;
1923
}
20-
}
24+
25+
if (variant === 'warning') {
26+
return styles.isRootWarning;
27+
}
28+
29+
if (variant === 'info') {
30+
return styles.isRootInfo;
31+
}
32+
33+
if (variant === 'help') {
34+
return styles.isRootHelp;
35+
}
36+
37+
return styles.isRootNote;
38+
};
2139

2240
return (
2341
<div
24-
className={(`
25-
${styles.root}
26-
${rootTypeClass}
27-
`).trim()}
28-
id={props.id}
42+
className={[
43+
styles.root,
44+
rootTypeClass(type),
45+
].join(' ')}
46+
id={id}
2947
role="alert"
3048
>
31-
{props.icon && (
49+
{icon && (
3250
<div className={styles.icon}>
33-
{props.icon}
51+
{icon}
3452
</div>
3553
)}
3654
<div
3755
className={styles.message}
38-
{...(props.id && { id: `${props.id}__content` })}
56+
{...(id && { id: `${id}__content` })}
3957
>
40-
{props.children}
58+
{children}
4159
</div>
60+
{closeHandler && (
61+
<button
62+
type="button"
63+
{...(id && { id: `${id}__close` })}
64+
className={styles.close}
65+
onClick={() => closeHandler()}
66+
onKeyPress={() => closeHandler()}
67+
tabIndex="0"
68+
title={translations.close}
69+
>
70+
<span className={styles.closeSign}>×</span>
71+
</button>
72+
)}
4273
</div>
4374
);
4475
};
4576

4677
Alert.defaultProps = {
78+
closeHandler: null,
4779
icon: null,
4880
id: undefined,
4981
type: 'note',
5082
};
5183

5284
Alert.propTypes = {
5385
children: PropTypes.node.isRequired,
86+
closeHandler: PropTypes.func,
5487
icon: PropTypes.node,
5588
id: PropTypes.string,
89+
translations: PropTypes.shape({
90+
close: PropTypes.string.isRequired,
91+
}).isRequired,
5692
type: PropTypes.oneOf(['error', 'help', 'info', 'note', 'success', 'warning']),
5793
};
5894

59-
export default Alert;
95+
export default withTranslationContext(Alert, 'Alert');
Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,37 @@
1+
@import '../../../styles/tools/offset';
12
@import 'mixins';
23

34
.root {
4-
@include alert();
5+
position: relative;
6+
display: flex;
7+
align-items: flex-start;
8+
width: 100%;
9+
border-width: $alert-border-width $alert-border-width $alert-border-width $alert-stripe-width;
10+
border-style: solid;
11+
border-radius: $alert-border-radius;
12+
}
13+
14+
.close,
15+
.icon,
16+
.message {
17+
padding: $alert-padding;
18+
}
19+
20+
.close,
21+
.icon {
22+
height: $alert-min-height;
523
}
624

725
.icon {
826
display: flex;
927
flex: none;
1028
align-items: center;
11-
align-self: flex-start;
1229
justify-content: center;
13-
height: calc(#{$alert-line-height} * #{$alert-font-size});
30+
padding-right: 0;
1431
}
1532

1633
.message {
17-
padding-left: $alert-padding;
34+
flex-grow: 1;
1835
font-weight: $alert-message-font-weight;
1936
font-size: $alert-font-size;
2037
line-height: $alert-line-height;
@@ -24,26 +41,42 @@
2441
font-weight: $alert-title-font-weight;
2542
}
2643

27-
.success {
44+
.close {
45+
font-size: map-get($typography-size-values, 3);
46+
line-height: 1;
47+
border: 0;
48+
background: none;
49+
box-shadow: none;
50+
appearance: none;
51+
user-select: none;
52+
cursor: pointer;
53+
}
54+
55+
.closeSign {
56+
position: relative;
57+
top: -0.1em;
58+
}
59+
60+
.isRootSuccess {
2861
@include alert-type(success);
2962
}
3063

31-
.warning {
64+
.isRootWarning {
3265
@include alert-type(warning);
3366
}
3467

35-
.error {
68+
.isRootError {
3669
@include alert-type(error);
3770
}
3871

39-
.info {
72+
.isRootInfo {
4073
@include alert-type(info);
4174
}
4275

43-
.help {
76+
.isRootHelp {
4477
@include alert-type(help);
4578
}
4679

47-
.note {
80+
.isRootNote {
4881
@include alert-type(note);
4982
}

src/lib/components/ui/Alert/_mixins.scss

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,4 @@
1-
@import '../../../styles/tools/breakpoints';
21
@import 'variables';
3-
@import 'theme';
4-
5-
@mixin alert() {
6-
position: relative;
7-
display: flex;
8-
width: 100%;
9-
min-height: $alert-min-height;
10-
padding: $alert-padding;
11-
border-width: $alert-border-width $alert-border-width $alert-border-width $alert-stripe-width;
12-
border-style: solid;
13-
border-radius: $alert-border-radius;
14-
}
152

163
@mixin alert-type($type) {
174
$type-properties: map-get($alert-types, $type);
@@ -22,6 +9,7 @@
229
background-color: map-get($type-properties, background-color);
2310

2411
strong,
12+
.close,
2513
.icon {
2614
color: $foreground-color;
2715
}

src/lib/components/ui/Alert/_theme.scss

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
$alert-border-width: var(--rui-alert-border-width);
22
$alert-border-radius: var(--rui-alert-border-radius);
33
$alert-padding: var(--rui-alert-padding);
4-
$alert-icon-size: var(--rui-icon-size-default);
54

65
$alert-types: (
76
success: (
Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,9 @@
1-
@import '../../../styles/settings/colors';
2-
@import '../../../styles/settings/offsets';
31
@import '../../../styles/settings/typography';
42
@import './theme';
53

64
$alert-font-size: map-get($typography-size-values, 0);
7-
$alert-line-height: 1.2;
8-
$alert-min-height:
9-
calc(
10-
#{$alert-font-size} * #{$alert-line-height} + 2 * #{$alert-padding} + 2 * #{$alert-border-width}
11-
);
5+
$alert-line-height: 1.5;
6+
$alert-min-height: calc(#{$alert-font-size} * #{$alert-line-height} + 2 * #{$alert-padding});
127
$alert-stripe-width: 5px;
138
$alert-message-font-weight: map-get($typography-font-weight-values, light);
149
$alert-title-font-weight: map-get($typography-font-weight-values, bold);

0 commit comments

Comments
 (0)