@sproutsocial/seeds-react-popout 2.4.22 → 2.4.25

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.
@@ -37,6 +37,8 @@ function Popout({
37
37
  onOpenAutoFocus,
38
38
  onEscapeKeyDown,
39
39
  onCloseAutoFocus,
40
+ onPointerDownOutside,
41
+ onInteractOutside,
40
42
  ...rest
41
43
  }) {
42
44
  const [isOpen, setIsOpen] = React.useState(defaultOpen ?? false);
@@ -63,6 +65,8 @@ function Popout({
63
65
  onOpenAutoFocus,
64
66
  onEscapeKeyDown,
65
67
  onCloseAutoFocus,
68
+ onPointerDownOutside,
69
+ onInteractOutside,
66
70
  children: /* @__PURE__ */ jsx(StyledMotionDiv, { ...animationConfig, ...rest, children: content })
67
71
  }
68
72
  ) })
@@ -75,4 +79,4 @@ import "react";
75
79
  export {
76
80
  Popout
77
81
  };
78
- //# sourceMappingURL=chunk-KPXAE7KF.js.map
82
+ //# sourceMappingURL=chunk-TDP63II4.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/v2/Popout.tsx","../../src/v2/PopoutTypes.ts"],"sourcesContent":["import * as React from \"react\";\nimport { AnimatePresence, motion } from \"motion/react\";\nimport * as Popover from \"@radix-ui/react-popover\";\nimport { MOTION_DURATION_FAST } from \"@sproutsocial/seeds-motion/unitless\";\nimport type { TypePopoutProps } from \"./PopoutTypes\";\nimport styled from \"styled-components\";\n\nconst defaultAnimationConfig = {\n initial: { opacity: 0 },\n animate: { opacity: 1 },\n exit: { opacity: 0 },\n transition: {\n ease: \"circOut\",\n type: \"tween\",\n duration: process.env.NODE_ENV === \"test\" ? 0 : MOTION_DURATION_FAST,\n },\n};\n\nconst StyledMotionDiv = styled(motion.div)`\n background-color: ${({ theme }) => theme.colors.container.background.base};\n border: ${({ theme }) => theme.borders[500]};\n border-color: ${({ theme }) => theme.colors.container.border.base};\n border-radius: ${({ theme }) => theme.radii[500]};\n box-shadow: ${({ theme }) => theme.shadows.medium};\n padding: ${({ theme }) => theme.space[400]};\n`;\n\nexport function Popout({\n children,\n content,\n open,\n defaultOpen,\n onOpenChange,\n animationConfig = defaultAnimationConfig,\n side = \"bottom\",\n sideOffset = 8,\n align = \"center\",\n alignOffset = 0,\n onOpenAutoFocus,\n onEscapeKeyDown,\n onCloseAutoFocus,\n onPointerDownOutside,\n onInteractOutside,\n ...rest\n}: TypePopoutProps) {\n const [isOpen, setIsOpen] = React.useState(defaultOpen ?? false);\n\n const handleOpenChange = React.useCallback(\n (newOpen: boolean) => {\n setIsOpen(newOpen);\n onOpenChange?.(newOpen);\n },\n [onOpenChange]\n );\n\n // Use controlled state if open prop is provided\n const isControlled = open !== undefined;\n const popoverOpen = isControlled ? open : isOpen;\n const popoverOnOpenChange = isControlled ? onOpenChange : handleOpenChange;\n\n // Handle ref forwarding for components that use innerRef instead of ref\n // (e.g., seeds-react-button)\n // Radix UI's asChild passes ref, but Button uses innerRef\n const radixRef = React.useRef<HTMLButtonElement | null>(null);\n\n return (\n <Popover.Root open={popoverOpen} onOpenChange={popoverOnOpenChange}>\n <Popover.Trigger ref={radixRef} asChild>\n {children}\n </Popover.Trigger>\n <Popover.Portal>\n <Popover.Content\n side={side}\n sideOffset={sideOffset}\n align={align}\n alignOffset={alignOffset}\n onOpenAutoFocus={onOpenAutoFocus}\n onEscapeKeyDown={onEscapeKeyDown}\n onCloseAutoFocus={onCloseAutoFocus}\n onPointerDownOutside={onPointerDownOutside}\n onInteractOutside={onInteractOutside}\n >\n <StyledMotionDiv {...animationConfig} {...rest}>\n {content}\n </StyledMotionDiv>\n </Popover.Content>\n </Popover.Portal>\n </Popover.Root>\n );\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport * as React from \"react\";\nimport type {\n TypeSystemCommonProps,\n TypeSystemLayoutProps,\n TypeStyledComponentsCommonProps,\n} from \"@sproutsocial/seeds-react-system-props\";\nimport type { HTMLMotionProps } from \"motion/react\";\n\nexport interface TypePopoutProps\n extends TypeStyledComponentsCommonProps,\n TypeSystemCommonProps,\n TypeSystemLayoutProps,\n Omit<\n React.ComponentPropsWithoutRef<\"div\">,\n \"color\" | \"children\" | \"content\"\n > {\n /**\n * The content that the popout should be attached to (renders in Popover.Trigger)\n */\n children: React.ReactElement<any>;\n\n /**\n * The content to be shown in the popout (renders in Popover.Content)\n */\n content: React.ReactNode;\n\n /**\n * Whether the popout is open (controlled)\n */\n open?: boolean;\n\n /**\n * Default open state (uncontrolled)\n */\n defaultOpen?: boolean;\n\n /**\n * Callback fired when the open state changes\n */\n onOpenChange?: (open: boolean) => void;\n\n /**\n * Used to override the default Popout animations.\n * Any props that are valid for use on a Motion div can be passed here as an object.\n * See https://motion.dev/docs/react-motion-component#props\n */\n animationConfig?: Omit<HTMLMotionProps<\"div\">, \"children\">;\n\n /**\n * The preferred side of the trigger to render against when open.\n * @default \"bottom\"\n */\n side?: \"top\" | \"right\" | \"bottom\" | \"left\";\n\n /**\n * The distance in pixels from the trigger.\n * @default 8\n */\n sideOffset?: number;\n\n /**\n * The preferred alignment against the trigger.\n * @default \"center\"\n */\n align?: \"start\" | \"center\" | \"end\";\n\n /**\n * An offset in pixels from the \"start\" or \"end\" alignment options.\n * @default 0\n */\n alignOffset?: number;\n\n /**\n * Event handler called when the popout content tries to auto-focus on open.\n * Can be used to prevent the default auto-focus behavior or customize it.\n * If not provided, defaults to allowing auto-focus on the content.\n */\n onOpenAutoFocus?: (event: Event) => void;\n\n /**\n * Event handler called when the Escape key is pressed while the popout is open.\n * Can be used to prevent the default close behavior or customize it.\n */\n onEscapeKeyDown?: (event: KeyboardEvent) => void;\n\n /**\n * Event handler called when the popout tries to return focus to the trigger on close.\n * Can be used to prevent the default focus return behavior or customize it.\n */\n onCloseAutoFocus?: (event: Event) => void;\n\n /**\n * Event handler called when a pointer down event occurs outside the popout content.\n * Call `event.preventDefault()` to prevent the default dismiss behavior.\n * Useful when the Popout is nested inside a Radix Dialog (e.g. ModalV2) to\n * avoid conflicts between nested DismissableLayer instances.\n */\n onPointerDownOutside?: (\n event: CustomEvent<{ originalEvent: PointerEvent }>\n ) => void;\n\n /**\n * Event handler called when an interaction (pointer or focus) occurs outside\n * the popout content. Call `event.preventDefault()` to prevent the popout\n * from closing.\n */\n onInteractOutside?: (event: CustomEvent<{ originalEvent: Event }>) => void;\n}\n"],"mappings":";AAAA,YAAY,WAAW;AACvB,SAA0B,cAAc;AACxC,YAAY,aAAa;AACzB,SAAS,4BAA4B;AAErC,OAAO,YAAY;AA6Df,SACE,KADF;AA3DJ,IAAM,yBAAyB;AAAA,EAC7B,SAAS,EAAE,SAAS,EAAE;AAAA,EACtB,SAAS,EAAE,SAAS,EAAE;AAAA,EACtB,MAAM,EAAE,SAAS,EAAE;AAAA,EACnB,YAAY;AAAA,IACV,MAAM;AAAA,IACN,MAAM;AAAA,IACN,UAAU,QAAQ,IAAI,aAAa,SAAS,IAAI;AAAA,EAClD;AACF;AAEA,IAAM,kBAAkB,OAAO,OAAO,GAAG;AAAA,sBACnB,CAAC,EAAE,MAAM,MAAM,MAAM,OAAO,UAAU,WAAW,IAAI;AAAA,YAC/D,CAAC,EAAE,MAAM,MAAM,MAAM,QAAQ,GAAG,CAAC;AAAA,kBAC3B,CAAC,EAAE,MAAM,MAAM,MAAM,OAAO,UAAU,OAAO,IAAI;AAAA,mBAChD,CAAC,EAAE,MAAM,MAAM,MAAM,MAAM,GAAG,CAAC;AAAA,gBAClC,CAAC,EAAE,MAAM,MAAM,MAAM,QAAQ,MAAM;AAAA,aACtC,CAAC,EAAE,MAAM,MAAM,MAAM,MAAM,GAAG,CAAC;AAAA;AAGrC,SAAS,OAAO;AAAA,EACrB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,kBAAkB;AAAA,EAClB,OAAO;AAAA,EACP,aAAa;AAAA,EACb,QAAQ;AAAA,EACR,cAAc;AAAA,EACd;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAoB;AAClB,QAAM,CAAC,QAAQ,SAAS,IAAU,eAAS,eAAe,KAAK;AAE/D,QAAM,mBAAyB;AAAA,IAC7B,CAAC,YAAqB;AACpB,gBAAU,OAAO;AACjB,qBAAe,OAAO;AAAA,IACxB;AAAA,IACA,CAAC,YAAY;AAAA,EACf;AAGA,QAAM,eAAe,SAAS;AAC9B,QAAM,cAAc,eAAe,OAAO;AAC1C,QAAM,sBAAsB,eAAe,eAAe;AAK1D,QAAM,WAAiB,aAAiC,IAAI;AAE5D,SACE,qBAAS,cAAR,EAAa,MAAM,aAAa,cAAc,qBAC7C;AAAA,wBAAS,iBAAR,EAAgB,KAAK,UAAU,SAAO,MACpC,UACH;AAAA,IACA,oBAAS,gBAAR,EACC;AAAA,MAAS;AAAA,MAAR;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QAEA,8BAAC,mBAAiB,GAAG,iBAAkB,GAAG,MACvC,mBACH;AAAA;AAAA,IACF,GACF;AAAA,KACF;AAEJ;;;ACxFA,OAAuB;","names":[]}
package/dist/esm/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  Popout
3
- } from "./chunk-KPXAE7KF.js";
3
+ } from "./chunk-TDP63II4.js";
4
4
 
5
5
  // src/Popout.tsx
6
6
  import * as React from "react";
@@ -10,7 +10,9 @@ import FocusLock from "react-focus-lock";
10
10
  import { Popper } from "react-popper";
11
11
  import { MOTION_DURATION_FAST } from "@sproutsocial/seeds-motion/unitless";
12
12
  import { useMutationObserver } from "@sproutsocial/seeds-react-hooks";
13
- import Portal from "@sproutsocial/seeds-react-portal";
13
+ import Portal, {
14
+ DisablePortalToBodyContext
15
+ } from "@sproutsocial/seeds-react-portal";
14
16
  import Box from "@sproutsocial/seeds-react-box";
15
17
 
16
18
  // src/styles.ts
