@sproutsocial/seeds-react-drawer 1.1.12 → 1.1.14
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/.turbo/turbo-build.log +10 -10
- package/CHANGELOG.md +14 -0
- package/dist/esm/index.js +12 -3
- package/dist/esm/index.js.map +1 -1
- package/dist/index.d.mts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +12 -3
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/Drawer.tsx +11 -2
- package/src/DrawerTypes.ts +1 -0
- package/src/__tests__/Drawer.test.tsx +25 -0
package/.turbo/turbo-build.log
CHANGED
|
@@ -8,14 +8,14 @@ $ tsup --dts
|
|
|
8
8
|
[34mCLI[39m Cleaning output folder
|
|
9
9
|
[34mCJS[39m Build start
|
|
10
10
|
[34mESM[39m Build start
|
|
11
|
-
[32mCJS[39m [1mdist/index.js [22m[32m9.
|
|
12
|
-
[32mCJS[39m [1mdist/index.js.map [22m[32m15.
|
|
13
|
-
[32mCJS[39m ⚡️ Build success in
|
|
14
|
-
[32mESM[39m [1mdist/esm/index.js [22m[32m6.
|
|
15
|
-
[32mESM[39m [1mdist/esm/index.js.map [22m[32m15.
|
|
16
|
-
[32mESM[39m ⚡️ Build success in
|
|
11
|
+
[32mCJS[39m [1mdist/index.js [22m[32m9.48 KB[39m
|
|
12
|
+
[32mCJS[39m [1mdist/index.js.map [22m[32m15.55 KB[39m
|
|
13
|
+
[32mCJS[39m ⚡️ Build success in 221ms
|
|
14
|
+
[32mESM[39m [1mdist/esm/index.js [22m[32m6.89 KB[39m
|
|
15
|
+
[32mESM[39m [1mdist/esm/index.js.map [22m[32m15.37 KB[39m
|
|
16
|
+
[32mESM[39m ⚡️ Build success in 228ms
|
|
17
17
|
[34mDTS[39m Build start
|
|
18
|
-
[32mDTS[39m ⚡️ Build success in
|
|
19
|
-
[32mDTS[39m [1mdist/index.d.ts [22m[32m3.
|
|
20
|
-
[32mDTS[39m [1mdist/index.d.mts [22m[32m3.
|
|
21
|
-
Done in 40.
|
|
18
|
+
[32mDTS[39m ⚡️ Build success in 32470ms
|
|
19
|
+
[32mDTS[39m [1mdist/index.d.ts [22m[32m3.79 KB[39m
|
|
20
|
+
[32mDTS[39m [1mdist/index.d.mts [22m[32m3.79 KB[39m
|
|
21
|
+
Done in 40.11s.
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @sproutsocial/seeds-react-drawer
|
|
2
2
|
|
|
3
|
+
## 1.1.14
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [b147e07]
|
|
8
|
+
- @sproutsocial/seeds-react-icon@2.1.0
|
|
9
|
+
- @sproutsocial/seeds-react-button@1.3.11
|
|
10
|
+
|
|
11
|
+
## 1.1.13
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- b7d7463: Prevent Drawer onClose from firing when closed
|
|
16
|
+
|
|
3
17
|
## 1.1.12
|
|
4
18
|
|
|
5
19
|
### 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
|
-
}, [
|
|
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(
|
package/dist/esm/index.js.map
CHANGED
|
@@ -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
|
-
}, [
|
|
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.
|
|
3
|
+
"version": "1.1.14",
|
|
4
4
|
"description": "Seeds React Drawer",
|
|
5
5
|
"author": "Sprout Social, Inc.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
"@sproutsocial/seeds-react-theme": "^3.3.1",
|
|
22
22
|
"@sproutsocial/seeds-react-system-props": "^3.0.1",
|
|
23
23
|
"@sproutsocial/seeds-react-box": "^1.1.9",
|
|
24
|
-
"@sproutsocial/seeds-react-button": "^1.3.
|
|
25
|
-
"@sproutsocial/seeds-react-icon": "^2.0
|
|
24
|
+
"@sproutsocial/seeds-react-button": "^1.3.11",
|
|
25
|
+
"@sproutsocial/seeds-react-icon": "^2.1.0",
|
|
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
|
-
}, [
|
|
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);
|
package/src/DrawerTypes.ts
CHANGED
|
@@ -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,
|