@elementor/editor-global-classes 0.18.0 → 0.19.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -12,40 +12,36 @@ import {
12
12
  __useActiveDocument as useActiveDocument,
13
13
  __useActiveDocumentActions as useActiveDocumentActions
14
14
  } from "@elementor/editor-documents";
15
+ import { useUserStylesCapability } from "@elementor/editor-styles-repository";
15
16
  import { IconButton as IconButton3, Tooltip as Tooltip2 } from "@elementor/ui";
16
- import { __ as __5 } from "@wordpress/i18n";
17
-
18
- // src/components/class-manager/class-manager-panel.tsx
19
- import * as React7 from "react";
20
- import { useEffect } from "react";
21
- import { setDocumentModifiedStatus } from "@elementor/editor-documents";
22
- import {
23
- __createPanel as createPanel,
24
- Panel,
25
- PanelBody,
26
- PanelFooter,
27
- PanelHeader,
28
- PanelHeaderTitle
29
- } from "@elementor/editor-panels";
30
- import { ThemeProvider } from "@elementor/editor-ui";
31
- import { changeEditMode } from "@elementor/editor-v1-adapters";
32
- import { XIcon } from "@elementor/icons";
33
- import { useMutation } from "@elementor/query";
34
- import { Alert, Box as Box4, Button as Button3, ErrorBoundary, IconButton as IconButton2, Stack as Stack2 } from "@elementor/ui";
35
- import { __ as __4 } from "@wordpress/i18n";
36
-
37
- // src/hooks/use-dirty-state.ts
38
- import { __useSelector as useSelector } from "@elementor/store";
17
+ import { __ as __6 } from "@wordpress/i18n";
39
18
 
40
- // src/store.ts
41
- import { mergeProps } from "@elementor/editor-props";
42
- import {
43
- getVariantByMeta
44
- } from "@elementor/editor-styles";
19
+ // src/global-classes-styles-provider.ts
20
+ import { generateId } from "@elementor/editor-styles";
21
+ import { createStylesProvider } from "@elementor/editor-styles-repository";
22
+ import { isExperimentActive as isExperimentActive2 } from "@elementor/editor-v1-adapters";
45
23
  import {
46
- __createSelector as createSelector,
47
- __createSlice as createSlice
24
+ __dispatch as dispatch,
25
+ __getState as getState,
26
+ __subscribeWithSelector as subscribeWithSelector
48
27
  } from "@elementor/store";
28
+ import { __ } from "@wordpress/i18n";
29
+
30
+ // src/capabilities.ts
31
+ import { isExperimentActive } from "@elementor/editor-v1-adapters";
32
+ var EXPERIMENT_KEY = "global_classes_should_enforce_capabilities";
33
+ var UPDATE_CLASS_CAPABILITY_KEY = "elementor_global_classes_update_class";
34
+ var getCapabilities = () => {
35
+ const shouldEnforceCapabilities = isExperimentActive(EXPERIMENT_KEY);
36
+ if (shouldEnforceCapabilities) {
37
+ return {
38
+ update: UPDATE_CLASS_CAPABILITY_KEY,
39
+ create: UPDATE_CLASS_CAPABILITY_KEY,
40
+ delete: UPDATE_CLASS_CAPABILITY_KEY,
41
+ updateProps: UPDATE_CLASS_CAPABILITY_KEY
42
+ };
43
+ }
44
+ };
49
45
 
50
46
  // src/errors.ts
51
47
  import { createError } from "@elementor/utils";
@@ -59,6 +55,14 @@ var GlobalClassLabelAlreadyExistsError = createError({
59
55
  });
60
56
 
61
57
  // src/store.ts