@@ -24,6 +26,7 @@ var TargetWrapper = styled.div`
24
26
 
25
27
  // src/Popout.tsx
26
28
  import { jsx, jsxs } from "react/jsx-runtime";
29
+ var PortalToBodyContext = DisablePortalToBodyContext ?? React.createContext(false);
27
30
  var doesRefContainEventTarget = (ref, event) => {
28
31
  return ref.current && event.target instanceof Node && ref.current.contains(event.target);
29
32
  };
@@ -63,7 +66,9 @@ function Popout2({
63
66
  id,
64
67
  ...rest
65
68
  }) {
66
- const PopoutComponentWrapper = appendToBody ? Portal : React.Fragment;
69
+ const disablePortalToBody = React.useContext(PortalToBodyContext);
70
+ const effectiveAppendToBody = disablePortalToBody ? false : appendToBody;
71
+ const PopoutComponentWrapper = effectiveAppendToBody ? Portal : React.Fragment;
67
72
  const [isInternalShown, setIsInternalShown] = useState(false);
68
73
  const [lockedPlacement, setLockedPlacement] = useState();
69
74
  const isControlled = typeof isOpen === "boolean";
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/Popout.tsx","../../src/styles.ts","../../src/PopoutTypes.ts","../../src/index.ts"],"sourcesContent":["import * as React from \"react\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { AnimatePresence, motion } from \"motion/react\";\nimport FocusLock from \"react-focus-lock\";\nimport { Popper } from \"react-popper\";\nimport { MOTION_DURATION_FAST } from \"@sproutsocial/seeds-motion/unitless\";\nimport { useMutationObserver } from \"@sproutsocial/seeds-react-hooks\";\nimport Portal from \"@sproutsocial/seeds-react-portal\";\nimport Box, { type TypeBoxProps } from \"@sproutsocial/seeds-react-box\";\nimport { TargetWrapper } from \"./styles\";\nimport type { TypePopoutProps } from \"./PopoutTypes\";\n\nconst doesRefContainEventTarget = (\n ref: React.MutableRefObject<HTMLDivElement | undefined>,\n event: MouseEvent\n) => {\n return (\n ref.current &&\n event.target instanceof Node &&\n ref.current.contains(event.target)\n );\n};\n\nconst defaultAnimationConfig = {\n initial: { opacity: 0 },\n animate: { opacity: 1 },\n exit: { opacity: 0 },\n transition: {\n ease: \"circOut\",\n type: \"tween\",\n duration: process.env.NODE_ENV === \"test\" ? 0 : MOTION_DURATION_FAST,\n },\n};\n\nexport function Popout({\n isOpen,\n setIsOpen,\n content,\n children,\n placement = \"auto\",\n lockPlacement = false,\n fullWidth = false,\n zIndex = 7,\n focusOnContent = true,\n onOpen,\n onClose,\n qa = {},\n popperProps: { modifiers: popperModifiers, ...restPopperProps } = {},\n animationConfig = defaultAnimationConfig,\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n scheduleUpdateRef = () => {},\n appendToBody = true,\n focusLockProps = {},\n color,\n \"aria-haspopup\": ariaHasPopup,\n disableWrapperAria = false,\n id,\n ...rest\n}: TypePopoutProps) {\n const PopoutComponentWrapper = appendToBody ? Portal : React.Fragment;\n const [isInternalShown, setIsInternalShown] = useState<boolean>(false);\n const [lockedPlacement, setLockedPlacement] = useState<\n typeof placement | undefined\n >();\n const isControlled = typeof isOpen === \"boolean\";\n const isShown = isControlled ? isOpen : isInternalShown;\n const setIsShown = useMemo(\n () => (isControlled && setIsOpen ? setIsOpen : setIsInternalShown),\n [isControlled, setIsOpen]\n );\n\n const targetRef = useRef<HTMLElement | any>();\n const popoutRef = useRef<HTMLDivElement>();\n\n // This callback will automatically trigger a recalculation of the popout position if the content is changed\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n const scheduleUpdateCallback = useRef(() => {});\n\n useMutationObserver(\n popoutRef.current ?? null,\n {\n childList: true,\n characterData: true,\n subtree: true,\n },\n scheduleUpdateCallback.current\n );\n\n const {\n autoFocus = true,\n returnFocus = true,\n ...restFocusLockProps\n } = focusLockProps;\n\n const isInvalidContent = content === null || content === undefined;\n\n // Callbacks for showing, hiding, and toggling visibility of the popout\n // (Not used when isOpen is passed explicitly)\n const show = useCallback(() => setIsShown(true), [setIsShown]);\n const hide = useCallback(() => setIsShown(false), [setIsShown]);\n const toggle = useCallback(() => setIsShown(!isShown), [isShown, setIsShown]);\n\n useEffect(() => {\n const documentBody = document.body;\n\n if (isShown && documentBody) {\n // Callback passed to a click handler attached to document.body,\n // allowing user to close the popout by clicking outside\n const bodyClick = (e: MouseEvent): void => {\n if (\n doesRefContainEventTarget(targetRef, e) ||\n doesRefContainEventTarget(popoutRef, e)\n ) {\n return;\n }\n\n setIsShown(false, e);\n };\n\n // Callback for allowing user to close by keying \"esc\"\n const onEsc = (e: KeyboardEvent): void => {\n // older browsers use \"Esc\"\n if ([\"Escape\", \"Esc\"].includes(e.key)) {\n // stop propagation to avoid interacting with other components when popout is shown\n // ie if we have a popout shown in a modal and hit esc, we don't want to close both the popout and modal\n e.stopPropagation();\n setIsShown(false, e);\n }\n };\n\n documentBody.addEventListener(\"click\", bodyClick, { capture: true });\n documentBody.addEventListener(\"keydown\", onEsc, { capture: true });\n return () => {\n documentBody.removeEventListener(\"click\", bodyClick, { capture: true });\n documentBody.removeEventListener(\"keydown\", onEsc, { capture: true });\n };\n }\n }, [isShown, setIsShown]);\n\n const callbackStateRef = useRef({ calledFor: isShown });\n useEffect(() => {\n if (callbackStateRef.current.calledFor === isShown) {\n return;\n }\n\n callbackStateRef.current.calledFor = isShown;\n if (isShown) {\n onOpen?.();\n } else {\n onClose?.();\n }\n }, [isShown, onOpen, onClose]);\n\n // WAI-Aria properties for the popout trigger, disabled if necessary\n const ariaProps = useMemo(\n () =>\n disableWrapperAria\n ? {}\n : {\n \"aria-expanded\": isShown,\n \"aria-haspopup\": ariaHasPopup ? ariaHasPopup : true,\n },\n [isShown, ariaHasPopup, disableWrapperAria]\n );\n\n // In cases where a controlled popout is used (e.g. props.isOpen is true), we need\n // to wait for the targetRef to receive a value before rendering the popout. Otherwise,\n // the Popout component renders, but doesn't know how to position itself due the\n // `refereElement` property being undefined.\n const [shouldRenderPopout, setShouldRenderPopout] = useState<boolean>( // Only trigger this shouldRenderPopout logic when using a controlled component.\n // The reason for that is because controlled components may render the popout\n // immediately before the targetRef has a value set to it.\n !isControlled\n );\n\n // Reset the locked placement when the popout is closed\n useEffect(() => {\n if (!isShown && lockedPlacement) {\n setLockedPlacement(undefined);\n }\n }, [isShown, lockedPlacement]);\n\n const childrenRef = (el: React.ElementRef<any> | HTMLElement) => {\n targetRef.current = el;\n\n if (targetRef.current) {\n setShouldRenderPopout(true);\n }\n };\n\n return (\n <React.Fragment>\n {typeof children === \"function\" ? (\n children({\n ref: childrenRef,\n toggle,\n show,\n hide,\n ariaProps,\n })\n ) : (\n <TargetWrapper {...qa} id={id} {...rest} ref={childrenRef}>\n {React.cloneElement(children, {\n ...ariaProps,\n ...(!isControlled\n ? {\n onClick: toggle,\n }\n : undefined),\n })}\n </TargetWrapper>\n )}\n {shouldRenderPopout && !isInvalidContent && (\n <AnimatePresence>\n {isShown && (\n <PopoutComponentWrapper>\n <Popper\n referenceElement={targetRef.current}\n placement={\n lockPlacement && lockedPlacement ? lockedPlacement : placement\n }\n modifiers={{\n preventOverflow: {\n boundariesElement: \"viewport\",\n },\n // Disable flip after locking when lockPlacement is true\n flip: { enabled: !(lockPlacement && lockedPlacement) },\n ...popperModifiers,\n }}\n {...restPopperProps}\n >\n {({\n ref,\n style,\n placement: actualPlacement,\n outOfBoundaries,\n scheduleUpdate,\n }) => {\n // HACK: We use setTimeout to defer locking the placement until after render,\n // because Popper v1 only exposes the computed placement in the render prop,\n // and React does not allow setState during render.\n if (lockPlacement && !lockedPlacement && actualPlacement) {\n setTimeout(() => {\n // Check again before setting to avoid a race condition\n if (\n lockPlacement &&\n !lockedPlacement &&\n actualPlacement\n ) {\n setLockedPlacement(actualPlacement);\n }\n }, 0);\n }\n\n const interceptRef = (el: HTMLDivElement | undefined) => {\n popoutRef.current = el;\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n ref(el);\n };\n\n scheduleUpdateCallback.current = scheduleUpdate;\n scheduleUpdateRef(scheduleUpdate);\n\n return (\n <div\n ref={interceptRef}\n style={{\n ...style,\n zIndex,\n width:\n fullWidth && targetRef.current\n ? targetRef.current.offsetWidth\n : \"initial\",\n }}\n data-placement={actualPlacement}\n data-qa-popout=\"\"\n data-qa-popout-isopen={isOpen === true}\n // TODO: fix this type since `color` should be valid here. TS can't resolve the correct type.\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n color={color}\n {...rest}\n >\n {!outOfBoundaries && (\n <motion.div\n {...animationConfig}\n // pass the placement in the custom prop so it can be used in the animation\n custom={{\n placement: actualPlacement,\n ...animationConfig.custom,\n }}\n >\n <FocusLock\n autoFocus={autoFocus}\n returnFocus={returnFocus}\n disabled={!focusOnContent}\n {...restFocusLockProps}\n >\n {typeof content === \"function\" &&\n content({\n hide,\n actualPlacement,\n })}\n {typeof content !== \"function\" && content}\n </FocusLock>\n </motion.div>\n )}\n </div>\n );\n }}\n </Popper>\n </PopoutComponentWrapper>\n )}\n </AnimatePresence>\n )}\n </React.Fragment>\n );\n}\n\nconst PopoutContent = ({ children, ...rest }: TypeBoxProps) => (\n <Box\n bg=\"container.background.base\"\n color=\"text.body\"\n border={500}\n borderColor=\"container.border.base\"\n borderRadius=\"outer\"\n boxShadow=\"medium\"\n p={400}\n m={300}\n {...rest}\n >\n {children}\n </Box>\n);\n\nPopoutContent.displayName = \"Popout.Content\";\nPopout.Content = PopoutContent;\n\nexport default Popout;\n","import styled from \"styled-components\";\nimport { COMMON, LAYOUT } from \"@sproutsocial/seeds-react-system-props\";\n\nexport const TargetWrapper = styled.div`\n display: inline-block;\n ${COMMON}\n ${LAYOUT}\n`;\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport * as React from \"react\";\nimport type { PopperProps } from \"react-popper\";\nimport type {\n TypeSystemCommonProps,\n TypeSystemLayoutProps,\n TypeStyledComponentsCommonProps,\n} from \"@sproutsocial/seeds-react-system-props\";\nimport type { HTMLMotionProps } from \"motion/react\";\n\nexport type EnumPlacements = Exclude<PopperProps[\"placement\"], undefined>;\n\nexport interface TypeFocusLockProps {\n disabled?: boolean;\n returnFocus?:\n | boolean\n | FocusOptions\n | ((returnTo: Element) => boolean | FocusOptions);\n persistentFocus?: boolean;\n autoFocus?: boolean;\n crossFrame?: boolean;\n noFocusGuards?: boolean | \"tail\";\n group?: string;\n className?: string;\n onActivation?: (node: HTMLElement) => void;\n onDeactivation?: (node: HTMLElement) => void;\n as?: TypeStyledComponentsCommonProps[\"as\"];\n lockProps?: any;\n ref?: any;\n whiteList?: (activeElement: HTMLElement) => boolean;\n shards?: Array<any>;\n children?: React.ReactNode;\n}\n\nexport interface TypePopoutProps\n extends TypeStyledComponentsCommonProps,\n TypeSystemCommonProps,\n TypeSystemLayoutProps,\n Omit<\n React.ComponentPropsWithoutRef<\"div\">,\n \"color\" | \"children\" | \"content\"\n > {\n /**\n * Whether Popout should automatically add aria-attributes to its wrapped elements\n */\n disableWrapperAria?: boolean;\n /**\n * Is the popout open? This prop is optional. By using it, you will lose some automatic handling of the logic for opening and closing the popout.\n */\n isOpen?: boolean;\n\n /**\n * If you use the isOpen prop you will need to pass a handler to change the state of the popout\n */\n setIsOpen?: (isOpen: boolean, event?: MouseEvent | KeyboardEvent) => void;\n\n /**\n * The content to be shown in the popout. If there is no content, just the children are rendered\n */\n content:\n | (React.ReactElement<any> | null | undefined)\n | (\n | ((opts: {\n hide: () => void;\n actualPlacement: EnumPlacements;\n }) => React.ReactElement<any>)\n | null\n | undefined\n );\n\n /**\n * The content that the popout should be attached to\n */\n children:\n | React.ReactElement<any>\n | ((opts: {\n ref: (arg0: React.ElementRef<any> | HTMLElement) => void;\n toggle: () => void;\n show: () => void;\n hide: () => void;\n ariaProps: Record<string, any>;\n }) => React.ReactNode);\n\n /** How the popped-out content should be placed, in relationship to the children */\n placement?: EnumPlacements;\n\n /**\n * Should the popout be locked in place? This will prevent it from moving when the user scrolls or if the height of the popout changes.\n * This is useful for modals and other places where you want the popout to stay in place\n * after it has been opened but want to use an auto placement strategy.\n */\n lockPlacement?: boolean;\n\n /**\n * Should the popped-out content inherit its width from the children?\n * This is useful for typeaheads and other places where a popout needs to match the width of a given element.\n */\n fullWidth?: boolean;\n\n /**\n * When the popout has opened, should we focus on its content?\n * Focus will be brought inside by looking for elements with [autofocus] first, [tabindex] second and buttons/links/other natively-focusable elements last.\n * Upon closing the popout, focus will be returned to the popout's target.\n * If nothing within your popout's content is focusable, this prop will do nothing.\n */\n focusOnContent?: boolean;\n qa?: Record<string, string>;\n zIndex?: number;\n /** Used to override the default Popout animations.\n * Any props that are valid for use on a Motion div can be passed here as an object.\n * See https://motion.dev/docs/react-motion-component#props */\n animationConfig?: Omit<HTMLMotionProps<\"div\">, \"children\">;\n\n /**\n * Override react-popper per the API documentation here: https://github.com/FezVrasta/react-popper#api-documentation\n */\n popperProps?: Partial<PopperProps>;\n onClose?: () => void;\n onOpen?: () => void;\n\n /**\n * An optional callback to receive the scheduleUpdate function.\n * Use the function to recalculate the popout position in relation to the contents.\n */\n scheduleUpdateRef?: (arg0: () => void) => void;\n\n /**\n * Mount the popout at the bottom of the DOM (using React.Portal) instead of inside the current DOM tree\n */\n appendToBody?: boolean;\n\n /**\n * Override `FocusLock` props, see the API documentation for more details: https://github.com/theKashey/react-focus-lock#api\n */\n focusLockProps?: TypeFocusLockProps;\n}\n","import Popout from \"./Popout\";\n\nexport default Popout;\nexport { Popout };\nexport * from \"./PopoutTypes\";\nexport { Popout as PopoutV2 } from \"./v2\";\nexport type { TypePopoutProps as TypePopoutV2Props } from \"./v2/PopoutTypes\";\n"],"mappings":"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","names":["Popout"]}
1
+ {"version":3,"sources":["../../src/Popout.tsx","../../src/styles.ts","../../src/PopoutTypes.ts","../../src/index.ts"],"sourcesContent":["import * as React from \"react\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { AnimatePresence, motion } from \"motion/react\";\nimport FocusLock from \"react-focus-lock\";\nimport { Popper } from \"react-popper\";\nimport { MOTION_DURATION_FAST } from \"@sproutsocial/seeds-motion/unitless\";\nimport { useMutationObserver } from \"@sproutsocial/seeds-react-hooks\";\nimport Portal, {\n DisablePortalToBodyContext,\n} from \"@sproutsocial/seeds-react-portal\";\nimport Box, { type TypeBoxProps } from \"@sproutsocial/seeds-react-box\";\n\n// Fallback for environments where the portal module is mocked or an older\n// version is installed that doesn't export DisablePortalToBodyContext.\nconst PortalToBodyContext =\n DisablePortalToBodyContext ?? React.createContext<boolean>(false);\nimport { TargetWrapper } from \"./styles\";\nimport type { TypePopoutProps } from \"./PopoutTypes\";\n\nconst doesRefContainEventTarget = (\n ref: React.MutableRefObject<HTMLDivElement | undefined>,\n event: MouseEvent\n) => {\n return (\n ref.current &&\n event.target instanceof Node &&\n ref.current.contains(event.target)\n );\n};\n\nconst defaultAnimationConfig = {\n initial: { opacity: 0 },\n animate: { opacity: 1 },\n exit: { opacity: 0 },\n transition: {\n ease: \"circOut\",\n type: \"tween\",\n duration: process.env.NODE_ENV === \"test\" ? 0 : MOTION_DURATION_FAST,\n },\n};\n\nexport function Popout({\n isOpen,\n setIsOpen,\n content,\n children,\n placement = \"auto\",\n lockPlacement = false,\n fullWidth = false,\n zIndex = 7,\n focusOnContent = true,\n onOpen,\n onClose,\n qa = {},\n popperProps: { modifiers: popperModifiers, ...restPopperProps } = {},\n animationConfig = defaultAnimationConfig,\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n scheduleUpdateRef = () => {},\n appendToBody = true,\n focusLockProps = {},\n color,\n \"aria-haspopup\": ariaHasPopup,\n disableWrapperAria = false,\n id,\n ...rest\n}: TypePopoutProps) {\n const disablePortalToBody = React.useContext(PortalToBodyContext);\n const effectiveAppendToBody = disablePortalToBody ? false : appendToBody;\n const PopoutComponentWrapper = effectiveAppendToBody\n ? Portal\n : React.Fragment;\n const [isInternalShown, setIsInternalShown] = useState<boolean>(false);\n const [lockedPlacement, setLockedPlacement] = useState<\n typeof placement | undefined\n >();\n const isControlled = typeof isOpen === \"boolean\";\n const isShown = isControlled ? isOpen : isInternalShown;\n const setIsShown = useMemo(\n () => (isControlled && setIsOpen ? setIsOpen : setIsInternalShown),\n [isControlled, setIsOpen]\n );\n\n const targetRef = useRef<HTMLElement | any>();\n const popoutRef = useRef<HTMLDivElement>();\n\n // This callback will automatically trigger a recalculation of the popout position if the content is changed\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n const scheduleUpdateCallback = useRef(() => {});\n\n useMutationObserver(\n popoutRef.current ?? null,\n {\n childList: true,\n characterData: true,\n subtree: true,\n },\n scheduleUpdateCallback.current\n );\n\n const {\n autoFocus = true,\n returnFocus = true,\n ...restFocusLockProps\n } = focusLockProps;\n\n const isInvalidContent = content === null || content === undefined;\n\n // Callbacks for showing, hiding, and toggling visibility of the popout\n // (Not used when isOpen is passed explicitly)\n const show = useCallback(() => setIsShown(true), [setIsShown]);\n const hide = useCallback(() => setIsShown(false), [setIsShown]);\n const toggle = useCallback(() => setIsShown(!isShown), [isShown, setIsShown]);\n\n useEffect(() => {\n const documentBody = document.body;\n\n if (isShown && documentBody) {\n // Callback passed to a click handler attached to document.body,\n // allowing user to close the popout by clicking outside\n const bodyClick = (e: MouseEvent): void => {\n if (\n doesRefContainEventTarget(targetRef, e) ||\n doesRefContainEventTarget(popoutRef, e)\n ) {\n return;\n }\n\n setIsShown(false, e);\n };\n\n // Callback for allowing user to close by keying \"esc\"\n const onEsc = (e: KeyboardEvent): void => {\n // older browsers use \"Esc\"\n if ([\"Escape\", \"Esc\"].includes(e.key)) {\n // stop propagation to avoid interacting with other components when popout is shown\n // ie if we have a popout shown in a modal and hit esc, we don't want to close both the popout and modal\n e.stopPropagation();\n setIsShown(false, e);\n }\n };\n\n documentBody.addEventListener(\"click\", bodyClick, { capture: true });\n documentBody.addEventListener(\"keydown\", onEsc, { capture: true });\n return () => {\n documentBody.removeEventListener(\"click\", bodyClick, { capture: true });\n documentBody.removeEventListener(\"keydown\", onEsc, { capture: true });\n };\n }\n }, [isShown, setIsShown]);\n\n const callbackStateRef = useRef({ calledFor: isShown });\n useEffect(() => {\n if (callbackStateRef.current.calledFor === isShown) {\n return;\n }\n\n callbackStateRef.current.calledFor = isShown;\n if (isShown) {\n onOpen?.();\n } else {\n onClose?.();\n }\n }, [isShown, onOpen, onClose]);\n\n // WAI-Aria properties for the popout trigger, disabled if necessary\n const ariaProps = useMemo(\n () =>\n disableWrapperAria\n ? {}\n : {\n \"aria-expanded\": isShown,\n \"aria-haspopup\": ariaHasPopup ? ariaHasPopup : true,\n },\n [isShown, ariaHasPopup, disableWrapperAria]\n );\n\n // In cases where a controlled popout is used (e.g. props.isOpen is true), we need\n // to wait for the targetRef to receive a value before rendering the popout. Otherwise,\n // the Popout component renders, but doesn't know how to position itself due the\n // `refereElement` property being undefined.\n const [shouldRenderPopout, setShouldRenderPopout] = useState<boolean>( // Only trigger this shouldRenderPopout logic when using a controlled component.\n // The reason for that is because controlled components may render the popout\n // immediately before the targetRef has a value set to it.\n !isControlled\n );\n\n // Reset the locked placement when the popout is closed\n useEffect(() => {\n if (!isShown && lockedPlacement) {\n setLockedPlacement(undefined);\n }\n }, [isShown, lockedPlacement]);\n\n const childrenRef = (el: React.ElementRef<any> | HTMLElement) => {\n targetRef.current = el;\n\n if (targetRef.current) {\n setShouldRenderPopout(true);\n }\n };\n\n return (\n <React.Fragment>\n {typeof children === \"function\" ? (\n children({\n ref: childrenRef,\n toggle,\n show,\n hide,\n ariaProps,\n })\n ) : (\n <TargetWrapper {...qa} id={id} {...rest} ref={childrenRef}>\n {React.cloneElement(children, {\n ...ariaProps,\n ...(!isControlled\n ? {\n onClick: toggle,\n }\n : undefined),\n })}\n </TargetWrapper>\n )}\n {shouldRenderPopout && !isInvalidContent && (\n <AnimatePresence>\n {isShown && (\n <PopoutComponentWrapper>\n <Popper\n referenceElement={targetRef.current}\n placement={\n lockPlacement && lockedPlacement ? lockedPlacement : placement\n }\n modifiers={{\n preventOverflow: {\n boundariesElement: \"viewport\",\n },\n // Disable flip after locking when lockPlacement is true\n flip: { enabled: !(lockPlacement && lockedPlacement) },\n ...popperModifiers,\n }}\n {...restPopperProps}\n >\n {({\n ref,\n style,\n placement: actualPlacement,\n outOfBoundaries,\n scheduleUpdate,\n }) => {\n // HACK: We use setTimeout to defer locking the placement until after render,\n // because Popper v1 only exposes the computed placement in the render prop,\n // and React does not allow setState during render.\n if (lockPlacement && !lockedPlacement && actualPlacement) {\n setTimeout(() => {\n // Check again before setting to avoid a race condition\n if (\n lockPlacement &&\n !lockedPlacement &&\n actualPlacement\n ) {\n setLockedPlacement(actualPlacement);\n }\n }, 0);\n }\n\n const interceptRef = (el: HTMLDivElement | undefined) => {\n popoutRef.current = el;\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n ref(el);\n };\n\n scheduleUpdateCallback.current = scheduleUpdate;\n scheduleUpdateRef(scheduleUpdate);\n\n return (\n <div\n ref={interceptRef}\n style={{\n ...style,\n zIndex,\n width:\n fullWidth && targetRef.current\n ? targetRef.current.offsetWidth\n : \"initial\",\n }}\n data-placement={actualPlacement}\n data-qa-popout=\"\"\n data-qa-popout-isopen={isOpen === true}\n // TODO: fix this type since `color` should be valid here. TS can't resolve the correct type.\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n color={color}\n {...rest}\n >\n {!outOfBoundaries && (\n <motion.div\n {...animationConfig}\n // pass the placement in the custom prop so it can be used in the animation\n custom={{\n placement: actualPlacement,\n ...animationConfig.custom,\n }}\n >\n <FocusLock\n autoFocus={autoFocus}\n returnFocus={returnFocus}\n disabled={!focusOnContent}\n {...restFocusLockProps}\n >\n {typeof content === \"function\" &&\n content({\n hide,\n actualPlacement,\n })}\n {typeof content !== \"function\" && content}\n </FocusLock>\n </motion.div>\n )}\n </div>\n );\n }}\n </Popper>\n </PopoutComponentWrapper>\n )}\n </AnimatePresence>\n )}\n </React.Fragment>\n );\n}\n\nconst PopoutContent = ({ children, ...rest }: TypeBoxProps) => (\n <Box\n bg=\"container.background.base\"\n color=\"text.body\"\n border={500}\n borderColor=\"container.border.base\"\n borderRadius=\"outer\"\n boxShadow=\"medium\"\n p={400}\n m={300}\n {...rest}\n >\n {children}\n </Box>\n);\n\nPopoutContent.displayName = \"Popout.Content\";\nPopout.Content = PopoutContent;\n\nexport default Popout;\n","import styled from \"styled-components\";\nimport { COMMON, LAYOUT } from \"@sproutsocial/seeds-react-system-props\";\n\nexport const TargetWrapper = styled.div`\n display: inline-block;\n ${COMMON}\n ${LAYOUT}\n`;\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport * as React from \"react\";\nimport type { PopperProps } from \"react-popper\";\nimport type {\n TypeSystemCommonProps,\n TypeSystemLayoutProps,\n TypeStyledComponentsCommonProps,\n} from \"@sproutsocial/seeds-react-system-props\";\nimport type { HTMLMotionProps } from \"motion/react\";\n\nexport type EnumPlacements = Exclude<PopperProps[\"placement\"], undefined>;\n\nexport interface TypeFocusLockProps {\n disabled?: boolean;\n returnFocus?:\n | boolean\n | FocusOptions\n | ((returnTo: Element) => boolean | FocusOptions);\n persistentFocus?: boolean;\n autoFocus?: boolean;\n crossFrame?: boolean;\n noFocusGuards?: boolean | \"tail\";\n group?: string;\n className?: string;\n onActivation?: (node: HTMLElement) => void;\n onDeactivation?: (node: HTMLElement) => void;\n as?: TypeStyledComponentsCommonProps[\"as\"];\n lockProps?: any;\n ref?: any;\n whiteList?: (activeElement: HTMLElement) => boolean;\n shards?: Array<any>;\n children?: React.ReactNode;\n}\n\nexport interface TypePopoutProps\n extends TypeStyledComponentsCommonProps,\n TypeSystemCommonProps,\n TypeSystemLayoutProps,\n Omit<\n React.ComponentPropsWithoutRef<\"div\">,\n \"color\" | \"children\" | \"content\"\n > {\n /**\n * Whether Popout should automatically add aria-attributes to its wrapped elements\n */\n disableWrapperAria?: boolean;\n /**\n * Is the popout open? This prop is optional. By using it, you will lose some automatic handling of the logic for opening and closing the popout.\n */\n isOpen?: boolean;\n\n /**\n * If you use the isOpen prop you will need to pass a handler to change the state of the popout\n */\n setIsOpen?: (isOpen: boolean, event?: MouseEvent | KeyboardEvent) => void;\n\n /**\n * The content to be shown in the popout. If there is no content, just the children are rendered\n */\n content:\n | (React.ReactElement<any> | null | undefined)\n | (\n | ((opts: {\n hide: () => void;\n actualPlacement: EnumPlacements;\n }) => React.ReactElement<any>)\n | null\n | undefined\n );\n\n /**\n * The content that the popout should be attached to\n */\n children:\n | React.ReactElement<any>\n | ((opts: {\n ref: (arg0: React.ElementRef<any> | HTMLElement) => void;\n toggle: () => void;\n show: () => void;\n hide: () => void;\n ariaProps: Record<string, any>;\n }) => React.ReactNode);\n\n /** How the popped-out content should be placed, in relationship to the children */\n placement?: EnumPlacements;\n\n /**\n * Should the popout be locked in place? This will prevent it from moving when the user scrolls or if the height of the popout changes.\n * This is useful for modals and other places where you want the popout to stay in place\n * after it has been opened but want to use an auto placement strategy.\n */\n lockPlacement?: boolean;\n\n /**\n * Should the popped-out content inherit its width from the children?\n * This is useful for typeaheads and other places where a popout needs to match the width of a given element.\n */\n fullWidth?: boolean;\n\n /**\n * When the popout has opened, should we focus on its content?\n * Focus will be brought inside by looking for elements with [autofocus] first, [tabindex] second and buttons/links/other natively-focusable elements last.\n * Upon closing the popout, focus will be returned to the popout's target.\n * If nothing within your popout's content is focusable, this prop will do nothing.\n */\n focusOnContent?: boolean;\n qa?: Record<string, string>;\n zIndex?: number;\n /** Used to override the default Popout animations.\n * Any props that are valid for use on a Motion div can be passed here as an object.\n * See https://motion.dev/docs/react-motion-component#props */\n animationConfig?: Omit<HTMLMotionProps<\"div\">, \"children\">;\n\n /**\n * Override react-popper per the API documentation here: https://github.com/FezVrasta/react-popper#api-documentation\n */\n popperProps?: Partial<PopperProps>;\n onClose?: () => void;\n onOpen?: () => void;\n\n /**\n * An optional callback to receive the scheduleUpdate function.\n * Use the function to recalculate the popout position in relation to the contents.\n */\n scheduleUpdateRef?: (arg0: () => void) => void;\n\n /**\n * Mount the popout at the bottom of the DOM (using React.Portal) instead of inside the current DOM tree\n */\n appendToBody?: boolean;\n\n /**\n * Override `FocusLock` props, see the API documentation for more details: https://github.com/theKashey/react-focus-lock#api\n */\n focusLockProps?: TypeFocusLockProps;\n}\n","import Popout from \"./Popout\";\n\nexport default Popout;\nexport { Popout };\nexport * from \"./PopoutTypes\";\nexport { Popout as PopoutV2 } from \"./v2\";\nexport type { TypePopoutProps as TypePopoutV2Props } from \"./v2/PopoutTypes\";\n"],"mappings":"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","names":["Popout"]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  Popout
3
- } from "../chunk-KPXAE7KF.js";
3
+ } from "../chunk-TDP63II4.js";
4
4
  export {
5
5
  Popout
6
6
  };
package/dist/index.js CHANGED
@@ -58,6 +58,7 @@ var TargetWrapper = import_styled_components.default.div`
58
58
 
