@elementor/editor-global-classes 0.22.2 → 3.32.0-20

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.
Files changed (35) hide show
  1. package/CHANGELOG.md +0 -21
  2. package/dist/index.js +1069 -327
  3. package/dist/index.js.map +1 -1
  4. package/dist/index.mjs +1049 -279
  5. package/dist/index.mjs.map +1 -1
  6. package/package.json +18 -18
  7. package/src/api.ts +14 -2
  8. package/src/components/class-manager/class-item.tsx +40 -65
  9. package/src/components/class-manager/class-manager-button.tsx +4 -0
  10. package/src/components/class-manager/class-manager-panel.tsx +82 -74
  11. package/src/components/class-manager/delete-confirmation-dialog.tsx +26 -6
  12. package/src/components/class-manager/global-classes-list.tsx +76 -57
  13. package/src/components/class-manager/not-found.tsx +138 -0
  14. package/src/components/convert-local-class-to-global-class.tsx +62 -0
  15. package/src/components/css-class-usage/components/css-class-usage-popover.tsx +169 -0
  16. package/src/components/css-class-usage/components/css-class-usage-trigger.tsx +116 -0
  17. package/src/components/css-class-usage/components/index.ts +2 -0
  18. package/src/components/css-class-usage/types.ts +19 -0
  19. package/src/components/css-class-usage/utils.ts +10 -0
  20. package/src/components/search-and-filter/components/filter/active-filters.tsx +54 -0
  21. package/src/components/search-and-filter/components/filter/clear-icon-button.tsx +31 -0
  22. package/src/components/search-and-filter/components/filter/css-class-filter.tsx +74 -0
  23. package/src/components/search-and-filter/components/filter/filter-list.tsx +77 -0
  24. package/src/components/{class-manager → search-and-filter/components/search}/class-manager-search.tsx +12 -11
  25. package/src/components/search-and-filter/context.tsx +78 -0
  26. package/src/global-classes-styles-provider.ts +13 -8
  27. package/src/hooks/use-css-class-usage-by-id.ts +15 -0
  28. package/src/hooks/use-css-class-usage.ts +13 -0
  29. package/src/hooks/use-empty-css-class.ts +12 -0
  30. package/src/hooks/use-filtered-css-class-usage.tsx +67 -0
  31. package/src/hooks/use-filters.ts +30 -0
  32. package/src/hooks/use-prefetch-css-class-usage.ts +16 -0
  33. package/src/init.ts +11 -1
  34. package/src/store.ts +23 -6
  35. package/src/components/class-manager/class-manager-class-not-found.tsx +0 -56
package/dist/index.js CHANGED
@@ -36,23 +36,22 @@ module.exports = __toCommonJS(index_exports);
36
36
 
37
37
  // src/init.ts
38
38
  var import_editor = require("@elementor/editor");
39
- var import_editor_editing_panel3 = require("@elementor/editor-editing-panel");
39
+ var import_editor_editing_panel = require("@elementor/editor-editing-panel");
40
40
  var import_editor_panels2 = require("@elementor/editor-panels");
41
- var import_editor_styles_repository4 = require("@elementor/editor-styles-repository");
42
- var import_editor_v1_adapters7 = require("@elementor/editor-v1-adapters");
43
- var import_store22 = require("@elementor/store");
41
+ var import_editor_styles_repository5 = require("@elementor/editor-styles-repository");
42
+ var import_editor_v1_adapters5 = require("@elementor/editor-v1-adapters");
43
+ var import_store24 = require("@elementor/store");
44
44
 
45
45
  // src/components/class-manager/class-manager-button.tsx
46
- var React11 = __toESM(require("react"));
47
- var import_editor_documents3 = require("@elementor/editor-documents");
46
+ var React18 = __toESM(require("react"));
47
+ var import_editor_documents5 = require("@elementor/editor-documents");
48
48
  var import_editor_styles_repository3 = require("@elementor/editor-styles-repository");
49
- var import_ui10 = require("@elementor/ui");
50
- var import_i18n9 = require("@wordpress/i18n");
49
+ var import_ui16 = require("@elementor/ui");
50
+ var import_i18n14 = require("@wordpress/i18n");
51
51
 
52
52
  // src/global-classes-styles-provider.ts
53
53
  var import_editor_styles2 = require("@elementor/editor-styles");
54
54
  var import_editor_styles_repository = require("@elementor/editor-styles-repository");
55
- var import_editor_v1_adapters2 = require("@elementor/editor-v1-adapters");
56
55
  var import_store2 = require("@elementor/store");
57
56
  var import_i18n = require("@wordpress/i18n");
58
57
 
@@ -209,13 +208,14 @@ var slice = (0, import_store.__createSlice)({
209
208
  }
210
209
  localHistory.next(state.data);
211
210
  const variant = (0, import_editor_styles.getVariantByMeta)(style, payload.meta);
211
+ let customCss = ("custom_css" in payload ? payload.custom_css : variant?.custom_css) ?? null;
212
+ customCss = customCss?.raw ? customCss : null;
212
213
  if (variant) {
213
214
  variant.props = (0, import_editor_props.mergeProps)(variant.props, payload.props);
214
- if (Object.keys(variant.props).length === 0) {
215
- style.variants = style.variants.filter((v) => v !== variant);
216
- }
215
+ variant.custom_css = customCss;
216
+ style.variants = getNonEmptyVariants(style);
217
217
  } else {
218
- style.variants.push({ meta: payload.meta, props: payload.props });
218
+ style.variants.push({ meta: payload.meta, props: payload.props, custom_css: customCss });
219
219
  }
220
220
  state.isDirty = true;
221
221
  },
@@ -256,6 +256,11 @@ var slice = (0, import_store.__createSlice)({
256
256
  }
257
257
  }
258
258
  });
259
+ var getNonEmptyVariants = (style) => {
260
+ return style.variants.filter(
261
+ ({ props, custom_css: customCss }) => Object.keys(props).length || customCss?.raw
262
+ );
263
+ };
259
264
  var selectData = (state) => state[SLICE_NAME].data;
260
265
  var selectFrontendInitialData = (state) => state[SLICE_NAME].initialData.frontend;
261
266
  var selectPreviewInitialData = (state) => state[SLICE_NAME].initialData.preview;
@@ -268,6 +273,10 @@ var selectOrderedClasses = (0, import_store.__createSelector)(
268
273
  (items, order) => order.map((id2) => items[id2])
269
274
  );
270
275
  var selectClass = (state, id2) => state[SLICE_NAME].data.items[id2] ?? null;
276
+ var selectEmptyCssClass = (0, import_store.__createSelector)(
277
+ selectData,
278
+ ({ items }) => Object.values(items).filter((cssClass) => cssClass.variants.length === 0)
279
+ );
271
280
 
272
281
  // src/global-classes-styles-provider.ts
273
282
  var MAX_CLASSES = 50;
@@ -286,12 +295,9 @@ var globalClassesStylesProvider = (0, import_editor_styles_repository.createStyl
286
295
  all: () => selectOrderedClasses((0, import_store2.__getState)()),
287
296
  get: (id2) => selectClass((0, import_store2.__getState)(), id2),
288
297
  resolveCssName: (id2) => {
289
- if (!(0, import_editor_v1_adapters2.isExperimentActive)("e_v_3_30")) {
290
- return id2;
291
- }
292
298
  return selectClass((0, import_store2.__getState)(), id2)?.label ?? id2;
293
299
  },
294
- create: (label) => {
300
+ create: (label, variants = []) => {
295
301
  const classes = selectGlobalClasses((0, import_store2.__getState)());
296
302
  const existingLabels = Object.values(classes).map((style) => style.label);
297
303
  if (existingLabels.includes(label)) {
@@ -304,7 +310,7 @@ var globalClassesStylesProvider = (0, import_editor_styles_repository.createStyl
304
310
  id: id2,
305
311
  type: "class",
306
312
  label,
307
- variants: []
313
+ variants
308
314
  })
309
315
  );
310
316
  return id2;
@@ -327,39 +333,31 @@ var globalClassesStylesProvider = (0, import_editor_styles_repository.createStyl
327
333
  props: args.props
328
334
  })
329
335
  );
336
+ },
337
+ updateCustomCss: (args) => {
338
+ (0, import_store2.__dispatch)(
339
+ slice.actions.updateProps({
340
+ id: args.id,
341
+ meta: args.meta,
342
+ custom_css: args.custom_css,
343
+ props: {}
344
+ })
345
+ );
330
346
  }
331
347
  }
332
348
  });
333
349
 
334
- // src/components/class-manager/class-manager-panel.tsx
335
- var import_react6 = require("react");
336
- var React10 = __toESM(require("react"));
337
- var import_editor_documents2 = require("@elementor/editor-documents");
338
- var import_editor_editing_panel2 = require("@elementor/editor-editing-panel");
339
- var import_editor_panels = require("@elementor/editor-panels");
340
- var import_editor_ui3 = require("@elementor/editor-ui");
341
- var import_editor_v1_adapters5 = require("@elementor/editor-v1-adapters");
342
- var import_icons7 = require("@elementor/icons");
350
+ // src/hooks/use-prefetch-css-class-usage.ts
343
351
  var import_query = require("@elementor/query");
344
- var import_store16 = require("@elementor/store");
345
- var import_ui9 = require("@elementor/ui");
346
- var import_utils2 = require("@elementor/utils");
347
- var import_i18n8 = require("@wordpress/i18n");
348
-
349
- // src/hooks/use-dirty-state.ts
350
- var import_store4 = require("@elementor/store");
351
- var useDirtyState = () => {
352
- return (0, import_store4.__useSelector)(selectIsDirty);
353
- };
354
-
355
- // src/save-global-classes.ts
356
- var import_store6 = require("@elementor/store");
357
352
 
358
353
  // src/api.ts
359
354
  var import_http_client = require("@elementor/http-client");
360
355
  var RESOURCE_URL = "/global-classes";
