@elementor/editor-variables 4.2.0-945 → 4.2.0-beta1

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
@@ -10,20 +10,31 @@ import { __ as __10 } from "@wordpress/i18n";
10
10
 
11
11
  // src/utils/tracking.ts
12
12
  import { getMixpanel } from "@elementor/events";
13
- var trackVariableEvent = ({ varType, controlPath, action }) => {
13
+ var trackVariableEvent = ({ varType, controlPath, action, executedBy }) => {
14
14
  const { dispatchEvent, config } = getMixpanel();
15
15
  if (!config?.names?.variables?.[action]) {
16
16
  return;
17
17
  }
18
18
  const name = config.names.variables[action];
19
- dispatchEvent?.(name, {
20
- location: config?.locations?.variables || "",
21
- secondaryLocation: config?.secondaryLocations?.variablesPopover || "",
22
- trigger: config?.triggers?.click || "",
19
+ let eventData = {
23
20
  var_type: varType,
24
- control_path: controlPath,
25
21
  action_type: name
26
- });
22
+ };
23
+ if (executedBy) {
24
+ eventData.executed_by = executedBy;
25
+ }
26
+ const defaultLocationInfo = {
27
+ location: config?.locations?.variables || "",
28
+ secondaryLocation: config?.secondaryLocations?.variablesPopover || "",
29
+ trigger: config?.triggers?.click || ""
30
+ };
31
+ if (!executedBy || executedBy !== "mcp_tool") {
32
+ eventData = { ...defaultLocationInfo, ...eventData };
33
+ }
34
+ if (controlPath) {
35
+ eventData.control_path = controlPath;
36
+ }
37
+ dispatchEvent?.(name, eventData);
27
38
  };
28
39
  var trackVariablesManagerEvent = ({ action, source, varType, controlPath }) => {
29
40
  const { dispatchEvent, config } = getMixpanel();
@@ -48,24 +59,21 @@ var trackVariablesManagerEvent = ({ action, source, varType, controlPath }) => {
48
59
  dispatchEvent?.(name, eventData);
49
60
  };
50
61
  var trackVariableSyncToV3 = ({ variableLabel, action }) => {
51
- try {
52
- const { dispatchEvent, config } = getMixpanel();
53
- if (!config?.names?.variables?.variableSyncToV3) {
54
- return;
55
- }
56
- const name = config.names.variables.variableSyncToV3;
57
- const isSync = action === "sync";
58
- dispatchEvent?.(name, {
59
- interaction_type: "click",
60
- target_type: variableLabel,
61
- target_name: isSync ? "sync_to_v3" : "unsync_to_v3",
62
- interaction_result: isSync ? "var_is_synced_to_V3" : "var_is_unsynced_from_V3",
63
- target_location: "widget_panel",
64
- location_l1: "var_manager",
65
- interaction_description: isSync ? `user_synced_${variableLabel}_to_v3` : `user_unsync_${variableLabel}_from_v3`
66
- });
67
- } catch {
62
+ const { dispatchEvent, config } = getMixpanel();
63
+ if (!config?.names?.variables?.variableSyncToV3) {
64
+ return;
68
65
  }
66
+ const name = config.names.variables.variableSyncToV3;
67
+ const isSync = action === "sync";
68
+ dispatchEvent?.(name, {
69
+ interaction_type: "click",
70
+ target_type: variableLabel,
71
+ target_name: isSync ? "sync_to_v3" : "unsync_to_v3",
72
+ interaction_result: isSync ? "var_is_synced_to_V3" : "var_is_unsynced_from_V3",
73
+ target_location: "widget_panel",
74
+ location_l1: "var_manager",
75
+ interaction_description: isSync ? `user_synced_${variableLabel}_to_v3` : `user_unsync_${variableLabel}_from_v3`
76
+ });
69
77
  };
70
78
 
71
79
  // src/utils/validations.ts
@@ -465,7 +473,7 @@ var service = {
465
473
  return variables;
466
474
  });
467
475
  },
468
- create: ({ type, label, value }) => {
476
+ create: ({ type, label, value }, options = {}) => {
469
477
  return apiClient.create(type, label, value).then((response) => {
470
478
  const { success, data: payload } = response.data;
471
479
  if (!success) {
@@ -481,13 +489,18 @@ var service = {
481
489
  styleVariablesRepository.update({
482
490
  [variableId]: createdVariable
483
491
  });
492
+ trackVariableEvent({
493
+ varType: type,
494
+ action: "save",
495
+ ...options.eventData
496
+ });
484
497
  return {
485
498
  id: variableId,
486
499
  variable: createdVariable
487
500
  };
488
501
  });
489
502
  },
490
- update: (id, { label, value, type }) => {
503
+ update: (id, { label, value, type }, options = {}) => {
491
504
  return apiClient.update(id, label, value, type).then((response) => {
492
505
  const { success, data: payload } = response.data;
493
506
  if (!success) {
@@ -503,6 +516,11 @@ var service = {
503
516
  styleVariablesRepository.update({
504
517
  [variableId]: updatedVariable
505
518
  });
519
+ trackVariableEvent({
520
+ varType: updatedVariable.type,
521
+ action: "update",
522
+ ...options.eventData
523
+ });
506
524
  return {
507
525
  id: variableId,
508
526
  variable: updatedVariable
@@ -979,11 +997,11 @@ var normalizeVariables = (propKey) => {
979
997
  return variablesToList(variables).filter((variable) => matchingTypes.includes(variable.type)).map(toNormalizedVariable);
980
998
  };
981
999
  var extractId = ({ id }) => id;
982
- var createVariable = (newVariable) => {
983
- return service.create(newVariable).then(extractId);
1000
+ var createVariable = (newVariable, options) => {
1001
+ return service.create(newVariable, options).then(extractId);
984
1002
  };
985
- var updateVariable = (updateId, { value, label, type }) => {
986
- return service.update(updateId, { value, label, type }).then(extractId);
1003
+ var updateVariable = (updateId, { value, label, type }, options) => {
1004
+ return service.update(updateId, { value, label, type }, options).then(extractId);
987
1005
  };
988
1006
  var deleteVariable = (deleteId) => {
989
1007
  return service.delete(deleteId).then(extractId);
@@ -2319,7 +2337,7 @@ var StopSyncConfirmationDialog = ({ open, onClose, onConfirm }) => {
2319
2337
  import { injectIntoLogic, injectIntoTop } from "@elementor/editor";
2320
2338
  import { registerControlReplacement } from "@elementor/editor-controls";
2321
2339
  import { getMCPByDomain } from "@elementor/editor-mcp";
2322
- import { isTransformable as isTransformable2 } from "@elementor/editor-props";
2340
+ import { isTransformable as isTransformable3 } from "@elementor/editor-props";
2323
2341
  import { controlActionsMenu } from "@elementor/menus";
2324
2342
 
2325
2343
  // src/components/global-styles-import-listener.tsx
@@ -2338,6 +2356,78 @@ function GlobalStylesImportListener() {
2338
2356
  return null;
2339
2357
  }
2340
2358
 
2359
+ // src/components/mcp-variable-connect-listener.tsx
2360
+ import { useEffect as useEffect6 } from "react";
2361
+ import { MCP_STYLES_APPLIED_EVENT } from "@elementor/editor-mcp";
2362
+
2363
+ // src/utils/extract-variables-from-style-value.ts
2364
+ import { getPropSchemaFromCache, isTransformable } from "@elementor/editor-props";
2365
+ var VARIABLE_TYPE_KEYS = [
2366
+ "global-color-variable",
2367
+ "global-font-variable",
2368
+ "global-size-variable",
2369
+ "global-custom-size-variable"
2370
+ ];
2371
+ function tryExtractVariable(value) {
2372
+ for (const key of VARIABLE_TYPE_KEYS) {
2373
+ const propUtil = getPropSchemaFromCache(key);
2374
+ if (propUtil?.isValid(value)) {
2375
+ return {
2376
+ type: key,
2377
+ variableId: propUtil.extract(value)
2378
+ };
2379
+ }
2380
+ }
2381
+ return null;
2382
+ }
2383
+ function traverse(value, path, result) {
2384
+ const extracted = tryExtractVariable(value);
2385
+ if (extracted) {
2386
+ result.push({
2387
+ ...extracted,
2388
+ controlPath: path.join(".")
2389
+ });
2390
+ return;
2391
+ }
2392
+ if (isTransformable(value)) {
2393
+ traverse(value.value, path, result);
2394
+ return;
2395
+ }
2396
+ if (value && typeof value === "object") {
2397
+ for (const [key, val] of Object.entries(value)) {
2398
+ traverse(val, [...path, key], result);
2399
+ }
2400
+ }
2401
+ }
2402
+ function extractVariablesFromStyleValue(styleValue) {
2403
+ const result = [];
2404
+ traverse(styleValue, [], result);
2405
+ return result;
2406
+ }
2407
+
2408
+ // src/components/mcp-variable-connect-listener.tsx
2409
+ function McpVariableConnectListener() {
2410
+ useEffect6(() => {
2411
+ const handleMcpStylesApplied = (event) => {
2412
+ const { styleValue } = event.detail;
2413
+ const variables = extractVariablesFromStyleValue(styleValue);
2414
+ variables.forEach(({ type, controlPath }) => {
2415
+ trackVariableEvent({
2416
+ varType: type,
2417
+ controlPath,
2418
+ action: "connect",
2419
+ executedBy: "mcp_tool"
2420
+ });
2421
+ });
2422
+ };
2423
+ window.addEventListener(MCP_STYLES_APPLIED_EVENT, handleMcpStylesApplied);
2424
+ return () => {
2425
+ window.removeEventListener(MCP_STYLES_APPLIED_EVENT, handleMcpStylesApplied);
2426
+ };
2427
+ }, []);
2428
+ return null;
2429
+ }
2430
+
2341
2431
  // src/controls/variable-control.tsx
2342
2432
  import * as React33 from "react";
2343
2433
  import { useBoundProp as useBoundProp11 } from "@elementor/editor-controls";
@@ -2406,7 +2496,7 @@ var useInitialValue = () => {
2406
2496
 
2407
2497
  // src/hooks/use-variable-bound-prop.ts
2408
2498
  import { useBoundProp as useBoundProp3 } from "@elementor/editor-controls";
2409
- import { isTransformable } from "@elementor/editor-props";
2499
+ import { isTransformable as isTransformable2 } from "@elementor/editor-props";
2410
2500
  var useVariableBoundProp = () => {
2411
2501
  const { propTypeUtil } = useVariableType();
2412
2502
  const boundProp = useBoundProp3(propTypeUtil);
@@ -2426,7 +2516,7 @@ var resolveBoundPropAndSetValue = (value, boundProp) => {
2426
2516
  return boundProp.setValue(value);
2427
2517
  };
2428
2518
  var unwrapValue = (input) => {
2429
- if (isTransformable(input)) {
2519
+ if (isTransformable2(input)) {
2430
2520
  return input.value;
2431
2521
  }
2432
2522
  return input;
@@ -2442,7 +2532,7 @@ var FormField = ({ id, label, errorMsg, noticeMsg, children }) => {
2442
2532
  // src/components/variable-creation.tsx
2443
2533
  var SIZE2 = "tiny";
2444
2534
  var VariableCreation = ({ onGoBack, onClose }) => {
2445
- const { icon: VariableIcon, valueField: ValueField, variableType, propTypeUtil } = useVariableType();
2535
+ const { icon: VariableIcon, valueField: ValueField, propTypeUtil } = useVariableType();
2446
2536
  const { setVariableValue: setVariable, path } = useVariableBoundProp();
2447
2537
  const { propType } = useBoundProp4();
2448
2538
  const initialValue = useInitialValue();
@@ -2463,11 +2553,14 @@ var VariableCreation = ({ onGoBack, onClose }) => {
2463
2553
  onClose();
2464
2554
  };
2465
2555
  const handleCreateAndTrack = () => {
2466
- createVariable({
2467
- value,
2468
- label,
2469
- type: propTypeKey
2470
- }).then((key) => {
2556
+ createVariable(
2557
+ {
2558
+ value,
2559
+ label,
2560
+ type: propTypeKey
2561
+ },
2562
+ { eventData: { controlPath: path.join(".") } }
2563
+ ).then((key) => {
2471
2564
  setVariable(key);
2472
2565
  closePopover();
2473
2566
  }).catch((error) => {
@@ -2482,11 +2575,6 @@ var VariableCreation = ({ onGoBack, onClose }) => {
2482
2575
  }
2483
2576
  setErrorMessage(ERROR_MESSAGES.UNEXPECTED_ERROR);
2484
2577
  });
2485
- trackVariableEvent({
2486
- varType: variableType,
2487
- controlPath: path.join("."),
2488
- action: "save"
2489
- });
2490
2578
  };
2491
2579
  const hasEmptyFields = () => {
2492
2580
  if ("" === label.trim()) {
@@ -2571,7 +2659,7 @@ var VariableCreation = ({ onGoBack, onClose }) => {
2571
2659
 
2572
2660
  // src/components/variable-edit.tsx
2573
2661
  import * as React19 from "react";
2574
- import { useEffect as useEffect6, useState as useState10 } from "react";
2662
+ import { useEffect as useEffect7, useState as useState10 } from "react";
2575
2663
  import { PopoverContent as PopoverContent2, useBoundProp as useBoundProp5 } from "@elementor/editor-controls";
2576
2664
  import { useSuppressedMessage as useSuppressedMessage2 } from "@elementor/editor-current-user";
2577
2665
  import { PopoverHeader as PopoverHeader2, SectionPopoverBody as SectionPopoverBody2 } from "@elementor/editor-ui";
@@ -2632,7 +2720,7 @@ var SIZE3 = "tiny";
2632
2720
  var DELETE_LABEL = __13("Delete variable", "elementor");
2633
2721
  var VariableEdit = ({ onClose, onGoBack, onSubmit, editId }) => {
2634
2722
  const { icon: VariableIcon, valueField: ValueField, variableType, propTypeUtil } = useVariableType();
2635
- const { setVariableValue: notifyBoundPropChange, variableId } = useVariableBoundProp();
2723
+ const { setVariableValue: notifyBoundPropChange, variableId, path } = useVariableBoundProp();
2636
2724
  const { propType } = useBoundProp5();
2637
2725
  const [isMessageSuppressed, suppressMessage] = useSuppressedMessage2(EDIT_CONFIRMATION_DIALOG_ID);
2638
2726
  const [deleteConfirmation, setDeleteConfirmation] = useState10(false);
@@ -2648,7 +2736,7 @@ var VariableEdit = ({ onClose, onGoBack, onSubmit, editId }) => {
2648
2736
  const userPermissions = usePermissions();
2649
2737
  const [value, setValue] = useState10(() => variable.value);
2650
2738
  const [label, setLabel] = useState10(() => variable.label);
2651
- useEffect6(() => {
2739
+ useEffect7(() => {
2652
2740
  styleVariablesRepository.update({
2653
2741
  [editId]: {
2654
2742
  ...variable,
@@ -2671,7 +2759,7 @@ var VariableEdit = ({ onClose, onGoBack, onSubmit, editId }) => {
2671
2759
  const handleSaveVariable = () => {
2672
2760
  const typeChanged = propTypeKey !== variable.type;
2673
2761
  const updatePayload = typeChanged ? { value, label, type: propTypeKey } : { value, label };
2674
- updateVariable(editId, updatePayload).then(() => {
2762
+ updateVariable(editId, updatePayload, { eventData: { controlPath: path.join(".") } }).then(() => {
2675
2763
  maybeTriggerBoundPropChange();
2676
2764
  onSubmit?.();
2677
2765
  }).catch((error) => {
@@ -2813,7 +2901,7 @@ var VariableEdit = ({ onClose, onGoBack, onSubmit, editId }) => {
2813
2901
  };
2814
2902
 
2815
2903
  // src/components/variables-selection.tsx
2816
- import { useEffect as useEffect7, useState as useState11 } from "react";
2904
+ import { useEffect as useEffect8, useState as useState11 } from "react";
2817
2905
  import * as React21 from "react";
2818
2906
  import { trackUpgradePromotionClick as trackUpgradePromotionClick2, trackViewPromotion as trackViewPromotion2 } from "@elementor/editor-controls";
2819
2907
  import {
@@ -3004,7 +3092,7 @@ var VariablesSelection = ({ closePopover, onAdd, onEdit, onSettings, disabled =
3004
3092
  const handleClearSearch = () => {
3005
3093
  setSearchValue("");
3006
3094
  };
3007
- useEffect7(() => {
3095
+ useEffect8(() => {
3008
3096
  if (disabled) {
3009
3097
  trackViewPromotion2({
3010
3098
  target_name: "variables_popover",
@@ -3996,7 +4084,7 @@ function getServiceActions(svc) {
3996
4084
  if (valueError) {
3997
4085
  throw new Error(valueError);
3998
4086
  }
3999
- return svc.create({ type, label, value });
4087
+ return svc.create({ type, label, value }, { eventData: { executedBy: "mcp_tool" } });
4000
4088
  },
4001
4089
  update({ id, label, value }) {
4002
4090
  if (!id || !label || !value) {
@@ -4013,7 +4101,7 @@ function getServiceActions(svc) {
4013
4101
  throw new Error(valueError);
4014
4102
  }
4015
4103
  }
4016
- return svc.update(id, { label, value });
4104
+ return svc.update(id, { label, value }, { eventData: { executedBy: "mcp_tool" } });
4017
4105
  },
4018
4106
  delete({ id }) {
4019
4107
  if (!id) {
@@ -4239,7 +4327,7 @@ function registerVariableTypes() {
4239
4327
 
4240
4328
  // src/renderers/style-variables-renderer.tsx
4241
4329
  import * as React38 from "react";
4242
- import { useEffect as useEffect8, useState as useState19 } from "react";
4330
+ import { useEffect as useEffect9, useState as useState19 } from "react";
4243
4331
  import {
4244
4332
  __privateUseListenTo as useListenTo,
4245
4333
  commandEndEvent as commandEndEvent2,
@@ -4263,7 +4351,7 @@ function usePortalContainer() {
4263
4351
  }
4264
4352
  function useStyleVariables() {
4265
4353
  const [variables, setVariables] = useState19({});
4266
- useEffect8(() => {
4354
+ useEffect9(() => {
4267
4355
  const unsubscribe = styleVariablesRepository.subscribe(setVariables);
4268
4356
  return () => {
4269
4357
  unsubscribe();
@@ -4577,9 +4665,13 @@ function init() {
4577
4665
  id: "variables-import-listener",
4578
4666
  component: GlobalStylesImportListener
4579
4667
  });
4668
+ injectIntoLogic({
4669
+ id: "mcp-variable-connect-listener",
4670
+ component: McpVariableConnectListener
4671
+ });
4580
4672
  }
4581
4673
  function hasVariableAssigned(value) {
4582
- if (isTransformable2(value)) {
4674
+ if (isTransformable3(value)) {
4583
4675
  return hasVariableType(value.$$type);
4584
4676
  }
4585
4677
  return false;