59
59
  // src/Popout.tsx
60
60
  var import_jsx_runtime = require("react/jsx-runtime");
61
+ var PortalToBodyContext = import_seeds_react_portal.DisablePortalToBodyContext ?? React.createContext(false);
61
62
  var doesRefContainEventTarget = (ref, event) => {
62
63
  return ref.current && event.target instanceof Node && ref.current.contains(event.target);
63
64
  };
@@ -97,7 +98,9 @@ function Popout({
97
98
  id,
98
99
  ...rest
99
100
  }) {
100
- const PopoutComponentWrapper = appendToBody ? import_seeds_react_portal.default : React.Fragment;
101
+ const disablePortalToBody = React.useContext(PortalToBodyContext);
102
+ const effectiveAppendToBody = disablePortalToBody ? false : appendToBody;
103
+ const PopoutComponentWrapper = effectiveAppendToBody ? import_seeds_react_portal.default : React.Fragment;
101
104
  const [isInternalShown, setIsInternalShown] = (0, import_react.useState)(false);
102
105
  const [lockedPlacement, setLockedPlacement] = (0, import_react.useState)();
103
106
  const isControlled = typeof isOpen === "boolean";
@@ -342,6 +345,8 @@ function Popout2({
342
345
  onOpenAutoFocus,
343
346
  onEscapeKeyDown,
344
347
  onCloseAutoFocus,
348
+ onPointerDownOutside,
349
+ onInteractOutside,
345
350
  ...rest
346
351
  }) {
347
352
  const [isOpen, setIsOpen] = React3.useState(defaultOpen ?? false);
@@ -368,6 +373,8 @@ function Popout2({
368
373
  onOpenAutoFocus,
369
374
  onEscapeKeyDown,
370
375
  onCloseAutoFocus,
376
+ onPointerDownOutside,
377
+ onInteractOutside,
371
378
  children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(StyledMotionDiv, { ...animationConfig, ...rest, children: content })
372
379
  }
373
380
  ) })
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/Popout.tsx","../src/styles.ts","../src/PopoutTypes.ts","../src/v2/Popout.tsx","../src/v2/PopoutTypes.ts"],"sourcesContent":["import Popout from \"./Popout\";\n\nexport default Popout;\nexport { Popout };\nexport * from \"./PopoutTypes\";\nexport { Popout as PopoutV2 } from \"./v2\";\nexport type { TypePopoutProps as TypePopoutV2Props } from \"./v2/PopoutTypes\";\n","import * as React from \"react\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { AnimatePresence, motion } from \"motion/react\";\nimport FocusLock from \"react-focus-lock\";\nimport { Popper } from \"react-popper\";\nimport { MOTION_DURATION_FAST } from \"@sproutsocial/seeds-motion/unitless\";\nimport { useMutationObserver } from \"@sproutsocial/seeds-react-hooks\";\nimport Portal from \"@sproutsocial/seeds-react-portal\";\nimport Box, { type TypeBoxProps } from \"@sproutsocial/seeds-react-box\";\nimport { TargetWrapper } from \"./styles\";\nimport type { TypePopoutProps } from \"./PopoutTypes\";\n\nconst doesRefContainEventTarget = (\n ref: React.MutableRefObject<HTMLDivElement | undefined>,\n event: MouseEvent\n) => {\n return (\n ref.current &&\n event.target instanceof Node &&\n ref.current.contains(event.target)\n );\n};\n\nconst defaultAnimationConfig = {\n initial: { opacity: 0 },\n animate: { opacity: 1 },\n exit: { opacity: 0 },\n transition: {\n ease: \"circOut\",\n type: \"tween\",\n duration: process.env.NODE_ENV === \"test\" ? 0 : MOTION_DURATION_FAST,\n },\n};\n\nexport function Popout({\n isOpen,\n setIsOpen,\n content,\n children,\n placement = \"auto\",\n lockPlacement = false,\n fullWidth = false,\n zIndex = 7,\n focusOnContent = true,\n onOpen,\n onClose,\n qa = {},\n popperProps: { modifiers: popperModifiers, ...restPopperProps } = {},\n animationConfig = defaultAnimationConfig,\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n scheduleUpdateRef = () => {},\n appendToBody = true,\n focusLockProps = {},\n color,\n \"aria-haspopup\": ariaHasPopup,\n disableWrapperAria = false,\n id,\n ...rest\n}: TypePopoutProps) {\n const PopoutComponentWrapper = appendToBody ? Portal : React.Fragment;\n const [isInternalShown, setIsInternalShown] = useState<boolean>(false);\n const [lockedPlacement, setLockedPlacement] = useState<\n typeof placement | undefined\n >();\n const isControlled = typeof isOpen === \"boolean\";\n const isShown = isControlled ? isOpen : isInternalShown;\n const setIsShown = useMemo(\n () => (isControlled && setIsOpen ? setIsOpen : setIsInternalShown),\n [isControlled, setIsOpen]\n );\n\n const targetRef = useRef<HTMLElement | any>();\n const popoutRef = useRef<HTMLDivElement>();\n\n // This callback will automatically trigger a recalculation of the popout position if the content is changed\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n const scheduleUpdateCallback = useRef(() => {});\n\n useMutationObserver(\n popoutRef.current ?? null,\n {\n childList: true,\n characterData: true,\n subtree: true,\n },\n scheduleUpdateCallback.current\n );\n\n const {\n autoFocus = true,\n returnFocus = true,\n ...restFocusLockProps\n } = focusLockProps;\n\n const isInvalidContent = content === null || content === undefined;\n\n // Callbacks for showing, hiding, and toggling visibility of the popout\n // (Not used when isOpen is passed explicitly)\n const show = useCallback(() => setIsShown(true), [setIsShown]);\n const hide = useCallback(() => setIsShown(false), [setIsShown]);\n const toggle = useCallback(() => setIsShown(!isShown), [isShown, setIsShown]);\n\n useEffect(() => {\n const documentBody = document.body;\n\n if (isShown && documentBody) {\n // Callback passed to a click handler attached to document.body,\n // allowing user to close the popout by clicking outside\n const bodyClick = (e: MouseEvent): void => {\n if (\n doesRefContainEventTarget(targetRef, e) ||\n doesRefContainEventTarget(popoutRef, e)\n ) {\n return;\n }\n\n setIsShown(false, e);\n };\n\n // Callback for allowing user to close by keying \"esc\"\n const onEsc = (e: KeyboardEvent): void => {\n // older browsers use \"Esc\"\n if ([\"Escape\", \"Esc\"].includes(e.key)) {\n // stop propagation to avoid interacting with other components when popout is shown\n // ie if we have a popout shown in a modal and hit esc, we don't want to close both the popout and modal\n e.stopPropagation();\n setIsShown(false, e);\n }\n };\n\n documentBody.addEventListener(\"click\", bodyClick, { capture: true });\n documentBody.addEventListener(\"keydown\", onEsc, { capture: true });\n return () => {\n documentBody.removeEventListener(\"click\", bodyClick, { capture: true });\n documentBody.removeEventListener(\"keydown\", onEsc, { capture: true });\n };\n }\n }, [isShown, setIsShown]);\n\n const callbackStateRef = useRef({ calledFor: isShown });\n useEffect(() => {\n if (callbackStateRef.current.calledFor === isShown) {\n return;\n }\n\n callbackStateRef.current.calledFor = isShown;\n if (isShown) {\n onOpen?.();\n } else {\n onClose?.();\n }\n }, [isShown, onOpen, onClose]);\n\n // WAI-Aria properties for the popout trigger, disabled if necessary\n const ariaProps = useMemo(\n () =>\n disableWrapperAria\n ? {}\n : {\n \"aria-expanded\": isShown,\n \"aria-haspopup\": ariaHasPopup ? ariaHasPopup : true,\n },\n [isShown, ariaHasPopup, disableWrapperAria]\n );\n\n // In cases where a controlled popout is used (e.g. props.isOpen is true), we need\n // to wait for the targetRef to receive a value before rendering the popout. Otherwise,\n // the Popout component renders, but doesn't know how to position itself due the\n // `refereElement` property being undefined.\n const [shouldRenderPopout, setShouldRenderPopout] = useState<boolean>( // Only trigger this shouldRenderPopout logic when using a controlled component.\n // The reason for that is because controlled components may render the popout\n // immediately before the targetRef has a value set to it.\n !isControlled\n );\n\n // Reset the locked placement when the popout is closed\n useEffect(() => {\n if (!isShown && lockedPlacement) {\n setLockedPlacement(undefined);\n }\n }, [isShown, lockedPlacement]);\n\n const childrenRef = (el: React.ElementRef<any> | HTMLElement) => {\n targetRef.current = el;\n\n if (targetRef.current) {\n setShouldRenderPopout(true);\n }\n };\n\n return (\n <React.Fragment>\n {typeof children === \"function\" ? (\n children({\n ref: childrenRef,\n toggle,\n show,\n hide,\n ariaProps,\n })\n ) : (\n <TargetWrapper {...qa} id={id} {...rest} ref={childrenRef}>\n {React.cloneElement(children, {\n ...ariaProps,\n ...(!isControlled\n ? {\n onClick: toggle,\n }\n : undefined),\n })}\n </TargetWrapper>\n )}\n {shouldRenderPopout && !isInvalidContent && (\n <AnimatePresence>\n {isShown && (\n <PopoutComponentWrapper>\n <Popper\n referenceElement={targetRef.current}\n placement={\n lockPlacement && lockedPlacement ? lockedPlacement : placement\n }\n modifiers={{\n preventOverflow: {\n boundariesElement: \"viewport\",\n },\n // Disable flip after locking when lockPlacement is true\n flip: { enabled: !(lockPlacement && lockedPlacement) },\n ...popperModifiers,\n }}\n {...restPopperProps}\n >\n {({\n ref,\n style,\n placement: actualPlacement,\n outOfBoundaries,\n scheduleUpdate,\n }) => {\n // HACK: We use setTimeout to defer locking the placement until after render,\n // because Popper v1 only exposes the computed placement in the render prop,\n // and React does not allow setState during render.\n if (lockPlacement && !lockedPlacement && actualPlacement) {\n setTimeout(() => {\n // Check again before setting to avoid a race condition\n if (\n lockPlacement &&\n !lockedPlacement &&\n actualPlacement\n ) {\n setLockedPlacement(actualPlacement);\n }\n }, 0);\n }\n\n const interceptRef = (el: HTMLDivElement | undefined) => {\n popoutRef.current = el;\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n ref(el);\n };\n\n scheduleUpdateCallback.current = scheduleUpdate;\n scheduleUpdateRef(scheduleUpdate);\n\n return (\n <div\n ref={interceptRef}\n style={{\n ...style,\n zIndex,\n width:\n fullWidth && targetRef.current\n ? targetRef.current.offsetWidth\n : \"initial\",\n }}\n data-placement={actualPlacement}\n data-qa-popout=\"\"\n data-qa-popout-isopen={isOpen === true}\n // TODO: fix this type since `color` should be valid here. TS can't resolve the correct type.\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n color={color}\n {...rest}\n >\n {!outOfBoundaries && (\n <motion.div\n {...animationConfig}\n // pass the placement in the custom prop so it can be used in the animation\n custom={{\n placement: actualPlacement,\n ...animationConfig.custom,\n }}\n >\n <FocusLock\n autoFocus={autoFocus}\n returnFocus={returnFocus}\n disabled={!focusOnContent}\n {...restFocusLockProps}\n >\n {typeof content === \"function\" &&\n content({\n hide,\n actualPlacement,\n })}\n {typeof content !== \"function\" && content}\n </FocusLock>\n </motion.div>\n )}\n </div>\n );\n }}\n </Popper>\n </PopoutComponentWrapper>\n )}\n </AnimatePresence>\n )}\n </React.Fragment>\n );\n}\n\nconst PopoutContent = ({ children, ...rest }: TypeBoxProps) => (\n <Box\n bg=\"container.background.base\"\n color=\"text.body\"\n border={500}\n borderColor=\"container.border.base\"\n borderRadius=\"outer\"\n boxShadow=\"medium\"\n p={400}\n m={300}\n {...rest}\n >\n {children}\n </Box>\n);\n\nPopoutContent.displayName = \"Popout.Content\";\nPopout.Content = PopoutContent;\n\nexport default Popout;\n","import styled from \"styled-components\";\nimport { COMMON, LAYOUT } from \"@sproutsocial/seeds-react-system-props\";\n\nexport const TargetWrapper = styled.div`\n display: inline-block;\n ${COMMON}\n ${LAYOUT}\n`;\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport * as React from \"react\";\nimport type { PopperProps } from \"react-popper\";\nimport type {\n TypeSystemCommonProps,\n TypeSystemLayoutProps,\n TypeStyledComponentsCommonProps,\n} from \"@sproutsocial/seeds-react-system-props\";\nimport type { HTMLMotionProps } from \"motion/react\";\n\nexport type EnumPlacements = Exclude<PopperProps[\"placement\"], undefined>;\n\nexport interface TypeFocusLockProps {\n disabled?: boolean;\n returnFocus?:\n | boolean\n | FocusOptions\n | ((returnTo: Element) => boolean | FocusOptions);\n persistentFocus?: boolean;\n autoFocus?: boolean;\n crossFrame?: boolean;\n noFocusGuards?: boolean | \"tail\";\n group?: string;\n className?: string;\n onActivation?: (node: HTMLElement) => void;\n onDeactivation?: (node: HTMLElement) => void;\n as?: TypeStyledComponentsCommonProps[\"as\"];\n lockProps?: any;\n ref?: any;\n whiteList?: (activeElement: HTMLElement) => boolean;\n shards?: Array<any>;\n children?: React.ReactNode;\n}\n\nexport interface TypePopoutProps\n extends TypeStyledComponentsCommonProps,\n TypeSystemCommonProps,\n TypeSystemLayoutProps,\n Omit<\n React.ComponentPropsWithoutRef<\"div\">,\n \"color\" | \"children\" | \"content\"\n > {\n /**\n * Whether Popout should automatically add aria-attributes to its wrapped elements\n */\n disableWrapperAria?: boolean;\n /**\n * Is the popout open? This prop is optional. By using it, you will lose some automatic handling of the logic for opening and closing the popout.\n */\n isOpen?: boolean;\n\n /**\n * If you use the isOpen prop you will need to pass a handler to change the state of the popout\n */\n setIsOpen?: (isOpen: boolean, event?: MouseEvent | KeyboardEvent) => void;\n\n /**\n * The content to be shown in the popout. If there is no content, just the children are rendered\n */\n content:\n | (React.ReactElement<any> | null | undefined)\n | (\n | ((opts: {\n hide: () => void;\n actualPlacement: EnumPlacements;\n }) => React.ReactElement<any>)\n | null\n | undefined\n );\n\n /**\n * The content that the popout should be attached to\n */\n children:\n | React.ReactElement<any>\n | ((opts: {\n ref: (arg0: React.ElementRef<any> | HTMLElement) => void;\n toggle: () => void;\n show: () => void;\n hide: () => void;\n ariaProps: Record<string, any>;\n }) => React.ReactNode);\n\n /** How the popped-out content should be placed, in relationship to the children */\n placement?: EnumPlacements;\n\n /**\n * Should the popout be locked in place? This will prevent it from moving when the user scrolls or if the height of the popout changes.\n * This is useful for modals and other places where you want the popout to stay in place\n * after it has been opened but want to use an auto placement strategy.\n */\n lockPlacement?: boolean;\n\n /**\n * Should the popped-out content inherit its width from the children?\n * This is useful for typeaheads and other places where a popout needs to match the width of a given element.\n */\n fullWidth?: boolean;\n\n /**\n * When the popout has opened, should we focus on its content?\n * Focus will be brought inside by looking for elements with [autofocus] first, [tabindex] second and buttons/links/other natively-focusable elements last.\n * Upon closing the popout, focus will be returned to the popout's target.\n * If nothing within your popout's content is focusable, this prop will do nothing.\n */\n focusOnContent?: boolean;\n qa?: Record<string, string>;\n zIndex?: number;\n /** Used to override the default Popout animations.\n * Any props that are valid for use on a Motion div can be passed here as an object.\n * See https://motion.dev/docs/react-motion-component#props */\n animationConfig?: Omit<HTMLMotionProps<\"div\">, \"children\">;\n\n /**\n * Override react-popper per the API documentation here: https://github.com/FezVrasta/react-popper#api-documentation\n */\n popperProps?: Partial<PopperProps>;\n onClose?: () => void;\n onOpen?: () => void;\n\n /**\n * An optional callback to receive the scheduleUpdate function.\n * Use the function to recalculate the popout position in relation to the contents.\n */\n scheduleUpdateRef?: (arg0: () => void) => void;\n\n /**\n * Mount the popout at the bottom of the DOM (using React.Portal) instead of inside the current DOM tree\n */\n appendToBody?: boolean;\n\n /**\n * Override `FocusLock` props, see the API documentation for more details: https://github.com/theKashey/react-focus-lock#api\n */\n focusLockProps?: TypeFocusLockProps;\n}\n","import * as React from \"react\";\nimport { AnimatePresence, motion } from \"motion/react\";\nimport * as Popover from \"@radix-ui/react-popover\";\nimport { MOTION_DURATION_FAST } from \"@sproutsocial/seeds-motion/unitless\";\nimport type { TypePopoutProps } from \"./PopoutTypes\";\nimport styled from \"styled-components\";\n\nconst defaultAnimationConfig = {\n initial: { opacity: 0 },\n animate: { opacity: 1 },\n exit: { opacity: 0 },\n transition: {\n ease: \"circOut\",\n type: \"tween\",\n duration: process.env.NODE_ENV === \"test\" ? 0 : MOTION_DURATION_FAST,\n },\n};\n\nconst StyledMotionDiv = styled(motion.div)`\n background-color: ${({ theme }) => theme.colors.container.background.base};\n border: ${({ theme }) => theme.borders[500]};\n border-color: ${({ theme }) => theme.colors.container.border.base};\n border-radius: ${({ theme }) => theme.radii[500]};\n box-shadow: ${({ theme }) => theme.shadows.medium};\n padding: ${({ theme }) => theme.space[400]};\n`;\n\nexport function Popout({\n children,\n content,\n open,\n defaultOpen,\n onOpenChange,\n animationConfig = defaultAnimationConfig,\n side = \"bottom\",\n sideOffset = 8,\n align = \"center\",\n alignOffset = 0,\n onOpenAutoFocus,\n onEscapeKeyDown,\n onCloseAutoFocus,\n ...rest\n}: TypePopoutProps) {\n const [isOpen, setIsOpen] = React.useState(defaultOpen ?? false);\n\n const handleOpenChange = React.useCallback(\n (newOpen: boolean) => {\n setIsOpen(newOpen);\n onOpenChange?.(newOpen);\n },\n [onOpenChange]\n );\n\n // Use controlled state if open prop is provided\n const isControlled = open !== undefined;\n const popoverOpen = isControlled ? open : isOpen;\n const popoverOnOpenChange = isControlled ? onOpenChange : handleOpenChange;\n\n // Handle ref forwarding for components that use innerRef instead of ref\n // (e.g., seeds-react-button)\n // Radix UI's asChild passes ref, but Button uses innerRef\n const radixRef = React.useRef<HTMLButtonElement | null>(null);\n\n return (\n <Popover.Root open={popoverOpen} onOpenChange={popoverOnOpenChange}>\n <Popover.Trigger ref={radixRef} asChild>\n {children}\n </Popover.Trigger>\n <Popover.Portal>\n <Popover.Content\n side={side}\n sideOffset={sideOffset}\n align={align}\n alignOffset={alignOffset}\n onOpenAutoFocus={onOpenAutoFocus}\n onEscapeKeyDown={onEscapeKeyDown}\n onCloseAutoFocus={onCloseAutoFocus}\n >\n <StyledMotionDiv {...animationConfig} {...rest}>\n {content}\n </StyledMotionDiv>\n </Popover.Content>\n </Popover.Portal>\n </Popover.Root>\n );\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport * as React from \"react\";\nimport type {\n TypeSystemCommonProps,\n TypeSystemLayoutProps,\n TypeStyledComponentsCommonProps,\n} from \"@sproutsocial/seeds-react-system-props\";\nimport type { HTMLMotionProps } from \"motion/react\";\n\nexport interface TypePopoutProps\n extends TypeStyledComponentsCommonProps,\n TypeSystemCommonProps,\n TypeSystemLayoutProps,\n Omit<\n React.ComponentPropsWithoutRef<\"div\">,\n \"color\" | \"children\" | \"content\"\n > {\n /**\n * The content that the popout should be attached to (renders in Popover.Trigger)\n */\n children: React.ReactElement<any>;\n\n /**\n * The content to be shown in the popout (renders in Popover.Content)\n */\n content: React.ReactNode;\n\n /**\n * Whether the popout is open (controlled)\n */\n open?: boolean;\n\n /**\n * Default open state (uncontrolled)\n */\n defaultOpen?: boolean;\n\n /**\n * Callback fired when the open state changes\n */\n onOpenChange?: (open: boolean) => void;\n\n /**\n * Used to override the default Popout animations.\n * Any props that are valid for use on a Motion div can be passed here as an object.\n * See https://motion.dev/docs/react-motion-component#props\n */\n animationConfig?: Omit<HTMLMotionProps<\"div\">, \"children\">;\n\n /**\n * The preferred side of the trigger to render against when open.\n * @default \"bottom\"\n */\n side?: \"top\" | \"right\" | \"bottom\" | \"left\";\n\n /**\n * The distance in pixels from the trigger.\n * @default 8\n */\n sideOffset?: number;\n\n /**\n * The preferred alignment against the trigger.\n * @default \"center\"\n */\n align?: \"start\" | \"center\" | \"end\";\n\n /**\n * An offset in pixels from the \"start\" or \"end\" alignment options.\n * @default 0\n */\n alignOffset?: number;\n\n /**\n * Event handler called when the popout content tries to auto-focus on open.\n * Can be used to prevent the default auto-focus behavior or customize it.\n * If not provided, defaults to allowing auto-focus on the content.\n */\n onOpenAutoFocus?: (event: Event) => void;\n\n /**\n * Event handler called when the Escape key is pressed while the popout is open.\n * Can be used to prevent the default close behavior or customize it.\n */\n onEscapeKeyDown?: (event: KeyboardEvent) => void;\n\n /**\n * Event handler called when the popout tries to return focus to the trigger on close.\n * Can be used to prevent the default focus return behavior or customize it.\n */\n onCloseAutoFocus?: (event: Event) => void;\n}\n"],"mappings":"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","names":["Popout","import_react","styled","Portal","FocusLock","Box","React","React","import_react","import_unitless","import_styled_components","import_jsx_runtime","defaultAnimationConfig","styled","Popout","React"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/Popout.tsx","../src/styles.ts","../src/PopoutTypes.ts","../src/v2/Popout.tsx","../src/v2/PopoutTypes.ts"],"sourcesContent":["import Popout from \"./Popout\";\n\nexport default Popout;\nexport { Popout };\nexport * from \"./PopoutTypes\";\nexport { Popout as PopoutV2 } from \"./v2\";\nexport type { TypePopoutProps as TypePopoutV2Props } from \"./v2/PopoutTypes\";\n","import * as React from \"react\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { AnimatePresence, motion } from \"motion/react\";\nimport FocusLock from \"react-focus-lock\";\nimport { Popper } from \"react-popper\";\nimport { MOTION_DURATION_FAST } from \"@sproutsocial/seeds-motion/unitless\";\nimport { useMutationObserver } from \"@sproutsocial/seeds-react-hooks\";\nimport Portal, {\n DisablePortalToBodyContext,\n} from \"@sproutsocial/seeds-react-portal\";\nimport Box, { type TypeBoxProps } from \"@sproutsocial/seeds-react-box\";\n\n// Fallback for environments where the portal module is mocked or an older\n// version is installed that doesn't export DisablePortalToBodyContext.\nconst PortalToBodyContext =\n DisablePortalToBodyContext ?? React.createContext<boolean>(false);\nimport { TargetWrapper } from \"./styles\";\nimport type { TypePopoutProps } from \"./PopoutTypes\";\n\nconst doesRefContainEventTarget = (\n ref: React.MutableRefObject<HTMLDivElement | undefined>,\n event: MouseEvent\n) => {\n return (\n ref.current &&\n event.target instanceof Node &&\n ref.current.contains(event.target)\n );\n};\n\nconst defaultAnimationConfig = {\n initial: { opacity: 0 },\n animate: { opacity: 1 },\n exit: { opacity: 0 },\n transition: {\n ease: \"circOut\",\n type: \"tween\",\n duration: process.env.NODE_ENV === \"test\" ? 0 : MOTION_DURATION_FAST,\n },\n};\n\nexport function Popout({\n isOpen,\n setIsOpen,\n content,\n children,\n placement = \"auto\",\n lockPlacement = false,\n fullWidth = false,\n zIndex = 7,\n focusOnContent = true,\n onOpen,\n onClose,\n qa = {},\n popperProps: { modifiers: popperModifiers, ...restPopperProps } = {},\n animationConfig = defaultAnimationConfig,\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n scheduleUpdateRef = () => {},\n appendToBody = true,\n focusLockProps = {},\n color,\n \"aria-haspopup\": ariaHasPopup,\n disableWrapperAria = false,\n id,\n ...rest\n}: TypePopoutProps) {\n const disablePortalToBody = React.useContext(PortalToBodyContext);\n const effectiveAppendToBody = disablePortalToBody ? false : appendToBody;\n const PopoutComponentWrapper = effectiveAppendToBody\n ? Portal\n : React.Fragment;\n const [isInternalShown, setIsInternalShown] = useState<boolean>(false);\n const [lockedPlacement, setLockedPlacement] = useState<\n typeof placement | undefined\n >();\n const isControlled = typeof isOpen === \"boolean\";\n const isShown = isControlled ? isOpen : isInternalShown;\n const setIsShown = useMemo(\n () => (isControlled && setIsOpen ? setIsOpen : setIsInternalShown),\n [isControlled, setIsOpen]\n );\n\n const targetRef = useRef<HTMLElement | any>();\n const popoutRef = useRef<HTMLDivElement>();\n\n // This callback will automatically trigger a recalculation of the popout position if the content is changed\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n const scheduleUpdateCallback = useRef(() => {});\n\n useMutationObserver(\n popoutRef.current ?? null,\n {\n childList: true,\n characterData: true,\n subtree: true,\n },\n scheduleUpdateCallback.current\n );\n\n const {\n autoFocus = true,\n returnFocus = true,\n ...restFocusLockProps\n } = focusLockProps;\n\n const isInvalidContent = content === null || content === undefined;\n\n // Callbacks for showing, hiding, and toggling visibility of the popout\n // (Not used when isOpen is passed explicitly)\n const show = useCallback(() => setIsShown(true), [setIsShown]);\n const hide = useCallback(() => setIsShown(false), [setIsShown]);\n const toggle = useCallback(() => setIsShown(!isShown), [isShown, setIsShown]);\n\n useEffect(() => {\n const documentBody = document.body;\n\n if (isShown && documentBody) {\n // Callback passed to a click handler attached to document.body,\n // allowing user to close the popout by clicking outside\n const bodyClick = (e: MouseEvent): void => {\n if (\n doesRefContainEventTarget(targetRef, e) ||\n doesRefContainEventTarget(popoutRef, e)\n ) {\n return;\n }\n\n setIsShown(false, e);\n };\n\n // Callback for allowing user to close by keying \"esc\"\n const onEsc = (e: KeyboardEvent): void => {\n // older browsers use \"Esc\"\n if ([\"Escape\", \"Esc\"].includes(e.key)) {\n // stop propagation to avoid interacting with other components when popout is shown\n // ie if we have a popout shown in a modal and hit esc, we don't want to close both the popout and modal\n e.stopPropagation();\n setIsShown(false, e);\n }\n };\n\n documentBody.addEventListener(\"click\", bodyClick, { capture: true });\n documentBody.addEventListener(\"keydown\", onEsc, { capture: true });\n return () => {\n documentBody.removeEventListener(\"click\", bodyClick, { capture: true });\n documentBody.removeEventListener(\"keydown\", onEsc, { capture: true });\n };\n }\n }, [isShown, setIsShown]);\n\n const callbackStateRef = useRef({ calledFor: isShown });\n useEffect(() => {\n if (callbackStateRef.current.calledFor === isShown) {\n return;\n }\n\n callbackStateRef.current.calledFor = isShown;\n if (isShown) {\n onOpen?.();\n } else {\n onClose?.();\n }\n }, [isShown, onOpen, onClose]);\n\n // WAI-Aria properties for the popout trigger, disabled if necessary\n const ariaProps = useMemo(\n () =>\n disableWrapperAria\n ? {}\n : {\n \"aria-expanded\": isShown,\n \"aria-haspopup\": ariaHasPopup ? ariaHasPopup : true,\n },\n [isShown, ariaHasPopup, disableWrapperAria]\n );\n\n // In cases where a controlled popout is used (e.g. props.isOpen is true), we need\n // to wait for the targetRef to receive a value before rendering the popout. Otherwise,\n // the Popout component renders, but doesn't know how to position itself due the\n // `refereElement` property being undefined.\n const [shouldRenderPopout, setShouldRenderPopout] = useState<boolean>( // Only trigger this shouldRenderPopout logic when using a controlled component.\n // The reason for that is because controlled components may render the popout\n // immediately before the targetRef has a value set to it.\n !isControlled\n );\n\n // Reset the locked placement when the popout is closed\n useEffect(() => {\n if (!isShown && lockedPlacement) {\n setLockedPlacement(undefined);\n }\n }, [isShown, lockedPlacement]);\n\n const childrenRef = (el: React.ElementRef<any> | HTMLElement) => {\n targetRef.current = el;\n\n if (targetRef.current) {\n setShouldRenderPopout(true);\n }\n };\n\n return (\n <React.Fragment>\n {typeof children === \"function\" ? (\n children({\n ref: childrenRef,\n toggle,\n show,\n hide,\n ariaProps,\n })\n ) : (\n <TargetWrapper {...qa} id={id} {...rest} ref={childrenRef}>\n {React.cloneElement(children, {\n ...ariaProps,\n ...(!isControlled\n ? {\n onClick: toggle,\n }\n : undefined),\n })}\n </TargetWrapper>\n )}\n {shouldRenderPopout && !isInvalidContent && (\n <AnimatePresence>\n {isShown && (\n <PopoutComponentWrapper>\n <Popper\n referenceElement={targetRef.current}\n placement={\n lockPlacement && lockedPlacement ? lockedPlacement : placement\n }\n modifiers={{\n preventOverflow: {\n boundariesElement: \"viewport\",\n },\n // Disable flip after locking when lockPlacement is true\n flip: { enabled: !(lockPlacement && lockedPlacement) },\n ...popperModifiers,\n }}\n {...restPopperProps}\n >\n {({\n ref,\n style,\n placement: actualPlacement,\n outOfBoundaries,\n scheduleUpdate,\n }) => {\n // HACK: We use setTimeout to defer locking the placement until after render,\n // because Popper v1 only exposes the computed placement in the render prop,\n // and React does not allow setState during render.\n if (lockPlacement && !lockedPlacement && actualPlacement) {\n setTimeout(() => {\n // Check again before setting to avoid a race condition\n if (\n lockPlacement &&\n !lockedPlacement &&\n actualPlacement\n ) {\n setLockedPlacement(actualPlacement);\n }\n }, 0);\n }\n\n const interceptRef = (el: HTMLDivElement | undefined) => {\n popoutRef.current = el;\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n ref(el);\n };\n\n scheduleUpdateCallback.current = scheduleUpdate;\n scheduleUpdateRef(scheduleUpdate);\n\n return (\n <div\n ref={interceptRef}\n style={{\n ...style,\n zIndex,\n width:\n fullWidth && targetRef.current\n ? targetRef.current.offsetWidth\n : \"initial\",\n }}\n data-placement={actualPlacement}\n data-qa-popout=\"\"\n data-qa-popout-isopen={isOpen === true}\n // TODO: fix this type since `color` should be valid here. TS can't resolve the correct type.\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n color={color}\n {...rest}\n >\n {!outOfBoundaries && (\n <motion.div\n {...animationConfig}\n // pass the placement in the custom prop so it can be used in the animation\n custom={{\n placement: actualPlacement,\n ...animationConfig.custom,\n }}\n >\n <FocusLock\n autoFocus={autoFocus}\n returnFocus={returnFocus}\n disabled={!focusOnContent}\n {...restFocusLockProps}\n >\n {typeof content === \"function\" &&\n content({\n hide,\n actualPlacement,\n })}\n {typeof content !== \"function\" && content}\n </FocusLock>\n </motion.div>\n )}\n </div>\n );\n }}\n </Popper>\n </PopoutComponentWrapper>\n )}\n </AnimatePresence>\n )}\n </React.Fragment>\n );\n}\n\nconst PopoutContent = ({ children, ...rest }: TypeBoxProps) => (\n <Box\n bg=\"container.background.base\"\n color=\"text.body\"\n border={500}\n borderColor=\"container.border.base\"\n borderRadius=\"outer\"\n boxShadow=\"medium\"\n p={400}\n m={300}\n {...rest}\n >\n {children}\n </Box>\n);\n\nPopoutContent.displayName = \"Popout.Content\";\nPopout.Content = PopoutContent;\n\nexport default Popout;\n","import styled from \"styled-components\";\nimport { COMMON, LAYOUT } from \"@sproutsocial/seeds-react-system-props\";\n\nexport const TargetWrapper = styled.div`\n display: inline-block;\n ${COMMON}\n ${LAYOUT}\n`;\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport * as React from \"react\";\nimport type { PopperProps } from \"react-popper\";\nimport type {\n TypeSystemCommonProps,\n TypeSystemLayoutProps,\n TypeStyledComponentsCommonProps,\n} from \"@sproutsocial/seeds-react-system-props\";\nimport type { HTMLMotionProps } from \"motion/react\";\n\nexport type EnumPlacements = Exclude<PopperProps[\"placement\"], undefined>;\n\nexport interface TypeFocusLockProps {\n disabled?: boolean;\n returnFocus?:\n | boolean\n | FocusOptions\n | ((returnTo: Element) => boolean | FocusOptions);\n persistentFocus?: boolean;\n autoFocus?: boolean;\n crossFrame?: boolean;\n noFocusGuards?: boolean | \"tail\";\n group?: string;\n className?: string;\n onActivation?: (node: HTMLElement) => void;\n onDeactivation?: (node: HTMLElement) => void;\n as?: TypeStyledComponentsCommonProps[\"as\"];\n lockProps?: any;\n ref?: any;\n whiteList?: (activeElement: HTMLElement) => boolean;\n shards?: Array<any>;\n children?: React.ReactNode;\n}\n\nexport interface TypePopoutProps\n extends TypeStyledComponentsCommonProps,\n TypeSystemCommonProps,\n TypeSystemLayoutProps,\n Omit<\n React.ComponentPropsWithoutRef<\"div\">,\n \"color\" | \"children\" | \"content\"\n > {\n /**\n * Whether Popout should automatically add aria-attributes to its wrapped elements\n */\n disableWrapperAria?: boolean;\n /**\n * Is the popout open? This prop is optional. By using it, you will lose some automatic handling of the logic for opening and closing the popout.\n */\n isOpen?: boolean;\n\n /**\n * If you use the isOpen prop you will need to pass a handler to change the state of the popout\n */\n setIsOpen?: (isOpen: boolean, event?: MouseEvent | KeyboardEvent) => void;\n\n /**\n * The content to be shown in the popout. If there is no content, just the children are rendered\n */\n content:\n | (React.ReactElement<any> | null | undefined)\n | (\n | ((opts: {\n hide: () => void;\n actualPlacement: EnumPlacements;\n }) => React.ReactElement<any>)\n | null\n | undefined\n );\n\n /**\n * The content that the popout should be attached to\n */\n children:\n | React.ReactElement<any>\n | ((opts: {\n ref: (arg0: React.ElementRef<any> | HTMLElement) => void;\n toggle: () => void;\n show: () => void;\n hide: () => void;\n ariaProps: Record<string, any>;\n }) => React.ReactNode);\n\n /** How the popped-out content should be placed, in relationship to the children */\n placement?: EnumPlacements;\n\n /**\n * Should the popout be locked in place? This will prevent it from moving when the user scrolls or if the height of the popout changes.\n * This is useful for modals and other places where you want the popout to stay in place\n * after it has been opened but want to use an auto placement strategy.\n */\n lockPlacement?: boolean;\n\n /**\n * Should the popped-out content inherit its width from the children?\n * This is useful for typeaheads and other places where a popout needs to match the width of a given element.\n */\n fullWidth?: boolean;\n\n /**\n * When the popout has opened, should we focus on its content?\n * Focus will be brought inside by looking for elements with [autofocus] first, [tabindex] second and buttons/links/other natively-focusable elements last.\n * Upon closing the popout, focus will be returned to the popout's target.\n * If nothing within your popout's content is focusable, this prop will do nothing.\n */\n focusOnContent?: boolean;\n qa?: Record<string, string>;\n zIndex?: number;\n /** Used to override the default Popout animations.\n * Any props that are valid for use on a Motion div can be passed here as an object.\n * See https://motion.dev/docs/react-motion-component#props */\n animationConfig?: Omit<HTMLMotionProps<\"div\">, \"children\">;\n\n /**\n * Override react-popper per the API documentation here: https://github.com/FezVrasta/react-popper#api-documentation\n */\n popperProps?: Partial<PopperProps>;\n onClose?: () => void;\n onOpen?: () => void;\n\n /**\n * An optional callback to receive the scheduleUpdate function.\n * Use the function to recalculate the popout position in relation to the contents.\n */\n scheduleUpdateRef?: (arg0: () => void) => void;\n\n /**\n * Mount the popout at the bottom of the DOM (using React.Portal) instead of inside the current DOM tree\n */\n appendToBody?: boolean;\n\n /**\n * Override `FocusLock` props, see the API documentation for more details: https://github.com/theKashey/react-focus-lock#api\n */\n focusLockProps?: TypeFocusLockProps;\n}\n","import * as React from \"react\";\nimport { AnimatePresence, motion } from \"motion/react\";\nimport * as Popover from \"@radix-ui/react-popover\";\nimport { MOTION_DURATION_FAST } from \"@sproutsocial/seeds-motion/unitless\";\nimport type { TypePopoutProps } from \"./PopoutTypes\";\nimport styled from \"styled-components\";\n\nconst defaultAnimationConfig = {\n initial: { opacity: 0 },\n animate: { opacity: 1 },\n exit: { opacity: 0 },\n transition: {\n ease: \"circOut\",\n type: \"tween\",\n duration: process.env.NODE_ENV === \"test\" ? 0 : MOTION_DURATION_FAST,\n },\n};\n\nconst StyledMotionDiv = styled(motion.div)`\n background-color: ${({ theme }) => theme.colors.container.background.base};\n border: ${({ theme }) => theme.borders[500]};\n border-color: ${({ theme }) => theme.colors.container.border.base};\n border-radius: ${({ theme }) => theme.radii[500]};\n box-shadow: ${({ theme }) => theme.shadows.medium};\n padding: ${({ theme }) => theme.space[400]};\n`;\n\nexport function Popout({\n children,\n content,\n open,\n defaultOpen,\n onOpenChange,\n animationConfig = defaultAnimationConfig,\n side = \"bottom\",\n sideOffset = 8,\n align = \"center\",\n alignOffset = 0,\n onOpenAutoFocus,\n onEscapeKeyDown,\n onCloseAutoFocus,\n onPointerDownOutside,\n onInteractOutside,\n ...rest\n}: TypePopoutProps) {\n const [isOpen, setIsOpen] = React.useState(defaultOpen ?? false);\n\n const handleOpenChange = React.useCallback(\n (newOpen: boolean) => {\n setIsOpen(newOpen);\n onOpenChange?.(newOpen);\n },\n [onOpenChange]\n );\n\n // Use controlled state if open prop is provided\n const isControlled = open !== undefined;\n const popoverOpen = isControlled ? open : isOpen;\n const popoverOnOpenChange = isControlled ? onOpenChange : handleOpenChange;\n\n // Handle ref forwarding for components that use innerRef instead of ref\n // (e.g., seeds-react-button)\n // Radix UI's asChild passes ref, but Button uses innerRef\n const radixRef = React.useRef<HTMLButtonElement | null>(null);\n\n return (\n <Popover.Root open={popoverOpen} onOpenChange={popoverOnOpenChange}>\n <Popover.Trigger ref={radixRef} asChild>\n {children}\n </Popover.Trigger>\n <Popover.Portal>\n <Popover.Content\n side={side}\n sideOffset={sideOffset}\n align={align}\n alignOffset={alignOffset}\n onOpenAutoFocus={onOpenAutoFocus}\n onEscapeKeyDown={onEscapeKeyDown}\n onCloseAutoFocus={onCloseAutoFocus}\n onPointerDownOutside={onPointerDownOutside}\n onInteractOutside={onInteractOutside}\n >\n <StyledMotionDiv {...animationConfig} {...rest}>\n {content}\n </StyledMotionDiv>\n </Popover.Content>\n </Popover.Portal>\n </Popover.Root>\n );\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport * as React from \"react\";\nimport type {\n TypeSystemCommonProps,\n TypeSystemLayoutProps,\n TypeStyledComponentsCommonProps,\n} from \"@sproutsocial/seeds-react-system-props\";\nimport type { HTMLMotionProps } from \"motion/react\";\n\nexport interface TypePopoutProps\n extends TypeStyledComponentsCommonProps,\n TypeSystemCommonProps,\n TypeSystemLayoutProps,\n Omit<\n React.ComponentPropsWithoutRef<\"div\">,\n \"color\" | \"children\" | \"content\"\n > {\n /**\n * The content that the popout should be attached to (renders in Popover.Trigger)\n */\n children: React.ReactElement<any>;\n\n /**\n * The content to be shown in the popout (renders in Popover.Content)\n */\n content: React.ReactNode;\n\n /**\n * Whether the popout is open (controlled)\n */\n open?: boolean;\n\n /**\n * Default open state (uncontrolled)\n */\n defaultOpen?: boolean;\n\n /**\n * Callback fired when the open state changes\n */\n onOpenChange?: (open: boolean) => void;\n\n /**\n * Used to override the default Popout animations.\n * Any props that are valid for use on a Motion div can be passed here as an object.\n * See https://motion.dev/docs/react-motion-component#props\n */\n animationConfig?: Omit<HTMLMotionProps<\"div\">, \"children\">;\n\n /**\n * The preferred side of the trigger to render against when open.\n * @default \"bottom\"\n */\n side?: \"top\" | \"right\" | \"bottom\" | \"left\";\n\n /**\n * The distance in pixels from the trigger.\n * @default 8\n */\n sideOffset?: number;\n\n /**\n * The preferred alignment against the trigger.\n * @default \"center\"\n */\n align?: \"start\" | \"center\" | \"end\";\n\n /**\n * An offset in pixels from the \"start\" or \"end\" alignment options.\n * @default 0\n */\n alignOffset?: number;\n\n /**\n * Event handler called when the popout content tries to auto-focus on open.\n * Can be used to prevent the default auto-focus behavior or customize it.\n * If not provided, defaults to allowing auto-focus on the content.\n */\n onOpenAutoFocus?: (event: Event) => void;\n\n /**\n * Event handler called when the Escape key is pressed while the popout is open.\n * Can be used to prevent the default close behavior or customize it.\n */\n onEscapeKeyDown?: (event: KeyboardEvent) => void;\n\n /**\n * Event handler called when the popout tries to return focus to the trigger on close.\n * Can be used to prevent the default focus return behavior or customize it.\n */\n onCloseAutoFocus?: (event: Event) => void;\n\n /**\n * Event handler called when a pointer down event occurs outside the popout content.\n * Call `event.preventDefault()` to prevent the default dismiss behavior.\n * Useful when the Popout is nested inside a Radix Dialog (e.g. ModalV2) to\n * avoid conflicts between nested DismissableLayer instances.\n */\n onPointerDownOutside?: (\n event: CustomEvent<{ originalEvent: PointerEvent }>\n ) => void;\n\n /**\n * Event handler called when an interaction (pointer or focus) occurs outside\n * the popout content. Call `event.preventDefault()` to prevent the popout\n * from closing.\n */\n onInteractOutside?: (event: CustomEvent<{ originalEvent: Event }>) => void;\n}\n"],"mappings":"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","names":["Popout","import_react","styled","Portal","FocusLock","Box","React","React","import_react","import_unitless","import_styled_components","import_jsx_runtime","defaultAnimationConfig","styled","Popout","React"]}
@@ -66,8 +66,25 @@ interface TypePopoutProps extends TypeStyledComponentsCommonProps, TypeSystemCom
66
66
  * Can be used to prevent the default focus return behavior or customize it.
