@elementor/editor-global-classes 0.4.0 → 0.6.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 +79 -0
- package/dist/index.js +471 -99
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +502 -100
- package/dist/index.mjs.map +1 -1
- package/package.json +16 -11
- package/src/api.ts +6 -12
- package/src/components/class-manager/class-manager-introduction.tsx +51 -0
- package/src/components/class-manager/class-manager-panel.tsx +21 -17
- package/src/components/class-manager/delete-confirmation-dialog.tsx +96 -0
- package/src/components/class-manager/global-classes-list.tsx +250 -14
- package/src/components/class-manager/sortable.tsx +90 -0
- package/src/components/{logic-hooks.tsx → populate-store.tsx} +1 -1
- package/src/errors.ts +5 -0
- package/src/global-classes-styles-provider.ts +34 -23
- package/src/init.ts +10 -4
- package/src/store.ts +49 -13
- package/src/sync-with-document-save.ts +44 -0
package/dist/index.js
CHANGED
|
@@ -26,31 +26,71 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
26
26
|
var import_editor = require("@elementor/editor");
|
|
27
27
|
var import_editor_editing_panel = require("@elementor/editor-editing-panel");
|
|
28
28
|
var import_editor_panels2 = require("@elementor/editor-panels");
|
|
29
|
-
var
|
|
30
|
-
var
|
|
29
|
+
var import_editor_styles_repository2 = require("@elementor/editor-styles-repository");
|
|
30
|
+
var import_editor_v1_adapters2 = require("@elementor/editor-v1-adapters");
|
|
31
|
+
var import_store9 = require("@elementor/store");
|
|
31
32
|
|
|
32
33
|
// src/components/class-manager/class-manager-button.tsx
|
|
33
|
-
var
|
|
34
|
-
var
|
|
35
|
-
var
|
|
36
|
-
var
|
|
34
|
+
var React6 = __toESM(require("react"));
|
|
35
|
+
var import_icons5 = require("@elementor/icons");
|
|
36
|
+
var import_ui6 = require("@elementor/ui");
|
|
37
|
+
var import_i18n6 = require("@wordpress/i18n");
|
|
37
38
|
|
|
38
39
|
// src/components/class-manager/class-manager-panel.tsx
|
|
39
|
-
var
|
|
40
|
+
var React5 = __toESM(require("react"));
|
|
40
41
|
var import_editor_panels = require("@elementor/editor-panels");
|
|
41
|
-
var
|
|
42
|
-
var
|
|
43
|
-
var
|
|
42
|
+
var import_icons4 = require("@elementor/icons");
|
|
43
|
+
var import_ui5 = require("@elementor/ui");
|
|
44
|
+
var import_i18n5 = require("@wordpress/i18n");
|
|
44
45
|
|
|
45
|
-
// src/components/class-manager/
|
|
46
|
+
// src/components/class-manager/class-manager-introduction.tsx
|
|
46
47
|
var React = __toESM(require("react"));
|
|
48
|
+
var import_react = require("react");
|
|
49
|
+
var import_editor_current_user = require("@elementor/editor-current-user");
|
|
47
50
|
var import_editor_ui = require("@elementor/editor-ui");
|
|
48
51
|
var import_ui = require("@elementor/ui");
|
|
52
|
+
var import_i18n = require("@wordpress/i18n");
|
|
53
|
+
var MESSAGE_KEY = "global-class-manager-4";
|
|
54
|
+
var ClassManagerIntroduction = () => {
|
|
55
|
+
const [isMessageSuppressed, suppressMessage] = (0, import_editor_current_user.useSuppressedMessage)(MESSAGE_KEY);
|
|
56
|
+
const [shouldShowIntroduction, setShouldShowIntroduction] = (0, import_react.useState)(!isMessageSuppressed);
|
|
57
|
+
return /* @__PURE__ */ React.createElement(
|
|
58
|
+
import_editor_ui.IntroductionModal,
|
|
59
|
+
{
|
|
60
|
+
open: shouldShowIntroduction,
|
|
61
|
+
title: (0, import_i18n.__)("CSS Class manager"),
|
|
62
|
+
content: /* @__PURE__ */ React.createElement(IntroductionContent, null),
|
|
63
|
+
handleClose: (shouldShowAgain) => {
|
|
64
|
+
if (!shouldShowAgain) {
|
|
65
|
+
suppressMessage();
|
|
66
|
+
}
|
|
67
|
+
setShouldShowIntroduction(false);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
);
|
|
71
|
+
};
|
|
72
|
+
var IntroductionContent = () => {
|
|
73
|
+
return /* @__PURE__ */ React.createElement(import_ui.Stack, { gap: 1.5, padding: 3 }, /* @__PURE__ */ React.createElement(import_ui.Image, { sx: { width: "100%", height: "312px" }, src: "", alt: "Introduction" }), /* @__PURE__ */ React.createElement(import_ui.Box, null, /* @__PURE__ */ React.createElement(import_ui.Typography, { variant: "body2" }, (0, import_i18n.__)(
|
|
74
|
+
"The CSS Class Manager allows you to manage and organize your site's CSS classes efficiently. You can reorder classes to adjust their priority, rename them to maintain clarity in your design system, and delete unused classes to keep your CSS structured.",
|
|
75
|
+
"elementor"
|
|
76
|
+
)), /* @__PURE__ */ React.createElement("br", null), /* @__PURE__ */ React.createElement(import_ui.Typography, { variant: "body2" }, (0, import_i18n.__)(
|
|
77
|
+
"Changes apply globally\u2014any modifications will affect all elements using the class, impacting the class order and priority across your site.",
|
|
78
|
+
"elementor"
|
|
79
|
+
))));
|
|
80
|
+
};
|
|
49
81
|
|
|
50
|
-
// src/
|
|
51
|
-
var
|
|
52
|
-
var
|
|
53
|
-
var
|
|
82
|
+
// src/components/class-manager/global-classes-list.tsx
|
|
83
|
+
var React4 = __toESM(require("react"));
|
|
84
|
+
var import_editor_styles_repository = require("@elementor/editor-styles-repository");
|
|
85
|
+
var import_editor_ui2 = require("@elementor/editor-ui");
|
|
86
|
+
var import_icons3 = require("@elementor/icons");
|
|
87
|
+
var import_ui4 = require("@elementor/ui");
|
|
88
|
+
var import_i18n4 = require("@wordpress/i18n");
|
|
89
|
+
|
|
90
|
+
// src/global-classes-styles-provider.ts
|
|
91
|
+
var import_editor_styles2 = require("@elementor/editor-styles");
|
|
92
|
+
var import_store2 = require("@elementor/store");
|
|
93
|
+
var import_i18n2 = require("@wordpress/i18n");
|
|
54
94
|
|
|
55
95
|
// src/errors.ts
|
|
56
96
|
var import_utils = require("@elementor/utils");
|
|
@@ -58,11 +98,19 @@ var GlobalClassNotFoundError = (0, import_utils.createError)({
|
|
|
58
98
|
code: "global_class_not_found",
|
|
59
99
|
message: "Global class not found."
|
|
60
100
|
});
|
|
101
|
+
var GlobalClassLabelAlreadyExistsError = (0, import_utils.createError)({
|
|
102
|
+
code: "global_class_label_already_exists",
|
|
103
|
+
message: "Class with this name already exists."
|
|
104
|
+
});
|
|
61
105
|
|
|
62
106
|
// src/store.ts
|
|
107
|
+
var import_editor_props = require("@elementor/editor-props");
|
|
108
|
+
var import_editor_styles = require("@elementor/editor-styles");
|
|
109
|
+
var import_store = require("@elementor/store");
|
|
63
110
|
var initialState = {
|
|
64
111
|
items: {},
|
|
65
|
-
order: []
|
|
112
|
+
order: [],
|
|
113
|
+
isDirty: false
|
|
66
114
|
};
|
|
67
115
|
var SLICE_NAME = "globalClasses";
|
|
68
116
|
var slice = (0, import_store.__createSlice)({
|
|
@@ -72,14 +120,29 @@ var slice = (0, import_store.__createSlice)({
|
|
|
72
120
|
init(state, { payload }) {
|
|
73
121
|
state.items = payload.items;
|
|
74
122
|
state.order = payload.order;
|
|
123
|
+
state.isDirty = false;
|
|
75
124
|
},
|
|
76
125
|
add(state, { payload }) {
|
|
77
|
-
state.items[payload.
|
|
78
|
-
state.order
|
|
126
|
+
state.items[payload.id] = payload;
|
|
127
|
+
state.order.unshift(payload.id);
|
|
128
|
+
state.isDirty = true;
|
|
129
|
+
},
|
|
130
|
+
delete(state, { payload }) {
|
|
131
|
+
state.items = Object.fromEntries(Object.entries(state.items).filter(([id]) => id !== payload));
|
|
132
|
+
state.order = state.order.filter((id) => id !== payload);
|
|
133
|
+
state.isDirty = true;
|
|
134
|
+
},
|
|
135
|
+
setOrder(state, { payload }) {
|
|
136
|
+
state.order = payload;
|
|
79
137
|
},
|
|
80
138
|
update(state, { payload }) {
|
|
81
|
-
state.items[payload.style.id]
|
|
82
|
-
|
|
139
|
+
const style = state.items[payload.style.id];
|
|
140
|
+
const mergedData = {
|
|
141
|
+
...style,
|
|
142
|
+
...payload.style
|
|
143
|
+
};
|
|
144
|
+
state.items[payload.style.id] = mergedData;
|
|
145
|
+
state.isDirty = true;
|
|
83
146
|
},
|
|
84
147
|
updateProps(state, {
|
|
85
148
|
payload
|
|
@@ -94,73 +157,396 @@ var slice = (0, import_store.__createSlice)({
|
|
|
94
157
|
} else {
|
|
95
158
|
style.variants.push({ meta: payload.meta, props: payload.props });
|
|
96
159
|
}
|
|
160
|
+
state.isDirty = true;
|
|
161
|
+
},
|
|
162
|
+
setPristine(state) {
|
|
163
|
+
state.isDirty = false;
|
|
97
164
|
}
|
|
98
165
|
}
|
|
99
166
|
});
|
|
100
|
-
var selectItems = (state) => state[SLICE_NAME].items;
|
|
101
167
|
var selectOrder = (state) => state[SLICE_NAME].order;
|
|
168
|
+
var selectGlobalClasses = (state) => state[SLICE_NAME].items;
|
|
102
169
|
var selectOrderedGlobalClasses = (0, import_store.__createSelector)(
|
|
103
|
-
|
|
170
|
+
selectGlobalClasses,
|
|
104
171
|
selectOrder,
|
|
105
172
|
(items, order) => order.map((id) => items[id])
|
|
106
173
|
);
|
|
107
174
|
var selectClass = (state, id) => state[SLICE_NAME].items[id] ?? null;
|
|
175
|
+
var selectIsDirty = (state) => state.globalClasses.isDirty;
|
|
108
176
|
var useOrderedGlobalClasses = () => {
|
|
109
177
|
const items = (0, import_store.__useSelector)(selectOrderedGlobalClasses);
|
|
110
178
|
return items;
|
|
111
179
|
};
|
|
180
|
+
var useGlobalClassesOrder = () => (0, import_store.__useSelector)(selectOrder);
|
|
181
|
+
|
|
182
|
+
// src/global-classes-styles-provider.ts
|
|
183
|
+
var globalClassesStylesProvider = {
|
|
184
|
+
key: "global-classes",
|
|
185
|
+
priority: 30,
|
|
186
|
+
actions: {
|
|
187
|
+
get: () => selectOrderedGlobalClasses((0, import_store2.__getState)()),
|
|
188
|
+
getById: (id) => selectClass((0, import_store2.__getState)(), id),
|
|
189
|
+
create: (label) => {
|
|
190
|
+
const classes = selectGlobalClasses((0, import_store2.__getState)());
|
|
191
|
+
const existingLabels = Object.values(classes).map((style) => style.label);
|
|
192
|
+
if (existingLabels.includes(label)) {
|
|
193
|
+
throw new GlobalClassLabelAlreadyExistsError({ context: { label } });
|
|
194
|
+
}
|
|
195
|
+
const existingIds = Object.keys(classes);
|
|
196
|
+
const id = (0, import_editor_styles2.generateId)("g-", existingIds);
|
|
197
|
+
(0, import_store2.__dispatch)(
|
|
198
|
+
slice.actions.add({
|
|
199
|
+
id,
|
|
200
|
+
type: "class",
|
|
201
|
+
label,
|
|
202
|
+
variants: []
|
|
203
|
+
})
|
|
204
|
+
);
|
|
205
|
+
return id;
|
|
206
|
+
},
|
|
207
|
+
update: (payload) => {
|
|
208
|
+
(0, import_store2.__dispatch)(
|
|
209
|
+
slice.actions.update({
|
|
210
|
+
style: payload
|
|
211
|
+
})
|
|
212
|
+
);
|
|
213
|
+
},
|
|
214
|
+
delete: (id) => {
|
|
215
|
+
(0, import_store2.__dispatch)(slice.actions.delete(id));
|
|
216
|
+
},
|
|
217
|
+
setOrder: (order) => {
|
|
218
|
+
(0, import_store2.__dispatch)(slice.actions.setOrder(order));
|
|
219
|
+
},
|
|
220
|
+
updateProps: (args) => {
|
|
221
|
+
(0, import_store2.__dispatch)(
|
|
222
|
+
slice.actions.updateProps({
|
|
223
|
+
id: args.id,
|
|
224
|
+
meta: args.meta,
|
|
225
|
+
props: args.props
|
|
226
|
+
})
|
|
227
|
+
);
|
|
228
|
+
}
|
|
229
|
+
},
|
|
230
|
+
subscribe: (cb) => (0, import_store2.__subscribeWithSelector)((state) => state.globalClasses, cb),
|
|
231
|
+
labels: {
|
|
232
|
+
singular: (0, import_i18n2.__)("Global class", "elementor"),
|
|
233
|
+
plural: (0, import_i18n2.__)("Global CSS Classes", "elementor")
|
|
234
|
+
}
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
// src/components/class-manager/delete-confirmation-dialog.tsx
|
|
238
|
+
var React2 = __toESM(require("react"));
|
|
239
|
+
var import_react2 = require("react");
|
|
240
|
+
var import_icons = require("@elementor/icons");
|
|
241
|
+
var import_ui2 = require("@elementor/ui");
|
|
242
|
+
var import_i18n3 = require("@wordpress/i18n");
|
|
243
|
+
var context = (0, import_react2.createContext)(null);
|
|
244
|
+
var DeleteConfirmationProvider = ({ children }) => {
|
|
245
|
+
const [dialogProps, setDialogProps] = (0, import_react2.useState)(null);
|
|
246
|
+
const openDialog = (props) => {
|
|
247
|
+
setDialogProps(props);
|
|
248
|
+
};
|
|
249
|
+
const closeDialog = () => {
|
|
250
|
+
setDialogProps(null);
|
|
251
|
+
};
|
|
252
|
+
return /* @__PURE__ */ React2.createElement(context.Provider, { value: { openDialog, closeDialog, dialogProps } }, children, !!dialogProps && /* @__PURE__ */ React2.createElement(DeleteConfirmationDialog, { ...dialogProps }));
|
|
253
|
+
};
|
|
254
|
+
var TITLE_ID = "delete-class-dialog";
|
|
255
|
+
var DeleteConfirmationDialog = ({ label, id }) => {
|
|
256
|
+
const { closeDialog } = useDeleteConfirmation();
|
|
257
|
+
const onConfirm = () => {
|
|
258
|
+
globalClassesStylesProvider.actions.delete(id);
|
|
259
|
+
closeDialog();
|
|
260
|
+
};
|
|
261
|
+
return /* @__PURE__ */ React2.createElement(import_ui2.Dialog, { open: true, onClose: closeDialog, "aria-labelledby": TITLE_ID, maxWidth: "xs" }, /* @__PURE__ */ React2.createElement(import_ui2.DialogTitle, { id: TITLE_ID, display: "flex", alignItems: "center", gap: 1, sx: { lineHeight: 1 } }, /* @__PURE__ */ React2.createElement(import_icons.AlertOctagonFilledIcon, { color: "error" }), (0, import_i18n3.__)("Delete global class", "elementor")), /* @__PURE__ */ React2.createElement(import_ui2.DialogContent, null, /* @__PURE__ */ React2.createElement(import_ui2.DialogContentText, { variant: "body2", color: "textPrimary" }, (0, import_i18n3.__)("Deleting", "elementor"), /* @__PURE__ */ React2.createElement(import_ui2.Typography, { variant: "subtitle2", component: "span" }, "\xA0", label, "\xA0"), (0, import_i18n3.__)(
|
|
262
|
+
"will permanently remove it from your project and may affect the design across all elements using it. This action cannot be undone.",
|
|
263
|
+
"elementor"
|
|
264
|
+
))), /* @__PURE__ */ React2.createElement(import_ui2.DialogActions, null, /* @__PURE__ */ React2.createElement(import_ui2.Button, { color: "secondary", onClick: closeDialog }, (0, import_i18n3.__)("Cancel", "elementor")), /* @__PURE__ */ React2.createElement(import_ui2.Button, { variant: "contained", color: "error", onClick: onConfirm }, (0, import_i18n3.__)("Delete", "elementor"))));
|
|
265
|
+
};
|
|
266
|
+
var useDeleteConfirmation = () => {
|
|
267
|
+
const contextValue = (0, import_react2.useContext)(context);
|
|
268
|
+
if (!contextValue) {
|
|
269
|
+
throw new Error("useDeleteConfirmation must be used within a DeleteConfirmationProvider");
|
|
270
|
+
}
|
|
271
|
+
return contextValue;
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
// src/components/class-manager/sortable.tsx
|
|
275
|
+
var React3 = __toESM(require("react"));
|
|
276
|
+
var import_icons2 = require("@elementor/icons");
|
|
277
|
+
var import_ui3 = require("@elementor/ui");
|
|
278
|
+
var SortableProvider = (props) => /* @__PURE__ */ React3.createElement(import_ui3.UnstableSortableProvider, { restrictAxis: true, variant: "static", dragPlaceholderStyle: { opacity: "1" }, ...props });
|
|
279
|
+
var SortableTrigger = (props) => /* @__PURE__ */ React3.createElement("div", { ...props, role: "button", className: "class-item-sortable-trigger" }, /* @__PURE__ */ React3.createElement(import_icons2.GripVerticalIcon, { fontSize: "tiny" }));
|
|
280
|
+
var SortableItem = ({ children, id }) => {
|
|
281
|
+
return /* @__PURE__ */ React3.createElement(
|
|
282
|
+
import_ui3.UnstableSortableItem,
|
|
283
|
+
{
|
|
284
|
+
id,
|
|
285
|
+
render: ({
|
|
286
|
+
itemProps,
|
|
287
|
+
isDragged,
|
|
288
|
+
triggerProps,
|
|
289
|
+
itemStyle,
|
|
290
|
+
triggerStyle,
|
|
291
|
+
dropIndicationStyle,
|
|
292
|
+
showDropIndication
|
|
293
|
+
}) => {
|
|
294
|
+
return /* @__PURE__ */ React3.createElement(StyledSortableItem, { ...itemProps, elevation: 0, sx: itemStyle, role: "listitem" }, /* @__PURE__ */ React3.createElement(SortableTrigger, { ...triggerProps, style: triggerStyle }), children({
|
|
295
|
+
itemProps,
|
|
296
|
+
isDragged,
|
|
297
|
+
triggerProps,
|
|
298
|
+
itemStyle,
|
|
299
|
+
triggerStyle,
|
|
300
|
+
dropIndicationStyle,
|
|
301
|
+
showDropIndication
|
|
302
|
+
}));
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
);
|
|
306
|
+
};
|
|
307
|
+
var StyledSortableItem = (0, import_ui3.styled)(import_ui3.Paper)`
|
|
308
|
+
position: relative;
|
|
309
|
+
|
|
310
|
+
&:hover {
|
|
311
|
+
& .class-item-sortable-trigger {
|
|
312
|
+
visibility: visible;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
& .class-item-sortable-trigger {
|
|
317
|
+
visibility: hidden;
|
|
318
|
+
position: absolute;
|
|
319
|
+
left: 0;
|
|
320
|
+
top: 50%;
|
|
321
|
+
transform: translate( -75%, -50% );
|
|
322
|
+
}
|
|
323
|
+
`;
|
|
324
|
+
var SortableItemIndicator = (0, import_ui3.styled)(import_ui3.Box)`
|
|
325
|
+
width: 100%;
|
|
326
|
+
height: 3px;
|
|
327
|
+
border-radius: ${({ theme }) => theme.spacing(0.5)};
|
|
328
|
+
background-color: ${({ theme }) => theme.palette.text.primary};
|
|
329
|
+
`;
|
|
112
330
|
|
|
113
331
|
// src/components/class-manager/global-classes-list.tsx
|
|
114
332
|
var GlobalClassesList = () => {
|
|
115
333
|
const cssClasses = useOrderedGlobalClasses();
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
334
|
+
const [classesOrder, reorderClasses] = useClassesOrder();
|
|
335
|
+
if (!cssClasses?.length) {
|
|
336
|
+
return /* @__PURE__ */ React4.createElement(EmptyState, null);
|
|
337
|
+
}
|
|
338
|
+
return /* @__PURE__ */ React4.createElement(DeleteConfirmationProvider, null, /* @__PURE__ */ React4.createElement(import_ui4.List, { sx: { display: "flex", flexDirection: "column", gap: 0.5 } }, /* @__PURE__ */ React4.createElement(SortableProvider, { value: classesOrder, onChange: reorderClasses }, cssClasses?.map(({ id, label }) => {
|
|
339
|
+
const renameClass = (newLabel) => {
|
|
340
|
+
globalClassesStylesProvider.actions.update({ label: newLabel, id });
|
|
341
|
+
};
|
|
342
|
+
return /* @__PURE__ */ React4.createElement(SortableItem, { key: id, id }, ({ isDragged, showDropIndication, dropIndicationStyle }) => /* @__PURE__ */ React4.createElement(
|
|
343
|
+
ClassItem,
|
|
344
|
+
{
|
|
345
|
+
id,
|
|
346
|
+
label,
|
|
347
|
+
renameClass,
|
|
348
|
+
selected: isDragged
|
|
349
|
+
},
|
|
350
|
+
showDropIndication && /* @__PURE__ */ React4.createElement(SortableItemIndicator, { style: dropIndicationStyle })
|
|
351
|
+
));
|
|
352
|
+
}))));
|
|
353
|
+
};
|
|
354
|
+
var useClassesOrder = () => {
|
|
355
|
+
const order = useGlobalClassesOrder();
|
|
356
|
+
const reorder = (newIds) => {
|
|
357
|
+
globalClassesStylesProvider.actions.setOrder(newIds);
|
|
358
|
+
};
|
|
359
|
+
return [order, reorder];
|
|
360
|
+
};
|
|
361
|
+
var ClassItem = ({
|
|
362
|
+
id,
|
|
363
|
+
label,
|
|
364
|
+
renameClass,
|
|
365
|
+
selected,
|
|
366
|
+
children
|
|
367
|
+
}) => {
|
|
368
|
+
const {
|
|
369
|
+
ref: editableRef,
|
|
370
|
+
openEditMode,
|
|
371
|
+
isEditing,
|
|
372
|
+
error,
|
|
373
|
+
getProps: getEditableProps
|
|
374
|
+
} = (0, import_editor_ui2.useEditable)({
|
|
375
|
+
value: label,
|
|
376
|
+
onSubmit: renameClass,
|
|
377
|
+
validation: validateLabel
|
|
378
|
+
});
|
|
379
|
+
const { openDialog } = useDeleteConfirmation();
|
|
380
|
+
const popupState = (0, import_ui4.usePopupState)({
|
|
381
|
+
variant: "popover",
|
|
382
|
+
disableAutoFocus: true
|
|
383
|
+
});
|
|
384
|
+
return /* @__PURE__ */ React4.createElement(import_ui4.Stack, { direction: "row", alignItems: "center", gap: 1, flexGrow: 1, flexShrink: 0 }, /* @__PURE__ */ React4.createElement(
|
|
385
|
+
StyledListItem,
|
|
386
|
+
{
|
|
387
|
+
component: "div",
|
|
388
|
+
disablePadding: true,
|
|
389
|
+
disableGutters: true,
|
|
390
|
+
secondaryAction: /* @__PURE__ */ React4.createElement(
|
|
391
|
+
import_ui4.Tooltip,
|
|
392
|
+
{
|
|
393
|
+
placement: "top",
|
|
394
|
+
className: "class-item-more-actions",
|
|
395
|
+
title: (0, import_i18n4.__)("More actions", "elementor")
|
|
396
|
+
},
|
|
397
|
+
/* @__PURE__ */ React4.createElement(import_ui4.IconButton, { size: "tiny", ...(0, import_ui4.bindTrigger)(popupState), "aria-label": "More actions" }, /* @__PURE__ */ React4.createElement(import_icons3.DotsVerticalIcon, { fontSize: "tiny" }))
|
|
398
|
+
)
|
|
399
|
+
},
|
|
400
|
+
/* @__PURE__ */ React4.createElement(
|
|
401
|
+
import_ui4.ListItemButton,
|
|
402
|
+
{
|
|
403
|
+
dense: true,
|
|
404
|
+
disableGutters: true,
|
|
405
|
+
shape: "rounded",
|
|
406
|
+
onDoubleClick: openEditMode,
|
|
407
|
+
selected: selected || popupState.isOpen,
|
|
408
|
+
focusVisibleClassName: "visible-class-item",
|
|
409
|
+
sx: {
|
|
410
|
+
minHeight: "36px",
|
|
411
|
+
display: "flex",
|
|
412
|
+
"&.visible-class-item": {
|
|
413
|
+
boxShadow: "none !important"
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
},
|
|
417
|
+
/* @__PURE__ */ React4.createElement(Indicator, { isActive: isEditing, isError: !!error }, isEditing ? /* @__PURE__ */ React4.createElement(
|
|
418
|
+
import_editor_ui2.EditableField,
|
|
419
|
+
{
|
|
420
|
+
ref: editableRef,
|
|
421
|
+
error,
|
|
422
|
+
as: import_ui4.Typography,
|
|
423
|
+
variant: "caption",
|
|
424
|
+
...getEditableProps()
|
|
425
|
+
}
|
|
426
|
+
) : /* @__PURE__ */ React4.createElement(import_editor_ui2.EllipsisWithTooltip, { title: label, as: import_ui4.Typography, variant: "caption" }))
|
|
427
|
+
),
|
|
428
|
+
children,
|
|
429
|
+
/* @__PURE__ */ React4.createElement(
|
|
430
|
+
import_ui4.Menu,
|
|
431
|
+
{
|
|
432
|
+
...(0, import_ui4.bindMenu)(popupState),
|
|
433
|
+
anchorOrigin: {
|
|
434
|
+
vertical: "bottom",
|
|
435
|
+
horizontal: "right"
|
|
436
|
+
},
|
|
437
|
+
transformOrigin: {
|
|
438
|
+
vertical: "top",
|
|
439
|
+
horizontal: "right"
|
|
440
|
+
}
|
|
441
|
+
},
|
|
442
|
+
/* @__PURE__ */ React4.createElement(
|
|
443
|
+
import_ui4.MenuItem,
|
|
444
|
+
{
|
|
445
|
+
sx: { minWidth: "160px" },
|
|
446
|
+
onClick: () => {
|
|
447
|
+
popupState.close();
|
|
448
|
+
openEditMode();
|
|
449
|
+
}
|
|
450
|
+
},
|
|
451
|
+
/* @__PURE__ */ React4.createElement(import_ui4.ListItemText, { primary: (0, import_i18n4.__)("Rename", "elementor") })
|
|
452
|
+
),
|
|
453
|
+
/* @__PURE__ */ React4.createElement(
|
|
454
|
+
import_ui4.MenuItem,
|
|
455
|
+
{
|
|
456
|
+
onClick: () => {
|
|
457
|
+
popupState.close();
|
|
458
|
+
openDialog({ id, label });
|
|
459
|
+
}
|
|
460
|
+
},
|
|
461
|
+
/* @__PURE__ */ React4.createElement(import_ui4.ListItemText, { primary: (0, import_i18n4.__)("Delete", "elementor"), sx: { color: "error.light" } })
|
|
462
|
+
)
|
|
463
|
+
)
|
|
464
|
+
));
|
|
465
|
+
};
|
|
466
|
+
var StyledListItem = (0, import_ui4.styled)(import_ui4.ListItem)`
|
|
467
|
+
.class-item-more-actions {
|
|
468
|
+
visibility: hidden;
|
|
469
|
+
}
|
|
470
|
+
&:hover {
|
|
471
|
+
.class-item-more-actions {
|
|
472
|
+
visibility: visible;
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
`;
|
|
476
|
+
var EmptyState = () => /* @__PURE__ */ React4.createElement(import_ui4.Stack, { alignItems: "center", gap: 3, pt: 4, px: 0.5 }, /* @__PURE__ */ React4.createElement(import_icons3.PhotoIcon, { fontSize: "large" }), /* @__PURE__ */ React4.createElement(StyledHeader, { variant: "subtitle2", component: "h2", color: "text.secondary" }, (0, import_i18n4.__)("No CSS classes created yet", "elementor")), /* @__PURE__ */ React4.createElement(import_ui4.Typography, { align: "center", variant: "caption", color: "text.secondary" }, (0, import_i18n4.__)(
|
|
477
|
+
"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.",
|
|
478
|
+
"elementor"
|
|
479
|
+
)));
|
|
480
|
+
var StyledHeader = (0, import_ui4.styled)(import_ui4.Typography)(({ theme, variant }) => ({
|
|
481
|
+
"&.MuiTypography-root": {
|
|
482
|
+
...theme.typography[variant]
|
|
483
|
+
}
|
|
484
|
+
}));
|
|
485
|
+
var Indicator = (0, import_ui4.styled)(import_ui4.Box, {
|
|
486
|
+
shouldForwardProp: (prop) => !["isActive", "isError"].includes(prop)
|
|
487
|
+
})(({ theme, isActive, isError }) => ({
|
|
488
|
+
display: "flex",
|
|
489
|
+
width: "100%",
|
|
490
|
+
flexGrow: 1,
|
|
491
|
+
borderRadius: theme.spacing(0.5),
|
|
492
|
+
border: getIndicatorBorder({ isActive, isError, theme }),
|
|
493
|
+
padding: `0 ${theme.spacing(1)}`,
|
|
494
|
+
marginLeft: isActive ? theme.spacing(1) : 0
|
|
495
|
+
}));
|
|
496
|
+
var getIndicatorBorder = ({ isActive, isError, theme }) => {
|
|
497
|
+
if (isError) {
|
|
498
|
+
return `2px solid ${theme.palette.error.main}`;
|
|
499
|
+
}
|
|
500
|
+
if (isActive) {
|
|
501
|
+
return `2px solid ${theme.palette.secondary.main}`;
|
|
502
|
+
}
|
|
503
|
+
return "none";
|
|
504
|
+
};
|
|
505
|
+
var validateLabel = (newLabel) => {
|
|
506
|
+
if (!import_editor_styles_repository.stylesRepository.isLabelValid(newLabel)) {
|
|
507
|
+
return (0, import_i18n4.__)("Format is not valid", "elementor");
|
|
508
|
+
}
|
|
509
|
+
if (import_editor_styles_repository.stylesRepository.isLabelExist(newLabel)) {
|
|
510
|
+
return (0, import_i18n4.__)("Existing name", "elementor");
|
|
511
|
+
}
|
|
119
512
|
};
|
|
120
513
|
|
|
121
514
|
// src/components/class-manager/class-manager-panel.tsx
|
|
122
|
-
var { panel, usePanelActions
|
|
515
|
+
var { panel, usePanelActions } = (0, import_editor_panels.__createPanel)({
|
|
123
516
|
id: "class-manager-panel",
|
|
124
517
|
component: ClassManagerPanel
|
|
125
518
|
});
|
|
126
519
|
function ClassManagerPanel() {
|
|
127
|
-
return /* @__PURE__ */
|
|
520
|
+
return /* @__PURE__ */ React5.createElement(React5.Fragment, null, /* @__PURE__ */ React5.createElement(import_ui5.ErrorBoundary, { fallback: /* @__PURE__ */ React5.createElement(ErrorBoundaryFallback, null) }, /* @__PURE__ */ React5.createElement(import_editor_panels.Panel, null, /* @__PURE__ */ React5.createElement(import_editor_panels.PanelHeader, null, /* @__PURE__ */ React5.createElement(import_ui5.Stack, { p: 1, pl: 2, width: "100%", direction: "row", alignItems: "center" }, /* @__PURE__ */ React5.createElement(import_editor_panels.PanelHeaderTitle, { sx: { display: "flex", alignItems: "center", gap: 0.5 } }, /* @__PURE__ */ React5.createElement(import_icons4.ColorSwatchIcon, { fontSize: "inherit", sx: { transform: "rotate(90deg)" } }), (0, import_i18n5.__)("CSS Class manager")), /* @__PURE__ */ React5.createElement(CloseButton, { sx: { marginLeft: "auto" } }))), /* @__PURE__ */ React5.createElement(import_editor_panels.PanelBody, { px: 2 }, /* @__PURE__ */ React5.createElement(GlobalClassesList, null)))), /* @__PURE__ */ React5.createElement(ClassManagerIntroduction, null));
|
|
128
521
|
}
|
|
129
522
|
var CloseButton = (props) => {
|
|
130
523
|
const { close } = usePanelActions();
|
|
131
|
-
return /* @__PURE__ */
|
|
524
|
+
return /* @__PURE__ */ React5.createElement(import_ui5.IconButton, { size: "small", color: "secondary", onClick: close, ...props }, /* @__PURE__ */ React5.createElement(import_icons4.XIcon, { fontSize: "small" }));
|
|
132
525
|
};
|
|
133
|
-
var ErrorBoundaryFallback = () => /* @__PURE__ */
|
|
526
|
+
var ErrorBoundaryFallback = () => /* @__PURE__ */ React5.createElement(import_ui5.Box, { role: "alert", sx: { minHeight: "100%", p: 2 } }, /* @__PURE__ */ React5.createElement(import_ui5.Alert, { severity: "error", sx: { mb: 2, maxWidth: 400, textAlign: "center" } }, /* @__PURE__ */ React5.createElement("strong", null, (0, import_i18n5.__)("Something went wrong", "elementor"))));
|
|
134
527
|
|
|
135
528
|
// src/components/class-manager/class-manager-button.tsx
|
|
136
529
|
var ClassManagerButton = () => {
|
|
137
530
|
const { open } = usePanelActions();
|
|
138
|
-
return /* @__PURE__ */
|
|
531
|
+
return /* @__PURE__ */ React6.createElement(import_ui6.Tooltip, { title: (0, import_i18n6.__)("Class manager"), placement: "top" }, /* @__PURE__ */ React6.createElement(import_ui6.IconButton, { onClick: open }, /* @__PURE__ */ React6.createElement(import_icons5.ColorSwatchIcon, { fontSize: "tiny" })));
|
|
139
532
|
};
|
|
140
533
|
|
|
141
|
-
// src/components/
|
|
142
|
-
var
|
|
143
|
-
var
|
|
534
|
+
// src/components/populate-store.tsx
|
|
535
|
+
var import_react3 = require("react");
|
|
536
|
+
var import_store5 = require("@elementor/store");
|
|
144
537
|
|
|
145
538
|
// src/api.ts
|
|
146
539
|
var import_http = require("@elementor/http");
|
|
147
540
|
var RESOURCE_URL = "/global-classes";
|
|
148
541
|
var apiClient = {
|
|
149
|
-
all:
|
|
150
|
-
|
|
151
|
-
},
|
|
152
|
-
post: async (data) => {
|
|
153
|
-
return (0, import_http.httpService)().post(RESOURCE_URL, data);
|
|
154
|
-
},
|
|
155
|
-
put: async (id, data) => {
|
|
156
|
-
return (0, import_http.httpService)().put(`${RESOURCE_URL}/${id}`, data);
|
|
157
|
-
}
|
|
542
|
+
all: () => (0, import_http.httpService)().get("elementor/v1" + RESOURCE_URL),
|
|
543
|
+
update: (payload) => (0, import_http.httpService)().put("elementor/v1" + RESOURCE_URL, payload)
|
|
158
544
|
};
|
|
159
545
|
|
|
160
|
-
// src/components/
|
|
161
|
-
function
|
|
162
|
-
const dispatch2 = (0,
|
|
163
|
-
(0,
|
|
546
|
+
// src/components/populate-store.tsx
|
|
547
|
+
function PopulateStore() {
|
|
548
|
+
const dispatch2 = (0, import_store5.__useDispatch)();
|
|
549
|
+
(0, import_react3.useEffect)(() => {
|
|
164
550
|
apiClient.all().then((res) => {
|
|
165
551
|
const { data, meta } = res.data;
|
|
166
552
|
dispatch2(slice.actions.init({ items: data, order: meta.order }));
|
|
@@ -169,69 +555,55 @@ function LogicHooks() {
|
|
|
169
555
|
return null;
|
|
170
556
|
}
|
|
171
557
|
|
|
172
|
-
// src/
|
|
173
|
-
var
|
|
174
|
-
var
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
(0, import_store5.__dispatch)(
|
|
185
|
-
slice.actions.add({
|
|
186
|
-
style: data,
|
|
187
|
-
order: meta.order
|
|
188
|
-
})
|
|
189
|
-
);
|
|
190
|
-
return data;
|
|
191
|
-
},
|
|
192
|
-
update: async (payload) => {
|
|
193
|
-
const style = selectClass((0, import_store5.__getState)(), payload.id);
|
|
194
|
-
const mergedData = { ...style, ...payload };
|
|
195
|
-
const res = await apiClient.put(payload.id, mergedData);
|
|
196
|
-
const { data, meta } = res.data;
|
|
197
|
-
(0, import_store5.__dispatch)(
|
|
198
|
-
slice.actions.update({
|
|
199
|
-
style: data,
|
|
200
|
-
order: meta.order
|
|
201
|
-
})
|
|
202
|
-
);
|
|
203
|
-
return data;
|
|
204
|
-
},
|
|
205
|
-
updateProps: (args) => {
|
|
206
|
-
(0, import_store5.__dispatch)(
|
|
207
|
-
slice.actions.updateProps({
|
|
208
|
-
id: args.id,
|
|
209
|
-
meta: args.meta,
|
|
210
|
-
props: args.props
|
|
211
|
-
})
|
|
212
|
-
);
|
|
558
|
+
// src/sync-with-document-save.ts
|
|
559
|
+
var import_editor_v1_adapters = require("@elementor/editor-v1-adapters");
|
|
560
|
+
var import_store7 = require("@elementor/store");
|
|
561
|
+
function syncWithDocumentSave() {
|
|
562
|
+
const unsubscribe = syncDirtyState();
|
|
563
|
+
bindSaveAction();
|
|
564
|
+
return unsubscribe;
|
|
565
|
+
}
|
|
566
|
+
function syncDirtyState() {
|
|
567
|
+
return (0, import_store7.__subscribeWithSelector)(selectIsDirty, () => {
|
|
568
|
+
if (!isDirty()) {
|
|
569
|
+
return;
|
|
213
570
|
}
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
571
|
+
(0, import_editor_v1_adapters.__privateRunCommandSync)("document/save/set-is-modified", { status: true }, { internal: true });
|
|
572
|
+
});
|
|
573
|
+
}
|
|
574
|
+
function bindSaveAction() {
|
|
575
|
+
(0, import_editor_v1_adapters.registerDataHook)("after", "document/save/save", async () => {
|
|
576
|
+
if (!isDirty()) {
|
|
577
|
+
return;
|
|
578
|
+
}
|
|
579
|
+
const state = (0, import_store7.__getState)().globalClasses;
|
|
580
|
+
await apiClient.update({
|
|
581
|
+
items: state.items,
|
|
582
|
+
order: state.order
|
|
583
|
+
});
|
|
584
|
+
(0, import_store7.__dispatch)(slice.actions.setPristine());
|
|
585
|
+
});
|
|
586
|
+
}
|
|
587
|
+
function isDirty() {
|
|
588
|
+
return selectIsDirty((0, import_store7.__getState)());
|
|
589
|
+
}
|
|
221
590
|
|
|
222
591
|
// src/init.ts
|
|
223
592
|
function init() {
|
|
224
|
-
(0,
|
|
593
|
+
(0, import_store9.__registerSlice)(slice);
|
|
225
594
|
(0, import_editor_panels2.__registerPanel)(panel);
|
|
226
|
-
|
|
595
|
+
import_editor_styles_repository2.stylesRepository.register(globalClassesStylesProvider);
|
|
227
596
|
(0, import_editor.injectIntoLogic)({
|
|
228
|
-
id: "global-classes-
|
|
229
|
-
component:
|
|
597
|
+
id: "global-classes-populate-store",
|
|
598
|
+
component: PopulateStore
|
|
230
599
|
});
|
|
231
600
|
(0, import_editor_editing_panel.injectIntoClassSelectorActions)({
|
|
232
|
-
id: "global-classes",
|
|
601
|
+
id: "global-classes-manager-button",
|
|
233
602
|
component: ClassManagerButton
|
|
234
603
|
});
|
|
604
|
+
(0, import_editor_v1_adapters2.__privateListenTo)((0, import_editor_v1_adapters2.v1ReadyEvent)(), () => {
|
|
605
|
+
syncWithDocumentSave();
|
|
606
|
+
});
|
|
235
607
|
}
|
|
236
608
|
|
|
237
609
|
// src/index.ts
|