@cerberus-design/react 0.7.4-next-9a605c3 → 0.7.4-next-02f723e
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/{chunk-SPGBCV6A.js → chunk-BYDTAFCU.js} +11 -5
- package/build/legacy/chunk-BYDTAFCU.js.map +1 -0
- package/build/legacy/{chunk-TAJBSUS7.js → chunk-I5FPKT7H.js} +53 -30
- package/build/legacy/chunk-I5FPKT7H.js.map +1 -0
- package/build/legacy/components/Notification.js +1 -2
- package/build/legacy/context/notification-center.js +3 -3
- package/build/legacy/index.js +2 -2
- package/build/modern/{chunk-32E6OUMD.js → chunk-NZWANWYC.js} +53 -30
- package/build/modern/chunk-NZWANWYC.js.map +1 -0
- package/build/modern/{chunk-OCBED5GL.js → chunk-U5QWMMKZ.js} +11 -5
- package/build/modern/chunk-U5QWMMKZ.js.map +1 -0
- package/build/modern/components/Notification.js +1 -2
- package/build/modern/context/notification-center.js +3 -3
- package/build/modern/index.js +2 -2
- package/package.json +3 -3
- package/src/components/Notification.tsx +7 -3
- package/src/context/notification-center.tsx +50 -28
- package/build/legacy/chunk-SPGBCV6A.js.map +0 -1
- package/build/legacy/chunk-TAJBSUS7.js.map +0 -1
- package/build/modern/chunk-32E6OUMD.js.map +0 -1
- package/build/modern/chunk-OCBED5GL.js.map +0 -1
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
IconButton
|
|
3
|
-
} from "./chunk-SLHX5K6I.js";
|
|
4
1
|
import {
|
|
5
2
|
trapFocus
|
|
6
3
|
} from "./chunk-KESKDLX6.js";
|
|
@@ -58,7 +55,16 @@ function Notification(props) {
|
|
|
58
55
|
children
|
|
59
56
|
}
|
|
60
57
|
),
|
|
61
|
-
/* @__PURE__ */ jsx(
|
|
58
|
+
/* @__PURE__ */ jsx(
|
|
59
|
+
"button",
|
|
60
|
+
{
|
|
61
|
+
"aria-label": "Close",
|
|
62
|
+
className: styles.close,
|
|
63
|
+
onClick: onClose,
|
|
64
|
+
value: props.id,
|
|
65
|
+
children: /* @__PURE__ */ jsx(Close, {})
|
|
66
|
+
}
|
|
67
|
+
)
|
|
62
68
|
]
|
|
63
69
|
}
|
|
64
70
|
);
|
|
@@ -67,4 +73,4 @@ function Notification(props) {
|
|
|
67
73
|
export {
|
|
68
74
|
Notification
|
|
69
75
|
};
|
|
70
|
-
//# sourceMappingURL=chunk-
|
|
76
|
+
//# sourceMappingURL=chunk-BYDTAFCU.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/Notification.tsx"],"sourcesContent":["'use client'\n\nimport { cx } from '@cerberus-design/styled-system/css'\nimport { hstack, vstack } from '@cerberus-design/styled-system/patterns'\nimport {\n notification,\n type NotificationVariantProps,\n} from '@cerberus-design/styled-system/recipes'\nimport {\n useRef,\n type DialogHTMLAttributes,\n type PropsWithChildren,\n type MouseEvent,\n} from 'react'\nimport { Close } from '@cerberus/icons'\nimport { $cerberusIcons } from '../config/defineIcons'\nimport type { IconType } from '../config/cerbIcons'\nimport { trapFocus } from '../aria-helpers/trap-focus.aria'\n\n/**\n * This module exports the Notification component.\n * @module\n */\n\nfunction MatchNotificationIcon(props: NotificationVariantProps) {\n const palette = props.palette || 'info'\n const key = `${palette}Notification` as keyof typeof $cerberusIcons\n const Icon = $cerberusIcons[key] as IconType\n return <Icon />\n}\n\nexport interface NotificationBaseProps\n extends Omit<DialogHTMLAttributes<HTMLDialogElement>, 'onClose'> {\n id: string\n onClose?: (e: MouseEvent<HTMLButtonElement>) => void\n}\nexport type NotificationProps = NotificationBaseProps & NotificationVariantProps\n\n/**\n * The info notification component.\n * @param props - The component props.\n * @returns The info notification component.\n * @example\n * ```tsx\n * <Notification id=\"info:1\" open>\n * <NotificationHeading>Info Notification</NotificationHeading>\n * <NotificationDescription>\n * This is a description with a <a href=\"#\">link</a> in the message.\n * </NotificationDescription>\n * </Notification>\n * ```\n */\nexport function Notification(props: PropsWithChildren<NotificationProps>) {\n const { children, palette, onClose, ...nativeProps } = props\n const ref = useRef<HTMLDialogElement>(null)\n const onKeyDown = trapFocus(ref)\n const styles = notification({ palette })\n\n return (\n <dialog\n {...nativeProps}\n className={cx(\n nativeProps.className,\n hstack({\n position: 'relative',\n gap: '4',\n }),\n styles.dialog,\n )}\n onKeyDown={onKeyDown}\n ref={ref}\n role=\"alert\"\n >\n <span className={styles.icon}>\n <MatchNotificationIcon palette={palette} />\n </span>\n\n <div\n className={vstack({\n alignItems: 'flex-start',\n gap: '0',\n py: '2',\n })}\n >\n {children}\n </div>\n\n <button\n aria-label=\"Close\"\n className={styles.close}\n onClick={onClose}\n value={props.id}\n >\n <Close />\n </button>\n </dialog>\n )\n}\n"],"mappings":";;;;;;;;AAEA,SAAS,UAAU;AACnB,SAAS,QAAQ,cAAc;AAC/B;AAAA,EACE;AAAA,OAEK;AACP;AAAA,EACE;AAAA,OAIK;AACP,SAAS,aAAa;AAcb,cA+BL,YA/BK;AAJT,SAAS,sBAAsB,OAAiC;AAC9D,QAAM,UAAU,MAAM,WAAW;AACjC,QAAM,MAAM,GAAG,OAAO;AACtB,QAAM,OAAO,eAAe,GAAG;AAC/B,SAAO,oBAAC,QAAK;AACf;AAuBO,SAAS,aAAa,OAA6C;AACxE,QAAM,EAAE,UAAU,SAAS,SAAS,GAAG,YAAY,IAAI;AACvD,QAAM,MAAM,OAA0B,IAAI;AAC1C,QAAM,YAAY,UAAU,GAAG;AAC/B,QAAM,SAAS,aAAa,EAAE,QAAQ,CAAC;AAEvC,SACE;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACJ,WAAW;AAAA,QACT,YAAY;AAAA,QACZ,OAAO;AAAA,UACL,UAAU;AAAA,UACV,KAAK;AAAA,QACP,CAAC;AAAA,QACD,OAAO;AAAA,MACT;AAAA,MACA;AAAA,MACA;AAAA,MACA,MAAK;AAAA,MAEL;AAAA,4BAAC,UAAK,WAAW,OAAO,MACtB,8BAAC,yBAAsB,SAAkB,GAC3C;AAAA,QAEA;AAAA,UAAC;AAAA;AAAA,YACC,WAAW,OAAO;AAAA,cAChB,YAAY;AAAA,cACZ,KAAK;AAAA,cACL,IAAI;AAAA,YACN,CAAC;AAAA,YAEA;AAAA;AAAA,QACH;AAAA,QAEA;AAAA,UAAC;AAAA;AAAA,YACC,cAAW;AAAA,YACX,WAAW,OAAO;AAAA,YAClB,SAAS;AAAA,YACT,OAAO,MAAM;AAAA,YAEb,8BAAC,SAAM;AAAA;AAAA,QACT;AAAA;AAAA;AAAA,EACF;AAEJ;","names":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Notification
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-BYDTAFCU.js";
|
|
4
4
|
import {
|
|
5
5
|
NotificationDescription
|
|
6
6
|
} from "./chunk-SINTHADQ.js";
|
|
@@ -10,6 +10,9 @@ import {
|
|
|
10
10
|
import {
|
|
11
11
|
Portal
|
|
12
12
|
} from "./chunk-4CAT3FHV.js";
|
|
13
|
+
import {
|
|
14
|
+
Button
|
|
15
|
+
} from "./chunk-2ATICEW3.js";
|
|
13
16
|
import {
|
|
14
17
|
Show
|
|
15
18
|
} from "./chunk-4O4QFF4S.js";
|
|
@@ -22,13 +25,14 @@ import {
|
|
|
22
25
|
useMemo,
|
|
23
26
|
useState
|
|
24
27
|
} from "react";
|
|
25
|
-
import { vstack } from "@cerberus-design/styled-system/patterns";
|
|
26
|
-
import { cx } from "@cerberus-design/styled-system/css";
|
|
28
|
+
import { animateIn, vstack } from "@cerberus-design/styled-system/patterns";
|
|
27
29
|
import { notification } from "@cerberus-design/styled-system/recipes";
|
|
30
|
+
import { cx } from "@cerberus-design/styled-system/css";
|
|
28
31
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
29
32
|
var NotificationsContext = createContext(null);
|
|
30
33
|
function NotificationCenter(props) {
|
|
31
34
|
const [activeNotifications, setActiveNotifications] = useState([]);
|
|
35
|
+
const styles = notification();
|
|
32
36
|
const handleNotify = useCallback((options) => {
|
|
33
37
|
setActiveNotifications((prev) => {
|
|
34
38
|
const id = `${options.palette}:${prev.length + 1}`;
|
|
@@ -43,6 +47,14 @@ function NotificationCenter(props) {
|
|
|
43
47
|
return prev.filter((option) => option.id !== target.value);
|
|
44
48
|
});
|
|
45
49
|
}, []);
|
|
50
|
+
const handleCloseAll = useCallback(() => {
|
|
51
|
+
setActiveNotifications((prev) => {
|
|
52
|
+
prev.forEach((item) => {
|
|
53
|
+
if (item.onClose) item.onClose();
|
|
54
|
+
});
|
|
55
|
+
return [];
|
|
56
|
+
});
|
|
57
|
+
}, []);
|
|
46
58
|
const value = useMemo(
|
|
47
59
|
() => ({
|
|
48
60
|
notify: handleNotify
|
|
@@ -51,35 +63,46 @@ function NotificationCenter(props) {
|
|
|
51
63
|
);
|
|
52
64
|
return /* @__PURE__ */ jsxs(NotificationsContext.Provider, { value, children: [
|
|
53
65
|
props.children,
|
|
54
|
-
/* @__PURE__ */ jsx(Show, { when: activeNotifications.length > 0, children: /* @__PURE__ */ jsx(Portal, { container: props.container, children: /* @__PURE__ */
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
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: "text",
|
|
76
|
+
children: "Close all"
|
|
77
|
+
}
|
|
78
|
+
) }),
|
|
79
|
+
/* @__PURE__ */ jsx(
|
|
80
|
+
"div",
|
|
81
|
+
{
|
|
82
|
+
className: vstack({
|
|
60
83
|
alignItems: "flex-end",
|
|
61
84
|
gap: "4"
|
|
62
|
-
})
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
alignItems: "flex-end"
|
|
66
|
-
},
|
|
67
|
-
children: activeNotifications.map((option) => /* @__PURE__ */ jsxs(
|
|
68
|
-
Notification,
|
|
69
|
-
{
|
|
70
|
-
id: option.id,
|
|
71
|
-
onClose: handleClose,
|
|
72
|
-
open: true,
|
|
73
|
-
palette: option.palette,
|
|
74
|
-
children: [
|
|
75
|
-
/* @__PURE__ */ jsx(NotificationHeading, { palette: option.palette, children: option.heading }),
|
|
76
|
-
/* @__PURE__ */ jsx(NotificationDescription, { palette: option.palette, children: option.description })
|
|
77
|
-
]
|
|
85
|
+
}),
|
|
86
|
+
style: {
|
|
87
|
+
alignItems: "flex-end"
|
|
78
88
|
},
|
|
79
|
-
option
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
89
|
+
children: activeNotifications.map((option) => /* @__PURE__ */ jsxs(
|
|
90
|
+
Notification,
|
|
91
|
+
{
|
|
92
|
+
id: option.id,
|
|
93
|
+
onClose: handleClose,
|
|
94
|
+
open: true,
|
|
95
|
+
palette: option.palette,
|
|
96
|
+
children: [
|
|
97
|
+
/* @__PURE__ */ jsx(NotificationHeading, { palette: option.palette, children: option.heading }),
|
|
98
|
+
/* @__PURE__ */ jsx(NotificationDescription, { palette: option.palette, children: option.description })
|
|
99
|
+
]
|
|
100
|
+
},
|
|
101
|
+
option.id
|
|
102
|
+
))
|
|
103
|
+
}
|
|
104
|
+
)
|
|
105
|
+
] }) }) })
|
|
83
106
|
] });
|
|
84
107
|
}
|
|
85
108
|
function useNotificationCenter() {
|
|
@@ -96,4 +119,4 @@ export {
|
|
|
96
119
|
NotificationCenter,
|
|
97
120
|
useNotificationCenter
|
|
98
121
|
};
|
|
99
|
-
//# sourceMappingURL=chunk-
|
|
122
|
+
//# sourceMappingURL=chunk-I5FPKT7H.js.map
|
|
@@ -0,0 +1 @@
|
|
|
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-design/styled-system/patterns'\nimport { Portal, type PortalProps } from '../components/Portal'\nimport { notification } from '@cerberus-design/styled-system/recipes'\nimport { Button } from '../components/Button'\nimport { cx } from '@cerberus-design/styled-system/css'\n\n/**\n * This module provides a context and hook for notifications.\n * @module\n */\n\nexport interface NotifyOptions {\n palette: 'info' | 'success' | 'warning' | 'danger'\n heading: string\n id?: string\n description?: ReactNode\n onClose?: () => void\n}\n\nexport interface NotificationsValue {\n notify: (options: NotifyOptions) => void\n}\n\nconst NotificationsContext = createContext<NotificationsValue | null>(null)\n\nexport interface NotificationsProviderProps extends PortalProps {}\n\n/**\n * Provides a notification center to the app.\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=\"text\"\n >\n Close all\n </Button>\n </Show>\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 <Notification\n id={option.id!}\n key={option.id}\n onClose={handleClose}\n open\n palette={option.palette}\n >\n <NotificationHeading palette={option.palette}>\n {option.heading}\n </NotificationHeading>\n <NotificationDescription palette={option.palette}>\n {option.description}\n </NotificationDescription>\n </Notification>\n ))}\n </div>\n </div>\n </Portal>\n </Show>\n </NotificationsContext.Provider>\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":";;;;;;;;;;;;;;;;;;;;AAEA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAIK;AAKP,SAAS,WAAW,cAAc;AAElC,SAAS,oBAAoB;AAE7B,SAAS,UAAU;AA+FL,cAqBE,YArBF;AA5Ed,IAAM,uBAAuB,cAAyC,IAAI;AAyBnE,SAAS,mBACd,OACA;AACA,QAAM,CAAC,qBAAqB,sBAAsB,IAAI,SAEpD,CAAC,CAAC;AACJ,QAAM,SAAS,aAAa;AAE5B,QAAM,eAAe,YAAY,CAAC,YAA2B;AAC3D,2BAAuB,CAAC,SAAS;AAC/B,YAAM,KAAK,GAAG,QAAQ,OAAO,IAAI,KAAK,SAAS,CAAC;AAChD,aAAO,CAAC,GAAG,MAAM,EAAE,GAAG,SAAS,GAAG,CAAC;AAAA,IACrC,CAAC;AAAA,EACH,GAAG,CAAC,CAAC;AAEL,QAAM,cAAc,YAAY,CAAC,MAAqC;AACpE,UAAM,SAAS,EAAE;AACjB,2BAAuB,CAAC,SAAS;AAC/B,YAAM,OAAO,KAAK,KAAK,CAAC,WAAW,OAAO,OAAO,OAAO,KAAK;AAC7D,UAAI,6BAAM,QAAS,MAAK,QAAQ;AAChC,aAAO,KAAK,OAAO,CAAC,WAAW,OAAO,OAAO,OAAO,KAAK;AAAA,IAC3D,CAAC;AAAA,EACH,GAAG,CAAC,CAAC;AAEL,QAAM,iBAAiB,YAAY,MAAM;AACvC,2BAAuB,CAAC,SAAS;AAC/B,WAAK,QAAQ,CAAC,SAAS;AACrB,YAAI,KAAK,QAAS,MAAK,QAAQ;AAAA,MACjC,CAAC;AACD,aAAO,CAAC;AAAA,IACV,CAAC;AAAA,EACH,GAAG,CAAC,CAAC;AAEL,QAAM,QAAQ;AAAA,IACZ,OAAO;AAAA,MACL,QAAQ;AAAA,IACV;AAAA,IACA,CAAC,YAAY;AAAA,EACf;AAKA,SACE,qBAAC,qBAAqB,UAArB,EAA8B,OAC5B;AAAA,UAAM;AAAA,IAEP,oBAAC,QAAK,MAAM,oBAAoB,SAAS,GACvC,8BAAC,UAAO,WAAW,MAAM,WACvB,+BAAC,SAAI,WAAW,OAAO,QACrB;AAAA,0BAAC,QAAK,MAAM,oBAAoB,UAAU,GACxC;AAAA,QAAC;AAAA;AAAA,UACC,WAAW,GAAG,OAAO,UAAU,UAAU,CAAC;AAAA,UAC1C,SAAS;AAAA,UACT,SAAQ;AAAA,UACR,OAAM;AAAA,UACN,MAAK;AAAA,UACL,OAAM;AAAA,UACP;AAAA;AAAA,MAED,GACF;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,WAAW,OAAO;AAAA,YAChB,YAAY;AAAA,YACZ,KAAK;AAAA,UACP,CAAC;AAAA,UACD,OAAO;AAAA,YACL,YAAY;AAAA,UACd;AAAA,UAEC,8BAAoB,IAAI,CAAC,WACxB;AAAA,YAAC;AAAA;AAAA,cACC,IAAI,OAAO;AAAA,cAEX,SAAS;AAAA,cACT,MAAI;AAAA,cACJ,SAAS,OAAO;AAAA,cAEhB;AAAA,oCAAC,uBAAoB,SAAS,OAAO,SAClC,iBAAO,SACV;AAAA,gBACA,oBAAC,2BAAwB,SAAS,OAAO,SACtC,iBAAO,aACV;AAAA;AAAA;AAAA,YAVK,OAAO;AAAA,UAWd,CACD;AAAA;AAAA,MACH;AAAA,OACF,GACF,GACF;AAAA,KACF;AAEJ;AAeO,SAAS,wBAA4C;AAC1D,QAAM,UAAU,WAAW,oBAAoB;AAC/C,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;","names":[]}
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
import {
|
|
3
3
|
NotificationCenter,
|
|
4
4
|
useNotificationCenter
|
|
5
|
-
} from "../chunk-
|
|
6
|
-
import "../chunk-
|
|
5
|
+
} from "../chunk-I5FPKT7H.js";
|
|
6
|
+
import "../chunk-BYDTAFCU.js";
|
|
7
7
|
import "../chunk-SINTHADQ.js";
|
|
8
8
|
import "../chunk-NWMNEJGU.js";
|
|
9
9
|
import "../chunk-4CAT3FHV.js";
|
|
10
|
+
import "../chunk-2ATICEW3.js";
|
|
10
11
|
import "../chunk-4O4QFF4S.js";
|
|
11
|
-
import "../chunk-SLHX5K6I.js";
|
|
12
12
|
import "../chunk-KESKDLX6.js";
|
|
13
13
|
import "../chunk-BEYPMC73.js";
|
|
14
14
|
import "../chunk-GVNPFXKL.js";
|
package/build/legacy/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
NotificationCenter,
|
|
3
3
|
useNotificationCenter
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-I5FPKT7H.js";
|
|
5
5
|
import {
|
|
6
6
|
PromptModal,
|
|
7
7
|
usePromptModal
|
|
@@ -41,7 +41,7 @@ import {
|
|
|
41
41
|
} from "./chunk-KJUCHZHV.js";
|
|
42
42
|
import {
|
|
43
43
|
Notification
|
|
44
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-BYDTAFCU.js";
|
|
45
45
|
import {
|
|
46
46
|
NotificationDescription
|
|
47
47
|
} from "./chunk-SINTHADQ.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Notification
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-U5QWMMKZ.js";
|
|
4
4
|
import {
|
|
5
5
|
NotificationDescription
|
|
6
6
|
} from "./chunk-SINTHADQ.js";
|
|
@@ -10,6 +10,9 @@ import {
|
|
|
10
10
|
import {
|
|
11
11
|
Portal
|
|
12
12
|
} from "./chunk-4CAT3FHV.js";
|
|
13
|
+
import {
|
|
14
|
+
Button
|
|
15
|
+
} from "./chunk-2ATICEW3.js";
|
|
13
16
|
import {
|
|
14
17
|
Show
|
|
15
18
|
} from "./chunk-4O4QFF4S.js";
|
|
@@ -22,13 +25,14 @@ import {
|
|
|
22
25
|
useMemo,
|
|
23
26
|
useState
|
|
24
27
|
} from "react";
|
|
25
|
-
import { vstack } from "@cerberus-design/styled-system/patterns";
|
|
26
|
-
import { cx } from "@cerberus-design/styled-system/css";
|
|
28
|
+
import { animateIn, vstack } from "@cerberus-design/styled-system/patterns";
|
|
27
29
|
import { notification } from "@cerberus-design/styled-system/recipes";
|
|
30
|
+
import { cx } from "@cerberus-design/styled-system/css";
|
|
28
31
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
29
32
|
var NotificationsContext = createContext(null);
|
|
30
33
|
function NotificationCenter(props) {
|
|
31
34
|
const [activeNotifications, setActiveNotifications] = useState([]);
|
|
35
|
+
const styles = notification();
|
|
32
36
|
const handleNotify = useCallback((options) => {
|
|
33
37
|
setActiveNotifications((prev) => {
|
|
34
38
|
const id = `${options.palette}:${prev.length + 1}`;
|
|
@@ -43,6 +47,14 @@ function NotificationCenter(props) {
|
|
|
43
47
|
return prev.filter((option) => option.id !== target.value);
|
|
44
48
|
});
|
|
45
49
|
}, []);
|
|
50
|
+
const handleCloseAll = useCallback(() => {
|
|
51
|
+
setActiveNotifications((prev) => {
|
|
52
|
+
prev.forEach((item) => {
|
|
53
|
+
if (item.onClose) item.onClose();
|
|
54
|
+
});
|
|
55
|
+
return [];
|
|
56
|
+
});
|
|
57
|
+
}, []);
|
|
46
58
|
const value = useMemo(
|
|
47
59
|
() => ({
|
|
48
60
|
notify: handleNotify
|
|
@@ -51,35 +63,46 @@ function NotificationCenter(props) {
|
|
|
51
63
|
);
|
|
52
64
|
return /* @__PURE__ */ jsxs(NotificationsContext.Provider, { value, children: [
|
|
53
65
|
props.children,
|
|
54
|
-
/* @__PURE__ */ jsx(Show, { when: activeNotifications.length > 0, children: /* @__PURE__ */ jsx(Portal, { container: props.container, children: /* @__PURE__ */
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
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: "text",
|
|
76
|
+
children: "Close all"
|
|
77
|
+
}
|
|
78
|
+
) }),
|
|
79
|
+
/* @__PURE__ */ jsx(
|
|
80
|
+
"div",
|
|
81
|
+
{
|
|
82
|
+
className: vstack({
|
|
60
83
|
alignItems: "flex-end",
|
|
61
84
|
gap: "4"
|
|
62
|
-
})
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
alignItems: "flex-end"
|
|
66
|
-
},
|
|
67
|
-
children: activeNotifications.map((option) => /* @__PURE__ */ jsxs(
|
|
68
|
-
Notification,
|
|
69
|
-
{
|
|
70
|
-
id: option.id,
|
|
71
|
-
onClose: handleClose,
|
|
72
|
-
open: true,
|
|
73
|
-
palette: option.palette,
|
|
74
|
-
children: [
|
|
75
|
-
/* @__PURE__ */ jsx(NotificationHeading, { palette: option.palette, children: option.heading }),
|
|
76
|
-
/* @__PURE__ */ jsx(NotificationDescription, { palette: option.palette, children: option.description })
|
|
77
|
-
]
|
|
85
|
+
}),
|
|
86
|
+
style: {
|
|
87
|
+
alignItems: "flex-end"
|
|
78
88
|
},
|
|
79
|
-
option
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
89
|
+
children: activeNotifications.map((option) => /* @__PURE__ */ jsxs(
|
|
90
|
+
Notification,
|
|
91
|
+
{
|
|
92
|
+
id: option.id,
|
|
93
|
+
onClose: handleClose,
|
|
94
|
+
open: true,
|
|
95
|
+
palette: option.palette,
|
|
96
|
+
children: [
|
|
97
|
+
/* @__PURE__ */ jsx(NotificationHeading, { palette: option.palette, children: option.heading }),
|
|
98
|
+
/* @__PURE__ */ jsx(NotificationDescription, { palette: option.palette, children: option.description })
|
|
99
|
+
]
|
|
100
|
+
},
|
|
101
|
+
option.id
|
|
102
|
+
))
|
|
103
|
+
}
|
|
104
|
+
)
|
|
105
|
+
] }) }) })
|
|
83
106
|
] });
|
|
84
107
|
}
|
|
85
108
|
function useNotificationCenter() {
|
|
@@ -96,4 +119,4 @@ export {
|
|
|
96
119
|
NotificationCenter,
|
|
97
120
|
useNotificationCenter
|
|
98
121
|
};
|
|
99
|
-
//# sourceMappingURL=chunk-
|
|
122
|
+
//# sourceMappingURL=chunk-NZWANWYC.js.map
|
|
@@ -0,0 +1 @@
|
|
|
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-design/styled-system/patterns'\nimport { Portal, type PortalProps } from '../components/Portal'\nimport { notification } from '@cerberus-design/styled-system/recipes'\nimport { Button } from '../components/Button'\nimport { cx } from '@cerberus-design/styled-system/css'\n\n/**\n * This module provides a context and hook for notifications.\n * @module\n */\n\nexport interface NotifyOptions {\n palette: 'info' | 'success' | 'warning' | 'danger'\n heading: string\n id?: string\n description?: ReactNode\n onClose?: () => void\n}\n\nexport interface NotificationsValue {\n notify: (options: NotifyOptions) => void\n}\n\nconst NotificationsContext = createContext<NotificationsValue | null>(null)\n\nexport interface NotificationsProviderProps extends PortalProps {}\n\n/**\n * Provides a notification center to the app.\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=\"text\"\n >\n Close all\n </Button>\n </Show>\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 <Notification\n id={option.id!}\n key={option.id}\n onClose={handleClose}\n open\n palette={option.palette}\n >\n <NotificationHeading palette={option.palette}>\n {option.heading}\n </NotificationHeading>\n <NotificationDescription palette={option.palette}>\n {option.description}\n </NotificationDescription>\n </Notification>\n ))}\n </div>\n </div>\n </Portal>\n </Show>\n </NotificationsContext.Provider>\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":";;;;;;;;;;;;;;;;;;;;AAEA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAIK;AAKP,SAAS,WAAW,cAAc;AAElC,SAAS,oBAAoB;AAE7B,SAAS,UAAU;AA+FL,cAqBE,YArBF;AA5Ed,IAAM,uBAAuB,cAAyC,IAAI;AAyBnE,SAAS,mBACd,OACA;AACA,QAAM,CAAC,qBAAqB,sBAAsB,IAAI,SAEpD,CAAC,CAAC;AACJ,QAAM,SAAS,aAAa;AAE5B,QAAM,eAAe,YAAY,CAAC,YAA2B;AAC3D,2BAAuB,CAAC,SAAS;AAC/B,YAAM,KAAK,GAAG,QAAQ,OAAO,IAAI,KAAK,SAAS,CAAC;AAChD,aAAO,CAAC,GAAG,MAAM,EAAE,GAAG,SAAS,GAAG,CAAC;AAAA,IACrC,CAAC;AAAA,EACH,GAAG,CAAC,CAAC;AAEL,QAAM,cAAc,YAAY,CAAC,MAAqC;AACpE,UAAM,SAAS,EAAE;AACjB,2BAAuB,CAAC,SAAS;AAC/B,YAAM,OAAO,KAAK,KAAK,CAAC,WAAW,OAAO,OAAO,OAAO,KAAK;AAC7D,UAAI,MAAM,QAAS,MAAK,QAAQ;AAChC,aAAO,KAAK,OAAO,CAAC,WAAW,OAAO,OAAO,OAAO,KAAK;AAAA,IAC3D,CAAC;AAAA,EACH,GAAG,CAAC,CAAC;AAEL,QAAM,iBAAiB,YAAY,MAAM;AACvC,2BAAuB,CAAC,SAAS;AAC/B,WAAK,QAAQ,CAAC,SAAS;AACrB,YAAI,KAAK,QAAS,MAAK,QAAQ;AAAA,MACjC,CAAC;AACD,aAAO,CAAC;AAAA,IACV,CAAC;AAAA,EACH,GAAG,CAAC,CAAC;AAEL,QAAM,QAAQ;AAAA,IACZ,OAAO;AAAA,MACL,QAAQ;AAAA,IACV;AAAA,IACA,CAAC,YAAY;AAAA,EACf;AAKA,SACE,qBAAC,qBAAqB,UAArB,EAA8B,OAC5B;AAAA,UAAM;AAAA,IAEP,oBAAC,QAAK,MAAM,oBAAoB,SAAS,GACvC,8BAAC,UAAO,WAAW,MAAM,WACvB,+BAAC,SAAI,WAAW,OAAO,QACrB;AAAA,0BAAC,QAAK,MAAM,oBAAoB,UAAU,GACxC;AAAA,QAAC;AAAA;AAAA,UACC,WAAW,GAAG,OAAO,UAAU,UAAU,CAAC;AAAA,UAC1C,SAAS;AAAA,UACT,SAAQ;AAAA,UACR,OAAM;AAAA,UACN,MAAK;AAAA,UACL,OAAM;AAAA,UACP;AAAA;AAAA,MAED,GACF;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,WAAW,OAAO;AAAA,YAChB,YAAY;AAAA,YACZ,KAAK;AAAA,UACP,CAAC;AAAA,UACD,OAAO;AAAA,YACL,YAAY;AAAA,UACd;AAAA,UAEC,8BAAoB,IAAI,CAAC,WACxB;AAAA,YAAC;AAAA;AAAA,cACC,IAAI,OAAO;AAAA,cAEX,SAAS;AAAA,cACT,MAAI;AAAA,cACJ,SAAS,OAAO;AAAA,cAEhB;AAAA,oCAAC,uBAAoB,SAAS,OAAO,SAClC,iBAAO,SACV;AAAA,gBACA,oBAAC,2BAAwB,SAAS,OAAO,SACtC,iBAAO,aACV;AAAA;AAAA;AAAA,YAVK,OAAO;AAAA,UAWd,CACD;AAAA;AAAA,MACH;AAAA,OACF,GACF,GACF;AAAA,KACF;AAEJ;AAeO,SAAS,wBAA4C;AAC1D,QAAM,UAAU,WAAW,oBAAoB;AAC/C,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;","names":[]}
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
IconButton
|
|
3
|
-
} from "./chunk-SLHX5K6I.js";
|
|
4
1
|
import {
|
|
5
2
|
trapFocus
|
|
6
3
|
} from "./chunk-JIZQFTW6.js";
|
|
@@ -58,7 +55,16 @@ function Notification(props) {
|
|
|
58
55
|
children
|
|
59
56
|
}
|
|
60
57
|
),
|
|
61
|
-
/* @__PURE__ */ jsx(
|
|
58
|
+
/* @__PURE__ */ jsx(
|
|
59
|
+
"button",
|
|
60
|
+
{
|
|
61
|
+
"aria-label": "Close",
|
|
62
|
+
className: styles.close,
|
|
63
|
+
onClick: onClose,
|
|
64
|
+
value: props.id,
|
|
65
|
+
children: /* @__PURE__ */ jsx(Close, {})
|
|
66
|
+
}
|
|
67
|
+
)
|
|
62
68
|
]
|
|
63
69
|
}
|
|
64
70
|
);
|
|
@@ -67,4 +73,4 @@ function Notification(props) {
|
|
|
67
73
|
export {
|
|
68
74
|
Notification
|
|
69
75
|
};
|
|
70
|
-
//# sourceMappingURL=chunk-
|
|
76
|
+
//# sourceMappingURL=chunk-U5QWMMKZ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/Notification.tsx"],"sourcesContent":["'use client'\n\nimport { cx } from '@cerberus-design/styled-system/css'\nimport { hstack, vstack } from '@cerberus-design/styled-system/patterns'\nimport {\n notification,\n type NotificationVariantProps,\n} from '@cerberus-design/styled-system/recipes'\nimport {\n useRef,\n type DialogHTMLAttributes,\n type PropsWithChildren,\n type MouseEvent,\n} from 'react'\nimport { Close } from '@cerberus/icons'\nimport { $cerberusIcons } from '../config/defineIcons'\nimport type { IconType } from '../config/cerbIcons'\nimport { trapFocus } from '../aria-helpers/trap-focus.aria'\n\n/**\n * This module exports the Notification component.\n * @module\n */\n\nfunction MatchNotificationIcon(props: NotificationVariantProps) {\n const palette = props.palette || 'info'\n const key = `${palette}Notification` as keyof typeof $cerberusIcons\n const Icon = $cerberusIcons[key] as IconType\n return <Icon />\n}\n\nexport interface NotificationBaseProps\n extends Omit<DialogHTMLAttributes<HTMLDialogElement>, 'onClose'> {\n id: string\n onClose?: (e: MouseEvent<HTMLButtonElement>) => void\n}\nexport type NotificationProps = NotificationBaseProps & NotificationVariantProps\n\n/**\n * The info notification component.\n * @param props - The component props.\n * @returns The info notification component.\n * @example\n * ```tsx\n * <Notification id=\"info:1\" open>\n * <NotificationHeading>Info Notification</NotificationHeading>\n * <NotificationDescription>\n * This is a description with a <a href=\"#\">link</a> in the message.\n * </NotificationDescription>\n * </Notification>\n * ```\n */\nexport function Notification(props: PropsWithChildren<NotificationProps>) {\n const { children, palette, onClose, ...nativeProps } = props\n const ref = useRef<HTMLDialogElement>(null)\n const onKeyDown = trapFocus(ref)\n const styles = notification({ palette })\n\n return (\n <dialog\n {...nativeProps}\n className={cx(\n nativeProps.className,\n hstack({\n position: 'relative',\n gap: '4',\n }),\n styles.dialog,\n )}\n onKeyDown={onKeyDown}\n ref={ref}\n role=\"alert\"\n >\n <span className={styles.icon}>\n <MatchNotificationIcon palette={palette} />\n </span>\n\n <div\n className={vstack({\n alignItems: 'flex-start',\n gap: '0',\n py: '2',\n })}\n >\n {children}\n </div>\n\n <button\n aria-label=\"Close\"\n className={styles.close}\n onClick={onClose}\n value={props.id}\n >\n <Close />\n </button>\n </dialog>\n )\n}\n"],"mappings":";;;;;;;;AAEA,SAAS,UAAU;AACnB,SAAS,QAAQ,cAAc;AAC/B;AAAA,EACE;AAAA,OAEK;AACP;AAAA,EACE;AAAA,OAIK;AACP,SAAS,aAAa;AAcb,cA+BL,YA/BK;AAJT,SAAS,sBAAsB,OAAiC;AAC9D,QAAM,UAAU,MAAM,WAAW;AACjC,QAAM,MAAM,GAAG,OAAO;AACtB,QAAM,OAAO,eAAe,GAAG;AAC/B,SAAO,oBAAC,QAAK;AACf;AAuBO,SAAS,aAAa,OAA6C;AACxE,QAAM,EAAE,UAAU,SAAS,SAAS,GAAG,YAAY,IAAI;AACvD,QAAM,MAAM,OAA0B,IAAI;AAC1C,QAAM,YAAY,UAAU,GAAG;AAC/B,QAAM,SAAS,aAAa,EAAE,QAAQ,CAAC;AAEvC,SACE;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACJ,WAAW;AAAA,QACT,YAAY;AAAA,QACZ,OAAO;AAAA,UACL,UAAU;AAAA,UACV,KAAK;AAAA,QACP,CAAC;AAAA,QACD,OAAO;AAAA,MACT;AAAA,MACA;AAAA,MACA;AAAA,MACA,MAAK;AAAA,MAEL;AAAA,4BAAC,UAAK,WAAW,OAAO,MACtB,8BAAC,yBAAsB,SAAkB,GAC3C;AAAA,QAEA;AAAA,UAAC;AAAA;AAAA,YACC,WAAW,OAAO;AAAA,cAChB,YAAY;AAAA,cACZ,KAAK;AAAA,cACL,IAAI;AAAA,YACN,CAAC;AAAA,YAEA;AAAA;AAAA,QACH;AAAA,QAEA;AAAA,UAAC;AAAA;AAAA,YACC,cAAW;AAAA,YACX,WAAW,OAAO;AAAA,YAClB,SAAS;AAAA,YACT,OAAO,MAAM;AAAA,YAEb,8BAAC,SAAM;AAAA;AAAA,QACT;AAAA;AAAA;AAAA,EACF;AAEJ;","names":[]}
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
import {
|
|
3
3
|
NotificationCenter,
|
|
4
4
|
useNotificationCenter
|
|
5
|
-
} from "../chunk-
|
|
6
|
-
import "../chunk-
|
|
5
|
+
} from "../chunk-NZWANWYC.js";
|
|
6
|
+
import "../chunk-U5QWMMKZ.js";
|
|
7
7
|
import "../chunk-SINTHADQ.js";
|
|
8
8
|
import "../chunk-NWMNEJGU.js";
|
|
9
9
|
import "../chunk-4CAT3FHV.js";
|
|
10
|
+
import "../chunk-2ATICEW3.js";
|
|
10
11
|
import "../chunk-4O4QFF4S.js";
|
|
11
|
-
import "../chunk-SLHX5K6I.js";
|
|
12
12
|
import "../chunk-JIZQFTW6.js";
|
|
13
13
|
import "../chunk-BEYPMC73.js";
|
|
14
14
|
import "../chunk-GVNPFXKL.js";
|
package/build/modern/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
NotificationCenter,
|
|
3
3
|
useNotificationCenter
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-NZWANWYC.js";
|
|
5
5
|
import {
|
|
6
6
|
PromptModal,
|
|
7
7
|
usePromptModal
|
|
@@ -41,7 +41,7 @@ import {
|
|
|
41
41
|
} from "./chunk-KJUCHZHV.js";
|
|
42
42
|
import {
|
|
43
43
|
Notification
|
|
44
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-U5QWMMKZ.js";
|
|
45
45
|
import {
|
|
46
46
|
NotificationDescription
|
|
47
47
|
} from "./chunk-SINTHADQ.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cerberus-design/react",
|
|
3
|
-
"version": "0.7.4-next-
|
|
3
|
+
"version": "0.7.4-next-02f723e",
|
|
4
4
|
"description": "The Cerberus Design React component library.",
|
|
5
5
|
"browserslist": "> 0.25%, not dead",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
"react": "^18",
|
|
26
26
|
"react-dom": "^18",
|
|
27
27
|
"tsup": "^8.1.0",
|
|
28
|
-
"@cerberus-design/
|
|
29
|
-
"@cerberus-design/
|
|
28
|
+
"@cerberus-design/configs": "0.0.0",
|
|
29
|
+
"@cerberus-design/styled-system": "0.7.4-next-02f723e"
|
|
30
30
|
},
|
|
31
31
|
"publishConfig": {
|
|
32
32
|
"access": "public"
|
|
@@ -12,7 +12,6 @@ import {
|
|
|
12
12
|
type PropsWithChildren,
|
|
13
13
|
type MouseEvent,
|
|
14
14
|
} from 'react'
|
|
15
|
-
import { IconButton } from './IconButton'
|
|
16
15
|
import { Close } from '@cerberus/icons'
|
|
17
16
|
import { $cerberusIcons } from '../config/defineIcons'
|
|
18
17
|
import type { IconType } from '../config/cerbIcons'
|
|
@@ -86,9 +85,14 @@ export function Notification(props: PropsWithChildren<NotificationProps>) {
|
|
|
86
85
|
{children}
|
|
87
86
|
</div>
|
|
88
87
|
|
|
89
|
-
<
|
|
88
|
+
<button
|
|
89
|
+
aria-label="Close"
|
|
90
|
+
className={styles.close}
|
|
91
|
+
onClick={onClose}
|
|
92
|
+
value={props.id}
|
|
93
|
+
>
|
|
90
94
|
<Close />
|
|
91
|
-
</
|
|
95
|
+
</button>
|
|
92
96
|
</dialog>
|
|
93
97
|
)
|
|
94
98
|
}
|
|
@@ -14,10 +14,11 @@ import { Show } from '../components/Show'
|
|
|
14
14
|
import { NotificationHeading } from '../components/NotificationHeading'
|
|
15
15
|
import { NotificationDescription } from '../components/NotificationDescription'
|
|
16
16
|
import { Notification } from '../components/Notification'
|
|
17
|
-
import { vstack } from '@cerberus-design/styled-system/patterns'
|
|
17
|
+
import { animateIn, vstack } from '@cerberus-design/styled-system/patterns'
|
|
18
18
|
import { Portal, type PortalProps } from '../components/Portal'
|
|
19
|
-
import { cx } from '@cerberus-design/styled-system/css'
|
|
20
19
|
import { notification } from '@cerberus-design/styled-system/recipes'
|
|
20
|
+
import { Button } from '../components/Button'
|
|
21
|
+
import { cx } from '@cerberus-design/styled-system/css'
|
|
21
22
|
|
|
22
23
|
/**
|
|
23
24
|
* This module provides a context and hook for notifications.
|
|
@@ -67,6 +68,7 @@ export function NotificationCenter(
|
|
|
67
68
|
const [activeNotifications, setActiveNotifications] = useState<
|
|
68
69
|
NotifyOptions[]
|
|
69
70
|
>([])
|
|
71
|
+
const styles = notification()
|
|
70
72
|
|
|
71
73
|
const handleNotify = useCallback((options: NotifyOptions) => {
|
|
72
74
|
setActiveNotifications((prev) => {
|
|
@@ -84,6 +86,15 @@ export function NotificationCenter(
|
|
|
84
86
|
})
|
|
85
87
|
}, [])
|
|
86
88
|
|
|
89
|
+
const handleCloseAll = useCallback(() => {
|
|
90
|
+
setActiveNotifications((prev) => {
|
|
91
|
+
prev.forEach((item) => {
|
|
92
|
+
if (item.onClose) item.onClose()
|
|
93
|
+
})
|
|
94
|
+
return []
|
|
95
|
+
})
|
|
96
|
+
}, [])
|
|
97
|
+
|
|
87
98
|
const value = useMemo(
|
|
88
99
|
() => ({
|
|
89
100
|
notify: handleNotify,
|
|
@@ -100,34 +111,45 @@ export function NotificationCenter(
|
|
|
100
111
|
|
|
101
112
|
<Show when={activeNotifications.length > 0}>
|
|
102
113
|
<Portal container={props.container}>
|
|
103
|
-
<div
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
114
|
+
<div className={styles.center}>
|
|
115
|
+
<Show when={activeNotifications.length >= 4}>
|
|
116
|
+
<Button
|
|
117
|
+
className={cx(styles.closeAll, animateIn())}
|
|
118
|
+
onClick={handleCloseAll}
|
|
119
|
+
palette="action"
|
|
120
|
+
shape="rounded"
|
|
121
|
+
size="sm"
|
|
122
|
+
usage="text"
|
|
123
|
+
>
|
|
124
|
+
Close all
|
|
125
|
+
</Button>
|
|
126
|
+
</Show>
|
|
127
|
+
<div
|
|
128
|
+
className={vstack({
|
|
107
129
|
alignItems: 'flex-end',
|
|
108
130
|
gap: '4',
|
|
109
|
-
})
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
</
|
|
129
|
-
|
|
130
|
-
|
|
131
|
+
})}
|
|
132
|
+
style={{
|
|
133
|
+
alignItems: 'flex-end',
|
|
134
|
+
}}
|
|
135
|
+
>
|
|
136
|
+
{activeNotifications.map((option) => (
|
|
137
|
+
<Notification
|
|
138
|
+
id={option.id!}
|
|
139
|
+
key={option.id}
|
|
140
|
+
onClose={handleClose}
|
|
141
|
+
open
|
|
142
|
+
palette={option.palette}
|
|
143
|
+
>
|
|
144
|
+
<NotificationHeading palette={option.palette}>
|
|
145
|
+
{option.heading}
|
|
146
|
+
</NotificationHeading>
|
|
147
|
+
<NotificationDescription palette={option.palette}>
|
|
148
|
+
{option.description}
|
|
149
|
+
</NotificationDescription>
|
|
150
|
+
</Notification>
|
|
151
|
+
))}
|
|
152
|
+
</div>
|
|
131
153
|
</div>
|
|
132
154
|
</Portal>
|
|
133
155
|
</Show>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/Notification.tsx"],"sourcesContent":["'use client'\n\nimport { cx } from '@cerberus-design/styled-system/css'\nimport { hstack, vstack } from '@cerberus-design/styled-system/patterns'\nimport {\n notification,\n type NotificationVariantProps,\n} from '@cerberus-design/styled-system/recipes'\nimport {\n useRef,\n type DialogHTMLAttributes,\n type PropsWithChildren,\n type MouseEvent,\n} from 'react'\nimport { IconButton } from './IconButton'\nimport { Close } from '@cerberus/icons'\nimport { $cerberusIcons } from '../config/defineIcons'\nimport type { IconType } from '../config/cerbIcons'\nimport { trapFocus } from '../aria-helpers/trap-focus.aria'\n\n/**\n * This module exports the Notification component.\n * @module\n */\n\nfunction MatchNotificationIcon(props: NotificationVariantProps) {\n const palette = props.palette || 'info'\n const key = `${palette}Notification` as keyof typeof $cerberusIcons\n const Icon = $cerberusIcons[key] as IconType\n return <Icon />\n}\n\nexport interface NotificationBaseProps\n extends Omit<DialogHTMLAttributes<HTMLDialogElement>, 'onClose'> {\n id: string\n onClose?: (e: MouseEvent<HTMLButtonElement>) => void\n}\nexport type NotificationProps = NotificationBaseProps & NotificationVariantProps\n\n/**\n * The info notification component.\n * @param props - The component props.\n * @returns The info notification component.\n * @example\n * ```tsx\n * <Notification id=\"info:1\" open>\n * <NotificationHeading>Info Notification</NotificationHeading>\n * <NotificationDescription>\n * This is a description with a <a href=\"#\">link</a> in the message.\n * </NotificationDescription>\n * </Notification>\n * ```\n */\nexport function Notification(props: PropsWithChildren<NotificationProps>) {\n const { children, palette, onClose, ...nativeProps } = props\n const ref = useRef<HTMLDialogElement>(null)\n const onKeyDown = trapFocus(ref)\n const styles = notification({ palette })\n\n return (\n <dialog\n {...nativeProps}\n className={cx(\n nativeProps.className,\n hstack({\n position: 'relative',\n gap: '4',\n }),\n styles.dialog,\n )}\n onKeyDown={onKeyDown}\n ref={ref}\n role=\"alert\"\n >\n <span className={styles.icon}>\n <MatchNotificationIcon palette={palette} />\n </span>\n\n <div\n className={vstack({\n alignItems: 'flex-start',\n gap: '0',\n py: '2',\n })}\n >\n {children}\n </div>\n\n <IconButton ariaLabel=\"Close\" onClick={onClose} value={props.id}>\n <Close />\n </IconButton>\n </dialog>\n )\n}\n"],"mappings":";;;;;;;;;;;AAEA,SAAS,UAAU;AACnB,SAAS,QAAQ,cAAc;AAC/B;AAAA,EACE;AAAA,OAEK;AACP;AAAA,EACE;AAAA,OAIK;AAEP,SAAS,aAAa;AAcb,cA+BL,YA/BK;AAJT,SAAS,sBAAsB,OAAiC;AAC9D,QAAM,UAAU,MAAM,WAAW;AACjC,QAAM,MAAM,GAAG,OAAO;AACtB,QAAM,OAAO,eAAe,GAAG;AAC/B,SAAO,oBAAC,QAAK;AACf;AAuBO,SAAS,aAAa,OAA6C;AACxE,QAAM,EAAE,UAAU,SAAS,SAAS,GAAG,YAAY,IAAI;AACvD,QAAM,MAAM,OAA0B,IAAI;AAC1C,QAAM,YAAY,UAAU,GAAG;AAC/B,QAAM,SAAS,aAAa,EAAE,QAAQ,CAAC;AAEvC,SACE;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACJ,WAAW;AAAA,QACT,YAAY;AAAA,QACZ,OAAO;AAAA,UACL,UAAU;AAAA,UACV,KAAK;AAAA,QACP,CAAC;AAAA,QACD,OAAO;AAAA,MACT;AAAA,MACA;AAAA,MACA;AAAA,MACA,MAAK;AAAA,MAEL;AAAA,4BAAC,UAAK,WAAW,OAAO,MACtB,8BAAC,yBAAsB,SAAkB,GAC3C;AAAA,QAEA;AAAA,UAAC;AAAA;AAAA,YACC,WAAW,OAAO;AAAA,cAChB,YAAY;AAAA,cACZ,KAAK;AAAA,cACL,IAAI;AAAA,YACN,CAAC;AAAA,YAEA;AAAA;AAAA,QACH;AAAA,QAEA,oBAAC,cAAW,WAAU,SAAQ,SAAS,SAAS,OAAO,MAAM,IAC3D,8BAAC,SAAM,GACT;AAAA;AAAA;AAAA,EACF;AAEJ;","names":[]}
|
|
@@ -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 { vstack } from '@cerberus-design/styled-system/patterns'\nimport { Portal, type PortalProps } from '../components/Portal'\nimport { cx } from '@cerberus-design/styled-system/css'\nimport { notification } from '@cerberus-design/styled-system/recipes'\n\n/**\n * This module provides a context and hook for notifications.\n * @module\n */\n\nexport interface NotifyOptions {\n palette: 'info' | 'success' | 'warning' | 'danger'\n heading: string\n id?: string\n description?: ReactNode\n onClose?: () => void\n}\n\nexport interface NotificationsValue {\n notify: (options: NotifyOptions) => void\n}\n\nconst NotificationsContext = createContext<NotificationsValue | null>(null)\n\nexport interface NotificationsProviderProps extends PortalProps {}\n\n/**\n * Provides a notification center to the app.\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\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 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\n className={cx(\n notification().center,\n vstack({\n alignItems: 'flex-end',\n gap: '4',\n }),\n )}\n style={{\n alignItems: 'flex-end',\n }}\n >\n {activeNotifications.map((option) => (\n <Notification\n id={option.id!}\n key={option.id}\n onClose={handleClose}\n open\n palette={option.palette}\n >\n <NotificationHeading palette={option.palette}>\n {option.heading}\n </NotificationHeading>\n <NotificationDescription palette={option.palette}>\n {option.description}\n </NotificationDescription>\n </Notification>\n ))}\n </div>\n </Portal>\n </Show>\n </NotificationsContext.Provider>\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":";;;;;;;;;;;;;;;;;AAEA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAIK;AAKP,SAAS,cAAc;AAEvB,SAAS,UAAU;AACnB,SAAS,oBAAoB;AAgGf,SAOE,KAPF;AA7Ed,IAAM,uBAAuB,cAAyC,IAAI;AAyBnE,SAAS,mBACd,OACA;AACA,QAAM,CAAC,qBAAqB,sBAAsB,IAAI,SAEpD,CAAC,CAAC;AAEJ,QAAM,eAAe,YAAY,CAAC,YAA2B;AAC3D,2BAAuB,CAAC,SAAS;AAC/B,YAAM,KAAK,GAAG,QAAQ,OAAO,IAAI,KAAK,SAAS,CAAC;AAChD,aAAO,CAAC,GAAG,MAAM,EAAE,GAAG,SAAS,GAAG,CAAC;AAAA,IACrC,CAAC;AAAA,EACH,GAAG,CAAC,CAAC;AAEL,QAAM,cAAc,YAAY,CAAC,MAAqC;AACpE,UAAM,SAAS,EAAE;AACjB,2BAAuB,CAAC,SAAS;AAC/B,YAAM,OAAO,KAAK,KAAK,CAAC,WAAW,OAAO,OAAO,OAAO,KAAK;AAC7D,UAAI,6BAAM,QAAS,MAAK,QAAQ;AAChC,aAAO,KAAK,OAAO,CAAC,WAAW,OAAO,OAAO,OAAO,KAAK;AAAA,IAC3D,CAAC;AAAA,EACH,GAAG,CAAC,CAAC;AAEL,QAAM,QAAQ;AAAA,IACZ,OAAO;AAAA,MACL,QAAQ;AAAA,IACV;AAAA,IACA,CAAC,YAAY;AAAA,EACf;AAKA,SACE,qBAAC,qBAAqB,UAArB,EAA8B,OAC5B;AAAA,UAAM;AAAA,IAEP,oBAAC,QAAK,MAAM,oBAAoB,SAAS,GACvC,8BAAC,UAAO,WAAW,MAAM,WACvB;AAAA,MAAC;AAAA;AAAA,QACC,WAAW;AAAA,UACT,aAAa,EAAE;AAAA,UACf,OAAO;AAAA,YACL,YAAY;AAAA,YACZ,KAAK;AAAA,UACP,CAAC;AAAA,QACH;AAAA,QACA,OAAO;AAAA,UACL,YAAY;AAAA,QACd;AAAA,QAEC,8BAAoB,IAAI,CAAC,WACxB;AAAA,UAAC;AAAA;AAAA,YACC,IAAI,OAAO;AAAA,YAEX,SAAS;AAAA,YACT,MAAI;AAAA,YACJ,SAAS,OAAO;AAAA,YAEhB;AAAA,kCAAC,uBAAoB,SAAS,OAAO,SAClC,iBAAO,SACV;AAAA,cACA,oBAAC,2BAAwB,SAAS,OAAO,SACtC,iBAAO,aACV;AAAA;AAAA;AAAA,UAVK,OAAO;AAAA,QAWd,CACD;AAAA;AAAA,IACH,GACF,GACF;AAAA,KACF;AAEJ;AAeO,SAAS,wBAA4C;AAC1D,QAAM,UAAU,WAAW,oBAAoB;AAC/C,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;","names":[]}
|
|
@@ -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 { vstack } from '@cerberus-design/styled-system/patterns'\nimport { Portal, type PortalProps } from '../components/Portal'\nimport { cx } from '@cerberus-design/styled-system/css'\nimport { notification } from '@cerberus-design/styled-system/recipes'\n\n/**\n * This module provides a context and hook for notifications.\n * @module\n */\n\nexport interface NotifyOptions {\n palette: 'info' | 'success' | 'warning' | 'danger'\n heading: string\n id?: string\n description?: ReactNode\n onClose?: () => void\n}\n\nexport interface NotificationsValue {\n notify: (options: NotifyOptions) => void\n}\n\nconst NotificationsContext = createContext<NotificationsValue | null>(null)\n\nexport interface NotificationsProviderProps extends PortalProps {}\n\n/**\n * Provides a notification center to the app.\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\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 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\n className={cx(\n notification().center,\n vstack({\n alignItems: 'flex-end',\n gap: '4',\n }),\n )}\n style={{\n alignItems: 'flex-end',\n }}\n >\n {activeNotifications.map((option) => (\n <Notification\n id={option.id!}\n key={option.id}\n onClose={handleClose}\n open\n palette={option.palette}\n >\n <NotificationHeading palette={option.palette}>\n {option.heading}\n </NotificationHeading>\n <NotificationDescription palette={option.palette}>\n {option.description}\n </NotificationDescription>\n </Notification>\n ))}\n </div>\n </Portal>\n </Show>\n </NotificationsContext.Provider>\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":";;;;;;;;;;;;;;;;;AAEA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAIK;AAKP,SAAS,cAAc;AAEvB,SAAS,UAAU;AACnB,SAAS,oBAAoB;AAgGf,SAOE,KAPF;AA7Ed,IAAM,uBAAuB,cAAyC,IAAI;AAyBnE,SAAS,mBACd,OACA;AACA,QAAM,CAAC,qBAAqB,sBAAsB,IAAI,SAEpD,CAAC,CAAC;AAEJ,QAAM,eAAe,YAAY,CAAC,YAA2B;AAC3D,2BAAuB,CAAC,SAAS;AAC/B,YAAM,KAAK,GAAG,QAAQ,OAAO,IAAI,KAAK,SAAS,CAAC;AAChD,aAAO,CAAC,GAAG,MAAM,EAAE,GAAG,SAAS,GAAG,CAAC;AAAA,IACrC,CAAC;AAAA,EACH,GAAG,CAAC,CAAC;AAEL,QAAM,cAAc,YAAY,CAAC,MAAqC;AACpE,UAAM,SAAS,EAAE;AACjB,2BAAuB,CAAC,SAAS;AAC/B,YAAM,OAAO,KAAK,KAAK,CAAC,WAAW,OAAO,OAAO,OAAO,KAAK;AAC7D,UAAI,MAAM,QAAS,MAAK,QAAQ;AAChC,aAAO,KAAK,OAAO,CAAC,WAAW,OAAO,OAAO,OAAO,KAAK;AAAA,IAC3D,CAAC;AAAA,EACH,GAAG,CAAC,CAAC;AAEL,QAAM,QAAQ;AAAA,IACZ,OAAO;AAAA,MACL,QAAQ;AAAA,IACV;AAAA,IACA,CAAC,YAAY;AAAA,EACf;AAKA,SACE,qBAAC,qBAAqB,UAArB,EAA8B,OAC5B;AAAA,UAAM;AAAA,IAEP,oBAAC,QAAK,MAAM,oBAAoB,SAAS,GACvC,8BAAC,UAAO,WAAW,MAAM,WACvB;AAAA,MAAC;AAAA;AAAA,QACC,WAAW;AAAA,UACT,aAAa,EAAE;AAAA,UACf,OAAO;AAAA,YACL,YAAY;AAAA,YACZ,KAAK;AAAA,UACP,CAAC;AAAA,QACH;AAAA,QACA,OAAO;AAAA,UACL,YAAY;AAAA,QACd;AAAA,QAEC,8BAAoB,IAAI,CAAC,WACxB;AAAA,UAAC;AAAA;AAAA,YACC,IAAI,OAAO;AAAA,YAEX,SAAS;AAAA,YACT,MAAI;AAAA,YACJ,SAAS,OAAO;AAAA,YAEhB;AAAA,kCAAC,uBAAoB,SAAS,OAAO,SAClC,iBAAO,SACV;AAAA,cACA,oBAAC,2BAAwB,SAAS,OAAO,SACtC,iBAAO,aACV;AAAA;AAAA;AAAA,UAVK,OAAO;AAAA,QAWd,CACD;AAAA;AAAA,IACH,GACF,GACF;AAAA,KACF;AAEJ;AAeO,SAAS,wBAA4C;AAC1D,QAAM,UAAU,WAAW,oBAAoB;AAC/C,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/Notification.tsx"],"sourcesContent":["'use client'\n\nimport { cx } from '@cerberus-design/styled-system/css'\nimport { hstack, vstack } from '@cerberus-design/styled-system/patterns'\nimport {\n notification,\n type NotificationVariantProps,\n} from '@cerberus-design/styled-system/recipes'\nimport {\n useRef,\n type DialogHTMLAttributes,\n type PropsWithChildren,\n type MouseEvent,\n} from 'react'\nimport { IconButton } from './IconButton'\nimport { Close } from '@cerberus/icons'\nimport { $cerberusIcons } from '../config/defineIcons'\nimport type { IconType } from '../config/cerbIcons'\nimport { trapFocus } from '../aria-helpers/trap-focus.aria'\n\n/**\n * This module exports the Notification component.\n * @module\n */\n\nfunction MatchNotificationIcon(props: NotificationVariantProps) {\n const palette = props.palette || 'info'\n const key = `${palette}Notification` as keyof typeof $cerberusIcons\n const Icon = $cerberusIcons[key] as IconType\n return <Icon />\n}\n\nexport interface NotificationBaseProps\n extends Omit<DialogHTMLAttributes<HTMLDialogElement>, 'onClose'> {\n id: string\n onClose?: (e: MouseEvent<HTMLButtonElement>) => void\n}\nexport type NotificationProps = NotificationBaseProps & NotificationVariantProps\n\n/**\n * The info notification component.\n * @param props - The component props.\n * @returns The info notification component.\n * @example\n * ```tsx\n * <Notification id=\"info:1\" open>\n * <NotificationHeading>Info Notification</NotificationHeading>\n * <NotificationDescription>\n * This is a description with a <a href=\"#\">link</a> in the message.\n * </NotificationDescription>\n * </Notification>\n * ```\n */\nexport function Notification(props: PropsWithChildren<NotificationProps>) {\n const { children, palette, onClose, ...nativeProps } = props\n const ref = useRef<HTMLDialogElement>(null)\n const onKeyDown = trapFocus(ref)\n const styles = notification({ palette })\n\n return (\n <dialog\n {...nativeProps}\n className={cx(\n nativeProps.className,\n hstack({\n position: 'relative',\n gap: '4',\n }),\n styles.dialog,\n )}\n onKeyDown={onKeyDown}\n ref={ref}\n role=\"alert\"\n >\n <span className={styles.icon}>\n <MatchNotificationIcon palette={palette} />\n </span>\n\n <div\n className={vstack({\n alignItems: 'flex-start',\n gap: '0',\n py: '2',\n })}\n >\n {children}\n </div>\n\n <IconButton ariaLabel=\"Close\" onClick={onClose} value={props.id}>\n <Close />\n </IconButton>\n </dialog>\n )\n}\n"],"mappings":";;;;;;;;;;;AAEA,SAAS,UAAU;AACnB,SAAS,QAAQ,cAAc;AAC/B;AAAA,EACE;AAAA,OAEK;AACP;AAAA,EACE;AAAA,OAIK;AAEP,SAAS,aAAa;AAcb,cA+BL,YA/BK;AAJT,SAAS,sBAAsB,OAAiC;AAC9D,QAAM,UAAU,MAAM,WAAW;AACjC,QAAM,MAAM,GAAG,OAAO;AACtB,QAAM,OAAO,eAAe,GAAG;AAC/B,SAAO,oBAAC,QAAK;AACf;AAuBO,SAAS,aAAa,OAA6C;AACxE,QAAM,EAAE,UAAU,SAAS,SAAS,GAAG,YAAY,IAAI;AACvD,QAAM,MAAM,OAA0B,IAAI;AAC1C,QAAM,YAAY,UAAU,GAAG;AAC/B,QAAM,SAAS,aAAa,EAAE,QAAQ,CAAC;AAEvC,SACE;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACJ,WAAW;AAAA,QACT,YAAY;AAAA,QACZ,OAAO;AAAA,UACL,UAAU;AAAA,UACV,KAAK;AAAA,QACP,CAAC;AAAA,QACD,OAAO;AAAA,MACT;AAAA,MACA;AAAA,MACA;AAAA,MACA,MAAK;AAAA,MAEL;AAAA,4BAAC,UAAK,WAAW,OAAO,MACtB,8BAAC,yBAAsB,SAAkB,GAC3C;AAAA,QAEA;AAAA,UAAC;AAAA;AAAA,YACC,WAAW,OAAO;AAAA,cAChB,YAAY;AAAA,cACZ,KAAK;AAAA,cACL,IAAI;AAAA,YACN,CAAC;AAAA,YAEA;AAAA;AAAA,QACH;AAAA,QAEA,oBAAC,cAAW,WAAU,SAAQ,SAAS,SAAS,OAAO,MAAM,IAC3D,8BAAC,SAAM,GACT;AAAA;AAAA;AAAA,EACF;AAEJ;","names":[]}
|