@elementor/editor-ui 4.0.0-551 → 4.0.0-564

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
@@ -1,7 +1,7 @@
1
1
  import * as _emotion_styled from '@emotion/styled';
2
2
  import * as _mui_system from '@mui/system';
3
3
  import * as React$1 from 'react';
4
- import { ReactNode, PropsWithChildren, ReactElement, ComponentProps, ElementType, ComponentType, RefObject } from 'react';
4
+ import { ReactNode, PropsWithChildren, ReactElement, MouseEvent as MouseEvent$1, ComponentProps, ElementType, ComponentType, RefObject } from 'react';
5
5
  import * as _mui_material from '@mui/material';
6
6
  import { MenuItemProps, MenuItemTextProps, TypographyProps, AlertProps, InfotipProps, BoxProps, ButtonProps, MenuList, DialogProps, DialogContentTextProps } from '@elementor/ui';
7
7
 
@@ -88,8 +88,9 @@ declare const SearchField: ({ value, onSearch, placeholder, id, sx }: Props$1) =
88
88
 
89
89
  type Props = PropsWithChildren<{
90
90
  onSubmit?: () => void;
91
+ 'data-testid'?: string;
91
92
  }>;
92
- declare const Form: ({ children, onSubmit }: Props) => React$1.JSX.Element;
93
+ declare const Form: ({ children, onSubmit, "data-testid": dataTestId }: Props) => React$1.JSX.Element;
93
94
 
