@elementor/editor-global-classes 4.3.0-1001 → 4.3.0-1002

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
@@ -1988,7 +1988,7 @@ var GlobalClassesList = ({
1988
1988
  search: { debouncedValue: searchValue }
1989
1989
  } = useSearchAndFilters();
1990
1990
  const cssClasses = useOrderedClasses();
1991
- const dispatch7 = useDispatch();
1991
+ const dispatch8 = useDispatch();
1992
1992
  const filters = useFilters();
1993
1993
  const [draggedItemId, setDraggedItemId] = useState5(null);
1994
1994
  const [loading, setLoading] = useState5({});
@@ -2021,22 +2021,22 @@ var GlobalClassesList = ({
2021
2021
  }
2022
2022
  });
2023
2023
  useEffect2(() => {
2024
- const handler2 = (event) => {
2024
+ const handler = (event) => {
2025
2025
  if (event.key === "z" && (event.ctrlKey || event.metaKey)) {
2026
2026
  event.stopImmediatePropagation();
2027
2027
  event.preventDefault();
2028
2028
  if (event.shiftKey) {
2029
- dispatch7(slice.actions.redo());
2029
+ dispatch8(slice.actions.redo());
2030
2030
  return;
2031
2031
  }
2032
- dispatch7(slice.actions.undo());
2032
+ dispatch8(slice.actions.undo());
2033
2033
  }
2034
2034
  };
2035
- window.addEventListener("keydown", handler2, {
2035
+ window.addEventListener("keydown", handler, {
2036
2036
  capture: true
2037
2037
  });
2038
- return () => window.removeEventListener("keydown", handler2);
2039
- }, [dispatch7]);
2038
+ return () => window.removeEventListener("keydown", handler);
2039
+ }, [dispatch8]);
2040
2040
  if (!cssClasses?.length) {
2041
2041
  return /* @__PURE__ */ React17.createElement(EmptyState, null);
2042
2042
  }
@@ -2096,7 +2096,7 @@ var GlobalClassesList = ({
2096
2096
  source: "class-manager"
2097
2097
  });
2098
2098
  void await loadExistingClasses([cssClass.id]);
2099
- dispatch7(
2099
+ dispatch8(
2100
2100
  slice.actions.update({
2101
2101
  style: {
2102
2102
  id: cssClass.id,
@@ -2122,7 +2122,7 @@ var GlobalClassesList = ({
2122
2122
  } else if (newValue && onStartSyncRequest) {
2123
2123
  onStartSyncRequest(id);
2124
2124
  } else {
2125
- dispatch7(
2125
+ dispatch8(
2126
2126
  slice.actions.update({
2127
2127
  style: {
2128
2128
  id,
@@ -2149,10 +2149,10 @@ var StyledHeader = styled6(Typography8)(({ theme, variant }) => ({
2149
2149
  }
2150
2150
  }));
2151
2151
  var useReorder = (draggedItemId, setDraggedItemId, draggedItemLabel) => {
2152
- const dispatch7 = useDispatch();
2152
+ const dispatch8 = useDispatch();
2153
2153
  const order = useClassesOrder();
2154
2154
  const reorder = (newIds) => {
2155
- dispatch7(slice.actions.setOrder(newIds));
2155
+ dispatch8(slice.actions.setOrder(newIds));
2156
2156
  if (draggedItemId) {
2157
2157
  trackGlobalClasses({
2158
2158
  event: "classManagerReorder",
@@ -2788,7 +2788,7 @@ import { useEffect as useEffect5 } from "react";
2788
2788
  import { GLOBAL_STYLES_IMPORTED_EVENT } from "@elementor/editor-canvas";
2789
2789
  import { __useDispatch as useDispatch2 } from "@elementor/store";
2790
2790
  function GlobalStylesImportListener() {
2791
- const dispatch7 = useDispatch2();
2791
+ const dispatch8 = useDispatch2();
2792
2792
  useEffect5(() => {
2793
2793
  const handleGlobalStylesImported = async (event) => {
2794
2794
  const customEvent = event;
@@ -2797,7 +2797,7 @@ function GlobalStylesImportListener() {
2797
2797
  loadCurrentDocumentClasses();
2798
2798
  return;
2799
2799
  }
2800
- dispatch7(
2800
+ dispatch8(
2801
2801
  slice.actions.updateAfterTemplateImport({
2802
2802
  addedItems: globalClasses.added_items,
2803
2803
  addedIdsOrder: globalClasses.added_items_order,
@@ -2809,7 +2809,7 @@ function GlobalStylesImportListener() {
2809
2809
  return () => {
2810
2810
  window.removeEventListener(GLOBAL_STYLES_IMPORTED_EVENT, handleGlobalStylesImported);
2811
2811
  };
2812
- }, [dispatch7]);
2812
+ }, [dispatch8]);
2813
2813
  return null;
2814
2814
  }
2815
2815
 
@@ -2826,9 +2826,67 @@ function PopulateStore() {
2826
2826
  return null;
2827
2827
  }
2828
2828
 
2829
+ // src/mcp-integration/manage-classes-tool.ts
2830
+ import { httpService as httpService2 } from "@elementor/http-client";
2831
+ import { z } from "@elementor/schema";
2832
+ import { __dispatch as dispatch7 } from "@elementor/store";
2833
+ var MCP_PROXY_URL = "elementor/v1/mcp-proxy";
2834
+ var TOOL_NAME = "manage-classes";
2835
+ var initManageClassesTool = (reg) => {
2836
+ const { addTool } = reg;
2837
+ addTool({
2838
+ name: TOOL_NAME,
2839
+ description: "Manage V4 global CSS classes on the active kit. Create, update, or delete a single class using raw CSS declarations.",
2840
+ schema: {
2841
+ action: z.enum(["create", "update", "delete"]),
2842
+ id: z.string().optional().describe("Class id \u2014 required for update/delete. Get from the global-classes resource."),
2843
+ label: z.string().optional().describe("Class label (lowercase, dash-separated) \u2014 required for create/update."),
2844
+ css: z.record(z.string()).optional().describe("Raw CSS declarations (property \u2192 value) \u2014 required for create/update.")
2845
+ },
2846
+ outputSchema: {
2847
+ status: z.enum(["ok"]).describe("Operation status")
2848
+ },
2849
+ requiredResources: [
2850
+ {
2851
+ uri: GLOBAL_CLASSES_URI,
2852
+ description: "Current global classes \u2014 check before creating to avoid duplicates"
2853
+ }
2854
+ ],
2855
+ isDestructive: true,
2856
+ handler: async (params) => {
2857
+ const { data } = await httpService2().post(MCP_PROXY_URL, {
2858
+ tool: TOOL_NAME,
2859
+ input: params
2860
+ });
2861
+ const payload = data.data;
2862
+ const { create, update, delete: del } = globalClassesStylesProvider.actions;
2863
+ switch (params.action) {
2864
+ case "create":
2865
+ if (payload.class && create) {
2866
+ create(payload.class.label, payload.class.variants, payload.class.id);
2867
+ }
2868
+ break;
2869
+ case "update":
2870
+ if (payload.class && update) {
2871
+ update(payload.class);
2872
+ }
2873
+ break;
2874
+ case "delete":
2875
+ if (params.id && del) {
2876
+ del(params.id);
2877
+ }
2878
+ break;
2879
+ }
2880
+ dispatch7(slice.actions.reset({ context: "frontend" }));
2881
+ window.dispatchEvent(new CustomEvent("classes:updated", { detail: { context: "frontend" } }));
2882
+ return { status: "ok" };
2883
+ }
2884
+ });
2885
+ };
2886
+
2829
2887
  // src/mcp-integration/mcp-apply-unapply-global-classes.ts
2830
2888
  import { doApplyClasses, doGetAppliedClasses, doUnapplyClass } from "@elementor/editor-editing-panel";
2831
- import { z } from "@elementor/schema";
2889
+ import { z as z2 } from "@elementor/schema";
2832
2890
 
2833
2891
  // src/mcp-integration/apply-global-class-guide-prompt.ts
2834
2892
  import { toolPrompts } from "@elementor/editor-mcp";
@@ -2882,12 +2940,12 @@ function initMcpApplyUnapplyGlobalClasses(server) {
2882
2940
  );
2883
2941
  addTool({
2884
2942
  schema: {
2885
- classId: z.string().describe("The ID of the class to apply"),
2886
- elementId: z.string().describe("The ID of the element to which the class will be applied")
2943
+ classId: z2.string().describe("The ID of the class to apply"),
2944
+ elementId: z2.string().describe("The ID of the element to which the class will be applied")
2887
2945
  },
2888
2946
  outputSchema: {
2889
- result: z.string().describe("Result message indicating the success of the apply operation"),
2890
- llm_instructions: z.string().describe("Instructions what to do next, Important to follow these instructions!")
2947
+ result: z2.string().describe("Result message indicating the success of the apply operation"),
2948
+ llm_instructions: z2.string().describe("Instructions what to do next, Important to follow these instructions!")
2891
2949
  },
2892
2950
  name: "apply-global-class",
2893
2951
  description: `Apply a global class to an element for shared design-system styling. Read the full guide at [${APPLY_GLOBAL_CLASS_GUIDE_URI}].`,
@@ -2913,11 +2971,11 @@ function initMcpApplyUnapplyGlobalClasses(server) {
2913
2971
  addTool({
2914
2972
  name: "unapply-global-class",
2915
2973
  schema: {
2916
- classId: z.string().describe("The ID of the class to unapply"),
2917
- elementId: z.string().describe("The ID of the element from which the class will be unapplied")
2974
+ classId: z2.string().describe("The ID of the class to unapply"),
2975
+ elementId: z2.string().describe("The ID of the element from which the class will be unapplied")
2918
2976
  },
2919
2977
  outputSchema: {
2920
- result: z.string().describe("Result message indicating the success of the unapply operation")
2978
+ result: z2.string().describe("Result message indicating the success of the unapply operation")
2921
2979
  },
2922
2980
  description: `Unapply a global class from an element by class ID. Resolve class names to IDs via [${GLOBAL_CLASSES_URI}].`,
2923
2981
  requiredResources: [{ description: "Global classes list", uri: GLOBAL_CLASSES_URI }],
@@ -2935,21 +2993,21 @@ function initMcpApplyUnapplyGlobalClasses(server) {
2935
2993
  }
2936
2994
 
2937
2995
  // src/mcp-integration/mcp-get-global-class-usages.ts
2938
- import { z as z2 } from "@elementor/schema";
2996
+ import { z as z3 } from "@elementor/schema";
2939
2997
  function initMcpApplyGetGlobalClassUsages(reg) {
2940
2998
  const { addTool } = reg;
2941
2999
  const globalClassesUsageSchema = {
2942
- usages: z2.array(
2943
- z2.object({
2944
- classId: z2.string().describe(
3000
+ usages: z3.array(
3001
+ z3.object({
3002
+ classId: z3.string().describe(
2945
3003
  'The ID of the class, not visible to the user. To retrieve the name of the class, use the "list-global-classes" tool'
2946
3004
  ),
2947
- usages: z2.array(
2948
- z2.object({
2949
- pageId: z2.string().describe("The ID of the page where the class is used"),
2950
- title: z2.string().describe("The title of the page where the class is used"),
2951
- total: z2.number().describe("The number of times the class is used on this page"),
2952
- elements: z2.array(z2.string()).describe("List of element IDs using this class on the page")
3005
+ usages: z3.array(
3006
+ z3.object({
3007
+ pageId: z3.string().describe("The ID of the page where the class is used"),
3008
+ title: z3.string().describe("The title of the page where the class is used"),
3009
+ total: z3.number().describe("The number of times the class is used on this page"),
3010
+ elements: z3.array(z3.string()).describe("List of element IDs using this class on the page")
2953
3011
  })
2954
3012
  )
2955
3013
  })
@@ -2997,270 +3055,11 @@ function initMcpApplyGetGlobalClassUsages(reg) {
2997
3055
  });
2998
3056
  }
2999
3057
 
3000
- // src/mcp-integration/mcp-manage-global-classes.ts
3001
- import { BREAKPOINTS_SCHEMA_FULL_URI, convertStyleBlocksToAtomic } from "@elementor/editor-canvas";
3002
- import { dispatchMcpStylesAppliedEvent } from "@elementor/editor-mcp";
3003
- import { z as z3 } from "@elementor/schema";
3004
- var schema = {
3005
- action: z3.enum(["create", "modify", "delete"]).describe("Operation to perform"),
3006
- classId: z3.string().optional().describe("Global class ID (required for modify). Get from elementor://global-classes resource."),
3007
- globalClassName: z3.string().optional().describe("Global class name (required for create)"),
3008
- style: z3.object({
3009
- default: z3.string().describe("Plaintext CSS for the default state. MUST be non-empty \u2014 blank strings are rejected."),
3010
- hover: z3.string().describe("Plaintext CSS for the :hover state. optional").optional(),
3011
- focus: z3.string().describe("Plaintext CSS for the :focus state. optional").optional(),
3012
- active: z3.string().describe("Plaintext CSS for the :active state. optional").optional()
3013
- }).describe(
3014
- "Plaintext CSS per pseudo-state. All states are converted in one bulk request; unconvertible declarations are stored as custom CSS."
3015
- ),
3016
- breakpoint: z3.nullable(z3.string().describe("Responsive breakpoint name for styles. Defaults to desktop (null).")).default(null).describe("Responsive breakpoint name for styles. Defaults to desktop (null).")
3017
- };
3018
- var outputSchema = {
3019
- status: z3.enum(["ok", "error"]).describe("Operation status"),
3020
- classId: z3.string().optional().describe("Class ID (returned on create success)"),
3021
- message: z3.string().optional().describe("Error details if status is error")
3022
- };
3023
- var handler = async (input) => {
3024
- const { action, classId: rawClassId, globalClassName, style: rawStyle, breakpoint } = input;
3025
- let classId = rawClassId;
3026
- if (action === "create" && !globalClassName) {
3027
- return {
3028
- status: "error",
3029
- message: "Create requires globalClassName"
3030
- };
3031
- }
3032
- if (action === "modify" && !classId) {
3033
- return {
3034
- status: "error",
3035
- message: "Modify requires classId"
3036
- };
3037
- }
3038
- if (action === "delete" && !classId) {
3039
- return {
3040
- status: "error",
3041
- message: "Delete requires classId"
3042
- };
3043
- }
3044
- const { create, update, delete: deleteClass2 } = globalClassesStylesProvider.actions;
3045
- if (!create || !update || !deleteClass2) {
3046
- return {
3047
- status: "error",
3048
- message: "Required actions not available"
3049
- };
3050
- }
3051
- const styleBlocks = collectNonEmptyStyleBlocks(rawStyle);
3052
- if (action !== "delete" && Object.keys(styleBlocks).length === 0) {
3053
- throw new Error(
3054
- 'Style must not be empty. Provide plaintext CSS per state.\n\nExample: style.default = "display: flex; flex-direction: column; gap: 1rem;"'
3055
- );
3056
- }
3057
- let convertedByState = {};
3058
- if (action !== "delete") {
3059
- const conversionResults = await convertStyleBlocksToAtomic(styleBlocks);
3060
- convertedByState = Object.fromEntries(
3061
- Object.entries(conversionResults).map(([state, { props, customCss }]) => [
3062
- state,
3063
- { props, customCss: toStoredCustomCss(customCss) }
3064
- ])
3065
- );
3066
- }
3067
- const breakpointValue = breakpoint ?? "desktop";
3068
- let result = {
3069
- status: "error",
3070
- classId: "",
3071
- message: "unknown error"
3072
- };
3073
- try {
3074
- if (action === "delete") {
3075
- const deleted = await attemptDelete({
3076
- classId,
3077
- stylesProvider: globalClassesStylesProvider
3078
- });
3079
- if (deleted) {
3080
- return { status: "ok", message: `deleted global class with ID ${classId}` };
3081
- }
3082
- throw new Error("error deleting class");
3083
- }
3084
- let currentAction = action;
3085
- for await (const [state, { props, customCss }] of Object.entries(convertedByState)) {
3086
- switch (currentAction) {
3087
- case "create":
3088
- const newClassId = await attemptCreate({
3089
- props,
3090
- customCss,
3091
- className: globalClassName,
3092
- stylesProvider: globalClassesStylesProvider,
3093
- breakpoint: breakpointValue,
3094
- state
3095
- });
3096
- if (newClassId && currentAction === "create") {
3097
- currentAction = "modify";
3098
- classId = newClassId;
3099
- result = {
3100
- status: "ok",
3101
- message: `created global class with ID ${newClassId}`
3102
- };
3103
- globalClassesStylesProvider.actions.tracking?.({
3104
- event: "classCreated",
3105
- executedBy: "mcp_tool",
3106
- classId: newClassId
3107
- });
3108
- dispatchMcpStylesAppliedEvent({ styleValue: props });
3109
- } else {
3110
- throw new Error("error creating class");
3111
- }
3112
- break;
3113
- case "modify":
3114
- const updated = await attemptUpdate({
3115
- classId,
3116
- props,
3117
- customCss,
3118
- stylesProvider: globalClassesStylesProvider,
3119
- breakpoint: breakpointValue,
3120
- state
3121
- });
3122
- if (updated) {
3123
- result = { status: "ok", classId };
3124
- dispatchMcpStylesAppliedEvent({ styleValue: props });
3125
- } else {
3126
- throw new Error("error modifying class");
3127
- }
3128
- break;
3129
- default:
3130
- throw new Error(`Unsupported action ${action}`);
3131
- }
3132
- }
3133
- } catch (error) {
3134
- return {
3135
- status: "error",
3136
- message: `${action} failed: ${error.message || "Unknown error"}`
3137
- };
3138
- }
3139
- return result;
3140
- };
3141
- var initManageGlobalClasses = (reg) => {
3142
- const { addTool } = reg;
3143
- addTool({
3144
- name: "manage-global-classes",
3145
- requiredResources: [
3146
- { uri: GLOBAL_CLASSES_URI, description: "Global classes list" },
3147
- { uri: BREAKPOINTS_SCHEMA_FULL_URI, description: "Breakpoints list" }
3148
- ],
3149
- 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.
3150
-
3151
- IMPORTANT: style must contain plaintext CSS rules per state \u2014 never pass empty strings.
3152
- CSS is converted server-side in one bulk request; any declaration that cannot be converted is stored as the class custom CSS.
3153
-
3154
- Example \u2014 creating a flex column class:
3155
- style.default = "display: flex; flex-direction: column; gap: 1rem;"
3156
-
3157
- Example \u2014 hover state:
3158
- style.hover = "opacity: 0.85;"`,
3159
- schema,
3160
- outputSchema,
3161
- handler
3162
- });
3163
- };
3164
- async function attemptCreate(opts) {
3165
- const { props, customCss, breakpoint, className, stylesProvider, state } = opts;
3166
- const { create, delete: deleteClass2 } = stylesProvider.actions;
3167
- if (!className) {
3168
- throw new Error("Global class name is a required for creation");
3169
- }
3170
- if (!create || !deleteClass2) {
3171
- throw new Error("User is unable to create global classes");
3172
- }
3173
- const newClassId = create(className, [
3174
- {
3175
- meta: {
3176
- breakpoint,
3177
- state: state === "default" ? null : state
3178
- },
3179
- custom_css: customCss,
3180
- props
3181
- }
3182
- ]);
3183
- try {
3184
- await saveGlobalClasses2({ context: "frontend" });
3185
- return newClassId;
3186
- } catch {
3187
- deleteClass2(newClassId);
3188
- throw new Error("error creating class");
3189
- }
3190
- }
3191
- async function attemptUpdate(opts) {
3192
- const { props, customCss, breakpoint, classId, stylesProvider, state } = opts;
3193
- const { updateProps, update } = stylesProvider.actions;
3194
- if (!classId) {
3195
- throw new Error("Class ID is required for modification");
3196
- }
3197
- if (!updateProps || !update) {
3198
- throw new Error("User is unable to update global classes");
3199
- }
3200
- await loadExistingClasses([classId]);
3201
- const snapshot = structuredClone(stylesProvider.actions.all());
3202
- try {
3203
- updateProps({
3204
- id: classId,
3205
- props,
3206
- custom_css: customCss,
3207
- meta: {
3208
- breakpoint,
3209
- state: state === "default" ? null : state
3210
- }
3211
- });
3212
- await saveGlobalClasses2({ context: "frontend" });
3213
- return true;
3214
- } catch {
3215
- snapshot.forEach((style) => {
3216
- update({
3217
- id: style.id,
3218
- variants: style.variants
3219
- });
3220
- });
3221
- await saveGlobalClasses2({ context: "frontend" });
3222
- throw new Error("error updating class");
3223
- }
3224
- }
3225
- async function attemptDelete(opts) {
3226
- const { classId, stylesProvider } = opts;
3227
- const { delete: deleteClass2, create } = stylesProvider.actions;
3228
- if (!classId) {
3229
- throw new Error("Class ID is required for deletion");
3230
- }
3231
- if (!deleteClass2 || !create) {
3232
- throw new Error("User is unable to delete global classes");
3233
- }
3234
- const snapshot = structuredClone(stylesProvider.actions.all());
3235
- const targetClass = snapshot.find((style) => style.id === classId);
3236
- if (!targetClass) {
3237
- throw new Error(`Class with ID "${classId}" not found`);
3238
- }
3239
- deleteClass2(classId);
3240
- await saveGlobalClasses2({ context: "frontend" });
3241
- return true;
3242
- }
3243
- function collectNonEmptyStyleBlocks(style) {
3244
- const blocks = {};
3245
- Object.entries(style).forEach(([state, cssText]) => {
3246
- if (cssText?.trim()) {
3247
- blocks[state] = cssText.trim();
3248
- }
3249
- });
3250
- return blocks;
3251
- }
3252
- function toStoredCustomCss(customCss) {
3253
- if (!customCss?.trim()) {
3254
- return null;
3255
- }
3256
- return { raw: btoa(customCss) };
3257
- }
3258
-
3259
3058
  // src/mcp-integration/index.ts
3260
3059
  var initMcpIntegration = (reg, canvasMcpEntry) => {
3261
3060
  initMcpApplyUnapplyGlobalClasses(reg);
3262
3061
  initMcpApplyGetGlobalClassUsages(reg);
3263
- initManageGlobalClasses(reg);
3062
+ initManageClassesTool(reg);
3264
3063
  initClassesResource(reg, canvasMcpEntry);
3265
3064
  };
3266
3065