@sproutsocial/seeds-react-popout 1.0.2 → 1.1.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 CHANGED
@@ -248,3 +248,4 @@ export {
248
248
  Popout_default as Popout,
249
249
  src_default as default
250
250
  };
251
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/Popout.tsx","../../src/styles.ts","../../src/index.ts"],"sourcesContent":["import * as React from \"react\";\nimport { useState, useEffect, useRef, useCallback, useMemo } from \"react\";\nimport { useTransition, animated } from \"react-spring\";\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, { TypeBoxProps } from \"@sproutsocial/seeds-react-box\";\nimport { TargetWrapper } from \"./styles\";\nimport type { TypePopoutProps, EnumPlacements } from \"./PopoutTypes\";\n\nexport const placements: { [key: string]: EnumPlacements } = {\n auto: \"auto\",\n\n top: \"top\",\n right: \"right\",\n bottom: \"bottom\",\n left: \"left\",\n\n \"top-start\": \"top-start\",\n \"right-start\": \"right-start\",\n \"bottom-start\": \"bottom-start\",\n \"left-start\": \"left-start\",\n\n \"top-end\": \"top-end\",\n \"right-end\": \"right-end\",\n \"bottom-end\": \"bottom-end\",\n \"left-end\": \"left-end\",\n};\n\nconst doesRefContainEventTarget = (ref, event) => {\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: 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 () =>\n isControlled && setIsOpen\n ? setIsOpen\n : (nextIsShown) => setIsInternalShown(nextIsShown),\n [isControlled, setIsOpen]\n );\n\n const targetRef = useRef<HTMLDivElement>();\n const popoutRef = useRef<HTMLDivElement>();\n const isFirstRender = useRef(true);\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 // Manage onOpen and onClose callbacks\n useEffect(\n () => {\n // Don't fire onClose on the first render\n if (isFirstRender.current) {\n isFirstRender.current = false;\n return;\n }\n\n if (!onOpen && !onClose) {\n return;\n }\n\n if (isShown && onOpen) {\n onOpen();\n }\n\n if (!isShown && onClose) {\n onClose();\n }\n },\n // eslint-disable-next-line\n [isShown]\n );\n\n const transitions = useTransition(isShown, null, 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) => {\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 transitions.map(\n ({ item, key, props }) =>\n item && (\n <PopoutComponentWrapper key={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) => {\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 {item && !outOfBoundaries && (\n <animated.div style={props}>\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","import Popout from \"./Popout\";\n\nexport default Popout;\nexport { Popout };\nexport * from \"./PopoutTypes\";\n"],"mappings":"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","names":["placement"]}
package/dist/index.js CHANGED
@@ -285,3 +285,4 @@ var src_default = Popout_default;
285
285
  0 && (module.exports = {
286
286
  Popout
287
287
  });
288
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/Popout.tsx","../src/styles.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\";\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, { TypeBoxProps } from \"@sproutsocial/seeds-react-box\";\nimport { TargetWrapper } from \"./styles\";\nimport type { TypePopoutProps, EnumPlacements } from \"./PopoutTypes\";\n\nexport const placements: { [key: string]: EnumPlacements } = {\n auto: \"auto\",\n\n top: \"top\",\n right: \"right\",\n bottom: \"bottom\",\n left: \"left\",\n\n \"top-start\": \"top-start\",\n \"right-start\": \"right-start\",\n \"bottom-start\": \"bottom-start\",\n \"left-start\": \"left-start\",\n\n \"top-end\": \"top-end\",\n \"right-end\": \"right-end\",\n \"bottom-end\": \"bottom-end\",\n \"left-end\": \"left-end\",\n};\n\nconst doesRefContainEventTarget = (ref, event) => {\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: 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 () =>\n isControlled && setIsOpen\n ? setIsOpen\n : (nextIsShown) => setIsInternalShown(nextIsShown),\n [isControlled, setIsOpen]\n );\n\n const targetRef = useRef<HTMLDivElement>();\n const popoutRef = useRef<HTMLDivElement>();\n const isFirstRender = useRef(true);\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 // Manage onOpen and onClose callbacks\n useEffect(\n () => {\n // Don't fire onClose on the first render\n if (isFirstRender.current) {\n isFirstRender.current = false;\n return;\n }\n\n if (!onOpen && !onClose) {\n return;\n }\n\n if (isShown && onOpen) {\n onOpen();\n }\n\n if (!isShown && onClose) {\n onClose();\n }\n },\n // eslint-disable-next-line\n [isShown]\n );\n\n const transitions = useTransition(isShown, null, 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) => {\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 transitions.map(\n ({ item, key, props }) =>\n item && (\n <PopoutComponentWrapper key={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) => {\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 {item && !outOfBoundaries && (\n <animated.div style={props}>\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"],"mappings":"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","names":["styled","Portal","placement","FocusLock","Box"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sproutsocial/seeds-react-popout",
3
- "version": "1.0.2",
3
+ "version": "1.1.0",
4
4
  "description": "Seeds React Popout",
5
5
  "author": "Sprout Social, Inc.",
6
6
  "license": "MIT",
@@ -11,7 +11,11 @@
11
11
  "dist"
12
12
  ],
13
13
  "scripts": {
14
- "build": "tsup"
14
+ "build": "tsup --dts",
15
+ "dev": "tsup --watch --dts",
16
+ "clean": "rm -rf .turbo dist",
17
+ "clean:modules": "rm -rf node_modules",
18
+ "typecheck": "tsc --noEmit"
15
19
  },
16
20
  "dependencies": {
17
21
  "@sproutsocial/seeds-motion": "^1.6.0",
@@ -25,10 +29,10 @@
25
29
  "react-spring": "^8.0.25"
26
30
  },
27
31
  "devDependencies": {
28
- "@types/react": "^17.0.0",
32
+ "@types/react": "^18.0.0",
29
33
  "@types/styled-components": "^5.1.26",
30
34
  "@sproutsocial/eslint-config-seeds": "*",
31
- "react": "^17.0.2",
35
+ "react": "^18.0.0",
32
36
  "styled-components": "^5.2.3",
33
37
  "typescript": "^5.1.6"
34
38
  },