@vuu-ui/vuu-notifications 4.0.0-alpha.20 → 4.0.0-alpha.22
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/package.json +6 -6
- package/src/NotificationsProvider.js +61 -14
- package/src/index.js +2 -2
- package/types/NotificationsCenter.d.ts +1 -1
- package/types/NotificationsContext.d.ts +25 -0
- package/types/NotificationsProvider.d.ts +26 -5
- package/types/ToastNotification.d.ts +1 -1
- package/types/WorkspaceNotification.d.ts +1 -1
- package/types/index.d.ts +2 -2
- package/types/src/NotificationsCenter.d.ts +0 -6
- package/types/src/NotificationsContext.d.ts +0 -47
- package/types/src/NotificationsProvider.d.ts +0 -9
- package/types/src/ToastNotification.d.ts +0 -15
- package/types/src/WorkspaceNotification.d.ts +0 -5
- package/types/src/index.d.ts +0 -3
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "4.0.0-alpha.
|
|
2
|
+
"version": "4.0.0-alpha.22",
|
|
3
3
|
"description": "VUU notifications - Toast, WorkspaceNotification etc",
|
|
4
4
|
"main": "./src/index.js",
|
|
5
5
|
"author": "heswell",
|
|
@@ -11,11 +11,11 @@
|
|
|
11
11
|
"type-defs": "node ../../scripts/build-type-defs.mjs"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@salt-ds/core": "1.
|
|
15
|
-
"@salt-ds/styles": "0.
|
|
16
|
-
"@salt-ds/window": "0.1.
|
|
17
|
-
"@vuu-ui/vuu-ui-controls": "4.0.0-alpha.
|
|
18
|
-
"@vuu-ui/vuu-utils": "4.0.0-alpha.
|
|
14
|
+
"@salt-ds/core": "1.72.0",
|
|
15
|
+
"@salt-ds/styles": "0.4.1",
|
|
16
|
+
"@salt-ds/window": "0.1.2",
|
|
17
|
+
"@vuu-ui/vuu-ui-controls": "4.0.0-alpha.22",
|
|
18
|
+
"@vuu-ui/vuu-utils": "4.0.0-alpha.22"
|
|
19
19
|
},
|
|
20
20
|
"peerDependencies": {
|
|
21
21
|
"clsx": "^2.0.0",
|
|
@@ -1,26 +1,47 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
-
import react, { useContext, useMemo } from "react";
|
|
3
|
-
import { NotificationsCenter } from "./NotificationsCenter.js";
|
|
4
2
|
import { getLocalEntity } from "@vuu-ui/vuu-utils";
|
|
3
|
+
import { createContext, useContext, useMemo, useState } from "react";
|
|
4
|
+
import { NotificationsCenter } from "./NotificationsCenter.js";
|
|
5
|
+
const globalContext = (name, defaultValue)=>{
|
|
6
|
+
const key = Symbol.for(name);
|
|
7
|
+
const contexts = globalThis;
|
|
8
|
+
let context = contexts[key];
|
|
9
|
+
if (void 0 === context) {
|
|
10
|
+
context = /*#__PURE__*/ createContext(defaultValue);
|
|
11
|
+
contexts[key] = context;
|
|
12
|
+
}
|
|
13
|
+
return context;
|
|
14
|
+
};
|
|
5
15
|
class NotificationsContextObject {
|
|
6
16
|
#showNotification = ()=>{
|
|
7
17
|
console.log("have you forgotten to provide a NotificationsCenter?");
|
|
8
18
|
};
|
|
9
19
|
#hideNotification = ()=>console.log("have you forgotten to provide a NotificationsCenter?");
|
|
10
|
-
|
|
20
|
+
interceptor = void 0;
|
|
21
|
+
showNotification = (notification)=>this.interceptor?.(notification) === "suppress" ? void 0 : this.#showNotification(notification);
|
|
11
22
|
hideNotification = (id)=>this.#hideNotification(id);
|
|
12
23
|
setNotify = (showNotificationDispatcher, hideNotificationDispatcher)=>{
|
|
13
24
|
this.#showNotification = showNotificationDispatcher;
|
|
14
25
|
this.#hideNotification = hideNotificationDispatcher;
|
|
15
26
|
};
|
|
16
27
|
}
|
|
17
|
-
const NotificationsContext =
|
|
18
|
-
const
|
|
19
|
-
|
|
28
|
+
const NotificationsContext = globalContext("vuu.notifications.context", null);
|
|
29
|
+
const NotificationOriginContext = globalContext("vuu.notifications.origin", void 0);
|
|
30
|
+
const noProvider = new NotificationsContextObject();
|
|
31
|
+
const NotificationsProvider = ({ children, interceptor })=>{
|
|
32
|
+
const outerContext = useContext(NotificationsContext);
|
|
33
|
+
return outerContext ? children : /*#__PURE__*/ jsx(OutermostNotificationsProvider, {
|
|
34
|
+
interceptor: interceptor,
|
|
35
|
+
children: children
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
const OutermostNotificationsProvider = ({ children, interceptor })=>{
|
|
39
|
+
const [context] = useState(()=>new NotificationsContextObject());
|
|
40
|
+
context.interceptor = interceptor;
|
|
20
41
|
const startupToastNotification = useMemo(()=>{
|
|
21
42
|
const toast = getLocalEntity("startup-notification", true);
|
|
22
43
|
if (toast && toast.expires >= +Date.now()) {
|
|
23
|
-
const { expires, ...toastDescriptor } = toast;
|
|
44
|
+
const { expires: _expires, ...toastDescriptor } = toast;
|
|
24
45
|
return toastDescriptor;
|
|
25
46
|
}
|
|
26
47
|
}, []);
|
|
@@ -31,15 +52,41 @@ const NotificationsProvider = (props)=>{
|
|
|
31
52
|
startupToastNotification: startupToastNotification,
|
|
32
53
|
notificationsContext: context
|
|
33
54
|
}),
|
|
34
|
-
|
|
55
|
+
children
|
|
35
56
|
]
|
|
36
57
|
});
|
|
37
58
|
};
|
|
59
|
+
const NotificationOriginProvider = ({ children, connectionId, moduleId })=>{
|
|
60
|
+
const outerOrigin = useContext(NotificationOriginContext);
|
|
61
|
+
const outerModuleId = outerOrigin?.moduleId ?? outerOrigin?.parentModuleId;
|
|
62
|
+
const parentModuleId = outerModuleId !== moduleId ? outerModuleId : outerOrigin?.parentModuleId;
|
|
63
|
+
const origin = useMemo(()=>({
|
|
64
|
+
connectionId,
|
|
65
|
+
moduleId,
|
|
66
|
+
parentModuleId
|
|
67
|
+
}), [
|
|
68
|
+
connectionId,
|
|
69
|
+
moduleId,
|
|
70
|
+
parentModuleId
|
|
71
|
+
]);
|
|
72
|
+
return /*#__PURE__*/ jsx(NotificationOriginContext.Provider, {
|
|
73
|
+
value: origin,
|
|
74
|
+
children: children
|
|
75
|
+
});
|
|
76
|
+
};
|
|
77
|
+
const useNotificationOrigin = ()=>useContext(NotificationOriginContext);
|
|
38
78
|
const useNotifications = ()=>{
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
79
|
+
const context = useContext(NotificationsContext) ?? noProvider;
|
|
80
|
+
const origin = useContext(NotificationOriginContext);
|
|
81
|
+
return useMemo(()=>({
|
|
82
|
+
hideNotification: context.hideNotification,
|
|
83
|
+
showNotification: origin ? (notification)=>context.showNotification(notification.origin ? notification : {
|
|
84
|
+
...notification,
|
|
85
|
+
origin
|
|
86
|
+
}) : context.showNotification
|
|
87
|
+
}), [
|
|
88
|
+
context,
|
|
89
|
+
origin
|
|
90
|
+
]);
|
|
44
91
|
};
|
|
45
|
-
export { NotificationsProvider, useNotifications };
|
|
92
|
+
export { NotificationOriginProvider, NotificationsProvider, useNotificationOrigin, useNotifications };
|
package/src/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { NotificationType } from "./NotificationsContext.js";
|
|
2
|
-
export { NotificationsProvider, useNotifications } from "./NotificationsProvider.js";
|
|
1
|
+
export { NotificationType, isToastNotification, isWorkspaceNotification } from "./NotificationsContext.js";
|
|
2
|
+
export { NotificationOriginProvider, NotificationsProvider, useNotificationOrigin, useNotifications } from "./NotificationsProvider.js";
|
|
3
3
|
export { ToastNotification } from "./ToastNotification.js";
|
|
@@ -3,4 +3,4 @@ export interface NotificationsCenterProps {
|
|
|
3
3
|
notificationsContext: NotificationsContextProps;
|
|
4
4
|
startupToastNotification?: ToastNotificationDescriptor;
|
|
5
5
|
}
|
|
6
|
-
export declare const NotificationsCenter: ({ notificationsContext, startupToastNotification, }: NotificationsCenterProps) => import("react").JSX.Element;
|
|
6
|
+
export declare const NotificationsCenter: ({ notificationsContext, startupToastNotification, }: NotificationsCenterProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -10,6 +10,18 @@ export declare const NotificationType: {
|
|
|
10
10
|
export type NotificationType = ValueOf<typeof NotificationType>;
|
|
11
11
|
export type DismissalStyle = "automatic" | "manual";
|
|
12
12
|
export type NotificationAnimationType = "slide-in" | "slide-out" | "slide-in,slide-out";
|
|
13
|
+
/**
|
|
14
|
+
* Where a notification was raised. Filled in by `useNotifications` from the
|
|
15
|
+
* nearest `NotificationOriginProvider`, e.g. the portal module rendering the
|
|
16
|
+
* caller.
|
|
17
|
+
*/
|
|
18
|
+
export interface NotificationOrigin {
|
|
19
|
+
moduleId?: string | number;
|
|
20
|
+
/** The Vuu server the module uses. */
|
|
21
|
+
connectionId?: string;
|
|
22
|
+
/** The module hosting the origin's module, for nested modules. */
|
|
23
|
+
parentModuleId?: string | number;
|
|
24
|
+
}
|
|
13
25
|
interface NotificationDescriptorBase<T extends NotificationType> {
|
|
14
26
|
animationType?: NotificationAnimationType;
|
|
15
27
|
/**
|
|
@@ -23,6 +35,13 @@ interface NotificationDescriptorBase<T extends NotificationType> {
|
|
|
23
35
|
* Default icons will be rendered for the different status values.
|
|
24
36
|
*/
|
|
25
37
|
icon?: string | false;
|
|
38
|
+
/** Set automatically by `useNotifications`, when a provider gives one. */
|
|
39
|
+
origin?: NotificationOrigin;
|
|
40
|
+
/**
|
|
41
|
+
* Whether a host that keeps a notification history (e.g. a portal) should
|
|
42
|
+
* record this notification. Hosts choose the default.
|
|
43
|
+
*/
|
|
44
|
+
record?: boolean;
|
|
26
45
|
renderPostRefresh?: boolean;
|
|
27
46
|
showCloseButton?: boolean;
|
|
28
47
|
status: ValidationStatus;
|
|
@@ -39,6 +58,12 @@ export interface WorkspaceNotificationDescriptor extends NotificationDescriptorB
|
|
|
39
58
|
export type Notification = ToastNotificationDescriptor | WorkspaceNotificationDescriptor;
|
|
40
59
|
export declare const isToastNotification: (n: Notification) => n is ToastNotificationDescriptor;
|
|
41
60
|
export declare const isWorkspaceNotification: (n: Notification) => n is WorkspaceNotificationDescriptor;
|
|
61
|
+
/**
|
|
62
|
+
* Decides whether a notification is shown. Given to the outermost
|
|
63
|
+
* `NotificationsProvider`, it sees every notification raised beneath it,
|
|
64
|
+
* including those raised inside nested providers.
|
|
65
|
+
*/
|
|
66
|
+
export type NotificationInterceptor = (notification: Notification) => "present" | "suppress";
|
|
42
67
|
export type NotificationsContextProps = {
|
|
43
68
|
hideNotification: DispatchHideNotification;
|
|
44
69
|
showNotification: DispatchShowNotification;
|
|
@@ -1,8 +1,29 @@
|
|
|
1
|
-
import
|
|
2
|
-
import type { DispatchHideNotification, DispatchShowNotification } from "./NotificationsContext";
|
|
3
|
-
export
|
|
4
|
-
children
|
|
5
|
-
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
import type { DispatchHideNotification, DispatchShowNotification, NotificationInterceptor, NotificationOrigin } from "./NotificationsContext";
|
|
3
|
+
export interface NotificationsProviderProps {
|
|
4
|
+
children?: ReactNode;
|
|
5
|
+
/**
|
|
6
|
+
* Sees every notification raised beneath the provider before it is shown.
|
|
7
|
+
* Only used by the outermost provider.
|
|
8
|
+
*/
|
|
9
|
+
interceptor?: NotificationInterceptor;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Shows the notifications raised beneath it. Inside another
|
|
13
|
+
* `NotificationsProvider` it renders only its children, so notifications
|
|
14
|
+
* from nested applications are shown, once, by the outermost provider.
|
|
15
|
+
*/
|
|
16
|
+
export declare const NotificationsProvider: ({ children, interceptor, }: NotificationsProviderProps) => string | number | bigint | boolean | import("react/jsx-runtime").JSX.Element | Iterable<ReactNode> | Promise<string | number | bigint | boolean | Iterable<ReactNode> | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | import("react").ReactPortal | null | undefined> | null | undefined;
|
|
17
|
+
/**
|
|
18
|
+
* Tags notifications raised beneath it with their origin. A nested provider
|
|
19
|
+
* records the enclosing origin's module as its `parentModuleId`.
|
|
20
|
+
*/
|
|
21
|
+
export declare const NotificationOriginProvider: ({ children, connectionId, moduleId, }: {
|
|
22
|
+
children?: ReactNode;
|
|
23
|
+
connectionId?: string;
|
|
24
|
+
moduleId?: string | number;
|
|
25
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
26
|
+
export declare const useNotificationOrigin: () => NotificationOrigin | undefined;
|
|
6
27
|
export declare const useNotifications: () => {
|
|
7
28
|
hideNotification: DispatchHideNotification;
|
|
8
29
|
showNotification: DispatchShowNotification;
|
|
@@ -12,4 +12,4 @@ export type ToastNotificationProps = {
|
|
|
12
12
|
opacity?: number;
|
|
13
13
|
top?: number;
|
|
14
14
|
};
|
|
15
|
-
export declare const ToastNotification: ({ hidden, id, left, onDismiss, onMeasured, top, notification, onHoverEntry, onHoverExit, opacity, }: ToastNotificationProps) => import("react").JSX.Element;
|
|
15
|
+
export declare const ToastNotification: ({ hidden, id, left, onDismiss, onMeasured, top, notification, onHoverEntry, onHoverExit, opacity, }: ToastNotificationProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -2,4 +2,4 @@ import { HTMLAttributes, ReactNode } from "react";
|
|
|
2
2
|
export interface WorkspaceNotificationProps extends HTMLAttributes<HTMLDivElement> {
|
|
3
3
|
children: ReactNode;
|
|
4
4
|
}
|
|
5
|
-
export declare const WorkspaceNotification: ({ children, className, style: styleProp, ...htmlAttributes }: WorkspaceNotificationProps) => import("react").JSX.Element;
|
|
5
|
+
export declare const WorkspaceNotification: ({ children, className, style: styleProp, ...htmlAttributes }: WorkspaceNotificationProps) => import("react/jsx-runtime").JSX.Element;
|
package/types/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { NotificationType, type Notification, type NotificationAnimationType, } from "./NotificationsContext";
|
|
2
|
-
export { NotificationsProvider, useNotifications, } from "./NotificationsProvider";
|
|
1
|
+
export { NotificationType, type Notification, type NotificationAnimationType, type NotificationInterceptor, type NotificationOrigin, type ToastNotificationDescriptor, type WorkspaceNotificationDescriptor, isToastNotification, isWorkspaceNotification, } from "./NotificationsContext";
|
|
2
|
+
export { NotificationOriginProvider, NotificationsProvider, type NotificationsProviderProps, useNotificationOrigin, useNotifications, } from "./NotificationsProvider";
|
|
3
3
|
export { ToastNotification, type ToastNotificationProps, } from "./ToastNotification";
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { NotificationsContextProps, ToastNotificationDescriptor } from "./NotificationsContext";
|
|
2
|
-
export interface NotificationsCenterProps {
|
|
3
|
-
notificationsContext: NotificationsContextProps;
|
|
4
|
-
startupToastNotification?: ToastNotificationDescriptor;
|
|
5
|
-
}
|
|
6
|
-
export declare const NotificationsCenter: ({ notificationsContext, startupToastNotification, }: NotificationsCenterProps) => import("react").JSX.Element;
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import type { ValidationStatus } from "@salt-ds/core";
|
|
2
|
-
import type { ValueOf } from "@vuu-ui/vuu-utils";
|
|
3
|
-
import type { ReactNode } from "react";
|
|
4
|
-
export type DispatchShowNotification = (notification: Notification) => string | undefined;
|
|
5
|
-
export type DispatchHideNotification = (id?: string) => void;
|
|
6
|
-
export declare const NotificationType: {
|
|
7
|
-
readonly Toast: "toast";
|
|
8
|
-
readonly Workspace: "workspace";
|
|
9
|
-
};
|
|
10
|
-
export type NotificationType = ValueOf<typeof NotificationType>;
|
|
11
|
-
export type DismissalStyle = "automatic" | "manual";
|
|
12
|
-
export type NotificationAnimationType = "slide-in" | "slide-out" | "slide-in,slide-out";
|
|
13
|
-
interface NotificationDescriptorBase<T extends NotificationType> {
|
|
14
|
-
animationType?: NotificationAnimationType;
|
|
15
|
-
/**
|
|
16
|
-
* 'automatic' dismissal means the Notification will be removed after a configurable delay
|
|
17
|
-
* (6 seconds by default). 'manual' means a close button will be rendered and user must
|
|
18
|
-
* manually dismiss by clicking the close button.
|
|
19
|
-
*/
|
|
20
|
-
dismissal?: DismissalStyle;
|
|
21
|
-
/**
|
|
22
|
-
* A custom icon can be provided or false can be used to suppress rendering of any icon.
|
|
23
|
-
* Default icons will be rendered for the different status values.
|
|
24
|
-
*/
|
|
25
|
-
icon?: string | false;
|
|
26
|
-
renderPostRefresh?: boolean;
|
|
27
|
-
showCloseButton?: boolean;
|
|
28
|
-
status: ValidationStatus;
|
|
29
|
-
type: T;
|
|
30
|
-
}
|
|
31
|
-
export interface ToastNotificationDescriptor extends NotificationDescriptorBase<"toast"> {
|
|
32
|
-
className?: string;
|
|
33
|
-
content?: ReactNode;
|
|
34
|
-
header: string;
|
|
35
|
-
}
|
|
36
|
-
export interface WorkspaceNotificationDescriptor extends NotificationDescriptorBase<"workspace"> {
|
|
37
|
-
content: ReactNode;
|
|
38
|
-
}
|
|
39
|
-
export type Notification = ToastNotificationDescriptor | WorkspaceNotificationDescriptor;
|
|
40
|
-
export declare const isToastNotification: (n: Notification) => n is ToastNotificationDescriptor;
|
|
41
|
-
export declare const isWorkspaceNotification: (n: Notification) => n is WorkspaceNotificationDescriptor;
|
|
42
|
-
export type NotificationsContextProps = {
|
|
43
|
-
hideNotification: DispatchHideNotification;
|
|
44
|
-
showNotification: DispatchShowNotification;
|
|
45
|
-
setNotify: (showNotificationDispatcher: DispatchShowNotification, hideNotificationDispatcher: DispatchHideNotification) => void;
|
|
46
|
-
};
|
|
47
|
-
export {};
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import React, { type ReactElement } from "react";
|
|
2
|
-
import type { DispatchHideNotification, DispatchShowNotification } from "./NotificationsContext";
|
|
3
|
-
export declare const NotificationsProvider: (props: {
|
|
4
|
-
children: ReactElement | ReactElement[];
|
|
5
|
-
}) => React.JSX.Element;
|
|
6
|
-
export declare const useNotifications: () => {
|
|
7
|
-
hideNotification: DispatchHideNotification;
|
|
8
|
-
showNotification: DispatchShowNotification;
|
|
9
|
-
};
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type { ToastNotificationDescriptor } from "./NotificationsContext";
|
|
2
|
-
export type ToastHoverHandler = (id?: string) => void;
|
|
3
|
-
export type ToastNotificationProps = {
|
|
4
|
-
hidden?: boolean;
|
|
5
|
-
id?: string;
|
|
6
|
-
left?: number;
|
|
7
|
-
notification: ToastNotificationDescriptor;
|
|
8
|
-
onMeasured?: (id: string, height: number, width: number) => void;
|
|
9
|
-
onDismiss?: (id?: string) => void;
|
|
10
|
-
onHoverEntry?: ToastHoverHandler;
|
|
11
|
-
onHoverExit?: ToastHoverHandler;
|
|
12
|
-
opacity?: number;
|
|
13
|
-
top?: number;
|
|
14
|
-
};
|
|
15
|
-
export declare const ToastNotification: ({ hidden, id, left, onDismiss, onMeasured, top, notification, onHoverEntry, onHoverExit, opacity, }: ToastNotificationProps) => import("react").JSX.Element;
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import { HTMLAttributes, ReactNode } from "react";
|
|
2
|
-
export interface WorkspaceNotificationProps extends HTMLAttributes<HTMLDivElement> {
|
|
3
|
-
children: ReactNode;
|
|
4
|
-
}
|
|
5
|
-
export declare const WorkspaceNotification: ({ children, className, style: styleProp, ...htmlAttributes }: WorkspaceNotificationProps) => import("react").JSX.Element;
|
package/types/src/index.d.ts
DELETED
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
export { NotificationType, type Notification, type NotificationAnimationType, } from "./NotificationsContext";
|
|
2
|
-
export { NotificationsProvider, useNotifications, } from "./NotificationsProvider";
|
|
3
|
-
export { ToastNotification, type ToastNotificationProps, } from "./ToastNotification";
|