@elementor/editor-controls 4.1.0-745 → 4.1.0-747

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
@@ -107,11 +107,20 @@ var ArrayPropKeyProvider = ({ children, bind }) => {
107
107
  return context?.setValue(newValue, options, { bind });
108
108
  };
109
109
  const value = context.value?.[Number(bind)];
110
+ const placeholder = context.placeholder?.[Number(bind)];
110
111
  const propType = context.propType.item_prop_type;
111
112
  return /* @__PURE__ */ React2.createElement(
112
113
  PropKeyContext.Provider,
113
114
  {
114
- value: { ...context, value, setValue, bind, propType, path: [...path ?? [], bind] }
115
+ value: {
116
+ ...context,
117
+ value,
118
+ setValue,
119
+ bind,
120
+ propType,
121
+ path: [...path ?? [], bind],
122
+ placeholder: placeholder ?? void 0
123
+ }
115
124
  },
116
125
  children
117
126
  );
@@ -152,7 +161,9 @@ function useBoundProp(propTypeUtil) {
152
161
  return propKeyContext?.setValue(propTypeUtil?.create(value2, options), {}, meta);
153
162
  }
154
163
  const propType = resolveUnionPropType(propKeyContext.propType, propTypeUtil.key);
155
- const value = propTypeUtil.extract(propKeyContext.value ?? propType.default ?? null);
164
+ const hasPlaceholder = propKeyContext.placeholder !== void 0 && propKeyContext.placeholder !== null;
165
+ const fallbackValue = hasPlaceholder ? null : propType.default;
166
+ const value = propTypeUtil.extract(propKeyContext.value ?? fallbackValue ?? null);
156
167
  const placeholder = propTypeUtil.extract(propKeyContext.placeholder ?? null);
