@elementor/editor-global-classes 4.2.0-888 → 4.2.0-895

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.d.mts CHANGED
@@ -4,8 +4,9 @@ import { StyleDefinitionID, StyleDefinition } from '@elementor/editor-styles';
4
4
  type ClassManagerPanelEmbeddedProps = {
5
5
  onRequestClose: () => void | Promise<void>;
6
6
  onExposeCloseAttempt?: (attemptClose: (() => void) | null) => void;
7
+ isActive?: boolean;
7
8
  };
8
- declare function ClassManagerPanelEmbedded({ onRequestClose, onExposeCloseAttempt }: ClassManagerPanelEmbeddedProps): React.JSX.Element;
9
+ declare function ClassManagerPanelEmbedded({ onRequestClose, onExposeCloseAttempt, isActive, }: ClassManagerPanelEmbeddedProps): React.JSX.Element;
9
10
 
10
11
  declare const GLOBAL_CLASSES_URI = "elementor://global-classes";
11
12
 
package/dist/index.d.ts CHANGED
@@ -4,8 +4,9 @@ import { StyleDefinitionID, StyleDefinition } from '@elementor/editor-styles';
4
4
  type ClassManagerPanelEmbeddedProps = {
5
5
  onRequestClose: () => void | Promise<void>;
6
6
  onExposeCloseAttempt?: (attemptClose: (() => void) | null) => void;
7
+ isActive?: boolean;
7
8
  };
8
- declare function ClassManagerPanelEmbedded({ onRequestClose, onExposeCloseAttempt }: ClassManagerPanelEmbeddedProps): React.JSX.Element;
9
+ declare function ClassManagerPanelEmbedded({ onRequestClose, onExposeCloseAttempt, isActive, }: ClassManagerPanelEmbeddedProps): React.JSX.Element;
9
10
 
10
11
  declare const GLOBAL_CLASSES_URI = "elementor://global-classes";
11
12
 
