@elementor/editor-controls 4.1.0-797 → 4.1.0-799

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
@@ -351,7 +351,7 @@ var formatResponse = (response) => {
351
351
 
352
352
  // src/controls/image-media-control.tsx
353
353
  import * as React11 from "react";
354
- import { imageSrcPropTypeUtil } from "@elementor/editor-props";
354
+ import { imageSrcPropTypeUtil, urlPropTypeUtil } from "@elementor/editor-props";
355
355
  import { UploadIcon } from "@elementor/icons";
356
356
  import { Button, Card, CardMedia, CardOverlay, CircularProgress, Stack as Stack2 } from "@elementor/ui";
357
357
  import { useWpMediaAttachment, useWpMediaFrame } from "@elementor/wp-media";
@@ -396,6 +396,7 @@ var ImageMediaControl = createControl(({ mediaTypes = ["image"] }) => {
396
396
  mediaTypes,
397
397
  multiple: false,
398
398
  selected: id?.value || null,
399
+ allowUrlImport: true,
399
400
  onSelect: (selectedAttachment) => {
400
401
  setValue({
401
402
  id: {
@@ -404,6 +405,12 @@ var ImageMediaControl = createControl(({ mediaTypes = ["image"] }) => {
404
405
  },
405
406
  url: null
406
407
  });
408
+ },
409
+ onSelectUrl: (selectedUrl) => {
410
+ setValue({
411
+ id: null,
412
+ url: urlPropTypeUtil.create(selectedUrl)
413
+ });
407
414
  }
408
415
  });
409
416
  return /* @__PURE__ */ React11.createElement(ControlActions, null, /* @__PURE__ */ React11.createElement(Card, { variant: "outlined" }, /* @__PURE__ */ React11.createElement(CardMedia, { image: src, sx: { height: propType.meta.isDynamic ? 134 : 150 } }, isFetching ? /* @__PURE__ */ React11.createElement(Stack2, { justifyContent: "center", alignItems: "center", width: "100%", height: "100%" }, /* @__PURE__ */ React11.createElement(CircularProgress, null)) : /* @__PURE__ */ React11.createElement(React11.Fragment, null)), /* @__PURE__ */ React11.createElement(CardOverlay, null, /* @__PURE__ */ React11.createElement(Stack2, { gap: 1 }, /* @__PURE__ */ React11.createElement(
@@ -425,7 +432,7 @@ var ImageMediaControl = createControl(({ mediaTypes = ["image"] }) => {
425
432
  onClick: () => open({ mode: "upload" })
426
433
  },
427
434
  __("Upload", "elementor")
428
- )))));
435
+ ), /* @__PURE__ */ React11.createElement(Button, { size: "tiny", variant: "text", color: "inherit", onClick: () => open({ mode: "url" }) }, __("Insert from URL", "elementor"))))));
429
436
  });
430
437
 
431
438
  // src/controls/select-control.tsx
@@ -633,25 +640,30 @@ var MentionWrapper = styled("div")(({ theme }) => ({
633
640
  "&.p-highlight": {
634
641
  backgroundColor: theme.palette.action.selected
635
642
  }
643
+ },
644
+ '&[data-single-line="true"] textarea': {
645
+ resize: "none"
636
646
  }
637
647
  }));
