@elementor/editor-global-classes 4.1.0-manual → 4.2.0-840

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -30,32 +30,35 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/index.ts
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
+ ClassManagerPanelEmbedded: () => ClassManagerPanelEmbedded,
33
34
  GLOBAL_CLASSES_URI: () => GLOBAL_CLASSES_URI,
34
- init: () => init
35
+ addDocumentClasses: () => addDocumentClasses,
36
+ createLabelsForClasses: () => createLabelsForClasses,
37
+ init: () => init,
38
+ loadExistingClasses: () => loadExistingClasses
35
39
  });
36
40
  module.exports = __toCommonJS(index_exports);
37
41
 
38
- // src/global-classes-styles-provider.ts
39
- var import_editor_styles2 = require("@elementor/editor-styles");
40
- var import_editor_styles_repository = require("@elementor/editor-styles-repository");
41
- var import_store4 = require("@elementor/store");
42
- var import_i18n = require("@wordpress/i18n");
43
-
44
- // src/capabilities.ts
42
+ // src/components/class-manager/class-manager-panel.tsx
43
+ var React19 = __toESM(require("react"));
44
+ var import_react10 = require("react");
45
+ var import_editor_current_user2 = require("@elementor/editor-current-user");
46
+ var import_editor_documents3 = require("@elementor/editor-documents");
47
+ var import_editor_panels = require("@elementor/editor-panels");
48
+ var import_editor_ui9 = require("@elementor/editor-ui");
45
49
  var import_editor_v1_adapters = require("@elementor/editor-v1-adapters");
46
- var EXPERIMENT_KEY = "global_classes_should_enforce_capabilities";
47
- var UPDATE_CLASS_CAPABILITY_KEY = "elementor_global_classes_update_class";
48
- var getCapabilities = () => {
49
- const shouldEnforceCapabilities = (0, import_editor_v1_adapters.isExperimentActive)(EXPERIMENT_KEY);
50
- if (shouldEnforceCapabilities) {
51
- return {
52
- update: UPDATE_CLASS_CAPABILITY_KEY,
53
- create: UPDATE_CLASS_CAPABILITY_KEY,
54
- delete: UPDATE_CLASS_CAPABILITY_KEY,
55
- updateProps: UPDATE_CLASS_CAPABILITY_KEY
56
- };
57
- }
58
- };
50
+ var import_icons11 = require("@elementor/icons");
51
+ var import_query2 = require("@elementor/query");
52
+ var import_store18 = require("@elementor/store");
53
+ var import_ui16 = require("@elementor/ui");
54
+ var import_i18n14 = require("@wordpress/i18n");
55
+
56
+ // src/hooks/use-classes-order.ts
57
+ var import_store2 = require("@elementor/store");
58
+
59
+ // src/store.ts
60
+ var import_editor_styles = require("@elementor/editor-styles");
61
+ var import_store = require("@elementor/store");
59
62
 
60
63
  // src/errors.ts
61
64
  var import_utils = require("@elementor/utils");
@@ -72,10 +75,6 @@ var GlobalClassTrackingError = (0, import_utils.createError)({
72
75
  message: "Error tracking global classes event."
73
76
  });
74
77
 
75
- // src/store.ts
76
- var import_editor_styles = require("@elementor/editor-styles");
77
- var import_store = require("@elementor/store");
78
-
79
78
  // src/utils/snapshot-history.ts
