@kaizen/components 1.64.2 → 1.64.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/Notification/InlineNotification/InlineNotification.cjs +4 -3
- package/dist/cjs/Notification/subcomponents/GenericNotification/GenericNotification.cjs +5 -3
- package/dist/esm/Notification/InlineNotification/InlineNotification.mjs +5 -4
- package/dist/esm/Notification/subcomponents/GenericNotification/GenericNotification.mjs +6 -4
- package/dist/styles.css +34 -30
- package/dist/types/Notification/InlineNotification/InlineNotification.d.ts +1 -4
- package/dist/types/Notification/subcomponents/GenericNotification/GenericNotification.d.ts +1 -4
- package/dist/types/ToggleSwitch/ToggleSwitch/ToggleSwitch.d.ts +1 -1
- package/package.json +3 -3
- package/src/Notification/InlineNotification/InlineNotification.tsx +25 -16
- package/src/Notification/InlineNotification/_docs/InlineNotification.stickersheet.stories.tsx +18 -0
- package/src/Notification/subcomponents/GenericNotification/GenericNotification.stories.tsx +44 -1
- package/src/Notification/subcomponents/GenericNotification/GenericNotification.tsx +93 -72
- package/src/Notification/subcomponents/GenericNotification/_mixins.scss +5 -0
- package/src/ToggleSwitch/ToggleSwitch/ToggleSwitch.tsx +3 -1
|
@@ -17,7 +17,7 @@ var classnames__default = /*#__PURE__*/_interopDefault(classnames);
|
|
|
17
17
|
* {@link https://cultureamp.atlassian.net/wiki/spaces/DesignSystem/pages/3082093392/Inline+Notification Guidance} |
|
|
18
18
|
* {@link https://cultureamp.design/storybook/?path=/docs/components-notifications-inline-notification--docs Storybook}
|
|
19
19
|
*/
|
|
20
|
-
var InlineNotification = function (_a) {
|
|
20
|
+
var InlineNotification = React.forwardRef(function (_a, ref) {
|
|
21
21
|
var isSubtle = _a.isSubtle,
|
|
22
22
|
_b = _a.hideCloseIcon,
|
|
23
23
|
hideCloseIcon = _b === void 0 ? false : _b,
|
|
@@ -28,8 +28,9 @@ var InlineNotification = function (_a) {
|
|
|
28
28
|
return React__default.default.createElement(GenericNotification.GenericNotification, tslib.__assign({
|
|
29
29
|
style: "inline",
|
|
30
30
|
persistent: persistent || hideCloseIcon,
|
|
31
|
-
classNameOverride: classnames__default.default(classNameOverride, [isSubtle && GenericNotification_module.subtle])
|
|
31
|
+
classNameOverride: classnames__default.default(classNameOverride, [isSubtle && GenericNotification_module.subtle]),
|
|
32
|
+
ref: ref
|
|
32
33
|
}, otherProps));
|
|
33
|
-
};
|
|
34
|
+
});
|
|
34
35
|
InlineNotification.displayName = "InlineNotification";
|
|
35
36
|
exports.InlineNotification = InlineNotification;
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
var tslib = require('tslib');
|
|
4
4
|
var React = require('react');
|
|
5
5
|
var classnames = require('classnames');
|
|
6
|
+
var isRefObject = require('../../../utils/isRefObject.cjs');
|
|
6
7
|
var CancelButton = require('../CancelButton/CancelButton.cjs');
|
|
7
8
|
var NotificationHeading = require('../NotificationHeading/NotificationHeading.cjs');
|
|
8
9
|
var NotificationIcon = require('../NotificationIcon/NotificationIcon.cjs');
|
|
@@ -14,7 +15,7 @@ function _interopDefault(e) {
|
|
|
14
15
|
}
|
|
15
16
|
var React__default = /*#__PURE__*/_interopDefault(React);
|
|
16
17
|
var classnames__default = /*#__PURE__*/_interopDefault(classnames);
|
|
17
|
-
var GenericNotification = function (_a) {
|
|
18
|
+
var GenericNotification = React.forwardRef(function (_a, ref) {
|
|
18
19
|
var type = _a.type,
|
|
19
20
|
variant = _a.variant,
|
|
20
21
|
style = _a.style,
|
|
@@ -34,7 +35,8 @@ var GenericNotification = function (_a) {
|
|
|
34
35
|
var _d = React.useState(false),
|
|
35
36
|
isRemoved = _d[0],
|
|
36
37
|
setIsRemoved = _d[1];
|
|
37
|
-
var
|
|
38
|
+
var fallbackRef = React.useRef(null);
|
|
39
|
+
var containerRef = isRefObject.isRefObject(ref) ? ref : fallbackRef;
|
|
38
40
|
React.useEffect(function () {
|
|
39
41
|
requestAnimationFrame(function () {
|
|
40
42
|
if (containerRef.current) {
|
|
@@ -83,6 +85,6 @@ var GenericNotification = function (_a) {
|
|
|
83
85
|
return setIsHidden(true);
|
|
84
86
|
}
|
|
85
87
|
}));
|
|
86
|
-
};
|
|
88
|
+
});
|
|
87
89
|
GenericNotification.displayName = "GenericNotification";
|
|
88
90
|
exports.GenericNotification = GenericNotification;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { __rest, __assign } from 'tslib';
|
|
2
|
-
import React from 'react';
|
|
2
|
+
import React, { forwardRef } from 'react';
|
|
3
3
|
import classnames from 'classnames';
|
|
4
4
|
import { GenericNotification } from '../subcomponents/GenericNotification/GenericNotification.mjs';
|
|
5
5
|
import styles from '../subcomponents/GenericNotification/GenericNotification.module.scss.mjs';
|
|
@@ -9,7 +9,7 @@ import styles from '../subcomponents/GenericNotification/GenericNotification.mod
|
|
|
9
9
|
* {@link https://cultureamp.design/storybook/?path=/docs/components-notifications-inline-notification--docs Storybook}
|
|
10
10
|
*/
|
|
11
11
|
const InlineNotification = /*#__PURE__*/function () {
|
|
12
|
-
const InlineNotification = function (_a) {
|
|
12
|
+
const InlineNotification = /*#__PURE__*/forwardRef(function (_a, ref) {
|
|
13
13
|
var isSubtle = _a.isSubtle,
|
|
14
14
|
_b = _a.hideCloseIcon,
|
|
15
15
|
hideCloseIcon = _b === void 0 ? false : _b,
|
|
@@ -20,9 +20,10 @@ const InlineNotification = /*#__PURE__*/function () {
|
|
|
20
20
|
return /*#__PURE__*/React.createElement(GenericNotification, __assign({
|
|
21
21
|
style: "inline",
|
|
22
22
|
persistent: persistent || hideCloseIcon,
|
|
23
|
-
classNameOverride: classnames(classNameOverride, [isSubtle && styles.subtle])
|
|
23
|
+
classNameOverride: classnames(classNameOverride, [isSubtle && styles.subtle]),
|
|
24
|
+
ref: ref
|
|
24
25
|
}, otherProps));
|
|
25
|
-
};
|
|
26
|
+
});
|
|
26
27
|
InlineNotification.displayName = "InlineNotification";
|
|
27
28
|
return InlineNotification;
|
|
28
29
|
}();
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { __rest, __assign } from 'tslib';
|
|
2
|
-
import React, { useState, useRef, useEffect } from 'react';
|
|
2
|
+
import React, { forwardRef, useState, useRef, useEffect } from 'react';
|
|
3
3
|
import classnames from 'classnames';
|
|
4
|
+
import { isRefObject } from '../../../utils/isRefObject.mjs';
|
|
4
5
|
import { CancelButton } from '../CancelButton/CancelButton.mjs';
|
|
5
6
|
import { NotificationHeading } from '../NotificationHeading/NotificationHeading.mjs';
|
|
6
7
|
import { NotificationIconType, NotificationIconVariant } from '../NotificationIcon/NotificationIcon.mjs';
|
|
7
8
|
import styles from './GenericNotification.module.scss.mjs';
|
|
8
9
|
const GenericNotification = /*#__PURE__*/function () {
|
|
9
|
-
const GenericNotification = function (_a) {
|
|
10
|
+
const GenericNotification = /*#__PURE__*/forwardRef(function (_a, ref) {
|
|
10
11
|
var type = _a.type,
|
|
11
12
|
variant = _a.variant,
|
|
12
13
|
style = _a.style,
|
|
@@ -26,7 +27,8 @@ const GenericNotification = /*#__PURE__*/function () {
|
|
|
26
27
|
var _d = useState(false),
|
|
27
28
|
isRemoved = _d[0],
|
|
28
29
|
setIsRemoved = _d[1];
|
|
29
|
-
var
|
|
30
|
+
var fallbackRef = useRef(null);
|
|
31
|
+
var containerRef = isRefObject(ref) ? ref : fallbackRef;
|
|
30
32
|
useEffect(function () {
|
|
31
33
|
requestAnimationFrame(function () {
|
|
32
34
|
if (containerRef.current) {
|
|
@@ -75,7 +77,7 @@ const GenericNotification = /*#__PURE__*/function () {
|
|
|
75
77
|
return setIsHidden(true);
|
|
76
78
|
}
|
|
77
79
|
}));
|
|
78
|
-
};
|
|
80
|
+
});
|
|
79
81
|
GenericNotification.displayName = "GenericNotification";
|
|
80
82
|
return GenericNotification;
|
|
81
83
|
}();
|
package/dist/styles.css
CHANGED
|
@@ -89,36 +89,6 @@
|
|
|
89
89
|
.MenuItem-module_item__DPerF[data-disabled] {
|
|
90
90
|
opacity: 0.3;
|
|
91
91
|
}
|
|
92
|
-
.Menu-module_menu__iHYqh {
|
|
93
|
-
background-color: var(--color-white);
|
|
94
|
-
color: var(--color-purple-800);
|
|
95
|
-
width: 248px;
|
|
96
|
-
max-height: 22rem;
|
|
97
|
-
overflow: auto;
|
|
98
|
-
padding-block: var(--spacing-6);
|
|
99
|
-
outline: none;
|
|
100
|
-
border-radius: var(--border-solid-border-radius);
|
|
101
|
-
box-shadow: var(--shadow-large-box-shadow);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
.Menu-module_menu__iHYqh .react-aria-Header {
|
|
105
|
-
font-family: var(--typography-heading-6-font-family);
|
|
106
|
-
font-size: var(--typography-heading-6-font-size);
|
|
107
|
-
letter-spacing: var(--typography-heading-6-letter-spacing);
|
|
108
|
-
font-weight: var(--typography-heading-6-font-weight);
|
|
109
|
-
line-height: var(--typography-heading-6-line-height);
|
|
110
|
-
padding: var(--spacing-6) 10px;
|
|
111
|
-
margin-inline: var(--spacing-6);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
.Menu-module_menu__iHYqh section:not(:last-of-type)::after {
|
|
115
|
-
width: 100%;
|
|
116
|
-
height: 1px;
|
|
117
|
-
background-color: var(--border-solid-border-color);
|
|
118
|
-
content: "";
|
|
119
|
-
display: block;
|
|
120
|
-
margin-block: var(--spacing-6);
|
|
121
|
-
}
|
|
122
92
|
.Button-module_button__QOSYH {
|
|
123
93
|
--button-min-height-width: var(--spacing-48);
|
|
124
94
|
--button-padding-x: calc(
|
|
@@ -210,6 +180,36 @@
|
|
|
210
180
|
.Focusable-module_focusableWrapper__NfuIi {
|
|
211
181
|
display: inline-flex;
|
|
212
182
|
}
|
|
183
|
+
.Menu-module_menu__iHYqh {
|
|
184
|
+
background-color: var(--color-white);
|
|
185
|
+
color: var(--color-purple-800);
|
|
186
|
+
width: 248px;
|
|
187
|
+
max-height: 22rem;
|
|
188
|
+
overflow: auto;
|
|
189
|
+
padding-block: var(--spacing-6);
|
|
190
|
+
outline: none;
|
|
191
|
+
border-radius: var(--border-solid-border-radius);
|
|
192
|
+
box-shadow: var(--shadow-large-box-shadow);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
.Menu-module_menu__iHYqh .react-aria-Header {
|
|
196
|
+
font-family: var(--typography-heading-6-font-family);
|
|
197
|
+
font-size: var(--typography-heading-6-font-size);
|
|
198
|
+
letter-spacing: var(--typography-heading-6-letter-spacing);
|
|
199
|
+
font-weight: var(--typography-heading-6-font-weight);
|
|
200
|
+
line-height: var(--typography-heading-6-line-height);
|
|
201
|
+
padding: var(--spacing-6) 10px;
|
|
202
|
+
margin-inline: var(--spacing-6);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
.Menu-module_menu__iHYqh section:not(:last-of-type)::after {
|
|
206
|
+
width: 100%;
|
|
207
|
+
height: 1px;
|
|
208
|
+
background-color: var(--border-solid-border-color);
|
|
209
|
+
content: "";
|
|
210
|
+
display: block;
|
|
211
|
+
margin-block: var(--spacing-6);
|
|
212
|
+
}
|
|
213
213
|
/** THIS IS AN AUTOGENERATED FILE **/
|
|
214
214
|
/** THIS IS AN AUTOGENERATED FILE **/
|
|
215
215
|
.OverlayArrow-module_overlayArrow__hoDyK {
|
|
@@ -5408,6 +5408,10 @@ input[type=range].InputRange-module_ratingScaleRange__gI-rs::-ms-thumb:not(:disa
|
|
|
5408
5408
|
box-sizing: border-box;
|
|
5409
5409
|
pointer-events: all;
|
|
5410
5410
|
}
|
|
5411
|
+
.GenericNotification-module_notification__-JP1M:focus {
|
|
5412
|
+
outline-offset: 1px;
|
|
5413
|
+
outline: 2px solid var(--color-blue-500);
|
|
5414
|
+
}
|
|
5411
5415
|
.GenericNotification-module_notification__-JP1M.GenericNotification-module_inline__OciO5, .GenericNotification-module_notification__-JP1M.GenericNotification-module_toast__GOVfC {
|
|
5412
5416
|
margin-bottom: var(--spacing-24, 1.5rem);
|
|
5413
5417
|
border-width: var(--border-width-1);
|
|
@@ -19,7 +19,4 @@ export type InlineNotificationProps = InlineNotificationBase & (GenericNotificat
|
|
|
19
19
|
* {@link https://cultureamp.atlassian.net/wiki/spaces/DesignSystem/pages/3082093392/Inline+Notification Guidance} |
|
|
20
20
|
* {@link https://cultureamp.design/storybook/?path=/docs/components-notifications-inline-notification--docs Storybook}
|
|
21
21
|
*/
|
|
22
|
-
export declare const InlineNotification:
|
|
23
|
-
({ isSubtle, hideCloseIcon, persistent, classNameOverride, ...otherProps }: InlineNotificationProps): JSX.Element;
|
|
24
|
-
displayName: string;
|
|
25
|
-
};
|
|
22
|
+
export declare const InlineNotification: React.ForwardRefExoticComponent<InlineNotificationProps & React.RefAttributes<HTMLDivElement>>;
|
|
@@ -32,8 +32,5 @@ export type GenericNotificationVariant = {
|
|
|
32
32
|
variant: NotificationVariant;
|
|
33
33
|
};
|
|
34
34
|
export type GenericNotificationProps = GenericNotificationBase & (GenericNotificationType | GenericNotificationVariant);
|
|
35
|
-
export declare const GenericNotification:
|
|
36
|
-
({ type, variant, style, children, title, persistent, onHide, noBottomMargin, forceMultiline, headingProps, classNameOverride, ...restProps }: GenericNotificationProps): JSX.Element | null;
|
|
37
|
-
displayName: string;
|
|
38
|
-
};
|
|
35
|
+
export declare const GenericNotification: React.ForwardRefExoticComponent<GenericNotificationProps & React.RefAttributes<HTMLDivElement>>;
|
|
39
36
|
export {};
|
|
@@ -8,7 +8,7 @@ export type ToggleSwitchProps = {
|
|
|
8
8
|
*/
|
|
9
9
|
onToggle?: React.ChangeEventHandler<HTMLInputElement>;
|
|
10
10
|
reversed?: boolean;
|
|
11
|
-
} & OverrideClassName<Omit<InputHTMLAttributes<HTMLInputElement>, "onChange">>;
|
|
11
|
+
} & OverrideClassName<Omit<InputHTMLAttributes<HTMLInputElement>, "onChange" | "onToggle">>;
|
|
12
12
|
export declare const ToggleSwitch: {
|
|
13
13
|
({ toggledStatus, onToggle, reversed, ...restProps }: ToggleSwitchProps): JSX.Element;
|
|
14
14
|
displayName: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kaizen/components",
|
|
3
|
-
"version": "1.64.
|
|
3
|
+
"version": "1.64.4",
|
|
4
4
|
"description": "Kaizen component library",
|
|
5
5
|
"author": "Geoffrey Chong <geoff.chong@cultureamp.com>",
|
|
6
6
|
"homepage": "https://cultureamp.design",
|
|
@@ -120,8 +120,8 @@
|
|
|
120
120
|
"svgo": "^3.3.2",
|
|
121
121
|
"tslib": "^2.6.3",
|
|
122
122
|
"tsx": "^4.17.0",
|
|
123
|
-
"@kaizen/
|
|
124
|
-
"@kaizen/
|
|
123
|
+
"@kaizen/package-bundler": "1.1.5",
|
|
124
|
+
"@kaizen/design-tokens": "10.6.1"
|
|
125
125
|
},
|
|
126
126
|
"peerDependencies": {
|
|
127
127
|
"@cultureamp/i18n-react-intl": "^2.5.9",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { HTMLAttributes } from "react"
|
|
1
|
+
import React, { forwardRef, HTMLAttributes } from "react"
|
|
2
2
|
import classnames from "classnames"
|
|
3
3
|
import { HeadingProps } from "~components/Heading"
|
|
4
4
|
import { OverrideClassName } from "~components/types/OverrideClassName"
|
|
@@ -30,21 +30,30 @@ export type InlineNotificationProps = InlineNotificationBase &
|
|
|
30
30
|
* {@link https://cultureamp.atlassian.net/wiki/spaces/DesignSystem/pages/3082093392/Inline+Notification Guidance} |
|
|
31
31
|
* {@link https://cultureamp.design/storybook/?path=/docs/components-notifications-inline-notification--docs Storybook}
|
|
32
32
|
*/
|
|
33
|
-
export const InlineNotification =
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
33
|
+
export const InlineNotification = forwardRef<
|
|
34
|
+
HTMLDivElement,
|
|
35
|
+
InlineNotificationProps
|
|
36
|
+
>(
|
|
37
|
+
(
|
|
38
|
+
{
|
|
39
|
+
isSubtle,
|
|
40
|
+
hideCloseIcon = false,
|
|
41
|
+
persistent = false,
|
|
42
|
+
classNameOverride,
|
|
43
|
+
...otherProps
|
|
44
|
+
},
|
|
45
|
+
ref
|
|
46
|
+
): JSX.Element => (
|
|
47
|
+
<GenericNotification
|
|
48
|
+
style="inline"
|
|
49
|
+
persistent={persistent || hideCloseIcon}
|
|
50
|
+
classNameOverride={classnames(classNameOverride, [
|
|
51
|
+
isSubtle && styles.subtle,
|
|
52
|
+
])}
|
|
53
|
+
ref={ref}
|
|
54
|
+
{...otherProps}
|
|
55
|
+
/>
|
|
56
|
+
)
|
|
48
57
|
)
|
|
49
58
|
|
|
50
59
|
InlineNotification.displayName = "InlineNotification"
|
package/src/Notification/InlineNotification/_docs/InlineNotification.stickersheet.stories.tsx
CHANGED
|
@@ -131,6 +131,19 @@ const VARIANTS_PROPS: Array<{
|
|
|
131
131
|
forceMultiline: true,
|
|
132
132
|
},
|
|
133
133
|
},
|
|
134
|
+
{
|
|
135
|
+
title: "Focus",
|
|
136
|
+
props: {
|
|
137
|
+
// @ts-ignore
|
|
138
|
+
"data-sb-pseudo-styles": "focus",
|
|
139
|
+
variant: "informative",
|
|
140
|
+
headingProps: {
|
|
141
|
+
variant: "heading-6",
|
|
142
|
+
tag: "span",
|
|
143
|
+
children: "Focused title",
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
},
|
|
134
147
|
]
|
|
135
148
|
|
|
136
149
|
const TYPE_PROPS: Array<{
|
|
@@ -206,6 +219,11 @@ const StickerSheetTemplate: StickerSheetStory = {
|
|
|
206
219
|
</StickerSheet>
|
|
207
220
|
</>
|
|
208
221
|
),
|
|
222
|
+
parameters: {
|
|
223
|
+
pseudo: {
|
|
224
|
+
focus: '[data-sb-pseudo-styles="focus"]',
|
|
225
|
+
},
|
|
226
|
+
},
|
|
209
227
|
}
|
|
210
228
|
|
|
211
229
|
export const StickerSheetDefault: StickerSheetStory = {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useState } from "react"
|
|
1
|
+
import React, { useRef, useState } from "react"
|
|
2
2
|
import { Meta, StoryObj } from "@storybook/react"
|
|
3
3
|
import { userEvent, within, expect, waitFor } from "@storybook/test"
|
|
4
4
|
import { GenericNotification } from "./index"
|
|
@@ -58,3 +58,46 @@ export const GenericNotificationTest: Story = {
|
|
|
58
58
|
})
|
|
59
59
|
},
|
|
60
60
|
}
|
|
61
|
+
|
|
62
|
+
export const RefTest: Story = {
|
|
63
|
+
render: () => {
|
|
64
|
+
const customRef = useRef<HTMLDivElement>(null)
|
|
65
|
+
const [isHidden, setIsHidden] = useState<boolean>(false)
|
|
66
|
+
|
|
67
|
+
return (
|
|
68
|
+
<div>
|
|
69
|
+
<span data-testid="hidden-state">{isHidden ? "Hidden" : "Shown"}</span>
|
|
70
|
+
<GenericNotification
|
|
71
|
+
ref={customRef}
|
|
72
|
+
variant="success"
|
|
73
|
+
style="inline"
|
|
74
|
+
title="Success"
|
|
75
|
+
data-testid="generic-notification"
|
|
76
|
+
onHide={() => setIsHidden(true)}
|
|
77
|
+
>
|
|
78
|
+
This is my positive notification
|
|
79
|
+
</GenericNotification>
|
|
80
|
+
</div>
|
|
81
|
+
)
|
|
82
|
+
},
|
|
83
|
+
name: "Test: still renders and closes properly when custom ref passed in",
|
|
84
|
+
play: async ({ canvasElement }) => {
|
|
85
|
+
const canvas = within(canvasElement)
|
|
86
|
+
const element = canvas.getByTestId("generic-notification")
|
|
87
|
+
const hiddenState = canvas.getByTestId("hidden-state")
|
|
88
|
+
|
|
89
|
+
await waitFor(() => {
|
|
90
|
+
expect(element).toBeInTheDocument()
|
|
91
|
+
expect(hiddenState).toHaveTextContent("Shown")
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
await userEvent.click(canvas.getByTestId("close-button"))
|
|
95
|
+
|
|
96
|
+
await waitFor(() => {
|
|
97
|
+
setTimeout(() => {
|
|
98
|
+
expect(hiddenState).toHaveTextContent("Hidden")
|
|
99
|
+
expect(element).not.toBeInTheDocument()
|
|
100
|
+
}, 1000)
|
|
101
|
+
})
|
|
102
|
+
},
|
|
103
|
+
}
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, {
|
|
2
|
+
forwardRef,
|
|
3
|
+
HTMLAttributes,
|
|
4
|
+
useEffect,
|
|
5
|
+
useRef,
|
|
6
|
+
useState,
|
|
7
|
+
} from "react"
|
|
2
8
|
import classnames from "classnames"
|
|
3
9
|
import { HeadingProps } from "~components/Heading"
|
|
4
10
|
import {
|
|
@@ -6,6 +12,7 @@ import {
|
|
|
6
12
|
NotificationVariant,
|
|
7
13
|
} from "~components/Notification/types"
|
|
8
14
|
import { OverrideClassName } from "~components/types/OverrideClassName"
|
|
15
|
+
import { isRefObject } from "~components/utils/isRefObject"
|
|
9
16
|
import { CancelButton } from "../CancelButton"
|
|
10
17
|
import { NotificationHeading } from "../NotificationHeading"
|
|
11
18
|
import {
|
|
@@ -49,89 +56,103 @@ export type GenericNotificationVariant = {
|
|
|
49
56
|
export type GenericNotificationProps = GenericNotificationBase &
|
|
50
57
|
(GenericNotificationType | GenericNotificationVariant)
|
|
51
58
|
|
|
52
|
-
export const GenericNotification =
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
59
|
+
export const GenericNotification = forwardRef<
|
|
60
|
+
HTMLDivElement,
|
|
61
|
+
GenericNotificationProps
|
|
62
|
+
>(
|
|
63
|
+
(
|
|
64
|
+
{
|
|
65
|
+
type,
|
|
66
|
+
variant,
|
|
67
|
+
style,
|
|
68
|
+
children,
|
|
69
|
+
title,
|
|
70
|
+
persistent = false,
|
|
71
|
+
onHide,
|
|
72
|
+
noBottomMargin,
|
|
73
|
+
forceMultiline,
|
|
74
|
+
headingProps,
|
|
75
|
+
classNameOverride,
|
|
76
|
+
...restProps
|
|
77
|
+
},
|
|
78
|
+
ref
|
|
79
|
+
): JSX.Element | null => {
|
|
80
|
+
const [isHidden, setIsHidden] = useState<boolean>(true)
|
|
81
|
+
const [isRemoved, setIsRemoved] = useState<boolean>(false)
|
|
68
82
|
|
|
69
|
-
|
|
83
|
+
const fallbackRef = useRef<HTMLDivElement>(null)
|
|
84
|
+
const containerRef = isRefObject(ref) ? ref : fallbackRef
|
|
70
85
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
86
|
+
useEffect(() => {
|
|
87
|
+
requestAnimationFrame(() => {
|
|
88
|
+
if (containerRef.current) {
|
|
89
|
+
setIsHidden(false)
|
|
90
|
+
}
|
|
91
|
+
})
|
|
92
|
+
}, [])
|
|
78
93
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
94
|
+
const getMarginTop = (): string => {
|
|
95
|
+
if (isHidden && containerRef.current) {
|
|
96
|
+
return -containerRef.current.clientHeight + "px"
|
|
97
|
+
}
|
|
98
|
+
return "0"
|
|
82
99
|
}
|
|
83
|
-
return "0"
|
|
84
|
-
}
|
|
85
100
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
101
|
+
const onTransitionEnd = (
|
|
102
|
+
e: React.TransitionEvent<HTMLDivElement>
|
|
103
|
+
): void => {
|
|
104
|
+
// Be careful: this assumes the final CSS property to be animated is "margin-top".
|
|
105
|
+
if (isHidden && e.propertyName === "margin-top") {
|
|
106
|
+
setIsRemoved(true)
|
|
107
|
+
onHide?.()
|
|
108
|
+
}
|
|
91
109
|
}
|
|
92
|
-
}
|
|
93
110
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
111
|
+
if (isRemoved) {
|
|
112
|
+
return null
|
|
113
|
+
}
|
|
97
114
|
|
|
98
|
-
|
|
99
|
-
<div
|
|
100
|
-
ref={containerRef}
|
|
101
|
-
className={classnames(
|
|
102
|
-
styles.notification,
|
|
103
|
-
variant ? styles[variant] : styles[type],
|
|
104
|
-
styles[style],
|
|
105
|
-
isHidden && styles.hidden,
|
|
106
|
-
noBottomMargin && styles.noBottomMargin,
|
|
107
|
-
classNameOverride,
|
|
108
|
-
persistent && styles.persistent
|
|
109
|
-
)}
|
|
110
|
-
style={{ marginTop: getMarginTop() }}
|
|
111
|
-
onTransitionEnd={onTransitionEnd}
|
|
112
|
-
{...restProps}
|
|
113
|
-
>
|
|
114
|
-
<div className={styles.icon}>
|
|
115
|
-
{type ? (
|
|
116
|
-
<NotificationIconType type={type} />
|
|
117
|
-
) : (
|
|
118
|
-
<NotificationIconVariant variant={variant} />
|
|
119
|
-
)}
|
|
120
|
-
</div>
|
|
115
|
+
return (
|
|
121
116
|
<div
|
|
117
|
+
ref={containerRef}
|
|
122
118
|
className={classnames(
|
|
123
|
-
styles.
|
|
124
|
-
|
|
119
|
+
styles.notification,
|
|
120
|
+
variant ? styles[variant] : styles[type],
|
|
121
|
+
styles[style],
|
|
122
|
+
isHidden && styles.hidden,
|
|
123
|
+
noBottomMargin && styles.noBottomMargin,
|
|
124
|
+
classNameOverride,
|
|
125
|
+
persistent && styles.persistent
|
|
125
126
|
)}
|
|
127
|
+
style={{ marginTop: getMarginTop() }}
|
|
128
|
+
onTransitionEnd={onTransitionEnd}
|
|
129
|
+
{...restProps}
|
|
126
130
|
>
|
|
127
|
-
{
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
+
<div className={styles.icon}>
|
|
132
|
+
{type ? (
|
|
133
|
+
<NotificationIconType type={type} />
|
|
134
|
+
) : (
|
|
135
|
+
<NotificationIconVariant variant={variant} />
|
|
136
|
+
)}
|
|
137
|
+
</div>
|
|
138
|
+
<div
|
|
139
|
+
className={classnames(
|
|
140
|
+
styles.textContainer,
|
|
141
|
+
forceMultiline && styles.forceMultiline
|
|
142
|
+
)}
|
|
143
|
+
>
|
|
144
|
+
{style !== "global" && (
|
|
145
|
+
<NotificationHeading
|
|
146
|
+
titleProp={title}
|
|
147
|
+
headingProps={headingProps}
|
|
148
|
+
/>
|
|
149
|
+
)}
|
|
150
|
+
{children && <div className={styles.text}>{children}</div>}
|
|
151
|
+
</div>
|
|
152
|
+
{!persistent && <CancelButton onClick={() => setIsHidden(true)} />}
|
|
131
153
|
</div>
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
}
|
|
154
|
+
)
|
|
155
|
+
}
|
|
156
|
+
)
|
|
136
157
|
|
|
137
158
|
GenericNotification.displayName = "GenericNotification"
|
|
@@ -22,6 +22,11 @@ $notification-slide-right: transform 300ms ease-out;
|
|
|
22
22
|
box-sizing: border-box;
|
|
23
23
|
pointer-events: all;
|
|
24
24
|
|
|
25
|
+
&:focus {
|
|
26
|
+
outline-offset: 1px;
|
|
27
|
+
outline: 2px solid var(--color-blue-500);
|
|
28
|
+
}
|
|
29
|
+
|
|
25
30
|
// Variants
|
|
26
31
|
&%ca-notification---inline,
|
|
27
32
|
&%ca-notification---toast {
|
|
@@ -13,7 +13,9 @@ export type ToggleSwitchProps = {
|
|
|
13
13
|
*/
|
|
14
14
|
onToggle?: React.ChangeEventHandler<HTMLInputElement>
|
|
15
15
|
reversed?: boolean
|
|
16
|
-
} & OverrideClassName<
|
|
16
|
+
} & OverrideClassName<
|
|
17
|
+
Omit<InputHTMLAttributes<HTMLInputElement>, "onChange" | "onToggle">
|
|
18
|
+
>
|
|
17
19
|
|
|
18
20
|
export const ToggleSwitch = ({
|
|
19
21
|
toggledStatus,
|