@sproutsocial/seeds-react-drawer 1.1.11 → 1.1.13

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.
@@ -8,14 +8,14 @@ $ tsup --dts
8
8
  CLI Cleaning output folder
9
9
  CJS Build start
10
10
  ESM Build start
11
- CJS dist/index.js 9.41 KB
12
- CJS dist/index.js.map 15.38 KB
13
- CJS ⚡️ Build success in 257ms
14
- ESM dist/esm/index.js 6.83 KB
15
- ESM dist/esm/index.js.map 15.20 KB
16
- ESM ⚡️ Build success in 244ms
11
+ CJS dist/index.js 9.48 KB
12
+ CJS dist/index.js.map 15.55 KB
13
+ CJS ⚡️ Build success in 293ms
14
+ ESM dist/esm/index.js 6.89 KB
15
+ ESM dist/esm/index.js.map 15.37 KB
16
+ ESM ⚡️ Build success in 282ms
17
17
  DTS Build start
18
- DTS ⚡️ Build success in 31763ms
19
- DTS dist/index.d.ts 3.76 KB
20
- DTS dist/index.d.mts 3.76 KB
21
- Done in 39.89s.
18
+ DTS ⚡️ Build success in 30579ms
19
+ DTS dist/index.d.ts 3.79 KB
20
+ DTS dist/index.d.mts 3.79 KB
21
+ Done in 37.67s.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # @sproutsocial/seeds-react-drawer
2
2
 
3
+ ## 1.1.13
4
+
5
+ ### Patch Changes
6
+
7
+ - b7d7463: Prevent Drawer onClose from firing when closed
8
+
9
+ ## 1.1.12
10
+
11
+ ### Patch Changes
12
+
13
+ - @sproutsocial/seeds-react-theme@3.3.1
14
+ - @sproutsocial/seeds-react-box@1.1.9
15
+ - @sproutsocial/seeds-react-icon@2.0.5
16
+ - @sproutsocial/seeds-react-button@1.3.10
17
+
3
18
  ## 1.1.11
4
19
 
5
20
  ### Patch Changes
