@elementor/editor-controls 4.3.0-1008 → 4.3.0-1010

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.d.mts CHANGED
@@ -105,13 +105,18 @@ type SelectOption$1 = {
105
105
  value: StringPropValue['value'];
106
106
  disabled?: boolean;
107
107
  };
108
- type SelectControlProps = {
108
+ type SelectOptionGroup = {
109
+ label: string;
109
110
  options: SelectOption$1[];
111
+ };
112
+ type SelectControlProps = {
113
+ options?: SelectOption$1[];
114
+ groups?: SelectOptionGroup[];
110
115
  onChange?: (newValue: string | null, previousValue: string | null | undefined) => void;
111
116
  MenuProps?: SelectProps['MenuProps'];
112
117
  ariaLabel?: string;
113
118
  };
114
- declare const SelectControl: ControlComponent$1<({ options, onChange, MenuProps, ariaLabel }: SelectControlProps) => React$1.JSX.Element>;
119
+ declare const SelectControl: ControlComponent$1<({ options, groups, onChange, MenuProps, ariaLabel }: SelectControlProps) => React$1.JSX.Element>;
115
120
 
116
121
  declare const collectionMethods: {
117
122
  readonly 'off-canvas': () => SelectOption$1[];
package/dist/index.d.ts CHANGED
@@ -105,13 +105,18 @@ type SelectOption$1 = {
105
105
  value: StringPropValue['value'];
106
106
  disabled?: boolean;
107
107
  };
108
- type SelectControlProps = {
108
+ type SelectOptionGroup = {
109
+ label: string;
109
110
  options: SelectOption$1[];
111
+ };
112
+ type SelectControlProps = {
113
+ options?: SelectOption$1[];
114
+ groups?: SelectOptionGroup[];
110
115
  onChange?: (newValue: string | null, previousValue: string | null | undefined) => void;
111
116
  MenuProps?: SelectProps['MenuProps'];
112
117
  ariaLabel?: string;
113
118
  };
114
- declare const SelectControl: ControlComponent$1<({ options, onChange, MenuProps, ariaLabel }: SelectControlProps) => React$1.JSX.Element>;
119
+ declare const SelectControl: ControlComponent$1<({ options, groups, onChange, MenuProps, ariaLabel }: SelectControlProps) => React$1.JSX.Element>;
115
120
 
116
121
  declare const collectionMethods: {
117
122
  readonly 'off-canvas': () => SelectOption$1[];
package/dist/index.js CHANGED
@@ -584,14 +584,15 @@ var DEFAULT_MENU_PROPS = {
584
584
  }
585
585
  };
586
586
  var SelectControl = createControl(
587
- ({ options, onChange, MenuProps = DEFAULT_MENU_PROPS, ariaLabel }) => {
587
+ ({ options = [], groups = [], onChange, MenuProps = DEFAULT_MENU_PROPS, ariaLabel }) => {
588
588
  const { value, setValue, disabled, placeholder } = useBoundProp(import_editor_props2.stringPropTypeUtil);
589
589
  const handleChange = (event) => {
590
590
  const newValue = event.target.value || null;
591
591
  onChange?.(newValue, value);
592
592
  setValue(newValue);
593
593
  };
594
- const isDisabled = disabled || options.length === 0;
594
+ const flatOptions = flattenGroupedOptions(options, groups);
595
+ const isDisabled = disabled || flatOptions.length === 0;
595
596
  return /* @__PURE__ */ React12.createElement(ControlActions, null, /* @__PURE__ */ React12.createElement(
596
597
  import_ui5.Select,
597
598
  {
@@ -600,16 +601,41 @@ var SelectControl = createControl(
600
601
  size: "tiny",
601
602
  MenuProps,
602
603
  "aria-label": ariaLabel || placeholder,
603
- renderValue: (selectedValue) => getSelectRenderValue(options, placeholder, selectedValue),
604
+ renderValue: (selectedValue) => getSelectRenderValue(flatOptions, placeholder, selectedValue),
604
605
  value: value ?? "",
605
606
  onChange: handleChange,
606
607
  disabled: isDisabled,
607
608
  fullWidth: true
608
609
  },
609
- options.map(({ label, ...props }) => /* @__PURE__ */ React12.createElement(import_editor_ui2.MenuListItem, { key: props.value, ...props, value: props.value ?? "" }, label))
610
+ groups.length ? groups.flatMap((group) => renderGroup(group)) : options.map((option) => renderOption(option))
610
611
  ));
611
612
  }
612
613
  );
614
+ var GROUPED_OPTION_INDENT = 3.5;
615
+ function renderGroup(group) {
616
+ return [
617
+ /* @__PURE__ */ React12.createElement(import_ui5.MenuSubheader, { key: `group-${group.label}`, sx: { fontWeight: 400, color: "text.tertiary" } }, group.label),
618
+ ...group.options.map((option) => renderOption(option, true))
619
+ ];
620
+ }
621
+ function renderOption({ label, ...props }, isGrouped = false) {
622
+ return /* @__PURE__ */ React12.createElement(
623
+ import_editor_ui2.MenuListItem,
624
+ {
625
+ key: props.value,
626
+ ...props,
627
+ value: props.value ?? "",
628
+ sx: isGrouped ? { pl: GROUPED_OPTION_INDENT } : void 0
629
+ },
630
+ label
631
+ );
632
+ }
633
+ function flattenGroupedOptions(options, groups) {
634
+ if (!groups.length) {
635
+ return options;
636
+ }
637
+ return groups.flatMap((group) => group.options);
638
+ }
613
639
  function getSelectRenderValue(options, placeholder, selectedValue) {
614
640
  const optionWithValue = (v) => options.find(({ value }) => value === v);
615
641
  if (!isUnsetSelectValue(selectedValue)) {
@@ -8299,6 +8325,10 @@ var CHIP_TRIGGER_KEYS = /* @__PURE__ */ new Set([" ", ","]);
8299
8325
  function isValidEmail(email) {
8300
8326
  return import_schema.z.string().email().safeParse(email).success;
8301
8327
  }
8328
+ var FORM_FIELD_SHORTCODE_PATTERN = /^\[[^[\]]+]$/;
8329
+ function isFormFieldShortcode(value) {
8330
+ return FORM_FIELD_SHORTCODE_PATTERN.test(value);
8331
+ }
8302
8332
  var shouldShowMentionsInfo = () => {
8303
8333
  if (!(0, import_utils9.hasProInstalled)()) {
8304
8334
  return true;
@@ -8311,14 +8341,26 @@ var shouldShowMentionsInfo = () => {
8311
8341
  };
8312
8342
 
8313
8343
  // src/controls/email-form-action-control/email-chips-field.tsx
8314
- var EmailChipsControl = createControl(({ placeholder }) => {
8344
+ var isValidRecipient = (address) => isValidEmail(address) || isFormFieldShortcode(address);
8345
+ function resolveMention(raw, suggestions) {
8346
+ if (!raw.startsWith("@")) {
8347
+ return raw;
8348
+ }
8349
+ const match = suggestions.find((suggestion) => createMentionPattern(suggestion.value, "start").test(raw));
8350
+ return match ? `[${match.value}]` : raw;
8351
+ }
8352
+ var EmailChipsControl = createControl(({ placeholder, suggestions = [] }) => {
8315
8353
  const { value, setValue, disabled } = useBoundProp(import_editor_props65.stringArrayPropTypeUtil);
8316
8354
  const [inputValue, setInputValue] = (0, import_react69.useState)("");
8317
8355
  const items2 = value || [];
8318
8356
  const selectedValues = items2.map((item) => import_editor_props65.stringPropTypeUtil.extract(item)).filter((val) => val !== null);
8357
+ const suggestionOptions = (0, import_react69.useMemo)(
8358
+ () => suggestions.map((suggestion) => `[${suggestion.value}]`),
8359
+ [suggestions]
8360
+ );
8319
8361
  const tryAddChip = (raw) => {
8320
- const address = raw.trim();
8321
- if (!address || selectedValues.includes(address) || !isValidEmail(address)) {
8362
+ const address = resolveMention(raw.trim(), suggestions);
8363
+ if (!address || selectedValues.includes(address) || !isValidRecipient(address)) {
8322
8364
  return;
8323
8365
  }
8324
8366
  setValue([...items2, import_editor_props65.stringPropTypeUtil.create(address)]);
@@ -8327,8 +8369,8 @@ var EmailChipsControl = createControl(({ placeholder }) => {
8327
8369
  const handleChange = (_, newValue) => {
8328
8370
  const updated = [];
8329
8371
  for (const entry of newValue) {
8330
- const address = entry.trim();
8331
- if (!address || !isValidEmail(address)) {
8372
+ const address = resolveMention(entry.trim(), suggestions);
8373
+ if (!address || !isValidRecipient(address)) {
8332
8374
  continue;
8333
8375
  }
8334
8376
  updated.push(import_editor_props65.stringPropTypeUtil.create(address));
@@ -8363,7 +8405,12 @@ var EmailChipsControl = createControl(({ placeholder }) => {
8363
8405
  },
8364
8406
  value: selectedValues,
8365
8407
  onChange: handleChange,
8366
- options: [],
8408
+ options: suggestionOptions,
8409
+ filterOptions: (options, state) => {
8410
+ const query = state.inputValue.trim().replace(/^@/, "").toLowerCase();
8411
+ return query ? options.filter((option) => option.toLowerCase().includes(query)) : options;
8412
+ },
8413
+ filterSelectedOptions: true,
8367
8414
  onBlur: handleBlur,
8368
8415
  getOptionLabel: (option) => option,
8369
8416
  isOptionEqualToValue: (option, val) => option === val,
@@ -8372,7 +8419,7 @@ var EmailChipsControl = createControl(({ placeholder }) => {
8372
8419
  }
8373
8420
  ));
8374
8421
  });
8375
- var EmailChipsField = ({ fieldLabel, placeholder }) => /* @__PURE__ */ React116.createElement(import_ui100.Grid, { container: true, direction: "column", gap: 0.5 }, /* @__PURE__ */ React116.createElement(import_ui100.Grid, { item: true }, /* @__PURE__ */ React116.createElement(ControlFormLabel, null, fieldLabel)), /* @__PURE__ */ React116.createElement(import_ui100.Grid, { item: true }, /* @__PURE__ */ React116.createElement(EmailChipsControl, { placeholder })));
8422
+ var EmailChipsField = ({ fieldLabel, placeholder, suggestions }) => /* @__PURE__ */ React116.createElement(import_ui100.Grid, { container: true, direction: "column", gap: 0.5 }, /* @__PURE__ */ React116.createElement(import_ui100.Grid, { item: true }, /* @__PURE__ */ React116.createElement(ControlFormLabel, null, fieldLabel)), /* @__PURE__ */ React116.createElement(import_ui100.Grid, { item: true }, /* @__PURE__ */ React116.createElement(EmailChipsControl, { placeholder, suggestions })));
8376
8423
 
8377
8424
  // src/controls/email-form-action-control/email-field.tsx
8378
8425
  var React117 = __toESM(require("react"));
@@ -8380,7 +8427,17 @@ var import_ui101 = require("@elementor/ui");
8380
8427
  var EmailField = ({ bind, label, placeholder }) => /* @__PURE__ */ React117.createElement(PropKeyProvider, { bind }, /* @__PURE__ */ React117.createElement(import_ui101.Grid, { container: true, direction: "column", gap: 0.5 }, /* @__PURE__ */ React117.createElement(import_ui101.Grid, { item: true }, /* @__PURE__ */ React117.createElement(ControlFormLabel, null, label)), /* @__PURE__ */ React117.createElement(import_ui101.Grid, { item: true }, /* @__PURE__ */ React117.createElement(TextControl, { placeholder }))));
8381
8428
 
8382
8429
  // src/controls/email-form-action-control/fields.tsx
8383
- var SendToField = ({ placeholder }) => /* @__PURE__ */ React118.createElement(PropKeyProvider, { bind: "to" }, /* @__PURE__ */ React118.createElement(EmailChipsField, { fieldLabel: (0, import_i18n57.__)("Send to", "elementor"), placeholder }));
8430
+ var SendToField = ({ placeholder }) => {
8431
+ const suggestions = useFormFieldSuggestions({ inputType: "email" });
8432
+ return /* @__PURE__ */ React118.createElement(PropKeyProvider, { bind: "to" }, /* @__PURE__ */ React118.createElement(import_ui102.Stack, { gap: 0.5 }, /* @__PURE__ */ React118.createElement(
8433
+ EmailChipsField,
8434
+ {
8435
+ fieldLabel: (0, import_i18n57.__)("Send to", "elementor"),
8436
+ placeholder,
8437
+ suggestions
8438
+ }
8439
+ ), shouldShowMentionsInfo() && /* @__PURE__ */ React118.createElement(import_editor_ui15.InfoAlert, null, (0, import_i18n57.__)("Type @ or an email field name to insert its submitted value.", "elementor"))));
8440
+ };
8384
8441
  var SubjectField = () => /* @__PURE__ */ React118.createElement(
8385
8442
  EmailField,
8386
8443
  {
@@ -8424,8 +8481,14 @@ var ReplyToField = () => {
8424
8481
  }
8425
8482
  ))));
8426
8483
  };
8427
- var CcField = () => /* @__PURE__ */ React118.createElement(PropKeyProvider, { bind: "cc" }, /* @__PURE__ */ React118.createElement(EmailChipsField, { fieldLabel: (0, import_i18n57.__)("Cc", "elementor") }));
8428
- var BccField = () => /* @__PURE__ */ React118.createElement(PropKeyProvider, { bind: "bcc" }, /* @__PURE__ */ React118.createElement(EmailChipsField, { fieldLabel: (0, import_i18n57.__)("Bcc", "elementor") }));
8484
+ var CcField = () => {
8485
+ const suggestions = useFormFieldSuggestions({ inputType: "email" });
8486
+ return /* @__PURE__ */ React118.createElement(PropKeyProvider, { bind: "cc" }, /* @__PURE__ */ React118.createElement(EmailChipsField, { fieldLabel: (0, import_i18n57.__)("Cc", "elementor"), suggestions }));
8487
+ };
8488
+ var BccField = () => {
8489
+ const suggestions = useFormFieldSuggestions({ inputType: "email" });
8490
+ return /* @__PURE__ */ React118.createElement(PropKeyProvider, { bind: "bcc" }, /* @__PURE__ */ React118.createElement(EmailChipsField, { fieldLabel: (0, import_i18n57.__)("Bcc", "elementor"), suggestions }));
8491
+ };
8429
8492
  var MetaDataField = () => /* @__PURE__ */ React118.createElement(PropKeyProvider, { bind: "meta-data" }, /* @__PURE__ */ React118.createElement(import_ui102.Stack, { gap: 0.5 }, /* @__PURE__ */ React118.createElement(ControlFormLabel, null, (0, import_i18n57.__)("Metadata", "elementor")), /* @__PURE__ */ React118.createElement(
8430
8493
  ChipsControl,
8431
8494
  {