@elementor/editor-controls 0.1.1 → 0.3.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/dist/index.js CHANGED
@@ -28,8 +28,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
29
 
30
30
  // src/index.ts
31
- var src_exports = {};
32
- __export(src_exports, {
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
33
  BackgroundOverlayRepeaterControl: () => BackgroundOverlayRepeaterControl,
34
34
  BoundPropProvider: () => BoundPropProvider,
35
35
  BoxShadowRepeaterControl: () => BoxShadowRepeaterControl,
@@ -40,7 +40,9 @@ __export(src_exports, {
40
40
  ControlToggleButtonGroup: () => ControlToggleButtonGroup,
41
41
  EqualUnequalSizesControl: () => EqualUnequalSizesControl,
42
42
  FontFamilyControl: () => FontFamilyControl,
43
+ GapControl: () => GapControl,
43
44
  ImageControl: () => ImageControl,
45
+ LinkControl: () => LinkControl,
44
46
  LinkedDimensionsControl: () => LinkedDimensionsControl,
45
47
  NumberControl: () => NumberControl,
46
48
  SelectControl: () => SelectControl,
@@ -49,15 +51,17 @@ __export(src_exports, {
49
51
  TextAreaControl: () => TextAreaControl,
50
52
  TextControl: () => TextControl,
51
53
  ToggleControl: () => ToggleControl,
54
+ UrlControl: () => UrlControl,
52
55
  createControlReplacement: () => createControlReplacement,
53
56
  useBoundProp: () => useBoundProp,
54
57
  useControlActions: () => useControlActions,
55
58
  useSyncExternalState: () => useSyncExternalState
56
59
  });
57
- module.exports = __toCommonJS(src_exports);
60
+ module.exports = __toCommonJS(index_exports);
58
61
 
59
62
  // src/controls/image-control.tsx
60
63
  var React9 = __toESM(require("react"));
64
+ var import_editor_props3 = require("@elementor/editor-props");
61
65
  var import_ui6 = require("@elementor/ui");
62
66
  var import_i18n2 = require("@wordpress/i18n");
63
67
 
@@ -68,12 +72,26 @@ var BoundPropContext = (0, import_react.createContext)(null);
68
72
  var BoundPropProvider = ({ children, value, setValue, bind }) => {
69
73
  return /* @__PURE__ */ React.createElement(BoundPropContext.Provider, { value: { value, setValue, bind } }, children);
70
74
  };
71
- function useBoundProp(defaultValue) {
75
+ function useBoundProp(propTypeUtil) {
72
76
  const boundPropContext = (0, import_react.useContext)(BoundPropContext);
73
77
  if (!boundPropContext) {
74
- throw new Error("useBoundProp must be used within a BoundPropContext");
78
+ throw new Error("useBoundProp must be used within a BoundPropProvider");
75
79
  }
76
- return { ...boundPropContext, value: boundPropContext.value ?? defaultValue };
80
+ if (!propTypeUtil) {
81
+ return boundPropContext;
82
+ }
83
+ function setValue(value2, options) {
84
+ if (value2 === null) {
85
+ return boundPropContext.setValue(null);
86
+ }
87
+ return boundPropContext.setValue(propTypeUtil?.create(value2, options));
88
+ }
89
+ const value = propTypeUtil.extract(boundPropContext.value);
90
+ return {
91
+ ...boundPropContext,
92
+ setValue,
93
+ value
94
+ };
77
95
  }
78
96
 
79
97
  // src/components/control-label.tsx
@@ -133,6 +151,7 @@ function createControl(Component, { supportsReplacements = true } = {}) {
133
151
 
134
152
  // src/controls/image-media-control.tsx
135
153
  var React7 = __toESM(require("react"));
154
+ var import_editor_props = require("@elementor/editor-props");
136
155
  var import_icons = require("@elementor/icons");
137
156
  var import_ui4 = require("@elementor/ui");
138
157
  var import_wp_media = require("@elementor/wp-media");
@@ -174,8 +193,8 @@ function ControlActions({ children }) {
174
193
 
175
194
  // src/controls/image-media-control.tsx
176
195
  var ImageMediaControl = createControl(() => {
177
- const { value, setValue } = useBoundProp();
178
- const { id, url } = value?.value ?? {};
196
+ const { value, setValue } = useBoundProp(import_editor_props.imageSrcPropTypeUtil);
197
+ const { id, url } = value ?? {};
179
198
  const { data: attachment, isFetching } = (0, import_wp_media.useWpMediaAttachment)(id?.value || null);
180
199
  const src = attachment?.url ?? url;
181
200
  const { open } = (0, import_wp_media.useWpMediaFrame)({
@@ -184,14 +203,11 @@ var ImageMediaControl = createControl(() => {
184
203
  selected: id?.value || null,
185
204
  onSelect: (selectedAttachment) => {
186
205
  setValue({
187
- $$type: "image-src",
188
- value: {
189
- id: {
190
- $$type: "image-attachment-id",
191
- value: selectedAttachment.id
192
- },
193
- url: null
194
- }
206
+ id: {
207
+ $$type: "image-attachment-id",
208
+ value: selectedAttachment.id
209
+ },
210
+ url: null
195
211
  });
196
212
  }
197
213
  });
@@ -219,9 +235,10 @@ var ImageMediaControl = createControl(() => {
219
235
 
220
236
  // src/controls/select-control.tsx
221
237
  var React8 = __toESM(require("react"));
238
+ var import_editor_props2 = require("@elementor/editor-props");
222
239
  var import_ui5 = require("@elementor/ui");
223
240
  var SelectControl = createControl(({ options }) => {
224
- const { value, setValue } = useBoundProp();
241
+ const { value, setValue } = useBoundProp(import_editor_props2.stringPropTypeUtil);
225
242
  const handleChange = (event) => {
226
243
  setValue(event.target.value);
227
244
  };
@@ -230,24 +247,18 @@ var SelectControl = createControl(({ options }) => {
230
247
 
231
248
  // src/controls/image-control.tsx
232
249
  var ImageControl = createControl((props) => {
233
- const { value, setValue } = useBoundProp();
234
- const { src, size } = value?.value || {};
250
+ const { value, setValue } = useBoundProp(import_editor_props3.imagePropTypeUtil);
251
+ const { src, size } = value || {};
235
252
  const setImageSrc = (newValue) => {
236
253
  setValue({
237
- $$type: "image",
238
- value: {
239
- src: newValue,
240
- size
241
- }
254
+ src: newValue,
255
+ size
242
256
  });
243
257
  };
244
258
  const setImageSize = (newValue) => {
245
259
  setValue({
246
- $$type: "image",
247
- value: {
248
- src,
249
- size: newValue
250
- }
260
+ src,
261
+ size: newValue
251
262
  });
252
263
  };
253
264
  return /* @__PURE__ */ React9.createElement(import_ui6.Stack, { gap: 1.5 }, /* @__PURE__ */ React9.createElement(BoundPropProvider, { value: src, setValue: setImageSrc, bind: "src" }, /* @__PURE__ */ React9.createElement(ImageMediaControl, null)), /* @__PURE__ */ React9.createElement(BoundPropProvider, { value: size, setValue: setImageSize, bind: "size" }, /* @__PURE__ */ React9.createElement(import_ui6.Grid, { container: true, gap: 2, alignItems: "center", flexWrap: "nowrap" }, /* @__PURE__ */ React9.createElement(import_ui6.Grid, { item: true, xs: 6 }, /* @__PURE__ */ React9.createElement(ControlLabel, null, " ", (0, import_i18n2.__)("Image Resolution", "elementor"))), /* @__PURE__ */ React9.createElement(import_ui6.Grid, { item: true, xs: 6 }, /* @__PURE__ */ React9.createElement(SelectControl, { options: props.sizes })))));
@@ -255,18 +266,20 @@ var ImageControl = createControl((props) => {
255
266
 
256
267
  // src/controls/text-control.tsx
257
268
  var React10 = __toESM(require("react"));
269
+ var import_editor_props4 = require("@elementor/editor-props");
258
270
  var import_ui7 = require("@elementor/ui");
259
271
  var TextControl = createControl(({ placeholder }) => {
260
- const { value, setValue } = useBoundProp("");
272
+ const { value, setValue } = useBoundProp(import_editor_props4.stringPropTypeUtil);
261
273
  const handleChange = (event) => setValue(event.target.value);
262
274
  return /* @__PURE__ */ React10.createElement(ControlActions, null, /* @__PURE__ */ React10.createElement(import_ui7.TextField, { size: "tiny", fullWidth: true, value, onChange: handleChange, placeholder }));
263
275
  });
264
276
 
265
277
  // src/controls/text-area-control.tsx
266
278
  var React11 = __toESM(require("react"));
279
+ var import_editor_props5 = require("@elementor/editor-props");
267
280
  var import_ui8 = require("@elementor/ui");
268
281
  var TextAreaControl = createControl(({ placeholder }) => {
269
- const { value, setValue } = useBoundProp();
282
+ const { value, setValue } = useBoundProp(import_editor_props5.stringPropTypeUtil);
270
283
  const handleChange = (event) => {
271
284
  setValue(event.target.value);
272
285
  };
@@ -286,6 +299,7 @@ var TextAreaControl = createControl(({ placeholder }) => {
286
299
 
287
300
  // src/controls/size-control.tsx
288
301
  var React13 = __toESM(require("react"));
302
+ var import_editor_props6 = require("@elementor/editor-props");
289
303
  var import_ui10 = require("@elementor/ui");
290
304
 
291
305
  // src/components/text-field-inner-selection.tsx
@@ -349,7 +363,7 @@ var useSyncExternalState = ({
349
363
  if (persistWhen(internalValue)) {
350
364
  return internalValue;
351
365
  }
352
- return void 0;
366
+ return null;
353
367
  }
354
368
  function toInternal(externalValue, internalValue) {
355
369
  if (!externalValue) {
@@ -357,7 +371,7 @@ var useSyncExternalState = ({
357
371
  }
358
372
  return externalValue;
359
373
  }
360
- const [internal, setInternal] = (0, import_react5.useState)(toInternal(external, void 0));
374
+ const [internal, setInternal] = (0, import_react5.useState)(toInternal(external, null));
361
375
  (0, import_react5.useEffect)(() => {
362
376
  setInternal((prevInternal) => toInternal(external, prevInternal));
363
377
  }, [external]);
@@ -375,33 +389,24 @@ var defaultUnits = ["px", "%", "em", "rem", "vw", "vh"];
375
389
  var defaultUnit = "px";
376
390
  var defaultSize = NaN;
377
391
  var SizeControl = createControl(({ units: units2 = defaultUnits, placeholder, startIcon }) => {
378
- const { value, setValue } = useBoundProp();
392
+ const { value, setValue } = useBoundProp(import_editor_props6.sizePropTypeUtil);
379
393
  const [state, setState] = useSyncExternalState({
380
394
  external: value,
381
395
  setExternal: setValue,
382
- persistWhen: (controlValue) => !!controlValue?.value?.size || controlValue?.value?.size === 0,
383
- fallback: (controlValue) => ({
384
- $$type: "size",
385
- value: { unit: controlValue?.value?.unit || defaultUnit, size: defaultSize }
386
- })
396
+ persistWhen: (controlValue) => !!controlValue?.size || controlValue?.size === 0,
397
+ fallback: (controlValue) => ({ unit: controlValue?.unit || defaultUnit, size: defaultSize })
387
398
  });
388
399
  const handleUnitChange = (unit) => {
389
400
  setState((prev) => ({
390
- ...prev,
391
- value: {
392
- ...prev.value,
393
- unit
394
- }
401
+ size: prev?.size ?? defaultSize,
402
+ unit
395
403
  }));
396
404
  };
397
405
  const handleSizeChange = (event) => {
398
406
  const { value: size } = event.target;
399
407
  setState((prev) => ({
400
408
  ...prev,
401
- value: {
402
- ...prev.value,
403
- size: size || size === "0" ? parseFloat(size) : defaultSize
404
- }
409
+ size: size || size === "0" ? parseFloat(size) : defaultSize
405
410
  }));
406
411
  };
407
412
  return /* @__PURE__ */ React13.createElement(ControlActions, null, /* @__PURE__ */ React13.createElement(
@@ -412,13 +417,13 @@ var SizeControl = createControl(({ units: units2 = defaultUnits, placeholder, st
412
417
  {
413
418
  options: units2,
414
419
  onClick: handleUnitChange,
415
- value: state.value.unit ?? defaultUnit
420
+ value: state?.unit ?? defaultUnit
416
421
  }
417
422
  ),
418
423
  placeholder,
419
424
  startAdornment: startIcon ?? /* @__PURE__ */ React13.createElement(import_ui10.InputAdornment, { position: "start" }, startIcon),
420
425
  type: "number",
421
- value: Number.isNaN(state.value.size) ? "" : state.value.size,
426
+ value: Number.isNaN(state?.size) ? "" : state?.size,
422
427
  onChange: handleSizeChange
423
428
  }
424
429
  ));
@@ -426,64 +431,48 @@ var SizeControl = createControl(({ units: units2 = defaultUnits, placeholder, st
426
431
 
427
432
  // src/controls/stroke-control.tsx
428
433
  var React15 = __toESM(require("react"));
434
+ var import_editor_props8 = require("@elementor/editor-props");
429
435
  var import_ui12 = require("@elementor/ui");
430
436
  var import_i18n3 = require("@wordpress/i18n");
431
437
 
432
438
  // src/controls/color-control.tsx
433
439
  var React14 = __toESM(require("react"));
440
+ var import_editor_props7 = require("@elementor/editor-props");
434
441
  var import_ui11 = require("@elementor/ui");
435
442
  var ColorControl = createControl(
436
443
  (props) => {
437
- const { value, setValue } = useBoundProp();
444
+ const { value, setValue } = useBoundProp(import_editor_props7.colorPropTypeUtil);
438
445
  const handleChange = (selectedColor) => {
439
- setValue({
440
- $$type: "color",
441
- value: selectedColor
442
- });
446
+ setValue(selectedColor);
443
447
  };
444
- return /* @__PURE__ */ React14.createElement(ControlActions, null, /* @__PURE__ */ React14.createElement(
445
- import_ui11.UnstableColorField,
446
- {
447
- size: "tiny",
448
- ...props,
449
- value: value?.value,
450
- onChange: handleChange,
451
- fullWidth: true
452
- }
453
- ));
448
+ return /* @__PURE__ */ React14.createElement(ControlActions, null, /* @__PURE__ */ React14.createElement(import_ui11.UnstableColorField, { size: "tiny", ...props, value, onChange: handleChange, fullWidth: true }));
454
449
  }
455
450
  );
456
451
 
457
452
  // src/controls/stroke-control.tsx
458
453
  var units = ["px", "em", "rem"];
459
454
  var StrokeControl = createControl(() => {
460
- const { value, setValue } = useBoundProp();
455
+ const { value, setValue } = useBoundProp(import_editor_props8.strokePropTypeUtil);
461
456
  const setStrokeWidth = (newValue) => {
462
457
  const updatedValue = {
463
- ...value?.value,
458
+ ...value,
464
459
  width: newValue
465
460
  };
466
- setValue({
467
- $$type: "stroke",
468
- value: updatedValue
469
- });
461
+ setValue(updatedValue);
470
462
  };
471
463
  const setStrokeColor = (newValue) => {
472
464
  const updatedValue = {
473
- ...value?.value,
465
+ ...value,
474
466
  color: newValue
475
467
  };
476
- setValue({
477
- $$type: "stroke",
478
- value: updatedValue
479
- });
468
+ setValue(updatedValue);
480
469
  };
481
470
  return /* @__PURE__ */ React15.createElement(import_ui12.Stack, { gap: 1.5 }, /* @__PURE__ */ React15.createElement(
482
471
  Control,
483
472
  {
484
473
  bind: "width",
485
474
  label: (0, import_i18n3.__)("Stroke Width", "elementor"),
486
- value: value?.value.width,
475
+ value: value?.width,
487
476
  setValue: setStrokeWidth
488
477
  },
489
478
  /* @__PURE__ */ React15.createElement(SizeControl, { units })
@@ -492,7 +481,7 @@ var StrokeControl = createControl(() => {
492
481
  {
493
482
  bind: "color",
494
483
  label: (0, import_i18n3.__)("Stroke Color", "elementor"),
495
- value: value?.value.color,
484
+ value: value?.color,
496
485
  setValue: setStrokeColor
497
486
  },
498
487
  /* @__PURE__ */ React15.createElement(ColorControl, null)
@@ -502,6 +491,7 @@ var Control = ({ bind, value, setValue, label, children }) => /* @__PURE__ */ Re
502
491
 
503
492
  // src/controls/box-shadow-repeater-control.tsx
504
493
  var React17 = __toESM(require("react"));
494
+ var import_editor_props9 = require("@elementor/editor-props");
505
495
  var import_ui14 = require("@elementor/ui");
506
496
  var import_i18n5 = require("@wordpress/i18n");
507
497
 
@@ -635,18 +625,14 @@ var RepeaterItem = ({
635
625
 
636
626
  // src/controls/box-shadow-repeater-control.tsx
637
627
  var BoxShadowRepeaterControl = createControl(() => {
638
- const { value, setValue } = useBoundProp();
639
- const boxShadowValues = value?.value;
628
+ const { value: boxShadowValues, setValue } = useBoundProp(import_editor_props9.boxShadowPropTypeUtil);
640
629
  const setBoxShadow = (newValue) => {
641
- setValue({
642
- $$type: "box-shadow",
643
- value: newValue
644
- });
630
+ setValue(newValue);
645
631
  };
646
632
  return /* @__PURE__ */ React17.createElement(
647
633
  Repeater,
648
634
  {
649
- values: boxShadowValues,
635
+ values: boxShadowValues ?? [],
650
636
  setValues: setBoxShadow,
651
637
  label: (0, import_i18n5.__)("Box shadow", "elementor"),
652
638
  itemSettings: {
@@ -801,16 +787,13 @@ var initialShadow = {
801
787
 
802
788
  // src/controls/background-overlay-repeater-control.tsx
803
789
  var React18 = __toESM(require("react"));
790
+ var import_editor_props10 = require("@elementor/editor-props");
804
791
  var import_ui15 = require("@elementor/ui");
805
792
  var import_i18n6 = require("@wordpress/i18n");
806
793
  var BackgroundOverlayRepeaterControl = createControl(() => {
807
- const { value, setValue } = useBoundProp();
808
- const colorOverlayValues = value?.value;
794
+ const { value: colorOverlayValues, setValue } = useBoundProp(import_editor_props10.backgroundImagePropTypeUtil);
809
795
  const setColorOverlay = (newValue) => {
810
- setValue({
811
- $$type: "background-image",
812
- value: newValue
813
- });
796
+ setValue(newValue);
814
797
  };
815
798
  return /* @__PURE__ */ React18.createElement(
816
799
  Repeater,
@@ -872,6 +855,7 @@ var initialGradient = {
872
855
 
873
856
  // src/controls/toggle-control.tsx
874
857
  var React20 = __toESM(require("react"));
858
+ var import_editor_props11 = require("@elementor/editor-props");
875
859
 
876
860
  // src/components/control-toggle-button-group.tsx
877
861
  var React19 = __toESM(require("react"));
@@ -922,7 +906,7 @@ var ControlToggleButtonGroup = ({
922
906
  // src/controls/toggle-control.tsx
923
907
  var ToggleControl = createControl(
924
908
  ({ options, fullWidth = false, size = "tiny" }) => {
925
- const { value, setValue } = useBoundProp();
909
+ const { value, setValue } = useBoundProp(import_editor_props11.stringPropTypeUtil);
926
910
  const handleToggle = (option) => {
927
911
  setValue(option);
928
912
  };
@@ -930,7 +914,7 @@ var ToggleControl = createControl(
930
914
  ControlToggleButtonGroup,
931
915
  {
932
916
  items: options,
933
- value: value || null,
917
+ value: value ?? null,
934
918
  onChange: handleToggle,
935
919
  exclusive: true,
936
920
  fullWidth,
@@ -942,8 +926,9 @@ var ToggleControl = createControl(
942
926
 
943
927
  // src/controls/number-control.tsx
944
928
  var React21 = __toESM(require("react"));
929
+ var import_editor_props12 = require("@elementor/editor-props");
945
930
  var import_ui17 = require("@elementor/ui");
946
- var isEmptyOrNaN = (value) => value === void 0 || value === "" || Number.isNaN(Number(value));
931
+ var isEmptyOrNaN = (value) => value === null || value === void 0 || value === "" || Number.isNaN(Number(value));
947
932
  var NumberControl = createControl(
948
933
  ({
949
934
  placeholder,
@@ -952,14 +937,14 @@ var NumberControl = createControl(
952
937
  step = 1,
953
938
  shouldForceInt = false
954
939
  }) => {
955
- const { value, setValue } = useBoundProp();
940
+ const { value, setValue } = useBoundProp(import_editor_props12.numberPropTypeUtil);
956
941
  const handleChange = (event) => {
957
942
  const eventValue = event.target.value;
958
943
  if (isEmptyOrNaN(eventValue)) {
959
- setValue(void 0);
944
+ setValue(null);
960
945
  return;
961
946
  }
962
- const formattedValue = shouldForceInt ? +parseFloat(eventValue) : Number(eventValue);
947
+ const formattedValue = shouldForceInt ? +parseInt(eventValue) : Number(eventValue);
963
948
  setValue(Math.min(Math.max(formattedValue, min), max));
964
949
  };
965
950
  return /* @__PURE__ */ React21.createElement(ControlActions, null, /* @__PURE__ */ React21.createElement(
@@ -980,52 +965,50 @@ var NumberControl = createControl(
980
965
  // src/controls/equal-unequal-sizes-control.tsx
981
966
  var React22 = __toESM(require("react"));
982
967
  var import_react7 = require("react");
968
+ var import_editor_props13 = require("@elementor/editor-props");
983
969
  var import_ui18 = require("@elementor/ui");
984
970
  var import_i18n7 = require("@wordpress/i18n");
985
- function hasMixedSizes(values) {
971
+ var isEqualSizes = (values, items) => {
972
+ if (values.length !== items.length) {
973
+ return false;
974
+ }
986
975
  const [firstValue, ...restValues] = values;
987
- return restValues.some(
988
- (value) => value?.value?.size !== firstValue?.value?.size || value?.value?.unit !== firstValue?.value?.unit
976
+ return restValues.every(
977
+ (value) => value.value?.size === firstValue.value?.size && value.value?.unit === firstValue.value?.unit
989
978
  );
990
- }
991
- function getMultiSizeProps(controlValue, items) {
992
- return controlValue?.$$type === "size" ? items.reduce((values, item) => {
993
- const { bind } = item;
994
- values[bind] = controlValue;
995
- return values;
996
- }, {}) : controlValue?.value ?? {};
997
- }
998
- function EqualUnequalSizesControl({ label, icon, items, multiSizeType }) {
979
+ };
980
+ function EqualUnequalSizesControl({
981
+ label,
982
+ icon,
983
+ items,
984
+ multiSizePropTypeUtil
985
+ }) {
999
986
  const popupId = (0, import_react7.useId)();
1000
987
  const controlRef = (0, import_react7.useRef)(null);
1001
- const { value: controlValue, setValue: setControlValue } = useBoundProp();
1002
- const setMultiSizeValue = (newValue) => {
1003
- setControlValue({ $$type: multiSizeType, value: newValue });
988
+ const popupState = (0, import_ui18.usePopupState)({ variant: "popover", popupId });
989
+ const { value: sizeValue, setValue: setSizeValue } = useBoundProp(import_editor_props13.sizePropTypeUtil);
990
+ const { value: multiSizeValue, setValue: setMultiSizeValue } = useBoundProp(multiSizePropTypeUtil);
991
+ const splitEqualValue = () => {
992
+ return items.reduce((acc, item) => ({ ...acc, [item.bind]: import_editor_props13.sizePropTypeUtil.create(sizeValue) }), {});
1004
993
  };
1005
- const mappedValues = getMultiSizeProps(controlValue, items);
1006
994
  const setNestedProp = (item, newValue) => {
1007
- const { bind } = item;
1008
995
  const newMappedValues = {
1009
- ...mappedValues,
1010
- [bind]: newValue
996
+ ...multiSizeValue ?? splitEqualValue(),
997
+ [item.bind]: newValue
1011
998
  };
1012
- const sizes = Object.values(newMappedValues);
1013
- const isMixed = hasMixedSizes(sizes);
1014
- if (isMixed) {
1015
- setMultiSizeValue(newMappedValues);
1016
- return;
999
+ const isEqual = isEqualSizes(Object.values(newMappedValues), items);
1000
+ if (isEqual) {
1001
+ return setSizeValue(newValue?.value);
1017
1002
  }
1018
- setControlValue(newValue);
1003
+ setMultiSizeValue(newMappedValues);
1019
1004
  };
1020
- const popupState = (0, import_ui18.usePopupState)({
1021
- variant: "popover",
1022
- popupId
1023
- });
1024
1005
  return /* @__PURE__ */ React22.createElement(React22.Fragment, null, /* @__PURE__ */ React22.createElement(import_ui18.Grid, { container: true, gap: 2, alignItems: "center", flexWrap: "nowrap", ref: controlRef }, /* @__PURE__ */ React22.createElement(import_ui18.Grid, { item: true, xs: 6 }, /* @__PURE__ */ React22.createElement(ControlLabel, null, label)), /* @__PURE__ */ React22.createElement(import_ui18.Grid, { item: true, xs: 6 }, /* @__PURE__ */ React22.createElement(
1025
- EqualValuesControl,
1006
+ EqualSizeControl,
1026
1007
  {
1027
- value: mappedValues,
1028
- setValue: setControlValue,
1008
+ items,
1009
+ value: sizeValue,
1010
+ multiSizeValue,
1011
+ setValue: setSizeValue,
1029
1012
  iconButton: /* @__PURE__ */ React22.createElement(
1030
1013
  import_ui18.ToggleButton,
1031
1014
  {
@@ -1057,79 +1040,86 @@ function EqualUnequalSizesControl({ label, icon, items, multiSizeType }) {
1057
1040
  }
1058
1041
  },
1059
1042
  /* @__PURE__ */ React22.createElement(import_ui18.Stack, { gap: 1.5 }, /* @__PURE__ */ React22.createElement(import_ui18.Grid, { container: true, gap: 2, alignItems: "center", flexWrap: "nowrap" }, /* @__PURE__ */ React22.createElement(
1060
- NestedValueControl,
1043
+ MultiSizeValueControl,
1061
1044
  {
1062
1045
  item: items[0],
1063
- value: mappedValues,
1064
- setNestedProp
1046
+ value: multiSizeValue,
1047
+ setNestedProp,
1048
+ splitEqualValue
1065
1049
  }
1066
1050
  ), /* @__PURE__ */ React22.createElement(
1067
- NestedValueControl,
1051
+ MultiSizeValueControl,
1068
1052
  {
1069
1053
  item: items[1],
1070
- value: mappedValues,
1071
- setNestedProp
1054
+ value: multiSizeValue,
1055
+ setNestedProp,
1056
+ splitEqualValue
1072
1057
  }
1073
1058
  )), /* @__PURE__ */ React22.createElement(import_ui18.Grid, { container: true, gap: 2, alignItems: "center", flexWrap: "nowrap" }, /* @__PURE__ */ React22.createElement(
1074
- NestedValueControl,
1059
+ MultiSizeValueControl,
1075
1060
  {
1076
1061
  item: items[3],
1077
- value: mappedValues,
1078
- setNestedProp
1062
+ value: multiSizeValue,
1063
+ setNestedProp,
1064
+ splitEqualValue
1079
1065
  }
1080
1066
  ), /* @__PURE__ */ React22.createElement(
1081
- NestedValueControl,
1067
+ MultiSizeValueControl,
1082
1068
  {
1083
1069
  item: items[2],
1084
- value: mappedValues,
1085
- setNestedProp
1070
+ value: multiSizeValue,
1071
+ setNestedProp,
1072
+ splitEqualValue
1086
1073
  }
1087
1074
  )))
1088
1075
  ));
1089
1076
  }
1090
- var NestedValueControl = ({
1077
+ var MultiSizeValueControl = ({
1091
1078
  item,
1092
1079
  value,
1093
- setNestedProp
1080
+ setNestedProp,
1081
+ splitEqualValue
1094
1082
  }) => {
1095
- const { bind } = item;
1096
- const nestedValue = value?.[bind] ? value[bind] : void 0;
1097
- return /* @__PURE__ */ React22.createElement(
1098
- BoundPropProvider,
1099
- {
1100
- bind: "",
1101
- setValue: (val) => setNestedProp(item, val),
1102
- value: nestedValue
1103
- },
1104
- /* @__PURE__ */ React22.createElement(import_ui18.Grid, { item: true, xs: 6 }, /* @__PURE__ */ React22.createElement(import_ui18.Grid, { container: true, gap: 1, alignItems: "center" }, /* @__PURE__ */ React22.createElement(import_ui18.Grid, { item: true, xs: 12 }, /* @__PURE__ */ React22.createElement(ControlLabel, null, item.label)), /* @__PURE__ */ React22.createElement(import_ui18.Grid, { item: true, xs: 12 }, /* @__PURE__ */ React22.createElement(SizeControl, { startIcon: item.icon }))))
1105
- );
1083
+ const handleChange = (val) => setNestedProp(item, val);
1084
+ const getMultiSizeValues = () => {
1085
+ if (value) {
1086
+ return value?.[item.bind] ?? null;
1087
+ }
1088
+ return splitEqualValue()?.[item.bind] ?? null;
1089
+ };
1090
+ return /* @__PURE__ */ React22.createElement(BoundPropProvider, { bind: "", setValue: handleChange, value: getMultiSizeValues() }, /* @__PURE__ */ React22.createElement(import_ui18.Grid, { item: true, xs: 6 }, /* @__PURE__ */ React22.createElement(import_ui18.Grid, { container: true, gap: 1, alignItems: "center" }, /* @__PURE__ */ React22.createElement(import_ui18.Grid, { item: true, xs: 12 }, /* @__PURE__ */ React22.createElement(ControlLabel, null, item.label)), /* @__PURE__ */ React22.createElement(import_ui18.Grid, { item: true, xs: 12 }, /* @__PURE__ */ React22.createElement(SizeControl, { startIcon: item.icon })))));
1106
1091
  };
1107
- var EqualValuesControl = ({
1092
+ var EqualSizeControl = ({
1108
1093
  value,
1094
+ items,
1109
1095
  setValue,
1110
- iconButton
1096
+ iconButton,
1097
+ multiSizeValue
1111
1098
  }) => {
1112
- const values = Object.values(value ?? {});
1113
- const isMixed = hasMixedSizes(values);
1114
- return /* @__PURE__ */ React22.createElement(
1115
- BoundPropProvider,
1116
- {
1117
- bind: "",
1118
- setValue: (val) => setValue(val),
1119
- value: isMixed ? void 0 : values[0]
1120
- },
1121
- /* @__PURE__ */ React22.createElement(import_ui18.Stack, { direction: "row", alignItems: "center", gap: 1 }, /* @__PURE__ */ React22.createElement(SizeControl, { placeholder: (0, import_i18n7.__)("MIXED", "elementor") }), iconButton)
1122
- );
1099
+ const handleChange = (newValue) => {
1100
+ setValue(newValue.value);
1101
+ };
1102
+ const getDisplayValue = () => {
1103
+ if (value) {
1104
+ return import_editor_props13.sizePropTypeUtil.create(value);
1105
+ }
1106
+ const multiValues = Object.values(multiSizeValue ?? {});
1107
+ if (isEqualSizes(multiValues, items)) {
1108
+ return import_editor_props13.sizePropTypeUtil.create(multiValues[0].value);
1109
+ }
1110
+ };
1111
+ return /* @__PURE__ */ React22.createElement(BoundPropProvider, { bind: "", setValue: handleChange, value: getDisplayValue() ?? null }, /* @__PURE__ */ React22.createElement(import_ui18.Stack, { direction: "row", alignItems: "center", gap: 1 }, /* @__PURE__ */ React22.createElement(SizeControl, { placeholder: (0, import_i18n7.__)("MIXED", "elementor") }), iconButton));
1123
1112
  };
1124
1113
 
1125
1114
  // src/controls/linked-dimensions-control.tsx
1126
1115
  var React23 = __toESM(require("react"));
1116
+ var import_editor_props14 = require("@elementor/editor-props");
1127
1117
  var import_icons3 = require("@elementor/icons");
1128
1118
  var import_ui19 = require("@elementor/ui");
1129
1119
  var import_i18n8 = require("@wordpress/i18n");
1130
1120
  var LinkedDimensionsControl = createControl(({ label }) => {
1131
- const { value, setValue } = useBoundProp();
1132
- const { top, right, bottom, left, isLinked = true } = value?.value || {};
1121
+ const { value, setValue } = useBoundProp(import_editor_props14.linkedDimensionsPropTypeUtil);
1122
+ const { top, right, bottom, left, isLinked = true } = value || {};
1133
1123
  const setLinkedValue = (position, newValue) => {
1134
1124
  const updatedValue = {
1135
1125
  isLinked,
@@ -1139,10 +1129,7 @@ var LinkedDimensionsControl = createControl(({ label }) => {
1139
1129
  left: isLinked ? newValue : left,
1140
1130
  [position]: newValue
1141
1131
  };
1142
- setValue({
1143
- $$type: "linked-dimensions",
1144
- value: updatedValue
1145
- });
1132
+ setValue(updatedValue);
1146
1133
  };
1147
1134
  const toggleLinked = () => {
1148
1135
  const updatedValue = {
@@ -1152,10 +1139,7 @@ var LinkedDimensionsControl = createControl(({ label }) => {
1152
1139
  bottom: !isLinked ? top : bottom,
1153
1140
  left: !isLinked ? top : left
1154
1141
  };
1155
- setValue({
1156
- $$type: "linked-dimensions",
1157
- value: updatedValue
1158
- });
1142
+ setValue(updatedValue);
1159
1143
  };
1160
1144
  const LinkedIcon = isLinked ? import_icons3.LinkIcon : import_icons3.DetachIcon;
1161
1145
  return /* @__PURE__ */ React23.createElement(React23.Fragment, null, /* @__PURE__ */ React23.createElement(import_ui19.Stack, { direction: "row", gap: 2, flexWrap: "nowrap" }, /* @__PURE__ */ React23.createElement(ControlLabel, null, label), /* @__PURE__ */ React23.createElement(
@@ -1213,6 +1197,7 @@ var Control4 = ({
1213
1197
  // src/controls/font-family-control.tsx
1214
1198
  var import_react8 = require("react");
1215
1199
  var React24 = __toESM(require("react"));
1200
+ var import_editor_props15 = require("@elementor/editor-props");
1216
1201
  var import_icons4 = require("@elementor/icons");
1217
1202
  var import_ui20 = require("@elementor/ui");
1218
1203
  var import_i18n10 = require("@wordpress/i18n");
@@ -1250,8 +1235,8 @@ var useFilteredFontFamilies = (fontFamilies, searchValue) => {
1250
1235
  // src/controls/font-family-control.tsx
1251
1236
  var SIZE2 = "tiny";
1252
1237
  var FontFamilyControl = createControl(({ fontFamilies }) => {
1253
- const { value: fontFamily, setValue: setFontFamily } = useBoundProp();
1254
1238
  const [searchValue, setSearchValue] = (0, import_react8.useState)("");
1239
+ const { value: fontFamily, setValue: setFontFamily } = useBoundProp(import_editor_props15.stringPropTypeUtil);
1255
1240
  const popupId = (0, import_react8.useId)();
1256
1241
  const popoverState = (0, import_ui20.usePopupState)({ variant: "popover", popupId });
1257
1242
  const filteredFontFamilies = useFilteredFontFamilies(fontFamilies, searchValue);
@@ -1324,6 +1309,144 @@ var FontFamilyControl = createControl(({ fontFamilies }) => {
1324
1309
  ), "\xA0", (0, import_i18n10.__)("and try again.", "elementor")))))
1325
1310
  ));
1326
1311
  });
1312
+
1313
+ // src/controls/url-control.tsx
1314
+ var React25 = __toESM(require("react"));
1315
+ var import_ui21 = require("@elementor/ui");
1316
+ var UrlControl = createControl(({ placeholder }) => {
1317
+ const { value, setValue } = useBoundProp();
1318
+ const handleChange = (event) => setValue({
1319
+ $$type: "url",
1320
+ value: event.target.value
1321
+ });
1322
+ return /* @__PURE__ */ React25.createElement(ControlActions, null, /* @__PURE__ */ React25.createElement(
1323
+ import_ui21.TextField,
1324
+ {
1325
+ size: "tiny",
1326
+ fullWidth: true,
1327
+ value: value?.value,
1328
+ onChange: handleChange,
1329
+ placeholder
1330
+ }
1331
+ ));
1332
+ });
1333
+
1334
+ // src/controls/link-control.tsx
1335
+ var React26 = __toESM(require("react"));
1336
+ var import_icons5 = require("@elementor/icons");
1337
+ var import_ui22 = require("@elementor/ui");
1338
+ var import_i18n11 = require("@wordpress/i18n");
1339
+ var SIZE3 = "tiny";
1340
+ var DEFAULT_LINK_CONTROL_VALUE = {
1341
+ $$type: "link",
1342
+ value: {
1343
+ enabled: false,
1344
+ href: {
1345
+ $$type: "url",
1346
+ value: ""
1347
+ },
1348
+ isTargetBlank: false
1349
+ }
1350
+ };
1351
+ var LinkControl = createControl(() => {
1352
+ const { value = DEFAULT_LINK_CONTROL_VALUE, setValue } = useBoundProp();
1353
+ const { enabled, href, isTargetBlank } = value?.value || {};
1354
+ const handleOnChange = (key, newValue) => {
1355
+ setValue({
1356
+ $$type: "link",
1357
+ value: {
1358
+ ...value?.value ?? DEFAULT_LINK_CONTROL_VALUE.value,
1359
+ [key]: newValue
1360
+ }
1361
+ });
1362
+ };
1363
+ return /* @__PURE__ */ React26.createElement(import_ui22.Stack, { gap: 1.5 }, /* @__PURE__ */ React26.createElement(import_ui22.Divider, null), /* @__PURE__ */ React26.createElement(
1364
+ import_ui22.Stack,
1365
+ {
1366
+ direction: "row",
1367
+ sx: {
1368
+ justifyContent: "space-between",
1369
+ alignItems: "center"
1370
+ }
1371
+ },
1372
+ /* @__PURE__ */ React26.createElement(ControlLabel, null, (0, import_i18n11.__)("Link", "elementor")),
1373
+ /* @__PURE__ */ React26.createElement(import_ui22.IconButton, { size: SIZE3, onClick: () => handleOnChange("enabled", !enabled) }, enabled ? /* @__PURE__ */ React26.createElement(import_icons5.MinusIcon, { fontSize: SIZE3 }) : /* @__PURE__ */ React26.createElement(import_icons5.PlusIcon, { fontSize: SIZE3 }))
1374
+ ), /* @__PURE__ */ React26.createElement(import_ui22.Collapse, { in: enabled, timeout: "auto", unmountOnExit: true }, /* @__PURE__ */ React26.createElement(import_ui22.Stack, { gap: 1.5 }, /* @__PURE__ */ React26.createElement(
1375
+ BoundPropProvider,
1376
+ {
1377
+ value: href,
1378
+ setValue: (newHref) => handleOnChange("href", newHref),
1379
+ bind: "href"
1380
+ },
1381
+ /* @__PURE__ */ React26.createElement(UrlControl, { placeholder: (0, import_i18n11.__)("Paste URL or type", "elementor") })
1382
+ ), /* @__PURE__ */ React26.createElement(
1383
+ SwitchControl,
1384
+ {
1385
+ value: isTargetBlank,
1386
+ onSwitch: () => handleOnChange("isTargetBlank", !isTargetBlank)
1387
+ }
1388
+ ))));
1389
+ });
1390
+ var SwitchControl = ({ value, onSwitch }) => {
1391
+ return /* @__PURE__ */ React26.createElement(import_ui22.Grid, { container: true, alignItems: "center", flexWrap: "nowrap", justifyContent: "space-between" }, /* @__PURE__ */ React26.createElement(import_ui22.Grid, { item: true }, /* @__PURE__ */ React26.createElement(ControlLabel, null, (0, import_i18n11.__)("Open in new tab", "elementor"))), /* @__PURE__ */ React26.createElement(import_ui22.Grid, { item: true }, /* @__PURE__ */ React26.createElement(import_ui22.Switch, { checked: value, onChange: onSwitch })));
1392
+ };
1393
+
1394
+ // src/controls/gap-control.tsx
1395
+ var React27 = __toESM(require("react"));
1396
+ var import_editor_props16 = require("@elementor/editor-props");
1397
+ var import_icons6 = require("@elementor/icons");
1398
+ var import_ui23 = require("@elementor/ui");
1399
+ var import_i18n12 = require("@wordpress/i18n");
1400
+ var GapControl = createControl(({ label }) => {
1401
+ const { value, setValue } = useBoundProp(import_editor_props16.gapPropTypeUtil);
1402
+ const { column, row, isLinked = true } = value || {};
1403
+ const setLinkedValue = (gap, newValue) => {
1404
+ const updatedValue = {
1405
+ isLinked,
1406
+ column: isLinked ? newValue : column,
1407
+ row: isLinked ? newValue : row,
1408
+ [gap]: newValue
1409
+ };
1410
+ setValue(updatedValue);
1411
+ };
1412
+ const toggleLinked = () => {
1413
+ const updatedValue = {
1414
+ isLinked: !isLinked,
1415
+ column,
1416
+ row: !isLinked ? column : row
1417
+ };
1418
+ setValue(updatedValue);
1419
+ };
1420
+ const LinkedIcon = isLinked ? import_icons6.LinkIcon : import_icons6.DetachIcon;
1421
+ return /* @__PURE__ */ React27.createElement(React27.Fragment, null, /* @__PURE__ */ React27.createElement(import_ui23.Stack, { direction: "row", gap: 2, flexWrap: "nowrap" }, /* @__PURE__ */ React27.createElement(ControlLabel, null, label), /* @__PURE__ */ React27.createElement(
1422
+ import_ui23.ToggleButton,
1423
+ {
1424
+ "aria-label": (0, import_i18n12.__)("Link Inputs", "elementor"),
1425
+ size: "tiny",
1426
+ value: "check",
1427
+ selected: isLinked,
1428
+ sx: { marginLeft: "auto" },
1429
+ onChange: toggleLinked
1430
+ },
1431
+ /* @__PURE__ */ React27.createElement(LinkedIcon, { fontSize: "tiny" })
1432
+ )), /* @__PURE__ */ React27.createElement(import_ui23.Stack, { direction: "row", gap: 2, flexWrap: "nowrap" }, /* @__PURE__ */ React27.createElement(import_ui23.Grid, { container: true, gap: 1, alignItems: "center" }, /* @__PURE__ */ React27.createElement(import_ui23.Grid, { item: true, xs: 12 }, /* @__PURE__ */ React27.createElement(ControlLabel, null, (0, import_i18n12.__)("Column", "elementor"))), /* @__PURE__ */ React27.createElement(import_ui23.Grid, { item: true, xs: 12 }, /* @__PURE__ */ React27.createElement(
1433
+ BoundPropProvider,
1434
+ {
1435
+ setValue: (newValue) => setLinkedValue("column", newValue),
1436
+ value: column,
1437
+ bind: "column"
1438
+ },
1439
+ /* @__PURE__ */ React27.createElement(SizeControl, null)
1440
+ ))), /* @__PURE__ */ React27.createElement(import_ui23.Grid, { container: true, gap: 1, alignItems: "center" }, /* @__PURE__ */ React27.createElement(import_ui23.Grid, { item: true, xs: 12 }, /* @__PURE__ */ React27.createElement(ControlLabel, null, (0, import_i18n12.__)("Row", "elementor"))), /* @__PURE__ */ React27.createElement(import_ui23.Grid, { item: true, xs: 12 }, /* @__PURE__ */ React27.createElement(
1441
+ BoundPropProvider,
1442
+ {
1443
+ setValue: (newValue) => setLinkedValue("row", newValue),
1444
+ value: row,
1445
+ bind: "row"
1446
+ },
1447
+ /* @__PURE__ */ React27.createElement(SizeControl, null)
1448
+ )))));
1449
+ });
1327
1450
  // Annotate the CommonJS export names for ESM import in node:
1328
1451
  0 && (module.exports = {
1329
1452
  BackgroundOverlayRepeaterControl,
@@ -1336,7 +1459,9 @@ var FontFamilyControl = createControl(({ fontFamilies }) => {
1336
1459
  ControlToggleButtonGroup,
1337
1460
  EqualUnequalSizesControl,
1338
1461
  FontFamilyControl,
1462
+ GapControl,
1339
1463
  ImageControl,
1464
+ LinkControl,
1340
1465
  LinkedDimensionsControl,
1341
1466
  NumberControl,
1342
1467
  SelectControl,
@@ -1345,6 +1470,7 @@ var FontFamilyControl = createControl(({ fontFamilies }) => {
1345
1470
  TextAreaControl,
1346
1471
  TextControl,
1347
1472
  ToggleControl,
1473
+ UrlControl,
1348
1474
  createControlReplacement,
1349
1475
  useBoundProp,
1350
1476
  useControlActions,