58
+ import { mergeProps } from "@elementor/editor-props";
59
+ import {
60
+ getVariantByMeta
61
+ } from "@elementor/editor-styles";
62
+ import {
63
+ __createSelector as createSelector,
64
+ __createSlice as createSlice
65
+ } from "@elementor/store";
62
66
  var initialState = {
63
67
  data: { items: {}, order: [] },
64
68
  initialData: {
@@ -142,13 +146,94 @@ var selectOrderedClasses = createSelector(
142
146
  );
143
147
  var selectClass = (state, id2) => state[SLICE_NAME].data.items[id2] ?? null;
144
148
 
149
+ // src/global-classes-styles-provider.ts
150
+ var MAX_CLASSES = 50;
151
+ var globalClassesStylesProvider = createStylesProvider({
152
+ key: "global-classes",
153
+ priority: 30,
154
+ limit: MAX_CLASSES,
155
+ labels: {
156
+ singular: __("class", "elementor"),
157
+ plural: __("classes", "elementor")
158
+ },
159
+ subscribe: (cb) => subscribeWithSelector((state) => state.globalClasses, cb),
160
+ capabilities: getCapabilities(),
161
+ actions: {
162
+ all: () => selectOrderedClasses(getState()),
163
+ get: (id2) => selectClass(getState(), id2),
164
+ resolveCssName: (id2) => {
165
+ if (!isExperimentActive2("e_v_3_30")) {
166
+ return id2;
167
+ }
168
+ return selectClass(getState(), id2)?.label ?? id2;
169
+ },
170
+ create: (label) => {
171
+ const classes = selectGlobalClasses(getState());
172
+ const existingLabels = Object.values(classes).map((style) => style.label);
173
+ if (existingLabels.includes(label)) {
174
+ throw new GlobalClassLabelAlreadyExistsError({ context: { label } });
175
+ }
176
+ const existingIds = Object.keys(classes);
177
+ const id2 = generateId("g-", existingIds);
178
+ dispatch(
179
+ slice.actions.add({
180
+ id: id2,
181
+ type: "class",
182
+ label,
183
+ variants: []
184
+ })
185
+ );
186
+ return id2;
187
+ },
188
+ update: (payload) => {
189
+ dispatch(
190
+ slice.actions.update({
191
+ style: payload
192
+ })
193
+ );
194
+ },
195
+ delete: (id2) => {
196
+ dispatch(slice.actions.delete(id2));
197
+ },
198
+ updateProps: (args) => {
199
+ dispatch(
200
+ slice.actions.updateProps({
201
+ id: args.id,
202
+ meta: args.meta,
203
+ props: args.props
204
+ })
205
+ );
206
+ }
207
+ }
208
+ });
209
+
210
+ // src/components/class-manager/class-manager-panel.tsx
211
+ import * as React7 from "react";
212
+ import { useEffect } from "react";
213
+ import { setDocumentModifiedStatus } from "@elementor/editor-documents";
214
+ import {
215
+ __createPanel as createPanel,
216
+ Panel,
217
+ PanelBody,
218
+ PanelFooter,
219
+ PanelHeader,
220
+ PanelHeaderTitle
221
+ } from "@elementor/editor-panels";
222
+ import { ThemeProvider } from "@elementor/editor-ui";
223
+ import { changeEditMode } from "@elementor/editor-v1-adapters";
224
+ import { XIcon } from "@elementor/icons";
225
+ import { useMutation } from "@elementor/query";
226
+ import { Alert, Box as Box4, Button as Button3, ErrorBoundary, IconButton as IconButton2, Stack as Stack2 } from "@elementor/ui";
227
+ import { __ as __5 } from "@wordpress/i18n";
228
+
145
229
  // src/hooks/use-dirty-state.ts
230
+ import { __useSelector as useSelector } from "@elementor/store";
146
231
  var useDirtyState = () => {
147
232
  return useSelector(selectIsDirty);
148
233
  };
149
234
 
150
235
  // src/save-global-classes.ts
151
- import { __dispatch as dispatch, __getState as getState } from "@elementor/store";
236
+ import { __dispatch as dispatch2, __getState as getState2 } from "@elementor/store";
152
237
 
153
238
  // src/api.ts
154
239
  import { httpService } from "@elementor/http-client";
@@ -171,21 +256,21 @@ var apiClient = {
171
256
 
172
257
  // src/save-global-classes.ts
173
258
  async function saveGlobalClasses({ context: context2 }) {
174
- const state = selectData(getState());
259
+ const state = selectData(getState2());
175
260
  if (context2 === "preview") {
176
261
  await apiClient.saveDraft({
177
262
  items: state.items,
178
263
  order: state.order,
179
- changes: calculateChanges(state, selectPreviewInitialData(getState()))
264
+ changes: calculateChanges(state, selectPreviewInitialData(getState2()))
180
265
  });
181
266
  } else {
182
267
  await apiClient.publish({
183
268
  items: state.items,
184
269
  order: state.order,
185
- changes: calculateChanges(state, selectFrontendInitialData(getState()))
270
+ changes: calculateChanges(state, selectFrontendInitialData(getState2()))
186
271
  });
187
272
  }
188
- dispatch(slice.actions.reset({ context: context2 }));
273
+ dispatch2(slice.actions.reset({ context: context2 }));
189
274
  }
190
275
  function calculateChanges(state, initialData) {
191
276
  const stateIds = Object.keys(state.items);
@@ -217,7 +302,7 @@ import { useState } from "react";
217
302
  import { useSuppressedMessage } from "@elementor/editor-current-user";
218
303
  import { IntroductionModal } from "@elementor/editor-ui";
219
304
  import { Box, Image, Typography } from "@elementor/ui";
220
- import { __ } from "@wordpress/i18n";
305
+ import { __ as __2 } from "@wordpress/i18n";
221
306
  var MESSAGE_KEY = "global-class-manager";
222
307
  var ClassManagerIntroduction = () => {
223
308
  const [isMessageSuppressed, suppressMessage] = useSuppressedMessage(MESSAGE_KEY);
@@ -226,7 +311,7 @@ var ClassManagerIntroduction = () => {
226
311
  IntroductionModal,
227
312
  {
228
313
  open: shouldShowIntroduction,
229
- title: __("Class Manager", "elementor"),
314
+ title: __2("Class Manager", "elementor"),
230
315
  handleClose: (shouldShowAgain) => {
231
316
  if (!shouldShowAgain) {
232
317
  suppressMessage();
@@ -246,10 +331,10 @@ var ClassManagerIntroduction = () => {
246
331
  );
247
332
  };
248
333
  var IntroductionContent = () => {
249
- return /* @__PURE__ */ React.createElement(Box, { p: 3 }, /* @__PURE__ */ React.createElement(Typography, { variant: "body2" }, __(
334
+ return /* @__PURE__ */ React.createElement(Box, { p: 3 }, /* @__PURE__ */ React.createElement(Typography, { variant: "body2" }, __2(
250
335
  "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.",
251
336
  "elementor"
252
- )), /* @__PURE__ */ React.createElement("br", null), /* @__PURE__ */ React.createElement(Typography, { variant: "body2" }, __(
337
+ )), /* @__PURE__ */ React.createElement("br", null), /* @__PURE__ */ React.createElement(Typography, { variant: "body2" }, __2(
253
338
  "Remember, when editing an item within a specific class, any changes you make will apply across all elements in that class.",
254
339
  "elementor"
255
340
  )));
@@ -258,10 +343,10 @@ var IntroductionContent = () => {
258
343
  // src/components/class-manager/delete-class.ts
259
344
  import { getCurrentDocument, getV1DocumentsManager } from "@elementor/editor-documents";
260
345
  import { __privateRunCommand as runCommand } from "@elementor/editor-v1-adapters";
261
- import { __dispatch as dispatch2 } from "@elementor/store";
346
+ import { __dispatch as dispatch3 } from "@elementor/store";
262
347
  var isDeleted = false;
263
348
  var deleteClass = (id2) => {
264
- dispatch2(slice.actions.delete(id2));
349
+ dispatch3(slice.actions.delete(id2));
265
350
  isDeleted = true;
266
351
  };
267
352
  var onDelete = async () => {
@@ -306,7 +391,7 @@ import {
306
391
  Typography as Typography3,
307
392
  usePopupState
308
393
  } from "@elementor/ui";
309
- import { __ as __3 } from "@wordpress/i18n";
394
+ import { __ as __4 } from "@wordpress/i18n";
310
395
 
311
396
  // src/hooks/use-classes-order.ts
312
397
  import { __useSelector as useSelector2 } from "@elementor/store";
@@ -333,7 +418,7 @@ import {
333
418
  DialogTitle,
334
419
  Typography as Typography2
335
420
  } from "@elementor/ui";
336
- import { __ as __2 } from "@wordpress/i18n";
421
+ import { __ as __3 } from "@wordpress/i18n";
337
422
  var context = createContext(null);
338
423
  var DeleteConfirmationProvider = ({ children }) => {
339
424
  const [dialogProps, setDialogProps] = useState2(null);
@@ -352,10 +437,10 @@ var DeleteConfirmationDialog = ({ label, id: id2 }) => {
352
437
  deleteClass(id2);
353
438
  closeDialog();
354
439
  };
355
- return /* @__PURE__ */ React3.createElement(Dialog, { open: true, onClose: closeDialog, "aria-labelledby": TITLE_ID, maxWidth: "xs" }, /* @__PURE__ */ React3.createElement(DialogTitle, { id: TITLE_ID, display: "flex", alignItems: "center", gap: 1, sx: { lineHeight: 1 } }, /* @__PURE__ */ React3.createElement(AlertOctagonFilledIcon, { color: "error" }), __2("Delete this class?", "elementor")), /* @__PURE__ */ React3.createElement(DialogContent, null, /* @__PURE__ */ React3.createElement(DialogContentText, { variant: "body2", color: "textPrimary" }, __2("Deleting", "elementor"), /* @__PURE__ */ React3.createElement(Typography2, { variant: "subtitle2", component: "span" }, "\xA0", label, "\xA0"), __2(
440
+ return /* @__PURE__ */ React3.createElement(Dialog, { open: true, onClose: closeDialog, "aria-labelledby": TITLE_ID, maxWidth: "xs" }, /* @__PURE__ */ React3.createElement(DialogTitle, { id: TITLE_ID, display: "flex", alignItems: "center", gap: 1, sx: { lineHeight: 1 } }, /* @__PURE__ */ React3.createElement(AlertOctagonFilledIcon, { color: "error" }), __3("Delete this class?", "elementor")), /* @__PURE__ */ React3.createElement(DialogContent, null, /* @__PURE__ */ React3.createElement(DialogContentText, { variant: "body2", color: "textPrimary" }, __3("Deleting", "elementor"), /* @__PURE__ */ React3.createElement(Typography2, { variant: "subtitle2", component: "span" }, "\xA0", label, "\xA0"), __3(
356
441
  "will permanently remove it from your project and may affect the design across all elements using it. This action cannot be undone.",
357
442
  "elementor"
358
- ))), /* @__PURE__ */ React3.createElement(DialogActions, null, /* @__PURE__ */ React3.createElement(Button, { color: "secondary", onClick: closeDialog }, __2("Not now", "elementor")), /* @__PURE__ */ React3.createElement(Button, { variant: "contained", color: "error", onClick: onConfirm }, __2("Delete", "elementor"))));
443
+ ))), /* @__PURE__ */ React3.createElement(DialogActions, null, /* @__PURE__ */ React3.createElement(Button, { color: "secondary", onClick: closeDialog }, __3("Not now", "elementor")), /* @__PURE__ */ React3.createElement(Button, { variant: "contained", color: "error", onClick: onConfirm }, __3("Delete", "elementor"))));
359
444
  };
360
445
  var useDeleteConfirmation = () => {
361
446
  const contextValue = useContext(context);
@@ -527,7 +612,7 @@ var ClassItem = ({ id: id2, label, renameClass, selected, disabled, sortableTrig
527
612
  {
528
613
  placement: "top",
529
614
  className: "class-item-more-actions",
530
- title: __3("More actions", "elementor")
615
+ title: __4("More actions", "elementor")
531
616
  },
532
617
  /* @__PURE__ */ React5.createElement(IconButton, { size: "tiny", ...bindTrigger(popupState), "aria-label": "More actions" }, /* @__PURE__ */ React5.createElement(DotsVerticalIcon, { fontSize: "tiny" }))
533
618
  )
@@ -554,7 +639,7 @@ var ClassItem = ({ id: id2, label, renameClass, selected, disabled, sortableTrig
554
639
  openEditMode();
555
640
  }
556
641
  },
557
- /* @__PURE__ */ React5.createElement(Typography3, { variant: "caption", sx: { color: "text.primary" } }, __3("Rename", "elementor"))
642
+ /* @__PURE__ */ React5.createElement(Typography3, { variant: "caption", sx: { color: "text.primary" } }, __4("Rename", "elementor"))
558
643
  ),
559
644
  /* @__PURE__ */ React5.createElement(
560
645
  MenuListItem,
@@ -564,7 +649,7 @@ var ClassItem = ({ id: id2, label, renameClass, selected, disabled, sortableTrig
564
649
  openDialog({ id: id2, label });
565
650
  }
566
651
  },
567
- /* @__PURE__ */ React5.createElement(Typography3, { variant: "caption", sx: { color: "error.light" } }, __3("Delete", "elementor"))
652
+ /* @__PURE__ */ React5.createElement(Typography3, { variant: "caption", sx: { color: "error.light" } }, __4("Delete", "elementor"))
568
653
  )
569
654
  ));
570
655
  };
@@ -593,7 +678,7 @@ var StyledListItemButton = styled2(ListItemButton, {
593
678
  }
594
679
  `
595
680
  );
596
- var EmptyState = () => /* @__PURE__ */ React5.createElement(Stack, { alignItems: "center", gap: 1.5, pt: 10, px: 0.5, maxWidth: "260px", margin: "auto" }, /* @__PURE__ */ React5.createElement(FlippedColorSwatchIcon, { fontSize: "large" }), /* @__PURE__ */ React5.createElement(StyledHeader, { variant: "subtitle2", component: "h2", color: "text.secondary" }, __3("There are no global classes yet.", "elementor")), /* @__PURE__ */ React5.createElement(Typography3, { align: "center", variant: "caption", color: "text.secondary" }, __3(
681
+ var EmptyState = () => /* @__PURE__ */ React5.createElement(Stack, { alignItems: "center", gap: 1.5, pt: 10, px: 0.5, maxWidth: "260px", margin: "auto" }, /* @__PURE__ */ React5.createElement(FlippedColorSwatchIcon, { fontSize: "large" }), /* @__PURE__ */ React5.createElement(StyledHeader, { variant: "subtitle2", component: "h2", color: "text.secondary" }, __4("There are no global classes yet.", "elementor")), /* @__PURE__ */ React5.createElement(Typography3, { align: "center", variant: "caption", color: "text.secondary" }, __4(
597
682
  "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.",
598
683
  "elementor"
599
684
  )));
@@ -700,7 +785,7 @@ function ClassManagerPanel() {
700
785
  const { open: openSaveChangesDialog, close: closeSaveChangesDialog, isOpen: isSaveChangesDialogOpen } = useDialog();
701
786
  const { mutateAsync: publish, isPending: isPublishing } = usePublish();
702
787
  usePreventUnload();
703
- return /* @__PURE__ */ React7.createElement(ThemeProvider, null, /* @__PURE__ */ React7.createElement(ErrorBoundary, { fallback: /* @__PURE__ */ React7.createElement(ErrorBoundaryFallback, null) }, /* @__PURE__ */ React7.createElement(Panel, null, /* @__PURE__ */ React7.createElement(PanelHeader, null, /* @__PURE__ */ React7.createElement(Stack2, { p: 1, pl: 2, width: "100%", direction: "row", alignItems: "center" }, /* @__PURE__ */ React7.createElement(PanelHeaderTitle, { sx: { display: "flex", alignItems: "center", gap: 0.5 } }, /* @__PURE__ */ React7.createElement(FlippedColorSwatchIcon, { fontSize: "inherit" }), __4("Class Manager", "elementor")), /* @__PURE__ */ React7.createElement(
788
+ return /* @__PURE__ */ React7.createElement(ThemeProvider, null, /* @__PURE__ */ React7.createElement(ErrorBoundary, { fallback: /* @__PURE__ */ React7.createElement(ErrorBoundaryFallback, null) }, /* @__PURE__ */ React7.createElement(Panel, null, /* @__PURE__ */ React7.createElement(PanelHeader, null, /* @__PURE__ */ React7.createElement(Stack2, { p: 1, pl: 2, width: "100%", direction: "row", alignItems: "center" }, /* @__PURE__ */ React7.createElement(PanelHeaderTitle, { sx: { display: "flex", alignItems: "center", gap: 0.5 } }, /* @__PURE__ */ React7.createElement(FlippedColorSwatchIcon, { fontSize: "inherit" }), __5("Class Manager", "elementor")), /* @__PURE__ */ React7.createElement(
704
789
  CloseButton,
705
790
  {
706
791
  sx: { marginLeft: "auto" },
@@ -724,17 +809,17 @@ function ClassManagerPanel() {
724
809
  disabled: !isDirty2,
725
810
  loading: isPublishing
726
811
  },
727
- __4("Save changes", "elementor")
728
- )))), /* @__PURE__ */ React7.createElement(ClassManagerIntroduction, null), isSaveChangesDialogOpen && /* @__PURE__ */ React7.createElement(SaveChangesDialog, null, /* @__PURE__ */ React7.createElement(SaveChangesDialog.Title, null, __4("You have unsaved changes", "elementor")), /* @__PURE__ */ React7.createElement(SaveChangesDialog.Content, null, /* @__PURE__ */ React7.createElement(SaveChangesDialog.ContentText, null, __4("You have unsaved changes in the Class Manager.", "elementor")), /* @__PURE__ */ React7.createElement(SaveChangesDialog.ContentText, null, __4("To avoid losing your updates, save your changes before leaving.", "elementor"))), /* @__PURE__ */ React7.createElement(
812
+ __5("Save changes", "elementor")
813
+ )))), /* @__PURE__ */ React7.createElement(ClassManagerIntroduction, null), isSaveChangesDialogOpen && /* @__PURE__ */ React7.createElement(SaveChangesDialog, null, /* @__PURE__ */ React7.createElement(SaveChangesDialog.Title, null, __5("You have unsaved changes", "elementor")), /* @__PURE__ */ React7.createElement(SaveChangesDialog.Content, null, /* @__PURE__ */ React7.createElement(SaveChangesDialog.ContentText, null, __5("You have unsaved changes in the Class Manager.", "elementor")), /* @__PURE__ */ React7.createElement(SaveChangesDialog.ContentText, null, __5("To avoid losing your updates, save your changes before leaving.", "elementor"))), /* @__PURE__ */ React7.createElement(
729
814
  SaveChangesDialog.Actions,
730
815
  {
731
816
  actions: {
732
817
  cancel: {
733
- label: __4("Cancel", "elementor"),
818
+ label: __5("Cancel", "elementor"),
734
819
  action: closeSaveChangesDialog
735
820
  },
736
821
  confirm: {
737
- label: __4("Save & Continue", "elementor"),
822
+ label: __5("Save & Continue", "elementor"),
738
823
  action: async () => {
739
824
  await publish();
740
825
  closeSaveChangesDialog();
@@ -746,7 +831,7 @@ function ClassManagerPanel() {
746
831
  )));
747
832
  }
748
833
  var CloseButton = ({ onClose, ...props }) => /* @__PURE__ */ React7.createElement(IconButton2, { size: "small", color: "secondary", onClick: onClose, "aria-label": "Close", ...props }, /* @__PURE__ */ React7.createElement(XIcon, { fontSize: "small" }));
749
- var ErrorBoundaryFallback = () => /* @__PURE__ */ React7.createElement(Box4, { role: "alert", sx: { minHeight: "100%", p: 2 } }, /* @__PURE__ */ React7.createElement(Alert, { severity: "error", sx: { mb: 2, maxWidth: 400, textAlign: "center" } }, /* @__PURE__ */ React7.createElement("strong", null, __4("Something went wrong", "elementor"))));
834
+ var ErrorBoundaryFallback = () => /* @__PURE__ */ React7.createElement(Box4, { role: "alert", sx: { minHeight: "100%", p: 2 } }, /* @__PURE__ */ React7.createElement(Alert, { severity: "error", sx: { mb: 2, maxWidth: 400, textAlign: "center" } }, /* @__PURE__ */ React7.createElement("strong", null, __5("Something went wrong", "elementor"))));
750
835
  var usePreventUnload = () => {
751
836
  const isDirty2 = useDirtyState();
752
837
  useEffect(() => {
@@ -779,6 +864,11 @@ var ClassManagerButton = () => {
779
864
  const { open: openPanel } = usePanelActions();
780
865
  const { save: saveDocument } = useActiveDocumentActions();
781
866
  const { open: openSaveChangesDialog, close: closeSaveChangesDialog, isOpen: isSaveChangesDialogOpen } = useDialog();
867
+ const { userCan } = useUserStylesCapability();
868
+ const isUserAllowedToUpdateClass = userCan(globalClassesStylesProvider.getKey()).update;
869
+ if (!isUserAllowedToUpdateClass) {
870
+ return null;
871
+ }
782
872
  const handleOpenPanel = () => {
783
873
  if (document?.isDirty) {
784
874
  openSaveChangesDialog();
@@ -786,7 +876,7 @@ var ClassManagerButton = () => {
786
876
  }
787
877
  openPanel();
788
878
  };
789
- return /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement(Tooltip2, { title: __5("Class Manager", "elementor"), placement: "top" }, /* @__PURE__ */ React8.createElement(IconButton3, { size: "tiny", onClick: handleOpenPanel, sx: { marginInlineEnd: -0.75 } }, /* @__PURE__ */ React8.createElement(FlippedColorSwatchIcon, { fontSize: "tiny" }))), isSaveChangesDialogOpen && /* @__PURE__ */ React8.createElement(SaveChangesDialog, null, /* @__PURE__ */ React8.createElement(SaveChangesDialog.Title, null, __5("You have unsaved changes", "elementor")), /* @__PURE__ */ React8.createElement(SaveChangesDialog.Content, null, /* @__PURE__ */ React8.createElement(SaveChangesDialog.ContentText, { sx: { mb: 2 } }, __5(
879
+ return /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement(Tooltip2, { title: __6("Class Manager", "elementor"), placement: "top" }, /* @__PURE__ */ React8.createElement(IconButton3, { size: "tiny", onClick: handleOpenPanel, sx: { marginInlineEnd: -0.75 } }, /* @__PURE__ */ React8.createElement(FlippedColorSwatchIcon, { fontSize: "tiny" }))), isSaveChangesDialogOpen && /* @__PURE__ */ React8.createElement(SaveChangesDialog, null, /* @__PURE__ */ React8.createElement(SaveChangesDialog.Title, null, __6("You have unsaved changes", "elementor")), /* @__PURE__ */ React8.createElement(SaveChangesDialog.Content, null, /* @__PURE__ */ React8.createElement(SaveChangesDialog.ContentText, { sx: { mb: 2 } }, __6(
790
880
  "To open the Class Manager, save your page first. You can't continue without saving.",
791
881
  "elementor"
792
882
  ))), /* @__PURE__ */ React8.createElement(
@@ -794,11 +884,11 @@ var ClassManagerButton = () => {
794
884
  {
795
885
  actions: {
796
886
  cancel: {
797
- label: __5("Stay here", "elementor"),
887
+ label: __6("Stay here", "elementor"),
798
888
  action: closeSaveChangesDialog
799
889
  },
800
890
  confirm: {
801
- label: __5("Save & Continue", "elementor"),
891
+ label: __6("Save & Continue", "elementor"),
802
892
  action: async () => {
803
893
  await saveDocument();
804
894
  closeSaveChangesDialog();
@@ -838,75 +928,6 @@ function PopulateStore() {
838
928
  return null;
839
929
  }
840
930
 
841
- // src/global-classes-styles-provider.ts
842
- import { generateId } from "@elementor/editor-styles";
843
- import { createStylesProvider } from "@elementor/editor-styles-repository";
844
- import { isExperimentActive } from "@elementor/editor-v1-adapters";
845
- import {
846
- __dispatch as dispatch3,
847
- __getState as getState2,
848
- __subscribeWithSelector as subscribeWithSelector
849
- } from "@elementor/store";
850
- import { __ as __6 } from "@wordpress/i18n";
851
- var MAX_CLASSES = 50;
852
- var globalClassesStylesProvider = createStylesProvider({
853
- key: "global-classes",
854
- priority: 30,
855
- limit: MAX_CLASSES,
856
- labels: {
857
- singular: __6("class", "elementor"),
858
- plural: __6("classes", "elementor")
859
- },
860
- subscribe: (cb) => subscribeWithSelector((state) => state.globalClasses, cb),
861
- actions: {
862
- all: () => selectOrderedClasses(getState2()),
863
- get: (id2) => selectClass(getState2(), id2),
864
- resolveCssName: (id2) => {
865
- if (!isExperimentActive("e_v_3_30")) {
866
- return id2;
867
- }
868
- return selectClass(getState2(), id2)?.label ?? id2;
869
- },
870
- create: (label) => {
871
- const classes = selectGlobalClasses(getState2());
872
- const existingLabels = Object.values(classes).map((style) => style.label);
873
- if (existingLabels.includes(label)) {
874
- throw new GlobalClassLabelAlreadyExistsError({ context: { label } });
875
- }
876
- const existingIds = Object.keys(classes);
877
- const id2 = generateId("g-", existingIds);
878
- dispatch3(
879
- slice.actions.add({
880
- id: id2,
881
- type: "class",
882
- label,
883
- variants: []
884
- })
885
- );
886
- return id2;
887
- },
888
- update: (payload) => {
889
- dispatch3(
890
- slice.actions.update({
891
- style: payload
892
- })
893
- );
894
- },
895
- delete: (id2) => {
896
- dispatch3(slice.actions.delete(id2));
897
- },
898
- updateProps: (args) => {
899
- dispatch3(
900
- slice.actions.updateProps({
901
- id: args.id,
902
- meta: args.meta,
903
- props: args.props
904
- })
905
- );
906
- }
907
- }
908
- });
909
-
910
931
  // src/sync-with-document-save.ts
911
932
  import { setDocumentModifiedStatus as setDocumentModifiedStatus2 } from "@elementor/editor-documents";
912
933
  import { registerDataHook } from "@elementor/editor-v1-adapters";