67
67
  */
68
68
  onCloseAutoFocus?: (event: Event) => void;
69
+ /**
70
+ * Event handler called when a pointer down event occurs outside the popout content.
71
+ * Call `event.preventDefault()` to prevent the default dismiss behavior.
72
+ * Useful when the Popout is nested inside a Radix Dialog (e.g. ModalV2) to
73
+ * avoid conflicts between nested DismissableLayer instances.
74
+ */
75
+ onPointerDownOutside?: (event: CustomEvent<{
76
+ originalEvent: PointerEvent;
77
+ }>) => void;
78
+ /**
79
+ * Event handler called when an interaction (pointer or focus) occurs outside
80
+ * the popout content. Call `event.preventDefault()` to prevent the popout
81
+ * from closing.
82
+ */
83
+ onInteractOutside?: (event: CustomEvent<{
84
+ originalEvent: Event;
85
+ }>) => void;
69
86
  }
70
87
 
71
- declare function Popout({ children, content, open, defaultOpen, onOpenChange, animationConfig, side, sideOffset, align, alignOffset, onOpenAutoFocus, onEscapeKeyDown, onCloseAutoFocus, ...rest }: TypePopoutProps): react_jsx_runtime.JSX.Element;
88
+ declare function Popout({ children, content, open, defaultOpen, onOpenChange, animationConfig, side, sideOffset, align, alignOffset, onOpenAutoFocus, onEscapeKeyDown, onCloseAutoFocus, onPointerDownOutside, onInteractOutside, ...rest }: TypePopoutProps): react_jsx_runtime.JSX.Element;
72
89
 