80
79
  function createLink({ value, next, prev }) {
81
80
  return {
@@ -140,6 +139,7 @@ var SnapshotHistory = class _SnapshotHistory {
140
139
  var localHistory = SnapshotHistory.get("global-classes");
141
140
  var initialState = {
142
141
  data: { items: {}, order: [] },
142
+ classLabels: {},
143
143
  initialData: {
144
144
  frontend: { items: {}, order: [] },
145
145
  preview: { items: {}, order: [] }
@@ -152,17 +152,19 @@ var slice = (0, import_store.__createSlice)({
152
152
  initialState,
153
153
  reducers: {
154
154
  load(state, {
155
- payload: { frontend, preview }
155
+ payload: { frontend, preview, classLabels }
156
156
  }) {
157
157
  state.initialData.frontend = frontend;
158
158
  state.initialData.preview = preview;
159
159
  state.data = preview;
160
+ state.classLabels = classLabels;
160
161
  state.isDirty = false;
161
162
  },
162
163
  add(state, { payload }) {
163
164
  localHistory.next(state.data);
164
165
  state.data.items[payload.id] = payload;
165
166
  state.data.order.unshift(payload.id);
167
+ state.classLabels[payload.id] = payload.label;
166
168
  state.isDirty = true;
167
169
  },
168
170
  delete(state, { payload }) {
@@ -171,6 +173,7 @@ var slice = (0, import_store.__createSlice)({
171
173
  Object.entries(state.data.items).filter(([id2]) => id2 !== payload)
172
174
  );
173
175
  state.data.order = state.data.order.filter((id2) => id2 !== payload);
176
+ delete state.classLabels[payload];
174
177
  state.isDirty = true;
175
178
  },
176
179
  setOrder(state, { payload }) {
@@ -192,6 +195,7 @@ var slice = (0, import_store.__createSlice)({
192
195
  localHistory.next(state.data);
193
196
  Object.entries(payload).forEach(([id2, { modified }]) => {
194
197
  state.data.items[id2].label = modified;
198
+ state.classLabels[id2] = modified;
195
199
  });
196
200
  state.isDirty = false;
197
201
  },
@@ -207,9 +211,14 @@ var slice = (0, import_store.__createSlice)({
207
211
  let customCss = ("custom_css" in payload ? payload.custom_css : variant?.custom_css) ?? null;
208
212
  customCss = customCss?.raw ? customCss : null;
209
213
  if (variant) {
210
- const variantProps = JSON.parse(JSON.stringify(variant.props));
211
214
  const payloadProps = JSON.parse(JSON.stringify(payload.props));
212
- variant.props = mergeProps(variantProps, payloadProps);
215
+ const mode = payload.mode ?? "merge";
216
+ if (mode === "replace") {
217
+ variant.props = payloadProps;
218
+ } else {
219
+ const variantProps = JSON.parse(JSON.stringify(variant.props));
220
+ variant.props = mergeProps(variantProps, payloadProps);
221
+ }
213
222
  variant.custom_css = customCss;
214
223
  style.variants = getNonEmptyVariants(style);
215
224
  } else {
@@ -251,6 +260,28 @@ var slice = (0, import_store.__createSlice)({
251
260
  state.data = data;
252
261
  state.isDirty = true;
253
262
  }
263
+ },
264
+ mergeExistingClasses(state, {
265
+ payload: { preview, frontend }
266
+ }) {
267
+ Object.entries(preview).forEach(([id2, previewClassData]) => {
268
+ const frontendClassData = frontend[id2];
269
+ if (previewClassData === null || previewClassData === void 0) {
270
+ return;
271
+ }
272
+ if (!(id2 in state.data.items)) {
273
+ state.data.items[id2] = previewClassData;
274
+ }
275
+ if (!(id2 in state.initialData.frontend.items)) {
276
+ state.initialData.frontend.items[id2] = frontendClassData;
277
+ }
278
+ if (!(id2 in state.initialData.preview.items)) {
279
+ state.initialData.preview.items[id2] = previewClassData;
280
+ }
281
+ if (!(id2 in state.classLabels)) {
282
+ state.classLabels[id2] = previewClassData.label;
283
+ }
284
+ });
254
285
  }
255
286
  }
256
287
  });
@@ -270,388 +301,47 @@ var getNonEmptyVariants = (style) => {
270
301
  ({ props, custom_css: customCss }) => Object.keys(props).length || customCss?.raw
271
302
  );
272
303
  };
304
+ var placeholderDefinition = (id2, label) => ({
305
+ id: id2,
306
+ type: "class",
307
+ label,
308
+ variants: []
309
+ });
273
310
  var selectData = (state) => state[SLICE_NAME].data;
311
+ var selectClassLabels = (state) => state[SLICE_NAME].classLabels;
274
312
  var selectFrontendInitialData = (state) => state[SLICE_NAME].initialData.frontend;
275
313
  var selectPreviewInitialData = (state) => state[SLICE_NAME].initialData.preview;
276
314
  var selectOrder = (0, import_store.__createSelector)(selectData, ({ order }) => order);
277
315
  var selectGlobalClasses = (0, import_store.__createSelector)(selectData, ({ items }) => items);
278
316
  var selectIsDirty = (state) => state[SLICE_NAME].isDirty;
279
317
  var selectOrderedClasses = (0, import_store.__createSelector)(
280
- selectGlobalClasses,
281
- selectOrder,
282
- (items, order) => order.map((id2) => items[id2])
318
+ selectData,
319
+ selectClassLabels,
320
+ ({ items, order }, classLabels) => order.map((id2) => {
321
+ const loaded = items[id2];
322
+ if (loaded) {
323
+ return loaded;
324
+ }
325
+ const label = classLabels[id2];
326
+ return label !== void 0 ? placeholderDefinition(id2, label) : null;
327
+ }).filter((s) => s !== null)
283
328
  );
284
329
  var selectClass = (state, id2) => state[SLICE_NAME].data.items[id2] ?? null;
285
330
  var selectEmptyCssClass = (0, import_store.__createSelector)(
286
331
  selectData,
287
332
  ({ items }) => Object.values(items).filter((cssClass) => cssClass.variants.length === 0)
288
333
  );
289
-
290
- // src/utils/tracking.ts
291
- var import_events = require("@elementor/events");
292
- var import_store2 = require("@elementor/store");
293
-
294
- // src/api.ts
295
- var import_http_client = require("@elementor/http-client");
296
- var RESOURCE_URL = "/global-classes";
297
- var BASE_URL = "elementor/v1";
298
- var RESOURCE_USAGE_URL = `${RESOURCE_URL}/usage`;
299
- var apiClient = {
300
- usage: () => (0, import_http_client.httpService)().get(`${BASE_URL}${RESOURCE_USAGE_URL}`),
301
- all: (context2 = "preview") => (0, import_http_client.httpService)().get(`${BASE_URL}${RESOURCE_URL}`, {
302
- params: { context: context2 }
303
- }),
304
- publish: (payload) => (0, import_http_client.httpService)().put("elementor/v1" + RESOURCE_URL, payload, {
305
- params: {
306
- context: "frontend"
307
- }
308
- }),
309
- saveDraft: (payload) => (0, import_http_client.httpService)().put("elementor/v1" + RESOURCE_URL, payload, {
310
- params: {
311
- context: "preview"
312
- }
313
- })
314
- };
315
- var API_ERROR_CODES = {
316
- DUPLICATED_LABEL: "DUPLICATED_LABEL"
317
- };
318
-
319
- // src/components/css-class-usage/utils.ts
320
- var transformData = (data) => Object.entries(data).reduce((acc, [key, value]) => {
321
- acc[key] = {
322
- content: value || [],
323
- total: value.reduce((total, val) => total + (val?.total || 0), 0)
324
- };
325
- return acc;
326
- }, {});
327
-
328
- // service/css-class-usage-service.ts
329
- var fetchCssClassUsage = async () => {
330
- const response = await apiClient.usage();
331
- return transformData(response?.data?.data || {});
332
- };
333
-
334
- // src/utils/tracking.ts
335
- var trackGlobalClasses = async (payload) => {
336
- const { runAction } = payload;
337
- const data = await getSanitizedData(payload);
338
- if (data) {
339
- track(data);
340
- if (data.event === "classCreated" && "classId" in data) {
341
- fireClassApplied(data.classId);
342
- }
343
- }
344
- runAction?.();
345
- };
346
- var fireClassApplied = async (classId) => {
347
- const appliedInfo = await getAppliedInfo(classId);
348
- track({
349
- event: "classApplied",
350
- classId,
351
- ...appliedInfo,
352
- totalInstancesAfterApply: 1
353
- });
354
- };
355
- var getSanitizedData = async (payload) => {
356
- switch (payload.event) {
357
- case "classApplied":
358
- if ("classId" in payload && payload.classId) {
359
- const appliedInfo = await getAppliedInfo(payload.classId);
360
- return { ...payload, ...appliedInfo };
361
- }
362
- break;
363
- case "classRemoved":
364
- if ("classId" in payload && payload.classId) {
365
- const deleteInfo = getRemovedInfo(payload.classId);
366
- return { ...payload, ...deleteInfo };
367
- }
368
- break;
369
- case "classDeleted":
370
- if ("classId" in payload && payload.classId) {
371
- const deleteInfo = await trackDeleteClass(payload.classId);
372
- return { ...payload, ...deleteInfo };
373
- }
374
- break;
375
- case "classCreated":
376
- if ("source" in payload && payload.source !== "created") {
377
- if ("classId" in payload && payload.classId) {
378
- return { ...payload, classTitle: getCssClass(payload.classId).label };
379
- }
380
- }
381
- return payload;
382
- case "classStateClicked":
383
- if ("classId" in payload && payload.classId) {
384
- return { ...payload, classTitle: getCssClass(payload.classId).label };
385
- }
386
- break;
387
- case "classSyncToV3PopupShown":
388
- return {
389
- ...payload,
390
- interaction_type: "popup_shown",
391
- target_type: "popup",
392
- target_name: "sync_to_v3_popup",
393
- interaction_result: "popup_viewed",
394
- target_location: "widget_panel",
395
- location_l1: "class_manager"
396
- };
397
- case "classSyncToV3": {
398
- const classLabel = getCssClass(payload.classId).label;
399
- const isSync = payload.action === "sync";
400
- return {
401
- ...payload,
402
- interaction_type: "click",
403
- target_type: classLabel,
404
- target_name: isSync ? "sync_to_v3" : "unsync_to_v3",
405
- interaction_result: isSync ? "class_is_synced_to_V3" : "class_is_unsynced_from_V3",
406
- target_location: "widget_panel",
407
- location_l1: "class_manager",
408
- interaction_description: isSync ? `user_synced_${classLabel}_to_v3` : `user_unsync_${classLabel}_from_v3`
409
- };
410
- }
411
- case "classSyncToV3PopupClick": {
412
- const isSyncAction = payload.action === "sync";
413
- return {
414
- ...payload,
415
- interaction_type: "click",
416
- target_type: "button",
417
- target_name: isSyncAction ? "sync_to_v3" : "cancel",
418
- interaction_result: isSyncAction ? "class_is_synced" : "cancel",
419
- target_location: "sync_to_v3_popup"
420
- };
421
- }
422
- default:
423
- return payload;
424
- }
425
- };
426
- var track = (data) => {
427
- const { dispatchEvent, config } = (0, import_events.getMixpanel)();
428
- if (!config?.names?.global_classes?.[data.event]) {
429
- console.error("Global class tracking event not found", { event: data.event });
430
- return;
431
- }
432
- const name = config.names.global_classes[data.event];
433
- const { event, ...eventData } = data;
434
- try {
435
- dispatchEvent?.(name, {
436
- event,
437
- ...eventData
438
- });
439
- } catch (error) {
440
- throw new GlobalClassTrackingError({ cause: error });
441
- }
442
- };
443
- var extractCssClassData = (classId) => {
444
- const cssClass = getCssClass(classId);
445
- const classTitle = cssClass.label;
446
- return { classTitle };
447
- };
448
- var getCssClass = (classId) => {
449
- const cssClass = selectClass((0, import_store2.__getState)(), classId);
450
- if (!cssClass) {
451
- throw new Error(`CSS class with ID ${classId} not found`);
452
- }
453
- return cssClass;
454
- };
455
- var trackDeleteClass = async (classId) => {
456
- const totalInstances = await getTotalInstancesByCssClassID(classId);
457
- const classTitle = getCssClass(classId).label;
458
- return { totalInstances, classTitle };
459
- };
460
- var getTotalInstancesByCssClassID = async (classId) => {
461
- const cssClassUsage = await fetchCssClassUsage();
462
- return cssClassUsage[classId]?.total ?? 1;
463
- };
464
- var getAppliedInfo = async (classId) => {
465
- const { classTitle } = extractCssClassData(classId);
466
- const totalInstancesAfterApply = await getTotalInstancesByCssClassID(classId) + 1;
467
- return { classTitle, totalInstancesAfterApply };
468
- };
469
- var getRemovedInfo = (classId) => {
470
- const { classTitle } = extractCssClassData(classId);
471
- return {
472
- classTitle
473
- };
474
- };
475
-
476
- // src/global-classes-styles-provider.ts
477
- var MAX_CLASSES = 100;
478
- var GLOBAL_CLASSES_PROVIDER_KEY = "global-classes";
479
- var PREGENERATED_LINK_PATTERN = /^global-(preview|frontend)-[a-zA-Z_-]+-css$/;
480
- var globalClassesStylesProvider = (0, import_editor_styles_repository.createStylesProvider)({
481
- key: GLOBAL_CLASSES_PROVIDER_KEY,
482
- priority: 30,
483
- limit: MAX_CLASSES,
484
- isPregeneratedLink: ({ id: id2 }) => PREGENERATED_LINK_PATTERN.test(id2),
485
- labels: {
486
- singular: (0, import_i18n.__)("class", "elementor"),
487
- plural: (0, import_i18n.__)("classes", "elementor")
488
- },
489
- subscribe: (cb) => subscribeWithStates(cb),
490
- capabilities: getCapabilities(),
491
- actions: {
492
- all: () => selectOrderedClasses((0, import_store4.__getState)()),
493
- get: (id2) => selectClass((0, import_store4.__getState)(), id2),
494
- resolveCssName: (id2) => {
495
- return selectClass((0, import_store4.__getState)(), id2)?.label ?? id2;
496
- },
497
- create: (label, variants = []) => {
498
- const classes = selectGlobalClasses((0, import_store4.__getState)());
499
- const existingLabels = Object.values(classes).map((style) => style.label);
500
- if (existingLabels.includes(label)) {
501
- throw new GlobalClassLabelAlreadyExistsError({ context: { label } });
502
- }
503
- const existingIds = Object.keys(classes);
504
- const id2 = (0, import_editor_styles2.generateId)("g-", existingIds);
505
- (0, import_store4.__dispatch)(
506
- slice.actions.add({
507
- id: id2,
508
- type: "class",
509
- label,
510
- variants
511
- })
512
- );
513
- return id2;
514
- },
515
- update: (payload) => {
516
- (0, import_store4.__dispatch)(
517
- slice.actions.update({
518
- style: payload
519
- })
520
- );
521
- },
522
- delete: (id2) => {
523
- (0, import_store4.__dispatch)(slice.actions.delete(id2));
524
- },
525
- updateProps: (args) => {
526
- (0, import_store4.__dispatch)(
527
- slice.actions.updateProps({
528
- id: args.id,
529
- meta: args.meta,
530
- props: args.props
531
- })
532
- );
533
- },
534
- updateCustomCss: (args) => {
535
- (0, import_store4.__dispatch)(
536
- slice.actions.updateProps({
537
- id: args.id,
538
- meta: args.meta,
539
- custom_css: args.custom_css,
540
- props: {}
541
- })
542
- );
543
- },
544
- tracking: (data) => {
545
- trackGlobalClasses(data).catch((error) => {
546
- throw new GlobalClassTrackingError({ cause: error });
547
- });
548
- }
549
- }
550
- });
551
- var subscribeWithStates = (cb) => {
552
- let previousState = selectData((0, import_store4.__getState)());
553
- return (0, import_store4.__subscribeWithSelector)(
554
- (state) => state.globalClasses,
555
- (currentState) => {
556
- cb(previousState.items, currentState.data.items);
557
- previousState = currentState.data;
558
- }
559
- );
560
- };
561
-
562
- // src/mcp-integration/classes-resource.ts
563
- var GLOBAL_CLASSES_URI = "elementor://global-classes";
564
- var STORAGE_KEY = "elementor-global-classes";
565
- var updateLocalStorageCache = () => {
566
- const classes = globalClassesStylesProvider.actions.all();
567
- localStorage.setItem(STORAGE_KEY, JSON.stringify(classes));
568
- };
569
- var initClassesResource = (classesMcpEntry, canvasMcpEntry) => {
570
- [canvasMcpEntry, classesMcpEntry].forEach((entry) => {
571
- const { sendResourceUpdated, resource, waitForReady } = entry;
572
- resource(
573
- "global-classes",
574
- GLOBAL_CLASSES_URI,
575
- {
576
- description: "Global classes list."
577
- },
578
- async () => {
579
- return {
580
- contents: [{ uri: GLOBAL_CLASSES_URI, text: localStorage[STORAGE_KEY] ?? "[]" }]
581
- };
582
- }
583
- );
584
- waitForReady().then(() => {
585
- updateLocalStorageCache();
586
- globalClassesStylesProvider.subscribe(() => {
587
- updateLocalStorageCache();
588
- sendResourceUpdated({ uri: GLOBAL_CLASSES_URI });
589
- });
590
- });
591
- });
592
- };
593
-
594
- // src/init.ts
595
- var import_editor = require("@elementor/editor");
596
- var import_editor_editing_panel2 = require("@elementor/editor-editing-panel");
597
- var import_editor_mcp = require("@elementor/editor-mcp");
598
- var import_editor_panels2 = require("@elementor/editor-panels");
599
- var import_editor_styles_repository5 = require("@elementor/editor-styles-repository");
600
- var import_store28 = require("@elementor/store");
601
-
602
- // src/components/class-manager/class-manager-button.tsx
603
- var React20 = __toESM(require("react"));
604
- var import_editor_documents4 = require("@elementor/editor-documents");
605
- var import_editor_styles_repository3 = require("@elementor/editor-styles-repository");
606
- var import_editor_ui10 = require("@elementor/editor-ui");
607
- var import_ui17 = require("@elementor/ui");
608
- var import_i18n16 = require("@wordpress/i18n");
609
-
610
- // src/hooks/use-prefetch-css-class-usage.ts
611
- var import_query = require("@elementor/query");
612
-
613
- // src/components/css-class-usage/types.ts
614
- var QUERY_KEY = "css-classes-usage";
615
-
616
- // src/hooks/use-prefetch-css-class-usage.ts
617
- function usePrefetchCssClassUsage() {
618
- const queryClient = (0, import_query.useQueryClient)();
619
- const prefetchClassesUsage = () => queryClient.prefetchQuery({
620
- queryKey: [QUERY_KEY],
621
- queryFn: fetchCssClassUsage
622
- });
623
- return { prefetchClassesUsage };
624
- }
625
- var PrefetchCssClassUsage = () => {
626
- const { prefetchClassesUsage } = usePrefetchCssClassUsage();
627
- prefetchClassesUsage();
628
- return null;
629
- };
630
-
631
- // src/components/class-manager/class-manager-panel.tsx
632
- var React19 = __toESM(require("react"));
633
- var import_react10 = require("react");
634
- var import_editor_current_user2 = require("@elementor/editor-current-user");
635
- var import_editor_documents3 = require("@elementor/editor-documents");
636
- var import_editor_panels = require("@elementor/editor-panels");
637
- var import_editor_ui9 = require("@elementor/editor-ui");
638
- var import_editor_v1_adapters2 = require("@elementor/editor-v1-adapters");
639
- var import_icons11 = require("@elementor/icons");
640
- var import_query3 = require("@elementor/query");
641
- var import_store20 = require("@elementor/store");
642
- var import_ui16 = require("@elementor/ui");
643
- var import_i18n15 = require("@wordpress/i18n");
334
+ var selectIsClassFetched = (state, id2) => !!state[SLICE_NAME].initialData.preview.items[id2] || !!state[SLICE_NAME].initialData.frontend.items[id2] || false;
644
335
 
645
336
  // src/hooks/use-classes-order.ts
646
- var import_store6 = require("@elementor/store");
647
337
  var useClassesOrder = () => {
648
- return (0, import_store6.__useSelector)(selectOrder);
338
+ return (0, import_store2.__useSelector)(selectOrder);
649
339
  };
650
340
 
651
341
  // src/hooks/use-dirty-state.ts
652
- var import_store8 = require("@elementor/store");
342
+ var import_store4 = require("@elementor/store");
653
343
  var useDirtyState = () => {
654
- return (0, import_store8.__useSelector)(selectIsDirty);
344
+ return (0, import_store4.__useSelector)(selectIsDirty);
655
345
  };
656
346
 
657
347
  // src/hooks/use-filters.ts
@@ -660,7 +350,7 @@ var import_react3 = require("react");
660
350
  // src/components/search-and-filter/context.tsx
661
351
  var React = __toESM(require("react"));
662
352
  var import_react = require("react");
663
- var import_utils3 = require("@elementor/utils");
353
+ var import_utils2 = require("@elementor/utils");
664
354
  var SearchAndFilterContext = (0, import_react.createContext)(void 0);
665
355
  var INIT_CHECKED_FILTERS = {
666
356
  empty: false,
@@ -677,7 +367,7 @@ var SearchAndFilterProvider = ({ children }) => {
677
367
  }
678
368
  return "";
679
369
  };
680
- const { debouncedValue, inputValue, handleChange } = (0, import_utils3.useDebounceState)({
370
+ const { debouncedValue, inputValue, handleChange } = (0, import_utils2.useDebounceState)({
681
371
  delay: 300,
682
372
  initialValue: getInitialSearchValue()
683
373
  });
@@ -720,9 +410,59 @@ var import_react2 = require("react");
720
410
  var import_editor_documents = require("@elementor/editor-documents");
721
411
 
722
412
  // src/hooks/use-css-class-usage.ts
723
- var import_query2 = require("@elementor/query");
413
+ var import_query = require("@elementor/query");
414
+
415
+ // src/api.ts
416
+ var import_http_client = require("@elementor/http-client");
417
+ var RESOURCE_URL = "/global-classes";
418
+ var BASE_URL = "elementor/v1";
419
+ var RESOURCE_USAGE_URL = `${RESOURCE_URL}/usage`;
420
+ var RESOURCE_POST_URL = `${RESOURCE_URL}/post`;
421
+ var RESOURCE_STYLES_URL = `${RESOURCE_URL}/styles`;
422
+ function saveGlobalClasses(context2, payload) {
423
+ return (0, import_http_client.httpService)().put(`${BASE_URL}${RESOURCE_URL}`, payload, {
424
+ params: { context: context2 }
425
+ });
426
+ }
427
+ var apiClient = {
428
+ usage: () => (0, import_http_client.httpService)().get(`${BASE_URL}${RESOURCE_USAGE_URL}`),
429
+ all: (context2 = "preview") => (0, import_http_client.httpService)().get(`${BASE_URL}${RESOURCE_URL}`, {
430
+ params: { context: context2 }
431
+ }),
432
+ getStylesForPost: (postId, context2 = "preview") => (0, import_http_client.httpService)().get(`${BASE_URL}${RESOURCE_POST_URL}`, {
433
+ params: { context: context2, post_id: postId }
434
+ }),
435
+ getStylesByIds: (ids, context2 = "preview") => (0, import_http_client.httpService)().get(`${BASE_URL}${RESOURCE_STYLES_URL}`, {
436
+ params: { context: context2, ids: ids.join(",") }
437
+ }),
438
+ publish: (payload) => saveGlobalClasses("frontend", payload),
439
+ saveDraft: (payload) => saveGlobalClasses("preview", payload)
440
+ };
441
+ var API_ERROR_CODES = {
442
+ DUPLICATED_LABEL: "DUPLICATED_LABEL"
443
+ };
444
+
445
+ // src/components/css-class-usage/utils.ts
446
+ var transformData = (data) => Object.entries(data).reduce((acc, [key, value]) => {
447
+ acc[key] = {
448
+ content: value || [],
449
+ total: value.reduce((total, val) => total + (val?.total || 0), 0)
450
+ };
451
+ return acc;
452
+ }, {});
453
+
454
+ // service/css-class-usage-service.ts
455
+ var fetchCssClassUsage = async () => {
456
+ const response = await apiClient.usage();
457
+ return transformData(response?.data?.data || {});
458
+ };
459
+
460
+ // src/components/css-class-usage/types.ts
461
+ var QUERY_KEY = "css-classes-usage";
462
+
463
+ // src/hooks/use-css-class-usage.ts
724
464
  var useCssClassUsage = () => {
725
- return (0, import_query2.useQuery)({
465
+ return (0, import_query.useQuery)({
726
466
  queryKey: [QUERY_KEY],
727
467
  queryFn: fetchCssClassUsage,
728
468
  refetchOnMount: false,
@@ -731,12 +471,12 @@ var useCssClassUsage = () => {
731
471
  };
732
472
 
733
473
  // src/hooks/use-empty-css-class.ts
734
- var import_store10 = require("@elementor/store");
474
+ var import_store6 = require("@elementor/store");
735
475
  var useEmptyCssClass = () => {
736
- return (0, import_store10.__useSelector)(selectEmptyCssClass);
476
+ return (0, import_store6.__useSelector)(selectEmptyCssClass);
737
477
  };
738
478
  var useAllCssClassesIDs = () => {
739
- const cssClasses = (0, import_store10.__useSelector)(selectGlobalClasses);
479
+ const cssClasses = (0, import_store6.__useSelector)(selectGlobalClasses);
740
480
  return Object.keys(cssClasses);
741
481
  };
742
482
 
@@ -813,7 +553,7 @@ var useFilters = () => {
813
553
  // src/save-global-classes.tsx
814
554
  var React3 = __toESM(require("react"));
815
555
  var import_editor_ui2 = require("@elementor/editor-ui");
816
- var import_store12 = require("@elementor/store");
556
+ var import_store10 = require("@elementor/store");
817
557
  var import_utils4 = require("@elementor/utils");
818
558
 
819
559
  // src/components/class-manager/duplicate-label-dialog.tsx
@@ -821,7 +561,7 @@ var React2 = __toESM(require("react"));
821
561
  var import_editor_ui = require("@elementor/editor-ui");
822
562
  var import_icons = require("@elementor/icons");
823
563
  var import_ui = require("@elementor/ui");
824
- var import_i18n2 = require("@wordpress/i18n");
564
+ var import_i18n = require("@wordpress/i18n");
825
565
  var DUP_PREFIX = "DUP_";
826
566
  var DuplicateLabelDialog = ({
827
567
  modifiedLabels,
@@ -832,7 +572,7 @@ var DuplicateLabelDialog = ({
832
572
  onApprove?.();
833
573
  (0, import_editor_ui.closeDialog)();
834
574
  };
835
- return /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(import_ui.DialogHeader, { logo: false }, /* @__PURE__ */ React2.createElement(import_ui.Box, { display: "flex", alignItems: "center", gap: 1 }, /* @__PURE__ */ React2.createElement(import_ui.Icon, { color: "secondary" }, /* @__PURE__ */ React2.createElement(import_icons.InfoCircleFilledIcon, { fontSize: "medium" })), /* @__PURE__ */ React2.createElement(import_ui.Typography, { variant: "subtitle1" }, (0, import_i18n2.__)("We've published your page and updated class names.", "elementor")))), /* @__PURE__ */ React2.createElement(import_ui.DialogContent, null, /* @__PURE__ */ React2.createElement(import_ui.Stack, { spacing: 2, direction: "column" }, /* @__PURE__ */ React2.createElement(import_ui.Typography, { variant: "body2" }, (0, import_i18n2.__)(
575
+ return /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(import_ui.DialogHeader, { logo: false }, /* @__PURE__ */ React2.createElement(import_ui.Box, { display: "flex", alignItems: "center", gap: 1 }, /* @__PURE__ */ React2.createElement(import_ui.Icon, { color: "secondary" }, /* @__PURE__ */ React2.createElement(import_icons.InfoCircleFilledIcon, { fontSize: "medium" })), /* @__PURE__ */ React2.createElement(import_ui.Typography, { variant: "subtitle1" }, (0, import_i18n.__)("We've published your page and updated class names.", "elementor")))), /* @__PURE__ */ React2.createElement(import_ui.DialogContent, null, /* @__PURE__ */ React2.createElement(import_ui.Stack, { spacing: 2, direction: "column" }, /* @__PURE__ */ React2.createElement(import_ui.Typography, { variant: "body2" }, (0, import_i18n.__)(
836
576
  "Some new classes used the same names as existing ones. To prevent conflicts, we added the prefix",
837
577
  "elementor"
838
578
  ), /* @__PURE__ */ React2.createElement("strong", null, " ", DUP_PREFIX)), /* @__PURE__ */ React2.createElement(import_ui.Box, null, /* @__PURE__ */ React2.createElement(
@@ -857,7 +597,7 @@ var DuplicateLabelDialog = ({
857
597
  minWidth: 0
858
598
  }
859
599
  },
860
- (0, import_i18n2.__)("Before", "elementor")
600
+ (0, import_i18n.__)("Before", "elementor")
861
601
  ),
862
602
  /* @__PURE__ */ React2.createElement(
863
603
  import_ui.Typography,
@@ -872,7 +612,7 @@ var DuplicateLabelDialog = ({
872
612
  maxWidth: "200px"
873
613
  }
874
614
  },
875
- (0, import_i18n2.__)("After", "elementor")
615
+ (0, import_i18n.__)("After", "elementor")
876
616
  )
877
617
  ), /* @__PURE__ */ React2.createElement(import_ui.Divider, { sx: { mt: 0.5, mb: 0.5 } }), /* @__PURE__ */ React2.createElement(import_ui.Stack, { direction: "column", gap: 0.5, sx: { pb: 2 } }, Object.values(modifiedLabels).map(({ original, modified }, index) => /* @__PURE__ */ React2.createElement(
878
618
  import_ui.Box,
@@ -910,26 +650,180 @@ var DuplicateLabelDialog = ({
910
650
  },
911
651
  /* @__PURE__ */ React2.createElement(import_editor_ui.EllipsisWithTooltip, { title: modified }, /* @__PURE__ */ React2.createElement(import_ui.Typography, { variant: "body2", sx: { color: "text.primary" } }, modified))
912
652
  )
913
- ))), /* @__PURE__ */ React2.createElement(import_ui.Box, null, /* @__PURE__ */ React2.createElement(import_ui.Alert, { severity: "info", size: "small", color: "secondary" }, /* @__PURE__ */ React2.createElement("strong", null, (0, import_i18n2.__)("Your designs and classes are safe.", "elementor")), (0, import_i18n2.__)(
653
+ ))), /* @__PURE__ */ React2.createElement(import_ui.Box, null, /* @__PURE__ */ React2.createElement(import_ui.Alert, { severity: "info", size: "small", color: "secondary" }, /* @__PURE__ */ React2.createElement("strong", null, (0, import_i18n.__)("Your designs and classes are safe.", "elementor")), (0, import_i18n.__)(
914
654
  "Only the prefixes were added. Find them in Class Manager by searching",
915
655
  "elementor"
916
- ), /* @__PURE__ */ React2.createElement("strong", null, DUP_PREFIX)))))), /* @__PURE__ */ React2.createElement(import_ui.DialogActions, null, /* @__PURE__ */ React2.createElement(import_ui.Button, { color: "secondary", variant: "text", onClick: handleButtonClick }, (0, import_i18n2.__)("Go to Class Manager", "elementor")), /* @__PURE__ */ React2.createElement(import_ui.Button, { color: "secondary", variant: "contained", onClick: import_editor_ui.closeDialog }, (0, import_i18n2.__)("Done", "elementor"))));
656
+ ), /* @__PURE__ */ React2.createElement("strong", null, DUP_PREFIX)))))), /* @__PURE__ */ React2.createElement(import_ui.DialogActions, null, /* @__PURE__ */ React2.createElement(import_ui.Button, { color: "secondary", variant: "text", onClick: handleButtonClick }, (0, import_i18n.__)("Go to Class Manager", "elementor")), /* @__PURE__ */ React2.createElement(import_ui.Button, { color: "secondary", variant: "contained", onClick: import_editor_ui.closeDialog }, (0, import_i18n.__)("Done", "elementor"))));
657
+ };
658
+
659
+ // src/utils/tracking.ts
660
+ var import_events = require("@elementor/events");
661
+ var import_store8 = require("@elementor/store");
662
+ var trackGlobalClasses = async (payload) => {
663
+ const { runAction } = payload;
664
+ const data = await getSanitizedData(payload);
665
+ if (data) {
666
+ track(data);
667
+ if (data.event === "classCreated" && "classId" in data) {
668
+ fireClassApplied(data.classId);
669
+ }
670
+ }
671
+ runAction?.();
672
+ };
673
+ var fireClassApplied = async (classId) => {
674
+ const appliedInfo = await getAppliedInfo(classId);
675
+ track({
676
+ event: "classApplied",
677
+ classId,
678
+ ...appliedInfo,
679
+ totalInstancesAfterApply: 1
680
+ });
681
+ };
682
+ var getSanitizedData = async (payload) => {
683
+ switch (payload.event) {
684
+ case "classApplied":
685
+ if ("classId" in payload && payload.classId) {
686
+ const appliedInfo = await getAppliedInfo(payload.classId);
687
+ return { ...payload, ...appliedInfo };
688
+ }
689
+ break;
690
+ case "classRemoved":
691
+ if ("classId" in payload && payload.classId) {
692
+ const deleteInfo = getRemovedInfo(payload.classId);
693
+ return { ...payload, ...deleteInfo };
694
+ }
695
+ break;
696
+ case "classDeleted":
697
+ if ("classId" in payload && payload.classId) {
698
+ const deleteInfo = await trackDeleteClass(payload.classId);
699
+ return { ...payload, ...deleteInfo };
700
+ }
701
+ break;
702
+ case "classCreated":
703
+ if ("source" in payload && payload.source !== "created") {
704
+ if ("classId" in payload && payload.classId) {
705
+ return { ...payload, classTitle: getCssClass(payload.classId).label };
706
+ }
707
+ }
708
+ return payload;
709
+ case "classStateClicked":
710
+ if ("classId" in payload && payload.classId) {
711
+ return { ...payload, classTitle: getCssClass(payload.classId).label };
712
+ }
713
+ break;
714
+ case "classSyncToV3PopupShown":
715
+ return {
716
+ ...payload,
717
+ interaction_type: "popup_shown",
718
+ target_type: "popup",
719
+ target_name: "sync_to_v3_popup",
720
+ interaction_result: "popup_viewed",
721
+ target_location: "widget_panel",
722
+ location_l1: "class_manager"
723
+ };
724
+ case "classSyncToV3": {
725
+ const classLabel = getCssClass(payload.classId).label;
726
+ const isSync = payload.action === "sync";
727
+ return {
728
+ ...payload,
729
+ interaction_type: "click",
730
+ target_type: classLabel,
731
+ target_name: isSync ? "sync_to_v3" : "unsync_to_v3",
732
+ interaction_result: isSync ? "class_is_synced_to_V3" : "class_is_unsynced_from_V3",
733
+ target_location: "widget_panel",
734
+ location_l1: "class_manager",
735
+ interaction_description: isSync ? `user_synced_${classLabel}_to_v3` : `user_unsync_${classLabel}_from_v3`
736
+ };
737
+ }
738
+ case "classSyncToV3PopupClick": {
739
+ const isSyncAction = payload.action === "sync";
740
+ return {
741
+ ...payload,
742
+ interaction_type: "click",
743
+ target_type: "button",
744
+ target_name: isSyncAction ? "sync_to_v3" : "cancel",
745
+ interaction_result: isSyncAction ? "class_is_synced" : "cancel",
746
+ target_location: "sync_to_v3_popup"
747
+ };
748
+ }
749
+ default:
750
+ return payload;
751
+ }
752
+ };
753
+ var track = (data) => {
754
+ const { dispatchEvent, config } = (0, import_events.getMixpanel)();
755
+ if (!config?.names?.global_classes?.[data.event]) {
756
+ console.error("Global class tracking event not found", { event: data.event });
757
+ return;
758
+ }
759
+ const name = config.names.global_classes[data.event];
760
+ const { event, ...eventData } = data;
761
+ try {
762
+ dispatchEvent?.(name, {
763
+ event,
764
+ ...eventData
765
+ });
766
+ } catch (error) {
767
+ throw new GlobalClassTrackingError({ cause: error });
768
+ }
769
+ };
770
+ var extractCssClassData = (classId) => {
771
+ const cssClass = getCssClass(classId);
772
+ const classTitle = cssClass.label;
773
+ return { classTitle };
774
+ };
775
+ var getCssClass = (classId) => {
776
+ const state = (0, import_store8.__getState)();
777
+ const cssClass = selectClass(state, classId);
778
+ if (cssClass) {
779
+ return cssClass;
780
+ }
781
+ const label = selectClassLabels(state)[classId];
782
+ if (label !== void 0) {
783
+ return placeholderDefinition(classId, label);
784
+ }
785
+ throw new Error(`CSS class with ID ${classId} not found`);
786
+ };
787
+ var trackDeleteClass = async (classId) => {
788
+ const classTitle = getCssClass(classId).label;
789
+ const totalInstances = await getTotalInstancesByCssClassID(classId);
790
+ return { totalInstances, classTitle };
791
+ };
792
+ var getTotalInstancesByCssClassID = async (classId) => {
793
+ const cssClassUsage = await fetchCssClassUsage();
794
+ return cssClassUsage[classId]?.total ?? 1;
795
+ };
796
+ var getAppliedInfo = async (classId) => {
797
+ const { classTitle } = extractCssClassData(classId);
798
+ const totalInstancesAfterApply = await getTotalInstancesByCssClassID(classId) + 1;
799
+ return { classTitle, totalInstancesAfterApply };
800
+ };
801
+ var getRemovedInfo = (classId) => {
802
+ const { classTitle } = extractCssClassData(classId);
803
+ return {
804
+ classTitle
805
+ };
917
806
  };
918
807
 
919
808
  // src/save-global-classes.tsx
920
- async function saveGlobalClasses({ context: context2, onApprove }) {
921
- const state = selectData((0, import_store12.__getState)());
809
+ async function saveGlobalClasses2({ context: context2, onApprove }) {
810
+ const state = selectData((0, import_store10.__getState)());
922
811
  const apiAction = context2 === "preview" ? apiClient.saveDraft : apiClient.publish;
923
812
  const currentContext = context2 === "preview" ? selectPreviewInitialData : selectFrontendInitialData;
813
+ const changes = calculateChanges(state, currentContext((0, import_store10.__getState)()));
814
+ const touchedIds = [...changes.added, ...changes.modified];
815
+ const touchedItems = Object.fromEntries(
816
+ touchedIds.map((id2) => [id2, state.items[id2]]).filter(([, v]) => v)
817
+ );
924
818
  const response = await apiAction({
925
- items: state.items,
819
+ items: touchedItems,
926
820
  order: state.order,
927
- changes: calculateChanges(state, currentContext((0, import_store12.__getState)()))
821
+ changes
928
822
  });
929
- (0, import_store12.__dispatch)(slice.actions.reset({ context: context2 }));
823
+ (0, import_store10.__dispatch)(slice.actions.reset({ context: context2 }));
930
824
  window.dispatchEvent(new CustomEvent("classes:updated", { detail: { context: context2 } }));
931
825
  if (response?.data?.data?.code === API_ERROR_CODES.DUPLICATED_LABEL) {
932
- (0, import_store12.__dispatch)(slice.actions.updateMultiple(response.data.data.modifiedLabels));
826
+ (0, import_store10.__dispatch)(slice.actions.updateMultiple(response.data.data.modifiedLabels));
933
827
  trackGlobalClasses({
934
828
  event: "classPublishConflict",
935
829
  numOfConflicts: Object.keys(response.data.data.modifiedLabels).length
@@ -948,19 +842,23 @@ async function saveGlobalClasses({ context: context2, onApprove }) {
948
842
  function calculateChanges(state, initialData) {
949
843
  const stateIds = Object.keys(state.items);
950
844
  const initialDataIds = Object.keys(initialData.items);
845
+ const { order: stateOrder } = state;
846
+ const { order: initialDataOrder } = initialData;
847
+ const order = stateOrder.join(";") !== initialDataOrder.join(";");
951
848
  return {
952
849
  added: stateIds.filter((id2) => !initialDataIds.includes(id2)),
953
850
  deleted: initialDataIds.filter((id2) => !stateIds.includes(id2)),
954
851
  modified: stateIds.filter((id2) => {
955
852
  return id2 in initialData.items && (0, import_utils4.hash)(state.items[id2]) !== (0, import_utils4.hash)(initialData.items[id2]);
956
- })
853
+ }),
854
+ order
957
855
  };
958
856
  }
959
857
 
960
858
  // src/components/search-and-filter/components/filter/active-filters.tsx
961
859
  var React6 = __toESM(require("react"));
962
860
  var import_ui4 = require("@elementor/ui");
963
- var import_i18n4 = require("@wordpress/i18n");
861
+ var import_i18n3 = require("@wordpress/i18n");
964
862
 
965
863
  // src/components/search-and-filter/components/filter/clear-icon-button.tsx
966
864
  var React4 = __toESM(require("react"));
@@ -991,11 +889,11 @@ var CustomIconButton = (0, import_ui2.styled)(import_ui2.IconButton)(({ theme })
991
889
  // src/components/search-and-filter/components/filter/filter-list.tsx
992
890
  var React5 = __toESM(require("react"));
993
891
  var import_ui3 = require("@elementor/ui");
994
- var import_i18n3 = require("@wordpress/i18n");
892
+ var import_i18n2 = require("@wordpress/i18n");
995
893
  var filterConfig = {
996
- unused: (0, import_i18n3.__)("Unused", "elementor"),
997
- empty: (0, import_i18n3.__)("Empty", "elementor"),
998
- onThisPage: (0, import_i18n3.__)("On this page", "elementor")
894
+ unused: (0, import_i18n2.__)("Unused", "elementor"),
895
+ empty: (0, import_i18n2.__)("Empty", "elementor"),
896
+ onThisPage: (0, import_i18n2.__)("On this page", "elementor")
999
897
  };
1000
898
  var FilterList = () => {
1001
899
  const {
@@ -1078,7 +976,7 @@ var ActiveFilters = () => {
1078
976
  ClearIconButton,
1079
977
  {
1080
978
  trigger: "header",
1081
- tooltipText: (0, import_i18n4.__)("Clear Filters", "elementor"),
979
+ tooltipText: (0, import_i18n3.__)("Clear Filters", "elementor"),
1082
980
  sx: { margin: "0 0 auto auto" }
1083
981
  }
1084
982
  ));
@@ -1099,7 +997,7 @@ var import_react4 = require("react");
1099
997
  var import_editor_ui3 = require("@elementor/editor-ui");
1100
998
  var import_icons3 = require("@elementor/icons");
1101
999
  var import_ui5 = require("@elementor/ui");
1102
- var import_i18n5 = require("@wordpress/i18n");
1000
+ var import_i18n4 = require("@wordpress/i18n");
1103
1001
  var CssClassFilter = () => {
1104
1002
  const {
1105
1003
  filters: { filters }
@@ -1116,7 +1014,7 @@ var CssClassFilter = () => {
1116
1014
  }
1117
1015
  }, [popupState.isOpen]);
1118
1016
  const showCleanIcon = Object.values(filters).some((value) => value);
1119
- return /* @__PURE__ */ React7.createElement(React7.Fragment, null, /* @__PURE__ */ React7.createElement(import_ui5.Tooltip, { title: (0, import_i18n5.__)("Filters", "elementor"), placement: "top" }, /* @__PURE__ */ React7.createElement(
1017
+ return /* @__PURE__ */ React7.createElement(React7.Fragment, null, /* @__PURE__ */ React7.createElement(import_ui5.Tooltip, { title: (0, import_i18n4.__)("Filters", "elementor"), placement: "top" }, /* @__PURE__ */ React7.createElement(
1120
1018
  import_ui5.ToggleButton,
1121
1019
  {
1122
1020
  value: "filter",
@@ -1150,12 +1048,12 @@ var CssClassFilter = () => {
1150
1048
  {
1151
1049
  trigger: "menu",
1152
1050
  key: "clear-all-button",
1153
- tooltipText: (0, import_i18n5.__)("Clear all", "elementor")
1051
+ tooltipText: (0, import_i18n4.__)("Clear all", "elementor")
1154
1052
  }
1155
1053
  )
1156
1054
  ] : [],
1157
1055
  onClose: popupState.close,
1158
- title: (0, import_i18n5.__)("Filters", "elementor"),
1056
+ title: (0, import_i18n4.__)("Filters", "elementor"),
1159
1057
  icon: /* @__PURE__ */ React7.createElement(import_icons3.FilterIcon, { fontSize: "tiny" })
1160
1058
  }
1161
1059
  ),
@@ -1175,7 +1073,7 @@ var CssClassFilter = () => {
1175
1073
  var React8 = __toESM(require("react"));
1176
1074
  var import_icons4 = require("@elementor/icons");
1177
1075
  var import_ui6 = require("@elementor/ui");
1178
- var import_i18n6 = require("@wordpress/i18n");
1076
+ var import_i18n5 = require("@wordpress/i18n");
1179
1077
  var ClassManagerSearch = () => {
1180
1078
  const {
1181
1079
  search: { inputValue, handleChange }
@@ -1192,7 +1090,7 @@ var ClassManagerSearch = () => {
1192
1090
  event: "classManagerSearched"
1193
1091
  });
1194
1092
  },
1195
- placeholder: (0, import_i18n6.__)("Search", "elementor"),
1093
+ placeholder: (0, import_i18n5.__)("Search", "elementor"),
1196
1094
  onChange: (e) => handleChange(e.target.value),
1197
1095
  InputProps: {
1198
1096
  startAdornment: /* @__PURE__ */ React8.createElement(import_ui6.InputAdornment, { position: "start" }, /* @__PURE__ */ React8.createElement(import_icons4.SearchIcon, { fontSize: "tiny" }))
@@ -1207,7 +1105,7 @@ var import_react5 = require("react");
1207
1105
  var import_editor_current_user = require("@elementor/editor-current-user");
1208
1106
  var import_editor_ui4 = require("@elementor/editor-ui");
1209
1107
  var import_ui7 = require("@elementor/ui");
1210
- var import_i18n7 = require("@wordpress/i18n");
1108
+ var import_i18n6 = require("@wordpress/i18n");
1211
1109
  var MESSAGE_KEY = "global-class-manager";
1212
1110
  var ClassManagerIntroduction = () => {
1213
1111
  const [isMessageSuppressed, suppressMessage] = (0, import_editor_current_user.useSuppressedMessage)(MESSAGE_KEY);
@@ -1216,7 +1114,7 @@ var ClassManagerIntroduction = () => {
1216
1114
  import_editor_ui4.IntroductionModal,
1217
1115
  {
1218
1116
  open: shouldShowIntroduction,
1219
- title: (0, import_i18n7.__)("Class Manager", "elementor"),
1117
+ title: (0, import_i18n6.__)("Class Manager", "elementor"),
1220
1118
  handleClose: (shouldShowAgain) => {
1221
1119
  if (!shouldShowAgain) {
1222
1120
  suppressMessage();
@@ -1236,24 +1134,24 @@ var ClassManagerIntroduction = () => {
1236
1134
  );
1237
1135
  };
1238
1136
  var IntroductionContent = () => {
1239
- return /* @__PURE__ */ React9.createElement(import_ui7.Box, { p: 3 }, /* @__PURE__ */ React9.createElement(import_ui7.Typography, { variant: "body2" }, (0, import_i18n7.__)(
1137
+ return /* @__PURE__ */ React9.createElement(import_ui7.Box, { p: 3 }, /* @__PURE__ */ React9.createElement(import_ui7.Typography, { variant: "body2" }, (0, import_i18n6.__)(
1240
1138
  "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.",
1241
1139
  "elementor"
1242
- )), /* @__PURE__ */ React9.createElement("br", null), /* @__PURE__ */ React9.createElement(import_ui7.Typography, { variant: "body2" }, (0, import_i18n7.__)(
1140
+ )), /* @__PURE__ */ React9.createElement("br", null), /* @__PURE__ */ React9.createElement(import_ui7.Typography, { variant: "body2" }, (0, import_i18n6.__)(
1243
1141
  "Remember, when editing an item within a specific class, any changes you make will apply across all elements in that class.",
1244
1142
  "elementor"
1245
1143
  )));
1246
1144
  };
1247
1145
 
1248
1146
  // src/components/class-manager/delete-class.ts
1249
- var import_store14 = require("@elementor/store");
1147
+ var import_store12 = require("@elementor/store");
1250
1148
  var isDeleted = false;
1251
1149
  var deleteClass = (id2) => {
1252
1150
  trackGlobalClasses({
1253
1151
  event: "classDeleted",
1254
1152
  classId: id2,
1255
1153
  runAction: () => {
1256
- (0, import_store14.__dispatch)(slice.actions.delete(id2));
1154
+ (0, import_store12.__dispatch)(slice.actions.delete(id2));
1257
1155
  isDeleted = true;
1258
1156
  }
1259
1157
  });
@@ -1271,24 +1169,25 @@ var FlippedColorSwatchIcon = ({ sx, ...props }) => /* @__PURE__ */ React10.creat
1271
1169
  // src/components/class-manager/global-classes-list.tsx
1272
1170
  var React17 = __toESM(require("react"));
1273
1171
  var import_react8 = require("react");
1274
- var import_store18 = require("@elementor/store");
1172
+ var import_store16 = require("@elementor/store");
1275
1173
  var import_ui14 = require("@elementor/ui");
1276
- var import_i18n13 = require("@wordpress/i18n");
1174
+ var import_react_virtual = require("@tanstack/react-virtual");
1175
+ var import_i18n12 = require("@wordpress/i18n");
1277
1176
 
1278
1177
  // src/hooks/use-ordered-classes.ts
1279
- var import_store16 = require("@elementor/store");
1178
+ var import_store14 = require("@elementor/store");
1280
1179
  var useOrderedClasses = () => {
1281
- return (0, import_store16.__useSelector)(selectOrderedClasses);
1180
+ return (0, import_store14.__useSelector)(selectOrderedClasses);
1282
1181
  };
1283
1182
 
1284
1183
  // src/components/class-manager/class-item.tsx
1285
1184
  var React15 = __toESM(require("react"));
1286
1185
  var import_react7 = require("react");
1287
- var import_editor_styles_repository2 = require("@elementor/editor-styles-repository");
1186
+ var import_editor_styles_repository = require("@elementor/editor-styles-repository");
1288
1187
  var import_editor_ui8 = require("@elementor/editor-ui");
1289
1188
  var import_icons9 = require("@elementor/icons");
1290
1189
  var import_ui12 = require("@elementor/ui");
1291
- var import_i18n11 = require("@wordpress/i18n");
1190
+ var import_i18n10 = require("@wordpress/i18n");
1292
1191
 
1293
1192
  // src/components/css-class-usage/components/css-class-usage-popover.tsx
1294
1193
  var React11 = __toESM(require("react"));
@@ -1296,7 +1195,7 @@ var import_editor_documents2 = require("@elementor/editor-documents");
1296
1195
  var import_editor_ui5 = require("@elementor/editor-ui");
1297
1196
  var import_icons6 = require("@elementor/icons");
1298
1197
  var import_ui8 = require("@elementor/ui");
1299
- var import_i18n8 = require("@wordpress/i18n");
1198
+ var import_i18n7 = require("@wordpress/i18n");
1300
1199
 
1301
1200
  // src/hooks/use-css-class-usage-by-id.ts
1302
1201
  var EMPTY_CLASS_USAGE = {
@@ -1312,23 +1211,23 @@ var useCssClassUsageByID = (id2) => {
1312
1211
  // src/components/css-class-usage/components/css-class-usage-popover.tsx
1313
1212
  var iconMapper = {
1314
1213
  "wp-post": {
1315
- label: (0, import_i18n8.__)("Post", "elementor"),
1214
+ label: (0, import_i18n7.__)("Post", "elementor"),
1316
1215
  icon: /* @__PURE__ */ React11.createElement(import_icons6.PostTypeIcon, { fontSize: "inherit" })
1317
1216
  },
1318
1217
  "wp-page": {
1319
- label: (0, import_i18n8.__)("Page", "elementor"),
1218
+ label: (0, import_i18n7.__)("Page", "elementor"),
1320
1219
  icon: /* @__PURE__ */ React11.createElement(import_icons6.PagesIcon, { fontSize: "inherit" })
1321
1220
  },
1322
1221
  popup: {
1323
- label: (0, import_i18n8.__)("Popup", "elementor"),
1222
+ label: (0, import_i18n7.__)("Popup", "elementor"),
1324
1223
  icon: /* @__PURE__ */ React11.createElement(import_icons6.PopupTemplateIcon, { fontSize: "inherit" })
1325
1224
  },
1326
1225
  header: {
1327
- label: (0, import_i18n8.__)("Header", "elementor"),
1226
+ label: (0, import_i18n7.__)("Header", "elementor"),
1328
1227
  icon: /* @__PURE__ */ React11.createElement(import_icons6.HeaderTemplateIcon, { fontSize: "inherit" })
1329
1228
  },
1330
1229
  footer: {
1331
- label: (0, import_i18n8.__)("Footer", "elementor"),
1230
+ label: (0, import_i18n7.__)("Footer", "elementor"),
1332
1231
  icon: /* @__PURE__ */ React11.createElement(import_icons6.FooterTemplateIcon, { fontSize: "inherit" })
1333
1232
  }
1334
1233
  };
@@ -1358,7 +1257,7 @@ var CssClassUsagePopover = ({
1358
1257
  import_editor_ui5.PopoverHeader,
1359
1258
  {
1360
1259
  icon: /* @__PURE__ */ React11.createElement(import_icons6.CurrentLocationIcon, { fontSize: "tiny" }),
1361
- title: /* @__PURE__ */ React11.createElement(import_ui8.Stack, { flexDirection: "row", gap: 1, alignItems: "center" }, /* @__PURE__ */ React11.createElement(import_ui8.Box, { "aria-label": "header-title" }, (0, import_i18n8.__)("Locator", "elementor")), /* @__PURE__ */ React11.createElement(import_ui8.Box, null, /* @__PURE__ */ React11.createElement(import_ui8.Chip, { sx: { lineHeight: 1 }, size: "tiny", label: classUsage.total }))),
1260
+ title: /* @__PURE__ */ React11.createElement(import_ui8.Stack, { flexDirection: "row", gap: 1, alignItems: "center" }, /* @__PURE__ */ React11.createElement(import_ui8.Box, { "aria-label": "header-title" }, (0, import_i18n7.__)("Locator", "elementor")), /* @__PURE__ */ React11.createElement(import_ui8.Box, null, /* @__PURE__ */ React11.createElement(import_ui8.Chip, { sx: { lineHeight: 1 }, size: "tiny", label: classUsage.total }))),
1362
1261
  onClose
1363
1262
  }
1364
1263
  ), /* @__PURE__ */ React11.createElement(import_ui8.Divider, null), /* @__PURE__ */ React11.createElement(import_editor_ui5.PopoverBody, { width: 300 }, /* @__PURE__ */ React11.createElement(
@@ -1439,7 +1338,7 @@ var React12 = __toESM(require("react"));
1439
1338
  var import_editor_ui6 = require("@elementor/editor-ui");
1440
1339
  var import_icons7 = require("@elementor/icons");
1441
1340
  var import_ui9 = require("@elementor/ui");
1442
- var import_i18n9 = require("@wordpress/i18n");
1341
+ var import_i18n8 = require("@wordpress/i18n");
1443
1342
  var CssClassUsageTrigger = ({ id: id2, onClick }) => {
1444
1343
  const {
1445
1344
  data: { total },
@@ -1520,9 +1419,9 @@ var TooltipWrapper = ({ children, total }) => /* @__PURE__ */ React12.createElem
1520
1419
  {
1521
1420
  disableInteractive: true,
1522
1421
  placement: "top",
1523
- title: `${(0, import_i18n9.__)("Show {{number}} {{locations}}", "elementor").replace("{{number}}", total.toString()).replace(
1422
+ title: `${(0, import_i18n8.__)("Show {{number}} {{locations}}", "elementor").replace("{{number}}", total.toString()).replace(
1524
1423
  "{{locations}}",
1525
- total === 1 ? (0, import_i18n9.__)("location", "elementor") : (0, import_i18n9.__)("locations", "elementor")
1424
+ total === 1 ? (0, import_i18n8.__)("location", "elementor") : (0, import_i18n8.__)("locations", "elementor")
1526
1425
  )}`
1527
1426
  },
1528
1427
  /* @__PURE__ */ React12.createElement("span", null, children)
@@ -1533,7 +1432,7 @@ var InfoAlertMessage = ({ children }) => /* @__PURE__ */ React12.createElement(
1533
1432
  disableInteractive: true,
1534
1433
  placement: "top",
1535
1434
  color: "secondary",
1536
- content: /* @__PURE__ */ React12.createElement(import_editor_ui6.InfoAlert, { sx: { mt: 1 } }, (0, import_i18n9.__)("This class isn\u2019t being used yet.", "elementor"))
1435
+ content: /* @__PURE__ */ React12.createElement(import_editor_ui6.InfoAlert, { sx: { mt: 1 } }, (0, import_i18n8.__)("This class isn\u2019t being used yet.", "elementor"))
1537
1436
  },
1538
1437
  /* @__PURE__ */ React12.createElement("span", null, children)
1539
1438
  );
@@ -1543,7 +1442,7 @@ var React13 = __toESM(require("react"));
1543
1442
  var import_react6 = require("react");
1544
1443
  var import_editor_ui7 = require("@elementor/editor-ui");
1545
1444
  var import_ui10 = require("@elementor/ui");
1546
- var import_i18n10 = require("@wordpress/i18n");
1445
+ var import_i18n9 = require("@wordpress/i18n");
1547
1446
  var context = (0, import_react6.createContext)(null);
1548
1447
  var DeleteConfirmationProvider = ({ children }) => {
1549
1448
  const [dialogProps, setDialogProps] = (0, import_react6.useState)(null);
@@ -1564,14 +1463,14 @@ var DeleteClassDialog = ({ label, id: id2 }) => {
1564
1463
  closeDialog2();
1565
1464
  deleteClass(id2);
1566
1465
  };
1567
- const text = total && content.length ? (0, import_i18n10.__)(
1466
+ const text = total && content.length ? (0, import_i18n9.__)(
1568
1467
  "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.",
1569
1468
  "elementor"
1570
- ).replace("%1", total.toString()).replace("%2", content.length.toString()) : (0, import_i18n10.__)(
1469
+ ).replace("%1", total.toString()).replace("%2", content.length.toString()) : (0, import_i18n9.__)(
1571
1470
  "Will permanently remove it from your project and may affect the design across all elements using it. This action cannot be undone.",
1572
1471
  "elementor"
1573
1472
  );
1574
- return /* @__PURE__ */ React13.createElement(import_editor_ui7.ConfirmationDialog, { open: true, onClose: closeDialog2 }, /* @__PURE__ */ React13.createElement(import_editor_ui7.ConfirmationDialog.Title, null, (0, import_i18n10.__)("Delete this class?", "elementor")), /* @__PURE__ */ React13.createElement(import_editor_ui7.ConfirmationDialog.Content, null, /* @__PURE__ */ React13.createElement(import_editor_ui7.ConfirmationDialog.ContentText, null, (0, import_i18n10.__)("Deleting", "elementor"), /* @__PURE__ */ React13.createElement(import_ui10.Typography, { variant: "subtitle2", component: "span" }, "\xA0", label, "\xA0"), text)), /* @__PURE__ */ React13.createElement(import_editor_ui7.ConfirmationDialog.Actions, { onClose: closeDialog2, onConfirm: handleConfirm }));
1473
+ return /* @__PURE__ */ React13.createElement(import_editor_ui7.ConfirmationDialog, { open: true, onClose: closeDialog2 }, /* @__PURE__ */ React13.createElement(import_editor_ui7.ConfirmationDialog.Title, null, (0, import_i18n9.__)("Delete this class?", "elementor")), /* @__PURE__ */ React13.createElement(import_editor_ui7.ConfirmationDialog.Content, null, /* @__PURE__ */ React13.createElement(import_editor_ui7.ConfirmationDialog.ContentText, null, (0, import_i18n9.__)("Deleting", "elementor"), /* @__PURE__ */ React13.createElement(import_ui10.Typography, { variant: "subtitle2", component: "span" }, "\xA0", label, "\xA0"), text)), /* @__PURE__ */ React13.createElement(import_editor_ui7.ConfirmationDialog.Actions, { onClose: closeDialog2, onConfirm: handleConfirm }));
1575
1474
  };
1576
1475
  var useDeleteConfirmation = () => {
1577
1476
  const contextValue = (0, import_react6.useContext)(context);
@@ -1585,9 +1484,17 @@ var useDeleteConfirmation = () => {
1585
1484
  var React14 = __toESM(require("react"));
1586
1485
  var import_icons8 = require("@elementor/icons");
1587
1486
  var import_ui11 = require("@elementor/ui");
1588
- var SortableProvider = (props) => /* @__PURE__ */ React14.createElement(import_ui11.UnstableSortableProvider, { restrictAxis: true, variant: "static", dragPlaceholderStyle: { opacity: "1" }, ...props });
1487
+ var SortableProvider = (props) => /* @__PURE__ */ React14.createElement(
1488
+ import_ui11.UnstableSortableProvider,
1489
+ {
1490
+ restrictAxis: true,
1491
+ variant: "static",
1492
+ dragPlaceholderStyle: { visibility: "hidden" },
1493
+ ...props
1494
+ }
1495
+ );
1589
1496
  var SortableTrigger = (props) => /* @__PURE__ */ React14.createElement(StyledSortableTrigger, { ...props, role: "button", className: "class-item-sortable-trigger", "aria-label": "sort" }, /* @__PURE__ */ React14.createElement(import_icons8.GripVerticalIcon, { fontSize: "tiny" }));
1590
- var SortableItem = ({ children, id: id2, ...props }) => {
1497
+ var SortableItem = ({ children, id: id2, style, ...props }) => {
1591
1498
  return /* @__PURE__ */ React14.createElement(
1592
1499
  import_ui11.UnstableSortableItem,
1593
1500
  {
@@ -1608,7 +1515,7 @@ var SortableItem = ({ children, id: id2, ...props }) => {
1608
1515
  import_ui11.Box,
1609
1516
  {
1610
1517
  ...itemProps,
1611
- style: itemStyle,
1518
+ style: { ...itemStyle, ...!isDragOverlay ? style : null },
1612
1519
  component: "li",
1613
1520
  role: "listitem",
1614
1521
  sx: {
@@ -1712,7 +1619,7 @@ var ClassItem = ({
1712
1619
  {
1713
1620
  placement: "top",
1714
1621
  className: "class-item-more-actions",
1715
- title: (0, import_i18n11.__)("More actions", "elementor")
1622
+ title: (0, import_i18n10.__)("More actions", "elementor")
1716
1623
  },
1717
1624
  /* @__PURE__ */ React15.createElement(import_ui12.IconButton, { size: "tiny", ...(0, import_ui12.bindTrigger)(popupState), "aria-label": "More actions" }, /* @__PURE__ */ React15.createElement(import_icons9.DotsVerticalIcon, { fontSize: "tiny" }))
1718
1625
  )
@@ -1739,7 +1646,7 @@ var ClassItem = ({
1739
1646
  openEditMode();
1740
1647
  }
1741
1648
  },
1742
- /* @__PURE__ */ React15.createElement(import_ui12.Typography, { variant: "caption", sx: { color: "text.primary" } }, (0, import_i18n11.__)("Rename", "elementor"))
1649
+ /* @__PURE__ */ React15.createElement(import_ui12.Typography, { variant: "caption", sx: { color: "text.primary" } }, (0, import_i18n10.__)("Rename", "elementor"))
1743
1650
  ),
1744
1651
  onToggleSync && /* @__PURE__ */ React15.createElement(
1745
1652
  import_editor_ui8.MenuListItem,
@@ -1749,7 +1656,7 @@ var ClassItem = ({
1749
1656
  onToggleSync(id2, !syncToV3);
1750
1657
  }
1751
1658
  },
1752
- /* @__PURE__ */ React15.createElement(import_ui12.Stack, { direction: "row", alignItems: "center", gap: 1 }, syncToV3 ? /* @__PURE__ */ React15.createElement(import_icons9.RefreshOffIcon, { fontSize: "tiny" }) : /* @__PURE__ */ React15.createElement(import_icons9.RefreshIcon, { fontSize: "tiny" }), /* @__PURE__ */ React15.createElement(import_ui12.Typography, { variant: "caption", sx: { color: "text.primary" } }, syncToV3 ? (0, import_i18n11.__)("Stop syncing to Global Fonts", "elementor") : (0, import_i18n11.__)("Sync to Global Fonts", "elementor")))
1659
+ /* @__PURE__ */ React15.createElement(import_ui12.Stack, { direction: "row", alignItems: "center", gap: 1 }, syncToV3 ? /* @__PURE__ */ React15.createElement(import_icons9.RefreshOffIcon, { fontSize: "tiny" }) : /* @__PURE__ */ React15.createElement(import_icons9.RefreshIcon, { fontSize: "tiny" }), /* @__PURE__ */ React15.createElement(import_ui12.Typography, { variant: "caption", sx: { color: "text.primary" } }, syncToV3 ? (0, import_i18n10.__)("Stop syncing to Global Fonts", "elementor") : (0, import_i18n10.__)("Sync to Global Fonts", "elementor")))
1753
1660
  ),
1754
1661
  /* @__PURE__ */ React15.createElement(
1755
1662
  import_editor_ui8.MenuListItem,
@@ -1759,7 +1666,7 @@ var ClassItem = ({
1759
1666
  openDialog2({ id: id2, label });
1760
1667
  }
1761
1668
  },
1762
- /* @__PURE__ */ React15.createElement(import_ui12.Typography, { variant: "caption", sx: { color: "error.light" } }, (0, import_i18n11.__)("Delete", "elementor"))
1669
+ /* @__PURE__ */ React15.createElement(import_ui12.Typography, { variant: "caption", sx: { color: "error.light" } }, (0, import_i18n10.__)("Delete", "elementor"))
1763
1670
  )
1764
1671
  ));
1765
1672
  };
@@ -1814,7 +1721,7 @@ var getIndicatorBorder = ({ isActive, isError, theme }) => {
1814
1721
  return "none";
1815
1722
  };
1816
1723
  var validateLabel = (newLabel) => {
1817
- const result = (0, import_editor_styles_repository2.validateStyleLabel)(newLabel, "rename");
1724
+ const result = (0, import_editor_styles_repository.validateStyleLabel)(newLabel, "rename");
1818
1725
  if (result.isValid) {
1819
1726
  return null;
1820
1727
  }
@@ -1825,7 +1732,7 @@ var validateLabel = (newLabel) => {
1825
1732
  var React16 = __toESM(require("react"));
1826
1733
  var import_icons10 = require("@elementor/icons");
1827
1734
  var import_ui13 = require("@elementor/ui");
1828
- var import_i18n12 = require("@wordpress/i18n");
1735
+ var import_i18n11 = require("@wordpress/i18n");
1829
1736
  var getNotFoundType = (searchValue, filters, filteredClasses) => {
1830
1737
  const searchNotFound = filteredClasses.length <= 0 && searchValue.length > 1;
1831
1738
  const filterNotFound = filters && filters.length === 0;
@@ -1843,18 +1750,18 @@ var getNotFoundType = (searchValue, filters, filteredClasses) => {
1843
1750
  };
1844
1751
  var notFound = {
1845
1752
  filterAndSearch: {
1846
- mainText: (0, import_i18n12.__)("Sorry, nothing matched.", "elementor"),
1847
- sceneryText: (0, import_i18n12.__)("Try something else.", "elementor"),
1753
+ mainText: (0, import_i18n11.__)("Sorry, nothing matched.", "elementor"),
1754
+ sceneryText: (0, import_i18n11.__)("Try something else.", "elementor"),
1848
1755
  icon: /* @__PURE__ */ React16.createElement(import_icons10.PhotoIcon, { color: "inherit", fontSize: "large" })
1849
1756
  },
1850
1757
  search: {
1851
- mainText: (0, import_i18n12.__)("Sorry, nothing matched", "elementor"),
1852
- sceneryText: (0, import_i18n12.__)("Clear your input and try something else.", "elementor"),
1758
+ mainText: (0, import_i18n11.__)("Sorry, nothing matched", "elementor"),
1759
+ sceneryText: (0, import_i18n11.__)("Clear your input and try something else.", "elementor"),
1853
1760
  icon: /* @__PURE__ */ React16.createElement(import_icons10.PhotoIcon, { color: "inherit", fontSize: "large" })
1854
1761
  },
1855
1762
  filter: {
1856
- mainText: (0, import_i18n12.__)("Sorry, nothing matched that search.", "elementor"),
1857
- sceneryText: (0, import_i18n12.__)("Clear the filters and try something else.", "elementor"),
1763
+ mainText: (0, import_i18n11.__)("Sorry, nothing matched that search.", "elementor"),
1764
+ sceneryText: (0, import_i18n11.__)("Clear the filters and try something else.", "elementor"),
1858
1765
  icon: /* @__PURE__ */ React16.createElement(import_icons10.ColorSwatchIcon, { color: "inherit", fontSize: "large" })
1859
1766
  }
1860
1767
  };
@@ -1927,38 +1834,65 @@ var NotFoundLayout = ({ onClear, searchValue, mainText, sceneryText, icon }) =>
1927
1834
  )
1928
1835
  ),
1929
1836
  /* @__PURE__ */ React16.createElement(import_ui13.Typography, { align: "center", variant: "caption", color: "inherit" }, sceneryText),
1930
- /* @__PURE__ */ React16.createElement(import_ui13.Typography, { align: "center", variant: "caption", color: "inherit" }, /* @__PURE__ */ React16.createElement(import_ui13.Link, { color: "secondary", variant: "caption", component: "button", onClick: onClear }, (0, import_i18n12.__)("Clear & try again", "elementor")))
1837
+ /* @__PURE__ */ React16.createElement(import_ui13.Typography, { align: "center", variant: "caption", color: "inherit" }, /* @__PURE__ */ React16.createElement(import_ui13.Link, { color: "secondary", variant: "caption", component: "button", onClick: onClear }, (0, import_i18n11.__)("Clear & try again", "elementor")))
1931
1838
  );
1932
1839
 
1933
1840
  // src/components/class-manager/global-classes-list.tsx
1934
- var GlobalClassesList = ({ disabled, onStopSyncRequest, onStartSyncRequest }) => {
1841
+ var ROW_HEIGHT = 40;
1842
+ var OVERSCAN = 6;
1843
+ var GlobalClassesList = ({
1844
+ disabled,
1845
+ scrollElement,
1846
+ onStopSyncRequest,
1847
+ onStartSyncRequest
1848
+ }) => {
1935
1849
  const {
1936
1850
  search: { debouncedValue: searchValue }
1937
1851
  } = useSearchAndFilters();
1938
1852
  const cssClasses = useOrderedClasses();
1939
- const dispatch5 = (0, import_store18.__useDispatch)();
1853
+ const dispatch7 = (0, import_store16.__useDispatch)();
1940
1854
  const filters = useFilters();
1941
1855
  const [draggedItemId, setDraggedItemId] = (0, import_react8.useState)(null);
1942
1856
  const draggedItemLabel = cssClasses.find((cssClass) => cssClass.id === draggedItemId)?.label ?? "";
1943
1857
  const [classesOrder, reorderClasses] = useReorder(draggedItemId, setDraggedItemId, draggedItemLabel ?? "");
1944
1858
  const filteredCssClasses = useFilteredCssClasses();
1859
+ const virtualizer = (0, import_react_virtual.useVirtualizer)({
1860
+ count: filteredCssClasses.length,
1861
+ getScrollElement: () => scrollElement ?? null,
1862
+ estimateSize: () => ROW_HEIGHT,
1863
+ overscan: OVERSCAN,
1864
+ getItemKey: (index) => filteredCssClasses[index].id,
1865
+ // Keep the actively dragged row mounted even when scrolled out of view.
1866
+ // SortableItem unregisters its render on unmount, which would make the
1867
+ // DragOverlay clone disappear mid-drag.
1868
+ rangeExtractor: (range) => {
1869
+ const indices = new Set((0, import_react_virtual.defaultRangeExtractor)(range));
1870
+ if (draggedItemId) {
1871
+ const draggedItemIndex = filteredCssClasses.findIndex((cssClass) => cssClass.id === draggedItemId);
1872
+ if (draggedItemIndex >= 0) {
1873
+ indices.add(draggedItemIndex);
1874
+ }
1875
+ }
1876
+ return [...indices].sort((a, b) => a - b);
1877
+ }
1878
+ });
1945
1879
  (0, import_react8.useEffect)(() => {
1946
1880
  const handler2 = (event) => {
1947
1881
  if (event.key === "z" && (event.ctrlKey || event.metaKey)) {
1948
1882
  event.stopImmediatePropagation();
1949
1883
  event.preventDefault();
1950
1884
  if (event.shiftKey) {
1951
- dispatch5(slice.actions.redo());
1885
+ dispatch7(slice.actions.redo());
1952
1886
  return;
1953
1887
  }
1954
- dispatch5(slice.actions.undo());
1888
+ dispatch7(slice.actions.undo());
1955
1889
  }
1956
1890
  };
1957
1891
  window.addEventListener("keydown", handler2, {
1958
1892
  capture: true
1959
1893
  });
1960
1894
  return () => window.removeEventListener("keydown", handler2);
1961
- }, [dispatch5]);
1895
+ }, [dispatch7]);
1962
1896
  if (!cssClasses?.length) {
1963
1897
  return /* @__PURE__ */ React17.createElement(EmptyState, null);
1964
1898
  }
@@ -1968,69 +1902,94 @@ var GlobalClassesList = ({ disabled, onStopSyncRequest, onStartSyncRequest }) =>
1968
1902
  }
1969
1903
  const isFiltersApplied = filters?.length || searchValue;
1970
1904
  const allowSorting = filteredCssClasses.length > 1 && !isFiltersApplied;
1971
- return /* @__PURE__ */ React17.createElement(DeleteConfirmationProvider, null, /* @__PURE__ */ React17.createElement(import_ui14.List, { sx: { display: "flex", flexDirection: "column", gap: 0.5 } }, /* @__PURE__ */ React17.createElement(
1972
- SortableProvider,
1905
+ return /* @__PURE__ */ React17.createElement(DeleteConfirmationProvider, null, /* @__PURE__ */ React17.createElement(
1906
+ import_ui14.List,
1973
1907
  {
1974
- value: classesOrder,
1975
- onChange: reorderClasses,
1976
- disableDragOverlay: !allowSorting
1977
- },
1978
- filteredCssClasses?.map((cssClass) => /* @__PURE__ */ React17.createElement(SortableItem, { key: cssClass.id, id: cssClass.id }, ({ isDragged, isDragPlaceholder, triggerProps, triggerStyle }) => {
1979
- if (isDragged && !draggedItemId) {
1980
- setDraggedItemId(cssClass.id);
1908
+ sx: {
1909
+ position: "relative",
1910
+ display: "block",
1911
+ height: virtualizer.getTotalSize(),
1912
+ padding: 0
1981
1913
  }
1982
- return /* @__PURE__ */ React17.createElement(
1983
- ClassItem,
1984
- {
1985
- id: cssClass.id,
1986
- label: cssClass.label,
1987
- renameClass: (newLabel) => {
1988
- trackGlobalClasses({
1989
- event: "classRenamed",
1990
- classId: cssClass.id,
1991
- oldValue: cssClass.label,
1992
- newValue: newLabel,
1993
- source: "class-manager"
1994
- });
1995
- dispatch5(
1996
- slice.actions.update({
1997
- style: {
1998
- id: cssClass.id,
1999
- label: newLabel
2000
- }
2001
- })
2002
- );
2003
- },
2004
- selected: isDragged,
2005
- disabled: disabled || isDragPlaceholder,
2006
- sortableTriggerProps: {
2007
- ...triggerProps,
2008
- style: triggerStyle
1914
+ },
1915
+ /* @__PURE__ */ React17.createElement(
1916
+ SortableProvider,
1917
+ {
1918
+ value: classesOrder,
1919
+ onChange: reorderClasses,
1920
+ onDragStart: (event) => setDraggedItemId(event.active.id),
1921
+ onDragEnd: () => setDraggedItemId(null),
1922
+ onDragCancel: () => setDraggedItemId(null),
1923
+ disableDragOverlay: !allowSorting
1924
+ },
1925
+ virtualizer.getVirtualItems().map((virtualRow) => {
1926
+ const cssClass = filteredCssClasses[virtualRow.index];
1927
+ return /* @__PURE__ */ React17.createElement(
1928
+ SortableItem,
1929
+ {
1930
+ key: virtualRow.key,
1931
+ id: cssClass.id,
1932
+ style: {
1933
+ position: "absolute",
1934
+ top: virtualRow.start,
1935
+ left: 0,
1936
+ width: "100%"
1937
+ }
2009
1938
  },
2010
- showSortIndicator: allowSorting,
2011
- syncToV3: cssClass.sync_to_v3,
2012
- onToggleSync: (id2, newValue) => {
2013
- if (!newValue && onStopSyncRequest) {
2014
- onStopSyncRequest(id2);
2015
- } else if (newValue && onStartSyncRequest) {
2016
- onStartSyncRequest(id2);
2017
- } else {
2018
- dispatch5(
2019
- slice.actions.update({
2020
- style: {
2021
- id: id2,
2022
- sync_to_v3: newValue
2023
- }
2024
- })
2025
- );
1939
+ ({ isDragged, isDragPlaceholder, triggerProps, triggerStyle }) => /* @__PURE__ */ React17.createElement(
1940
+ ClassItem,
1941
+ {
1942
+ id: cssClass.id,
1943
+ label: cssClass.label,
1944
+ renameClass: (newLabel) => {
1945
+ trackGlobalClasses({
1946
+ event: "classRenamed",
1947
+ classId: cssClass.id,
1948
+ oldValue: cssClass.label,
1949
+ newValue: newLabel,
1950
+ source: "class-manager"
1951
+ });
1952
+ dispatch7(
1953
+ slice.actions.update({
1954
+ style: {
1955
+ id: cssClass.id,
1956
+ label: newLabel
1957
+ }
1958
+ })
1959
+ );
1960
+ },
1961
+ selected: isDragged,
1962
+ disabled: disabled || isDragPlaceholder,
1963
+ sortableTriggerProps: {
1964
+ ...triggerProps,
1965
+ style: triggerStyle
1966
+ },
1967
+ showSortIndicator: allowSorting,
1968
+ syncToV3: cssClass.sync_to_v3,
1969
+ onToggleSync: (id2, newValue) => {
1970
+ if (!newValue && onStopSyncRequest) {
1971
+ onStopSyncRequest(id2);
1972
+ } else if (newValue && onStartSyncRequest) {
1973
+ onStartSyncRequest(id2);
1974
+ } else {
1975
+ dispatch7(
1976
+ slice.actions.update({
1977
+ style: {
1978
+ id: id2,
1979
+ sync_to_v3: newValue
1980
+ }
1981
+ })
1982
+ );
1983
+ }
1984
+ }
2026
1985
  }
2027
- }
2028
- }
2029
- );
2030
- }))
2031
- )));
1986
+ )
1987
+ );
1988
+ })
1989
+ )
1990
+ ));
2032
1991
  };
2033
- var EmptyState = () => /* @__PURE__ */ React17.createElement(import_ui14.Stack, { alignItems: "center", gap: 1.5, pt: 10, px: 0.5, maxWidth: "260px", margin: "auto" }, /* @__PURE__ */ React17.createElement(FlippedColorSwatchIcon, { fontSize: "large" }), /* @__PURE__ */ React17.createElement(StyledHeader, { variant: "subtitle2", component: "h2", color: "text.secondary" }, (0, import_i18n13.__)("There are no global classes yet.", "elementor")), /* @__PURE__ */ React17.createElement(import_ui14.Typography, { align: "center", variant: "caption", color: "text.secondary" }, (0, import_i18n13.__)(
1992
+ var EmptyState = () => /* @__PURE__ */ React17.createElement(import_ui14.Stack, { alignItems: "center", gap: 1.5, pt: 10, px: 0.5, maxWidth: "260px", margin: "auto" }, /* @__PURE__ */ React17.createElement(FlippedColorSwatchIcon, { fontSize: "large" }), /* @__PURE__ */ React17.createElement(StyledHeader, { variant: "subtitle2", component: "h2", color: "text.secondary" }, (0, import_i18n12.__)("There are no global classes yet.", "elementor")), /* @__PURE__ */ React17.createElement(import_ui14.Typography, { align: "center", variant: "caption", color: "text.secondary" }, (0, import_i18n12.__)(
2034
1993
  "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.",
2035
1994
  "elementor"
2036
1995
  )));
@@ -2040,10 +1999,10 @@ var StyledHeader = (0, import_ui14.styled)(import_ui14.Typography)(({ theme, var
2040
1999
  }
2041
2000
  }));
2042
2001
  var useReorder = (draggedItemId, setDraggedItemId, draggedItemLabel) => {
2043
- const dispatch5 = (0, import_store18.__useDispatch)();
2002
+ const dispatch7 = (0, import_store16.__useDispatch)();
2044
2003
  const order = useClassesOrder();
2045
2004
  const reorder = (newIds) => {
2046
- dispatch5(slice.actions.setOrder(newIds));
2005
+ dispatch7(slice.actions.setOrder(newIds));
2047
2006
  if (draggedItemId) {
2048
2007
  trackGlobalClasses({
2049
2008
  event: "classManagerReorder",
@@ -2096,7 +2055,7 @@ function unblockPanelInteractions() {
2096
2055
  var React18 = __toESM(require("react"));
2097
2056
  var import_react9 = require("react");
2098
2057
  var import_ui15 = require("@elementor/ui");
2099
- var import_i18n14 = require("@wordpress/i18n");
2058
+ var import_i18n13 = require("@wordpress/i18n");
2100
2059
  var IMAGE_URL = "https://assets.elementor.com/packages/v1/images/class-manager-sync-modal.png";
2101
2060
  var StartSyncToV3Modal = ({
2102
2061
  externalOpen,
@@ -2128,7 +2087,7 @@ var StartSyncToV3Modal = ({
2128
2087
  onConfirm?.();
2129
2088
  onExternalClose?.();
2130
2089
  };
2131
- return /* @__PURE__ */ React18.createElement(import_ui15.Dialog, { open: !!externalOpen, onClose: handleClose, maxWidth: "sm", fullWidth: true }, /* @__PURE__ */ React18.createElement(import_ui15.DialogContent, { sx: { p: 0 } }, /* @__PURE__ */ React18.createElement(import_ui15.Box, { component: "img", src: IMAGE_URL, alt: "", sx: { width: "100%", display: "block" } }), /* @__PURE__ */ React18.createElement(import_ui15.Box, { sx: { px: 3, pt: 4, pb: 1 } }, /* @__PURE__ */ React18.createElement(import_ui15.Typography, { variant: "h6" }, (0, import_i18n14.__)("Sync class to Global Fonts", "elementor")), /* @__PURE__ */ React18.createElement(import_ui15.Typography, { variant: "body2", color: "secondary", sx: { mb: 2, pt: 1 } }, (0, import_i18n14.__)(
2090
+ return /* @__PURE__ */ React18.createElement(import_ui15.Dialog, { open: !!externalOpen, onClose: handleClose, maxWidth: "sm", fullWidth: true }, /* @__PURE__ */ React18.createElement(import_ui15.DialogContent, { sx: { p: 0 } }, /* @__PURE__ */ React18.createElement(import_ui15.Box, { component: "img", src: IMAGE_URL, alt: "", sx: { width: "100%", display: "block" } }), /* @__PURE__ */ React18.createElement(import_ui15.Box, { sx: { px: 3, pt: 4, pb: 1 } }, /* @__PURE__ */ React18.createElement(import_ui15.Typography, { variant: "h6" }, (0, import_i18n13.__)("Sync class to Global Fonts", "elementor")), /* @__PURE__ */ React18.createElement(import_ui15.Typography, { variant: "body2", color: "secondary", sx: { mb: 2, pt: 1 } }, (0, import_i18n13.__)(
2132
2091
  "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.",
2133
2092
  "elementor"
2134
2093
  )))), /* @__PURE__ */ React18.createElement(import_ui15.DialogActions, { sx: { justifyContent: "space-between", px: 3, pb: 2 } }, /* @__PURE__ */ React18.createElement(
@@ -2141,53 +2100,89 @@ var StartSyncToV3Modal = ({
2141
2100
  onChange: (e) => setShouldShowAgain(!e.target.checked)
2142
2101
  }
2143
2102
  ),
2144
- label: /* @__PURE__ */ React18.createElement(import_ui15.Typography, { variant: "body2", color: "secondary" }, (0, import_i18n14.__)("Don't show again", "elementor"))
2103
+ label: /* @__PURE__ */ React18.createElement(import_ui15.Typography, { variant: "body2", color: "secondary" }, (0, import_i18n13.__)("Don't show again", "elementor"))
2145
2104
  }
2146
- ), /* @__PURE__ */ React18.createElement(import_ui15.Box, { sx: { display: "flex", gap: 1 } }, /* @__PURE__ */ React18.createElement(import_ui15.Button, { onClick: handleClose, color: "secondary", size: "small" }, (0, import_i18n14.__)("Cancel", "elementor")), /* @__PURE__ */ React18.createElement(import_ui15.Button, { onClick: handleConfirm, variant: "contained", size: "small" }, (0, import_i18n14.__)("Sync to Global Fonts", "elementor")))));
2105
+ ), /* @__PURE__ */ React18.createElement(import_ui15.Box, { sx: { display: "flex", gap: 1 } }, /* @__PURE__ */ React18.createElement(import_ui15.Button, { onClick: handleClose, color: "secondary", size: "small" }, (0, import_i18n13.__)("Cancel", "elementor")), /* @__PURE__ */ React18.createElement(import_ui15.Button, { onClick: handleConfirm, variant: "contained", size: "small" }, (0, import_i18n13.__)("Sync to Global Fonts", "elementor")))));
2147
2106
  };
2148
2107
 
2149
2108
  // src/components/class-manager/class-manager-panel.tsx
2150
2109
  var STOP_SYNC_MESSAGE_KEY = "stop-sync-class";
2151
2110
  var id = "global-classes-manager";
2152
- var reloadDocument = () => {
2153
- const currentDocument = (0, import_editor_documents3.getCurrentDocument)();
2154
- const documentsManager = (0, import_editor_documents3.getV1DocumentsManager)();
2155
- documentsManager.invalidateCache();
2156
- return (0, import_editor_v1_adapters2.__privateRunCommand)("editor/documents/switch", {
2157
- id: currentDocument?.id,
2158
- shouldScroll: false,
2159
- shouldNavigateToDefaultRoute: false
2160
- });
2161
- };
2111
+ function ClassManagerPanelEmbedded({ onRequestClose, onExposeCloseAttempt }) {
2112
+ return /* @__PURE__ */ React19.createElement(
2113
+ ClassManagerPanelRoot,
2114
+ {
2115
+ embedded: true,
2116
+ onRequestClose,
2117
+ onExposeCloseAttempt
2118
+ }
2119
+ );
2120
+ }
2121
+ function ClassManagerPanel() {
2122
+ return /* @__PURE__ */ React19.createElement(ClassManagerPanelRoot, null);
2123
+ }
2162
2124
  var { panel, usePanelActions } = (0, import_editor_panels.__createPanel)({
2163
2125
  id,
2164
2126
  component: ClassManagerPanel,
2165
2127
  allowedEditModes: ["edit", id],
2166
2128
  onOpen: () => {
2167
- (0, import_editor_v1_adapters2.changeEditMode)(id);
2129
+ (0, import_editor_v1_adapters.changeEditMode)(id);
2168
2130
  blockPanelInteractions();
2169
2131
  },
2170
2132
  onClose: async () => {
2171
- (0, import_editor_v1_adapters2.changeEditMode)("edit");
2172
- await reloadDocument();
2133
+ (0, import_editor_v1_adapters.changeEditMode)("edit");
2134
+ await (0, import_editor_documents3.reloadCurrentDocument)();
2173
2135
  unblockPanelInteractions();
2174
2136
  },
2175
2137
  isOpenPreviousElement: true
2176
2138
  });
2177
- function ClassManagerPanel() {
2139
+ function ClassManagerPanelRoot({
2140
+ embedded = false,
2141
+ onRequestClose,
2142
+ onExposeCloseAttempt
2143
+ } = {}) {
2178
2144
  const isDirty2 = useDirtyState();
2179
- const { close: closePanel } = usePanelActions();
2145
+ const { close: closeStandalonePanel } = usePanelActions();
2146
+ const closePanel = (0, import_react10.useMemo)(
2147
+ () => embedded ? onRequestClose ?? (async () => {
2148
+ }) : closeStandalonePanel,
2149
+ [embedded, onRequestClose, closeStandalonePanel]
2150
+ );
2180
2151
  const { open: openSaveChangesDialog, close: closeSaveChangesDialog, isOpen: isSaveChangesDialogOpen } = (0, import_editor_ui9.useDialog)();
2181
2152
  const [stopSyncConfirmation, setStopSyncConfirmation] = (0, import_react10.useState)(null);
2182
2153
  const [startSyncConfirmation, setStartSyncConfirmation] = (0, import_react10.useState)(null);
2183
2154
  const [isStopSyncSuppressed] = (0, import_editor_current_user2.useSuppressedMessage)(STOP_SYNC_MESSAGE_KEY);
2155
+ const [scrollElement, setScrollElement] = (0, import_react10.useState)(null);
2184
2156
  const { mutateAsync: publish, isPending: isPublishing } = usePublish();
2185
2157
  const resetAndClosePanel = () => {
2186
- (0, import_store20.__dispatch)(slice.actions.resetToInitialState({ context: "frontend" }));
2158
+ (0, import_store18.__dispatch)(slice.actions.resetToInitialState({ context: "frontend" }));
2187
2159
  closeSaveChangesDialog();
2188
2160
  };
2161
+ const handleClosePanel = (0, import_react10.useCallback)(() => {
2162
+ if (isDirty2) {
2163
+ openSaveChangesDialog();
2164
+ return;
2165
+ }
2166
+ void closePanel();
2167
+ }, [isDirty2, openSaveChangesDialog, closePanel]);
2168
+ (0, import_react10.useEffect)(() => {
2169
+ if (!embedded || !onExposeCloseAttempt) {
2170
+ return;
2171
+ }
2172
+ onExposeCloseAttempt(() => handleClosePanel());
2173
+ return () => onExposeCloseAttempt(null);
2174
+ }, [embedded, onExposeCloseAttempt, handleClosePanel]);
2175
+ (0, import_react10.useEffect)(() => {
2176
+ if (!embedded) {
2177
+ return;
2178
+ }
2179
+ blockPanelInteractions();
2180
+ return () => {
2181
+ unblockPanelInteractions();
2182
+ };
2183
+ }, [embedded]);
2189
2184
  const handleStopSync = (0, import_react10.useCallback)((classId) => {
2190
- (0, import_store20.__dispatch)(
2185
+ (0, import_store18.__dispatch)(
2191
2186
  slice.actions.update({
2192
2187
  style: {
2193
2188
  id: classId,
@@ -2199,7 +2194,7 @@ function ClassManagerPanel() {
2199
2194
  setStopSyncConfirmation(null);
2200
2195
  }, []);
2201
2196
  const handleStartSync = (0, import_react10.useCallback)((classId) => {
2202
- (0, import_store20.__dispatch)(
2197
+ (0, import_store18.__dispatch)(
2203
2198
  slice.actions.update({
2204
2199
  style: {
2205
2200
  id: classId,
@@ -2221,49 +2216,29 @@ function ClassManagerPanel() {
2221
2216
  [isStopSyncSuppressed, handleStopSync]
2222
2217
  );
2223
2218
  usePreventUnload();
2224
- return /* @__PURE__ */ React19.createElement(import_editor_ui9.ThemeProvider, null, /* @__PURE__ */ React19.createElement(import_ui16.ErrorBoundary, { fallback: /* @__PURE__ */ React19.createElement(ErrorBoundaryFallback, null) }, /* @__PURE__ */ React19.createElement(import_editor_panels.Panel, null, /* @__PURE__ */ React19.createElement(SearchAndFilterProvider, null, /* @__PURE__ */ React19.createElement(import_editor_panels.PanelHeader, null, /* @__PURE__ */ React19.createElement(import_ui16.Stack, { p: 1, pl: 2, width: "100%", direction: "row", alignItems: "center" }, /* @__PURE__ */ React19.createElement(import_ui16.Stack, { width: "100%", direction: "row", gap: 1 }, /* @__PURE__ */ React19.createElement(import_editor_panels.PanelHeaderTitle, { sx: { display: "flex", alignItems: "center", gap: 0.5 } }, /* @__PURE__ */ React19.createElement(FlippedColorSwatchIcon, { fontSize: "inherit" }), (0, import_i18n15.__)("Class Manager", "elementor")), /* @__PURE__ */ React19.createElement(TotalCssClassCounter, null)), /* @__PURE__ */ React19.createElement(
2225
- CloseButton,
2226
- {
2227
- sx: { marginLeft: "auto" },
2228
- disabled: isPublishing,
2229
- onClose: () => {
2230
- if (isDirty2) {
2231
- openSaveChangesDialog();
2232
- return;
2233
- }
2234
- closePanel();
2235
- }
2236
- }
2237
- ))), /* @__PURE__ */ React19.createElement(
2238
- import_editor_panels.PanelBody,
2219
+ const searchFiltersBlock = /* @__PURE__ */ React19.createElement(import_ui16.Box, { px: 2, pb: 1 }, /* @__PURE__ */ React19.createElement(import_ui16.Stack, { direction: "row", alignItems: "center", justifyContent: "space-between", gap: 0.5, sx: { pb: 0.5 } }, /* @__PURE__ */ React19.createElement(import_ui16.Box, { sx: embedded ? { flexGrow: 1, minWidth: 0 } : { flexGrow: 1 } }, /* @__PURE__ */ React19.createElement(ClassManagerSearch, null)), /* @__PURE__ */ React19.createElement(CssClassFilter, null), embedded && /* @__PURE__ */ React19.createElement(TotalCssClassCounter, null)), /* @__PURE__ */ React19.createElement(ActiveFilters, null));
2220
+ const listArea = /* @__PURE__ */ React19.createElement(
2221
+ import_ui16.Box,
2239
2222
  {
2223
+ ref: setScrollElement,
2224
+ px: 2,
2240
2225
  sx: {
2241
- display: "flex",
2242
- flexDirection: "column",
2243
- height: "100%"
2226
+ flexGrow: 1,
2227
+ overflowY: "auto",
2228
+ ...embedded ? { minHeight: 0 } : {}
2244
2229
  }
2245
2230
  },
2246
- /* @__PURE__ */ React19.createElement(import_ui16.Box, { px: 2, pb: 1 }, /* @__PURE__ */ React19.createElement(import_ui16.Stack, { direction: "row", justifyContent: "spaceBetween", gap: 0.5, sx: { pb: 0.5 } }, /* @__PURE__ */ React19.createElement(import_ui16.Box, { sx: { flexGrow: 1 } }, /* @__PURE__ */ React19.createElement(ClassManagerSearch, null)), /* @__PURE__ */ React19.createElement(CssClassFilter, null)), /* @__PURE__ */ React19.createElement(ActiveFilters, null)),
2247
- /* @__PURE__ */ React19.createElement(import_ui16.Divider, null),
2248
2231
  /* @__PURE__ */ React19.createElement(
2249
- import_ui16.Box,
2232
+ GlobalClassesList,
2250
2233
  {
2251
- px: 2,
2252
- sx: {
2253
- flexGrow: 1,
2254
- overflowY: "auto"
2255
- }
2256
- },
2257
- /* @__PURE__ */ React19.createElement(
2258
- GlobalClassesList,
2259
- {
2260
- disabled: isPublishing,
2261
- onStopSyncRequest: handleStopSyncRequest,
2262
- onStartSyncRequest: (classId) => setStartSyncConfirmation(classId)
2263
- }
2264
- )
2234
+ disabled: isPublishing,
2235
+ scrollElement,
2236
+ onStopSyncRequest: handleStopSyncRequest,
2237
+ onStartSyncRequest: (classId) => setStartSyncConfirmation(classId)
2238
+ }
2265
2239
  )
2266
- ), /* @__PURE__ */ React19.createElement(import_editor_panels.PanelFooter, null, /* @__PURE__ */ React19.createElement(
2240
+ );
2241
+ const saveFooter = /* @__PURE__ */ React19.createElement(import_editor_panels.PanelFooter, null, /* @__PURE__ */ React19.createElement(
2267
2242
  import_ui16.Button,
2268
2243
  {
2269
2244
  fullWidth: true,
@@ -2274,8 +2249,9 @@ function ClassManagerPanel() {
2274
2249
  disabled: !isDirty2,
2275
2250
  loading: isPublishing
2276
2251
  },
2277
- (0, import_i18n15.__)("Save changes", "elementor")
2278
- ))))), /* @__PURE__ */ React19.createElement(ClassManagerIntroduction, null), startSyncConfirmation && /* @__PURE__ */ React19.createElement(
2252
+ (0, import_i18n14.__)("Save changes", "elementor")
2253
+ ));
2254
+ const dialogs = /* @__PURE__ */ React19.createElement(React19.Fragment, null, startSyncConfirmation && /* @__PURE__ */ React19.createElement(
2279
2255
  StartSyncToV3Modal,
2280
2256
  {
2281
2257
  externalOpen: true,
@@ -2290,30 +2266,84 @@ function ClassManagerPanel() {
2290
2266
  onClose: () => setStopSyncConfirmation(null),
2291
2267
  onConfirm: () => handleStopSync(stopSyncConfirmation)
2292
2268
  }
2293
- ), isSaveChangesDialogOpen && /* @__PURE__ */ React19.createElement(import_editor_ui9.SaveChangesDialog, null, /* @__PURE__ */ React19.createElement(import_ui16.DialogHeader, { onClose: closeSaveChangesDialog, logo: false }, /* @__PURE__ */ React19.createElement(import_editor_ui9.SaveChangesDialog.Title, null, (0, import_i18n15.__)("You have unsaved changes", "elementor"))), /* @__PURE__ */ React19.createElement(import_editor_ui9.SaveChangesDialog.Content, null, /* @__PURE__ */ React19.createElement(import_editor_ui9.SaveChangesDialog.ContentText, null, (0, import_i18n15.__)("You have unsaved changes in the Class Manager.", "elementor")), /* @__PURE__ */ React19.createElement(import_editor_ui9.SaveChangesDialog.ContentText, null, (0, import_i18n15.__)("To avoid losing your updates, save your changes before leaving.", "elementor"))), /* @__PURE__ */ React19.createElement(
2269
+ ), isSaveChangesDialogOpen && /* @__PURE__ */ React19.createElement(import_editor_ui9.SaveChangesDialog, null, /* @__PURE__ */ React19.createElement(import_ui16.DialogHeader, { onClose: closeSaveChangesDialog, logo: false }, /* @__PURE__ */ React19.createElement(import_editor_ui9.SaveChangesDialog.Title, null, (0, import_i18n14.__)("You have unsaved changes", "elementor"))), /* @__PURE__ */ React19.createElement(import_editor_ui9.SaveChangesDialog.Content, null, /* @__PURE__ */ React19.createElement(import_editor_ui9.SaveChangesDialog.ContentText, null, (0, import_i18n14.__)("You have unsaved changes in the Class Manager.", "elementor")), /* @__PURE__ */ React19.createElement(import_editor_ui9.SaveChangesDialog.ContentText, null, (0, import_i18n14.__)("To avoid losing your updates, save your changes before leaving.", "elementor"))), /* @__PURE__ */ React19.createElement(
2294
2270
  import_editor_ui9.SaveChangesDialog.Actions,
2295
2271
  {
2296
2272
  actions: {
2297
2273
  discard: {
2298
- label: (0, import_i18n15.__)("Discard", "elementor"),
2274
+ label: (0, import_i18n14.__)("Discard", "elementor"),
2299
2275
  action: () => {
2300
2276
  resetAndClosePanel();
2301
2277
  }
2302
2278
  },
2303
2279
  confirm: {
2304
- label: (0, import_i18n15.__)("Save & Continue", "elementor"),
2280
+ label: (0, import_i18n14.__)("Save & Continue", "elementor"),
2305
2281
  action: async () => {
2306
2282
  await publish();
2307
2283
  closeSaveChangesDialog();
2308
- closePanel();
2284
+ void closePanel();
2309
2285
  }
2310
2286
  }
2311
2287
  }
2312
2288
  }
2313
2289
  )));
2290
+ const classManagerLayout = embedded ? /* @__PURE__ */ React19.createElement(
2291
+ import_ui16.Stack,
2292
+ {
2293
+ direction: "column",
2294
+ sx: {
2295
+ height: "100%",
2296
+ width: "100%",
2297
+ flex: 1,
2298
+ minHeight: 0,
2299
+ overflow: "hidden"
2300
+ }
2301
+ },
2302
+ searchFiltersBlock,
2303
+ /* @__PURE__ */ React19.createElement(import_ui16.Divider, null),
2304
+ listArea,
2305
+ saveFooter
2306
+ ) : /* @__PURE__ */ React19.createElement(import_editor_panels.Panel, null, /* @__PURE__ */ React19.createElement(import_editor_panels.PanelHeader, null, /* @__PURE__ */ React19.createElement(import_ui16.Stack, { p: 1, pl: 2, width: "100%", direction: "row", alignItems: "center" }, /* @__PURE__ */ React19.createElement(import_ui16.Stack, { width: "100%", direction: "row", gap: 1 }, /* @__PURE__ */ React19.createElement(import_editor_panels.PanelHeaderTitle, { sx: { display: "flex", alignItems: "center", gap: 0.5 } }, /* @__PURE__ */ React19.createElement(FlippedColorSwatchIcon, { fontSize: "inherit" }), (0, import_i18n14.__)("Class Manager", "elementor")), /* @__PURE__ */ React19.createElement(TotalCssClassCounter, null)), /* @__PURE__ */ React19.createElement(
2307
+ ClassPanelCloseButton,
2308
+ {
2309
+ disabled: isPublishing,
2310
+ onClose: () => {
2311
+ if (isDirty2) {
2312
+ openSaveChangesDialog();
2313
+ return;
2314
+ }
2315
+ void closeStandalonePanel();
2316
+ }
2317
+ }
2318
+ ))), /* @__PURE__ */ React19.createElement(
2319
+ import_editor_panels.PanelBody,
2320
+ {
2321
+ sx: {
2322
+ display: "flex",
2323
+ flexDirection: "column",
2324
+ height: "100%"
2325
+ }
2326
+ },
2327
+ searchFiltersBlock,
2328
+ /* @__PURE__ */ React19.createElement(import_ui16.Divider, null),
2329
+ listArea
2330
+ ), saveFooter);
2331
+ const core = /* @__PURE__ */ React19.createElement(React19.Fragment, null, /* @__PURE__ */ React19.createElement(import_ui16.ErrorBoundary, { fallback: /* @__PURE__ */ React19.createElement(ErrorBoundaryFallback, null) }, /* @__PURE__ */ React19.createElement(SearchAndFilterProvider, null, classManagerLayout)), /* @__PURE__ */ React19.createElement(ClassManagerIntroduction, null), dialogs);
2332
+ return embedded ? core : /* @__PURE__ */ React19.createElement(import_editor_ui9.ThemeProvider, null, core);
2314
2333
  }
2315
- var CloseButton = ({ onClose, ...props }) => /* @__PURE__ */ React19.createElement(import_ui16.IconButton, { size: "small", color: "secondary", onClick: onClose, "aria-label": "Close", ...props }, /* @__PURE__ */ React19.createElement(import_icons11.XIcon, { fontSize: "small" }));
2316
- var ErrorBoundaryFallback = () => /* @__PURE__ */ React19.createElement(import_ui16.Box, { role: "alert", sx: { minHeight: "100%", p: 2 } }, /* @__PURE__ */ React19.createElement(import_ui16.Alert, { severity: "error", sx: { mb: 2, maxWidth: 400, textAlign: "center" } }, /* @__PURE__ */ React19.createElement("strong", null, (0, import_i18n15.__)("Something went wrong", "elementor"))));
2334
+ var ClassPanelCloseButton = ({ onClose, sx, ...props }) => /* @__PURE__ */ React19.createElement(
2335
+ import_ui16.IconButton,
2336
+ {
2337
+ size: "small",
2338
+ color: "secondary",
2339
+ onClick: onClose,
2340
+ "aria-label": "Close",
2341
+ sx: { marginLeft: "auto", ...sx },
2342
+ ...props
2343
+ },
2344
+ /* @__PURE__ */ React19.createElement(import_icons11.XIcon, { fontSize: "small" })
2345
+ );
2346
+ var ErrorBoundaryFallback = () => /* @__PURE__ */ React19.createElement(import_ui16.Box, { role: "alert", sx: { minHeight: "100%", p: 2 } }, /* @__PURE__ */ React19.createElement(import_ui16.Alert, { severity: "error", sx: { mb: 2, maxWidth: 400, textAlign: "center" } }, /* @__PURE__ */ React19.createElement("strong", null, (0, import_i18n14.__)("Something went wrong", "elementor"))));
2317
2347
  var usePreventUnload = () => {
2318
2348
  const isDirty2 = useDirtyState();
2319
2349
  (0, import_react10.useEffect)(() => {
@@ -2329,8 +2359,8 @@ var usePreventUnload = () => {
2329
2359
  }, [isDirty2]);
2330
2360
  };
2331
2361
  var usePublish = () => {
2332
- return (0, import_query3.useMutation)({
2333
- mutationFn: () => saveGlobalClasses({ context: "frontend" }),
2362
+ return (0, import_query2.useMutation)({
2363
+ mutationFn: () => saveGlobalClasses2({ context: "frontend" }),
2334
2364
  onSuccess: async () => {
2335
2365
  (0, import_editor_documents3.setDocumentModifiedStatus)(false);
2336
2366
  if (hasDeletedItems()) {
@@ -2352,7 +2382,7 @@ var TotalCssClassCounter = () => {
2352
2382
  };
2353
2383
  var StopSyncConfirmationDialog = ({ open, onClose, onConfirm }) => {
2354
2384
  const [, suppressStopSyncMessage] = (0, import_editor_current_user2.useSuppressedMessage)(STOP_SYNC_MESSAGE_KEY);
2355
- return /* @__PURE__ */ React19.createElement(import_editor_ui9.ConfirmationDialog, { open, onClose }, /* @__PURE__ */ React19.createElement(import_editor_ui9.ConfirmationDialog.Title, { icon: FlippedColorSwatchIcon, iconColor: "primary" }, (0, import_i18n15.__)("Un-sync typography class", "elementor")), /* @__PURE__ */ React19.createElement(import_editor_ui9.ConfirmationDialog.Content, null, /* @__PURE__ */ React19.createElement(import_editor_ui9.ConfirmationDialog.ContentText, null, (0, import_i18n15.__)("You're about to stop syncing a typography class to Global Fonts.", "elementor")), /* @__PURE__ */ React19.createElement(import_editor_ui9.ConfirmationDialog.ContentText, { sx: { mt: 1 } }, (0, import_i18n15.__)(
2385
+ return /* @__PURE__ */ React19.createElement(import_editor_ui9.ConfirmationDialog, { open, onClose }, /* @__PURE__ */ React19.createElement(import_editor_ui9.ConfirmationDialog.Title, { icon: FlippedColorSwatchIcon, iconColor: "primary" }, (0, import_i18n14.__)("Un-sync typography class", "elementor")), /* @__PURE__ */ React19.createElement(import_editor_ui9.ConfirmationDialog.Content, null, /* @__PURE__ */ React19.createElement(import_editor_ui9.ConfirmationDialog.ContentText, null, (0, import_i18n14.__)("You're about to stop syncing a typography class to Global Fonts.", "elementor")), /* @__PURE__ */ React19.createElement(import_editor_ui9.ConfirmationDialog.ContentText, { sx: { mt: 1 } }, (0, import_i18n14.__)(
2356
2386
  "Note that if it's being used anywhere, the affected elements will inherit the default typography.",
2357
2387
  "elementor"
2358
2388
  ))), /* @__PURE__ */ React19.createElement(
@@ -2360,15 +2390,313 @@ var StopSyncConfirmationDialog = ({ open, onClose, onConfirm }) => {
2360
2390
  {
2361
2391
  onClose,
2362
2392
  onConfirm,
2363
- cancelLabel: (0, import_i18n15.__)("Cancel", "elementor"),
2364
- confirmLabel: (0, import_i18n15.__)("Got it", "elementor"),
2393
+ cancelLabel: (0, import_i18n14.__)("Cancel", "elementor"),
2394
+ confirmLabel: (0, import_i18n14.__)("Got it", "elementor"),
2365
2395
  color: "primary",
2366
2396
  onSuppressMessage: suppressStopSyncMessage,
2367
- suppressLabel: (0, import_i18n15.__)("Don't show again", "elementor")
2397
+ suppressLabel: (0, import_i18n14.__)("Don't show again", "elementor")
2368
2398
  }
2369
2399
  ));
2370
2400
  };
2371
2401
 
2402
+ // src/mcp-integration/classes-resource.ts
2403
+ var import_store26 = require("@elementor/store");
2404
+
2405
+ // src/global-classes-styles-provider.ts
2406
+ var import_editor_styles2 = require("@elementor/editor-styles");
2407
+ var import_editor_styles_repository2 = require("@elementor/editor-styles-repository");
2408
+ var import_store24 = require("@elementor/store");
2409
+ var import_i18n15 = require("@wordpress/i18n");
2410
+
2411
+ // src/capabilities.ts
2412
+ var import_editor_v1_adapters2 = require("@elementor/editor-v1-adapters");
2413
+ var EXPERIMENT_KEY = "global_classes_should_enforce_capabilities";
2414
+ var UPDATE_CLASS_CAPABILITY_KEY = "elementor_global_classes_update_class";
2415
+ var getCapabilities = () => {
2416
+ const shouldEnforceCapabilities = (0, import_editor_v1_adapters2.isExperimentActive)(EXPERIMENT_KEY);
2417
+ if (shouldEnforceCapabilities) {
2418
+ return {
2419
+ update: UPDATE_CLASS_CAPABILITY_KEY,
2420
+ create: UPDATE_CLASS_CAPABILITY_KEY,
2421
+ delete: UPDATE_CLASS_CAPABILITY_KEY,
2422
+ updateProps: UPDATE_CLASS_CAPABILITY_KEY
2423
+ };
2424
+ }
2425
+ };
2426
+
2427
+ // src/load-existing-classes.ts
2428
+ var import_store22 = require("@elementor/store");
2429
+
2430
+ // src/load-document-classes.ts
2431
+ var import_editor_documents4 = require("@elementor/editor-documents");
2432
+ var import_store20 = require("@elementor/store");
2433
+
2434
+ // src/utils/create-labels-for-classes.ts
2435
+ function createLabelsForClasses(entries) {
2436
+ return Object.fromEntries(entries.map((e) => [e.id, e.label]));
2437
+ }
2438
+
2439
+ // src/load-document-classes.ts
2440
+ function styleDefinitionsMapWithoutNull(map) {
2441
+ return Object.fromEntries(
2442
+ Object.entries(map).filter(
2443
+ (entry) => entry[1] !== null
2444
+ )
2445
+ );
2446
+ }
2447
+ function resetGlobalClassesState(globalOrder, classLabels) {
2448
+ (0, import_store20.__dispatch)(
2449
+ slice.actions.load({
2450
+ preview: { items: {}, order: globalOrder },
2451
+ frontend: { items: {}, order: globalOrder },
2452
+ classLabels
2453
+ })
2454
+ );
2455
+ }
2456
+ async function loadCurrentDocumentClasses() {
2457
+ const previewIndexRes = await apiClient.all("preview");
2458
+ const previewIndex = previewIndexRes.data.data;
2459
+ const classLabels = createLabelsForClasses(previewIndex);
2460
+ const globalOrder = previewIndex.map((e) => e.id);
2461
+ resetGlobalClassesState(globalOrder, classLabels);
2462
+ const postId = (0, import_editor_documents4.getCurrentDocument)()?.id;
2463
+ if (!postId) {
2464
+ return;
2465
+ }
2466
+ const [previewPostRes, frontendPostRes] = await Promise.all([
2467
+ apiClient.getStylesForPost(postId, "preview"),
2468
+ apiClient.getStylesForPost(postId, "frontend")
2469
+ ]);
2470
+ const previewItems = styleDefinitionsMapWithoutNull(previewPostRes.data.data);
2471
+ const frontendItems = styleDefinitionsMapWithoutNull(frontendPostRes.data.data);
2472
+ (0, import_store20.__dispatch)(
2473
+ slice.actions.load({
2474
+ preview: { items: previewItems, order: globalOrder },
2475
+ frontend: { items: frontendItems, order: globalOrder },
2476
+ classLabels
2477
+ })
2478
+ );
2479
+ }
2480
+ async function addDocumentClasses(documentId) {
2481
+ const [previewPostRes, frontendPostRes] = await Promise.all([
2482
+ apiClient.getStylesForPost(documentId, "preview"),
2483
+ apiClient.getStylesForPost(documentId, "frontend")
2484
+ ]);
2485
+ const previewItems = styleDefinitionsMapWithoutNull(previewPostRes.data.data);
2486
+ const frontendItems = styleDefinitionsMapWithoutNull(frontendPostRes.data.data);
2487
+ (0, import_store20.__dispatch)(
2488
+ slice.actions.mergeExistingClasses({
2489
+ preview: previewItems,
2490
+ frontend: frontendItems
2491
+ })
2492
+ );
2493
+ }
2494
+
2495
+ // src/load-existing-classes.ts
2496
+ var pendingLoad = null;
2497
+ var pendingIds = /* @__PURE__ */ new Set();
2498
+ async function loadExistingClasses(classIds) {
2499
+ const existingClasses = selectGlobalClasses((0, import_store22.__getState)());
2500
+ const missingIds = classIds.filter((id2) => !(id2 in existingClasses));
2501
+ if (missingIds.length === 0) {
2502
+ return;
2503
+ }
2504
+ missingIds.forEach((id2) => pendingIds.add(id2));
2505
+ if (pendingLoad) {
2506
+ await pendingLoad;
2507
+ return loadExistingClasses(classIds);
2508
+ }
2509
+ pendingLoad = fetchAndMergeClasses();
2510
+ try {
2511
+ await pendingLoad;
2512
+ } finally {
2513
+ pendingLoad = null;
2514
+ }
2515
+ }
2516
+ async function fetchAndMergeClasses() {
2517
+ const idsToFetch = Array.from(pendingIds);
2518
+ pendingIds.clear();
2519
+ if (idsToFetch.length === 0) {
2520
+ return;
2521
+ }
2522
+ const previewResponse = await apiClient.getStylesByIds(idsToFetch, "preview");
2523
+ const frontendResponse = await apiClient.getStylesByIds(idsToFetch, "frontend");
2524
+ const previewItems = styleDefinitionsMapWithoutNull(previewResponse.data.data);
2525
+ const frontendItems = styleDefinitionsMapWithoutNull(frontendResponse.data.data);
2526
+ (0, import_store22.__dispatch)(slice.actions.mergeExistingClasses({ preview: previewItems, frontend: frontendItems }));
2527
+ }
2528
+
2529
+ // src/global-classes-styles-provider.ts
2530
+ var MAX_CLASSES = 5e3;
2531
+ var GLOBAL_CLASSES_PROVIDER_KEY = "global-classes";
2532
+ var PREGENERATED_LINK_PATTERN = /^global-([0-9]+-)?(preview|frontend)-[a-zA-Z_-]+-css$/;
2533
+ var globalClassesStylesProvider = (0, import_editor_styles_repository2.createStylesProvider)({
2534
+ key: GLOBAL_CLASSES_PROVIDER_KEY,
2535
+ priority: 30,
2536
+ limit: MAX_CLASSES,
2537
+ isPregeneratedLink: ({ id: id2 }) => PREGENERATED_LINK_PATTERN.test(id2),
2538
+ labels: {
2539
+ singular: (0, import_i18n15.__)("class", "elementor"),
2540
+ plural: (0, import_i18n15.__)("classes", "elementor")
2541
+ },
2542
+ subscribe: (cb) => subscribeWithStates(cb),
2543
+ capabilities: getCapabilities(),
2544
+ actions: {
2545
+ all: () => selectOrderedClasses((0, import_store24.__getState)()),
2546
+ get: (id2) => {
2547
+ const state = (0, import_store24.__getState)();
2548
+ const isFetched = selectIsClassFetched(state, id2);
2549
+ const style = selectClass(state, id2);
2550
+ if (isFetched || style) {
2551
+ return style;
2552
+ }
2553
+ loadExistingClasses([id2]);
2554
+ const label = selectClassLabels(state)[id2] ?? id2;
2555
+ return placeholderDefinition(id2, label);
2556
+ },
2557
+ resolveCssName: (id2) => {
2558
+ const state = (0, import_store24.__getState)();
2559
+ const loaded = selectClass(state, id2);
2560
+ if (loaded) {
2561
+ return loaded.label;
2562
+ }
2563
+ const fromIndex = selectClassLabels(state)[id2];
2564
+ return fromIndex ?? id2;
2565
+ },
2566
+ create: (label, variants = [], id2) => {
2567
+ const existingClasses = Object.entries(selectClassLabels((0, import_store24.__getState)()));
2568
+ const existingLabels = existingClasses.map(([, classLabel]) => classLabel);
2569
+ if (existingLabels.includes(label)) {
2570
+ throw new GlobalClassLabelAlreadyExistsError({ context: { label } });
2571
+ }
2572
+ const existingIds = existingClasses.map(([existingId]) => existingId);
2573
+ if (!id2) {
2574
+ id2 = (0, import_editor_styles2.generateId)("g-", existingIds);
2575
+ }
2576
+ (0, import_store24.__dispatch)(
2577
+ slice.actions.add({
2578
+ id: id2,
2579
+ type: "class",
2580
+ label,
2581
+ variants
2582
+ })
2583
+ );
2584
+ return id2;
2585
+ },
2586
+ update: (payload) => {
2587
+ (0, import_store24.__dispatch)(
2588
+ slice.actions.update({
2589
+ style: payload
2590
+ })
2591
+ );
2592
+ },
2593
+ delete: (id2) => {
2594
+ (0, import_store24.__dispatch)(slice.actions.delete(id2));
2595
+ },
2596
+ updateProps: (args) => {
2597
+ (0, import_store24.__dispatch)(
2598
+ slice.actions.updateProps({
2599
+ id: args.id,
2600
+ meta: args.meta,
2601
+ props: args.props,
2602
+ mode: args.mode
2603
+ })
2604
+ );
2605
+ },
2606
+ updateCustomCss: (args) => {
2607
+ (0, import_store24.__dispatch)(
2608
+ slice.actions.updateProps({
2609
+ id: args.id,
2610
+ meta: args.meta,
2611
+ custom_css: args.custom_css,
2612
+ props: {}
2613
+ })
2614
+ );
2615
+ },
2616
+ tracking: (data) => {
2617
+ trackGlobalClasses(data).catch((error) => {
2618
+ throw new GlobalClassTrackingError({ cause: error });
2619
+ });
2620
+ }
2621
+ }
2622
+ });
2623
+ var subscribeWithStates = (cb) => {
2624
+ let previousState = selectData((0, import_store24.__getState)());
2625
+ return (0, import_store24.__subscribeWithSelector)(
2626
+ (state) => selectData(state),
2627
+ (currentState) => {
2628
+ cb(previousState.items, currentState.items);
2629
+ previousState = currentState;
2630
+ }
2631
+ );
2632
+ };
2633
+
2634
+ // src/mcp-integration/classes-resource.ts
2635
+ var GLOBAL_CLASSES_URI = "elementor://global-classes";
2636
+ var STORAGE_KEY = "elementor-global-classes";
2637
+ var updateLocalStorageCache = () => {
2638
+ const classes = selectOrderedClasses((0, import_store26.__getState)());
2639
+ localStorage.setItem(STORAGE_KEY, JSON.stringify(classes));
2640
+ };
2641
+ var initClassesResource = (classesMcpEntry, canvasMcpEntry) => {
2642
+ [canvasMcpEntry, classesMcpEntry].forEach((entry) => {
2643
+ const { sendResourceUpdated, resource, waitForReady } = entry;
2644
+ resource(
2645
+ "global-classes",
2646
+ GLOBAL_CLASSES_URI,
2647
+ {
2648
+ description: "Global classes list."
2649
+ },
2650
+ async () => {
2651
+ return {
2652
+ contents: [{ uri: GLOBAL_CLASSES_URI, text: localStorage[STORAGE_KEY] ?? "[]" }]
2653
+ };
2654
+ }
2655
+ );
2656
+ waitForReady().then(() => {
2657
+ updateLocalStorageCache();
2658
+ globalClassesStylesProvider.subscribe(() => {
2659
+ updateLocalStorageCache();
2660
+ sendResourceUpdated({ uri: GLOBAL_CLASSES_URI });
2661
+ });
2662
+ });
2663
+ });
2664
+ };
2665
+
2666
+ // src/init.ts
2667
+ var import_editor = require("@elementor/editor");
2668
+ var import_editor_editing_panel2 = require("@elementor/editor-editing-panel");
2669
+ var import_editor_mcp = require("@elementor/editor-mcp");
2670
+ var import_editor_panels2 = require("@elementor/editor-panels");
2671
+ var import_editor_styles_repository5 = require("@elementor/editor-styles-repository");
2672
+ var import_editor_v1_adapters8 = require("@elementor/editor-v1-adapters");
2673
+ var import_store32 = require("@elementor/store");
2674
+
2675
+ // src/components/class-manager/class-manager-button.tsx
2676
+ var React20 = __toESM(require("react"));
2677
+ var import_editor_documents5 = require("@elementor/editor-documents");
2678
+ var import_editor_styles_repository3 = require("@elementor/editor-styles-repository");
2679
+ var import_editor_ui10 = require("@elementor/editor-ui");
2680
+ var import_editor_v1_adapters3 = require("@elementor/editor-v1-adapters");
2681
+ var import_ui17 = require("@elementor/ui");
2682
+ var import_i18n16 = require("@wordpress/i18n");
2683
+
2684
+ // src/hooks/use-prefetch-css-class-usage.ts
2685
+ var import_query3 = require("@elementor/query");
2686
+ function usePrefetchCssClassUsage() {
2687
+ const queryClient = (0, import_query3.useQueryClient)();
2688
+ const prefetchClassesUsage = () => queryClient.prefetchQuery({
2689
+ queryKey: [QUERY_KEY],
2690
+ queryFn: fetchCssClassUsage
2691
+ });
2692
+ return { prefetchClassesUsage };
2693
+ }
2694
+ var PrefetchCssClassUsage = () => {
2695
+ const { prefetchClassesUsage } = usePrefetchCssClassUsage();
2696
+ prefetchClassesUsage();
2697
+ return null;
2698
+ };
2699
+
2372
2700
  // src/components/class-manager/class-manager-button.tsx
2373
2701
  var trackGlobalClassesButton = () => {
2374
2702
  trackGlobalClasses({
@@ -2377,9 +2705,9 @@ var trackGlobalClassesButton = () => {
2377
2705
  });
2378
2706
  };
2379
2707
  var ClassManagerButton = () => {
2380
- const document = (0, import_editor_documents4.__useActiveDocument)();
2708
+ const document = (0, import_editor_documents5.__useActiveDocument)();
2381
2709
  const { open: openPanel } = usePanelActions();
2382
- const { save: saveDocument } = (0, import_editor_documents4.__useActiveDocumentActions)();
2710
+ const { save: saveDocument } = (0, import_editor_documents5.__useActiveDocumentActions)();
2383
2711
  const { open: openSaveChangesDialog, close: closeSaveChangesDialog, isOpen: isSaveChangesDialogOpen } = (0, import_editor_ui10.useDialog)();
2384
2712
  const { prefetchClassesUsage } = usePrefetchCssClassUsage();
2385
2713
  const { userCan } = (0, import_editor_styles_repository3.useUserStylesCapability)();
@@ -2387,17 +2715,24 @@ var ClassManagerButton = () => {
2387
2715
  if (!isUserAllowedToUpdateClass) {
2388
2716
  return null;
2389
2717
  }
2718
+ const toggleClassesManagerPanel = () => {
2719
+ if ((0, import_editor_v1_adapters3.isExperimentActive)("e_editor_design_system_panel")) {
2720
+ window.dispatchEvent(
2721
+ new CustomEvent("elementor/toggle-design-system", {
2722
+ detail: { tab: "classes" }
2723
+ })
2724
+ );
2725
+ } else {
2726
+ openPanel();
2727
+ }
2728
+ };
2390
2729
  const handleOpenPanel = () => {
2391
2730
  if (document?.isDirty) {
2392
2731
  openSaveChangesDialog();
2393
2732
  return;
2394
2733
  }
2395
- openPanel();
2734
+ toggleClassesManagerPanel();
2396
2735
  trackGlobalClassesButton();
2397
- trackGlobalClasses({
2398
- event: "classManagerOpened",
2399
- source: "style-panel"
2400
- });
2401
2736
  prefetchClassesUsage();
2402
2737
  };
2403
2738
  return /* @__PURE__ */ React20.createElement(React20.Fragment, null, /* @__PURE__ */ React20.createElement(import_ui17.Tooltip, { title: (0, import_i18n16.__)("Class Manager", "elementor"), placement: "top" }, /* @__PURE__ */ React20.createElement(import_ui17.IconButton, { size: "tiny", onClick: handleOpenPanel, sx: { marginInlineEnd: -0.75 } }, /* @__PURE__ */ React20.createElement(FlippedColorSwatchIcon, { fontSize: "tiny" }))), isSaveChangesDialogOpen && /* @__PURE__ */ React20.createElement(import_editor_ui10.SaveChangesDialog, null, /* @__PURE__ */ React20.createElement(import_editor_ui10.SaveChangesDialog.Title, null, (0, import_i18n16.__)("You have unsaved changes", "elementor")), /* @__PURE__ */ React20.createElement(import_editor_ui10.SaveChangesDialog.Content, null, /* @__PURE__ */ React20.createElement(import_editor_ui10.SaveChangesDialog.ContentText, { sx: { mb: 2 } }, (0, import_i18n16.__)(
@@ -2416,7 +2751,7 @@ var ClassManagerButton = () => {
2416
2751
  action: async () => {
2417
2752
  await saveDocument();
2418
2753
  closeSaveChangesDialog();
2419
- openPanel();
2754
+ toggleClassesManagerPanel();
2420
2755
  trackGlobalClassesButton();
2421
2756
  prefetchClassesUsage();
2422
2757
  }
@@ -2478,58 +2813,34 @@ function createClassName(prefix) {
2478
2813
 
2479
2814
  // src/components/global-styles-import-listener.tsx
2480
2815
  var import_react11 = require("react");
2481
- var import_store22 = require("@elementor/store");
2816
+ var import_editor_canvas = require("@elementor/editor-canvas");
2817
+ var import_store28 = require("@elementor/store");
2482
2818
  function GlobalStylesImportListener() {
2483
- const dispatch5 = (0, import_store22.__useDispatch)();
2819
+ const dispatch7 = (0, import_store28.__useDispatch)();
2484
2820
  (0, import_react11.useEffect)(() => {
2485
2821
  const handleGlobalStylesImported = (event) => {
2486
2822
  const importedClasses = event.detail?.global_classes;
2487
2823
  if (importedClasses?.items && importedClasses?.order) {
2488
- dispatch5(
2489
- slice.actions.load({
2490
- preview: {
2491
- items: importedClasses.items,
2492
- order: importedClasses.order
2493
- },
2494
- frontend: {
2495
- items: importedClasses.items,
2496
- order: importedClasses.order
2497
- }
2824
+ const { items } = importedClasses;
2825
+ dispatch7(
2826
+ slice.actions.mergeExistingClasses({
2827
+ preview: items,
2828
+ frontend: items
2498
2829
  })
2499
2830
  );
2500
2831
  }
2501
- Promise.all([apiClient.all("preview"), apiClient.all("frontend")]).then(([previewRes, frontendRes]) => {
2502
- const { data: previewData } = previewRes;
2503
- const { data: frontendData } = frontendRes;
2504
- dispatch5(
2505
- slice.actions.load({
2506
- preview: {
2507
- items: previewData.data,
2508
- order: previewData.meta.order
2509
- },
2510
- frontend: {
2511
- items: frontendData.data,
2512
- order: frontendData.meta.order
2513
- }
2514
- })
2515
- );
2516
- }).catch(() => {
2517
- });
2518
2832
  };
2519
- window.addEventListener("elementor/global-styles/imported", handleGlobalStylesImported);
2833
+ window.addEventListener(import_editor_canvas.GLOBAL_STYLES_IMPORTED_EVENT, handleGlobalStylesImported);
2520
2834
  return () => {
2521
- window.removeEventListener(
2522
- "elementor/global-styles/imported",
2523
- handleGlobalStylesImported
2524
- );
2835
+ window.removeEventListener(import_editor_canvas.GLOBAL_STYLES_IMPORTED_EVENT, handleGlobalStylesImported);
2525
2836
  };
2526
- }, [dispatch5]);
2837
+ }, [dispatch7]);
2527
2838
  return null;
2528
2839
  }
2529
2840
 
2530
2841
  // src/components/open-panel-from-url.tsx
2531
2842
  var import_react12 = require("react");
2532
- var import_editor_v1_adapters3 = require("@elementor/editor-v1-adapters");
2843
+ var import_editor_v1_adapters4 = require("@elementor/editor-v1-adapters");
2533
2844
  var ACTIVE_PANEL_PARAM = "active-panel";
2534
2845
  var PANEL_ID = "global-classes-manager";
2535
2846
  var DEFAULT_PANEL_ROUTE = "panel/elements";
@@ -2542,7 +2853,7 @@ function OpenPanelFromUrl() {
2542
2853
  if (activePanel !== PANEL_ID) {
2543
2854
  return;
2544
2855
  }
2545
- const cleanup = (0, import_editor_v1_adapters3.__privateListenTo)((0, import_editor_v1_adapters3.routeOpenEvent)(DEFAULT_PANEL_ROUTE), () => {
2856
+ const cleanup = (0, import_editor_v1_adapters4.__privateListenTo)((0, import_editor_v1_adapters4.routeOpenEvent)(DEFAULT_PANEL_ROUTE), () => {
2546
2857
  if (hasOpened.current) {
2547
2858
  return;
2548
2859
  }
@@ -2558,29 +2869,14 @@ function OpenPanelFromUrl() {
2558
2869
 
2559
2870
  // src/components/populate-store.tsx
2560
2871
  var import_react13 = require("react");
2561
- var import_store24 = require("@elementor/store");
2872
+ var import_editor_v1_adapters5 = require("@elementor/editor-v1-adapters");
2562
2873
  function PopulateStore() {
2563
- const dispatch5 = (0, import_store24.__useDispatch)();
2564
2874
  (0, import_react13.useEffect)(() => {
2565
- Promise.all([apiClient.all("preview"), apiClient.all("frontend")]).then(
2566
- ([previewRes, frontendRes]) => {
2567
- const { data: previewData } = previewRes;
2568
- const { data: frontendData } = frontendRes;
2569
- dispatch5(
2570
- slice.actions.load({
2571
- preview: {
2572
- items: previewData.data,
2573
- order: previewData.meta.order
2574
- },
2575
- frontend: {
2576
- items: frontendData.data,
2577
- order: frontendData.meta.order
2578
- }
2579
- })
2580
- );
2581
- }
2582
- );
2583
- }, [dispatch5]);
2875
+ loadCurrentDocumentClasses();
2876
+ (0, import_editor_v1_adapters5.registerDataHook)("after", "editor/documents/attach-preview", async () => {
2877
+ await loadCurrentDocumentClasses();
2878
+ });
2879
+ }, []);
2584
2880
  return null;
2585
2881
  }
2586
2882
 
@@ -2660,7 +2956,7 @@ function initMcpApplyUnapplyGlobalClasses(server) {
2660
2956
  - Make sure you have the correct class ID that you want to unapply.
2661
2957
 
2662
2958
  <note>
2663
- If 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
2959
+ If the user want to unapply a class by it's name and not ID, retrieve the id from the list, available at uri elementor://global-classes
2664
2960
  </note>
2665
2961
  `,
2666
2962
  handler: async (params) => {
@@ -2684,7 +2980,7 @@ function initMcpApplyGetGlobalClassUsages(reg) {
2684
2980
  usages: import_schema2.z.array(
2685
2981
  import_schema2.z.object({
2686
2982
  classId: import_schema2.z.string().describe(
2687
- 'The ID of the class, not visible to the user. To retreive the name of the class, use the "list-global-classes" tool'
2983
+ 'The ID of the class, not visible to the user. To retrieve the name of the class, use the "list-global-classes" tool'
2688
2984
  ),
2689
2985
  usages: import_schema2.z.array(
2690
2986
  import_schema2.z.object({
@@ -2703,13 +2999,13 @@ function initMcpApplyGetGlobalClassUsages(reg) {
2703
2999
  intelligencePriority: 0.6,
2704
3000
  speedPriority: 0.8
2705
3001
  },
2706
- description: `Retreive the usages of global-classes ACCROSS PAGES designed by Elementor editor.
3002
+ description: `Retrieve the usages of global-classes ACROSS PAGES designed by Elementor editor.
2707
3003
 
2708
- ## Prequisites: CRITICAL
3004
+ ## Prerequisites: CRITICAL
2709
3005
  - The list of global classes and their applid values is available at resource uri elementor://global-classes
2710
3006
 
2711
3007
  ## When to use this tool:
2712
- - When a user requests to see where a specific global class is being used accross the site.
3008
+ - When a user requests to see where a specific global class is being used across the site.
2713
3009
  - When you need to manage or clean up unused global classes.
2714
3010
  - Before deleting a global class, to ensure it is not in use in any other pages.
2715
3011
 
@@ -2748,7 +3044,7 @@ function initMcpApplyGetGlobalClassUsages(reg) {
2748
3044
  }
2749
3045
 
2750
3046
  // src/mcp-integration/mcp-manage-global-classes.ts
2751
- var import_editor_canvas = require("@elementor/editor-canvas");
3047
+ var import_editor_canvas2 = require("@elementor/editor-canvas");
2752
3048
  var import_editor_props = require("@elementor/editor-props");
2753
3049
  var import_editor_styles3 = require("@elementor/editor-styles");
2754
3050
  var import_schema3 = require("@elementor/schema");
@@ -2908,8 +3204,8 @@ var initManageGlobalClasses = (reg) => {
2908
3204
  name: "manage-global-classes",
2909
3205
  requiredResources: [
2910
3206
  { uri: GLOBAL_CLASSES_URI, description: "Global classes list" },
2911
- { uri: import_editor_canvas.STYLE_SCHEMA_URI, description: "Style schema resources" },
2912
- { uri: import_editor_canvas.BREAKPOINTS_SCHEMA_URI, description: "Breakpoints list" }
3207
+ { uri: import_editor_canvas2.STYLE_SCHEMA_URI, description: "Style schema resources" },
3208
+ { uri: import_editor_canvas2.BREAKPOINTS_SCHEMA_URI, description: "Breakpoints list" }
2913
3209
  ],
2914
3210
  modelPreferences: {
2915
3211
  intelligencePriority: 0.85,
@@ -2949,7 +3245,7 @@ async function attemptCreate(opts) {
2949
3245
  }
2950
3246
  ]);
2951
3247
  try {
2952
- await saveGlobalClasses({ context: "frontend" });
3248
+ await saveGlobalClasses2({ context: "frontend" });
2953
3249
  return newClassId;
2954
3250
  } catch {
2955
3251
  deleteClass2(newClassId);
@@ -2975,7 +3271,7 @@ async function attemptUpdate(opts) {
2975
3271
  state
2976
3272
  }
2977
3273
  });
2978
- await saveGlobalClasses({ context: "frontend" });
3274
+ await saveGlobalClasses2({ context: "frontend" });
2979
3275
  return true;
2980
3276
  } catch {
2981
3277
  snapshot.forEach((style) => {
@@ -2984,7 +3280,7 @@ async function attemptUpdate(opts) {
2984
3280
  variants: style.variants
2985
3281
  });
2986
3282
  });
2987
- await saveGlobalClasses({ context: "frontend" });
3283
+ await saveGlobalClasses2({ context: "frontend" });
2988
3284
  return false;
2989
3285
  }
2990
3286
  }
@@ -3004,7 +3300,7 @@ async function attemptDelete(opts) {
3004
3300
  }
3005
3301
  try {
3006
3302
  deleteClass2(classId);
3007
- await saveGlobalClasses({ context: "frontend" });
3303
+ await saveGlobalClasses2({ context: "frontend" });
3008
3304
  return true;
3009
3305
  } catch {
3010
3306
  return false;
@@ -3031,13 +3327,13 @@ var initMcpIntegration = (reg, canvasMcpEntry) => {
3031
3327
 
3032
3328
  // src/sync-with-document.tsx
3033
3329
  var import_react14 = require("react");
3034
- var import_editor_v1_adapters5 = require("@elementor/editor-v1-adapters");
3330
+ var import_editor_v1_adapters7 = require("@elementor/editor-v1-adapters");
3035
3331
 
3036
3332
  // src/sync-with-document-save.ts
3037
3333
  var import_editor_current_user3 = require("@elementor/editor-current-user");
3038
- var import_editor_documents5 = require("@elementor/editor-documents");
3039
- var import_editor_v1_adapters4 = require("@elementor/editor-v1-adapters");
3040
- var import_store26 = require("@elementor/store");
3334
+ var import_editor_documents6 = require("@elementor/editor-documents");
3335
+ var import_editor_v1_adapters6 = require("@elementor/editor-v1-adapters");
3336
+ var import_store30 = require("@elementor/store");
3041
3337
  var pendingSave = null;
3042
3338
  function syncWithDocumentSave(panelActions) {
3043
3339
  const unsubscribe = syncDirtyState();
@@ -3046,11 +3342,11 @@ function syncWithDocumentSave(panelActions) {
3046
3342
  return unsubscribe;
3047
3343
  }
3048
3344
  function syncDirtyState() {
3049
- return (0, import_store26.__subscribeWithSelector)(selectIsDirty, () => {
3345
+ return (0, import_store30.__subscribeWithSelector)(selectIsDirty, () => {
3050
3346
  if (!isDirty()) {
3051
3347
  return;
3052
3348
  }
3053
- (0, import_editor_documents5.setDocumentModifiedStatus)(true);
3349
+ (0, import_editor_documents6.setDocumentModifiedStatus)(true);
3054
3350
  });
3055
3351
  }
3056
3352
  function triggerSave(panelActions, context2 = "preview") {
@@ -3062,7 +3358,7 @@ function triggerSave(panelActions, context2 = "preview") {
3062
3358
  if (pendingSave) {
3063
3359
  return pendingSave;
3064
3360
  }
3065
- const promise = saveGlobalClasses({
3361
+ const promise = saveGlobalClasses2({
3066
3362
  context: context2,
3067
3363
  onApprove: panelActions?.open
3068
3364
  });
@@ -3073,7 +3369,7 @@ function triggerSave(panelActions, context2 = "preview") {
3073
3369
  return promise;
3074
3370
  }
3075
3371
  function bindSaveAction(panelActions) {
3076
- (0, import_editor_v1_adapters4.registerDataHook)("dependency", "document/save/save", (args) => {
3372
+ (0, import_editor_v1_adapters6.registerDataHook)("dependency", "document/save/save", (args) => {
3077
3373
  triggerSave(panelActions, args.status === "publish" ? "frontend" : "preview");
3078
3374
  return true;
3079
3375
  });
@@ -3089,24 +3385,30 @@ function bindBeforeSaveTemplateAction() {
3089
3385
  }));
3090
3386
  }
3091
3387
  function isDirty() {
3092
- return selectIsDirty((0, import_store26.__getState)());
3388
+ return selectIsDirty((0, import_store30.__getState)());
3093
3389
  }
3094
3390
 
3095
3391
  // src/sync-with-document.tsx
3096
3392
  function SyncWithDocumentSave() {
3097
- const panelActions = usePanelActions();
3393
+ const { open: openClassPanel } = usePanelActions();
3098
3394
  (0, import_react14.useEffect)(() => {
3099
- (0, import_editor_v1_adapters5.__privateListenTo)((0, import_editor_v1_adapters5.v1ReadyEvent)(), () => {
3100
- syncWithDocumentSave(panelActions);
3395
+ const unsubscribe = (0, import_editor_v1_adapters7.__privateListenTo)((0, import_editor_v1_adapters7.v1ReadyEvent)(), () => {
3396
+ const open = (0, import_editor_v1_adapters7.isExperimentActive)("e_editor_design_system_panel") ? () => {
3397
+ window.dispatchEvent(new CustomEvent("elementor/open-global-classes-manager"));
3398
+ } : openClassPanel;
3399
+ syncWithDocumentSave({ open });
3101
3400
  });
3401
+ return unsubscribe;
3102
3402
  }, []);
3103
3403
  return null;
3104
3404
  }
3105
3405
 
3106
3406
  // src/init.ts
3107
3407
  function init() {
3108
- (0, import_store28.__registerSlice)(slice);
3109
- (0, import_editor_panels2.__registerPanel)(panel);
3408
+ (0, import_store32.__registerSlice)(slice);
3409
+ if (!(0, import_editor_v1_adapters8.isExperimentActive)("e_editor_design_system_panel")) {
3410
+ (0, import_editor_panels2.__registerPanel)(panel);
3411
+ }
3110
3412
  import_editor_styles_repository5.stylesRepository.register(globalClassesStylesProvider);
3111
3413
  (0, import_editor.injectIntoLogic)({
3112
3414
  id: "global-classes-populate-store",
@@ -3124,10 +3426,12 @@ function init() {
3124
3426
  id: "global-classes-prefetch-css-class-usage",
3125
3427
  component: PrefetchCssClassUsage
3126
3428
  });
3127
- (0, import_editor.injectIntoLogic)({
3128
- id: "global-classes-open-panel-from-url",
3129
- component: OpenPanelFromUrl
3130
- });
3429
+ if (!(0, import_editor_v1_adapters8.isExperimentActive)("e_editor_design_system_panel")) {
3430
+ (0, import_editor.injectIntoLogic)({
3431
+ id: "global-classes-open-panel-from-url",
3432
+ component: OpenPanelFromUrl
3433
+ });
3434
+ }
3131
3435
  (0, import_editor_editing_panel2.injectIntoCssClassConvert)({
3132
3436
  id: "global-classes-convert-from-local-class",
3133
3437
  component: ConvertLocalClassToGlobalClass
@@ -3147,7 +3451,11 @@ function init() {
3147
3451
  }
3148
3452
  // Annotate the CommonJS export names for ESM import in node:
3149
3453
  0 && (module.exports = {
3454
+ ClassManagerPanelEmbedded,
3150
3455
  GLOBAL_CLASSES_URI,
3151
- init
3456
+ addDocumentClasses,
3457
+ createLabelsForClasses,
3458
+ init,
3459
+ loadExistingClasses
3152
3460
  });
3153
3461
  //# sourceMappingURL=index.js.map