package/dist/index.js CHANGED
@@ -2122,10 +2122,25 @@ var StartSyncToV3Modal = ({
2122
2122
 
2123
2123
  // src/components/class-manager/class-manager-panel.tsx
2124
2124
  var STOP_SYNC_MESSAGE_KEY = "stop-sync-class";
2125
- function ClassManagerPanelEmbedded({ onRequestClose, onExposeCloseAttempt }) {
2126
- return /* @__PURE__ */ React19.createElement(ClassManagerPanelContent, { onRequestClose, onExposeCloseAttempt });
2125
+ function ClassManagerPanelEmbedded({
2126
+ onRequestClose,
2127
+ onExposeCloseAttempt,
2128
+ isActive
2129
+ }) {
2130
+ return /* @__PURE__ */ React19.createElement(
2131
+ ClassManagerPanelContent,
2132
+ {
2133
+ onRequestClose,
2134
+ onExposeCloseAttempt,
2135
+ isActive
2136
+ }
2137
+ );
2127
2138
  }
2128
- function ClassManagerPanelContent({ onRequestClose, onExposeCloseAttempt }) {
2139
+ function ClassManagerPanelContent({
2140
+ onRequestClose,
2141
+ onExposeCloseAttempt,
2142
+ isActive = true
2143
+ }) {
2129
2144
  const isDirty2 = useDirtyState();
2130
2145
  const { open: openSaveChangesDialog, close: closeSaveChangesDialog, isOpen: isSaveChangesDialogOpen } = (0, import_editor_ui9.useDialog)();
2131
2146
  const [stopSyncConfirmation, setStopSyncConfirmation] = (0, import_react10.useState)(null);
@@ -2252,7 +2267,7 @@ function ClassManagerPanelContent({ onRequestClose, onExposeCloseAttempt }) {
2252
2267
  },
2253
2268
  (0, import_i18n14.__)("Save changes", "elementor")
2254
2269
  ))
2255
- ))), /* @__PURE__ */ React19.createElement(ClassManagerIntroduction, null), startSyncConfirmation && /* @__PURE__ */ React19.createElement(
2270
+ ))), isActive && /* @__PURE__ */ React19.createElement(ClassManagerIntroduction, null), startSyncConfirmation && /* @__PURE__ */ React19.createElement(
2256
2271
  StartSyncToV3Modal,
2257
2272
  {
2258
2273
  externalOpen: true,
@@ -2465,8 +2480,10 @@ async function fetchAndMergeClasses() {
2465
2480
  if (idsToFetch.length === 0) {
2466
2481
  return;
2467
2482
  }
2468
- const previewResponse = await apiClient.getStylesByIds(idsToFetch, "preview");
2469
- const frontendResponse = await apiClient.getStylesByIds(idsToFetch, "frontend");
2483
+ const [previewResponse, frontendResponse] = await Promise.all([
2484
+ apiClient.getStylesByIds(idsToFetch, "preview"),
2485
+ apiClient.getStylesByIds(idsToFetch, "frontend")
2486
+ ]);
2470
2487
  const previewItems = styleDefinitionsMapWithoutNull(previewResponse.data.data);
2471
2488
  const frontendItems = styleDefinitionsMapWithoutNull(frontendResponse.data.data);
2472
2489
  (0, import_store22.__dispatch)(slice.actions.mergeExistingClasses({ preview: previewItems, frontend: frontendItems }));
@@ -2618,9 +2635,7 @@ var import_store32 = require("@elementor/store");
2618
2635
 
2619
2636
  // src/components/class-manager/class-manager-button.tsx
2620
2637
  var React20 = __toESM(require("react"));
2621
- var import_editor_documents5 = require("@elementor/editor-documents");
2622
2638
  var import_editor_styles_repository3 = require("@elementor/editor-styles-repository");
2623
- var import_editor_ui10 = require("@elementor/editor-ui");
2624
2639
  var import_ui17 = require("@elementor/ui");
2625
2640
  var import_i18n16 = require("@wordpress/i18n");
2626
2641
 
@@ -2641,68 +2656,33 @@ var PrefetchCssClassUsage = () => {
2641
2656
  };
2642
2657
 
2643
2658
  // src/components/class-manager/class-manager-button.tsx
2644
- var trackGlobalClassesButton = () => {
2645
- trackGlobalClasses({
2646
- event: "classManagerOpened",
2647
- source: "style-panel"
2648
- });
2649
- };
2659
+ var EVENT_TOGGLE_DESIGN_SYSTEM = "elementor/toggle-design-system";
2650
2660
  var ClassManagerButton = () => {
2651
- const document = (0, import_editor_documents5.__useActiveDocument)();
2652
- const { save: saveDocument } = (0, import_editor_documents5.__useActiveDocumentActions)();
2653
- const { open: openSaveChangesDialog, close: closeSaveChangesDialog, isOpen: isSaveChangesDialogOpen } = (0, import_editor_ui10.useDialog)();
2654
2661
  const { prefetchClassesUsage } = usePrefetchCssClassUsage();
2655
2662
  const { userCan } = (0, import_editor_styles_repository3.useUserStylesCapability)();
2656
2663
  const isUserAllowedToUpdateClass = userCan(globalClassesStylesProvider.getKey()).update;
2657
2664
  if (!isUserAllowedToUpdateClass) {
2658
2665
  return null;
2659
2666
  }
2660
- const toggleClassesManagerPanel = () => {
2667
+ const handleOpenPanel = () => {
2661
2668
  window.dispatchEvent(
2662
- new CustomEvent("elementor/toggle-design-system", {
2669
+ new CustomEvent(EVENT_TOGGLE_DESIGN_SYSTEM, {
2663
2670
  detail: { tab: "classes" }
2664
2671
  })
2665
2672
  );
2666
- };
2667
- const handleOpenPanel = () => {
2668
- if (document?.isDirty) {
2669
- openSaveChangesDialog();
2670
- return;
2671
- }
2672
- toggleClassesManagerPanel();
2673
- trackGlobalClassesButton();
2673
+ trackGlobalClasses({
2674
+ event: "classManagerOpened",
2675
+ source: "style-panel"
2676
+ });
2674
2677
  prefetchClassesUsage();
2675
2678
  };
2676
- return /* @__PURE__ */ React20.createElement(React20.Fragment, null, /* @__PURE__ */ React20.createElement(import_ui17.Tooltip, { title: (0, import_i18n16.__)("Class Manager", "elementor"), placement: "top" }, /* @__PURE__ */ React20.createElement(import_ui17.IconButton, { size: "tiny", onClick: handleOpenPanel, sx: { marginInlineEnd: -0.75 } }, /* @__PURE__ */ React20.createElement(FlippedColorSwatchIcon, { fontSize: "tiny" }))), isSaveChangesDialogOpen && /* @__PURE__ */ React20.createElement(import_editor_ui10.SaveChangesDialog, null, /* @__PURE__ */ React20.createElement(import_editor_ui10.SaveChangesDialog.Title, null, (0, import_i18n16.__)("You have unsaved changes", "elementor")), /* @__PURE__ */ React20.createElement(import_editor_ui10.SaveChangesDialog.Content, null, /* @__PURE__ */ React20.createElement(import_editor_ui10.SaveChangesDialog.ContentText, { sx: { mb: 2 } }, (0, import_i18n16.__)(
2677
- "To open the Class Manager, save your page first. You can't continue without saving.",
2678
- "elementor"
2679
- ))), /* @__PURE__ */ React20.createElement(
2680
- import_editor_ui10.SaveChangesDialog.Actions,
2681
- {
2682
- actions: {
2683
- cancel: {
2684
- label: (0, import_i18n16.__)("Stay here", "elementor"),
2685
- action: closeSaveChangesDialog
2686
- },
2687
- confirm: {
2688
- label: (0, import_i18n16.__)("Save & Continue", "elementor"),
2689
- action: async () => {
2690
- await saveDocument();
2691
- closeSaveChangesDialog();
2692
- toggleClassesManagerPanel();
2693
- trackGlobalClassesButton();
2694
- prefetchClassesUsage();
2695
- }
2696
- }
2697
- }
2698
- }
2699
- )));
2679
+ return /* @__PURE__ */ React20.createElement(import_ui17.Tooltip, { title: (0, import_i18n16.__)("Class Manager", "elementor"), placement: "top" }, /* @__PURE__ */ React20.createElement(import_ui17.IconButton, { size: "tiny", onClick: handleOpenPanel, sx: { marginInlineEnd: -0.75 } }, /* @__PURE__ */ React20.createElement(FlippedColorSwatchIcon, { fontSize: "tiny" })));
2700
2680
  };
2701
2681
 
2702
2682
  // src/components/convert-local-class-to-global-class.tsx
2703
2683
  var React21 = __toESM(require("react"));
2704
2684
  var import_editor_styles_repository4 = require("@elementor/editor-styles-repository");
2705
- var import_editor_ui11 = require("@elementor/editor-ui");
2685
+ var import_editor_ui10 = require("@elementor/editor-ui");
2706
2686
  var import_ui18 = require("@elementor/ui");
2707
2687
  var import_i18n17 = require("@wordpress/i18n");
2708
2688
  var ConvertLocalClassToGlobalClass = (props) => {
@@ -2724,7 +2704,7 @@ var ConvertLocalClassToGlobalClass = (props) => {
2724
2704
  }
2725
2705
  };
2726
2706
  return /* @__PURE__ */ React21.createElement(React21.Fragment, null, /* @__PURE__ */ React21.createElement(
2727
- import_editor_ui11.MenuListItem,
2707
+ import_editor_ui10.MenuListItem,
2728
2708
  {
2729
2709
  disabled: !props.canConvert,
2730
2710
  onClick: handleConversion,
@@ -2968,12 +2948,30 @@ var schema = {
2968
2948
  classId: import_schema3.z.string().optional().describe("Global class ID (required for modify). Get from elementor://global-classes resource."),
2969
2949
  globalClassName: import_schema3.z.string().optional().describe("Global class name (required for create)"),
2970
2950
  props: import_schema3.z.object({
2971
- default: import_schema3.z.record(import_schema3.z.any()).describe(
2972
- 'key-value of style-schema PropValues. Available properties at dynamic resource "elementor://styles/schema/{property-name}"'
2951
+ default: import_schema3.z.record(
2952
+ import_schema3.z.string().describe("The style property name"),
2953
+ import_schema3.z.any().describe(`The style PropValue, refer to [${import_editor_canvas2.STYLE_SCHEMA_FULL_URI}] how to generate values`)
2954
+ ).describe(
2955
+ "An object record containing style property names and their new values. MUST contain at least one property \u2014 empty objects are rejected."
2973
2956
  ),
2974
- hover: import_schema3.z.record(import_schema3.z.any()).describe("key-value of style-schema PropValues, for :hover css state. optional").optional(),
2975
- focus: import_schema3.z.record(import_schema3.z.any()).describe("key-value of style-schema PropValues, for :focus css state. optional").optional(),
2976
- active: import_schema3.z.record(import_schema3.z.any()).describe("key-value of style-schema PropValues, for :active css state. optional").optional()
2957
+ hover: import_schema3.z.record(
2958
+ import_schema3.z.string().describe("The style property name"),
2959
+ import_schema3.z.any().describe(`The style PropValue, refer to [${import_editor_canvas2.STYLE_SCHEMA_FULL_URI}] how to generate values`)
2960
+ ).describe(
2961
+ "An object record containing style property names and their new values to be set on the element. for :hover css state. optional"
2962
+ ).optional(),
2963
+ focus: import_schema3.z.record(
2964
+ import_schema3.z.string().describe("The style property name"),
2965
+ import_schema3.z.any().describe(`The style PropValue, refer to [${import_editor_canvas2.STYLE_SCHEMA_FULL_URI}] how to generate values`)
2966
+ ).describe(
2967
+ "An object record containing style property names and their new values to be set on the element. for :focus css state. optional"
2968
+ ).optional(),
2969
+ active: import_schema3.z.record(
2970
+ import_schema3.z.string().describe("The style property name"),
2971
+ import_schema3.z.any().describe(`The style PropValue, refer to [${import_editor_canvas2.STYLE_SCHEMA_FULL_URI}] how to generate values`)
2972
+ ).describe(
2973
+ "An object record containing style property names and their new values to be set on the element. for :active css state. optional"
2974
+ ).optional()
2977
2975
  }),
2978
2976
  breakpoint: import_schema3.z.nullable(import_schema3.z.string().describe("Responsive breakpoint name for styles. Defaults to desktop (null).")).default(null).describe("Responsive breakpoint name for styles. Defaults to desktop (null).")
2979
2977
  };
@@ -3029,16 +3027,32 @@ var handler = async (input) => {
3029
3027
  }
3030
3028
  });
3031
3029
  });
3030
+ if (action !== "delete") {
3031
+ const hasAnyProps = Object.values(propsWithStates).some(
3032
+ (stateProps) => Object.keys(stateProps).length > 0
3033
+ );
3034
+ if (!hasAnyProps) {
3035
+ throw new Error(
3036
+ `Props must not be empty. Each prop must be a PropValue object from the style schema.
3037
+
3038
+ Example: { "display": { "$$type": "string", "value": "flex" }, "flex-direction": { "$$type": "string", "value": "column" } }
3039
+
3040
+ ${import_editor_canvas2.STYLE_SCHEMA_FULL_URI} to get the allowed values (look at the "value" enum in the schema response), then construct { "$$type": "string", "value": "<chosen value>" } for each property.
3041
+ Available Properties: ${validProps.join(
3042
+ ", "
3043
+ )}`
3044
+ );
3045
+ }
3046
+ }
3032
3047
  if (errors.length > 0) {
3033
- return {
3034
- status: "error",
3035
- message: `Validation errors:
3048
+ throw new Error(
3049
+ `Validation errors:
3036
3050
  ${errors.join("\n")}
3037
3051
  Available Properties: ${validProps.join(
3038
3052
  ", "
3039
3053
  )}
3040
3054
  Update your input and try again.`
3041
- };
3055
+ );
3042
3056
  }
3043
3057
  const Utils = window.elementorV2.editorVariables.Utils;
3044
3058
  Object.values(propsWithStates).forEach((props) => {
@@ -3055,6 +3069,16 @@ Update your input and try again.`
3055
3069
  message: "unknown error"
3056
3070
  };
3057
3071
  try {
3072
+ if (action === "delete") {
3073
+ const deleted = await attemptDelete({
3074
+ classId,
3075
+ stylesProvider: globalClassesStylesProvider
3076
+ });
3077
+ if (deleted) {
3078
+ return { status: "ok", message: `deleted global class with ID ${classId}` };
3079
+ }
3080
+ throw new Error("error deleting class");
3081
+ }
3058
3082
  let currentAction = action;
3059
3083
  for await (const [state, props] of Object.entries(propsWithStates)) {
3060
3084
  switch (currentAction) {
@@ -3069,14 +3093,13 @@ Update your input and try again.`
3069
3093
  if (newClassId && currentAction === "create") {
3070
3094
  currentAction = "modify";
3071
3095
  classId = newClassId;
3096
+ result = {
3097
+ status: "ok",
3098
+ message: `created global class with ID ${newClassId}`
3099
+ };
3100
+ } else {
3101
+ throw new Error("error creating class");
3072
3102
  }
3073
- result = newClassId ? {
3074
- status: "ok",
3075
- message: `created global class with ID ${newClassId}`
3076
- } : {
3077
- status: "error",
3078
- message: "error creating class"
3079
- };
3080
3103
  break;
3081
3104
  case "modify":
3082
3105
  const updated = await attemptUpdate({
@@ -3086,20 +3109,11 @@ Update your input and try again.`
3086
3109
  breakpoint: breakpointValue,
3087
3110
  state
3088
3111
  });
3089
- result = updated ? { status: "ok", classId } : {
3090
- status: "error",
3091
- message: "error modifying class"
3092
- };
3093
- break;
3094
- case "delete":
3095
- const deleted = await attemptDelete({
3096
- classId,
3097
- stylesProvider: globalClassesStylesProvider
3098
- });
3099
- result = deleted ? { status: "ok", message: `deleted global class with ID ${classId}` } : {
3100
- status: "error",
3101
- message: "error deleting class"
3102
- };
3112
+ if (updated) {
3113
+ result = { status: "ok", classId };
3114
+ } else {
3115
+ throw new Error("error modifying class");
3116
+ }
3103
3117
  break;
3104
3118
  default:
3105
3119
  throw new Error(`Unsupported action ${action}`);
@@ -3119,10 +3133,21 @@ var initManageGlobalClasses = (reg) => {
3119
3133
  name: "manage-global-classes",
3120
3134
  requiredResources: [
3121
3135
  { uri: GLOBAL_CLASSES_URI, description: "Global classes list" },
3122
- { uri: import_editor_canvas2.STYLE_SCHEMA_URI, description: "Style schema resources" },
3123
- { uri: import_editor_canvas2.BREAKPOINTS_SCHEMA_URI, description: "Breakpoints list" }
3136
+ { uri: import_editor_canvas2.STYLE_SCHEMA_FULL_URI, description: "Style schema resources" },
3137
+ { uri: import_editor_canvas2.BREAKPOINTS_SCHEMA_FULL_URI, description: "Breakpoints list" }
3124
3138
  ],
3125
- description: `Create or modify global classes for reusable design-system styling. Class names must reflect purpose (e.g. heading-primary, button-cta). Create classes BEFORE compositions. Do NOT create classes for one-off styles or layout-specific properties.`,
3139
+ description: `Create or modify global classes for reusable design-system styling. Class names must reflect purpose (e.g. heading-primary, button-cta). Create classes BEFORE applying them. Do NOT create classes for one-off styles.
3140
+
3141
+ IMPORTANT: props must contain actual CSS property values \u2014 never pass empty objects.
3142
+ Fetch ${import_editor_canvas2.STYLE_SCHEMA_FULL_URI} to get the allowed values for each property, then use them to build the props object.
3143
+
3144
+ Example \u2014 creating a flex column class:
3145
+ props.default = {
3146
+ "display": { "$$type": "string", "value": "flex" },
3147
+ "flex-direction": { "$$type": "string", "value": "column" }
3148
+ }
3149
+
3150
+ The style schema returns a JSON Schema. Extract the "value" enum to pick the right value, then construct { "$$type": "string", "value": "<picked value>" }.`,
3126
3151
  schema,
3127
3152
  outputSchema,
3128
3153
  handler
@@ -3152,7 +3177,7 @@ async function attemptCreate(opts) {
3152
3177
  return newClassId;
3153
3178
  } catch {
3154
3179
  deleteClass2(newClassId);
3155
- return null;
3180
+ throw new Error("error creating class");
3156
3181
  }
3157
3182
  }
3158
3183
  async function attemptUpdate(opts) {
@@ -3164,6 +3189,7 @@ async function attemptUpdate(opts) {
3164
3189
  if (!updateProps || !update) {
3165
3190
  throw new Error("User is unable to update global classes");
3166
3191
  }
3192
+ await loadExistingClasses([classId]);
3167
3193
  const snapshot = structuredClone(stylesProvider.actions.all());
3168
3194
  try {
3169
3195
  updateProps({
@@ -3171,7 +3197,7 @@ async function attemptUpdate(opts) {
3171
3197
  props,
3172
3198
  meta: {
3173
3199
  breakpoint,
3174
- state
3200
+ state: state === "default" ? null : state
3175
3201
  }
3176
3202
  });
3177
3203
  await saveGlobalClasses2({ context: "frontend" });
@@ -3184,7 +3210,7 @@ async function attemptUpdate(opts) {
3184
3210
  });
3185
3211
  });
3186
3212
  await saveGlobalClasses2({ context: "frontend" });
3187
- return false;
3213
+ throw new Error("error updating class");
3188
3214
  }
3189
3215
  }
3190
3216
  async function attemptDelete(opts) {
@@ -3201,13 +3227,9 @@ async function attemptDelete(opts) {
3201
3227
  if (!targetClass) {
3202
3228
  throw new Error(`Class with ID "${classId}" not found`);
3203
3229
  }
3204
- try {
3205
- deleteClass2(classId);
3206
- await saveGlobalClasses2({ context: "frontend" });
3207
- return true;
3208
- } catch {
3209
- return false;
3210
- }
3230
+ deleteClass2(classId);
3231
+ await saveGlobalClasses2({ context: "frontend" });
3232
+ return true;
3211
3233
  }
3212
3234
 
3213
3235
  // src/mcp-integration/index.ts
@@ -3224,7 +3246,7 @@ var import_editor_v1_adapters4 = require("@elementor/editor-v1-adapters");
3224
3246
 
3225
3247
  // src/sync-with-document-save.ts
3226
3248
  var import_editor_current_user3 = require("@elementor/editor-current-user");
3227
- var import_editor_documents6 = require("@elementor/editor-documents");
3249
+ var import_editor_documents5 = require("@elementor/editor-documents");
3228
3250
  var import_editor_v1_adapters3 = require("@elementor/editor-v1-adapters");
3229
3251
  var import_store30 = require("@elementor/store");
3230
3252
  var pendingSave = null;
@@ -3239,7 +3261,7 @@ function syncDirtyState() {
3239
3261
  if (!isDirty()) {
3240
3262
  return;
3241
3263
  }
3242
- (0, import_editor_documents6.setDocumentModifiedStatus)(true);
3264
+ (0, import_editor_documents5.setDocumentModifiedStatus)(true);
3243
3265
  });
3244
3266
  }
3245
3267
  function triggerSave(panelActions, context2 = "preview") {