648
+ function createMentionPattern(value, triggerPosition) {
649
+ const escaped = value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
650
+ const prefix = "start" === triggerPosition ? "^" : "";
651
+ return new RegExp(`${prefix}@${escaped}(?=\\s|$|[^a-zA-Z0-9_-])`, "g");
652
+ }
638
653
  var MentionTextAreaControl = createControl(
639
- ({ placeholder, ariaLabel, suggestions: allSuggestions }) => {
654
+ ({ placeholder, ariaLabel, suggestions: allSuggestions, rows = 5, triggerPosition = "auto" }) => {
640
655
  const { value, setValue, disabled } = useBoundProp(stringPropTypeUtil4);
641
656
  const [filteredSuggestions, setFilteredSuggestions] = useState2([]);
642
657
  const transformMentionsToShortcodes = useCallback(
643
658
  (text) => {
644
659
  let result = text;
645
660
  for (const suggestion of allSuggestions) {
646
- const mentionPattern = new RegExp(
647
- `@${suggestion.value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}(?=\\s|$|[^a-zA-Z0-9_-])`,
648
- "g"
649
- );
650
- result = result.replace(mentionPattern, `[${suggestion.value}]`);
661
+ const pattern = createMentionPattern(suggestion.value, triggerPosition);
662
+ result = result.replace(pattern, `[${suggestion.value}]`);
651
663
  }
652
664
  return result;
653
665
  },
654
- [allSuggestions]
666
+ [allSuggestions, triggerPosition]
655
667
  );
656
668
  const handleChange = useCallback(
657
669
  (e) => {
@@ -663,15 +675,23 @@ var MentionTextAreaControl = createControl(
663
675
  );
664
676
  const handleSearch = useCallback(
665
677
  (event) => {
678
+ if ("start" === triggerPosition) {
679
+ const target = event.originalEvent.target;
680
+ const triggerIndex = target.selectionStart - event.query.length - event.trigger.length;
681
+ if (triggerIndex !== 0) {
682
+ setFilteredSuggestions([]);
683
+ return;
684
+ }
685
+ }
666
686
  const query = event.query.toLowerCase();
667
687
  const filtered = allSuggestions.filter(
668
688
  (item) => item.label.toLowerCase().includes(query) || item.value.toLowerCase().includes(query)
669
689
  );
670
690
  setFilteredSuggestions(filtered);
671
691
  },
672
- [allSuggestions]
692
+ [allSuggestions, triggerPosition]
673
693
  );
674
- return /* @__PURE__ */ React16.createElement(ControlActions, null, /* @__PURE__ */ React16.createElement(MentionWrapper, null, /* @__PURE__ */ React16.createElement(
694
+ return /* @__PURE__ */ React16.createElement(ControlActions, null, /* @__PURE__ */ React16.createElement(MentionWrapper, { "data-single-line": rows === 1 ? "true" : void 0 }, /* @__PURE__ */ React16.createElement(
675
695
  Mention,
676
696
  {
677
697
  value: value ?? "",
@@ -680,7 +700,7 @@ var MentionTextAreaControl = createControl(
680
700
  onSearch: handleSearch,
681
701
  field: "value",
682
702
  trigger: "@",
683
- rows: 5,
703
+ rows,
684
704
  disabled,
685
705
  placeholder,
686
706
  itemTemplate: SuggestionItem,
@@ -4051,11 +4071,11 @@ var FontFamilyControl = createControl(
4051
4071
 
4052
4072
  // src/controls/url-control.tsx
4053
4073
  import * as React67 from "react";
4054
- import { urlPropTypeUtil } from "@elementor/editor-props";
4074
+ import { urlPropTypeUtil as urlPropTypeUtil2 } from "@elementor/editor-props";
4055
4075
  import { TextField as TextField7 } from "@elementor/ui";
4056
4076
  var UrlControl = createControl(
4057
4077
  ({ placeholder: propPlaceholder, ariaLabel }) => {
4058
- const { value, setValue, disabled, placeholder: boundPlaceholder } = useBoundProp(urlPropTypeUtil);
4078
+ const { value, setValue, disabled, placeholder: boundPlaceholder } = useBoundProp(urlPropTypeUtil2);
4059
4079
  const handleChange = (event) => setValue(event.target.value);
4060
4080
  const placeholder = propPlaceholder ?? boundPlaceholder ?? void 0;
4061
4081
  return /* @__PURE__ */ React67.createElement(ControlActions, null, /* @__PURE__ */ React67.createElement(
@@ -4156,7 +4176,7 @@ import {
4156
4176
  numberPropTypeUtil as numberPropTypeUtil2,
4157
4177
  queryPropTypeUtil,
4158
4178
  stringPropTypeUtil as stringPropTypeUtil8,
4159
- urlPropTypeUtil as urlPropTypeUtil2
4179
+ urlPropTypeUtil as urlPropTypeUtil3
4160
4180
  } from "@elementor/editor-props";
4161
4181
  import { httpService as httpService2 } from "@elementor/http-client";
4162
4182
  import { SearchIcon } from "@elementor/icons";
@@ -4297,7 +4317,7 @@ function factoryFilter(newValue, options, minInputLength) {
4297
4317
  // src/controls/query-control.tsx
4298
4318
  var QueryControl = createControl((props) => {
4299
4319
  const { value: queryValue, setValue: setQueryValue } = useBoundProp(queryPropTypeUtil);
4300
- const { value: urlValue, setValue: setUrlValue, placeholder: urlPlaceholder } = useBoundProp(urlPropTypeUtil2);
4320
+ const { value: urlValue, setValue: setUrlValue, placeholder: urlPlaceholder } = useBoundProp(urlPropTypeUtil3);
4301
4321
  const {
4302
4322
  allowCustomValues = true,
4303
4323
  queryOptions: { url, params = {} },
@@ -4330,7 +4350,7 @@ var QueryControl = createControl((props) => {
4330
4350
  return;
4331
4351
  }
4332
4352
  setUrlValue(trimmedValue);
4333
- onSetValue?.(urlPropTypeUtil2.create(trimmedValue));
4353
+ onSetValue?.(urlPropTypeUtil3.create(trimmedValue));
4334
4354
  updateOptions(newValue);
4335
4355
  };
4336
4356
  const updateOptions = (newValue) => {
@@ -4875,7 +4895,7 @@ var AspectRatioControl = createControl(({ label }) => {
4875
4895
  import * as React78 from "react";
4876
4896
  import { useState as useState16 } from "react";
4877
4897
  import { useCurrentUserCapabilities } from "@elementor/editor-current-user";
4878
- import { svgSrcPropTypeUtil, urlPropTypeUtil as urlPropTypeUtil3 } from "@elementor/editor-props";
4898
+ import { svgSrcPropTypeUtil, urlPropTypeUtil as urlPropTypeUtil4 } from "@elementor/editor-props";
4879
4899
  import { UploadIcon as UploadIcon2 } from "@elementor/icons";
4880
4900
  import { Button as Button5, Card as Card2, CardMedia as CardMedia2, CardOverlay as CardOverlay2, CircularProgress as CircularProgress3, Stack as Stack13, styled as styled9, ThemeProvider } from "@elementor/ui";
4881
4901
  import { useWpMediaAttachment as useWpMediaAttachment2, useWpMediaFrame as useWpMediaFrame2 } from "@elementor/wp-media";
@@ -4985,7 +5005,7 @@ var SvgMediaControl = createControl(() => {
4985
5005
  $$type: "image-attachment-id",
4986
5006
  value: selectedAttachment.id
4987
5007
  },
4988
- url: urlPropTypeUtil3.create(selectedAttachment.url)
5008
+ url: urlPropTypeUtil4.create(selectedAttachment.url)
4989
5009
  });
4990
5010
  }
4991
5011
  });
@@ -7592,7 +7612,7 @@ import { getContainer, getSelectedElements as getSelectedElements3 } from "@elem
7592
7612
  import { isTransformable as isTransformable3 } from "@elementor/editor-props";
7593
7613
  import { __privateUseListenTo as useListenTo, commandEndEvent, v1ReadyEvent } from "@elementor/editor-v1-adapters";
7594
7614
  var FORM_FIELD_WIDGET_TYPES = ["e-form-input", "e-form-textarea", "e-form-checkbox"];
7595
- function useFormFieldSuggestions() {
7615
+ function useFormFieldSuggestions(options) {
7596
7616
  return useListenTo(
7597
7617
  [
7598
7618
  v1ReadyEvent(),
@@ -7616,6 +7636,13 @@ function useFormFieldSuggestions() {
7616
7636
  if (!widgetType || !FORM_FIELD_WIDGET_TYPES.includes(widgetType)) {
7617
7637
  return;
7618
7638
  }
7639
+ if (options?.inputType) {
7640
+ const typeProp = child.settings.get("type");
7641
+ const typeValue = isTransformable3(typeProp) ? typeProp.value : typeProp;
7642
+ if (typeValue !== options.inputType) {
7643
+ return;
7644
+ }
7645
+ }
7619
7646
  const cssIdProp = child.settings.get("_cssid");
7620
7647
  const fieldId = isTransformable3(cssIdProp) ? cssIdProp.value : cssIdProp;
7621
7648
  if (fieldId && typeof fieldId === "string") {
@@ -7673,7 +7700,18 @@ var FromNameField = () => /* @__PURE__ */ React109.createElement(
7673
7700
  placeholder: __53("What name should appear as the sender?", "elementor")
7674
7701
  }
7675
7702
  );
7676
- var ReplyToField = () => /* @__PURE__ */ React109.createElement(EmailField, { bind: "reply-to", label: __53("Reply-to", "elementor") });
7703
+ var ReplyToField = () => {
7704
+ const emailSuggestions = useFormFieldSuggestions({ inputType: "email" });
7705
+ return /* @__PURE__ */ React109.createElement(PropKeyProvider, { bind: "reply-to" }, /* @__PURE__ */ React109.createElement(Grid29, { container: true, direction: "column", gap: 0.5 }, /* @__PURE__ */ React109.createElement(Grid29, { item: true }, /* @__PURE__ */ React109.createElement(ControlFormLabel, null, __53("Reply-to", "elementor"))), /* @__PURE__ */ React109.createElement(Grid29, { item: true }, /* @__PURE__ */ React109.createElement(
7706
+ MentionTextAreaControl,
7707
+ {
7708
+ suggestions: emailSuggestions,
7709
+ rows: 1,
7710
+ triggerPosition: "start",
7711
+ placeholder: __53("You can type @ to insert an email field", "elementor")
7712
+ }
7713
+ ))));
7714
+ };
7677
7715
  var CcField = () => /* @__PURE__ */ React109.createElement(EmailField, { bind: "cc", label: __53("Cc", "elementor") });
7678
7716
  var BccField = () => /* @__PURE__ */ React109.createElement(EmailField, { bind: "bcc", label: __53("Bcc", "elementor") });
7679
7717
  var MetaDataField = () => /* @__PURE__ */ React109.createElement(PropKeyProvider, { bind: "meta-data" }, /* @__PURE__ */ React109.createElement(Stack17, { gap: 0.5 }, /* @__PURE__ */ React109.createElement(ControlFormLabel, null, __53("Metadata", "elementor")), /* @__PURE__ */ React109.createElement(