@cerberus-design/react 0.14.2-next-6531b4c → 0.14.2-next-58af9c8
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/build/legacy/_tsup-dts-rollup.d.cts +77 -1
- package/build/legacy/components/Notification.cjs +1 -0
- package/build/legacy/components/Notification.cjs.map +1 -1
- package/build/legacy/context/notification-center/store.cjs +66 -0
- package/build/legacy/context/notification-center/store.cjs.map +1 -0
- package/build/legacy/context/notification-center/types.cjs +19 -0
- package/build/legacy/context/notification-center/types.cjs.map +1 -0
- package/build/legacy/context/notification-center.cjs +102 -58
- package/build/legacy/context/notification-center.cjs.map +1 -1
- package/build/legacy/index.cjs +102 -58
- package/build/legacy/index.cjs.map +1 -1
- package/build/modern/_tsup-dts-rollup.d.ts +77 -1
- package/build/modern/{chunk-JQCRDZNI.js → chunk-BAWZBF5Q.js} +4 -4
- package/build/modern/{chunk-UMF2TWZN.js → chunk-D252JE4V.js} +7 -7
- package/build/modern/{chunk-KF35CYT4.js → chunk-RDRD6ACD.js} +2 -1
- package/build/modern/{chunk-KF35CYT4.js.map → chunk-RDRD6ACD.js.map} +1 -1
- package/build/modern/{chunk-EMNBMH7Z.js → chunk-USYM6XU6.js} +4 -4
- package/build/modern/chunk-V3M3ZOQI.js +38 -0
- package/build/modern/chunk-V3M3ZOQI.js.map +1 -0
- package/build/modern/{chunk-Z64YZ5IH.js → chunk-XDDLXEFV.js} +13 -13
- package/build/modern/{chunk-CCTLGF5U.js → chunk-YJI4Y7BH.js} +13 -13
- package/build/modern/chunk-YLMGZAKU.js +180 -0
- package/build/modern/chunk-YLMGZAKU.js.map +1 -0
- package/build/modern/{chunk-QKZZHZL4.js → chunk-ZHBHPMTP.js} +16 -16
- package/build/modern/components/AccordionItemGroup.js +3 -3
- package/build/modern/components/DatePicker.client.js +3 -3
- package/build/modern/components/FileStatus.js +2 -2
- package/build/modern/components/Notification.js +1 -1
- package/build/modern/context/confirm-modal.js +5 -5
- package/build/modern/context/cta-modal.js +5 -5
- package/build/modern/context/notification-center/store.js +15 -0
- package/build/modern/context/notification-center/store.js.map +1 -0
- package/build/modern/context/notification-center/types.js +1 -0
- package/build/modern/context/notification-center/types.js.map +1 -0
- package/build/modern/context/notification-center.js +4 -3
- package/build/modern/context/prompt-modal.js +6 -6
- package/build/modern/index.js +82 -81
- package/build/modern/index.js.map +1 -1
- package/package.json +2 -2
- package/src/components/Notification.tsx +2 -0
- package/src/context/notification-center/store.ts +88 -0
- package/src/context/notification-center/types.ts +28 -0
- package/src/context/notification-center.tsx +81 -46
- package/build/modern/chunk-N3L3PEMF.js +0 -162
- package/build/modern/chunk-N3L3PEMF.js.map +0 -1
- /package/build/modern/{chunk-JQCRDZNI.js.map → chunk-BAWZBF5Q.js.map} +0 -0
- /package/build/modern/{chunk-UMF2TWZN.js.map → chunk-D252JE4V.js.map} +0 -0
- /package/build/modern/{chunk-EMNBMH7Z.js.map → chunk-USYM6XU6.js.map} +0 -0
- /package/build/modern/{chunk-Z64YZ5IH.js.map → chunk-XDDLXEFV.js.map} +0 -0
- /package/build/modern/{chunk-CCTLGF5U.js.map → chunk-YJI4Y7BH.js.map} +0 -0
- /package/build/modern/{chunk-QKZZHZL4.js.map → chunk-ZHBHPMTP.js.map} +0 -0
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
useCallback,
|
|
6
6
|
useContext,
|
|
7
7
|
useMemo,
|
|
8
|
-
|
|
8
|
+
useReducer,
|
|
9
9
|
type MouseEvent,
|
|
10
10
|
type PropsWithChildren,
|
|
11
11
|
type ReactNode,
|
|
@@ -19,6 +19,13 @@ import { Portal, type PortalProps } from '../components/Portal'
|
|
|
19
19
|
import { notification } from '@cerberus/styled-system/recipes'
|
|
20
20
|
import { Button } from '../components/Button'
|
|
21
21
|
import { cx } from '@cerberus/styled-system/css'
|
|
22
|
+
import {
|
|
23
|
+
addNotification,
|
|
24
|
+
clearNotificationState,
|
|
25
|
+
notificationCenterReducer,
|
|
26
|
+
removeNotification,
|
|
27
|
+
updateNotificationState,
|
|
28
|
+
} from './notification-center/store'
|
|
22
29
|
|
|
23
30
|
/**
|
|
24
31
|
* This module provides a context and hook for notifications.
|
|
@@ -55,7 +62,13 @@ export interface NotificationsValue {
|
|
|
55
62
|
|
|
56
63
|
const NotificationsContext = createContext<NotificationsValue | null>(null)
|
|
57
64
|
|
|
58
|
-
export type NotificationsProviderProps = PortalProps
|
|
65
|
+
export type NotificationsProviderProps = PortalProps & {
|
|
66
|
+
/**
|
|
67
|
+
* The duration in milliseconds to show the notification.
|
|
68
|
+
* @default 6000
|
|
69
|
+
*/
|
|
70
|
+
duration?: number
|
|
71
|
+
}
|
|
59
72
|
|
|
60
73
|
/**
|
|
61
74
|
* Provides a notification center to the app.
|
|
@@ -82,35 +95,58 @@ export type NotificationsProviderProps = PortalProps
|
|
|
82
95
|
export function NotificationCenter(
|
|
83
96
|
props: PropsWithChildren<NotificationsProviderProps>,
|
|
84
97
|
) {
|
|
85
|
-
const [
|
|
86
|
-
NotifyOptions[]
|
|
87
|
-
>([])
|
|
98
|
+
const [state, dispatch] = useReducer(notificationCenterReducer, [])
|
|
88
99
|
const styles = notification()
|
|
89
100
|
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
})
|
|
95
|
-
}, [])
|
|
96
|
-
|
|
97
|
-
const handleClose = useCallback((e: MouseEvent<HTMLButtonElement>) => {
|
|
98
|
-
const target = e.currentTarget as HTMLButtonElement
|
|
99
|
-
setActiveNotifications((prev) => {
|
|
100
|
-
const item = prev.find((option) => option.id === target.value)
|
|
101
|
-
if (item?.onClose) item.onClose()
|
|
102
|
-
return prev.filter((option) => option.id !== target.value)
|
|
103
|
-
})
|
|
104
|
-
}, [])
|
|
101
|
+
const timeout = useMemo<number>(
|
|
102
|
+
() => props.duration || 6000,
|
|
103
|
+
[props.duration],
|
|
104
|
+
)
|
|
105
105
|
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
106
|
+
const closeNotification = useCallback(
|
|
107
|
+
(id: string) => {
|
|
108
|
+
updateNotificationState(dispatch, {
|
|
109
|
+
id,
|
|
110
|
+
state: 'closed',
|
|
111
|
+
})
|
|
112
|
+
setTimeout(() => {
|
|
113
|
+
removeNotification(dispatch, id)
|
|
114
|
+
}, 150)
|
|
115
|
+
},
|
|
116
|
+
[dispatch],
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
const handleNotify = useCallback(
|
|
120
|
+
(options: NotifyOptions) => {
|
|
121
|
+
const id = `${options.palette}:${state.length + 1}`
|
|
122
|
+
addNotification(dispatch, {
|
|
123
|
+
...options,
|
|
124
|
+
id,
|
|
125
|
+
state: 'open',
|
|
110
126
|
})
|
|
111
|
-
|
|
127
|
+
|
|
128
|
+
setTimeout(() => {
|
|
129
|
+
closeNotification(id)
|
|
130
|
+
}, timeout)
|
|
131
|
+
},
|
|
132
|
+
[dispatch, state, timeout, closeNotification],
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
const handleClose = useCallback(
|
|
136
|
+
(e: MouseEvent<HTMLButtonElement>) => {
|
|
137
|
+
const target = e.currentTarget as HTMLButtonElement
|
|
138
|
+
closeNotification(target.value)
|
|
139
|
+
},
|
|
140
|
+
[closeNotification],
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
const handleCloseAll = useCallback(() => {
|
|
144
|
+
state.forEach((item) => {
|
|
145
|
+
if (item.onClose) item.onClose()
|
|
112
146
|
})
|
|
113
|
-
|
|
147
|
+
// we don't want to animate out for this one
|
|
148
|
+
clearNotificationState(dispatch)
|
|
149
|
+
}, [state, dispatch])
|
|
114
150
|
|
|
115
151
|
const value = useMemo(
|
|
116
152
|
() => ({
|
|
@@ -126,10 +162,10 @@ export function NotificationCenter(
|
|
|
126
162
|
<NotificationsContext.Provider value={value}>
|
|
127
163
|
{props.children}
|
|
128
164
|
|
|
129
|
-
<Show when={
|
|
165
|
+
<Show when={state.length > 0}>
|
|
130
166
|
<Portal container={props.container}>
|
|
131
167
|
<div className={styles.center}>
|
|
132
|
-
<Show when={
|
|
168
|
+
<Show when={state.length >= 4}>
|
|
133
169
|
<Button
|
|
134
170
|
className={cx(styles.closeAll, animateIn())}
|
|
135
171
|
onClick={handleCloseAll}
|
|
@@ -151,11 +187,12 @@ export function NotificationCenter(
|
|
|
151
187
|
alignItems: 'flex-end',
|
|
152
188
|
}}
|
|
153
189
|
>
|
|
154
|
-
{
|
|
190
|
+
{state.map((option) => (
|
|
155
191
|
<MatchNotification
|
|
156
192
|
key={option.id}
|
|
157
193
|
{...option}
|
|
158
194
|
onClose={handleClose}
|
|
195
|
+
open={option.state}
|
|
159
196
|
/>
|
|
160
197
|
))}
|
|
161
198
|
</div>
|
|
@@ -167,23 +204,27 @@ export function NotificationCenter(
|
|
|
167
204
|
}
|
|
168
205
|
|
|
169
206
|
interface MatchNotificationProps extends Omit<NotifyOptions, 'onClose'> {
|
|
207
|
+
open: 'open' | 'closed'
|
|
170
208
|
onClose: (e: MouseEvent<HTMLButtonElement>) => void
|
|
171
209
|
key: string | undefined
|
|
172
210
|
}
|
|
173
211
|
|
|
174
212
|
function MatchNotification(props: MatchNotificationProps) {
|
|
175
|
-
const { palette, id, onClose, heading, description } = props
|
|
213
|
+
const { palette, id, onClose, heading, description, open } = props
|
|
214
|
+
const sharedProps = useMemo(
|
|
215
|
+
() => ({
|
|
216
|
+
id: id!,
|
|
217
|
+
open: true,
|
|
218
|
+
onClose,
|
|
219
|
+
'data-state': open,
|
|
220
|
+
}),
|
|
221
|
+
[id, open, onClose],
|
|
222
|
+
)
|
|
176
223
|
|
|
177
224
|
switch (palette) {
|
|
178
225
|
case 'success':
|
|
179
226
|
return (
|
|
180
|
-
<Notification
|
|
181
|
-
id={id!}
|
|
182
|
-
key={id}
|
|
183
|
-
onClose={onClose}
|
|
184
|
-
open
|
|
185
|
-
palette="success"
|
|
186
|
-
>
|
|
227
|
+
<Notification {...sharedProps} palette="success">
|
|
187
228
|
<NotificationHeading palette="success">{heading}</NotificationHeading>
|
|
188
229
|
<NotificationDescription palette="success">
|
|
189
230
|
{description}
|
|
@@ -193,13 +234,7 @@ function MatchNotification(props: MatchNotificationProps) {
|
|
|
193
234
|
|
|
194
235
|
case 'warning':
|
|
195
236
|
return (
|
|
196
|
-
<Notification
|
|
197
|
-
id={id!}
|
|
198
|
-
key={id}
|
|
199
|
-
onClose={onClose}
|
|
200
|
-
open
|
|
201
|
-
palette="warning"
|
|
202
|
-
>
|
|
237
|
+
<Notification {...sharedProps} palette="warning">
|
|
203
238
|
<NotificationHeading palette="warning">{heading}</NotificationHeading>
|
|
204
239
|
<NotificationDescription palette="warning">
|
|
205
240
|
{description}
|
|
@@ -209,7 +244,7 @@ function MatchNotification(props: MatchNotificationProps) {
|
|
|
209
244
|
|
|
210
245
|
case 'danger':
|
|
211
246
|
return (
|
|
212
|
-
<Notification
|
|
247
|
+
<Notification {...sharedProps} palette="danger">
|
|
213
248
|
<NotificationHeading palette="danger">{heading}</NotificationHeading>
|
|
214
249
|
<NotificationDescription palette="danger">
|
|
215
250
|
{description}
|
|
@@ -220,7 +255,7 @@ function MatchNotification(props: MatchNotificationProps) {
|
|
|
220
255
|
case 'info':
|
|
221
256
|
default:
|
|
222
257
|
return (
|
|
223
|
-
<Notification
|
|
258
|
+
<Notification {...sharedProps} palette="info">
|
|
224
259
|
<NotificationHeading palette="info">{heading}</NotificationHeading>
|
|
225
260
|
<NotificationDescription palette="info">
|
|
226
261
|
{description}
|
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Notification
|
|
3
|
-
} from "./chunk-KF35CYT4.js";
|
|
4
|
-
import {
|
|
5
|
-
NotificationDescription
|
|
6
|
-
} from "./chunk-UXY3KCC3.js";
|
|
7
|
-
import {
|
|
8
|
-
NotificationHeading
|
|
9
|
-
} from "./chunk-SLHYBPJ5.js";
|
|
10
|
-
import {
|
|
11
|
-
Portal
|
|
12
|
-
} from "./chunk-IQJDVFPP.js";
|
|
13
|
-
import {
|
|
14
|
-
Button
|
|
15
|
-
} from "./chunk-EXGKZGML.js";
|
|
16
|
-
import {
|
|
17
|
-
Show
|
|
18
|
-
} from "./chunk-BUVVRQLZ.js";
|
|
19
|
-
|
|
20
|
-
// src/context/notification-center.tsx
|
|
21
|
-
import {
|
|
22
|
-
createContext,
|
|
23
|
-
useCallback,
|
|
24
|
-
useContext,
|
|
25
|
-
useMemo,
|
|
26
|
-
useState
|
|
27
|
-
} from "react";
|
|
28
|
-
import { animateIn, vstack } from "@cerberus/styled-system/patterns";
|
|
29
|
-
import { notification } from "@cerberus/styled-system/recipes";
|
|
30
|
-
import { cx } from "@cerberus/styled-system/css";
|
|
31
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
32
|
-
var NotificationsContext = createContext(null);
|
|
33
|
-
function NotificationCenter(props) {
|
|
34
|
-
const [activeNotifications, setActiveNotifications] = useState([]);
|
|
35
|
-
const styles = notification();
|
|
36
|
-
const handleNotify = useCallback((options) => {
|
|
37
|
-
setActiveNotifications((prev) => {
|
|
38
|
-
const id = `${options.palette}:${prev.length + 1}`;
|
|
39
|
-
return [...prev, { ...options, id }];
|
|
40
|
-
});
|
|
41
|
-
}, []);
|
|
42
|
-
const handleClose = useCallback((e) => {
|
|
43
|
-
const target = e.currentTarget;
|
|
44
|
-
setActiveNotifications((prev) => {
|
|
45
|
-
const item = prev.find((option) => option.id === target.value);
|
|
46
|
-
if (item?.onClose) item.onClose();
|
|
47
|
-
return prev.filter((option) => option.id !== target.value);
|
|
48
|
-
});
|
|
49
|
-
}, []);
|
|
50
|
-
const handleCloseAll = useCallback(() => {
|
|
51
|
-
setActiveNotifications((prev) => {
|
|
52
|
-
prev.forEach((item) => {
|
|
53
|
-
if (item.onClose) item.onClose();
|
|
54
|
-
});
|
|
55
|
-
return [];
|
|
56
|
-
});
|
|
57
|
-
}, []);
|
|
58
|
-
const value = useMemo(
|
|
59
|
-
() => ({
|
|
60
|
-
notify: handleNotify
|
|
61
|
-
}),
|
|
62
|
-
[handleNotify]
|
|
63
|
-
);
|
|
64
|
-
return /* @__PURE__ */ jsxs(NotificationsContext.Provider, { value, children: [
|
|
65
|
-
props.children,
|
|
66
|
-
/* @__PURE__ */ jsx(Show, { when: activeNotifications.length > 0, children: /* @__PURE__ */ jsx(Portal, { container: props.container, children: /* @__PURE__ */ jsxs("div", { className: styles.center, children: [
|
|
67
|
-
/* @__PURE__ */ jsx(Show, { when: activeNotifications.length >= 4, children: /* @__PURE__ */ jsx(
|
|
68
|
-
Button,
|
|
69
|
-
{
|
|
70
|
-
className: cx(styles.closeAll, animateIn()),
|
|
71
|
-
onClick: handleCloseAll,
|
|
72
|
-
palette: "action",
|
|
73
|
-
shape: "rounded",
|
|
74
|
-
size: "sm",
|
|
75
|
-
usage: "ghost",
|
|
76
|
-
children: "Close all"
|
|
77
|
-
}
|
|
78
|
-
) }),
|
|
79
|
-
/* @__PURE__ */ jsx(
|
|
80
|
-
"div",
|
|
81
|
-
{
|
|
82
|
-
className: vstack({
|
|
83
|
-
alignItems: "flex-end",
|
|
84
|
-
gap: "4"
|
|
85
|
-
}),
|
|
86
|
-
style: {
|
|
87
|
-
alignItems: "flex-end"
|
|
88
|
-
},
|
|
89
|
-
children: activeNotifications.map((option) => /* @__PURE__ */ jsx(
|
|
90
|
-
MatchNotification,
|
|
91
|
-
{
|
|
92
|
-
...option,
|
|
93
|
-
onClose: handleClose
|
|
94
|
-
},
|
|
95
|
-
option.id
|
|
96
|
-
))
|
|
97
|
-
}
|
|
98
|
-
)
|
|
99
|
-
] }) }) })
|
|
100
|
-
] });
|
|
101
|
-
}
|
|
102
|
-
function MatchNotification(props) {
|
|
103
|
-
const { palette, id, onClose, heading, description } = props;
|
|
104
|
-
switch (palette) {
|
|
105
|
-
case "success":
|
|
106
|
-
return /* @__PURE__ */ jsxs(
|
|
107
|
-
Notification,
|
|
108
|
-
{
|
|
109
|
-
id,
|
|
110
|
-
onClose,
|
|
111
|
-
open: true,
|
|
112
|
-
palette: "success",
|
|
113
|
-
children: [
|
|
114
|
-
/* @__PURE__ */ jsx(NotificationHeading, { palette: "success", children: heading }),
|
|
115
|
-
/* @__PURE__ */ jsx(NotificationDescription, { palette: "success", children: description })
|
|
116
|
-
]
|
|
117
|
-
},
|
|
118
|
-
id
|
|
119
|
-
);
|
|
120
|
-
case "warning":
|
|
121
|
-
return /* @__PURE__ */ jsxs(
|
|
122
|
-
Notification,
|
|
123
|
-
{
|
|
124
|
-
id,
|
|
125
|
-
onClose,
|
|
126
|
-
open: true,
|
|
127
|
-
palette: "warning",
|
|
128
|
-
children: [
|
|
129
|
-
/* @__PURE__ */ jsx(NotificationHeading, { palette: "warning", children: heading }),
|
|
130
|
-
/* @__PURE__ */ jsx(NotificationDescription, { palette: "warning", children: description })
|
|
131
|
-
]
|
|
132
|
-
},
|
|
133
|
-
id
|
|
134
|
-
);
|
|
135
|
-
case "danger":
|
|
136
|
-
return /* @__PURE__ */ jsxs(Notification, { id, onClose, open: true, palette: "danger", children: [
|
|
137
|
-
/* @__PURE__ */ jsx(NotificationHeading, { palette: "danger", children: heading }),
|
|
138
|
-
/* @__PURE__ */ jsx(NotificationDescription, { palette: "danger", children: description })
|
|
139
|
-
] }, id);
|
|
140
|
-
case "info":
|
|
141
|
-
default:
|
|
142
|
-
return /* @__PURE__ */ jsxs(Notification, { id, onClose, open: true, palette: "info", children: [
|
|
143
|
-
/* @__PURE__ */ jsx(NotificationHeading, { palette: "info", children: heading }),
|
|
144
|
-
/* @__PURE__ */ jsx(NotificationDescription, { palette: "info", children: description })
|
|
145
|
-
] }, id);
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
function useNotificationCenter() {
|
|
149
|
-
const context = useContext(NotificationsContext);
|
|
150
|
-
if (!context) {
|
|
151
|
-
throw new Error(
|
|
152
|
-
"useNotificationCenter must be used within a NotificationsProvider"
|
|
153
|
-
);
|
|
154
|
-
}
|
|
155
|
-
return context;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
export {
|
|
159
|
-
NotificationCenter,
|
|
160
|
-
useNotificationCenter
|
|
161
|
-
};
|
|
162
|
-
//# sourceMappingURL=chunk-N3L3PEMF.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/context/notification-center.tsx"],"sourcesContent":["'use client'\n\nimport {\n createContext,\n useCallback,\n useContext,\n useMemo,\n useState,\n type MouseEvent,\n type PropsWithChildren,\n type ReactNode,\n} from 'react'\nimport { Show } from '../components/Show'\nimport { NotificationHeading } from '../components/NotificationHeading'\nimport { NotificationDescription } from '../components/NotificationDescription'\nimport { Notification } from '../components/Notification'\nimport { animateIn, vstack } from '@cerberus/styled-system/patterns'\nimport { Portal, type PortalProps } from '../components/Portal'\nimport { notification } from '@cerberus/styled-system/recipes'\nimport { Button } from '../components/Button'\nimport { cx } from '@cerberus/styled-system/css'\n\n/**\n * This module provides a context and hook for notifications.\n * @module\n */\n\nexport interface NotifyOptions {\n /**\n * The palette of the notification.\n * @default 'info'\n */\n palette: 'info' | 'success' | 'warning' | 'danger'\n /**\n * The heading of the notification.\n */\n heading: string\n /**\n * The unique id of the notification.\n */\n id?: string\n /**\n * The description of the notification.\n */\n description?: ReactNode\n /**\n * The action to take when the notification is closed\n */\n onClose?: () => void\n}\n\nexport interface NotificationsValue {\n notify: (options: NotifyOptions) => void\n}\n\nconst NotificationsContext = createContext<NotificationsValue | null>(null)\n\nexport type NotificationsProviderProps = PortalProps\n\n/**\n * Provides a notification center to the app.\n * @see https://cerberus.digitalu.design/react/notification\n * @example\n * ```tsx\n * // Wrap the Provider around the root of the feature.\n * <Notifications>\n * <SomeFeatureSection />\n * </Notifications>\n *\n * // Use the hook to show a notification.\n * const notify = useNotifications()\n *\n * const handleClick = useCallback(() => {\n * notify({\n * palette: 'info',\n * heading: 'New feature!',\n * description: 'We have added a new feature to the app.',\n * })\n * }, [notify])\n * ```\n */\nexport function NotificationCenter(\n props: PropsWithChildren<NotificationsProviderProps>,\n) {\n const [activeNotifications, setActiveNotifications] = useState<\n NotifyOptions[]\n >([])\n const styles = notification()\n\n const handleNotify = useCallback((options: NotifyOptions) => {\n setActiveNotifications((prev) => {\n const id = `${options.palette}:${prev.length + 1}`\n return [...prev, { ...options, id }]\n })\n }, [])\n\n const handleClose = useCallback((e: MouseEvent<HTMLButtonElement>) => {\n const target = e.currentTarget as HTMLButtonElement\n setActiveNotifications((prev) => {\n const item = prev.find((option) => option.id === target.value)\n if (item?.onClose) item.onClose()\n return prev.filter((option) => option.id !== target.value)\n })\n }, [])\n\n const handleCloseAll = useCallback(() => {\n setActiveNotifications((prev) => {\n prev.forEach((item) => {\n if (item.onClose) item.onClose()\n })\n return []\n })\n }, [])\n\n const value = useMemo(\n () => ({\n notify: handleNotify,\n }),\n [handleNotify],\n )\n\n // For some reason, the vstack pattern alignItems is not registering here.\n // So we are forcing it with the style prop.\n\n return (\n <NotificationsContext.Provider value={value}>\n {props.children}\n\n <Show when={activeNotifications.length > 0}>\n <Portal container={props.container}>\n <div className={styles.center}>\n <Show when={activeNotifications.length >= 4}>\n <Button\n className={cx(styles.closeAll, animateIn())}\n onClick={handleCloseAll}\n palette=\"action\"\n shape=\"rounded\"\n size=\"sm\"\n usage=\"ghost\"\n >\n Close all\n </Button>\n </Show>\n\n <div\n className={vstack({\n alignItems: 'flex-end',\n gap: '4',\n })}\n style={{\n alignItems: 'flex-end',\n }}\n >\n {activeNotifications.map((option) => (\n <MatchNotification\n key={option.id}\n {...option}\n onClose={handleClose}\n />\n ))}\n </div>\n </div>\n </Portal>\n </Show>\n </NotificationsContext.Provider>\n )\n}\n\ninterface MatchNotificationProps extends Omit<NotifyOptions, 'onClose'> {\n onClose: (e: MouseEvent<HTMLButtonElement>) => void\n key: string | undefined\n}\n\nfunction MatchNotification(props: MatchNotificationProps) {\n const { palette, id, onClose, heading, description } = props\n\n switch (palette) {\n case 'success':\n return (\n <Notification\n id={id!}\n key={id}\n onClose={onClose}\n open\n palette=\"success\"\n >\n <NotificationHeading palette=\"success\">{heading}</NotificationHeading>\n <NotificationDescription palette=\"success\">\n {description}\n </NotificationDescription>\n </Notification>\n )\n\n case 'warning':\n return (\n <Notification\n id={id!}\n key={id}\n onClose={onClose}\n open\n palette=\"warning\"\n >\n <NotificationHeading palette=\"warning\">{heading}</NotificationHeading>\n <NotificationDescription palette=\"warning\">\n {description}\n </NotificationDescription>\n </Notification>\n )\n\n case 'danger':\n return (\n <Notification id={id!} key={id} onClose={onClose} open palette=\"danger\">\n <NotificationHeading palette=\"danger\">{heading}</NotificationHeading>\n <NotificationDescription palette=\"danger\">\n {description}\n </NotificationDescription>\n </Notification>\n )\n\n case 'info':\n default:\n return (\n <Notification id={id!} key={id} onClose={onClose} open palette=\"info\">\n <NotificationHeading palette=\"info\">{heading}</NotificationHeading>\n <NotificationDescription palette=\"info\">\n {description}\n </NotificationDescription>\n </Notification>\n )\n }\n}\n\n/**\n * The hook to use the NotificationCenter.\n * @returns The notify method to trigger a notification.\n * @example\n * ```tsx\n * const {notify} = useNotificationCenter()\n * notify({\n * palette: 'info',\n * heading: 'New feature',\n * description: 'We have added a new feature to the app.',\n * })\n * ```\n */\nexport function useNotificationCenter(): NotificationsValue {\n const context = useContext(NotificationsContext)\n if (!context) {\n throw new Error(\n 'useNotificationCenter must be used within a NotificationsProvider',\n )\n }\n return context\n}\n"],"mappings":"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","names":[]}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|