@vuu-ui/vuu-notifications 3.0.0 → 3.1.0-beta.2

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.
Files changed (41) hide show
  1. package/package.json +12 -9
  2. package/src/NotificationsCenter.js +192 -0
  3. package/src/NotificationsContext.js +7 -0
  4. package/src/NotificationsProvider.js +45 -0
  5. package/src/ToastNotification.css.js +133 -0
  6. package/src/ToastNotification.js +86 -0
  7. package/src/WorkspaceNotification.css.js +16 -0
  8. package/src/WorkspaceNotification.js +53 -0
  9. package/src/index.js +3 -0
  10. package/cjs/NotificationsCenter.js +0 -239
  11. package/cjs/NotificationsCenter.js.map +0 -1
  12. package/cjs/NotificationsContext.js +0 -13
  13. package/cjs/NotificationsContext.js.map +0 -1
  14. package/cjs/NotificationsProvider.js +0 -67
  15. package/cjs/NotificationsProvider.js.map +0 -1
  16. package/cjs/ToastNotification.css.js +0 -6
  17. package/cjs/ToastNotification.css.js.map +0 -1
  18. package/cjs/ToastNotification.js +0 -113
  19. package/cjs/ToastNotification.js.map +0 -1
  20. package/cjs/WorkspaceNotification.css.js +0 -6
  21. package/cjs/WorkspaceNotification.css.js.map +0 -1
  22. package/cjs/WorkspaceNotification.js +0 -52
  23. package/cjs/WorkspaceNotification.js.map +0 -1
  24. package/cjs/index.js +0 -13
  25. package/cjs/index.js.map +0 -1
  26. package/esm/NotificationsCenter.js +0 -237
  27. package/esm/NotificationsCenter.js.map +0 -1
  28. package/esm/NotificationsContext.js +0 -9
  29. package/esm/NotificationsContext.js.map +0 -1
  30. package/esm/NotificationsProvider.js +0 -64
  31. package/esm/NotificationsProvider.js.map +0 -1
  32. package/esm/ToastNotification.css.js +0 -4
  33. package/esm/ToastNotification.css.js.map +0 -1
  34. package/esm/ToastNotification.js +0 -111
  35. package/esm/ToastNotification.js.map +0 -1
  36. package/esm/WorkspaceNotification.css.js +0 -4
  37. package/esm/WorkspaceNotification.css.js.map +0 -1
  38. package/esm/WorkspaceNotification.js +0 -50
  39. package/esm/WorkspaceNotification.js.map +0 -1
  40. package/esm/index.js +0 -4
  41. package/esm/index.js.map +0 -1