73
90
  export { Popout, type TypePopoutProps };
@@ -66,8 +66,25 @@ interface TypePopoutProps extends TypeStyledComponentsCommonProps, TypeSystemCom
66
66
  * Can be used to prevent the default focus return behavior or customize it.
67
67
  */
68
68
  onCloseAutoFocus?: (event: Event) => void;
69
+ /**
70
+ * Event handler called when a pointer down event occurs outside the popout content.
71
+ * Call `event.preventDefault()` to prevent the default dismiss behavior.
72
+ * Useful when the Popout is nested inside a Radix Dialog (e.g. ModalV2) to
73
+ * avoid conflicts between nested DismissableLayer instances.
74
+ */
75
+ onPointerDownOutside?: (event: CustomEvent<{
76
+ originalEvent: PointerEvent;
77
+ }>) => void;
78
+ /**
79
+ * Event handler called when an interaction (pointer or focus) occurs outside
80
+ * the popout content. Call `event.preventDefault()` to prevent the popout
81
+ * from closing.
82
+ */
83
+ onInteractOutside?: (event: CustomEvent<{
84
+ originalEvent: Event;
85
+ }>) => void;
69
86
  }
70
87
 
71
- declare function Popout({ children, content, open, defaultOpen, onOpenChange, animationConfig, side, sideOffset, align, alignOffset, onOpenAutoFocus, onEscapeKeyDown, onCloseAutoFocus, ...rest }: TypePopoutProps): react_jsx_runtime.JSX.Element;
88
+ declare function Popout({ children, content, open, defaultOpen, onOpenChange, animationConfig, side, sideOffset, align, alignOffset, onOpenAutoFocus, onEscapeKeyDown, onCloseAutoFocus, onPointerDownOutside, onInteractOutside, ...rest }: TypePopoutProps): react_jsx_runtime.JSX.Element;
72
89
 
