@hyphen/hyphen-components 2.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +70 -0
- package/package.json +138 -0
- package/src/components/Alert/Alert.constants.ts +19 -0
- package/src/components/Alert/Alert.mdx +29 -0
- package/src/components/Alert/Alert.module.scss +74 -0
- package/src/components/Alert/Alert.stories.tsx +102 -0
- package/src/components/Alert/Alert.test.tsx +187 -0
- package/src/components/Alert/Alert.tsx +157 -0
- package/src/components/Alert/Alert.types.ts +14 -0
- package/src/components/Badge/Badge.mdx +28 -0
- package/src/components/Badge/Badge.module.scss +155 -0
- package/src/components/Badge/Badge.stories.tsx +52 -0
- package/src/components/Badge/Badge.test.tsx +74 -0
- package/src/components/Badge/Badge.tsx +70 -0
- package/src/components/Box/Box.mdx +259 -0
- package/src/components/Box/Box.module.scss +16 -0
- package/src/components/Box/Box.stories.tsx +1679 -0
- package/src/components/Box/Box.test.tsx +478 -0
- package/src/components/Box/Box.tsx +636 -0
- package/src/components/Button/Button.constants.ts +10 -0
- package/src/components/Button/Button.mdx +71 -0
- package/src/components/Button/Button.module.scss +312 -0
- package/src/components/Button/Button.stories.tsx +117 -0
- package/src/components/Button/Button.test.tsx +460 -0
- package/src/components/Button/Button.tsx +241 -0
- package/src/components/Card/Card.mdx +46 -0
- package/src/components/Card/Card.module.scss +6 -0
- package/src/components/Card/Card.stories.tsx +101 -0
- package/src/components/Card/Card.test.tsx +11 -0
- package/src/components/Card/Card.tsx +61 -0
- package/src/components/Card/components/CardFooter/CardFooter.test.tsx +11 -0
- package/src/components/Card/components/CardFooter/CardFooter.tsx +35 -0
- package/src/components/Card/components/CardHeader/CardHeader.test.tsx +23 -0
- package/src/components/Card/components/CardHeader/CardHeader.tsx +54 -0
- package/src/components/Card/components/CardSection/CardSection.test.tsx +28 -0
- package/src/components/Card/components/CardSection/CardSection.tsx +102 -0
- package/src/components/Card/components/index.ts +3 -0
- package/src/components/CheckboxInput/CheckboxInput.mdx +98 -0
- package/src/components/CheckboxInput/CheckboxInput.stories.tsx +254 -0
- package/src/components/CheckboxInput/CheckboxInput.test.tsx +436 -0
- package/src/components/CheckboxInput/CheckboxInput.tsx +171 -0
- package/src/components/CheckboxInput/components/Checkbox.module.scss +174 -0
- package/src/components/CheckboxInput/components/Checkbox.test.tsx +201 -0
- package/src/components/CheckboxInput/components/Checkbox.tsx +176 -0
- package/src/components/CheckboxInput/components/CheckboxIcon.tsx +71 -0
- package/src/components/DateInput/DateInput.mdx +61 -0
- package/src/components/DateInput/DateInput.stories.tsx +168 -0
- package/src/components/DateInput/DateInput.test.tsx +258 -0
- package/src/components/DateInput/DateInput.tsx +189 -0
- package/src/components/DatePicker/DatePicker.mdx +52 -0
- package/src/components/DatePicker/DatePicker.module.scss +603 -0
- package/src/components/DatePicker/DatePicker.stories.tsx +199 -0
- package/src/components/DatePicker/DatePicker.test.tsx +26 -0
- package/src/components/DatePicker/DatePicker.tsx +138 -0
- package/src/components/Details/Details.mdx +30 -0
- package/src/components/Details/Details.module.scss +32 -0
- package/src/components/Details/Details.stories.tsx +38 -0
- package/src/components/Details/Details.test.tsx +189 -0
- package/src/components/Details/Details.tsx +51 -0
- package/src/components/Details/DetailsSummary.tsx +65 -0
- package/src/components/Drawer/Drawer.mdx +117 -0
- package/src/components/Drawer/Drawer.module.scss +96 -0
- package/src/components/Drawer/Drawer.stories.tsx +380 -0
- package/src/components/Drawer/Drawer.test.tsx +90 -0
- package/src/components/Drawer/Drawer.tsx +249 -0
- package/src/components/FormControl/FormControl.tsx +78 -0
- package/src/components/FormLabel/FormLabel.mdx +24 -0
- package/src/components/FormLabel/FormLabel.module.scss +19 -0
- package/src/components/FormLabel/FormLabel.stories.tsx +20 -0
- package/src/components/FormLabel/FormLabel.test.tsx +35 -0
- package/src/components/FormLabel/FormLabel.tsx +96 -0
- package/src/components/Formik/Formik.mdx +10 -0
- package/src/components/Formik/Formik.stories.tsx +307 -0
- package/src/components/Formik/FormikCheckboxInput/FormikCheckboxInput.test.tsx +172 -0
- package/src/components/Formik/FormikCheckboxInput/FormikCheckboxInput.tsx +41 -0
- package/src/components/Formik/FormikRadioGroup/FormikRadioGroup.test.tsx +205 -0
- package/src/components/Formik/FormikRadioGroup/FormikRadioGroup.tsx +37 -0
- package/src/components/Formik/FormikSelectInput/FormikSelectInput.test.tsx +210 -0
- package/src/components/Formik/FormikSelectInput/FormikSelectInput.tsx +41 -0
- package/src/components/Formik/FormikSelectInputInset/FormikSelectInputInset.test.tsx +153 -0
- package/src/components/Formik/FormikSelectInputInset/FormikSelectInputInset.tsx +44 -0
- package/src/components/Formik/FormikSelectInputNative/FormikSelectInputNative.test.tsx +161 -0
- package/src/components/Formik/FormikSelectInputNative/FormikSelectInputNative.tsx +46 -0
- package/src/components/Formik/FormikTextInput/FormikTextInput.test.tsx +176 -0
- package/src/components/Formik/FormikTextInput/FormikTextInput.tsx +38 -0
- package/src/components/Formik/FormikTextInputInset/FormikTextInputInset.test.tsx +170 -0
- package/src/components/Formik/FormikTextInputInset/FormikTextInputInset.tsx +42 -0
- package/src/components/Formik/FormikTextareaInput/FormikTextareaInput.test.tsx +186 -0
- package/src/components/Formik/FormikTextareaInput/FormikTextareaInput.tsx +42 -0
- package/src/components/Formik/FormikTextareaInputInset/FormikTextareaInputInset.test.tsx +179 -0
- package/src/components/Formik/FormikTextareaInputInset/FormikTextareaInputInset.tsx +42 -0
- package/src/components/Formik/FormikTimePicker/FormikTimePicker.test.tsx +224 -0
- package/src/components/Formik/FormikTimePicker/FormikTimePicker.tsx +37 -0
- package/src/components/Formik/FormikTimePickerNative/FormikTimePickerNative.test.tsx +175 -0
- package/src/components/Formik/FormikTimePickerNative/FormikTimePickerNative.tsx +38 -0
- package/src/components/Formik/FormikToggle/FormikToggle.test.tsx +172 -0
- package/src/components/Formik/FormikToggle/FormikToggle.tsx +38 -0
- package/src/components/Heading/Heading.constants.ts +19 -0
- package/src/components/Heading/Heading.mdx +35 -0
- package/src/components/Heading/Heading.module.scss +5 -0
- package/src/components/Heading/Heading.stories.tsx +90 -0
- package/src/components/Heading/Heading.test.tsx +67 -0
- package/src/components/Heading/Heading.tsx +67 -0
- package/src/components/HelpText/HelpText.module.scss +14 -0
- package/src/components/HelpText/HelpText.tsx +33 -0
- package/src/components/Icon/Icon.mdx +40 -0
- package/src/components/Icon/Icon.stories.tsx +72 -0
- package/src/components/Icon/Icon.test.tsx +30 -0
- package/src/components/Icon/Icon.tsx +61 -0
- package/src/components/InputValidationMessage/InputValidationMessage.module.scss +3 -0
- package/src/components/InputValidationMessage/InputValidationMessage.tsx +27 -0
- package/src/components/Modal/Modal.mdx +60 -0
- package/src/components/Modal/Modal.module.scss +135 -0
- package/src/components/Modal/Modal.stories.tsx +194 -0
- package/src/components/Modal/Modal.test.tsx +81 -0
- package/src/components/Modal/Modal.tsx +174 -0
- package/src/components/Modal/components/ModalBody/ModalBody.test.tsx +20 -0
- package/src/components/Modal/components/ModalBody/ModalBody.tsx +24 -0
- package/src/components/Modal/components/ModalFooter/ModalFooter.test.tsx +32 -0
- package/src/components/Modal/components/ModalFooter/ModalFooter.tsx +37 -0
- package/src/components/Modal/components/ModalHeader/ModalHeader.test.tsx +29 -0
- package/src/components/Modal/components/ModalHeader/ModalHeader.tsx +58 -0
- package/src/components/Modal/components/index.ts +5 -0
- package/src/components/Pagination/Pagination.mdx +26 -0
- package/src/components/Pagination/Pagination.stories.tsx +55 -0
- package/src/components/Pagination/Pagination.test.tsx +225 -0
- package/src/components/Pagination/Pagination.tsx +162 -0
- package/src/components/Pagination/Pagination.utilities.test.ts +133 -0
- package/src/components/Pagination/Pagination.utilities.ts +101 -0
- package/src/components/Popover/Popover.mdx +104 -0
- package/src/components/Popover/Popover.module.scss +74 -0
- package/src/components/Popover/Popover.stories.tsx +471 -0
- package/src/components/Popover/Popover.test.tsx +128 -0
- package/src/components/Popover/Popover.tsx +277 -0
- package/src/components/RadioGroup/RadioGroup.mdx +81 -0
- package/src/components/RadioGroup/RadioGroup.module.scss +23 -0
- package/src/components/RadioGroup/RadioGroup.stories.tsx +375 -0
- package/src/components/RadioGroup/RadioGroup.test.tsx +282 -0
- package/src/components/RadioGroup/RadioGroup.tsx +145 -0
- package/src/components/RadioGroup/RadioInput/RadioInput.module.scss +114 -0
- package/src/components/RadioGroup/RadioInput/RadioInput.test.tsx +156 -0
- package/src/components/RadioGroup/RadioInput/RadioInput.tsx +148 -0
- package/src/components/RadioGroup/RadioInput/RadioInputIcon.tsx +59 -0
- package/src/components/ResponsiveProvider/ResponsiveProvider.mdx +36 -0
- package/src/components/ResponsiveProvider/ResponsiveProvider.stories.tsx +54 -0
- package/src/components/ResponsiveProvider/ResponsiveProvider.test.tsx +70 -0
- package/src/components/ResponsiveProvider/ResponsiveProvider.tsx +73 -0
- package/src/components/SelectInput/SelectInput.mdx +115 -0
- package/src/components/SelectInput/SelectInput.module.scss +357 -0
- package/src/components/SelectInput/SelectInput.stories.tsx +373 -0
- package/src/components/SelectInput/SelectInput.test.tsx +403 -0
- package/src/components/SelectInput/SelectInput.tsx +245 -0
- package/src/components/SelectInputInset/SelectInputInset.mdx +56 -0
- package/src/components/SelectInputInset/SelectInputInset.module.scss +397 -0
- package/src/components/SelectInputInset/SelectInputInset.stories.tsx +189 -0
- package/src/components/SelectInputInset/SelectInputInset.test.tsx +305 -0
- package/src/components/SelectInputInset/SelectInputInset.tsx +235 -0
- package/src/components/SelectInputNative/SelectInputNative.mdx +87 -0
- package/src/components/SelectInputNative/SelectInputNative.module.scss +356 -0
- package/src/components/SelectInputNative/SelectInputNative.stories.tsx +282 -0
- package/src/components/SelectInputNative/SelectInputNative.test.tsx +341 -0
- package/src/components/SelectInputNative/SelectInputNative.tsx +121 -0
- package/src/components/Spinner/Spinner.mdx +29 -0
- package/src/components/Spinner/Spinner.module.scss +16 -0
- package/src/components/Spinner/Spinner.stories.tsx +48 -0
- package/src/components/Spinner/Spinner.test.tsx +47 -0
- package/src/components/Spinner/Spinner.tsx +116 -0
- package/src/components/Table/Table.mdx +216 -0
- package/src/components/Table/Table.module.scss +61 -0
- package/src/components/Table/Table.stories.tsx +884 -0
- package/src/components/Table/Table.test.tsx +437 -0
- package/src/components/Table/Table.tsx +171 -0
- package/src/components/Table/TableBody/TableBody.module.scss +19 -0
- package/src/components/Table/TableBody/TableBody.test.tsx +38 -0
- package/src/components/Table/TableBody/TableBody.tsx +96 -0
- package/src/components/Table/TableBody/TableBodyCell/TableBodyCell.module.scss +47 -0
- package/src/components/Table/TableBody/TableBodyCell/TableBodyCell.test.tsx +81 -0
- package/src/components/Table/TableBody/TableBodyCell/TableBodyCell.tsx +94 -0
- package/src/components/Table/TableHead/TableHead.test.tsx +20 -0
- package/src/components/Table/TableHead/TableHead.tsx +78 -0
- package/src/components/Table/TableHead/TableHeaderCell/TableHeaderCell.module.scss +72 -0
- package/src/components/Table/TableHead/TableHeaderCell/TableHeaderCell.test.tsx +187 -0
- package/src/components/Table/TableHead/TableHeaderCell/TableHeaderCell.tsx +192 -0
- package/src/components/Table/common/TableRow/TableRow.module.scss +5 -0
- package/src/components/Table/common/TableRow/TableRow.test.tsx +52 -0
- package/src/components/Table/common/TableRow/TableRow.tsx +155 -0
- package/src/components/TextInput/TextInput.mdx +96 -0
- package/src/components/TextInput/TextInput.module.scss +405 -0
- package/src/components/TextInput/TextInput.stories.tsx +268 -0
- package/src/components/TextInput/TextInput.test.tsx +231 -0
- package/src/components/TextInput/TextInput.tsx +263 -0
- package/src/components/TextInputInset/TextInputInset.mdx +62 -0
- package/src/components/TextInputInset/TextInputInset.module.scss +418 -0
- package/src/components/TextInputInset/TextInputInset.stories.tsx +213 -0
- package/src/components/TextInputInset/TextInputInset.test.tsx +222 -0
- package/src/components/TextInputInset/TextInputInset.tsx +261 -0
- package/src/components/TextareaInput/TextareaInput.mdx +117 -0
- package/src/components/TextareaInput/TextareaInput.module.scss +275 -0
- package/src/components/TextareaInput/TextareaInput.stories.tsx +293 -0
- package/src/components/TextareaInput/TextareaInput.test.tsx +195 -0
- package/src/components/TextareaInput/TextareaInput.tsx +182 -0
- package/src/components/TextareaInputInset/TextareaInputInset.mdx +55 -0
- package/src/components/TextareaInputInset/TextareaInputInset.module.scss +337 -0
- package/src/components/TextareaInputInset/TextareaInputInset.stories.tsx +160 -0
- package/src/components/TextareaInputInset/TextareaInputInset.test.tsx +199 -0
- package/src/components/TextareaInputInset/TextareaInputInset.tsx +213 -0
- package/src/components/ThemeProvider/ThemeProvider.mdx +11 -0
- package/src/components/ThemeProvider/ThemeProvider.stories.tsx +56 -0
- package/src/components/ThemeProvider/ThemeProvider.tsx +75 -0
- package/src/components/TimePicker/TimePicker.mdx +75 -0
- package/src/components/TimePicker/TimePicker.stories.tsx +149 -0
- package/src/components/TimePicker/TimePicker.test.tsx +97 -0
- package/src/components/TimePicker/TimePicker.tsx +83 -0
- package/src/components/TimePickerNative/TimePickerNative.mdx +67 -0
- package/src/components/TimePickerNative/TimePickerNative.stories.tsx +151 -0
- package/src/components/TimePickerNative/TimePickerNative.test.tsx +117 -0
- package/src/components/TimePickerNative/TimePickerNative.tsx +93 -0
- package/src/components/Toast/Toast.mdx +134 -0
- package/src/components/Toast/Toast.store.ts +280 -0
- package/src/components/Toast/Toast.stories.tsx +283 -0
- package/src/components/Toast/Toast.test.tsx +784 -0
- package/src/components/Toast/Toast.types.ts +98 -0
- package/src/components/Toast/ToastContainer.tsx +170 -0
- package/src/components/Toast/ToastNotification.module.scss +63 -0
- package/src/components/Toast/ToastNotification.tsx +176 -0
- package/src/components/Toast/index.ts +4 -0
- package/src/components/Toast/toast.ts +102 -0
- package/src/components/Toast/useToasts.ts +102 -0
- package/src/components/Toggle/Toggle.mdx +51 -0
- package/src/components/Toggle/Toggle.module.scss +294 -0
- package/src/components/Toggle/Toggle.stories.tsx +128 -0
- package/src/components/Toggle/Toggle.test.tsx +308 -0
- package/src/components/Toggle/Toggle.tsx +184 -0
- package/src/constants/keyCodes.ts +2 -0
- package/src/docs/Brands.mdx +153 -0
- package/src/docs/Colors.mdx +158 -0
- package/src/docs/DesignTokens.mdx +415 -0
- package/src/docs/GetStarted.mdx +47 -0
- package/src/docs/intro.mdx +12 -0
- package/src/fonts/AvenirBold.otf +0 -0
- package/src/fonts/AvenirBold.woff +0 -0
- package/src/fonts/AvenirBold.woff2 +0 -0
- package/src/fonts/AvenirLight.otf +0 -0
- package/src/fonts/AvenirLight.woff +0 -0
- package/src/fonts/AvenirLight.woff2 +0 -0
- package/src/fonts/AvenirRegular.otf +0 -0
- package/src/fonts/AvenirRegular.woff +0 -0
- package/src/fonts/AvenirRegular.woff2 +0 -0
- package/src/fonts/Geist-Bold.otf +0 -0
- package/src/fonts/Geist-Bold.woff +0 -0
- package/src/fonts/Geist-Bold.woff2 +0 -0
- package/src/fonts/Geist-Medium.otf +0 -0
- package/src/fonts/Geist-Medium.woff +0 -0
- package/src/fonts/Geist-Medium.woff2 +0 -0
- package/src/fonts/Geist-Regular.otf +0 -0
- package/src/fonts/Geist-Regular.woff +0 -0
- package/src/fonts/Geist-Regular.woff2 +0 -0
- package/src/fonts/Geist-SemiBold.otf +0 -0
- package/src/fonts/Geist-SemiBold.woff +0 -0
- package/src/fonts/Geist-SemiBold.woff2 +0 -0
- package/src/fonts/GeistMono-Regular.otf +0 -0
- package/src/fonts/GeistMono-Regular.woff +0 -0
- package/src/fonts/GeistMono-Regular.woff2 +0 -0
- package/src/hooks/index.ts +4 -0
- package/src/hooks/useBreakpoint/useBreakpoint.mdx +26 -0
- package/src/hooks/useBreakpoint/useBreakpoint.stories.tsx +30 -0
- package/src/hooks/useBreakpoint/useBreakpoint.test.tsx +19 -0
- package/src/hooks/useBreakpoint/useBreakpoint.ts +50 -0
- package/src/hooks/useIsomorphicLayoutEffect/useIsomorphicLayouEffect.ts +5 -0
- package/src/hooks/useOpenClose/useOpenClose.mdx +15 -0
- package/src/hooks/useOpenClose/useOpenClose.stories.tsx +41 -0
- package/src/hooks/useOpenClose/useOpenClose.test.tsx +119 -0
- package/src/hooks/useOpenClose/useOpenClose.tsx +95 -0
- package/src/hooks/useWindowSize/useWindowSize.mdx +25 -0
- package/src/hooks/useWindowSize/useWindowSize.stories.tsx +35 -0
- package/src/hooks/useWindowSize/useWindowSize.ts +24 -0
- package/src/index.ts +48 -0
- package/src/lib/cssShorthandToClasses.test.ts +149 -0
- package/src/lib/cssShorthandToClasses.ts +133 -0
- package/src/lib/doesStringIncludeCssUnit.ts +6 -0
- package/src/lib/generateResponsiveClasses.test.ts +24 -0
- package/src/lib/generateResponsiveClasses.ts +30 -0
- package/src/lib/getAutoCompleteValue.test.ts +27 -0
- package/src/lib/getAutoCompleteValue.ts +12 -0
- package/src/lib/getColumnKeys.ts +27 -0
- package/src/lib/getDimensionCss.test.ts +148 -0
- package/src/lib/getDimensionCss.ts +73 -0
- package/src/lib/getElementType.test.tsx +42 -0
- package/src/lib/getElementType.ts +42 -0
- package/src/lib/getFlexCss.test.ts +122 -0
- package/src/lib/getFlexCss.ts +67 -0
- package/src/lib/index.ts +15 -0
- package/src/lib/isFunction.ts +6 -0
- package/src/lib/mergeRefs.ts +15 -0
- package/src/lib/prefersReducedMotion.ts +12 -0
- package/src/lib/react-children-utilities/filter.ts +12 -0
- package/src/lib/react-children-utilities/index.ts +1 -0
- package/src/lib/reactRouterClickHandler.ts +37 -0
- package/src/lib/resolveValue.ts +7 -0
- package/src/lib/tokens.ts +139 -0
- package/src/modes.ts +8 -0
- package/src/styles/animation.scss +152 -0
- package/src/styles/cursor.scss +43 -0
- package/src/styles/display.scss +119 -0
- package/src/styles/flex.scss +453 -0
- package/src/styles/fonts.scss +44 -0
- package/src/styles/globals/utilities.scss +4 -0
- package/src/styles/mixins.scss +14 -0
- package/src/styles/overflow.scss +41 -0
- package/src/styles/position.scss +45 -0
- package/src/styles/reset.scss +108 -0
- package/src/styles/text-align.scss +21 -0
- package/src/styles/utilities.scss +9 -0
- package/src/styles/variables/forms.scss +71 -0
- package/src/styles/variables/index.scss +3 -0
- package/src/styles/white-space.scss +21 -0
- package/src/types/index.ts +201 -0
- package/src/types/lib.types.ts +3 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import classNames from 'classnames';
|
|
3
|
+
import { DetailsSummary } from './DetailsSummary';
|
|
4
|
+
import styles from './Details.module.scss';
|
|
5
|
+
import { Box, BoxProps } from '../Box/Box';
|
|
6
|
+
|
|
7
|
+
export interface DetailsProps extends BoxProps {
|
|
8
|
+
/**
|
|
9
|
+
* Whether the details below the summary are opened. Directly corresponds to `open` property in <details> element.
|
|
10
|
+
*/
|
|
11
|
+
isOpen: boolean;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const DetailsBaseComponent: React.FC<DetailsProps> = React.forwardRef<
|
|
15
|
+
HTMLDetailsElement,
|
|
16
|
+
DetailsProps
|
|
17
|
+
>(({ children, className, display = 'block', isOpen, ...restProps }, ref) => {
|
|
18
|
+
const detailsClasses = classNames(
|
|
19
|
+
className,
|
|
20
|
+
styles['details-reset'],
|
|
21
|
+
styles.details
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<Box
|
|
26
|
+
as="details"
|
|
27
|
+
className={detailsClasses}
|
|
28
|
+
display={display}
|
|
29
|
+
open={isOpen}
|
|
30
|
+
ref={ref}
|
|
31
|
+
{...restProps}
|
|
32
|
+
>
|
|
33
|
+
{children}
|
|
34
|
+
</Box>
|
|
35
|
+
);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
export interface DetailsStatic {
|
|
39
|
+
Summary: typeof DetailsSummary;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export type DetailsWithStaticComponents = typeof DetailsBaseComponent &
|
|
43
|
+
DetailsStatic;
|
|
44
|
+
|
|
45
|
+
// Actual component is wrapped in an IIFE for the export
|
|
46
|
+
// To allow tree-shaking even with static properties (subcomponents in this case).
|
|
47
|
+
export const Details = (() => {
|
|
48
|
+
const Details = DetailsBaseComponent as DetailsWithStaticComponents; // eslint-disable-line no-shadow
|
|
49
|
+
Details.Summary = DetailsSummary;
|
|
50
|
+
return Details;
|
|
51
|
+
})();
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import React, { MouseEvent, KeyboardEvent } from 'react';
|
|
2
|
+
import { ENTER, SPACE } from '../../constants/keyCodes';
|
|
3
|
+
import { Box, BoxProps } from '../Box/Box';
|
|
4
|
+
|
|
5
|
+
export interface DetailsSummaryProps extends BoxProps {
|
|
6
|
+
isDetailsOpen: boolean;
|
|
7
|
+
onToggle?: (
|
|
8
|
+
event: MouseEvent<HTMLElement> | KeyboardEvent<HTMLElement>
|
|
9
|
+
) => void;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const DetailsSummary: React.FC<DetailsSummaryProps> = ({
|
|
13
|
+
children,
|
|
14
|
+
display = 'block',
|
|
15
|
+
isDetailsOpen,
|
|
16
|
+
onToggle,
|
|
17
|
+
...restProps
|
|
18
|
+
}) => {
|
|
19
|
+
const handleClick = (event: MouseEvent<HTMLElement>) => {
|
|
20
|
+
// Needed to avoid default `details` behavior on a click event and keep this as controlled component.
|
|
21
|
+
event.preventDefault();
|
|
22
|
+
|
|
23
|
+
if (!onToggle && !restProps?.onClick) return;
|
|
24
|
+
|
|
25
|
+
if (onToggle) {
|
|
26
|
+
onToggle(event);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (restProps?.onClick) {
|
|
30
|
+
restProps.onClick(event);
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const handleKeyDown = (event: KeyboardEvent<HTMLElement>) => {
|
|
35
|
+
if ([ENTER, SPACE].indexOf(event.keyCode) !== -1) {
|
|
36
|
+
// Needed to avoid default `details` behavior on a click event and keep this as controlled component.
|
|
37
|
+
event.preventDefault();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (!onToggle && !restProps?.onKeyDown) return;
|
|
41
|
+
|
|
42
|
+
if (onToggle && [ENTER, SPACE].indexOf(event.keyCode) !== -1) {
|
|
43
|
+
onToggle(event);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (restProps?.onKeyDown) {
|
|
47
|
+
restProps.onKeyDown(event);
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
return (
|
|
52
|
+
<Box
|
|
53
|
+
{...restProps}
|
|
54
|
+
as="summary"
|
|
55
|
+
display={display}
|
|
56
|
+
role="button"
|
|
57
|
+
aria-expanded={isDetailsOpen}
|
|
58
|
+
tabIndex={0}
|
|
59
|
+
onClick={handleClick}
|
|
60
|
+
onKeyDown={handleKeyDown}
|
|
61
|
+
>
|
|
62
|
+
{children}
|
|
63
|
+
</Box>
|
|
64
|
+
);
|
|
65
|
+
};
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { Canvas, Meta, ArgTypes } from '@storybook/blocks';
|
|
2
|
+
import { Drawer } from './Drawer';
|
|
3
|
+
import { Alert } from '../Alert/Alert';
|
|
4
|
+
import * as Stories from './Drawer.stories';
|
|
5
|
+
|
|
6
|
+
<Meta of={Stories} />
|
|
7
|
+
|
|
8
|
+
# Drawer
|
|
9
|
+
|
|
10
|
+
A Drawer is a panel that slides in from one edge of the viewport and overlays content on top of the page. It contains information or actions without leaving the context of the original page.
|
|
11
|
+
|
|
12
|
+
<Canvas withSource="open" of={Stories.BasicUsage} />
|
|
13
|
+
|
|
14
|
+
## Usage Guidelines
|
|
15
|
+
|
|
16
|
+
- Use the drawer as way to achieve progressive disclosure, to reveal relevant information at the appropriate time.
|
|
17
|
+
- The Drawer visibility is controlled via the `isOpen` prop, and is hidden by default. To handle closing the Drawer, provide an `onDismiss` callback that will be called when the user clicks the Overlay or Esc keyboard key.
|
|
18
|
+
- When a Drawer is open, the main body is scroll-locked by default.
|
|
19
|
+
- Avoid nesting Drawers to prevent usability issues.
|
|
20
|
+
- The button that triggers the drawer opening should be in close proximity to the Drawer itself.
|
|
21
|
+
- Drawers are appropriate for supplemental information, filters, or subtasks where it's important to keep the subtasks in the context of the main task
|
|
22
|
+
|
|
23
|
+
### When not to use
|
|
24
|
+
|
|
25
|
+
- To force users to complete an action before continuing. Use a [Modal](/docs/components-modal--docs) instead.
|
|
26
|
+
- For small content or a few options near the original content, use a [Popover](/docs/components-popover--docs).
|
|
27
|
+
|
|
28
|
+
## Content Guidelines
|
|
29
|
+
|
|
30
|
+
Drawers are good for short pieces of content that are related to the main screen but not a part of it. Examples include:
|
|
31
|
+
|
|
32
|
+
- Contextual help
|
|
33
|
+
- Notifications or activity log
|
|
34
|
+
- Simple forms or settings
|
|
35
|
+
- Navigation or page table of contents
|
|
36
|
+
|
|
37
|
+
## Accessibility
|
|
38
|
+
|
|
39
|
+
- Use the `ariaLabel` or `ariaLabelledBy` props to properly label a drawer to provide context for users with assistive technology such as screen readers. If a drawer is announced to the user without a label, it can be confusing and difficult to navigate.
|
|
40
|
+
- When the Drawer is opened, focus is trapped inside the Drawer.
|
|
41
|
+
- The 'Esc' key will close the Drawer.
|
|
42
|
+
- After the drawer closes, focus is returned to the element that triggered it.
|
|
43
|
+
|
|
44
|
+
## Props
|
|
45
|
+
|
|
46
|
+
<ArgTypes of={Drawer} />
|
|
47
|
+
|
|
48
|
+
## Placement
|
|
49
|
+
|
|
50
|
+
The Drawer can appear from the right (default), left, top, or bottom of the screen. When appearing from the left or right of the screen, the close Icon Button is positioned on the same side where the Drawer originates from. When appearing from the top or bottom of the screen, the close Icon Button is positioned on the right as default.
|
|
51
|
+
|
|
52
|
+
<Canvas withSource="open" of={Stories.Placement} />
|
|
53
|
+
|
|
54
|
+
## Drawer Header
|
|
55
|
+
|
|
56
|
+
A header will be added to the drawer content if `title` is defined, or `closeButton` is `true`. If the content of the drawer is taller than the drawer height, then the content will scroll while the header remains fixed to the top.
|
|
57
|
+
|
|
58
|
+
<Canvas withSource="open" of={Stories.DrawerHeader} />
|
|
59
|
+
|
|
60
|
+
## Title and Close Button
|
|
61
|
+
|
|
62
|
+
<Canvas withSource="open" of={Stories.TitleAndCloseButton} />
|
|
63
|
+
|
|
64
|
+
## Close Button Only
|
|
65
|
+
|
|
66
|
+
<Canvas withSource="open" of={Stories.CloseButtonOnly} />
|
|
67
|
+
|
|
68
|
+
## Width
|
|
69
|
+
|
|
70
|
+
Set the width of a Drawer to specific value for a `left` or `right` placement via `width`. The Drawer height will be 100% of the viewport, or if `containerRef` is used, 100% of the container.
|
|
71
|
+
|
|
72
|
+
When `placement` is set to `top` or `bottom`, the `width` prop is ignored and the drawer will be 100% of the viewport or container.
|
|
73
|
+
|
|
74
|
+
<Canvas withSource="open" of={Stories.Width} />
|
|
75
|
+
|
|
76
|
+
## Height
|
|
77
|
+
|
|
78
|
+
The height of Drawers with a `top` or `bottom` placement is determined by Drawer's contents. The width will be set to 100%.
|
|
79
|
+
|
|
80
|
+
<Canvas withSource="open" of={Stories.Height} />
|
|
81
|
+
|
|
82
|
+
## Hidden Overlay
|
|
83
|
+
|
|
84
|
+
In cases where content in the drawer is supplemental to content on the main area of the page, use `hideOverlay` to allow for interaction between the areas (e.g. copy-and-paste text from main area into a form in the drawer).
|
|
85
|
+
|
|
86
|
+
<Alert
|
|
87
|
+
variant="warning"
|
|
88
|
+
title="Focus Management"
|
|
89
|
+
hasIcon
|
|
90
|
+
message="If you decide to use `hideOverlay`, then you must also manage focus. Focus and page scrolling will not be locked if `hideOverlay` is true. Also, the 'Esc' key button will no longer automatically close the Drawer."
|
|
91
|
+
/>
|
|
92
|
+
|
|
93
|
+
<Canvas withSource="open" of={Stories.HiddenOverlay} />
|
|
94
|
+
|
|
95
|
+
## Initial Focus Ref
|
|
96
|
+
|
|
97
|
+
By default the first focusable element will receive focus when the drawer opens, but you can provide a ref to focus instead.
|
|
98
|
+
|
|
99
|
+
<Alert
|
|
100
|
+
hasIcon
|
|
101
|
+
message="Without the initialFocusRef prop, the drawer will automatically focus on the first focusable element in it's children."
|
|
102
|
+
variant="info"
|
|
103
|
+
/>
|
|
104
|
+
|
|
105
|
+
<Canvas withSource="open" of={Stories.InitialFocusRef} />
|
|
106
|
+
|
|
107
|
+
## Contained Drawer
|
|
108
|
+
|
|
109
|
+
Render the Drawer within a containing div using `containerRef`.
|
|
110
|
+
|
|
111
|
+
<Alert
|
|
112
|
+
hasIcon
|
|
113
|
+
message="When choosing to use a Drawer within a containing div, use dangerouslyBypassScrollLock to allow the content outside of the containing div to remain interactive."
|
|
114
|
+
variant="info"
|
|
115
|
+
/>
|
|
116
|
+
|
|
117
|
+
<Canvas withSource="open" of={Stories.ContainedDrawer} />
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
@import '@hyphen/hyphen-design-tokens/build/scss/variables';
|
|
2
|
+
|
|
3
|
+
.drawer {
|
|
4
|
+
top: 0;
|
|
5
|
+
right: 0;
|
|
6
|
+
bottom: 0;
|
|
7
|
+
left: 0;
|
|
8
|
+
z-index: var(--size-z-index-overlay);
|
|
9
|
+
background: hsl(0deg 0% 0% / 33%);
|
|
10
|
+
max-height: 100vh;
|
|
11
|
+
overflow: visible;
|
|
12
|
+
|
|
13
|
+
//for the hide-overlay-* classes, push the overlay to opposite edge so that underlying content is not covered
|
|
14
|
+
&.hide-overlay-right {
|
|
15
|
+
left: 100%;
|
|
16
|
+
background-color: transparent;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
&.hide-overlay-left {
|
|
20
|
+
right: 100%;
|
|
21
|
+
background-color: transparent;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
&.hide-overlay-bottom {
|
|
25
|
+
top: 100%;
|
|
26
|
+
background-color: transparent;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
&.hide-overlay-top {
|
|
30
|
+
bottom: 100%;
|
|
31
|
+
background-color: transparent;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
:global {
|
|
35
|
+
animation: fadeIn 0.2s;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.drawer {
|
|
40
|
+
.drawer-content {
|
|
41
|
+
background-color: var(--color-background-primary);
|
|
42
|
+
display: flex;
|
|
43
|
+
flex-direction: column;
|
|
44
|
+
padding: 0;
|
|
45
|
+
position: absolute;
|
|
46
|
+
box-shadow: var(--drawer-box-shadow, var(--size-box-shadow-xl));
|
|
47
|
+
z-index: var(--size-z-index-drawer);
|
|
48
|
+
|
|
49
|
+
&.left {
|
|
50
|
+
left: 0;
|
|
51
|
+
width: var(--w, 80vw);
|
|
52
|
+
height: 100%;
|
|
53
|
+
|
|
54
|
+
:global {
|
|
55
|
+
animation: fadeInRight 0.2s ease-out;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
&.right {
|
|
60
|
+
right: 0;
|
|
61
|
+
width: var(--w, 80vw);
|
|
62
|
+
height: 100%;
|
|
63
|
+
|
|
64
|
+
:global {
|
|
65
|
+
animation: fadeInLeft 0.2s ease-out;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
&.bottom {
|
|
70
|
+
bottom: 0;
|
|
71
|
+
width: 100%;
|
|
72
|
+
max-height: 100vh;
|
|
73
|
+
|
|
74
|
+
:global {
|
|
75
|
+
animation: fadeInUp 0.2s ease-out;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
&.top {
|
|
80
|
+
top: 0;
|
|
81
|
+
width: 100%;
|
|
82
|
+
max-height: 100vh;
|
|
83
|
+
|
|
84
|
+
:global {
|
|
85
|
+
animation: fadeInDown 0.2s ease-out;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
@media (min-width: $size-breakpoint-tablet) {
|
|
90
|
+
&.right,
|
|
91
|
+
&.left {
|
|
92
|
+
width: var(--w, var(--size-dimension-8xl));
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
import { Drawer, DrawerPlacementType } from './Drawer';
|
|
2
|
+
import type { Meta } from '@storybook/react';
|
|
3
|
+
import React, { MutableRefObject, useEffect, useRef, useState } from 'react';
|
|
4
|
+
import { useOpenClose } from '../../hooks';
|
|
5
|
+
import { Button } from '../Button/Button';
|
|
6
|
+
import { Box } from '../Box/Box';
|
|
7
|
+
import { RadioGroup } from '../RadioGroup/RadioGroup';
|
|
8
|
+
import { WidthSize } from '../../types';
|
|
9
|
+
|
|
10
|
+
const meta: Meta<typeof Drawer> = {
|
|
11
|
+
title: 'Components/Drawer',
|
|
12
|
+
component: Drawer,
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export default meta;
|
|
16
|
+
|
|
17
|
+
export const BasicUsage = () => {
|
|
18
|
+
const {
|
|
19
|
+
isOpen: isDrawerOpen,
|
|
20
|
+
handleOpen: openDrawer,
|
|
21
|
+
handleClose: closeDrawer,
|
|
22
|
+
} = useOpenClose();
|
|
23
|
+
return (
|
|
24
|
+
<>
|
|
25
|
+
<Button variant="primary" onClick={openDrawer}>
|
|
26
|
+
Open Drawer
|
|
27
|
+
</Button>
|
|
28
|
+
<Drawer
|
|
29
|
+
isOpen={isDrawerOpen}
|
|
30
|
+
title="Drawer Title"
|
|
31
|
+
onDismiss={closeDrawer}
|
|
32
|
+
ariaLabel="drawer component example"
|
|
33
|
+
>
|
|
34
|
+
<Box padding="2xl" display="block" childGap="md">
|
|
35
|
+
<Box>Drawer content…</Box>
|
|
36
|
+
<Box>Drawer content…</Box>
|
|
37
|
+
<Box>Drawer content…</Box>
|
|
38
|
+
</Box>
|
|
39
|
+
</Drawer>
|
|
40
|
+
</>
|
|
41
|
+
);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export const Placement = () => {
|
|
45
|
+
const {
|
|
46
|
+
isOpen: isDrawerOpen,
|
|
47
|
+
handleOpen: openDrawer,
|
|
48
|
+
handleClose: closeDrawer,
|
|
49
|
+
} = useOpenClose();
|
|
50
|
+
const [placement, setPlacement] = useState('right');
|
|
51
|
+
const placementOptions = [
|
|
52
|
+
{
|
|
53
|
+
id: 'top',
|
|
54
|
+
value: 'top',
|
|
55
|
+
label: 'top',
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
id: 'right',
|
|
59
|
+
value: 'right',
|
|
60
|
+
label: 'right',
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
id: 'bottom',
|
|
64
|
+
value: 'bottom',
|
|
65
|
+
label: 'bottom',
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
id: 'left',
|
|
69
|
+
value: 'left',
|
|
70
|
+
label: 'left',
|
|
71
|
+
},
|
|
72
|
+
];
|
|
73
|
+
return (
|
|
74
|
+
<Box display="block" childGap="md">
|
|
75
|
+
<RadioGroup
|
|
76
|
+
title="Placement"
|
|
77
|
+
direction="row"
|
|
78
|
+
name="placement"
|
|
79
|
+
onChange={(event) => setPlacement(event.target.value)}
|
|
80
|
+
value={placement}
|
|
81
|
+
options={placementOptions}
|
|
82
|
+
/>
|
|
83
|
+
<Button variant="primary" onClick={openDrawer}>
|
|
84
|
+
Open Drawer
|
|
85
|
+
</Button>
|
|
86
|
+
<Drawer
|
|
87
|
+
title="test"
|
|
88
|
+
isOpen={isDrawerOpen}
|
|
89
|
+
onDismiss={closeDrawer}
|
|
90
|
+
placement={placement as DrawerPlacementType}
|
|
91
|
+
ariaLabel="drawer component example"
|
|
92
|
+
>
|
|
93
|
+
<Box padding="2xl" display="block" childGap="md">
|
|
94
|
+
<Box as="p">drawer content</Box>
|
|
95
|
+
<Box as="p">drawer content</Box>
|
|
96
|
+
<Box as="p">drawer content</Box>
|
|
97
|
+
<Box as="p">drawer content</Box>
|
|
98
|
+
<Box as="p">drawer content</Box>
|
|
99
|
+
<Box as="p">drawer content</Box>
|
|
100
|
+
<Box as="p">drawer content</Box>
|
|
101
|
+
<Box as="p">drawer content</Box>
|
|
102
|
+
<Box as="p">drawer content</Box>
|
|
103
|
+
</Box>
|
|
104
|
+
</Drawer>
|
|
105
|
+
</Box>
|
|
106
|
+
);
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
export const DrawerHeader = () => {
|
|
110
|
+
const {
|
|
111
|
+
isOpen: isDrawerOpen,
|
|
112
|
+
handleOpen: openDrawer,
|
|
113
|
+
handleClose: closeDrawer,
|
|
114
|
+
} = useOpenClose();
|
|
115
|
+
const drawerContent = [];
|
|
116
|
+
for (let i = 0; i < 50; i++) {
|
|
117
|
+
drawerContent.push(<Box key={i}>Drawer content…</Box>);
|
|
118
|
+
}
|
|
119
|
+
return (
|
|
120
|
+
<>
|
|
121
|
+
<Button variant="primary" onClick={openDrawer}>
|
|
122
|
+
Title and Close Button
|
|
123
|
+
</Button>
|
|
124
|
+
<Drawer
|
|
125
|
+
ariaLabel="drawer component example"
|
|
126
|
+
isOpen={isDrawerOpen}
|
|
127
|
+
onDismiss={closeDrawer}
|
|
128
|
+
title="Drawer Title"
|
|
129
|
+
>
|
|
130
|
+
<Box padding="2xl" display="block" childGap="md">
|
|
131
|
+
{drawerContent}
|
|
132
|
+
</Box>
|
|
133
|
+
</Drawer>
|
|
134
|
+
</>
|
|
135
|
+
);
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
export const TitleAndCloseButton = () => {
|
|
139
|
+
const {
|
|
140
|
+
isOpen: isDrawerOpen,
|
|
141
|
+
handleOpen: openDrawer,
|
|
142
|
+
handleClose: closeDrawer,
|
|
143
|
+
} = useOpenClose();
|
|
144
|
+
const drawerContent = [];
|
|
145
|
+
for (let i = 0; i < 50; i++) {
|
|
146
|
+
drawerContent.push(<Box key={i}>Drawer content…</Box>);
|
|
147
|
+
}
|
|
148
|
+
return (
|
|
149
|
+
<>
|
|
150
|
+
<Button variant="primary" onClick={openDrawer}>
|
|
151
|
+
Title and Close Button
|
|
152
|
+
</Button>
|
|
153
|
+
<Drawer
|
|
154
|
+
ariaLabel="drawer component example"
|
|
155
|
+
isOpen={isDrawerOpen}
|
|
156
|
+
onDismiss={closeDrawer}
|
|
157
|
+
title="Drawer Title"
|
|
158
|
+
>
|
|
159
|
+
<Box padding="2xl" display="block" childGap="md">
|
|
160
|
+
{drawerContent}
|
|
161
|
+
</Box>
|
|
162
|
+
</Drawer>
|
|
163
|
+
</>
|
|
164
|
+
);
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
export const CloseButtonOnly = () => {
|
|
168
|
+
const {
|
|
169
|
+
isOpen: isDrawerOpen,
|
|
170
|
+
handleOpen: openDrawer,
|
|
171
|
+
handleClose: closeDrawer,
|
|
172
|
+
} = useOpenClose();
|
|
173
|
+
const drawerContent = [];
|
|
174
|
+
for (let i = 0; i < 50; i++) {
|
|
175
|
+
drawerContent.push(<Box key={i}>Drawer content…</Box>);
|
|
176
|
+
}
|
|
177
|
+
return (
|
|
178
|
+
<>
|
|
179
|
+
<Button variant="primary" onClick={openDrawer}>
|
|
180
|
+
Close Button Only
|
|
181
|
+
</Button>
|
|
182
|
+
<Drawer
|
|
183
|
+
ariaLabel="drawer component example"
|
|
184
|
+
isOpen={isDrawerOpen}
|
|
185
|
+
onDismiss={closeDrawer}
|
|
186
|
+
closeButton
|
|
187
|
+
>
|
|
188
|
+
<Box padding="2xl" display="block" childGap="md">
|
|
189
|
+
{drawerContent}
|
|
190
|
+
</Box>
|
|
191
|
+
</Drawer>
|
|
192
|
+
</>
|
|
193
|
+
);
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
export const Width = () => {
|
|
197
|
+
const {
|
|
198
|
+
isOpen: isDrawerOpen,
|
|
199
|
+
handleOpen: openDrawer,
|
|
200
|
+
handleClose: closeDrawer,
|
|
201
|
+
} = useOpenClose();
|
|
202
|
+
const [width, setWidth] = React.useState('default');
|
|
203
|
+
const handleClick = (newWidth: WidthSize) => {
|
|
204
|
+
setWidth(newWidth);
|
|
205
|
+
openDrawer();
|
|
206
|
+
};
|
|
207
|
+
const widths = ['16rem', '400px', '100%'];
|
|
208
|
+
return (
|
|
209
|
+
<>
|
|
210
|
+
<Box gap="sm" direction="row">
|
|
211
|
+
{widths.map((width: string) => (
|
|
212
|
+
<Button
|
|
213
|
+
variant="primary"
|
|
214
|
+
onClick={() => handleClick(width as WidthSize)}
|
|
215
|
+
key={width}
|
|
216
|
+
>
|
|
217
|
+
{`Open ${width} Drawer `}
|
|
218
|
+
</Button>
|
|
219
|
+
))}
|
|
220
|
+
</Box>
|
|
221
|
+
<Drawer
|
|
222
|
+
width={width as WidthSize}
|
|
223
|
+
title={`${width} wide drawer`}
|
|
224
|
+
isOpen={isDrawerOpen}
|
|
225
|
+
onDismiss={closeDrawer}
|
|
226
|
+
closeButton
|
|
227
|
+
ariaLabel="drawer component example"
|
|
228
|
+
>
|
|
229
|
+
<Box padding="2xl" display="block" childGap="md">
|
|
230
|
+
<Box>drawer content</Box>
|
|
231
|
+
</Box>
|
|
232
|
+
</Drawer>
|
|
233
|
+
</>
|
|
234
|
+
);
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
export const Height = () => {
|
|
238
|
+
const {
|
|
239
|
+
isOpen: isDrawerOpen,
|
|
240
|
+
handleOpen: openDrawer,
|
|
241
|
+
handleClose: closeDrawer,
|
|
242
|
+
} = useOpenClose();
|
|
243
|
+
return (
|
|
244
|
+
<>
|
|
245
|
+
<Button variant="primary" onClick={openDrawer}>
|
|
246
|
+
Open Drawer
|
|
247
|
+
</Button>
|
|
248
|
+
<Drawer
|
|
249
|
+
placement="top"
|
|
250
|
+
isOpen={isDrawerOpen}
|
|
251
|
+
onDismiss={closeDrawer}
|
|
252
|
+
closeButton
|
|
253
|
+
ariaLabel="drawer component example"
|
|
254
|
+
>
|
|
255
|
+
<Box padding="lg" height="3xl" display="block" childGap="md">
|
|
256
|
+
<Box>3xl Height</Box>
|
|
257
|
+
</Box>
|
|
258
|
+
</Drawer>
|
|
259
|
+
</>
|
|
260
|
+
);
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
export const HiddenOverlay = () => {
|
|
264
|
+
const closeBtnRef = useRef<HTMLButtonElement>();
|
|
265
|
+
const returnFocusRef = useRef<HTMLButtonElement>();
|
|
266
|
+
const returnFocus = () => {
|
|
267
|
+
if (returnFocusRef && returnFocusRef.current) {
|
|
268
|
+
returnFocusRef.current.focus();
|
|
269
|
+
}
|
|
270
|
+
};
|
|
271
|
+
const {
|
|
272
|
+
isOpen: isDrawerOpen,
|
|
273
|
+
handleToggle: handleDrawerToggle,
|
|
274
|
+
handleClose: closeDrawer,
|
|
275
|
+
} = useOpenClose({ onClose: returnFocus });
|
|
276
|
+
useEffect(() => {
|
|
277
|
+
setTimeout(() => {
|
|
278
|
+
if (closeBtnRef && closeBtnRef.current) {
|
|
279
|
+
closeBtnRef.current.focus();
|
|
280
|
+
}
|
|
281
|
+
}, 100);
|
|
282
|
+
}, [isDrawerOpen]);
|
|
283
|
+
return (
|
|
284
|
+
<>
|
|
285
|
+
<Button
|
|
286
|
+
variant="primary"
|
|
287
|
+
onClick={handleDrawerToggle}
|
|
288
|
+
ref={returnFocusRef as MutableRefObject<HTMLButtonElement>}
|
|
289
|
+
>
|
|
290
|
+
Toggle Drawer
|
|
291
|
+
</Button>
|
|
292
|
+
<Drawer
|
|
293
|
+
isOpen={isDrawerOpen}
|
|
294
|
+
onDismiss={closeDrawer}
|
|
295
|
+
ariaLabel="drawer component example"
|
|
296
|
+
hideOverlay
|
|
297
|
+
>
|
|
298
|
+
<Box padding="2xl" display="block" childGap="md">
|
|
299
|
+
<Button
|
|
300
|
+
ref={closeBtnRef as MutableRefObject<HTMLButtonElement>}
|
|
301
|
+
onClick={closeDrawer}
|
|
302
|
+
variant="primary"
|
|
303
|
+
>
|
|
304
|
+
close
|
|
305
|
+
</Button>
|
|
306
|
+
<Box>drawer content</Box>
|
|
307
|
+
</Box>
|
|
308
|
+
</Drawer>
|
|
309
|
+
</>
|
|
310
|
+
);
|
|
311
|
+
};
|
|
312
|
+
|
|
313
|
+
export const InitialFocusRef = () => {
|
|
314
|
+
const {
|
|
315
|
+
isOpen: isDrawerOpen,
|
|
316
|
+
handleOpen: openDrawer,
|
|
317
|
+
handleClose: closeDrawer,
|
|
318
|
+
} = useOpenClose();
|
|
319
|
+
const ref = useRef(null);
|
|
320
|
+
return (
|
|
321
|
+
<>
|
|
322
|
+
<Button variant="primary" onClick={openDrawer}>
|
|
323
|
+
Open Drawer
|
|
324
|
+
</Button>
|
|
325
|
+
<Drawer
|
|
326
|
+
isOpen={isDrawerOpen}
|
|
327
|
+
onDismiss={closeDrawer}
|
|
328
|
+
initialFocusRef={ref}
|
|
329
|
+
title="initialFocusRef"
|
|
330
|
+
ariaLabel="drawer component example"
|
|
331
|
+
>
|
|
332
|
+
<Box padding="2xl" display="block" childGap="md">
|
|
333
|
+
<Box>drawer content</Box>
|
|
334
|
+
<Button variant="primary" ref={ref} onClick={closeDrawer}>
|
|
335
|
+
I receive focus
|
|
336
|
+
</Button>
|
|
337
|
+
</Box>
|
|
338
|
+
</Drawer>
|
|
339
|
+
</>
|
|
340
|
+
);
|
|
341
|
+
};
|
|
342
|
+
|
|
343
|
+
export const ContainedDrawer = () => {
|
|
344
|
+
const containerRef = useRef<HTMLDivElement>();
|
|
345
|
+
const {
|
|
346
|
+
isOpen: isDrawerOpen,
|
|
347
|
+
handleOpen: openDrawer,
|
|
348
|
+
handleClose: closeDrawer,
|
|
349
|
+
} = useOpenClose();
|
|
350
|
+
return (
|
|
351
|
+
<Box
|
|
352
|
+
position="relative"
|
|
353
|
+
display="block"
|
|
354
|
+
height="500px"
|
|
355
|
+
id="myContainer"
|
|
356
|
+
ref={containerRef}
|
|
357
|
+
background="info"
|
|
358
|
+
padding="lg"
|
|
359
|
+
overflow="hidden"
|
|
360
|
+
>
|
|
361
|
+
<Button variant="primary" onClick={openDrawer}>
|
|
362
|
+
Show Drawer
|
|
363
|
+
</Button>
|
|
364
|
+
<Drawer
|
|
365
|
+
isOpen={isDrawerOpen}
|
|
366
|
+
onDismiss={closeDrawer}
|
|
367
|
+
containerRef={containerRef as MutableRefObject<HTMLDivElement>}
|
|
368
|
+
dangerouslyBypassScrollLock
|
|
369
|
+
hideOverlay
|
|
370
|
+
title="containerRef"
|
|
371
|
+
ariaLabel="drawer component example"
|
|
372
|
+
>
|
|
373
|
+
<Box padding="lg" as="p">
|
|
374
|
+
This drawer is rendered inside it's containing div, rather than
|
|
375
|
+
the document.body
|
|
376
|
+
</Box>
|
|
377
|
+
</Drawer>
|
|
378
|
+
</Box>
|
|
379
|
+
);
|
|
380
|
+
};
|