@novu/react 2.3.0 → 2.3.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.
- package/dist/index.d.mts +34 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.js +167 -0
- package/dist/index.mjs +157 -0
- package/package.json +7 -5
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { InboxNotification } from '@novu/js';
|
|
3
|
+
import { BaseNovuUIOptions } from '@novu/js/ui';
|
|
4
|
+
|
|
5
|
+
type BellRenderProps = ({ unreadCount }: {
|
|
6
|
+
unreadCount: number;
|
|
7
|
+
}) => React.ReactNode;
|
|
8
|
+
type BellProps$1 = {
|
|
9
|
+
children?: never | BellRenderProps;
|
|
10
|
+
};
|
|
11
|
+
declare const Bell: (props: BellProps$1) => React.JSX.Element;
|
|
12
|
+
|
|
13
|
+
type InboxDefaultProps = {
|
|
14
|
+
renderNotification?: (notification: InboxNotification) => React.ReactNode;
|
|
15
|
+
renderBell?: ({ unreadCount }: {
|
|
16
|
+
unreadCount: number;
|
|
17
|
+
}) => React.ReactNode;
|
|
18
|
+
};
|
|
19
|
+
type InboxProps = BaseNovuUIOptions & (({
|
|
20
|
+
children?: never;
|
|
21
|
+
} & InboxDefaultProps) | {
|
|
22
|
+
children: React.ReactNode;
|
|
23
|
+
});
|
|
24
|
+
declare const Inbox: (props: InboxProps) => React.JSX.Element;
|
|
25
|
+
|
|
26
|
+
declare const Settings: () => React.JSX.Element;
|
|
27
|
+
|
|
28
|
+
type NotificationsRenderProps = (notification: InboxNotification) => React.ReactNode;
|
|
29
|
+
type BellProps = {
|
|
30
|
+
children?: never | NotificationsRenderProps;
|
|
31
|
+
};
|
|
32
|
+
declare const Notifications: (props: BellProps) => React.JSX.Element;
|
|
33
|
+
|
|
34
|
+
export { Bell, Inbox, Notifications, Settings };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { InboxNotification } from '@novu/js';
|
|
3
|
+
import { BaseNovuUIOptions } from '@novu/js/ui';
|
|
4
|
+
|
|
5
|
+
type BellRenderProps = ({ unreadCount }: {
|
|
6
|
+
unreadCount: number;
|
|
7
|
+
}) => React.ReactNode;
|
|
8
|
+
type BellProps$1 = {
|
|
9
|
+
children?: never | BellRenderProps;
|
|
10
|
+
};
|
|
11
|
+
declare const Bell: (props: BellProps$1) => React.JSX.Element;
|
|
12
|
+
|
|
13
|
+
type InboxDefaultProps = {
|
|
14
|
+
renderNotification?: (notification: InboxNotification) => React.ReactNode;
|
|
15
|
+
renderBell?: ({ unreadCount }: {
|
|
16
|
+
unreadCount: number;
|
|
17
|
+
}) => React.ReactNode;
|
|
18
|
+
};
|
|
19
|
+
type InboxProps = BaseNovuUIOptions & (({
|
|
20
|
+
children?: never;
|
|
21
|
+
} & InboxDefaultProps) | {
|
|
22
|
+
children: React.ReactNode;
|
|
23
|
+
});
|
|
24
|
+
declare const Inbox: (props: InboxProps) => React.JSX.Element;
|
|
25
|
+
|
|
26
|
+
declare const Settings: () => React.JSX.Element;
|
|
27
|
+
|
|
28
|
+
type NotificationsRenderProps = (notification: InboxNotification) => React.ReactNode;
|
|
29
|
+
type BellProps = {
|
|
30
|
+
children?: never | NotificationsRenderProps;
|
|
31
|
+
};
|
|
32
|
+
declare const Notifications: (props: BellProps) => React.JSX.Element;
|
|
33
|
+
|
|
34
|
+
export { Bell, Inbox, Notifications, Settings };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var React5 = require('react');
|
|
4
|
+
var ReactDOM = require('react-dom');
|
|
5
|
+
|
|
6
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
7
|
+
|
|
8
|
+
var React5__default = /*#__PURE__*/_interopDefault(React5);
|
|
9
|
+
var ReactDOM__default = /*#__PURE__*/_interopDefault(ReactDOM);
|
|
10
|
+
|
|
11
|
+
// src/components/Bell.tsx
|
|
12
|
+
function assertContextExists(contextVal, msgOrCtx) {
|
|
13
|
+
if (!contextVal) {
|
|
14
|
+
throw typeof msgOrCtx === "string" ? new Error(msgOrCtx) : new Error(`${msgOrCtx.displayName} not found`);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
var createContextAndHook = (displayName, options) => {
|
|
18
|
+
const { assertCtxFn = assertContextExists } = {};
|
|
19
|
+
const Ctx = React5__default.default.createContext(void 0);
|
|
20
|
+
Ctx.displayName = displayName;
|
|
21
|
+
const useCtx = () => {
|
|
22
|
+
const ctx = React5__default.default.useContext(Ctx);
|
|
23
|
+
assertCtxFn(ctx, `${displayName} not found`);
|
|
24
|
+
return ctx.value;
|
|
25
|
+
};
|
|
26
|
+
const useCtxWithoutGuarantee = () => {
|
|
27
|
+
const ctx = React5__default.default.useContext(Ctx);
|
|
28
|
+
return ctx ? ctx.value : {};
|
|
29
|
+
};
|
|
30
|
+
return [Ctx, useCtx, useCtxWithoutGuarantee];
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
// src/context/RenderContext.tsx
|
|
34
|
+
var [RendererContext, useRendererContext] = createContextAndHook("RendererContext");
|
|
35
|
+
var RendererProvider = (props) => {
|
|
36
|
+
return /* @__PURE__ */ React5__default.default.createElement(RendererContext.Provider, { value: { value: props.value } }, props.children);
|
|
37
|
+
};
|
|
38
|
+
function Mounter({ mount }) {
|
|
39
|
+
const ref = React5__default.default.useRef(null);
|
|
40
|
+
React5__default.default.useEffect(() => {
|
|
41
|
+
let unmount;
|
|
42
|
+
const element = ref.current;
|
|
43
|
+
if (element && mount) {
|
|
44
|
+
const possibleUnmount = mount(element);
|
|
45
|
+
if (possibleUnmount) {
|
|
46
|
+
unmount = possibleUnmount;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return () => {
|
|
50
|
+
if (element && unmount) {
|
|
51
|
+
unmount(element);
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
}, [ref, mount]);
|
|
55
|
+
return /* @__PURE__ */ React5__default.default.createElement("div", { ref });
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// src/components/Bell.tsx
|
|
59
|
+
var Bell = (props) => {
|
|
60
|
+
const { novuUI, mountElement } = useRendererContext();
|
|
61
|
+
const mount = React5__default.default.useCallback((element) => {
|
|
62
|
+
return novuUI.mountComponent({
|
|
63
|
+
name: "Bell",
|
|
64
|
+
element,
|
|
65
|
+
props: props.children ? { mountBell: (el, { unreadCount }) => mountElement(el, props.children?.({ unreadCount })) } : void 0
|
|
66
|
+
});
|
|
67
|
+
}, []);
|
|
68
|
+
return /* @__PURE__ */ React5__default.default.createElement(Mounter, { mount });
|
|
69
|
+
};
|
|
70
|
+
var Renderer = (props) => {
|
|
71
|
+
const { options, children } = props;
|
|
72
|
+
const [novuUI, setNovuUI] = React5__default.default.useState();
|
|
73
|
+
const [mountedElements, setMountedElements] = React5__default.default.useState(/* @__PURE__ */ new Map());
|
|
74
|
+
const mountElement = React5__default.default.useCallback(
|
|
75
|
+
(el, mountedElement) => {
|
|
76
|
+
setMountedElements((prev) => {
|
|
77
|
+
const newMountedElements = new Map(prev);
|
|
78
|
+
newMountedElements.set(el, mountedElement);
|
|
79
|
+
return newMountedElements;
|
|
80
|
+
});
|
|
81
|
+
return () => {
|
|
82
|
+
setMountedElements((prev) => {
|
|
83
|
+
const newMountedElements = new Map(prev);
|
|
84
|
+
newMountedElements.delete(el);
|
|
85
|
+
return newMountedElements;
|
|
86
|
+
});
|
|
87
|
+
};
|
|
88
|
+
},
|
|
89
|
+
[setMountedElements]
|
|
90
|
+
);
|
|
91
|
+
React5__default.default.useEffect(() => {
|
|
92
|
+
const loadNovuUI = async () => {
|
|
93
|
+
const { NovuUI } = await import('@novu/js/ui');
|
|
94
|
+
const ui = new NovuUI(options);
|
|
95
|
+
setNovuUI(ui);
|
|
96
|
+
};
|
|
97
|
+
loadNovuUI();
|
|
98
|
+
}, [options]);
|
|
99
|
+
if (!novuUI) {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
return /* @__PURE__ */ React5__default.default.createElement(RendererProvider, { value: { mountElement, novuUI } }, [...mountedElements].map(([element, mountedElement]) => {
|
|
103
|
+
return ReactDOM__default.default.createPortal(mountedElement, element);
|
|
104
|
+
}), children);
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
// src/components/Inbox.tsx
|
|
108
|
+
var InboxDefault = (props) => {
|
|
109
|
+
const { renderNotification, renderBell, ...rest } = props;
|
|
110
|
+
const { novuUI, mountElement } = useRendererContext();
|
|
111
|
+
const mount = React5__default.default.useCallback(
|
|
112
|
+
(element) => {
|
|
113
|
+
return novuUI.mountComponent({
|
|
114
|
+
name: "Inbox",
|
|
115
|
+
props: {
|
|
116
|
+
...rest,
|
|
117
|
+
mountNotification: renderNotification ? (el, { notification }) => {
|
|
118
|
+
return mountElement(el, renderNotification(notification));
|
|
119
|
+
} : void 0,
|
|
120
|
+
mountBell: renderBell ? (el, { unreadCount }) => {
|
|
121
|
+
return mountElement(el, renderBell({ unreadCount }));
|
|
122
|
+
} : void 0
|
|
123
|
+
},
|
|
124
|
+
element
|
|
125
|
+
});
|
|
126
|
+
},
|
|
127
|
+
[renderNotification]
|
|
128
|
+
);
|
|
129
|
+
return /* @__PURE__ */ React5__default.default.createElement(Mounter, { mount });
|
|
130
|
+
};
|
|
131
|
+
var Inbox = (props) => {
|
|
132
|
+
if ("children" in props) {
|
|
133
|
+
const { children, ...options2 } = props;
|
|
134
|
+
return /* @__PURE__ */ React5__default.default.createElement(Renderer, { options: options2 }, children);
|
|
135
|
+
}
|
|
136
|
+
const { renderNotification, renderBell, ...options } = props;
|
|
137
|
+
return /* @__PURE__ */ React5__default.default.createElement(Renderer, { options }, /* @__PURE__ */ React5__default.default.createElement(InboxDefault, { renderNotification, renderBell }));
|
|
138
|
+
};
|
|
139
|
+
var SettingsDefault = () => {
|
|
140
|
+
const { novuUI } = useRendererContext();
|
|
141
|
+
const mount = React5__default.default.useCallback((element) => {
|
|
142
|
+
return novuUI.mountComponent({
|
|
143
|
+
name: "Settings",
|
|
144
|
+
element
|
|
145
|
+
});
|
|
146
|
+
}, []);
|
|
147
|
+
return /* @__PURE__ */ React5__default.default.createElement(Mounter, { mount });
|
|
148
|
+
};
|
|
149
|
+
var Settings = () => {
|
|
150
|
+
return /* @__PURE__ */ React5__default.default.createElement(SettingsDefault, null);
|
|
151
|
+
};
|
|
152
|
+
var Notifications = (props) => {
|
|
153
|
+
const { novuUI, mountElement } = useRendererContext();
|
|
154
|
+
const mount = React5__default.default.useCallback((element) => {
|
|
155
|
+
return novuUI.mountComponent({
|
|
156
|
+
name: "NotificationList",
|
|
157
|
+
element,
|
|
158
|
+
props: props.children ? { mountNotification: (el, { notification }) => mountElement(el, props.children?.(notification)) } : void 0
|
|
159
|
+
});
|
|
160
|
+
}, []);
|
|
161
|
+
return /* @__PURE__ */ React5__default.default.createElement(Mounter, { mount });
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
exports.Bell = Bell;
|
|
165
|
+
exports.Inbox = Inbox;
|
|
166
|
+
exports.Notifications = Notifications;
|
|
167
|
+
exports.Settings = Settings;
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import React5 from 'react';
|
|
2
|
+
import ReactDOM from 'react-dom';
|
|
3
|
+
|
|
4
|
+
// src/components/Bell.tsx
|
|
5
|
+
function assertContextExists(contextVal, msgOrCtx) {
|
|
6
|
+
if (!contextVal) {
|
|
7
|
+
throw typeof msgOrCtx === "string" ? new Error(msgOrCtx) : new Error(`${msgOrCtx.displayName} not found`);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
var createContextAndHook = (displayName, options) => {
|
|
11
|
+
const { assertCtxFn = assertContextExists } = {};
|
|
12
|
+
const Ctx = React5.createContext(void 0);
|
|
13
|
+
Ctx.displayName = displayName;
|
|
14
|
+
const useCtx = () => {
|
|
15
|
+
const ctx = React5.useContext(Ctx);
|
|
16
|
+
assertCtxFn(ctx, `${displayName} not found`);
|
|
17
|
+
return ctx.value;
|
|
18
|
+
};
|
|
19
|
+
const useCtxWithoutGuarantee = () => {
|
|
20
|
+
const ctx = React5.useContext(Ctx);
|
|
21
|
+
return ctx ? ctx.value : {};
|
|
22
|
+
};
|
|
23
|
+
return [Ctx, useCtx, useCtxWithoutGuarantee];
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
// src/context/RenderContext.tsx
|
|
27
|
+
var [RendererContext, useRendererContext] = createContextAndHook("RendererContext");
|
|
28
|
+
var RendererProvider = (props) => {
|
|
29
|
+
return /* @__PURE__ */ React5.createElement(RendererContext.Provider, { value: { value: props.value } }, props.children);
|
|
30
|
+
};
|
|
31
|
+
function Mounter({ mount }) {
|
|
32
|
+
const ref = React5.useRef(null);
|
|
33
|
+
React5.useEffect(() => {
|
|
34
|
+
let unmount;
|
|
35
|
+
const element = ref.current;
|
|
36
|
+
if (element && mount) {
|
|
37
|
+
const possibleUnmount = mount(element);
|
|
38
|
+
if (possibleUnmount) {
|
|
39
|
+
unmount = possibleUnmount;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return () => {
|
|
43
|
+
if (element && unmount) {
|
|
44
|
+
unmount(element);
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
}, [ref, mount]);
|
|
48
|
+
return /* @__PURE__ */ React5.createElement("div", { ref });
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// src/components/Bell.tsx
|
|
52
|
+
var Bell = (props) => {
|
|
53
|
+
const { novuUI, mountElement } = useRendererContext();
|
|
54
|
+
const mount = React5.useCallback((element) => {
|
|
55
|
+
return novuUI.mountComponent({
|
|
56
|
+
name: "Bell",
|
|
57
|
+
element,
|
|
58
|
+
props: props.children ? { mountBell: (el, { unreadCount }) => mountElement(el, props.children?.({ unreadCount })) } : void 0
|
|
59
|
+
});
|
|
60
|
+
}, []);
|
|
61
|
+
return /* @__PURE__ */ React5.createElement(Mounter, { mount });
|
|
62
|
+
};
|
|
63
|
+
var Renderer = (props) => {
|
|
64
|
+
const { options, children } = props;
|
|
65
|
+
const [novuUI, setNovuUI] = React5.useState();
|
|
66
|
+
const [mountedElements, setMountedElements] = React5.useState(/* @__PURE__ */ new Map());
|
|
67
|
+
const mountElement = React5.useCallback(
|
|
68
|
+
(el, mountedElement) => {
|
|
69
|
+
setMountedElements((prev) => {
|
|
70
|
+
const newMountedElements = new Map(prev);
|
|
71
|
+
newMountedElements.set(el, mountedElement);
|
|
72
|
+
return newMountedElements;
|
|
73
|
+
});
|
|
74
|
+
return () => {
|
|
75
|
+
setMountedElements((prev) => {
|
|
76
|
+
const newMountedElements = new Map(prev);
|
|
77
|
+
newMountedElements.delete(el);
|
|
78
|
+
return newMountedElements;
|
|
79
|
+
});
|
|
80
|
+
};
|
|
81
|
+
},
|
|
82
|
+
[setMountedElements]
|
|
83
|
+
);
|
|
84
|
+
React5.useEffect(() => {
|
|
85
|
+
const loadNovuUI = async () => {
|
|
86
|
+
const { NovuUI } = await import('@novu/js/ui');
|
|
87
|
+
const ui = new NovuUI(options);
|
|
88
|
+
setNovuUI(ui);
|
|
89
|
+
};
|
|
90
|
+
loadNovuUI();
|
|
91
|
+
}, [options]);
|
|
92
|
+
if (!novuUI) {
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
return /* @__PURE__ */ React5.createElement(RendererProvider, { value: { mountElement, novuUI } }, [...mountedElements].map(([element, mountedElement]) => {
|
|
96
|
+
return ReactDOM.createPortal(mountedElement, element);
|
|
97
|
+
}), children);
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
// src/components/Inbox.tsx
|
|
101
|
+
var InboxDefault = (props) => {
|
|
102
|
+
const { renderNotification, renderBell, ...rest } = props;
|
|
103
|
+
const { novuUI, mountElement } = useRendererContext();
|
|
104
|
+
const mount = React5.useCallback(
|
|
105
|
+
(element) => {
|
|
106
|
+
return novuUI.mountComponent({
|
|
107
|
+
name: "Inbox",
|
|
108
|
+
props: {
|
|
109
|
+
...rest,
|
|
110
|
+
mountNotification: renderNotification ? (el, { notification }) => {
|
|
111
|
+
return mountElement(el, renderNotification(notification));
|
|
112
|
+
} : void 0,
|
|
113
|
+
mountBell: renderBell ? (el, { unreadCount }) => {
|
|
114
|
+
return mountElement(el, renderBell({ unreadCount }));
|
|
115
|
+
} : void 0
|
|
116
|
+
},
|
|
117
|
+
element
|
|
118
|
+
});
|
|
119
|
+
},
|
|
120
|
+
[renderNotification]
|
|
121
|
+
);
|
|
122
|
+
return /* @__PURE__ */ React5.createElement(Mounter, { mount });
|
|
123
|
+
};
|
|
124
|
+
var Inbox = (props) => {
|
|
125
|
+
if ("children" in props) {
|
|
126
|
+
const { children, ...options2 } = props;
|
|
127
|
+
return /* @__PURE__ */ React5.createElement(Renderer, { options: options2 }, children);
|
|
128
|
+
}
|
|
129
|
+
const { renderNotification, renderBell, ...options } = props;
|
|
130
|
+
return /* @__PURE__ */ React5.createElement(Renderer, { options }, /* @__PURE__ */ React5.createElement(InboxDefault, { renderNotification, renderBell }));
|
|
131
|
+
};
|
|
132
|
+
var SettingsDefault = () => {
|
|
133
|
+
const { novuUI } = useRendererContext();
|
|
134
|
+
const mount = React5.useCallback((element) => {
|
|
135
|
+
return novuUI.mountComponent({
|
|
136
|
+
name: "Settings",
|
|
137
|
+
element
|
|
138
|
+
});
|
|
139
|
+
}, []);
|
|
140
|
+
return /* @__PURE__ */ React5.createElement(Mounter, { mount });
|
|
141
|
+
};
|
|
142
|
+
var Settings = () => {
|
|
143
|
+
return /* @__PURE__ */ React5.createElement(SettingsDefault, null);
|
|
144
|
+
};
|
|
145
|
+
var Notifications = (props) => {
|
|
146
|
+
const { novuUI, mountElement } = useRendererContext();
|
|
147
|
+
const mount = React5.useCallback((element) => {
|
|
148
|
+
return novuUI.mountComponent({
|
|
149
|
+
name: "NotificationList",
|
|
150
|
+
element,
|
|
151
|
+
props: props.children ? { mountNotification: (el, { notification }) => mountElement(el, props.children?.(notification)) } : void 0
|
|
152
|
+
});
|
|
153
|
+
}, []);
|
|
154
|
+
return /* @__PURE__ */ React5.createElement(Mounter, { mount });
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
export { Bell, Inbox, Notifications, Settings };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@novu/react",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.1",
|
|
4
4
|
"repository": "https://github.com/novuhq/novu",
|
|
5
5
|
"description": "Novu's React SDK for building custom inbox notification experiences",
|
|
6
6
|
"author": "",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"default": "./dist/hooks/index.js"
|
|
34
34
|
}
|
|
35
35
|
},
|
|
36
|
-
|
|
36
|
+
"./themes": {
|
|
37
37
|
"import": {
|
|
38
38
|
"types": "./dist/themes/index.d.mts",
|
|
39
39
|
"default": "./dist/themes/index.mjs"
|
|
@@ -62,8 +62,7 @@
|
|
|
62
62
|
"build:watch": "tsup --watch",
|
|
63
63
|
"build": "tsup && pnpm run check-exports",
|
|
64
64
|
"lint": "eslint src",
|
|
65
|
-
"check-exports": "attw --pack ."
|
|
66
|
-
"release:preview": "pnpx pkg-pr-new publish"
|
|
65
|
+
"check-exports": "attw --pack ."
|
|
67
66
|
},
|
|
68
67
|
"browserslist": {
|
|
69
68
|
"production": [
|
|
@@ -95,6 +94,9 @@
|
|
|
95
94
|
}
|
|
96
95
|
},
|
|
97
96
|
"dependencies": {
|
|
98
|
-
"@novu/js": "^2.3.
|
|
97
|
+
"@novu/js": "^2.3.1"
|
|
98
|
+
},
|
|
99
|
+
"nx": {
|
|
100
|
+
"tags": ["package:public"]
|
|
99
101
|
}
|
|
100
102
|
}
|