@sproutsocial/seeds-react-popout 1.2.2 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/index.js +91 -73
- package/dist/esm/index.js.map +1 -1
- package/dist/index.d.mts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +91 -73
- package/dist/index.js.map +1 -1
- package/package.json +8 -7
package/dist/esm/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// src/Popout.tsx
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
import { useState, useEffect, useRef, useCallback, useMemo } from "react";
|
|
4
|
-
import {
|
|
4
|
+
import { AnimatePresence, motion } from "motion/react";
|
|
5
5
|
import FocusLock from "react-focus-lock";
|
|
6
6
|
import { Popper } from "react-popper";
|
|
7
7
|
import { MOTION_DURATION_FAST } from "@sproutsocial/seeds-motion/dist/seeds-motion-unitless";
|
|
@@ -23,21 +23,40 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
23
23
|
var doesRefContainEventTarget = (ref, event) => {
|
|
24
24
|
return ref.current && event.target instanceof Node && ref.current.contains(event.target);
|
|
25
25
|
};
|
|
26
|
-
var
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
},
|
|
30
|
-
|
|
31
|
-
|
|
26
|
+
var defaultAnimationConfig = {
|
|
27
|
+
initial: { opacity: 0 },
|
|
28
|
+
animate: { opacity: 1 },
|
|
29
|
+
exit: { opacity: 0 },
|
|
30
|
+
transition: {
|
|
31
|
+
duration: process.env.NODE_ENV === "test" ? 0 : MOTION_DURATION_FAST
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
var menuAnimationConfig = {
|
|
35
|
+
initial: {
|
|
36
|
+
scale: 0,
|
|
37
|
+
opacity: 0,
|
|
38
|
+
originX: 0,
|
|
39
|
+
originY: 0
|
|
32
40
|
},
|
|
33
|
-
|
|
34
|
-
opacity:
|
|
41
|
+
animate: {
|
|
42
|
+
opacity: 1,
|
|
43
|
+
scale: 1,
|
|
44
|
+
originX: 0,
|
|
45
|
+
originY: 0,
|
|
46
|
+
transition: {
|
|
47
|
+
type: "tween",
|
|
48
|
+
duration: MOTION_DURATION_FAST,
|
|
49
|
+
ease: "circOut"
|
|
50
|
+
}
|
|
35
51
|
},
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
52
|
+
exit: {
|
|
53
|
+
opacity: 0,
|
|
54
|
+
scale: 1,
|
|
55
|
+
transition: {
|
|
56
|
+
type: "tween",
|
|
57
|
+
duration: MOTION_DURATION_FAST,
|
|
58
|
+
ease: "circIn"
|
|
59
|
+
}
|
|
41
60
|
}
|
|
42
61
|
};
|
|
43
62
|
function Popout({
|
|
@@ -62,12 +81,14 @@ function Popout({
|
|
|
62
81
|
"aria-haspopup": ariaHasPopup,
|
|
63
82
|
disableWrapperAria = false,
|
|
64
83
|
id,
|
|
84
|
+
menuPopout = false,
|
|
65
85
|
...rest
|
|
66
86
|
}) {
|
|
67
87
|
const PopoutComponentWrapper = appendToBody ? Portal : React.Fragment;
|
|
68
88
|
const [isInternalShown, setIsInternalShown] = useState(false);
|
|
69
89
|
const isControlled = typeof isOpen === "boolean";
|
|
70
90
|
const isShown = isControlled ? isOpen : isInternalShown;
|
|
91
|
+
const animationConfig = menuPopout ? menuAnimationConfig : defaultAnimationConfig;
|
|
71
92
|
const setIsShown = useMemo(
|
|
72
93
|
() => isControlled && setIsOpen ? setIsOpen : setIsInternalShown,
|
|
73
94
|
[isControlled, setIsOpen]
|
|
@@ -129,7 +150,6 @@ function Popout({
|
|
|
129
150
|
onClose?.();
|
|
130
151
|
}
|
|
131
152
|
}, [isShown, onOpen, onClose]);
|
|
132
|
-
const transition = useTransition(isShown, transitionConfig);
|
|
133
153
|
const ariaProps = useMemo(
|
|
134
154
|
() => disableWrapperAria ? {} : {
|
|
135
155
|
"aria-expanded": isShown,
|
|
@@ -162,66 +182,64 @@ function Popout({
|
|
|
162
182
|
onClick: toggle
|
|
163
183
|
} : void 0
|
|
164
184
|
}) }),
|
|
165
|
-
shouldRenderPopout && !isInvalidContent &&
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
boundariesElement: "viewport"
|
|
174
|
-
}
|
|
175
|
-
},
|
|
176
|
-
...popperProps,
|
|
177
|
-
children: ({
|
|
178
|
-
ref,
|
|
179
|
-
style,
|
|
180
|
-
placement: placement2,
|
|
181
|
-
outOfBoundaries,
|
|
182
|
-
scheduleUpdate
|
|
183
|
-
}) => {
|
|
184
|
-
const interceptRef = (el) => {
|
|
185
|
-
popoutRef.current = el;
|
|
186
|
-
ref(el);
|
|
187
|
-
};
|
|
188
|
-
scheduleUpdateCallback.current = scheduleUpdate;
|
|
189
|
-
scheduleUpdateRef(scheduleUpdate);
|
|
190
|
-
return /* @__PURE__ */ jsx(
|
|
191
|
-
"div",
|
|
192
|
-
{
|
|
193
|
-
ref: interceptRef,
|
|
194
|
-
style: {
|
|
195
|
-
...style,
|
|
196
|
-
zIndex,
|
|
197
|
-
width: fullWidth && targetRef.current ? targetRef.current.offsetWidth : "initial"
|
|
198
|
-
},
|
|
199
|
-
"data-placement": placement2,
|
|
200
|
-
"data-qa-popout": "",
|
|
201
|
-
"data-qa-popout-isopen": isOpen === true,
|
|
202
|
-
color,
|
|
203
|
-
...rest,
|
|
204
|
-
children: isVisible && !outOfBoundaries && /* @__PURE__ */ jsx(animated.div, { style: transitionStyle, children: /* @__PURE__ */ jsxs(
|
|
205
|
-
FocusLock,
|
|
206
|
-
{
|
|
207
|
-
autoFocus,
|
|
208
|
-
returnFocus,
|
|
209
|
-
disabled: !focusOnContent,
|
|
210
|
-
...restFocusLockProps,
|
|
211
|
-
children: [
|
|
212
|
-
typeof content === "function" && content({
|
|
213
|
-
hide
|
|
214
|
-
}),
|
|
215
|
-
typeof content !== "function" && content
|
|
216
|
-
]
|
|
217
|
-
}
|
|
218
|
-
) })
|
|
219
|
-
}
|
|
220
|
-
);
|
|
185
|
+
shouldRenderPopout && !isInvalidContent && /* @__PURE__ */ jsx(AnimatePresence, { children: isShown && /* @__PURE__ */ jsx(PopoutComponentWrapper, { children: /* @__PURE__ */ jsx(
|
|
186
|
+
Popper,
|
|
187
|
+
{
|
|
188
|
+
referenceElement: targetRef.current,
|
|
189
|
+
placement,
|
|
190
|
+
modifiers: {
|
|
191
|
+
preventOverflow: {
|
|
192
|
+
boundariesElement: "viewport"
|
|
221
193
|
}
|
|
194
|
+
},
|
|
195
|
+
...popperProps,
|
|
196
|
+
children: ({
|
|
197
|
+
ref,
|
|
198
|
+
style,
|
|
199
|
+
placement: placement2,
|
|
200
|
+
outOfBoundaries,
|
|
201
|
+
scheduleUpdate
|
|
202
|
+
}) => {
|
|
203
|
+
const interceptRef = (el) => {
|
|
204
|
+
popoutRef.current = el;
|
|
205
|
+
ref(el);
|
|
206
|
+
};
|
|
207
|
+
scheduleUpdateCallback.current = scheduleUpdate;
|
|
208
|
+
scheduleUpdateRef(scheduleUpdate);
|
|
209
|
+
return /* @__PURE__ */ jsx(
|
|
210
|
+
"div",
|
|
211
|
+
{
|
|
212
|
+
ref: interceptRef,
|
|
213
|
+
style: {
|
|
214
|
+
...style,
|
|
215
|
+
zIndex,
|
|
216
|
+
width: fullWidth && targetRef.current ? targetRef.current.offsetWidth : "initial"
|
|
217
|
+
},
|
|
218
|
+
"data-placement": placement2,
|
|
219
|
+
"data-qa-popout": "",
|
|
220
|
+
"data-qa-popout-isopen": isOpen === true,
|
|
221
|
+
color,
|
|
222
|
+
...rest,
|
|
223
|
+
children: !outOfBoundaries && /* @__PURE__ */ jsx(motion.div, { ...animationConfig, children: /* @__PURE__ */ jsxs(
|
|
224
|
+
FocusLock,
|
|
225
|
+
{
|
|
226
|
+
autoFocus,
|
|
227
|
+
returnFocus,
|
|
228
|
+
disabled: !focusOnContent,
|
|
229
|
+
...restFocusLockProps,
|
|
230
|
+
children: [
|
|
231
|
+
typeof content === "function" && content({
|
|
232
|
+
hide
|
|
233
|
+
}),
|
|
234
|
+
typeof content !== "function" && content
|
|
235
|
+
]
|
|
236
|
+
}
|
|
237
|
+
) })
|
|
238
|
+
}
|
|
239
|
+
);
|
|
222
240
|
}
|
|
223
|
-
|
|
224
|
-
)
|
|
241
|
+
}
|
|
242
|
+
) }) })
|
|
225
243
|
] });
|
|
226
244
|
}
|
|
227
245
|
var PopoutContent = ({ children, ...rest }) => /* @__PURE__ */ jsx(
|
package/dist/esm/index.js.map
CHANGED
|
@@ -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 { useState, useEffect, useRef, useCallback, useMemo } from \"react\";\nimport { useTransition, animated } from \"@react-spring/web\";\nimport FocusLock from \"react-focus-lock\";\nimport { Popper } from \"react-popper\";\nimport { MOTION_DURATION_FAST } from \"@sproutsocial/seeds-motion/dist/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\n// Transition definitions for fading in and out\nconst transitionConfig = {\n from: {\n opacity: 0,\n },\n enter: {\n opacity: 1,\n },\n leave: {\n opacity: 0,\n },\n config: {\n duration:\n // skip animation in test environment\n process.env.NODE_ENV === \"test\" ? 0 : MOTION_DURATION_FAST * 1000,\n },\n};\n\nexport function Popout({\n isOpen,\n setIsOpen,\n content,\n children,\n placement = \"auto\",\n fullWidth = false,\n zIndex = 7,\n focusOnContent = true,\n onOpen,\n onClose,\n qa = {},\n popperProps,\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 isControlled = typeof isOpen === \"boolean\";\n const isShown = isControlled ? isOpen : isInternalShown;\n\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 const transition = useTransition(isShown, transitionConfig);\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 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 &&\n !isInvalidContent &&\n transition(\n (transitionStyle, isVisible, transition) =>\n isVisible && (\n <PopoutComponentWrapper key={transition.key}>\n <Popper\n referenceElement={targetRef.current}\n placement={placement}\n modifiers={{\n preventOverflow: {\n boundariesElement: \"viewport\",\n },\n }}\n {...popperProps}\n >\n {({\n ref,\n style,\n placement,\n outOfBoundaries,\n scheduleUpdate,\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={placement}\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 {isVisible && !outOfBoundaries && (\n <animated.div style={transitionStyle}>\n <FocusLock\n autoFocus={autoFocus}\n returnFocus={returnFocus}\n disabled={!focusOnContent}\n {...restFocusLockProps}\n >\n {typeof content === \"function\" &&\n content({\n hide,\n })}\n {typeof content !== \"function\" && content}\n </FocusLock>\n </animated.div>\n )}\n </div>\n );\n }}\n </Popper>\n </PopoutComponentWrapper>\n )\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\";\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 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: { hide: () => void }) => 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 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\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 * And 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\";\n"],"mappings":"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","names":["transition","placement"]}
|
|
1
|
+
{"version":3,"sources":["../../src/Popout.tsx","../../src/styles.ts","../../src/PopoutTypes.ts","../../src/index.ts"],"sourcesContent":["import * as React from \"react\";\nimport { useState, useEffect, useRef, useCallback, useMemo } 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/dist/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 duration: process.env.NODE_ENV === \"test\" ? 0 : MOTION_DURATION_FAST,\n },\n};\n\nconst menuAnimationConfig = {\n initial: {\n scale: 0,\n opacity: 0,\n originX: 0,\n originY: 0,\n },\n animate: {\n opacity: 1,\n scale: 1,\n originX: 0,\n originY: 0,\n\n transition: {\n type: \"tween\",\n duration: MOTION_DURATION_FAST,\n ease: \"circOut\",\n },\n },\n exit: {\n opacity: 0,\n scale: 1,\n transition: {\n type: \"tween\",\n duration: MOTION_DURATION_FAST,\n ease: \"circIn\",\n },\n },\n};\n\nexport function Popout({\n isOpen,\n setIsOpen,\n content,\n children,\n placement = \"auto\",\n fullWidth = false,\n zIndex = 7,\n focusOnContent = true,\n onOpen,\n onClose,\n qa = {},\n popperProps,\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 menuPopout = false,\n ...rest\n}: TypePopoutProps) {\n const PopoutComponentWrapper = appendToBody ? Portal : React.Fragment;\n const [isInternalShown, setIsInternalShown] = useState<boolean>(false);\n const isControlled = typeof isOpen === \"boolean\";\n const isShown = isControlled ? isOpen : isInternalShown;\n const animationConfig = menuPopout\n ? menuAnimationConfig\n : defaultAnimationConfig;\n\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 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={placement}\n modifiers={{\n preventOverflow: {\n boundariesElement: \"viewport\",\n },\n }}\n {...popperProps}\n >\n {({\n ref,\n style,\n placement,\n outOfBoundaries,\n scheduleUpdate,\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={placement}\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 {...animationConfig}>\n <FocusLock\n autoFocus={autoFocus}\n returnFocus={returnFocus}\n disabled={!focusOnContent}\n {...restFocusLockProps}\n >\n {typeof content === \"function\" &&\n content({\n hide,\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\";\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: { hide: () => void }) => 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 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\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 * And 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 menuPopout?: boolean;\n}\n","import Popout from \"./Popout\";\n\nexport default Popout;\nexport { Popout };\nexport * from \"./PopoutTypes\";\n"],"mappings":"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","names":["placement"]}
|
package/dist/index.d.mts
CHANGED
|
@@ -10,6 +10,7 @@ interface TypeFocusLockProps {
|
|
|
10
10
|
returnFocus?: boolean | FocusOptions | ((returnTo: Element) => boolean | FocusOptions);
|
|
11
11
|
persistentFocus?: boolean;
|
|
12
12
|
autoFocus?: boolean;
|
|
13
|
+
crossFrame?: boolean;
|
|
13
14
|
noFocusGuards?: boolean | "tail";
|
|
14
15
|
group?: string;
|
|
15
16
|
className?: string;
|
|
@@ -86,9 +87,10 @@ interface TypePopoutProps extends TypeStyledComponentsCommonProps, TypeSystemCom
|
|
|
86
87
|
* Override `FocusLock` props, see the API documentation for more details: https://github.com/theKashey/react-focus-lock#api
|
|
87
88
|
*/
|
|
88
89
|
focusLockProps?: TypeFocusLockProps;
|
|
90
|
+
menuPopout?: boolean;
|
|
89
91
|
}
|
|
90
92
|
|
|
91
|
-
declare function Popout({ isOpen, setIsOpen, content, children, placement, fullWidth, zIndex, focusOnContent, onOpen, onClose, qa, popperProps, scheduleUpdateRef, appendToBody, focusLockProps, color, "aria-haspopup": ariaHasPopup, disableWrapperAria, id, ...rest }: TypePopoutProps): react_jsx_runtime.JSX.Element;
|
|
93
|
+
declare function Popout({ isOpen, setIsOpen, content, children, placement, fullWidth, zIndex, focusOnContent, onOpen, onClose, qa, popperProps, scheduleUpdateRef, appendToBody, focusLockProps, color, "aria-haspopup": ariaHasPopup, disableWrapperAria, id, menuPopout, ...rest }: TypePopoutProps): react_jsx_runtime.JSX.Element;
|
|
92
94
|
declare namespace Popout {
|
|
93
95
|
var Content: {
|
|
94
96
|
({ children, ...rest }: TypeBoxProps): react_jsx_runtime.JSX.Element;
|
package/dist/index.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ interface TypeFocusLockProps {
|
|
|
10
10
|
returnFocus?: boolean | FocusOptions | ((returnTo: Element) => boolean | FocusOptions);
|
|
11
11
|
persistentFocus?: boolean;
|
|
12
12
|
autoFocus?: boolean;
|
|
13
|
+
crossFrame?: boolean;
|
|
13
14
|
noFocusGuards?: boolean | "tail";
|
|
14
15
|
group?: string;
|
|
15
16
|
className?: string;
|
|
@@ -86,9 +87,10 @@ interface TypePopoutProps extends TypeStyledComponentsCommonProps, TypeSystemCom
|
|
|
86
87
|
* Override `FocusLock` props, see the API documentation for more details: https://github.com/theKashey/react-focus-lock#api
|
|
87
88
|
*/
|
|
88
89
|
focusLockProps?: TypeFocusLockProps;
|
|
90
|
+
menuPopout?: boolean;
|
|
89
91
|
}
|
|
90
92
|
|
|
91
|
-
declare function Popout({ isOpen, setIsOpen, content, children, placement, fullWidth, zIndex, focusOnContent, onOpen, onClose, qa, popperProps, scheduleUpdateRef, appendToBody, focusLockProps, color, "aria-haspopup": ariaHasPopup, disableWrapperAria, id, ...rest }: TypePopoutProps): react_jsx_runtime.JSX.Element;
|
|
93
|
+
declare function Popout({ isOpen, setIsOpen, content, children, placement, fullWidth, zIndex, focusOnContent, onOpen, onClose, qa, popperProps, scheduleUpdateRef, appendToBody, focusLockProps, color, "aria-haspopup": ariaHasPopup, disableWrapperAria, id, menuPopout, ...rest }: TypePopoutProps): react_jsx_runtime.JSX.Element;
|
|
92
94
|
declare namespace Popout {
|
|
93
95
|
var Content: {
|
|
94
96
|
({ children, ...rest }: TypeBoxProps): react_jsx_runtime.JSX.Element;
|
package/dist/index.js
CHANGED
|
@@ -38,7 +38,7 @@ module.exports = __toCommonJS(src_exports);
|
|
|
38
38
|
// src/Popout.tsx
|
|
39
39
|
var React = __toESM(require("react"));
|
|
40
40
|
var import_react = require("react");
|
|
41
|
-
var
|
|
41
|
+
var import_react2 = require("motion/react");
|
|
42
42
|
var import_react_focus_lock = __toESM(require("react-focus-lock"));
|
|
43
43
|
var import_react_popper = require("react-popper");
|
|
44
44
|
var import_seeds_motion_unitless = require("@sproutsocial/seeds-motion/dist/seeds-motion-unitless");
|
|
@@ -60,21 +60,40 @@ var import_jsx_runtime = require("react/jsx-runtime");
|
|
|
60
60
|
var doesRefContainEventTarget = (ref, event) => {
|
|
61
61
|
return ref.current && event.target instanceof Node && ref.current.contains(event.target);
|
|
62
62
|
};
|
|
63
|
-
var
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
},
|
|
67
|
-
|
|
68
|
-
|
|
63
|
+
var defaultAnimationConfig = {
|
|
64
|
+
initial: { opacity: 0 },
|
|
65
|
+
animate: { opacity: 1 },
|
|
66
|
+
exit: { opacity: 0 },
|
|
67
|
+
transition: {
|
|
68
|
+
duration: process.env.NODE_ENV === "test" ? 0 : import_seeds_motion_unitless.MOTION_DURATION_FAST
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
var menuAnimationConfig = {
|
|
72
|
+
initial: {
|
|
73
|
+
scale: 0,
|
|
74
|
+
opacity: 0,
|
|
75
|
+
originX: 0,
|
|
76
|
+
originY: 0
|
|
69
77
|
},
|
|
70
|
-
|
|
71
|
-
opacity:
|
|
78
|
+
animate: {
|
|
79
|
+
opacity: 1,
|
|
80
|
+
scale: 1,
|
|
81
|
+
originX: 0,
|
|
82
|
+
originY: 0,
|
|
83
|
+
transition: {
|
|
84
|
+
type: "tween",
|
|
85
|
+
duration: import_seeds_motion_unitless.MOTION_DURATION_FAST,
|
|
86
|
+
ease: "circOut"
|
|
87
|
+
}
|
|
72
88
|
},
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
89
|
+
exit: {
|
|
90
|
+
opacity: 0,
|
|
91
|
+
scale: 1,
|
|
92
|
+
transition: {
|
|
93
|
+
type: "tween",
|
|
94
|
+
duration: import_seeds_motion_unitless.MOTION_DURATION_FAST,
|
|
95
|
+
ease: "circIn"
|
|
96
|
+
}
|
|
78
97
|
}
|
|
79
98
|
};
|
|
80
99
|
function Popout({
|
|
@@ -99,12 +118,14 @@ function Popout({
|
|
|
99
118
|
"aria-haspopup": ariaHasPopup,
|
|
100
119
|
disableWrapperAria = false,
|
|
101
120
|
id,
|
|
121
|
+
menuPopout = false,
|
|
102
122
|
...rest
|
|
103
123
|
}) {
|
|
104
124
|
const PopoutComponentWrapper = appendToBody ? import_seeds_react_portal.default : React.Fragment;
|
|
105
125
|
const [isInternalShown, setIsInternalShown] = (0, import_react.useState)(false);
|
|
106
126
|
const isControlled = typeof isOpen === "boolean";
|
|
107
127
|
const isShown = isControlled ? isOpen : isInternalShown;
|
|
128
|
+
const animationConfig = menuPopout ? menuAnimationConfig : defaultAnimationConfig;
|
|
108
129
|
const setIsShown = (0, import_react.useMemo)(
|
|
109
130
|
() => isControlled && setIsOpen ? setIsOpen : setIsInternalShown,
|
|
110
131
|
[isControlled, setIsOpen]
|
|
@@ -166,7 +187,6 @@ function Popout({
|
|
|
166
187
|
onClose?.();
|
|
167
188
|
}
|
|
168
189
|
}, [isShown, onOpen, onClose]);
|
|
169
|
-
const transition = (0, import_web.useTransition)(isShown, transitionConfig);
|
|
170
190
|
const ariaProps = (0, import_react.useMemo)(
|
|
171
191
|
() => disableWrapperAria ? {} : {
|
|
172
192
|
"aria-expanded": isShown,
|
|
@@ -199,66 +219,64 @@ function Popout({
|
|
|
199
219
|
onClick: toggle
|
|
200
220
|
} : void 0
|
|
201
221
|
}) }),
|
|
202
|
-
shouldRenderPopout && !isInvalidContent &&
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
boundariesElement: "viewport"
|
|
211
|
-
}
|
|
212
|
-
},
|
|
213
|
-
...popperProps,
|
|
214
|
-
children: ({
|
|
215
|
-
ref,
|
|
216
|
-
style,
|
|
217
|
-
placement: placement2,
|
|
218
|
-
outOfBoundaries,
|
|
219
|
-
scheduleUpdate
|
|
220
|
-
}) => {
|
|
221
|
-
const interceptRef = (el) => {
|
|
222
|
-
popoutRef.current = el;
|
|
223
|
-
ref(el);
|
|
224
|
-
};
|
|
225
|
-
scheduleUpdateCallback.current = scheduleUpdate;
|
|
226
|
-
scheduleUpdateRef(scheduleUpdate);
|
|
227
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
228
|
-
"div",
|
|
229
|
-
{
|
|
230
|
-
ref: interceptRef,
|
|
231
|
-
style: {
|
|
232
|
-
...style,
|
|
233
|
-
zIndex,
|
|
234
|
-
width: fullWidth && targetRef.current ? targetRef.current.offsetWidth : "initial"
|
|
235
|
-
},
|
|
236
|
-
"data-placement": placement2,
|
|
237
|
-
"data-qa-popout": "",
|
|
238
|
-
"data-qa-popout-isopen": isOpen === true,
|
|
239
|
-
color,
|
|
240
|
-
...rest,
|
|
241
|
-
children: isVisible && !outOfBoundaries && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_web.animated.div, { style: transitionStyle, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
242
|
-
import_react_focus_lock.default,
|
|
243
|
-
{
|
|
244
|
-
autoFocus,
|
|
245
|
-
returnFocus,
|
|
246
|
-
disabled: !focusOnContent,
|
|
247
|
-
...restFocusLockProps,
|
|
248
|
-
children: [
|
|
249
|
-
typeof content === "function" && content({
|
|
250
|
-
hide
|
|
251
|
-
}),
|
|
252
|
-
typeof content !== "function" && content
|
|
253
|
-
]
|
|
254
|
-
}
|
|
255
|
-
) })
|
|
256
|
-
}
|
|
257
|
-
);
|
|
222
|
+
shouldRenderPopout && !isInvalidContent && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react2.AnimatePresence, { children: isShown && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PopoutComponentWrapper, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
223
|
+
import_react_popper.Popper,
|
|
224
|
+
{
|
|
225
|
+
referenceElement: targetRef.current,
|
|
226
|
+
placement,
|
|
227
|
+
modifiers: {
|
|
228
|
+
preventOverflow: {
|
|
229
|
+
boundariesElement: "viewport"
|
|
258
230
|
}
|
|
231
|
+
},
|
|
232
|
+
...popperProps,
|
|
233
|
+
children: ({
|
|
234
|
+
ref,
|
|
235
|
+
style,
|
|
236
|
+
placement: placement2,
|
|
237
|
+
outOfBoundaries,
|
|
238
|
+
scheduleUpdate
|
|
239
|
+
}) => {
|
|
240
|
+
const interceptRef = (el) => {
|
|
241
|
+
popoutRef.current = el;
|
|
242
|
+
ref(el);
|
|
243
|
+
};
|
|
244
|
+
scheduleUpdateCallback.current = scheduleUpdate;
|
|
245
|
+
scheduleUpdateRef(scheduleUpdate);
|
|
246
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
247
|
+
"div",
|
|
248
|
+
{
|
|
249
|
+
ref: interceptRef,
|
|
250
|
+
style: {
|
|
251
|
+
...style,
|
|
252
|
+
zIndex,
|
|
253
|
+
width: fullWidth && targetRef.current ? targetRef.current.offsetWidth : "initial"
|
|
254
|
+
},
|
|
255
|
+
"data-placement": placement2,
|
|
256
|
+
"data-qa-popout": "",
|
|
257
|
+
"data-qa-popout-isopen": isOpen === true,
|
|
258
|
+
color,
|
|
259
|
+
...rest,
|
|
260
|
+
children: !outOfBoundaries && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react2.motion.div, { ...animationConfig, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
261
|
+
import_react_focus_lock.default,
|
|
262
|
+
{
|
|
263
|
+
autoFocus,
|
|
264
|
+
returnFocus,
|
|
265
|
+
disabled: !focusOnContent,
|
|
266
|
+
...restFocusLockProps,
|
|
267
|
+
children: [
|
|
268
|
+
typeof content === "function" && content({
|
|
269
|
+
hide
|
|
270
|
+
}),
|
|
271
|
+
typeof content !== "function" && content
|
|
272
|
+
]
|
|
273
|
+
}
|
|
274
|
+
) })
|
|
275
|
+
}
|
|
276
|
+
);
|
|
259
277
|
}
|
|
260
|
-
|
|
261
|
-
)
|
|
278
|
+
}
|
|
279
|
+
) }) })
|
|
262
280
|
] });
|
|
263
281
|
}
|
|
264
282
|
var PopoutContent = ({ children, ...rest }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/Popout.tsx","../src/styles.ts","../src/PopoutTypes.ts"],"sourcesContent":["import Popout from \"./Popout\";\n\nexport default Popout;\nexport { Popout };\nexport * from \"./PopoutTypes\";\n","import * as React from \"react\";\nimport { useState, useEffect, useRef, useCallback, useMemo } from \"react\";\nimport { useTransition, animated } from \"@react-spring/web\";\nimport FocusLock from \"react-focus-lock\";\nimport { Popper } from \"react-popper\";\nimport { MOTION_DURATION_FAST } from \"@sproutsocial/seeds-motion/dist/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\n// Transition definitions for fading in and out\nconst transitionConfig = {\n from: {\n opacity: 0,\n },\n enter: {\n opacity: 1,\n },\n leave: {\n opacity: 0,\n },\n config: {\n duration:\n // skip animation in test environment\n process.env.NODE_ENV === \"test\" ? 0 : MOTION_DURATION_FAST * 1000,\n },\n};\n\nexport function Popout({\n isOpen,\n setIsOpen,\n content,\n children,\n placement = \"auto\",\n fullWidth = false,\n zIndex = 7,\n focusOnContent = true,\n onOpen,\n onClose,\n qa = {},\n popperProps,\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 isControlled = typeof isOpen === \"boolean\";\n const isShown = isControlled ? isOpen : isInternalShown;\n\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 const transition = useTransition(isShown, transitionConfig);\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 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 &&\n !isInvalidContent &&\n transition(\n (transitionStyle, isVisible, transition) =>\n isVisible && (\n <PopoutComponentWrapper key={transition.key}>\n <Popper\n referenceElement={targetRef.current}\n placement={placement}\n modifiers={{\n preventOverflow: {\n boundariesElement: \"viewport\",\n },\n }}\n {...popperProps}\n >\n {({\n ref,\n style,\n placement,\n outOfBoundaries,\n scheduleUpdate,\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={placement}\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 {isVisible && !outOfBoundaries && (\n <animated.div style={transitionStyle}>\n <FocusLock\n autoFocus={autoFocus}\n returnFocus={returnFocus}\n disabled={!focusOnContent}\n {...restFocusLockProps}\n >\n {typeof content === \"function\" &&\n content({\n hide,\n })}\n {typeof content !== \"function\" && content}\n </FocusLock>\n </animated.div>\n )}\n </div>\n );\n }}\n </Popper>\n </PopoutComponentWrapper>\n )\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\";\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 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: { hide: () => void }) => 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 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\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 * And 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"],"mappings":"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","names":["styled","Portal","transition","placement","FocusLock","Box","React"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/Popout.tsx","../src/styles.ts","../src/PopoutTypes.ts"],"sourcesContent":["import Popout from \"./Popout\";\n\nexport default Popout;\nexport { Popout };\nexport * from \"./PopoutTypes\";\n","import * as React from \"react\";\nimport { useState, useEffect, useRef, useCallback, useMemo } 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/dist/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 duration: process.env.NODE_ENV === \"test\" ? 0 : MOTION_DURATION_FAST,\n },\n};\n\nconst menuAnimationConfig = {\n initial: {\n scale: 0,\n opacity: 0,\n originX: 0,\n originY: 0,\n },\n animate: {\n opacity: 1,\n scale: 1,\n originX: 0,\n originY: 0,\n\n transition: {\n type: \"tween\",\n duration: MOTION_DURATION_FAST,\n ease: \"circOut\",\n },\n },\n exit: {\n opacity: 0,\n scale: 1,\n transition: {\n type: \"tween\",\n duration: MOTION_DURATION_FAST,\n ease: \"circIn\",\n },\n },\n};\n\nexport function Popout({\n isOpen,\n setIsOpen,\n content,\n children,\n placement = \"auto\",\n fullWidth = false,\n zIndex = 7,\n focusOnContent = true,\n onOpen,\n onClose,\n qa = {},\n popperProps,\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 menuPopout = false,\n ...rest\n}: TypePopoutProps) {\n const PopoutComponentWrapper = appendToBody ? Portal : React.Fragment;\n const [isInternalShown, setIsInternalShown] = useState<boolean>(false);\n const isControlled = typeof isOpen === \"boolean\";\n const isShown = isControlled ? isOpen : isInternalShown;\n const animationConfig = menuPopout\n ? menuAnimationConfig\n : defaultAnimationConfig;\n\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 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={placement}\n modifiers={{\n preventOverflow: {\n boundariesElement: \"viewport\",\n },\n }}\n {...popperProps}\n >\n {({\n ref,\n style,\n placement,\n outOfBoundaries,\n scheduleUpdate,\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={placement}\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 {...animationConfig}>\n <FocusLock\n autoFocus={autoFocus}\n returnFocus={returnFocus}\n disabled={!focusOnContent}\n {...restFocusLockProps}\n >\n {typeof content === \"function\" &&\n content({\n hide,\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\";\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: { hide: () => void }) => 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 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\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 * And 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 menuPopout?: boolean;\n}\n"],"mappings":"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","names":["import_react","styled","Portal","placement","FocusLock","Box","React"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sproutsocial/seeds-react-popout",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Seeds React Popout",
|
|
5
5
|
"author": "Sprout Social, Inc.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
],
|
|
13
13
|
"scripts": {
|
|
14
14
|
"build": "tsup --dts",
|
|
15
|
+
"build:debug": "tsup --dts --metafile",
|
|
15
16
|
"dev": "tsup --watch --dts",
|
|
16
17
|
"clean": "rm -rf .turbo dist",
|
|
17
18
|
"clean:modules": "rm -rf node_modules",
|
|
@@ -24,19 +25,19 @@
|
|
|
24
25
|
"@sproutsocial/seeds-react-hooks": "*",
|
|
25
26
|
"@sproutsocial/seeds-react-portal": "*",
|
|
26
27
|
"@sproutsocial/seeds-react-system-props": "*",
|
|
28
|
+
"motion": "^11.11.17",
|
|
27
29
|
"react-focus-lock": "^2.0.3",
|
|
28
|
-
"react-popper": "^1.3.11"
|
|
29
|
-
"@react-spring/web": "^9.0.0"
|
|
30
|
+
"react-popper": "^1.3.11"
|
|
30
31
|
},
|
|
31
32
|
"devDependencies": {
|
|
33
|
+
"@sproutsocial/eslint-config-seeds": "*",
|
|
34
|
+
"@sproutsocial/seeds-tsconfig": "*",
|
|
32
35
|
"@types/react": "^18.0.0",
|
|
33
36
|
"@types/styled-components": "^5.1.26",
|
|
34
|
-
"@sproutsocial/eslint-config-seeds": "*",
|
|
35
37
|
"react": "^18.0.0",
|
|
36
38
|
"styled-components": "^5.2.3",
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"tsup": "^8.0.2"
|
|
39
|
+
"tsup": "^8.0.2",
|
|
40
|
+
"typescript": "^5.6.2"
|
|
40
41
|
},
|
|
41
42
|
"peerDependencies": {
|
|
42
43
|
"styled-components": "^5.2.3"
|