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