package/dist/esm/index.js CHANGED
@@ -103,6 +103,7 @@ var DrawerHeader = ({
103
103
  };
104
104
  var DrawerContent = ({ children, ...rest }) => /* @__PURE__ */ jsx(Content, { height: "100%", p: 450, color: "text.body", ...rest, children });
105
105
  var useCloseOnBodyClick = ({
106
+ isOpen,
106
107
  ref,
107
108
  disableCloseOnClickOutside,
108
109
  onClose,
@@ -111,7 +112,7 @@ var useCloseOnBodyClick = ({
111
112
  const { isLocked } = useContext(DrawerContext);
112
113
  useEffect(() => {
113
114
  const documentBody = document.body;
114
- if (!documentBody) {
115
+ if (!documentBody || !isOpen) {
115
116
  return;
116
117
  }
117
118
  const onEsc = (event) => {
@@ -153,7 +154,14 @@ var useCloseOnBodyClick = ({
153
154
  );
154
155
  }
155
156
  };
156
- }, [onClose, disableCloseOnClickOutside, closeTargets, ref, isLocked]);
157
+ }, [
158
+ onClose,
159
+ disableCloseOnClickOutside,
160
+ closeTargets,
161
+ ref,
162
+ isLocked,
163
+ isOpen
164
+ ]);
157
165
  };
158
166
  var Drawer = ({
159
167
  id,
@@ -174,7 +182,8 @@ var Drawer = ({
174
182
  ref,
175
183
  disableCloseOnClickOutside,
176
184
  onClose,
177
- closeTargets
185
+ closeTargets,
186
+ isOpen
178
187
  });
179
188
  const offset_x = width * (direction === "left" ? -1 : 1);
180
189
  return /* @__PURE__ */ jsx(
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/Drawer.tsx","../../src/styles.ts","../../src/DrawerTypes.ts","../../src/index.ts"],"sourcesContent":["import * as React from \"react\";\nimport { useContext, useEffect, useRef } from \"react\";\nimport FocusLock from \"react-focus-lock\";\nimport { motion, AnimatePresence } from \"motion/react\";\nimport { MOTION_DURATION_MEDIUM } from \"@sproutsocial/seeds-motion/unitless\";\nimport Box from \"@sproutsocial/seeds-react-box\";\nimport Button from \"@sproutsocial/seeds-react-button\";\nimport Icon from \"@sproutsocial/seeds-react-icon\";\n// eslint-disable-next-line import/no-deprecated\nimport Text from \"@sproutsocial/seeds-react-text\";\nimport Portal from \"@sproutsocial/seeds-react-portal\";\nimport Container, { Content } from \"./styles\";\nimport type {\n TypeDrawerContext,\n TypeDrawerCloseButtonProps,\n TypeDrawerHeaderProps,\n TypeDrawerProps,\n TypeInnerDrawerProps,\n TypeDrawerContentProps,\n TypeUseCloseOnBodyClickProps,\n} from \"./DrawerTypes\";\n\nconst MotionContainer = motion(Container as any);\n\nconst doesRefContainEventTarget = (\n ref: { current: { contains: (arg0: any) => any } },\n event: Event\n) => {\n return (\n ref.current &&\n event.target instanceof Node &&\n ref.current.contains(event.target)\n );\n};\n\nexport const DrawerContext = React.createContext<TypeDrawerContext>({\n isLocked: false,\n setIsLocked: () => {},\n});\n\nconst DrawerCloseButton = (props: TypeDrawerCloseButtonProps) => {\n const drawerContext = useContext(DrawerContext);\n\n if (props.render) {\n return props.render(drawerContext) ?? null;\n }\n\n return (\n <Button\n appearance=\"pill\"\n aria-label={drawerContext.closeButtonLabel}\n onClick={drawerContext.onClose}\n {...props}\n >\n {props.children || <Icon aria-hidden name=\"x-outline\" />}\n </Button>\n );\n};\n\nconst DrawerHeader = ({\n title = \"\",\n id = undefined,\n children,\n render,\n ...rest\n}: TypeDrawerHeaderProps) => {\n const drawerContext = useContext(DrawerContext);\n\n if (render) {\n return render(drawerContext);\n }\n\n return (\n <Box\n display=\"flex\"\n flex=\"0 0 auto\"\n justifyContent=\"space-between\"\n alignItems=\"center\"\n pt={400}\n px={450}\n {...rest}\n >\n {children || (\n <React.Fragment>\n <Text\n as=\"h2\"\n fontSize={400}\n fontWeight=\"semibold\"\n color=\"text.headline\"\n id={id}\n >\n {title}\n </Text>\n <DrawerCloseButton />\n </React.Fragment>\n )}\n </Box>\n );\n};\n\nconst DrawerContent = ({ children, ...rest }: TypeDrawerContentProps) => (\n <Content height=\"100%\" p={450} color=\"text.body\" {...rest}>\n {children}\n </Content>\n);\n\nconst useCloseOnBodyClick = ({\n ref,\n disableCloseOnClickOutside,\n onClose,\n closeTargets,\n}: TypeUseCloseOnBodyClickProps) => {\n const { isLocked } = useContext(DrawerContext);\n\n useEffect(() => {\n const documentBody = document.body;\n\n if (!documentBody) {\n return;\n }\n\n const onEsc = (event: KeyboardEvent): void => {\n if (!isLocked && event.key === \"Escape\") {\n onClose();\n }\n };\n\n const bodyClick = (event: Event): void => {\n if (\n // @ts-ignore I'm not sure how to type this ref properly\n !doesRefContainEventTarget(ref, event) &&\n !disableCloseOnClickOutside\n ) {\n onClose();\n }\n };\n\n documentBody?.addEventListener(\"keydown\", onEsc, { capture: true });\n\n if (closeTargets) {\n closeTargets.forEach((targetElement) =>\n targetElement?.addEventListener(\"click\", bodyClick, { capture: true })\n );\n } else {\n documentBody.firstElementChild?.addEventListener(\"click\", bodyClick, {\n capture: true,\n });\n }\n\n return () => {\n documentBody?.removeEventListener(\"keydown\", onEsc, { capture: true });\n\n if (closeTargets) {\n closeTargets.forEach((targetElement) =>\n targetElement?.removeEventListener(\"click\", bodyClick, {\n capture: true,\n })\n );\n } else {\n documentBody.firstElementChild?.removeEventListener(\n \"click\",\n bodyClick,\n { capture: true }\n );\n }\n };\n }, [onClose, disableCloseOnClickOutside, closeTargets, ref, isLocked]);\n};\n\nconst Drawer = ({\n id,\n offset,\n direction,\n children,\n disableCloseOnClickOutside,\n onClose,\n zIndex,\n closeTargets,\n width,\n focusLockExemptCheck,\n isOpen,\n ...rest\n}: TypeInnerDrawerProps) => {\n const ref = useRef(null);\n useCloseOnBodyClick({\n ref,\n disableCloseOnClickOutside,\n onClose,\n closeTargets,\n });\n\n const offset_x = width * (direction === \"left\" ? -1 : 1);\n\n return (\n <FocusLock\n key={id}\n autoFocus={true}\n returnFocus\n whiteList={\n focusLockExemptCheck ? (e) => !focusLockExemptCheck(e) : undefined\n }\n >\n <AnimatePresence>\n {isOpen && (\n <MotionContainer\n ref={ref}\n style={{ zIndex }}\n width={width}\n offset={offset}\n direction={direction}\n data-qa-drawer={id}\n role=\"dialog\"\n initial={{ opacity: 0, x: offset_x }}\n animate={{ opacity: 1, x: 0 }}\n exit={{ opacity: 0, x: offset_x }}\n transition={{ duration: MOTION_DURATION_MEDIUM }}\n {...rest}\n >\n {children}\n </MotionContainer>\n )}\n </AnimatePresence>\n </FocusLock>\n );\n};\n\nconst DrawerContainer = ({\n children,\n closeButtonLabel,\n direction = \"right\",\n disableCloseOnClickOutside = false,\n id,\n isOpen,\n offset = 0,\n onClose,\n zIndex = 7,\n closeTargets = [],\n width = 600,\n ...rest\n}: TypeDrawerProps) => {\n const [isLocked, setIsLocked] = React.useState(false);\n return (\n <Portal id={id}>\n <DrawerContext.Provider\n value={{\n onClose,\n closeButtonLabel,\n isLocked,\n setIsLocked,\n }}\n >\n <Drawer\n isOpen={isOpen}\n id={id}\n offset={offset}\n direction={direction}\n disableCloseOnClickOutside={disableCloseOnClickOutside}\n onClose={onClose}\n zIndex={zIndex}\n closeTargets={closeTargets}\n width={width}\n data-qa-drawer={id || \"\"}\n data-qa-drawer-isopen={isOpen}\n {...rest}\n >\n {children}\n </Drawer>\n </DrawerContext.Provider>\n </Portal>\n );\n};\n\nDrawerHeader.displayName = \"Drawer.Header\";\nDrawerContent.displayName = \"Drawer.Content\";\nDrawerCloseButton.displayName = \"Drawer.CloseButton\";\n\nDrawerContainer.Header = DrawerHeader;\nDrawerContainer.Content = DrawerContent;\nDrawerContainer.CloseButton = DrawerCloseButton;\n\nexport default DrawerContainer;\n","import type { TypeDrawerProps } from \"./DrawerTypes\";\nimport styled, { css } from \"styled-components\";\nimport { COMMON } from \"@sproutsocial/seeds-react-system-props\";\nimport type { TypeSystemCommonProps } from \"@sproutsocial/seeds-react-system-props\";\n\nimport Box from \"@sproutsocial/seeds-react-box\";\n\nexport const Content = styled(Box)`\n overflow-y: auto;\n`;\n\ninterface ContainerType\n extends Pick<TypeDrawerProps, \"offset\" | \"direction\">,\n TypeSystemCommonProps {\n width: number;\n}\n\nconst Container = styled.div<ContainerType>`\n display: flex;\n flex-direction: column;\n position: fixed;\n top: 0;\n height: 100%;\n width: ${(props) => props.width}px;\n background-color: ${(props) => props.theme.colors.container.background.base};\n box-shadow: ${(props) => props.theme.shadows.high};\n filter: blur(0);\n\n ${(props) => css`\n ${props.direction}: ${props.offset}px;\n `}\n\n ${COMMON}\n`;\nexport default Container;\n","import * as React from \"react\";\nimport type {\n TypeSystemCommonProps,\n TypeStyledComponentsCommonProps,\n} from \"@sproutsocial/seeds-react-system-props\";\nimport type { TypeBoxProps } from \"@sproutsocial/seeds-react-box\";\nimport type { TypeButtonProps } from \"@sproutsocial/seeds-react-button\";\n\ntype DrawerAnimationDirection = \"left\" | \"right\";\n\nexport interface TypeDrawerContext {\n /** Callback for close button */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n onClose?: () => any;\n\n /** aria-label for drawer close button */\n closeButtonLabel?: string;\n /**\n * isLocked and setIsLocked are used when a Drawer contains other components (like Menu) that also\n * listen for Escape key events. By locking the Drawer, we can prevent conflicts\n * where multiple components try to handle the same keydown event.\n */\n isLocked: boolean;\n setIsLocked: (locked: boolean) => void;\n}\n// TODO: Should the render prop be a React.FC?\nexport interface TypeDrawerCloseButtonProps\n extends Omit<TypeButtonProps, \"children\"> {\n /** An optional function that receives the context of the parent drawer as an argument. Can be used to customize the on-close behavior. */\n render?: React.FC<TypeDrawerContext>;\n children?: React.ReactNode;\n}\n\nexport interface TypeDrawerHeaderProps extends TypeBoxProps {\n title?: string;\n children?: React.ReactNode;\n\n /** An optional function that receives the context of the parent drawer as an argument. Can be used to customize the appearance of the header. */\n render?: React.FC<TypeDrawerContext>;\n}\n\nexport interface TypeInnerDrawerProps\n extends Omit<TypeDrawerProps, \"closeButtonLabel\"> {\n width: number;\n direction: DrawerAnimationDirection;\n}\n\ntype useBodyClicksProps = Pick<\n TypeDrawerProps,\n \"closeTargets\" | \"onClose\" | \"disableCloseOnClickOutside\"\n>;\n\nexport interface TypeUseCloseOnBodyClickProps\n extends Pick<\n TypeDrawerProps,\n \"closeTargets\" | \"onClose\" | \"disableCloseOnClickOutside\"\n > {\n ref?: React.RefObject<HTMLElement | null>;\n}\n\nexport interface TypeDrawerProps\n extends TypeStyledComponentsCommonProps,\n TypeSystemCommonProps,\n Omit<React.ComponentPropsWithoutRef<\"nav\">, \"color\"> {\n children: React.ReactNode;\n\n /** Label for the close button. Usually this should be \"Close\" */\n closeButtonLabel: string;\n\n /** Whether the drawer slides in from the left or right side of the screen */\n direction?: DrawerAnimationDirection;\n\n /** In some cases, you may not want the user to be able to click outside of the drawer to close it. You can disable that with this prop. */\n disableCloseOnClickOutside?: boolean;\n id: string;\n isOpen: boolean;\n offset?: number;\n onClose: () => void;\n zIndex?: number;\n closeTargets?: Array<Element>;\n width?: number;\n focusLockExemptCheck?: (element: HTMLElement) => boolean;\n}\n\nexport interface TypeDrawerContentProps extends TypeBoxProps {\n children?: React.ReactNode;\n}\n","import Drawer, { DrawerContext } from \"./Drawer\";\n\nexport default Drawer;\nexport { Drawer, DrawerContext };\nexport * from \"./DrawerTypes\";\n"],"mappings":"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","names":["Box","Box"]}
1
+ {"version":3,"sources":["../../src/Drawer.tsx","../../src/styles.ts","../../src/DrawerTypes.ts","../../src/index.ts"],"sourcesContent":["import * as React from \"react\";\nimport { useContext, useEffect, useRef } from \"react\";\nimport FocusLock from \"react-focus-lock\";\nimport { motion, AnimatePresence } from \"motion/react\";\nimport { MOTION_DURATION_MEDIUM } from \"@sproutsocial/seeds-motion/unitless\";\nimport Box from \"@sproutsocial/seeds-react-box\";\nimport Button from \"@sproutsocial/seeds-react-button\";\nimport Icon from \"@sproutsocial/seeds-react-icon\";\n// eslint-disable-next-line import/no-deprecated\nimport Text from \"@sproutsocial/seeds-react-text\";\nimport Portal from \"@sproutsocial/seeds-react-portal\";\nimport Container, { Content } from \"./styles\";\nimport type {\n TypeDrawerContext,\n TypeDrawerCloseButtonProps,\n TypeDrawerHeaderProps,\n TypeDrawerProps,\n TypeInnerDrawerProps,\n TypeDrawerContentProps,\n TypeUseCloseOnBodyClickProps,\n} from \"./DrawerTypes\";\n\nconst MotionContainer = motion(Container as any);\n\nconst doesRefContainEventTarget = (\n ref: { current: { contains: (arg0: any) => any } },\n event: Event\n) => {\n return (\n ref.current &&\n event.target instanceof Node &&\n ref.current.contains(event.target)\n );\n};\n\nexport const DrawerContext = React.createContext<TypeDrawerContext>({\n isLocked: false,\n setIsLocked: () => {},\n});\n\nconst DrawerCloseButton = (props: TypeDrawerCloseButtonProps) => {\n const drawerContext = useContext(DrawerContext);\n\n if (props.render) {\n return props.render(drawerContext) ?? null;\n }\n\n return (\n <Button\n appearance=\"pill\"\n aria-label={drawerContext.closeButtonLabel}\n onClick={drawerContext.onClose}\n {...props}\n >\n {props.children || <Icon aria-hidden name=\"x-outline\" />}\n </Button>\n );\n};\n\nconst DrawerHeader = ({\n title = \"\",\n id = undefined,\n children,\n render,\n ...rest\n}: TypeDrawerHeaderProps) => {\n const drawerContext = useContext(DrawerContext);\n\n if (render) {\n return render(drawerContext);\n }\n\n return (\n <Box\n display=\"flex\"\n flex=\"0 0 auto\"\n justifyContent=\"space-between\"\n alignItems=\"center\"\n pt={400}\n px={450}\n {...rest}\n >\n {children || (\n <React.Fragment>\n <Text\n as=\"h2\"\n fontSize={400}\n fontWeight=\"semibold\"\n color=\"text.headline\"\n id={id}\n >\n {title}\n </Text>\n <DrawerCloseButton />\n </React.Fragment>\n )}\n </Box>\n );\n};\n\nconst DrawerContent = ({ children, ...rest }: TypeDrawerContentProps) => (\n <Content height=\"100%\" p={450} color=\"text.body\" {...rest}>\n {children}\n </Content>\n);\n\nconst useCloseOnBodyClick = ({\n isOpen,\n ref,\n disableCloseOnClickOutside,\n onClose,\n closeTargets,\n}: TypeUseCloseOnBodyClickProps) => {\n const { isLocked } = useContext(DrawerContext);\n\n useEffect(() => {\n const documentBody = document.body;\n\n if (!documentBody || !isOpen) {\n return;\n }\n\n const onEsc = (event: KeyboardEvent): void => {\n if (!isLocked && event.key === \"Escape\") {\n onClose();\n }\n };\n\n const bodyClick = (event: Event): void => {\n if (\n // @ts-ignore I'm not sure how to type this ref properly\n !doesRefContainEventTarget(ref, event) &&\n !disableCloseOnClickOutside\n ) {\n onClose();\n }\n };\n\n documentBody?.addEventListener(\"keydown\", onEsc, { capture: true });\n\n if (closeTargets) {\n closeTargets.forEach((targetElement) =>\n targetElement?.addEventListener(\"click\", bodyClick, { capture: true })\n );\n } else {\n documentBody.firstElementChild?.addEventListener(\"click\", bodyClick, {\n capture: true,\n });\n }\n\n return () => {\n documentBody?.removeEventListener(\"keydown\", onEsc, { capture: true });\n\n if (closeTargets) {\n closeTargets.forEach((targetElement) =>\n targetElement?.removeEventListener(\"click\", bodyClick, {\n capture: true,\n })\n );\n } else {\n documentBody.firstElementChild?.removeEventListener(\n \"click\",\n bodyClick,\n { capture: true }\n );\n }\n };\n }, [\n onClose,\n disableCloseOnClickOutside,\n closeTargets,\n ref,\n isLocked,\n isOpen,\n ]);\n};\n\nconst Drawer = ({\n id,\n offset,\n direction,\n children,\n disableCloseOnClickOutside,\n onClose,\n zIndex,\n closeTargets,\n width,\n focusLockExemptCheck,\n isOpen,\n ...rest\n}: TypeInnerDrawerProps) => {\n const ref = useRef(null);\n useCloseOnBodyClick({\n ref,\n disableCloseOnClickOutside,\n onClose,\n closeTargets,\n isOpen,\n });\n\n const offset_x = width * (direction === \"left\" ? -1 : 1);\n\n return (\n <FocusLock\n key={id}\n autoFocus={true}\n returnFocus\n whiteList={\n focusLockExemptCheck ? (e) => !focusLockExemptCheck(e) : undefined\n }\n >\n <AnimatePresence>\n {isOpen && (\n <MotionContainer\n ref={ref}\n style={{ zIndex }}\n width={width}\n offset={offset}\n direction={direction}\n data-qa-drawer={id}\n role=\"dialog\"\n initial={{ opacity: 0, x: offset_x }}\n animate={{ opacity: 1, x: 0 }}\n exit={{ opacity: 0, x: offset_x }}\n transition={{ duration: MOTION_DURATION_MEDIUM }}\n {...rest}\n >\n {children}\n </MotionContainer>\n )}\n </AnimatePresence>\n </FocusLock>\n );\n};\n\nconst DrawerContainer = ({\n children,\n closeButtonLabel,\n direction = \"right\",\n disableCloseOnClickOutside = false,\n id,\n isOpen,\n offset = 0,\n onClose,\n zIndex = 7,\n closeTargets = [],\n width = 600,\n ...rest\n}: TypeDrawerProps) => {\n const [isLocked, setIsLocked] = React.useState(false);\n return (\n <Portal id={id}>\n <DrawerContext.Provider\n value={{\n onClose,\n closeButtonLabel,\n isLocked,\n setIsLocked,\n }}\n >\n <Drawer\n isOpen={isOpen}\n id={id}\n offset={offset}\n direction={direction}\n disableCloseOnClickOutside={disableCloseOnClickOutside}\n onClose={onClose}\n zIndex={zIndex}\n closeTargets={closeTargets}\n width={width}\n data-qa-drawer={id || \"\"}\n data-qa-drawer-isopen={isOpen}\n {...rest}\n >\n {children}\n </Drawer>\n </DrawerContext.Provider>\n </Portal>\n );\n};\n\nDrawerHeader.displayName = \"Drawer.Header\";\nDrawerContent.displayName = \"Drawer.Content\";\nDrawerCloseButton.displayName = \"Drawer.CloseButton\";\n\nDrawerContainer.Header = DrawerHeader;\nDrawerContainer.Content = DrawerContent;\nDrawerContainer.CloseButton = DrawerCloseButton;\n\nexport default DrawerContainer;\n","import type { TypeDrawerProps } from \"./DrawerTypes\";\nimport styled, { css } from \"styled-components\";\nimport { COMMON } from \"@sproutsocial/seeds-react-system-props\";\nimport type { TypeSystemCommonProps } from \"@sproutsocial/seeds-react-system-props\";\n\nimport Box from \"@sproutsocial/seeds-react-box\";\n\nexport const Content = styled(Box)`\n overflow-y: auto;\n`;\n\ninterface ContainerType\n extends Pick<TypeDrawerProps, \"offset\" | \"direction\">,\n TypeSystemCommonProps {\n width: number;\n}\n\nconst Container = styled.div<ContainerType>`\n display: flex;\n flex-direction: column;\n position: fixed;\n top: 0;\n height: 100%;\n width: ${(props) => props.width}px;\n background-color: ${(props) => props.theme.colors.container.background.base};\n box-shadow: ${(props) => props.theme.shadows.high};\n filter: blur(0);\n\n ${(props) => css`\n ${props.direction}: ${props.offset}px;\n `}\n\n ${COMMON}\n`;\nexport default Container;\n","import * as React from \"react\";\nimport type {\n TypeSystemCommonProps,\n TypeStyledComponentsCommonProps,\n} from \"@sproutsocial/seeds-react-system-props\";\nimport type { TypeBoxProps } from \"@sproutsocial/seeds-react-box\";\nimport type { TypeButtonProps } from \"@sproutsocial/seeds-react-button\";\n\ntype DrawerAnimationDirection = \"left\" | \"right\";\n\nexport interface TypeDrawerContext {\n /** Callback for close button */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n onClose?: () => any;\n\n /** aria-label for drawer close button */\n closeButtonLabel?: string;\n /**\n * isLocked and setIsLocked are used when a Drawer contains other components (like Menu) that also\n * listen for Escape key events. By locking the Drawer, we can prevent conflicts\n * where multiple components try to handle the same keydown event.\n */\n isLocked: boolean;\n setIsLocked: (locked: boolean) => void;\n}\n// TODO: Should the render prop be a React.FC?\nexport interface TypeDrawerCloseButtonProps\n extends Omit<TypeButtonProps, \"children\"> {\n /** An optional function that receives the context of the parent drawer as an argument. Can be used to customize the on-close behavior. */\n render?: React.FC<TypeDrawerContext>;\n children?: React.ReactNode;\n}\n\nexport interface TypeDrawerHeaderProps extends TypeBoxProps {\n title?: string;\n children?: React.ReactNode;\n\n /** An optional function that receives the context of the parent drawer as an argument. Can be used to customize the appearance of the header. */\n render?: React.FC<TypeDrawerContext>;\n}\n\nexport interface TypeInnerDrawerProps\n extends Omit<TypeDrawerProps, \"closeButtonLabel\"> {\n width: number;\n direction: DrawerAnimationDirection;\n}\n\ntype useBodyClicksProps = Pick<\n TypeDrawerProps,\n \"closeTargets\" | \"onClose\" | \"disableCloseOnClickOutside\"\n>;\n\nexport interface TypeUseCloseOnBodyClickProps\n extends Pick<\n TypeDrawerProps,\n \"closeTargets\" | \"onClose\" | \"disableCloseOnClickOutside\"\n > {\n ref?: React.RefObject<HTMLElement | null>;\n isOpen: boolean;\n}\n\nexport interface TypeDrawerProps\n extends TypeStyledComponentsCommonProps,\n TypeSystemCommonProps,\n Omit<React.ComponentPropsWithoutRef<\"nav\">, \"color\"> {\n children: React.ReactNode;\n\n /** Label for the close button. Usually this should be \"Close\" */\n closeButtonLabel: string;\n\n /** Whether the drawer slides in from the left or right side of the screen */\n direction?: DrawerAnimationDirection;\n\n /** In some cases, you may not want the user to be able to click outside of the drawer to close it. You can disable that with this prop. */\n disableCloseOnClickOutside?: boolean;\n id: string;\n isOpen: boolean;\n offset?: number;\n onClose: () => void;\n zIndex?: number;\n closeTargets?: Array<Element>;\n width?: number;\n focusLockExemptCheck?: (element: HTMLElement) => boolean;\n}\n\nexport interface TypeDrawerContentProps extends TypeBoxProps {\n children?: React.ReactNode;\n}\n","import Drawer, { DrawerContext } from \"./Drawer\";\n\nexport default Drawer;\nexport { Drawer, DrawerContext };\nexport * from \"./DrawerTypes\";\n"],"mappings":"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","names":["Box","Box"]}
package/dist/index.d.mts CHANGED
@@ -35,6 +35,7 @@ interface TypeInnerDrawerProps extends Omit<TypeDrawerProps, "closeButtonLabel">
35
35
  }
36
36
  interface TypeUseCloseOnBodyClickProps extends Pick<TypeDrawerProps, "closeTargets" | "onClose" | "disableCloseOnClickOutside"> {
37
37
  ref?: React.RefObject<HTMLElement | null>;
38
+ isOpen: boolean;
38
39
  }
39
40
  interface TypeDrawerProps extends TypeStyledComponentsCommonProps, TypeSystemCommonProps, Omit<React.ComponentPropsWithoutRef<"nav">, "color"> {
40
41
  children: React.ReactNode;
package/dist/index.d.ts CHANGED
@@ -35,6 +35,7 @@ interface TypeInnerDrawerProps extends Omit<TypeDrawerProps, "closeButtonLabel">
35
35
  }
36
36
  interface TypeUseCloseOnBodyClickProps extends Pick<TypeDrawerProps, "closeTargets" | "onClose" | "disableCloseOnClickOutside"> {
37
37
  ref?: React.RefObject<HTMLElement | null>;
38
+ isOpen: boolean;
38
39
  }
39
40
  interface TypeDrawerProps extends TypeStyledComponentsCommonProps, TypeSystemCommonProps, Omit<React.ComponentPropsWithoutRef<"nav">, "color"> {
40
41
  children: React.ReactNode;
package/dist/index.js CHANGED
@@ -141,6 +141,7 @@ var DrawerHeader = ({
141
141
  };
142
142
  var DrawerContent = ({ children, ...rest }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Content, { height: "100%", p: 450, color: "text.body", ...rest, children });
143
143
  var useCloseOnBodyClick = ({
144
+ isOpen,
144
145
  ref,
145
146
  disableCloseOnClickOutside,
146
147
  onClose,
@@ -149,7 +150,7 @@ var useCloseOnBodyClick = ({
149
150
  const { isLocked } = (0, import_react.useContext)(DrawerContext);
150
151
  (0, import_react.useEffect)(() => {
151
152
  const documentBody = document.body;
152
- if (!documentBody) {
153
+ if (!documentBody || !isOpen) {
153
154
  return;
154
155
  }
155
156
  const onEsc = (event) => {
@@ -191,7 +192,14 @@ var useCloseOnBodyClick = ({
191
192
  );
192
193
  }
193
194
  };
194
- }, [onClose, disableCloseOnClickOutside, closeTargets, ref, isLocked]);
195
+ }, [
196
+ onClose,
197
+ disableCloseOnClickOutside,
198
+ closeTargets,
199
+ ref,
200
+ isLocked,
201
+ isOpen
202
+ ]);
195
203
  };
196
204
  var Drawer = ({
197
205
  id,
@@ -212,7 +220,8 @@ var Drawer = ({
212
220
  ref,
213
221
  disableCloseOnClickOutside,
214
222
  onClose,
215
- closeTargets
223
+ closeTargets,
224
+ isOpen
216
225
  });
217
226
  const offset_x = width * (direction === "left" ? -1 : 1);
218
227
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/Drawer.tsx","../src/styles.ts","../src/DrawerTypes.ts"],"sourcesContent":["import Drawer, { DrawerContext } from \"./Drawer\";\n\nexport default Drawer;\nexport { Drawer, DrawerContext };\nexport * from \"./DrawerTypes\";\n","import * as React from \"react\";\nimport { useContext, useEffect, useRef } from \"react\";\nimport FocusLock from \"react-focus-lock\";\nimport { motion, AnimatePresence } from \"motion/react\";\nimport { MOTION_DURATION_MEDIUM } from \"@sproutsocial/seeds-motion/unitless\";\nimport Box from \"@sproutsocial/seeds-react-box\";\nimport Button from \"@sproutsocial/seeds-react-button\";\nimport Icon from \"@sproutsocial/seeds-react-icon\";\n// eslint-disable-next-line import/no-deprecated\nimport Text from \"@sproutsocial/seeds-react-text\";\nimport Portal from \"@sproutsocial/seeds-react-portal\";\nimport Container, { Content } from \"./styles\";\nimport type {\n TypeDrawerContext,\n TypeDrawerCloseButtonProps,\n TypeDrawerHeaderProps,\n TypeDrawerProps,\n TypeInnerDrawerProps,\n TypeDrawerContentProps,\n TypeUseCloseOnBodyClickProps,\n} from \"./DrawerTypes\";\n\nconst MotionContainer = motion(Container as any);\n\nconst doesRefContainEventTarget = (\n ref: { current: { contains: (arg0: any) => any } },\n event: Event\n) => {\n return (\n ref.current &&\n event.target instanceof Node &&\n ref.current.contains(event.target)\n );\n};\n\nexport const DrawerContext = React.createContext<TypeDrawerContext>({\n isLocked: false,\n setIsLocked: () => {},\n});\n\nconst DrawerCloseButton = (props: TypeDrawerCloseButtonProps) => {\n const drawerContext = useContext(DrawerContext);\n\n if (props.render) {\n return props.render(drawerContext) ?? null;\n }\n\n return (\n <Button\n appearance=\"pill\"\n aria-label={drawerContext.closeButtonLabel}\n onClick={drawerContext.onClose}\n {...props}\n >\n {props.children || <Icon aria-hidden name=\"x-outline\" />}\n </Button>\n );\n};\n\nconst DrawerHeader = ({\n title = \"\",\n id = undefined,\n children,\n render,\n ...rest\n}: TypeDrawerHeaderProps) => {\n const drawerContext = useContext(DrawerContext);\n\n if (render) {\n return render(drawerContext);\n }\n\n return (\n <Box\n display=\"flex\"\n flex=\"0 0 auto\"\n justifyContent=\"space-between\"\n alignItems=\"center\"\n pt={400}\n px={450}\n {...rest}\n >\n {children || (\n <React.Fragment>\n <Text\n as=\"h2\"\n fontSize={400}\n fontWeight=\"semibold\"\n color=\"text.headline\"\n id={id}\n >\n {title}\n </Text>\n <DrawerCloseButton />\n </React.Fragment>\n )}\n </Box>\n );\n};\n\nconst DrawerContent = ({ children, ...rest }: TypeDrawerContentProps) => (\n <Content height=\"100%\" p={450} color=\"text.body\" {...rest}>\n {children}\n </Content>\n);\n\nconst useCloseOnBodyClick = ({\n ref,\n disableCloseOnClickOutside,\n onClose,\n closeTargets,\n}: TypeUseCloseOnBodyClickProps) => {\n const { isLocked } = useContext(DrawerContext);\n\n useEffect(() => {\n const documentBody = document.body;\n\n if (!documentBody) {\n return;\n }\n\n const onEsc = (event: KeyboardEvent): void => {\n if (!isLocked && event.key === \"Escape\") {\n onClose();\n }\n };\n\n const bodyClick = (event: Event): void => {\n if (\n // @ts-ignore I'm not sure how to type this ref properly\n !doesRefContainEventTarget(ref, event) &&\n !disableCloseOnClickOutside\n ) {\n onClose();\n }\n };\n\n documentBody?.addEventListener(\"keydown\", onEsc, { capture: true });\n\n if (closeTargets) {\n closeTargets.forEach((targetElement) =>\n targetElement?.addEventListener(\"click\", bodyClick, { capture: true })\n );\n } else {\n documentBody.firstElementChild?.addEventListener(\"click\", bodyClick, {\n capture: true,\n });\n }\n\n return () => {\n documentBody?.removeEventListener(\"keydown\", onEsc, { capture: true });\n\n if (closeTargets) {\n closeTargets.forEach((targetElement) =>\n targetElement?.removeEventListener(\"click\", bodyClick, {\n capture: true,\n })\n );\n } else {\n documentBody.firstElementChild?.removeEventListener(\n \"click\",\n bodyClick,\n { capture: true }\n );\n }\n };\n }, [onClose, disableCloseOnClickOutside, closeTargets, ref, isLocked]);\n};\n\nconst Drawer = ({\n id,\n offset,\n direction,\n children,\n disableCloseOnClickOutside,\n onClose,\n zIndex,\n closeTargets,\n width,\n focusLockExemptCheck,\n isOpen,\n ...rest\n}: TypeInnerDrawerProps) => {\n const ref = useRef(null);\n useCloseOnBodyClick({\n ref,\n disableCloseOnClickOutside,\n onClose,\n closeTargets,\n });\n\n const offset_x = width * (direction === \"left\" ? -1 : 1);\n\n return (\n <FocusLock\n key={id}\n autoFocus={true}\n returnFocus\n whiteList={\n focusLockExemptCheck ? (e) => !focusLockExemptCheck(e) : undefined\n }\n >\n <AnimatePresence>\n {isOpen && (\n <MotionContainer\n ref={ref}\n style={{ zIndex }}\n width={width}\n offset={offset}\n direction={direction}\n data-qa-drawer={id}\n role=\"dialog\"\n initial={{ opacity: 0, x: offset_x }}\n animate={{ opacity: 1, x: 0 }}\n exit={{ opacity: 0, x: offset_x }}\n transition={{ duration: MOTION_DURATION_MEDIUM }}\n {...rest}\n >\n {children}\n </MotionContainer>\n )}\n </AnimatePresence>\n </FocusLock>\n );\n};\n\nconst DrawerContainer = ({\n children,\n closeButtonLabel,\n direction = \"right\",\n disableCloseOnClickOutside = false,\n id,\n isOpen,\n offset = 0,\n onClose,\n zIndex = 7,\n closeTargets = [],\n width = 600,\n ...rest\n}: TypeDrawerProps) => {\n const [isLocked, setIsLocked] = React.useState(false);\n return (\n <Portal id={id}>\n <DrawerContext.Provider\n value={{\n onClose,\n closeButtonLabel,\n isLocked,\n setIsLocked,\n }}\n >\n <Drawer\n isOpen={isOpen}\n id={id}\n offset={offset}\n direction={direction}\n disableCloseOnClickOutside={disableCloseOnClickOutside}\n onClose={onClose}\n zIndex={zIndex}\n closeTargets={closeTargets}\n width={width}\n data-qa-drawer={id || \"\"}\n data-qa-drawer-isopen={isOpen}\n {...rest}\n >\n {children}\n </Drawer>\n </DrawerContext.Provider>\n </Portal>\n );\n};\n\nDrawerHeader.displayName = \"Drawer.Header\";\nDrawerContent.displayName = \"Drawer.Content\";\nDrawerCloseButton.displayName = \"Drawer.CloseButton\";\n\nDrawerContainer.Header = DrawerHeader;\nDrawerContainer.Content = DrawerContent;\nDrawerContainer.CloseButton = DrawerCloseButton;\n\nexport default DrawerContainer;\n","import type { TypeDrawerProps } from \"./DrawerTypes\";\nimport styled, { css } from \"styled-components\";\nimport { COMMON } from \"@sproutsocial/seeds-react-system-props\";\nimport type { TypeSystemCommonProps } from \"@sproutsocial/seeds-react-system-props\";\n\nimport Box from \"@sproutsocial/seeds-react-box\";\n\nexport const Content = styled(Box)`\n overflow-y: auto;\n`;\n\ninterface ContainerType\n extends Pick<TypeDrawerProps, \"offset\" | \"direction\">,\n TypeSystemCommonProps {\n width: number;\n}\n\nconst Container = styled.div<ContainerType>`\n display: flex;\n flex-direction: column;\n position: fixed;\n top: 0;\n height: 100%;\n width: ${(props) => props.width}px;\n background-color: ${(props) => props.theme.colors.container.background.base};\n box-shadow: ${(props) => props.theme.shadows.high};\n filter: blur(0);\n\n ${(props) => css`\n ${props.direction}: ${props.offset}px;\n `}\n\n ${COMMON}\n`;\nexport default Container;\n","import * as React from \"react\";\nimport type {\n TypeSystemCommonProps,\n TypeStyledComponentsCommonProps,\n} from \"@sproutsocial/seeds-react-system-props\";\nimport type { TypeBoxProps } from \"@sproutsocial/seeds-react-box\";\nimport type { TypeButtonProps } from \"@sproutsocial/seeds-react-button\";\n\ntype DrawerAnimationDirection = \"left\" | \"right\";\n\nexport interface TypeDrawerContext {\n /** Callback for close button */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n onClose?: () => any;\n\n /** aria-label for drawer close button */\n closeButtonLabel?: string;\n /**\n * isLocked and setIsLocked are used when a Drawer contains other components (like Menu) that also\n * listen for Escape key events. By locking the Drawer, we can prevent conflicts\n * where multiple components try to handle the same keydown event.\n */\n isLocked: boolean;\n setIsLocked: (locked: boolean) => void;\n}\n// TODO: Should the render prop be a React.FC?\nexport interface TypeDrawerCloseButtonProps\n extends Omit<TypeButtonProps, \"children\"> {\n /** An optional function that receives the context of the parent drawer as an argument. Can be used to customize the on-close behavior. */\n render?: React.FC<TypeDrawerContext>;\n children?: React.ReactNode;\n}\n\nexport interface TypeDrawerHeaderProps extends TypeBoxProps {\n title?: string;\n children?: React.ReactNode;\n\n /** An optional function that receives the context of the parent drawer as an argument. Can be used to customize the appearance of the header. */\n render?: React.FC<TypeDrawerContext>;\n}\n\nexport interface TypeInnerDrawerProps\n extends Omit<TypeDrawerProps, \"closeButtonLabel\"> {\n width: number;\n direction: DrawerAnimationDirection;\n}\n\ntype useBodyClicksProps = Pick<\n TypeDrawerProps,\n \"closeTargets\" | \"onClose\" | \"disableCloseOnClickOutside\"\n>;\n\nexport interface TypeUseCloseOnBodyClickProps\n extends Pick<\n TypeDrawerProps,\n \"closeTargets\" | \"onClose\" | \"disableCloseOnClickOutside\"\n > {\n ref?: React.RefObject<HTMLElement | null>;\n}\n\nexport interface TypeDrawerProps\n extends TypeStyledComponentsCommonProps,\n TypeSystemCommonProps,\n Omit<React.ComponentPropsWithoutRef<\"nav\">, \"color\"> {\n children: React.ReactNode;\n\n /** Label for the close button. Usually this should be \"Close\" */\n closeButtonLabel: string;\n\n /** Whether the drawer slides in from the left or right side of the screen */\n direction?: DrawerAnimationDirection;\n\n /** In some cases, you may not want the user to be able to click outside of the drawer to close it. You can disable that with this prop. */\n disableCloseOnClickOutside?: boolean;\n id: string;\n isOpen: boolean;\n offset?: number;\n onClose: () => void;\n zIndex?: number;\n closeTargets?: Array<Element>;\n width?: number;\n focusLockExemptCheck?: (element: HTMLElement) => boolean;\n}\n\nexport interface TypeDrawerContentProps extends TypeBoxProps {\n children?: React.ReactNode;\n}\n"],"mappings":"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","names":["import_react","import_seeds_react_box","styled","Box","Button","Icon","Box","Text","FocusLock","Portal","React"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/Drawer.tsx","../src/styles.ts","../src/DrawerTypes.ts"],"sourcesContent":["import Drawer, { DrawerContext } from \"./Drawer\";\n\nexport default Drawer;\nexport { Drawer, DrawerContext };\nexport * from \"./DrawerTypes\";\n","import * as React from \"react\";\nimport { useContext, useEffect, useRef } from \"react\";\nimport FocusLock from \"react-focus-lock\";\nimport { motion, AnimatePresence } from \"motion/react\";\nimport { MOTION_DURATION_MEDIUM } from \"@sproutsocial/seeds-motion/unitless\";\nimport Box from \"@sproutsocial/seeds-react-box\";\nimport Button from \"@sproutsocial/seeds-react-button\";\nimport Icon from \"@sproutsocial/seeds-react-icon\";\n// eslint-disable-next-line import/no-deprecated\nimport Text from \"@sproutsocial/seeds-react-text\";\nimport Portal from \"@sproutsocial/seeds-react-portal\";\nimport Container, { Content } from \"./styles\";\nimport type {\n TypeDrawerContext,\n TypeDrawerCloseButtonProps,\n TypeDrawerHeaderProps,\n TypeDrawerProps,\n TypeInnerDrawerProps,\n TypeDrawerContentProps,\n TypeUseCloseOnBodyClickProps,\n} from \"./DrawerTypes\";\n\nconst MotionContainer = motion(Container as any);\n\nconst doesRefContainEventTarget = (\n ref: { current: { contains: (arg0: any) => any } },\n event: Event\n) => {\n return (\n ref.current &&\n event.target instanceof Node &&\n ref.current.contains(event.target)\n );\n};\n\nexport const DrawerContext = React.createContext<TypeDrawerContext>({\n isLocked: false,\n setIsLocked: () => {},\n});\n\nconst DrawerCloseButton = (props: TypeDrawerCloseButtonProps) => {\n const drawerContext = useContext(DrawerContext);\n\n if (props.render) {\n return props.render(drawerContext) ?? null;\n }\n\n return (\n <Button\n appearance=\"pill\"\n aria-label={drawerContext.closeButtonLabel}\n onClick={drawerContext.onClose}\n {...props}\n >\n {props.children || <Icon aria-hidden name=\"x-outline\" />}\n </Button>\n );\n};\n\nconst DrawerHeader = ({\n title = \"\",\n id = undefined,\n children,\n render,\n ...rest\n}: TypeDrawerHeaderProps) => {\n const drawerContext = useContext(DrawerContext);\n\n if (render) {\n return render(drawerContext);\n }\n\n return (\n <Box\n display=\"flex\"\n flex=\"0 0 auto\"\n justifyContent=\"space-between\"\n alignItems=\"center\"\n pt={400}\n px={450}\n {...rest}\n >\n {children || (\n <React.Fragment>\n <Text\n as=\"h2\"\n fontSize={400}\n fontWeight=\"semibold\"\n color=\"text.headline\"\n id={id}\n >\n {title}\n </Text>\n <DrawerCloseButton />\n </React.Fragment>\n )}\n </Box>\n );\n};\n\nconst DrawerContent = ({ children, ...rest }: TypeDrawerContentProps) => (\n <Content height=\"100%\" p={450} color=\"text.body\" {...rest}>\n {children}\n </Content>\n);\n\nconst useCloseOnBodyClick = ({\n isOpen,\n ref,\n disableCloseOnClickOutside,\n onClose,\n closeTargets,\n}: TypeUseCloseOnBodyClickProps) => {\n const { isLocked } = useContext(DrawerContext);\n\n useEffect(() => {\n const documentBody = document.body;\n\n if (!documentBody || !isOpen) {\n return;\n }\n\n const onEsc = (event: KeyboardEvent): void => {\n if (!isLocked && event.key === \"Escape\") {\n onClose();\n }\n };\n\n const bodyClick = (event: Event): void => {\n if (\n // @ts-ignore I'm not sure how to type this ref properly\n !doesRefContainEventTarget(ref, event) &&\n !disableCloseOnClickOutside\n ) {\n onClose();\n }\n };\n\n documentBody?.addEventListener(\"keydown\", onEsc, { capture: true });\n\n if (closeTargets) {\n closeTargets.forEach((targetElement) =>\n targetElement?.addEventListener(\"click\", bodyClick, { capture: true })\n );\n } else {\n documentBody.firstElementChild?.addEventListener(\"click\", bodyClick, {\n capture: true,\n });\n }\n\n return () => {\n documentBody?.removeEventListener(\"keydown\", onEsc, { capture: true });\n\n if (closeTargets) {\n closeTargets.forEach((targetElement) =>\n targetElement?.removeEventListener(\"click\", bodyClick, {\n capture: true,\n })\n );\n } else {\n documentBody.firstElementChild?.removeEventListener(\n \"click\",\n bodyClick,\n { capture: true }\n );\n }\n };\n }, [\n onClose,\n disableCloseOnClickOutside,\n closeTargets,\n ref,\n isLocked,\n isOpen,\n ]);\n};\n\nconst Drawer = ({\n id,\n offset,\n direction,\n children,\n disableCloseOnClickOutside,\n onClose,\n zIndex,\n closeTargets,\n width,\n focusLockExemptCheck,\n isOpen,\n ...rest\n}: TypeInnerDrawerProps) => {\n const ref = useRef(null);\n useCloseOnBodyClick({\n ref,\n disableCloseOnClickOutside,\n onClose,\n closeTargets,\n isOpen,\n });\n\n const offset_x = width * (direction === \"left\" ? -1 : 1);\n\n return (\n <FocusLock\n key={id}\n autoFocus={true}\n returnFocus\n whiteList={\n focusLockExemptCheck ? (e) => !focusLockExemptCheck(e) : undefined\n }\n >\n <AnimatePresence>\n {isOpen && (\n <MotionContainer\n ref={ref}\n style={{ zIndex }}\n width={width}\n offset={offset}\n direction={direction}\n data-qa-drawer={id}\n role=\"dialog\"\n initial={{ opacity: 0, x: offset_x }}\n animate={{ opacity: 1, x: 0 }}\n exit={{ opacity: 0, x: offset_x }}\n transition={{ duration: MOTION_DURATION_MEDIUM }}\n {...rest}\n >\n {children}\n </MotionContainer>\n )}\n </AnimatePresence>\n </FocusLock>\n );\n};\n\nconst DrawerContainer = ({\n children,\n closeButtonLabel,\n direction = \"right\",\n disableCloseOnClickOutside = false,\n id,\n isOpen,\n offset = 0,\n onClose,\n zIndex = 7,\n closeTargets = [],\n width = 600,\n ...rest\n}: TypeDrawerProps) => {\n const [isLocked, setIsLocked] = React.useState(false);\n return (\n <Portal id={id}>\n <DrawerContext.Provider\n value={{\n onClose,\n closeButtonLabel,\n isLocked,\n setIsLocked,\n }}\n >\n <Drawer\n isOpen={isOpen}\n id={id}\n offset={offset}\n direction={direction}\n disableCloseOnClickOutside={disableCloseOnClickOutside}\n onClose={onClose}\n zIndex={zIndex}\n closeTargets={closeTargets}\n width={width}\n data-qa-drawer={id || \"\"}\n data-qa-drawer-isopen={isOpen}\n {...rest}\n >\n {children}\n </Drawer>\n </DrawerContext.Provider>\n </Portal>\n );\n};\n\nDrawerHeader.displayName = \"Drawer.Header\";\nDrawerContent.displayName = \"Drawer.Content\";\nDrawerCloseButton.displayName = \"Drawer.CloseButton\";\n\nDrawerContainer.Header = DrawerHeader;\nDrawerContainer.Content = DrawerContent;\nDrawerContainer.CloseButton = DrawerCloseButton;\n\nexport default DrawerContainer;\n","import type { TypeDrawerProps } from \"./DrawerTypes\";\nimport styled, { css } from \"styled-components\";\nimport { COMMON } from \"@sproutsocial/seeds-react-system-props\";\nimport type { TypeSystemCommonProps } from \"@sproutsocial/seeds-react-system-props\";\n\nimport Box from \"@sproutsocial/seeds-react-box\";\n\nexport const Content = styled(Box)`\n overflow-y: auto;\n`;\n\ninterface ContainerType\n extends Pick<TypeDrawerProps, \"offset\" | \"direction\">,\n TypeSystemCommonProps {\n width: number;\n}\n\nconst Container = styled.div<ContainerType>`\n display: flex;\n flex-direction: column;\n position: fixed;\n top: 0;\n height: 100%;\n width: ${(props) => props.width}px;\n background-color: ${(props) => props.theme.colors.container.background.base};\n box-shadow: ${(props) => props.theme.shadows.high};\n filter: blur(0);\n\n ${(props) => css`\n ${props.direction}: ${props.offset}px;\n `}\n\n ${COMMON}\n`;\nexport default Container;\n","import * as React from \"react\";\nimport type {\n TypeSystemCommonProps,\n TypeStyledComponentsCommonProps,\n} from \"@sproutsocial/seeds-react-system-props\";\nimport type { TypeBoxProps } from \"@sproutsocial/seeds-react-box\";\nimport type { TypeButtonProps } from \"@sproutsocial/seeds-react-button\";\n\ntype DrawerAnimationDirection = \"left\" | \"right\";\n\nexport interface TypeDrawerContext {\n /** Callback for close button */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n onClose?: () => any;\n\n /** aria-label for drawer close button */\n closeButtonLabel?: string;\n /**\n * isLocked and setIsLocked are used when a Drawer contains other components (like Menu) that also\n * listen for Escape key events. By locking the Drawer, we can prevent conflicts\n * where multiple components try to handle the same keydown event.\n */\n isLocked: boolean;\n setIsLocked: (locked: boolean) => void;\n}\n// TODO: Should the render prop be a React.FC?\nexport interface TypeDrawerCloseButtonProps\n extends Omit<TypeButtonProps, \"children\"> {\n /** An optional function that receives the context of the parent drawer as an argument. Can be used to customize the on-close behavior. */\n render?: React.FC<TypeDrawerContext>;\n children?: React.ReactNode;\n}\n\nexport interface TypeDrawerHeaderProps extends TypeBoxProps {\n title?: string;\n children?: React.ReactNode;\n\n /** An optional function that receives the context of the parent drawer as an argument. Can be used to customize the appearance of the header. */\n render?: React.FC<TypeDrawerContext>;\n}\n\nexport interface TypeInnerDrawerProps\n extends Omit<TypeDrawerProps, \"closeButtonLabel\"> {\n width: number;\n direction: DrawerAnimationDirection;\n}\n\ntype useBodyClicksProps = Pick<\n TypeDrawerProps,\n \"closeTargets\" | \"onClose\" | \"disableCloseOnClickOutside\"\n>;\n\nexport interface TypeUseCloseOnBodyClickProps\n extends Pick<\n TypeDrawerProps,\n \"closeTargets\" | \"onClose\" | \"disableCloseOnClickOutside\"\n > {\n ref?: React.RefObject<HTMLElement | null>;\n isOpen: boolean;\n}\n\nexport interface TypeDrawerProps\n extends TypeStyledComponentsCommonProps,\n TypeSystemCommonProps,\n Omit<React.ComponentPropsWithoutRef<\"nav\">, \"color\"> {\n children: React.ReactNode;\n\n /** Label for the close button. Usually this should be \"Close\" */\n closeButtonLabel: string;\n\n /** Whether the drawer slides in from the left or right side of the screen */\n direction?: DrawerAnimationDirection;\n\n /** In some cases, you may not want the user to be able to click outside of the drawer to close it. You can disable that with this prop. */\n disableCloseOnClickOutside?: boolean;\n id: string;\n isOpen: boolean;\n offset?: number;\n onClose: () => void;\n zIndex?: number;\n closeTargets?: Array<Element>;\n width?: number;\n focusLockExemptCheck?: (element: HTMLElement) => boolean;\n}\n\nexport interface TypeDrawerContentProps extends TypeBoxProps {\n children?: React.ReactNode;\n}\n"],"mappings":"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","names":["import_react","import_seeds_react_box","styled","Box","Button","Icon","Box","Text","FocusLock","Portal","React"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sproutsocial/seeds-react-drawer",
3
- "version": "1.1.11",
3
+ "version": "1.1.13",
4
4
  "description": "Seeds React Drawer",
5
5
  "author": "Sprout Social, Inc.",
6
6
  "license": "MIT",
@@ -18,11 +18,11 @@
18
18
  "test:watch": "jest --watch --coverage=false"
19
19
  },
20
20
  "dependencies": {
21
- "@sproutsocial/seeds-react-theme": "^3.3.0",
21
+ "@sproutsocial/seeds-react-theme": "^3.3.1",
22
22
  "@sproutsocial/seeds-react-system-props": "^3.0.1",
23
- "@sproutsocial/seeds-react-box": "^1.1.8",
24
- "@sproutsocial/seeds-react-button": "^1.3.9",
25
- "@sproutsocial/seeds-react-icon": "^2.0.4",
23
+ "@sproutsocial/seeds-react-box": "^1.1.9",
24
+ "@sproutsocial/seeds-react-button": "^1.3.10",
25
+ "@sproutsocial/seeds-react-icon": "^2.0.5",
26
26
  "@sproutsocial/seeds-react-text": "^1.3.2",
27
27
  "@sproutsocial/seeds-react-portal": "^1.1.4",
28
28
  "@sproutsocial/seeds-motion": "^1.8.0",
package/src/Drawer.tsx CHANGED
@@ -105,6 +105,7 @@ const DrawerContent = ({ children, ...rest }: TypeDrawerContentProps) => (
105
105
  );
106
106
 
107
107
  const useCloseOnBodyClick = ({
108
+ isOpen,
108
109
  ref,
109
110
  disableCloseOnClickOutside,
110
111
  onClose,
@@ -115,7 +116,7 @@ const useCloseOnBodyClick = ({
115
116
  useEffect(() => {
116
117
  const documentBody = document.body;
117
118
 
118
- if (!documentBody) {
119
+ if (!documentBody || !isOpen) {
119
120
  return;
120
121
  }
121
122
 
@@ -164,7 +165,14 @@ const useCloseOnBodyClick = ({
164
165
  );
165
166
  }
166
167
  };
167
- }, [onClose, disableCloseOnClickOutside, closeTargets, ref, isLocked]);
168
+ }, [
169
+ onClose,
170
+ disableCloseOnClickOutside,
171
+ closeTargets,
172
+ ref,
173
+ isLocked,
174
+ isOpen,
175
+ ]);
168
176
  };
169
177
 
170
178
  const Drawer = ({
@@ -187,6 +195,7 @@ const Drawer = ({
187
195
  disableCloseOnClickOutside,
188
196
  onClose,
189
197
  closeTargets,
198
+ isOpen,
190
199
  });
191
200
 
192
201
  const offset_x = width * (direction === "left" ? -1 : 1);
@@ -56,6 +56,7 @@ export interface TypeUseCloseOnBodyClickProps
56
56
  "closeTargets" | "onClose" | "disableCloseOnClickOutside"
57
57
  > {
58
58
  ref?: React.RefObject<HTMLElement | null>;
59
+ isOpen: boolean;
59
60
  }
60
61
 
61
62
  export interface TypeDrawerProps
@@ -173,6 +173,31 @@ describe("Drawer", () => {
173
173
  });
174
174
  });
175
175
 
176
+ it("should call onClose callback when drawer is closed", async () => {
177
+ const onClose = jest.fn();
178
+ const { user } = render({
179
+ isOpen: true,
180
+ onClose,
181
+ });
182
+ expect(screen.getByText(/drawer content/i)).toBeInTheDocument();
183
+ await act(async () => {
184
+ await user.click(screen.getByLabelText("close button"));
185
+ });
186
+ await waitFor(() => {
187
+ expect(onClose).toHaveBeenCalledTimes(1);
188
+ });
189
+ });
190
+
191
+ it("should not call onClose callback when drawer is already closed", async () => {
192
+ const onClose = jest.fn();
193
+ render({
194
+ isOpen: false,
195
+ onClose,
196
+ });
197
+ expect(screen.queryByText(/drawer content/i)).not.toBeInTheDocument();
198
+ expect(onClose).toHaveBeenCalledTimes(0);
199
+ });
200
+
176
201
  it("should have dialog role", () => {
177
202
  render({
178
203
  isOpen: true,