PluginProbe
Elementor Website Builder – more than just a page builder / 3.35.0-dev2
Elementor Website Builder – more than just a page builder v3.35.0-dev2
4.3.2 4.3.1 4.3.0 4.3.0-beta3 4.3.0-beta2 4.3.0-beta1 4.2.4 4.2.3 4.2.2 4.2.1 4.2.0 4.1.5 4.2.0-beta2 4.2.0-dev2 4.2.0-beta1 4.1.4 4.1.3 4.1.2 4.1.1 4.1.0 4.1.0-beta3 4.1.0-dev3 4.0.9 4.1.0-beta2 4.1.0-dev2 All 455 releases
← All changes | assets/js/packages/editor-global-classes/editor-global-classes.js +4 -3544 4.3.0 → 3.35.0-dev2 View file →
@@ -1,3547 +1,7 @@
1 -(function(react, _elementor_editor_current_user, _elementor_editor_documents, _elementor_editor_panels, _elementor_editor_ui, _elementor_query, _elementor_store, _elementor_ui, _wordpress_i18n, _elementor_editor_styles, _elementor_utils, _elementor_http_client, _elementor_icons, _elementor_events, react_dom, _elementor_editor_styles_repository, _elementor_editor, _elementor_editor_editing_panel, _elementor_editor_embedded_documents_manager, _elementor_editor_mcp, _elementor_editor_canvas, _elementor_editor_v1_adapters, _elementor_schema) {
2 -
3 -//#region \0rolldown/runtime.js
4 - var __create = Object.create;
5 - var __defProp$1 = Object.defineProperty;
6 - var __name = (target, value) => __defProp$1(target, "name", {
7 - value,
8 - configurable: true
9 - });
10 - var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
11 - var __getOwnPropNames = Object.getOwnPropertyNames;
12 - var __getProtoOf = Object.getPrototypeOf;
13 - var __hasOwnProp = Object.prototype.hasOwnProperty;
14 - var __exportAll = (all, no_symbols) => {
15 - let target = {};
16 - for (var name in all) {
17 - __defProp$1(target, name, {
18 - get: all[name],
19 - enumerable: true
20 - });
21 - }
22 - if (!no_symbols) {
23 - __defProp$1(target, Symbol.toStringTag, { value: "Module" });
24 - }
25 - return target;
26 - };
27 - var __copyProps = (to, from, except, desc) => {
28 - if (from && typeof from === "object" || typeof from === "function") {
29 - for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
30 - key = keys[i];
31 - if (!__hasOwnProp.call(to, key) && key !== except) {
32 - __defProp$1(to, key, {
33 - get: ((k) => from[k]).bind(null, key),
34 - enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
35 - });
36 - }
37 - }
38 - }
39 - return to;
40 - };
41 - var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp$1(target, "default", {
42 - value: mod,
43 - enumerable: true
44 - }) : target, mod));
45 -
46 -//#endregion
47 -let react$1 = __toESM(react, 1);
48 -react = __toESM(react);
49 -
50 -//#region packages/packages/core/editor-global-classes/src/errors.ts
51 - var GlobalClassNotFoundError = (0, _elementor_utils.createError)({
52 - code: "global_class_not_found",
53 - message: "Global class not found."
54 - });
55 - var GlobalClassLabelAlreadyExistsError = (0, _elementor_utils.createError)({
56 - code: "global_class_label_already_exists",
57 - message: "Class with this name already exists."
58 - });
59 - var GlobalClassTrackingError = (0, _elementor_utils.createError)({
60 - code: "global_class_tracking_error",
61 - message: "Error tracking global classes event."
62 - });
63 -
64 -//#endregion
65 -//#region packages/packages/core/editor-global-classes/src/utils/snapshot-history.ts
66 - var __defProp = Object.defineProperty;
67 - var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, {
68 - enumerable: true,
69 - configurable: true,
70 - writable: true,
71 - value
72 - }) : obj[key] = value;
73 - var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
74 - function createLink({ value, next, prev }) {
75 - return {
76 - value,
77 - prev: prev || null,
78 - next: next || null
79 - };
80 - }
81 - var _SnapshotHistory = class _SnapshotHistory {
82 - constructor(namespace) {
83 - __publicField(this, "namespace", namespace);
84 - __publicField(this, "first", null);
85 - __publicField(this, "current", null);
86 - }
87 - static get(namespace) {
88 - if (!_SnapshotHistory.registry[namespace]) _SnapshotHistory.registry[namespace] = new _SnapshotHistory(namespace);
89 - return _SnapshotHistory.registry[namespace];
90 - }
91 - transform(item) {
92 - return JSON.parse(JSON.stringify(item));
93 - }
94 - reset() {
95 - this.first = this.current = null;
96 - }
97 - prev() {
98 - if (!this.current || this.current === this.first) return null;
99 - this.current = this.current.prev;
100 - return this.current?.value || null;
101 - }
102 - isLast() {
103 - return !this.current || !this.current.next;
104 - }
105 - next(value) {
106 - if (value) {
107 - if (!this.current) {
108 - this.first = createLink({ value: this.transform(value) });
109 - this.current = this.first;
110 - return this.current.value;
111 - }
112 - const nextLink = createLink({
113 - value: this.transform(value),
114 - prev: this.current
115 - });
116 - this.current.next = nextLink;
117 - this.current = nextLink;
118 - return this.current.value;
119 - }
120 - if (!this.current || !this.current.next) return null;
121 - this.current = this.current.next;
122 - return this.current.value;
123 - }
124 - };
125 - __publicField(_SnapshotHistory, "registry", {});
126 - var SnapshotHistory = _SnapshotHistory;
127 -
128 -//#endregion
129 -//#region packages/packages/core/editor-global-classes/src/store.ts
130 - var localHistory = SnapshotHistory.get("global-classes");
131 - var initialState = {
132 - data: {
133 - items: {},
134 - order: []
135 - },
136 - classLabels: {},
137 - initialData: {
138 - frontend: {
139 - items: {},
140 - order: []
141 - },
142 - preview: {
143 - items: {},
144 - order: []
145 - }
146 - },
147 - isDirty: false
148 - };
149 - var SLICE_NAME = "globalClasses";
150 - var slice = (0, _elementor_store.__createSlice)({
151 - name: SLICE_NAME,
152 - initialState,
153 - reducers: {
154 - load(state, { payload: { frontend, preview, classLabels } }) {
155 - state.initialData.frontend = frontend;
156 - state.initialData.preview = preview;
157 - state.data = preview;
158 - state.classLabels = classLabels;
159 - state.isDirty = false;
160 - },
161 - add(state, { payload }) {
162 - localHistory.next(state.data);
163 - state.data.items[payload.id] = payload;
164 - state.data.order.unshift(payload.id);
165 - state.classLabels[payload.id] = payload.label;
166 - state.isDirty = true;
167 - },
168 - delete(state, { payload }) {
169 - localHistory.next(state.data);
170 - state.data.items = Object.fromEntries(Object.entries(state.data.items).filter(([id]) => id !== payload));
171 - state.data.order = state.data.order.filter((id) => id !== payload);
172 - delete state.classLabels[payload];
173 - state.isDirty = true;
174 - },
175 - setOrder(state, { payload }) {
176 - localHistory.next(state.data);
177 - state.data.order = payload;
178 - state.isDirty = true;
179 - },
180 - update(state, { payload }) {
181 - const oldLabel = state.classLabels[payload.style.id];
182 - localHistory.next(state.data);
183 - const mergedData = {
184 - ...state.data.items[payload.style.id],
185 - ...payload.style
186 - };
187 - if (oldLabel && payload.style.label && payload.style.label !== oldLabel) state.classLabels[payload.style.id] = payload.style.label;
188 - state.data.items[payload.style.id] = mergedData;
189 - state.isDirty = true;
190 - },
191 - updateMultiple(state, { payload }) {
192 - localHistory.next(state.data);
193 - Object.entries(payload).forEach(([id, { modified }]) => {
194 - state.data.items[id].label = modified;
195 - state.classLabels[id] = modified;
196 - });
197 - state.isDirty = false;
198 - },
199 - updateProps(state, { payload }) {
200 - const style = state.data.items[payload.id];
201 - if (!style) throw new GlobalClassNotFoundError({ context: { styleId: payload.id } });
202 - localHistory.next(state.data);
203 - const variant = (0, _elementor_editor_styles.getVariantByMeta)(style, payload.meta);
204 - let customCss = ("custom_css" in payload ? payload.custom_css : variant?.custom_css) ?? null;
205 - customCss = customCss?.raw ? customCss : null;
206 - if (variant) {
207 - const payloadProps = JSON.parse(JSON.stringify(payload.props));
208 - if ((payload.mode ?? "merge") === "replace") variant.props = payloadProps;
209 - else {
210 - const variantProps = JSON.parse(JSON.stringify(variant.props));
211 - variant.props = mergeProps(variantProps, payloadProps);
212 - }
213 - variant.custom_css = customCss;
214 - style.variants = getNonEmptyVariants(style);
215 - } else style.variants.push({
216 - meta: payload.meta,
217 - props: payload.props,
218 - custom_css: customCss
219 - });
220 - state.isDirty = true;
221 - },
222 - reset(state, { payload: { context } }) {
223 - if (context === "frontend") {
224 - localHistory.reset();
225 - state.initialData.frontend = state.data;
226 - state.isDirty = false;
227 - }
228 - state.initialData.preview = state.data;
229 - },
230 - undo(state) {
231 - if (localHistory.isLast()) localHistory.next(state.data);
232 - const data = localHistory.prev();
233 - if (data) {
234 - state.data = data;
235 - state.isDirty = true;
236 - } else state.data = state.initialData.preview;
237 - },
238 - resetToInitialState(state, { payload: { context } }) {
239 - localHistory.reset();
240 - state.data = state.initialData[context];
241 - state.isDirty = false;
242 - },
243 - redo(state) {
244 - const data = localHistory.next();
245 - if (localHistory.isLast()) localHistory.prev();
246 - if (data) {
247 - state.data = data;
248 - state.isDirty = true;
249 - }
250 - },
251 - mergeExistingClasses(state, { payload: { preview, frontend } }) {
252 - Object.entries(preview).forEach(([id, previewClassData]) => {
253 - const frontendClassData = frontend[id];
254 - if (previewClassData === null || previewClassData === void 0) return;
255 - if (!(id in state.data.items)) state.data.items[id] = previewClassData;
256 - if (frontendClassData && !(id in state.initialData.frontend.items)) state.initialData.frontend.items[id] = frontendClassData;
257 - if (!(id in state.initialData.preview.items)) state.initialData.preview.items[id] = previewClassData;
258 - if (!(id in state.classLabels)) state.classLabels[id] = previewClassData.label;
259 - });
260 - },
261 - setOrderWithoutHistory(state, { payload }) {
262 - state.data.order = payload;
263 - },
264 - updateAfterTemplateImport(state, { payload }) {
265 - state.initialData.frontend.items = {
266 - ...state.initialData.frontend.items,
267 - ...payload.addedItems
268 - };
269 - state.initialData.frontend.order = [...state.initialData.frontend.order, ...payload.addedIdsOrder];
270 - state.initialData.preview.items = {
271 - ...state.initialData.preview.items,
272 - ...payload.addedItems
273 - };
274 - state.initialData.preview.order = [...state.initialData.preview.order, ...payload.addedIdsOrder];
275 - state.data.items = {
276 - ...state.data.items,
277 - ...payload.addedItems
278 - };
279 - state.data.order = [...state.data.order, ...payload.addedIdsOrder];
280 - state.classLabels = {
281 - ...state.classLabels,
282 - ...payload.addedClassLabels
283 - };
284 - }
285 - }
286 - });
287 - var mergeProps = (current, updates) => {
288 - const props = Array.isArray(current) ? {} : current;
289 - Object.entries(updates).forEach(([key, value]) => {
290 - if (value === null || value === void 0) delete props[key];
291 - else props[key] = value;
292 - });
293 - return props;
294 - };
295 - var getNonEmptyVariants = (style) => {
296 - return style.variants.filter(({ props, custom_css: customCss }) => Object.keys(props).length || customCss?.raw);
297 - };
298 - var placeholderDefinition = (id, label) => ({
299 - id,
300 - type: "class",
301 - label,
302 - variants: []
303 - });
304 - var selectData = (state) => state[SLICE_NAME].data;
305 - var selectClassLabels = (state) => state[SLICE_NAME].classLabels;
306 - var selectFrontendInitialData = (state) => state[SLICE_NAME].initialData.frontend;
307 - var selectPreviewInitialData = (state) => state[SLICE_NAME].initialData.preview;
308 - var selectOrder = (0, _elementor_store.__createSelector)(selectData, ({ order }) => order);
309 - var selectGlobalClasses = (0, _elementor_store.__createSelector)(selectData, ({ items }) => items);
310 - var selectIsDirty = (state) => state[SLICE_NAME].isDirty;
311 - var selectOrderedClasses = (0, _elementor_store.__createSelector)(selectData, selectClassLabels, ({ items, order }, classLabels) => order.map((id) => {
312 - const loaded = items[id];
313 - if (loaded) return loaded;
314 - const label = classLabels[id];
315 - return label !== void 0 ? placeholderDefinition(id, label) : null;
316 - }).filter((s) => s !== null));
317 - var selectClass = (state, id) => state[SLICE_NAME].data.items[id] ?? null;
318 - var selectEmptyCssClass = (0, _elementor_store.__createSelector)(selectData, ({ items }) => Object.values(items).filter((cssClass) => (cssClass.variants?.length ?? 0) === 0));
319 - var selectIsClassFetched = (state, id) => !!state[SLICE_NAME].initialData.preview.items[id] || !!state[SLICE_NAME].initialData.frontend.items[id] || false;
320 -
321 -//#endregion
322 -//#region packages/packages/core/editor-global-classes/src/hooks/use-classes-order.ts
323 - var useClassesOrder = () => {
324 - return (0, _elementor_store.__useSelector)(selectOrder);
325 - };
326 -
327 -//#endregion
328 -//#region packages/packages/core/editor-global-classes/src/hooks/use-dirty-state.ts
329 - var useDirtyState = () => {
330 - return (0, _elementor_store.__useSelector)(selectIsDirty);
331 - };
332 -
333 -//#endregion
334 -//#region packages/packages/core/editor-global-classes/src/components/search-and-filter/context.tsx
335 - var SearchAndFilterContext = (0, react.createContext)(void 0);
336 - var INIT_CHECKED_FILTERS = {
337 - empty: false,
338 - onThisPage: false,
339 - unused: false
340 - };
341 - var SearchAndFilterProvider = ({ children }) => {
342 - const [filters, setFilters] = (0, react.useState)(INIT_CHECKED_FILTERS);
343 - const getInitialSearchValue = () => {
344 - const storedValue = localStorage.getItem("elementor-global-classes-search");
345 - if (storedValue) {
346 - localStorage.removeItem("elementor-global-classes-search");
347 - return storedValue;
348 - }
349 - return "";
350 - };
351 - const { debouncedValue, inputValue, handleChange } = (0, _elementor_utils.useDebounceState)({
352 - delay: 300,
353 - initialValue: getInitialSearchValue()
354 - });
355 - const onClearSearch = () => {
356 - handleChange("");
357 - };
358 - const onClearFilter = () => {
359 - setFilters(INIT_CHECKED_FILTERS);
360 - };
361 - return /* @__PURE__ */ react.createElement(SearchAndFilterContext.Provider, { value: {
362 - search: {
363 - debouncedValue,
364 - inputValue,
365 - handleChange,
366 - onClearSearch
367 - },
368 - filters: {
369 - filters,
370 - setFilters,
371 - onClearFilter
372 - }
373 - } }, children);
374 - };
375 - var useSearchAndFilters = () => {
376 - const context = (0, react.useContext)(SearchAndFilterContext);
377 - if (!context) throw new Error("useSearchContext must be used within a SearchContextProvider");
378 - return context;
379 - };
380 -
381 -//#endregion
382 -//#region packages/packages/core/editor-global-classes/src/api.ts
383 - var RESOURCE_URL = "/global-classes";
384 - var BASE_URL = "elementor/v1";
385 - var RESOURCE_USAGE_URL = `${RESOURCE_URL}/usage`;
386 - var RESOURCE_POST_URL = `${RESOURCE_URL}/post`;
387 - var RESOURCE_STYLES_URL = `${RESOURCE_URL}/styles`;
388 - function saveGlobalClasses$1(context, payload) {
389 - return (0, _elementor_http_client.httpService)().put(`${BASE_URL}${RESOURCE_URL}`, payload, { params: { context } });
390 - }
391 - __name(saveGlobalClasses$1, "saveGlobalClasses");
392 - var apiClient = {
393 - usage: () => (0, _elementor_http_client.httpService)().get(`${BASE_URL}${RESOURCE_USAGE_URL}`),
394 - all: (context = "preview") => (0, _elementor_http_client.httpService)().get(`${BASE_URL}${RESOURCE_URL}`, { params: { context } }),
395 - getStylesForPost: (postId, context = "preview") => (0, _elementor_http_client.httpService)().get(`${BASE_URL}${RESOURCE_POST_URL}`, { params: {
396 - context,
397 - post_id: postId
398 - } }),
399 - getStylesByIds: (ids, context = "preview") => (0, _elementor_http_client.httpService)().get(`${BASE_URL}${RESOURCE_STYLES_URL}`, { params: {
400 - context,
401 - ids: ids.join(",")
402 - } }),
403 - publish: (payload) => saveGlobalClasses$1("frontend", payload),
404 - saveDraft: (payload) => saveGlobalClasses$1("preview", payload)
405 - };
406 - var API_ERROR_CODES = { DUPLICATED_LABEL: "DUPLICATED_LABEL" };
407 -
408 -//#endregion
409 -//#region packages/packages/core/editor-global-classes/src/components/css-class-usage/utils.ts
410 - var transformData = (data) => Object.entries(data).reduce((acc, [key, value]) => {
411 - acc[key] = {
412 - content: value || [],
413 - total: value.reduce((total, val) => total + (val?.total || 0), 0)
414 - };
415 - return acc;
416 - }, {});
417 -
418 -//#endregion
419 -//#region packages/packages/core/editor-global-classes/service/css-class-usage-service.ts
420 - var fetchCssClassUsage = async () => {
421 - return transformData((await apiClient.usage())?.data?.data || {});
422 - };
423 -
424 -//#endregion
425 -//#region packages/packages/core/editor-global-classes/src/components/css-class-usage/types.ts
426 - var QUERY_KEY = "css-classes-usage";
427 -
428 -//#endregion
429 -//#region packages/packages/core/editor-global-classes/src/hooks/use-css-class-usage.ts
430 - var useCssClassUsage = () => {
431 - return (0, _elementor_query.useQuery)({
432 - queryKey: [QUERY_KEY],
433 - queryFn: fetchCssClassUsage,
434 - refetchOnMount: false,
435 - refetchOnWindowFocus: true
436 - });
437 - };
438 -
439 -//#endregion
440 -//#region packages/packages/core/editor-global-classes/src/hooks/use-empty-css-class.ts
441 - var useEmptyCssClass = () => {
442 - return (0, _elementor_store.__useSelector)(selectEmptyCssClass);
443 - };
444 - var useAllCssClassesIDs = () => {
445 - const cssClasses = (0, _elementor_store.__useSelector)(selectGlobalClasses);
446 - return Object.keys(cssClasses);
447 - };
448 -
449 -//#endregion
450 -//#region packages/packages/core/editor-global-classes/src/hooks/use-filtered-css-class-usage.tsx
451 - var findCssClassKeysByPageID = (data, pageId) => {
452 - const result = [];
453 - for (const key in data) data[key].content.forEach((content) => {
454 - if (+content.pageId === pageId) result.push(key);
455 - });
456 - return result;
457 - };
458 - var getUnusedClasses = (usedCssClass, potentialUnused) => {
459 - const set = new Set(usedCssClass);
460 - return potentialUnused.filter((cssClass) => !set.has(cssClass));
461 - };
462 - var EMPTY_FILTERED_CSS_CLASS_RESPONSE = {
463 - empty: [],
464 - onThisPage: [],
465 - unused: []
466 - };
467 - var useFilteredCssClassUsage = () => {
468 - const document = (0, _elementor_editor_documents.__useActiveDocument)();
469 - const emptyCssClasses = useEmptyCssClass();
470 - const { data, isLoading } = useCssClassUsage();
471 - const listOfCssClasses = useAllCssClassesIDs();
472 - const emptyCssClassesIDs = (0, react.useMemo)(() => emptyCssClasses.map(({ id }) => id), [emptyCssClasses]);
473 - const onThisPage = (0, react.useMemo)(() => {
474 - if (!data || !document) return [];
475 - return findCssClassKeysByPageID(data, document.id);
476 - }, [data, document]);
477 - const unused = (0, react.useMemo)(() => {
478 - if (!data) return [];
479 - return getUnusedClasses(Object.keys(data), listOfCssClasses);
480 - }, [data, listOfCssClasses]);
481 - if (isLoading || !data || !document) return EMPTY_FILTERED_CSS_CLASS_RESPONSE;
482 - return {
483 - onThisPage,
484 - unused,
485 - empty: emptyCssClassesIDs
486 - };
487 - };
488 -
489 -//#endregion
490 -//#region packages/packages/core/editor-global-classes/src/hooks/use-filters.ts
491 - var useFilters = () => {
492 - const { filters: { filters } } = useSearchAndFilters();
493 - const allFilters = useFilteredCssClassUsage();
494 - return (0, react.useMemo)(() => {
495 - const activeEntries = Object.entries(filters).filter(([, isActive]) => isActive);
496 - if (activeEntries.length === 0) return null;
497 - return activeEntries.reduce((acc, [key], index) => {
498 - const current = allFilters[key] || [];
499 - if (index === 0) return current;
500 - return acc.filter((val) => current.includes(val));
501 - }, []);
502 - }, [filters, allFilters]);
503 - };
504 -
505 -//#endregion
506 -//#region packages/packages/core/editor-global-classes/src/utils/create-labels-for-classes.ts
507 - function createLabelsForClasses(entries) {
508 - return Object.fromEntries(entries.map((e) => [e.id, e.label]));
509 - }
510 -
511 -//#endregion
512 -//#region packages/packages/core/editor-global-classes/src/load-document-classes.ts
513 - function styleDefinitionsMapWithoutNull(map) {
514 - return Object.fromEntries(Object.entries(map).filter((entry) => entry[1] !== null));
515 - }
516 - function resetGlobalClassesState(globalOrder, classLabels) {
517 - (0, _elementor_store.__dispatch)(slice.actions.load({
518 - preview: {
519 - items: {},
520 - order: globalOrder
521 - },
522 - frontend: {
523 - items: {},
524 - order: globalOrder
525 - },
526 - classLabels
527 - }));
528 - }
529 - async function loadCurrentDocumentClasses() {
530 - const [previewIndexRes, frontendIndexRes] = await Promise.all([apiClient.all("preview"), apiClient.all("frontend")]);
531 - const previewIndex = previewIndexRes.data.data;
532 - const frontendIndex = frontendIndexRes.data.data;
533 - const classLabels = createLabelsForClasses(previewIndex);
534 - const previewOrder = previewIndex.map((e) => e.id);
535 - const frontendOrder = frontendIndex.map((e) => e.id);
536 - resetGlobalClassesState(previewOrder, classLabels);
537 - const postId = (0, _elementor_editor_documents.getCurrentDocument)()?.id;
538 - if (!postId) return;
539 - const [previewPostRes, frontendPostRes] = await Promise.all([apiClient.getStylesForPost(postId, "preview"), apiClient.getStylesForPost(postId, "frontend")]);
540 - const previewItems = styleDefinitionsMapWithoutNull(previewPostRes.data.data);
541 - const frontendItems = styleDefinitionsMapWithoutNull(frontendPostRes.data.data);
542 - (0, _elementor_store.__dispatch)(slice.actions.load({
543 - preview: {
544 - items: previewItems,
545 - order: previewOrder
546 - },
547 - frontend: {
548 - items: frontendItems,
549 - order: frontendOrder
550 - },
551 - classLabels
552 - }));
553 - }
554 - async function addDocumentClasses(documentId) {
555 - const [previewPostRes, frontendPostRes] = await Promise.all([apiClient.getStylesForPost(documentId, "preview"), apiClient.getStylesForPost(documentId, "frontend")]);
556 - const previewItems = styleDefinitionsMapWithoutNull(previewPostRes.data.data);
557 - const frontendItems = styleDefinitionsMapWithoutNull(frontendPostRes.data.data);
558 - (0, _elementor_store.__dispatch)(slice.actions.mergeExistingClasses({
559 - preview: previewItems,
560 - frontend: frontendItems
561 - }));
562 - }
563 -
564 -//#endregion
565 -//#region packages/packages/core/editor-global-classes/src/load-existing-classes.ts
566 - var pendingLoad = null;
567 - var pendingIds = /* @__PURE__ */ new Set();
568 - async function loadExistingClasses(classIds) {
569 - const existingClasses = selectGlobalClasses((0, _elementor_store.__getState)());
570 - const missingIds = classIds.filter((id) => !(id in existingClasses));
571 - if (missingIds.length === 0) return;
572 - missingIds.forEach((id) => pendingIds.add(id));
573 - if (pendingLoad) {
574 - await pendingLoad;
575 - return loadExistingClasses(classIds);
576 - }
577 - pendingLoad = fetchAndMergeClasses();
578 - try {
579 - await pendingLoad;
580 - } finally {
581 - pendingLoad = null;
582 - }
583 - }
584 - async function fetchAndMergeClasses() {
585 - const idsToFetch = Array.from(pendingIds);
586 - pendingIds.clear();
587 - if (idsToFetch.length === 0) return;
588 - const [previewResponse, frontendResponse] = await Promise.all([apiClient.getStylesByIds(idsToFetch, "preview"), apiClient.getStylesByIds(idsToFetch, "frontend")]);
589 - const previewItems = styleDefinitionsMapWithoutNull(previewResponse.data.data);
590 - const frontendItems = styleDefinitionsMapWithoutNull(frontendResponse.data.data);
591 - (0, _elementor_store.__dispatch)(slice.actions.mergeExistingClasses({
592 - preview: previewItems,
593 - frontend: frontendItems
594 - }));
595 - }
596 -
597 -//#endregion
598 -//#region packages/packages/core/editor-global-classes/src/components/class-manager/duplicate-label-dialog.tsx
599 - var DUP_PREFIX = "DUP_";
600 - var DuplicateLabelDialog = ({ modifiedLabels, onApprove }) => {
601 - const handleButtonClick = () => {
602 - localStorage.setItem("elementor-global-classes-search", DUP_PREFIX);
603 - onApprove?.();
604 - (0, _elementor_editor_ui.closeDialog)();
605 - };
606 - return /* @__PURE__ */ react.createElement(react.Fragment, null, /* @__PURE__ */ react.createElement(_elementor_ui.DialogHeader, { logo: false }, /* @__PURE__ */ react.createElement(_elementor_ui.Box, {
607 - display: "flex",
608 - alignItems: "center",
609 - gap: 1
610 - }, /* @__PURE__ */ react.createElement(_elementor_ui.Icon, { color: "secondary" }, /* @__PURE__ */ react.createElement(_elementor_icons.InfoCircleFilledIcon, { fontSize: "medium" })), /* @__PURE__ */ react.createElement(_elementor_ui.Typography, { variant: "subtitle1" }, (0, _wordpress_i18n.__)("We've published your page and updated class names.", "elementor")))), /* @__PURE__ */ react.createElement(_elementor_ui.DialogContent, null, /* @__PURE__ */ react.createElement(_elementor_ui.Stack, {
611 - spacing: 2,
612 - direction: "column"
613 - }, /* @__PURE__ */ react.createElement(_elementor_ui.Typography, { variant: "body2" }, (0, _wordpress_i18n.__)("Some new classes used the same names as existing ones. To prevent conflicts, we added the prefix", "elementor"), /* @__PURE__ */ react.createElement("strong", null, " ", DUP_PREFIX)), /* @__PURE__ */ react.createElement(_elementor_ui.Box, null, /* @__PURE__ */ react.createElement(_elementor_ui.Box, { sx: {
614 - width: "100%",
615 - display: "flex",
616 - gap: 2,
617 - alignItems: "flex-start"
618 - } }, /* @__PURE__ */ react.createElement(_elementor_ui.Typography, {
619 - variant: "subtitle2",
620 - sx: {
621 - fontWeight: "bold",
622 - flex: 1,
623 - flexShrink: 1,
624 - flexGrow: 1,
625 - minWidth: 0
626 - }
627 - }, (0, _wordpress_i18n.__)("Before", "elementor")), /* @__PURE__ */ react.createElement(_elementor_ui.Typography, {
628 - variant: "subtitle2",
629 - sx: {
630 - minWidth: "200px",
631 - fontWeight: "bold",
632 - flexShrink: 0,
633 - flexGrow: 0,
634 - width: "200px",
635 - maxWidth: "200px"
636 - }
637 - }, (0, _wordpress_i18n.__)("After", "elementor"))), /* @__PURE__ */ react.createElement(_elementor_ui.Divider, { sx: {
638 - mt: .5,
639 - mb: .5
640 - } }), /* @__PURE__ */ react.createElement(_elementor_ui.Stack, {
641 - direction: "column",
642 - gap: .5,
643 - sx: { pb: 2 }
644 - }, Object.values(modifiedLabels).map(({ original, modified }, index) => /* @__PURE__ */ react.createElement(_elementor_ui.Box, {
645 - key: index,
646 - sx: {
647 - width: "100%",
648 - display: "flex",
649 - gap: 2,
650 - alignItems: "flex-start"
651 - }
652 - }, /* @__PURE__ */ react.createElement(_elementor_ui.Box, { sx: {
653 - flex: 1,
654 - flexShrink: 1,
655 - flexGrow: 1,
656 - minWidth: 0
657 - } }, /* @__PURE__ */ react.createElement(_elementor_editor_ui.EllipsisWithTooltip, { title: original }, /* @__PURE__ */ react.createElement(_elementor_ui.Typography, {
658 - variant: "body2",
659 - sx: { color: "text.secondary" }
660 - }, original))), /* @__PURE__ */ react.createElement(_elementor_ui.Box, { sx: {
661 - minWidth: "200px",
662 - flexShrink: 0,
663 - flexGrow: 0,
664 - width: "200px",
665 - maxWidth: "200px"
666 - } }, /* @__PURE__ */ react.createElement(_elementor_editor_ui.EllipsisWithTooltip, { title: modified }, /* @__PURE__ */ react.createElement(_elementor_ui.Typography, {
667 - variant: "body2",
668 - sx: { color: "text.primary" }
669 - }, modified)))))), /* @__PURE__ */ react.createElement(_elementor_ui.Box, null, /* @__PURE__ */ react.createElement(_elementor_ui.Alert, {
670 - severity: "info",
671 - size: "small",
672 - color: "secondary"
673 - }, /* @__PURE__ */ react.createElement("strong", null, (0, _wordpress_i18n.__)("Your designs and classes are safe.", "elementor")), (0, _wordpress_i18n.__)("Only the prefixes were added. Find them in Class Manager by searching", "elementor"), /* @__PURE__ */ react.createElement("strong", null, DUP_PREFIX)))))), /* @__PURE__ */ react.createElement(_elementor_ui.DialogActions, null, /* @__PURE__ */ react.createElement(_elementor_ui.Button, {
674 - color: "secondary",
675 - variant: "text",
676 - onClick: handleButtonClick
677 - }, (0, _wordpress_i18n.__)("Go to Class Manager", "elementor")), /* @__PURE__ */ react.createElement(_elementor_ui.Button, {
678 - color: "secondary",
679 - variant: "contained",
680 - onClick: _elementor_editor_ui.closeDialog
681 - }, (0, _wordpress_i18n.__)("Done", "elementor"))));
682 - };
683 -
684 -//#endregion
685 -//#region packages/packages/core/editor-global-classes/src/utils/tracking.ts
686 - var trackGlobalClasses = async (payload) => {
687 - const { runAction } = payload;
688 - const data = await getSanitizedData(payload);
689 - if (data) {
690 - track(data);
691 - if (data.event === "classCreated" && "classId" in data) fireClassApplied(data.classId);
692 - }
693 - runAction?.();
694 - };
695 - var fireClassApplied = async (classId) => {
696 - const appliedInfo = await getAppliedInfo(classId);
697 - track({
698 - event: "classApplied",
699 - classId,
700 - ...appliedInfo,
701 - totalInstancesAfterApply: 1
702 - });
703 - };
704 - var getSanitizedData = async (payload) => {
705 - switch (payload.event) {
706 - case "classApplied":
707 - if ("classId" in payload && payload.classId) {
708 - const appliedInfo = await getAppliedInfo(payload.classId);
709 - return {
710 - ...payload,
711 - ...appliedInfo
712 - };
713 - }
714 - break;
715 - case "classRemoved":
716 - if ("classId" in payload && payload.classId) {
717 - const deleteInfo = getRemovedInfo(payload.classId);
718 - return {
719 - ...payload,
720 - ...deleteInfo
721 - };
722 - }
723 - break;
724 - case "classDeleted":
725 - if ("classId" in payload && payload.classId) {
726 - const deleteInfo = await trackDeleteClass(payload.classId);
727 - return {
728 - ...payload,
729 - ...deleteInfo
730 - };
731 - }
732 - break;
733 - case "classCreated":
734 - if ("source" in payload && payload.source !== "created") {
735 - if ("classId" in payload && payload.classId) return {
736 - ...payload,
737 - classTitle: getCssClass(payload.classId).label
738 - };
739 - }
740 - return payload;
741 - case "classStateClicked":
742 - if ("classId" in payload && payload.classId) return {
743 - ...payload,
744 - classTitle: getCssClass(payload.classId).label
745 - };
746 - break;
747 - case "classSyncToV3PopupShown": return {
748 - ...payload,
749 - interaction_type: "popup_shown",
750 - target_type: "popup",
751 - target_name: "sync_to_v3_popup",
752 - interaction_result: "popup_viewed",
753 - target_location: "widget_panel",
754 - location_l1: "class_manager"
755 - };
756 - case "classSyncToV3": {
757 - const classLabel = getCssClass(payload.classId).label;
758 - const isSync = payload.action === "sync";
759 - return {
760 - ...payload,
761 - interaction_type: "click",
762 - target_type: classLabel,
763 - target_name: isSync ? "sync_to_v3" : "unsync_to_v3",
764 - interaction_result: isSync ? "class_is_synced_to_V3" : "class_is_unsynced_from_V3",
765 - target_location: "widget_panel",
766 - location_l1: "class_manager",
767 - interaction_description: isSync ? `user_synced_${classLabel}_to_v3` : `user_unsync_${classLabel}_from_v3`
768 - };
769 - }
770 - case "classSyncToV3PopupClick": {
771 - const isSyncAction = payload.action === "sync";
772 - return {
773 - ...payload,
774 - interaction_type: "click",
775 - target_type: "button",
776 - target_name: isSyncAction ? "sync_to_v3" : "cancel",
777 - interaction_result: isSyncAction ? "class_is_synced" : "cancel",
778 - target_location: "sync_to_v3_popup"
779 - };
780 - }
781 - default: return payload;
782 - }
783 - };
784 - var track = (data) => {
785 - const { dispatchEvent, config } = (0, _elementor_events.getMixpanel)();
786 - if (!config?.names?.global_classes?.[data.event]) {
787 - console.error("Global class tracking event not found", { event: data.event });
788 - return;
789 - }
790 - const name = config.names.global_classes[data.event];
791 - const { event, ...eventData } = data;
792 - try {
793 - dispatchEvent?.(name, {
794 - event,
795 - ...eventData
796 - });
797 - } catch (error) {
798 - throw new GlobalClassTrackingError({ cause: error });
799 - }
800 - };
801 - var extractCssClassData = (classId) => {
802 - return { classTitle: getCssClass(classId).label };
803 - };
804 - var getCssClass = (classId) => {
805 - const state = (0, _elementor_store.__getState)();
806 - const cssClass = selectClass(state, classId);
807 - if (cssClass) return cssClass;
808 - const label = selectClassLabels(state)[classId];
809 - if (label !== void 0) return placeholderDefinition(classId, label);
810 - throw new Error(`CSS class with ID ${classId} not found`);
811 - };
812 - var trackDeleteClass = async (classId) => {
813 - const classTitle = getCssClass(classId).label;
814 - return {
815 - totalInstances: await getTotalInstancesByCssClassID(classId),
816 - classTitle
817 - };
818 - };
819 - var getTotalInstancesByCssClassID = async (classId) => {
820 - return (await fetchCssClassUsage())[classId]?.total ?? 1;
821 - };
822 - var getAppliedInfo = async (classId) => {
823 - const { classTitle } = extractCssClassData(classId);
824 - return {
825 - classTitle,
826 - totalInstancesAfterApply: await getTotalInstancesByCssClassID(classId) + 1
827 - };
828 - };
829 - var getRemovedInfo = (classId) => {
830 - const { classTitle } = extractCssClassData(classId);
831 - return { classTitle };
832 - };
833 -
834 -//#endregion
835 -//#region packages/packages/core/editor-global-classes/src/save-global-classes.tsx
836 - async function saveGlobalClasses({ context, onApprove }) {
837 - const state = selectData((0, _elementor_store.__getState)());
838 - const apiAction = context === "preview" ? apiClient.saveDraft : apiClient.publish;
839 - const changes = calculateChanges(state, (context === "preview" ? selectPreviewInitialData : selectFrontendInitialData)((0, _elementor_store.__getState)()));
840 - const touchedIds = [...changes.added, ...changes.modified];
841 - const response = await apiAction({
842 - items: Object.fromEntries(touchedIds.map((id) => [id, state.items[id]]).filter(([, v]) => v)),
843 - order: state.order,
844 - changes
845 - });
846 - (0, _elementor_store.__dispatch)(slice.actions.reset({ context }));
847 - window.dispatchEvent(new CustomEvent("classes:updated", { detail: { context } }));
848 - if (response?.data?.data?.code === API_ERROR_CODES.DUPLICATED_LABEL) {
849 - (0, _elementor_store.__dispatch)(slice.actions.updateMultiple(response.data.data.modifiedLabels));
850 - trackGlobalClasses({
851 - event: "classPublishConflict",
852 - numOfConflicts: Object.keys(response.data.data.modifiedLabels).length
853 - });
854 - (0, _elementor_editor_ui.openDialog)({ component: /* @__PURE__ */ react.createElement(DuplicateLabelDialog, {
855 - modifiedLabels: response.data.data.modifiedLabels || [],
856 - onApprove
857 - }) });
858 - }
859 - }
860 - function calculateChanges(state, initialData) {
861 - const stateIds = Object.keys(state.items);
862 - const initialDataIds = Object.keys(initialData.items);
863 - const { order: stateOrder } = state;
864 - const { order: initialDataOrder } = initialData;
865 - const stateOrderIdSet = new Set(stateOrder);
866 - const deleted = initialDataOrder.filter((id) => !stateOrderIdSet.has(id));
867 - const order = stateOrder.join(";") !== initialDataOrder.join(";");
868 - return {
869 - added: stateIds.filter((id) => !initialDataIds.includes(id)),
870 - deleted,
871 - modified: stateIds.filter((id) => {
872 - return id in initialData.items && (0, _elementor_utils.hash)(state.items[id]) !== (0, _elementor_utils.hash)(initialData.items[id]);
873 - }),
874 - order
875 - };
876 - }
877 -
878 -//#endregion
879 -//#region packages/packages/core/editor-global-classes/src/components/search-and-filter/components/filter/clear-icon-button.tsx
880 - var ClearIconButton = ({ tooltipText, sx, trigger }) => {
881 - const { filters: { onClearFilter } } = useSearchAndFilters();
882 - const handleClearFilters = () => {
883 - onClearFilter(trigger);
884 - trackGlobalClasses({
885 - event: "classManagerFilterCleared",
886 - trigger
887 - });
888 - };
889 - return /* @__PURE__ */ react.createElement(_elementor_ui.Tooltip, {
890 - title: tooltipText,
891 - placement: "top",
892 - disableInteractive: true
893 - }, /* @__PURE__ */ react.createElement(_elementor_ui.Box, null, /* @__PURE__ */ react.createElement(CustomIconButton$1, {
894 - "aria-label": tooltipText,
895 - size: "tiny",
896 - onClick: handleClearFilters,
897 - sx
898 - }, /* @__PURE__ */ react.createElement(_elementor_icons.BrushBigIcon, { fontSize: "tiny" }))));
899 - };
900 - var CustomIconButton$1 = (0, _elementor_ui.styled)(_elementor_ui.IconButton)(({ theme }) => ({ "&.Mui-disabled": {
901 - pointerEvents: "auto",
902 - "&:hover": { color: theme.palette.action.disabled }
903 - } }));
904 -
905 -//#endregion
906 -//#region packages/packages/core/editor-global-classes/src/components/search-and-filter/components/filter/filter-list.tsx
907 - var filterConfig = {
908 - unused: (0, _wordpress_i18n.__)("Unused", "elementor"),
909 - empty: (0, _wordpress_i18n.__)("Empty", "elementor"),
910 - onThisPage: (0, _wordpress_i18n.__)("On this page", "elementor")
911 - };
912 - var FilterList = () => {
913 - const { filters: { filters, setFilters } } = useSearchAndFilters();
914 - const filteredCssClass = useFilteredCssClassUsage();
915 - const handleOnClick = (value) => {
916 - setFilters((prev) => ({
917 - ...prev,
918 - [value]: !prev[value]
919 - }));
920 - trackGlobalClasses({
921 - event: "classManagerFilterUsed",
922 - action: filters[value] ? "remove" : "apply",
923 - type: value,
924 - trigger: "menu"
925 - });
926 - };
927 - return /* @__PURE__ */ react.createElement(_elementor_ui.MenuList, null, /* @__PURE__ */ react.createElement(_elementor_ui.MenuItem, { onClick: () => handleOnClick("unused") }, /* @__PURE__ */ react.createElement(LabeledCheckbox, {
928 - label: filterConfig.unused,
929 - checked: filters.unused,
930 - suffix: /* @__PURE__ */ react.createElement(_elementor_ui.Chip, {
931 - size: "tiny",
932 - sx: { ml: "auto" },
933 - label: filteredCssClass.unused.length
934 - })
935 - })), /* @__PURE__ */ react.createElement(_elementor_ui.MenuItem, { onClick: () => handleOnClick("empty") }, /* @__PURE__ */ react.createElement(LabeledCheckbox, {
936 - label: filterConfig.empty,
937 - checked: filters.empty,
938 - suffix: /* @__PURE__ */ react.createElement(_elementor_ui.Chip, {
939 - size: "tiny",
940 - sx: { ml: "auto" },
941 - label: filteredCssClass.empty.length
942 - })
943 - })), /* @__PURE__ */ react.createElement(_elementor_ui.MenuItem, { onClick: () => handleOnClick("onThisPage") }, /* @__PURE__ */ react.createElement(LabeledCheckbox, {
944 - label: filterConfig.onThisPage,
945 - checked: filters.onThisPage,
946 - suffix: /* @__PURE__ */ react.createElement(_elementor_ui.Chip, {
947 - size: "tiny",
948 - sx: { ml: "auto" },
949 - label: filteredCssClass.onThisPage.length
950 - })
951 - })));
952 - };
953 - var LabeledCheckbox = ({ label, suffix, checked }) => /* @__PURE__ */ react.createElement(_elementor_ui.Stack, {
954 - direction: "row",
955 - alignItems: "center",
956 - gap: .5,
957 - flex: 1
958 - }, /* @__PURE__ */ react.createElement(_elementor_ui.Checkbox, {
959 - size: "small",
960 - checked,
961 - sx: {
962 - padding: 0,
963 - color: "text.tertiary",
964 - "&.Mui-checked": { color: "text.tertiary" }
965 - }
966 - }), /* @__PURE__ */ react.createElement(_elementor_ui.Typography, {
967 - variant: "caption",
968 - sx: { color: "text.secondary" }
969 - }, label), suffix);
970 -
971 -//#endregion
972 -//#region packages/packages/core/editor-global-classes/src/components/search-and-filter/components/filter/active-filters.tsx
973 - var ActiveFilters = () => {
974 - const { filters: { filters, setFilters } } = useSearchAndFilters();
975 - const handleRemove = (key) => {
976 - setFilters((prev) => ({
977 - ...prev,
978 - [key]: false
979 - }));
980 - trackGlobalClasses({
981 - event: "classManagerFilterUsed",
982 - action: "remove",
983 - type: key,
984 - trigger: "header"
985 - });
986 - };
987 - const activeKeys = Object.keys(filters).filter((key) => filters[key]);
988 - const showClearIcon = activeKeys.length > 0;
989 - return /* @__PURE__ */ react.createElement(_elementor_ui.Stack, {
990 - direction: "row",
991 - alignItems: "center",
992 - justifyContent: "space-between"
993 - }, /* @__PURE__ */ react.createElement(_elementor_ui.Stack, {
994 - direction: "row",
995 - gap: .5,
996 - alignItems: "center",
997 - flexWrap: "wrap"
998 - }, activeKeys.map((key) => /* @__PURE__ */ react.createElement(_elementor_ui.Chip, {
999 - key,
1000 - label: filterConfig[key],
1001 - onDelete: () => handleRemove(key),
1002 - sx: chipSx,
1003 - size: "tiny"
1004 - }))), showClearIcon && /* @__PURE__ */ react.createElement(ClearIconButton, {
1005 - trigger: "header",
1006 - tooltipText: (0, _wordpress_i18n.__)("Clear Filters", "elementor"),
1007 - sx: { margin: "0 0 auto auto" }
1008 - }));
1009 - };
1010 - var chipSx = {
1011 - "& .MuiChip-deleteIcon": {
1012 - display: "none",
1013 - transition: "opacity 0.2s"
1014 - },
1015 - "&:hover .MuiChip-deleteIcon": { display: "block" }
1016 - };
1017 -
1018 -//#endregion
1019 -//#region packages/packages/core/editor-global-classes/src/components/search-and-filter/components/filter/css-class-filter.tsx
1020 - var CssClassFilter = () => {
1021 - const { filters: { filters } } = useSearchAndFilters();
1022 - const popupState = (0, _elementor_ui.usePopupState)({
1023 - variant: "popover",
1024 - disableAutoFocus: true
1025 - });
1026 - (0, react.useEffect)(() => {
1027 - if (popupState.isOpen) trackGlobalClasses({ event: "classManagerFiltersOpened" });
1028 - }, [popupState.isOpen]);
1029 - const showCleanIcon = Object.values(filters).some((value) => value);
1030 - return /* @__PURE__ */ react.createElement(react.Fragment, null, /* @__PURE__ */ react.createElement(_elementor_ui.Tooltip, {
1031 - title: (0, _wordpress_i18n.__)("Filters", "elementor"),
1032 - placement: "top"
1033 - }, /* @__PURE__ */ react.createElement(_elementor_ui.ToggleButton, {
1034 - value: "filter",
1035 - size: "tiny",
1036 - selected: popupState.isOpen,
1037 - ...(0, _elementor_ui.bindToggle)(popupState)
1038 - }, /* @__PURE__ */ react.createElement(_elementor_icons.FilterIcon, { fontSize: "tiny" }))), /* @__PURE__ */ react.createElement(_elementor_ui.Popover, {
1039 - sx: { maxWidth: "344px" },
1040 - anchorOrigin: {
1041 - vertical: "top",
1042 - horizontal: "right"
1043 - },
1044 - transformOrigin: {
1045 - vertical: "top",
1046 - horizontal: -21
1047 - },
1048 - ...(0, _elementor_ui.bindPopover)(popupState)
1049 - }, /* @__PURE__ */ react.createElement(_elementor_editor_ui.PopoverHeader, {
1050 - actions: showCleanIcon ? [/* @__PURE__ */ react.createElement(ClearIconButton, {
1051 - trigger: "menu",
1052 - key: "clear-all-button",
1053 - tooltipText: (0, _wordpress_i18n.__)("Clear all", "elementor")
1054 - })] : [],
1055 - onClose: popupState.close,
1056 - title: (0, _wordpress_i18n.__)("Filters", "elementor"),
1057 - icon: /* @__PURE__ */ react.createElement(_elementor_icons.FilterIcon, { fontSize: "tiny" })
1058 - }), /* @__PURE__ */ react.createElement(_elementor_ui.Divider, { sx: { borderWidth: "1px 0 0 0" } }), /* @__PURE__ */ react.createElement(_elementor_editor_ui.PopoverBody, {
1059 - width: 344,
1060 - height: 125
1061 - }, /* @__PURE__ */ react.createElement(FilterList, null))));
1062 - };
1063 -
1064 -//#endregion
1065 -//#region packages/packages/core/editor-global-classes/src/components/search-and-filter/components/search/class-manager-search.tsx
1066 - var ClassManagerSearch = () => {
1067 - const { search: { inputValue, handleChange } } = useSearchAndFilters();
1068 - return /* @__PURE__ */ react.createElement(_elementor_ui.Stack, {
1069 - direction: "row",
1070 - gap: .5,
1071 - sx: { width: "100%" }
1072 - }, /* @__PURE__ */ react.createElement(_elementor_ui.Box, { sx: { flexGrow: 1 } }, /* @__PURE__ */ react.createElement(_elementor_ui.TextField, {
1073 - role: "search",
1074 - fullWidth: true,
1075 - size: "tiny",
1076 - value: inputValue,
1077 - onFocus: () => {
1078 - trackGlobalClasses({ event: "classManagerSearched" });
1079 - },
1080 - placeholder: (0, _wordpress_i18n.__)("Search", "elementor"),
1081 - onChange: (e) => handleChange(e.target.value),
1082 - InputProps: { startAdornment: /* @__PURE__ */ react.createElement(_elementor_ui.InputAdornment, { position: "start" }, /* @__PURE__ */ react.createElement(_elementor_icons.SearchIcon, { fontSize: "tiny" })) }
1083 - })));
1084 - };
1085 -
1086 -//#endregion
1087 -//#region packages/packages/core/editor-global-classes/src/components/class-manager/class-manager-introduction.tsx
1088 - var MESSAGE_KEY = "global-class-manager";
1089 - var ClassManagerIntroduction = () => {
1090 - const [isMessageSuppressed, suppressMessage] = (0, _elementor_editor_current_user.useSuppressedMessage)(MESSAGE_KEY);
1091 - const [shouldShowIntroduction, setShouldShowIntroduction] = (0, react.useState)(!isMessageSuppressed);
1092 - return /* @__PURE__ */ react.createElement(_elementor_editor_ui.IntroductionModal, {
1093 - open: shouldShowIntroduction,
1094 - title: (0, _wordpress_i18n.__)("Class Manager", "elementor"),
1095 - handleClose: (shouldShowAgain) => {
1096 - if (!shouldShowAgain) suppressMessage();
1097 - setShouldShowIntroduction(false);
1098 - }
1099 - }, /* @__PURE__ */ react.createElement(_elementor_ui.Image, {
1100 - sx: {
1101 - width: "100%",
1102 - aspectRatio: "16 / 9"
1103 - },
1104 - src: "https://assets.elementor.com/packages/v1/images/class-manager-intro.svg",
1105 - alt: ""
1106 - }), /* @__PURE__ */ react.createElement(IntroductionContent, null));
1107 - };
1108 - var IntroductionContent = () => {
1109 - return /* @__PURE__ */ react.createElement(_elementor_ui.Box, { p: 3 }, /* @__PURE__ */ react.createElement(_elementor_ui.Typography, { variant: "body2" }, (0, _wordpress_i18n.__)("The Class Manager lets you see all the classes you've created, plus adjust their priority, rename them, and delete unused classes to keep your CSS structured.", "elementor")), /* @__PURE__ */ react.createElement("br", null), /* @__PURE__ */ react.createElement(_elementor_ui.Typography, { variant: "body2" }, (0, _wordpress_i18n.__)("Remember, when editing an item within a specific class, any changes you make will apply across all elements in that class.", "elementor")));
1110 - };
1111 -
1112 -//#endregion
1113 -//#region packages/packages/core/editor-global-classes/src/components/class-manager/delete-class.ts
1114 - var isDeleted = false;
1115 - var deleteClass = (id) => {
1116 - trackGlobalClasses({
1117 - event: "classDeleted",
1118 - classId: id,
1119 - runAction: () => {
1120 - (0, _elementor_store.__dispatch)(slice.actions.delete(id));
1121 - isDeleted = true;
1122 - }
1123 - });
1124 - };
1125 - var onDelete = async () => {
1126 - isDeleted = false;
1127 - };
1128 - var hasDeletedItems = () => isDeleted;
1129 -
1130 -//#endregion
1131 -//#region packages/packages/core/editor-global-classes/src/components/class-manager/flipped-color-swatch-icon.tsx
1132 - var FlippedColorSwatchIcon = ({ sx, ...props }) => /* @__PURE__ */ react.createElement(_elementor_icons.ColorSwatchIcon, {
1133 - sx: {
1134 - transform: "rotate(90deg)",
1135 - ...sx
1136 - },
1137 - ...props
1138 - });
1139 -
1140 -//#endregion
1141 -//#region packages/node_modules/@tanstack/virtual-core/dist/esm/utils.js
1142 - function memo(getDeps, fn, opts) {
1143 - let deps = opts.initialDeps ?? [];
1144 - let result;
1145 - let isInitial = true;
1146 - function memoizedFunction() {
1147 - var _a;
1148 - var _b;
1149 - var _c;
1150 - let depTime;
1151 - if (opts.key && ((_a = opts.debug) == null ? void 0 : _a.call(opts))) depTime = Date.now();
1152 - const newDeps = getDeps();
1153 - if (!(newDeps.length !== deps.length || newDeps.some((dep, index) => deps[index] !== dep))) return result;
1154 - deps = newDeps;
1155 - let resultTime;
1156 - if (opts.key && ((_b = opts.debug) == null ? void 0 : _b.call(opts))) resultTime = Date.now();
1157 - result = fn(...newDeps);
1158 - if (opts.key && ((_c = opts.debug) == null ? void 0 : _c.call(opts))) {
1159 - const depEndTime = Math.round((Date.now() - depTime) * 100) / 100;
1160 - const resultEndTime = Math.round((Date.now() - resultTime) * 100) / 100;
1161 - const resultFpsPercentage = resultEndTime / 16;
1162 - const pad = (str, num) => {
1163 - str = String(str);
1164 - while (str.length < num) str = " " + str;
1165 - return str;
1166 - };
1167 - console.info(`%c⏱ ${pad(resultEndTime, 5)} /${pad(depEndTime, 5)} ms`, `
1168 - font-size: .6rem;
1169 - font-weight: bold;
1170 - color: hsl(${Math.max(0, Math.min(120 - 120 * resultFpsPercentage, 120))}deg 100% 31%);`, opts == null ? void 0 : opts.key);
1171 - }
1172 - if ((opts == null ? void 0 : opts.onChange) && !(isInitial && opts.skipInitialOnChange)) opts.onChange(result);
1173 - isInitial = false;
1174 - return result;
1175 - }
1176 - memoizedFunction.updateDeps = (newDeps) => {
1177 - deps = newDeps;
1178 - };
1179 - return memoizedFunction;
1180 - }
1181 - function notUndefined(value, msg) {
1182 - if (value === void 0) throw new Error(`Unexpected undefined${msg ? `: ${msg}` : ""}`);
1183 - else return value;
1184 - }
1185 - var approxEqual = (a, b) => Math.abs(a - b) < 1.01;
1186 - var debounce = (targetWindow, fn, ms) => {
1187 - let timeoutId;
1188 - return function(...args) {
1189 - targetWindow.clearTimeout(timeoutId);
1190 - timeoutId = targetWindow.setTimeout(() => fn.apply(this, args), ms);
1191 - };
1192 - };
1193 -
1194 -//#endregion
1195 -//#region packages/node_modules/@tanstack/virtual-core/dist/esm/index.js
1196 - var getRect = (element) => {
1197 - const { offsetWidth, offsetHeight } = element;
1198 - return {
1199 - width: offsetWidth,
1200 - height: offsetHeight
1201 - };
1202 - };
1203 - var defaultKeyExtractor = (index) => index;
1204 - var defaultRangeExtractor = (range) => {
1205 - const start = Math.max(range.startIndex - range.overscan, 0);
1206 - const end = Math.min(range.endIndex + range.overscan, range.count - 1);
1207 - const arr = [];
1208 - for (let i = start; i <= end; i++) arr.push(i);
1209 - return arr;
1210 - };
1211 - var observeElementRect = (instance, cb) => {
1212 - const element = instance.scrollElement;
1213 - if (!element) return;
1214 - const targetWindow = instance.targetWindow;
1215 - if (!targetWindow) return;
1216 - const handler = (rect) => {
1217 - const { width, height } = rect;
1218 - cb({
1219 - width: Math.round(width),
1220 - height: Math.round(height)
1221 - });
1222 - };
1223 - handler(getRect(element));
1224 - if (!targetWindow.ResizeObserver) return () => {};
1225 - const observer = new targetWindow.ResizeObserver((entries) => {
1226 - const run = () => {
1227 - const entry = entries[0];
1228 - if (entry == null ? void 0 : entry.borderBoxSize) {
1229 - const box = entry.borderBoxSize[0];
1230 - if (box) {
1231 - handler({
1232 - width: box.inlineSize,
1233 - height: box.blockSize
1234 - });
1235 - return;
1236 - }
1237 - }
1238 - handler(getRect(element));
1239 - };
1240 - instance.options.useAnimationFrameWithResizeObserver ? requestAnimationFrame(run) : run();
1241 - });
1242 - observer.observe(element, { box: "border-box" });
1243 - return () => {
1244 - observer.unobserve(element);
1245 - };
1246 - };
1247 - var addEventListenerOptions = { passive: true };
1248 - var supportsScrollend = typeof window == "undefined" ? true : "onscrollend" in window;
1249 - var observeElementOffset = (instance, cb) => {
1250 - const element = instance.scrollElement;
1251 - if (!element) return;
1252 - const targetWindow = instance.targetWindow;
1253 - if (!targetWindow) return;
1254 - let offset = 0;
1255 - const fallback = instance.options.useScrollendEvent && supportsScrollend ? () => void 0 : debounce(targetWindow, () => {
1256 - cb(offset, false);
1257 - }, instance.options.isScrollingResetDelay);
1258 - const createHandler = (isScrolling) => () => {
1259 - const { horizontal, isRtl } = instance.options;
1260 - offset = horizontal ? element["scrollLeft"] * (isRtl && -1 || 1) : element["scrollTop"];
1261 - fallback();
1262 - cb(offset, isScrolling);
1263 - };
1264 - const handler = createHandler(true);
1265 - const endHandler = createHandler(false);
1266 - element.addEventListener("scroll", handler, addEventListenerOptions);
1267 - const registerScrollendEvent = instance.options.useScrollendEvent && supportsScrollend;
1268 - if (registerScrollendEvent) element.addEventListener("scrollend", endHandler, addEventListenerOptions);
1269 - return () => {
1270 - element.removeEventListener("scroll", handler);
1271 - if (registerScrollendEvent) element.removeEventListener("scrollend", endHandler);
1272 - };
1273 - };
1274 - var measureElement = (element, entry, instance) => {
1275 - if (entry == null ? void 0 : entry.borderBoxSize) {
1276 - const box = entry.borderBoxSize[0];
1277 - if (box) return Math.round(box[instance.options.horizontal ? "inlineSize" : "blockSize"]);
1278 - }
1279 - return element[instance.options.horizontal ? "offsetWidth" : "offsetHeight"];
1280 - };
1281 - var elementScroll = (offset, { adjustments = 0, behavior }, instance) => {
1282 - var _a;
1283 - var _b;
1284 - const toOffset = offset + adjustments;
1285 - (_b = (_a = instance.scrollElement) == null ? void 0 : _a.scrollTo) == null || _b.call(_a, {
1286 - [instance.options.horizontal ? "left" : "top"]: toOffset,
1287 - behavior
1288 - });
1289 - };
1290 - var Virtualizer = class {
1291 - constructor(opts) {
1292 - this.unsubs = [];
1293 - this.scrollElement = null;
1294 - this.targetWindow = null;
1295 - this.isScrolling = false;
1296 - this.scrollState = null;
1297 - this.measurementsCache = [];
1298 - this.itemSizeCache = /* @__PURE__ */ new Map();
1299 - this.laneAssignments = /* @__PURE__ */ new Map();
1300 - this.pendingMeasuredCacheIndexes = [];
1301 - this.prevLanes = void 0;
1302 - this.lanesChangedFlag = false;
1303 - this.lanesSettling = false;
1304 - this.scrollRect = null;
1305 - this.scrollOffset = null;
1306 - this.scrollDirection = null;
1307 - this.scrollAdjustments = 0;
1308 - this.elementsCache = /* @__PURE__ */ new Map();
1309 - this.now = () => {
1310 - var _a;
1311 - var _b;
1312 - var _c;
1313 - return ((_c = (_b = (_a = this.targetWindow) == null ? void 0 : _a.performance) == null ? void 0 : _b.now) == null ? void 0 : _c.call(_b)) ?? Date.now();
1314 - };
1315 - this.observer = /* @__PURE__ */ (() => {
1316 - let _ro = null;
1317 - const get = () => {
1318 - if (_ro) return _ro;
1319 - if (!this.targetWindow || !this.targetWindow.ResizeObserver) return null;
1320 - return _ro = new this.targetWindow.ResizeObserver((entries) => {
1321 - entries.forEach((entry) => {
1322 - const run = () => {
1323 - const node = entry.target;
1324 - const index = this.indexFromElement(node);
1325 - if (!node.isConnected) {
1326 - this.observer.unobserve(node);
1327 - return;
1328 - }
1329 - if (this.shouldMeasureDuringScroll(index)) this.resizeItem(index, this.options.measureElement(node, entry, this));
1330 - };
1331 - this.options.useAnimationFrameWithResizeObserver ? requestAnimationFrame(run) : run();
1332 - });
1333 - });
1334 - };
1335 - return {
1336 - disconnect: () => {
1337 - var _a;
1338 - (_a = get()) == null || _a.disconnect();
1339 - _ro = null;
1340 - },
1341 - observe: (target) => {
1342 - var _a;
1343 - return (_a = get()) == null ? void 0 : _a.observe(target, { box: "border-box" });
1344 - },
1345 - unobserve: (target) => {
1346 - var _a;
1347 - return (_a = get()) == null ? void 0 : _a.unobserve(target);
1348 - }
1349 - };
1350 - })();
1351 - this.range = null;
1352 - this.setOptions = (opts2) => {
1353 - Object.entries(opts2).forEach(([key, value]) => {
1354 - if (typeof value === "undefined") delete opts2[key];
1355 - });
1356 - this.options = {
1357 - debug: false,
1358 - initialOffset: 0,
1359 - overscan: 1,
1360 - paddingStart: 0,
1361 - paddingEnd: 0,
1362 - scrollPaddingStart: 0,
1363 - scrollPaddingEnd: 0,
1364 - horizontal: false,
1365 - getItemKey: defaultKeyExtractor,
1366 - rangeExtractor: defaultRangeExtractor,
1367 - onChange: () => {},
1368 - measureElement,
1369 - initialRect: {
1370 - width: 0,
1371 - height: 0
1372 - },
1373 - scrollMargin: 0,
1374 - gap: 0,
1375 - indexAttribute: "data-index",
1376 - initialMeasurementsCache: [],
1377 - lanes: 1,
1378 - isScrollingResetDelay: 150,
1379 - enabled: true,
1380 - isRtl: false,
1381 - useScrollendEvent: false,
1382 - useAnimationFrameWithResizeObserver: false,
1383 - laneAssignmentMode: "estimate",
1384 - ...opts2
1385 - };
1386 - };
1387 - this.notify = (sync) => {
1388 - var _a;
1389 - var _b;
1390 - (_b = (_a = this.options).onChange) == null || _b.call(_a, this, sync);
1391 - };
1392 - this.maybeNotify = memo(() => {
1393 - this.calculateRange();
1394 - return [
1395 - this.isScrolling,
1396 - this.range ? this.range.startIndex : null,
1397 - this.range ? this.range.endIndex : null
1398 - ];
1399 - }, (isScrolling) => {
1400 - this.notify(isScrolling);
1401 - }, {
1402 - key: "maybeNotify",
1403 - debug: () => this.options.debug,
1404 - initialDeps: [
1405 - this.isScrolling,
1406 - this.range ? this.range.startIndex : null,
1407 - this.range ? this.range.endIndex : null
1408 - ]
1409 - });
1410 - this.cleanup = () => {
1411 - this.unsubs.filter(Boolean).forEach((d) => d());
1412 - this.unsubs = [];
1413 - this.observer.disconnect();
1414 - if (this.rafId != null && this.targetWindow) {
1415 - this.targetWindow.cancelAnimationFrame(this.rafId);
1416 - this.rafId = null;
1417 - }
1418 - this.scrollState = null;
1419 - this.scrollElement = null;
1420 - this.targetWindow = null;
1421 - };
1422 - this._didMount = () => {
1423 - return () => {
1424 - this.cleanup();
1425 - };
1426 - };
1427 - this._willUpdate = () => {
1428 - var _a;
1429 - const scrollElement = this.options.enabled ? this.options.getScrollElement() : null;
1430 - if (this.scrollElement !== scrollElement) {
1431 - this.cleanup();
1432 - if (!scrollElement) {
1433 - this.maybeNotify();
1434 - return;
1435 - }
1436 - this.scrollElement = scrollElement;
1437 - if (this.scrollElement && "ownerDocument" in this.scrollElement) this.targetWindow = this.scrollElement.ownerDocument.defaultView;
1438 - else this.targetWindow = ((_a = this.scrollElement) == null ? void 0 : _a.window) ?? null;
1439 - this.elementsCache.forEach((cached) => {
1440 - this.observer.observe(cached);
1441 - });
1442 - this.unsubs.push(this.options.observeElementRect(this, (rect) => {
1443 - this.scrollRect = rect;
1444 - this.maybeNotify();
1445 - }));
1446 - this.unsubs.push(this.options.observeElementOffset(this, (offset, isScrolling) => {
1447 - this.scrollAdjustments = 0;
1448 - this.scrollDirection = isScrolling ? this.getScrollOffset() < offset ? "forward" : "backward" : null;
1449 - this.scrollOffset = offset;
1450 - this.isScrolling = isScrolling;
1451 - if (this.scrollState) this.scheduleScrollReconcile();
1452 - this.maybeNotify();
1453 - }));
1454 - this._scrollToOffset(this.getScrollOffset(), {
1455 - adjustments: void 0,
1456 - behavior: void 0
1457 - });
1458 - }
1459 - };
1460 - this.rafId = null;
1461 - this.getSize = () => {
1462 - if (!this.options.enabled) {
1463 - this.scrollRect = null;
1464 - return 0;
1465 - }
1466 - this.scrollRect = this.scrollRect ?? this.options.initialRect;
1467 - return this.scrollRect[this.options.horizontal ? "width" : "height"];
1468 - };
1469 - this.getScrollOffset = () => {
1470 - if (!this.options.enabled) {
1471 - this.scrollOffset = null;
1472 - return 0;
1473 - }
1474 - this.scrollOffset = this.scrollOffset ?? (typeof this.options.initialOffset === "function" ? this.options.initialOffset() : this.options.initialOffset);
1475 - return this.scrollOffset;
1476 - };
1477 - this.getFurthestMeasurement = (measurements, index) => {
1478 - const furthestMeasurementsFound = /* @__PURE__ */ new Map();
1479 - const furthestMeasurements = /* @__PURE__ */ new Map();
1480 - for (let m = index - 1; m >= 0; m--) {
1481 - const measurement = measurements[m];
1482 - if (furthestMeasurementsFound.has(measurement.lane)) continue;
1483 - const previousFurthestMeasurement = furthestMeasurements.get(measurement.lane);
1484 - if (previousFurthestMeasurement == null || measurement.end > previousFurthestMeasurement.end) furthestMeasurements.set(measurement.lane, measurement);
1485 - else if (measurement.end < previousFurthestMeasurement.end) furthestMeasurementsFound.set(measurement.lane, true);
1486 - if (furthestMeasurementsFound.size === this.options.lanes) break;
1487 - }
1488 - return furthestMeasurements.size === this.options.lanes ? Array.from(furthestMeasurements.values()).sort((a, b) => {
1489 - if (a.end === b.end) return a.index - b.index;
1490 - return a.end - b.end;
1491 - })[0] : void 0;
1492 - };
1493 - this.getMeasurementOptions = memo(() => [
1494 - this.options.count,
1495 - this.options.paddingStart,
1496 - this.options.scrollMargin,
1497 - this.options.getItemKey,
1498 - this.options.enabled,
1499 - this.options.lanes,
1500 - this.options.laneAssignmentMode
1501 - ], (count, paddingStart, scrollMargin, getItemKey, enabled, lanes, laneAssignmentMode) => {
1502 - if (this.prevLanes !== void 0 && this.prevLanes !== lanes) this.lanesChangedFlag = true;
1503 - this.prevLanes = lanes;
1504 - this.pendingMeasuredCacheIndexes = [];
1505 - return {
1506 - count,
1507 - paddingStart,
1508 - scrollMargin,
1509 - getItemKey,
1510 - enabled,
1511 - lanes,
1512 - laneAssignmentMode
1513 - };
1514 - }, { key: false });
1515 - this.getMeasurements = memo(() => [this.getMeasurementOptions(), this.itemSizeCache], ({ count, paddingStart, scrollMargin, getItemKey, enabled, lanes, laneAssignmentMode }, itemSizeCache) => {
1516 - if (!enabled) {
1517 - this.measurementsCache = [];
1518 - this.itemSizeCache.clear();
1519 - this.laneAssignments.clear();
1520 - return [];
1521 - }
1522 - if (this.laneAssignments.size > count) {
1523 - for (const index of this.laneAssignments.keys()) if (index >= count) this.laneAssignments.delete(index);
1524 - }
1525 - if (this.lanesChangedFlag) {
1526 - this.lanesChangedFlag = false;
1527 - this.lanesSettling = true;
1528 - this.measurementsCache = [];
1529 - this.itemSizeCache.clear();
1530 - this.laneAssignments.clear();
1531 - this.pendingMeasuredCacheIndexes = [];
1532 - }
1533 - if (this.measurementsCache.length === 0 && !this.lanesSettling) {
1534 - this.measurementsCache = this.options.initialMeasurementsCache;
1535 - this.measurementsCache.forEach((item) => {
1536 - this.itemSizeCache.set(item.key, item.size);
1537 - });
1538 - }
1539 - const min = this.lanesSettling ? 0 : this.pendingMeasuredCacheIndexes.length > 0 ? Math.min(...this.pendingMeasuredCacheIndexes) : 0;
1540 - this.pendingMeasuredCacheIndexes = [];
1541 - if (this.lanesSettling && this.measurementsCache.length === count) this.lanesSettling = false;
1542 - const measurements = this.measurementsCache.slice(0, min);
1543 - const laneLastIndex = new Array(lanes).fill(void 0);
1544 - for (let m = 0; m < min; m++) {
1545 - const item = measurements[m];
1546 - if (item) laneLastIndex[item.lane] = m;
1547 - }
1548 - for (let i = min; i < count; i++) {
1549 - const key = getItemKey(i);
1550 - const cachedLane = this.laneAssignments.get(i);
1551 - let lane;
1552 - let start;
1553 - const shouldCacheLane = laneAssignmentMode === "estimate" || itemSizeCache.has(key);
1554 - if (cachedLane !== void 0 && this.options.lanes > 1) {
1555 - lane = cachedLane;
1556 - const prevIndex = laneLastIndex[lane];
1557 - const prevInLane = prevIndex !== void 0 ? measurements[prevIndex] : void 0;
1558 - start = prevInLane ? prevInLane.end + this.options.gap : paddingStart + scrollMargin;
1559 - } else {
1560 - const furthestMeasurement = this.options.lanes === 1 ? measurements[i - 1] : this.getFurthestMeasurement(measurements, i);
1561 - start = furthestMeasurement ? furthestMeasurement.end + this.options.gap : paddingStart + scrollMargin;
1562 - lane = furthestMeasurement ? furthestMeasurement.lane : i % this.options.lanes;
1563 - if (this.options.lanes > 1 && shouldCacheLane) this.laneAssignments.set(i, lane);
1564 - }
1565 - const measuredSize = itemSizeCache.get(key);
1566 - const size = typeof measuredSize === "number" ? measuredSize : this.options.estimateSize(i);
1567 - const end = start + size;
1568 - measurements[i] = {
1569 - index: i,
1570 - start,
1571 - size,
1572 - end,
1573 - key,
1574 - lane
1575 - };
1576 - laneLastIndex[lane] = i;
1577 - }
1578 - this.measurementsCache = measurements;
1579 - return measurements;
1580 - }, {
1581 - key: "getMeasurements",
1582 - debug: () => this.options.debug
1583 - });
1584 - this.calculateRange = memo(() => [
1585 - this.getMeasurements(),
1586 - this.getSize(),
1587 - this.getScrollOffset(),
1588 - this.options.lanes
1589 - ], (measurements, outerSize, scrollOffset, lanes) => {
1590 - return this.range = measurements.length > 0 && outerSize > 0 ? calculateRange({
1591 - measurements,
1592 - outerSize,
1593 - scrollOffset,
1594 - lanes
1595 - }) : null;
1596 - }, {
1597 - key: "calculateRange",
1598 - debug: () => this.options.debug
1599 - });
1600 - this.getVirtualIndexes = memo(() => {
1601 - let startIndex = null;
1602 - let endIndex = null;
1603 - const range = this.calculateRange();
1604 - if (range) {
1605 - startIndex = range.startIndex;
1606 - endIndex = range.endIndex;
1607 - }
1608 - this.maybeNotify.updateDeps([
1609 - this.isScrolling,
1610 - startIndex,
1611 - endIndex
1612 - ]);
1613 - return [
1614 - this.options.rangeExtractor,
1615 - this.options.overscan,
1616 - this.options.count,
1617 - startIndex,
1618 - endIndex
1619 - ];
1620 - }, (rangeExtractor, overscan, count, startIndex, endIndex) => {
1621 - return startIndex === null || endIndex === null ? [] : rangeExtractor({
1622 - startIndex,
1623 - endIndex,
1624 - overscan,
1625 - count
1626 - });
1627 - }, {
1628 - key: "getVirtualIndexes",
1629 - debug: () => this.options.debug
1630 - });
1631 - this.indexFromElement = (node) => {
1632 - const attributeName = this.options.indexAttribute;
1633 - const indexStr = node.getAttribute(attributeName);
1634 - if (!indexStr) {
1635 - console.warn(`Missing attribute name '${attributeName}={index}' on measured element.`);
1636 - return -1;
1637 - }
1638 - return parseInt(indexStr, 10);
1639 - };
1640 - this.shouldMeasureDuringScroll = (index) => {
1641 - var _a;
1642 - if (!this.scrollState || this.scrollState.behavior !== "smooth") return true;
1643 - const scrollIndex = this.scrollState.index ?? ((_a = this.getVirtualItemForOffset(this.scrollState.lastTargetOffset)) == null ? void 0 : _a.index);
1644 - if (scrollIndex !== void 0 && this.range) {
1645 - const bufferSize = Math.max(this.options.overscan, Math.ceil((this.range.endIndex - this.range.startIndex) / 2));
1646 - const minIndex = Math.max(0, scrollIndex - bufferSize);
1647 - const maxIndex = Math.min(this.options.count - 1, scrollIndex + bufferSize);
1648 - return index >= minIndex && index <= maxIndex;
1649 - }
1650 - return true;
1651 - };
1652 - this.measureElement = (node) => {
1653 - if (!node) {
1654 - this.elementsCache.forEach((cached, key2) => {
1655 - if (!cached.isConnected) {
1656 - this.observer.unobserve(cached);
1657 - this.elementsCache.delete(key2);
1658 - }
1659 - });
1660 - return;
1661 - }
1662 - const index = this.indexFromElement(node);
1663 - const key = this.options.getItemKey(index);
1664 - const prevNode = this.elementsCache.get(key);
1665 - if (prevNode !== node) {
1666 - if (prevNode) this.observer.unobserve(prevNode);
1667 - this.observer.observe(node);
1668 - this.elementsCache.set(key, node);
1669 - }
1670 - if ((!this.isScrolling || this.scrollState) && this.shouldMeasureDuringScroll(index)) this.resizeItem(index, this.options.measureElement(node, void 0, this));
1671 - };
1672 - this.resizeItem = (index, size) => {
1673 - var _a;
1674 - const item = this.measurementsCache[index];
1675 - if (!item) return;
1676 - const delta = size - (this.itemSizeCache.get(item.key) ?? item.size);
1677 - if (delta !== 0) {
1678 - if (((_a = this.scrollState) == null ? void 0 : _a.behavior) !== "smooth" && (this.shouldAdjustScrollPositionOnItemSizeChange !== void 0 ? this.shouldAdjustScrollPositionOnItemSizeChange(item, delta, this) : item.start < this.getScrollOffset() + this.scrollAdjustments)) {
1679 - if (this.options.debug) console.info("correction", delta);
1680 - this._scrollToOffset(this.getScrollOffset(), {
1681 - adjustments: this.scrollAdjustments += delta,
1682 - behavior: void 0
1683 - });
1684 - }
1685 - this.pendingMeasuredCacheIndexes.push(item.index);
1686 - this.itemSizeCache = new Map(this.itemSizeCache.set(item.key, size));
1687 - this.notify(false);
1688 - }
1689 - };
1690 - this.getVirtualItems = memo(() => [this.getVirtualIndexes(), this.getMeasurements()], (indexes, measurements) => {
1691 - const virtualItems = [];
1692 - for (let k = 0, len = indexes.length; k < len; k++) {
1693 - const measurement = measurements[indexes[k]];
1694 - virtualItems.push(measurement);
1695 - }
1696 - return virtualItems;
1697 - }, {
1698 - key: "getVirtualItems",
1699 - debug: () => this.options.debug
1700 - });
1701 - this.getVirtualItemForOffset = (offset) => {
1702 - const measurements = this.getMeasurements();
1703 - if (measurements.length === 0) return;
1704 - return notUndefined(measurements[findNearestBinarySearch(0, measurements.length - 1, (index) => notUndefined(measurements[index]).start, offset)]);
1705 - };
1706 - this.getMaxScrollOffset = () => {
1707 - if (!this.scrollElement) return 0;
1708 - if ("scrollHeight" in this.scrollElement) return this.options.horizontal ? this.scrollElement.scrollWidth - this.scrollElement.clientWidth : this.scrollElement.scrollHeight - this.scrollElement.clientHeight;
1709 - else {
1710 - const doc = this.scrollElement.document.documentElement;
1711 - return this.options.horizontal ? doc.scrollWidth - this.scrollElement.innerWidth : doc.scrollHeight - this.scrollElement.innerHeight;
1712 - }
1713 - };
1714 - this.getOffsetForAlignment = (toOffset, align, itemSize = 0) => {
1715 - if (!this.scrollElement) return 0;
1716 - const size = this.getSize();
1717 - const scrollOffset = this.getScrollOffset();
1718 - if (align === "auto") align = toOffset >= scrollOffset + size ? "end" : "start";
1719 - if (align === "center") toOffset += (itemSize - size) / 2;
1720 - else if (align === "end") toOffset -= size;
1721 - const maxOffset = this.getMaxScrollOffset();
1722 - return Math.max(Math.min(maxOffset, toOffset), 0);
1723 - };
1724 - this.getOffsetForIndex = (index, align = "auto") => {
1725 - index = Math.max(0, Math.min(index, this.options.count - 1));
1726 - const size = this.getSize();
1727 - const scrollOffset = this.getScrollOffset();
1728 - const item = this.measurementsCache[index];
1729 - if (!item) return;
1730 - if (align === "auto") if (item.end >= scrollOffset + size - this.options.scrollPaddingEnd) align = "end";
1731 - else if (item.start <= scrollOffset + this.options.scrollPaddingStart) align = "start";
1732 - else return [scrollOffset, align];
1733 - if (align === "end" && index === this.options.count - 1) return [this.getMaxScrollOffset(), align];
1734 - const toOffset = align === "end" ? item.end + this.options.scrollPaddingEnd : item.start - this.options.scrollPaddingStart;
1735 - return [this.getOffsetForAlignment(toOffset, align, item.size), align];
1736 - };
1737 - this.scrollToOffset = (toOffset, { align = "start", behavior = "auto" } = {}) => {
1738 - const offset = this.getOffsetForAlignment(toOffset, align);
1739 - const now = this.now();
1740 - this.scrollState = {
1741 - index: null,
1742 - align,
1743 - behavior,
1744 - startedAt: now,
1745 - lastTargetOffset: offset,
1746 - stableFrames: 0
1747 - };
1748 - this._scrollToOffset(offset, {
1749 - adjustments: void 0,
1750 - behavior
1751 - });
1752 - this.scheduleScrollReconcile();
1753 - };
1754 - this.scrollToIndex = (index, { align: initialAlign = "auto", behavior = "auto" } = {}) => {
1755 - index = Math.max(0, Math.min(index, this.options.count - 1));
1756 - const offsetInfo = this.getOffsetForIndex(index, initialAlign);
1757 - if (!offsetInfo) return;
1758 - const [offset, align] = offsetInfo;
1759 - const now = this.now();
1760 - this.scrollState = {
1761 - index,
1762 - align,
1763 - behavior,
1764 - startedAt: now,
1765 - lastTargetOffset: offset,
1766 - stableFrames: 0
1767 - };
1768 - this._scrollToOffset(offset, {
1769 - adjustments: void 0,
1770 - behavior
1771 - });
1772 - this.scheduleScrollReconcile();
1773 - };
1774 - this.scrollBy = (delta, { behavior = "auto" } = {}) => {
1775 - const offset = this.getScrollOffset() + delta;
1776 - const now = this.now();
1777 - this.scrollState = {
1778 - index: null,
1779 - align: "start",
1780 - behavior,
1781 - startedAt: now,
1782 - lastTargetOffset: offset,
1783 - stableFrames: 0
1784 - };
1785 - this._scrollToOffset(offset, {
1786 - adjustments: void 0,
1787 - behavior
1788 - });
1789 - this.scheduleScrollReconcile();
1790 - };
1791 - this.getTotalSize = () => {
1792 - var _a;
1793 - const measurements = this.getMeasurements();
1794 - let end;
1795 - if (measurements.length === 0) end = this.options.paddingStart;
1796 - else if (this.options.lanes === 1) end = ((_a = measurements[measurements.length - 1]) == null ? void 0 : _a.end) ?? 0;
1797 - else {
1798 - const endByLane = Array(this.options.lanes).fill(null);
1799 - let endIndex = measurements.length - 1;
1800 - while (endIndex >= 0 && endByLane.some((val) => val === null)) {
1801 - const item = measurements[endIndex];
1802 - if (endByLane[item.lane] === null) endByLane[item.lane] = item.end;
1803 - endIndex--;
1804 - }
1805 - end = Math.max(...endByLane.filter((val) => val !== null));
1806 - }
1807 - return Math.max(end - this.options.scrollMargin + this.options.paddingEnd, 0);
1808 - };
1809 - this._scrollToOffset = (offset, { adjustments, behavior }) => {
1810 - this.options.scrollToFn(offset, {
1811 - behavior,
1812 - adjustments
1813 - }, this);
1814 - };
1815 - this.measure = () => {
1816 - this.itemSizeCache = /* @__PURE__ */ new Map();
1817 - this.laneAssignments = /* @__PURE__ */ new Map();
1818 - this.notify(false);
1819 - };
1820 - this.setOptions(opts);
1821 - }
1822 - scheduleScrollReconcile() {
1823 - if (!this.targetWindow) {
1824 - this.scrollState = null;
1825 - return;
1826 - }
1827 - if (this.rafId != null) return;
1828 - this.rafId = this.targetWindow.requestAnimationFrame(() => {
1829 - this.rafId = null;
1830 - this.reconcileScroll();
1831 - });
1832 - }
1833 - reconcileScroll() {
1834 - if (!this.scrollState) return;
1835 - if (!this.scrollElement) return;
1836 - if (this.now() - this.scrollState.startedAt > 5e3) {
1837 - this.scrollState = null;
1838 - return;
1839 - }
1840 - const offsetInfo = this.scrollState.index != null ? this.getOffsetForIndex(this.scrollState.index, this.scrollState.align) : void 0;
1841 - const targetOffset = offsetInfo ? offsetInfo[0] : this.scrollState.lastTargetOffset;
1842 - const STABLE_FRAMES = 1;
1843 - const targetChanged = targetOffset !== this.scrollState.lastTargetOffset;
1844 - if (!targetChanged && approxEqual(targetOffset, this.getScrollOffset())) {
1845 - this.scrollState.stableFrames++;
1846 - if (this.scrollState.stableFrames >= STABLE_FRAMES) {
1847 - this.scrollState = null;
1848 - return;
1849 - }
1850 - } else {
1851 - this.scrollState.stableFrames = 0;
1852 - if (targetChanged) {
1853 - this.scrollState.lastTargetOffset = targetOffset;
1854 - this.scrollState.behavior = "auto";
1855 - this._scrollToOffset(targetOffset, {
1856 - adjustments: void 0,
1857 - behavior: "auto"
1858 - });
1859 - }
1860 - }
1861 - this.scheduleScrollReconcile();
1862 - }
1863 - };
1864 - var findNearestBinarySearch = (low, high, getCurrentValue, value) => {
1865 - while (low <= high) {
1866 - const middle = (low + high) / 2 | 0;
1867 - const currentValue = getCurrentValue(middle);
1868 - if (currentValue < value) low = middle + 1;
1869 - else if (currentValue > value) high = middle - 1;
1870 - else return middle;
1871 - }
1872 - if (low > 0) return low - 1;
1873 - else return 0;
1874 - };
1875 - function calculateRange({ measurements, outerSize, scrollOffset, lanes }) {
1876 - const lastIndex = measurements.length - 1;
1877 - const getOffset = (index) => measurements[index].start;
1878 - if (measurements.length <= lanes) return {
1879 - startIndex: 0,
1880 - endIndex: lastIndex
1881 - };
1882 - let startIndex = findNearestBinarySearch(0, lastIndex, getOffset, scrollOffset);
1883 - let endIndex = startIndex;
1884 - if (lanes === 1) while (endIndex < lastIndex && measurements[endIndex].end < scrollOffset + outerSize) endIndex++;
1885 - else if (lanes > 1) {
1886 - const endPerLane = Array(lanes).fill(0);
1887 - while (endIndex < lastIndex && endPerLane.some((pos) => pos < scrollOffset + outerSize)) {
1888 - const item = measurements[endIndex];
1889 - endPerLane[item.lane] = item.end;
1890 - endIndex++;
1891 - }
1892 - const startPerLane = Array(lanes).fill(scrollOffset + outerSize);
1893 - while (startIndex >= 0 && startPerLane.some((pos) => pos >= scrollOffset)) {
1894 - const item = measurements[startIndex];
1895 - startPerLane[item.lane] = item.start;
1896 - startIndex--;
1897 - }
1898 - startIndex = Math.max(0, startIndex - startIndex % lanes);
1899 - endIndex = Math.min(lastIndex, endIndex + (lanes - 1 - endIndex % lanes));
1900 - }
1901 - return {
1902 - startIndex,
1903 - endIndex
1904 - };
1905 - }
1906 -
1907 -//#endregion
1908 -//#region packages/node_modules/@tanstack/react-virtual/dist/esm/index.js
1909 - var useIsomorphicLayoutEffect = typeof document !== "undefined" ? react$1.useLayoutEffect : react$1.useEffect;
1910 - function useVirtualizerBase({ useFlushSync = true, ...options }) {
1911 - const rerender = react$1.useReducer(() => ({}), {})[1];
1912 - const resolvedOptions = {
1913 - ...options,
1914 - onChange: (instance2, sync) => {
1915 - var _a;
1916 - if (useFlushSync && sync) (0, react_dom.flushSync)(rerender);
1917 - else rerender();
1918 - (_a = options.onChange) == null || _a.call(options, instance2, sync);
1919 - }
1920 - };
1921 - const [instance] = react$1.useState(() => new Virtualizer(resolvedOptions));
1922 - instance.setOptions(resolvedOptions);
1923 - useIsomorphicLayoutEffect(() => {
1924 - return instance._didMount();
1925 - }, []);
1926 - useIsomorphicLayoutEffect(() => {
1927 - return instance._willUpdate();
1928 - });
1929 - return instance;
1930 - }
1931 - function useVirtualizer(options) {
1932 - return useVirtualizerBase({
1933 - observeElementRect,
1934 - observeElementOffset,
1935 - scrollToFn: elementScroll,
1936 - ...options
1937 - });
1938 - }
1939 -
1940 -//#endregion
1941 -//#region packages/packages/core/editor-global-classes/src/hooks/use-ordered-classes.ts
1942 - var useOrderedClasses = () => {
1943 - return (0, _elementor_store.__useSelector)(selectOrderedClasses);
1944 - };
1945 -
1946 -//#endregion
1947 -//#region packages/packages/core/editor-global-classes/src/hooks/use-css-class-usage-by-id.ts
1948 - var EMPTY_CLASS_USAGE = {
1949 - total: 0,
1950 - content: []
1951 - };
1952 - var useCssClassUsageByID = (id) => {
1953 - const { data, ...rest } = useCssClassUsage();
1954 - const classData = data?.[id] ?? EMPTY_CLASS_USAGE;
1955 - return {
1956 - ...rest,
1957 - data: classData
1958 - };
1959 - };
1960 -
1961 -//#endregion
1962 -//#region packages/packages/core/editor-global-classes/src/components/css-class-usage/components/css-class-usage-popover.tsx
1963 - var iconMapper = {
1964 - "wp-post": {
1965 - label: (0, _wordpress_i18n.__)("Post", "elementor"),
1966 - icon: /* @__PURE__ */ react.createElement(_elementor_icons.PostTypeIcon, { fontSize: "inherit" })
1967 - },
1968 - "wp-page": {
1969 - label: (0, _wordpress_i18n.__)("Page", "elementor"),
1970 - icon: /* @__PURE__ */ react.createElement(_elementor_icons.PagesIcon, { fontSize: "inherit" })
1971 - },
1972 - popup: {
1973 - label: (0, _wordpress_i18n.__)("Popup", "elementor"),
1974 - icon: /* @__PURE__ */ react.createElement(_elementor_icons.PopupTemplateIcon, { fontSize: "inherit" })
1975 - },
1976 - header: {
1977 - label: (0, _wordpress_i18n.__)("Header", "elementor"),
1978 - icon: /* @__PURE__ */ react.createElement(_elementor_icons.HeaderTemplateIcon, { fontSize: "inherit" })
1979 - },
1980 - footer: {
1981 - label: (0, _wordpress_i18n.__)("Footer", "elementor"),
1982 - icon: /* @__PURE__ */ react.createElement(_elementor_icons.FooterTemplateIcon, { fontSize: "inherit" })
1983 - }
1984 - };
1985 - var CssClassUsagePopover = ({ cssClassID, onClose }) => {
1986 - const { data: classUsage } = useCssClassUsageByID(cssClassID);
1987 - const onNavigate = (0, _elementor_editor_documents.__useOpenDocumentInNewTab)();
1988 - const cssClassUsageRecords = classUsage?.content.map(({ title, elements, pageId, type }) => ({
1989 - type: "item",
1990 - value: pageId,
1991 - label: title,
1992 - secondaryText: elements.length.toString(),
1993 - docType: type
1994 - })) ?? [];
1995 - const handleSelect = (value) => {
1996 - onNavigate(+value);
1997 - trackGlobalClasses({
1998 - event: "classUsageLocate",
1999 - classId: cssClassID
2000 - });
2001 - };
2002 - return /* @__PURE__ */ react.createElement(react.Fragment, null, /* @__PURE__ */ react.createElement(_elementor_editor_ui.PopoverHeader, {
2003 - icon: /* @__PURE__ */ react.createElement(_elementor_icons.CurrentLocationIcon, { fontSize: "tiny" }),
2004 - title: /* @__PURE__ */ react.createElement(_elementor_ui.Stack, {
2005 - flexDirection: "row",
2006 - gap: 1,
2007 - alignItems: "center"
2008 - }, /* @__PURE__ */ react.createElement(_elementor_ui.Box, { "aria-label": "header-title" }, (0, _wordpress_i18n.__)("Locator", "elementor")), /* @__PURE__ */ react.createElement(_elementor_ui.Box, null, /* @__PURE__ */ react.createElement(_elementor_ui.Chip, {
2009 - sx: { lineHeight: 1 },
2010 - size: "tiny",
2011 - label: classUsage.total
2012 - }))),
2013 - onClose
2014 - }), /* @__PURE__ */ react.createElement(_elementor_ui.Divider, null), /* @__PURE__ */ react.createElement(_elementor_editor_ui.PopoverBody, { width: 300 }, /* @__PURE__ */ react.createElement(_elementor_editor_ui.PopoverMenuList, {
2015 - onSelect: handleSelect,
2016 - items: cssClassUsageRecords,
2017 - onClose: () => {},
2018 - menuListTemplate: StyledCssClassUsageItem,
2019 - menuItemContentTemplate: (cssClassUsageRecord) => /* @__PURE__ */ react.createElement(_elementor_ui.Stack, {
2020 - flexDirection: "row",
2021 - flex: 1,
2022 - alignItems: "center"
2023 - }, /* @__PURE__ */ react.createElement(_elementor_ui.Box, {
2024 - display: "flex",
2025 - sx: { pr: 1 }
2026 - }, /* @__PURE__ */ react.createElement(_elementor_ui.Tooltip, {
2027 - disableInteractive: true,
2028 - title: iconMapper?.[cssClassUsageRecord.docType]?.label ?? cssClassUsageRecord.docType,
2029 - placement: "top"
2030 - }, /* @__PURE__ */ react.createElement(_elementor_ui.Icon, { fontSize: "small" }, iconMapper?.[cssClassUsageRecord.docType]?.icon || /* @__PURE__ */ react.createElement(_elementor_icons.PagesIcon, { fontSize: "inherit" })))), /* @__PURE__ */ react.createElement(_elementor_ui.Box, {
2031 - sx: {
2032 - pr: .5,
2033 - maxWidth: "173px"
2034 - },
2035 - display: "flex"
2036 - }, /* @__PURE__ */ react.createElement(_elementor_editor_ui.EllipsisWithTooltip, {
2037 - title: cssClassUsageRecord.label,
2038 - as: _elementor_ui.Typography,
2039 - variant: "caption",
2040 - maxWidth: "173px",
2041 - sx: { lineHeight: 1 }
2042 - })), /* @__PURE__ */ react.createElement(_elementor_icons.ExternalLinkIcon, {
2043 - className: "hover-only-icon",
2044 - fontSize: "tiny"
2045 - }), /* @__PURE__ */ react.createElement(_elementor_ui.Chip, {
2046 - sx: { ml: "auto" },
2047 - size: "tiny",
2048 - label: cssClassUsageRecord.secondaryText
2049 - }))
2050 - })));
2051 - };
2052 - var StyledCssClassUsageItem = (0, _elementor_ui.styled)(_elementor_ui.MenuList)(({ theme }) => ({
2053 - "& > li": {
2054 - display: "flex",
2055 - cursor: "pointer",
2056 - height: 32,
2057 - width: "100%"
2058 - },
2059 - "& > [role=\"option\"]": {
2060 - ...theme.typography.caption,
2061 - lineHeight: "inherit",
2062 - padding: theme.spacing(.5, 1, .5, 2),
2063 - textOverflow: "ellipsis",
2064 - position: "absolute",
2065 - top: 0,
2066 - left: 0,
2067 - opacity: 1,
2068 - ".hover-only-icon": {
2069 - color: theme.palette.text.disabled,
2070 - opacity: 0
2071 - },
2072 - "&:hover": {
2073 - borderRadius: theme.spacing(.5),
2074 - backgroundColor: theme.palette.action.hover,
2075 - ".hover-only-icon": {
2076 - color: theme.palette.text.disabled,
2077 - opacity: 1
2078 - }
2079 - }
2080 - },
2081 - width: "100%",
2082 - position: "relative"
2083 - }));
2084 -
2085 -//#endregion
2086 -//#region packages/packages/core/editor-global-classes/src/components/css-class-usage/components/css-class-usage-trigger.tsx
2087 - var CssClassUsageTrigger = ({ id, onClick }) => {
2088 - const { data: { total }, isLoading } = useCssClassUsageByID(id);
2089 - const cssClassUsagePopover = (0, _elementor_ui.usePopupState)({
2090 - variant: "popover",
2091 - popupId: "css-class-usage-popover"
2092 - });
2093 - if (isLoading) return null;
2094 - const WrapperComponent = total !== 0 ? TooltipWrapper : InfoAlertMessage;
2095 - const handleMouseEnter = () => {
2096 - trackGlobalClasses({
2097 - event: "classUsageHovered",
2098 - classId: id,
2099 - usage: total
2100 - });
2101 - };
2102 - const handleClick = (e) => {
2103 - if (total !== 0) {
2104 - (0, _elementor_ui.bindTrigger)(cssClassUsagePopover).onClick(e);
2105 - onClick(id);
2106 - trackGlobalClasses({
2107 - event: "classUsageClicked",
2108 - classId: id
2109 - });
2110 - }
2111 - };
2112 - return /* @__PURE__ */ react.createElement(react.Fragment, null, /* @__PURE__ */ react.createElement(_elementor_ui.Box, {
2113 - position: "relative",
2114 - onMouseEnter: handleMouseEnter
2115 - }, /* @__PURE__ */ react.createElement(WrapperComponent, { total }, /* @__PURE__ */ react.createElement(CustomIconButton, {
2116 - disabled: total === 0,
2117 - size: "tiny",
2118 - ...(0, _elementor_ui.bindTrigger)(cssClassUsagePopover),
2119 - onClick: handleClick
2120 - }, /* @__PURE__ */ react.createElement(_elementor_icons.CurrentLocationIcon, { fontSize: "tiny" })))), /* @__PURE__ */ react.createElement(_elementor_ui.Box, null, /* @__PURE__ */ react.createElement(_elementor_ui.Popover, {
2121 - anchorOrigin: {
2122 - vertical: "center",
2123 - horizontal: "right"
2124 - },
2125 - transformOrigin: {
2126 - vertical: 15,
2127 - horizontal: -50
2128 - },
2129 - ...(0, _elementor_ui.bindPopover)(cssClassUsagePopover),
2130 - onClose: () => {
2131 - (0, _elementor_ui.bindPopover)(cssClassUsagePopover).onClose();
2132 - onClick("");
2133 - }
2134 - }, /* @__PURE__ */ react.createElement(CssClassUsagePopover, {
2135 - onClose: cssClassUsagePopover.close,
2136 - "aria-label": "css-class-usage-popover",
2137 - cssClassID: id
2138 - }))));
2139 - };
2140 - var CustomIconButton = (0, _elementor_ui.styled)(_elementor_ui.IconButton)(({ theme }) => ({
2141 - "&.Mui-disabled": {
2142 - pointerEvents: "auto",
2143 - "&:hover": { color: theme.palette.action.disabled }
2144 - },
2145 - height: "22px",
2146 - width: "22px"
2147 - }));
2148 - var TooltipWrapper = ({ children, total }) => /* @__PURE__ */ react.createElement(_elementor_ui.Tooltip, {
2149 - disableInteractive: true,
2150 - placement: "top",
2151 - title: `${(0, _wordpress_i18n.__)("Show {{number}} {{locations}}", "elementor").replace("{{number}}", total.toString()).replace("{{locations}}", total === 1 ? (0, _wordpress_i18n.__)("location", "elementor") : (0, _wordpress_i18n.__)("locations", "elementor"))}`
2152 - }, /* @__PURE__ */ react.createElement("span", null, children));
2153 - var InfoAlertMessage = ({ children }) => /* @__PURE__ */ react.createElement(_elementor_ui.Infotip, {
2154 - disableInteractive: true,
2155 - placement: "top",
2156 - color: "secondary",
2157 - content: /* @__PURE__ */ react.createElement(_elementor_editor_ui.InfoAlert, { sx: { mt: 1 } }, (0, _wordpress_i18n.__)("This class isn’t being used yet.", "elementor"))
2158 - }, /* @__PURE__ */ react.createElement("span", null, children));
2159 -
2160 -//#endregion
2161 -//#region packages/packages/core/editor-global-classes/src/components/class-manager/delete-confirmation-dialog.tsx
2162 - var context = (0, react.createContext)(null);
2163 - var DeleteConfirmationProvider = ({ children }) => {
2164 - const [dialogProps, setDialogProps] = (0, react.useState)(null);
2165 - const openDialog = (props) => {
2166 - setDialogProps(props);
2167 - };
2168 - const closeDialog = () => {
2169 - setDialogProps(null);
2170 - };
2171 - return /* @__PURE__ */ react.createElement(context.Provider, { value: {
2172 - openDialog,
2173 - closeDialog,
2174 - dialogProps
2175 - } }, children, !!dialogProps && /* @__PURE__ */ react.createElement(DeleteClassDialog, { ...dialogProps }));
2176 - };
2177 - var DeleteClassDialog = ({ label, id }) => {
2178 - const { closeDialog } = useDeleteConfirmation();
2179 - const { data: { total, content } } = useCssClassUsageByID(id);
2180 - const handleConfirm = () => {
2181 - closeDialog();
2182 - deleteClass(id);
2183 - };
2184 - const text = total && content.length ? (0, _wordpress_i18n.__)("Will permanently remove it from your project and may affect the design across all elements using it. Used %1 times across %2 pages. This action cannot be undone.", "elementor").replace("%1", total.toString()).replace("%2", content.length.toString()) : (0, _wordpress_i18n.__)("Will permanently remove it from your project and may affect the design across all elements using it. This action cannot be undone.", "elementor");
2185 - return /* @__PURE__ */ react.createElement(_elementor_editor_ui.ConfirmationDialog, {
2186 - open: true,
2187 - onClose: closeDialog
2188 - }, /* @__PURE__ */ react.createElement(_elementor_editor_ui.ConfirmationDialog.Title, null, (0, _wordpress_i18n.__)("Delete this class?", "elementor")), /* @__PURE__ */ react.createElement(_elementor_editor_ui.ConfirmationDialog.Content, null, /* @__PURE__ */ react.createElement(_elementor_editor_ui.ConfirmationDialog.ContentText, null, (0, _wordpress_i18n.__)("Deleting", "elementor"), /* @__PURE__ */ react.createElement(_elementor_ui.Typography, {
2189 - variant: "subtitle2",
2190 - component: "span"
2191 - }, "\xA0", label, "\xA0"), text)), /* @__PURE__ */ react.createElement(_elementor_editor_ui.ConfirmationDialog.Actions, {
2192 - onClose: closeDialog,
2193 - onConfirm: handleConfirm
2194 - }));
2195 - };
2196 - var useDeleteConfirmation = () => {
2197 - const contextValue = (0, react.useContext)(context);
2198 - if (!contextValue) throw new Error("useDeleteConfirmation must be used within a DeleteConfirmationProvider");
2199 - return contextValue;
2200 - };
2201 -
2202 -//#endregion
2203 -//#region packages/packages/core/editor-global-classes/src/components/class-manager/sortable.tsx
2204 - var SortableProvider = (props) => /* @__PURE__ */ react.createElement(_elementor_ui.UnstableSortableProvider, {
2205 - restrictAxis: true,
2206 - variant: "static",
2207 - dragPlaceholderStyle: { visibility: "hidden" },
2208 - ...props
2209 - });
2210 - var SortableTrigger = (props) => /* @__PURE__ */ react.createElement(StyledSortableTrigger, {
2211 - ...props,
2212 - role: "button",
2213 - className: "class-item-sortable-trigger",
2214 - "aria-label": "sort"
2215 - }, /* @__PURE__ */ react.createElement(_elementor_icons.GripVerticalIcon, { fontSize: "tiny" }));
2216 - var SortableItem = ({ children, id, style, ...props }) => {
2217 - return /* @__PURE__ */ react.createElement(_elementor_ui.UnstableSortableItem, {
2218 - ...props,
2219 - id,
2220 - render: ({ itemProps, isDragged, triggerProps, itemStyle, triggerStyle, dropIndicationStyle, showDropIndication, isDragOverlay, isDragPlaceholder }) => {
2221 - return /* @__PURE__ */ react.createElement(_elementor_ui.Box, {
2222 - ...itemProps,
2223 - style: {
2224 - ...itemStyle,
2225 - ...!isDragOverlay ? style : null
2226 - },
2227 - component: "li",
2228 - role: "listitem",
2229 - sx: { backgroundColor: isDragOverlay ? "background.paper" : void 0 }
2230 - }, children({
2231 - itemProps,
2232 - isDragged,
2233 - triggerProps,
2234 - itemStyle,
2235 - triggerStyle,
2236 - isDragPlaceholder
2237 - }), showDropIndication && /* @__PURE__ */ react.createElement(SortableItemIndicator, { style: dropIndicationStyle }));
2238 - }
2239 - });
2240 - };
2241 - var StyledSortableTrigger = (0, _elementor_ui.styled)("div")(({ theme }) => ({
2242 - position: "absolute",
2243 - left: 0,
2244 - top: "50%",
2245 - transform: `translate( -${theme.spacing(1.5)}, -50% )`,
2246 - color: theme.palette.action.active
2247 - }));
2248 - var SortableItemIndicator = (0, _elementor_ui.styled)(_elementor_ui.Box)`
1 +/*! For license information please see editor-global-classes.js.LICENSE.txt */
2 +!function(){"use strict";var e={"./packages/packages/core/editor-global-classes/service/css-class-usage-service.ts":function(e,s,t){t.r(s),t.d(s,{fetchCssClassUsage:function(){return fetchCssClassUsage}});var a=t("./packages/packages/core/editor-global-classes/src/api.ts"),r=t("./packages/packages/core/editor-global-classes/src/components/css-class-usage/utils.ts");const fetchCssClassUsage=async()=>{const e=await a.apiClient.usage();return(0,r.transformData)(e?.data?.data||{})}},"./packages/packages/core/editor-global-classes/src/api.ts":function(e,s,t){t.r(s),t.d(s,{API_ERROR_CODES:function(){return c},apiClient:function(){return l}});var a=t("@elementor/http-client");const r="/global-classes",o="elementor/v1",n=`${r}/usage`,l={usage:()=>(0,a.httpService)().get(`${o}${n}`),all:(e="preview")=>(0,a.httpService)().get(`${o}${r}`,{params:{context:e}}),publish:e=>(0,a.httpService)().put("elementor/v1"+r,e,{params:{context:"frontend"}}),saveDraft:e=>(0,a.httpService)().put("elementor/v1"+r,e,{params:{context:"preview"}})},c={DUPLICATED_LABEL:"DUPLICATED_LABEL"}},"./packages/packages/core/editor-global-classes/src/capabilities.ts":function(e,s,t){t.r(s),t.d(s,{UPDATE_CLASS_CAPABILITY_KEY:function(){return r},getCapabilities:function(){return getCapabilities}});var a=t("@elementor/editor-v1-adapters");const r="elementor_global_classes_update_class",getCapabilities=()=>{if((0,a.isExperimentActive)("global_classes_should_enforce_capabilities"))return{update:r,create:r,delete:r,updateProps:r}}},"./packages/packages/core/editor-global-classes/src/components/class-manager/class-item.tsx":function(e,s,t){t.r(s),t.d(s,{ClassItem:function(){return ClassItem}});var a=t("react"),r=t("@elementor/editor-styles-repository"),o=t("@elementor/editor-ui"),n=t("@elementor/icons"),l=t("@elementor/ui"),c=t("@wordpress/i18n"),i=t("./packages/packages/core/editor-global-classes/src/components/css-class-usage/components/index.ts"),d=t("./packages/packages/core/editor-global-classes/src/components/class-manager/delete-confirmation-dialog.tsx"),p=t("./packages/packages/core/editor-global-classes/src/components/class-manager/sortable.tsx");function _extends(){return _extends=Object.assign?Object.assign.bind():function(e){for(var s=1;s<arguments.length;s++){var t=arguments[s];for(var a in t)({}).hasOwnProperty.call(t,a)&&(e[a]=t[a])}return e},_extends.apply(null,arguments)}const ClassItem=({id:e,label:s,renameClass:t,selected:r,disabled:m,sortableTriggerProps:h,showSortIndicator:b})=>{const f=(0,a.useRef)(null),{ref:y,openEditMode:k,isEditing:v,error:C,getProps:x}=(0,o.useEditable)({value:s,onSubmit:t,validation:validateLabel}),[_,E]=(0,a.useState)(""),{openDialog:w}=(0,d.useDeleteConfirmation)(),S=(0,l.usePopupState)({variant:"popover",disableAutoFocus:!0}),I=(_===e||r||S.isOpen)&&!m;return a.createElement(a.Fragment,null,a.createElement(l.Stack,{p:0},a.createElement(o.WarningInfotip,{open:Boolean(C),text:C??"",placement:"bottom",width:f.current?.getBoundingClientRect().width,offset:[0,-15]},a.createElement(u,{ref:f,dense:!0,disableGutters:!0,showSortIndicator:b,showActions:I||v,shape:"rounded",onDoubleClick:k,selected:I,disabled:m,focusVisibleClassName:"visible-class-item"},a.createElement(p.SortableTrigger,h),a.createElement(g,{isActive:v,isError:!!C},v?a.createElement(o.EditableField,_extends({ref:y,as:l.Typography,variant:"caption"},x())):a.createElement(o.EllipsisWithTooltip,{title:s,as:l.Typography,variant:"caption"})),a.createElement(l.Box,{className:"class-item-locator"},a.createElement(i.CssClassUsageTrigger,{id:e,onClick:E})),a.createElement(l.Tooltip,{placement:"top",className:"class-item-more-actions",title:(0,c.__)("More actions","elementor")},a.createElement(l.IconButton,_extends({size:"tiny"},(0,l.bindTrigger)(S),{"aria-label":"More actions"}),a.createElement(n.DotsVerticalIcon,{fontSize:"tiny"})))))),a.createElement(l.Menu,_extends({},(0,l.bindMenu)(S),{anchorOrigin:{vertical:"bottom",horizontal:"right"},transformOrigin:{vertical:"top",horizontal:"right"}}),a.createElement(o.MenuListItem,{sx:{minWidth:"160px"},onClick:()=>{S.close(),k()}},a.createElement(l.Typography,{variant:"caption",sx:{color:"text.primary"}},(0,c.__)("Rename","elementor"))),a.createElement(o.MenuListItem,{onClick:()=>{S.close(),w({id:e,label:s})}},a.createElement(l.Typography,{variant:"caption",sx:{color:"error.light"}},(0,c.__)("Delete","elementor")))))},u=(0,l.styled)(l.ListItemButton,{shouldForwardProp:e=>!["showActions","showSortIndicator"].includes(e)})(({showActions:e,showSortIndicator:s})=>`\n min-height: 36px;\n\n &.visible-class-item {\n box-shadow: none !important;\n }\n\n .class-item-locator {\n visibility: hidden;\n }\n\n .class-item-sortable-trigger {\n visibility: ${s&&e?"visible":"hidden"};\n }\n\n &:hover:not(:disabled) {\n .class-item-locator {\n visibility: visible;\n }\n\n .class-item-sortable-trigger {\n visibility: ${s?"visible":"hidden"};\n }\n }\n `),g=(0,l.styled)(l.Box,{shouldForwardProp:e=>!["isActive","isError"].includes(e)})(({theme:e,isActive:s,isError:t})=>({display:"flex",width:"100%",flexGrow:1,borderRadius:e.spacing(.5),border:getIndicatorBorder({isActive:s,isError:t,theme:e}),padding:`0 ${e.spacing(1)}`,marginLeft:s?e.spacing(1):0,minWidth:0})),getIndicatorBorder=({isActive:e,isError:s,theme:t})=>s?`2px solid ${t.palette.error.main}`:e?`2px solid ${t.palette.secondary.main}`:"none",validateLabel=e=>{const s=(0,r.validateStyleLabel)(e,"rename");return s.isValid?null:s.errorMessage}},"./packages/packages/core/editor-global-classes/src/components/class-manager/class-manager-button.tsx":function(e,s,t){t.r(s),t.d(s,{ClassManagerButton:function(){return ClassManagerButton}});var a=t("react"),r=t("@elementor/editor-documents"),o=t("@elementor/editor-styles-repository"),n=t("@elementor/editor-ui"),l=t("@elementor/ui"),c=t("@wordpress/i18n"),i=t("./packages/packages/core/editor-global-classes/src/global-classes-styles-provider.ts"),d=t("./packages/packages/core/editor-global-classes/src/hooks/use-prefetch-css-class-usage.ts"),p=t("./packages/packages/core/editor-global-classes/src/utils/tracking.ts"),u=t("./packages/packages/core/editor-global-classes/src/components/class-manager/class-manager-panel.tsx"),g=t("./packages/packages/core/editor-global-classes/src/components/class-manager/flipped-color-swatch-icon.tsx");const trackGlobalClassesButton=()=>{(0,p.trackGlobalClasses)({event:"classManagerOpened",source:"style-panel"})},ClassManagerButton=()=>{const e=(0,r.__useActiveDocument)(),{open:s}=(0,u.usePanelActions)(),{save:t}=(0,r.__useActiveDocumentActions)(),{open:m,close:h,isOpen:b}=(0,n.useDialog)(),{prefetchClassesUsage:f}=(0,d.usePrefetchCssClassUsage)(),{userCan:y}=(0,o.useUserStylesCapability)();if(!y(i.globalClassesStylesProvider.getKey()).update)return null;return a.createElement(a.Fragment,null,a.createElement(l.Tooltip,{title:(0,c.__)("Class Manager","elementor"),placement:"top"},a.createElement(l.IconButton,{size:"tiny",onClick:()=>{e?.isDirty?m():(s(),trackGlobalClassesButton(),(0,p.trackGlobalClasses)({event:"classManagerOpened",source:"style-panel"}),f())},sx:{marginInlineEnd:-.75}},a.createElement(g.FlippedColorSwatchIcon,{fontSize:"tiny"}))),b&&a.createElement(n.SaveChangesDialog,null,a.createElement(n.SaveChangesDialog.Title,null,(0,c.__)("You have unsaved changes","elementor")),a.createElement(n.SaveChangesDialog.Content,null,a.createElement(n.SaveChangesDialog.ContentText,{sx:{mb:2}},(0,c.__)("To open the Class Manager, save your page first. You can't continue without saving.","elementor"))),a.createElement(n.SaveChangesDialog.Actions,{actions:{cancel:{label:(0,c.__)("Stay here","elementor"),action:h},confirm:{label:(0,c.__)("Save & Continue","elementor"),action:async()=>{await t(),h(),s(),trackGlobalClassesButton(),f()}}}})))}},"./packages/packages/core/editor-global-classes/src/components/class-manager/class-manager-introduction.tsx":function(e,s,t){t.r(s),t.d(s,{ClassManagerIntroduction:function(){return ClassManagerIntroduction}});var a=t("react"),r=t("@elementor/editor-current-user"),o=t("@elementor/editor-ui"),n=t("@elementor/ui"),l=t("@wordpress/i18n");const ClassManagerIntroduction=()=>{const[e,s]=(0,r.useSuppressedMessage)("global-class-manager"),[t,c]=(0,a.useState)(!e);return a.createElement(o.IntroductionModal,{open:t,title:(0,l.__)("Class Manager","elementor"),handleClose:e=>{e||s(),c(!1)}},a.createElement(n.Image,{sx:{width:"100%",aspectRatio:"16 / 9"},src:"https://assets.elementor.com/packages/v1/images/class-manager-intro.svg",alt:""}),a.createElement(IntroductionContent,null))},IntroductionContent=()=>a.createElement(n.Box,{p:3},a.createElement(n.Typography,{variant:"body2"},(0,l.__)("The Class Manager lets you see all the classes you've created, plus adjust their priority, rename them, and delete unused classes to keep your CSS structured.","elementor")),a.createElement("br",null),a.createElement(n.Typography,{variant:"body2"},(0,l.__)("Remember, when editing an item within a specific class, any changes you make will apply across all elements in that class.","elementor")))},"./packages/packages/core/editor-global-classes/src/components/class-manager/class-manager-panel.tsx":function(e,s,t){t.r(s),t.d(s,{ClassManagerPanel:function(){return ClassManagerPanel},panel:function(){return D},usePanelActions:function(){return P}});var a=t("react"),r=t("@elementor/editor-documents"),o=t("@elementor/editor-panels"),n=t("@elementor/editor-ui"),l=t("@elementor/editor-v1-adapters"),c=t("@elementor/icons"),i=t("@elementor/query"),d=t("@elementor/store"),p=t("@elementor/ui"),u=t("@wordpress/i18n"),g=t("./packages/packages/core/editor-global-classes/src/hooks/use-classes-order.ts"),m=t("./packages/packages/core/editor-global-classes/src/hooks/use-dirty-state.ts"),h=t("./packages/packages/core/editor-global-classes/src/hooks/use-filters.ts"),b=t("./packages/packages/core/editor-global-classes/src/save-global-classes.tsx"),f=t("./packages/packages/core/editor-global-classes/src/store.ts"),y=t("./packages/packages/core/editor-global-classes/src/components/search-and-filter/components/filter/active-filters.tsx"),k=t("./packages/packages/core/editor-global-classes/src/components/search-and-filter/components/filter/css-class-filter.tsx"),v=t("./packages/packages/core/editor-global-classes/src/components/search-and-filter/components/search/class-manager-search.tsx"),C=t("./packages/packages/core/editor-global-classes/src/components/search-and-filter/context.tsx"),x=t("./packages/packages/core/editor-global-classes/src/components/class-manager/class-manager-introduction.tsx"),_=t("./packages/packages/core/editor-global-classes/src/components/class-manager/delete-class.ts"),E=t("./packages/packages/core/editor-global-classes/src/components/class-manager/flipped-color-swatch-icon.tsx"),w=t("./packages/packages/core/editor-global-classes/src/components/class-manager/global-classes-list.tsx"),S=t("./packages/packages/core/editor-global-classes/src/components/class-manager/panel-interactions.ts");function _extends(){return _extends=Object.assign?Object.assign.bind():function(e){for(var s=1;s<arguments.length;s++){var t=arguments[s];for(var a in t)({}).hasOwnProperty.call(t,a)&&(e[a]=t[a])}return e},_extends.apply(null,arguments)}const I="global-classes-manager",{panel:D,usePanelActions:P}=(0,o.__createPanel)({id:I,component:ClassManagerPanel,allowedEditModes:["edit",I],onOpen:()=>{(0,l.changeEditMode)(I),(0,S.blockPanelInteractions)()},onClose:()=>{(0,l.changeEditMode)("edit"),(0,S.unblockPanelInteractions)()},isOpenPreviousElement:!0});function ClassManagerPanel(){const e=(0,m.useDirtyState)(),{close:s}=P(),{open:t,close:r,isOpen:l}=(0,n.useDialog)(),{mutateAsync:c,isPending:i}=usePublish();return usePreventUnload(),a.createElement(n.ThemeProvider,null,a.createElement(p.ErrorBoundary,{fallback:a.createElement(ErrorBoundaryFallback,null)},a.createElement(o.Panel,null,a.createElement(C.SearchAndFilterProvider,null,a.createElement(o.PanelHeader,null,a.createElement(p.Stack,{p:1,pl:2,width:"100%",direction:"row",alignItems:"center"},a.createElement(p.Stack,{width:"100%",direction:"row",gap:1},a.createElement(o.PanelHeaderTitle,{sx:{display:"flex",alignItems:"center",gap:.5}},a.createElement(E.FlippedColorSwatchIcon,{fontSize:"inherit"}),(0,u.__)("Class Manager","elementor")),a.createElement(TotalCssClassCounter,null)),a.createElement(CloseButton,{sx:{marginLeft:"auto"},disabled:i,onClose:()=>{e?t():s()}}))),a.createElement(o.PanelBody,{sx:{display:"flex",flexDirection:"column",height:"100%"}},a.createElement(p.Box,{px:2,pb:1},a.createElement(p.Stack,{direction:"row",justifyContent:"spaceBetween",gap:.5,sx:{pb:.5}},a.createElement(p.Box,{sx:{flexGrow:1}},a.createElement(v.ClassManagerSearch,null)),a.createElement(k.CssClassFilter,null)),a.createElement(y.ActiveFilters,null)),a.createElement(p.Divider,null),a.createElement(p.Box,{px:2,sx:{flexGrow:1,overflowY:"auto"}},a.createElement(w.GlobalClassesList,{disabled:i}))),a.createElement(o.PanelFooter,null,a.createElement(p.Button,{fullWidth:!0,size:"small",color:"global",variant:"contained",onClick:c,disabled:!e,loading:i},(0,u.__)("Save changes","elementor")))))),a.createElement(x.ClassManagerIntroduction,null),l&&a.createElement(n.SaveChangesDialog,null,a.createElement(p.DialogHeader,{onClose:r,logo:!1},a.createElement(n.SaveChangesDialog.Title,null,(0,u.__)("You have unsaved changes","elementor"))),a.createElement(n.SaveChangesDialog.Content,null,a.createElement(n.SaveChangesDialog.ContentText,null,(0,u.__)("You have unsaved changes in the Class Manager.","elementor")),a.createElement(n.SaveChangesDialog.ContentText,null,(0,u.__)("To avoid losing your updates, save your changes before leaving.","elementor"))),a.createElement(n.SaveChangesDialog.Actions,{actions:{discard:{label:(0,u.__)("Discard","elementor"),action:()=>{(0,d.__dispatch)(f.slice.actions.resetToInitialState({context:"frontend"})),r()}},confirm:{label:(0,u.__)("Save & Continue","elementor"),action:async()=>{await c(),r(),s()}}}})))}const CloseButton=({onClose:e,...s})=>a.createElement(p.IconButton,_extends({size:"small",color:"secondary",onClick:e,"aria-label":"Close"},s),a.createElement(c.XIcon,{fontSize:"small"})),ErrorBoundaryFallback=()=>a.createElement(p.Box,{role:"alert",sx:{minHeight:"100%",p:2}},a.createElement(p.Alert,{severity:"error",sx:{mb:2,maxWidth:400,textAlign:"center"}},a.createElement("strong",null,(0,u.__)("Something went wrong","elementor")))),usePreventUnload=()=>{const e=(0,m.useDirtyState)();(0,a.useEffect)(()=>{const handleBeforeUnload=s=>{e&&s.preventDefault()};return window.addEventListener("beforeunload",handleBeforeUnload),()=>{window.removeEventListener("beforeunload",handleBeforeUnload)}},[e])},usePublish=()=>(0,i.useMutation)({mutationFn:()=>(0,b.saveGlobalClasses)({context:"frontend"}),onSuccess:async()=>{(0,r.setDocumentModifiedStatus)(!1),(0,_.hasDeletedItems)()&&await(0,_.onDelete)()}}),TotalCssClassCounter=()=>{const e=(0,h.useFilters)(),s=(0,g.useClassesOrder)();return a.createElement(p.Chip,{size:"small",label:e?`${e.length} / ${s?.length}`:s?.length})}},"./packages/packages/core/editor-global-classes/src/components/class-manager/delete-class.ts":function(e,s,t){t.r(s),t.d(s,{deleteClass:function(){return deleteClass},hasDeletedItems:function(){return hasDeletedItems},onDelete:function(){return onDelete}});var a=t("@elementor/editor-documents"),r=t("@elementor/editor-v1-adapters"),o=t("@elementor/store"),n=t("./packages/packages/core/editor-global-classes/src/store.ts"),l=t("./packages/packages/core/editor-global-classes/src/utils/tracking.ts");let c=!1;const deleteClass=e=>{(0,l.trackGlobalClasses)({event:"classDeleted",classId:e,runAction:()=>{(0,o.__dispatch)(n.slice.actions.delete(e)),c=!0}})},onDelete=async()=>{await reloadDocument(),c=!1},hasDeletedItems=()=>c,reloadDocument=()=>{const e=(0,a.getCurrentDocument)();return(0,a.getV1DocumentsManager)().invalidateCache(),(0,r.__privateRunCommand)("editor/documents/switch",{id:e?.id,shouldScroll:!1,shouldNavigateToDefaultRoute:!1})}},"./packages/packages/core/editor-global-classes/src/components/class-manager/delete-confirmation-dialog.tsx":function(e,s,t){t.r(s),t.d(s,{DeleteConfirmationProvider:function(){return DeleteConfirmationProvider},useDeleteConfirmation:function(){return useDeleteConfirmation}});var a=t("react"),r=t("@elementor/editor-ui"),o=t("@elementor/ui"),n=t("@wordpress/i18n"),l=t("./packages/packages/core/editor-global-classes/src/hooks/use-css-class-usage-by-id.ts"),c=t("./packages/packages/core/editor-global-classes/src/components/class-manager/delete-class.ts");const i=(0,a.createContext)(null),DeleteConfirmationProvider=({children:e})=>{const[s,t]=(0,a.useState)(null);return a.createElement(i.Provider,{value:{openDialog:e=>{t(e)},closeDialog:()=>{t(null)},dialogProps:s}},e,!!s&&a.createElement(DeleteClassDialog,s))},DeleteClassDialog=({label:e,id:s})=>{const{closeDialog:t}=useDeleteConfirmation(),{data:{total:i,content:d}}=(0,l.useCssClassUsageByID)(s),p=i&&d.length?(0,n.__)("Will permanently remove it from your project and may affect the design across all elements using it. Used %1 times across %2 pages. This action cannot be undone.","elementor").replace("%1",i.toString()).replace("%2",d.length.toString()):(0,n.__)("Will permanently remove it from your project and may affect the design across all elements using it. This action cannot be undone.","elementor");return a.createElement(r.ConfirmationDialog,{open:!0,onClose:t},a.createElement(r.ConfirmationDialog.Title,null,(0,n.__)("Delete this class?","elementor")),a.createElement(r.ConfirmationDialog.Content,null,a.createElement(r.ConfirmationDialog.ContentText,null,(0,n.__)("Deleting","elementor"),a.createElement(o.Typography,{variant:"subtitle2",component:"span"}," ",e," "),p)),a.createElement(r.ConfirmationDialog.Actions,{onClose:t,onConfirm:()=>{t(),(0,c.deleteClass)(s)}}))},useDeleteConfirmation=()=>{const e=(0,a.useContext)(i);if(!e)throw new Error("useDeleteConfirmation must be used within a DeleteConfirmationProvider");return e}},"./packages/packages/core/editor-global-classes/src/components/class-manager/duplicate-label-dialog.tsx":function(e,s,t){t.r(s),t.d(s,{DuplicateLabelDialog:function(){return DuplicateLabelDialog}});var a=t("react"),r=t("@elementor/editor-ui"),o=t("@elementor/icons"),n=t("@elementor/ui"),l=t("@wordpress/i18n");const c="DUP_",DuplicateLabelDialog=({modifiedLabels:e,onApprove:s})=>a.createElement(a.Fragment,null,a.createElement(n.DialogHeader,{logo:!1},a.createElement(n.Box,{display:"flex",alignItems:"center",gap:1},a.createElement(n.Icon,{color:"secondary"},a.createElement(o.InfoCircleFilledIcon,{fontSize:"medium"})),a.createElement(n.Typography,{variant:"subtitle1"},(0,l.__)("We've published your page and updated class names.","elementor")))),a.createElement(n.DialogContent,null,a.createElement(n.Stack,{spacing:2,direction:"column"},a.createElement(n.Typography,{variant:"body2"},(0,l.__)("Some new classes used the same names as existing ones. To prevent conflicts, we added the prefix","elementor"),a.createElement("strong",null," ",c)),a.createElement(n.Box,null,a.createElement(n.Box,{sx:{width:"100%",display:"flex",gap:2,alignItems:"flex-start"}},a.createElement(n.Typography,{variant:"subtitle2",sx:{fontWeight:"bold",flex:1,flexShrink:1,flexGrow:1,minWidth:0}},(0,l.__)("Before","elementor")),a.createElement(n.Typography,{variant:"subtitle2",sx:{minWidth:"200px",fontWeight:"bold",flexShrink:0,flexGrow:0,width:"200px",maxWidth:"200px"}},(0,l.__)("After","elementor"))),a.createElement(n.Divider,{sx:{mt:.5,mb:.5}}),a.createElement(n.Stack,{direction:"column",gap:.5,sx:{pb:2}},Object.values(e).map(({original:e,modified:s},t)=>a.createElement(n.Box,{key:t,sx:{width:"100%",display:"flex",gap:2,alignItems:"flex-start"}},a.createElement(n.Box,{sx:{flex:1,flexShrink:1,flexGrow:1,minWidth:0}},a.createElement(r.EllipsisWithTooltip,{title:e},a.createElement(n.Typography,{variant:"body2",sx:{color:"text.secondary"}},e))),a.createElement(n.Box,{sx:{minWidth:"200px",flexShrink:0,flexGrow:0,width:"200px",maxWidth:"200px"}},a.createElement(r.EllipsisWithTooltip,{title:s},a.createElement(n.Typography,{variant:"body2",sx:{color:"text.primary"}},s)))))),a.createElement(n.Box,null,a.createElement(n.Alert,{severity:"info",size:"small",color:"secondary"},a.createElement("strong",null,(0,l.__)("Your designs and classes are safe.","elementor")),(0,l.__)("Only the prefixes were added. Find them in Class Manager by searching","elementor"),a.createElement("strong",null,c)))))),a.createElement(n.DialogActions,null,a.createElement(n.Button,{color:"secondary",variant:"text",onClick:()=>{localStorage.setItem("elementor-global-classes-search",c),s?.(),(0,r.closeDialog)()}},(0,l.__)("Go to Class Manager","elementor")),a.createElement(n.Button,{color:"secondary",variant:"contained",onClick:r.closeDialog},(0,l.__)("Done","elementor"))))},"./packages/packages/core/editor-global-classes/src/components/class-manager/flipped-color-swatch-icon.tsx":function(e,s,t){t.r(s),t.d(s,{FlippedColorSwatchIcon:function(){return FlippedColorSwatchIcon}});var a=t("react"),r=t("@elementor/icons");function _extends(){return _extends=Object.assign?Object.assign.bind():function(e){for(var s=1;s<arguments.length;s++){var t=arguments[s];for(var a in t)({}).hasOwnProperty.call(t,a)&&(e[a]=t[a])}return e},_extends.apply(null,arguments)}const FlippedColorSwatchIcon=({sx:e,...s})=>a.createElement(r.ColorSwatchIcon,_extends({sx:{transform:"rotate(90deg)",...e}},s))},"./packages/packages/core/editor-global-classes/src/components/class-manager/global-classes-list.tsx":function(e,s,t){t.r(s),t.d(s,{GlobalClassesList:function(){return GlobalClassesList}});var a=t("react"),r=t("@elementor/store"),o=t("@elementor/ui"),n=t("@wordpress/i18n"),l=t("./packages/packages/core/editor-global-classes/src/hooks/use-classes-order.ts"),c=t("./packages/packages/core/editor-global-classes/src/hooks/use-filters.ts"),i=t("./packages/packages/core/editor-global-classes/src/hooks/use-ordered-classes.ts"),d=t("./packages/packages/core/editor-global-classes/src/store.ts"),p=t("./packages/packages/core/editor-global-classes/src/utils/tracking.ts"),u=t("./packages/packages/core/editor-global-classes/src/components/search-and-filter/context.tsx"),g=t("./packages/packages/core/editor-global-classes/src/components/class-manager/class-item.tsx"),m=t("./packages/packages/core/editor-global-classes/src/components/class-manager/delete-confirmation-dialog.tsx"),h=t("./packages/packages/core/editor-global-classes/src/components/class-manager/flipped-color-swatch-icon.tsx"),b=t("./packages/packages/core/editor-global-classes/src/components/class-manager/not-found.tsx"),f=t("./packages/packages/core/editor-global-classes/src/components/class-manager/sortable.tsx");const GlobalClassesList=({disabled:e})=>{const{search:{debouncedValue:s}}=(0,u.useSearchAndFilters)(),t=(0,i.useOrderedClasses)(),n=(0,r.__useDispatch)(),l=(0,c.useFilters)(),[h,y]=a.useState(null),k=t.find(e=>e.id===h)?.label??"",[v,C]=useReorder(h,y,k??""),x=useFilteredCssClasses();if((0,a.useEffect)(()=>{const handler=e=>{if("z"===e.key&&(e.ctrlKey||e.metaKey)){if(e.stopImmediatePropagation(),e.preventDefault(),e.shiftKey)return void n(d.slice.actions.redo());n(d.slice.actions.undo())}};return window.addEventListener("keydown",handler,{capture:!0}),()=>window.removeEventListener("keydown",handler)},[n]),!t?.length)return a.createElement(EmptyState,null);const _=(0,b.getNotFoundType)(s,l,x);if(_)return a.createElement(b.NotFound,{notFoundType:_});const E=l?.length||s,w=x.length>1&&!E;return a.createElement(m.DeleteConfirmationProvider,null,a.createElement(o.List,{sx:{display:"flex",flexDirection:"column",gap:.5}},a.createElement(f.SortableProvider,{value:v,onChange:C,disableDragOverlay:!w},x?.map(({id:s,label:t})=>a.createElement(f.SortableItem,{key:s,id:s},({isDragged:r,isDragPlaceholder:o,triggerProps:l,triggerStyle:c})=>(r&&!h&&y(s),a.createElement(g.ClassItem,{id:s,label:t,renameClass:e=>{(0,p.trackGlobalClasses)({event:"classRenamed",classId:s,oldValue:t,newValue:e,source:"class-manager"}),n(d.slice.actions.update({style:{id:s,label:e}}))},selected:r,disabled:e||o,sortableTriggerProps:{...l,style:c},showSortIndicator:w})))))))},EmptyState=()=>a.createElement(o.Stack,{alignItems:"center",gap:1.5,pt:10,px:.5,maxWidth:"260px",margin:"auto"},a.createElement(h.FlippedColorSwatchIcon,{fontSize:"large"}),a.createElement(y,{variant:"subtitle2",component:"h2",color:"text.secondary"},(0,n.__)("There are no global classes yet.","elementor")),a.createElement(o.Typography,{align:"center",variant:"caption",color:"text.secondary"},(0,n.__)("CSS classes created in the editor panel will appear here. Once they are available, you can arrange their hierarchy, rename them, or delete them as needed.","elementor"))),y=(0,o.styled)(o.Typography)(({theme:e,variant:s})=>({"&.MuiTypography-root":{...e.typography[s]}})),useReorder=(e,s,t)=>{const a=(0,r.__useDispatch)();return[(0,l.useClassesOrder)(),r=>{a(d.slice.actions.setOrder(r)),e&&((0,p.trackGlobalClasses)({event:"classManagerReorder",classId:e,classTitle:t}),s(null))}]},useFilteredCssClasses=()=>{const e=(0,i.useOrderedClasses)(),{search:{debouncedValue:s}}=(0,u.useSearchAndFilters)(),t=(0,c.useFilters)(),r=(0,a.useMemo)(()=>e.map(e=>({...e,lowerLabel:e.label.toLowerCase()})),[e]),o=(0,a.useMemo)(()=>s.length>1?r.filter(e=>e.lowerLabel.includes(s.toLowerCase())):e,[s,e,r]);return(0,a.useMemo)(()=>t&&t.length>0?o.filter(e=>t.includes(e.id)):o,[o,t])}},"./packages/packages/core/editor-global-classes/src/components/class-manager/not-found.tsx":function(e,s,t){t.r(s),t.d(s,{NotFound:function(){return NotFound},NotFoundLayout:function(){return NotFoundLayout},getNotFoundType:function(){return getNotFoundType}});var a=t("react"),r=t("@elementor/icons"),o=t("@elementor/ui"),n=t("@wordpress/i18n"),l=t("./packages/packages/core/editor-global-classes/src/components/search-and-filter/context.tsx");function _extends(){return _extends=Object.assign?Object.assign.bind():function(e){for(var s=1;s<arguments.length;s++){var t=arguments[s];for(var a in t)({}).hasOwnProperty.call(t,a)&&(e[a]=t[a])}return e},_extends.apply(null,arguments)}const getNotFoundType=(e,s,t)=>{const a=t.length<=0&&e.length>1,r=s&&0===s.length;return a&&r?"filterAndSearch":a?"search":r?"filter":void 0},c={filterAndSearch:{mainText:(0,n.__)("Sorry, nothing matched.","elementor"),sceneryText:(0,n.__)("Try something else.","elementor"),icon:a.createElement(r.PhotoIcon,{color:"inherit",fontSize:"large"})},search:{mainText:(0,n.__)("Sorry, nothing matched","elementor"),sceneryText:(0,n.__)("Clear your input and try something else.","elementor"),icon:a.createElement(r.PhotoIcon,{color:"inherit",fontSize:"large"})},filter:{mainText:(0,n.__)("Sorry, nothing matched that search.","elementor"),sceneryText:(0,n.__)("Clear the filters and try something else.","elementor"),icon:a.createElement(r.ColorSwatchIcon,{color:"inherit",fontSize:"large"})}},NotFound=({notFoundType:e})=>{const{search:{onClearSearch:s,inputValue:t},filters:{onClearFilter:r}}=(0,l.useSearchAndFilters)();switch(e){case"filter":return a.createElement(NotFoundLayout,_extends({},c.filter,{onClear:r}));case"search":return a.createElement(NotFoundLayout,_extends({},c.search,{searchValue:t,onClear:s}));case"filterAndSearch":return a.createElement(NotFoundLayout,_extends({},c.filterAndSearch,{onClear:()=>{r(),s()}}))}},NotFoundLayout=({onClear:e,searchValue:s,mainText:t,sceneryText:r,icon:l})=>a.createElement(o.Stack,{color:"text.secondary",pt:5,alignItems:"center",gap:1,overflow:"hidden",justifySelf:"center"},l,a.createElement(o.Box,{sx:{width:"100%"}},a.createElement(o.Typography,{align:"center",variant:"subtitle2",color:"inherit"},t),s&&a.createElement(o.Typography,{variant:"subtitle2",color:"inherit",sx:{display:"flex",width:"100%",justifyContent:"center"}},a.createElement("span",null,"“"),a.createElement("span",{style:{maxWidth:"80%",overflow:"hidden",textOverflow:"ellipsis"}},s),a.createElement("span",null,"”."))),a.createElement(o.Typography,{align:"center",variant:"caption",color:"inherit"},r),a.createElement(o.Typography,{align:"center",variant:"caption",color:"inherit"},a.createElement(o.Link,{color:"secondary",variant:"caption",component:"button",onClick:e},(0,n.__)("Clear & try again","elementor"))))},"./packages/packages/core/editor-global-classes/src/components/class-manager/panel-interactions.ts":function(e,s,t){function blockPanelInteractions(){const e=window;e.$e?.components?.get?.("panel")?.blockUserInteractions?.()}function unblockPanelInteractions(){const e=window;e.$e?.components?.get?.("panel")?.unblockUserInteractions?.()}t.r(s),t.d(s,{blockPanelInteractions:function(){return blockPanelInteractions},unblockPanelInteractions:function(){return unblockPanelInteractions}})},"./packages/packages/core/editor-global-classes/src/components/class-manager/sortable.tsx":function(e,s,t){t.r(s),t.d(s,{SortableItem:function(){return SortableItem},SortableProvider:function(){return SortableProvider},SortableTrigger:function(){return SortableTrigger}});var a=t("react"),r=t("@elementor/icons"),o=t("@elementor/ui");function _extends(){return _extends=Object.assign?Object.assign.bind():function(e){for(var s=1;s<arguments.length;s++){var t=arguments[s];for(var a in t)({}).hasOwnProperty.call(t,a)&&(e[a]=t[a])}return e},_extends.apply(null,arguments)}const SortableProvider=e=>a.createElement(o.UnstableSortableProvider,_extends({restrictAxis:!0,variant:"static",dragPlaceholderStyle:{opacity:"1"}},e)),SortableTrigger=e=>a.createElement(n,_extends({},e,{role:"button",className:"class-item-sortable-trigger","aria-label":"sort"}),a.createElement(r.GripVerticalIcon,{fontSize:"tiny"})),SortableItem=({children:e,id:s,...t})=>a.createElement(o.UnstableSortableItem,_extends({},t,{id:s,render:({itemProps:s,isDragged:t,triggerProps:r,itemStyle:n,triggerStyle:c,dropIndicationStyle:i,showDropIndication:d,isDragOverlay:p,isDragPlaceholder:u})=>a.createElement(o.Box,_extends({},s,{style:n,component:"li",role:"listitem",sx:{backgroundColor:p?"background.paper":void 0}}),e({itemProps:s,isDragged:t,triggerProps:r,itemStyle:n,triggerStyle:c,isDragPlaceholder:u}),d&&a.createElement(l,{style:i}))})),n=(0,o.styled)("div")(({theme:e})=>({position:"absolute",left:0,top:"50%",transform:`translate( -${e.spacing(1.5)}, -50% )`,color:e.palette.action.active})),l=(0,o.styled)(o.Box)`
2249 3 width: 100%;
2250 4 height: 1px;
2251 - background-color: ${({ theme }) => theme.palette.text.primary};
2252 -`;
2253 -
2254 -//#endregion
2255 -//#region packages/packages/core/editor-global-classes/src/components/class-manager/class-item.tsx
2256 - var ClassItem = ({ id, label, renameClass, selected, disabled, sortableTriggerProps, showSortIndicator, syncToV3, onToggleSync }) => {
2257 - const itemRef = (0, react.useRef)(null);
2258 - const { ref: editableRef, openEditMode, isEditing, error, getProps: getEditableProps } = (0, _elementor_editor_ui.useEditable)({
2259 - value: label,
2260 - onSubmit: renameClass,
2261 - validation: validateLabel
2262 - });
2263 - const [selectedCssUsage, setSelectedCssUsage] = (0, react.useState)("");
2264 - const { openDialog } = useDeleteConfirmation();
2265 - const popupState = (0, _elementor_ui.usePopupState)({
2266 - variant: "popover",
2267 - disableAutoFocus: true
2268 - });
2269 - const isSelected = (selectedCssUsage === id || selected || popupState.isOpen) && !disabled;
2270 - return /* @__PURE__ */ react.createElement(react.Fragment, null, /* @__PURE__ */ react.createElement(_elementor_ui.Stack, { p: 0 }, /* @__PURE__ */ react.createElement(_elementor_editor_ui.WarningInfotip, {
2271 - open: Boolean(error),
2272 - text: error ?? "",
2273 - placement: "bottom",
2274 - width: itemRef.current?.getBoundingClientRect().width,
2275 - offset: [0, -15]
2276 - }, /* @__PURE__ */ react.createElement(StyledListItemButton, {
2277 - ref: itemRef,
2278 - dense: true,
2279 - disableGutters: true,
2280 - showSortIndicator,
2281 - showActions: isSelected || isEditing,
2282 - shape: "rounded",
2283 - onDoubleClick: openEditMode,
2284 - selected: isSelected,
2285 - disabled,
2286 - focusVisibleClassName: "visible-class-item"
2287 - }, /* @__PURE__ */ react.createElement(SortableTrigger, { ...sortableTriggerProps }), /* @__PURE__ */ react.createElement(Indicator, {
2288 - isActive: isEditing,
2289 - isError: !!error
2290 - }, isEditing ? /* @__PURE__ */ react.createElement(_elementor_editor_ui.EditableField, {
2291 - ref: editableRef,
2292 - as: _elementor_ui.Typography,
2293 - variant: "caption",
2294 - ...getEditableProps()
2295 - }) : /* @__PURE__ */ react.createElement(_elementor_editor_ui.EllipsisWithTooltip, {
2296 - title: label,
2297 - as: _elementor_ui.Typography,
2298 - variant: "caption"
2299 - })), /* @__PURE__ */ react.createElement(_elementor_ui.Box, { className: "class-item-locator" }, /* @__PURE__ */ react.createElement(CssClassUsageTrigger, {
2300 - id,
2301 - onClick: setSelectedCssUsage
2302 - })), /* @__PURE__ */ react.createElement(_elementor_ui.Tooltip, {
2303 - placement: "top",
2304 - className: "class-item-more-actions",
2305 - title: (0, _wordpress_i18n.__)("More actions", "elementor")
2306 - }, /* @__PURE__ */ react.createElement(_elementor_ui.IconButton, {
2307 - size: "tiny",
2308 - ...(0, _elementor_ui.bindTrigger)(popupState),
2309 - "aria-label": "More actions"
2310 - }, /* @__PURE__ */ react.createElement(_elementor_icons.DotsVerticalIcon, { fontSize: "tiny" })))))), /* @__PURE__ */ react.createElement(_elementor_ui.Menu, {
2311 - ...(0, _elementor_ui.bindMenu)(popupState),
2312 - anchorOrigin: {
2313 - vertical: "bottom",
2314 - horizontal: "right"
2315 - },
2316 - transformOrigin: {
2317 - vertical: "top",
2318 - horizontal: "right"
2319 - }
2320 - }, /* @__PURE__ */ react.createElement(_elementor_editor_ui.MenuListItem, {
2321 - sx: { minWidth: "160px" },
2322 - onClick: () => {
2323 - popupState.close();
2324 - openEditMode();
2325 - }
2326 - }, /* @__PURE__ */ react.createElement(_elementor_ui.Typography, {
2327 - variant: "caption",
2328 - sx: { color: "text.primary" }
2329 - }, (0, _wordpress_i18n.__)("Rename", "elementor"))), onToggleSync && /* @__PURE__ */ react.createElement(_elementor_editor_ui.MenuListItem, { onClick: () => {
2330 - popupState.close();
2331 - onToggleSync(id, !syncToV3);
2332 - } }, /* @__PURE__ */ react.createElement(_elementor_ui.Stack, {
2333 - direction: "row",
2334 - alignItems: "center",
2335 - gap: 1
2336 - }, syncToV3 ? /* @__PURE__ */ react.createElement(_elementor_icons.RefreshOffIcon, { fontSize: "tiny" }) : /* @__PURE__ */ react.createElement(_elementor_icons.RefreshIcon, { fontSize: "tiny" }), /* @__PURE__ */ react.createElement(_elementor_ui.Typography, {
2337 - variant: "caption",
2338 - sx: { color: "text.primary" }
2339 - }, syncToV3 ? (0, _wordpress_i18n.__)("Stop syncing to Global Fonts", "elementor") : (0, _wordpress_i18n.__)("Sync to Global Fonts", "elementor")))), /* @__PURE__ */ react.createElement(_elementor_editor_ui.MenuListItem, { onClick: () => {
2340 - popupState.close();
2341 - openDialog({
2342 - id,
2343 - label
2344 - });
2345 - } }, /* @__PURE__ */ react.createElement(_elementor_ui.Typography, {
2346 - variant: "caption",
2347 - sx: { color: "error.light" }
2348 - }, (0, _wordpress_i18n.__)("Delete", "elementor")))));
2349 - };
2350 - var StyledListItemButton = (0, _elementor_ui.styled)(_elementor_ui.ListItemButton, { shouldForwardProp: (prop) => !["showActions", "showSortIndicator"].includes(prop) })(({ showActions, showSortIndicator }) => `
2351 - min-height: 36px;
2352 -
2353 - &.visible-class-item {
2354 - box-shadow: none !important;
2355 - }
2356 -
2357 - .class-item-locator {
2358 - visibility: hidden;
2359 - }
2360 -
2361 - .class-item-sortable-trigger {
2362 - visibility: ${showSortIndicator && showActions ? "visible" : "hidden"};
2363 - }
2364 -
2365 - &:hover:not(:disabled) {
2366 - .class-item-locator {
2367 - visibility: visible;
2368 - }
2369 -
2370 - .class-item-sortable-trigger {
2371 - visibility: ${showSortIndicator ? "visible" : "hidden"};
2372 - }
2373 - }
2374 - `);
2375 - var Indicator = (0, _elementor_ui.styled)(_elementor_ui.Box, { shouldForwardProp: (prop) => !["isActive", "isError"].includes(prop) })(({ theme, isActive, isError }) => ({
2376 - display: "flex",
2377 - width: "100%",
2378 - flexGrow: 1,
2379 - borderRadius: theme.spacing(.5),
2380 - border: getIndicatorBorder({
2381 - isActive,
2382 - isError,
2383 - theme
2384 - }),
2385 - padding: `0 ${theme.spacing(1)}`,
2386 - marginLeft: isActive ? theme.spacing(1) : 0,
2387 - minWidth: 0
2388 - }));
2389 - var getIndicatorBorder = ({ isActive, isError, theme }) => {
2390 - if (isError) return `2px solid ${theme.palette.error.main}`;
2391 - if (isActive) return `2px solid ${theme.palette.secondary.main}`;
2392 - return "none";
2393 - };
2394 - var validateLabel = (newLabel) => {
2395 - const result = (0, _elementor_editor_styles_repository.validateStyleLabel)(newLabel, "rename");
2396 - if (result.isValid) return null;
2397 - return result.errorMessage;
2398 - };
2399 -
2400 -//#endregion
2401 -//#region packages/packages/core/editor-global-classes/src/components/class-manager/not-found.tsx
2402 - var getNotFoundType = (searchValue, filters, filteredClasses) => {
2403 - const searchNotFound = filteredClasses.length <= 0 && searchValue.length > 1;
2404 - const filterNotFound = filters && filters.length === 0;
2405 - if (searchNotFound && filterNotFound) return "filterAndSearch";
2406 - if (searchNotFound) return "search";
2407 - if (filterNotFound) return "filter";
2408 - };
2409 - var notFound = {
2410 - filterAndSearch: {
2411 - mainText: (0, _wordpress_i18n.__)("Sorry, nothing matched.", "elementor"),
2412 - sceneryText: (0, _wordpress_i18n.__)("Try something else.", "elementor"),
2413 - icon: /* @__PURE__ */ react.createElement(_elementor_icons.PhotoIcon, {
2414 - color: "inherit",
2415 - fontSize: "large"
2416 - })
2417 - },
2418 - search: {
2419 - mainText: (0, _wordpress_i18n.__)("Sorry, nothing matched", "elementor"),
2420 - sceneryText: (0, _wordpress_i18n.__)("Clear your input and try something else.", "elementor"),
2421 - icon: /* @__PURE__ */ react.createElement(_elementor_icons.PhotoIcon, {
2422 - color: "inherit",
2423 - fontSize: "large"
2424 - })
2425 - },
2426 - filter: {
2427 - mainText: (0, _wordpress_i18n.__)("Sorry, nothing matched that search.", "elementor"),
2428 - sceneryText: (0, _wordpress_i18n.__)("Clear the filters and try something else.", "elementor"),
2429 - icon: /* @__PURE__ */ react.createElement(_elementor_icons.ColorSwatchIcon, {
2430 - color: "inherit",
2431 - fontSize: "large"
2432 - })
2433 - }
2434 - };
2435 - var NotFound = ({ notFoundType }) => {
2436 - const { search: { onClearSearch, inputValue }, filters: { onClearFilter } } = useSearchAndFilters();
2437 - switch (notFoundType) {
2438 - case "filter": return /* @__PURE__ */ react.createElement(NotFoundLayout, {
2439 - ...notFound.filter,
2440 - onClear: onClearFilter
2441 - });
2442 - case "search": return /* @__PURE__ */ react.createElement(NotFoundLayout, {
2443 - ...notFound.search,
2444 - searchValue: inputValue,
2445 - onClear: onClearSearch
2446 - });
2447 - case "filterAndSearch": return /* @__PURE__ */ react.createElement(NotFoundLayout, {
2448 - ...notFound.filterAndSearch,
2449 - onClear: () => {
2450 - onClearFilter();
2451 - onClearSearch();
2452 - }
2453 - });
2454 - }
2455 - };
2456 - var NotFoundLayout = ({ onClear, searchValue, mainText, sceneryText, icon }) => /* @__PURE__ */ react.createElement(_elementor_ui.Stack, {
2457 - color: "text.secondary",
2458 - pt: 5,
2459 - alignItems: "center",
2460 - gap: 1,
2461 - overflow: "hidden",
2462 - justifySelf: "center"
2463 - }, icon, /* @__PURE__ */ react.createElement(_elementor_ui.Box, { sx: { width: "100%" } }, /* @__PURE__ */ react.createElement(_elementor_ui.Typography, {
2464 - align: "center",
2465 - variant: "subtitle2",
2466 - color: "inherit"
2467 - }, mainText), searchValue && /* @__PURE__ */ react.createElement(_elementor_ui.Typography, {
2468 - variant: "subtitle2",
2469 - color: "inherit",
2470 - sx: {
2471 - display: "flex",
2472 - width: "100%",
2473 - justifyContent: "center"
2474 - }
2475 - }, /* @__PURE__ */ react.createElement("span", null, "“"), /* @__PURE__ */ react.createElement("span", { style: {
2476 - maxWidth: "80%",
2477 - overflow: "hidden",
2478 - textOverflow: "ellipsis"
2479 - } }, searchValue), /* @__PURE__ */ react.createElement("span", null, "”."))), /* @__PURE__ */ react.createElement(_elementor_ui.Typography, {
2480 - align: "center",
2481 - variant: "caption",
2482 - color: "inherit"
2483 - }, sceneryText), /* @__PURE__ */ react.createElement(_elementor_ui.Typography, {
2484 - align: "center",
2485 - variant: "caption",
2486 - color: "inherit"
2487 - }, /* @__PURE__ */ react.createElement(_elementor_ui.Link, {
2488 - color: "secondary",
2489 - variant: "caption",
2490 - component: "button",
2491 - onClick: onClear
2492 - }, (0, _wordpress_i18n.__)("Clear & try again", "elementor"))));
2493 -
2494 -//#endregion
2495 -//#region packages/packages/core/editor-global-classes/src/components/class-manager/global-classes-list.tsx
2496 - var ROW_HEIGHT = 40;
2497 - var OVERSCAN = 6;
2498 - var GlobalClassesList = ({ disabled, scrollElement, onStopSyncRequest, onStartSyncRequest }) => {
2499 - const { search: { debouncedValue: searchValue } } = useSearchAndFilters();
2500 - const cssClasses = useOrderedClasses();
2501 - const dispatch = (0, _elementor_store.__useDispatch)();
2502 - const filters = useFilters();
2503 - const [draggedItemId, setDraggedItemId] = (0, react.useState)(null);
2504 - const [loading, setLoading] = (0, react.useState)({});
2505 - const addLoadingClass = (classId) => setLoading((prev) => ({
2506 - ...prev,
2507 - [classId]: true
2508 - }));
2509 - const removeLoadingClass = (classId) => setLoading((prev) => {
2510 - const { [classId]: _, ...rest } = prev;
2511 - return rest;
2512 - });
2513 - const draggedItemLabel = cssClasses.find((cssClass) => cssClass.id === draggedItemId)?.label ?? "";
2514 - const [classesOrder, reorderClasses] = useReorder(draggedItemId, setDraggedItemId, draggedItemLabel ?? "");
2515 - const filteredCssClasses = useFilteredCssClasses();
2516 - const virtualizer = useVirtualizer({
2517 - count: filteredCssClasses.length,
2518 - getScrollElement: () => scrollElement ?? null,
2519 - estimateSize: () => ROW_HEIGHT,
2520 - overscan: OVERSCAN,
2521 - getItemKey: (index) => filteredCssClasses[index].id,
2522 - rangeExtractor: (range) => {
2523 - const indices = new Set(defaultRangeExtractor(range));
2524 - if (draggedItemId) {
2525 - const draggedItemIndex = filteredCssClasses.findIndex((cssClass) => cssClass.id === draggedItemId);
2526 - if (draggedItemIndex >= 0) indices.add(draggedItemIndex);
2527 - }
2528 - return [...indices].sort((a, b) => a - b);
2529 - }
2530 - });
2531 - (0, react.useEffect)(() => {
2532 - const handler = (event) => {
2533 - if (event.key === "z" && (event.ctrlKey || event.metaKey)) {
2534 - event.stopImmediatePropagation();
2535 - event.preventDefault();
2536 - if (event.shiftKey) {
2537 - dispatch(slice.actions.redo());
2538 - return;
2539 - }
2540 - dispatch(slice.actions.undo());
2541 - }
2542 - };
2543 - window.addEventListener("keydown", handler, { capture: true });
2544 - return () => window.removeEventListener("keydown", handler);
2545 - }, [dispatch]);
2546 - if (!cssClasses?.length) return /* @__PURE__ */ react.createElement(EmptyState, null);
2547 - const notFoundType = getNotFoundType(searchValue, filters, filteredCssClasses);
2548 - if (notFoundType) return /* @__PURE__ */ react.createElement(NotFound, { notFoundType });
2549 - const isFiltersApplied = filters?.length || searchValue;
2550 - const allowSorting = filteredCssClasses.length > 1 && !isFiltersApplied;
2551 - return /* @__PURE__ */ react.createElement(DeleteConfirmationProvider, null, /* @__PURE__ */ react.createElement(_elementor_ui.List, { sx: {
2552 - position: "relative",
2553 - display: "block",
2554 - height: virtualizer.getTotalSize(),
2555 - padding: 0
2556 - } }, /* @__PURE__ */ react.createElement(SortableProvider, {
2557 - value: classesOrder,
2558 - onChange: reorderClasses,
2559 - onDragStart: (event) => setDraggedItemId(event.active.id),
2560 - onDragEnd: () => setDraggedItemId(null),
2561 - onDragCancel: () => setDraggedItemId(null),
2562 - disableDragOverlay: !allowSorting
2563 - }, virtualizer.getVirtualItems().map((virtualRow) => {
2564 - const cssClass = filteredCssClasses[virtualRow.index];
2565 - return /* @__PURE__ */ react.createElement(SortableItem, {
2566 - key: virtualRow.key,
2567 - id: cssClass.id,
2568 - style: {
2569 - position: "absolute",
2570 - top: virtualRow.start,
2571 - left: 0,
2572 - width: "100%"
2573 - }
2574 - }, ({ isDragged, isDragPlaceholder, triggerProps, triggerStyle }) => /* @__PURE__ */ react.createElement(ClassItem, {
2575 - id: cssClass.id,
2576 - label: cssClass.label,
2577 - renameClass: async (newLabel) => {
2578 - addLoadingClass(cssClass.id);
2579 - try {
2580 - trackGlobalClasses({
2581 - event: "classRenamed",
2582 - classId: cssClass.id,
2583 - oldValue: cssClass.label,
2584 - newValue: newLabel,
2585 - source: "class-manager"
2586 - });
2587 - await loadExistingClasses([cssClass.id]);
2588 - dispatch(slice.actions.update({ style: {
2589 - id: cssClass.id,
2590 - label: newLabel
2591 - } }));
2592 - } finally {
2593 - removeLoadingClass(cssClass.id);
2594 - }
2595 - },
2596 - selected: isDragged,
2597 - disabled: disabled || isDragPlaceholder || loading[cssClass.id],
2598 - sortableTriggerProps: {
2599 - ...triggerProps,
2600 - style: triggerStyle
2601 - },
2602 - showSortIndicator: allowSorting,
2603 - syncToV3: cssClass.sync_to_v3,
2604 - onToggleSync: (id, newValue) => {
2605 - if (!newValue && onStopSyncRequest) onStopSyncRequest(id);
2606 - else if (newValue && onStartSyncRequest) onStartSyncRequest(id);
2607 - else dispatch(slice.actions.update({ style: {
2608 - id,
2609 - sync_to_v3: newValue
2610 - } }));
2611 - }
2612 - }));
2613 - }))));
2614 - };
2615 - var EmptyState = () => /* @__PURE__ */ react.createElement(_elementor_ui.Stack, {
2616 - alignItems: "center",
2617 - gap: 1.5,
2618 - pt: 10,
2619 - px: .5,
2620 - maxWidth: "260px",
2621 - margin: "auto"
2622 - }, /* @__PURE__ */ react.createElement(FlippedColorSwatchIcon, { fontSize: "large" }), /* @__PURE__ */ react.createElement(StyledHeader, {
2623 - variant: "subtitle2",
2624 - component: "h2",
2625 - color: "text.secondary"
2626 - }, (0, _wordpress_i18n.__)("There are no global classes yet.", "elementor")), /* @__PURE__ */ react.createElement(_elementor_ui.Typography, {
2627 - align: "center",
2628 - variant: "caption",
2629 - color: "text.secondary"
2630 - }, (0, _wordpress_i18n.__)("CSS classes created in the editor panel will appear here. Once they are available, you can arrange their hierarchy, rename them, or delete them as needed.", "elementor")));
2631 - var StyledHeader = (0, _elementor_ui.styled)(_elementor_ui.Typography)(({ theme, variant }) => ({ "&.MuiTypography-root": { ...theme.typography[variant] } }));
2632 - var useReorder = (draggedItemId, setDraggedItemId, draggedItemLabel) => {
2633 - const dispatch = (0, _elementor_store.__useDispatch)();
2634 - const order = useClassesOrder();
2635 - const reorder = (newIds) => {
2636 - dispatch(slice.actions.setOrder(newIds));
2637 - if (draggedItemId) {
2638 - trackGlobalClasses({
2639 - event: "classManagerReorder",
2640 - classId: draggedItemId,
2641 - classTitle: draggedItemLabel
2642 - });
2643 - setDraggedItemId(null);
2644 - }
2645 - };
2646 - return [order, reorder];
2647 - };
2648 - var useFilteredCssClasses = () => {
2649 - const cssClasses = useOrderedClasses();
2650 - const { search: { debouncedValue: searchValue } } = useSearchAndFilters();
2651 - const filters = useFilters();
2652 - const lowercaseLabels = (0, react.useMemo)(() => cssClasses.map((cssClass) => ({
2653 - ...cssClass,
2654 - lowerLabel: cssClass.label.toLowerCase()
2655 - })), [cssClasses]);
2656 - const filteredClasses = (0, react.useMemo)(() => {
2657 - const normalizedSearch = searchValue.replace(/[^a-zA-Z0-9_-]/g, "").toLowerCase();
2658 - if (normalizedSearch.length > 1) return lowercaseLabels.filter((cssClass) => cssClass.lowerLabel.includes(normalizedSearch));
2659 - return cssClasses;
2660 - }, [
2661 - searchValue,
2662 - cssClasses,
2663 - lowercaseLabels
2664 - ]);
2665 - return (0, react.useMemo)(() => {
2666 - if (filters && filters.length > 0) return filteredClasses.filter((cssClass) => filters.includes(cssClass.id));
2667 - return filteredClasses;
2668 - }, [filteredClasses, filters]);
2669 - };
2670 -
2671 -//#endregion
2672 -//#region packages/packages/core/editor-global-classes/src/components/class-manager/panel-interactions.ts
2673 - function blockPanelInteractions() {
2674 - window.$e?.components?.get?.("panel")?.blockUserInteractions?.();
2675 - }
2676 - function unblockPanelInteractions() {
2677 - window.$e?.components?.get?.("panel")?.unblockUserInteractions?.();
2678 - }
2679 -
2680 -//#endregion
2681 -//#region packages/packages/core/editor-global-classes/src/components/class-manager/start-sync-to-v3-modal.tsx
2682 - var IMAGE_URL = "https://assets.elementor.com/packages/v1/images/class-manager-sync-modal.png";
2683 - var StartSyncToV3Modal = ({ externalOpen, classId, onExternalClose, onConfirm } = {}) => {
2684 - const [shouldShowAgain, setShouldShowAgain] = (0, react.useState)(true);
2685 - const hasTrackedExposure = (0, react.useRef)(false);
2686 - (0, react.useEffect)(() => {
2687 - if (externalOpen && classId && !hasTrackedExposure.current) {
2688 - hasTrackedExposure.current = true;
2689 - trackGlobalClasses({
2690 - event: "classSyncToV3PopupShown",
2691 - classId
2692 - });
2693 - }
2694 - if (!externalOpen) hasTrackedExposure.current = false;
2695 - }, [externalOpen, classId]);
2696 - const handleClose = () => {
2697 - if (classId) trackGlobalClasses({
2698 - event: "classSyncToV3PopupClick",
2699 - classId,
2700 - action: "cancel"
2701 - });
2702 - onExternalClose?.();
2703 - };
2704 - const handleConfirm = () => {
2705 - if (classId) trackGlobalClasses({
2706 - event: "classSyncToV3PopupClick",
2707 - classId,
2708 - action: "sync"
2709 - });
2710 - onConfirm?.();
2711 - onExternalClose?.();
2712 - };
2713 - return /* @__PURE__ */ react.createElement(_elementor_ui.Dialog, {
2714 - open: !!externalOpen,
2715 - onClose: handleClose,
2716 - maxWidth: "sm",
2717 - fullWidth: true
2718 - }, /* @__PURE__ */ react.createElement(_elementor_ui.DialogContent, { sx: { p: 0 } }, /* @__PURE__ */ react.createElement(_elementor_ui.Box, {
2719 - component: "img",
2720 - src: IMAGE_URL,
2721 - alt: "",
2722 - sx: {
2723 - width: "100%",
2724 - display: "block"
2725 - }
2726 - }), /* @__PURE__ */ react.createElement(_elementor_ui.Box, { sx: {
2727 - px: 3,
2728 - pt: 4,
2729 - pb: 1
2730 - } }, /* @__PURE__ */ react.createElement(_elementor_ui.Typography, { variant: "h6" }, (0, _wordpress_i18n.__)("Sync class to Global Fonts", "elementor")), /* @__PURE__ */ react.createElement(_elementor_ui.Typography, {
2731 - variant: "body2",
2732 - color: "secondary",
2733 - sx: {
2734 - mb: 2,
2735 - pt: 1
2736 - }
2737 - }, (0, _wordpress_i18n.__)("Only typography settings supported in Global Fonts will be applied, including: font family, responsive font sizes, weight, text transform, decoration, line height, letter spacing, and word spacing. Changes made in the class will automatically apply to Global Fonts.", "elementor")))), /* @__PURE__ */ react.createElement(_elementor_ui.DialogActions, { sx: {
2738 - justifyContent: "space-between",
2739 - px: 3,
2740 - pb: 2
2741 - } }, /* @__PURE__ */ react.createElement(_elementor_ui.FormControlLabel, {
2742 - control: /* @__PURE__ */ react.createElement(_elementor_ui.Checkbox, {
2743 - checked: !shouldShowAgain,
2744 - onChange: (e) => setShouldShowAgain(!e.target.checked)
2745 - }),
2746 - label: /* @__PURE__ */ react.createElement(_elementor_ui.Typography, {
2747 - variant: "body2",
2748 - color: "secondary"
2749 - }, (0, _wordpress_i18n.__)("Don't show again", "elementor"))
2750 - }), /* @__PURE__ */ react.createElement(_elementor_ui.Box, { sx: {
2751 - display: "flex",
2752 - gap: 1
2753 - } }, /* @__PURE__ */ react.createElement(_elementor_ui.Button, {
2754 - onClick: handleClose,
2755 - color: "secondary",
2756 - size: "small"
2757 - }, (0, _wordpress_i18n.__)("Cancel", "elementor")), /* @__PURE__ */ react.createElement(_elementor_ui.Button, {
2758 - onClick: handleConfirm,
2759 - variant: "contained",
2760 - size: "small"
2761 - }, (0, _wordpress_i18n.__)("Sync to Global Fonts", "elementor")))));
2762 - };
2763 -
2764 -//#endregion
2765 -//#region packages/packages/core/editor-global-classes/src/components/class-manager/class-manager-panel.tsx
2766 - var STOP_SYNC_MESSAGE_KEY = "stop-sync-class";
2767 - function ClassManagerPanelEmbedded({ onRequestClose, onExposeCloseAttempt, isActive }) {
2768 - return /* @__PURE__ */ react.createElement(ClassManagerPanelContent, {
2769 - onRequestClose,
2770 - onExposeCloseAttempt,
2771 - isActive
2772 - });
2773 - }
2774 - function ClassManagerPanelContent({ onRequestClose, onExposeCloseAttempt, isActive = true }) {
2775 - const isDirty = useDirtyState();
2776 - const { open: openSaveChangesDialog, close: closeSaveChangesDialog, isOpen: isSaveChangesDialogOpen } = (0, _elementor_editor_ui.useDialog)();
2777 - const [stopSyncConfirmation, setStopSyncConfirmation] = (0, react.useState)(null);
2778 - const [startSyncConfirmation, setStartSyncConfirmation] = (0, react.useState)(null);
2779 - const [isStopSyncSuppressed] = (0, _elementor_editor_current_user.useSuppressedMessage)(STOP_SYNC_MESSAGE_KEY);
2780 - const [scrollElement, setScrollElement] = (0, react.useState)(null);
2781 - const { mutateAsync: publish, isPending: isPublishing } = usePublish();
2782 - const resetAndClosePanel = () => {
2783 - (0, _elementor_store.__dispatch)(slice.actions.resetToInitialState({ context: "frontend" }));
2784 - closeSaveChangesDialog();
2785 - };
2786 - const handleClosePanel = (0, react.useCallback)(() => {
2787 - if (isDirty) {
2788 - openSaveChangesDialog();
2789 - return;
2790 - }
2791 - onRequestClose();
2792 - }, [
2793 - isDirty,
2794 - openSaveChangesDialog,
2795 - onRequestClose
2796 - ]);
2797 - (0, react.useEffect)(() => {
2798 - if (!onExposeCloseAttempt) return;
2799 - onExposeCloseAttempt(() => handleClosePanel());
2800 - return () => onExposeCloseAttempt(null);
2801 - }, [onExposeCloseAttempt, handleClosePanel]);
2802 - (0, react.useEffect)(() => {
2803 - blockPanelInteractions();
2804 - return () => {
2805 - unblockPanelInteractions();
2806 - };
2807 - }, []);
2808 - const handleStopSync = (0, react.useCallback)(async (classId) => {
2809 - await loadExistingClasses([classId]);
2810 - (0, _elementor_store.__dispatch)(slice.actions.update({ style: {
2811 - id: classId,
2812 - sync_to_v3: false
2813 - } }));
2814 - trackGlobalClasses({
2815 - event: "classSyncToV3",
2816 - classId,
2817 - action: "unsync"
2818 - });
2819 - setStopSyncConfirmation(null);
2820 - }, []);
2821 - const handleStartSync = (0, react.useCallback)(async (classId) => {
2822 - await loadExistingClasses([classId]);
2823 - (0, _elementor_store.__dispatch)(slice.actions.update({ style: {
2824 - id: classId,
2825 - sync_to_v3: true
2826 - } }));
2827 - trackGlobalClasses({
2828 - event: "classSyncToV3",
2829 - classId,
2830 - action: "sync"
2831 - });
2832 - setStartSyncConfirmation(null);
2833 - }, []);
2834 - const handleStopSyncRequest = (0, react.useCallback)((classId) => {
2835 - if (!isStopSyncSuppressed) setStopSyncConfirmation(classId);
2836 - else handleStopSync(classId);
2837 - }, [isStopSyncSuppressed, handleStopSync]);
2838 - usePreventUnload();
2839 - return /* @__PURE__ */ react.createElement(react.Fragment, null, /* @__PURE__ */ react.createElement(_elementor_ui.ErrorBoundary, { fallback: /* @__PURE__ */ react.createElement(ErrorBoundaryFallback, null) }, /* @__PURE__ */ react.createElement(SearchAndFilterProvider, null, /* @__PURE__ */ react.createElement(_elementor_ui.Stack, {
2840 - direction: "column",
2841 - sx: {
2842 - height: "100%",
2843 - width: "100%",
2844 - flex: 1,
2845 - minHeight: 0,
2846 - overflow: "hidden"
2847 - }
2848 - }, /* @__PURE__ */ react.createElement(_elementor_ui.Box, {
2849 - px: 2,
2850 - pb: 1
2851 - }, /* @__PURE__ */ react.createElement(_elementor_ui.Stack, {
2852 - direction: "row",
2853 - alignItems: "center",
2854 - justifyContent: "space-between",
2855 - gap: .5,
2856 - sx: { pb: .5 }
2857 - }, /* @__PURE__ */ react.createElement(_elementor_ui.Box, { sx: {
2858 - flexGrow: 1,
2859 - minWidth: 0
2860 - } }, /* @__PURE__ */ react.createElement(ClassManagerSearch, null)), /* @__PURE__ */ react.createElement(CssClassFilter, null), /* @__PURE__ */ react.createElement(TotalCssClassCounter, null)), /* @__PURE__ */ react.createElement(ActiveFilters, null)), /* @__PURE__ */ react.createElement(_elementor_ui.Divider, null), /* @__PURE__ */ react.createElement(_elementor_ui.Box, {
2861 - ref: setScrollElement,
2862 - px: 2,
2863 - sx: {
2864 - flexGrow: 1,
2865 - overflowY: "auto",
2866 - minHeight: 0
2867 - }
2868 - }, /* @__PURE__ */ react.createElement(GlobalClassesList, {
2869 - disabled: isPublishing,
2870 - scrollElement,
2871 - onStopSyncRequest: handleStopSyncRequest,
2872 - onStartSyncRequest: (classId) => setStartSyncConfirmation(classId)
2873 - })), /* @__PURE__ */ react.createElement(_elementor_editor_panels.PanelFooter, null, /* @__PURE__ */ react.createElement(_elementor_ui.Button, {
2874 - fullWidth: true,
2875 - size: "small",
2876 - color: "global",
2877 - variant: "contained",
2878 - onClick: publish,
2879 - disabled: !isDirty,
2880 - loading: isPublishing
2881 - }, (0, _wordpress_i18n.__)("Save changes", "elementor")))))), isActive && /* @__PURE__ */ react.createElement(ClassManagerIntroduction, null), startSyncConfirmation && /* @__PURE__ */ react.createElement(StartSyncToV3Modal, {
2882 - externalOpen: true,
2883 - classId: startSyncConfirmation,
2884 - onExternalClose: () => setStartSyncConfirmation(null),
2885 - onConfirm: () => handleStartSync(startSyncConfirmation)
2886 - }), stopSyncConfirmation && /* @__PURE__ */ react.createElement(StopSyncConfirmationDialog, {
2887 - open: true,
2888 - onClose: () => setStopSyncConfirmation(null),
2889 - onConfirm: () => handleStopSync(stopSyncConfirmation)
2890 - }), isSaveChangesDialogOpen && /* @__PURE__ */ react.createElement(_elementor_editor_ui.SaveChangesDialog, null, /* @__PURE__ */ react.createElement(_elementor_ui.DialogHeader, {
2891 - onClose: closeSaveChangesDialog,
2892 - logo: false
2893 - }, /* @__PURE__ */ react.createElement(_elementor_editor_ui.SaveChangesDialog.Title, null, (0, _wordpress_i18n.__)("You have unsaved changes", "elementor"))), /* @__PURE__ */ react.createElement(_elementor_editor_ui.SaveChangesDialog.Content, null, /* @__PURE__ */ react.createElement(_elementor_editor_ui.SaveChangesDialog.ContentText, null, (0, _wordpress_i18n.__)("You have unsaved changes in the Class Manager.", "elementor")), /* @__PURE__ */ react.createElement(_elementor_editor_ui.SaveChangesDialog.ContentText, null, (0, _wordpress_i18n.__)("To avoid losing your updates, save your changes before leaving.", "elementor"))), /* @__PURE__ */ react.createElement(_elementor_editor_ui.SaveChangesDialog.Actions, { actions: {
2894 - discard: {
2895 - label: (0, _wordpress_i18n.__)("Discard", "elementor"),
2896 - action: () => {
2897 - resetAndClosePanel();
2898 - }
2899 - },
2900 - confirm: {
2901 - label: (0, _wordpress_i18n.__)("Save & Continue", "elementor"),
2902 - action: async () => {
2903 - await publish();
2904 - closeSaveChangesDialog();
2905 - onRequestClose();
2906 - }
2907 - }
2908 - } })));
2909 - }
2910 - var ErrorBoundaryFallback = () => /* @__PURE__ */ react.createElement(_elementor_ui.Box, {
2911 - role: "alert",
2912 - sx: {
2913 - minHeight: "100%",
2914 - p: 2
2915 - }
2916 - }, /* @__PURE__ */ react.createElement(_elementor_ui.Alert, {
2917 - severity: "error",
2918 - sx: {
2919 - mb: 2,
2920 - maxWidth: 400,
2921 - textAlign: "center"
2922 - }
2923 - }, /* @__PURE__ */ react.createElement("strong", null, (0, _wordpress_i18n.__)("Something went wrong", "elementor"))));
2924 - var usePreventUnload = () => {
2925 - const isDirty = useDirtyState();
2926 - (0, react.useEffect)(() => {
2927 - const handleBeforeUnload = (event) => {
2928 - if (isDirty) event.preventDefault();
2929 - };
2930 - window.addEventListener("beforeunload", handleBeforeUnload);
2931 - return () => {
2932 - window.removeEventListener("beforeunload", handleBeforeUnload);
2933 - };
2934 - }, [isDirty]);
2935 - };
2936 - var usePublish = () => {
2937 - return (0, _elementor_query.useMutation)({
2938 - mutationFn: () => saveGlobalClasses({ context: "frontend" }),
2939 - onSuccess: async () => {
2940 - (0, _elementor_editor_documents.setDocumentModifiedStatus)(false);
2941 - if (hasDeletedItems()) await onDelete();
2942 - }
2943 - });
2944 - };
2945 - var TotalCssClassCounter = () => {
2946 - const filters = useFilters();
2947 - const cssClasses = useClassesOrder();
2948 - return /* @__PURE__ */ react.createElement(_elementor_ui.Chip, {
2949 - size: "small",
2950 - label: filters ? `${filters.length} / ${cssClasses?.length}` : cssClasses?.length
2951 - });
2952 - };
2953 - var StopSyncConfirmationDialog = ({ open, onClose, onConfirm }) => {
2954 - const [, suppressStopSyncMessage] = (0, _elementor_editor_current_user.useSuppressedMessage)(STOP_SYNC_MESSAGE_KEY);
2955 - return /* @__PURE__ */ react.createElement(_elementor_editor_ui.ConfirmationDialog, {
2956 - open,
2957 - onClose
2958 - }, /* @__PURE__ */ react.createElement(_elementor_editor_ui.ConfirmationDialog.Title, {
2959 - icon: FlippedColorSwatchIcon,
2960 - iconColor: "primary"
2961 - }, (0, _wordpress_i18n.__)("Un-sync typography class", "elementor")), /* @__PURE__ */ react.createElement(_elementor_editor_ui.ConfirmationDialog.Content, null, /* @__PURE__ */ react.createElement(_elementor_editor_ui.ConfirmationDialog.ContentText, null, (0, _wordpress_i18n.__)("You're about to stop syncing a typography class to Global Fonts.", "elementor")), /* @__PURE__ */ react.createElement(_elementor_editor_ui.ConfirmationDialog.ContentText, { sx: { mt: 1 } }, (0, _wordpress_i18n.__)("Note that if it's being used anywhere, the affected elements will inherit the default typography.", "elementor"))), /* @__PURE__ */ react.createElement(_elementor_editor_ui.ConfirmationDialog.Actions, {
2962 - onClose,
2963 - onConfirm,
2964 - cancelLabel: (0, _wordpress_i18n.__)("Cancel", "elementor"),
2965 - confirmLabel: (0, _wordpress_i18n.__)("Got it", "elementor"),
2966 - color: "primary",
2967 - onSuppressMessage: suppressStopSyncMessage,
2968 - suppressLabel: (0, _wordpress_i18n.__)("Don't show again", "elementor")
2969 - }));
2970 - };
2971 -
2972 -//#endregion
2973 -//#region packages/packages/core/editor-global-classes/src/capabilities.ts
2974 - var UPDATE_CLASS_CAPABILITY_KEY = "elementor_global_classes_update_class";
2975 - var getCapabilities = () => {
2976 - return {
2977 - update: UPDATE_CLASS_CAPABILITY_KEY,
2978 - create: UPDATE_CLASS_CAPABILITY_KEY,
2979 - delete: UPDATE_CLASS_CAPABILITY_KEY,
2980 - updateProps: UPDATE_CLASS_CAPABILITY_KEY
2981 - };
2982 - };
2983 -
2984 -//#endregion
2985 -//#region packages/packages/core/editor-global-classes/src/global-classes-styles-provider.ts
2986 - var MAX_CLASSES = 1e3;
2987 - var GLOBAL_CLASSES_PROVIDER_KEY = "global-classes";
2988 - var PREGENERATED_LINK_PATTERN = /^global-([0-9]+-)?(preview|frontend)-[a-zA-Z_-]+-css$/;
2989 - var globalClassesStylesProvider = (0, _elementor_editor_styles_repository.createStylesProvider)({
2990 - key: GLOBAL_CLASSES_PROVIDER_KEY,
2991 - priority: 30,
2992 - limit: MAX_CLASSES,
2993 - isPregeneratedLink: ({ id }) => PREGENERATED_LINK_PATTERN.test(id),
2994 - labels: {
2995 - singular: (0, _wordpress_i18n.__)("class", "elementor"),
2996 - plural: (0, _wordpress_i18n.__)("classes", "elementor")
2997 - },
2998 - subscribe: (cb) => subscribeWithStates(cb),
2999 - capabilities: getCapabilities(),
3000 - actions: {
3001 - all: () => selectOrderedClasses((0, _elementor_store.__getState)()),
3002 - get: (id) => {
3003 - const state = (0, _elementor_store.__getState)();
3004 - const isFetched = selectIsClassFetched(state, id);
3005 - const style = selectClass(state, id);
3006 - if (isFetched || style) return style;
3007 - loadExistingClasses([id]);
3008 - return placeholderDefinition(id, selectClassLabels(state)[id] ?? id);
3009 - },
3010 - resolveCssName: (id) => {
3011 - const state = (0, _elementor_store.__getState)();
3012 - const loaded = selectClass(state, id);
3013 - if (loaded) return loaded.label;
3014 - return selectClassLabels(state)[id] ?? id;
3015 - },
3016 - create: (label, variants = [], id) => {
3017 - const existingClasses = Object.entries(selectClassLabels((0, _elementor_store.__getState)()));
3018 - if (existingClasses.map(([, classLabel]) => classLabel).includes(label)) throw new GlobalClassLabelAlreadyExistsError({ context: { label } });
3019 - const existingIds = existingClasses.map(([existingId]) => existingId);
3020 - if (!id) id = (0, _elementor_editor_styles.generateId)("g-", existingIds);
3021 - (0, _elementor_store.__dispatch)(slice.actions.add({
3022 - id,
3023 - type: "class",
3024 - label,
3025 - variants
3026 - }));
3027 - return id;
3028 - },
3029 - update: (payload) => {
3030 - (0, _elementor_store.__dispatch)(slice.actions.update({ style: payload }));
3031 - },
3032 - delete: (id) => {
3033 - (0, _elementor_store.__dispatch)(slice.actions.delete(id));
3034 - },
3035 - updateProps: (args) => {
3036 - (0, _elementor_store.__dispatch)(slice.actions.updateProps({
3037 - id: args.id,
3038 - meta: args.meta,
3039 - props: args.props,
3040 - mode: args.mode
3041 - }));
3042 - },
3043 - updateCustomCss: (args) => {
3044 - (0, _elementor_store.__dispatch)(slice.actions.updateProps({
3045 - id: args.id,
3046 - meta: args.meta,
3047 - custom_css: args.custom_css,
3048 - props: {}
3049 - }));
3050 - },
3051 - tracking: (data) => {
3052 - trackGlobalClasses(data).catch((error) => {
3053 - throw new GlobalClassTrackingError({ cause: error });
3054 - });
3055 - }
3056 - }
3057 - });
3058 - var subscribeWithStates = (cb) => {
3059 - let previousState = selectData((0, _elementor_store.__getState)());
3060 - return (0, _elementor_store.__subscribeWithSelector)((state) => selectData(state), (currentState) => {
3061 - cb(previousState.items, currentState.items);
3062 - previousState = currentState;
3063 - });
3064 - };
3065 -
3066 -//#endregion
3067 -//#region packages/packages/core/editor-global-classes/src/mcp-integration/classes-resource.ts
3068 - var GLOBAL_CLASSES_URI = "elementor://global-classes";
3069 - var STORAGE_KEY = "elementor-global-classes";
3070 - var updateLocalStorageCache = () => {
3071 - const classes = selectOrderedClasses((0, _elementor_store.__getState)());
3072 - localStorage.setItem(STORAGE_KEY, JSON.stringify(classes));
3073 - };
3074 - var initClassesResource = (classesMcpEntry, canvasMcpEntry) => {
3075 - [canvasMcpEntry, classesMcpEntry].forEach((entry) => {
3076 - const { sendResourceUpdated, resource, waitForReady } = entry;
3077 - resource("global-classes", GLOBAL_CLASSES_URI, { description: "Global classes list." }, async () => {
3078 - return { contents: [{
3079 - uri: GLOBAL_CLASSES_URI,
3080 - text: localStorage[STORAGE_KEY] ?? "[]"
3081 - }] };
3082 - });
3083 - waitForReady().then(() => {
3084 - updateLocalStorageCache();
3085 - globalClassesStylesProvider.subscribe(() => {
3086 - updateLocalStorageCache();
3087 - sendResourceUpdated({ uri: GLOBAL_CLASSES_URI });
3088 - });
3089 - });
3090 - });
3091 - };
3092 -
3093 -//#endregion
3094 -//#region packages/packages/core/editor-global-classes/src/hooks/use-prefetch-css-class-usage.ts
3095 - function usePrefetchCssClassUsage() {
3096 - const queryClient = (0, _elementor_query.useQueryClient)();
3097 - const prefetchClassesUsage = () => queryClient.prefetchQuery({
3098 - queryKey: [QUERY_KEY],
3099 - queryFn: fetchCssClassUsage
3100 - });
3101 - return { prefetchClassesUsage };
3102 - }
3103 - var PrefetchCssClassUsage = () => {
3104 - const { prefetchClassesUsage } = usePrefetchCssClassUsage();
3105 - prefetchClassesUsage();
3106 - return null;
3107 - };
3108 -
3109 -//#endregion
3110 -//#region packages/packages/core/editor-global-classes/src/components/class-manager/class-manager-button.tsx
3111 - var EVENT_TOGGLE_DESIGN_SYSTEM = "elementor/toggle-design-system";
3112 - var ClassManagerButton = () => {
3113 - const { prefetchClassesUsage } = usePrefetchCssClassUsage();
3114 - const { userCan } = (0, _elementor_editor_styles_repository.useUserStylesCapability)();
3115 - if (!userCan(globalClassesStylesProvider.getKey()).update) return null;
3116 - const handleOpenPanel = () => {
3117 - window.dispatchEvent(new CustomEvent(EVENT_TOGGLE_DESIGN_SYSTEM, { detail: { tab: "classes" } }));
3118 - trackGlobalClasses({
3119 - event: "classManagerOpened",
3120 - source: "style-panel"
3121 - });
3122 - prefetchClassesUsage();
3123 - };
3124 - return /* @__PURE__ */ react.createElement(_elementor_ui.Tooltip, {
3125 - title: (0, _wordpress_i18n.__)("Class Manager", "elementor"),
3126 - placement: "top"
3127 - }, /* @__PURE__ */ react.createElement(_elementor_ui.IconButton, {
3128 - size: "tiny",
3129 - onClick: handleOpenPanel,
3130 - sx: { marginInlineEnd: -.75 }
3131 - }, /* @__PURE__ */ react.createElement(FlippedColorSwatchIcon, { fontSize: "tiny" })));
3132 - };
3133 -
3134 -//#endregion
3135 -//#region packages/packages/core/editor-global-classes/src/components/convert-local-class-to-global-class.tsx
3136 - var ConvertLocalClassToGlobalClass = (props) => {
3137 - const localStyleData = props.styleDef;
3138 - const handleConversion = () => {
3139 - const newClassName = createClassName(`converted-class-`);
3140 - if (!localStyleData) throw new Error("Style definition is required for converting local class to global class.");
3141 - const newId = globalClassesStylesProvider.actions.create?.(newClassName, localStyleData.variants);
3142 - if (newId) {
3143 - props.successCallback(newId);
3144 - trackGlobalClasses({
3145 - classId: newId,
3146 - event: "classCreated",
3147 - source: "converted",
3148 - classTitle: newClassName
3149 - });
3150 - }
3151 - };
3152 - return /* @__PURE__ */ react.createElement(react.Fragment, null, /* @__PURE__ */ react.createElement(_elementor_editor_ui.MenuListItem, {
3153 - disabled: !props.canConvert,
3154 - onClick: handleConversion,
3155 - dense: true,
3156 - sx: { "&.Mui-focusVisible": {
3157 - border: "none",
3158 - boxShadow: "none !important",
3159 - backgroundColor: "transparent"
3160 - } }
3161 - }, (0, _wordpress_i18n.__)("Convert to global class", "elementor")), /* @__PURE__ */ react.createElement(_elementor_ui.Divider, null));
3162 - };
3163 - function createClassName(prefix) {
3164 - let i = 1;
3165 - let newClassName = `${prefix}${i}`;
3166 - while (!(0, _elementor_editor_styles_repository.validateStyleLabel)(newClassName, "create").isValid) newClassName = `${prefix}${++i}`;
3167 - return newClassName;
3168 - }
3169 -
3170 -//#endregion
3171 -//#region packages/packages/core/editor-global-classes/src/components/global-styles-import-listener.tsx
3172 - function GlobalStylesImportListener() {
3173 - const dispatch = (0, _elementor_store.__useDispatch)();
3174 - (0, react.useEffect)(() => {
3175 - const handleGlobalStylesImported = async (event) => {
3176 - const globalClasses = event.detail?.global_classes;
3177 - if (!globalClasses?.added_items_order || !globalClasses?.added_items || globalClasses?.added_items_order?.length === 0) {
3178 - loadCurrentDocumentClasses();
3179 - return;
3180 - }
3181 - dispatch(slice.actions.updateAfterTemplateImport({
3182 - addedItems: globalClasses.added_items,
3183 - addedIdsOrder: globalClasses.added_items_order,
3184 - addedClassLabels: createLabelsForClasses(Object.values(globalClasses.added_items))
3185 - }));
3186 - };
3187 - window.addEventListener(_elementor_editor_canvas.GLOBAL_STYLES_IMPORTED_EVENT, handleGlobalStylesImported);
3188 - return () => {
3189 - window.removeEventListener(_elementor_editor_canvas.GLOBAL_STYLES_IMPORTED_EVENT, handleGlobalStylesImported);
3190 - };
3191 - }, [dispatch]);
3192 - return null;
3193 - }
3194 -
3195 -//#endregion
3196 -//#region packages/packages/core/editor-global-classes/src/components/populate-store.tsx
3197 - function PopulateStore() {
3198 - (0, react.useEffect)(() => {
3199 - loadCurrentDocumentClasses();
3200 - (0, _elementor_editor_v1_adapters.registerDataHook)("after", "editor/documents/attach-preview", async () => {
3201 - await loadCurrentDocumentClasses();
3202 - });
3203 - }, []);
3204 - return null;
3205 - }
3206 -
3207 -//#endregion
3208 -//#region packages/packages/core/editor-global-classes/src/mcp-integration/manage-classes-tool.ts
3209 - var MCP_PROXY_URL = "elementor/v1/mcp-proxy";
3210 - var TOOL_NAME = "manage-classes";
3211 - var initManageClassesTool = (reg) => {
3212 - const { addTool } = reg;
3213 - addTool({
3214 - name: TOOL_NAME,
3215 - description: "Manage V4 global CSS classes on the active kit. Bulk create, update, or delete using raw CSS declarations (up to 50 operations). Duplicate labels are auto-renamed with a DUP_ prefix.",
3216 - schema: {
3217 - action: _elementor_schema.z.enum([
3218 - "create",
3219 - "update",
3220 - "delete"
3221 - ]),
3222 - id: _elementor_schema.z.string().optional().describe("Class id — required for update/delete. Get from the global-classes resource."),
3223 - label: _elementor_schema.z.string().optional().describe("Class label (lowercase, dash-separated) — required for create/update."),
3224 - css: _elementor_schema.z.string().optional().describe("Plain CSS string. Supports &:hover/&:focus/&:active nesting and @media(--breakpoint) blocks. font-family must be a single Google Font name (no fallback stacks). In patch mode: \"prop: null\" removes that prop; \"all: null\" wipes the variant."),
3225 - mode: _elementor_schema.z.enum(["patch", "replace"]).optional().describe("Merge strategy for update — patch (default): merge incoming props with existing; replace: discard all existing variants for the affected breakpoints.")
3226 - },
3227 - outputSchema: {
3228 - status: _elementor_schema.z.enum(["ok"]).describe("Operation status"),
3229 - id: _elementor_schema.z.string().optional().describe("ID of the affected class — use for subsequent update/delete calls."),
3230 - label: _elementor_schema.z.string().optional().describe("Final label of the class after any auto-rename.")
3231 - },
3232 - requiredResources: [{
3233 - uri: GLOBAL_CLASSES_URI,
3234 - description: "Current global classes — check before creating to avoid duplicates"
3235 - }],
3236 - isDestructive: true,
3237 - handler: async (params) => {
3238 - const { data } = await (0, _elementor_http_client.httpService)().post(MCP_PROXY_URL, {
3239 - tool: TOOL_NAME,
3240 - input: { operations: [params] }
3241 - });
3242 - const result = data.data.results?.[0];
3243 - const { create, update, delete: del } = globalClassesStylesProvider.actions;
3244 - switch (params.action) {
3245 - case "create":
3246 - if (result && create) create(result.label, result.variants, result.id);
3247 - break;
3248 - case "update":
3249 - if (result && update) update(result);
3250 - break;
3251 - case "delete":
3252 - if (params.id && del) del(params.id);
3253 - break;
3254 - }
3255 - (0, _elementor_store.__dispatch)(slice.actions.reset({ context: "frontend" }));
3256 - window.dispatchEvent(new CustomEvent("classes:updated", { detail: { context: "frontend" } }));
3257 - return {
3258 - status: "ok",
3259 - id: result?.id,
3260 - label: result?.label
3261 - };
3262 - }
3263 - });
3264 - };
3265 -
3266 -//#endregion
3267 -//#region packages/packages/core/editor-global-classes/src/mcp-integration/apply-global-class-guide-prompt.ts
3268 - var APPLY_GLOBAL_CLASS_GUIDE_URI = "elementor://global-classes/tools/apply-global-class-guide";
3269 - var generateApplyGlobalClassGuidePrompt = () => {
3270 - const prompt = (0, _elementor_editor_mcp.toolPrompts)("apply-global-class");
3271 - prompt.description("Apply a global class to an element, enabling consistent styling through your design system.");
3272 - prompt.instruction(`## When to use this tool:
3273 -**ALWAYS use this IMMEDIATELY AFTER creating or updating elements** to apply the global classes you created beforehand:
3274 -- After adding elements to the canvas, apply semantic classes to them
3275 -- When applying consistent typography styles (heading-primary, text-body, etc.)
3276 -- When applying theme colors or brand styles (bg-brand, button-cta, etc.)
3277 -- When ensuring spacing consistency (spacing-section-large, etc.)
3278 -
3279 -**DO NOT use this tool** for:
3280 -- Elements that don't share styles with other elements (use inline styles instead)
3281 -- Layout-specific properties (those should remain inline in stylesConfig)`);
3282 - prompt.instruction(`## Prerequisites:
3283 -- **REQUIRED**: Get the list of available global classes from 'elementor://global-classes' resource
3284 -- **REQUIRED**: Get element IDs from the page structure or selected element resources
3285 -- Ensure you have the most up-to-date list of classes applied to the element to avoid duplicates
3286 -- Make sure you have the correct class ID that you want to apply`);
3287 - prompt.instruction(`## Best Practices:
3288 -1. Apply multiple classes to a single element if needed (typography + color + spacing)
3289 -2. After applying, the tool will remind you to remove duplicate inline styles from elementConfig
3290 -3. Classes should describe purpose, not implementation (e.g., "heading-primary" not "big-red-text")`);
3291 - return prompt.prompt();
3292 - };
3293 -
3294 -//#endregion
3295 -//#region packages/packages/core/editor-global-classes/src/mcp-integration/mcp-apply-unapply-global-classes.ts
3296 - function initMcpApplyUnapplyGlobalClasses(server) {
3297 - const { addTool, resource } = server;
3298 - const applyGlobalClassGuideText = generateApplyGlobalClassGuidePrompt();
3299 - resource("apply-global-class-guide", APPLY_GLOBAL_CLASS_GUIDE_URI, {
3300 - description: "Workflow, prerequisites, and best practices for apply-global-class",
3301 - mimeType: "text/plain",
3302 - title: "Apply global class tool guide"
3303 - }, async (uri) => ({ contents: [{
3304 - mimeType: "text/plain",
3305 - text: applyGlobalClassGuideText,
3306 - uri: uri.href
3307 - }] }));
3308 - addTool({
3309 - schema: {
3310 - classId: _elementor_schema.z.string().describe("The ID of the class to apply"),
3311 - elementId: _elementor_schema.z.string().describe("The ID of the element to which the class will be applied")
3312 - },
3313 - outputSchema: {
3314 - result: _elementor_schema.z.string().describe("Result message indicating the success of the apply operation"),
3315 - llm_instructions: _elementor_schema.z.string().describe("Instructions what to do next, Important to follow these instructions!")
3316 - },
3317 - name: "apply-global-class",
3318 - description: `Apply a global class to an element for shared design-system styling. Read the full guide at [${APPLY_GLOBAL_CLASS_GUIDE_URI}].`,
3319 - requiredResources: [{
3320 - description: "Apply global class tool guide",
3321 - uri: APPLY_GLOBAL_CLASS_GUIDE_URI
3322 - }, {
3323 - description: "Global classes list",
3324 - uri: GLOBAL_CLASSES_URI
3325 - }],
3326 - handler: async (params) => {
3327 - const { classId, elementId } = params;
3328 - (0, _elementor_editor_editing_panel.doApplyClasses)(elementId, [...(0, _elementor_editor_editing_panel.doGetAppliedClasses)(elementId), classId]);
3329 - globalClassesStylesProvider.actions.tracking?.({
3330 - event: "classApplied",
3331 - executedBy: "mcp_tool",
3332 - classId
3333 - });
3334 - return {
3335 - llm_instructions: "Please check the element configuration, find inline styles duplicated by the applied global class, and remove them",
3336 - result: `Class ${classId} applied to element ${elementId} successfully.`
3337 - };
3338 - }
3339 - });
3340 - addTool({
3341 - name: "unapply-global-class",
3342 - schema: {
3343 - classId: _elementor_schema.z.string().describe("The ID of the class to unapply"),
3344 - elementId: _elementor_schema.z.string().describe("The ID of the element from which the class will be unapplied")
3345 - },
3346 - outputSchema: { result: _elementor_schema.z.string().describe("Result message indicating the success of the unapply operation") },
3347 - description: `Unapply a global class from an element by class ID. Resolve class names to IDs via [${GLOBAL_CLASSES_URI}].`,
3348 - requiredResources: [{
3349 - description: "Global classes list",
3350 - uri: GLOBAL_CLASSES_URI
3351 - }],
3352 - handler: async (params) => {
3353 - const { classId, elementId } = params;
3354 - if (!(0, _elementor_editor_editing_panel.doUnapplyClass)(elementId, classId)) throw new Error(`Class ${classId} is not applied to element ${elementId}, cannot unapply it.`);
3355 - return { result: `Class ${classId} unapplied from element ${elementId} successfully.` };
3356 - }
3357 - });
3358 - }
3359 -
3360 -//#endregion
3361 -//#region packages/packages/core/editor-global-classes/src/mcp-integration/mcp-get-global-class-usages.ts
3362 - function initMcpApplyGetGlobalClassUsages(reg) {
3363 - const { addTool } = reg;
3364 - const globalClassesUsageSchema = { usages: _elementor_schema.z.array(_elementor_schema.z.object({
3365 - classId: _elementor_schema.z.string().describe("The ID of the class, not visible to the user. To retrieve the name of the class, use the \"list-global-classes\" tool"),
3366 - usages: _elementor_schema.z.array(_elementor_schema.z.object({
3367 - pageId: _elementor_schema.z.string().describe("The ID of the page where the class is used"),
3368 - title: _elementor_schema.z.string().describe("The title of the page where the class is used"),
3369 - total: _elementor_schema.z.number().describe("The number of times the class is used on this page"),
3370 - elements: _elementor_schema.z.array(_elementor_schema.z.string()).describe("List of element IDs using this class on the page")
3371 - }))
3372 - })) };
3373 - addTool({
3374 - name: "get-global-class-usages",
3375 - description: `Retrieve usages of global classes across all Elementor pages. Heavy operation \u2014 scans every page in the site.
3376 -
3377 -## When to use:
3378 -- Before deleting or radically changing a class \u2014 to understand cross-page side effects and decide whether to consult the user.
3379 -- To identify unused global classes for cleanup.
3380 -
3381 -## When NOT to use:
3382 -- To list global classes themselves \u2014 use the global-classes resource instead (this tool returns usages, not the class list).`,
3383 - requiredResources: [{
3384 - description: "Global classes list",
3385 - uri: GLOBAL_CLASSES_URI
3386 - }],
3387 - outputSchema: globalClassesUsageSchema,
3388 - handler: async () => {
3389 - const data = await fetchCssClassUsage();
3390 - const result = { usages: [] };
3391 - Object.entries(data).forEach(([classId, usageDetails]) => {
3392 - const newEntry = {
3393 - classId,
3394 - usages: []
3395 - };
3396 - if (typeof usageDetails !== "number") {
3397 - const { content } = usageDetails;
3398 - content.forEach((detail) => {
3399 - newEntry.usages.push({
3400 - pageId: String(detail.pageId),
3401 - title: detail.title,
3402 - total: detail.total,
3403 - elements: detail.elements
3404 - });
3405 - });
3406 - result.usages.push(newEntry);
3407 - }
3408 - });
3409 - return result;
3410 - }
3411 - });
3412 - }
3413 -
3414 -//#endregion
3415 -//#region packages/packages/core/editor-global-classes/src/mcp-integration/index.ts
3416 - var initMcpIntegration = (reg, canvasMcpEntry) => {
3417 - initMcpApplyUnapplyGlobalClasses(reg);
3418 - initMcpApplyGetGlobalClassUsages(reg);
3419 - initManageClassesTool(reg);
3420 - initClassesResource(reg, canvasMcpEntry);
3421 - };
3422 -
3423 -//#endregion
3424 -//#region packages/packages/core/editor-global-classes/src/sync-with-document-save.ts
3425 - var pendingSave = null;
3426 - function syncWithDocumentSave(panelActions) {
3427 - const unsubscribe = syncDirtyState();
3428 - bindSaveAction(panelActions);
3429 - bindBeforeSaveTemplateAction();
3430 - return unsubscribe;
3431 - }
3432 - function syncDirtyState() {
3433 - return (0, _elementor_store.__subscribeWithSelector)(selectIsDirty, () => {
3434 - if (!isDirty()) return;
3435 - (0, _elementor_editor_documents.setDocumentModifiedStatus)(true);
3436 - });
3437 - }
3438 - function triggerSave(panelActions, context = "preview") {
3439 - if (!(0, _elementor_editor_current_user.getCurrentUser)()?.capabilities.includes("elementor_global_classes_update_class")) return null;
3440 - if (pendingSave) return pendingSave;
3441 - const promise = saveGlobalClasses({
3442 - context,
3443 - onApprove: panelActions?.open
3444 - });
3445 - pendingSave = promise;
3446 - promise.finally(() => {
3447 - pendingSave = null;
3448 - });
3449 - return promise;
3450 - }
3451 - function bindSaveAction(panelActions) {
3452 - (0, _elementor_editor_v1_adapters.registerDataHook)("dependency", "document/save/save", (args) => {
3453 - triggerSave(panelActions, args.status === "publish" ? "frontend" : "preview");
3454 - return true;
3455 - });
3456 - }
3457 - function bindBeforeSaveTemplateAction() {
3458 - window.addEventListener("elementor/global-styles/before-save", (event) => {
3459 - if (!pendingSave && isDirty()) triggerSave();
3460 - if (pendingSave) event.detail.promises.push(pendingSave);
3461 - });
3462 - }
3463 - function isDirty() {
3464 - return selectIsDirty((0, _elementor_store.__getState)());
3465 - }
3466 -
3467 -//#endregion
3468 -//#region packages/packages/core/editor-global-classes/src/sync-with-document.tsx
3469 - function SyncWithDocumentSave() {
3470 - (0, react.useEffect)(() => {
3471 - return (0, _elementor_editor_v1_adapters.__privateListenTo)((0, _elementor_editor_v1_adapters.v1ReadyEvent)(), () => {
3472 - const open = () => {
3473 - window.dispatchEvent(new CustomEvent("elementor/open-global-classes-manager"));
3474 - };
3475 - syncWithDocumentSave({ open });
3476 - });
3477 - }, []);
3478 - return null;
3479 - }
3480 -
3481 -//#endregion
3482 -//#region packages/packages/core/editor-global-classes/src/init.ts
3483 - function init() {
3484 - (0, _elementor_store.__registerSlice)(slice);
3485 - _elementor_editor_embedded_documents_manager.embeddedDocumentsManager.onDocumentLoad((documentId) => {
3486 - addDocumentClasses(documentId);
3487 - });
3488 - _elementor_editor_styles_repository.stylesRepository.register(globalClassesStylesProvider);
3489 - (0, _elementor_editor.injectIntoLogic)({
3490 - id: "global-classes-populate-store",
3491 - component: PopulateStore
3492 - });
3493 - (0, _elementor_editor.injectIntoLogic)({
3494 - id: "global-classes-sync-with-document",
3495 - component: SyncWithDocumentSave
3496 - });
3497 - (0, _elementor_editor.injectIntoLogic)({
3498 - id: "global-classes-import-listener",
3499 - component: GlobalStylesImportListener
3500 - });
3501 - (0, _elementor_editor.injectIntoLogic)({
3502 - id: "global-classes-prefetch-css-class-usage",
3503 - component: PrefetchCssClassUsage
3504 - });
3505 - (0, _elementor_editor_editing_panel.injectIntoCssClassConvert)({
3506 - id: "global-classes-convert-from-local-class",
3507 - component: ConvertLocalClassToGlobalClass
3508 - });
3509 - (0, _elementor_editor_editing_panel.injectIntoClassSelectorActions)({
3510 - id: "global-classes-manager-button",
3511 - component: ClassManagerButton
3512 - });
3513 - (0, _elementor_editor_editing_panel.registerStyleProviderToColors)(GLOBAL_CLASSES_PROVIDER_KEY, {
3514 - name: "global",
3515 - getThemeColor: (theme) => theme.palette.global.dark
3516 - });
3517 - initMcpIntegration((0, _elementor_editor_mcp.getMCPByDomain)("classes", {
3518 - instructions: "MCP server for management of Elementor global classes",
3519 - docs: `Everything related to V4 ( Atomic ) global classes.
3520 -# Global classes
3521 -- Create/update/delete global classes
3522 -- Get list of global classes
3523 -- Get details of a global class
3524 -`
3525 - }), (0, _elementor_editor_mcp.getMCPByDomain)("canvas"));
3526 - }
3527 -
3528 -//#endregion
3529 -//#region packages/packages/core/editor-global-classes/src/index.ts
3530 - var src_exports = /* @__PURE__ */ __exportAll({
3531 - ClassManagerPanelEmbedded: () => ClassManagerPanelEmbedded,
3532 - GLOBAL_CLASSES_URI: () => GLOBAL_CLASSES_URI,
3533 - addDocumentClasses: () => addDocumentClasses,
3534 - createLabelsForClasses: () => createLabelsForClasses,
3535 - init: () => init,
3536 - loadExistingClasses: () => loadExistingClasses,
3537 - trackGlobalClasses: () => trackGlobalClasses
3538 - });
3539 -
3540 -//#endregion
3541 -//#region \0elementor-package-library-entry
3542 - (window.elementorV2 = window.elementorV2 || {}).editorGlobalClasses = src_exports;
3543 -
3544 -//#endregion
3545 -})(React, elementorV2.editorCurrentUser, elementorV2.editorDocuments, elementorV2.editorPanels, elementorV2.editorUi, elementorV2.query, elementorV2.store, elementorV2.ui, wp.i18n, elementorV2.editorStyles, elementorV2.utils, elementorV2.httpClient, elementorV2.icons, elementorV2.events, ReactDOM, elementorV2.editorStylesRepository, elementorV2.editor, elementorV2.editorEditingPanel, elementorV2.editorEmbeddedDocumentsManager, elementorV2.editorMcp, elementorV2.editorCanvas, elementorV2.editorV1Adapters, elementorV2.schema);
3546 -window.elementorV2.editorGlobalClasses?.init?.();
5 + background-color: ${({theme:e})=>e.palette.text.primary};
6 +`},"./packages/packages/core/editor-global-classes/src/components/convert-local-class-to-global-class.tsx":function(e,s,t){t.r(s),t.d(s,{ConvertLocalClassToGlobalClass:function(){return ConvertLocalClassToGlobalClass}});var a=t("react"),r=t("@elementor/editor-styles-repository"),o=t("@elementor/editor-ui"),n=t("@elementor/ui"),l=t("@wordpress/i18n"),c=t("./packages/packages/core/editor-global-classes/src/global-classes-styles-provider.ts"),i=t("./packages/packages/core/editor-global-classes/src/utils/tracking.ts");const ConvertLocalClassToGlobalClass=e=>{const s=e.styleDef;return a.createElement(a.Fragment,null,a.createElement(o.MenuListItem,{disabled:!e.canConvert,onClick:()=>{const t=function createClassName(e){let s=1,t=`${e}${s}`;for(;!(0,r.validateStyleLabel)(t,"create").isValid;)t=`${e}${++s}`;return t}("converted-class-");if(!s)throw new Error("Style definition is required for converting local class to global class.");const a=c.globalClassesStylesProvider.actions.create?.(t,s.variants);a&&(e.successCallback(a),(0,i.trackGlobalClasses)({classId:a,event:"classCreated",source:"converted",classTitle:t}))},dense:!0,sx:{"&.Mui-focusVisible":{border:"none",boxShadow:"none !important",backgroundColor:"transparent"}}},(0,l.__)("Convert to global class","elementor")),a.createElement(n.Divider,null))}},"./packages/packages/core/editor-global-classes/src/components/css-class-usage/components/css-class-usage-popover.tsx":function(e,s,t){t.r(s),t.d(s,{CssClassUsagePopover:function(){return CssClassUsagePopover}});var a=t("react"),r=t("@elementor/editor-documents"),o=t("@elementor/editor-ui"),n=t("@elementor/icons"),l=t("@elementor/ui"),c=t("@wordpress/i18n"),i=t("./packages/packages/core/editor-global-classes/src/hooks/use-css-class-usage-by-id.ts"),d=t("./packages/packages/core/editor-global-classes/src/utils/tracking.ts");const p={"wp-post":{label:(0,c.__)("Post","elementor"),icon:a.createElement(n.PostTypeIcon,{fontSize:"inherit"})},"wp-page":{label:(0,c.__)("Page","elementor"),icon:a.createElement(n.PagesIcon,{fontSize:"inherit"})},popup:{label:(0,c.__)("Popup","elementor"),icon:a.createElement(n.PopupTemplateIcon,{fontSize:"inherit"})},header:{label:(0,c.__)("Header","elementor"),icon:a.createElement(n.HeaderTemplateIcon,{fontSize:"inherit"})},footer:{label:(0,c.__)("Footer","elementor"),icon:a.createElement(n.FooterTemplateIcon,{fontSize:"inherit"})}},CssClassUsagePopover=({cssClassID:e,onClose:s})=>{const{data:t}=(0,i.useCssClassUsageByID)(e),g=(0,r.__useOpenDocumentInNewTab)(),m=t?.content.map(({title:e,elements:s,pageId:t,type:a})=>({type:"item",value:t,label:e,secondaryText:s.length.toString(),docType:a}))??[];return a.createElement(a.Fragment,null,a.createElement(o.PopoverHeader,{icon:a.createElement(n.CurrentLocationIcon,{fontSize:"tiny"}),title:a.createElement(l.Stack,{flexDirection:"row",gap:1,alignItems:"center"},a.createElement(l.Box,{"aria-label":"header-title"},(0,c.__)("Locator","elementor")),a.createElement(l.Box,null,a.createElement(l.Chip,{sx:{lineHeight:1},size:"tiny",label:t.total}))),onClose:s}),a.createElement(l.Divider,null),a.createElement(o.PopoverBody,{width:300},a.createElement(o.PopoverMenuList,{onSelect:s=>{g(+s),(0,d.trackGlobalClasses)({event:"classUsageLocate",classId:e})},items:m,onClose:()=>{},menuListTemplate:u,menuItemContentTemplate:e=>a.createElement(l.Stack,{flexDirection:"row",flex:1,alignItems:"center"},a.createElement(l.Box,{display:"flex",sx:{pr:1}},a.createElement(l.Tooltip,{disableInteractive:!0,title:p?.[e.docType]?.label??e.docType,placement:"top"},a.createElement(l.Icon,{fontSize:"small"},p?.[e.docType]?.icon||a.createElement(n.PagesIcon,{fontSize:"inherit"})))),a.createElement(l.Box,{sx:{pr:.5,maxWidth:"173px"},display:"flex"},a.createElement(o.EllipsisWithTooltip,{title:e.label,as:l.Typography,variant:"caption",maxWidth:"173px",sx:{lineHeight:1}})),a.createElement(n.ExternalLinkIcon,{className:"hover-only-icon",fontSize:"tiny"}),a.createElement(l.Chip,{sx:{ml:"auto"},size:"tiny",label:e.secondaryText}))})))},u=(0,l.styled)(l.MenuList)(({theme:e})=>({"& > li":{display:"flex",cursor:"pointer",height:32,width:"100%"},'& > [role="option"]':{...e.typography.caption,lineHeight:"inherit",padding:e.spacing(.5,1,.5,2),textOverflow:"ellipsis",position:"absolute",top:0,left:0,opacity:1,".hover-only-icon":{color:e.palette.text.disabled,opacity:0},"&:hover":{borderRadius:e.spacing(.5),backgroundColor:e.palette.action.hover,".hover-only-icon":{color:e.palette.text.disabled,opacity:1}}},width:"100%",position:"relative"}))},"./packages/packages/core/editor-global-classes/src/components/css-class-usage/components/css-class-usage-trigger.tsx":function(e,s,t){t.r(s),t.d(s,{CssClassUsageTrigger:function(){return CssClassUsageTrigger}});var a=t("react"),r=t("@elementor/editor-ui"),o=t("@elementor/icons"),n=t("@elementor/ui"),l=t("@wordpress/i18n"),c=t("./packages/packages/core/editor-global-classes/src/hooks/use-css-class-usage-by-id.ts"),i=t("./packages/packages/core/editor-global-classes/src/utils/tracking.ts"),d=t("./packages/packages/core/editor-global-classes/src/components/css-class-usage/components/css-class-usage-popover.tsx");function _extends(){return _extends=Object.assign?Object.assign.bind():function(e){for(var s=1;s<arguments.length;s++){var t=arguments[s];for(var a in t)({}).hasOwnProperty.call(t,a)&&(e[a]=t[a])}return e},_extends.apply(null,arguments)}const CssClassUsageTrigger=({id:e,onClick:s})=>{const{data:{total:t},isLoading:r}=(0,c.useCssClassUsageByID)(e),l=(0,n.usePopupState)({variant:"popover",popupId:"css-class-usage-popover"});if(r)return null;const u=0!==t?TooltipWrapper:InfoAlertMessage;return a.createElement(a.Fragment,null,a.createElement(n.Box,{position:"relative",onMouseEnter:()=>{(0,i.trackGlobalClasses)({event:"classUsageHovered",classId:e,usage:t})}},a.createElement(u,{total:t},a.createElement(p,_extends({disabled:0===t,size:"tiny"},(0,n.bindTrigger)(l),{onClick:a=>{0!==t&&((0,n.bindTrigger)(l).onClick(a),s(e),(0,i.trackGlobalClasses)({event:"classUsageClicked",classId:e}))}}),a.createElement(o.CurrentLocationIcon,{fontSize:"tiny"})))),a.createElement(n.Box,null,a.createElement(n.Popover,_extends({anchorOrigin:{vertical:"center",horizontal:"right"},transformOrigin:{vertical:15,horizontal:-50}},(0,n.bindPopover)(l),{onClose:()=>{(0,n.bindPopover)(l).onClose(),s("")}}),a.createElement(d.CssClassUsagePopover,{onClose:l.close,"aria-label":"css-class-usage-popover",cssClassID:e}))))},p=(0,n.styled)(n.IconButton)(({theme:e})=>({"&.Mui-disabled":{pointerEvents:"auto","&:hover":{color:e.palette.action.disabled}},height:"22px",width:"22px"})),TooltipWrapper=({children:e,total:s})=>a.createElement(n.Tooltip,{disableInteractive:!0,placement:"top",title:`${(0,l.__)("Show {{number}} {{locations}}","elementor").replace("{{number}}",s.toString()).replace("{{locations}}",1===s?(0,l.__)("location","elementor"):(0,l.__)("locations","elementor"))}`},a.createElement("span",null,e)),InfoAlertMessage=({children:e})=>a.createElement(n.Infotip,{disableInteractive:!0,placement:"top",color:"secondary",content:a.createElement(r.InfoAlert,{sx:{mt:1}},(0,l.__)("This class isn’t being used yet.","elementor"))},a.createElement("span",null,e))},"./packages/packages/core/editor-global-classes/src/components/css-class-usage/components/index.ts":function(e,s,t){t.r(s),t.d(s,{CssClassUsagePopover:function(){return a.CssClassUsagePopover},CssClassUsageTrigger:function(){return r.CssClassUsageTrigger}});var a=t("./packages/packages/core/editor-global-classes/src/components/css-class-usage/components/css-class-usage-popover.tsx"),r=t("./packages/packages/core/editor-global-classes/src/components/css-class-usage/components/css-class-usage-trigger.tsx")},"./packages/packages/core/editor-global-classes/src/components/css-class-usage/types.ts":function(e,s,t){t.r(s),t.d(s,{QUERY_KEY:function(){return a}});const a="css-classes-usage"},"./packages/packages/core/editor-global-classes/src/components/css-class-usage/utils.ts":function(e,s,t){t.r(s),t.d(s,{transformData:function(){return transformData}});const transformData=e=>Object.entries(e).reduce((e,[s,t])=>(e[s]={content:t||[],total:t.reduce((e,s)=>e+(s?.total||0),0)},e),{})},"./packages/packages/core/editor-global-classes/src/components/populate-store.tsx":function(e,s,t){t.r(s),t.d(s,{PopulateStore:function(){return PopulateStore}});var a=t("react"),r=t("@elementor/store"),o=t("./packages/packages/core/editor-global-classes/src/api.ts"),n=t("./packages/packages/core/editor-global-classes/src/store.ts");function PopulateStore(){const e=(0,r.__useDispatch)();return(0,a.useEffect)(()=>{Promise.all([o.apiClient.all("preview"),o.apiClient.all("frontend")]).then(([s,t])=>{const{data:a}=s,{data:r}=t;e(n.slice.actions.load({preview:{items:a.data,order:a.meta.order},frontend:{items:r.data,order:r.meta.order}}))})},[e]),null}},"./packages/packages/core/editor-global-classes/src/components/search-and-filter/components/filter/active-filters.tsx":function(e,s,t){t.r(s),t.d(s,{ActiveFilters:function(){return ActiveFilters}});var a=t("react"),r=t("@elementor/ui"),o=t("@wordpress/i18n"),n=t("./packages/packages/core/editor-global-classes/src/utils/tracking.ts"),l=t("./packages/packages/core/editor-global-classes/src/components/search-and-filter/context.tsx"),c=t("./packages/packages/core/editor-global-classes/src/components/search-and-filter/components/filter/clear-icon-button.tsx"),i=t("./packages/packages/core/editor-global-classes/src/components/search-and-filter/components/filter/filter-list.tsx");const ActiveFilters=()=>{const{filters:{filters:e,setFilters:s}}=(0,l.useSearchAndFilters)(),t=Object.keys(e).filter(s=>e[s]),p=t.length>0;return a.createElement(r.Stack,{direction:"row",alignItems:"center",justifyContent:"space-between"},a.createElement(r.Stack,{direction:"row",gap:.5,alignItems:"center",flexWrap:"wrap"},t.map(e=>a.createElement(r.Chip,{key:e,label:i.filterConfig[e],onDelete:()=>(e=>{s(s=>({...s,[e]:!1})),(0,n.trackGlobalClasses)({event:"classManagerFilterUsed",action:"remove",type:e,trigger:"header"})})(e),sx:d,size:"tiny"}))),p&&a.createElement(c.ClearIconButton,{trigger:"header",tooltipText:(0,o.__)("Clear Filters","elementor"),sx:{margin:"0 0 auto auto"}}))},d={"& .MuiChip-deleteIcon":{display:"none",transition:"opacity 0.2s"},"&:hover .MuiChip-deleteIcon":{display:"block"}}},"./packages/packages/core/editor-global-classes/src/components/search-and-filter/components/filter/clear-icon-button.tsx":function(e,s,t){t.r(s),t.d(s,{ClearIconButton:function(){return ClearIconButton}});var a=t("react"),r=t("@elementor/icons"),o=t("@elementor/ui"),n=t("./packages/packages/core/editor-global-classes/src/utils/tracking.ts"),l=t("./packages/packages/core/editor-global-classes/src/components/search-and-filter/context.tsx");const ClearIconButton=({tooltipText:e,sx:s,trigger:t})=>{const{filters:{onClearFilter:i}}=(0,l.useSearchAndFilters)();return a.createElement(o.Tooltip,{title:e,placement:"top",disableInteractive:!0},a.createElement(o.Box,null,a.createElement(c,{"aria-label":e,size:"tiny",onClick:()=>{i(t),(0,n.trackGlobalClasses)({event:"classManagerFilterCleared",trigger:t})},sx:s},a.createElement(r.BrushBigIcon,{fontSize:"tiny"}))))},c=(0,o.styled)(o.IconButton)(({theme:e})=>({"&.Mui-disabled":{pointerEvents:"auto","&:hover":{color:e.palette.action.disabled}}}))},"./packages/packages/core/editor-global-classes/src/components/search-and-filter/components/filter/css-class-filter.tsx":function(e,s,t){t.r(s),t.d(s,{CssClassFilter:function(){return CssClassFilter}});var a=t("react"),r=t("@elementor/editor-ui"),o=t("@elementor/icons"),n=t("@elementor/ui"),l=t("@wordpress/i18n"),c=t("./packages/packages/core/editor-global-classes/src/utils/tracking.ts"),i=t("./packages/packages/core/editor-global-classes/src/components/search-and-filter/context.tsx"),d=t("./packages/packages/core/editor-global-classes/src/components/search-and-filter/components/filter/clear-icon-button.tsx"),p=t("./packages/packages/core/editor-global-classes/src/components/search-and-filter/components/filter/filter-list.tsx");function _extends(){return _extends=Object.assign?Object.assign.bind():function(e){for(var s=1;s<arguments.length;s++){var t=arguments[s];for(var a in t)({}).hasOwnProperty.call(t,a)&&(e[a]=t[a])}return e},_extends.apply(null,arguments)}const CssClassFilter=()=>{const{filters:{filters:e}}=(0,i.useSearchAndFilters)(),s=(0,n.usePopupState)({variant:"popover",disableAutoFocus:!0});a.useEffect(()=>{s.isOpen&&(0,c.trackGlobalClasses)({event:"classManagerFiltersOpened"})},[s.isOpen]);const t=Object.values(e).some(e=>e);return a.createElement(a.Fragment,null,a.createElement(n.Tooltip,{title:(0,l.__)("Filters","elementor"),placement:"top"},a.createElement(n.ToggleButton,_extends({value:"filter",size:"tiny",selected:s.isOpen},(0,n.bindToggle)(s)),a.createElement(o.FilterIcon,{fontSize:"tiny"}))),a.createElement(n.Popover,_extends({sx:{maxWidth:"344px"},anchorOrigin:{vertical:"top",horizontal:"right"},transformOrigin:{vertical:"top",horizontal:-21}},(0,n.bindPopover)(s)),a.createElement(r.PopoverHeader,{actions:t?[a.createElement(d.ClearIconButton,{trigger:"menu",key:"clear-all-button",tooltipText:(0,l.__)("Clear all","elementor")})]:[],onClose:s.close,title:(0,l.__)("Filters","elementor"),icon:a.createElement(o.FilterIcon,{fontSize:"tiny"})}),a.createElement(n.Divider,{sx:{borderWidth:"1px 0 0 0"}}),a.createElement(r.PopoverBody,{width:344,height:125},a.createElement(p.FilterList,null))))}},"./packages/packages/core/editor-global-classes/src/components/search-and-filter/components/filter/filter-list.tsx":function(e,s,t){t.r(s),t.d(s,{FilterList:function(){return FilterList},filterConfig:function(){return i}});var a=t("react"),r=t("@elementor/ui"),o=t("@wordpress/i18n"),n=t("./packages/packages/core/editor-global-classes/src/hooks/use-filtered-css-class-usage.tsx"),l=t("./packages/packages/core/editor-global-classes/src/utils/tracking.ts"),c=t("./packages/packages/core/editor-global-classes/src/components/search-and-filter/context.tsx");const i={unused:(0,o.__)("Unused","elementor"),empty:(0,o.__)("Empty","elementor"),onThisPage:(0,o.__)("On this page","elementor")},FilterList=()=>{const{filters:{filters:e,setFilters:s}}=(0,c.useSearchAndFilters)(),t=(0,n.useFilteredCssClassUsage)(),handleOnClick=t=>{s(e=>({...e,[t]:!e[t]})),(0,l.trackGlobalClasses)({event:"classManagerFilterUsed",action:e[t]?"remove":"apply",type:t,trigger:"menu"})};return a.createElement(r.MenuList,null,a.createElement(r.MenuItem,{onClick:()=>handleOnClick("unused")},a.createElement(LabeledCheckbox,{label:i.unused,checked:e.unused,suffix:a.createElement(r.Chip,{size:"tiny",sx:{ml:"auto"},label:t.unused.length})})),a.createElement(r.MenuItem,{onClick:()=>handleOnClick("empty")},a.createElement(LabeledCheckbox,{label:i.empty,checked:e.empty,suffix:a.createElement(r.Chip,{size:"tiny",sx:{ml:"auto"},label:t.empty.length})})),a.createElement(r.MenuItem,{onClick:()=>handleOnClick("onThisPage")},a.createElement(LabeledCheckbox,{label:i.onThisPage,checked:e.onThisPage,suffix:a.createElement(r.Chip,{size:"tiny",sx:{ml:"auto"},label:t.onThisPage.length})})))},LabeledCheckbox=({label:e,suffix:s,checked:t})=>a.createElement(r.Stack,{direction:"row",alignItems:"center",gap:.5,flex:1},a.createElement(r.Checkbox,{size:"small",checked:t,sx:{padding:0,color:"text.tertiary","&.Mui-checked":{color:"text.tertiary"}}}),a.createElement(r.Typography,{variant:"caption",sx:{color:"text.secondary"}},e),s)},"./packages/packages/core/editor-global-classes/src/components/search-and-filter/components/search/class-manager-search.tsx":function(e,s,t){t.r(s),t.d(s,{ClassManagerSearch:function(){return ClassManagerSearch}});var a=t("react"),r=t("@elementor/icons"),o=t("@elementor/ui"),n=t("@wordpress/i18n"),l=t("./packages/packages/core/editor-global-classes/src/utils/tracking.ts"),c=t("./packages/packages/core/editor-global-classes/src/components/search-and-filter/context.tsx");const ClassManagerSearch=()=>{const{search:{inputValue:e,handleChange:s}}=(0,c.useSearchAndFilters)();return a.createElement(o.Stack,{direction:"row",gap:.5,sx:{width:"100%"}},a.createElement(o.Box,{sx:{flexGrow:1}},a.createElement(o.TextField,{role:"search",fullWidth:!0,size:"tiny",value:e,onFocus:()=>{(0,l.trackGlobalClasses)({event:"classManagerSearched"})},placeholder:(0,n.__)("Search","elementor"),onChange:e=>s(e.target.value),InputProps:{startAdornment:a.createElement(o.InputAdornment,{position:"start"},a.createElement(r.SearchIcon,{fontSize:"tiny"}))}})))}},"./packages/packages/core/editor-global-classes/src/components/search-and-filter/context.tsx":function(e,s,t){t.r(s),t.d(s,{SearchAndFilterProvider:function(){return SearchAndFilterProvider},useSearchAndFilters:function(){return useSearchAndFilters}});var a=t("react"),r=t("@elementor/utils");const o=(0,a.createContext)(void 0),n={empty:!1,onThisPage:!1,unused:!1},SearchAndFilterProvider=({children:e})=>{const[s,t]=a.useState(n),{debouncedValue:l,inputValue:c,handleChange:i}=(0,r.useDebounceState)({delay:300,initialValue:(()=>{const e=localStorage.getItem("elementor-global-classes-search");return e?(localStorage.removeItem("elementor-global-classes-search"),e):""})()});return a.createElement(o.Provider,{value:{search:{debouncedValue:l,inputValue:c,handleChange:i,onClearSearch:()=>{i("")}},filters:{filters:s,setFilters:t,onClearFilter:()=>{t(n)}}}},e)},useSearchAndFilters=()=>{const e=(0,a.useContext)(o);if(!e)throw new Error("useSearchContext must be used within a SearchContextProvider");return e}},"./packages/packages/core/editor-global-classes/src/errors.ts":function(e,s,t){t.r(s),t.d(s,{GlobalClassLabelAlreadyExistsError:function(){return o},GlobalClassNotFoundError:function(){return r},GlobalClassTrackingError:function(){return n}});var a=t("@elementor/utils");const r=(0,a.createError)({code:"global_class_not_found",message:"Global class not found."}),o=(0,a.createError)({code:"global_class_label_already_exists",message:"Class with this name already exists."}),n=(0,a.createError)({code:"global_class_tracking_error",message:"Error tracking global classes event."})},"./packages/packages/core/editor-global-classes/src/global-classes-styles-provider.ts":function(e,s,t){t.r(s),t.d(s,{GLOBAL_CLASSES_PROVIDER_KEY:function(){return p},globalClassesStylesProvider:function(){return u}});var a=t("@elementor/editor-styles"),r=t("@elementor/editor-styles-repository"),o=t("@elementor/store"),n=t("@wordpress/i18n"),l=t("./packages/packages/core/editor-global-classes/src/capabilities.ts"),c=t("./packages/packages/core/editor-global-classes/src/errors.ts"),i=t("./packages/packages/core/editor-global-classes/src/store.ts"),d=t("./packages/packages/core/editor-global-classes/src/utils/tracking.ts");const p="global-classes",u=(0,r.createStylesProvider)({key:p,priority:30,limit:100,labels:{singular:(0,n.__)("class","elementor"),plural:(0,n.__)("classes","elementor")},subscribe:e=>subscribeWithStates(e),capabilities:(0,l.getCapabilities)(),actions:{all:()=>{const e=(0,i.selectOrderedClasses)((0,o.__getState)());return localStorage.setItem("elementor-global-classes",JSON.stringify(e)),e},get:e=>(0,i.selectClass)((0,o.__getState)(),e),resolveCssName:e=>(0,i.selectClass)((0,o.__getState)(),e)?.label??e,create:(e,s=[])=>{const t=(0,i.selectGlobalClasses)((0,o.__getState)());if(Object.values(t).map(e=>e.label).includes(e))throw new c.GlobalClassLabelAlreadyExistsError({context:{label:e}});const r=Object.keys(t),n=(0,a.generateId)("g-",r);return(0,o.__dispatch)(i.slice.actions.add({id:n,type:"class",label:e,variants:s})),n},update:e=>{(0,o.__dispatch)(i.slice.actions.update({style:e}))},delete:e=>{(0,o.__dispatch)(i.slice.actions.delete(e))},updateProps:e=>{(0,o.__dispatch)(i.slice.actions.updateProps({id:e.id,meta:e.meta,props:e.props}))},updateCustomCss:e=>{(0,o.__dispatch)(i.slice.actions.updateProps({id:e.id,meta:e.meta,custom_css:e.custom_css,props:{}}))},tracking:e=>{(0,d.trackGlobalClasses)(e).catch(e=>{throw new c.GlobalClassTrackingError({cause:e})})}}}),subscribeWithStates=e=>{let s=(0,i.selectData)((0,o.__getState)());return(0,o.__subscribeWithSelector)(e=>e.globalClasses,t=>{e(s.items,t.data.items),s=t.data})}},"./packages/packages/core/editor-global-classes/src/hooks/use-classes-order.ts":function(e,s,t){t.r(s),t.d(s,{useClassesOrder:function(){return useClassesOrder}});var a=t("@elementor/store"),r=t("./packages/packages/core/editor-global-classes/src/store.ts");const useClassesOrder=()=>(0,a.__useSelector)(r.selectOrder)},"./packages/packages/core/editor-global-classes/src/hooks/use-css-class-usage-by-id.ts":function(e,s,t){t.r(s),t.d(s,{useCssClassUsageByID:function(){return useCssClassUsageByID}});var a=t("./packages/packages/core/editor-global-classes/src/hooks/use-css-class-usage.ts");const r={total:0,content:[]},useCssClassUsageByID=e=>{const{data:s,...t}=(0,a.useCssClassUsage)();return{...t,data:s?.[e]??r}}},"./packages/packages/core/editor-global-classes/src/hooks/use-css-class-usage.ts":function(e,s,t){t.r(s),t.d(s,{useCssClassUsage:function(){return useCssClassUsage}});var a=t("@elementor/query"),r=t("./packages/packages/core/editor-global-classes/service/css-class-usage-service.ts"),o=t("./packages/packages/core/editor-global-classes/src/components/css-class-usage/types.ts");const useCssClassUsage=()=>(0,a.useQuery)({queryKey:[o.QUERY_KEY],queryFn:r.fetchCssClassUsage,refetchOnMount:!1,refetchOnWindowFocus:!0})},"./packages/packages/core/editor-global-classes/src/hooks/use-dirty-state.ts":function(e,s,t){t.r(s),t.d(s,{useDirtyState:function(){return useDirtyState}});var a=t("@elementor/store"),r=t("./packages/packages/core/editor-global-classes/src/store.ts");const useDirtyState=()=>(0,a.__useSelector)(r.selectIsDirty)},"./packages/packages/core/editor-global-classes/src/hooks/use-empty-css-class.ts":function(e,s,t){t.r(s),t.d(s,{useAllCssClassesIDs:function(){return useAllCssClassesIDs},useEmptyCssClass:function(){return useEmptyCssClass}});var a=t("@elementor/store"),r=t("./packages/packages/core/editor-global-classes/src/store.ts");const useEmptyCssClass=()=>(0,a.__useSelector)(r.selectEmptyCssClass),useAllCssClassesIDs=()=>{const e=(0,a.__useSelector)(r.selectGlobalClasses);return Object.keys(e)}},"./packages/packages/core/editor-global-classes/src/hooks/use-filtered-css-class-usage.tsx":function(e,s,t){t.r(s),t.d(s,{useFilteredCssClassUsage:function(){return useFilteredCssClassUsage}});var a=t("react"),r=t("@elementor/editor-documents"),o=t("./packages/packages/core/editor-global-classes/src/hooks/use-css-class-usage.ts"),n=t("./packages/packages/core/editor-global-classes/src/hooks/use-empty-css-class.ts");const l={empty:[],onThisPage:[],unused:[]},useFilteredCssClassUsage=()=>{const e=(0,r.__useActiveDocument)(),s=(0,n.useEmptyCssClass)(),{data:t,isLoading:c}=(0,o.useCssClassUsage)(),i=(0,n.useAllCssClassesIDs)(),d=(0,a.useMemo)(()=>s.map(({id:e})=>e),[s]),p=(0,a.useMemo)(()=>t&&e?((e,s)=>{const t=[];for(const a in e)e[a].content.forEach(e=>{+e.pageId===s&&t.push(a)});return t})(t,e.id):[],[t,e]),u=(0,a.useMemo)(()=>t?((e,s)=>{const t=new Set(e);return s.filter(e=>!t.has(e))})(Object.keys(t),i):[],[t,i]);return!c&&t&&e?{onThisPage:p,unused:u,empty:d}:l}},"./packages/packages/core/editor-global-classes/src/hooks/use-filters.ts":function(e,s,t){t.r(s),t.d(s,{useFilters:function(){return useFilters}});var a=t("react"),r=t("./packages/packages/core/editor-global-classes/src/components/search-and-filter/context.tsx"),o=t("./packages/packages/core/editor-global-classes/src/hooks/use-filtered-css-class-usage.tsx");const useFilters=()=>{const{filters:{filters:e}}=(0,r.useSearchAndFilters)(),s=(0,o.useFilteredCssClassUsage)();return(0,a.useMemo)(()=>{const t=Object.entries(e).filter(([,e])=>e);return 0===t.length?null:t.reduce((e,[t],a)=>{const r=s[t]||[];return 0===a?r:e.filter(e=>r.includes(e))},[])},[e,s])}},"./packages/packages/core/editor-global-classes/src/hooks/use-ordered-classes.ts":function(e,s,t){t.r(s),t.d(s,{useOrderedClasses:function(){return useOrderedClasses}});var a=t("@elementor/store"),r=t("./packages/packages/core/editor-global-classes/src/store.ts");const useOrderedClasses=()=>(0,a.__useSelector)(r.selectOrderedClasses)},"./packages/packages/core/editor-global-classes/src/hooks/use-prefetch-css-class-usage.ts":function(e,s,t){t.r(s),t.d(s,{PrefetchCssClassUsage:function(){return PrefetchCssClassUsage},usePrefetchCssClassUsage:function(){return usePrefetchCssClassUsage}});var a=t("@elementor/query"),r=t("./packages/packages/core/editor-global-classes/service/css-class-usage-service.ts"),o=t("./packages/packages/core/editor-global-classes/src/components/css-class-usage/types.ts");function usePrefetchCssClassUsage(){const e=(0,a.useQueryClient)();return{prefetchClassesUsage:()=>e.prefetchQuery({queryKey:[o.QUERY_KEY],queryFn:r.fetchCssClassUsage})}}const PrefetchCssClassUsage=()=>{const{prefetchClassesUsage:e}=usePrefetchCssClassUsage();return e(),null}},"./packages/packages/core/editor-global-classes/src/init.ts":function(e,s,t){t.r(s),t.d(s,{init:function(){return init}});var a=t("@elementor/editor"),r=t("@elementor/editor-editing-panel"),o=t("@elementor/editor-panels"),n=t("@elementor/editor-styles-repository"),l=t("@elementor/store"),c=t("./packages/packages/core/editor-global-classes/src/components/class-manager/class-manager-button.tsx"),i=t("./packages/packages/core/editor-global-classes/src/components/class-manager/class-manager-panel.tsx"),d=t("./packages/packages/core/editor-global-classes/src/components/convert-local-class-to-global-class.tsx"),p=t("./packages/packages/core/editor-global-classes/src/components/populate-store.tsx"),u=t("./packages/packages/core/editor-global-classes/src/global-classes-styles-provider.ts"),g=t("./packages/packages/core/editor-global-classes/src/hooks/use-prefetch-css-class-usage.ts"),m=t("./packages/packages/core/editor-global-classes/src/mcp-integration/index.ts"),h=t("./packages/packages/core/editor-global-classes/src/store.ts"),b=t("./packages/packages/core/editor-global-classes/src/sync-with-document.tsx");function init(){(0,l.__registerSlice)(h.slice),(0,o.__registerPanel)(i.panel),n.stylesRepository.register(u.globalClassesStylesProvider),(0,a.injectIntoLogic)({id:"global-classes-populate-store",component:p.PopulateStore}),(0,a.injectIntoLogic)({id:"global-classes-sync-with-document",component:b.SyncWithDocumentSave}),(0,a.injectIntoLogic)({id:"global-classes-prefetch-css-class-usage",component:g.PrefetchCssClassUsage}),(0,r.injectIntoCssClassConvert)({id:"global-classes-convert-from-local-class",component:d.ConvertLocalClassToGlobalClass}),(0,r.injectIntoClassSelectorActions)({id:"global-classes-manager-button",component:c.ClassManagerButton}),(0,r.registerStyleProviderToColors)(u.GLOBAL_CLASSES_PROVIDER_KEY,{name:"global",getThemeColor:e=>e.palette.global.dark}),(0,m.initMcpIntegration)()}},"./packages/packages/core/editor-global-classes/src/mcp-integration/classes-resource.ts":function(e,s,t){t.r(s),t.d(s,{GLOBAL_CLASSES_URI:function(){return o},initClassesResource:function(){return initClassesResource}});var a=t("@elementor/editor-mcp"),r=t("./packages/packages/core/editor-global-classes/src/global-classes-styles-provider.ts");const o="elementor://global-classes",initClassesResource=()=>{[(0,a.getMCPByDomain)("canvas"),(0,a.getMCPByDomain)("classes")].forEach(e=>{const{mcpServer:s,resource:t,waitForReady:a}=e;t("global-classes",o,{description:"Global classes list."},async()=>({contents:[{uri:o,text:localStorage["elementor-global-classes"]??"{}"}]})),a().then(()=>{r.globalClassesStylesProvider.subscribe(()=>{s.sendResourceListChanged()})})})}},"./packages/packages/core/editor-global-classes/src/mcp-integration/index.ts":function(e,s,t){t.r(s),t.d(s,{initMcpIntegration:function(){return initMcpIntegration}});var a=t("@elementor/editor-mcp"),r=t("./packages/packages/core/editor-global-classes/src/mcp-integration/classes-resource.ts"),o=t("./packages/packages/core/editor-global-classes/src/mcp-integration/mcp-apply-unapply-global-classes.ts"),n=t("./packages/packages/core/editor-global-classes/src/mcp-integration/mcp-get-global-class-usages.ts"),l=t("./packages/packages/core/editor-global-classes/src/mcp-integration/mcp-manage-global-classes.ts");const initMcpIntegration=()=>{const e=(0,a.getMCPByDomain)("classes",{instructions:"MCP server for management of Elementor global classes"});(0,o.default)(e),(0,n.default)(e),(0,l.initManageGlobalClasses)(e),(0,r.initClassesResource)()}},"./packages/packages/core/editor-global-classes/src/mcp-integration/mcp-apply-unapply-global-classes.ts":function(e,s,t){t.r(s),t.d(s,{default:function(){return initMcpApplyUnapplyGlobalClasses}});var a=t("@elementor/editor-editing-panel"),r=t("@elementor/schema");function initMcpApplyUnapplyGlobalClasses(e){e.addTool({schema:{classId:r.z.string().describe("The ID of the class to apply"),elementId:r.z.string().describe("The ID of the element to which the class will be applied")},outputSchema:{result:r.z.string().describe("Result message indicating the success of the apply operation")},name:"apply-global-class",modelPreferences:{intelligencePriority:.7,speedPriority:.8},description:'Apply a global class to an element, enabling consistent styling through your design system.\n\n## When to use this tool:\n**ALWAYS use this IMMEDIATELY AFTER building compositions** to apply the global classes you created beforehand:\n- After using "build-compositions" tool, apply semantic classes to the created elements\n- When applying consistent typography styles (heading-primary, text-body, etc.)\n- When applying theme colors or brand styles (bg-brand, button-cta, etc.)\n- When ensuring spacing consistency (spacing-section-large, etc.)\n\n**DO NOT use this tool** for:\n- Elements that don\'t share styles with other elements (use inline styles instead)\n- Layout-specific properties (those should remain inline in stylesConfig)\n\n## Prerequisites:\n- **REQUIRED**: Get the list of available global classes from \'elementor://global-classes\' resource\n- **REQUIRED**: Get element IDs from the composition XML returned by "build-compositions" tool\n- Ensure you have the most up-to-date list of classes applied to the element to avoid duplicates\n- Make sure you have the correct class ID that you want to apply\n\n## Best Practices:\n1. Apply multiple classes to a single element if needed (typography + color + spacing)\n2. After applying, the tool will remind you to remove duplicate inline styles from elementConfig\n3. Classes should describe purpose, not implementation (e.g., "heading-primary" not "big-red-text")',handler:async e=>{const{classId:s,elementId:t}=e,r=(0,a.doGetAppliedClasses)(t);return(0,a.doApplyClasses)(t,[...r,s]),{llm_instructions:"Please check the element-configuration, find DUPLICATES in the style schema that are in the class, and remove them",result:`Class ${s} applied to element ${t} successfully.`}}}),e.addTool({name:"unapply-global-class",schema:{classId:r.z.string().describe("The ID of the class to unapply"),elementId:r.z.string().describe("The ID of the element from which the class will be unapplied")},outputSchema:{result:r.z.string().describe("Result message indicating the success of the unapply operation")},modelPreferences:{intelligencePriority:.7,speedPriority:.8},description:"Unapply a (global) class from the current element\n\n## When to use this tool:\n- When a user requests to unapply a global class or a class from an element in the Elementor editor.\n- When you need to remove a specific class from an element's applied classes.\n\n## Prerequisites:\n- Ensure you have the most up-to-date list of classes applied to the element to avoid errors.\n The list is available at always up-to-date resource 'elementor://global-classes'.\n- Make sure you have the correct class ID that you want to unapply.\n\n<note>\nIf the user want to unapply a class by it's name and not ID, retreive the id from the list, available at uri elementor://global-classes\n</note>\n",handler:async e=>{const{classId:s,elementId:t}=e;if(!(0,a.doUnapplyClass)(t,s))throw new Error(`Class ${s} is not applied to element ${t}, cannot unapply it.`);return{result:`Class ${s} unapplied from element ${t} successfully.`}}})}},"./packages/packages/core/editor-global-classes/src/mcp-integration/mcp-get-global-class-usages.ts":function(e,s,t){t.r(s),t.d(s,{default:function(){return initMcpApplyGetGlobalClassUsages}});var a=t("@elementor/schema"),r=t("./packages/packages/core/editor-global-classes/service/css-class-usage-service.ts");function initMcpApplyGetGlobalClassUsages(e){const{addTool:s}=e;s({name:"get-global-class-usages",modelPreferences:{intelligencePriority:.6,speedPriority:.8},description:"Retreive the usages of global-classes ACCROSS PAGES designed by Elementor editor.\n\n## Prequisites: CRITICAL\n- The list of global classes and their applid values is available at resource uri elementor://global-classes\n\n## When to use this tool:\n- When a user requests to see where a specific global class is being used accross the site.\n- When you need to manage or clean up unused global classes.\n- Before deleting a global class, to ensure it is not in use in any other pages.\n\n## When NOT to use this tool:\n- For getting the list of global classes, refer to the resource at uri elementor://global-classes\n",outputSchema:{usages:a.z.array(a.z.object({classId:a.z.string().describe('The ID of the class, not visible to the user. To retreive the name of the class, use the "list-global-classes" tool'),usages:a.z.array(a.z.object({pageId:a.z.string().describe("The ID of the page where the class is used"),title:a.z.string().describe("The title of the page where the class is used"),total:a.z.number().describe("The number of times the class is used on this page"),elements:a.z.array(a.z.string()).describe("List of element IDs using this class on the page")}))}))},handler:async()=>{const e=await(0,r.fetchCssClassUsage)(),s={usages:[]};return Object.entries(e).forEach(([e,t])=>{const a={classId:e,usages:[]};if("number"!=typeof t){const{content:e}=t;e.forEach(e=>{a.usages.push({pageId:String(e.pageId),title:e.title,total:e.total,elements:e.elements})}),s.usages.push(a)}}),s}})}},"./packages/packages/core/editor-global-classes/src/mcp-integration/mcp-manage-global-classes.ts":function(e,s,t){t.r(s),t.d(s,{initManageGlobalClasses:function(){return initManageGlobalClasses}});var a=t("@elementor/editor-canvas"),r=t("@elementor/editor-props"),o=t("@elementor/editor-styles"),n=t("@elementor/schema"),l=t("./packages/packages/core/editor-global-classes/src/global-classes-styles-provider.ts"),c=t("./packages/packages/core/editor-global-classes/src/save-global-classes.tsx"),i=t("./packages/packages/core/editor-global-classes/src/mcp-integration/classes-resource.ts");const d={action:n.z.enum(["create","modify","delete"]).describe("Operation to perform"),classId:n.z.string().optional().describe("Global class ID (required for modify). Get from elementor://global-classes resource."),globalClassName:n.z.string().optional().describe("Global class name (required for create)"),props:n.z.record(n.z.any()).describe('key-value of style-schema PropValues. Available properties at dynamic resource "elementor://styles/schema/{property-name}"'),breakpoint:n.z.nullable(n.z.string().describe("Responsive breakpoint name for styles. Defaults to desktop (null).")).default(null).describe("Responsive breakpoint name for styles. Defaults to desktop (null).")},p={status:n.z.enum(["ok","error"]).describe("Operation status"),classId:n.z.string().optional().describe("Class ID (returned on create success)"),message:n.z.string().optional().describe("Error details if status is error")},handler=async e=>{const{action:s,classId:t,globalClassName:a,props:n,breakpoint:i}=e;if("create"===s&&!a)return{status:"error",message:"Create requires globalClassName"};if("modify"===s&&!t)return{status:"error",message:"Modify requires classId"};if("delete"===s&&!t)return{status:"error",message:"Delete requires classId"};const{create:d,update:p,delete:u}=l.globalClassesStylesProvider.actions;if(!d||!p||!u)return{status:"error",message:"Required actions not available"};const g=[],m=(0,o.getStylesSchema)(),h=Object.keys(m);if(Object.keys(n).forEach(e=>{const s=m[e];if(!s)return void g.push(`Property "${e}" does not exist in styles schema.`);const{valid:t,jsonSchema:a}=r.Schema.validatePropValue(s,n[e]);t||g.push(`- Property "${e}" has invalid value\n Expected schema: ${a}\n`)}),g.length>0)return{status:"error",message:`Validation errors:\n${g.join("\n")}\nAvailable Properties: ${h.join(", ")}\nUpdate your input and try again.`};const b=window.elementorV2.editorVariables.Utils;Object.keys(n).forEach(e=>{n[e]=r.Schema.adjustLlmPropValueSchema(n[e],{transformers:b.globalVariablesLLMResolvers})});const f=i??"desktop";try{switch(s){case"create":const e=await async function attemptCreate(e){const{props:s,breakpoint:t,className:a,stylesProvider:r}=e,{create:o,delete:n}=r.actions;if(!a)throw new Error("Global class name is a required for creation");if(!o||!n)throw new Error("User is unable to create global classes");const l=o(a,[{meta:{breakpoint:t,state:null},custom_css:null,props:s}]);try{return await(0,c.saveGlobalClasses)({context:"frontend"}),l}catch{return n(l),null}}({props:n,className:a,stylesProvider:l.globalClassesStylesProvider,breakpoint:f});return e?{status:"ok",message:`created global class with ID ${e}`}:{status:"error",message:"error creating class"};case"modify":const s=await async function attemptUpdate(e){const{props:s,breakpoint:t,classId:a,stylesProvider:r}=e,{updateProps:o,update:n}=r.actions;if(!a)throw new Error("Class ID is required for modification");if(!o||!n)throw new Error("User is unable to update global classes");const l=structuredClone(r.actions.all());try{return o({id:a,props:s,meta:{breakpoint:t,state:null}}),await(0,c.saveGlobalClasses)({context:"frontend"}),!0}catch{return l.forEach(e=>{n({id:e.id,variants:e.variants})}),await(0,c.saveGlobalClasses)({context:"frontend"}),!1}}({classId:t,props:n,stylesProvider:l.globalClassesStylesProvider,breakpoint:f});return s?{status:"ok",classId:t}:{status:"error",message:"error modifying class"};case"delete":const r=await async function attemptDelete(e){const{classId:s,stylesProvider:t}=e,{delete:a,create:r}=t.actions;if(!s)throw new Error("Class ID is required for deletion");if(!a||!r)throw new Error("User is unable to delete global classes");const o=structuredClone(t.actions.all()).find(e=>e.id===s);if(!o)throw new Error(`Class with ID "${s}" not found`);try{return a(s),await(0,c.saveGlobalClasses)({context:"frontend"}),!0}catch{return!1}}({classId:t,stylesProvider:l.globalClassesStylesProvider});return r?{status:"ok",message:`deleted global class with ID ${t}`}:{status:"error",message:"error deleting class"}}}catch(e){return{status:"error",message:`${s} failed: ${e.message||"Unknown error"}`}}},initManageGlobalClasses=e=>{const{addTool:s}=e;s({name:"manage-global-classes",requiredResources:[{uri:i.GLOBAL_CLASSES_URI,description:"Global classes list"},{uri:a.STYLE_SCHEMA_URI,description:"Style schema resources"},{uri:a.BREAKPOINTS_SCHEMA_URI,description:"Breakpoints list"}],modelPreferences:{intelligencePriority:.85,speedPriority:.6},description:"Manages global classes (create/modify) in Elementor editor. Check [elementor://global-classes] and style schemas first.\n\nCREATE: Requires globalClassName, props. Use semantic naming (heading-primary, button-cta, text-muted). Check existing classes to avoid duplicates. ALWAYS create global classes BEFORE compositions for reusable styles.\nMODIFY: Requires classId, props. Get classId from [elementor://global-classes] resource.\n\nNaming pattern: [element-type]-[purpose/variant]-[modifier]\nDO NOT create global classes for: one-off styles, layout-specific properties.\n\nUse style schema at [elementor://styles/schema/{category}] for valid props. Errors include exact schema mismatch details.",schema:d,outputSchema:p,handler:handler})}},"./packages/packages/core/editor-global-classes/src/save-global-classes.tsx":function(e,s,t){t.r(s),t.d(s,{saveGlobalClasses:function(){return saveGlobalClasses}});var a=t("react"),r=t("@elementor/editor-ui"),o=t("@elementor/store"),n=t("@elementor/utils"),l=t("./packages/packages/core/editor-global-classes/src/api.ts"),c=t("./packages/packages/core/editor-global-classes/src/components/class-manager/duplicate-label-dialog.tsx"),i=t("./packages/packages/core/editor-global-classes/src/store.ts"),d=t("./packages/packages/core/editor-global-classes/src/utils/tracking.ts");async function saveGlobalClasses({context:e,onApprove:s}){const t=(0,i.selectData)((0,o.__getState)()),n="preview"===e?l.apiClient.saveDraft:l.apiClient.publish,p="preview"===e?i.selectPreviewInitialData:i.selectFrontendInitialData,u=await n({items:t.items,order:t.order,changes:calculateChanges(t,p((0,o.__getState)()))});(0,o.__dispatch)(i.slice.actions.reset({context:e})),u?.data?.data?.code===l.API_ERROR_CODES.DUPLICATED_LABEL&&((0,o.__dispatch)(i.slice.actions.updateMultiple(u.data.data.modifiedLabels)),(0,d.trackGlobalClasses)({event:"classPublishConflict",numOfConflicts:Object.keys(u.data.data.modifiedLabels).length}),(0,r.openDialog)({component:a.createElement(c.DuplicateLabelDialog,{modifiedLabels:u.data.data.modifiedLabels||[],onApprove:s})}))}function calculateChanges(e,s){const t=Object.keys(e.items),a=Object.keys(s.items);return{added:t.filter(e=>!a.includes(e)),deleted:a.filter(e=>!t.includes(e)),modified:t.filter(t=>t in s.items&&(0,n.hash)(e.items[t])!==(0,n.hash)(s.items[t]))}}},"./packages/packages/core/editor-global-classes/src/store.ts":function(e,s,t){t.r(s),t.d(s,{selectClass:function(){return selectClass},selectData:function(){return selectData},selectEmptyCssClass:function(){return u},selectFrontendInitialData:function(){return selectFrontendInitialData},selectGlobalClasses:function(){return d},selectIsDirty:function(){return selectIsDirty},selectOrder:function(){return i},selectOrderedClasses:function(){return p},selectPreviewInitialData:function(){return selectPreviewInitialData},slice:function(){return c}});var a=t("@elementor/editor-styles"),r=t("@elementor/store"),o=t("./packages/packages/core/editor-global-classes/src/errors.ts");const n=t("./packages/packages/core/editor-global-classes/src/utils/snapshot-history.ts").SnapshotHistory.get("global-classes"),l="globalClasses",c=(0,r.__createSlice)({name:l,initialState:{data:{items:{},order:[]},initialData:{frontend:{items:{},order:[]},preview:{items:{},order:[]}},isDirty:!1},reducers:{load(e,{payload:{frontend:s,preview:t}}){e.initialData.frontend=s,e.initialData.preview=t,e.data=t,e.isDirty=!1},add(e,{payload:s}){n.next(e.data),e.data.items[s.id]=s,e.data.order.unshift(s.id),e.isDirty=!0},delete(e,{payload:s}){n.next(e.data),e.data.items=Object.fromEntries(Object.entries(e.data.items).filter(([e])=>e!==s)),e.data.order=e.data.order.filter(e=>e!==s),e.isDirty=!0},setOrder(e,{payload:s}){n.next(e.data),e.data.order=s,e.isDirty=!0},update(e,{payload:s}){n.next(e.data);const t={...e.data.items[s.style.id],...s.style};e.data.items[s.style.id]=t,e.isDirty=!0},updateMultiple(e,{payload:s}){n.next(e.data),Object.entries(s).forEach(([s,{modified:t}])=>{e.data.items[s].label=t}),e.isDirty=!1},updateProps(e,{payload:s}){const t=e.data.items[s.id];if(!t)throw new o.GlobalClassNotFoundError({context:{styleId:s.id}});n.next(e.data);const r=(0,a.getVariantByMeta)(t,s.meta);let l=("custom_css"in s?s.custom_css:r?.custom_css)??null;if(l=l?.raw?l:null,r){const e=JSON.parse(JSON.stringify(r.props)),a=JSON.parse(JSON.stringify(s.props));r.props=mergeProps(e,a),r.custom_css=l,t.variants=getNonEmptyVariants(t)}else t.variants.push({meta:s.meta,props:s.props,custom_css:l});e.isDirty=!0},reset(e,{payload:{context:s}}){"frontend"===s&&(n.reset(),e.initialData.frontend=e.data,e.isDirty=!1),e.initialData.preview=e.data},undo(e){n.isLast()&&n.next(e.data);const s=n.prev();s?(e.data=s,e.isDirty=!0):e.data=e.initialData.preview},resetToInitialState(e,{payload:{context:s}}){n.reset(),e.data=e.initialData[s],e.isDirty=!1},redo(e){const s=n.next();n.isLast()&&n.prev(),s&&(e.data=s,e.isDirty=!0)}}}),mergeProps=(e,s)=>{const t=Array.isArray(e)?{}:e;return Object.entries(s).forEach(([e,s])=>{null==s?delete t[e]:t[e]=s}),t},getNonEmptyVariants=e=>e.variants.filter(({props:e,custom_css:s})=>Object.keys(e).length||s?.raw),selectData=e=>e[l].data,selectFrontendInitialData=e=>e[l].initialData.frontend,selectPreviewInitialData=e=>e[l].initialData.preview,i=(0,r.__createSelector)(selectData,({order:e})=>e),d=(0,r.__createSelector)(selectData,({items:e})=>e),selectIsDirty=e=>e[l].isDirty,p=(0,r.__createSelector)(d,i,(e,s)=>s.map(s=>e[s])),selectClass=(e,s)=>e[l].data.items[s]??null,u=(0,r.__createSelector)(selectData,({items:e})=>Object.values(e).filter(e=>0===e.variants.length))},"./packages/packages/core/editor-global-classes/src/sync-with-document-save.ts":function(e,s,t){t.r(s),t.d(s,{syncWithDocumentSave:function(){return syncWithDocumentSave}});var a=t("@elementor/editor-current-user"),r=t("@elementor/editor-documents"),o=t("@elementor/editor-v1-adapters"),n=t("@elementor/store"),l=t("./packages/packages/core/editor-global-classes/src/capabilities.ts"),c=t("./packages/packages/core/editor-global-classes/src/save-global-classes.tsx"),i=t("./packages/packages/core/editor-global-classes/src/store.ts");function syncWithDocumentSave(e){const s=function syncDirtyState(){return(0,n.__subscribeWithSelector)(i.selectIsDirty,()=>{(function isDirty(){return(0,i.selectIsDirty)((0,n.__getState)())})()&&(0,r.setDocumentModifiedStatus)(!0)})}();return function bindSaveAction(e){(0,o.registerDataHook)("dependency","document/save/save",s=>{const t=(0,a.getCurrentUser)(),r=t?.capabilities.includes(l.UPDATE_CLASS_CAPABILITY_KEY);return!r||((0,c.saveGlobalClasses)({context:"publish"===s.status?"frontend":"preview",onApprove:e?.open}),!0)})}(e),s}},"./packages/packages/core/editor-global-classes/src/sync-with-document.tsx":function(e,s,t){t.r(s),t.d(s,{SyncWithDocumentSave:function(){return SyncWithDocumentSave}});var a=t("react"),r=t("@elementor/editor-v1-adapters"),o=t("./packages/packages/core/editor-global-classes/src/components/class-manager/class-manager-panel.tsx"),n=t("./packages/packages/core/editor-global-classes/src/sync-with-document-save.ts");function SyncWithDocumentSave(){const e=(0,o.usePanelActions)();return(0,a.useEffect)(()=>{(0,r.__privateListenTo)((0,r.v1ReadyEvent)(),()=>{(0,n.syncWithDocumentSave)(e)})},[]),null}},"./packages/packages/core/editor-global-classes/src/utils/snapshot-history.ts":function(e,s,t){function createLink({value:e,next:s,prev:t}){return{value:e,prev:t||null,next:s||null}}t.r(s),t.d(s,{SnapshotHistory:function(){return SnapshotHistory}});class SnapshotHistory{static registry={};static get(e){return SnapshotHistory.registry[e]||(SnapshotHistory.registry[e]=new SnapshotHistory(e)),SnapshotHistory.registry[e]}first=null;current=null;constructor(e){this.namespace=e}transform(e){return JSON.parse(JSON.stringify(e))}reset(){this.first=this.current=null}prev(){return this.current&&this.current!==this.first?(this.current=this.current.prev,this.current?.value||null):null}isLast(){return!this.current||!this.current.next}next(e){if(e){if(!this.current)return this.first=createLink({value:this.transform(e)}),this.current=this.first,this.current.value;const s=createLink({value:this.transform(e),prev:this.current});return this.current.next=s,this.current=s,this.current.value}return this.current&&this.current.next?(this.current=this.current.next,this.current.value):null}}},"./packages/packages/core/editor-global-classes/src/utils/tracking.ts":function(e,s,t){t.r(s),t.d(s,{trackGlobalClasses:function(){return trackGlobalClasses}});var a=t("@elementor/mixpanel"),r=t("@elementor/store"),o=t("./packages/packages/core/editor-global-classes/service/css-class-usage-service.ts"),n=t("./packages/packages/core/editor-global-classes/src/errors.ts"),l=t("./packages/packages/core/editor-global-classes/src/store.ts");const trackGlobalClasses=async e=>{const{runAction:s}=e,t=await getSanitizedData(e);t&&(track(t),"classCreated"===t.event&&"classId"in t&&fireClassApplied(t.classId)),s?.()},fireClassApplied=async e=>{const s=await getAppliedInfo(e);track({event:"classApplied",classId:e,...s,totalInstancesAfterApply:1})},getSanitizedData=async e=>{switch(e.event){case"classApplied":if("classId"in e&&e.classId){const s=await getAppliedInfo(e.classId);return{...e,...s}}break;case"classRemoved":if("classId"in e&&e.classId){const s=getRemovedInfo(e.classId);return{...e,...s}}break;case"classDeleted":if("classId"in e&&e.classId){const s=await trackDeleteClass(e.classId);return{...e,...s}}break;case"classCreated":return"source"in e&&"created"!==e.source&&"classId"in e&&e.classId?{...e,classTitle:getCssClass(e.classId).label}:e;case"classStateClicked":if("classId"in e&&e.classId)return{...e,classTitle:getCssClass(e.classId).label};break;default:return e}},track=e=>{const{dispatchEvent:s,config:t}=(0,a.getMixpanel)();if(!t?.names?.global_classes?.[e.event])return void console.error("Global class tracking event not found",{event:e.event});const r=t.names.global_classes[e.event],{event:o,...l}=e;try{s?.(r,{event:o,...l})}catch(e){throw new n.GlobalClassTrackingError({cause:e})}},extractCssClassData=e=>({classTitle:getCssClass(e).label}),getCssClass=e=>{const s=(0,l.selectClass)((0,r.__getState)(),e);if(!s)throw new Error(`CSS class with ID ${e} not found`);return s},trackDeleteClass=async e=>({totalInstances:await getTotalInstancesByCssClassID(e),classTitle:getCssClass(e).label}),getTotalInstancesByCssClassID=async e=>{const s=await(0,o.fetchCssClassUsage)();return s[e]?.total??1},getAppliedInfo=async e=>{const{classTitle:s}=extractCssClassData(e);return{classTitle:s,totalInstancesAfterApply:await getTotalInstancesByCssClassID(e)+1}},getRemovedInfo=e=>{const{classTitle:s}=extractCssClassData(e);return{classTitle:s}}},"@elementor/editor":function(e){e.exports=window.elementorV2.editor},"@elementor/editor-canvas":function(e){e.exports=window.elementorV2.editorCanvas},"@elementor/editor-current-user":function(e){e.exports=window.elementorV2.editorCurrentUser},"@elementor/editor-documents":function(e){e.exports=window.elementorV2.editorDocuments},"@elementor/editor-editing-panel":function(e){e.exports=window.elementorV2.editorEditingPanel},"@elementor/editor-mcp":function(e){e.exports=window.elementorV2.editorMcp},"@elementor/editor-panels":function(e){e.exports=window.elementorV2.editorPanels},"@elementor/editor-props":function(e){e.exports=window.elementorV2.editorProps},"@elementor/editor-styles":function(e){e.exports=window.elementorV2.editorStyles},"@elementor/editor-styles-repository":function(e){e.exports=window.elementorV2.editorStylesRepository},"@elementor/editor-ui":function(e){e.exports=window.elementorV2.editorUi},"@elementor/editor-v1-adapters":function(e){e.exports=window.elementorV2.editorV1Adapters},"@elementor/http-client":function(e){e.exports=window.elementorV2.httpClient},"@elementor/icons":function(e){e.exports=window.elementorV2.icons},"@elementor/mixpanel":function(e){e.exports=window.elementorV2.mixpanel},"@elementor/query":function(e){e.exports=window.elementorV2.query},"@elementor/schema":function(e){e.exports=window.elementorV2.schema},"@elementor/store":function(e){e.exports=window.elementorV2.store},"@elementor/ui":function(e){e.exports=window.elementorV2.ui},"@elementor/utils":function(e){e.exports=window.elementorV2.utils},"@wordpress/i18n":function(e){e.exports=window.wp.i18n},react:function(e){e.exports=window.React}},s={};function __webpack_require__(t){var a=s[t];if(void 0!==a)return a.exports;var r=s[t]={exports:{}};return e[t](r,r.exports,__webpack_require__),r.exports}__webpack_require__.n=function(e){var s=e&&e.__esModule?function(){return e.default}:function(){return e};return __webpack_require__.d(s,{a:s}),s},__webpack_require__.d=function(e,s){for(var t in s)__webpack_require__.o(s,t)&&!__webpack_require__.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:s[t]})},__webpack_require__.o=function(e,s){return Object.prototype.hasOwnProperty.call(e,s)},__webpack_require__.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var t={};!function(){__webpack_require__.r(t),__webpack_require__.d(t,{GLOBAL_CLASSES_URI:function(){return e.GLOBAL_CLASSES_URI},init:function(){return s.init}});var e=__webpack_require__("./packages/packages/core/editor-global-classes/src/mcp-integration/classes-resource.ts"),s=__webpack_require__("./packages/packages/core/editor-global-classes/src/init.ts")}(),(window.elementorV2=window.elementorV2||{}).editorGlobalClasses=t}(),window.elementorV2.editorGlobalClasses?.init?.();
3547 7 //# sourceMappingURL=editor-global-classes.js.map