73
90
  export { Popout, type TypePopoutProps };
package/dist/v2/index.js CHANGED
@@ -73,6 +73,8 @@ function Popout({
73
73
  onOpenAutoFocus,
74
74
  onEscapeKeyDown,
75
75
  onCloseAutoFocus,
76
+ onPointerDownOutside,
77
+ onInteractOutside,
76
78
  ...rest
77
79
  }) {
78
80
  const [isOpen, setIsOpen] = React.useState(defaultOpen ?? false);
@@ -99,6 +101,8 @@ function Popout({
99
101
  onOpenAutoFocus,
100
102
  onEscapeKeyDown,
101
103
  onCloseAutoFocus,
104
+ onPointerDownOutside,
105
+ onInteractOutside,
102
106
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(StyledMotionDiv, { ...animationConfig, ...rest, children: content })
103
107
  }
104
108
  ) })
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/v2/index.ts","../../src/v2/Popout.tsx","../../src/v2/PopoutTypes.ts"],"sourcesContent":["export * from \"./Popout\";\nexport * from \"./PopoutTypes\";\n","import * as React from \"react\";\nimport { AnimatePresence, motion } from \"motion/react\";\nimport * as Popover from \"@radix-ui/react-popover\";\nimport { MOTION_DURATION_FAST } from \"@sproutsocial/seeds-motion/unitless\";\nimport type { TypePopoutProps } from \"./PopoutTypes\";\nimport styled from \"styled-components\";\n\nconst defaultAnimationConfig = {\n initial: { opacity: 0 },\n animate: { opacity: 1 },\n exit: { opacity: 0 },\n transition: {\n ease: \"circOut\",\n type: \"tween\",\n duration: process.env.NODE_ENV === \"test\" ? 0 : MOTION_DURATION_FAST,\n },\n};\n\nconst StyledMotionDiv = styled(motion.div)`\n background-color: ${({ theme }) => theme.colors.container.background.base};\n border: ${({ theme }) => theme.borders[500]};\n border-color: ${({ theme }) => theme.colors.container.border.base};\n border-radius: ${({ theme }) => theme.radii[500]};\n box-shadow: ${({ theme }) => theme.shadows.medium};\n padding: ${({ theme }) => theme.space[400]};\n`;\n\nexport function Popout({\n children,\n content,\n open,\n defaultOpen,\n onOpenChange,\n animationConfig = defaultAnimationConfig,\n side = \"bottom\",\n sideOffset = 8,\n align = \"center\",\n alignOffset = 0,\n onOpenAutoFocus,\n onEscapeKeyDown,\n onCloseAutoFocus,\n ...rest\n}: TypePopoutProps) {\n const [isOpen, setIsOpen] = React.useState(defaultOpen ?? false);\n\n const handleOpenChange = React.useCallback(\n (newOpen: boolean) => {\n setIsOpen(newOpen);\n onOpenChange?.(newOpen);\n },\n [onOpenChange]\n );\n\n // Use controlled state if open prop is provided\n const isControlled = open !== undefined;\n const popoverOpen = isControlled ? open : isOpen;\n const popoverOnOpenChange = isControlled ? onOpenChange : handleOpenChange;\n\n // Handle ref forwarding for components that use innerRef instead of ref\n // (e.g., seeds-react-button)\n // Radix UI's asChild passes ref, but Button uses innerRef\n const radixRef = React.useRef<HTMLButtonElement | null>(null);\n\n return (\n <Popover.Root open={popoverOpen} onOpenChange={popoverOnOpenChange}>\n <Popover.Trigger ref={radixRef} asChild>\n {children}\n </Popover.Trigger>\n <Popover.Portal>\n <Popover.Content\n side={side}\n sideOffset={sideOffset}\n align={align}\n alignOffset={alignOffset}\n onOpenAutoFocus={onOpenAutoFocus}\n onEscapeKeyDown={onEscapeKeyDown}\n onCloseAutoFocus={onCloseAutoFocus}\n >\n <StyledMotionDiv {...animationConfig} {...rest}>\n {content}\n </StyledMotionDiv>\n </Popover.Content>\n </Popover.Portal>\n </Popover.Root>\n );\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport * as React from \"react\";\nimport type {\n TypeSystemCommonProps,\n TypeSystemLayoutProps,\n TypeStyledComponentsCommonProps,\n} from \"@sproutsocial/seeds-react-system-props\";\nimport type { HTMLMotionProps } from \"motion/react\";\n\nexport interface TypePopoutProps\n extends TypeStyledComponentsCommonProps,\n TypeSystemCommonProps,\n TypeSystemLayoutProps,\n Omit<\n React.ComponentPropsWithoutRef<\"div\">,\n \"color\" | \"children\" | \"content\"\n > {\n /**\n * The content that the popout should be attached to (renders in Popover.Trigger)\n */\n children: React.ReactElement<any>;\n\n /**\n * The content to be shown in the popout (renders in Popover.Content)\n */\n content: React.ReactNode;\n\n /**\n * Whether the popout is open (controlled)\n */\n open?: boolean;\n\n /**\n * Default open state (uncontrolled)\n */\n defaultOpen?: boolean;\n\n /**\n * Callback fired when the open state changes\n */\n onOpenChange?: (open: boolean) => void;\n\n /**\n * Used to override the default Popout animations.\n * Any props that are valid for use on a Motion div can be passed here as an object.\n * See https://motion.dev/docs/react-motion-component#props\n */\n animationConfig?: Omit<HTMLMotionProps<\"div\">, \"children\">;\n\n /**\n * The preferred side of the trigger to render against when open.\n * @default \"bottom\"\n */\n side?: \"top\" | \"right\" | \"bottom\" | \"left\";\n\n /**\n * The distance in pixels from the trigger.\n * @default 8\n */\n sideOffset?: number;\n\n /**\n * The preferred alignment against the trigger.\n * @default \"center\"\n */\n align?: \"start\" | \"center\" | \"end\";\n\n /**\n * An offset in pixels from the \"start\" or \"end\" alignment options.\n * @default 0\n */\n alignOffset?: number;\n\n /**\n * Event handler called when the popout content tries to auto-focus on open.\n * Can be used to prevent the default auto-focus behavior or customize it.\n * If not provided, defaults to allowing auto-focus on the content.\n */\n onOpenAutoFocus?: (event: Event) => void;\n\n /**\n * Event handler called when the Escape key is pressed while the popout is open.\n * Can be used to prevent the default close behavior or customize it.\n */\n onEscapeKeyDown?: (event: KeyboardEvent) => void;\n\n /**\n * Event handler called when the popout tries to return focus to the trigger on close.\n * Can be used to prevent the default focus return behavior or customize it.\n */\n onCloseAutoFocus?: (event: Event) => void;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,YAAuB;AACvB,mBAAwC;AACxC,cAAyB;AACzB,sBAAqC;AAErC,+BAAmB;AA2Df;AAzDJ,IAAM,yBAAyB;AAAA,EAC7B,SAAS,EAAE,SAAS,EAAE;AAAA,EACtB,SAAS,EAAE,SAAS,EAAE;AAAA,EACtB,MAAM,EAAE,SAAS,EAAE;AAAA,EACnB,YAAY;AAAA,IACV,MAAM;AAAA,IACN,MAAM;AAAA,IACN,UAAU,QAAQ,IAAI,aAAa,SAAS,IAAI;AAAA,EAClD;AACF;AAEA,IAAM,sBAAkB,yBAAAA,SAAO,oBAAO,GAAG;AAAA,sBACnB,CAAC,EAAE,MAAM,MAAM,MAAM,OAAO,UAAU,WAAW,IAAI;AAAA,YAC/D,CAAC,EAAE,MAAM,MAAM,MAAM,QAAQ,GAAG,CAAC;AAAA,kBAC3B,CAAC,EAAE,MAAM,MAAM,MAAM,OAAO,UAAU,OAAO,IAAI;AAAA,mBAChD,CAAC,EAAE,MAAM,MAAM,MAAM,MAAM,GAAG,CAAC;AAAA,gBAClC,CAAC,EAAE,MAAM,MAAM,MAAM,QAAQ,MAAM;AAAA,aACtC,CAAC,EAAE,MAAM,MAAM,MAAM,MAAM,GAAG,CAAC;AAAA;AAGrC,SAAS,OAAO;AAAA,EACrB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,kBAAkB;AAAA,EAClB,OAAO;AAAA,EACP,aAAa;AAAA,EACb,QAAQ;AAAA,EACR,cAAc;AAAA,EACd;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAoB;AAClB,QAAM,CAAC,QAAQ,SAAS,IAAU,eAAS,eAAe,KAAK;AAE/D,QAAM,mBAAyB;AAAA,IAC7B,CAAC,YAAqB;AACpB,gBAAU,OAAO;AACjB,qBAAe,OAAO;AAAA,IACxB;AAAA,IACA,CAAC,YAAY;AAAA,EACf;AAGA,QAAM,eAAe,SAAS;AAC9B,QAAM,cAAc,eAAe,OAAO;AAC1C,QAAM,sBAAsB,eAAe,eAAe;AAK1D,QAAM,WAAiB,aAAiC,IAAI;AAE5D,SACE,6CAAS,cAAR,EAAa,MAAM,aAAa,cAAc,qBAC7C;AAAA,gDAAS,iBAAR,EAAgB,KAAK,UAAU,SAAO,MACpC,UACH;AAAA,IACA,4CAAS,gBAAR,EACC;AAAA,MAAS;AAAA,MAAR;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QAEA,sDAAC,mBAAiB,GAAG,iBAAkB,GAAG,MACvC,mBACH;AAAA;AAAA,IACF,GACF;AAAA,KACF;AAEJ;;;ACpFA,IAAAC,SAAuB;","names":["styled","React"]}
1
+ {"version":3,"sources":["../../src/v2/index.ts","../../src/v2/Popout.tsx","../../src/v2/PopoutTypes.ts"],"sourcesContent":["export * from \"./Popout\";\nexport * from \"./PopoutTypes\";\n","import * as React from \"react\";\nimport { AnimatePresence, motion } from \"motion/react\";\nimport * as Popover from \"@radix-ui/react-popover\";\nimport { MOTION_DURATION_FAST } from \"@sproutsocial/seeds-motion/unitless\";\nimport type { TypePopoutProps } from \"./PopoutTypes\";\nimport styled from \"styled-components\";\n\nconst defaultAnimationConfig = {\n initial: { opacity: 0 },\n animate: { opacity: 1 },\n exit: { opacity: 0 },\n transition: {\n ease: \"circOut\",\n type: \"tween\",\n duration: process.env.NODE_ENV === \"test\" ? 0 : MOTION_DURATION_FAST,\n },\n};\n\nconst StyledMotionDiv = styled(motion.div)`\n background-color: ${({ theme }) => theme.colors.container.background.base};\n border: ${({ theme }) => theme.borders[500]};\n border-color: ${({ theme }) => theme.colors.container.border.base};\n border-radius: ${({ theme }) => theme.radii[500]};\n box-shadow: ${({ theme }) => theme.shadows.medium};\n padding: ${({ theme }) => theme.space[400]};\n`;\n\nexport function Popout({\n children,\n content,\n open,\n defaultOpen,\n onOpenChange,\n animationConfig = defaultAnimationConfig,\n side = \"bottom\",\n sideOffset = 8,\n align = \"center\",\n alignOffset = 0,\n onOpenAutoFocus,\n onEscapeKeyDown,\n onCloseAutoFocus,\n onPointerDownOutside,\n onInteractOutside,\n ...rest\n}: TypePopoutProps) {\n const [isOpen, setIsOpen] = React.useState(defaultOpen ?? false);\n\n const handleOpenChange = React.useCallback(\n (newOpen: boolean) => {\n setIsOpen(newOpen);\n onOpenChange?.(newOpen);\n },\n [onOpenChange]\n );\n\n // Use controlled state if open prop is provided\n const isControlled = open !== undefined;\n const popoverOpen = isControlled ? open : isOpen;\n const popoverOnOpenChange = isControlled ? onOpenChange : handleOpenChange;\n\n // Handle ref forwarding for components that use innerRef instead of ref\n // (e.g., seeds-react-button)\n // Radix UI's asChild passes ref, but Button uses innerRef\n const radixRef = React.useRef<HTMLButtonElement | null>(null);\n\n return (\n <Popover.Root open={popoverOpen} onOpenChange={popoverOnOpenChange}>\n <Popover.Trigger ref={radixRef} asChild>\n {children}\n </Popover.Trigger>\n <Popover.Portal>\n <Popover.Content\n side={side}\n sideOffset={sideOffset}\n align={align}\n alignOffset={alignOffset}\n onOpenAutoFocus={onOpenAutoFocus}\n onEscapeKeyDown={onEscapeKeyDown}\n onCloseAutoFocus={onCloseAutoFocus}\n onPointerDownOutside={onPointerDownOutside}\n onInteractOutside={onInteractOutside}\n >\n <StyledMotionDiv {...animationConfig} {...rest}>\n {content}\n </StyledMotionDiv>\n </Popover.Content>\n </Popover.Portal>\n </Popover.Root>\n );\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport * as React from \"react\";\nimport type {\n TypeSystemCommonProps,\n TypeSystemLayoutProps,\n TypeStyledComponentsCommonProps,\n} from \"@sproutsocial/seeds-react-system-props\";\nimport type { HTMLMotionProps } from \"motion/react\";\n\nexport interface TypePopoutProps\n extends TypeStyledComponentsCommonProps,\n TypeSystemCommonProps,\n TypeSystemLayoutProps,\n Omit<\n React.ComponentPropsWithoutRef<\"div\">,\n \"color\" | \"children\" | \"content\"\n > {\n /**\n * The content that the popout should be attached to (renders in Popover.Trigger)\n */\n children: React.ReactElement<any>;\n\n /**\n * The content to be shown in the popout (renders in Popover.Content)\n */\n content: React.ReactNode;\n\n /**\n * Whether the popout is open (controlled)\n */\n open?: boolean;\n\n /**\n * Default open state (uncontrolled)\n */\n defaultOpen?: boolean;\n\n /**\n * Callback fired when the open state changes\n */\n onOpenChange?: (open: boolean) => void;\n\n /**\n * Used to override the default Popout animations.\n * Any props that are valid for use on a Motion div can be passed here as an object.\n * See https://motion.dev/docs/react-motion-component#props\n */\n animationConfig?: Omit<HTMLMotionProps<\"div\">, \"children\">;\n\n /**\n * The preferred side of the trigger to render against when open.\n * @default \"bottom\"\n */\n side?: \"top\" | \"right\" | \"bottom\" | \"left\";\n\n /**\n * The distance in pixels from the trigger.\n * @default 8\n */\n sideOffset?: number;\n\n /**\n * The preferred alignment against the trigger.\n * @default \"center\"\n */\n align?: \"start\" | \"center\" | \"end\";\n\n /**\n * An offset in pixels from the \"start\" or \"end\" alignment options.\n * @default 0\n */\n alignOffset?: number;\n\n /**\n * Event handler called when the popout content tries to auto-focus on open.\n * Can be used to prevent the default auto-focus behavior or customize it.\n * If not provided, defaults to allowing auto-focus on the content.\n */\n onOpenAutoFocus?: (event: Event) => void;\n\n /**\n * Event handler called when the Escape key is pressed while the popout is open.\n * Can be used to prevent the default close behavior or customize it.\n */\n onEscapeKeyDown?: (event: KeyboardEvent) => void;\n\n /**\n * Event handler called when the popout tries to return focus to the trigger on close.\n * Can be used to prevent the default focus return behavior or customize it.\n */\n onCloseAutoFocus?: (event: Event) => void;\n\n /**\n * Event handler called when a pointer down event occurs outside the popout content.\n * Call `event.preventDefault()` to prevent the default dismiss behavior.\n * Useful when the Popout is nested inside a Radix Dialog (e.g. ModalV2) to\n * avoid conflicts between nested DismissableLayer instances.\n */\n onPointerDownOutside?: (\n event: CustomEvent<{ originalEvent: PointerEvent }>\n ) => void;\n\n /**\n * Event handler called when an interaction (pointer or focus) occurs outside\n * the popout content. Call `event.preventDefault()` to prevent the popout\n * from closing.\n */\n onInteractOutside?: (event: CustomEvent<{ originalEvent: Event }>) => void;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,YAAuB;AACvB,mBAAwC;AACxC,cAAyB;AACzB,sBAAqC;AAErC,+BAAmB;AA6Df;AA3DJ,IAAM,yBAAyB;AAAA,EAC7B,SAAS,EAAE,SAAS,EAAE;AAAA,EACtB,SAAS,EAAE,SAAS,EAAE;AAAA,EACtB,MAAM,EAAE,SAAS,EAAE;AAAA,EACnB,YAAY;AAAA,IACV,MAAM;AAAA,IACN,MAAM;AAAA,IACN,UAAU,QAAQ,IAAI,aAAa,SAAS,IAAI;AAAA,EAClD;AACF;AAEA,IAAM,sBAAkB,yBAAAA,SAAO,oBAAO,GAAG;AAAA,sBACnB,CAAC,EAAE,MAAM,MAAM,MAAM,OAAO,UAAU,WAAW,IAAI;AAAA,YAC/D,CAAC,EAAE,MAAM,MAAM,MAAM,QAAQ,GAAG,CAAC;AAAA,kBAC3B,CAAC,EAAE,MAAM,MAAM,MAAM,OAAO,UAAU,OAAO,IAAI;AAAA,mBAChD,CAAC,EAAE,MAAM,MAAM,MAAM,MAAM,GAAG,CAAC;AAAA,gBAClC,CAAC,EAAE,MAAM,MAAM,MAAM,QAAQ,MAAM;AAAA,aACtC,CAAC,EAAE,MAAM,MAAM,MAAM,MAAM,GAAG,CAAC;AAAA;AAGrC,SAAS,OAAO;AAAA,EACrB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,kBAAkB;AAAA,EAClB,OAAO;AAAA,EACP,aAAa;AAAA,EACb,QAAQ;AAAA,EACR,cAAc;AAAA,EACd;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAoB;AAClB,QAAM,CAAC,QAAQ,SAAS,IAAU,eAAS,eAAe,KAAK;AAE/D,QAAM,mBAAyB;AAAA,IAC7B,CAAC,YAAqB;AACpB,gBAAU,OAAO;AACjB,qBAAe,OAAO;AAAA,IACxB;AAAA,IACA,CAAC,YAAY;AAAA,EACf;AAGA,QAAM,eAAe,SAAS;AAC9B,QAAM,cAAc,eAAe,OAAO;AAC1C,QAAM,sBAAsB,eAAe,eAAe;AAK1D,QAAM,WAAiB,aAAiC,IAAI;AAE5D,SACE,6CAAS,cAAR,EAAa,MAAM,aAAa,cAAc,qBAC7C;AAAA,gDAAS,iBAAR,EAAgB,KAAK,UAAU,SAAO,MACpC,UACH;AAAA,IACA,4CAAS,gBAAR,EACC;AAAA,MAAS;AAAA,MAAR;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QAEA,sDAAC,mBAAiB,GAAG,iBAAkB,GAAG,MACvC,mBACH;AAAA;AAAA,IACF,GACF;AAAA,KACF;AAEJ;;;ACxFA,IAAAC,SAAuB;","names":["styled","React"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sproutsocial/seeds-react-popout",
3
- "version": "2.4.22",
3
+ "version": "2.4.25",
4
4
  "description": "Seeds React Popout",
5
5
  "author": "Sprout Social, Inc.",
6
6
  "license": "MIT",
@@ -35,10 +35,10 @@
35
35
  "dependencies": {
36
36
  "@radix-ui/react-popover": "^1.1.2",
37
37
  "@sproutsocial/seeds-motion": "^1.8.2",
38
- "@sproutsocial/seeds-react-box": "^1.1.12",
39
- "@sproutsocial/seeds-react-button": "^1.3.16",
40
- "@sproutsocial/seeds-react-hooks": "^3.1.4",
41
- "@sproutsocial/seeds-react-portal": "^1.1.4",
38
+ "@sproutsocial/seeds-react-box": "^1.1.13",
39
+ "@sproutsocial/seeds-react-button": "^1.3.18",
40
+ "@sproutsocial/seeds-react-hooks": "^3.1.5",
41
+ "@sproutsocial/seeds-react-portal": "^1.2.0",
42
42
  "@sproutsocial/seeds-react-system-props": "^3.0.2",
43
43
  "motion": "^12.6.3",
44
44
  "react-focus-lock": "^2.0.3",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/v2/Popout.tsx","../../src/v2/PopoutTypes.ts"],"sourcesContent":["import * as React from \"react\";\nimport { AnimatePresence, motion } from \"motion/react\";\nimport * as Popover from \"@radix-ui/react-popover\";\nimport { MOTION_DURATION_FAST } from \"@sproutsocial/seeds-motion/unitless\";\nimport type { TypePopoutProps } from \"./PopoutTypes\";\nimport styled from \"styled-components\";\n\nconst defaultAnimationConfig = {\n initial: { opacity: 0 },\n animate: { opacity: 1 },\n exit: { opacity: 0 },\n transition: {\n ease: \"circOut\",\n type: \"tween\",\n duration: process.env.NODE_ENV === \"test\" ? 0 : MOTION_DURATION_FAST,\n },\n};\n\nconst StyledMotionDiv = styled(motion.div)`\n background-color: ${({ theme }) => theme.colors.container.background.base};\n border: ${({ theme }) => theme.borders[500]};\n border-color: ${({ theme }) => theme.colors.container.border.base};\n border-radius: ${({ theme }) => theme.radii[500]};\n box-shadow: ${({ theme }) => theme.shadows.medium};\n padding: ${({ theme }) => theme.space[400]};\n`;\n\nexport function Popout({\n children,\n content,\n open,\n defaultOpen,\n onOpenChange,\n animationConfig = defaultAnimationConfig,\n side = \"bottom\",\n sideOffset = 8,\n align = \"center\",\n alignOffset = 0,\n onOpenAutoFocus,\n onEscapeKeyDown,\n onCloseAutoFocus,\n ...rest\n}: TypePopoutProps) {\n const [isOpen, setIsOpen] = React.useState(defaultOpen ?? false);\n\n const handleOpenChange = React.useCallback(\n (newOpen: boolean) => {\n setIsOpen(newOpen);\n onOpenChange?.(newOpen);\n },\n [onOpenChange]\n );\n\n // Use controlled state if open prop is provided\n const isControlled = open !== undefined;\n const popoverOpen = isControlled ? open : isOpen;\n const popoverOnOpenChange = isControlled ? onOpenChange : handleOpenChange;\n\n // Handle ref forwarding for components that use innerRef instead of ref\n // (e.g., seeds-react-button)\n // Radix UI's asChild passes ref, but Button uses innerRef\n const radixRef = React.useRef<HTMLButtonElement | null>(null);\n\n return (\n <Popover.Root open={popoverOpen} onOpenChange={popoverOnOpenChange}>\n <Popover.Trigger ref={radixRef} asChild>\n {children}\n </Popover.Trigger>\n <Popover.Portal>\n <Popover.Content\n side={side}\n sideOffset={sideOffset}\n align={align}\n alignOffset={alignOffset}\n onOpenAutoFocus={onOpenAutoFocus}\n onEscapeKeyDown={onEscapeKeyDown}\n onCloseAutoFocus={onCloseAutoFocus}\n >\n <StyledMotionDiv {...animationConfig} {...rest}>\n {content}\n </StyledMotionDiv>\n </Popover.Content>\n </Popover.Portal>\n </Popover.Root>\n );\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport * as React from \"react\";\nimport type {\n TypeSystemCommonProps,\n TypeSystemLayoutProps,\n TypeStyledComponentsCommonProps,\n} from \"@sproutsocial/seeds-react-system-props\";\nimport type { HTMLMotionProps } from \"motion/react\";\n\nexport interface TypePopoutProps\n extends TypeStyledComponentsCommonProps,\n TypeSystemCommonProps,\n TypeSystemLayoutProps,\n Omit<\n React.ComponentPropsWithoutRef<\"div\">,\n \"color\" | \"children\" | \"content\"\n > {\n /**\n * The content that the popout should be attached to (renders in Popover.Trigger)\n */\n children: React.ReactElement<any>;\n\n /**\n * The content to be shown in the popout (renders in Popover.Content)\n */\n content: React.ReactNode;\n\n /**\n * Whether the popout is open (controlled)\n */\n open?: boolean;\n\n /**\n * Default open state (uncontrolled)\n */\n defaultOpen?: boolean;\n\n /**\n * Callback fired when the open state changes\n */\n onOpenChange?: (open: boolean) => void;\n\n /**\n * Used to override the default Popout animations.\n * Any props that are valid for use on a Motion div can be passed here as an object.\n * See https://motion.dev/docs/react-motion-component#props\n */\n animationConfig?: Omit<HTMLMotionProps<\"div\">, \"children\">;\n\n /**\n * The preferred side of the trigger to render against when open.\n * @default \"bottom\"\n */\n side?: \"top\" | \"right\" | \"bottom\" | \"left\";\n\n /**\n * The distance in pixels from the trigger.\n * @default 8\n */\n sideOffset?: number;\n\n /**\n * The preferred alignment against the trigger.\n * @default \"center\"\n */\n align?: \"start\" | \"center\" | \"end\";\n\n /**\n * An offset in pixels from the \"start\" or \"end\" alignment options.\n * @default 0\n */\n alignOffset?: number;\n\n /**\n * Event handler called when the popout content tries to auto-focus on open.\n * Can be used to prevent the default auto-focus behavior or customize it.\n * If not provided, defaults to allowing auto-focus on the content.\n */\n onOpenAutoFocus?: (event: Event) => void;\n\n /**\n * Event handler called when the Escape key is pressed while the popout is open.\n * Can be used to prevent the default close behavior or customize it.\n */\n onEscapeKeyDown?: (event: KeyboardEvent) => void;\n\n /**\n * Event handler called when the popout tries to return focus to the trigger on close.\n * Can be used to prevent the default focus return behavior or customize it.\n */\n onCloseAutoFocus?: (event: Event) => void;\n}\n"],"mappings":";AAAA,YAAY,WAAW;AACvB,SAA0B,cAAc;AACxC,YAAY,aAAa;AACzB,SAAS,4BAA4B;AAErC,OAAO,YAAY;AA2Df,SACE,KADF;AAzDJ,IAAM,yBAAyB;AAAA,EAC7B,SAAS,EAAE,SAAS,EAAE;AAAA,EACtB,SAAS,EAAE,SAAS,EAAE;AAAA,EACtB,MAAM,EAAE,SAAS,EAAE;AAAA,EACnB,YAAY;AAAA,IACV,MAAM;AAAA,IACN,MAAM;AAAA,IACN,UAAU,QAAQ,IAAI,aAAa,SAAS,IAAI;AAAA,EAClD;AACF;AAEA,IAAM,kBAAkB,OAAO,OAAO,GAAG;AAAA,sBACnB,CAAC,EAAE,MAAM,MAAM,MAAM,OAAO,UAAU,WAAW,IAAI;AAAA,YAC/D,CAAC,EAAE,MAAM,MAAM,MAAM,QAAQ,GAAG,CAAC;AAAA,kBAC3B,CAAC,EAAE,MAAM,MAAM,MAAM,OAAO,UAAU,OAAO,IAAI;AAAA,mBAChD,CAAC,EAAE,MAAM,MAAM,MAAM,MAAM,GAAG,CAAC;AAAA,gBAClC,CAAC,EAAE,MAAM,MAAM,MAAM,QAAQ,MAAM;AAAA,aACtC,CAAC,EAAE,MAAM,MAAM,MAAM,MAAM,GAAG,CAAC;AAAA;AAGrC,SAAS,OAAO;AAAA,EACrB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,kBAAkB;AAAA,EAClB,OAAO;AAAA,EACP,aAAa;AAAA,EACb,QAAQ;AAAA,EACR,cAAc;AAAA,EACd;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAoB;AAClB,QAAM,CAAC,QAAQ,SAAS,IAAU,eAAS,eAAe,KAAK;AAE/D,QAAM,mBAAyB;AAAA,IAC7B,CAAC,YAAqB;AACpB,gBAAU,OAAO;AACjB,qBAAe,OAAO;AAAA,IACxB;AAAA,IACA,CAAC,YAAY;AAAA,EACf;AAGA,QAAM,eAAe,SAAS;AAC9B,QAAM,cAAc,eAAe,OAAO;AAC1C,QAAM,sBAAsB,eAAe,eAAe;AAK1D,QAAM,WAAiB,aAAiC,IAAI;AAE5D,SACE,qBAAS,cAAR,EAAa,MAAM,aAAa,cAAc,qBAC7C;AAAA,wBAAS,iBAAR,EAAgB,KAAK,UAAU,SAAO,MACpC,UACH;AAAA,IACA,oBAAS,gBAAR,EACC;AAAA,MAAS;AAAA,MAAR;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QAEA,8BAAC,mBAAiB,GAAG,iBAAkB,GAAG,MACvC,mBACH;AAAA;AAAA,IACF,GACF;AAAA,KACF;AAEJ;;;ACpFA,OAAuB;","names":[]}