@elementor/editor-global-classes 0.20.4 → 0.21.0

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/CHANGELOG.md CHANGED
@@ -1,5 +1,50 @@
1
1
  # @elementor/editor-global-classes
2
2
 
3
+ ## 0.21.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 17b73ab: Update `@elementor/ui` version.
8
+ - 708531f: Add history support for class removing, renaming, and reordering in class manager
9
+
10
+ ### Patch Changes
11
+
12
+ - 29f1740: Handle provider-to-color logic from the style providers directly
13
+ - Updated dependencies [9ccd243]
14
+ - Updated dependencies [da0c4ca]
15
+ - Updated dependencies [ac09e27]
16
+ - Updated dependencies [17b73ab]
17
+ - Updated dependencies [7a4178f]
18
+ - Updated dependencies [29f1740]
19
+ - Updated dependencies [8e18905]
20
+ - Updated dependencies [3daa1c9]
21
+ - Updated dependencies [40d00c2]
22
+ - Updated dependencies [d5e9011]
23
+ - Updated dependencies [93dfad1]
24
+ - Updated dependencies [30a6d95]
25
+ - Updated dependencies [f37c325]
26
+ - Updated dependencies [20d04f2]
27
+ - @elementor/editor-editing-panel@1.46.0
28
+ - @elementor/editor-ui@0.12.0
29
+ - @elementor/editor-panels@0.16.0
30
+ - @elementor/editor@0.20.0
31
+ - @elementor/editor-styles-repository@0.10.3
32
+ - @elementor/editor-props@0.14.0
33
+ - @elementor/editor-documents@0.13.7
34
+ - @elementor/editor-styles@0.6.10
35
+
36
+ ## 0.20.5
37
+
38
+ ### Patch Changes
39
+
40
+ - Updated dependencies [ab6320c]
41
+ - Updated dependencies [dac8026]
42
+ - Updated dependencies [2c11540]
43
+ - @elementor/editor-editing-panel@1.45.0
44
+ - @elementor/editor-props@0.13.0
45
+ - @elementor/editor-styles-repository@0.10.2
46
+ - @elementor/editor-styles@0.6.9
47
+
3
48
  ## 0.20.4
4
49
 
5
50
  ### Patch Changes
package/dist/index.js CHANGED
@@ -40,7 +40,7 @@ var import_editor_editing_panel = require("@elementor/editor-editing-panel");
40
40
  var import_editor_panels2 = require("@elementor/editor-panels");
41
41
  var import_editor_styles_repository4 = require("@elementor/editor-styles-repository");
42
42
  var import_editor_v1_adapters6 = require("@elementor/editor-v1-adapters");
43
- var import_store20 = require("@elementor/store");
43
+ var import_store22 = require("@elementor/store");
44
44
 
45
45
  // src/components/class-manager/class-manager-button.tsx
46
46
  var React8 = __toESM(require("react"));
