@vuu-ui/vuu-notifications 2.0.0-alpha.1 → 2.1.0-alpha.1

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.
@@ -7,9 +7,12 @@ var NotificationsContext = require('./NotificationsContext.js');
7
7
  var ToastNotification = require('./ToastNotification.js');
8
8
  var WorkspaceNotification = require('./WorkspaceNotification.js');
9
9
 
10
+ const ZeroSize = { height: 0, width: 0 };
11
+ const toastContainerRightPadding = 20;
12
+ const NO_NOTIFICATIONS = [];
10
13
  const toastOffsetTop = 60;
11
- const toastDisplayDuration = 6e6;
12
- const horizontalTransitionDuration = 1e8;
14
+ const toastDisplayDuration = 6e3;
15
+ const toastDisplayDurationPostHover = 2e3;
13
16
  const toastContainerContentGap = 10;
14
17
  const NotificationsCenter = ({
15
18
  notificationsContext,
@@ -19,59 +22,225 @@ const NotificationsCenter = ({
19
22
  () => startupToastNotification ? [
20
23
  {
21
24
  ...startupToastNotification,
22
- id: vuuUtils.getUniqueId()
25
+ hidden: false,
26
+ id: vuuUtils.getUniqueId(),
27
+ left: -1,
28
+ size: ZeroSize
23
29
  }
24
30
  ] : [],
25
31
  [startupToastNotification]
26
32
  );
27
33
  const [workspaceNotification, setWorkspaceNotification] = React.useState(null);
28
- const [notifications, setNotifications] = React.useState(toastNotifications);
29
- const showNotification = React.useCallback((notification) => {
30
- if (NotificationsContext.isToastNotification(notification)) {
31
- if (notification.renderPostRefresh) {
32
- vuuUtils.saveLocalEntity("startup-notification", {
33
- ...notification,
34
- expires: +/* @__PURE__ */ new Date() + 1e4
35
- });
36
- } else {
37
- const newNotification = {
38
- ...notification,
39
- id: vuuUtils.getUniqueId()
40
- };
41
- setNotifications((prev) => prev.concat(newNotification));
42
- setTimeout(
43
- () => {
34
+ const hoveredToastRef = React.useRef(void 0);
35
+ const notificationsRef = React.useRef(NO_NOTIFICATIONS);
36
+ const [notifications, _setNotifications] = React.useState(toastNotifications);
37
+ const setNotifications = React.useCallback(
38
+ (notifications2) => {
39
+ _setNotifications(notificationsRef.current = notifications2);
40
+ },
41
+ []
42
+ );
43
+ const showNotification = React.useCallback(
44
+ (notification) => {
45
+ if (NotificationsContext.isToastNotification(notification)) {
46
+ const { animationType = "none", renderPostRefresh } = notification;
47
+ if (renderPostRefresh) {
48
+ vuuUtils.saveLocalEntity("startup-notification", {
49
+ ...notification,
50
+ expires: +/* @__PURE__ */ new Date() + 1e4
51
+ });
52
+ } else {
53
+ if (animationType.includes("slide-in")) {
44
54
  setNotifications(
45
- (prev) => prev.filter((n) => n !== newNotification)
55
+ notificationsRef.current.concat({
56
+ ...notification,
57
+ hidden: true,
58
+ id: vuuUtils.getUniqueId(),
59
+ left: -1,
60
+ size: ZeroSize
61
+ })
46
62
  );
47
- },
48
- toastDisplayDuration + horizontalTransitionDuration * 2
63
+ } else
64
+ setNotifications(
65
+ notificationsRef.current.concat({
66
+ ...notification,
67
+ hidden: false,
68
+ id: vuuUtils.getUniqueId(),
69
+ left: -1,
70
+ opacity: 0,
71
+ size: ZeroSize
72
+ })
73
+ );
74
+ }
75
+ } else if (NotificationsContext.isWorkspaceNotification(notification)) {
76
+ setWorkspaceNotification(
77
+ /* @__PURE__ */ jsxRuntime.jsx(WorkspaceNotification.WorkspaceNotification, { children: notification.content })
49
78
  );
79
+ } else {
80
+ throw Error("[NotificationsCenter] invalid notification received");
50
81
  }
51
- } else if (NotificationsContext.isWorkspaceNotification(notification)) {
52
- setWorkspaceNotification(
53
- /* @__PURE__ */ jsxRuntime.jsx(WorkspaceNotification.WorkspaceNotification, { children: notification.content })
54
- );
55
- } else {
56
- throw Error("[NotificationsCenter] invalid notification received");
57
- }
58
- }, []);
82
+ },
83
+ [setNotifications]
84
+ );
59
85
  const hideNotification = React.useCallback(() => {
60
86
  setWorkspaceNotification(null);
61
87
  }, []);
62
88
  React.useMemo(() => {
63
89
  notificationsContext.setNotify(showNotification, hideNotification);
64
90
  }, [hideNotification, notificationsContext, showNotification]);
91
+ const onMeasured = React.useCallback(
92
+ (id, height, width) => {
93
+ let scheduledUpdate = void 0;
94
+ const pageWidth = document.body.clientWidth;
95
+ setNotifications(
96
+ notificationsRef.current.map((n) => {
97
+ if (n.id === id) {
98
+ const slideIn = n.animationType?.includes("slide-in");
99
+ const newToast = {
100
+ ...n,
101
+ hidden: slideIn ? true : false,
102
+ left: slideIn ? pageWidth + width - toastContainerRightPadding : pageWidth - width - toastContainerRightPadding,
103
+ size: { height, width },
104
+ transitionStatus: "entry"
105
+ };
106
+ if (slideIn) {
107
+ scheduledUpdate = {
108
+ ...newToast,
109
+ hidden: false,
110
+ left: pageWidth - width - toastContainerRightPadding
111
+ };
112
+ } else {
113
+ scheduledUpdate = {
114
+ ...newToast,
115
+ opacity: 1
116
+ };
117
+ }
118
+ return newToast;
119
+ } else {
120
+ return n;
121
+ }
122
+ })
123
+ );
124
+ if (scheduledUpdate) {
125
+ const updateNotifications = notificationsRef.current.map((n) => {
126
+ if (n.id === scheduledUpdate?.id) {
127
+ return scheduledUpdate;
128
+ } else {
129
+ return n;
130
+ }
131
+ });
132
+ requestAnimationFrame(() => {
133
+ setNotifications(updateNotifications);
134
+ });
135
+ }
136
+ },
137
+ [setNotifications]
138
+ );
139
+ React.useEffect(() => {
140
+ document.body.addEventListener("transitionend", (e) => {
141
+ const { classList, id } = e.target;
142
+ if (classList?.contains("vuuToastNotification")) {
143
+ const notification = notificationsRef.current.find((n) => n.id === id);
144
+ if (notification?.transitionStatus === "exit") {
145
+ setNotifications(notificationsRef.current.filter((n) => n.id !== id));
146
+ } else if (notification?.dismissal !== "manual") {
147
+ setTimeout(() => {
148
+ if (notification && hoveredToastRef.current !== id) {
149
+ const pageWidth = document.body.clientWidth;
150
+ setNotifications(
151
+ notificationsRef.current.map((n) => {
152
+ if (n.id === id) {
153
+ if (n.animationType?.includes("slide-out")) {
154
+ return {
155
+ ...n,
156
+ transitionStatus: "exit",
157
+ left: pageWidth + toastContainerRightPadding
158
+ };
159
+ } else {
160
+ return {
161
+ ...n,
162
+ transitionStatus: "exit",
163
+ opacity: 0
164
+ };
165
+ }
166
+ } else {
167
+ return n;
168
+ }
169
+ }).filter((v) => v !== null)
170
+ );
171
+ }
172
+ }, toastDisplayDuration);
173
+ }
174
+ }
175
+ });
176
+ }, [setNotifications]);
177
+ const handleDismiss = React.useCallback(
178
+ (id) => {
179
+ if (id) {
180
+ setNotifications(notificationsRef.current.filter((n) => n.id !== id));
181
+ }
182
+ },
183
+ [setNotifications]
184
+ );
185
+ const handleHoverEntry = React.useCallback((id) => {
186
+ hoveredToastRef.current = id;
187
+ }, []);
188
+ const handleHoverExit = React.useCallback(
189
+ (id) => {
190
+ hoveredToastRef.current = void 0;
191
+ const notification = notificationsRef.current.find((n) => n.id === id);
192
+ setTimeout(() => {
193
+ if (notification) {
194
+ const pageWidth = document.body.clientWidth;
195
+ setNotifications(
196
+ notificationsRef.current.map((n) => {
197
+ if (n.id === id) {
198
+ if (n.animationType?.includes("slide-out")) {
199
+ return {
200
+ ...n,
201
+ transitionStatus: "exit",
202
+ left: pageWidth + toastContainerRightPadding
203
+ };
204
+ } else {
205
+ return {
206
+ ...n,
207
+ transitionStatus: "exit",
208
+ opacity: 0
209
+ };
210
+ }
211
+ } else {
212
+ return n;
213
+ }
214
+ }).filter((v) => v !== null)
215
+ );
216
+ }
217
+ }, toastDisplayDurationPostHover);
218
+ },
219
+ [setNotifications]
220
+ );
65
221
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
66
222
  workspaceNotification,
67
- notifications.map((notification, i) => /* @__PURE__ */ jsxRuntime.jsx(
68
- ToastNotification.ToastNotification,
69
- {
70
- top: toastOffsetTop + (ToastNotification.TOAST_HEIGHT + toastContainerContentGap) * i,
71
- notification
72
- },
73
- notification.id
74
- ))
223
+ notifications.map(
224
+ ({ hidden, id, left = 0, opacity, size, ...toast }, i) => {
225
+ const height = size ? size.height : 80;
226
+ return /* @__PURE__ */ jsxRuntime.jsx(
227
+ ToastNotification.ToastNotification,
228
+ {
229
+ hidden,
230
+ id,
231
+ left,
232
+ notification: toast,
233
+ onHoverEntry: handleHoverEntry,
234
+ onHoverExit: handleHoverExit,
235
+ onMeasured,
236
+ onDismiss: handleDismiss,
237
+ opacity,
238
+ top: toastOffsetTop + (height + toastContainerContentGap) * i
239
+ },
240
+ id
241
+ );
242
+ }
243
+ )
75
244
  ] });
76
245
  };
77
246
 
@@ -1 +1 @@
1
- {"version":3,"file":"NotificationsCenter.js","sources":["../../../packages/vuu-notifications/src/NotificationsCenter.tsx"],"sourcesContent":["import { getUniqueId, saveLocalEntity } from \"@vuu-ui/vuu-utils\";\nimport { ReactNode, useCallback, useMemo, useState } from \"react\";\nimport {\n isToastNotification,\n isWorkspaceNotification,\n Notification,\n NotificationsContext,\n ToastNotificationDescriptor,\n} from \"./NotificationsContext\";\nimport { TOAST_HEIGHT, ToastNotification } from \"./ToastNotification\";\nimport { WorkspaceNotification } from \"./WorkspaceNotification\";\n\nexport interface NotificationsCenterProps {\n notificationsContext: NotificationsContext;\n startupToastNotification?: ToastNotificationDescriptor;\n}\n\ninterface ToastNotificationWithId extends ToastNotificationDescriptor {\n id: string;\n}\n\n// animation times in milliseconds\nconst toastOffsetTop = 60;\n// const toastDisplayDuration = 6000;\nconst toastDisplayDuration = 6000000;\n// const horizontalTransitionDuration = 1000;\nconst horizontalTransitionDuration = 100000000;\n\nconst toastContainerContentGap = 10;\n// rightPadding is used together with the toastWidth to compute the toast position\n// at the beginning and at the end of the animation\n\nexport const NotificationsCenter = ({\n notificationsContext,\n startupToastNotification,\n}: NotificationsCenterProps) => {\n const toastNotifications = useMemo<ToastNotificationWithId[]>(\n () =>\n startupToastNotification\n ? [\n {\n ...startupToastNotification,\n id: getUniqueId(),\n },\n ]\n : [],\n [startupToastNotification],\n );\n\n const [workspaceNotification, setWorkspaceNotification] =\n useState<ReactNode>(null);\n\n const [notifications, setNotifications] =\n useState<ToastNotificationWithId[]>(toastNotifications);\n\n const showNotification = useCallback((notification: Notification) => {\n if (isToastNotification(notification)) {\n if (notification.renderPostRefresh) {\n saveLocalEntity(\"startup-notification\", {\n ...notification,\n expires: +new Date() + 10000,\n });\n } else {\n const newNotification: ToastNotificationWithId = {\n ...notification,\n id: getUniqueId(),\n };\n setNotifications((prev) => prev.concat(newNotification));\n setTimeout(\n () => {\n setNotifications((prev) =>\n prev.filter((n) => n !== newNotification),\n );\n },\n toastDisplayDuration + horizontalTransitionDuration * 2,\n );\n }\n } else if (isWorkspaceNotification(notification)) {\n setWorkspaceNotification(\n <WorkspaceNotification>{notification.content}</WorkspaceNotification>,\n );\n } else {\n throw Error(\"[NotificationsCenter] invalid notification received\");\n }\n }, []);\n\n const hideNotification = useCallback(() => {\n setWorkspaceNotification(null);\n }, []);\n\n useMemo(() => {\n notificationsContext.setNotify(showNotification, hideNotification);\n }, [hideNotification, notificationsContext, showNotification]);\n\n return (\n <>\n {workspaceNotification}\n {notifications.map((notification, i) => (\n <ToastNotification\n top={toastOffsetTop + (TOAST_HEIGHT + toastContainerContentGap) * i}\n notification={notification}\n key={notification.id}\n />\n ))}\n </>\n );\n};\n"],"names":["useMemo","getUniqueId","useState","useCallback","isToastNotification","saveLocalEntity","isWorkspaceNotification","jsx","WorkspaceNotification","jsxs","Fragment","ToastNotification","TOAST_HEIGHT"],"mappings":";;;;;;;;;AAsBA,MAAM,cAAiB,GAAA,EAAA;AAEvB,MAAM,oBAAuB,GAAA,GAAA;AAE7B,MAAM,4BAA+B,GAAA,GAAA;AAErC,MAAM,wBAA2B,GAAA,EAAA;AAI1B,MAAM,sBAAsB,CAAC;AAAA,EAClC,oBAAA;AAAA,EACA;AACF,CAAgC,KAAA;AAC9B,EAAA,MAAM,kBAAqB,GAAAA,aAAA;AAAA,IACzB,MACE,wBACI,GAAA;AAAA,MACE;AAAA,QACE,GAAG,wBAAA;AAAA,QACH,IAAIC,oBAAY;AAAA;AAClB,QAEF,EAAC;AAAA,IACP,CAAC,wBAAwB;AAAA,GAC3B;AAEA,EAAA,MAAM,CAAC,qBAAA,EAAuB,wBAAwB,CAAA,GACpDC,eAAoB,IAAI,CAAA;AAE1B,EAAA,MAAM,CAAC,aAAA,EAAe,gBAAgB,CAAA,GACpCA,eAAoC,kBAAkB,CAAA;AAExD,EAAM,MAAA,gBAAA,GAAmBC,iBAAY,CAAA,CAAC,YAA+B,KAAA;AACnE,IAAI,IAAAC,wCAAA,CAAoB,YAAY,CAAG,EAAA;AACrC,MAAA,IAAI,aAAa,iBAAmB,EAAA;AAClC,QAAAC,wBAAA,CAAgB,sBAAwB,EAAA;AAAA,UACtC,GAAG,YAAA;AAAA,UACH,OAAS,EAAA,iBAAK,IAAA,IAAA,EAAS,GAAA;AAAA,SACxB,CAAA;AAAA,OACI,MAAA;AACL,QAAA,MAAM,eAA2C,GAAA;AAAA,UAC/C,GAAG,YAAA;AAAA,UACH,IAAIJ,oBAAY;AAAA,SAClB;AACA,QAAA,gBAAA,CAAiB,CAAC,IAAA,KAAS,IAAK,CAAA,MAAA,CAAO,eAAe,CAAC,CAAA;AACvD,QAAA,UAAA;AAAA,UACE,MAAM;AACJ,YAAA,gBAAA;AAAA,cAAiB,CAAC,IAChB,KAAA,IAAA,CAAK,OAAO,CAAC,CAAA,KAAM,MAAM,eAAe;AAAA,aAC1C;AAAA,WACF;AAAA,UACA,uBAAuB,4BAA+B,GAAA;AAAA,SACxD;AAAA;AACF,KACF,MAAA,IAAWK,4CAAwB,CAAA,YAAY,CAAG,EAAA;AAChD,MAAA,wBAAA;AAAA,wBACEC,cAAA,CAACC,2CAAuB,EAAA,EAAA,QAAA,EAAA,YAAA,CAAa,OAAQ,EAAA;AAAA,OAC/C;AAAA,KACK,MAAA;AACL,MAAA,MAAM,MAAM,qDAAqD,CAAA;AAAA;AACnE,GACF,EAAG,EAAE,CAAA;AAEL,EAAM,MAAA,gBAAA,GAAmBL,kBAAY,MAAM;AACzC,IAAA,wBAAA,CAAyB,IAAI,CAAA;AAAA,GAC/B,EAAG,EAAE,CAAA;AAEL,EAAAH,aAAA,CAAQ,MAAM;AACZ,IAAqB,oBAAA,CAAA,SAAA,CAAU,kBAAkB,gBAAgB,CAAA;AAAA,GAChE,EAAA,CAAC,gBAAkB,EAAA,oBAAA,EAAsB,gBAAgB,CAAC,CAAA;AAE7D,EAAA,uBAEKS,eAAA,CAAAC,mBAAA,EAAA,EAAA,QAAA,EAAA;AAAA,IAAA,qBAAA;AAAA,IACA,aAAc,CAAA,GAAA,CAAI,CAAC,YAAA,EAAc,CAChC,qBAAAH,cAAA;AAAA,MAACI,mCAAA;AAAA,MAAA;AAAA,QACC,GAAA,EAAK,cAAkB,GAAA,CAAAC,8BAAA,GAAe,wBAA4B,IAAA,CAAA;AAAA,QAClE;AAAA,OAAA;AAAA,MACK,YAAa,CAAA;AAAA,KAErB;AAAA,GACH,EAAA,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"NotificationsCenter.js","sources":["../../../packages/vuu-notifications/src/NotificationsCenter.tsx"],"sourcesContent":["import { getUniqueId, saveLocalEntity } from \"@vuu-ui/vuu-utils\";\nimport {\n ReactNode,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport {\n isToastNotification,\n isWorkspaceNotification,\n Notification,\n NotificationsContext,\n ToastNotificationDescriptor,\n} from \"./NotificationsContext\";\nimport { ToastHoverHandler, ToastNotification } from \"./ToastNotification\";\nimport { WorkspaceNotification } from \"./WorkspaceNotification\";\nimport { MeasuredSize } from \"@vuu-ui/vuu-ui-controls\";\n\nconst ZeroSize: MeasuredSize = { height: 0, width: 0 };\nconst toastContainerRightPadding = 20;\nconst NO_NOTIFICATIONS: RuntimeToastNotification[] = [];\nexport interface NotificationsCenterProps {\n notificationsContext: NotificationsContext;\n startupToastNotification?: ToastNotificationDescriptor;\n}\n\ntype TransitionStatus = \"entry\" | \"exit\";\ninterface RuntimeToastNotification extends ToastNotificationDescriptor {\n hidden: boolean;\n id: string;\n left: number;\n opacity?: number;\n size: MeasuredSize;\n transitionStatus?: TransitionStatus;\n}\n\n// animation times in milliseconds\nconst toastOffsetTop = 60;\nconst toastDisplayDuration = 6000;\nconst toastDisplayDurationPostHover = 2000;\n\nconst toastContainerContentGap = 10;\n// rightPadding is used together with the toastWidth to compute the toast position\n// at the beginning and at the end of the animation\n\nexport const NotificationsCenter = ({\n notificationsContext,\n startupToastNotification,\n}: NotificationsCenterProps) => {\n const toastNotifications = useMemo<RuntimeToastNotification[]>(\n () =>\n startupToastNotification\n ? [\n {\n ...startupToastNotification,\n hidden: false,\n id: getUniqueId(),\n left: -1,\n size: ZeroSize,\n },\n ]\n : [],\n [startupToastNotification],\n );\n\n const [workspaceNotification, setWorkspaceNotification] =\n useState<ReactNode>(null);\n\n const hoveredToastRef = useRef<string | undefined>(undefined);\n const notificationsRef = useRef<RuntimeToastNotification[]>(NO_NOTIFICATIONS);\n const [notifications, _setNotifications] =\n useState<RuntimeToastNotification[]>(toastNotifications);\n\n const setNotifications = useCallback(\n (notifications: RuntimeToastNotification[]) => {\n _setNotifications((notificationsRef.current = notifications));\n },\n [],\n );\n\n const showNotification = useCallback(\n (notification: Notification) => {\n if (isToastNotification(notification)) {\n const { animationType = \"none\", renderPostRefresh } = notification;\n if (renderPostRefresh) {\n saveLocalEntity(\"startup-notification\", {\n ...notification,\n expires: +new Date() + 10000,\n });\n } else {\n if (animationType.includes(\"slide-in\")) {\n setNotifications(\n notificationsRef.current.concat({\n ...notification,\n hidden: true,\n id: getUniqueId(),\n left: -1,\n size: ZeroSize,\n }),\n );\n } else\n setNotifications(\n notificationsRef.current.concat({\n ...notification,\n hidden: false,\n id: getUniqueId(),\n left: -1,\n opacity: 0,\n size: ZeroSize,\n }),\n );\n }\n } else if (isWorkspaceNotification(notification)) {\n setWorkspaceNotification(\n <WorkspaceNotification>{notification.content}</WorkspaceNotification>,\n );\n } else {\n throw Error(\"[NotificationsCenter] invalid notification received\");\n }\n },\n [setNotifications],\n );\n\n const hideNotification = useCallback(() => {\n setWorkspaceNotification(null);\n }, []);\n\n useMemo(() => {\n notificationsContext.setNotify(showNotification, hideNotification);\n }, [hideNotification, notificationsContext, showNotification]);\n\n const onMeasured = useCallback(\n (id: string, height: number, width: number) => {\n let scheduledUpdate: RuntimeToastNotification | undefined = undefined;\n const pageWidth = document.body.clientWidth;\n\n setNotifications(\n notificationsRef.current.map((n) => {\n if (n.id === id) {\n const slideIn = n.animationType?.includes(\"slide-in\");\n const newToast: RuntimeToastNotification = {\n ...n,\n hidden: slideIn ? true : false,\n left: slideIn\n ? pageWidth + width - toastContainerRightPadding\n : pageWidth - width - toastContainerRightPadding,\n size: { height, width },\n transitionStatus: \"entry\",\n };\n\n if (slideIn) {\n scheduledUpdate = {\n ...newToast,\n hidden: false,\n left: pageWidth - width - toastContainerRightPadding,\n };\n } else {\n scheduledUpdate = {\n ...newToast,\n opacity: 1,\n };\n }\n\n return newToast;\n } else {\n return n;\n }\n }),\n );\n\n if (scheduledUpdate) {\n const updateNotifications = notificationsRef.current.map((n) => {\n if (n.id === scheduledUpdate?.id) {\n return scheduledUpdate;\n } else {\n return n;\n }\n });\n requestAnimationFrame(() => {\n setNotifications(updateNotifications);\n });\n }\n },\n [setNotifications],\n );\n\n useEffect(() => {\n // This handles both the entry transition and the exit transition\n document.body.addEventListener(\"transitionend\", (e) => {\n const { classList, id } = e.target as HTMLElement;\n if (classList?.contains(\"vuuToastNotification\")) {\n const notification = notificationsRef.current.find((n) => n.id === id);\n if (notification?.transitionStatus === \"exit\") {\n setNotifications(notificationsRef.current.filter((n) => n.id !== id));\n } else if (notification?.dismissal !== \"manual\") {\n setTimeout(() => {\n // In case notification has been manually cancelled ...\n if (notification && hoveredToastRef.current !== id) {\n const pageWidth = document.body.clientWidth;\n setNotifications(\n notificationsRef.current\n .map((n) => {\n if (n.id === id) {\n if (n.animationType?.includes(\"slide-out\")) {\n return {\n ...n,\n transitionStatus: \"exit\" as TransitionStatus,\n left: pageWidth + toastContainerRightPadding,\n };\n } else {\n return {\n ...n,\n transitionStatus: \"exit\" as TransitionStatus,\n opacity: 0,\n };\n }\n } else {\n return n;\n }\n })\n .filter((v) => v !== null),\n );\n }\n }, toastDisplayDuration);\n }\n }\n });\n }, [setNotifications]);\n\n const handleDismiss = useCallback(\n (id?: string) => {\n if (id) {\n setNotifications(notificationsRef.current.filter((n) => n.id !== id));\n }\n },\n [setNotifications],\n );\n\n const handleHoverEntry = useCallback<ToastHoverHandler>((id) => {\n hoveredToastRef.current = id;\n }, []);\n\n const handleHoverExit = useCallback<ToastHoverHandler>(\n (id) => {\n hoveredToastRef.current = undefined;\n const notification = notificationsRef.current.find((n) => n.id === id);\n setTimeout(() => {\n // In case notification has been manually cancelled ...\n if (notification) {\n const pageWidth = document.body.clientWidth;\n setNotifications(\n notificationsRef.current\n .map((n) => {\n if (n.id === id) {\n if (n.animationType?.includes(\"slide-out\")) {\n return {\n ...n,\n transitionStatus: \"exit\" as TransitionStatus,\n left: pageWidth + toastContainerRightPadding,\n };\n } else {\n return {\n ...n,\n transitionStatus: \"exit\" as TransitionStatus,\n opacity: 0,\n };\n }\n } else {\n return n;\n }\n })\n .filter((v) => v !== null),\n );\n }\n }, toastDisplayDurationPostHover);\n },\n [setNotifications],\n );\n\n return (\n <>\n {workspaceNotification}\n {notifications.map(\n ({ hidden, id, left = 0, opacity, size, ...toast }, i) => {\n const height = size ? size.height : 80;\n return (\n <ToastNotification\n hidden={hidden}\n id={id}\n key={id}\n left={left}\n notification={toast}\n onHoverEntry={handleHoverEntry}\n onHoverExit={handleHoverExit}\n onMeasured={onMeasured}\n onDismiss={handleDismiss}\n opacity={opacity}\n top={toastOffsetTop + (height + toastContainerContentGap) * i}\n />\n );\n },\n )}\n </>\n );\n};\n"],"names":["useMemo","getUniqueId","useState","useRef","useCallback","notifications","isToastNotification","saveLocalEntity","isWorkspaceNotification","jsx","WorkspaceNotification","useEffect","jsxs","Fragment","ToastNotification"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"NotificationsContext.js","sources":["../../../packages/vuu-notifications/src/NotificationsContext.tsx"],"sourcesContent":["import { type ValidationStatus } from \"@salt-ds/core\";\nimport { ValueOf } from \"@vuu-ui/vuu-utils\";\nimport { ReactNode } from \"react\";\n\nexport type DispatchShowNotification = (notification: Notification) => void;\nexport type DispatchHideNotification = () => void;\n\nexport const NotificationType = {\n Toast: \"toast\",\n Workspace: \"workspace\",\n} as const;\n\nexport type NotificationType = ValueOf<typeof NotificationType>;\n\nexport type NotificationAnimationType =\n | \"slide-in\"\n | \"slide-out\"\n | \"slide-in,slide-out\";\n\ninterface NotificationDescriptorBase<T extends NotificationType> {\n animationType?: NotificationAnimationType;\n renderPostRefresh?: boolean;\n status: ValidationStatus;\n type: T;\n}\n\nexport interface ToastNotificationDescriptor\n extends NotificationDescriptorBase<\"toast\"> {\n content: ReactNode;\n header: string;\n}\n\nexport interface WorkspaceNotificationDescriptor\n extends NotificationDescriptorBase<\"workspace\"> {\n content: ReactNode;\n}\n\nexport type Notification =\n | ToastNotificationDescriptor\n | WorkspaceNotificationDescriptor;\n\nexport const isToastNotification = (\n n: Notification,\n): n is ToastNotificationDescriptor => n.type === NotificationType.Toast;\n\nexport const isWorkspaceNotification = (\n n: Notification,\n): n is WorkspaceNotificationDescriptor =>\n n.type === NotificationType.Workspace;\n\nexport type NotificationsContext = {\n hideNotification: DispatchHideNotification;\n showNotification: DispatchShowNotification;\n setNotify: (\n showNotificationDispatcher: DispatchShowNotification,\n hideNotificationDispatcher: DispatchHideNotification,\n ) => void;\n};\n"],"names":[],"mappings":";;AAOO,MAAM,gBAAmB,GAAA;AAAA,EAC9B,KAAO,EAAA,OAAA;AAAA,EACP,SAAW,EAAA;AACb;AA+BO,MAAM,mBAAsB,GAAA,CACjC,CACqC,KAAA,CAAA,CAAE,SAAS,gBAAiB,CAAA;AAE5D,MAAM,uBAA0B,GAAA,CACrC,CAEA,KAAA,CAAA,CAAE,SAAS,gBAAiB,CAAA;;;;;;"}
1
+ {"version":3,"file":"NotificationsContext.js","sources":["../../../packages/vuu-notifications/src/NotificationsContext.tsx"],"sourcesContent":["import { type ValidationStatus } from \"@salt-ds/core\";\nimport { ValueOf } from \"@vuu-ui/vuu-utils\";\nimport { ReactNode } from \"react\";\n\nexport type DispatchShowNotification = (notification: Notification) => void;\nexport type DispatchHideNotification = () => void;\n\nexport const NotificationType = {\n Toast: \"toast\",\n Workspace: \"workspace\",\n} as const;\n\nexport type NotificationType = ValueOf<typeof NotificationType>;\n\nexport type DismissalStyle = \"automatic\" | \"manual\";\n\nexport type NotificationAnimationType =\n | \"slide-in\"\n | \"slide-out\"\n | \"slide-in,slide-out\";\n\ninterface NotificationDescriptorBase<T extends NotificationType> {\n animationType?: NotificationAnimationType;\n /**\n * 'automatic' dismissal means the Notification will be removed after a configurable delay\n * (6 seconds by default). 'manual' means a close button will be rendered and user must\n * manually dismiss by clicking the close button.\n */\n dismissal?: DismissalStyle;\n /**\n * A custom icon can be provided or false can be used to suppress rendering of any icon.\n * Default icons will be rendered for the different status values.\n */\n icon?: string | false;\n renderPostRefresh?: boolean;\n showCloseButton?: boolean;\n status: ValidationStatus;\n type: T;\n}\n\nexport interface ToastNotificationDescriptor\n extends NotificationDescriptorBase<\"toast\"> {\n content?: ReactNode;\n header: string;\n}\n\nexport interface WorkspaceNotificationDescriptor\n extends NotificationDescriptorBase<\"workspace\"> {\n content: ReactNode;\n}\n\nexport type Notification =\n | ToastNotificationDescriptor\n | WorkspaceNotificationDescriptor;\n\nexport const isToastNotification = (\n n: Notification,\n): n is ToastNotificationDescriptor => n.type === NotificationType.Toast;\n\nexport const isWorkspaceNotification = (\n n: Notification,\n): n is WorkspaceNotificationDescriptor =>\n n.type === NotificationType.Workspace;\n\nexport type NotificationsContext = {\n hideNotification: DispatchHideNotification;\n showNotification: DispatchShowNotification;\n setNotify: (\n showNotificationDispatcher: DispatchShowNotification,\n hideNotificationDispatcher: DispatchHideNotification,\n ) => void;\n};\n"],"names":[],"mappings":";;AAOO,MAAM,gBAAmB,GAAA;AAAA,EAC9B,KAAO,EAAA,OAAA;AAAA,EACP,SAAW,EAAA;AACb;AA6CO,MAAM,mBAAsB,GAAA,CACjC,CACqC,KAAA,CAAA,CAAE,SAAS,gBAAiB,CAAA;AAE5D,MAAM,uBAA0B,GAAA,CACrC,CAEA,KAAA,CAAA,CAAE,SAAS,gBAAiB,CAAA;;;;;;"}
@@ -35,7 +35,6 @@ const NotificationsContext = React.createContext(
35
35
  new NotificationsContextObject()
36
36
  );
37
37
  const NotificationsProvider = (props) => {
38
- console.log(`%c[NotificationsProvider]`, "color:green;font-weight: bold;");
39
38
  const context = React.useContext(NotificationsContext);
40
39
  const startupToastNotification = React.useMemo(() => {
41
40
  const toast = vuuUtils.getLocalEntity("startup-notification", true);
@@ -1 +1 @@
1
- {"version":3,"file":"NotificationsProvider.js","sources":["../../../packages/vuu-notifications/src/NotificationsProvider.tsx"],"sourcesContent":["import React, { ReactElement, useContext, useMemo } from \"react\";\nimport { NotificationsCenter } from \"./NotificationsCenter\";\nimport {\n DispatchHideNotification,\n DispatchShowNotification,\n type NotificationsContext,\n ToastNotificationDescriptor,\n} from \"./NotificationsContext\";\nimport { getLocalEntity } from \"@vuu-ui/vuu-utils\";\n\ninterface ToastWithExpiry extends ToastNotificationDescriptor {\n expires: number;\n}\n\n/*\n The Context is not exposed outside this module, only the notify\n prop can be accessed via the useNotifications hook.\n The NotificationsCenter receives the full context object and\n sets the notify method. State management around dispatched\n notifications is handled entirely within the NotificationsCenter,\n avoiding rerendering our children when notifications are \n dispatched.\n*/\nclass NotificationsContextObject implements NotificationsContext {\n #showNotification: DispatchShowNotification = () =>\n console.log(\"have you forgotten to provide a NotificationsCenter?\");\n #hideNotification: DispatchHideNotification = () =>\n console.log(\"have you forgotten to provide a NotificationsCenter?\");\n // We want the public notify method to be stable, setNotify call should not trigger re-renders\n showNotification: DispatchShowNotification = (notification) =>\n this.#showNotification(notification);\n hideNotification: DispatchHideNotification = () => this.#hideNotification();\n setNotify = (\n showNotificationDispatcher: DispatchShowNotification,\n hideNotificationDispatcher: DispatchHideNotification,\n ) => {\n this.#showNotification = showNotificationDispatcher;\n this.#hideNotification = hideNotificationDispatcher;\n };\n}\n\nconst NotificationsContext = React.createContext<NotificationsContext>(\n new NotificationsContextObject(),\n);\n\nexport const NotificationsProvider = (props: {\n children: ReactElement | ReactElement[];\n}) => {\n console.log(`%c[NotificationsProvider]`, \"color:green;font-weight: bold;\");\n const context = useContext(NotificationsContext);\n const startupToastNotification = useMemo<\n ToastNotificationDescriptor | undefined\n >(() => {\n const toast = getLocalEntity<ToastWithExpiry>(\"startup-notification\", true);\n if (toast && toast.expires >= +Date.now()) {\n const { expires, ...toastDescriptor } = toast;\n return toastDescriptor;\n }\n }, []);\n return (\n <NotificationsContext.Provider value={context}>\n <NotificationsCenter\n startupToastNotification={startupToastNotification}\n notificationsContext={context}\n />\n {props.children}\n </NotificationsContext.Provider>\n );\n};\n\nexport const useNotifications = () => {\n const { hideNotification, showNotification } =\n useContext(NotificationsContext);\n return { hideNotification, showNotification };\n};\n"],"names":["useContext","useMemo","getLocalEntity","jsxs","jsx","NotificationsCenter"],"mappings":";;;;;;;;;;;;;;;;;AAAA,IAAA,iBAAA,EAAA,iBAAA;AAuBA,MAAM,0BAA2D,CAAA;AAAA,EAAjE,WAAA,GAAA;AACE,IAA8C,YAAA,CAAA,IAAA,EAAA,iBAAA,EAAA,MAC5C,OAAQ,CAAA,GAAA,CAAI,sDAAsD,CAAA,CAAA;AACpE,IAA8C,YAAA,CAAA,IAAA,EAAA,iBAAA,EAAA,MAC5C,OAAQ,CAAA,GAAA,CAAI,sDAAsD,CAAA,CAAA;AAEpE;AAAA,IAAA,aAAA,CAAA,IAAA,EAAA,kBAAA,EAA6C,CAAC,YAAA,KAC5C,YAAK,CAAA,IAAA,EAAA,iBAAA,CAAA,CAAL,IAAuB,CAAA,IAAA,EAAA,YAAA,CAAA,CAAA;AACzB,IAA6C,aAAA,CAAA,IAAA,EAAA,kBAAA,EAAA,MAAM,mBAAK,iBAAL,CAAA,CAAA,IAAA,CAAA,IAAA,CAAA,CAAA;AACnD,IAAY,aAAA,CAAA,IAAA,EAAA,WAAA,EAAA,CACV,4BACA,0BACG,KAAA;AACH,MAAA,YAAA,CAAA,IAAA,EAAK,iBAAoB,EAAA,0BAAA,CAAA;AACzB,MAAA,YAAA,CAAA,IAAA,EAAK,iBAAoB,EAAA,0BAAA,CAAA;AAAA,KAC3B,CAAA;AAAA;AACF;AAfE,iBAAA,GAAA,IAAA,OAAA,EAAA;AAEA,iBAAA,GAAA,IAAA,OAAA,EAAA;AAeF,MAAM,uBAAuB,KAAM,CAAA,aAAA;AAAA,EACjC,IAAI,0BAA2B;AACjC,CAAA;AAEa,MAAA,qBAAA,GAAwB,CAAC,KAEhC,KAAA;AACJ,EAAQ,OAAA,CAAA,GAAA,CAAI,6BAA6B,gCAAgC,CAAA;AACzE,EAAM,MAAA,OAAA,GAAUA,iBAAW,oBAAoB,CAAA;AAC/C,EAAM,MAAA,wBAAA,GAA2BC,cAE/B,MAAM;AACN,IAAM,MAAA,KAAA,GAAQC,uBAAgC,CAAA,sBAAA,EAAwB,IAAI,CAAA;AAC1E,IAAA,IAAI,SAAS,KAAM,CAAA,OAAA,IAAW,CAAC,IAAA,CAAK,KAAO,EAAA;AACzC,MAAA,MAAM,EAAE,OAAA,EAAS,GAAG,eAAA,EAAoB,GAAA,KAAA;AACxC,MAAO,OAAA,eAAA;AAAA;AACT,GACF,EAAG,EAAE,CAAA;AACL,EAAA,uBACGC,eAAA,CAAA,oBAAA,CAAqB,QAArB,EAAA,EAA8B,OAAO,OACpC,EAAA,QAAA,EAAA;AAAA,oBAAAC,cAAA;AAAA,MAACC,uCAAA;AAAA,MAAA;AAAA,QACC,wBAAA;AAAA,QACA,oBAAsB,EAAA;AAAA;AAAA,KACxB;AAAA,IACC,KAAM,CAAA;AAAA,GACT,EAAA,CAAA;AAEJ;AAEO,MAAM,mBAAmB,MAAM;AACpC,EAAA,MAAM,EAAE,gBAAA,EAAkB,gBAAiB,EAAA,GACzCL,iBAAW,oBAAoB,CAAA;AACjC,EAAO,OAAA,EAAE,kBAAkB,gBAAiB,EAAA;AAC9C;;;;;"}
1
+ {"version":3,"file":"NotificationsProvider.js","sources":["../../../packages/vuu-notifications/src/NotificationsProvider.tsx"],"sourcesContent":["import React, { ReactElement, useContext, useMemo } from \"react\";\nimport { NotificationsCenter } from \"./NotificationsCenter\";\nimport {\n DispatchHideNotification,\n DispatchShowNotification,\n type NotificationsContext,\n ToastNotificationDescriptor,\n} from \"./NotificationsContext\";\nimport { getLocalEntity } from \"@vuu-ui/vuu-utils\";\n\ninterface ToastWithExpiry extends ToastNotificationDescriptor {\n expires: number;\n}\n\n/*\n The Context is not exposed outside this module, only the notify\n prop can be accessed via the useNotifications hook.\n The NotificationsCenter receives the full context object and\n sets the notify method. State management around dispatched\n notifications is handled entirely within the NotificationsCenter,\n avoiding rerendering our children when notifications are \n dispatched.\n*/\nclass NotificationsContextObject implements NotificationsContext {\n #showNotification: DispatchShowNotification = () =>\n console.log(\"have you forgotten to provide a NotificationsCenter?\");\n #hideNotification: DispatchHideNotification = () =>\n console.log(\"have you forgotten to provide a NotificationsCenter?\");\n // We want the public notify method to be stable, setNotify call should not trigger re-renders\n showNotification: DispatchShowNotification = (notification) =>\n this.#showNotification(notification);\n hideNotification: DispatchHideNotification = () => this.#hideNotification();\n setNotify = (\n showNotificationDispatcher: DispatchShowNotification,\n hideNotificationDispatcher: DispatchHideNotification,\n ) => {\n this.#showNotification = showNotificationDispatcher;\n this.#hideNotification = hideNotificationDispatcher;\n };\n}\n\nconst NotificationsContext = React.createContext<NotificationsContext>(\n new NotificationsContextObject(),\n);\n\nexport const NotificationsProvider = (props: {\n children: ReactElement | ReactElement[];\n}) => {\n const context = useContext(NotificationsContext);\n const startupToastNotification = useMemo<\n ToastNotificationDescriptor | undefined\n >(() => {\n const toast = getLocalEntity<ToastWithExpiry>(\"startup-notification\", true);\n if (toast && toast.expires >= +Date.now()) {\n const { expires, ...toastDescriptor } = toast;\n return toastDescriptor;\n }\n }, []);\n return (\n <NotificationsContext.Provider value={context}>\n <NotificationsCenter\n startupToastNotification={startupToastNotification}\n notificationsContext={context}\n />\n {props.children}\n </NotificationsContext.Provider>\n );\n};\n\nexport const useNotifications = () => {\n const { hideNotification, showNotification } =\n useContext(NotificationsContext);\n return { hideNotification, showNotification };\n};\n"],"names":["useContext","useMemo","getLocalEntity","jsxs","jsx","NotificationsCenter"],"mappings":";;;;;;;;;;;;;;;;;AAAA,IAAA,iBAAA,EAAA,iBAAA;AAuBA,MAAM,0BAA2D,CAAA;AAAA,EAAjE,WAAA,GAAA;AACE,IAA8C,YAAA,CAAA,IAAA,EAAA,iBAAA,EAAA,MAC5C,OAAQ,CAAA,GAAA,CAAI,sDAAsD,CAAA,CAAA;AACpE,IAA8C,YAAA,CAAA,IAAA,EAAA,iBAAA,EAAA,MAC5C,OAAQ,CAAA,GAAA,CAAI,sDAAsD,CAAA,CAAA;AAEpE;AAAA,IAAA,aAAA,CAAA,IAAA,EAAA,kBAAA,EAA6C,CAAC,YAAA,KAC5C,YAAK,CAAA,IAAA,EAAA,iBAAA,CAAA,CAAL,IAAuB,CAAA,IAAA,EAAA,YAAA,CAAA,CAAA;AACzB,IAA6C,aAAA,CAAA,IAAA,EAAA,kBAAA,EAAA,MAAM,mBAAK,iBAAL,CAAA,CAAA,IAAA,CAAA,IAAA,CAAA,CAAA;AACnD,IAAY,aAAA,CAAA,IAAA,EAAA,WAAA,EAAA,CACV,4BACA,0BACG,KAAA;AACH,MAAA,YAAA,CAAA,IAAA,EAAK,iBAAoB,EAAA,0BAAA,CAAA;AACzB,MAAA,YAAA,CAAA,IAAA,EAAK,iBAAoB,EAAA,0BAAA,CAAA;AAAA,KAC3B,CAAA;AAAA;AACF;AAfE,iBAAA,GAAA,IAAA,OAAA,EAAA;AAEA,iBAAA,GAAA,IAAA,OAAA,EAAA;AAeF,MAAM,uBAAuB,KAAM,CAAA,aAAA;AAAA,EACjC,IAAI,0BAA2B;AACjC,CAAA;AAEa,MAAA,qBAAA,GAAwB,CAAC,KAEhC,KAAA;AACJ,EAAM,MAAA,OAAA,GAAUA,iBAAW,oBAAoB,CAAA;AAC/C,EAAM,MAAA,wBAAA,GAA2BC,cAE/B,MAAM;AACN,IAAM,MAAA,KAAA,GAAQC,uBAAgC,CAAA,sBAAA,EAAwB,IAAI,CAAA;AAC1E,IAAA,IAAI,SAAS,KAAM,CAAA,OAAA,IAAW,CAAC,IAAA,CAAK,KAAO,EAAA;AACzC,MAAA,MAAM,EAAE,OAAA,EAAS,GAAG,eAAA,EAAoB,GAAA,KAAA;AACxC,MAAO,OAAA,eAAA;AAAA;AACT,GACF,EAAG,EAAE,CAAA;AACL,EAAA,uBACGC,eAAA,CAAA,oBAAA,CAAqB,QAArB,EAAA,EAA8B,OAAO,OACpC,EAAA,QAAA,EAAA;AAAA,oBAAAC,cAAA;AAAA,MAACC,uCAAA;AAAA,MAAA;AAAA,QACC,wBAAA;AAAA,QACA,oBAAsB,EAAA;AAAA;AAAA,KACxB;AAAA,IACC,KAAM,CAAA;AAAA,GACT,EAAA,CAAA;AAEJ;AAEO,MAAM,mBAAmB,MAAM;AACpC,EAAA,MAAM,EAAE,gBAAA,EAAkB,gBAAiB,EAAA,GACzCL,iBAAW,oBAAoB,CAAA;AACjC,EAAO,OAAA,EAAE,kBAAkB,gBAAiB,EAAA;AAC9C;;;;;"}
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var toastNotificationCss = ".vuuToastNotification {\n\n background: var(--vuuToastNotification-background, var(--toast-background));\n border-radius: var(--vuuToastNotification-borderRadius, var(--salt-curve-100, 0));\n box-sizing: border-box;\n box-shadow: var(--salt-overlayable-shadow-popout);\n\n\n\n &.vuuToastNotification-error {\n --toast-background: var(--vuuToastNotification-error-background, var(--salt-container-primary-background));\n }\n\n &.vuuToastNotification-success {\n --toast-background: var(--vuuToastNotification-success-background, var(--salt-container-primary-background));\n }\n}";
3
+ var toastNotificationCss = ".vuuToastNotification {\n --toast-transition-duration: .4s;\n --padding-base: var(--vuuToast-padding, var(--salt-spacing-300));\n\n align-items: center;;\n background: var(--vuuToast-background, var(--toast-background));\n border-radius: var(--vuuToast-borderRadius, var(--salt-curve-100, 0));\n box-sizing: border-box;\n box-shadow: var(--salt-overlayable-shadow-popout);\n color: var(--vuuToast-foreground, var(--toast-foreground));\n column-gap: var(--salt-spacing-100);\n display: grid;\n grid-template-areas: var(--vuuToast-grid-template-areas, \n \"toast-header\"\n );\n grid-template-columns: auto;\n max-width: var(--vuuToast-maxWidth, 600px);\n min-width: var(--vuuToast-minWidth, 300px);\n opacity: 1;\n padding: var(--padding-base);\n row-gap: var(--salt-spacing-100);\n transition: opacity .4s, top;\n\n &.vuuToastNotification-hidden {\n visibility: hidden;\n }\n\n &.vuuToastNotification-withCloseButton {\n grid-template-areas: var(--vuuToast-grid-template-areas, \n \"toast-header close-button\"\n );\n grid-template-columns: 1fr 36px;\n }\n\n &.vuuToastNotification-withIcon {\n grid-template-areas: var(--vuuToast-grid-template-areas, \n \"toast-icon toast-header\"\n );\n grid-template-columns: var(--vuuToast-gridTemplateColumns, 36px auto);\n }\n\n &.vuuToastNotification-withIcon.vuuToastNotification-withCloseButton {\n grid-template-areas: var(--vuuToast-grid-template-areas, \n \"toast-icon toast-header close-button\"\n );\n grid-template-columns: var(--vuuToast-gridTemplateColumns, 36px auto 36px);\n }\n\n &.vuuToastNotification-withContent {\n grid-template-areas: var(--vuuToast-grid-template-areas, \n \"toast-header\"\n \"toast-content\"\n );\n }\n &.vuuToastNotification-withContent.vuuToastNotification-withCloseButton {\n grid-template-areas: var(--vuuToast-grid-template-areas, \n \"toast-header close-button\"\n \"toast-content close-button\"\n );\n grid-template-columns: 1fr 36px;\n }\n\n &.vuuToastNotification-withTransition {\n transition: top .2s ease-out, left var(--toast-transition-duration) ease-in, opacity .4s;\n }\n\n &.vuuToastNotification-transparent {\n opacity: 0;\n transition: top .2s ease-out, opacity .4s;\n }\n\n &.vuuToastNotification-withIcon.vuuToastNotification-withContent {\n grid-template-areas: var(--vuuToast-grid-template-areas, \n \"toast-icon toast-header\"\n \"toast-icon toast-content\"\n );\n grid-template-columns: var(--vuuToast-gridTemplateColumns, 36px auto);\n }\n\n &.vuuToastNotification-withIcon.vuuToastNotification-withContent.vuuToastNotification-withCloseButton {\n grid-template-areas: var(--vuuToast-grid-template-areas, \n \"toast-icon toast-header close-button\"\n \"toast-icon toast-content close-button\"\n );\n grid-template-columns: var(--vuuToast-gridTemplateColumns, 36px auto 36px);\n }\n\n &.vuuToastNotification-error {\n --toast-background: var(--vuuToast-error-background, var(--salt-container-primary-background));\n --toast-foreground: var(--vuuToast-error-foreground, var(--salt-content-primary-foreground));\n }\n\n &.vuuToastNotification-success {\n --toast-background: var(--vuuToast-success-background, var(--salt-container-primary-background));\n --toast-foreground: var(--vuuToast-success-foreground, var(--salt-content-primary-foreground));\n --vuu-icon-svg: var(--vuuToast-success-icon, var(--vuu-svg-tick));\n }\n &.vuuToastNotification-warning {\n --toast-background: var(--vuuToast-warning-background, var(--salt-container-primary-background));\n --toast-foreground: var(--vuuToast-warning-foreground, var(--salt-content-primary-foreground));\n --vuu-icon-svg: var(--vuuToast-warning-icon, var(--vuu-svg-tick));\n }\n &.vuuToastNotification-info {\n --toast-background: var(--vuuToast-info-background, var(--salt-container-primary-background));\n --toast-foreground: var(--vuuToast-info-foreground, var(--salt-content-primary-foreground));\n --vuu-icon-svg: var(--vuuToast-info-icon, var(--vuu-svg-tick));\n }\n\n .vuuIcon {\n --vuu-icon-color: var(--toast-foreground);\n --vuu-icon-size: 20px;\n grid-area:toast-icon;\n justify-self: center;\n }\n\n .vuuToastNotification-header {\n font-size: var(--vuuToast-header-fontSize, var(--salt-text-h3-fontSize));\n font-weight: var(--salt-text-display1-fontWeight-strong);\n grid-area: toast-header;\n justify-self: start;\n line-height: var(--salt-text-h3-lineHeight);\n margin: 0;\n white-space: nowrap;\n }\n\n .vuuToastNotification-content {\n grid-area: toast-content;\n justify-self: start;\n }\n\n .vuuToastNotification-closeButton.saltButton {\n grid-area: close-button;\n justify-self: center;\n .vuuIcon {\n --vuu-icon-size: 16px;\n }\n }\n\n}";
4
4
 
5
5
  module.exports = toastNotificationCss;
6
6
  //# sourceMappingURL=ToastNotification.css.js.map
@@ -1,83 +1,112 @@
1
1
  'use strict';
2
2
 
3
3
  var jsxRuntime = require('react/jsx-runtime');
4
- var cx = require('clsx');
5
4
  var core = require('@salt-ds/core');
6
- var React = require('react');
7
5
  var styles = require('@salt-ds/styles');
8
6
  var window = require('@salt-ds/window');
7
+ var vuuUiControls = require('@vuu-ui/vuu-ui-controls');
8
+ var cx = require('clsx');
9
+ var React = require('react');
9
10
  var ToastNotification$1 = require('./ToastNotification.css.js');
10
11
 
11
- const toastContainerRightPadding = 20;
12
- const toastDisplayDuration = 12e5;
13
- const horizontalTransitionDuration = 400;
14
- const TOAST_HEIGHT = 80;
15
- const TOAST_WIDTH = 300;
16
- const verticalTransitionDuration = 300;
17
12
  const classBase = "vuuToastNotification";
18
- const ToastNotification = (props) => {
13
+ const ToastNotification = ({
14
+ hidden,
15
+ id,
16
+ left,
17
+ onDismiss,
18
+ onMeasured,
19
+ top,
20
+ notification,
21
+ onHoverEntry,
22
+ onHoverExit,
23
+ opacity = 1
24
+ }) => {
19
25
  const targetWindow = window.useWindow();
20
26
  styles.useComponentCssInjection({
21
27
  testId: "vuu-toast-notification",
22
28
  css: ToastNotification$1,
23
29
  window: targetWindow
24
30
  });
25
- const { top, notification, animated = true } = props;
26
31
  const { Component: FloatingComponent } = core.useFloatingComponent();
27
- const { animationType = "slide-in,slide-out" } = notification;
28
- const slideIn = animationType.includes("slide-in");
29
- const pageWidth = React.useMemo(() => document.body.clientWidth, []);
30
- const [left, setLeft] = React.useState(
31
- slideIn ? pageWidth + TOAST_WIDTH - toastContainerRightPadding : pageWidth - TOAST_WIDTH - toastContainerRightPadding
32
+ const {
33
+ animationType,
34
+ content,
35
+ dismissal,
36
+ header,
37
+ icon,
38
+ showCloseButton,
39
+ status
40
+ } = notification;
41
+ const iconName = icon === false ? void 0 : icon ?? status;
42
+ const callbackRef = React.useCallback(
43
+ (el) => {
44
+ if (el) {
45
+ setTimeout(() => {
46
+ const { height, width } = el.getBoundingClientRect();
47
+ if (id) {
48
+ onMeasured?.(id, height, width);
49
+ }
50
+ }, 60);
51
+ }
52
+ },
53
+ [id, onMeasured]
32
54
  );
33
- React.useEffect(() => {
34
- if (slideIn) {
35
- setTimeout(
36
- () => setLeft(pageWidth - TOAST_WIDTH - toastContainerRightPadding)
37
- );
38
- }
39
- if (animated) {
40
- setTimeout(
41
- () => setLeft(
42
- document.body.clientWidth + TOAST_WIDTH - toastContainerRightPadding
43
- ),
44
- toastDisplayDuration + horizontalTransitionDuration
45
- );
46
- }
47
- }, [animated, pageWidth, slideIn]);
48
- return /* @__PURE__ */ jsxRuntime.jsx(
55
+ const handleDismiss = React.useCallback(() => {
56
+ onDismiss?.(id);
57
+ }, [id, onDismiss]);
58
+ const handleMouseEnter = React.useCallback(
59
+ () => onHoverEntry?.(id),
60
+ [id, onHoverEntry]
61
+ );
62
+ const handleMouseLeave = React.useCallback(
63
+ () => onHoverExit?.(id),
64
+ [id, onHoverExit]
65
+ );
66
+ if (dismissal === "manual" && showCloseButton === false) {
67
+ console.warn(
68
+ "[ToastNotification] invalid props, if dismissal is manual, showCloseButton should not be false"
69
+ );
70
+ }
71
+ const withCloseButton = showCloseButton || dismissal === "manual";
72
+ return /* @__PURE__ */ jsxRuntime.jsxs(
49
73
  FloatingComponent,
50
74
  {
51
- className: cx(
52
- classBase,
53
- `${classBase}-${notification.type}`,
54
- `${classBase}-${notification.status}`
55
- ),
75
+ className: cx(classBase, `${classBase}-${notification.status}`, {
76
+ [`${classBase}-hidden`]: hidden,
77
+ [`${classBase}-transparent`]: opacity === 0,
78
+ [`${classBase}-withContent`]: content !== void 0,
79
+ [`${classBase}-withIcon`]: icon !== false,
80
+ [`${classBase}-withTransition`]: animationType !== void 0 && !hidden,
81
+ [`${classBase}-withCloseButton`]: withCloseButton
82
+ }),
83
+ id,
56
84
  left,
85
+ onMouseEnter: handleMouseEnter,
86
+ onMouseLeave: handleMouseLeave,
57
87
  open: true,
58
88
  position: "absolute",
89
+ ref: callbackRef,
90
+ role: "alert",
59
91
  top,
60
- style: {
61
- transition: animated ? `left ${horizontalTransitionDuration}ms, top ${verticalTransitionDuration}ms ` : "none"
62
- },
63
- children: /* @__PURE__ */ jsxRuntime.jsx(
64
- "div",
65
- {
66
- style: {
67
- height: TOAST_HEIGHT,
68
- width: TOAST_WIDTH
69
- },
70
- children: /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
71
- /* @__PURE__ */ jsxRuntime.jsx("h3", { className: `${classBase}-toastHeader`, children: notification.header }),
72
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: notification.content })
73
- ] })
74
- }
75
- )
92
+ children: [
93
+ iconName ? /* @__PURE__ */ jsxRuntime.jsx(vuuUiControls.Icon, { name: iconName }) : null,
94
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: `${classBase}-header`, children: header }),
95
+ content ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${classBase}-content`, children: content }) : null,
96
+ withCloseButton ? /* @__PURE__ */ jsxRuntime.jsx(
97
+ vuuUiControls.IconButton,
98
+ {
99
+ className: `${classBase}-closeButton`,
100
+ icon: "close",
101
+ onClick: handleDismiss,
102
+ appearance: "transparent",
103
+ sentiment: "neutral"
104
+ }
105
+ ) : null
106
+ ]
76
107
  }
77
108
  );
78
109
  };
79
110
 
80
- exports.TOAST_HEIGHT = TOAST_HEIGHT;
81
- exports.TOAST_WIDTH = TOAST_WIDTH;
82
111
  exports.ToastNotification = ToastNotification;
83
112
  //# sourceMappingURL=ToastNotification.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ToastNotification.js","sources":["../../../packages/vuu-notifications/src/ToastNotification.tsx"],"sourcesContent":["import cx from \"clsx\";\nimport { useFloatingComponent } from \"@salt-ds/core\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport type { ToastNotificationDescriptor } from \"./NotificationsContext\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\n\nconst toastContainerRightPadding = 20;\n// const toastDisplayDuration = 1200;\nconst toastDisplayDuration = 1200000;\nconst horizontalTransitionDuration = 400;\nexport const TOAST_HEIGHT = 80;\nexport const TOAST_WIDTH = 300;\nconst verticalTransitionDuration = 300;\n\nimport toastNotificationCss from \"./ToastNotification.css\";\n\nexport type ToastNotificationProps = {\n top: number;\n notification: ToastNotificationDescriptor;\n animated?: boolean;\n};\n\nconst classBase = \"vuuToastNotification\";\n\nexport const ToastNotification = (props: ToastNotificationProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-toast-notification\",\n css: toastNotificationCss,\n window: targetWindow,\n });\n\n const { top, notification, animated = true } = props;\n\n const { Component: FloatingComponent } = useFloatingComponent();\n\n const { animationType = \"slide-in,slide-out\" } = notification;\n\n const slideIn = animationType.includes(\"slide-in\");\n\n const pageWidth = useMemo(() => document.body.clientWidth, []);\n\n const [left, setLeft] = useState(\n slideIn\n ? pageWidth + TOAST_WIDTH - toastContainerRightPadding\n : pageWidth - TOAST_WIDTH - toastContainerRightPadding,\n );\n\n useEffect(() => {\n if (slideIn) {\n setTimeout(() =>\n setLeft(pageWidth - TOAST_WIDTH - toastContainerRightPadding),\n );\n }\n\n if (animated) {\n setTimeout(\n () =>\n setLeft(\n document.body.clientWidth +\n TOAST_WIDTH -\n toastContainerRightPadding,\n ),\n toastDisplayDuration + horizontalTransitionDuration,\n );\n }\n }, [animated, pageWidth, slideIn]);\n\n return (\n <FloatingComponent\n className={cx(\n classBase,\n `${classBase}-${notification.type}`,\n `${classBase}-${notification.status}`,\n )}\n left={left}\n open\n position=\"absolute\"\n top={top}\n style={{\n transition: animated\n ? `left ${horizontalTransitionDuration}ms, top ${verticalTransitionDuration}ms `\n : \"none\",\n }}\n >\n <div\n style={{\n height: TOAST_HEIGHT,\n width: TOAST_WIDTH,\n }}\n >\n <div>\n <h3 className={`${classBase}-toastHeader`}>{notification.header}</h3>\n <div>{notification.content}</div>\n </div>\n </div>\n </FloatingComponent>\n );\n};\n"],"names":["useWindow","useComponentCssInjection","toastNotificationCss","useFloatingComponent","useMemo","useState","useEffect","jsx"],"mappings":";;;;;;;;;;AAOA,MAAM,0BAA6B,GAAA,EAAA;AAEnC,MAAM,oBAAuB,GAAA,IAAA;AAC7B,MAAM,4BAA+B,GAAA,GAAA;AAC9B,MAAM,YAAe,GAAA;AACrB,MAAM,WAAc,GAAA;AAC3B,MAAM,0BAA6B,GAAA,GAAA;AAUnC,MAAM,SAAY,GAAA,sBAAA;AAEL,MAAA,iBAAA,GAAoB,CAAC,KAAkC,KAAA;AAClE,EAAA,MAAM,eAAeA,gBAAU,EAAA;AAC/B,EAAyBC,+BAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,wBAAA;AAAA,IACR,GAAK,EAAAC,mBAAA;AAAA,IACL,MAAQ,EAAA;AAAA,GACT,CAAA;AAED,EAAA,MAAM,EAAE,GAAA,EAAK,YAAc,EAAA,QAAA,GAAW,MAAS,GAAA,KAAA;AAE/C,EAAA,MAAM,EAAE,SAAA,EAAW,iBAAkB,EAAA,GAAIC,yBAAqB,EAAA;AAE9D,EAAM,MAAA,EAAE,aAAgB,GAAA,oBAAA,EAAyB,GAAA,YAAA;AAEjD,EAAM,MAAA,OAAA,GAAU,aAAc,CAAA,QAAA,CAAS,UAAU,CAAA;AAEjD,EAAA,MAAM,YAAYC,aAAQ,CAAA,MAAM,SAAS,IAAK,CAAA,WAAA,EAAa,EAAE,CAAA;AAE7D,EAAM,MAAA,CAAC,IAAM,EAAA,OAAO,CAAI,GAAAC,cAAA;AAAA,IACtB,OACI,GAAA,SAAA,GAAY,WAAc,GAAA,0BAAA,GAC1B,YAAY,WAAc,GAAA;AAAA,GAChC;AAEA,EAAAC,eAAA,CAAU,MAAM;AACd,IAAA,IAAI,OAAS,EAAA;AACX,MAAA,UAAA;AAAA,QAAW,MACT,OAAA,CAAQ,SAAY,GAAA,WAAA,GAAc,0BAA0B;AAAA,OAC9D;AAAA;AAGF,IAAA,IAAI,QAAU,EAAA;AACZ,MAAA,UAAA;AAAA,QACE,MACE,OAAA;AAAA,UACE,QAAA,CAAS,IAAK,CAAA,WAAA,GACZ,WACA,GAAA;AAAA,SACJ;AAAA,QACF,oBAAuB,GAAA;AAAA,OACzB;AAAA;AACF,GACC,EAAA,CAAC,QAAU,EAAA,SAAA,EAAW,OAAO,CAAC,CAAA;AAEjC,EACE,uBAAAC,cAAA;AAAA,IAAC,iBAAA;AAAA,IAAA;AAAA,MACC,SAAW,EAAA,EAAA;AAAA,QACT,SAAA;AAAA,QACA,CAAG,EAAA,SAAS,CAAI,CAAA,EAAA,YAAA,CAAa,IAAI,CAAA,CAAA;AAAA,QACjC,CAAG,EAAA,SAAS,CAAI,CAAA,EAAA,YAAA,CAAa,MAAM,CAAA;AAAA,OACrC;AAAA,MACA,IAAA;AAAA,MACA,IAAI,EAAA,IAAA;AAAA,MACJ,QAAS,EAAA,UAAA;AAAA,MACT,GAAA;AAAA,MACA,KAAO,EAAA;AAAA,QACL,YAAY,QACR,GAAA,CAAA,KAAA,EAAQ,4BAA4B,CAAA,QAAA,EAAW,0BAA0B,CACzE,GAAA,CAAA,GAAA;AAAA,OACN;AAAA,MAEA,QAAA,kBAAAA,cAAA;AAAA,QAAC,KAAA;AAAA,QAAA;AAAA,UACC,KAAO,EAAA;AAAA,YACL,MAAQ,EAAA,YAAA;AAAA,YACR,KAAO,EAAA;AAAA,WACT;AAAA,UAEA,0CAAC,KACC,EAAA,EAAA,QAAA,EAAA;AAAA,4BAAAA,cAAA,CAAC,QAAG,SAAW,EAAA,CAAA,EAAG,SAAS,CAAA,YAAA,CAAA,EAAiB,uBAAa,MAAO,EAAA,CAAA;AAAA,4BAChEA,cAAA,CAAC,KAAK,EAAA,EAAA,QAAA,EAAA,YAAA,CAAa,OAAQ,EAAA;AAAA,WAC7B,EAAA;AAAA;AAAA;AACF;AAAA,GACF;AAEJ;;;;;;"}
1
+ {"version":3,"file":"ToastNotification.js","sources":["../../../packages/vuu-notifications/src/ToastNotification.tsx"],"sourcesContent":["import { useFloatingComponent } from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { Icon, IconButton } from \"@vuu-ui/vuu-ui-controls\";\nimport cx from \"clsx\";\nimport { RefCallback, useCallback } from \"react\";\nimport type { ToastNotificationDescriptor } from \"./NotificationsContext\";\n\nimport toastNotificationCss from \"./ToastNotification.css\";\n\nexport type ToastHoverHandler = (id?: string) => void;\n\nexport type ToastNotificationProps = {\n hidden?: boolean;\n id?: string;\n left?: number;\n notification: ToastNotificationDescriptor;\n onMeasured?: (id: string, height: number, width: number) => void;\n onDismiss?: (id?: string) => void;\n onHoverEntry?: ToastHoverHandler;\n onHoverExit?: ToastHoverHandler;\n opacity?: number;\n top?: number;\n};\n\nconst classBase = \"vuuToastNotification\";\n\nexport const ToastNotification = ({\n hidden,\n id,\n left,\n onDismiss,\n onMeasured,\n top,\n notification,\n onHoverEntry,\n onHoverExit,\n opacity = 1,\n}: ToastNotificationProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-toast-notification\",\n css: toastNotificationCss,\n window: targetWindow,\n });\n\n const { Component: FloatingComponent } = useFloatingComponent();\n\n const {\n animationType,\n content,\n dismissal,\n header,\n icon,\n showCloseButton,\n status,\n } = notification;\n\n const iconName = icon === false ? undefined : (icon ?? status);\n\n const callbackRef = useCallback<RefCallback<HTMLDivElement>>(\n (el) => {\n if (el) {\n setTimeout(() => {\n const { height, width } = el.getBoundingClientRect();\n if (id) {\n onMeasured?.(id, height, width);\n }\n }, 60);\n }\n },\n [id, onMeasured],\n );\n\n const handleDismiss = useCallback(() => {\n onDismiss?.(id);\n }, [id, onDismiss]);\n\n const handleMouseEnter = useCallback(\n () => onHoverEntry?.(id),\n [id, onHoverEntry],\n );\n const handleMouseLeave = useCallback(\n () => onHoverExit?.(id),\n [id, onHoverExit],\n );\n\n if (dismissal === \"manual\" && showCloseButton === false) {\n console.warn(\n \"[ToastNotification] invalid props, if dismissal is manual, showCloseButton should not be false\",\n );\n }\n\n const withCloseButton = showCloseButton || dismissal === \"manual\";\n\n return (\n <FloatingComponent\n className={cx(classBase, `${classBase}-${notification.status}`, {\n [`${classBase}-hidden`]: hidden,\n [`${classBase}-transparent`]: opacity === 0,\n [`${classBase}-withContent`]: content !== undefined,\n [`${classBase}-withIcon`]: icon !== false,\n [`${classBase}-withTransition`]: animationType !== undefined && !hidden,\n [`${classBase}-withCloseButton`]: withCloseButton,\n })}\n id={id}\n left={left}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n open\n position=\"absolute\"\n ref={callbackRef}\n role=\"alert\"\n top={top}\n >\n {iconName ? <Icon name={iconName} /> : null}\n <h3 className={`${classBase}-header`}>{header}</h3>\n {content ? <div className={`${classBase}-content`}>{content}</div> : null}\n {withCloseButton ? (\n <IconButton\n className={`${classBase}-closeButton`}\n icon=\"close\"\n onClick={handleDismiss}\n appearance=\"transparent\"\n sentiment=\"neutral\"\n />\n ) : null}\n </FloatingComponent>\n );\n};\n"],"names":["useWindow","useComponentCssInjection","toastNotificationCss","useFloatingComponent","useCallback","jsxs","jsx","Icon","IconButton"],"mappings":"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"}