@elementor/editor-notifications 1.0.0

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/CHANGELOG.md ADDED
@@ -0,0 +1,11 @@
1
+ # Change Log
2
+
3
+ ## 1.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - f82191d: Added Notification center, and block for link in link will show notification
8
+
9
+ ## 0.0.1
10
+
11
+ Initial
package/README.md ADDED
@@ -0,0 +1,5 @@
1
+ # Editor Notifications
2
+
3
+ > [!WARNING]
4
+ > Please refrain from accessing or depending on functions and variables starting with double underscores, as they are subject to change without notice.
5
+ > Naming convention involving double underscores (`__`) as a prefix to indicate that a function or variable is meant for internal use and should not be accessed or relied upon by third-party developers.
@@ -0,0 +1,14 @@
1
+ import { VariantType } from 'notistack';
2
+ import { ButtonProps } from '@elementor/ui';
3
+
4
+ type NotificationData = {
5
+ type: VariantType;
6
+ message: string | React.ReactNode;
7
+ id: string;
8
+ additionalActionProps?: Partial<ButtonProps>[];
9
+ };
10
+
11
+ declare function notify(notification: NotificationData): void;
12
+ declare function NotifyReact(notification: NotificationData): void;
13
+
14
+ export { type NotificationData, NotifyReact, notify };
@@ -0,0 +1,14 @@
1
+ import { VariantType } from 'notistack';
2
+ import { ButtonProps } from '@elementor/ui';
3
+
4
+ type NotificationData = {
5
+ type: VariantType;
6
+ message: string | React.ReactNode;
7
+ id: string;
8
+ additionalActionProps?: Partial<ButtonProps>[];
9
+ };
10
+
11
+ declare function notify(notification: NotificationData): void;
12
+ declare function NotifyReact(notification: NotificationData): void;
13
+
14
+ export { type NotificationData, NotifyReact, notify };
package/dist/index.js ADDED
@@ -0,0 +1,139 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ NotifyReact: () => NotifyReact,
34
+ notify: () => notify
35
+ });
36
+ module.exports = __toCommonJS(index_exports);
37
+
38
+ // src/init.ts
39
+ var import_editor = require("@elementor/editor");
40
+ var import_store3 = require("@elementor/store");
41
+
42
+ // src/components/notifications.tsx
43
+ var React = __toESM(require("react"));
44
+ var import_notistack = require("notistack");
45
+ var import_store2 = require("@elementor/store");
46
+ var import_ui = require("@elementor/ui");
47
+
48
+ // src/slice.ts
49
+ var import_store = require("@elementor/store");
50
+ var notificationsSlice = (0, import_store.__createSlice)({
51
+ name: "notifications",
52
+ initialState: {},
53
+ reducers: {
54
+ notifyAction: (state, action) => {
55
+ const newState = { ...state };
56
+ if (!newState[action.payload.id]) {
57
+ newState[action.payload.id] = action.payload;
58
+ }
59
+ return newState;
60
+ },
61
+ clearAction: (state, action) => {
62
+ const newState = { ...state };
63
+ if (newState[action.payload.id]) {
64
+ delete newState[action.payload.id];
65
+ }
66
+ return newState;
67
+ }
68
+ }
69
+ });
70
+ var { notifyAction, clearAction } = notificationsSlice.actions;
71
+
72
+ // src/components/notifications.tsx
73
+ var Handler = () => {
74
+ const { enqueueSnackbar } = (0, import_notistack.useSnackbar)();
75
+ const notifications = (0, import_store2.__useSelector)((state) => state.notifications);
76
+ const dispatch = (0, import_store2.__useDispatch)();
77
+ if (!notifications) {
78
+ return null;
79
+ }
80
+ Object.values(notifications).forEach((notification) => {
81
+ const action = (key) => /* @__PURE__ */ React.createElement(React.Fragment, null, notification.additionalActionProps?.map((additionalAction, index) => /* @__PURE__ */ React.createElement(import_ui.Button, { key: index, ...additionalAction })), /* @__PURE__ */ React.createElement(
82
+ import_ui.CloseButton,
83
+ {
84
+ "aria-label": "close",
85
+ color: "inherit",
86
+ onClick: () => {
87
+ (0, import_notistack.closeSnackbar)(key);
88
+ dispatch(clearAction({ id: key }));
89
+ }
90
+ }
91
+ ));
92
+ enqueueSnackbar(notification.message, {
93
+ variant: notification.type,
94
+ key: notification.id,
95
+ onClose: () => dispatch(clearAction({ id: notification.id })),
96
+ preventDuplicate: true,
97
+ action
98
+ });
99
+ });
100
+ return null;
101
+ };
102
+ var Wrapper = () => {
103
+ return /* @__PURE__ */ React.createElement(
104
+ import_notistack.SnackbarProvider,
105
+ {
106
+ maxSnack: 3,
107
+ autoHideDuration: 8e3,
108
+ anchorOrigin: { horizontal: "center", vertical: "bottom" }
109
+ },
110
+ /* @__PURE__ */ React.createElement(Handler, null)
111
+ );
112
+ };
113
+ function notify(notification) {
114
+ const store = (0, import_store2.__getStore)();
115
+ store?.dispatch(notifyAction(notification));
116
+ }
117
+ function NotifyReact(notification) {
118
+ const dispatch = (0, import_store2.__useDispatch)();
119
+ dispatch(notifyAction(notification));
120
+ }
121
+ var notifications_default = Wrapper;
122
+
123
+ // src/init.ts
124
+ function init() {
125
+ (0, import_store3.__registerSlice)(notificationsSlice);
126
+ (0, import_editor.injectIntoTop)({
127
+ id: "notifications",
128
+ component: notifications_default
129
+ });
130
+ }
131
+
132
+ // src/index.ts
133
+ init();
134
+ // Annotate the CommonJS export names for ESM import in node:
135
+ 0 && (module.exports = {
136
+ NotifyReact,
137
+ notify
138
+ });
139
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/init.ts","../src/components/notifications.tsx","../src/slice.ts"],"sourcesContent":["import { init } from './init';\n\nexport { type NotificationData } from './types';\nexport { NotifyReact, notify } from './components/notifications';\n\ninit();\n","import { injectIntoTop } from '@elementor/editor';\nimport { __registerSlice as registerSlice } from '@elementor/store';\n\nimport Wrapper from './components/notifications';\nimport { notificationsSlice } from './slice';\n\nexport function init() {\n\tregisterSlice( notificationsSlice );\n\tinjectIntoTop( {\n\t\tid: 'notifications',\n\t\tcomponent: Wrapper,\n\t} );\n}\n","import * as React from 'react';\nimport { closeSnackbar, type SnackbarKey, SnackbarProvider, useSnackbar, type VariantType } from 'notistack';\nimport { __getStore as getStore, __useDispatch as useDispatch, __useSelector as useSelector } from '@elementor/store';\nimport { Button, CloseButton } from '@elementor/ui';\n\nimport { clearAction, notifyAction } from '../slice';\nimport { type NotificationData, type Notifications } from '../types';\n\nconst Handler = () => {\n\tconst { enqueueSnackbar } = useSnackbar();\n\tconst notifications = useSelector( ( state: { notifications: Notifications } ) => state.notifications );\n\tconst dispatch = useDispatch();\n\n\tif ( ! notifications ) {\n\t\treturn null;\n\t}\n\n\tObject.values( notifications ).forEach( ( notification: NotificationData ) => {\n\t\tconst action = ( key: SnackbarKey ) => (\n\t\t\t<>\n\t\t\t\t{ notification.additionalActionProps?.map( ( additionalAction, index ) => (\n\t\t\t\t\t<Button key={ index } { ...additionalAction } />\n\t\t\t\t) ) }\n\n\t\t\t\t<CloseButton\n\t\t\t\t\taria-label=\"close\"\n\t\t\t\t\tcolor=\"inherit\"\n\t\t\t\t\tonClick={ () => {\n\t\t\t\t\t\tcloseSnackbar( key );\n\t\t\t\t\t\tdispatch( clearAction( { id: key } ) );\n\t\t\t\t\t} }\n\t\t\t\t></CloseButton>\n\t\t\t</>\n\t\t);\n\n\t\tenqueueSnackbar( notification.message, {\n\t\t\tvariant: notification.type as VariantType,\n\t\t\tkey: notification.id,\n\t\t\tonClose: () => dispatch( clearAction( { id: notification.id } ) ),\n\t\t\tpreventDuplicate: true,\n\t\t\taction,\n\t\t} );\n\t} );\n\n\treturn null;\n};\n\nconst Wrapper = () => {\n\treturn (\n\t\t<SnackbarProvider\n\t\t\tmaxSnack={ 3 }\n\t\t\tautoHideDuration={ 8000 }\n\t\t\tanchorOrigin={ { horizontal: 'center', vertical: 'bottom' } }\n\t\t>\n\t\t\t<Handler />\n\t\t</SnackbarProvider>\n\t);\n};\n\n/*\n * This function can be used to trigger notifications from anywhere in the code.\n * even if you're running in a JS environment as opposed to a React environment.\n */\nexport function notify( notification: NotificationData ) {\n\tconst store = getStore();\n\n\tstore?.dispatch( notifyAction( notification ) );\n}\n\n/*\n * This function can be used to trigger notifications from within a React component.\n * This is the preferred way to trigger notifications.\n */\nexport function NotifyReact( notification: NotificationData ) {\n\tconst dispatch = useDispatch();\n\tdispatch( notifyAction( notification ) );\n}\n\nexport default Wrapper;\n","import { __createSlice as createSlice } from '@elementor/store';\n\nimport { type Notifications } from './types';\n\nexport const notificationsSlice = createSlice( {\n\tname: 'notifications',\n\tinitialState: {} as Notifications,\n\treducers: {\n\t\tnotifyAction: ( state, action ) => {\n\t\t\tconst newState = { ...state };\n\t\t\tif ( ! newState[ action.payload.id ] ) {\n\t\t\t\tnewState[ action.payload.id ] = action.payload;\n\t\t\t}\n\n\t\t\treturn newState;\n\t\t},\n\t\tclearAction: ( state, action ) => {\n\t\t\tconst newState = { ...state };\n\t\t\tif ( newState[ action.payload.id ] ) {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n\t\t\t\tdelete newState[ action.payload.id ];\n\t\t\t}\n\n\t\t\treturn newState;\n\t\t},\n\t},\n} );\n\nexport const { notifyAction, clearAction } = notificationsSlice.actions;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,oBAA8B;AAC9B,IAAAA,gBAAiD;;;ACDjD,YAAuB;AACvB,uBAAiG;AACjG,IAAAC,gBAAmG;AACnG,gBAAoC;;;ACHpC,mBAA6C;AAItC,IAAM,yBAAqB,aAAAC,eAAa;AAAA,EAC9C,MAAM;AAAA,EACN,cAAc,CAAC;AAAA,EACf,UAAU;AAAA,IACT,cAAc,CAAE,OAAO,WAAY;AAClC,YAAM,WAAW,EAAE,GAAG,MAAM;AAC5B,UAAK,CAAE,SAAU,OAAO,QAAQ,EAAG,GAAI;AACtC,iBAAU,OAAO,QAAQ,EAAG,IAAI,OAAO;AAAA,MACxC;AAEA,aAAO;AAAA,IACR;AAAA,IACA,aAAa,CAAE,OAAO,WAAY;AACjC,YAAM,WAAW,EAAE,GAAG,MAAM;AAC5B,UAAK,SAAU,OAAO,QAAQ,EAAG,GAAI;AAEpC,eAAO,SAAU,OAAO,QAAQ,EAAG;AAAA,MACpC;AAEA,aAAO;AAAA,IACR;AAAA,EACD;AACD,CAAE;AAEK,IAAM,EAAE,cAAc,YAAY,IAAI,mBAAmB;;;ADpBhE,IAAM,UAAU,MAAM;AACrB,QAAM,EAAE,gBAAgB,QAAI,8BAAY;AACxC,QAAM,oBAAgB,cAAAC,eAAa,CAAE,UAA6C,MAAM,aAAc;AACtG,QAAM,eAAW,cAAAC,eAAY;AAE7B,MAAK,CAAE,eAAgB;AACtB,WAAO;AAAA,EACR;AAEA,SAAO,OAAQ,aAAc,EAAE,QAAS,CAAE,iBAAoC;AAC7E,UAAM,SAAS,CAAE,QAChB,0DACG,aAAa,uBAAuB,IAAK,CAAE,kBAAkB,UAC9D,oCAAC,oBAAO,KAAM,OAAU,GAAG,kBAAmB,CAC7C,GAEF;AAAA,MAAC;AAAA;AAAA,QACA,cAAW;AAAA,QACX,OAAM;AAAA,QACN,SAAU,MAAM;AACf,8CAAe,GAAI;AACnB,mBAAU,YAAa,EAAE,IAAI,IAAI,CAAE,CAAE;AAAA,QACtC;AAAA;AAAA,IACA,CACF;AAGD,oBAAiB,aAAa,SAAS;AAAA,MACtC,SAAS,aAAa;AAAA,MACtB,KAAK,aAAa;AAAA,MAClB,SAAS,MAAM,SAAU,YAAa,EAAE,IAAI,aAAa,GAAG,CAAE,CAAE;AAAA,MAChE,kBAAkB;AAAA,MAClB;AAAA,IACD,CAAE;AAAA,EACH,CAAE;AAEF,SAAO;AACR;AAEA,IAAM,UAAU,MAAM;AACrB,SACC;AAAA,IAAC;AAAA;AAAA,MACA,UAAW;AAAA,MACX,kBAAmB;AAAA,MACnB,cAAe,EAAE,YAAY,UAAU,UAAU,SAAS;AAAA;AAAA,IAE1D,oCAAC,aAAQ;AAAA,EACV;AAEF;AAMO,SAAS,OAAQ,cAAiC;AACxD,QAAM,YAAQ,cAAAC,YAAS;AAEvB,SAAO,SAAU,aAAc,YAAa,CAAE;AAC/C;AAMO,SAAS,YAAa,cAAiC;AAC7D,QAAM,eAAW,cAAAD,eAAY;AAC7B,WAAU,aAAc,YAAa,CAAE;AACxC;AAEA,IAAO,wBAAQ;;;ADxER,SAAS,OAAO;AACtB,oBAAAE,iBAAe,kBAAmB;AAClC,mCAAe;AAAA,IACd,IAAI;AAAA,IACJ,WAAW;AAAA,EACZ,CAAE;AACH;;;ADPA,KAAK;","names":["import_store","import_store","createSlice","useSelector","useDispatch","getStore","registerSlice"]}
package/dist/index.mjs ADDED
@@ -0,0 +1,101 @@
1
+ // src/init.ts
2
+ import { injectIntoTop } from "@elementor/editor";
3
+ import { __registerSlice as registerSlice } from "@elementor/store";
4
+
5
+ // src/components/notifications.tsx
6
+ import * as React from "react";
7
+ import { closeSnackbar, SnackbarProvider, useSnackbar } from "notistack";
8
+ import { __getStore as getStore, __useDispatch as useDispatch, __useSelector as useSelector } from "@elementor/store";
9
+ import { Button, CloseButton } from "@elementor/ui";
10
+
11
+ // src/slice.ts
12
+ import { __createSlice as createSlice } from "@elementor/store";
13
+ var notificationsSlice = createSlice({
14
+ name: "notifications",
15
+ initialState: {},
16
+ reducers: {
17
+ notifyAction: (state, action) => {
18
+ const newState = { ...state };
19
+ if (!newState[action.payload.id]) {
20
+ newState[action.payload.id] = action.payload;
21
+ }
22
+ return newState;
23
+ },
24
+ clearAction: (state, action) => {
25
+ const newState = { ...state };
26
+ if (newState[action.payload.id]) {
27
+ delete newState[action.payload.id];
28
+ }
29
+ return newState;
30
+ }
31
+ }
32
+ });
33
+ var { notifyAction, clearAction } = notificationsSlice.actions;
34
+
35
+ // src/components/notifications.tsx
36
+ var Handler = () => {
37
+ const { enqueueSnackbar } = useSnackbar();
38
+ const notifications = useSelector((state) => state.notifications);
39
+ const dispatch = useDispatch();
40
+ if (!notifications) {
41
+ return null;
42
+ }
43
+ Object.values(notifications).forEach((notification) => {
44
+ const action = (key) => /* @__PURE__ */ React.createElement(React.Fragment, null, notification.additionalActionProps?.map((additionalAction, index) => /* @__PURE__ */ React.createElement(Button, { key: index, ...additionalAction })), /* @__PURE__ */ React.createElement(
45
+ CloseButton,
46
+ {
47
+ "aria-label": "close",
48
+ color: "inherit",
49
+ onClick: () => {
50
+ closeSnackbar(key);
51
+ dispatch(clearAction({ id: key }));
52
+ }
53
+ }
54
+ ));
55
+ enqueueSnackbar(notification.message, {
56
+ variant: notification.type,
57
+ key: notification.id,
58
+ onClose: () => dispatch(clearAction({ id: notification.id })),
59
+ preventDuplicate: true,
60
+ action
61
+ });
62
+ });
63
+ return null;
64
+ };
65
+ var Wrapper = () => {
66
+ return /* @__PURE__ */ React.createElement(
67
+ SnackbarProvider,
68
+ {
69
+ maxSnack: 3,
70
+ autoHideDuration: 8e3,
71
+ anchorOrigin: { horizontal: "center", vertical: "bottom" }
72
+ },
73
+ /* @__PURE__ */ React.createElement(Handler, null)
74
+ );
75
+ };
76
+ function notify(notification) {
77
+ const store = getStore();
78
+ store?.dispatch(notifyAction(notification));
79
+ }
80
+ function NotifyReact(notification) {
81
+ const dispatch = useDispatch();
82
+ dispatch(notifyAction(notification));
83
+ }
84
+ var notifications_default = Wrapper;
85
+
86
+ // src/init.ts
87
+ function init() {
88
+ registerSlice(notificationsSlice);
89
+ injectIntoTop({
90
+ id: "notifications",
91
+ component: notifications_default
92
+ });
93
+ }
94
+
95
+ // src/index.ts
96
+ init();
97
+ export {
98
+ NotifyReact,
99
+ notify
100
+ };
101
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/init.ts","../src/components/notifications.tsx","../src/slice.ts","../src/index.ts"],"sourcesContent":["import { injectIntoTop } from '@elementor/editor';\nimport { __registerSlice as registerSlice } from '@elementor/store';\n\nimport Wrapper from './components/notifications';\nimport { notificationsSlice } from './slice';\n\nexport function init() {\n\tregisterSlice( notificationsSlice );\n\tinjectIntoTop( {\n\t\tid: 'notifications',\n\t\tcomponent: Wrapper,\n\t} );\n}\n","import * as React from 'react';\nimport { closeSnackbar, type SnackbarKey, SnackbarProvider, useSnackbar, type VariantType } from 'notistack';\nimport { __getStore as getStore, __useDispatch as useDispatch, __useSelector as useSelector } from '@elementor/store';\nimport { Button, CloseButton } from '@elementor/ui';\n\nimport { clearAction, notifyAction } from '../slice';\nimport { type NotificationData, type Notifications } from '../types';\n\nconst Handler = () => {\n\tconst { enqueueSnackbar } = useSnackbar();\n\tconst notifications = useSelector( ( state: { notifications: Notifications } ) => state.notifications );\n\tconst dispatch = useDispatch();\n\n\tif ( ! notifications ) {\n\t\treturn null;\n\t}\n\n\tObject.values( notifications ).forEach( ( notification: NotificationData ) => {\n\t\tconst action = ( key: SnackbarKey ) => (\n\t\t\t<>\n\t\t\t\t{ notification.additionalActionProps?.map( ( additionalAction, index ) => (\n\t\t\t\t\t<Button key={ index } { ...additionalAction } />\n\t\t\t\t) ) }\n\n\t\t\t\t<CloseButton\n\t\t\t\t\taria-label=\"close\"\n\t\t\t\t\tcolor=\"inherit\"\n\t\t\t\t\tonClick={ () => {\n\t\t\t\t\t\tcloseSnackbar( key );\n\t\t\t\t\t\tdispatch( clearAction( { id: key } ) );\n\t\t\t\t\t} }\n\t\t\t\t></CloseButton>\n\t\t\t</>\n\t\t);\n\n\t\tenqueueSnackbar( notification.message, {\n\t\t\tvariant: notification.type as VariantType,\n\t\t\tkey: notification.id,\n\t\t\tonClose: () => dispatch( clearAction( { id: notification.id } ) ),\n\t\t\tpreventDuplicate: true,\n\t\t\taction,\n\t\t} );\n\t} );\n\n\treturn null;\n};\n\nconst Wrapper = () => {\n\treturn (\n\t\t<SnackbarProvider\n\t\t\tmaxSnack={ 3 }\n\t\t\tautoHideDuration={ 8000 }\n\t\t\tanchorOrigin={ { horizontal: 'center', vertical: 'bottom' } }\n\t\t>\n\t\t\t<Handler />\n\t\t</SnackbarProvider>\n\t);\n};\n\n/*\n * This function can be used to trigger notifications from anywhere in the code.\n * even if you're running in a JS environment as opposed to a React environment.\n */\nexport function notify( notification: NotificationData ) {\n\tconst store = getStore();\n\n\tstore?.dispatch( notifyAction( notification ) );\n}\n\n/*\n * This function can be used to trigger notifications from within a React component.\n * This is the preferred way to trigger notifications.\n */\nexport function NotifyReact( notification: NotificationData ) {\n\tconst dispatch = useDispatch();\n\tdispatch( notifyAction( notification ) );\n}\n\nexport default Wrapper;\n","import { __createSlice as createSlice } from '@elementor/store';\n\nimport { type Notifications } from './types';\n\nexport const notificationsSlice = createSlice( {\n\tname: 'notifications',\n\tinitialState: {} as Notifications,\n\treducers: {\n\t\tnotifyAction: ( state, action ) => {\n\t\t\tconst newState = { ...state };\n\t\t\tif ( ! newState[ action.payload.id ] ) {\n\t\t\t\tnewState[ action.payload.id ] = action.payload;\n\t\t\t}\n\n\t\t\treturn newState;\n\t\t},\n\t\tclearAction: ( state, action ) => {\n\t\t\tconst newState = { ...state };\n\t\t\tif ( newState[ action.payload.id ] ) {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n\t\t\t\tdelete newState[ action.payload.id ];\n\t\t\t}\n\n\t\t\treturn newState;\n\t\t},\n\t},\n} );\n\nexport const { notifyAction, clearAction } = notificationsSlice.actions;\n","import { init } from './init';\n\nexport { type NotificationData } from './types';\nexport { NotifyReact, notify } from './components/notifications';\n\ninit();\n"],"mappings":";AAAA,SAAS,qBAAqB;AAC9B,SAAS,mBAAmB,qBAAqB;;;ACDjD,YAAY,WAAW;AACvB,SAAS,eAAiC,kBAAkB,mBAAqC;AACjG,SAAS,cAAc,UAAU,iBAAiB,aAAa,iBAAiB,mBAAmB;AACnG,SAAS,QAAQ,mBAAmB;;;ACHpC,SAAS,iBAAiB,mBAAmB;AAItC,IAAM,qBAAqB,YAAa;AAAA,EAC9C,MAAM;AAAA,EACN,cAAc,CAAC;AAAA,EACf,UAAU;AAAA,IACT,cAAc,CAAE,OAAO,WAAY;AAClC,YAAM,WAAW,EAAE,GAAG,MAAM;AAC5B,UAAK,CAAE,SAAU,OAAO,QAAQ,EAAG,GAAI;AACtC,iBAAU,OAAO,QAAQ,EAAG,IAAI,OAAO;AAAA,MACxC;AAEA,aAAO;AAAA,IACR;AAAA,IACA,aAAa,CAAE,OAAO,WAAY;AACjC,YAAM,WAAW,EAAE,GAAG,MAAM;AAC5B,UAAK,SAAU,OAAO,QAAQ,EAAG,GAAI;AAEpC,eAAO,SAAU,OAAO,QAAQ,EAAG;AAAA,MACpC;AAEA,aAAO;AAAA,IACR;AAAA,EACD;AACD,CAAE;AAEK,IAAM,EAAE,cAAc,YAAY,IAAI,mBAAmB;;;ADpBhE,IAAM,UAAU,MAAM;AACrB,QAAM,EAAE,gBAAgB,IAAI,YAAY;AACxC,QAAM,gBAAgB,YAAa,CAAE,UAA6C,MAAM,aAAc;AACtG,QAAM,WAAW,YAAY;AAE7B,MAAK,CAAE,eAAgB;AACtB,WAAO;AAAA,EACR;AAEA,SAAO,OAAQ,aAAc,EAAE,QAAS,CAAE,iBAAoC;AAC7E,UAAM,SAAS,CAAE,QAChB,0DACG,aAAa,uBAAuB,IAAK,CAAE,kBAAkB,UAC9D,oCAAC,UAAO,KAAM,OAAU,GAAG,kBAAmB,CAC7C,GAEF;AAAA,MAAC;AAAA;AAAA,QACA,cAAW;AAAA,QACX,OAAM;AAAA,QACN,SAAU,MAAM;AACf,wBAAe,GAAI;AACnB,mBAAU,YAAa,EAAE,IAAI,IAAI,CAAE,CAAE;AAAA,QACtC;AAAA;AAAA,IACA,CACF;AAGD,oBAAiB,aAAa,SAAS;AAAA,MACtC,SAAS,aAAa;AAAA,MACtB,KAAK,aAAa;AAAA,MAClB,SAAS,MAAM,SAAU,YAAa,EAAE,IAAI,aAAa,GAAG,CAAE,CAAE;AAAA,MAChE,kBAAkB;AAAA,MAClB;AAAA,IACD,CAAE;AAAA,EACH,CAAE;AAEF,SAAO;AACR;AAEA,IAAM,UAAU,MAAM;AACrB,SACC;AAAA,IAAC;AAAA;AAAA,MACA,UAAW;AAAA,MACX,kBAAmB;AAAA,MACnB,cAAe,EAAE,YAAY,UAAU,UAAU,SAAS;AAAA;AAAA,IAE1D,oCAAC,aAAQ;AAAA,EACV;AAEF;AAMO,SAAS,OAAQ,cAAiC;AACxD,QAAM,QAAQ,SAAS;AAEvB,SAAO,SAAU,aAAc,YAAa,CAAE;AAC/C;AAMO,SAAS,YAAa,cAAiC;AAC7D,QAAM,WAAW,YAAY;AAC7B,WAAU,aAAc,YAAa,CAAE;AACxC;AAEA,IAAO,wBAAQ;;;ADxER,SAAS,OAAO;AACtB,gBAAe,kBAAmB;AAClC,gBAAe;AAAA,IACd,IAAI;AAAA,IACJ,WAAW;AAAA,EACZ,CAAE;AACH;;;AGPA,KAAK;","names":[]}
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "@elementor/editor-notifications",
3
+ "description": "Notifications manager for the Elementor editor",
4
+ "version": "1.0.0",
5
+ "private": false,
6
+ "author": "Elementor Team",
7
+ "homepage": "https://elementor.com/",
8
+ "license": "GPL-3.0-or-later",
9
+ "main": "dist/index.js",
10
+ "module": "dist/index.mjs",
11
+ "types": "dist/index.d.ts",
12
+ "exports": {
13
+ ".": {
14
+ "types": "./dist/index.d.ts",
15
+ "import": "./dist/index.mjs",
16
+ "require": "./dist/index.js"
17
+ },
18
+ "./package.json": "./package.json"
19
+ },
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "git+https://github.com/elementor/elementor-packages.git",
23
+ "directory": "packages/core/editor-notifications"
24
+ },
25
+ "bugs": {
26
+ "url": "https://github.com/elementor/elementor-packages/issues"
27
+ },
28
+ "publishConfig": {
29
+ "access": "public"
30
+ },
31
+ "files": [
32
+ "README.md",
33
+ "CHANGELOG.md",
34
+ "/dist",
35
+ "/src",
36
+ "!**/__tests__"
37
+ ],
38
+ "scripts": {
39
+ "build": "tsup --config=../../tsup.build.ts",
40
+ "dev": "tsup --config=../../tsup.dev.ts"
41
+ },
42
+ "dependencies": {
43
+ "@elementor/editor": "0.18.5",
44
+ "@elementor/store": "0.9.0",
45
+ "@elementor/ui": "1.32.1",
46
+ "notistack": "^3.0.2"
47
+ },
48
+ "peerDependencies": {
49
+ "react": "^18.3.1",
50
+ "react-dom": "^18.3.1"
51
+ },
52
+ "devDependencies": {
53
+ "tsup": "^8.3.5"
54
+ }
55
+ }
@@ -0,0 +1,79 @@
1
+ import * as React from 'react';
2
+ import { closeSnackbar, type SnackbarKey, SnackbarProvider, useSnackbar, type VariantType } from 'notistack';
3
+ import { __getStore as getStore, __useDispatch as useDispatch, __useSelector as useSelector } from '@elementor/store';
4
+ import { Button, CloseButton } from '@elementor/ui';
5
+
6
+ import { clearAction, notifyAction } from '../slice';
7
+ import { type NotificationData, type Notifications } from '../types';
8
+
9
+ const Handler = () => {
10
+ const { enqueueSnackbar } = useSnackbar();
11
+ const notifications = useSelector( ( state: { notifications: Notifications } ) => state.notifications );
12
+ const dispatch = useDispatch();
13
+
14
+ if ( ! notifications ) {
15
+ return null;
16
+ }
17
+
18
+ Object.values( notifications ).forEach( ( notification: NotificationData ) => {
19
+ const action = ( key: SnackbarKey ) => (
20
+ <>
21
+ { notification.additionalActionProps?.map( ( additionalAction, index ) => (
22
+ <Button key={ index } { ...additionalAction } />
23
+ ) ) }
24
+
25
+ <CloseButton
26
+ aria-label="close"
27
+ color="inherit"
28
+ onClick={ () => {
29
+ closeSnackbar( key );
30
+ dispatch( clearAction( { id: key } ) );
31
+ } }
32
+ ></CloseButton>
33
+ </>
34
+ );
35
+
36
+ enqueueSnackbar( notification.message, {
37
+ variant: notification.type as VariantType,
38
+ key: notification.id,
39
+ onClose: () => dispatch( clearAction( { id: notification.id } ) ),
40
+ preventDuplicate: true,
41
+ action,
42
+ } );
43
+ } );
44
+
45
+ return null;
46
+ };
47
+
48
+ const Wrapper = () => {
49
+ return (
50
+ <SnackbarProvider
51
+ maxSnack={ 3 }
52
+ autoHideDuration={ 8000 }
53
+ anchorOrigin={ { horizontal: 'center', vertical: 'bottom' } }
54
+ >
55
+ <Handler />
56
+ </SnackbarProvider>
57
+ );
58
+ };
59
+
60
+ /*
61
+ * This function can be used to trigger notifications from anywhere in the code.
62
+ * even if you're running in a JS environment as opposed to a React environment.
63
+ */
64
+ export function notify( notification: NotificationData ) {
65
+ const store = getStore();
66
+
67
+ store?.dispatch( notifyAction( notification ) );
68
+ }
69
+
70
+ /*
71
+ * This function can be used to trigger notifications from within a React component.
72
+ * This is the preferred way to trigger notifications.
73
+ */
74
+ export function NotifyReact( notification: NotificationData ) {
75
+ const dispatch = useDispatch();
76
+ dispatch( notifyAction( notification ) );
77
+ }
78
+
79
+ export default Wrapper;
package/src/index.ts ADDED
@@ -0,0 +1,6 @@
1
+ import { init } from './init';
2
+
3
+ export { type NotificationData } from './types';
4
+ export { NotifyReact, notify } from './components/notifications';
5
+
6
+ init();
package/src/init.ts ADDED
@@ -0,0 +1,13 @@
1
+ import { injectIntoTop } from '@elementor/editor';
2
+ import { __registerSlice as registerSlice } from '@elementor/store';
3
+
4
+ import Wrapper from './components/notifications';
5
+ import { notificationsSlice } from './slice';
6
+
7
+ export function init() {
8
+ registerSlice( notificationsSlice );
9
+ injectIntoTop( {
10
+ id: 'notifications',
11
+ component: Wrapper,
12
+ } );
13
+ }
package/src/slice.ts ADDED
@@ -0,0 +1,29 @@
1
+ import { __createSlice as createSlice } from '@elementor/store';
2
+
3
+ import { type Notifications } from './types';
4
+
5
+ export const notificationsSlice = createSlice( {
6
+ name: 'notifications',
7
+ initialState: {} as Notifications,
8
+ reducers: {
9
+ notifyAction: ( state, action ) => {
10
+ const newState = { ...state };
11
+ if ( ! newState[ action.payload.id ] ) {
12
+ newState[ action.payload.id ] = action.payload;
13
+ }
14
+
15
+ return newState;
16
+ },
17
+ clearAction: ( state, action ) => {
18
+ const newState = { ...state };
19
+ if ( newState[ action.payload.id ] ) {
20
+ // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
21
+ delete newState[ action.payload.id ];
22
+ }
23
+
24
+ return newState;
25
+ },
26
+ },
27
+ } );
28
+
29
+ export const { notifyAction, clearAction } = notificationsSlice.actions;
package/src/types.ts ADDED
@@ -0,0 +1,13 @@
1
+ import { type VariantType } from 'notistack';
2
+ import { type ButtonProps } from '@elementor/ui';
3
+
4
+ export type NotificationData = {
5
+ type: VariantType;
6
+ message: string | React.ReactNode;
7
+ id: string;
8
+ additionalActionProps?: Partial< ButtonProps >[];
9
+ };
10
+
11
+ type NotificationId = string;
12
+
13
+ export type Notifications = Record< NotificationId, NotificationData >;