package/package.json CHANGED
@@ -1,14 +1,20 @@
1
1
  {
2
- "version": "3.0.0",
2
+ "version": "3.1.0-beta.2",
3
3
  "description": "VUU notifications - Toast, WorkspaceNotification etc",
4
+ "main": "src/index.ts",
4
5
  "author": "heswell",
5
6
  "license": "Apache-2.0",
7
+ "scripts": {
8
+ "build:dev": "node ../../scripts/run-build.mjs",
9
+ "build": "node ../../scripts/run-build-rslib.ts",
10
+ "type-defs": "node ../../scripts/build-type-defs.mjs"
11
+ },
6
12
  "dependencies": {
7
13
  "@salt-ds/core": "1.54.1",
8
14
  "@salt-ds/styles": "0.2.1",
9
15
  "@salt-ds/window": "0.1.1",
10
- "@vuu-ui/vuu-ui-controls": "3.0.0",
11
- "@vuu-ui/vuu-utils": "3.0.0"
16
+ "@vuu-ui/vuu-ui-controls": "3.1.0-beta.2",
17
+ "@vuu-ui/vuu-utils": "3.1.0-beta.2"
12
18
  },
13
19
  "peerDependencies": {
14
20
  "clsx": "^2.0.0",
@@ -18,19 +24,16 @@
18
24
  "sideEffects": false,
19
25
  "files": [
20
26
  "README.md",
21
- "esm",
22
- "cjs",
27
+ "src",
23
28
  "/types"
24
29
  ],
25
30
  "exports": {
26
31
  ".": {
27
- "require": "./cjs/index.js",
28
- "import": "./esm/index.js",
32
+ "import": "./src/index.js",
29
33
  "types": "./types/index.d.ts"
30
34
  }
31
35
  },
32
- "main": "cjs/index.js",
33
- "module": "esm/index.js",
36
+ "module": "index.js",
34
37
  "name": "@vuu-ui/vuu-notifications",
35
38
  "type": "module",
36
39
  "types": "types/index.d.ts"
@@ -0,0 +1,192 @@
1
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
+ import { getUniqueId, saveLocalEntity } from "@vuu-ui/vuu-utils";
3
+ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
4
+ import { isToastNotification, isWorkspaceNotification } from "./NotificationsContext.js";
5
+ import { ToastNotification } from "./ToastNotification.js";
6
+ import { WorkspaceNotification } from "./WorkspaceNotification.js";
7
+ const ZeroSize = {
8
+ height: 0,
9
+ width: 0
10
+ };
11
+ const toastContainerRightPadding = 20;
12
+ const toastOffsetTop = 60;
13
+ const toastDisplayDuration = 6000;
14
+ const toastDisplayDurationPostHover = 2000;
15
+ const toastContainerContentGap = 10;
16
+ const RuntimeToast = (toast)=>{
17
+ const slidesIn = !!toast.animationType?.includes("slide-in");
18
+ return {
19
+ ...toast,
20
+ hidden: slidesIn,
21
+ id: getUniqueId(),
22
+ left: document.body.clientWidth,
23
+ opacity: slidesIn ? void 0 : 0,
24
+ size: ZeroSize
25
+ };
26
+ };
27
+ const NotificationsCenter = ({ notificationsContext, startupToastNotification })=>{
28
+ const toastNotifications = useMemo(()=>startupToastNotification ? [
29
+ RuntimeToast(startupToastNotification)
30
+ ] : [], [
31
+ startupToastNotification
32
+ ]);
33
+ const [workspaceNotification, setWorkspaceNotification] = useState(null);
34
+ const hoveredToastRef = useRef(void 0);
35
+ const notificationsRef = useRef(toastNotifications);
36
+ const [notifications, _setNotifications] = useState(toastNotifications);
37
+ const setNotifications = useCallback((notifications)=>{
38
+ _setNotifications(notificationsRef.current = notifications);
39
+ }, []);
40
+ const showNotification = useCallback((notification)=>{
41
+ if (isToastNotification(notification)) {
42
+ const runtimeToast = RuntimeToast(notification);
43
+ if (notification.renderPostRefresh) saveLocalEntity("startup-notification", {
44
+ ...runtimeToast,
45
+ expires: +new Date() + 10000
46
+ });
47
+ else setNotifications(notificationsRef.current.concat(runtimeToast));
48
+ return runtimeToast.id;
49
+ }
50
+ if (isWorkspaceNotification(notification)) return void setWorkspaceNotification(/*#__PURE__*/ jsx(WorkspaceNotification, {
51
+ children: notification.content
52
+ }));
53
+ throw Error("[NotificationsCenter] invalid notification received");
54
+ }, [
55
+ setNotifications
56
+ ]);
57
+ const hideNotification = useCallback((id)=>{
58
+ if (id) setNotifications(notificationsRef.current.filter((n)=>n.id !== id));
59
+ else setWorkspaceNotification(null);
60
+ }, [
61
+ setNotifications
62
+ ]);
63
+ useMemo(()=>{
64
+ notificationsContext.setNotify(showNotification, hideNotification);
65
+ }, [
66
+ hideNotification,
67
+ notificationsContext,
68
+ showNotification
69
+ ]);
70
+ const onMeasured = useCallback((id, height, width)=>{
71
+ let scheduledUpdate;
72
+ const pageWidth = document.body.clientWidth;
73
+ setNotifications(notificationsRef.current.map((n)=>{
74
+ if (n.id !== id) return n;
75
+ {
76
+ const slideIn = n.animationType?.includes("slide-in");
77
+ const newToast = {
78
+ ...n,
79
+ hidden: !!slideIn,
80
+ left: slideIn ? pageWidth + width - toastContainerRightPadding : pageWidth - width - toastContainerRightPadding,
81
+ size: {
82
+ height,
83
+ width
84
+ },
85
+ transitionStatus: "entry"
86
+ };
87
+ scheduledUpdate = slideIn ? {
88
+ ...newToast,
89
+ hidden: false,
90
+ left: pageWidth - width - toastContainerRightPadding
91
+ } : {
92
+ ...newToast,
93
+ opacity: 1
94
+ };
95
+ return newToast;
96
+ }
97
+ }));
98
+ if (scheduledUpdate) {
99
+ const updateNotifications = notificationsRef.current.map((n)=>{
100
+ if (n.id === scheduledUpdate?.id) return scheduledUpdate;
101
+ return n;
102
+ });
103
+ requestAnimationFrame(()=>{
104
+ setNotifications(updateNotifications);
105
+ });
106
+ }
107
+ }, [
108
+ setNotifications
109
+ ]);
110
+ useEffect(()=>{
111
+ document.body.addEventListener("transitionend", (e)=>{
112
+ const { classList, id } = e.target;
113
+ if (classList?.contains("vuuToastNotification")) {
114
+ const notification = notificationsRef.current.find((n)=>n.id === id);
115
+ if (notification?.transitionStatus === "exit") setNotifications(notificationsRef.current.filter((n)=>n.id !== id));
116
+ else if (notification?.dismissal !== "manual") setTimeout(()=>{
117
+ if (notification && hoveredToastRef.current !== id) {
118
+ const pageWidth = document.body.clientWidth;
119
+ setNotifications(notificationsRef.current.map((n)=>{
120
+ if (n.id !== id) return n;
121
+ if (n.animationType?.includes("slide-out")) return {
122
+ ...n,
123
+ transitionStatus: "exit",
124
+ left: pageWidth + toastContainerRightPadding
125
+ };
126
+ return {
127
+ ...n,
128
+ transitionStatus: "exit",
129
+ opacity: 0
130
+ };
131
+ }).filter((v)=>null !== v));
132
+ }
133
+ }, toastDisplayDuration);
134
+ }
135
+ });
136
+ }, [
137
+ setNotifications
138
+ ]);
139
+ const handleDismiss = useCallback((id)=>{
140
+ if (id) setNotifications(notificationsRef.current.filter((n)=>n.id !== id));
141
+ }, [
142
+ setNotifications
143
+ ]);
144
+ const handleHoverEntry = useCallback((id)=>{
145
+ hoveredToastRef.current = id;
146
+ }, []);
147
+ const handleHoverExit = useCallback((id)=>{
148
+ hoveredToastRef.current = void 0;
149
+ const notification = notificationsRef.current.find((n)=>n.id === id);
150
+ setTimeout(()=>{
151
+ if (notification) {
152
+ const pageWidth = document.body.clientWidth;
153
+ setNotifications(notificationsRef.current.map((n)=>{
154
+ if (n.id !== id) return n;
155
+ if (n.animationType?.includes("slide-out")) return {
156
+ ...n,
157
+ transitionStatus: "exit",
158
+ left: pageWidth + toastContainerRightPadding
159
+ };
160
+ return {
161
+ ...n,
162
+ transitionStatus: "exit",
163
+ opacity: 0
164
+ };
165
+ }).filter((v)=>null !== v));
166
+ }
167
+ }, toastDisplayDurationPostHover);
168
+ }, [
169
+ setNotifications
170
+ ]);
171
+ return /*#__PURE__*/ jsxs(Fragment, {
172
+ children: [
173
+ workspaceNotification,
174
+ notifications.map(({ hidden, id, left = 0, opacity, size, ...toast }, i)=>{
175
+ const height = size ? size.height : 80;
176
+ return /*#__PURE__*/ jsx(ToastNotification, {
177
+ hidden: hidden,
178
+ id: id,
179
+ left: left,
180
+ notification: toast,
181
+ onHoverEntry: handleHoverEntry,
182
+ onHoverExit: handleHoverExit,
183
+ onMeasured: onMeasured,
184
+ onDismiss: handleDismiss,
185
+ opacity: opacity,
186
+ top: toastOffsetTop + (height + toastContainerContentGap) * i
187
+ }, id);
188
+ })
189
+ ]
190
+ });
191
+ };
192
+ export { NotificationsCenter };
@@ -0,0 +1,7 @@
1
+ const NotificationType = {
2
+ Toast: "toast",
3
+ Workspace: "workspace"
4
+ };
5
+ const isToastNotification = (n)=>n.type === NotificationType.Toast;
6
+ const isWorkspaceNotification = (n)=>n.type === NotificationType.Workspace;
7
+ export { NotificationType, isToastNotification, isWorkspaceNotification };
@@ -0,0 +1,45 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import react, { useContext, useMemo } from "react";
3
+ import { NotificationsCenter } from "./NotificationsCenter.js";
4
+ import { getLocalEntity } from "@vuu-ui/vuu-utils";
5
+ class NotificationsContextObject {
6
+ #showNotification = ()=>{
7
+ console.log("have you forgotten to provide a NotificationsCenter?");
8
+ };
9
+ #hideNotification = ()=>console.log("have you forgotten to provide a NotificationsCenter?");
10
+ showNotification = (notification)=>this.#showNotification(notification);
11
+ hideNotification = (id)=>this.#hideNotification(id);
12
+ setNotify = (showNotificationDispatcher, hideNotificationDispatcher)=>{
13
+ this.#showNotification = showNotificationDispatcher;
14
+ this.#hideNotification = hideNotificationDispatcher;
15
+ };
16
+ }
17
+ const NotificationsContext = /*#__PURE__*/ react.createContext(new NotificationsContextObject());
18
+ const NotificationsProvider = (props)=>{
19
+ const context = useContext(NotificationsContext);
20
+ const startupToastNotification = useMemo(()=>{
21
+ const toast = getLocalEntity("startup-notification", true);
22
+ if (toast && toast.expires >= +Date.now()) {
23
+ const { expires, ...toastDescriptor } = toast;
24
+ return toastDescriptor;
25
+ }
26
+ }, []);
27
+ return /*#__PURE__*/ jsxs(NotificationsContext.Provider, {
28
+ value: context,
29
+ children: [
30
+ /*#__PURE__*/ jsx(NotificationsCenter, {
31
+ startupToastNotification: startupToastNotification,
32
+ notificationsContext: context
33
+ }),
34
+ props.children
35
+ ]
36
+ });
37
+ };
38
+ const useNotifications = ()=>{
39
+ const { hideNotification, showNotification } = useContext(NotificationsContext);
40
+ return {
41
+ hideNotification,
42
+ showNotification
43
+ };
44
+ };
45
+ export { NotificationsProvider, useNotifications };
@@ -0,0 +1,133 @@
1
+ const css = `
2
+ .vuuToastNotification {
3
+ --toast-transition-duration: .4s;
4
+ --padding-base: var(--vuuToast-padding, var(--salt-spacing-300));
5
+ background: var(--vuuToast-background, var(--toast-background));
6
+ border-radius: var(--vuuToast-borderRadius, var(--salt-curve-100, 0));
7
+ box-sizing: border-box;
8
+ box-shadow: var(--salt-overlayable-shadow-popout);
9
+ color: var(--vuuToast-foreground, var(--toast-foreground));
10
+ align-items: center;
11
+ column-gap: var(--salt-spacing-100);
12
+ grid-template-areas: var(--vuuToast-grid-template-areas, "toast-header");
13
+ max-width: var(--vuuToast-maxWidth, 600px);
14
+ min-width: var(--vuuToast-minWidth, 300px);
15
+ opacity: 1;
16
+ padding: var(--padding-base);
17
+ row-gap: var(--salt-spacing-100);
18
+ z-index: var(--salt-zIndex-notification);
19
+ grid-template-columns: auto;
20
+ transition: opacity .4s, top;
21
+ display: grid;
22
+
23
+ &.vuuToastNotification-hidden {
24
+ visibility: hidden;
25
+ }
26
+
27
+ &.vuuToastNotification-withCloseButton {
28
+ grid-template-areas: var(--vuuToast-grid-template-areas, "toast-header close-button");
29
+ grid-template-columns: 1fr 36px;
30
+ }
31
+
32
+ &.vuuToastNotification-withIcon {
33
+ grid-template-areas: var(--vuuToast-grid-template-areas, "toast-icon toast-header");
34
+ grid-template-columns: var(--vuuToast-gridTemplateColumns, 36px auto);
35
+ }
36
+
37
+ &.vuuToastNotification-withIcon.vuuToastNotification-withCloseButton {
38
+ grid-template-areas: var(--vuuToast-grid-template-areas, "toast-icon toast-header close-button");
39
+ grid-template-columns: var(--vuuToast-gridTemplateColumns, 36px auto 36px);
40
+ }
41
+
42
+ &.vuuToastNotification-withContent {
43
+ grid-template-areas: var(--vuuToast-grid-template-areas, "toast-header"
44
+ "toast-content");
45
+ }
46
+
47
+ &.vuuToastNotification-withContent.vuuToastNotification-withCloseButton {
48
+ grid-template-areas: var(--vuuToast-grid-template-areas, "toast-header close-button"
49
+ "toast-content close-button");
50
+ grid-template-columns: 1fr 36px;
51
+ }
52
+
53
+ &.vuuToastNotification-withTransition {
54
+ transition: top .2s ease-out, left var(--toast-transition-duration) ease-in, opacity .4s;
55
+ }
56
+
57
+ &.vuuToastNotification-transparent {
58
+ opacity: 0;
59
+ transition: top .2s ease-out, opacity .4s;
60
+ }
61
+
62
+ &.vuuToastNotification-withIcon.vuuToastNotification-withContent {
63
+ grid-template-areas: var(--vuuToast-grid-template-areas, "toast-icon toast-header"
64
+ "toast-icon toast-content");
65
+ grid-template-columns: var(--vuuToast-gridTemplateColumns, 36px auto);
66
+ }
67
+
68
+ &.vuuToastNotification-withIcon.vuuToastNotification-withContent.vuuToastNotification-withCloseButton {
69
+ grid-template-areas: var(--vuuToast-grid-template-areas, "toast-icon toast-header close-button"
70
+ "toast-icon toast-content close-button");
71
+ grid-template-columns: var(--vuuToast-gridTemplateColumns, 36px auto 36px);
72
+ }
73
+
74
+ &.vuuToastNotification-error {
75
+ --toast-background: var(--vuuToast-error-background, var(--salt-container-primary-background));
76
+ --toast-foreground: var(--vuuToast-error-foreground, var(--salt-content-primary-foreground));
77
+ --vuu-icon-svg: var(--vuuToast-error-icon, var(--vuu-svg-info-circle));
78
+ }
79
+
80
+ &.vuuToastNotification-success {
81
+ --toast-background: var(--vuuToast-success-background, var(--salt-container-primary-background));
82
+ --toast-foreground: var(--vuuToast-success-foreground, var(--salt-content-primary-foreground));
83
+ --vuu-icon-svg: var(--vuuToast-success-icon, var(--vuu-svg-tick));
84
+ }
85
+
86
+ &.vuuToastNotification-warning {
87
+ --toast-background: var(--vuuToast-warning-background, var(--salt-container-primary-background));
88
+ --toast-foreground: var(--vuuToast-warning-foreground, var(--salt-content-primary-foreground));
89
+ --vuu-icon-svg: var(--vuuToast-warning-icon, var(--vuu-svg-info-circle));
90
+ }
91
+
92
+ &.vuuToastNotification-info {
93
+ --toast-background: var(--vuuToast-info-background, var(--salt-container-primary-background));
94
+ --toast-foreground: var(--vuuToast-info-foreground, var(--salt-content-primary-foreground));
95
+ --vuu-icon-svg: var(--vuuToast-info-icon, var(--vuu-svg-info-circle));
96
+ }
97
+
98
+ & .vuuIcon {
99
+ --vuu-icon-color: var(--toast-foreground);
100
+ --vuu-icon-size: 20px;
101
+ grid-area: toast-icon;
102
+ justify-self: center;
103
+ }
104
+
105
+ & .vuuToastNotification-header {
106
+ font-size: var(--vuuToast-header-fontSize, var(--salt-text-h3-fontSize));
107
+ font-weight: var(--salt-text-display1-fontWeight-strong);
108
+ line-height: var(--salt-text-h3-lineHeight);
109
+ white-space: nowrap;
110
+ grid-area: toast-header;
111
+ justify-self: start;
112
+ margin: 0;
113
+ }
114
+
115
+ & .vuuToastNotification-content {
116
+ white-space: nowrap;
117
+ grid-area: toast-content;
118
+ justify-self: start;
119
+ }
120
+
121
+ & .vuuToastNotification-closeButton.saltButton {
122
+ grid-area: close-button;
123
+ justify-self: center;
124
+
125
+ & .vuuIcon {
126
+ --vuu-icon-size: 16px;
127
+ }
128
+ }
129
+ }
130
+
131
+
132
+ `;
133
+ export default css;
@@ -0,0 +1,86 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { useFloatingComponent } from "@salt-ds/core";
3
+ import { useComponentCssInjection } from "@salt-ds/styles";
4
+ import { useWindow } from "@salt-ds/window";
5
+ import { Icon, IconButton } from "@vuu-ui/vuu-ui-controls";
6
+ import clsx from "clsx";
7
+ import { useCallback } from "react";
8
+ import ToastNotification from "./ToastNotification.css";
9
+ const classBase = "vuuToastNotification";
10
+ const ToastNotification_ToastNotification = ({ hidden, id, left, onDismiss, onMeasured, top, notification, onHoverEntry, onHoverExit, opacity = 1 })=>{
11
+ const targetWindow = useWindow();
12
+ useComponentCssInjection({
13
+ testId: "vuu-toast-notification",
14
+ css: ToastNotification,
15
+ window: targetWindow
16
+ });
17
+ const { Component: FloatingComponent } = useFloatingComponent();
18
+ const { animationType, content, dismissal, header, icon, showCloseButton, status } = notification;
19
+ const iconName = false === icon ? void 0 : icon ?? status;
20
+ const callbackRef = useCallback((el)=>{
21
+ if (el) setTimeout(()=>{
22
+ const { height, width } = el.getBoundingClientRect();
23
+ if (id) onMeasured?.(id, height, width);
24
+ }, 60);
25
+ }, [
26
+ id,
27
+ onMeasured
28
+ ]);
29
+ const handleDismiss = useCallback(()=>{
30
+ onDismiss?.(id);
31
+ }, [
32
+ id,
33
+ onDismiss
34
+ ]);
35
+ const handleMouseEnter = useCallback(()=>onHoverEntry?.(id), [
36
+ id,
37
+ onHoverEntry
38
+ ]);
39
+ const handleMouseLeave = useCallback(()=>onHoverExit?.(id), [
40
+ id,
41
+ onHoverExit
42
+ ]);
43
+ if ("manual" === dismissal && false === showCloseButton) console.warn("[ToastNotification] invalid props, if dismissal is manual, showCloseButton should not be false");
44
+ const withCloseButton = showCloseButton || "manual" === dismissal;
45
+ return /*#__PURE__*/ jsxs(FloatingComponent, {
46
+ className: clsx(classBase, `${classBase}-${notification.status}`, {
47
+ [`${classBase}-hidden`]: hidden,
48
+ [`${classBase}-transparent`]: 0 === opacity,
49
+ [`${classBase}-withContent`]: void 0 !== content,
50
+ [`${classBase}-withIcon`]: false !== icon,
51
+ [`${classBase}-withTransition`]: void 0 !== animationType && !hidden,
52
+ [`${classBase}-withCloseButton`]: withCloseButton,
53
+ [`${classBase}-${notification.status}-${notification.className}`]: void 0 !== notification.className
54
+ }),
55
+ id: id,
56
+ left: left,
57
+ onMouseEnter: handleMouseEnter,
58
+ onMouseLeave: handleMouseLeave,
59
+ open: true,
60
+ position: "absolute",
61
+ ref: callbackRef,
62
+ role: "alert",
63
+ top: top,
64
+ children: [
65
+ iconName ? /*#__PURE__*/ jsx(Icon, {
66
+ name: iconName
67
+ }) : null,
68
+ /*#__PURE__*/ jsx("h3", {
69
+ className: `${classBase}-header`,
70
+ children: header
71
+ }),
72
+ content ? /*#__PURE__*/ jsx("div", {
73
+ className: `${classBase}-content`,
74
+ children: content
75
+ }) : null,
76
+ withCloseButton ? /*#__PURE__*/ jsx(IconButton, {
77
+ className: `${classBase}-closeButton`,
78
+ icon: "close",
79
+ onClick: handleDismiss,
80
+ appearance: "transparent",
81
+ sentiment: "neutral"
82
+ }) : null
83
+ ]
84
+ });
85
+ };
86
+ export { ToastNotification_ToastNotification as ToastNotification };
@@ -0,0 +1,16 @@
1
+ const css = `
2
+ .vuuWorkspaceNotification {
3
+ z-index: var(--salt-zIndex-notification);
4
+ position: absolute;
5
+
6
+ & .vuuWorkspaceNotification-content {
7
+ background: var(--salt-container-primary-background);
8
+ justify-content: center;
9
+ align-items: center;
10
+ display: flex;
11
+ }
12
+ }
13
+
14
+
15
+ `;
16
+ export default css;
@@ -0,0 +1,53 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { useFloatingComponent } from "@salt-ds/core";
3
+ import { useComponentCssInjection } from "@salt-ds/styles";
4
+ import { useWindow } from "@salt-ds/window";
5
+ import { VuuShellLocation } from "@vuu-ui/vuu-utils";
6
+ import clsx from "clsx";
7
+ import { useMemo } from "react";
8
+ import WorkspaceNotification from "./WorkspaceNotification.css";
9
+ const classBase = "vuuWorkspaceNotification";
10
+ const WorkspaceNotification_WorkspaceNotification = ({ children, className, style: styleProp, ...htmlAttributes })=>{
11
+ const targetWindow = useWindow();
12
+ useComponentCssInjection({
13
+ testId: "vuu-toast-notification",
14
+ css: WorkspaceNotification,
15
+ window: targetWindow
16
+ });
17
+ const { Component: FloatingComponent } = useFloatingComponent();
18
+ const [left, top, width, height] = useMemo(()=>{
19
+ const target = document.querySelector(`#${VuuShellLocation.WorkspaceContainer}`);
20
+ if (!target) return [
21
+ 0,
22
+ 0,
23
+ 200,
24
+ 200
25
+ ];
26
+ {
27
+ const { left, top, width, height } = target.getBoundingClientRect();
28
+ return [
29
+ left,
30
+ top,
31
+ width,
32
+ height
33
+ ];
34
+ }
35
+ }, []);
36
+ return /*#__PURE__*/ jsx(FloatingComponent, {
37
+ ...htmlAttributes,
38
+ className: clsx(classBase, className),
39
+ open: true,
40
+ role: "alert",
41
+ left: left,
42
+ top: top,
43
+ children: /*#__PURE__*/ jsx("div", {
44
+ className: `${classBase}-content`,
45
+ style: {
46
+ height,
47
+ width
48
+ },
49
+ children: children
50
+ })
51
+ });
52
+ };
53
+ export { WorkspaceNotification_WorkspaceNotification as WorkspaceNotification };
package/src/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export { NotificationType } from "./NotificationsContext.js";
2
+ export { NotificationsProvider, useNotifications } from "./NotificationsProvider.js";
3
+ export { ToastNotification } from "./ToastNotification.js";