@@ -87,6 +87,69 @@ var GlobalClassLabelAlreadyExistsError = (0, import_utils.createError)({
87
87
  var import_editor_props = require("@elementor/editor-props");
88
88
  var import_editor_styles = require("@elementor/editor-styles");
89
89
  var import_store = require("@elementor/store");
90
+
91
+ // src/utils/snapshot-history.ts
92
+ function createLink({ value, next, prev }) {
93
+ return {
94
+ value,
95
+ prev: prev || null,
96
+ next: next || null
97
+ };
98
+ }
99
+ var SnapshotHistory = class _SnapshotHistory {
100
+ constructor(namespace) {
101
+ this.namespace = namespace;
102
+ }
103
+ static registry = {};
104
+ static get(namespace) {
105
+ if (!_SnapshotHistory.registry[namespace]) {
106
+ _SnapshotHistory.registry[namespace] = new _SnapshotHistory(namespace);
107
+ }
108
+ return _SnapshotHistory.registry[namespace];
109
+ }
110
+ first = null;
111
+ current = null;
112
+ transform(item) {
113
+ return JSON.parse(JSON.stringify(item));
114
+ }
115
+ reset() {
116
+ this.first = this.current = null;
117
+ }
118
+ prev() {
119
+ if (!this.current || this.current === this.first) {
120
+ return null;
121
+ }
122
+ this.current = this.current.prev;
123
+ return this.current?.value || null;
124
+ }
125
+ isLast() {
126
+ return !this.current || !this.current.next;
127
+ }
128
+ next(value) {
129
+ if (value) {
130
+ if (!this.current) {
131
+ this.first = createLink({ value: this.transform(value) });
132
+ this.current = this.first;
133
+ return this.current.value;
134
+ }
135
+ const nextLink = createLink({
136
+ value: this.transform(value),
137
+ prev: this.current
138
+ });
139
+ this.current.next = nextLink;
140
+ this.current = nextLink;
141
+ return this.current.value;
142
+ }
143
+ if (!this.current || !this.current.next) {
144
+ return null;
145
+ }
146
+ this.current = this.current.next;
147
+ return this.current.value;
148
+ }
149
+ };
150
+
151
+ // src/store.ts
152
+ var localHistory = SnapshotHistory.get("global-classes");
90
153
  var initialState = {
91
154
  data: { items: {}, order: [] },
92
155
  initialData: {
@@ -109,11 +172,13 @@ var slice = (0, import_store.__createSlice)({
109
172
  state.isDirty = false;
110
173
  },
111
174
  add(state, { payload }) {
175
+ localHistory.next(state.data);
112
176
  state.data.items[payload.id] = payload;
113
177
  state.data.order.unshift(payload.id);
114
178
  state.isDirty = true;
115
179
  },
116
180
  delete(state, { payload }) {
181
+ localHistory.next(state.data);
117
182
  state.data.items = Object.fromEntries(
118
183
  Object.entries(state.data.items).filter(([id2]) => id2 !== payload)
119
184
  );
@@ -121,10 +186,12 @@ var slice = (0, import_store.__createSlice)({
121
186
  state.isDirty = true;
122
187
  },
123
188
  setOrder(state, { payload }) {
189
+ localHistory.next(state.data);
124
190
  state.data.order = payload;
125
191
  state.isDirty = true;
126
192
  },
127
193
  update(state, { payload }) {
194
+ localHistory.next(state.data);
128
195
  const style = state.data.items[payload.style.id];
129
196
  const mergedData = {
130
197
  ...style,
@@ -140,6 +207,7 @@ var slice = (0, import_store.__createSlice)({
140
207
  if (!style) {
141
208
  throw new GlobalClassNotFoundError({ context: { styleId: payload.id } });
142
209
  }
210
+ localHistory.next(state.data);
143
211
  const variant = (0, import_editor_styles.getVariantByMeta)(style, payload.meta);
144
212
  if (variant) {
145
213
  variant.props = (0, import_editor_props.mergeProps)(variant.props, payload.props);
@@ -153,10 +221,38 @@ var slice = (0, import_store.__createSlice)({
153
221
  },
154
222
  reset(state, { payload: { context: context2 } }) {
155
223
  if (context2 === "frontend") {
224
+ localHistory.reset();
156
225
  state.initialData.frontend = state.data;
157
226
  state.isDirty = false;
158
227
  }
159
228
  state.initialData.preview = state.data;
229
+ },
230
+ undo(state) {
231
+ if (localHistory.isLast()) {
232
+ localHistory.next(state.data);
233
+ }
234
+ const data = localHistory.prev();
235
+ if (data) {
236
+ state.data = data;
237
+ state.isDirty = true;
238
+ } else {
239
+ state.data = state.initialData.preview;
240
+ }
241
+ },
242
+ resetToInitialState(state, { payload: { context: context2 } }) {
243
+ localHistory.reset();
244
+ state.data = state.initialData[context2];
245
+ state.isDirty = false;
246
+ },
247
+ redo(state) {
248
+ const data = localHistory.next();
249
+ if (localHistory.isLast()) {
250
+ localHistory.prev();
251
+ }
252
+ if (data) {
253
+ state.data = data;
254
+ state.isDirty = true;
255
+ }
160
256
  }
161
257
  }
162
258
  });
@@ -175,8 +271,9 @@ var selectClass = (state, id2) => state[SLICE_NAME].data.items[id2] ?? null;
175
271
 
176
272
  // src/global-classes-styles-provider.ts
177
273
  var MAX_CLASSES = 50;
274
+ var GLOBAL_CLASSES_PROVIDER_KEY = "global-classes";
178
275
  var globalClassesStylesProvider = (0, import_editor_styles_repository.createStylesProvider)({
179
- key: "global-classes",
276
+ key: GLOBAL_CLASSES_PROVIDER_KEY,
180
277
  priority: 30,
181
278
  limit: MAX_CLASSES,
182
279
  labels: {
@@ -243,6 +340,7 @@ var import_editor_ui3 = require("@elementor/editor-ui");
243
340
  var import_editor_v1_adapters4 = require("@elementor/editor-v1-adapters");
244
341
  var import_icons6 = require("@elementor/icons");
245
342
  var import_query = require("@elementor/query");
343
+ var import_store16 = require("@elementor/store");
246
344
  var import_ui6 = require("@elementor/ui");
247
345
  var import_i18n5 = require("@wordpress/i18n");
248
346
 
@@ -513,14 +611,31 @@ var SortableItemIndicator = (0, import_ui3.styled)(import_ui3.Box)`
513
611
  // src/components/class-manager/global-classes-list.tsx
514
612
  var GlobalClassesList = ({ disabled }) => {
515
613
  const cssClasses = useOrderedClasses();
516
- const dispatch4 = (0, import_store14.__useDispatch)();
614
+ const dispatch5 = (0, import_store14.__useDispatch)();
517
615
  const [classesOrder, reorderClasses] = useReorder();
616
+ (0, import_react3.useEffect)(() => {
617
+ const handler = (event) => {
618
+ if (event.key === "z" && (event.ctrlKey || event.metaKey)) {
619
+ event.stopImmediatePropagation();
620
+ event.preventDefault();
621
+ if (event.shiftKey) {
622
+ dispatch5(slice.actions.redo());
623
+ return;
624
+ }
625
+ dispatch5(slice.actions.undo());
626
+ }
627
+ };
628
+ window.addEventListener("keydown", handler, {
629
+ capture: true
630
+ });
631
+ return () => window.removeEventListener("keydown", handler);
632
+ }, [dispatch5]);
518
633
  if (!cssClasses?.length) {
519
634
  return /* @__PURE__ */ React5.createElement(EmptyState, null);
520
635
  }
521
636
  return /* @__PURE__ */ React5.createElement(DeleteConfirmationProvider, null, /* @__PURE__ */ React5.createElement(import_ui4.List, { sx: { display: "flex", flexDirection: "column", gap: 0.5 } }, /* @__PURE__ */ React5.createElement(SortableProvider, { value: classesOrder, onChange: reorderClasses }, cssClasses?.map(({ id: id2, label }) => {
522
637
  const renameClass = (newLabel) => {
523
- dispatch4(
638
+ dispatch5(
524
639
  slice.actions.update({
525
640
  style: {
526
641
  id: id2,
@@ -543,10 +658,10 @@ var GlobalClassesList = ({ disabled }) => {
543
658
  }))));
544
659
  };
545
660
  var useReorder = () => {
546
- const dispatch4 = (0, import_store14.__useDispatch)();
661
+ const dispatch5 = (0, import_store14.__useDispatch)();
547
662
  const order = useClassesOrder();
548
663
  const reorder = (newIds) => {
549
- dispatch4(slice.actions.setOrder(newIds));
664
+ dispatch5(slice.actions.setOrder(newIds));
550
665
  };
551
666
  return [order, reorder];
552
667
  };
@@ -732,13 +847,13 @@ var SaveChangesDialogContent = ({ children }) => /* @__PURE__ */ React6.createEl
732
847
  var SaveChangesDialogContentText = (props) => /* @__PURE__ */ React6.createElement(import_ui5.DialogContentText, { variant: "body2", color: "textPrimary", display: "flex", flexDirection: "column", ...props });
733
848
  var SaveChangesDialogActions = ({ actions }) => {
734
849
  const [isConfirming, setIsConfirming] = (0, import_react4.useState)(false);
735
- const { cancel, confirm } = actions;
850
+ const { cancel, confirm, discard } = actions;
736
851
  const onConfirm = async () => {
737
852
  setIsConfirming(true);
738
853
  await confirm.action();
739
854
  setIsConfirming(false);
740
855
  };
741
- return /* @__PURE__ */ React6.createElement(import_ui5.DialogActions, null, /* @__PURE__ */ React6.createElement(import_ui5.Button, { variant: "text", color: "secondary", onClick: cancel.action }, cancel.label), /* @__PURE__ */ React6.createElement(import_ui5.Button, { variant: "contained", color: "secondary", onClick: onConfirm, loading: isConfirming }, confirm.label));
856
+ return /* @__PURE__ */ React6.createElement(import_ui5.DialogActions, null, cancel && /* @__PURE__ */ React6.createElement(import_ui5.Button, { variant: "text", color: "secondary", onClick: cancel.action }, cancel.label), discard && /* @__PURE__ */ React6.createElement(import_ui5.Button, { variant: "text", color: "secondary", onClick: discard.action }, discard.label), /* @__PURE__ */ React6.createElement(import_ui5.Button, { variant: "contained", color: "secondary", onClick: onConfirm, loading: isConfirming }, confirm.label));
742
857
  };
743
858
  SaveChangesDialog.Title = SaveChangesDialogTitle;
744
859
  SaveChangesDialog.Content = SaveChangesDialogContent;
@@ -771,6 +886,10 @@ function ClassManagerPanel() {
771
886
  const { close: closePanel } = usePanelActions();
772
887
  const { open: openSaveChangesDialog, close: closeSaveChangesDialog, isOpen: isSaveChangesDialogOpen } = useDialog();
773
888
  const { mutateAsync: publish, isPending: isPublishing } = usePublish();
889
+ const resetAndClosePanel = () => {
890
+ (0, import_store16.__dispatch)(slice.actions.resetToInitialState({ context: "frontend" }));
891
+ closeSaveChangesDialog();
892
+ };
774
893
  usePreventUnload();
775
894
  return /* @__PURE__ */ React7.createElement(import_editor_ui3.ThemeProvider, null, /* @__PURE__ */ React7.createElement(import_ui6.ErrorBoundary, { fallback: /* @__PURE__ */ React7.createElement(ErrorBoundaryFallback, null) }, /* @__PURE__ */ React7.createElement(import_editor_panels.Panel, null, /* @__PURE__ */ React7.createElement(import_editor_panels.PanelHeader, null, /* @__PURE__ */ React7.createElement(import_ui6.Stack, { p: 1, pl: 2, width: "100%", direction: "row", alignItems: "center" }, /* @__PURE__ */ React7.createElement(import_editor_panels.PanelHeaderTitle, { sx: { display: "flex", alignItems: "center", gap: 0.5 } }, /* @__PURE__ */ React7.createElement(FlippedColorSwatchIcon, { fontSize: "inherit" }), (0, import_i18n5.__)("Class Manager", "elementor")), /* @__PURE__ */ React7.createElement(
776
895
  CloseButton,
@@ -797,13 +916,15 @@ function ClassManagerPanel() {
797
916
  loading: isPublishing
798
917
  },
799
918
  (0, import_i18n5.__)("Save changes", "elementor")
800
- )))), /* @__PURE__ */ React7.createElement(ClassManagerIntroduction, null), isSaveChangesDialogOpen && /* @__PURE__ */ React7.createElement(SaveChangesDialog, null, /* @__PURE__ */ React7.createElement(SaveChangesDialog.Title, null, (0, import_i18n5.__)("You have unsaved changes", "elementor")), /* @__PURE__ */ React7.createElement(SaveChangesDialog.Content, null, /* @__PURE__ */ React7.createElement(SaveChangesDialog.ContentText, null, (0, import_i18n5.__)("You have unsaved changes in the Class Manager.", "elementor")), /* @__PURE__ */ React7.createElement(SaveChangesDialog.ContentText, null, (0, import_i18n5.__)("To avoid losing your updates, save your changes before leaving.", "elementor"))), /* @__PURE__ */ React7.createElement(
919
+ )))), /* @__PURE__ */ React7.createElement(ClassManagerIntroduction, null), isSaveChangesDialogOpen && /* @__PURE__ */ React7.createElement(SaveChangesDialog, null, /* @__PURE__ */ React7.createElement(import_ui6.DialogHeader, { onClose: closeSaveChangesDialog, logo: false }, /* @__PURE__ */ React7.createElement(SaveChangesDialog.Title, null, (0, import_i18n5.__)("You have unsaved changes", "elementor"))), /* @__PURE__ */ React7.createElement(SaveChangesDialog.Content, null, /* @__PURE__ */ React7.createElement(SaveChangesDialog.ContentText, null, (0, import_i18n5.__)("You have unsaved changes in the Class Manager.", "elementor")), /* @__PURE__ */ React7.createElement(SaveChangesDialog.ContentText, null, (0, import_i18n5.__)("To avoid losing your updates, save your changes before leaving.", "elementor"))), /* @__PURE__ */ React7.createElement(
801
920
  SaveChangesDialog.Actions,
802
921
  {
803
922
  actions: {
804
- cancel: {
805
- label: (0, import_i18n5.__)("Cancel", "elementor"),
806
- action: closeSaveChangesDialog
923
+ discard: {
924
+ label: (0, import_i18n5.__)("Discard", "elementor"),
925
+ action: () => {
926
+ resetAndClosePanel();
927
+ }
807
928
  },
808
929
  confirm: {
809
930
  label: (0, import_i18n5.__)("Save & Continue", "elementor"),
@@ -889,15 +1010,15 @@ var ClassManagerButton = () => {
889
1010
 
890
1011
  // src/components/populate-store.tsx
891
1012
  var import_react6 = require("react");
892
- var import_store16 = require("@elementor/store");
1013
+ var import_store18 = require("@elementor/store");
893
1014
  function PopulateStore() {
894
- const dispatch4 = (0, import_store16.__useDispatch)();
1015
+ const dispatch5 = (0, import_store18.__useDispatch)();
895
1016
  (0, import_react6.useEffect)(() => {
896
1017
  Promise.all([apiClient.all("preview"), apiClient.all("frontend")]).then(
897
1018
  ([previewRes, frontendRes]) => {
898
1019
  const { data: previewData } = previewRes;
899
1020
  const { data: frontendData } = frontendRes;
900
- dispatch4(
1021
+ dispatch5(
901
1022
  slice.actions.load({
902
1023
  preview: {
903
1024
  items: previewData.data,
@@ -911,21 +1032,21 @@ function PopulateStore() {
911
1032
  );
912
1033
  }
913
1034
  );
914
- }, [dispatch4]);
1035
+ }, [dispatch5]);
915
1036
  return null;
916
1037
  }
917
1038
 
918
1039
  // src/sync-with-document-save.ts
919
1040
  var import_editor_documents4 = require("@elementor/editor-documents");
920
1041
  var import_editor_v1_adapters5 = require("@elementor/editor-v1-adapters");
921
- var import_store18 = require("@elementor/store");
1042
+ var import_store20 = require("@elementor/store");
922
1043
  function syncWithDocumentSave() {
923
1044
  const unsubscribe = syncDirtyState();
924
1045
  bindSaveAction();
925
1046
  return unsubscribe;
926
1047
  }
927
1048
  function syncDirtyState() {
928
- return (0, import_store18.__subscribeWithSelector)(selectIsDirty, () => {
1049
+ return (0, import_store20.__subscribeWithSelector)(selectIsDirty, () => {
929
1050
  if (!isDirty()) {
930
1051
  return;
931
1052
  }
@@ -940,12 +1061,12 @@ function bindSaveAction() {
940
1061
  });
941
1062
  }
942
1063
  function isDirty() {
943
- return selectIsDirty((0, import_store18.__getState)());
1064
+ return selectIsDirty((0, import_store20.__getState)());
944
1065
  }
945
1066
 
946
1067
  // src/init.ts
947
1068
  function init() {
948
- (0, import_store20.__registerSlice)(slice);
1069
+ (0, import_store22.__registerSlice)(slice);
949
1070
  (0, import_editor_panels2.__registerPanel)(panel);
950
1071
  import_editor_styles_repository4.stylesRepository.register(globalClassesStylesProvider);
951
1072
  (0, import_editor.injectIntoLogic)({
@@ -956,6 +1077,10 @@ function init() {
956
1077
  id: "global-classes-manager-button",
957
1078
  component: ClassManagerButton
958
1079
  });
1080
+ (0, import_editor_editing_panel.registerStyleProviderToColors)(GLOBAL_CLASSES_PROVIDER_KEY, {
1081
+ name: "global",
1082
+ getThemeColor: (theme) => theme.palette.global.dark
1083
+ });
959
1084
  (0, import_editor_v1_adapters6.__privateListenTo)((0, import_editor_v1_adapters6.v1ReadyEvent)(), () => {
960
1085
  syncWithDocumentSave();
961
1086
  });