@elementor/editor-elements-panel 3.32.0-51

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/README.md ADDED
@@ -0,0 +1,4 @@
1
+ # Editor Elements Panel
2
+
3
+ > [!WARNING]
4
+ > This package is under development and not ready for production use.
@@ -0,0 +1,12 @@
1
+ import { ComponentType } from 'react';
2
+
3
+ declare function init(): void;
4
+
5
+ type Config = {
6
+ id: string;
7
+ label: string;
8
+ component: ComponentType;
9
+ };
10
+ declare function injectTab({ id, label, component }: Config): void;
11
+
12
+ export { init, injectTab };
@@ -0,0 +1,12 @@
1
+ import { ComponentType } from 'react';
2
+
3
+ declare function init(): void;
4
+
5
+ type Config = {
6
+ id: string;
7
+ label: string;
8
+ component: ComponentType;
9
+ };
10
+ declare function injectTab({ id, label, component }: Config): void;
11
+
12
+ export { init, injectTab };
package/dist/index.js ADDED
@@ -0,0 +1,184 @@
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
+ init: () => init,
34
+ injectTab: () => injectTab
35
+ });
36
+ module.exports = __toCommonJS(index_exports);
37
+
38
+ // src/init.ts
39
+ var import_editor = require("@elementor/editor");
40
+
41
+ // src/components/elements-panel-tab.tsx
42
+ var React = __toESM(require("react"));
43
+ var import_ui = require("@elementor/ui");
44
+
45
+ // src/hooks/use-active-tab.ts
46
+ var import_editor_v1_adapters = require("@elementor/editor-v1-adapters");
47
+
48
+ // src/consts.ts
49
+ var LEGACY_ELEMENTS_PANEL_COMPONENT_NAME = "panel/elements";
50
+ var LEGACY_ELEMENTS_PANEL_ROUTE_PREFIX = `${LEGACY_ELEMENTS_PANEL_COMPONENT_NAME}/`;
51
+
52
+ // src/tabs.ts
53
+ var tabs = {};
54
+ function registerTab(tab) {
55
+ tabs[tab.id] = tab;
56
+ }
57
+ function getTab(id) {
58
+ return tabs[id] || null;
59
+ }
60
+
61
+ // src/utils/get-window.ts
62
+ function getWindow() {
63
+ return window;
64
+ }
65
+
66
+ // src/hooks/use-active-tab.ts
67
+ function useActiveTab() {
68
+ return (0, import_editor_v1_adapters.__privateUseListenTo)(
69
+ [
70
+ (0, import_editor_v1_adapters.v1ReadyEvent)(),
71
+ (0, import_editor_v1_adapters.routeOpenEvent)(LEGACY_ELEMENTS_PANEL_ROUTE_PREFIX),
72
+ (0, import_editor_v1_adapters.routeCloseEvent)(LEGACY_ELEMENTS_PANEL_ROUTE_PREFIX)
73
+ ],
74
+ () => {
75
+ const panelRoute = getWindow().$e.routes.getCurrent()?.panel;
76
+ if (!panelRoute || !panelRoute.startsWith(LEGACY_ELEMENTS_PANEL_ROUTE_PREFIX)) {
77
+ return null;
78
+ }
79
+ const tab = panelRoute.replace(LEGACY_ELEMENTS_PANEL_ROUTE_PREFIX, "");
80
+ return getTab(tab) ?? null;
81
+ }
82
+ );
83
+ }
84
+
85
+ // src/components/elements-panel-tab.tsx
86
+ var PANEL_WRAPPER_ID = "elementor-panel-elements-wrapper";
87
+ function ElementsPanelTab() {
88
+ const tab = useActiveTab();
89
+ const TabComponent = tab?.component;
90
+ const container = document.getElementById(PANEL_WRAPPER_ID);
91
+ return TabComponent && container ? /* @__PURE__ */ React.createElement(import_ui.Portal, { container }, /* @__PURE__ */ React.createElement(TabComponent, null)) : null;
92
+ }
93
+
94
+ // src/init.ts
95
+ function init() {
96
+ (0, import_editor.injectIntoTop)({
97
+ id: "editor-elements-panel-tab",
98
+ component: ElementsPanelTab
99
+ });
100
+ }
101
+
102
+ // src/inject-tab.ts
103
+ var import_editor_v1_adapters2 = require("@elementor/editor-v1-adapters");
104
+
105
+ // src/utils/create-legacy-view.ts
106
+ function createLegacyView() {
107
+ return getWindow().Marionette.CompositeView.extend({
108
+ template: `<div></div>`,
109
+ initialize() {
110
+ getWindow().elementor.getPanelView().getCurrentPageView().search.reset();
111
+ }
112
+ });
113
+ }
114
+
115
+ // src/utils/get-navigation-wrapper-element.ts
116
+ var import_utils = require("@elementor/utils");
117
+ var NAVIGATION_WRAPPER_ID = "elementor-panel-elements-navigation";
118
+ var ElementsPanelWrapperElementNotFoundError = (0, import_utils.createError)({
119
+ code: "elements_panel_wrapper_element_not_found",
120
+ message: "Elementor Elements Panel wrapper element not found"
121
+ });
122
+ function getNavigationWrapperElement() {
123
+ const wrapper = document.getElementById(NAVIGATION_WRAPPER_ID);
124
+ if (!wrapper) {
125
+ throw new ElementsPanelWrapperElementNotFoundError();
126
+ }
127
+ return wrapper;
128
+ }
129
+
130
+ // src/utils/create-tab-nav-item.ts
131
+ function createTabNavItem({ id, label, route, isActive }) {
132
+ const wrapper = getNavigationWrapperElement();
133
+ const btn = document.createElement("button");
134
+ btn.className = ["elementor-component-tab", "elementor-panel-navigation-tab", isActive ? "elementor-active" : ""].filter(Boolean).join(" ");
135
+ btn.setAttribute("data-tab", id);
136
+ btn.textContent = label;
137
+ btn.addEventListener("click", () => {
138
+ getWindow().$e.route(route);
139
+ });
140
+ wrapper.appendChild(btn);
141
+ }
142
+
143
+ // src/utils/get-legacy-elements-panel-component.ts
144
+ var import_utils2 = require("@elementor/utils");
145
+ var ComponentNotFoundError = (0, import_utils2.createError)({
146
+ code: "e_component_not_found",
147
+ message: "Elementor component not found"
148
+ });
149
+ function getLegacyElementsPanelComponent() {
150
+ const eComponent = getWindow().$e.components.get(LEGACY_ELEMENTS_PANEL_COMPONENT_NAME);
151
+ if (!eComponent) {
152
+ throw new ComponentNotFoundError({ context: { componentId: LEGACY_ELEMENTS_PANEL_COMPONENT_NAME } });
153
+ }
154
+ return eComponent;
155
+ }
156
+
157
+ // src/inject-tab.ts
158
+ function injectTab({ id, label, component }) {
159
+ registerTab({ id, label, component });
160
+ (0, import_editor_v1_adapters2.__privateListenTo)((0, import_editor_v1_adapters2.v1ReadyEvent)(), () => {
161
+ getWindow().elementor.hooks.addFilter("panel/elements/regionViews", (regions, { elements }) => {
162
+ regions[id] = { region: elements, view: createLegacyView() };
163
+ return regions;
164
+ });
165
+ });
166
+ (0, import_editor_v1_adapters2.__privateListenTo)((0, import_editor_v1_adapters2.windowEvent)("elementor/panel/init"), () => {
167
+ getLegacyElementsPanelComponent().addTab(id, { title: label });
168
+ });
169
+ (0, import_editor_v1_adapters2.__privateListenTo)((0, import_editor_v1_adapters2.routeOpenEvent)(LEGACY_ELEMENTS_PANEL_ROUTE_PREFIX), (e) => {
170
+ const route = `${LEGACY_ELEMENTS_PANEL_ROUTE_PREFIX}${id}`;
171
+ createTabNavItem({
172
+ id,
173
+ label,
174
+ route,
175
+ isActive: "route" in e && e.route === route
176
+ });
177
+ });
178
+ }
179
+ // Annotate the CommonJS export names for ESM import in node:
180
+ 0 && (module.exports = {
181
+ init,
182
+ injectTab
183
+ });
184
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/init.ts","../src/components/elements-panel-tab.tsx","../src/hooks/use-active-tab.ts","../src/consts.ts","../src/tabs.ts","../src/utils/get-window.ts","../src/inject-tab.ts","../src/utils/create-legacy-view.ts","../src/utils/get-navigation-wrapper-element.ts","../src/utils/create-tab-nav-item.ts","../src/utils/get-legacy-elements-panel-component.ts"],"sourcesContent":["export { init } from './init';\nexport { injectTab } from './inject-tab';\n","import { injectIntoTop } from '@elementor/editor';\n\nimport { ElementsPanelTab } from './components/elements-panel-tab';\n\nexport function init() {\n\tinjectIntoTop( {\n\t\tid: 'editor-elements-panel-tab',\n\t\tcomponent: ElementsPanelTab,\n\t} );\n}\n","import * as React from 'react';\nimport { Portal } from '@elementor/ui';\n\nimport { useActiveTab } from '../hooks/use-active-tab';\n\nconst PANEL_WRAPPER_ID = 'elementor-panel-elements-wrapper';\n\nexport function ElementsPanelTab() {\n\tconst tab = useActiveTab();\n\n\tconst TabComponent = tab?.component;\n\tconst container = document.getElementById( PANEL_WRAPPER_ID );\n\n\treturn TabComponent && container ? (\n\t\t<Portal container={ container }>\n\t\t\t<TabComponent />\n\t\t</Portal>\n\t) : null;\n}\n","import {\n\t__privateUseListenTo as useListenTo,\n\trouteCloseEvent,\n\trouteOpenEvent,\n\tv1ReadyEvent,\n} from '@elementor/editor-v1-adapters';\n\nimport { LEGACY_ELEMENTS_PANEL_ROUTE_PREFIX } from '../consts';\nimport { getTab } from '../tabs';\nimport { getWindow } from '../utils/get-window';\n\nexport function useActiveTab() {\n\treturn useListenTo(\n\t\t[\n\t\t\tv1ReadyEvent(),\n\t\t\trouteOpenEvent( LEGACY_ELEMENTS_PANEL_ROUTE_PREFIX ),\n\t\t\trouteCloseEvent( LEGACY_ELEMENTS_PANEL_ROUTE_PREFIX ),\n\t\t],\n\t\t() => {\n\t\t\tconst panelRoute = getWindow().$e.routes.getCurrent()?.panel;\n\n\t\t\tif ( ! panelRoute || ! panelRoute.startsWith( LEGACY_ELEMENTS_PANEL_ROUTE_PREFIX ) ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tconst tab = panelRoute.replace( LEGACY_ELEMENTS_PANEL_ROUTE_PREFIX, '' );\n\n\t\t\treturn getTab( tab ) ?? null;\n\t\t}\n\t);\n}\n","export const LEGACY_ELEMENTS_PANEL_COMPONENT_NAME = 'panel/elements';\nexport const LEGACY_ELEMENTS_PANEL_ROUTE_PREFIX = `${ LEGACY_ELEMENTS_PANEL_COMPONENT_NAME }/`;\n","import { type ComponentType } from 'react';\n\ntype Tab = {\n\tid: string;\n\tlabel: string;\n\tcomponent: ComponentType;\n};\n\nconst tabs: Record< Tab[ 'id' ], Tab > = {};\n\nexport function registerTab( tab: Tab ) {\n\ttabs[ tab.id ] = tab;\n}\n\nexport function getTab( id: string ): Tab | null {\n\treturn tabs[ id ] || null;\n}\n","type EditorElementsPanelExtendsWindow = Window & {\n\tMarionette: {\n\t\tCompositeView: {\n\t\t\textend: ( options: { template: string; initialize: () => void } ) => {\n\t\t\t\tnew (): {\n\t\t\t\t\ttemplate: string;\n\t\t\t\t\tinitialize: () => void;\n\t\t\t\t};\n\t\t\t};\n\t\t};\n\t};\n\n\telementor: {\n\t\thooks: {\n\t\t\taddFilter: (\n\t\t\t\tfilterName: string,\n\t\t\t\tcallback: (\n\t\t\t\t\tregions: Record< string, unknown >,\n\t\t\t\t\toptions: { elements: unknown }\n\t\t\t\t) => Record< string, unknown >\n\t\t\t) => void;\n\t\t};\n\n\t\tgetPanelView: () => {\n\t\t\tgetCurrentPageView: () => {\n\t\t\t\tsearch: {\n\t\t\t\t\treset: () => void;\n\t\t\t\t};\n\t\t\t};\n\t\t};\n\t};\n\n\t$e: {\n\t\troutes: {\n\t\t\tgetCurrent: () => Record< string, string >;\n\t\t};\n\n\t\troute: ( route: string ) => void;\n\n\t\tcomponents: {\n\t\t\tget: ( componentName: string ) =>\n\t\t\t\t| {\n\t\t\t\t\t\taddTab: ( id: string, options: { title: string } ) => void;\n\t\t\t\t\t\tremoveTab: ( id: string ) => void;\n\t\t\t\t }\n\t\t\t\t| undefined;\n\t\t};\n\t};\n};\n\nexport function getWindow() {\n\treturn window as unknown as EditorElementsPanelExtendsWindow;\n}\n","import { type ComponentType } from 'react';\nimport {\n\t__privateListenTo as listenTo,\n\trouteOpenEvent,\n\tv1ReadyEvent,\n\twindowEvent,\n} from '@elementor/editor-v1-adapters';\n\nimport { LEGACY_ELEMENTS_PANEL_ROUTE_PREFIX } from './consts';\nimport { registerTab } from './tabs';\nimport { createLegacyView } from './utils/create-legacy-view';\nimport { createTabNavItem } from './utils/create-tab-nav-item';\nimport { getLegacyElementsPanelComponent } from './utils/get-legacy-elements-panel-component';\nimport { getWindow } from './utils/get-window';\n\ntype Config = {\n\tid: string;\n\tlabel: string;\n\tcomponent: ComponentType;\n};\n\nexport function injectTab( { id, label, component }: Config ) {\n\tregisterTab( { id, label, component } );\n\n\tlistenTo( v1ReadyEvent(), () => {\n\t\tgetWindow().elementor.hooks.addFilter( 'panel/elements/regionViews', ( regions, { elements } ) => {\n\t\t\t// Creating a empty legacy view that will be replaced by react component.\n\t\t\tregions[ id ] = { region: elements, view: createLegacyView() };\n\n\t\t\treturn regions;\n\t\t} );\n\t} );\n\n\tlistenTo( windowEvent( 'elementor/panel/init' ), () => {\n\t\t// when adding a tab to the legacy elements panel, it will generate new route based on the id.\n\t\tgetLegacyElementsPanelComponent().addTab( id, { title: label } );\n\t} );\n\n\tlistenTo( routeOpenEvent( LEGACY_ELEMENTS_PANEL_ROUTE_PREFIX ), ( e ) => {\n\t\tconst route = `${ LEGACY_ELEMENTS_PANEL_ROUTE_PREFIX }${ id }`;\n\n\t\tcreateTabNavItem( {\n\t\t\tid,\n\t\t\tlabel,\n\t\t\troute,\n\t\t\tisActive: 'route' in e && e.route === route,\n\t\t} );\n\t} );\n}\n","import { getWindow } from './get-window';\n\nexport function createLegacyView() {\n\treturn getWindow().Marionette.CompositeView.extend( {\n\t\ttemplate: `<div></div>`,\n\n\t\tinitialize() {\n\t\t\tgetWindow().elementor.getPanelView().getCurrentPageView().search.reset();\n\t\t},\n\t} );\n}\n","import { createError } from '@elementor/utils';\n\nconst NAVIGATION_WRAPPER_ID = 'elementor-panel-elements-navigation';\n\nconst ElementsPanelWrapperElementNotFoundError = createError( {\n\tcode: 'elements_panel_wrapper_element_not_found',\n\tmessage: 'Elementor Elements Panel wrapper element not found',\n} );\n\nexport function getNavigationWrapperElement() {\n\tconst wrapper = document.getElementById( NAVIGATION_WRAPPER_ID );\n\n\tif ( ! wrapper ) {\n\t\tthrow new ElementsPanelWrapperElementNotFoundError();\n\t}\n\n\treturn wrapper;\n}\n","import { getNavigationWrapperElement } from './get-navigation-wrapper-element';\nimport { getWindow } from './get-window';\n\ntype Args = {\n\tid: string;\n\tlabel: string;\n\troute: string;\n\tisActive: boolean;\n};\n\nexport function createTabNavItem( { id, label, route, isActive }: Args ): void {\n\tconst wrapper = getNavigationWrapperElement();\n\n\tconst btn = document.createElement( 'button' );\n\n\tbtn.className = [ 'elementor-component-tab', 'elementor-panel-navigation-tab', isActive ? 'elementor-active' : '' ]\n\t\t.filter( Boolean )\n\t\t.join( ' ' );\n\n\tbtn.setAttribute( 'data-tab', id );\n\n\tbtn.textContent = label;\n\n\tbtn.addEventListener( 'click', () => {\n\t\tgetWindow().$e.route( route );\n\t} );\n\n\twrapper.appendChild( btn );\n}\n","import { createError } from '@elementor/utils';\n\nimport { LEGACY_ELEMENTS_PANEL_COMPONENT_NAME } from '../consts';\nimport { getWindow } from './get-window';\n\nconst ComponentNotFoundError = createError< { componentId: string } >( {\n\tcode: 'e_component_not_found',\n\tmessage: 'Elementor component not found',\n} );\n\nexport function getLegacyElementsPanelComponent() {\n\tconst eComponent = getWindow().$e.components.get( LEGACY_ELEMENTS_PANEL_COMPONENT_NAME );\n\n\tif ( ! eComponent ) {\n\t\tthrow new ComponentNotFoundError( { context: { componentId: LEGACY_ELEMENTS_PANEL_COMPONENT_NAME } } );\n\t}\n\n\treturn eComponent;\n}\n"],"mappings":"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","names":["useListenTo","import_editor_v1_adapters","import_utils","listenTo"]}
package/dist/index.mjs ADDED
@@ -0,0 +1,156 @@
1
+ // src/init.ts
2
+ import { injectIntoTop } from "@elementor/editor";
3
+
4
+ // src/components/elements-panel-tab.tsx
5
+ import * as React from "react";
6
+ import { Portal } from "@elementor/ui";
7
+
8
+ // src/hooks/use-active-tab.ts
9
+ import {
10
+ __privateUseListenTo as useListenTo,
11
+ routeCloseEvent,
12
+ routeOpenEvent,
13
+ v1ReadyEvent
14
+ } from "@elementor/editor-v1-adapters";
15
+
16
+ // src/consts.ts
17
+ var LEGACY_ELEMENTS_PANEL_COMPONENT_NAME = "panel/elements";
18
+ var LEGACY_ELEMENTS_PANEL_ROUTE_PREFIX = `${LEGACY_ELEMENTS_PANEL_COMPONENT_NAME}/`;
19
+
20
+ // src/tabs.ts
21
+ var tabs = {};
22
+ function registerTab(tab) {
23
+ tabs[tab.id] = tab;
24
+ }
25
+ function getTab(id) {
26
+ return tabs[id] || null;
27
+ }
28
+
29
+ // src/utils/get-window.ts
30
+ function getWindow() {
31
+ return window;
32
+ }
33
+
34
+ // src/hooks/use-active-tab.ts
35
+ function useActiveTab() {
36
+ return useListenTo(
37
+ [
38
+ v1ReadyEvent(),
39
+ routeOpenEvent(LEGACY_ELEMENTS_PANEL_ROUTE_PREFIX),
40
+ routeCloseEvent(LEGACY_ELEMENTS_PANEL_ROUTE_PREFIX)
41
+ ],
42
+ () => {
43
+ const panelRoute = getWindow().$e.routes.getCurrent()?.panel;
44
+ if (!panelRoute || !panelRoute.startsWith(LEGACY_ELEMENTS_PANEL_ROUTE_PREFIX)) {
45
+ return null;
46
+ }
47
+ const tab = panelRoute.replace(LEGACY_ELEMENTS_PANEL_ROUTE_PREFIX, "");
48
+ return getTab(tab) ?? null;
49
+ }
50
+ );
51
+ }
52
+
53
+ // src/components/elements-panel-tab.tsx
54
+ var PANEL_WRAPPER_ID = "elementor-panel-elements-wrapper";
55
+ function ElementsPanelTab() {
56
+ const tab = useActiveTab();
57
+ const TabComponent = tab?.component;
58
+ const container = document.getElementById(PANEL_WRAPPER_ID);
59
+ return TabComponent && container ? /* @__PURE__ */ React.createElement(Portal, { container }, /* @__PURE__ */ React.createElement(TabComponent, null)) : null;
60
+ }
61
+
62
+ // src/init.ts
63
+ function init() {
64
+ injectIntoTop({
65
+ id: "editor-elements-panel-tab",
66
+ component: ElementsPanelTab
67
+ });
68
+ }
69
+
70
+ // src/inject-tab.ts
71
+ import {
72
+ __privateListenTo as listenTo,
73
+ routeOpenEvent as routeOpenEvent2,
74
+ v1ReadyEvent as v1ReadyEvent2,
75
+ windowEvent
76
+ } from "@elementor/editor-v1-adapters";
77
+
78
+ // src/utils/create-legacy-view.ts
79
+ function createLegacyView() {
80
+ return getWindow().Marionette.CompositeView.extend({
81
+ template: `<div></div>`,
82
+ initialize() {
83
+ getWindow().elementor.getPanelView().getCurrentPageView().search.reset();
84
+ }
85
+ });
86
+ }
87
+
88
+ // src/utils/get-navigation-wrapper-element.ts
89
+ import { createError } from "@elementor/utils";
90
+ var NAVIGATION_WRAPPER_ID = "elementor-panel-elements-navigation";
91
+ var ElementsPanelWrapperElementNotFoundError = createError({
92
+ code: "elements_panel_wrapper_element_not_found",
93
+ message: "Elementor Elements Panel wrapper element not found"
94
+ });
95
+ function getNavigationWrapperElement() {
96
+ const wrapper = document.getElementById(NAVIGATION_WRAPPER_ID);
97
+ if (!wrapper) {
98
+ throw new ElementsPanelWrapperElementNotFoundError();
99
+ }
100
+ return wrapper;
101
+ }
102
+
103
+ // src/utils/create-tab-nav-item.ts
104
+ function createTabNavItem({ id, label, route, isActive }) {
105
+ const wrapper = getNavigationWrapperElement();
106
+ const btn = document.createElement("button");
107
+ btn.className = ["elementor-component-tab", "elementor-panel-navigation-tab", isActive ? "elementor-active" : ""].filter(Boolean).join(" ");
108
+ btn.setAttribute("data-tab", id);
109
+ btn.textContent = label;
110
+ btn.addEventListener("click", () => {
111
+ getWindow().$e.route(route);
112
+ });
113
+ wrapper.appendChild(btn);
114
+ }
115
+
116
+ // src/utils/get-legacy-elements-panel-component.ts
117
+ import { createError as createError2 } from "@elementor/utils";
118
+ var ComponentNotFoundError = createError2({
119
+ code: "e_component_not_found",
120
+ message: "Elementor component not found"
121
+ });
122
+ function getLegacyElementsPanelComponent() {
123
+ const eComponent = getWindow().$e.components.get(LEGACY_ELEMENTS_PANEL_COMPONENT_NAME);
124
+ if (!eComponent) {
125
+ throw new ComponentNotFoundError({ context: { componentId: LEGACY_ELEMENTS_PANEL_COMPONENT_NAME } });
126
+ }
127
+ return eComponent;
128
+ }
129
+
130
+ // src/inject-tab.ts
131
+ function injectTab({ id, label, component }) {
132
+ registerTab({ id, label, component });
133
+ listenTo(v1ReadyEvent2(), () => {
134
+ getWindow().elementor.hooks.addFilter("panel/elements/regionViews", (regions, { elements }) => {
135
+ regions[id] = { region: elements, view: createLegacyView() };
136
+ return regions;
137
+ });
138
+ });
139
+ listenTo(windowEvent("elementor/panel/init"), () => {
140
+ getLegacyElementsPanelComponent().addTab(id, { title: label });
141
+ });
142
+ listenTo(routeOpenEvent2(LEGACY_ELEMENTS_PANEL_ROUTE_PREFIX), (e) => {
143
+ const route = `${LEGACY_ELEMENTS_PANEL_ROUTE_PREFIX}${id}`;
144
+ createTabNavItem({
145
+ id,
146
+ label,
147
+ route,
148
+ isActive: "route" in e && e.route === route
149
+ });
150
+ });
151
+ }
152
+ export {
153
+ init,
154
+ injectTab
155
+ };
156
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/init.ts","../src/components/elements-panel-tab.tsx","../src/hooks/use-active-tab.ts","../src/consts.ts","../src/tabs.ts","../src/utils/get-window.ts","../src/inject-tab.ts","../src/utils/create-legacy-view.ts","../src/utils/get-navigation-wrapper-element.ts","../src/utils/create-tab-nav-item.ts","../src/utils/get-legacy-elements-panel-component.ts"],"sourcesContent":["import { injectIntoTop } from '@elementor/editor';\n\nimport { ElementsPanelTab } from './components/elements-panel-tab';\n\nexport function init() {\n\tinjectIntoTop( {\n\t\tid: 'editor-elements-panel-tab',\n\t\tcomponent: ElementsPanelTab,\n\t} );\n}\n","import * as React from 'react';\nimport { Portal } from '@elementor/ui';\n\nimport { useActiveTab } from '../hooks/use-active-tab';\n\nconst PANEL_WRAPPER_ID = 'elementor-panel-elements-wrapper';\n\nexport function ElementsPanelTab() {\n\tconst tab = useActiveTab();\n\n\tconst TabComponent = tab?.component;\n\tconst container = document.getElementById( PANEL_WRAPPER_ID );\n\n\treturn TabComponent && container ? (\n\t\t<Portal container={ container }>\n\t\t\t<TabComponent />\n\t\t</Portal>\n\t) : null;\n}\n","import {\n\t__privateUseListenTo as useListenTo,\n\trouteCloseEvent,\n\trouteOpenEvent,\n\tv1ReadyEvent,\n} from '@elementor/editor-v1-adapters';\n\nimport { LEGACY_ELEMENTS_PANEL_ROUTE_PREFIX } from '../consts';\nimport { getTab } from '../tabs';\nimport { getWindow } from '../utils/get-window';\n\nexport function useActiveTab() {\n\treturn useListenTo(\n\t\t[\n\t\t\tv1ReadyEvent(),\n\t\t\trouteOpenEvent( LEGACY_ELEMENTS_PANEL_ROUTE_PREFIX ),\n\t\t\trouteCloseEvent( LEGACY_ELEMENTS_PANEL_ROUTE_PREFIX ),\n\t\t],\n\t\t() => {\n\t\t\tconst panelRoute = getWindow().$e.routes.getCurrent()?.panel;\n\n\t\t\tif ( ! panelRoute || ! panelRoute.startsWith( LEGACY_ELEMENTS_PANEL_ROUTE_PREFIX ) ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tconst tab = panelRoute.replace( LEGACY_ELEMENTS_PANEL_ROUTE_PREFIX, '' );\n\n\t\t\treturn getTab( tab ) ?? null;\n\t\t}\n\t);\n}\n","export const LEGACY_ELEMENTS_PANEL_COMPONENT_NAME = 'panel/elements';\nexport const LEGACY_ELEMENTS_PANEL_ROUTE_PREFIX = `${ LEGACY_ELEMENTS_PANEL_COMPONENT_NAME }/`;\n","import { type ComponentType } from 'react';\n\ntype Tab = {\n\tid: string;\n\tlabel: string;\n\tcomponent: ComponentType;\n};\n\nconst tabs: Record< Tab[ 'id' ], Tab > = {};\n\nexport function registerTab( tab: Tab ) {\n\ttabs[ tab.id ] = tab;\n}\n\nexport function getTab( id: string ): Tab | null {\n\treturn tabs[ id ] || null;\n}\n","type EditorElementsPanelExtendsWindow = Window & {\n\tMarionette: {\n\t\tCompositeView: {\n\t\t\textend: ( options: { template: string; initialize: () => void } ) => {\n\t\t\t\tnew (): {\n\t\t\t\t\ttemplate: string;\n\t\t\t\t\tinitialize: () => void;\n\t\t\t\t};\n\t\t\t};\n\t\t};\n\t};\n\n\telementor: {\n\t\thooks: {\n\t\t\taddFilter: (\n\t\t\t\tfilterName: string,\n\t\t\t\tcallback: (\n\t\t\t\t\tregions: Record< string, unknown >,\n\t\t\t\t\toptions: { elements: unknown }\n\t\t\t\t) => Record< string, unknown >\n\t\t\t) => void;\n\t\t};\n\n\t\tgetPanelView: () => {\n\t\t\tgetCurrentPageView: () => {\n\t\t\t\tsearch: {\n\t\t\t\t\treset: () => void;\n\t\t\t\t};\n\t\t\t};\n\t\t};\n\t};\n\n\t$e: {\n\t\troutes: {\n\t\t\tgetCurrent: () => Record< string, string >;\n\t\t};\n\n\t\troute: ( route: string ) => void;\n\n\t\tcomponents: {\n\t\t\tget: ( componentName: string ) =>\n\t\t\t\t| {\n\t\t\t\t\t\taddTab: ( id: string, options: { title: string } ) => void;\n\t\t\t\t\t\tremoveTab: ( id: string ) => void;\n\t\t\t\t }\n\t\t\t\t| undefined;\n\t\t};\n\t};\n};\n\nexport function getWindow() {\n\treturn window as unknown as EditorElementsPanelExtendsWindow;\n}\n","import { type ComponentType } from 'react';\nimport {\n\t__privateListenTo as listenTo,\n\trouteOpenEvent,\n\tv1ReadyEvent,\n\twindowEvent,\n} from '@elementor/editor-v1-adapters';\n\nimport { LEGACY_ELEMENTS_PANEL_ROUTE_PREFIX } from './consts';\nimport { registerTab } from './tabs';\nimport { createLegacyView } from './utils/create-legacy-view';\nimport { createTabNavItem } from './utils/create-tab-nav-item';\nimport { getLegacyElementsPanelComponent } from './utils/get-legacy-elements-panel-component';\nimport { getWindow } from './utils/get-window';\n\ntype Config = {\n\tid: string;\n\tlabel: string;\n\tcomponent: ComponentType;\n};\n\nexport function injectTab( { id, label, component }: Config ) {\n\tregisterTab( { id, label, component } );\n\n\tlistenTo( v1ReadyEvent(), () => {\n\t\tgetWindow().elementor.hooks.addFilter( 'panel/elements/regionViews', ( regions, { elements } ) => {\n\t\t\t// Creating a empty legacy view that will be replaced by react component.\n\t\t\tregions[ id ] = { region: elements, view: createLegacyView() };\n\n\t\t\treturn regions;\n\t\t} );\n\t} );\n\n\tlistenTo( windowEvent( 'elementor/panel/init' ), () => {\n\t\t// when adding a tab to the legacy elements panel, it will generate new route based on the id.\n\t\tgetLegacyElementsPanelComponent().addTab( id, { title: label } );\n\t} );\n\n\tlistenTo( routeOpenEvent( LEGACY_ELEMENTS_PANEL_ROUTE_PREFIX ), ( e ) => {\n\t\tconst route = `${ LEGACY_ELEMENTS_PANEL_ROUTE_PREFIX }${ id }`;\n\n\t\tcreateTabNavItem( {\n\t\t\tid,\n\t\t\tlabel,\n\t\t\troute,\n\t\t\tisActive: 'route' in e && e.route === route,\n\t\t} );\n\t} );\n}\n","import { getWindow } from './get-window';\n\nexport function createLegacyView() {\n\treturn getWindow().Marionette.CompositeView.extend( {\n\t\ttemplate: `<div></div>`,\n\n\t\tinitialize() {\n\t\t\tgetWindow().elementor.getPanelView().getCurrentPageView().search.reset();\n\t\t},\n\t} );\n}\n","import { createError } from '@elementor/utils';\n\nconst NAVIGATION_WRAPPER_ID = 'elementor-panel-elements-navigation';\n\nconst ElementsPanelWrapperElementNotFoundError = createError( {\n\tcode: 'elements_panel_wrapper_element_not_found',\n\tmessage: 'Elementor Elements Panel wrapper element not found',\n} );\n\nexport function getNavigationWrapperElement() {\n\tconst wrapper = document.getElementById( NAVIGATION_WRAPPER_ID );\n\n\tif ( ! wrapper ) {\n\t\tthrow new ElementsPanelWrapperElementNotFoundError();\n\t}\n\n\treturn wrapper;\n}\n","import { getNavigationWrapperElement } from './get-navigation-wrapper-element';\nimport { getWindow } from './get-window';\n\ntype Args = {\n\tid: string;\n\tlabel: string;\n\troute: string;\n\tisActive: boolean;\n};\n\nexport function createTabNavItem( { id, label, route, isActive }: Args ): void {\n\tconst wrapper = getNavigationWrapperElement();\n\n\tconst btn = document.createElement( 'button' );\n\n\tbtn.className = [ 'elementor-component-tab', 'elementor-panel-navigation-tab', isActive ? 'elementor-active' : '' ]\n\t\t.filter( Boolean )\n\t\t.join( ' ' );\n\n\tbtn.setAttribute( 'data-tab', id );\n\n\tbtn.textContent = label;\n\n\tbtn.addEventListener( 'click', () => {\n\t\tgetWindow().$e.route( route );\n\t} );\n\n\twrapper.appendChild( btn );\n}\n","import { createError } from '@elementor/utils';\n\nimport { LEGACY_ELEMENTS_PANEL_COMPONENT_NAME } from '../consts';\nimport { getWindow } from './get-window';\n\nconst ComponentNotFoundError = createError< { componentId: string } >( {\n\tcode: 'e_component_not_found',\n\tmessage: 'Elementor component not found',\n} );\n\nexport function getLegacyElementsPanelComponent() {\n\tconst eComponent = getWindow().$e.components.get( LEGACY_ELEMENTS_PANEL_COMPONENT_NAME );\n\n\tif ( ! eComponent ) {\n\t\tthrow new ComponentNotFoundError( { context: { componentId: LEGACY_ELEMENTS_PANEL_COMPONENT_NAME } } );\n\t}\n\n\treturn eComponent;\n}\n"],"mappings":"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","names":["routeOpenEvent","v1ReadyEvent","createError","createError","v1ReadyEvent","routeOpenEvent"]}
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "@elementor/editor-elements-panel",
3
+ "version": "3.32.0-51",
4
+ "private": false,
5
+ "author": "Elementor Team",
6
+ "homepage": "https://elementor.com/",
7
+ "license": "GPL-3.0-or-later",
8
+ "main": "dist/index.js",
9
+ "module": "dist/index.mjs",
10
+ "types": "dist/index.d.ts",
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "import": "./dist/index.mjs",
15
+ "require": "./dist/index.js"
16
+ },
17
+ "./package.json": "./package.json"
18
+ },
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "git+https://github.com/elementor/elementor.git",
22
+ "directory": "packages/core/editor-elements-panel"
23
+ },
24
+ "bugs": {
25
+ "url": "https://github.com/elementor/elementor/issues"
26
+ },
27
+ "publishConfig": {
28
+ "access": "public"
29
+ },
30
+ "files": [
31
+ "README.md",
32
+ "CHANGELOG.md",
33
+ "/dist",
34
+ "/src",
35
+ "!**/__tests__"
36
+ ],
37
+ "scripts": {
38
+ "build": "tsup --config=../../tsup.build.ts",
39
+ "dev": "tsup --config=../../tsup.dev.ts"
40
+ },
41
+ "dependencies": {
42
+ "@elementor/ui": "1.36.8",
43
+ "@elementor/editor": "3.32.0-51",
44
+ "@elementor/editor-v1-adapters": "3.32.0-51",
45
+ "@elementor/utils": "3.32.0-51"
46
+ },
47
+ "peerDependencies": {
48
+ "react": "^18.3.1"
49
+ },
50
+ "devDependencies": {
51
+ "tsup": "^8.3.5"
52
+ }
53
+ }
@@ -0,0 +1,19 @@
1
+ import * as React from 'react';
2
+ import { Portal } from '@elementor/ui';
3
+
4
+ import { useActiveTab } from '../hooks/use-active-tab';
5
+
6
+ const PANEL_WRAPPER_ID = 'elementor-panel-elements-wrapper';
7
+
8
+ export function ElementsPanelTab() {
9
+ const tab = useActiveTab();
10
+
11
+ const TabComponent = tab?.component;
12
+ const container = document.getElementById( PANEL_WRAPPER_ID );
13
+
14
+ return TabComponent && container ? (
15
+ <Portal container={ container }>
16
+ <TabComponent />
17
+ </Portal>
18
+ ) : null;
19
+ }
package/src/consts.ts ADDED
@@ -0,0 +1,2 @@
1
+ export const LEGACY_ELEMENTS_PANEL_COMPONENT_NAME = 'panel/elements';
2
+ export const LEGACY_ELEMENTS_PANEL_ROUTE_PREFIX = `${ LEGACY_ELEMENTS_PANEL_COMPONENT_NAME }/`;
@@ -0,0 +1,31 @@
1
+ import {
2
+ __privateUseListenTo as useListenTo,
3
+ routeCloseEvent,
4
+ routeOpenEvent,
5
+ v1ReadyEvent,
6
+ } from '@elementor/editor-v1-adapters';
7
+
8
+ import { LEGACY_ELEMENTS_PANEL_ROUTE_PREFIX } from '../consts';
9
+ import { getTab } from '../tabs';
10
+ import { getWindow } from '../utils/get-window';
11
+
12
+ export function useActiveTab() {
13
+ return useListenTo(
14
+ [
15
+ v1ReadyEvent(),
16
+ routeOpenEvent( LEGACY_ELEMENTS_PANEL_ROUTE_PREFIX ),
17
+ routeCloseEvent( LEGACY_ELEMENTS_PANEL_ROUTE_PREFIX ),
18
+ ],
19
+ () => {
20
+ const panelRoute = getWindow().$e.routes.getCurrent()?.panel;
21
+
22
+ if ( ! panelRoute || ! panelRoute.startsWith( LEGACY_ELEMENTS_PANEL_ROUTE_PREFIX ) ) {
23
+ return null;
24
+ }
25
+
26
+ const tab = panelRoute.replace( LEGACY_ELEMENTS_PANEL_ROUTE_PREFIX, '' );
27
+
28
+ return getTab( tab ) ?? null;
29
+ }
30
+ );
31
+ }
package/src/index.ts ADDED
@@ -0,0 +1,2 @@
1
+ export { init } from './init';
2
+ export { injectTab } from './inject-tab';
package/src/init.ts ADDED
@@ -0,0 +1,10 @@
1
+ import { injectIntoTop } from '@elementor/editor';
2
+
3
+ import { ElementsPanelTab } from './components/elements-panel-tab';
4
+
5
+ export function init() {
6
+ injectIntoTop( {
7
+ id: 'editor-elements-panel-tab',
8
+ component: ElementsPanelTab,
9
+ } );
10
+ }
@@ -0,0 +1,49 @@
1
+ import { type ComponentType } from 'react';
2
+ import {
3
+ __privateListenTo as listenTo,
4
+ routeOpenEvent,
5
+ v1ReadyEvent,
6
+ windowEvent,
7
+ } from '@elementor/editor-v1-adapters';
8
+
9
+ import { LEGACY_ELEMENTS_PANEL_ROUTE_PREFIX } from './consts';
10
+ import { registerTab } from './tabs';
11
+ import { createLegacyView } from './utils/create-legacy-view';
12
+ import { createTabNavItem } from './utils/create-tab-nav-item';
13
+ import { getLegacyElementsPanelComponent } from './utils/get-legacy-elements-panel-component';
14
+ import { getWindow } from './utils/get-window';
15
+
16
+ type Config = {
17
+ id: string;
18
+ label: string;
19
+ component: ComponentType;
20
+ };
21
+
22
+ export function injectTab( { id, label, component }: Config ) {
23
+ registerTab( { id, label, component } );
24
+
25
+ listenTo( v1ReadyEvent(), () => {
26
+ getWindow().elementor.hooks.addFilter( 'panel/elements/regionViews', ( regions, { elements } ) => {
27
+ // Creating a empty legacy view that will be replaced by react component.
28
+ regions[ id ] = { region: elements, view: createLegacyView() };
29
+
30
+ return regions;
31
+ } );
32
+ } );
33
+
34
+ listenTo( windowEvent( 'elementor/panel/init' ), () => {
35
+ // when adding a tab to the legacy elements panel, it will generate new route based on the id.
36
+ getLegacyElementsPanelComponent().addTab( id, { title: label } );
37
+ } );
38
+
39
+ listenTo( routeOpenEvent( LEGACY_ELEMENTS_PANEL_ROUTE_PREFIX ), ( e ) => {
40
+ const route = `${ LEGACY_ELEMENTS_PANEL_ROUTE_PREFIX }${ id }`;
41
+
42
+ createTabNavItem( {
43
+ id,
44
+ label,
45
+ route,
46
+ isActive: 'route' in e && e.route === route,
47
+ } );
48
+ } );
49
+ }
package/src/tabs.ts ADDED
@@ -0,0 +1,17 @@
1
+ import { type ComponentType } from 'react';
2
+
3
+ type Tab = {
4
+ id: string;
5
+ label: string;
6
+ component: ComponentType;
7
+ };
8
+
9
+ const tabs: Record< Tab[ 'id' ], Tab > = {};
10
+
11
+ export function registerTab( tab: Tab ) {
12
+ tabs[ tab.id ] = tab;
13
+ }
14
+
15
+ export function getTab( id: string ): Tab | null {
16
+ return tabs[ id ] || null;
17
+ }
@@ -0,0 +1,11 @@
1
+ import { getWindow } from './get-window';
2
+
3
+ export function createLegacyView() {
4
+ return getWindow().Marionette.CompositeView.extend( {
5
+ template: `<div></div>`,
6
+
7
+ initialize() {
8
+ getWindow().elementor.getPanelView().getCurrentPageView().search.reset();
9
+ },
10
+ } );
11
+ }
@@ -0,0 +1,29 @@
1
+ import { getNavigationWrapperElement } from './get-navigation-wrapper-element';
2
+ import { getWindow } from './get-window';
3
+
4
+ type Args = {
5
+ id: string;
6
+ label: string;
7
+ route: string;
8
+ isActive: boolean;
9
+ };
10
+
11
+ export function createTabNavItem( { id, label, route, isActive }: Args ): void {
12
+ const wrapper = getNavigationWrapperElement();
13
+
14
+ const btn = document.createElement( 'button' );
15
+
16
+ btn.className = [ 'elementor-component-tab', 'elementor-panel-navigation-tab', isActive ? 'elementor-active' : '' ]
17
+ .filter( Boolean )
18
+ .join( ' ' );
19
+
20
+ btn.setAttribute( 'data-tab', id );
21
+
22
+ btn.textContent = label;
23
+
24
+ btn.addEventListener( 'click', () => {
25
+ getWindow().$e.route( route );
26
+ } );
27
+
28
+ wrapper.appendChild( btn );
29
+ }
@@ -0,0 +1,19 @@
1
+ import { createError } from '@elementor/utils';
2
+
3
+ import { LEGACY_ELEMENTS_PANEL_COMPONENT_NAME } from '../consts';
4
+ import { getWindow } from './get-window';
5
+
6
+ const ComponentNotFoundError = createError< { componentId: string } >( {
7
+ code: 'e_component_not_found',
8
+ message: 'Elementor component not found',
9
+ } );
10
+
11
+ export function getLegacyElementsPanelComponent() {
12
+ const eComponent = getWindow().$e.components.get( LEGACY_ELEMENTS_PANEL_COMPONENT_NAME );
13
+
14
+ if ( ! eComponent ) {
15
+ throw new ComponentNotFoundError( { context: { componentId: LEGACY_ELEMENTS_PANEL_COMPONENT_NAME } } );
16
+ }
17
+
18
+ return eComponent;
19
+ }
@@ -0,0 +1,18 @@
1
+ import { createError } from '@elementor/utils';
2
+
3
+ const NAVIGATION_WRAPPER_ID = 'elementor-panel-elements-navigation';
4
+
5
+ const ElementsPanelWrapperElementNotFoundError = createError( {
6
+ code: 'elements_panel_wrapper_element_not_found',
7
+ message: 'Elementor Elements Panel wrapper element not found',
8
+ } );
9
+
10
+ export function getNavigationWrapperElement() {
11
+ const wrapper = document.getElementById( NAVIGATION_WRAPPER_ID );
12
+
13
+ if ( ! wrapper ) {
14
+ throw new ElementsPanelWrapperElementNotFoundError();
15
+ }
16
+
17
+ return wrapper;
18
+ }
@@ -0,0 +1,53 @@
1
+ type EditorElementsPanelExtendsWindow = Window & {
2
+ Marionette: {
3
+ CompositeView: {
4
+ extend: ( options: { template: string; initialize: () => void } ) => {
5
+ new (): {
6
+ template: string;
7
+ initialize: () => void;
8
+ };
9
+ };
10
+ };
11
+ };
12
+
13
+ elementor: {
14
+ hooks: {
15
+ addFilter: (
16
+ filterName: string,
17
+ callback: (
18
+ regions: Record< string, unknown >,
19
+ options: { elements: unknown }
20
+ ) => Record< string, unknown >
21
+ ) => void;
22
+ };
23
+
24
+ getPanelView: () => {
25
+ getCurrentPageView: () => {
26
+ search: {
27
+ reset: () => void;
28
+ };
29
+ };
30
+ };
31
+ };
32
+
33
+ $e: {
34
+ routes: {
35
+ getCurrent: () => Record< string, string >;
36
+ };
37
+
38
+ route: ( route: string ) => void;
39
+
40
+ components: {
41
+ get: ( componentName: string ) =>
42
+ | {
43
+ addTab: ( id: string, options: { title: string } ) => void;
44
+ removeTab: ( id: string ) => void;
45
+ }
46
+ | undefined;
47
+ };
48
+ };
49
+ };
50
+
51
+ export function getWindow() {
52
+ return window as unknown as EditorElementsPanelExtendsWindow;
53
+ }