356
+ var BASE_URL = "elementor/v1";
357
+ var RESOURCE_USAGE_URL = `${RESOURCE_URL}/usage`;
361
358
  var apiClient = {
362
- all: (context2 = "preview") => (0, import_http_client.httpService)().get("elementor/v1" + RESOURCE_URL, {
359
+ usage: () => (0, import_http_client.httpService)().get(`${BASE_URL}${RESOURCE_USAGE_URL}`),
360
+ all: (context2 = "preview") => (0, import_http_client.httpService)().get(`${BASE_URL}${RESOURCE_URL}`, {
363
361
  params: { context: context2 }
364
362
  }),
365
363
  publish: (payload) => (0, import_http_client.httpService)().put("elementor/v1" + RESOURCE_URL, payload, {
@@ -374,23 +372,225 @@ var apiClient = {
374
372
  })
375
373
  };
376
374
 
375
+ // src/components/css-class-usage/utils.ts
376
+ var transformData = (data) => Object.entries(data).reduce((acc, [key, value]) => {
377
+ acc[key] = {
378
+ content: value || [],
379
+ total: value.reduce((total, val) => total + (val?.total || 0), 0)
380
+ };
381
+ return acc;
382
+ }, {});
383
+
384
+ // service/css-class-usage-service.ts
385
+ var fetchCssClassUsage = async () => {
386
+ const response = await apiClient.usage();
387
+ return transformData(response.data.data);
388
+ };
389
+
390
+ // src/components/css-class-usage/types.ts
391
+ var QUERY_KEY = "css-classes-usage";
392
+
393
+ // src/hooks/use-prefetch-css-class-usage.ts
394
+ function usePrefetchCssClassUsage() {
395
+ const queryClient = (0, import_query.useQueryClient)();
396
+ const prefetchClassesUsage = () => queryClient.prefetchQuery({
397
+ queryKey: [QUERY_KEY],
398
+ queryFn: fetchCssClassUsage
399
+ });
400
+ return { prefetchClassesUsage };
401
+ }
402
+
403
+ // src/components/class-manager/class-manager-panel.tsx
404
+ var React17 = __toESM(require("react"));
405
+ var import_react9 = require("react");
406
+ var import_editor_documents4 = require("@elementor/editor-documents");
407
+ var import_editor_panels = require("@elementor/editor-panels");
408
+ var import_editor_ui6 = require("@elementor/editor-ui");
409
+ var import_editor_v1_adapters3 = require("@elementor/editor-v1-adapters");
410
+ var import_icons12 = require("@elementor/icons");
411
+ var import_query3 = require("@elementor/query");
412
+ var import_store18 = require("@elementor/store");
413
+ var import_ui15 = require("@elementor/ui");
414
+ var import_i18n13 = require("@wordpress/i18n");
415
+
416
+ // src/hooks/use-classes-order.ts
417
+ var import_store4 = require("@elementor/store");
418
+ var useClassesOrder = () => {
419
+ return (0, import_store4.__useSelector)(selectOrder);
420
+ };
421
+
422
+ // src/hooks/use-dirty-state.ts
423
+ var import_store6 = require("@elementor/store");
424
+ var useDirtyState = () => {
425
+ return (0, import_store6.__useSelector)(selectIsDirty);
426
+ };
427
+
428
+ // src/hooks/use-filters.ts
429
+ var import_react3 = require("react");
430
+
431
+ // src/components/search-and-filter/context.tsx
432
+ var React = __toESM(require("react"));
433
+ var import_react = require("react");
434
+ var import_utils3 = require("@elementor/utils");
435
+ var SearchAndFilterContext = (0, import_react.createContext)(void 0);
436
+ var INIT_CHECKED_FILTERS = {
437
+ empty: false,
438
+ onThisPage: false,
439
+ unused: false
440
+ };
441
+ var SearchAndFilterProvider = ({ children }) => {
442
+ const [filters, setFilters] = React.useState(INIT_CHECKED_FILTERS);
443
+ const { debouncedValue, inputValue, handleChange } = (0, import_utils3.useDebounceState)({
444
+ delay: 300,
445
+ initialValue: ""
446
+ });
447
+ const onClearSearch = () => {
448
+ handleChange("");
449
+ };
450
+ const onClearFilter = () => {
451
+ setFilters(INIT_CHECKED_FILTERS);
452
+ };
453
+ return /* @__PURE__ */ React.createElement(
454
+ SearchAndFilterContext.Provider,
455
+ {
456
+ value: {
457
+ search: {
458
+ debouncedValue,
459
+ inputValue,
460
+ handleChange,
461
+ onClearSearch
462
+ },
463
+ filters: {
464
+ filters,
465
+ setFilters,
466
+ onClearFilter
467
+ }
468
+ }
469
+ },
470
+ children
471
+ );
472
+ };
473
+ var useSearchAndFilters = () => {
474
+ const context2 = (0, import_react.useContext)(SearchAndFilterContext);
475
+ if (!context2) {
476
+ throw new Error("useSearchContext must be used within a SearchContextProvider");
477
+ }
478
+ return context2;
479
+ };
480
+
481
+ // src/hooks/use-filtered-css-class-usage.tsx
482
+ var import_react2 = require("react");
483
+ var import_editor_documents = require("@elementor/editor-documents");
484
+
485
+ // src/hooks/use-css-class-usage.ts
486
+ var import_query2 = require("@elementor/query");
487
+ var useCssClassUsage = () => {
488
+ return (0, import_query2.useQuery)({
489
+ queryKey: [QUERY_KEY],
490
+ queryFn: fetchCssClassUsage,
491
+ refetchOnMount: false,
492
+ refetchOnWindowFocus: true
493
+ });
494
+ };
495
+
496
+ // src/hooks/use-empty-css-class.ts
497
+ var import_store8 = require("@elementor/store");
498
+ var useEmptyCssClass = () => {
499
+ return (0, import_store8.__useSelector)(selectEmptyCssClass);
500
+ };
501
+ var useAllCssClassesIDs = () => {
502
+ const cssClasses = (0, import_store8.__useSelector)(selectGlobalClasses);
503
+ return Object.keys(cssClasses);
504
+ };
505
+
506
+ // src/hooks/use-filtered-css-class-usage.tsx
507
+ var findCssClassKeysByPageID = (data, pageId) => {
508
+ const result = [];
509
+ for (const key in data) {
510
+ data[key].content.forEach((content) => {
511
+ if (+content.pageId === pageId) {
512
+ result.push(key);
513
+ }
514
+ });
515
+ }
516
+ return result;
517
+ };
518
+ var getUnusedClasses = (usedCssClass, potentialUnused) => {
519
+ const set = new Set(usedCssClass);
520
+ return potentialUnused.filter((cssClass) => !set.has(cssClass));
521
+ };
522
+ var EMPTY_FILTERED_CSS_CLASS_RESPONSE = {
523
+ empty: [],
524
+ onThisPage: [],
525
+ unused: []
526
+ };
527
+ var useFilteredCssClassUsage = () => {
528
+ const document = (0, import_editor_documents.__useActiveDocument)();
529
+ const emptyCssClasses = useEmptyCssClass();
530
+ const { data, isLoading } = useCssClassUsage();
531
+ const listOfCssClasses = useAllCssClassesIDs();
532
+ const emptyCssClassesIDs = (0, import_react2.useMemo)(() => emptyCssClasses.map(({ id: id2 }) => id2), [emptyCssClasses]);
533
+ const onThisPage = (0, import_react2.useMemo)(() => {
534
+ if (!data || !document) {
535
+ return [];
536
+ }
537
+ return findCssClassKeysByPageID(data, document.id);
538
+ }, [data, document]);
539
+ const unused = (0, import_react2.useMemo)(() => {
540
+ if (!data) {
541
+ return [];
542
+ }
543
+ return getUnusedClasses(Object.keys(data), listOfCssClasses);
544
+ }, [data, listOfCssClasses]);
545
+ if (isLoading || !data || !document) {
546
+ return EMPTY_FILTERED_CSS_CLASS_RESPONSE;
547
+ }
548
+ return {
549
+ onThisPage,
550
+ unused,
551
+ empty: emptyCssClassesIDs
552
+ };
553
+ };
554
+
555
+ // src/hooks/use-filters.ts
556
+ var useFilters = () => {
557
+ const {
558
+ filters: { filters }
559
+ } = useSearchAndFilters();
560
+ const allFilters = useFilteredCssClassUsage();
561
+ return (0, import_react3.useMemo)(() => {
562
+ const activeEntries = Object.entries(filters).filter(([, isActive]) => isActive);
563
+ if (activeEntries.length === 0) {
564
+ return null;
565
+ }
566
+ return activeEntries.reduce((acc, [key], index) => {
567
+ const current = allFilters[key] || [];
568
+ if (index === 0) {
569
+ return current;
570
+ }
571
+ return acc.filter((val) => current.includes(val));
572
+ }, []);
573
+ }, [filters, allFilters]);
574
+ };
575
+
377
576
  // src/save-global-classes.ts
577
+ var import_store10 = require("@elementor/store");
378
578
  async function saveGlobalClasses({ context: context2 }) {
379
- const state = selectData((0, import_store6.__getState)());
579
+ const state = selectData((0, import_store10.__getState)());
380
580
  if (context2 === "preview") {
381
581
  await apiClient.saveDraft({
382
582
  items: state.items,
383
583
  order: state.order,
384
- changes: calculateChanges(state, selectPreviewInitialData((0, import_store6.__getState)()))
584
+ changes: calculateChanges(state, selectPreviewInitialData((0, import_store10.__getState)()))
385
585
  });
386
586
  } else {
387
587
  await apiClient.publish({
388
588
  items: state.items,
389
589
  order: state.order,
390
- changes: calculateChanges(state, selectFrontendInitialData((0, import_store6.__getState)()))
590
+ changes: calculateChanges(state, selectFrontendInitialData((0, import_store10.__getState)()))
391
591
  });
392
592
  }
393
- (0, import_store6.__dispatch)(slice.actions.reset({ context: context2 }));
593
+ (0, import_store10.__dispatch)(slice.actions.reset({ context: context2 }));
394
594
  }
395
595
  function calculateChanges(state, initialData) {
396
596
  const stateIds = Object.keys(state.items);
@@ -416,22 +616,232 @@ function isPlainObject(value) {
416
616
  return !!value && typeof value === "object" && !Array.isArray(value);
417
617
  }
418
618
 
419
- // src/components/class-manager/class-manager-introduction.tsx
420
- var React = __toESM(require("react"));
421
- var import_react = require("react");
422
- var import_editor_current_user = require("@elementor/editor-current-user");
423
- var import_editor_ui = require("@elementor/editor-ui");
619
+ // src/components/search-and-filter/components/filter/active-filters.tsx
620
+ var React4 = __toESM(require("react"));
621
+ var import_ui3 = require("@elementor/ui");
622
+ var import_i18n3 = require("@wordpress/i18n");
623
+
624
+ // src/components/search-and-filter/components/filter/clear-icon-button.tsx
625
+ var React2 = __toESM(require("react"));
626
+ var import_icons = require("@elementor/icons");
424
627
  var import_ui = require("@elementor/ui");
628
+ var ClearIconButton = ({ tooltipText, sx }) => {
629
+ const {
630
+ filters: { onClearFilter }
631
+ } = useSearchAndFilters();
632
+ return /* @__PURE__ */ React2.createElement(import_ui.Tooltip, { title: tooltipText, placement: "top", disableInteractive: true }, /* @__PURE__ */ React2.createElement(import_ui.Box, null, /* @__PURE__ */ React2.createElement(CustomIconButton, { "aria-label": tooltipText, size: "tiny", onClick: onClearFilter, sx }, /* @__PURE__ */ React2.createElement(import_icons.BrushBigIcon, { fontSize: "tiny" }))));
633
+ };
634
+ var CustomIconButton = (0, import_ui.styled)(import_ui.IconButton)(({ theme }) => ({
635
+ "&.Mui-disabled": {
636
+ pointerEvents: "auto",
637
+ "&:hover": {
638
+ color: theme.palette.action.disabled
639
+ }
640
+ }
641
+ }));
642
+
643
+ // src/components/search-and-filter/components/filter/filter-list.tsx
644
+ var React3 = __toESM(require("react"));
645
+ var import_ui2 = require("@elementor/ui");
425
646
  var import_i18n2 = require("@wordpress/i18n");
647
+ var filterConfig = {
648
+ unused: (0, import_i18n2.__)("Unused", "elementor"),
649
+ empty: (0, import_i18n2.__)("Empty", "elementor"),
650
+ onThisPage: (0, import_i18n2.__)("On this page", "elementor")
651
+ };
652
+ var FilterList = () => {
653
+ const {
654
+ filters: { filters, setFilters }
655
+ } = useSearchAndFilters();
656
+ const filteredCssClass = useFilteredCssClassUsage();
657
+ const handleOnClick = (value) => {
658
+ setFilters((prev) => ({ ...prev, [value]: !prev[value] }));
659
+ };
660
+ return /* @__PURE__ */ React3.createElement(import_ui2.MenuList, null, /* @__PURE__ */ React3.createElement(import_ui2.MenuItem, { onClick: () => handleOnClick("unused") }, /* @__PURE__ */ React3.createElement(
661
+ LabeledCheckbox,
662
+ {
663
+ label: filterConfig.unused,
664
+ checked: filters.unused,
665
+ suffix: /* @__PURE__ */ React3.createElement(import_ui2.Chip, { size: "tiny", sx: { ml: "auto" }, label: filteredCssClass.unused.length })
666
+ }
667
+ )), /* @__PURE__ */ React3.createElement(import_ui2.MenuItem, { onClick: () => handleOnClick("empty") }, /* @__PURE__ */ React3.createElement(
668
+ LabeledCheckbox,
669
+ {
670
+ label: filterConfig.empty,
671
+ checked: filters.empty,
672
+ suffix: /* @__PURE__ */ React3.createElement(import_ui2.Chip, { size: "tiny", sx: { ml: "auto" }, label: filteredCssClass.empty.length })
673
+ }
674
+ )), /* @__PURE__ */ React3.createElement(import_ui2.MenuItem, { onClick: () => handleOnClick("onThisPage") }, /* @__PURE__ */ React3.createElement(
675
+ LabeledCheckbox,
676
+ {
677
+ label: filterConfig.onThisPage,
678
+ checked: filters.onThisPage,
679
+ suffix: /* @__PURE__ */ React3.createElement(import_ui2.Chip, { size: "tiny", sx: { ml: "auto" }, label: filteredCssClass.onThisPage.length })
680
+ }
681
+ )));
682
+ };
683
+ var LabeledCheckbox = ({ label, suffix, checked }) => /* @__PURE__ */ React3.createElement(import_ui2.Stack, { direction: "row", alignItems: "center", gap: 0.5, flex: 1 }, /* @__PURE__ */ React3.createElement(
684
+ import_ui2.Checkbox,
685
+ {
686
+ size: "small",
687
+ checked,
688
+ sx: {
689
+ padding: 0,
690
+ color: "text.tertiary",
691
+ "&.Mui-checked": {
692
+ color: "text.tertiary"
693
+ }
694
+ }
695
+ }
696
+ ), /* @__PURE__ */ React3.createElement(import_ui2.Typography, { variant: "caption", sx: { color: "text.secondary" } }, label), suffix);
697
+
698
+ // src/components/search-and-filter/components/filter/active-filters.tsx
699
+ var ActiveFilters = () => {
700
+ const {
701
+ filters: { filters, setFilters }
702
+ } = useSearchAndFilters();
703
+ const handleRemove = (key) => {
704
+ setFilters((prev) => ({ ...prev, [key]: false }));
705
+ };
706
+ const activeKeys = Object.keys(filters).filter((key) => filters[key]);
707
+ const showClearIcon = activeKeys.length > 0;
708
+ return /* @__PURE__ */ React4.createElement(import_ui3.Stack, { direction: "row", alignItems: "center", justifyContent: "space-between" }, /* @__PURE__ */ React4.createElement(import_ui3.Stack, { direction: "row", gap: 0.5, alignItems: "center", flexWrap: "wrap" }, activeKeys.map((key) => /* @__PURE__ */ React4.createElement(
709
+ import_ui3.Chip,
710
+ {
711
+ key,
712
+ label: filterConfig[key],
713
+ onDelete: () => handleRemove(key),
714
+ sx: chipSx,
715
+ size: "tiny"
716
+ }
717
+ ))), showClearIcon && /* @__PURE__ */ React4.createElement(
718
+ ClearIconButton,
719
+ {
720
+ tooltipText: (0, import_i18n3.__)("Clear Filters", "elementor"),
721
+ sx: { margin: "0 0 auto auto" }
722
+ }
723
+ ));
724
+ };
725
+ var chipSx = {
726
+ "& .MuiChip-deleteIcon": {
727
+ display: "none",
728
+ transition: "opacity 0.2s"
729
+ },
730
+ "&:hover .MuiChip-deleteIcon": {
731
+ display: "block"
732
+ }
733
+ };
734
+
735
+ // src/components/search-and-filter/components/filter/css-class-filter.tsx
736
+ var React5 = __toESM(require("react"));
737
+ var import_editor_ui = require("@elementor/editor-ui");
738
+ var import_icons2 = require("@elementor/icons");
739
+ var import_ui4 = require("@elementor/ui");
740
+ var import_i18n4 = require("@wordpress/i18n");
741
+ var CssClassFilter = () => {
742
+ const {
743
+ filters: { filters }
744
+ } = useSearchAndFilters();
745
+ const popupState = (0, import_ui4.usePopupState)({
746
+ variant: "popover",
747
+ disableAutoFocus: true
748
+ });
749
+ const showCleanIcon = Object.values(filters).some((value) => value);
750
+ return /* @__PURE__ */ React5.createElement(React5.Fragment, null, /* @__PURE__ */ React5.createElement(import_ui4.Tooltip, { title: (0, import_i18n4.__)("Filters", "elementor"), placement: "top" }, /* @__PURE__ */ React5.createElement(
751
+ import_ui4.ToggleButton,
752
+ {
753
+ value: "filter",
754
+ size: "tiny",
755
+ selected: popupState.isOpen,
756
+ ...(0, import_ui4.bindToggle)(popupState)
757
+ },
758
+ /* @__PURE__ */ React5.createElement(import_icons2.FilterIcon, { fontSize: "tiny" })
759
+ )), /* @__PURE__ */ React5.createElement(
760
+ import_ui4.Popover,
761
+ {
762
+ sx: {
763
+ maxWidth: "344px"
764
+ },
765
+ anchorOrigin: {
766
+ vertical: "top",
767
+ horizontal: "right"
768
+ },
769
+ transformOrigin: {
770
+ vertical: "top",
771
+ horizontal: -21
772
+ },
773
+ ...(0, import_ui4.bindPopover)(popupState)
774
+ },
775
+ /* @__PURE__ */ React5.createElement(
776
+ import_editor_ui.PopoverHeader,
777
+ {
778
+ actions: showCleanIcon ? [
779
+ /* @__PURE__ */ React5.createElement(
780
+ ClearIconButton,
781
+ {
782
+ key: "clear-all-button",
783
+ tooltipText: (0, import_i18n4.__)("Clear all", "elementor")
784
+ }
785
+ )
786
+ ] : [],
787
+ onClose: popupState.close,
788
+ title: (0, import_i18n4.__)("Filters", "elementor"),
789
+ icon: /* @__PURE__ */ React5.createElement(import_icons2.FilterIcon, { fontSize: "tiny" })
790
+ }
791
+ ),
792
+ /* @__PURE__ */ React5.createElement(
793
+ import_ui4.Divider,
794
+ {
795
+ sx: {
796
+ borderWidth: "1px 0 0 0"
797
+ }
798
+ }
799
+ ),
800
+ /* @__PURE__ */ React5.createElement(import_editor_ui.PopoverBody, { width: 344, height: 125 }, /* @__PURE__ */ React5.createElement(FilterList, null))
801
+ ));
802
+ };
803
+
804
+ // src/components/search-and-filter/components/search/class-manager-search.tsx
805
+ var React6 = __toESM(require("react"));
806
+ var import_icons3 = require("@elementor/icons");
807
+ var import_ui5 = require("@elementor/ui");
808
+ var import_i18n5 = require("@wordpress/i18n");
809
+ var ClassManagerSearch = () => {
810
+ const {
811
+ search: { inputValue, handleChange }
812
+ } = useSearchAndFilters();
813
+ return /* @__PURE__ */ React6.createElement(import_ui5.Stack, { direction: "row", gap: 0.5, sx: { width: "100%" } }, /* @__PURE__ */ React6.createElement(import_ui5.Box, { sx: { flexGrow: 1 } }, /* @__PURE__ */ React6.createElement(
814
+ import_ui5.TextField,
815
+ {
816
+ role: "search",
817
+ fullWidth: true,
818
+ size: "tiny",
819
+ value: inputValue,
820
+ placeholder: (0, import_i18n5.__)("Search", "elementor"),
821
+ onChange: (e) => handleChange(e.target.value),
822
+ InputProps: {
823
+ startAdornment: /* @__PURE__ */ React6.createElement(import_ui5.InputAdornment, { position: "start" }, /* @__PURE__ */ React6.createElement(import_icons3.SearchIcon, { fontSize: "tiny" }))
824
+ }
825
+ }
826
+ )));
827
+ };
828
+
829
+ // src/components/class-manager/class-manager-introduction.tsx
830
+ var React7 = __toESM(require("react"));
831
+ var import_react4 = require("react");
832
+ var import_editor_current_user = require("@elementor/editor-current-user");
833
+ var import_editor_ui2 = require("@elementor/editor-ui");
834
+ var import_ui6 = require("@elementor/ui");
835
+ var import_i18n6 = require("@wordpress/i18n");
426
836
  var MESSAGE_KEY = "global-class-manager";
427
837
  var ClassManagerIntroduction = () => {
428
838
  const [isMessageSuppressed, suppressMessage] = (0, import_editor_current_user.useSuppressedMessage)(MESSAGE_KEY);
429
- const [shouldShowIntroduction, setShouldShowIntroduction] = (0, import_react.useState)(!isMessageSuppressed);
430
- return /* @__PURE__ */ React.createElement(
431
- import_editor_ui.IntroductionModal,
839
+ const [shouldShowIntroduction, setShouldShowIntroduction] = (0, import_react4.useState)(!isMessageSuppressed);
840
+ return /* @__PURE__ */ React7.createElement(
841
+ import_editor_ui2.IntroductionModal,
432
842
  {
433
843
  open: shouldShowIntroduction,
434
- title: (0, import_i18n2.__)("Class Manager", "elementor"),
844
+ title: (0, import_i18n6.__)("Class Manager", "elementor"),
435
845
  handleClose: (shouldShowAgain) => {
436
846
  if (!shouldShowAgain) {
437
847
  suppressMessage();
@@ -439,54 +849,34 @@ var ClassManagerIntroduction = () => {
439
849
  setShouldShowIntroduction(false);
440
850
  }
441
851
  },
442
- /* @__PURE__ */ React.createElement(
443
- import_ui.Image,
852
+ /* @__PURE__ */ React7.createElement(
853
+ import_ui6.Image,
444
854
  {
445
855
  sx: { width: "100%", aspectRatio: "16 / 9" },
446
856
  src: "https://assets.elementor.com/packages/v1/images/class-manager-intro.svg",
447
857
  alt: ""
448
858
  }
449
859
  ),
450
- /* @__PURE__ */ React.createElement(IntroductionContent, null)
860
+ /* @__PURE__ */ React7.createElement(IntroductionContent, null)
451
861
  );
452
862
  };
453
863
  var IntroductionContent = () => {
454
- return /* @__PURE__ */ React.createElement(import_ui.Box, { p: 3 }, /* @__PURE__ */ React.createElement(import_ui.Typography, { variant: "body2" }, (0, import_i18n2.__)(
864
+ return /* @__PURE__ */ React7.createElement(import_ui6.Box, { p: 3 }, /* @__PURE__ */ React7.createElement(import_ui6.Typography, { variant: "body2" }, (0, import_i18n6.__)(
455
865
  "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.",
456
866
  "elementor"
457
- )), /* @__PURE__ */ React.createElement("br", null), /* @__PURE__ */ React.createElement(import_ui.Typography, { variant: "body2" }, (0, import_i18n2.__)(
867
+ )), /* @__PURE__ */ React7.createElement("br", null), /* @__PURE__ */ React7.createElement(import_ui6.Typography, { variant: "body2" }, (0, import_i18n6.__)(
458
868
  "Remember, when editing an item within a specific class, any changes you make will apply across all elements in that class.",
459
869
  "elementor"
460
870
  )));
461
871
  };
462
872
 
463
- // src/components/class-manager/class-manager-search.tsx
464
- var React2 = __toESM(require("react"));
465
- var import_icons = require("@elementor/icons");
466
- var import_ui2 = require("@elementor/ui");
467
- var import_i18n3 = require("@wordpress/i18n");
468
- var ClassManagerSearch = ({ searchValue, onChange }) => /* @__PURE__ */ React2.createElement(import_ui2.Grid, { item: true, xs: 6, px: 2, pb: 1 }, /* @__PURE__ */ React2.createElement(import_ui2.Stack, { direction: "row", gap: 0.5, sx: { width: "100%" } }, /* @__PURE__ */ React2.createElement(import_ui2.Box, { sx: { flexGrow: 1 } }, /* @__PURE__ */ React2.createElement(
469
- import_ui2.TextField,
470
- {
471
- role: "search",
472
- fullWidth: true,
473
- size: "tiny",
474
- value: searchValue,
475
- placeholder: (0, import_i18n3.__)("Search", "elementor"),
476
- onChange: (e) => onChange(e.target.value),
477
- InputProps: {
478
- startAdornment: /* @__PURE__ */ React2.createElement(import_ui2.InputAdornment, { position: "start" }, /* @__PURE__ */ React2.createElement(import_icons.SearchIcon, { fontSize: "tiny" }))
479
- }
480
- }
481
- ))));
482
-
483
873
  // src/components/class-manager/delete-class.ts
484
- var import_editor_documents = require("@elementor/editor-documents");
485
- var import_editor_v1_adapters3 = require("@elementor/editor-v1-adapters");
486
- var import_store8 = require("@elementor/store");
874
+ var import_editor_documents2 = require("@elementor/editor-documents");
875
+ var import_editor_v1_adapters2 = require("@elementor/editor-v1-adapters");
876
+ var import_store12 = require("@elementor/store");
487
877
  var isDeleted = false;
488
878
  var deleteClass = (id2) => {
489
- (0, import_store8.__dispatch)(slice.actions.delete(id2));
879
+ (0, import_store12.__dispatch)(slice.actions.delete(id2));
490
880
  isDeleted = true;
491
881
  };
492
882
  var onDelete = async () => {
@@ -495,10 +885,10 @@ var onDelete = async () => {
495
885
  };
496
886
  var hasDeletedItems = () => isDeleted;
497
887
  var reloadDocument = () => {
498
- const currentDocument = (0, import_editor_documents.getCurrentDocument)();
499
- const documentsManager = (0, import_editor_documents.getV1DocumentsManager)();
888
+ const currentDocument = (0, import_editor_documents2.getCurrentDocument)();
889
+ const documentsManager = (0, import_editor_documents2.getV1DocumentsManager)();
500
890
  documentsManager.invalidateCache();
501
- return (0, import_editor_v1_adapters3.__privateRunCommand)("editor/documents/switch", {
891
+ return (0, import_editor_v1_adapters2.__privateRunCommand)("editor/documents/switch", {
502
892
  id: currentDocument?.id,
503
893
  shouldScroll: false,
504
894
  shouldNavigateToDefaultRoute: false
@@ -506,71 +896,308 @@ var reloadDocument = () => {
506
896
  };
507
897
 
508
898
  // src/components/class-manager/flipped-color-swatch-icon.tsx
509
- var React3 = __toESM(require("react"));
510
- var import_icons2 = require("@elementor/icons");
511
- var FlippedColorSwatchIcon = ({ sx, ...props }) => /* @__PURE__ */ React3.createElement(import_icons2.ColorSwatchIcon, { sx: { transform: "rotate(90deg)", ...sx }, ...props });
512
-
513
- // src/components/class-manager/global-classes-list.tsx
514
899
  var React8 = __toESM(require("react"));
515
- var import_react4 = require("react");
516
- var import_store14 = require("@elementor/store");
517
- var import_ui7 = require("@elementor/ui");
518
- var import_i18n7 = require("@wordpress/i18n");
900
+ var import_icons4 = require("@elementor/icons");
901
+ var FlippedColorSwatchIcon = ({ sx, ...props }) => /* @__PURE__ */ React8.createElement(import_icons4.ColorSwatchIcon, { sx: { transform: "rotate(90deg)", ...sx }, ...props });
519
902
 
520
- // src/hooks/use-classes-order.ts
521
- var import_store10 = require("@elementor/store");
522
- var useClassesOrder = () => {
523
- return (0, import_store10.__useSelector)(selectOrder);
524
- };
903
+ // src/components/class-manager/global-classes-list.tsx
904
+ var React15 = __toESM(require("react"));
905
+ var import_react7 = require("react");
906
+ var import_store16 = require("@elementor/store");
907
+ var import_ui13 = require("@elementor/ui");
908
+ var import_i18n12 = require("@wordpress/i18n");
525
909
 
526
910
  // src/hooks/use-ordered-classes.ts
527
- var import_store12 = require("@elementor/store");
911
+ var import_store14 = require("@elementor/store");
528
912
  var useOrderedClasses = () => {
529
- return (0, import_store12.__useSelector)(selectOrderedClasses);
913
+ return (0, import_store14.__useSelector)(selectOrderedClasses);
530
914
  };
531
915
 
532
916
  // src/components/class-manager/class-item.tsx
533
- var React6 = __toESM(require("react"));
534
- var import_react3 = require("react");
535
- var import_editor_editing_panel = require("@elementor/editor-editing-panel");
917
+ var React13 = __toESM(require("react"));
918
+ var import_react6 = require("react");
536
919
  var import_editor_styles_repository2 = require("@elementor/editor-styles-repository");
537
- var import_editor_ui2 = require("@elementor/editor-ui");
538
- var import_editor_v1_adapters4 = require("@elementor/editor-v1-adapters");
920
+ var import_editor_ui5 = require("@elementor/editor-ui");
921
+ var import_icons9 = require("@elementor/icons");
922
+ var import_ui11 = require("@elementor/ui");
923
+ var import_i18n10 = require("@wordpress/i18n");
924
+
925
+ // src/components/css-class-usage/components/css-class-usage-popover.tsx
926
+ var React9 = __toESM(require("react"));
927
+ var import_editor_documents3 = require("@elementor/editor-documents");
928
+ var import_editor_ui3 = require("@elementor/editor-ui");
539
929
  var import_icons5 = require("@elementor/icons");
540
- var import_ui5 = require("@elementor/ui");
541
- var import_i18n5 = require("@wordpress/i18n");
930
+ var import_ui7 = require("@elementor/ui");
931
+ var import_i18n7 = require("@wordpress/i18n");
932
+
933
+ // src/hooks/use-css-class-usage-by-id.ts
934
+ var EMPTY_CLASS_USAGE = {
935
+ total: 0,
936
+ content: []
937
+ };
938
+ var useCssClassUsageByID = (id2) => {
939
+ const { data, ...rest } = useCssClassUsage();
940
+ const classData = data?.[id2] ?? EMPTY_CLASS_USAGE;
941
+ return { ...rest, data: classData };
942
+ };
943
+
944
+ // src/components/css-class-usage/components/css-class-usage-popover.tsx
945
+ var iconMapper = {
946
+ "wp-post": {
947
+ label: (0, import_i18n7.__)("Post", "elementor"),
948
+ icon: /* @__PURE__ */ React9.createElement(import_icons5.PostTypeIcon, { fontSize: "inherit" })
949
+ },
950
+ "wp-page": {
951
+ label: (0, import_i18n7.__)("Page", "elementor"),
952
+ icon: /* @__PURE__ */ React9.createElement(import_icons5.PagesIcon, { fontSize: "inherit" })
953
+ },
954
+ popup: {
955
+ label: (0, import_i18n7.__)("Popup", "elementor"),
956
+ icon: /* @__PURE__ */ React9.createElement(import_icons5.PopupTemplateIcon, { fontSize: "inherit" })
957
+ },
958
+ header: {
959
+ label: (0, import_i18n7.__)("Header", "elementor"),
960
+ icon: /* @__PURE__ */ React9.createElement(import_icons5.HeaderTemplateIcon, { fontSize: "inherit" })
961
+ },
962
+ footer: {
963
+ label: (0, import_i18n7.__)("Footer", "elementor"),
964
+ icon: /* @__PURE__ */ React9.createElement(import_icons5.FooterTemplateIcon, { fontSize: "inherit" })
965
+ }
966
+ };
967
+ var CssClassUsagePopover = ({
968
+ cssClassID,
969
+ onClose
970
+ }) => {
971
+ const { data: classUsage } = useCssClassUsageByID(cssClassID);
972
+ const onNavigate = (0, import_editor_documents3.__useOpenDocumentInNewTab)();
973
+ const cssClassUsageRecords = classUsage?.content.map(
974
+ ({ title, elements, pageId, type }) => ({
975
+ type: "item",
976
+ value: pageId,
977
+ label: title,
978
+ secondaryText: elements.length.toString(),
979
+ docType: type
980
+ })
981
+ ) ?? [];
982
+ return /* @__PURE__ */ React9.createElement(React9.Fragment, null, /* @__PURE__ */ React9.createElement(
983
+ import_editor_ui3.PopoverHeader,
984
+ {
985
+ icon: /* @__PURE__ */ React9.createElement(import_icons5.CurrentLocationIcon, { fontSize: "tiny" }),
986
+ title: /* @__PURE__ */ React9.createElement(import_ui7.Stack, { flexDirection: "row", gap: 1, alignItems: "center" }, /* @__PURE__ */ React9.createElement(import_ui7.Box, { "aria-label": "header-title" }, (0, import_i18n7.__)("Locator", "elementor")), /* @__PURE__ */ React9.createElement(import_ui7.Box, null, /* @__PURE__ */ React9.createElement(import_ui7.Chip, { sx: { lineHeight: 1 }, size: "tiny", label: classUsage.total }))),
987
+ onClose
988
+ }
989
+ ), /* @__PURE__ */ React9.createElement(import_ui7.Divider, null), /* @__PURE__ */ React9.createElement(import_editor_ui3.PopoverBody, { width: 300 }, /* @__PURE__ */ React9.createElement(
990
+ import_editor_ui3.PopoverMenuList,
991
+ {
992
+ onSelect: (value) => onNavigate(+value),
993
+ items: cssClassUsageRecords,
994
+ onClose: () => {
995
+ },
996
+ menuListTemplate: StyledCssClassUsageItem,
997
+ menuItemContentTemplate: (cssClassUsageRecord) => /* @__PURE__ */ React9.createElement(import_ui7.Stack, { flexDirection: "row", flex: 1, alignItems: "center" }, /* @__PURE__ */ React9.createElement(import_ui7.Box, { display: "flex", sx: { pr: 1 } }, /* @__PURE__ */ React9.createElement(
998
+ import_ui7.Tooltip,
999
+ {
1000
+ disableInteractive: true,
1001
+ title: iconMapper?.[cssClassUsageRecord.docType]?.label ?? cssClassUsageRecord.docType,
1002
+ placement: "top"
1003
+ },
1004
+ /* @__PURE__ */ React9.createElement(import_ui7.Icon, { fontSize: "small" }, iconMapper?.[cssClassUsageRecord.docType]?.icon || /* @__PURE__ */ React9.createElement(import_icons5.PagesIcon, { fontSize: "inherit" }))
1005
+ )), /* @__PURE__ */ React9.createElement(import_ui7.Box, { sx: { pr: 0.5, maxWidth: "173px" }, display: "flex" }, /* @__PURE__ */ React9.createElement(
1006
+ import_editor_ui3.EllipsisWithTooltip,
1007
+ {
1008
+ title: cssClassUsageRecord.label,
1009
+ as: import_ui7.Typography,
1010
+ variant: "caption",
1011
+ maxWidth: "173px",
1012
+ sx: {
1013
+ lineHeight: 1
1014
+ }
1015
+ }
1016
+ )), /* @__PURE__ */ React9.createElement(import_icons5.ExternalLinkIcon, { className: "hover-only-icon", fontSize: "tiny" }), /* @__PURE__ */ React9.createElement(
1017
+ import_ui7.Chip,
1018
+ {
1019
+ sx: {
1020
+ ml: "auto"
1021
+ },
1022
+ size: "tiny",
1023
+ label: cssClassUsageRecord.secondaryText
1024
+ }
1025
+ ))
1026
+ }
1027
+ )));
1028
+ };
1029
+ var StyledCssClassUsageItem = (0, import_ui7.styled)(import_ui7.MenuList)(({ theme }) => ({
1030
+ "& > li": {
1031
+ display: "flex",
1032
+ cursor: "pointer",
1033
+ height: 32,
1034
+ width: "100%"
1035
+ },
1036
+ '& > [role="option"]': {
1037
+ ...theme.typography.caption,
1038
+ lineHeight: "inherit",
1039
+ padding: theme.spacing(0.5, 1, 0.5, 2),
1040
+ textOverflow: "ellipsis",
1041
+ position: "absolute",
1042
+ top: 0,
1043
+ left: 0,
1044
+ opacity: 1,
1045
+ ".hover-only-icon": {
1046
+ color: theme.palette.text.disabled,
1047
+ opacity: 0
1048
+ },
1049
+ "&:hover": {
1050
+ borderRadius: theme.spacing(0.5),
1051
+ backgroundColor: theme.palette.action.hover,
1052
+ ".hover-only-icon": {
1053
+ color: theme.palette.text.disabled,
1054
+ opacity: 1
1055
+ }
1056
+ }
1057
+ },
1058
+ width: "100%",
1059
+ position: "relative"
1060
+ }));
1061
+
1062
+ // src/components/css-class-usage/components/css-class-usage-trigger.tsx
1063
+ var React10 = __toESM(require("react"));
1064
+ var import_editor_ui4 = require("@elementor/editor-ui");
1065
+ var import_icons6 = require("@elementor/icons");
1066
+ var import_ui8 = require("@elementor/ui");
1067
+ var import_i18n8 = require("@wordpress/i18n");
1068
+ var CssClassUsageTrigger = ({ id: id2, onClick }) => {
1069
+ const {
1070
+ data: { total },
1071
+ isLoading
1072
+ } = useCssClassUsageByID(id2);
1073
+ const cssClassUsagePopover = (0, import_ui8.usePopupState)({ variant: "popover", popupId: "css-class-usage-popover" });
1074
+ if (isLoading) {
1075
+ return null;
1076
+ }
1077
+ const WrapperComponent = total !== 0 ? TooltipWrapper : InfoAlertMessage;
1078
+ return /* @__PURE__ */ React10.createElement(React10.Fragment, null, /* @__PURE__ */ React10.createElement(import_ui8.Box, { position: "relative" }, /* @__PURE__ */ React10.createElement(WrapperComponent, { total }, /* @__PURE__ */ React10.createElement(
1079
+ CustomIconButton2,
1080
+ {
1081
+ disabled: total === 0,
1082
+ size: "tiny",
1083
+ ...(0, import_ui8.bindTrigger)(cssClassUsagePopover),
1084
+ onClick: (e) => {
1085
+ if (total !== 0) {
1086
+ (0, import_ui8.bindTrigger)(cssClassUsagePopover).onClick(e);
1087
+ onClick(id2);
1088
+ }
1089
+ }
1090
+ },
1091
+ /* @__PURE__ */ React10.createElement(import_icons6.CurrentLocationIcon, { fontSize: "tiny" })
1092
+ ))), /* @__PURE__ */ React10.createElement(import_ui8.Box, null, /* @__PURE__ */ React10.createElement(
1093
+ import_ui8.Popover,
1094
+ {
1095
+ anchorOrigin: {
1096
+ vertical: "center",
1097
+ horizontal: "right"
1098
+ },
1099
+ transformOrigin: {
1100
+ vertical: 15,
1101
+ horizontal: -50
1102
+ },
1103
+ ...(0, import_ui8.bindPopover)(cssClassUsagePopover),
1104
+ onClose: () => {
1105
+ (0, import_ui8.bindPopover)(cssClassUsagePopover).onClose();
1106
+ onClick("");
1107
+ }
1108
+ },
1109
+ /* @__PURE__ */ React10.createElement(
1110
+ CssClassUsagePopover,
1111
+ {
1112
+ onClose: cssClassUsagePopover.close,
1113
+ "aria-label": "css-class-usage-popover",
1114
+ cssClassID: id2
1115
+ }
1116
+ )
1117
+ )));
1118
+ };
1119
+ var CustomIconButton2 = (0, import_ui8.styled)(import_ui8.IconButton)(({ theme }) => ({
1120
+ "&.Mui-disabled": {
1121
+ pointerEvents: "auto",
1122
+ // Enable hover
1123
+ "&:hover": {
1124
+ color: theme.palette.action.disabled
1125
+ // optional
1126
+ }
1127
+ },
1128
+ height: "22px",
1129
+ width: "22px"
1130
+ }));
1131
+ var TooltipWrapper = ({ children, total }) => /* @__PURE__ */ React10.createElement(
1132
+ import_ui8.Tooltip,
1133
+ {
1134
+ disableInteractive: true,
1135
+ placement: "top",
1136
+ title: `${(0, import_i18n8.__)("Show {{number}} {{locations}}", "elementor").replace("{{number}}", total.toString()).replace(
1137
+ "{{locations}}",
1138
+ total === 1 ? (0, import_i18n8.__)("location", "elementor") : (0, import_i18n8.__)("locations", "elementor")
1139
+ )}`
1140
+ },
1141
+ /* @__PURE__ */ React10.createElement("span", null, children)
1142
+ );
1143
+ var InfoAlertMessage = ({ children }) => /* @__PURE__ */ React10.createElement(
1144
+ import_ui8.Infotip,
1145
+ {
1146
+ disableInteractive: true,
1147
+ placement: "top",
1148
+ color: "secondary",
1149
+ content: /* @__PURE__ */ React10.createElement(import_editor_ui4.InfoAlert, { sx: { mt: 1 } }, (0, import_i18n8.__)("This class isn\u2019t being used yet.", "elementor"))
1150
+ },
1151
+ /* @__PURE__ */ React10.createElement("span", null, children)
1152
+ );
542
1153
 
543
1154
  // src/components/class-manager/delete-confirmation-dialog.tsx
544
- var React4 = __toESM(require("react"));
545
- var import_react2 = require("react");
546
- var import_icons3 = require("@elementor/icons");
547
- var import_ui3 = require("@elementor/ui");
548
- var import_i18n4 = require("@wordpress/i18n");
549
- var context = (0, import_react2.createContext)(null);
1155
+ var React11 = __toESM(require("react"));
1156
+ var import_react5 = require("react");
1157
+ var import_icons7 = require("@elementor/icons");
1158
+ var import_ui9 = require("@elementor/ui");
1159
+ var import_i18n9 = require("@wordpress/i18n");
1160
+ var context = (0, import_react5.createContext)(null);
550
1161
  var DeleteConfirmationProvider = ({ children }) => {
551
- const [dialogProps, setDialogProps] = (0, import_react2.useState)(null);
1162
+ const [dialogProps, setDialogProps] = (0, import_react5.useState)(null);
552
1163
  const openDialog = (props) => {
553
1164
  setDialogProps(props);
554
1165
  };
555
1166
  const closeDialog = () => {
556
1167
  setDialogProps(null);
557
1168
  };
558
- return /* @__PURE__ */ React4.createElement(context.Provider, { value: { openDialog, closeDialog, dialogProps } }, children, !!dialogProps && /* @__PURE__ */ React4.createElement(DeleteConfirmationDialog, { ...dialogProps }));
1169
+ return /* @__PURE__ */ React11.createElement(context.Provider, { value: { openDialog, closeDialog, dialogProps } }, children, !!dialogProps && /* @__PURE__ */ React11.createElement(DeleteConfirmationDialog, { ...dialogProps }));
559
1170
  };
560
1171
  var TITLE_ID = "delete-class-dialog";
561
1172
  var DeleteConfirmationDialog = ({ label, id: id2 }) => {
562
1173
  const { closeDialog } = useDeleteConfirmation();
1174
+ const {
1175
+ data: { total, content }
1176
+ } = useCssClassUsageByID(id2);
563
1177
  const onConfirm = () => {
564
1178
  deleteClass(id2);
565
1179
  closeDialog();
566
1180
  };
567
- return /* @__PURE__ */ React4.createElement(import_ui3.Dialog, { open: true, onClose: closeDialog, "aria-labelledby": TITLE_ID, maxWidth: "xs" }, /* @__PURE__ */ React4.createElement(import_ui3.DialogTitle, { id: TITLE_ID, display: "flex", alignItems: "center", gap: 1, sx: { lineHeight: 1 } }, /* @__PURE__ */ React4.createElement(import_icons3.AlertOctagonFilledIcon, { color: "error" }), (0, import_i18n4.__)("Delete this class?", "elementor")), /* @__PURE__ */ React4.createElement(import_ui3.DialogContent, null, /* @__PURE__ */ React4.createElement(import_ui3.DialogContentText, { variant: "body2", color: "textPrimary" }, (0, import_i18n4.__)("Deleting", "elementor"), /* @__PURE__ */ React4.createElement(import_ui3.Typography, { variant: "subtitle2", component: "span" }, "\xA0", label, "\xA0"), (0, import_i18n4.__)(
568
- "will permanently remove it from your project and may affect the design across all elements using it. This action cannot be undone.",
1181
+ const text = total && content.length ? (0, import_i18n9.__)(
1182
+ "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.",
1183
+ "elementor"
1184
+ ).replace("%1", total.toString()).replace("%2", content.length.toString()) : (0, import_i18n9.__)(
1185
+ "Will permanently remove it from your project and may affect the design across all elements using it. This action cannot be undone.",
569
1186
  "elementor"
570
- ))), /* @__PURE__ */ React4.createElement(import_ui3.DialogActions, null, /* @__PURE__ */ React4.createElement(import_ui3.Button, { color: "secondary", onClick: closeDialog }, (0, import_i18n4.__)("Not now", "elementor")), /* @__PURE__ */ React4.createElement(import_ui3.Button, { variant: "contained", color: "error", onClick: onConfirm }, (0, import_i18n4.__)("Delete", "elementor"))));
1187
+ );
1188
+ return /* @__PURE__ */ React11.createElement(import_ui9.Dialog, { open: true, onClose: closeDialog, "aria-labelledby": TITLE_ID, maxWidth: "xs" }, /* @__PURE__ */ React11.createElement(import_ui9.DialogTitle, { id: TITLE_ID, display: "flex", alignItems: "center", gap: 1, sx: { lineHeight: 1 } }, /* @__PURE__ */ React11.createElement(import_icons7.AlertOctagonFilledIcon, { color: "error" }), (0, import_i18n9.__)("Delete this class?", "elementor")), /* @__PURE__ */ React11.createElement(import_ui9.DialogContent, null, /* @__PURE__ */ React11.createElement(import_ui9.DialogContentText, { variant: "body2", color: "textPrimary" }, (0, import_i18n9.__)("Deleting", "elementor"), /* @__PURE__ */ React11.createElement(import_ui9.Typography, { variant: "subtitle2", component: "span" }, "\xA0", label, "\xA0"), text)), /* @__PURE__ */ React11.createElement(import_ui9.DialogActions, null, /* @__PURE__ */ React11.createElement(import_ui9.Button, { color: "secondary", onClick: closeDialog }, (0, import_i18n9.__)("Not now", "elementor")), /* @__PURE__ */ React11.createElement(
1189
+ import_ui9.Button,
1190
+ {
1191
+ autoFocus: true,
1192
+ variant: "contained",
1193
+ color: "error",
1194
+ onClick: onConfirm
1195
+ },
1196
+ (0, import_i18n9.__)("Delete", "elementor")
1197
+ )));
571
1198
  };
572
1199
  var useDeleteConfirmation = () => {
573
- const contextValue = (0, import_react2.useContext)(context);
1200
+ const contextValue = (0, import_react5.useContext)(context);
574
1201
  if (!contextValue) {
575
1202
  throw new Error("useDeleteConfirmation must be used within a DeleteConfirmationProvider");
576
1203
  }
@@ -578,14 +1205,14 @@ var useDeleteConfirmation = () => {
578
1205
  };
579
1206
 
580
1207
  // src/components/class-manager/sortable.tsx
581
- var React5 = __toESM(require("react"));
582
- var import_icons4 = require("@elementor/icons");
583
- var import_ui4 = require("@elementor/ui");
584
- var SortableProvider = (props) => /* @__PURE__ */ React5.createElement(import_ui4.UnstableSortableProvider, { restrictAxis: true, variant: "static", dragPlaceholderStyle: { opacity: "1" }, ...props });
585
- var SortableTrigger = (props) => /* @__PURE__ */ React5.createElement(StyledSortableTrigger, { ...props, role: "button", className: "class-item-sortable-trigger" }, /* @__PURE__ */ React5.createElement(import_icons4.GripVerticalIcon, { fontSize: "tiny" }));
1208
+ var React12 = __toESM(require("react"));
1209
+ var import_icons8 = require("@elementor/icons");
1210
+ var import_ui10 = require("@elementor/ui");
1211
+ var SortableProvider = (props) => /* @__PURE__ */ React12.createElement(import_ui10.UnstableSortableProvider, { restrictAxis: true, variant: "static", dragPlaceholderStyle: { opacity: "1" }, ...props });
1212
+ var SortableTrigger = (props) => /* @__PURE__ */ React12.createElement(StyledSortableTrigger, { ...props, role: "button", className: "class-item-sortable-trigger" }, /* @__PURE__ */ React12.createElement(import_icons8.GripVerticalIcon, { fontSize: "tiny" }));
586
1213
  var SortableItem = ({ children, id: id2, ...props }) => {
587
- return /* @__PURE__ */ React5.createElement(
588
- import_ui4.UnstableSortableItem,
1214
+ return /* @__PURE__ */ React12.createElement(
1215
+ import_ui10.UnstableSortableItem,
589
1216
  {
590
1217
  ...props,
591
1218
  id: id2,
@@ -600,8 +1227,8 @@ var SortableItem = ({ children, id: id2, ...props }) => {
600
1227
  isDragOverlay,
601
1228
  isDragPlaceholder
602
1229
  }) => {
603
- return /* @__PURE__ */ React5.createElement(
604
- import_ui4.Box,
1230
+ return /* @__PURE__ */ React12.createElement(
1231
+ import_ui10.Box,
605
1232
  {
606
1233
  ...itemProps,
607
1234
  style: itemStyle,
@@ -619,56 +1246,51 @@ var SortableItem = ({ children, id: id2, ...props }) => {
619
1246
  triggerStyle,
620
1247
  isDragPlaceholder
621
1248
  }),
622
- showDropIndication && /* @__PURE__ */ React5.createElement(SortableItemIndicator, { style: dropIndicationStyle })
1249
+ showDropIndication && /* @__PURE__ */ React12.createElement(SortableItemIndicator, { style: dropIndicationStyle })
623
1250
  );
624
1251
  }
625
1252
  }
626
1253
  );
627
1254
  };
628
- var StyledSortableTrigger = (0, import_ui4.styled)("div")(({ theme }) => ({
1255
+ var StyledSortableTrigger = (0, import_ui10.styled)("div")(({ theme }) => ({
629
1256
  position: "absolute",
630
1257
  left: 0,
631
1258
  top: "50%",
632
1259
  transform: `translate( -${theme.spacing(1.5)}, -50% )`,
633
1260
  color: theme.palette.action.active
634
1261
  }));
635
- var SortableItemIndicator = (0, import_ui4.styled)(import_ui4.Box)`
1262
+ var SortableItemIndicator = (0, import_ui10.styled)(import_ui10.Box)`
636
1263
  width: 100%;
637
1264
  height: 1px;
638
1265
  background-color: ${({ theme }) => theme.palette.text.primary};
639
1266
  `;
640
1267
 
641
1268
  // src/components/class-manager/class-item.tsx
642
- var isVersion311IsActive = (0, import_editor_v1_adapters4.isExperimentActive)(import_editor_editing_panel.EXPERIMENTAL_FEATURES.V_3_31);
643
- var ClassItem = ({
644
- id: id2,
645
- label,
646
- renameClass,
647
- selected,
648
- disabled,
649
- sortableTriggerProps,
650
- isSearchActive
651
- }) => {
652
- const itemRef = (0, import_react3.useRef)(null);
1269
+ var ClassItem = ({ id: id2, label, renameClass, selected, disabled, sortableTriggerProps }) => {
1270
+ const itemRef = (0, import_react6.useRef)(null);
1271
+ const {
1272
+ search: { inputValue }
1273
+ } = useSearchAndFilters();
653
1274
  const {
654
1275
  ref: editableRef,
655
1276
  openEditMode,
656
1277
  isEditing,
657
1278
  error,
658
1279
  getProps: getEditableProps
659
- } = (0, import_editor_ui2.useEditable)({
1280
+ } = (0, import_editor_ui5.useEditable)({
660
1281
  value: label,
661
1282
  onSubmit: renameClass,
662
1283
  validation: validateLabel
663
1284
  });
1285
+ const [selectedCssUsage, setSelectedCssUsage] = (0, import_react6.useState)("");
664
1286
  const { openDialog } = useDeleteConfirmation();
665
- const popupState = (0, import_ui5.usePopupState)({
1287
+ const popupState = (0, import_ui11.usePopupState)({
666
1288
  variant: "popover",
667
1289
  disableAutoFocus: true
668
1290
  });
669
- const isSelected = (selected || popupState.isOpen) && !disabled;
670
- return /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(import_ui5.Stack, { p: 0 }, /* @__PURE__ */ React6.createElement(
671
- import_editor_ui2.WarningInfotip,
1291
+ const isSelected = (selectedCssUsage === id2 || selected || popupState.isOpen) && !disabled;
1292
+ return /* @__PURE__ */ React13.createElement(React13.Fragment, null, /* @__PURE__ */ React13.createElement(import_ui11.Stack, { p: 0 }, /* @__PURE__ */ React13.createElement(
1293
+ import_editor_ui5.WarningInfotip,
672
1294
  {
673
1295
  open: Boolean(error),
674
1296
  text: error ?? "",
@@ -676,13 +1298,13 @@ var ClassItem = ({
676
1298
  width: itemRef.current?.getBoundingClientRect().width,
677
1299
  offset: [0, -15]
678
1300
  },
679
- /* @__PURE__ */ React6.createElement(
1301
+ /* @__PURE__ */ React13.createElement(
680
1302
  StyledListItemButton,
681
1303
  {
682
1304
  ref: itemRef,
683
1305
  dense: true,
684
1306
  disableGutters: true,
685
- showSortIndicator: isSearchActive,
1307
+ showSortIndicator: inputValue.length >= 2,
686
1308
  showActions: isSelected || isEditing,
687
1309
  shape: "rounded",
688
1310
  onDoubleClick: openEditMode,
@@ -690,30 +1312,31 @@ var ClassItem = ({
690
1312
  disabled,
691
1313
  focusVisibleClassName: "visible-class-item"
692
1314
  },
693
- /* @__PURE__ */ React6.createElement(SortableTrigger, { ...sortableTriggerProps }),
694
- /* @__PURE__ */ React6.createElement(Indicator, { isActive: isEditing, isError: !!error }, isEditing ? /* @__PURE__ */ React6.createElement(
695
- import_editor_ui2.EditableField,
1315
+ /* @__PURE__ */ React13.createElement(SortableTrigger, { ...sortableTriggerProps }),
1316
+ /* @__PURE__ */ React13.createElement(Indicator, { isActive: isEditing, isError: !!error }, isEditing ? /* @__PURE__ */ React13.createElement(
1317
+ import_editor_ui5.EditableField,
696
1318
  {
697
1319
  ref: editableRef,
698
- as: import_ui5.Typography,
1320
+ as: import_ui11.Typography,
699
1321
  variant: "caption",
700
1322
  ...getEditableProps()
701
1323
  }
702
- ) : /* @__PURE__ */ React6.createElement(import_editor_ui2.EllipsisWithTooltip, { title: label, as: import_ui5.Typography, variant: "caption" })),
703
- /* @__PURE__ */ React6.createElement(
704
- import_ui5.Tooltip,
1324
+ ) : /* @__PURE__ */ React13.createElement(import_editor_ui5.EllipsisWithTooltip, { title: label, as: import_ui11.Typography, variant: "caption" })),
1325
+ /* @__PURE__ */ React13.createElement(import_ui11.Box, { className: "class-item-locator" }, /* @__PURE__ */ React13.createElement(CssClassUsageTrigger, { id: id2, onClick: setSelectedCssUsage })),
1326
+ /* @__PURE__ */ React13.createElement(
1327
+ import_ui11.Tooltip,
705
1328
  {
706
1329
  placement: "top",
707
1330
  className: "class-item-more-actions",
708
- title: (0, import_i18n5.__)("More actions", "elementor")
1331
+ title: (0, import_i18n10.__)("More actions", "elementor")
709
1332
  },
710
- /* @__PURE__ */ React6.createElement(import_ui5.IconButton, { size: "tiny", ...(0, import_ui5.bindTrigger)(popupState), "aria-label": "More actions" }, /* @__PURE__ */ React6.createElement(import_icons5.DotsVerticalIcon, { fontSize: "tiny" }))
1333
+ /* @__PURE__ */ React13.createElement(import_ui11.IconButton, { size: "tiny", ...(0, import_ui11.bindTrigger)(popupState), "aria-label": "More actions" }, /* @__PURE__ */ React13.createElement(import_icons9.DotsVerticalIcon, { fontSize: "tiny" }))
711
1334
  )
712
1335
  )
713
- )), /* @__PURE__ */ React6.createElement(
714
- import_ui5.Menu,
1336
+ )), /* @__PURE__ */ React13.createElement(
1337
+ import_ui11.Menu,
715
1338
  {
716
- ...(0, import_ui5.bindMenu)(popupState),
1339
+ ...(0, import_ui11.bindMenu)(popupState),
717
1340
  anchorOrigin: {
718
1341
  vertical: "bottom",
719
1342
  horizontal: "right"
@@ -723,8 +1346,8 @@ var ClassItem = ({
723
1346
  horizontal: "right"
724
1347
  }
725
1348
  },
726
- /* @__PURE__ */ React6.createElement(
727
- import_editor_ui2.MenuListItem,
1349
+ /* @__PURE__ */ React13.createElement(
1350
+ import_editor_ui5.MenuListItem,
728
1351
  {
729
1352
  sx: { minWidth: "160px" },
730
1353
  onClick: () => {
@@ -732,62 +1355,50 @@ var ClassItem = ({
732
1355
  openEditMode();
733
1356
  }
734
1357
  },
735
- /* @__PURE__ */ React6.createElement(import_ui5.Typography, { variant: "caption", sx: { color: "text.primary" } }, (0, import_i18n5.__)("Rename", "elementor"))
1358
+ /* @__PURE__ */ React13.createElement(import_ui11.Typography, { variant: "caption", sx: { color: "text.primary" } }, (0, import_i18n10.__)("Rename", "elementor"))
736
1359
  ),
737
- /* @__PURE__ */ React6.createElement(
738
- import_editor_ui2.MenuListItem,
1360
+ /* @__PURE__ */ React13.createElement(
1361
+ import_editor_ui5.MenuListItem,
739
1362
  {
740
1363
  onClick: () => {
741
1364
  popupState.close();
742
1365
  openDialog({ id: id2, label });
743
1366
  }
744
1367
  },
745
- /* @__PURE__ */ React6.createElement(import_ui5.Typography, { variant: "caption", sx: { color: "error.light" } }, (0, import_i18n5.__)("Delete", "elementor"))
1368
+ /* @__PURE__ */ React13.createElement(import_ui11.Typography, { variant: "caption", sx: { color: "error.light" } }, (0, import_i18n10.__)("Delete", "elementor"))
746
1369
  )
747
1370
  ));
748
1371
  };
749
- var StyledListItemButtonV2 = (0, import_ui5.styled)(import_ui5.ListItemButton, {
1372
+ var StyledListItemButton = (0, import_ui11.styled)(import_ui11.ListItemButton, {
750
1373
  shouldForwardProp: (prop) => !["showActions", "showSortIndicator"].includes(prop)
751
1374
  })(
752
1375
  ({ showActions, showSortIndicator }) => `
753
- min-height: 36px;
1376
+ min-height: 36px;
754
1377
 
755
- &.visible-class-item {
756
- box-shadow: none !important;
757
- }
758
- .class-item-sortable-trigger {
759
- visibility: ${showSortIndicator && showActions ? "visible" : "hidden"};
760
- }
761
- &:hover&:not(:disabled) {
762
- .class-item-sortable-trigger {
763
- visibility: ${showSortIndicator ? "visible" : "hidden"};
764
- }
765
- }
766
- `
767
- );
768
- var StyledListItemButtonV1 = (0, import_ui5.styled)(import_ui5.ListItemButton, {
769
- shouldForwardProp: (prop) => !["showActions", "showSortIndicator"].includes(prop)
770
- })(
771
- ({ showActions }) => `
772
- min-height: 36px;
773
- &.visible-class-item {
774
- box-shadow: none !important;
775
- }
776
- .class-item-more-actions, .class-item-sortable-trigger {
777
- visibility: ${showActions ? "visible" : "hidden"};
778
- }
779
- .class-item-sortable-trigger {
780
- visibility: ${showActions ? "visible" : "hidden"};
781
- }
782
- &:hover&:not(:disabled) {
783
- .class-item-more-actions, .class-item-sortable-trigger {
784
- visibility: visible;
785
- }
786
- }
787
- `
1378
+ &.visible-class-item {
1379
+ box-shadow: none !important;
1380
+ }
1381
+
1382
+ .class-item-locator {
1383
+ visibility: hidden;
1384
+ }
1385
+
1386
+ .class-item-sortable-trigger {
1387
+ visibility: ${showSortIndicator && showActions ? "visible" : "hidden"};
1388
+ }
1389
+
1390
+ &:hover:not(:disabled) {
1391
+ .class-item-locator {
1392
+ visibility: visible;
1393
+ }
1394
+
1395
+ .class-item-sortable-trigger {
1396
+ visibility: ${showSortIndicator ? "visible" : "hidden"};
1397
+ }
1398
+ }
1399
+ `
788
1400
  );
789
- var StyledListItemButton = isVersion311IsActive ? StyledListItemButtonV2 : StyledListItemButtonV1;
790
- var Indicator = (0, import_ui5.styled)(import_ui5.Box, {
1401
+ var Indicator = (0, import_ui11.styled)(import_ui11.Box, {
791
1402
  shouldForwardProp: (prop) => !["isActive", "isError"].includes(prop)
792
1403
  })(({ theme, isActive, isError }) => ({
793
1404
  display: "flex",
@@ -816,68 +1427,126 @@ var validateLabel = (newLabel) => {
816
1427
  return result.errorMessage;
817
1428
  };
818
1429
 
819
- // src/components/class-manager/class-manager-class-not-found.tsx
820
- var React7 = __toESM(require("react"));
821
- var import_ui6 = require("@elementor/ui");
822
- var import_i18n6 = require("@wordpress/i18n");
823
- var CssClassNotFound = ({ onClear, searchValue }) => /* @__PURE__ */ React7.createElement(
824
- import_ui6.Stack,
1430
+ // src/components/class-manager/not-found.tsx
1431
+ var React14 = __toESM(require("react"));
1432
+ var import_icons10 = require("@elementor/icons");
1433
+ var import_ui12 = require("@elementor/ui");
1434
+ var import_i18n11 = require("@wordpress/i18n");
1435
+ var getNotFoundType = (searchValue, filters, filteredClasses) => {
1436
+ const searchNotFound = filteredClasses.length <= 0 && searchValue.length > 1;
1437
+ const filterNotFound = filters && filters.length === 0;
1438
+ const filterAndSearchNotFound = searchNotFound && filterNotFound;
1439
+ if (filterAndSearchNotFound) {
1440
+ return "filterAndSearch";
1441
+ }
1442
+ if (searchNotFound) {
1443
+ return "search";
1444
+ }
1445
+ if (filterNotFound) {
1446
+ return "filter";
1447
+ }
1448
+ return void 0;
1449
+ };
1450
+ var notFound = {
1451
+ filterAndSearch: {
1452
+ mainText: (0, import_i18n11.__)("Sorry, nothing matched.", "elementor"),
1453
+ sceneryText: (0, import_i18n11.__)("Try something else.", "elementor"),
1454
+ icon: /* @__PURE__ */ React14.createElement(import_icons10.PhotoIcon, { color: "inherit", fontSize: "large" })
1455
+ },
1456
+ search: {
1457
+ mainText: (0, import_i18n11.__)("Sorry, nothing matched", "elementor"),
1458
+ sceneryText: (0, import_i18n11.__)("Clear your input and try something else.", "elementor"),
1459
+ icon: /* @__PURE__ */ React14.createElement(import_icons10.PhotoIcon, { color: "inherit", fontSize: "large" })
1460
+ },
1461
+ filter: {
1462
+ mainText: (0, import_i18n11.__)("Sorry, nothing matched that search.", "elementor"),
1463
+ sceneryText: (0, import_i18n11.__)("Clear the filters and try something else.", "elementor"),
1464
+ icon: /* @__PURE__ */ React14.createElement(import_icons10.ColorSwatchIcon, { color: "inherit", fontSize: "large" })
1465
+ }
1466
+ };
1467
+ var NotFound = ({ notFoundType }) => {
1468
+ const {
1469
+ search: { onClearSearch, inputValue },
1470
+ filters: { onClearFilter }
1471
+ } = useSearchAndFilters();
1472
+ switch (notFoundType) {
1473
+ case "filter":
1474
+ return /* @__PURE__ */ React14.createElement(NotFoundLayout, { ...notFound.filter, onClear: onClearFilter });
1475
+ case "search":
1476
+ return /* @__PURE__ */ React14.createElement(NotFoundLayout, { ...notFound.search, searchValue: inputValue, onClear: onClearSearch });
1477
+ case "filterAndSearch":
1478
+ return /* @__PURE__ */ React14.createElement(
1479
+ NotFoundLayout,
1480
+ {
1481
+ ...notFound.filterAndSearch,
1482
+ onClear: () => {
1483
+ onClearFilter();
1484
+ onClearSearch();
1485
+ }
1486
+ }
1487
+ );
1488
+ }
1489
+ };
1490
+ var NotFoundLayout = ({ onClear, searchValue, mainText, sceneryText, icon }) => /* @__PURE__ */ React14.createElement(
1491
+ import_ui12.Stack,
825
1492
  {
826
1493
  color: "text.secondary",
827
1494
  pt: 5,
828
1495
  alignItems: "center",
829
1496
  gap: 1,
830
1497
  overflow: "hidden",
831
- maxWidth: "170px",
832
1498
  justifySelf: "center"
833
1499
  },
834
- /* @__PURE__ */ React7.createElement(FlippedColorSwatchIcon, { color: "inherit", fontSize: "large" }),
835
- /* @__PURE__ */ React7.createElement(import_ui6.Box, null, /* @__PURE__ */ React7.createElement(import_ui6.Typography, { align: "center", variant: "subtitle2", color: "inherit" }, (0, import_i18n6.__)("Sorry, nothing matched", "elementor")), /* @__PURE__ */ React7.createElement(
836
- import_ui6.Typography,
1500
+ icon,
1501
+ /* @__PURE__ */ React14.createElement(
1502
+ import_ui12.Box,
837
1503
  {
838
- variant: "subtitle2",
839
- color: "inherit",
840
1504
  sx: {
841
- display: "flex",
842
- width: "100%",
843
- justifyContent: "center"
1505
+ width: "100%"
844
1506
  }
845
1507
  },
846
- /* @__PURE__ */ React7.createElement("span", null, "\u201C"),
847
- /* @__PURE__ */ React7.createElement(
848
- "span",
1508
+ /* @__PURE__ */ React14.createElement(import_ui12.Typography, { align: "center", variant: "subtitle2", color: "inherit" }, mainText),
1509
+ searchValue && /* @__PURE__ */ React14.createElement(
1510
+ import_ui12.Typography,
849
1511
  {
850
- style: {
851
- maxWidth: "80%",
852
- overflow: "hidden",
853
- textOverflow: "ellipsis"
1512
+ variant: "subtitle2",
1513
+ color: "inherit",
1514
+ sx: {
1515
+ display: "flex",
1516
+ width: "100%",
1517
+ justifyContent: "center"
854
1518
  }
855
1519
  },
856
- searchValue
857
- ),
858
- /* @__PURE__ */ React7.createElement("span", null, "\u201D.")
859
- )),
860
- /* @__PURE__ */ React7.createElement(import_ui6.Typography, { align: "center", variant: "caption", color: "inherit" }, (0, import_i18n6.__)("Try something else.", "elementor"), /* @__PURE__ */ React7.createElement(import_ui6.Link, { color: "secondary", variant: "caption", component: "button", onClick: onClear }, (0, import_i18n6.__)("Clear & try again", "elementor")))
1520
+ /* @__PURE__ */ React14.createElement("span", null, "\u201C"),
1521
+ /* @__PURE__ */ React14.createElement(
1522
+ "span",
1523
+ {
1524
+ style: {
1525
+ maxWidth: "80%",
1526
+ overflow: "hidden",
1527
+ textOverflow: "ellipsis"
1528
+ }
1529
+ },
1530
+ searchValue
1531
+ ),
1532
+ /* @__PURE__ */ React14.createElement("span", null, "\u201D.")
1533
+ )
1534
+ ),
1535
+ /* @__PURE__ */ React14.createElement(import_ui12.Typography, { align: "center", variant: "caption", color: "inherit" }, sceneryText),
1536
+ /* @__PURE__ */ React14.createElement(import_ui12.Typography, { align: "center", variant: "caption", color: "inherit" }, /* @__PURE__ */ React14.createElement(import_ui12.Link, { color: "secondary", variant: "caption", component: "button", onClick: onClear }, (0, import_i18n11.__)("Clear & try again", "elementor")))
861
1537
  );
862
1538
 
863
1539
  // src/components/class-manager/global-classes-list.tsx
864
- var GlobalClassesList = ({ disabled, searchValue, onSearch }) => {
1540
+ var GlobalClassesList = ({ disabled }) => {
1541
+ const {
1542
+ search: { debouncedValue: searchValue }
1543
+ } = useSearchAndFilters();
865
1544
  const cssClasses = useOrderedClasses();
866
- const dispatch5 = (0, import_store14.__useDispatch)();
1545
+ const dispatch5 = (0, import_store16.__useDispatch)();
1546
+ const filters = useFilters();
867
1547
  const [classesOrder, reorderClasses] = useReorder();
868
- const lowercaseLabels = (0, import_react4.useMemo)(
869
- () => cssClasses.map((cssClass) => ({
870
- ...cssClass,
871
- lowerLabel: cssClass.label.toLowerCase()
872
- })),
873
- [cssClasses]
874
- );
875
- const filteredClasses = (0, import_react4.useMemo)(() => {
876
- return searchValue.length > 1 ? lowercaseLabels.filter(
877
- (cssClass) => cssClass.lowerLabel.toLowerCase().includes(searchValue.toLowerCase())
878
- ) : cssClasses;
879
- }, [searchValue, cssClasses, lowercaseLabels]);
880
- (0, import_react4.useEffect)(() => {
1548
+ const filteredCssClasses = useFilteredCssClasses();
1549
+ (0, import_react7.useEffect)(() => {
881
1550
  const handler = (event) => {
882
1551
  if (event.key === "z" && (event.ctrlKey || event.metaKey)) {
883
1552
  event.stopImmediatePropagation();
@@ -895,13 +1564,16 @@ var GlobalClassesList = ({ disabled, searchValue, onSearch }) => {
895
1564
  return () => window.removeEventListener("keydown", handler);
896
1565
  }, [dispatch5]);
897
1566
  if (!cssClasses?.length) {
898
- return /* @__PURE__ */ React8.createElement(EmptyState, null);
1567
+ return /* @__PURE__ */ React15.createElement(EmptyState, null);
1568
+ }
1569
+ const notFoundType = getNotFoundType(searchValue, filters, filteredCssClasses);
1570
+ if (notFoundType) {
1571
+ return /* @__PURE__ */ React15.createElement(NotFound, { notFoundType });
899
1572
  }
900
- return /* @__PURE__ */ React8.createElement(DeleteConfirmationProvider, null, filteredClasses.length <= 0 && searchValue.length > 1 ? /* @__PURE__ */ React8.createElement(CssClassNotFound, { onClear: () => onSearch(""), searchValue }) : /* @__PURE__ */ React8.createElement(import_ui7.List, { sx: { display: "flex", flexDirection: "column", gap: 0.5 } }, /* @__PURE__ */ React8.createElement(SortableProvider, { value: classesOrder, onChange: reorderClasses }, filteredClasses?.map(({ id: id2, label }) => {
901
- return /* @__PURE__ */ React8.createElement(SortableItem, { key: id2, id: id2 }, ({ isDragged, isDragPlaceholder, triggerProps, triggerStyle }) => /* @__PURE__ */ React8.createElement(
1573
+ return /* @__PURE__ */ React15.createElement(DeleteConfirmationProvider, null, /* @__PURE__ */ React15.createElement(import_ui13.List, { sx: { display: "flex", flexDirection: "column", gap: 0.5 } }, /* @__PURE__ */ React15.createElement(SortableProvider, { value: classesOrder, onChange: reorderClasses }, filteredCssClasses?.map(({ id: id2, label }) => {
1574
+ return /* @__PURE__ */ React15.createElement(SortableItem, { key: id2, id: id2 }, ({ isDragged, isDragPlaceholder, triggerProps, triggerStyle }) => /* @__PURE__ */ React15.createElement(
902
1575
  ClassItem,
903
1576
  {
904
- isSearchActive: searchValue.length < 2,
905
1577
  id: id2,
906
1578
  label,
907
1579
  renameClass: (newLabel) => {
@@ -921,23 +1593,49 @@ var GlobalClassesList = ({ disabled, searchValue, onSearch }) => {
921
1593
  ));
922
1594
  }))));
923
1595
  };
924
- var EmptyState = () => /* @__PURE__ */ React8.createElement(import_ui7.Stack, { alignItems: "center", gap: 1.5, pt: 10, px: 0.5, maxWidth: "260px", margin: "auto" }, /* @__PURE__ */ React8.createElement(FlippedColorSwatchIcon, { fontSize: "large" }), /* @__PURE__ */ React8.createElement(StyledHeader, { variant: "subtitle2", component: "h2", color: "text.secondary" }, (0, import_i18n7.__)("There are no global classes yet.", "elementor")), /* @__PURE__ */ React8.createElement(import_ui7.Typography, { align: "center", variant: "caption", color: "text.secondary" }, (0, import_i18n7.__)(
1596
+ var EmptyState = () => /* @__PURE__ */ React15.createElement(import_ui13.Stack, { alignItems: "center", gap: 1.5, pt: 10, px: 0.5, maxWidth: "260px", margin: "auto" }, /* @__PURE__ */ React15.createElement(FlippedColorSwatchIcon, { fontSize: "large" }), /* @__PURE__ */ React15.createElement(StyledHeader, { variant: "subtitle2", component: "h2", color: "text.secondary" }, (0, import_i18n12.__)("There are no global classes yet.", "elementor")), /* @__PURE__ */ React15.createElement(import_ui13.Typography, { align: "center", variant: "caption", color: "text.secondary" }, (0, import_i18n12.__)(
925
1597
  "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.",
926
1598
  "elementor"
927
1599
  )));
928
- var StyledHeader = (0, import_ui7.styled)(import_ui7.Typography)(({ theme, variant }) => ({
1600
+ var StyledHeader = (0, import_ui13.styled)(import_ui13.Typography)(({ theme, variant }) => ({
929
1601
  "&.MuiTypography-root": {
930
1602
  ...theme.typography[variant]
931
1603
  }
932
1604
  }));
933
1605
  var useReorder = () => {
934
- const dispatch5 = (0, import_store14.__useDispatch)();
1606
+ const dispatch5 = (0, import_store16.__useDispatch)();
935
1607
  const order = useClassesOrder();
936
1608
  const reorder = (newIds) => {
937
1609
  dispatch5(slice.actions.setOrder(newIds));
938
1610
  };
939
1611
  return [order, reorder];
940
1612
  };
1613
+ var useFilteredCssClasses = () => {
1614
+ const cssClasses = useOrderedClasses();
1615
+ const {
1616
+ search: { debouncedValue: searchValue }
1617
+ } = useSearchAndFilters();
1618
+ const filters = useFilters();
1619
+ const lowercaseLabels = (0, import_react7.useMemo)(
1620
+ () => cssClasses.map((cssClass) => ({
1621
+ ...cssClass,
1622
+ lowerLabel: cssClass.label.toLowerCase()
1623
+ })),
1624
+ [cssClasses]
1625
+ );
1626
+ const filteredClasses = (0, import_react7.useMemo)(() => {
1627
+ if (searchValue.length > 1) {
1628
+ return lowercaseLabels.filter((cssClass) => cssClass.lowerLabel.includes(searchValue.toLowerCase()));
1629
+ }
1630
+ return cssClasses;
1631
+ }, [searchValue, cssClasses, lowercaseLabels]);
1632
+ return (0, import_react7.useMemo)(() => {
1633
+ if (filters && filters.length > 0) {
1634
+ return filteredClasses.filter((cssClass) => filters.includes(cssClass.id));
1635
+ }
1636
+ return filteredClasses;
1637
+ }, [filteredClasses, filters]);
1638
+ };
941
1639
 
942
1640
  // src/components/class-manager/panel-interactions.ts
943
1641
  function blockPanelInteractions() {
@@ -950,67 +1648,62 @@ function unblockPanelInteractions() {
950
1648
  }
951
1649
 
952
1650
  // src/components/class-manager/save-changes-dialog.tsx
953
- var React9 = __toESM(require("react"));
954
- var import_react5 = require("react");
955
- var import_icons6 = require("@elementor/icons");
956
- var import_ui8 = require("@elementor/ui");
1651
+ var React16 = __toESM(require("react"));
1652
+ var import_react8 = require("react");
1653
+ var import_icons11 = require("@elementor/icons");
1654
+ var import_ui14 = require("@elementor/ui");
957
1655
  var TITLE_ID2 = "save-changes-dialog";
958
- var SaveChangesDialog = ({ children, onClose }) => /* @__PURE__ */ React9.createElement(import_ui8.Dialog, { open: true, onClose, "aria-labelledby": TITLE_ID2, maxWidth: "xs" }, children);
959
- var SaveChangesDialogTitle = ({ children }) => /* @__PURE__ */ React9.createElement(import_ui8.DialogTitle, { id: TITLE_ID2, display: "flex", alignItems: "center", gap: 1, sx: { lineHeight: 1 } }, /* @__PURE__ */ React9.createElement(import_icons6.AlertTriangleFilledIcon, { color: "secondary" }), children);
960
- var SaveChangesDialogContent = ({ children }) => /* @__PURE__ */ React9.createElement(import_ui8.DialogContent, null, children);
961
- var SaveChangesDialogContentText = (props) => /* @__PURE__ */ React9.createElement(import_ui8.DialogContentText, { variant: "body2", color: "textPrimary", display: "flex", flexDirection: "column", ...props });
1656
+ var SaveChangesDialog = ({ children, onClose }) => /* @__PURE__ */ React16.createElement(import_ui14.Dialog, { open: true, onClose, "aria-labelledby": TITLE_ID2, maxWidth: "xs" }, children);
1657
+ var SaveChangesDialogTitle = ({ children }) => /* @__PURE__ */ React16.createElement(import_ui14.DialogTitle, { id: TITLE_ID2, display: "flex", alignItems: "center", gap: 1, sx: { lineHeight: 1 } }, /* @__PURE__ */ React16.createElement(import_icons11.AlertTriangleFilledIcon, { color: "secondary" }), children);
1658
+ var SaveChangesDialogContent = ({ children }) => /* @__PURE__ */ React16.createElement(import_ui14.DialogContent, null, children);
1659
+ var SaveChangesDialogContentText = (props) => /* @__PURE__ */ React16.createElement(import_ui14.DialogContentText, { variant: "body2", color: "textPrimary", display: "flex", flexDirection: "column", ...props });
962
1660
  var SaveChangesDialogActions = ({ actions }) => {
963
- const [isConfirming, setIsConfirming] = (0, import_react5.useState)(false);
1661
+ const [isConfirming, setIsConfirming] = (0, import_react8.useState)(false);
964
1662
  const { cancel, confirm, discard } = actions;
965
1663
  const onConfirm = async () => {
966
1664
  setIsConfirming(true);
967
1665
  await confirm.action();
968
1666
  setIsConfirming(false);
969
1667
  };
970
- return /* @__PURE__ */ React9.createElement(import_ui8.DialogActions, null, cancel && /* @__PURE__ */ React9.createElement(import_ui8.Button, { variant: "text", color: "secondary", onClick: cancel.action }, cancel.label), discard && /* @__PURE__ */ React9.createElement(import_ui8.Button, { variant: "text", color: "secondary", onClick: discard.action }, discard.label), /* @__PURE__ */ React9.createElement(import_ui8.Button, { variant: "contained", color: "secondary", onClick: onConfirm, loading: isConfirming }, confirm.label));
1668
+ return /* @__PURE__ */ React16.createElement(import_ui14.DialogActions, null, cancel && /* @__PURE__ */ React16.createElement(import_ui14.Button, { variant: "text", color: "secondary", onClick: cancel.action }, cancel.label), discard && /* @__PURE__ */ React16.createElement(import_ui14.Button, { variant: "text", color: "secondary", onClick: discard.action }, discard.label), /* @__PURE__ */ React16.createElement(import_ui14.Button, { variant: "contained", color: "secondary", onClick: onConfirm, loading: isConfirming }, confirm.label));
971
1669
  };
972
1670
  SaveChangesDialog.Title = SaveChangesDialogTitle;
973
1671
  SaveChangesDialog.Content = SaveChangesDialogContent;
974
1672
  SaveChangesDialog.ContentText = SaveChangesDialogContentText;
975
1673
  SaveChangesDialog.Actions = SaveChangesDialogActions;
976
1674
  var useDialog = () => {
977
- const [isOpen, setIsOpen] = (0, import_react5.useState)(false);
1675
+ const [isOpen, setIsOpen] = (0, import_react8.useState)(false);
978
1676
  const open = () => setIsOpen(true);
979
1677
  const close = () => setIsOpen(false);
980
1678
  return { isOpen, open, close };
981
1679
  };
982
1680
 
983
1681
  // src/components/class-manager/class-manager-panel.tsx
984
- var isVersion311IsActive2 = (0, import_editor_v1_adapters5.isExperimentActive)(import_editor_editing_panel2.EXPERIMENTAL_FEATURES.V_3_31);
985
1682
  var id = "global-classes-manager";
986
1683
  var { panel, usePanelActions } = (0, import_editor_panels.__createPanel)({
987
1684
  id,
988
1685
  component: ClassManagerPanel,
989
1686
  allowedEditModes: ["edit", id],
990
1687
  onOpen: () => {
991
- (0, import_editor_v1_adapters5.changeEditMode)(id);
1688
+ (0, import_editor_v1_adapters3.changeEditMode)(id);
992
1689
  blockPanelInteractions();
993
1690
  },
994
1691
  onClose: () => {
995
- (0, import_editor_v1_adapters5.changeEditMode)("edit");
1692
+ (0, import_editor_v1_adapters3.changeEditMode)("edit");
996
1693
  unblockPanelInteractions();
997
1694
  }
998
1695
  });
999
1696
  function ClassManagerPanel() {
1000
- const { debouncedValue, inputValue, handleChange } = (0, import_utils2.useDebounceState)({
1001
- delay: 300,
1002
- initialValue: ""
1003
- });
1004
1697
  const isDirty2 = useDirtyState();
1005
1698
  const { close: closePanel } = usePanelActions();
1006
1699
  const { open: openSaveChangesDialog, close: closeSaveChangesDialog, isOpen: isSaveChangesDialogOpen } = useDialog();
1007
1700
  const { mutateAsync: publish, isPending: isPublishing } = usePublish();
1008
1701
  const resetAndClosePanel = () => {
1009
- (0, import_store16.__dispatch)(slice.actions.resetToInitialState({ context: "frontend" }));
1702
+ (0, import_store18.__dispatch)(slice.actions.resetToInitialState({ context: "frontend" }));
1010
1703
  closeSaveChangesDialog();
1011
1704
  };
1012
1705
  usePreventUnload();
1013
- return /* @__PURE__ */ React10.createElement(import_editor_ui3.ThemeProvider, null, /* @__PURE__ */ React10.createElement(import_ui9.ErrorBoundary, { fallback: /* @__PURE__ */ React10.createElement(ErrorBoundaryFallback, null) }, /* @__PURE__ */ React10.createElement(import_editor_panels.Panel, null, /* @__PURE__ */ React10.createElement(import_editor_panels.PanelHeader, null, /* @__PURE__ */ React10.createElement(import_ui9.Stack, { p: 1, pl: 2, width: "100%", direction: "row", alignItems: "center" }, /* @__PURE__ */ React10.createElement(import_editor_panels.PanelHeaderTitle, { sx: { display: "flex", alignItems: "center", gap: 0.5 } }, /* @__PURE__ */ React10.createElement(FlippedColorSwatchIcon, { fontSize: "inherit" }), (0, import_i18n8.__)("Class Manager", "elementor")), /* @__PURE__ */ React10.createElement(
1706
+ return /* @__PURE__ */ React17.createElement(import_editor_ui6.ThemeProvider, null, /* @__PURE__ */ React17.createElement(import_ui15.ErrorBoundary, { fallback: /* @__PURE__ */ React17.createElement(ErrorBoundaryFallback, null) }, /* @__PURE__ */ React17.createElement(import_editor_panels.Panel, null, /* @__PURE__ */ React17.createElement(SearchAndFilterProvider, null, /* @__PURE__ */ React17.createElement(import_editor_panels.PanelHeader, null, /* @__PURE__ */ React17.createElement(import_ui15.Stack, { p: 1, pl: 2, width: "100%", direction: "row", alignItems: "center" }, /* @__PURE__ */ React17.createElement(import_ui15.Stack, { width: "100%", direction: "row", gap: 1 }, /* @__PURE__ */ React17.createElement(import_editor_panels.PanelHeaderTitle, { sx: { display: "flex", alignItems: "center", gap: 0.5 } }, /* @__PURE__ */ React17.createElement(FlippedColorSwatchIcon, { fontSize: "inherit" }), (0, import_i18n13.__)("Class Manager", "elementor")), /* @__PURE__ */ React17.createElement(TotalCssClassCounter, null)), /* @__PURE__ */ React17.createElement(
1014
1707
  CloseButton,
1015
1708
  {
1016
1709
  sx: { marginLeft: "auto" },
@@ -1023,7 +1716,7 @@ function ClassManagerPanel() {
1023
1716
  closePanel();
1024
1717
  }
1025
1718
  }
1026
- ))), /* @__PURE__ */ React10.createElement(
1719
+ ))), /* @__PURE__ */ React17.createElement(
1027
1720
  import_editor_panels.PanelBody,
1028
1721
  {
1029
1722
  sx: {
@@ -1032,16 +1725,10 @@ function ClassManagerPanel() {
1032
1725
  height: "100%"
1033
1726
  }
1034
1727
  },
1035
- isVersion311IsActive2 && /* @__PURE__ */ React10.createElement(React10.Fragment, null, /* @__PURE__ */ React10.createElement(ClassManagerSearch, { searchValue: inputValue, onChange: handleChange }), /* @__PURE__ */ React10.createElement(
1036
- import_ui9.Divider,
1037
- {
1038
- sx: {
1039
- borderWidth: "1px 0 0 0"
1040
- }
1041
- }
1042
- )),
1043
- /* @__PURE__ */ React10.createElement(
1044
- import_ui9.Box,
1728
+ /* @__PURE__ */ React17.createElement(import_ui15.Box, { px: 2, pb: 1 }, /* @__PURE__ */ React17.createElement(import_ui15.Stack, { direction: "row", justifyContent: "spaceBetween", gap: 0.5, sx: { pb: 0.5 } }, /* @__PURE__ */ React17.createElement(import_ui15.Box, { sx: { flexGrow: 1 } }, /* @__PURE__ */ React17.createElement(ClassManagerSearch, null)), /* @__PURE__ */ React17.createElement(CssClassFilter, null)), /* @__PURE__ */ React17.createElement(ActiveFilters, null)),
1729
+ /* @__PURE__ */ React17.createElement(import_ui15.Divider, null),
1730
+ /* @__PURE__ */ React17.createElement(
1731
+ import_ui15.Box,
1045
1732
  {
1046
1733
  px: 2,
1047
1734
  sx: {
@@ -1049,17 +1736,10 @@ function ClassManagerPanel() {
1049
1736
  overflowY: "auto"
1050
1737
  }
1051
1738
  },
1052
- /* @__PURE__ */ React10.createElement(
1053
- GlobalClassesList,
1054
- {
1055
- disabled: isPublishing,
1056
- searchValue: debouncedValue,
1057
- onSearch: handleChange
1058
- }
1059
- )
1739
+ /* @__PURE__ */ React17.createElement(GlobalClassesList, { disabled: isPublishing })
1060
1740
  )
1061
- ), /* @__PURE__ */ React10.createElement(import_editor_panels.PanelFooter, null, /* @__PURE__ */ React10.createElement(
1062
- import_ui9.Button,
1741
+ ), /* @__PURE__ */ React17.createElement(import_editor_panels.PanelFooter, null, /* @__PURE__ */ React17.createElement(
1742
+ import_ui15.Button,
1063
1743
  {
1064
1744
  fullWidth: true,
1065
1745
  size: "small",
@@ -1069,19 +1749,19 @@ function ClassManagerPanel() {
1069
1749
  disabled: !isDirty2,
1070
1750
  loading: isPublishing
1071
1751
  },
1072
- (0, import_i18n8.__)("Save changes", "elementor")
1073
- )))), /* @__PURE__ */ React10.createElement(ClassManagerIntroduction, null), isSaveChangesDialogOpen && /* @__PURE__ */ React10.createElement(SaveChangesDialog, null, /* @__PURE__ */ React10.createElement(import_ui9.DialogHeader, { onClose: closeSaveChangesDialog, logo: false }, /* @__PURE__ */ React10.createElement(SaveChangesDialog.Title, null, (0, import_i18n8.__)("You have unsaved changes", "elementor"))), /* @__PURE__ */ React10.createElement(SaveChangesDialog.Content, null, /* @__PURE__ */ React10.createElement(SaveChangesDialog.ContentText, null, (0, import_i18n8.__)("You have unsaved changes in the Class Manager.", "elementor")), /* @__PURE__ */ React10.createElement(SaveChangesDialog.ContentText, null, (0, import_i18n8.__)("To avoid losing your updates, save your changes before leaving.", "elementor"))), /* @__PURE__ */ React10.createElement(
1752
+ (0, import_i18n13.__)("Save changes", "elementor")
1753
+ ))))), /* @__PURE__ */ React17.createElement(ClassManagerIntroduction, null), isSaveChangesDialogOpen && /* @__PURE__ */ React17.createElement(SaveChangesDialog, null, /* @__PURE__ */ React17.createElement(import_ui15.DialogHeader, { onClose: closeSaveChangesDialog, logo: false }, /* @__PURE__ */ React17.createElement(SaveChangesDialog.Title, null, (0, import_i18n13.__)("You have unsaved changes", "elementor"))), /* @__PURE__ */ React17.createElement(SaveChangesDialog.Content, null, /* @__PURE__ */ React17.createElement(SaveChangesDialog.ContentText, null, (0, import_i18n13.__)("You have unsaved changes in the Class Manager.", "elementor")), /* @__PURE__ */ React17.createElement(SaveChangesDialog.ContentText, null, (0, import_i18n13.__)("To avoid losing your updates, save your changes before leaving.", "elementor"))), /* @__PURE__ */ React17.createElement(
1074
1754
  SaveChangesDialog.Actions,
1075
1755
  {
1076
1756
  actions: {
1077
1757
  discard: {
1078
- label: (0, import_i18n8.__)("Discard", "elementor"),
1758
+ label: (0, import_i18n13.__)("Discard", "elementor"),
1079
1759
  action: () => {
1080
1760
  resetAndClosePanel();
1081
1761
  }
1082
1762
  },
1083
1763
  confirm: {
1084
- label: (0, import_i18n8.__)("Save & Continue", "elementor"),
1764
+ label: (0, import_i18n13.__)("Save & Continue", "elementor"),
1085
1765
  action: async () => {
1086
1766
  await publish();
1087
1767
  closeSaveChangesDialog();
@@ -1092,11 +1772,11 @@ function ClassManagerPanel() {
1092
1772
  }
1093
1773
  )));
1094
1774
  }
1095
- var CloseButton = ({ onClose, ...props }) => /* @__PURE__ */ React10.createElement(import_ui9.IconButton, { size: "small", color: "secondary", onClick: onClose, "aria-label": "Close", ...props }, /* @__PURE__ */ React10.createElement(import_icons7.XIcon, { fontSize: "small" }));
1096
- var ErrorBoundaryFallback = () => /* @__PURE__ */ React10.createElement(import_ui9.Box, { role: "alert", sx: { minHeight: "100%", p: 2 } }, /* @__PURE__ */ React10.createElement(import_ui9.Alert, { severity: "error", sx: { mb: 2, maxWidth: 400, textAlign: "center" } }, /* @__PURE__ */ React10.createElement("strong", null, (0, import_i18n8.__)("Something went wrong", "elementor"))));
1775
+ var CloseButton = ({ onClose, ...props }) => /* @__PURE__ */ React17.createElement(import_ui15.IconButton, { size: "small", color: "secondary", onClick: onClose, "aria-label": "Close", ...props }, /* @__PURE__ */ React17.createElement(import_icons12.XIcon, { fontSize: "small" }));
1776
+ var ErrorBoundaryFallback = () => /* @__PURE__ */ React17.createElement(import_ui15.Box, { role: "alert", sx: { minHeight: "100%", p: 2 } }, /* @__PURE__ */ React17.createElement(import_ui15.Alert, { severity: "error", sx: { mb: 2, maxWidth: 400, textAlign: "center" } }, /* @__PURE__ */ React17.createElement("strong", null, (0, import_i18n13.__)("Something went wrong", "elementor"))));
1097
1777
  var usePreventUnload = () => {
1098
1778
  const isDirty2 = useDirtyState();
1099
- (0, import_react6.useEffect)(() => {
1779
+ (0, import_react9.useEffect)(() => {
1100
1780
  const handleBeforeUnload = (event) => {
1101
1781
  if (isDirty2) {
1102
1782
  event.preventDefault();
@@ -1109,23 +1789,35 @@ var usePreventUnload = () => {
1109
1789
  }, [isDirty2]);
1110
1790
  };
1111
1791
  var usePublish = () => {
1112
- return (0, import_query.useMutation)({
1792
+ return (0, import_query3.useMutation)({
1113
1793
  mutationFn: () => saveGlobalClasses({ context: "frontend" }),
1114
1794
  onSuccess: async () => {
1115
- (0, import_editor_documents2.setDocumentModifiedStatus)(false);
1795
+ (0, import_editor_documents4.setDocumentModifiedStatus)(false);
1116
1796
  if (hasDeletedItems()) {
1117
1797
  await onDelete();
1118
1798
  }
1119
1799
  }
1120
1800
  });
1121
1801
  };
1802
+ var TotalCssClassCounter = () => {
1803
+ const filters = useFilters();
1804
+ const cssClasses = useClassesOrder();
1805
+ return /* @__PURE__ */ React17.createElement(
1806
+ import_ui15.Chip,
1807
+ {
1808
+ size: "small",
1809
+ label: filters ? `${filters.length} / ${cssClasses?.length}` : cssClasses?.length
1810
+ }
1811
+ );
1812
+ };
1122
1813
 
1123
1814
  // src/components/class-manager/class-manager-button.tsx
1124
1815
  var ClassManagerButton = () => {
1125
- const document = (0, import_editor_documents3.__useActiveDocument)();
1816
+ const document = (0, import_editor_documents5.__useActiveDocument)();
1126
1817
  const { open: openPanel } = usePanelActions();
1127
- const { save: saveDocument } = (0, import_editor_documents3.__useActiveDocumentActions)();
1818
+ const { save: saveDocument } = (0, import_editor_documents5.__useActiveDocumentActions)();
1128
1819
  const { open: openSaveChangesDialog, close: closeSaveChangesDialog, isOpen: isSaveChangesDialogOpen } = useDialog();
1820
+ const { prefetchClassesUsage } = usePrefetchCssClassUsage();
1129
1821
  const { userCan } = (0, import_editor_styles_repository3.useUserStylesCapability)();
1130
1822
  const isUserAllowedToUpdateClass = userCan(globalClassesStylesProvider.getKey()).update;
1131
1823
  if (!isUserAllowedToUpdateClass) {
@@ -1137,24 +1829,26 @@ var ClassManagerButton = () => {
1137
1829
  return;
1138
1830
  }
1139
1831
  openPanel();
1832
+ prefetchClassesUsage();
1140
1833
  };
1141
- return /* @__PURE__ */ React11.createElement(React11.Fragment, null, /* @__PURE__ */ React11.createElement(import_ui10.Tooltip, { title: (0, import_i18n9.__)("Class Manager", "elementor"), placement: "top" }, /* @__PURE__ */ React11.createElement(import_ui10.IconButton, { size: "tiny", onClick: handleOpenPanel, sx: { marginInlineEnd: -0.75 } }, /* @__PURE__ */ React11.createElement(FlippedColorSwatchIcon, { fontSize: "tiny" }))), isSaveChangesDialogOpen && /* @__PURE__ */ React11.createElement(SaveChangesDialog, null, /* @__PURE__ */ React11.createElement(SaveChangesDialog.Title, null, (0, import_i18n9.__)("You have unsaved changes", "elementor")), /* @__PURE__ */ React11.createElement(SaveChangesDialog.Content, null, /* @__PURE__ */ React11.createElement(SaveChangesDialog.ContentText, { sx: { mb: 2 } }, (0, import_i18n9.__)(
1834
+ return /* @__PURE__ */ React18.createElement(React18.Fragment, null, /* @__PURE__ */ React18.createElement(import_ui16.Tooltip, { title: (0, import_i18n14.__)("Class Manager", "elementor"), placement: "top" }, /* @__PURE__ */ React18.createElement(import_ui16.IconButton, { size: "tiny", onClick: handleOpenPanel, sx: { marginInlineEnd: -0.75 } }, /* @__PURE__ */ React18.createElement(FlippedColorSwatchIcon, { fontSize: "tiny" }))), isSaveChangesDialogOpen && /* @__PURE__ */ React18.createElement(SaveChangesDialog, null, /* @__PURE__ */ React18.createElement(SaveChangesDialog.Title, null, (0, import_i18n14.__)("You have unsaved changes", "elementor")), /* @__PURE__ */ React18.createElement(SaveChangesDialog.Content, null, /* @__PURE__ */ React18.createElement(SaveChangesDialog.ContentText, { sx: { mb: 2 } }, (0, import_i18n14.__)(
1142
1835
  "To open the Class Manager, save your page first. You can't continue without saving.",
1143
1836
  "elementor"
1144
- ))), /* @__PURE__ */ React11.createElement(
1837
+ ))), /* @__PURE__ */ React18.createElement(
1145
1838
  SaveChangesDialog.Actions,
1146
1839
  {
1147
1840
  actions: {
1148
1841
  cancel: {
1149
- label: (0, import_i18n9.__)("Stay here", "elementor"),
1842
+ label: (0, import_i18n14.__)("Stay here", "elementor"),
1150
1843
  action: closeSaveChangesDialog
1151
1844
  },
1152
1845
  confirm: {
1153
- label: (0, import_i18n9.__)("Save & Continue", "elementor"),
1846
+ label: (0, import_i18n14.__)("Save & Continue", "elementor"),
1154
1847
  action: async () => {
1155
1848
  await saveDocument();
1156
1849
  closeSaveChangesDialog();
1157
1850
  openPanel();
1851
+ prefetchClassesUsage();
1158
1852
  }
1159
1853
  }
1160
1854
  }
@@ -1162,12 +1856,56 @@ var ClassManagerButton = () => {
1162
1856
  )));
1163
1857
  };
1164
1858
 
1859
+ // src/components/convert-local-class-to-global-class.tsx
1860
+ var React19 = __toESM(require("react"));
1861
+ var import_editor_styles_repository4 = require("@elementor/editor-styles-repository");
1862
+ var import_editor_ui7 = require("@elementor/editor-ui");
1863
+ var import_ui17 = require("@elementor/ui");
1864
+ var import_i18n15 = require("@wordpress/i18n");
1865
+ var ConvertLocalClassToGlobalClass = (props) => {
1866
+ const localStyleData = props.styleDef;
1867
+ const handleConversion = () => {
1868
+ const newClassName = createClassName(`converted-class-`);
1869
+ if (!localStyleData) {
1870
+ throw new Error("Style definition is required for converting local class to global class.");
1871
+ }
1872
+ const newId = globalClassesStylesProvider.actions.create?.(newClassName, localStyleData.variants);
1873
+ if (newId) {
1874
+ props.successCallback(newId);
1875
+ }
1876
+ };
1877
+ return /* @__PURE__ */ React19.createElement(React19.Fragment, null, /* @__PURE__ */ React19.createElement(
1878
+ import_editor_ui7.MenuListItem,
1879
+ {
1880
+ disabled: !props.canConvert,
1881
+ onClick: handleConversion,
1882
+ dense: true,
1883
+ sx: {
1884
+ "&.Mui-focusVisible": {
1885
+ border: "none",
1886
+ boxShadow: "none !important",
1887
+ backgroundColor: "transparent"
1888
+ }
1889
+ }
1890
+ },
1891
+ (0, import_i18n15.__)("Convert to global class", "elementor")
1892
+ ), /* @__PURE__ */ React19.createElement(import_ui17.Divider, null));
1893
+ };
1894
+ function createClassName(prefix) {
1895
+ let i = 1;
1896
+ let newClassName = `${prefix}${i}`;
1897
+ while (!(0, import_editor_styles_repository4.validateStyleLabel)(newClassName, "create").isValid) {
1898
+ newClassName = `${prefix}${++i}`;
1899
+ }
1900
+ return newClassName;
1901
+ }
1902
+
1165
1903
  // src/components/populate-store.tsx
1166
- var import_react7 = require("react");
1167
- var import_store18 = require("@elementor/store");
1904
+ var import_react10 = require("react");
1905
+ var import_store20 = require("@elementor/store");
1168
1906
  function PopulateStore() {
1169
- const dispatch5 = (0, import_store18.__useDispatch)();
1170
- (0, import_react7.useEffect)(() => {
1907
+ const dispatch5 = (0, import_store20.__useDispatch)();
1908
+ (0, import_react10.useEffect)(() => {
1171
1909
  Promise.all([apiClient.all("preview"), apiClient.all("frontend")]).then(
1172
1910
  ([previewRes, frontendRes]) => {
1173
1911
  const { data: previewData } = previewRes;
@@ -1191,51 +1929,55 @@ function PopulateStore() {
1191
1929
  }
1192
1930
 
1193
1931
  // src/sync-with-document-save.ts
1194
- var import_editor_documents4 = require("@elementor/editor-documents");
1195
- var import_editor_v1_adapters6 = require("@elementor/editor-v1-adapters");
1196
- var import_store20 = require("@elementor/store");
1932
+ var import_editor_documents6 = require("@elementor/editor-documents");
1933
+ var import_editor_v1_adapters4 = require("@elementor/editor-v1-adapters");
1934
+ var import_store22 = require("@elementor/store");
1197
1935
  function syncWithDocumentSave() {
1198
1936
  const unsubscribe = syncDirtyState();
1199
1937
  bindSaveAction();
1200
1938
  return unsubscribe;
1201
1939
  }
1202
1940
  function syncDirtyState() {
1203
- return (0, import_store20.__subscribeWithSelector)(selectIsDirty, () => {
1941
+ return (0, import_store22.__subscribeWithSelector)(selectIsDirty, () => {
1204
1942
  if (!isDirty()) {
1205
1943
  return;
1206
1944
  }
1207
- (0, import_editor_documents4.setDocumentModifiedStatus)(true);
1945
+ (0, import_editor_documents6.setDocumentModifiedStatus)(true);
1208
1946
  });
1209
1947
  }
1210
1948
  function bindSaveAction() {
1211
- (0, import_editor_v1_adapters6.registerDataHook)("after", "document/save/save", (args) => {
1949
+ (0, import_editor_v1_adapters4.registerDataHook)("after", "document/save/save", (args) => {
1212
1950
  return saveGlobalClasses({
1213
1951
  context: args.status === "publish" ? "frontend" : "preview"
1214
1952
  });
1215
1953
  });
1216
1954
  }
1217
1955
  function isDirty() {
1218
- return selectIsDirty((0, import_store20.__getState)());
1956
+ return selectIsDirty((0, import_store22.__getState)());
1219
1957
  }
1220
1958
 
1221
1959
  // src/init.ts
1222
1960
  function init() {
1223
- (0, import_store22.__registerSlice)(slice);
1961
+ (0, import_store24.__registerSlice)(slice);
1224
1962
  (0, import_editor_panels2.__registerPanel)(panel);
1225
- import_editor_styles_repository4.stylesRepository.register(globalClassesStylesProvider);
1963
+ import_editor_styles_repository5.stylesRepository.register(globalClassesStylesProvider);
1226
1964
  (0, import_editor.injectIntoLogic)({
1227
1965
  id: "global-classes-populate-store",
1228
1966
  component: PopulateStore
1229
1967
  });
1230
- (0, import_editor_editing_panel3.injectIntoClassSelectorActions)({
1968
+ (0, import_editor_editing_panel.injectIntoCssClassConvert)({
1969
+ id: "global-classes-convert-from-local-class",
1970
+ component: ConvertLocalClassToGlobalClass
1971
+ });
1972
+ (0, import_editor_editing_panel.injectIntoClassSelectorActions)({
1231
1973
  id: "global-classes-manager-button",
1232
1974
  component: ClassManagerButton
1233
1975
  });
1234
- (0, import_editor_editing_panel3.registerStyleProviderToColors)(GLOBAL_CLASSES_PROVIDER_KEY, {
1976
+ (0, import_editor_editing_panel.registerStyleProviderToColors)(GLOBAL_CLASSES_PROVIDER_KEY, {
1235
1977
  name: "global",
1236
1978
  getThemeColor: (theme) => theme.palette.global.dark
1237
1979
  });
1238
- (0, import_editor_v1_adapters7.__privateListenTo)((0, import_editor_v1_adapters7.v1ReadyEvent)(), () => {
1980
+ (0, import_editor_v1_adapters5.__privateListenTo)((0, import_editor_v1_adapters5.v1ReadyEvent)(), () => {
1239
1981
  syncWithDocumentSave();
1240
1982
  });
1241
1983
  }