94
95
  type CtaButtonProps = {
95
96
  href: string;
@@ -114,7 +115,7 @@ type PromotionPopoverCardProps = {
114
115
  content: string;
115
116
  ctaUrl: string;
116
117
  ctaText?: string;
117
- onClose: () => void;
118
+ onClose: (e: MouseEvent$1) => void;
118
119
  };
119
120
  type PromotionPopoverProps = React$1.PropsWithChildren<PromotionPopoverCardProps & {
120
121
  open: boolean;
@@ -266,4 +267,6 @@ declare const useEditable: ({ value, onSubmit, validation, onClick, onError }: U
266
267
 
267
268
  declare const useTextFieldAutoSelect: () => React$1.RefObject<HTMLInputElement>;
268
269
 
269
- export { CollapseIcon, ConfirmationDialog, CtaButton, EditableField, EllipsisWithTooltip, FloatingActionsBar, Form, GlobalDialog, ITEM_HEIGHT, InfoAlert, InfoTipCard, IntroductionModal, MenuItemInfotip, MenuListItem, PopoverAction, type PopoverActionProps, PopoverBody, PopoverHeader, PopoverMenuList, type PopoverMenuListProps, PromotionAlert, PromotionChip, PromotionInfotip, PromotionPopover, SaveChangesDialog, SearchField, SectionPopoverBody, SectionRefContext, StyledMenuList, ThemeProvider, type VirtualizedItem, WarningInfotip, closeDialog, openDialog, useDialog, useEditable, useFloatingActionsBar, useSectionWidth, useTextFieldAutoSelect };
270
+ declare const useCanvasClickHandler: (isActive: boolean, onClickAway: (e: MouseEvent) => void) => void;
271
+
272
+ export { CollapseIcon, ConfirmationDialog, CtaButton, EditableField, EllipsisWithTooltip, FloatingActionsBar, Form, GlobalDialog, ITEM_HEIGHT, InfoAlert, InfoTipCard, IntroductionModal, MenuItemInfotip, MenuListItem, PopoverAction, type PopoverActionProps, PopoverBody, PopoverHeader, PopoverMenuList, type PopoverMenuListProps, PromotionAlert, PromotionChip, PromotionInfotip, PromotionPopover, SaveChangesDialog, SearchField, SectionPopoverBody, SectionRefContext, StyledMenuList, ThemeProvider, type VirtualizedItem, WarningInfotip, closeDialog, openDialog, useCanvasClickHandler, useDialog, useEditable, useFloatingActionsBar, useSectionWidth, useTextFieldAutoSelect };
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as _emotion_styled from '@emotion/styled';
2
2
  import * as _mui_system from '@mui/system';
3
3
  import * as React$1 from 'react';
4
- import { ReactNode, PropsWithChildren, ReactElement, ComponentProps, ElementType, ComponentType, RefObject } from 'react';
4
+ import { ReactNode, PropsWithChildren, ReactElement, MouseEvent as MouseEvent$1, ComponentProps, ElementType, ComponentType, RefObject } from 'react';
5
5
  import * as _mui_material from '@mui/material';
6
6
  import { MenuItemProps, MenuItemTextProps, TypographyProps, AlertProps, InfotipProps, BoxProps, ButtonProps, MenuList, DialogProps, DialogContentTextProps } from '@elementor/ui';
7
7
 
@@ -88,8 +88,9 @@ declare const SearchField: ({ value, onSearch, placeholder, id, sx }: Props$1) =
88
88
 
89
89
  type Props = PropsWithChildren<{
90
90
  onSubmit?: () => void;
91
+ 'data-testid'?: string;
91
92
  }>;
92
- declare const Form: ({ children, onSubmit }: Props) => React$1.JSX.Element;
93
+ declare const Form: ({ children, onSubmit, "data-testid": dataTestId }: Props) => React$1.JSX.Element;
93
94
 
94
95
  type CtaButtonProps = {
95
96
  href: string;
@@ -114,7 +115,7 @@ type PromotionPopoverCardProps = {
114
115
  content: string;
115
116
  ctaUrl: string;
116
117
  ctaText?: string;
117
- onClose: () => void;
118
+ onClose: (e: MouseEvent$1) => void;
118
119
  };
119
120
  type PromotionPopoverProps = React$1.PropsWithChildren<PromotionPopoverCardProps & {
120
121
  open: boolean;
@@ -266,4 +267,6 @@ declare const useEditable: ({ value, onSubmit, validation, onClick, onError }: U
266
267
 
267
268
  declare const useTextFieldAutoSelect: () => React$1.RefObject<HTMLInputElement>;
268
269
 
269
- export { CollapseIcon, ConfirmationDialog, CtaButton, EditableField, EllipsisWithTooltip, FloatingActionsBar, Form, GlobalDialog, ITEM_HEIGHT, InfoAlert, InfoTipCard, IntroductionModal, MenuItemInfotip, MenuListItem, PopoverAction, type PopoverActionProps, PopoverBody, PopoverHeader, PopoverMenuList, type PopoverMenuListProps, PromotionAlert, PromotionChip, PromotionInfotip, PromotionPopover, SaveChangesDialog, SearchField, SectionPopoverBody, SectionRefContext, StyledMenuList, ThemeProvider, type VirtualizedItem, WarningInfotip, closeDialog, openDialog, useDialog, useEditable, useFloatingActionsBar, useSectionWidth, useTextFieldAutoSelect };
270
+ declare const useCanvasClickHandler: (isActive: boolean, onClickAway: (e: MouseEvent) => void) => void;
271
+
272
+ export { CollapseIcon, ConfirmationDialog, CtaButton, EditableField, EllipsisWithTooltip, FloatingActionsBar, Form, GlobalDialog, ITEM_HEIGHT, InfoAlert, InfoTipCard, IntroductionModal, MenuItemInfotip, MenuListItem, PopoverAction, type PopoverActionProps, PopoverBody, PopoverHeader, PopoverMenuList, type PopoverMenuListProps, PromotionAlert, PromotionChip, PromotionInfotip, PromotionPopover, SaveChangesDialog, SearchField, SectionPopoverBody, SectionRefContext, StyledMenuList, ThemeProvider, type VirtualizedItem, WarningInfotip, closeDialog, openDialog, useCanvasClickHandler, useDialog, useEditable, useFloatingActionsBar, useSectionWidth, useTextFieldAutoSelect };
package/dist/index.js CHANGED
@@ -61,6 +61,7 @@ __export(index_exports, {
61
61
  WarningInfotip: () => WarningInfotip,
62
62
  closeDialog: () => closeDialog,
63
63
  openDialog: () => openDialog,
64
+ useCanvasClickHandler: () => useCanvasClickHandler,
64
65
  useDialog: () => useDialog,
65
66
  useEditable: () => useEditable,
66
67
  useFloatingActionsBar: () => useFloatingActionsBar,
@@ -417,7 +418,7 @@ var SearchField = ({ value, onSearch, placeholder, id, sx }) => {
417
418
  // src/components/form.tsx
418
419
  var React11 = __toESM(require("react"));
419
420
  var import_react9 = require("react");
420
- var Form = ({ children, onSubmit }) => {
421
+ var Form = ({ children, onSubmit, "data-testid": dataTestId }) => {
421
422
  const formRef = (0, import_react9.useRef)(null);
422
423
  const handleSubmit = (e) => {
423
424
  e.preventDefault();
@@ -432,7 +433,16 @@ var Form = ({ children, onSubmit }) => {
432
433
  };
433
434
  return (
434
435
  // eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions
435
- /* @__PURE__ */ React11.createElement("form", { onSubmit: handleSubmit, ref: formRef, onKeyDown: handleKeyDown }, children)
436
+ /* @__PURE__ */ React11.createElement(
437
+ "form",
438
+ {
439
+ onSubmit: handleSubmit,
440
+ ref: formRef,
441
+ onKeyDown: handleKeyDown,
442
+ ...dataTestId ? { "data-testid": dataTestId } : {}
443
+ },
444
+ children
445
+ )
436
446
  );
437
447
  };
438
448
 
@@ -454,20 +464,76 @@ var CtaButton = ({ href, children, showIcon = true, ...props }) => /* @__PURE__
454
464
  children ?? (0, import_i18n3.__)("Upgrade Now", "elementor")
455
465
  );
456
466
 
457
- // src/components/promotion-infotip.tsx
467
+ // src/components/promotions/promotion-infotip.tsx
458
468
  var React13 = __toESM(require("react"));
459
- var import_react10 = require("react");
460
- var import_editor_v1_adapters2 = require("@elementor/editor-v1-adapters");
461
469
  var import_ui13 = require("@elementor/ui");
462
- var PromotionInfotip = ({ children, open, onClose, ...cardProps }) => {
470
+
471
+ // src/hooks/use-scroll-to-selected.ts
472
+ var import_react10 = require("react");
473
+ var useScrollToSelected = ({
474
+ selectedValue,
475
+ items,
476
+ virtualizer
477
+ }) => {
463
478
  (0, import_react10.useEffect)(() => {
464
- const canvasDocument = open ? (0, import_editor_v1_adapters2.getCanvasIframeDocument)() : null;
479
+ if (!selectedValue || items.length === 0) {
480
+ return;
481
+ }
482
+ const selectedIndex = items.findIndex((item) => item.value === selectedValue);
483
+ if (selectedIndex !== -1) {
484
+ virtualizer.scrollToIndex(selectedIndex, { align: "center" });
485
+ }
486
+ }, [selectedValue, items, virtualizer]);
487
+ };
488
+
489
+ // src/hooks/use-scroll-top.ts
490
+ var import_react11 = require("react");
491
+ var useScrollTop = ({ containerRef }) => {
492
+ const [scrollTop, setScrollTop] = (0, import_react11.useState)(0);
493
+ (0, import_react11.useEffect)(() => {
494
+ const container = containerRef.current;
495
+ if (!container) {
496
+ return;
497
+ }
498
+ const handleScroll = () => {
499
+ setScrollTop(container.scrollTop);
500
+ };
501
+ container.addEventListener("scroll", handleScroll);
502
+ return () => container.removeEventListener("scroll", handleScroll);
503
+ }, [containerRef]);
504
+ return scrollTop;
505
+ };
506
+
507
+ // src/hooks/use-text-field-auto-select.ts
508
+ var import_react12 = require("react");
509
+ var useTextFieldAutoSelect = () => {
510
+ const inputRef = (0, import_react12.useRef)(null);
511
+ (0, import_react12.useEffect)(() => {
512
+ if (inputRef.current) {
513
+ inputRef.current.focus();
514
+ inputRef.current.select();
515
+ }
516
+ }, []);
517
+ return inputRef;
518
+ };
519
+
520
+ // src/hooks/use-canvas-click-handler.tsx
521
+ var import_react13 = require("react");
522
+ var import_editor_v1_adapters2 = require("@elementor/editor-v1-adapters");
523
+ var useCanvasClickHandler = (isActive, onClickAway) => {
524
+ (0, import_react13.useEffect)(() => {
525
+ const canvasDocument = isActive ? (0, import_editor_v1_adapters2.getCanvasIframeDocument)() : null;
465
526
  if (!canvasDocument) {
466
527
  return;
467
528
  }
468
- canvasDocument.addEventListener("mousedown", onClose);
469
- return () => canvasDocument.removeEventListener("mousedown", onClose);
470
- }, [open, onClose]);
529
+ canvasDocument.addEventListener("mousedown", onClickAway);
530
+ return () => canvasDocument.removeEventListener("mousedown", onClickAway);
531
+ }, [isActive, onClickAway]);
532
+ };
533
+
534
+ // src/components/promotions/promotion-infotip.tsx
535
+ var PromotionInfotip = ({ children, open, onClose, ...cardProps }) => {
536
+ useCanvasClickHandler(!!open, onClose);
471
537
  return /* @__PURE__ */ React13.createElement(import_ui13.Infotip, { placement: "right", content: /* @__PURE__ */ React13.createElement(InfotipCard, { onClose, ...cardProps }), open }, children);
472
538
  };
473
539
  function InfotipCard({ title, content, assetUrl, ctaUrl, onClose }) {
@@ -489,7 +555,7 @@ function InfotipCard({ title, content, assetUrl, ctaUrl, onClose }) {
489
555
  );
490
556
  }
491
557
 
492
- // src/components/promotion-popover.tsx
558
+ // src/components/promotions/promotion-popover.tsx
493
559
  var React14 = __toESM(require("react"));
494
560
  var import_icons5 = require("@elementor/icons");
495
561
  var import_ui14 = require("@elementor/ui");
@@ -560,7 +626,7 @@ function PopoverAlert({ title, content, ctaUrl, ctaText, onClose }) {
560
626
  );
561
627
  }
562
628
 
563
- // src/components/promotion-chip.tsx
629
+ // src/components/promotions/promotion-chip.tsx
564
630
  var React15 = __toESM(require("react"));
565
631
  var import_icons6 = require("@elementor/icons");
566
632
  var import_ui15 = require("@elementor/ui");
@@ -586,7 +652,7 @@ var PromotionChip = React15.forwardRef(({ ...props }, ref) => {
586
652
  );
587
653
  });
588
654
 
589
- // src/components/promotion-alert.tsx
655
+ // src/components/promotions/promotion-alert.tsx
590
656
  var React16 = __toESM(require("react"));
591
657
  var import_icons7 = require("@elementor/icons");
592
658
  var import_ui16 = require("@elementor/ui");
@@ -620,7 +686,7 @@ var PromotionAlert = ({ message, upgradeUrl }) => /* @__PURE__ */ React16.create
620
686
 
621
687
  // src/components/floating-bar.tsx
622
688
  var React17 = __toESM(require("react"));
623
- var import_react11 = require("react");
689
+ var import_react14 = require("react");
624
690
  var import_ui17 = require("@elementor/ui");
625
691
  var FloatingBarContainer = (0, import_ui17.styled)("span")`
626
692
  display: contents;
@@ -633,13 +699,13 @@ var FloatingBarContainer = (0, import_ui17.styled)("span")`
633
699
  z-index: 1000;
634
700
  }
635
701
  `;
636
- var FloatingActionsContext = (0, import_react11.createContext)(null);
702
+ var FloatingActionsContext = (0, import_react14.createContext)(null);
637
703
  function FloatingActionsBar({ actions, children }) {
638
- const [open, setOpen] = (0, import_react11.useState)(false);
704
+ const [open, setOpen] = (0, import_react14.useState)(false);
639
705
  return /* @__PURE__ */ React17.createElement(FloatingActionsContext.Provider, { value: { open, setOpen } }, /* @__PURE__ */ React17.createElement(FloatingBarContainer, null, /* @__PURE__ */ React17.createElement(import_ui17.UnstableFloatingActionBar, { actions, open: open || void 0 }, children)));
640
706
  }
641
707
  function useFloatingActionsBar() {
642
- const context = (0, import_react11.useContext)(FloatingActionsContext);
708
+ const context = (0, import_react14.useContext)(FloatingActionsContext);
643
709
  if (!context) {
644
710
  throw new Error("useFloatingActions must be used within a FloatingActionsBar");
645
711
  }
@@ -674,10 +740,10 @@ var PopoverBody = ({ children, height = DEFAULT_POPOVER_HEIGHT, width, id }) =>
674
740
  var React19 = __toESM(require("react"));
675
741
 
676
742
  // src/contexts/section-context.tsx
677
- var import_react12 = require("react");
743
+ var import_react15 = require("react");
678
744
  var FALLBACK_SECTION_WIDTH = 320;
679
- var SectionRefContext = (0, import_react12.createContext)(null);
680
- var useSectionRef = () => (0, import_react12.useContext)(SectionRefContext);
745
+ var SectionRefContext = (0, import_react15.createContext)(null);
746
+ var useSectionRef = () => (0, import_react15.useContext)(SectionRefContext);
681
747
  var useSectionWidth = () => {
682
748
  const sectionRef = useSectionRef();
683
749
  return sectionRef?.current?.offsetWidth ?? FALLBACK_SECTION_WIDTH;
@@ -708,57 +774,6 @@ var React21 = __toESM(require("react"));
708
774
  var import_react16 = require("react");
709
775
  var import_ui20 = require("@elementor/ui");
710
776
  var import_react_virtual = require("@tanstack/react-virtual");
711
-
712
- // src/hooks/use-scroll-to-selected.ts
713
- var import_react13 = require("react");
714
- var useScrollToSelected = ({
715
- selectedValue,
716
- items,
717
- virtualizer
718
- }) => {
719
- (0, import_react13.useEffect)(() => {
720
- if (!selectedValue || items.length === 0) {
721
- return;
722
- }
723
- const selectedIndex = items.findIndex((item) => item.value === selectedValue);
724
- if (selectedIndex !== -1) {
725
- virtualizer.scrollToIndex(selectedIndex, { align: "center" });
726
- }
727
- }, [selectedValue, items, virtualizer]);
728
- };
729
-
730
- // src/hooks/use-scroll-top.ts
731
- var import_react14 = require("react");
732
- var useScrollTop = ({ containerRef }) => {
733
- const [scrollTop, setScrollTop] = (0, import_react14.useState)(0);
734
- (0, import_react14.useEffect)(() => {
735
- const container = containerRef.current;
736
- if (!container) {
737
- return;
738
- }
739
- const handleScroll = () => {
740
- setScrollTop(container.scrollTop);
741
- };
742
- container.addEventListener("scroll", handleScroll);
743
- return () => container.removeEventListener("scroll", handleScroll);
744
- }, [containerRef]);
745
- return scrollTop;
746
- };
747
-
748
- // src/hooks/use-text-field-auto-select.ts
749
- var import_react15 = require("react");
750
- var useTextFieldAutoSelect = () => {
751
- const inputRef = (0, import_react15.useRef)(null);
752
- (0, import_react15.useEffect)(() => {
753
- if (inputRef.current) {
754
- inputRef.current.focus();
755
- inputRef.current.select();
756
- }
757
- }, []);
758
- return inputRef;
759
- };
760
-
761
- // src/components/popover/menu-list.tsx
762
777
  var ITEM_HEIGHT = 32;
763
778
  var LIST_ITEMS_BUFFER = 6;
764
779
  var MENU_LIST_PADDING_TOP = 8;
@@ -1178,6 +1193,7 @@ var selectAll = (el) => {
1178
1193
  WarningInfotip,
1179
1194
  closeDialog,
1180
1195
  openDialog,
1196
+ useCanvasClickHandler,
1181
1197
  useDialog,
1182
1198
  useEditable,
1183
1199
  useFloatingActionsBar,
package/dist/index.mjs CHANGED
@@ -364,7 +364,7 @@ var SearchField = ({ value, onSearch, placeholder, id, sx }) => {
364
364
  // src/components/form.tsx
365
365
  import * as React11 from "react";
366
366
  import { useRef as useRef2 } from "react";
367
- var Form = ({ children, onSubmit }) => {
367
+ var Form = ({ children, onSubmit, "data-testid": dataTestId }) => {
368
368
  const formRef = useRef2(null);
369
369
  const handleSubmit = (e) => {
370
370
  e.preventDefault();
@@ -379,7 +379,16 @@ var Form = ({ children, onSubmit }) => {
379
379
  };
380
380
  return (
381
381
  // eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions
382
- /* @__PURE__ */ React11.createElement("form", { onSubmit: handleSubmit, ref: formRef, onKeyDown: handleKeyDown }, children)
382
+ /* @__PURE__ */ React11.createElement(
383
+ "form",
384
+ {
385
+ onSubmit: handleSubmit,
386
+ ref: formRef,
387
+ onKeyDown: handleKeyDown,
388
+ ...dataTestId ? { "data-testid": dataTestId } : {}
389
+ },
390
+ children
391
+ )
383
392
  );
384
393
  };
385
394
 
@@ -401,10 +410,8 @@ var CtaButton = ({ href, children, showIcon = true, ...props }) => /* @__PURE__
401
410
  children ?? __3("Upgrade Now", "elementor")
402
411
  );
403
412
 
404
- // src/components/promotion-infotip.tsx
413
+ // src/components/promotions/promotion-infotip.tsx
405
414
  import * as React13 from "react";
406
- import { useEffect as useEffect4 } from "react";
407
- import { getCanvasIframeDocument } from "@elementor/editor-v1-adapters";
408
415
  import {
409
416
  Card as Card2,
410
417
  CardActions as CardActions2,
@@ -416,15 +423,73 @@ import {
416
423
  Infotip as Infotip3,
417
424
  Typography as Typography3
418
425
  } from "@elementor/ui";
419
- var PromotionInfotip = ({ children, open, onClose, ...cardProps }) => {
426
+
427
+ // src/hooks/use-scroll-to-selected.ts
428
+ import { useEffect as useEffect4 } from "react";
429
+ var useScrollToSelected = ({
430
+ selectedValue,
431
+ items,
432
+ virtualizer
433
+ }) => {
420
434
  useEffect4(() => {
421
- const canvasDocument = open ? getCanvasIframeDocument() : null;
435
+ if (!selectedValue || items.length === 0) {
436
+ return;
437
+ }
438
+ const selectedIndex = items.findIndex((item) => item.value === selectedValue);
439
+ if (selectedIndex !== -1) {
440
+ virtualizer.scrollToIndex(selectedIndex, { align: "center" });
441
+ }
442
+ }, [selectedValue, items, virtualizer]);
443
+ };
444
+
445
+ // src/hooks/use-scroll-top.ts
446
+ import { useEffect as useEffect5, useState as useState5 } from "react";
447
+ var useScrollTop = ({ containerRef }) => {
448
+ const [scrollTop, setScrollTop] = useState5(0);
449
+ useEffect5(() => {
450
+ const container = containerRef.current;
451
+ if (!container) {
452
+ return;
453
+ }
454
+ const handleScroll = () => {
455
+ setScrollTop(container.scrollTop);
456
+ };
457
+ container.addEventListener("scroll", handleScroll);
458
+ return () => container.removeEventListener("scroll", handleScroll);
459
+ }, [containerRef]);
460
+ return scrollTop;
461
+ };
462
+
463
+ // src/hooks/use-text-field-auto-select.ts
464
+ import { useEffect as useEffect6, useRef as useRef3 } from "react";
465
+ var useTextFieldAutoSelect = () => {
466
+ const inputRef = useRef3(null);
467
+ useEffect6(() => {
468
+ if (inputRef.current) {
469
+ inputRef.current.focus();
470
+ inputRef.current.select();
471
+ }
472
+ }, []);
473
+ return inputRef;
474
+ };
475
+
476
+ // src/hooks/use-canvas-click-handler.tsx
477
+ import { useEffect as useEffect7 } from "react";
478
+ import { getCanvasIframeDocument } from "@elementor/editor-v1-adapters";
479
+ var useCanvasClickHandler = (isActive, onClickAway) => {
480
+ useEffect7(() => {
481
+ const canvasDocument = isActive ? getCanvasIframeDocument() : null;
422
482
  if (!canvasDocument) {
423
483
  return;
424
484
  }
425
- canvasDocument.addEventListener("mousedown", onClose);
426
- return () => canvasDocument.removeEventListener("mousedown", onClose);
427
- }, [open, onClose]);
485
+ canvasDocument.addEventListener("mousedown", onClickAway);
486
+ return () => canvasDocument.removeEventListener("mousedown", onClickAway);
487
+ }, [isActive, onClickAway]);
488
+ };
489
+
490
+ // src/components/promotions/promotion-infotip.tsx
491
+ var PromotionInfotip = ({ children, open, onClose, ...cardProps }) => {
492
+ useCanvasClickHandler(!!open, onClose);
428
493
  return /* @__PURE__ */ React13.createElement(Infotip3, { placement: "right", content: /* @__PURE__ */ React13.createElement(InfotipCard, { onClose, ...cardProps }), open }, children);
429
494
  };
430
495
  function InfotipCard({ title, content, assetUrl, ctaUrl, onClose }) {
@@ -446,7 +511,7 @@ function InfotipCard({ title, content, assetUrl, ctaUrl, onClose }) {
446
511
  );
447
512
  }
448
513
 
449
- // src/components/promotion-popover.tsx
514
+ // src/components/promotions/promotion-popover.tsx
450
515
  import * as React14 from "react";
451
516
  import { CrownFilledIcon as CrownFilledIcon2 } from "@elementor/icons";
452
517
  import {
@@ -525,7 +590,7 @@ function PopoverAlert({ title, content, ctaUrl, ctaText, onClose }) {
525
590
  );
526
591
  }
527
592
 
528
- // src/components/promotion-chip.tsx
593
+ // src/components/promotions/promotion-chip.tsx
529
594
  import * as React15 from "react";
530
595
  import { CrownFilledIcon as CrownFilledIcon3 } from "@elementor/icons";
531
596
  import { Chip } from "@elementor/ui";
@@ -551,7 +616,7 @@ var PromotionChip = React15.forwardRef(({ ...props }, ref) => {
551
616
  );
552
617
  });
553
618
 
554
- // src/components/promotion-alert.tsx
619
+ // src/components/promotions/promotion-alert.tsx
555
620
  import * as React16 from "react";
556
621
  import { CrownFilledIcon as CrownFilledIcon4 } from "@elementor/icons";
557
622
  import { Alert as Alert4, Button as Button4 } from "@elementor/ui";
@@ -585,7 +650,7 @@ var PromotionAlert = ({ message, upgradeUrl }) => /* @__PURE__ */ React16.create
585
650
 
586
651
  // src/components/floating-bar.tsx
587
652
  import * as React17 from "react";
588
- import { createContext, useContext, useState as useState5 } from "react";
653
+ import { createContext, useContext, useState as useState6 } from "react";
589
654
  import { styled as styled3, UnstableFloatingActionBar } from "@elementor/ui";
590
655
  var FloatingBarContainer = styled3("span")`
591
656
  display: contents;
@@ -600,7 +665,7 @@ var FloatingBarContainer = styled3("span")`
600
665
  `;
601
666
  var FloatingActionsContext = createContext(null);
602
667
  function FloatingActionsBar({ actions, children }) {
603
- const [open, setOpen] = useState5(false);
668
+ const [open, setOpen] = useState6(false);
604
669
  return /* @__PURE__ */ React17.createElement(FloatingActionsContext.Provider, { value: { open, setOpen } }, /* @__PURE__ */ React17.createElement(FloatingBarContainer, null, /* @__PURE__ */ React17.createElement(UnstableFloatingActionBar, { actions, open: open || void 0 }, children)));
605
670
  }
606
671
  function useFloatingActionsBar() {
@@ -673,57 +738,6 @@ import * as React21 from "react";
673
738
  import { useEffect as useEffect8, useMemo, useRef as useRef4 } from "react";
674
739
  import { Box as Box7, ListItem, MenuList, MenuSubheader, styled as styled4, useTheme } from "@elementor/ui";
675
740
  import { useVirtualizer } from "@tanstack/react-virtual";
676
-
677
- // src/hooks/use-scroll-to-selected.ts
678
- import { useEffect as useEffect5 } from "react";
679
- var useScrollToSelected = ({
680
- selectedValue,
681
- items,
682
- virtualizer
683
- }) => {
684
- useEffect5(() => {
685
- if (!selectedValue || items.length === 0) {
686
- return;
687
- }
688
- const selectedIndex = items.findIndex((item) => item.value === selectedValue);
689
- if (selectedIndex !== -1) {
690
- virtualizer.scrollToIndex(selectedIndex, { align: "center" });
691
- }
692
- }, [selectedValue, items, virtualizer]);
693
- };
694
-
695
- // src/hooks/use-scroll-top.ts
696
- import { useEffect as useEffect6, useState as useState6 } from "react";
697
- var useScrollTop = ({ containerRef }) => {
698
- const [scrollTop, setScrollTop] = useState6(0);
699
- useEffect6(() => {
700
- const container = containerRef.current;
701
- if (!container) {
702
- return;
703
- }
704
- const handleScroll = () => {
705
- setScrollTop(container.scrollTop);
706
- };
707
- container.addEventListener("scroll", handleScroll);
708
- return () => container.removeEventListener("scroll", handleScroll);
709
- }, [containerRef]);
710
- return scrollTop;
711
- };
712
-
713
- // src/hooks/use-text-field-auto-select.ts
714
- import { useEffect as useEffect7, useRef as useRef3 } from "react";
715
- var useTextFieldAutoSelect = () => {
716
- const inputRef = useRef3(null);
717
- useEffect7(() => {
718
- if (inputRef.current) {
719
- inputRef.current.focus();
720
- inputRef.current.select();
721
- }
722
- }, []);
723
- return inputRef;
724
- };
725
-
726
- // src/components/popover/menu-list.tsx
727
741
  var ITEM_HEIGHT = 32;
728
742
  var LIST_ITEMS_BUFFER = 6;
729
743
  var MENU_LIST_PADDING_TOP = 8;
@@ -1158,6 +1172,7 @@ export {
1158
1172
  WarningInfotip,
1159
1173
  closeDialog,
1160
1174
  openDialog,
1175
+ useCanvasClickHandler,
1161
1176
  useDialog,
1162
1177
  useEditable,
1163
1178
  useFloatingActionsBar,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@elementor/editor-ui",
3
3
  "description": "Elementor Editor UI",
4
- "version": "4.0.0-551",
4
+ "version": "4.0.0-564",
5
5
  "private": false,
6
6
  "author": "Elementor Team",
7
7
  "homepage": "https://elementor.com/",
@@ -37,7 +37,7 @@
37
37
  "react-dom": "^18.3.1"
38
38
  },
39
39
  "dependencies": {
40
- "@elementor/editor-v1-adapters": "4.0.0-551",
40
+ "@elementor/editor-v1-adapters": "4.0.0-564",
41
41
  "@elementor/icons": "^1.63.0",
42
42
  "@elementor/ui": "1.36.17",
43
43
  "@tanstack/react-virtual": "^3.13.3",
@@ -3,8 +3,9 @@ import { type FormEvent as FormEvent, type KeyboardEvent, type PropsWithChildren
3
3
 
4
4
  type Props = PropsWithChildren< {
5
5
  onSubmit?: () => void;
6
+ 'data-testid'?: string;
6
7
  } >;
7
- export const Form = ( { children, onSubmit }: Props ) => {
8
+ export const Form = ( { children, onSubmit, 'data-testid': dataTestId }: Props ) => {
8
9
  const formRef = useRef< HTMLFormElement >( null );
9
10
 
10
11
  const handleSubmit = ( e: FormEvent< HTMLFormElement > | SubmitEvent ) => {
@@ -23,7 +24,12 @@ export const Form = ( { children, onSubmit }: Props ) => {
23
24
 
24
25
  return (
25
26
  // eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions
26
- <form onSubmit={ handleSubmit } ref={ formRef } onKeyDown={ handleKeyDown }>
27
+ <form
28
+ onSubmit={ handleSubmit }
29
+ ref={ formRef }
30
+ onKeyDown={ handleKeyDown }
31
+ { ...( dataTestId ? { 'data-testid': dataTestId } : {} ) }
32
+ >
27
33
  { children }
28
34
  </form>
29
35
  );
@@ -1,6 +1,4 @@
1
1
  import * as React from 'react';
2
- import { useEffect } from 'react';
3
- import { getCanvasIframeDocument } from '@elementor/editor-v1-adapters';
4
2
  import {
5
3
  Card,
6
4
  CardActions,
@@ -13,7 +11,8 @@ import {
13
11
  Typography,
14
12
  } from '@elementor/ui';
15
13
 
16
- import { CtaButton } from './cta-button';
14
+ import { useCanvasClickHandler } from '../../hooks';
15
+ import { CtaButton } from '../cta-button';
17
16
 
18
17
  type InfotipCardProps = {
19
18
  title: string;
@@ -30,17 +29,7 @@ type PromotionInfotipProps = React.PropsWithChildren<
30
29
  >;
31
30
 
32
31
  export const PromotionInfotip = ( { children, open, onClose, ...cardProps }: PromotionInfotipProps ) => {
33
- useEffect( () => {
34
- const canvasDocument = open ? getCanvasIframeDocument() : null;
35
-
36
- if ( ! canvasDocument ) {
37
- return;
38
- }
39
-
40
- canvasDocument.addEventListener( 'mousedown', onClose );
41
-
42
- return () => canvasDocument.removeEventListener( 'mousedown', onClose );
43
- }, [ open, onClose ] );
32
+ useCanvasClickHandler( !! open, onClose );
44
33
 
45
34
  return (
46
35
  <Infotip placement="right" content={ <InfotipCard onClose={ onClose } { ...cardProps } /> } open={ open }>
@@ -1,4 +1,5 @@
1
1
  import * as React from 'react';
2
+ import { type MouseEvent } from 'react';
2
3
  import { CrownFilledIcon } from '@elementor/icons';
3
4
  import {
4
5
  Alert,
@@ -16,7 +17,7 @@ type PromotionPopoverCardProps = {
16
17
  content: string;
17
18
  ctaUrl: string;
18
19
  ctaText?: string;
19
- onClose: () => void;
20
+ onClose: ( e: MouseEvent ) => void;
20
21
  };
21
22
 
22
23
  type PromotionPopoverProps = React.PropsWithChildren<
@@ -1,3 +1,4 @@
1
1
  export { useScrollToSelected } from './use-scroll-to-selected';
2
2
  export { useScrollTop } from './use-scroll-top';
3
3
  export { useTextFieldAutoSelect } from './use-text-field-auto-select';
4
+ export { useCanvasClickHandler } from './use-canvas-click-handler';
@@ -0,0 +1,16 @@
1
+ import { useEffect } from 'react';
2
+ import { getCanvasIframeDocument } from '@elementor/editor-v1-adapters';
3
+
4
+ export const useCanvasClickHandler = ( isActive: boolean, onClickAway: ( e: MouseEvent ) => void ) => {
5
+ useEffect( () => {
6
+ const canvasDocument = isActive ? getCanvasIframeDocument() : null;
7
+
8
+ if ( ! canvasDocument ) {
9
+ return;
10
+ }
11
+
12
+ canvasDocument.addEventListener( 'mousedown', onClickAway );
13
+
14
+ return () => canvasDocument.removeEventListener( 'mousedown', onClickAway );
15
+ }, [ isActive, onClickAway ] );
16
+ };
package/src/index.ts CHANGED
@@ -12,10 +12,10 @@ export { GlobalDialog, openDialog, closeDialog } from './components/global-dialo
12
12
  export { SearchField } from './components/search-field';
13
13
  export { Form } from './components/form';
14
14
  export { CtaButton } from './components/cta-button';
15
- export { PromotionInfotip } from './components/promotion-infotip';
16
- export { PromotionPopover } from './components/promotion-popover';
17
- export { PromotionChip } from './components/promotion-chip';
18
- export { PromotionAlert } from './components/promotion-alert';
15
+ export { PromotionInfotip } from './components/promotions/promotion-infotip';
16
+ export { PromotionPopover } from './components/promotions/promotion-popover';
17
+ export { PromotionChip } from './components/promotions/promotion-chip';
18
+ export { PromotionAlert } from './components/promotions/promotion-alert';
19
19
  export { FloatingActionsBar, useFloatingActionsBar } from './components/floating-bar';
20
20
 
21
21
  export * from './components/popover';
@@ -28,3 +28,4 @@ export { SectionRefContext, useSectionWidth } from './contexts/section-context';
28
28
  // hooks
29
29
  export { useEditable } from './hooks/use-editable';
30
30
  export { useTextFieldAutoSelect } from './hooks/use-text-field-auto-select';
31
+ export { useCanvasClickHandler } from './hooks/use-canvas-click-handler';