@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.mjs CHANGED
@@ -1,5 +1,6 @@
1
1
  // src/controls/image-control.tsx
2
2
  import * as React9 from "react";
3
+ import { imagePropTypeUtil } from "@elementor/editor-props";
3
4
  import { Grid, Stack as Stack2 } from "@elementor/ui";
4
5
  import { __ as __2 } from "@wordpress/i18n";
5
6
 
@@ -10,12 +11,26 @@ var BoundPropContext = createContext(null);
10
11
  var BoundPropProvider = ({ children, value, setValue, bind }) => {
11
12
  return /* @__PURE__ */ React.createElement(BoundPropContext.Provider, { value: { value, setValue, bind } }, children);
12
13
  };
13
- function useBoundProp(defaultValue) {
14
+ function useBoundProp(propTypeUtil) {
14
15
  const boundPropContext = useContext(BoundPropContext);
15
16
  if (!boundPropContext) {
16
- throw new Error("useBoundProp must be used within a BoundPropContext");
17
+ throw new Error("useBoundProp must be used within a BoundPropProvider");
17
18
  }
18
- return { ...boundPropContext, value: boundPropContext.value ?? defaultValue };
19
+ if (!propTypeUtil) {
20
+ return boundPropContext;
21
+ }
22
+ function setValue(value2, options) {
23
+ if (value2 === null) {
24
+ return boundPropContext.setValue(null);
25
+ }
26
+ return boundPropContext.setValue(propTypeUtil?.create(value2, options));
27
+ }
28
+ const value = propTypeUtil.extract(boundPropContext.value);
29
+ return {
30
+ ...boundPropContext,
31
+ setValue,
32
+ value
33
+ };
19
34
  }
20
35
 
21
36
  // src/components/control-label.tsx
@@ -75,6 +90,7 @@ function createControl(Component, { supportsReplacements = true } = {}) {
75
90
 
76
91
  // src/controls/image-media-control.tsx
77
92
  import * as React7 from "react";
93
+ import { imageSrcPropTypeUtil } from "@elementor/editor-props";
78
94
  import { UploadIcon } from "@elementor/icons";
79
95
  import { Button, Card, CardMedia, CardOverlay, CircularProgress, Stack } from "@elementor/ui";
80
96
  import { useWpMediaAttachment, useWpMediaFrame } from "@elementor/wp-media";
@@ -116,8 +132,8 @@ function ControlActions({ children }) {
116
132
 
117
133
  // src/controls/image-media-control.tsx
118
134
  var ImageMediaControl = createControl(() => {
119
- const { value, setValue } = useBoundProp();
120
- const { id, url } = value?.value ?? {};
135
+ const { value, setValue } = useBoundProp(imageSrcPropTypeUtil);
136
+ const { id, url } = value ?? {};
121
137
  const { data: attachment, isFetching } = useWpMediaAttachment(id?.value || null);
122
138
  const src = attachment?.url ?? url;
123
139
  const { open } = useWpMediaFrame({
@@ -126,14 +142,11 @@ var ImageMediaControl = createControl(() => {
126
142
  selected: id?.value || null,
127
143
  onSelect: (selectedAttachment) => {
128
144
  setValue({
129
- $$type: "image-src",
130
- value: {
131
- id: {
132
- $$type: "image-attachment-id",
133
- value: selectedAttachment.id
134
- },
135
- url: null
136
- }
145
+ id: {
146
+ $$type: "image-attachment-id",
147
+ value: selectedAttachment.id
148
+ },
149
+ url: null
137
150
  });
138
151
  }
139
152
  });
@@ -161,9 +174,10 @@ var ImageMediaControl = createControl(() => {
161
174
 
162
175
  // src/controls/select-control.tsx
163
176
  import * as React8 from "react";
177
+ import { stringPropTypeUtil } from "@elementor/editor-props";
164
178
  import { MenuItem, Select } from "@elementor/ui";
165
179
  var SelectControl = createControl(({ options }) => {
166
- const { value, setValue } = useBoundProp();
180
+ const { value, setValue } = useBoundProp(stringPropTypeUtil);
167
181
  const handleChange = (event) => {
168
182
  setValue(event.target.value);
169
183
  };
@@ -172,24 +186,18 @@ var SelectControl = createControl(({ options }) => {
172
186
 
173
187
  // src/controls/image-control.tsx
174
188
  var ImageControl = createControl((props) => {
175
- const { value, setValue } = useBoundProp();
176
- const { src, size } = value?.value || {};
189
+ const { value, setValue } = useBoundProp(imagePropTypeUtil);
190
+ const { src, size } = value || {};
177
191
  const setImageSrc = (newValue) => {
178
192
  setValue({
179
- $$type: "image",
180
- value: {
181
- src: newValue,
182
- size
183
- }
193
+ src: newValue,
194
+ size
184
195
  });
185
196
  };
186
197
  const setImageSize = (newValue) => {
187
198
  setValue({
188
- $$type: "image",
189
- value: {
190
- src,
191
- size: newValue
192
- }
199
+ src,
200
+ size: newValue
193
201
  });
194
202
  };
195
203
  return /* @__PURE__ */ React9.createElement(Stack2, { 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(Grid, { container: true, gap: 2, alignItems: "center", flexWrap: "nowrap" }, /* @__PURE__ */ React9.createElement(Grid, { item: true, xs: 6 }, /* @__PURE__ */ React9.createElement(ControlLabel, null, " ", __2("Image Resolution", "elementor"))), /* @__PURE__ */ React9.createElement(Grid, { item: true, xs: 6 }, /* @__PURE__ */ React9.createElement(SelectControl, { options: props.sizes })))));
@@ -197,18 +205,20 @@ var ImageControl = createControl((props) => {
197
205
 
198
206
  // src/controls/text-control.tsx
199
207
  import * as React10 from "react";
208
+ import { stringPropTypeUtil as stringPropTypeUtil2 } from "@elementor/editor-props";
200
209
  import { TextField } from "@elementor/ui";
201
210
  var TextControl = createControl(({ placeholder }) => {
202
- const { value, setValue } = useBoundProp("");
211
+ const { value, setValue } = useBoundProp(stringPropTypeUtil2);
203
212
  const handleChange = (event) => setValue(event.target.value);
204
213
  return /* @__PURE__ */ React10.createElement(ControlActions, null, /* @__PURE__ */ React10.createElement(TextField, { size: "tiny", fullWidth: true, value, onChange: handleChange, placeholder }));
205
214
  });
206
215
 
207
216
  // src/controls/text-area-control.tsx
208
217
  import * as React11 from "react";
218
+ import { stringPropTypeUtil as stringPropTypeUtil3 } from "@elementor/editor-props";
209
219
  import { TextField as TextField2 } from "@elementor/ui";
210
220
  var TextAreaControl = createControl(({ placeholder }) => {
211
- const { value, setValue } = useBoundProp();
221
+ const { value, setValue } = useBoundProp(stringPropTypeUtil3);
212
222
  const handleChange = (event) => {
213
223
  setValue(event.target.value);
214
224
  };
@@ -228,6 +238,7 @@ var TextAreaControl = createControl(({ placeholder }) => {
228
238
 
229
239
  // src/controls/size-control.tsx
230
240
  import * as React13 from "react";
241
+ import { sizePropTypeUtil } from "@elementor/editor-props";
231
242
  import { InputAdornment as InputAdornment2 } from "@elementor/ui";
232
243
 
233
244
  // src/components/text-field-inner-selection.tsx
@@ -291,7 +302,7 @@ var useSyncExternalState = ({
291
302
  if (persistWhen(internalValue)) {
292
303
  return internalValue;
293
304
  }
294
- return void 0;
305
+ return null;
295
306
  }
296
307
  function toInternal(externalValue, internalValue) {
297
308
  if (!externalValue) {
@@ -299,7 +310,7 @@ var useSyncExternalState = ({
299
310
  }
300
311
  return externalValue;
301
312
  }
302
- const [internal, setInternal] = useState(toInternal(external, void 0));
313
+ const [internal, setInternal] = useState(toInternal(external, null));
303
314
  useEffect(() => {
304
315
  setInternal((prevInternal) => toInternal(external, prevInternal));
305
316
  }, [external]);
@@ -317,33 +328,24 @@ var defaultUnits = ["px", "%", "em", "rem", "vw", "vh"];
317
328
  var defaultUnit = "px";
318
329
  var defaultSize = NaN;
319
330
  var SizeControl = createControl(({ units: units2 = defaultUnits, placeholder, startIcon }) => {
320
- const { value, setValue } = useBoundProp();
331
+ const { value, setValue } = useBoundProp(sizePropTypeUtil);
321
332
  const [state, setState] = useSyncExternalState({
322
333
  external: value,
323
334
  setExternal: setValue,
324
- persistWhen: (controlValue) => !!controlValue?.value?.size || controlValue?.value?.size === 0,
325
- fallback: (controlValue) => ({
326
- $$type: "size",
327
- value: { unit: controlValue?.value?.unit || defaultUnit, size: defaultSize }
328
- })
335
+ persistWhen: (controlValue) => !!controlValue?.size || controlValue?.size === 0,
336
+ fallback: (controlValue) => ({ unit: controlValue?.unit || defaultUnit, size: defaultSize })
329
337
  });
330
338
  const handleUnitChange = (unit) => {
331
339
  setState((prev) => ({
332
- ...prev,
333
- value: {
334
- ...prev.value,
335
- unit
336
- }
340
+ size: prev?.size ?? defaultSize,
341
+ unit
337
342
  }));
338
343
  };
339
344
  const handleSizeChange = (event) => {
340
345
  const { value: size } = event.target;
341
346
  setState((prev) => ({
342
347
  ...prev,
343
- value: {
344
- ...prev.value,
345
- size: size || size === "0" ? parseFloat(size) : defaultSize
346
- }
348
+ size: size || size === "0" ? parseFloat(size) : defaultSize
347
349
  }));
348
350
  };
349
351
  return /* @__PURE__ */ React13.createElement(ControlActions, null, /* @__PURE__ */ React13.createElement(
@@ -354,13 +356,13 @@ var SizeControl = createControl(({ units: units2 = defaultUnits, placeholder, st
354
356
  {
355
357
  options: units2,
356
358
  onClick: handleUnitChange,
357
- value: state.value.unit ?? defaultUnit
359
+ value: state?.unit ?? defaultUnit
358
360
  }
359
361
  ),
360
362
  placeholder,
361
363
  startAdornment: startIcon ?? /* @__PURE__ */ React13.createElement(InputAdornment2, { position: "start" }, startIcon),
362
364
  type: "number",
363
- value: Number.isNaN(state.value.size) ? "" : state.value.size,
365
+ value: Number.isNaN(state?.size) ? "" : state?.size,
364
366
  onChange: handleSizeChange
365
367
  }
366
368
  ));
@@ -368,64 +370,48 @@ var SizeControl = createControl(({ units: units2 = defaultUnits, placeholder, st
368
370
 
369
371
  // src/controls/stroke-control.tsx
370
372
  import * as React15 from "react";
373
+ import { strokePropTypeUtil } from "@elementor/editor-props";
371
374
  import { Grid as Grid2, Stack as Stack3 } from "@elementor/ui";
372
375
  import { __ as __3 } from "@wordpress/i18n";
373
376
 
374
377
  // src/controls/color-control.tsx
375
378
  import * as React14 from "react";
379
+ import { colorPropTypeUtil } from "@elementor/editor-props";
376
380
  import { UnstableColorField } from "@elementor/ui";
377
381
  var ColorControl = createControl(
378
382
  (props) => {
379
- const { value, setValue } = useBoundProp();
383
+ const { value, setValue } = useBoundProp(colorPropTypeUtil);
380
384
  const handleChange = (selectedColor) => {
381
- setValue({
382
- $$type: "color",
383
- value: selectedColor
384
- });
385
+ setValue(selectedColor);
385
386
  };
386
- return /* @__PURE__ */ React14.createElement(ControlActions, null, /* @__PURE__ */ React14.createElement(
387
- UnstableColorField,
388
- {
389
- size: "tiny",
390
- ...props,
391
- value: value?.value,
392
- onChange: handleChange,
393
- fullWidth: true
394
- }
395
- ));
387
+ return /* @__PURE__ */ React14.createElement(ControlActions, null, /* @__PURE__ */ React14.createElement(UnstableColorField, { size: "tiny", ...props, value, onChange: handleChange, fullWidth: true }));
396
388
  }
397
389
  );
398
390
 
399
391
  // src/controls/stroke-control.tsx
400
392
  var units = ["px", "em", "rem"];
401
393
  var StrokeControl = createControl(() => {
402
- const { value, setValue } = useBoundProp();
394
+ const { value, setValue } = useBoundProp(strokePropTypeUtil);
403
395
  const setStrokeWidth = (newValue) => {
404
396
  const updatedValue = {
405
- ...value?.value,
397
+ ...value,
406
398
  width: newValue
407
399
  };
408
- setValue({
409
- $$type: "stroke",
410
- value: updatedValue
411
- });
400
+ setValue(updatedValue);
412
401
  };
413
402
  const setStrokeColor = (newValue) => {
414
403
  const updatedValue = {
415
- ...value?.value,
404
+ ...value,
416
405
  color: newValue
417
406
  };
418
- setValue({
419
- $$type: "stroke",
420
- value: updatedValue
421
- });
407
+ setValue(updatedValue);
422
408
  };
423
409
  return /* @__PURE__ */ React15.createElement(Stack3, { gap: 1.5 }, /* @__PURE__ */ React15.createElement(
424
410
  Control,
425
411
  {
426
412
  bind: "width",
427
413
  label: __3("Stroke Width", "elementor"),
428
- value: value?.value.width,
414
+ value: value?.width,
429
415
  setValue: setStrokeWidth
430
416
  },
431
417
  /* @__PURE__ */ React15.createElement(SizeControl, { units })
@@ -434,7 +420,7 @@ var StrokeControl = createControl(() => {
434
420
  {
435
421
  bind: "color",
436
422
  label: __3("Stroke Color", "elementor"),
437
- value: value?.value.color,
423
+ value: value?.color,
438
424
  setValue: setStrokeColor
439
425
  },
440
426
  /* @__PURE__ */ React15.createElement(ColorControl, null)
@@ -444,6 +430,9 @@ var Control = ({ bind, value, setValue, label, children }) => /* @__PURE__ */ Re
444
430
 
445
431
  // src/controls/box-shadow-repeater-control.tsx
446
432
  import * as React17 from "react";
433
+ import {
434
+ boxShadowPropTypeUtil
435
+ } from "@elementor/editor-props";
447
436
  import { Grid as Grid3, Stack as Stack5, Typography as Typography3, UnstableColorIndicator } from "@elementor/ui";
448
437
  import { __ as __5 } from "@wordpress/i18n";
449
438
 
@@ -587,18 +576,14 @@ var RepeaterItem = ({
587
576
 
588
577
  // src/controls/box-shadow-repeater-control.tsx
589
578
  var BoxShadowRepeaterControl = createControl(() => {
590
- const { value, setValue } = useBoundProp();
591
- const boxShadowValues = value?.value;
579
+ const { value: boxShadowValues, setValue } = useBoundProp(boxShadowPropTypeUtil);
592
580
  const setBoxShadow = (newValue) => {
593
- setValue({
594
- $$type: "box-shadow",
595
- value: newValue
596
- });
581
+ setValue(newValue);
597
582
  };
598
583
  return /* @__PURE__ */ React17.createElement(
599
584
  Repeater,
600
585
  {
601
- values: boxShadowValues,
586
+ values: boxShadowValues ?? [],
602
587
  setValues: setBoxShadow,
603
588
  label: __5("Box shadow", "elementor"),
604
589
  itemSettings: {
@@ -753,16 +738,15 @@ var initialShadow = {
753
738
 
754
739
  // src/controls/background-overlay-repeater-control.tsx
755
740
  import * as React18 from "react";
741
+ import {
742
+ backgroundImagePropTypeUtil
743
+ } from "@elementor/editor-props";
756
744
  import { Grid as Grid4, Stack as Stack6, Typography as Typography4, UnstableColorIndicator as UnstableColorIndicator2 } from "@elementor/ui";
757
745
  import { __ as __6 } from "@wordpress/i18n";
758
746
  var BackgroundOverlayRepeaterControl = createControl(() => {
759
- const { value, setValue } = useBoundProp();
760
- const colorOverlayValues = value?.value;
747
+ const { value: colorOverlayValues, setValue } = useBoundProp(backgroundImagePropTypeUtil);
761
748
  const setColorOverlay = (newValue) => {
762
- setValue({
763
- $$type: "background-image",
764
- value: newValue
765
- });
749
+ setValue(newValue);
766
750
  };
767
751
  return /* @__PURE__ */ React18.createElement(
768
752
  Repeater,
@@ -824,6 +808,7 @@ var initialGradient = {
824
808
 
825
809
  // src/controls/toggle-control.tsx
826
810
  import * as React20 from "react";
811
+ import { stringPropTypeUtil as stringPropTypeUtil4 } from "@elementor/editor-props";
827
812
 
828
813
  // src/components/control-toggle-button-group.tsx
829
814
  import * as React19 from "react";
@@ -880,7 +865,7 @@ var ControlToggleButtonGroup = ({
880
865
  // src/controls/toggle-control.tsx
881
866
  var ToggleControl = createControl(
882
867
  ({ options, fullWidth = false, size = "tiny" }) => {
883
- const { value, setValue } = useBoundProp();
868
+ const { value, setValue } = useBoundProp(stringPropTypeUtil4);
884
869
  const handleToggle = (option) => {
885
870
  setValue(option);
886
871
  };
@@ -888,7 +873,7 @@ var ToggleControl = createControl(
888
873
  ControlToggleButtonGroup,
889
874
  {
890
875
  items: options,
891
- value: value || null,
876
+ value: value ?? null,
892
877
  onChange: handleToggle,
893
878
  exclusive: true,
894
879
  fullWidth,
@@ -900,8 +885,9 @@ var ToggleControl = createControl(
900
885
 
901
886
  // src/controls/number-control.tsx
902
887
  import * as React21 from "react";
888
+ import { numberPropTypeUtil } from "@elementor/editor-props";
903
889
  import { TextField as TextField4 } from "@elementor/ui";
904
- var isEmptyOrNaN = (value) => value === void 0 || value === "" || Number.isNaN(Number(value));
890
+ var isEmptyOrNaN = (value) => value === null || value === void 0 || value === "" || Number.isNaN(Number(value));
905
891
  var NumberControl = createControl(
906
892
  ({
907
893
  placeholder,
@@ -910,14 +896,14 @@ var NumberControl = createControl(
910
896
  step = 1,
911
897
  shouldForceInt = false
912
898
  }) => {
913
- const { value, setValue } = useBoundProp();
899
+ const { value, setValue } = useBoundProp(numberPropTypeUtil);
914
900
  const handleChange = (event) => {
915
901
  const eventValue = event.target.value;
916
902
  if (isEmptyOrNaN(eventValue)) {
917
- setValue(void 0);
903
+ setValue(null);
918
904
  return;
919
905
  }
920
- const formattedValue = shouldForceInt ? +parseFloat(eventValue) : Number(eventValue);
906
+ const formattedValue = shouldForceInt ? +parseInt(eventValue) : Number(eventValue);
921
907
  setValue(Math.min(Math.max(formattedValue, min), max));
922
908
  };
923
909
  return /* @__PURE__ */ React21.createElement(ControlActions, null, /* @__PURE__ */ React21.createElement(
@@ -938,52 +924,52 @@ var NumberControl = createControl(
938
924
  // src/controls/equal-unequal-sizes-control.tsx
939
925
  import * as React22 from "react";
940
926
  import { useId as useId3, useRef as useRef2 } from "react";
927
+ import {
928
+ sizePropTypeUtil as sizePropTypeUtil2
929
+ } from "@elementor/editor-props";
941
930
  import { bindPopover as bindPopover2, bindToggle, Grid as Grid5, Popover as Popover2, Stack as Stack7, ToggleButton as ToggleButton2, usePopupState as usePopupState3 } from "@elementor/ui";
942
931
  import { __ as __7 } from "@wordpress/i18n";
943
- function hasMixedSizes(values) {
932
+ var isEqualSizes = (values, items) => {
933
+ if (values.length !== items.length) {
934
+ return false;
935
+ }
944
936
  const [firstValue, ...restValues] = values;
945
- return restValues.some(
946
- (value) => value?.value?.size !== firstValue?.value?.size || value?.value?.unit !== firstValue?.value?.unit
937
+ return restValues.every(
938
+ (value) => value.value?.size === firstValue.value?.size && value.value?.unit === firstValue.value?.unit
947
939
  );
948
- }
949
- function getMultiSizeProps(controlValue, items) {
950
- return controlValue?.$$type === "size" ? items.reduce((values, item) => {
951
- const { bind } = item;
952
- values[bind] = controlValue;
953
- return values;
954
- }, {}) : controlValue?.value ?? {};
955
- }
956
- function EqualUnequalSizesControl({ label, icon, items, multiSizeType }) {
940
+ };
941
+ function EqualUnequalSizesControl({
942
+ label,
943
+ icon,
944
+ items,
945
+ multiSizePropTypeUtil
946
+ }) {
957
947
  const popupId = useId3();
958
948
  const controlRef = useRef2(null);
959
- const { value: controlValue, setValue: setControlValue } = useBoundProp();
960
- const setMultiSizeValue = (newValue) => {
961
- setControlValue({ $$type: multiSizeType, value: newValue });
949
+ const popupState = usePopupState3({ variant: "popover", popupId });
950
+ const { value: sizeValue, setValue: setSizeValue } = useBoundProp(sizePropTypeUtil2);
951
+ const { value: multiSizeValue, setValue: setMultiSizeValue } = useBoundProp(multiSizePropTypeUtil);
952
+ const splitEqualValue = () => {
953
+ return items.reduce((acc, item) => ({ ...acc, [item.bind]: sizePropTypeUtil2.create(sizeValue) }), {});
962
954
  };
963
- const mappedValues = getMultiSizeProps(controlValue, items);
964
955
  const setNestedProp = (item, newValue) => {
965
- const { bind } = item;
966
956
  const newMappedValues = {
967
- ...mappedValues,
968
- [bind]: newValue
957
+ ...multiSizeValue ?? splitEqualValue(),
958
+ [item.bind]: newValue
969
959
  };
970
- const sizes = Object.values(newMappedValues);
971
- const isMixed = hasMixedSizes(sizes);
972
- if (isMixed) {
973
- setMultiSizeValue(newMappedValues);
974
- return;
960
+ const isEqual = isEqualSizes(Object.values(newMappedValues), items);
961
+ if (isEqual) {
962
+ return setSizeValue(newValue?.value);
975
963
  }
976
- setControlValue(newValue);
964
+ setMultiSizeValue(newMappedValues);
977
965
  };
978
- const popupState = usePopupState3({
979
- variant: "popover",
980
- popupId
981
- });
982
966
  return /* @__PURE__ */ React22.createElement(React22.Fragment, null, /* @__PURE__ */ React22.createElement(Grid5, { container: true, gap: 2, alignItems: "center", flexWrap: "nowrap", ref: controlRef }, /* @__PURE__ */ React22.createElement(Grid5, { item: true, xs: 6 }, /* @__PURE__ */ React22.createElement(ControlLabel, null, label)), /* @__PURE__ */ React22.createElement(Grid5, { item: true, xs: 6 }, /* @__PURE__ */ React22.createElement(
983
- EqualValuesControl,
967
+ EqualSizeControl,
984
968
  {
985
- value: mappedValues,
986
- setValue: setControlValue,
969
+ items,
970
+ value: sizeValue,
971
+ multiSizeValue,
972
+ setValue: setSizeValue,
987
973
  iconButton: /* @__PURE__ */ React22.createElement(
988
974
  ToggleButton2,
989
975
  {
@@ -1015,79 +1001,86 @@ function EqualUnequalSizesControl({ label, icon, items, multiSizeType }) {
1015
1001
  }
1016
1002
  },
1017
1003
  /* @__PURE__ */ React22.createElement(Stack7, { gap: 1.5 }, /* @__PURE__ */ React22.createElement(Grid5, { container: true, gap: 2, alignItems: "center", flexWrap: "nowrap" }, /* @__PURE__ */ React22.createElement(
1018
- NestedValueControl,
1004
+ MultiSizeValueControl,
1019
1005
  {
1020
1006
  item: items[0],
1021
- value: mappedValues,
1022
- setNestedProp
1007
+ value: multiSizeValue,
1008
+ setNestedProp,
1009
+ splitEqualValue
1023
1010
  }
1024
1011
  ), /* @__PURE__ */ React22.createElement(
1025
- NestedValueControl,
1012
+ MultiSizeValueControl,
1026
1013
  {
1027
1014
  item: items[1],
1028
- value: mappedValues,
1029
- setNestedProp
1015
+ value: multiSizeValue,
1016
+ setNestedProp,
1017
+ splitEqualValue
1030
1018
  }
1031
1019
  )), /* @__PURE__ */ React22.createElement(Grid5, { container: true, gap: 2, alignItems: "center", flexWrap: "nowrap" }, /* @__PURE__ */ React22.createElement(
1032
- NestedValueControl,
1020
+ MultiSizeValueControl,
1033
1021
  {
1034
1022
  item: items[3],
1035
- value: mappedValues,
1036
- setNestedProp
1023
+ value: multiSizeValue,
1024
+ setNestedProp,
1025
+ splitEqualValue
1037
1026
  }
1038
1027
  ), /* @__PURE__ */ React22.createElement(
1039
- NestedValueControl,
1028
+ MultiSizeValueControl,
1040
1029
  {
1041
1030
  item: items[2],
1042
- value: mappedValues,
1043
- setNestedProp
1031
+ value: multiSizeValue,
1032
+ setNestedProp,
1033
+ splitEqualValue
1044
1034
  }
1045
1035
  )))
1046
1036
  ));
1047
1037
  }
1048
- var NestedValueControl = ({
1038
+ var MultiSizeValueControl = ({
1049
1039
  item,
1050
1040
  value,
1051
- setNestedProp
1041
+ setNestedProp,
1042
+ splitEqualValue
1052
1043
  }) => {
1053
- const { bind } = item;
1054
- const nestedValue = value?.[bind] ? value[bind] : void 0;
1055
- return /* @__PURE__ */ React22.createElement(
1056
- BoundPropProvider,
1057
- {
1058
- bind: "",
1059
- setValue: (val) => setNestedProp(item, val),
1060
- value: nestedValue
1061
- },
1062
- /* @__PURE__ */ React22.createElement(Grid5, { item: true, xs: 6 }, /* @__PURE__ */ React22.createElement(Grid5, { container: true, gap: 1, alignItems: "center" }, /* @__PURE__ */ React22.createElement(Grid5, { item: true, xs: 12 }, /* @__PURE__ */ React22.createElement(ControlLabel, null, item.label)), /* @__PURE__ */ React22.createElement(Grid5, { item: true, xs: 12 }, /* @__PURE__ */ React22.createElement(SizeControl, { startIcon: item.icon }))))
1063
- );
1044
+ const handleChange = (val) => setNestedProp(item, val);
1045
+ const getMultiSizeValues = () => {
1046
+ if (value) {
1047
+ return value?.[item.bind] ?? null;
1048
+ }
1049
+ return splitEqualValue()?.[item.bind] ?? null;
1050
+ };
1051
+ return /* @__PURE__ */ React22.createElement(BoundPropProvider, { bind: "", setValue: handleChange, value: getMultiSizeValues() }, /* @__PURE__ */ React22.createElement(Grid5, { item: true, xs: 6 }, /* @__PURE__ */ React22.createElement(Grid5, { container: true, gap: 1, alignItems: "center" }, /* @__PURE__ */ React22.createElement(Grid5, { item: true, xs: 12 }, /* @__PURE__ */ React22.createElement(ControlLabel, null, item.label)), /* @__PURE__ */ React22.createElement(Grid5, { item: true, xs: 12 }, /* @__PURE__ */ React22.createElement(SizeControl, { startIcon: item.icon })))));
1064
1052
  };
1065
- var EqualValuesControl = ({
1053
+ var EqualSizeControl = ({
1066
1054
  value,
1055
+ items,
1067
1056
  setValue,
1068
- iconButton
1057
+ iconButton,
1058
+ multiSizeValue
1069
1059
  }) => {
1070
- const values = Object.values(value ?? {});
1071
- const isMixed = hasMixedSizes(values);
1072
- return /* @__PURE__ */ React22.createElement(
1073
- BoundPropProvider,
1074
- {
1075
- bind: "",
1076
- setValue: (val) => setValue(val),
1077
- value: isMixed ? void 0 : values[0]
1078
- },
1079
- /* @__PURE__ */ React22.createElement(Stack7, { direction: "row", alignItems: "center", gap: 1 }, /* @__PURE__ */ React22.createElement(SizeControl, { placeholder: __7("MIXED", "elementor") }), iconButton)
1080
- );
1060
+ const handleChange = (newValue) => {
1061
+ setValue(newValue.value);
1062
+ };
1063
+ const getDisplayValue = () => {
1064
+ if (value) {
1065
+ return sizePropTypeUtil2.create(value);
1066
+ }
1067
+ const multiValues = Object.values(multiSizeValue ?? {});
1068
+ if (isEqualSizes(multiValues, items)) {
1069
+ return sizePropTypeUtil2.create(multiValues[0].value);
1070
+ }
1071
+ };
1072
+ return /* @__PURE__ */ React22.createElement(BoundPropProvider, { bind: "", setValue: handleChange, value: getDisplayValue() ?? null }, /* @__PURE__ */ React22.createElement(Stack7, { direction: "row", alignItems: "center", gap: 1 }, /* @__PURE__ */ React22.createElement(SizeControl, { placeholder: __7("MIXED", "elementor") }), iconButton));
1081
1073
  };
1082
1074
 
1083
1075
  // src/controls/linked-dimensions-control.tsx
1084
1076
  import * as React23 from "react";
1077
+ import { linkedDimensionsPropTypeUtil } from "@elementor/editor-props";
1085
1078
  import { DetachIcon, LinkIcon, SideBottomIcon, SideLeftIcon, SideRightIcon, SideTopIcon } from "@elementor/icons";
1086
1079
  import { Grid as Grid6, Stack as Stack8, ToggleButton as ToggleButton3 } from "@elementor/ui";
1087
1080
  import { __ as __8 } from "@wordpress/i18n";
1088
1081
  var LinkedDimensionsControl = createControl(({ label }) => {
1089
- const { value, setValue } = useBoundProp();
1090
- const { top, right, bottom, left, isLinked = true } = value?.value || {};
1082
+ const { value, setValue } = useBoundProp(linkedDimensionsPropTypeUtil);
1083
+ const { top, right, bottom, left, isLinked = true } = value || {};
1091
1084
  const setLinkedValue = (position, newValue) => {
1092
1085
  const updatedValue = {
1093
1086
  isLinked,
@@ -1097,10 +1090,7 @@ var LinkedDimensionsControl = createControl(({ label }) => {
1097
1090
  left: isLinked ? newValue : left,
1098
1091
  [position]: newValue
1099
1092
  };
1100
- setValue({
1101
- $$type: "linked-dimensions",
1102
- value: updatedValue
1103
- });
1093
+ setValue(updatedValue);
1104
1094
  };
1105
1095
  const toggleLinked = () => {
1106
1096
  const updatedValue = {
@@ -1110,10 +1100,7 @@ var LinkedDimensionsControl = createControl(({ label }) => {
1110
1100
  bottom: !isLinked ? top : bottom,
1111
1101
  left: !isLinked ? top : left
1112
1102
  };
1113
- setValue({
1114
- $$type: "linked-dimensions",
1115
- value: updatedValue
1116
- });
1103
+ setValue(updatedValue);
1117
1104
  };
1118
1105
  const LinkedIcon = isLinked ? LinkIcon : DetachIcon;
1119
1106
  return /* @__PURE__ */ React23.createElement(React23.Fragment, null, /* @__PURE__ */ React23.createElement(Stack8, { direction: "row", gap: 2, flexWrap: "nowrap" }, /* @__PURE__ */ React23.createElement(ControlLabel, null, label), /* @__PURE__ */ React23.createElement(
@@ -1171,6 +1158,7 @@ var Control4 = ({
1171
1158
  // src/controls/font-family-control.tsx
1172
1159
  import { Fragment as Fragment4, useId as useId4, useState as useState3 } from "react";
1173
1160
  import * as React24 from "react";
1161
+ import { stringPropTypeUtil as stringPropTypeUtil5 } from "@elementor/editor-props";
1174
1162
  import { ChevronDownIcon, EditIcon, PhotoIcon, SearchIcon, XIcon as XIcon2 } from "@elementor/icons";
1175
1163
  import {
1176
1164
  bindPopover as bindPopover3,
@@ -1225,8 +1213,8 @@ var useFilteredFontFamilies = (fontFamilies, searchValue) => {
1225
1213
  // src/controls/font-family-control.tsx
1226
1214
  var SIZE2 = "tiny";
1227
1215
  var FontFamilyControl = createControl(({ fontFamilies }) => {
1228
- const { value: fontFamily, setValue: setFontFamily } = useBoundProp();
1229
1216
  const [searchValue, setSearchValue] = useState3("");
1217
+ const { value: fontFamily, setValue: setFontFamily } = useBoundProp(stringPropTypeUtil5);
1230
1218
  const popupId = useId4();
1231
1219
  const popoverState = usePopupState4({ variant: "popover", popupId });
1232
1220
  const filteredFontFamilies = useFilteredFontFamilies(fontFamilies, searchValue);
@@ -1299,6 +1287,144 @@ var FontFamilyControl = createControl(({ fontFamilies }) => {
1299
1287
  ), "\xA0", __10("and try again.", "elementor")))))
1300
1288
  ));
1301
1289
  });
1290
+
1291
+ // src/controls/url-control.tsx
1292
+ import * as React25 from "react";
1293
+ import { TextField as TextField6 } from "@elementor/ui";
1294
+ var UrlControl = createControl(({ placeholder }) => {
1295
+ const { value, setValue } = useBoundProp();
1296
+ const handleChange = (event) => setValue({
1297
+ $$type: "url",
1298
+ value: event.target.value
1299
+ });
1300
+ return /* @__PURE__ */ React25.createElement(ControlActions, null, /* @__PURE__ */ React25.createElement(
1301
+ TextField6,
1302
+ {
1303
+ size: "tiny",
1304
+ fullWidth: true,
1305
+ value: value?.value,
1306
+ onChange: handleChange,
1307
+ placeholder
1308
+ }
1309
+ ));
1310
+ });
1311
+
1312
+ // src/controls/link-control.tsx
1313
+ import * as React26 from "react";
1314
+ import { MinusIcon, PlusIcon as PlusIcon2 } from "@elementor/icons";
1315
+ import { Collapse, Divider as Divider2, Grid as Grid7, IconButton as IconButton3, Stack as Stack10, Switch } from "@elementor/ui";
1316
+ import { __ as __11 } from "@wordpress/i18n";
1317
+ var SIZE3 = "tiny";
1318
+ var DEFAULT_LINK_CONTROL_VALUE = {
1319
+ $$type: "link",
1320
+ value: {
1321
+ enabled: false,
1322
+ href: {
1323
+ $$type: "url",
1324
+ value: ""
1325
+ },
1326
+ isTargetBlank: false
1327
+ }
1328
+ };
1329
+ var LinkControl = createControl(() => {
1330
+ const { value = DEFAULT_LINK_CONTROL_VALUE, setValue } = useBoundProp();
1331
+ const { enabled, href, isTargetBlank } = value?.value || {};
1332
+ const handleOnChange = (key, newValue) => {
1333
+ setValue({
1334
+ $$type: "link",
1335
+ value: {
1336
+ ...value?.value ?? DEFAULT_LINK_CONTROL_VALUE.value,
1337
+ [key]: newValue
1338
+ }
1339
+ });
1340
+ };
1341
+ return /* @__PURE__ */ React26.createElement(Stack10, { gap: 1.5 }, /* @__PURE__ */ React26.createElement(Divider2, null), /* @__PURE__ */ React26.createElement(
1342
+ Stack10,
1343
+ {
1344
+ direction: "row",
1345
+ sx: {
1346
+ justifyContent: "space-between",
1347
+ alignItems: "center"
1348
+ }
1349
+ },
1350
+ /* @__PURE__ */ React26.createElement(ControlLabel, null, __11("Link", "elementor")),
1351
+ /* @__PURE__ */ React26.createElement(IconButton3, { size: SIZE3, onClick: () => handleOnChange("enabled", !enabled) }, enabled ? /* @__PURE__ */ React26.createElement(MinusIcon, { fontSize: SIZE3 }) : /* @__PURE__ */ React26.createElement(PlusIcon2, { fontSize: SIZE3 }))
1352
+ ), /* @__PURE__ */ React26.createElement(Collapse, { in: enabled, timeout: "auto", unmountOnExit: true }, /* @__PURE__ */ React26.createElement(Stack10, { gap: 1.5 }, /* @__PURE__ */ React26.createElement(
1353
+ BoundPropProvider,
1354
+ {
1355
+ value: href,
1356
+ setValue: (newHref) => handleOnChange("href", newHref),
1357
+ bind: "href"
1358
+ },
1359
+ /* @__PURE__ */ React26.createElement(UrlControl, { placeholder: __11("Paste URL or type", "elementor") })
1360
+ ), /* @__PURE__ */ React26.createElement(
1361
+ SwitchControl,
1362
+ {
1363
+ value: isTargetBlank,
1364
+ onSwitch: () => handleOnChange("isTargetBlank", !isTargetBlank)
1365
+ }
1366
+ ))));
1367
+ });
1368
+ var SwitchControl = ({ value, onSwitch }) => {
1369
+ return /* @__PURE__ */ React26.createElement(Grid7, { container: true, alignItems: "center", flexWrap: "nowrap", justifyContent: "space-between" }, /* @__PURE__ */ React26.createElement(Grid7, { item: true }, /* @__PURE__ */ React26.createElement(ControlLabel, null, __11("Open in new tab", "elementor"))), /* @__PURE__ */ React26.createElement(Grid7, { item: true }, /* @__PURE__ */ React26.createElement(Switch, { checked: value, onChange: onSwitch })));
1370
+ };
1371
+
1372
+ // src/controls/gap-control.tsx
1373
+ import * as React27 from "react";
1374
+ import { gapPropTypeUtil } from "@elementor/editor-props";
1375
+ import { DetachIcon as DetachIcon2, LinkIcon as LinkIcon2 } from "@elementor/icons";
1376
+ import { Grid as Grid8, Stack as Stack11, ToggleButton as ToggleButton4 } from "@elementor/ui";
1377
+ import { __ as __12 } from "@wordpress/i18n";
1378
+ var GapControl = createControl(({ label }) => {
1379
+ const { value, setValue } = useBoundProp(gapPropTypeUtil);
1380
+ const { column, row, isLinked = true } = value || {};
1381
+ const setLinkedValue = (gap, newValue) => {
1382
+ const updatedValue = {
1383
+ isLinked,
1384
+ column: isLinked ? newValue : column,
1385
+ row: isLinked ? newValue : row,
1386
+ [gap]: newValue
1387
+ };
1388
+ setValue(updatedValue);
1389
+ };
1390
+ const toggleLinked = () => {
1391
+ const updatedValue = {
1392
+ isLinked: !isLinked,
1393
+ column,
1394
+ row: !isLinked ? column : row
1395
+ };
1396
+ setValue(updatedValue);
1397
+ };
1398
+ const LinkedIcon = isLinked ? LinkIcon2 : DetachIcon2;
1399
+ return /* @__PURE__ */ React27.createElement(React27.Fragment, null, /* @__PURE__ */ React27.createElement(Stack11, { direction: "row", gap: 2, flexWrap: "nowrap" }, /* @__PURE__ */ React27.createElement(ControlLabel, null, label), /* @__PURE__ */ React27.createElement(
1400
+ ToggleButton4,
1401
+ {
1402
+ "aria-label": __12("Link Inputs", "elementor"),
1403
+ size: "tiny",
1404
+ value: "check",
1405
+ selected: isLinked,
1406
+ sx: { marginLeft: "auto" },
1407
+ onChange: toggleLinked
1408
+ },
1409
+ /* @__PURE__ */ React27.createElement(LinkedIcon, { fontSize: "tiny" })
1410
+ )), /* @__PURE__ */ React27.createElement(Stack11, { direction: "row", gap: 2, flexWrap: "nowrap" }, /* @__PURE__ */ React27.createElement(Grid8, { container: true, gap: 1, alignItems: "center" }, /* @__PURE__ */ React27.createElement(Grid8, { item: true, xs: 12 }, /* @__PURE__ */ React27.createElement(ControlLabel, null, __12("Column", "elementor"))), /* @__PURE__ */ React27.createElement(Grid8, { item: true, xs: 12 }, /* @__PURE__ */ React27.createElement(
1411
+ BoundPropProvider,
1412
+ {
1413
+ setValue: (newValue) => setLinkedValue("column", newValue),
1414
+ value: column,
1415
+ bind: "column"
1416
+ },
1417
+ /* @__PURE__ */ React27.createElement(SizeControl, null)
1418
+ ))), /* @__PURE__ */ React27.createElement(Grid8, { container: true, gap: 1, alignItems: "center" }, /* @__PURE__ */ React27.createElement(Grid8, { item: true, xs: 12 }, /* @__PURE__ */ React27.createElement(ControlLabel, null, __12("Row", "elementor"))), /* @__PURE__ */ React27.createElement(Grid8, { item: true, xs: 12 }, /* @__PURE__ */ React27.createElement(
1419
+ BoundPropProvider,
1420
+ {
1421
+ setValue: (newValue) => setLinkedValue("row", newValue),
1422
+ value: row,
1423
+ bind: "row"
1424
+ },
1425
+ /* @__PURE__ */ React27.createElement(SizeControl, null)
1426
+ )))));
1427
+ });
1302
1428
  export {
1303
1429
  BackgroundOverlayRepeaterControl,
1304
1430
  BoundPropProvider,
@@ -1310,7 +1436,9 @@ export {
1310
1436
  ControlToggleButtonGroup,
1311
1437
  EqualUnequalSizesControl,
1312
1438
  FontFamilyControl,
1439
+ GapControl,
1313
1440
  ImageControl,
1441
+ LinkControl,
1314
1442
  LinkedDimensionsControl,
1315
1443
  NumberControl,
1316
1444
  SelectControl,
@@ -1319,6 +1447,7 @@ export {
1319
1447
  TextAreaControl,
1320
1448
  TextControl,
1321
1449
  ToggleControl,
1450
+ UrlControl,
1322
1451
  createControlReplacement,
1323
1452
  useBoundProp,
1324
1453
  useControlActions,