157
168
  return {
158
169
  ...propKeyContext,
@@ -360,10 +371,11 @@ function ControlActions({ children }) {
360
371
 
361
372
  // src/controls/image-media-control.tsx
362
373
  var ImageMediaControl = createControl(({ mediaTypes = ["image"] }) => {
363
- const { value, setValue, propType } = useBoundProp(imageSrcPropTypeUtil);
374
+ const { value, setValue, propType, placeholder } = useBoundProp(imageSrcPropTypeUtil);
364
375
  const { id, url } = value ?? {};
365
376
  const { data: attachment, isFetching } = useWpMediaAttachment(id?.value || null);
366
- const src = attachment?.url ?? url?.value ?? null;
377
+ const { data: placeholderAttachment } = useWpMediaAttachment(placeholder?.id?.value || null);
378
+ const src = attachment?.url ?? url?.value ?? placeholderAttachment?.url ?? null;
367
379
  const { open } = useWpMediaFrame({
368
380
  mediaTypes,
369
381
  multiple: false,
@@ -472,7 +484,7 @@ import { stringPropTypeUtil as stringPropTypeUtil2 } from "@elementor/editor-pro
472
484
  import { TextField } from "@elementor/ui";
473
485
  var TextControl = createControl(
474
486
  ({
475
- placeholder,
487
+ placeholder: propPlaceholder,
476
488
  error,
477
489
  inputValue,
478
490
  inputDisabled,
@@ -480,8 +492,9 @@ var TextControl = createControl(
480
492
  sx,
481
493
  ariaLabel
482
494
  }) => {
483
- const { value, setValue, disabled } = useBoundProp(stringPropTypeUtil2);
495
+ const { value, setValue, disabled, placeholder: boundPlaceholder } = useBoundProp(stringPropTypeUtil2);
484
496
  const handleChange = (event) => setValue(event.target.value);
497
+ const placeholder = propPlaceholder ?? boundPlaceholder ?? void 0;
485
498
  return /* @__PURE__ */ React14.createElement(ControlActions, null, /* @__PURE__ */ React14.createElement(
486
499
  TextField,
487
500
  {
@@ -506,11 +519,12 @@ var TextControl = createControl(
506
519
  import * as React15 from "react";
507
520
  import { stringPropTypeUtil as stringPropTypeUtil3 } from "@elementor/editor-props";
508
521
  import { TextField as TextField2 } from "@elementor/ui";
509
- var TextAreaControl = createControl(({ placeholder, ariaLabel }) => {
510
- const { value, setValue, disabled } = useBoundProp(stringPropTypeUtil3);
522
+ var TextAreaControl = createControl(({ placeholder: propPlaceholder, ariaLabel }) => {
523
+ const { value, setValue, disabled, placeholder: boundPlaceholder } = useBoundProp(stringPropTypeUtil3);
511
524
  const handleChange = (event) => {
512
525
  setValue(event.target.value);
513
526
  };
527
+ const placeholder = propPlaceholder ?? boundPlaceholder ?? void 0;
514
528
  return /* @__PURE__ */ React15.createElement(ControlActions, null, /* @__PURE__ */ React15.createElement(
515
529
  TextField2,
516
530
  {
@@ -3210,9 +3224,10 @@ import * as React60 from "react";
3210
3224
  import { urlPropTypeUtil } from "@elementor/editor-props";
3211
3225
  import { TextField as TextField6 } from "@elementor/ui";
3212
3226
  var UrlControl = createControl(
3213
- ({ placeholder, ariaLabel }) => {
3214
- const { value, setValue, disabled } = useBoundProp(urlPropTypeUtil);
3227
+ ({ placeholder: propPlaceholder, ariaLabel }) => {
3228
+ const { value, setValue, disabled, placeholder: boundPlaceholder } = useBoundProp(urlPropTypeUtil);
3215
3229
  const handleChange = (event) => setValue(event.target.value);
3230
+ const placeholder = propPlaceholder ?? boundPlaceholder ?? void 0;
3216
3231
  return /* @__PURE__ */ React60.createElement(ControlActions, null, /* @__PURE__ */ React60.createElement(
3217
3232
  TextField6,
3218
3233
  {
@@ -3306,7 +3321,12 @@ var RestrictedLinkInfotip = ({
3306
3321
  // src/controls/query-control.tsx
3307
3322
  import * as React63 from "react";
3308
3323
  import { useMemo as useMemo7, useState as useState9 } from "react";
3309
- import { numberPropTypeUtil as numberPropTypeUtil2, stringPropTypeUtil as stringPropTypeUtil7, urlPropTypeUtil as urlPropTypeUtil2 } from "@elementor/editor-props";
3324
+ import {
3325
+ numberPropTypeUtil as numberPropTypeUtil2,
3326
+ queryPropTypeUtil,
3327
+ stringPropTypeUtil as stringPropTypeUtil7,
3328
+ urlPropTypeUtil as urlPropTypeUtil2
3329
+ } from "@elementor/editor-props";
3310
3330
  import { httpService as httpService2 } from "@elementor/http-client";
3311
3331
  import { SearchIcon } from "@elementor/icons";
3312
3332
  import { debounce as debounce2 } from "@elementor/utils";
@@ -3445,45 +3465,41 @@ function factoryFilter(newValue, options, minInputLength) {
3445
3465
 
3446
3466
  // src/controls/query-control.tsx
3447
3467
  var QueryControl = createControl((props) => {
3448
- const { value, setValue } = useBoundProp();
3468
+ const { value: queryValue, setValue: setQueryValue } = useBoundProp(queryPropTypeUtil);
3469
+ const { value: urlValue, setValue: setUrlValue, placeholder: urlPlaceholder } = useBoundProp(urlPropTypeUtil2);
3449
3470
  const {
3450
3471
  allowCustomValues = true,
3451
3472
  queryOptions: { url, params = {} },
3452
- placeholder,
3473
+ placeholder = __22("Search", "elementor"),
3453
3474
  minInputLength = 2,
3454
3475
  onSetValue,
3455
3476
  ariaLabel
3456
3477
  } = props || {};
3457
- const normalizedPlaceholder = placeholder || __22("Search", "elementor");
3458
3478
  const [options, setOptions] = useState9(
3459
- generateFirstLoadedOption(value?.value)
3479
+ generateFirstLoadedOption(queryValue)
3460
3480
  );
3461
3481
  const onOptionChange = (newValue) => {
3462
3482
  if (newValue === null) {
3463
- setValue(null);
3483
+ setQueryValue(null);
3464
3484
  onSetValue?.(null);
3465
3485
  return;
3466
3486
  }
3467
- const valueToSave = {
3468
- $$type: "query",
3469
- value: {
3470
- id: numberPropTypeUtil2.create(newValue),
3471
- label: stringPropTypeUtil7.create(findMatchingOption(options, newValue)?.label || null)
3472
- }
3487
+ const newQueryValue = {
3488
+ id: numberPropTypeUtil2.create(newValue),
3489
+ label: stringPropTypeUtil7.create(findMatchingOption(options, newValue)?.label || null)
3473
3490
  };
3474
- setValue(valueToSave);
3475
- onSetValue?.(valueToSave);
3491
+ setQueryValue(newQueryValue);
3492
+ onSetValue?.(queryPropTypeUtil.create(newQueryValue));
3476
3493
  };
3477
3494
  const onTextChange = (newValue) => {
3478
- if (!newValue) {
3479
- setValue(null);
3495
+ const trimmedValue = newValue?.trim() || "";
3496
+ if (!trimmedValue) {
3497
+ setUrlValue(null);
3480
3498
  onSetValue?.(null);
3481
3499
  return;
3482
3500
  }
3483
- const newLinkValue = newValue?.trim() || "";
3484
- const valueToSave = newLinkValue ? urlPropTypeUtil2.create(newLinkValue) : null;
3485
- setValue(valueToSave);
3486
- onSetValue?.(valueToSave);
3501
+ setUrlValue(trimmedValue);
3502
+ onSetValue?.(urlPropTypeUtil2.create(trimmedValue));
3487
3503
  updateOptions(newValue);
3488
3504
  };
3489
3505
  const updateOptions = (newValue) => {
@@ -3502,14 +3518,15 @@ var QueryControl = createControl((props) => {
3502
3518
  ),
3503
3519
  [url]
3504
3520
  );
3521
+ const displayValue = queryValue?.id?.value ?? urlValue;
3505
3522
  return /* @__PURE__ */ React63.createElement(ControlActions, null, /* @__PURE__ */ React63.createElement(
3506
3523
  Autocomplete2,
3507
3524
  {
3508
3525
  options,
3509
3526
  allowCustomValues,
3510
- placeholder: normalizedPlaceholder,
3527
+ placeholder: urlPlaceholder ?? placeholder,
3511
3528
  startAdornment: /* @__PURE__ */ React63.createElement(SearchIcon, { fontSize: "tiny" }),
3512
- value: value?.value?.id?.value || value?.value,
3529
+ value: displayValue,
3513
3530
  onOptionChange,
3514
3531
  onTextChange,
3515
3532
  minInputLength,
@@ -3537,16 +3554,14 @@ function formatOptions(options) {
3537
3554
  (a, b) => a[compareKey] && b[compareKey] ? a[compareKey].localeCompare(b[compareKey]) : 0
3538
3555
  );
3539
3556
  }
3540
- function generateFirstLoadedOption(unionValue) {
3541
- const value = unionValue?.id?.value;
3542
- const label = unionValue?.label?.value;
3543
- const type = unionValue?.id?.$$type || "url";
3544
- return value && label && type === "number" ? [
3545
- {
3546
- id: value.toString(),
3547
- label
3548
- }
3549
- ] : [];
3557
+ function generateFirstLoadedOption(queryValue) {
3558
+ const id = queryValue?.id?.value;
3559
+ const label = queryValue?.label?.value;
3560
+ const option = [];
3561
+ if (id && label) {
3562
+ option.push({ id: id.toString(), label });
3563
+ }
3564
+ return option;
3550
3565
  }
3551
3566
 
3552
3567
  // src/controls/switch-control.tsx
@@ -3554,14 +3569,14 @@ import * as React64 from "react";
3554
3569
  import { booleanPropTypeUtil } from "@elementor/editor-props";
3555
3570
  import { Box as Box11, Switch } from "@elementor/ui";
3556
3571
  var SwitchControl = createControl(() => {
3557
- const { value, setValue, disabled } = useBoundProp(booleanPropTypeUtil);
3572
+ const { value, setValue, disabled, placeholder } = useBoundProp(booleanPropTypeUtil);
3558
3573
  const handleChange = (event) => {
3559
3574
  setValue(event.target.checked);
3560
3575
  };
3561
3576
  return /* @__PURE__ */ React64.createElement(Box11, { sx: { display: "flex", justifyContent: "flex-end" } }, /* @__PURE__ */ React64.createElement(
3562
3577
  Switch,
3563
3578
  {
3564
- checked: !!value,
3579
+ checked: !!(value || placeholder),
3565
3580
  onChange: handleChange,
3566
3581
  size: "small",
3567
3582
  disabled,
@@ -3576,8 +3591,9 @@ var SwitchControl = createControl(() => {
3576
3591
  var SIZE7 = "tiny";
3577
3592
  var LinkControl = createControl((props) => {
3578
3593
  const { value, path, setValue, ...propContext } = useBoundProp(linkPropTypeUtil);
3594
+ const linkPlaceholder = propContext.placeholder;
3579
3595
  const [linkSessionValue, setLinkSessionValue] = useSessionStorage(path.join("/"));
3580
- const [isActive, setIsActive] = useState10(!!value);
3596
+ const [isActive, setIsActive] = useState10(!!value || !!linkPlaceholder);
3581
3597
  const {
3582
3598
  allowCustomValues = true,
3583
3599
  queryOptions,
@@ -3588,18 +3604,18 @@ var LinkControl = createControl((props) => {
3588
3604
  ariaLabel
3589
3605
  } = props || {};
3590
3606
  const [linkInLinkRestriction, setLinkInLinkRestriction] = useState10(
3591
- getLinkInLinkRestriction(elementId, value)
3607
+ getLinkInLinkRestriction(elementId, value ?? linkPlaceholder)
3592
3608
  );
3593
3609
  const shouldDisableAddingLink = !isActive && linkInLinkRestriction.shouldRestrict;
3594
3610
  const debouncedCheckRestriction = useMemo8(
3595
3611
  () => debounce3(() => {
3596
- const newRestriction = getLinkInLinkRestriction(elementId, value);
3597
- if (newRestriction.shouldRestrict && isActive) {
3612
+ const newRestriction = getLinkInLinkRestriction(elementId, value ?? linkPlaceholder);
3613
+ if (newRestriction.shouldRestrict && isActive && !linkPlaceholder) {
3598
3614
  setIsActive(false);
3599
3615
  }
3600
3616
  setLinkInLinkRestriction(newRestriction);
3601
3617
  }, 300),
3602
- [elementId, isActive, value]
3618
+ [elementId, isActive, value, linkPlaceholder]
3603
3619
  );
3604
3620
  useEffect9(() => {
3605
3621
  debouncedCheckRestriction();
@@ -3616,7 +3632,7 @@ var LinkControl = createControl((props) => {
3616
3632
  };
3617
3633
  }, [elementId, debouncedCheckRestriction]);
3618
3634
  const onEnabledChange = () => {
3619
- setLinkInLinkRestriction(getLinkInLinkRestriction(elementId, value));
3635
+ setLinkInLinkRestriction(getLinkInLinkRestriction(elementId, value ?? linkPlaceholder));
3620
3636
  if (linkInLinkRestriction.shouldRestrict && !isActive) {
3621
3637
  return;
3622
3638
  }
@@ -3652,13 +3668,14 @@ var LinkControl = createControl((props) => {
3652
3668
  },
3653
3669
  /* @__PURE__ */ React65.createElement(ControlLabel, null, label),
3654
3670
  /* @__PURE__ */ React65.createElement(RestrictedLinkInfotip, { isVisible: !isActive, linkInLinkRestriction }, /* @__PURE__ */ React65.createElement(
3655
- ToggleIconControl,
3671
+ IconButton6,
3656
3672
  {
3657
- disabled: shouldDisableAddingLink,
3658
- active: isActive,
3659
- onIconClick: onEnabledChange,
3660
- label: __23("Toggle link", "elementor")
3661
- }
3673
+ size: SIZE7,
3674
+ onClick: onEnabledChange,
3675
+ "aria-label": __23("Toggle link", "elementor"),
3676
+ disabled: shouldDisableAddingLink
3677
+ },
3678
+ isActive ? /* @__PURE__ */ React65.createElement(MinusIcon, { fontSize: SIZE7 }) : /* @__PURE__ */ React65.createElement(PlusIcon2, { fontSize: SIZE7 })
3662
3679
  ))
3663
3680
  ), /* @__PURE__ */ React65.createElement(Collapse, { in: isActive, timeout: "auto", unmountOnExit: true }, /* @__PURE__ */ React65.createElement(Stack10, { gap: 1.5 }, /* @__PURE__ */ React65.createElement(PropKeyProvider, { bind: "destination" }, /* @__PURE__ */ React65.createElement(
3664
3681
  QueryControl,
@@ -3672,9 +3689,6 @@ var LinkControl = createControl((props) => {
3672
3689
  }
3673
3690
  )), /* @__PURE__ */ React65.createElement(PropKeyProvider, { bind: "isTargetBlank" }, /* @__PURE__ */ React65.createElement(Grid10, { container: true, alignItems: "center", flexWrap: "nowrap", justifyContent: "space-between" }, /* @__PURE__ */ React65.createElement(Grid10, { item: true }, /* @__PURE__ */ React65.createElement(ControlFormLabel, null, __23("Open in a new tab", "elementor"))), /* @__PURE__ */ React65.createElement(Grid10, { item: true, sx: { marginInlineEnd: -1 } }, /* @__PURE__ */ React65.createElement(SwitchControl, null))))))));
3674
3691
  });
3675
- var ToggleIconControl = ({ disabled, active, onIconClick, label }) => {
3676
- return /* @__PURE__ */ React65.createElement(IconButton6, { size: SIZE7, onClick: onIconClick, "aria-label": label, disabled }, active ? /* @__PURE__ */ React65.createElement(MinusIcon, { fontSize: SIZE7 }) : /* @__PURE__ */ React65.createElement(PlusIcon2, { fontSize: SIZE7 }));
3677
- };
3678
3692
 
3679
3693
  // src/controls/html-tag-control.tsx
3680
3694
  import * as React67 from "react";
@@ -6491,6 +6505,7 @@ var InlineEditor = React100.forwardRef((props, ref) => {
6491
6505
  const {
6492
6506
  value,
6493
6507
  setValue,
6508
+ placeholder = null,
6494
6509
  editorProps = {},
6495
6510
  elementClasses = "",
6496
6511
  autofocus = false,
@@ -6576,7 +6591,9 @@ var InlineEditor = React100.forwardRef((props, ref) => {
6576
6591
  },
6577
6592
  attributes: {
6578
6593
  ...editorProps.attributes ?? {},
6579
- role: "textbox"
6594
+ role: "textbox",
6595
+ ...placeholder ? { "data-placeholder": placeholder } : {},
6596
+ ...value === null || value === "" ? { class: "is-empty" } : {}
6580
6597
  }
6581
6598
  },
6582
6599
  onCreate: onEditorCreate ? ({ editor: mountedEditor }) => onEditorCreate(mountedEditor) : void 0,
@@ -6616,7 +6633,7 @@ var InlineEditingControl = createControl(
6616
6633
  attributes,
6617
6634
  props
6618
6635
  }) => {
6619
- const { value, setValue } = useBoundProp(htmlV3PropTypeUtil);
6636
+ const { value, setValue, placeholder } = useBoundProp(htmlV3PropTypeUtil);
6620
6637
  const content = stringPropTypeUtil16.extract(value?.content ?? null) ?? "";
6621
6638
  const debouncedParse = useMemo14(
6622
6639
  () => debounce4((html) => {
@@ -6668,6 +6685,13 @@ var InlineEditingControl = createControl(
6668
6685
  "& .elementor-inline-editor-reset": {
6669
6686
  margin: 0,
6670
6687
  padding: 0
6688
+ },
6689
+ "&.is-empty::before": {
6690
+ content: "attr(data-placeholder)",
6691
+ color: "text.tertiary",
6692
+ pointerEvents: "none",
6693
+ position: "absolute",
6694
+ opacity: 0.6
6671
6695
  }
6672
6696
  },
6673
6697
  ".strip-styles *": {
@@ -6678,7 +6702,14 @@ var InlineEditingControl = createControl(
6678
6702
  ...attributes,
6679
6703
  ...props
6680
6704
  },
6681
- /* @__PURE__ */ React101.createElement(InlineEditor, { value: content, setValue: handleChange })
6705
+ /* @__PURE__ */ React101.createElement(
6706
+ InlineEditor,
6707
+ {
6708
+ value: content,
6709
+ setValue: handleChange,
6710
+ placeholder: placeholder?.content?.value ?? null
6711
+ }
6712
+ )
6682
6713
  ));
6683
6714
  }
6684
6715
  );