@purpurds/drawer 6.10.0 → 6.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/LICENSE.txt +10 -3
- package/dist/drawer-content.d.ts +5 -0
- package/dist/drawer-content.d.ts.map +1 -1
- package/dist/drawer-frame.d.ts +2 -0
- package/dist/drawer-frame.d.ts.map +1 -1
- package/dist/drawer-header.d.ts +1 -0
- package/dist/drawer-header.d.ts.map +1 -1
- package/dist/drawer-scroll-area.d.ts +1 -0
- package/dist/drawer-scroll-area.d.ts.map +1 -1
- package/dist/drawer.cjs.js +20 -20
- package/dist/drawer.cjs.js.map +1 -1
- package/dist/drawer.es.js +1306 -1164
- package/dist/drawer.es.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +7 -6
- package/src/drawer-content.module.scss +14 -1
- package/src/drawer-content.test.tsx +26 -0
- package/src/drawer-content.tsx +14 -1
- package/src/drawer-frame.module.scss +13 -0
- package/src/drawer-frame.tsx +8 -0
- package/src/drawer-header.tsx +32 -12
- package/src/drawer-scroll-area.module.scss +7 -0
- package/src/drawer-scroll-area.tsx +7 -1
- package/src/drawer.stories.tsx +11 -1
package/dist/styles.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
._purpur-drawer-
|
|
1
|
+
._purpur-drawer-content_1xk2s_1{animation:_drawerSmallScreenAnimation_1xk2s_1 var(--purpur-motion-duration-200) var(--purpur-motion-easing-ease-in-out);bottom:0;height:90vh;height:90dvh;max-width:100%;position:absolute;right:0;transition:transform var(--purpur-motion-duration-200) var(--purpur-motion-easing-ease-in-out);width:100%}._purpur-drawer-content--fit-to-content_1xk2s_12{display:flex;flex-direction:column;height:auto;max-height:90vh;max-height:90dvh}@media screen and (min-width: 600px){._purpur-drawer-content_1xk2s_1{animation:_drawerLargeScreenAnimation_1xk2s_1 var(--purpur-motion-duration-200) var(--purpur-motion-easing-ease-in-out);height:100vh;height:100dvh;max-width:calc(30rem * var(--purpur-rescale));top:0}._purpur-drawer-content--fit-to-content_1xk2s_12{max-height:100vh;max-height:100dvh}}._purpur-drawer-content_1xk2s_1:focus{outline:none}._purpur-drawer-content__content-container_1xk2s_35{display:flex;flex-direction:column;gap:var(--purpur-spacing-400)}._purpur-drawer-content__drawer-frame_1xk2s_40[data-swipe=cancel]{transform:translateY(0);transition:transform var(--purpur-motion-duration-200) var(--purpur-motion-easing-ease-in-out)}._purpur-drawer-content__drawer-frame_1xk2s_40[data-swipe=move]{transform:translateY(var(--purpur-drawer-swipe-move-y))}._purpur-drawer-content__drawer-frame_1xk2s_40[data-swipe=end]{animation:_slideDown_1xk2s_1 var(--purpur-motion-duration-200) var(--purpur-motion-easing-ease-in-out) forwards}._purpur-drawer-content__description_1xk2s_50{color:var(--purpur-color-text-default);display:block;font-family:var(--purpur-typography-family-default);font-size:var(--purpur-typography-scale-100);font-weight:var(--purpur-typography-weight-normal);-webkit-hyphens:none;hyphens:none;line-height:var(--purpur-typography-line-height-loose);margin:0}._purpur-drawer-overlay_1xk2s_61{animation:_overlayAnimation_1xk2s_1 var(--purpur-motion-duration-200) var(--purpur-motion-easing-ease-in-out);background:var(--purpur-color-overlay-default);top:0;right:0;bottom:0;left:0;position:fixed;transition:opacity var(--purpur-motion-duration-200) var(--purpur-motion-easing-ease-in-out)}@keyframes _slideDown_1xk2s_1{0%{transform:translateY(var(--purpur-drawer-swipe-end-y))}to{transform:translateY(100%)}}@keyframes _overlayAnimation_1xk2s_1{0%{opacity:0}to{opacity:1}}@keyframes _drawerLargeScreenAnimation_1xk2s_1{0%{transform:translate(100%)}to{transform:translate(0)}}@keyframes _drawerSmallScreenAnimation_1xk2s_1{0%{transform:translateY(100%)}to{transform:translateY(0)}}._purpur-drawer-container--header_1r6tb_1{padding:var(--purpur-spacing-250) var(--purpur-spacing-300) var(--purpur-spacing-200);border-bottom:var(--purpur-border-width-xs) solid var(--purpur-color-border-weak)}._purpur-drawer-container--body_1r6tb_5{padding:var(--purpur-spacing-400) var(--purpur-spacing-300) 0}._purpur-drawer-container--body_1r6tb_5._purpur-drawer-container--sticky_1r6tb_8{padding:var(--purpur-spacing-400) var(--purpur-spacing-300)}._purpur-drawer-container--footer_1r6tb_11{padding:0 var(--purpur-spacing-300) var(--purpur-spacing-200)}._purpur-drawer-container--footer_1r6tb_11._purpur-drawer-container--sticky_1r6tb_8{border-top:var(--purpur-border-width-xs) solid var(--purpur-color-border-weak);padding:var(--purpur-spacing-200) var(--purpur-spacing-300)}._purpur-drawer-frame_1gdvv_1{background-color:var(--purpur-color-background-primary);border-top-left-radius:var(--purpur-border-radius-lg);border-top-right-radius:var(--purpur-border-radius-lg);box-shadow:var(--purpur-shadow-lg);display:flex;flex-direction:column;height:100%;position:relative}@media screen and (min-width: 600px){._purpur-drawer-frame_1gdvv_1{border-bottom-left-radius:var(--purpur-border-radius-lg);border-top-right-radius:0}}._purpur-drawer-frame--sticky-footer_1gdvv_17{gap:0}._purpur-drawer-frame__header_1gdvv_20{flex:0 0 auto}._purpur-drawer-frame__body_1gdvv_23{flex:1 1 auto;overflow:hidden}._purpur-drawer-frame--fit-to-content_1gdvv_27{flex:1 1 auto;height:auto;overflow:hidden}._purpur-drawer-frame--fit-to-content_1gdvv_27 ._purpur-drawer-frame__body_1gdvv_23{display:flex;flex-direction:column}._purpur-drawer-frame__footer_1gdvv_36{flex:0 0 auto}._purpur-drawer-frame__content-container_1gdvv_39{display:flex;flex-direction:column;gap:var(--purpur-spacing-400)}._purpur-drawer-frame__content-container--no-footer_1gdvv_44{margin-bottom:var(--purpur-spacing-400)}._purpur-drawer-handle_3n0ew_1{align-items:center;display:flex;height:var(--purpur-spacing-250);justify-content:center;position:absolute;top:0;width:100%}@media screen and (min-width: 600px){._purpur-drawer-handle_3n0ew_1{display:none}}._purpur-drawer-handle_3n0ew_1:before{content:"";background:var(--purpur-color-border-weak);border-radius:var(--purpur-border-radius-full);height:var(--purpur-spacing-50);width:var(--purpur-spacing-600)}._purpur-drawer-header__row_1yg5w_1{display:flex;align-items:center;gap:var(--purpur-spacing-100)}._purpur-drawer-header__row--with-back-button_1yg5w_6{margin-bottom:var(--purpur-spacing-100)}._purpur-drawer-header__left_1yg5w_9{flex:1 1 auto}._purpur-drawer-header__right_1yg5w_12{flex:0 0 auto}._purpur-drawer-header__close-button_1yg5w_15{margin-right:calc(-1 * var(--purpur-spacing-100))}._purpur-drawer-header__back-button--only-icon_1yg5w_18{margin-left:calc(-1 * var(--purpur-spacing-100))}._purpur-drawer-scroll-area__root_1r0fa_1{height:100%}._purpur-drawer-scroll-area__root--fit-to-content_1r0fa_4{display:flex;flex-direction:column;height:auto;overflow:hidden}._purpur-drawer-scroll-area__viewport_1r0fa_10{height:100%}._purpur-drawer-scroll-area__scrollbar_1r0fa_13{display:flex;-webkit-user-select:none;user-select:none;touch-action:none;padding:var(--purpur-spacing-25);background:var(--purpur-color-functional-white);transition:background var(--purpur-motion-duration-200) var(--purpur-motion-easing-ease-in-out);width:var(--purpur-spacing-100)}._purpur-drawer-scroll-area__thumb_1r0fa_24{background:var(--purpur-color-gray-200);border-radius:var(--purpur-spacing-200);flex:1;position:relative}._purpur-drawer-scroll-area__thumb_1r0fa_24:before{content:"";height:100%;left:50%;min-height:var(--purpur-spacing-300);min-width:var(--purpur-spacing-300);position:absolute;top:50%;transform:translate(-50%,-50%);width:100%}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@purpurds/drawer",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.11.1",
|
|
4
4
|
"license": "AGPL-3.0-only",
|
|
5
5
|
"main": "./dist/drawer.cjs.js",
|
|
6
6
|
"types": "./dist/drawer.d.ts",
|
|
@@ -18,11 +18,12 @@
|
|
|
18
18
|
"@radix-ui/react-dialog": "~1.1.6",
|
|
19
19
|
"@radix-ui/react-scroll-area": "~1.2.3",
|
|
20
20
|
"classnames": "~2.5.0",
|
|
21
|
-
"@purpurds/button": "6.
|
|
22
|
-
"@purpurds/
|
|
23
|
-
"@purpurds/icon": "6.
|
|
24
|
-
"@purpurds/tokens": "6.
|
|
25
|
-
"@purpurds/
|
|
21
|
+
"@purpurds/button": "6.11.1",
|
|
22
|
+
"@purpurds/paragraph": "6.11.1",
|
|
23
|
+
"@purpurds/icon": "6.11.1",
|
|
24
|
+
"@purpurds/tokens": "6.11.1",
|
|
25
|
+
"@purpurds/visually-hidden": "6.11.1",
|
|
26
|
+
"@purpurds/heading": "6.11.1"
|
|
26
27
|
},
|
|
27
28
|
"devDependencies": {
|
|
28
29
|
"eslint": "9.24.0",
|
|
@@ -4,21 +4,34 @@ $animation-settings: var(--purpur-motion-duration-200) var(--purpur-motion-easin
|
|
|
4
4
|
|
|
5
5
|
.purpur-drawer-content {
|
|
6
6
|
animation: drawerSmallScreenAnimation $animation-settings;
|
|
7
|
+
bottom: 0;
|
|
7
8
|
height: 90vh; /* Fallback for older browsers */
|
|
8
9
|
height: 90dvh;
|
|
9
10
|
max-width: 100%;
|
|
10
11
|
position: absolute;
|
|
11
12
|
right: 0;
|
|
12
|
-
top: 10%;
|
|
13
13
|
transition: transform $animation-settings;
|
|
14
14
|
width: 100%;
|
|
15
15
|
|
|
16
|
+
&--fit-to-content {
|
|
17
|
+
display: flex;
|
|
18
|
+
flex-direction: column;
|
|
19
|
+
height: auto;
|
|
20
|
+
max-height: 90vh; /* Fallback for older browsers */
|
|
21
|
+
max-height: 90dvh;
|
|
22
|
+
}
|
|
23
|
+
|
|
16
24
|
@media screen and (min-width: $purpur-breakpoint-md) {
|
|
17
25
|
animation: drawerLargeScreenAnimation $animation-settings;
|
|
18
26
|
height: 100vh; /* Fallback for older browsers */
|
|
19
27
|
height: 100dvh;
|
|
20
28
|
max-width: calc(30rem * var(--purpur-rescale));
|
|
21
29
|
top: 0;
|
|
30
|
+
|
|
31
|
+
&--fit-to-content {
|
|
32
|
+
max-height: 100vh; /* Fallback for older browsers */
|
|
33
|
+
max-height: 100dvh;
|
|
34
|
+
}
|
|
22
35
|
}
|
|
23
36
|
|
|
24
37
|
&:focus {
|
|
@@ -95,10 +95,36 @@ describe("DrawerContent", () => {
|
|
|
95
95
|
const dialogOverlayElement = screen.getByTestId(Selectors.DRAWER_CONTENT_OVERLAY);
|
|
96
96
|
expect(dialogOverlayElement.style.zIndex).toBe("200");
|
|
97
97
|
});
|
|
98
|
+
|
|
99
|
+
it("should show the header content if it is provided", () => {
|
|
100
|
+
render(
|
|
101
|
+
<RadixDialog.Root open={true}>
|
|
102
|
+
<DrawerContent
|
|
103
|
+
data-testid={Selectors.DRAWER_CONTENT}
|
|
104
|
+
bodyText="bodyText"
|
|
105
|
+
closeButtonText="Close"
|
|
106
|
+
stickyFooter
|
|
107
|
+
title="Title"
|
|
108
|
+
zIndex={200}
|
|
109
|
+
headerContent={
|
|
110
|
+
<div data-testid={Selectors.DRAWER_HEADER_CONTENT}>This is the header content</div>
|
|
111
|
+
}
|
|
112
|
+
>
|
|
113
|
+
Some drawer-content
|
|
114
|
+
</DrawerContent>
|
|
115
|
+
</RadixDialog.Root>
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
expect(screen.getByTestId(Selectors.DRAWER_HEADER_CONTENT)).toBeInTheDocument();
|
|
119
|
+
expect(screen.getByTestId(Selectors.DRAWER_HEADER_CONTENT)).toHaveTextContent(
|
|
120
|
+
"This is the header content"
|
|
121
|
+
);
|
|
122
|
+
});
|
|
98
123
|
});
|
|
99
124
|
|
|
100
125
|
const Selectors = {
|
|
101
126
|
DRAWER_CONTENT: "purpur-drawer-content",
|
|
102
127
|
DRAWER_CONTENT_OVERLAY: "purpur-drawer-content-overlay",
|
|
103
128
|
BODY_TEXT: "purpur-drawer-content-description",
|
|
129
|
+
DRAWER_HEADER_CONTENT: "purpur-drawer-header-content",
|
|
104
130
|
};
|
package/src/drawer-content.tsx
CHANGED
|
@@ -30,7 +30,12 @@ export type DrawerContentProps = {
|
|
|
30
30
|
className?: string;
|
|
31
31
|
closeButtonText: string;
|
|
32
32
|
disableCloseOnClickOutside?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* If true, the drawer height will fit to its content on small screens.
|
|
35
|
+
*/
|
|
36
|
+
fitToContent?: boolean;
|
|
33
37
|
footerContent?: ReactNode;
|
|
38
|
+
headerContent?: ReactNode;
|
|
34
39
|
stickyFooter?: boolean;
|
|
35
40
|
title: string;
|
|
36
41
|
zIndex?: number;
|
|
@@ -50,7 +55,9 @@ export const DrawerContent = forwardRef(
|
|
|
50
55
|
className,
|
|
51
56
|
closeButtonText,
|
|
52
57
|
disableCloseOnClickOutside = false,
|
|
58
|
+
fitToContent = false,
|
|
53
59
|
footerContent,
|
|
60
|
+
headerContent,
|
|
54
61
|
onBackButtonClick,
|
|
55
62
|
stickyFooter = false,
|
|
56
63
|
title,
|
|
@@ -59,7 +66,11 @@ export const DrawerContent = forwardRef(
|
|
|
59
66
|
}: DrawerContentProps,
|
|
60
67
|
ref: ForwardedRef<HTMLDivElement>
|
|
61
68
|
) => {
|
|
62
|
-
const classes = cx([
|
|
69
|
+
const classes = cx([
|
|
70
|
+
className,
|
|
71
|
+
rootClassName,
|
|
72
|
+
{ [`${rootClassName}--fit-to-content`]: fitToContent },
|
|
73
|
+
]);
|
|
63
74
|
|
|
64
75
|
const drawerFrameRef = useRef<HTMLDivElement>(null);
|
|
65
76
|
const onOpenChange = useContext(DrawerContext);
|
|
@@ -92,7 +103,9 @@ export const DrawerContent = forwardRef(
|
|
|
92
103
|
backButtonOnlyIcon={backButtonOnlyIcon}
|
|
93
104
|
closeButtonText={closeButtonText}
|
|
94
105
|
className={cx(`${rootClassName}__drawer-frame`)}
|
|
106
|
+
fitToContent={fitToContent}
|
|
95
107
|
footerContent={footerContent}
|
|
108
|
+
headerContent={headerContent}
|
|
96
109
|
ref={drawerFrameRef}
|
|
97
110
|
onAnimationEnd={onAnimationEnd}
|
|
98
111
|
onBackButtonClick={onBackButtonClick}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
@use "@purpurds/tokens/breakpoint/variables" as *;
|
|
2
2
|
|
|
3
3
|
.purpur-drawer-frame {
|
|
4
|
+
$root: &;
|
|
5
|
+
|
|
4
6
|
background-color: var(--purpur-color-background-primary);
|
|
5
7
|
border-top-left-radius: var(--purpur-border-radius-lg);
|
|
6
8
|
border-top-right-radius: var(--purpur-border-radius-lg);
|
|
@@ -28,6 +30,17 @@
|
|
|
28
30
|
overflow: hidden;
|
|
29
31
|
}
|
|
30
32
|
|
|
33
|
+
&--fit-to-content {
|
|
34
|
+
flex: 1 1 auto;
|
|
35
|
+
height: auto;
|
|
36
|
+
overflow: hidden;
|
|
37
|
+
|
|
38
|
+
#{$root}__body {
|
|
39
|
+
display: flex;
|
|
40
|
+
flex-direction: column;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
31
44
|
&__footer {
|
|
32
45
|
flex: 0 0 auto;
|
|
33
46
|
}
|
package/src/drawer-frame.tsx
CHANGED
|
@@ -17,7 +17,9 @@ export type DrawerFrameProps = {
|
|
|
17
17
|
children: ReactNode;
|
|
18
18
|
className?: string;
|
|
19
19
|
closeButtonText: string;
|
|
20
|
+
fitToContent?: boolean;
|
|
20
21
|
footerContent?: ReactNode;
|
|
22
|
+
headerContent?: ReactNode;
|
|
21
23
|
onAnimationEnd: (event: React.AnimationEvent<HTMLDivElement>) => void;
|
|
22
24
|
onBackButtonClick?: () => void;
|
|
23
25
|
onSwipeStart(): void;
|
|
@@ -40,7 +42,9 @@ export const DrawerFrame = forwardRef(
|
|
|
40
42
|
children,
|
|
41
43
|
className,
|
|
42
44
|
closeButtonText,
|
|
45
|
+
fitToContent = false,
|
|
43
46
|
footerContent,
|
|
47
|
+
headerContent,
|
|
44
48
|
onAnimationEnd,
|
|
45
49
|
onBackButtonClick,
|
|
46
50
|
onSwipeStart,
|
|
@@ -57,6 +61,7 @@ export const DrawerFrame = forwardRef(
|
|
|
57
61
|
className,
|
|
58
62
|
rootClassName,
|
|
59
63
|
{
|
|
64
|
+
[`${rootClassName}--fit-to-content`]: fitToContent,
|
|
60
65
|
[`${rootClassName}--sticky-footer`]: stickyFooter,
|
|
61
66
|
},
|
|
62
67
|
]);
|
|
@@ -82,6 +87,7 @@ export const DrawerFrame = forwardRef(
|
|
|
82
87
|
>
|
|
83
88
|
<DrawerHeader
|
|
84
89
|
title={title}
|
|
90
|
+
headerContent={headerContent}
|
|
85
91
|
backButtonOnlyIcon={backButtonOnlyIcon}
|
|
86
92
|
backButton={backButton}
|
|
87
93
|
backButtonText={backButtonText}
|
|
@@ -94,6 +100,7 @@ export const DrawerFrame = forwardRef(
|
|
|
94
100
|
<DrawerScrollArea
|
|
95
101
|
className={cx(`${rootClassName}__body`)}
|
|
96
102
|
data-testid={`${dataTestId}-sticky-footer-scroll-area`}
|
|
103
|
+
fitToContent={fitToContent}
|
|
97
104
|
>
|
|
98
105
|
<DrawerContainer stickyFooter>{children}</DrawerContainer>
|
|
99
106
|
</DrawerScrollArea>
|
|
@@ -112,6 +119,7 @@ export const DrawerFrame = forwardRef(
|
|
|
112
119
|
<DrawerScrollArea
|
|
113
120
|
className={cx(`${rootClassName}__body`)}
|
|
114
121
|
data-testid={`${dataTestId}-scroll-area`}
|
|
122
|
+
fitToContent={fitToContent}
|
|
115
123
|
>
|
|
116
124
|
<div
|
|
117
125
|
className={cx([
|
package/src/drawer-header.tsx
CHANGED
|
@@ -3,10 +3,12 @@ import { Button, BUTTON_VARIANT } from "@purpurds/button";
|
|
|
3
3
|
import { Heading, TitleVariant } from "@purpurds/heading";
|
|
4
4
|
import { IconArrowLeft } from "@purpurds/icon/arrow-left";
|
|
5
5
|
import { IconClose } from "@purpurds/icon/close";
|
|
6
|
+
import { VisuallyHidden } from "@purpurds/visually-hidden";
|
|
6
7
|
import * as RadixDialog from "@radix-ui/react-dialog";
|
|
7
8
|
import c from "classnames/bind";
|
|
8
9
|
|
|
9
10
|
import styles from "./drawer-header.module.scss";
|
|
11
|
+
|
|
10
12
|
const cx = c.bind(styles);
|
|
11
13
|
|
|
12
14
|
export type DrawerHeaderProps = {
|
|
@@ -16,6 +18,7 @@ export type DrawerHeaderProps = {
|
|
|
16
18
|
backButtonOnlyIcon: boolean;
|
|
17
19
|
className?: string;
|
|
18
20
|
closeButtonText: string;
|
|
21
|
+
headerContent?: React.ReactNode;
|
|
19
22
|
onBackButtonClick?: () => void;
|
|
20
23
|
title: string;
|
|
21
24
|
};
|
|
@@ -31,6 +34,7 @@ export const DrawerHeader = forwardRef(
|
|
|
31
34
|
backButtonOnlyIcon,
|
|
32
35
|
className,
|
|
33
36
|
closeButtonText,
|
|
37
|
+
headerContent,
|
|
34
38
|
onBackButtonClick,
|
|
35
39
|
title,
|
|
36
40
|
...props
|
|
@@ -70,6 +74,13 @@ export const DrawerHeader = forwardRef(
|
|
|
70
74
|
<IconArrowLeft size="sm" />
|
|
71
75
|
{!backButtonOnlyIcon && backButtonText}
|
|
72
76
|
</Button>
|
|
77
|
+
) : headerContent ? (
|
|
78
|
+
<>
|
|
79
|
+
{headerContent}
|
|
80
|
+
<VisuallyHidden asChild>
|
|
81
|
+
<RadixDialog.Title asChild>{title}</RadixDialog.Title>
|
|
82
|
+
</VisuallyHidden>
|
|
83
|
+
</>
|
|
73
84
|
) : (
|
|
74
85
|
<RadixDialog.Title asChild>
|
|
75
86
|
<Heading
|
|
@@ -97,18 +108,27 @@ export const DrawerHeader = forwardRef(
|
|
|
97
108
|
</RadixDialog.Close>
|
|
98
109
|
</div>
|
|
99
110
|
</div>
|
|
100
|
-
{backButton &&
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
111
|
+
{backButton &&
|
|
112
|
+
backButtonText &&
|
|
113
|
+
onBackButtonClick &&
|
|
114
|
+
(headerContent ? (
|
|
115
|
+
<>
|
|
116
|
+
{headerContent}
|
|
117
|
+
<VisuallyHidden asChild>
|
|
118
|
+
<RadixDialog.Title asChild>{title}</RadixDialog.Title>
|
|
119
|
+
</VisuallyHidden>
|
|
120
|
+
</>
|
|
121
|
+
) : (
|
|
122
|
+
<RadixDialog.Title asChild>
|
|
123
|
+
<Heading
|
|
124
|
+
data-testid={`${dataTestId}-title-with-back-button`}
|
|
125
|
+
tag="h2"
|
|
126
|
+
variant={TitleVariant.TITLE200}
|
|
127
|
+
>
|
|
128
|
+
{title}
|
|
129
|
+
</Heading>
|
|
130
|
+
</RadixDialog.Title>
|
|
131
|
+
))}
|
|
112
132
|
</div>
|
|
113
133
|
);
|
|
114
134
|
}
|
|
@@ -3,6 +3,13 @@ $animation-settings: var(--purpur-motion-duration-200) var(--purpur-motion-easin
|
|
|
3
3
|
.purpur-drawer-scroll-area {
|
|
4
4
|
&__root {
|
|
5
5
|
height: 100%;
|
|
6
|
+
|
|
7
|
+
&--fit-to-content {
|
|
8
|
+
display: flex;
|
|
9
|
+
flex-direction: column;
|
|
10
|
+
height: auto;
|
|
11
|
+
overflow: hidden;
|
|
12
|
+
}
|
|
6
13
|
}
|
|
7
14
|
|
|
8
15
|
&__viewport {
|
|
@@ -9,6 +9,7 @@ export type DrawerScrollAreaProps = {
|
|
|
9
9
|
["data-testid"]?: string;
|
|
10
10
|
children: ReactNode;
|
|
11
11
|
className?: string;
|
|
12
|
+
fitToContent?: boolean;
|
|
12
13
|
};
|
|
13
14
|
|
|
14
15
|
const rootClassName = "purpur-drawer-scroll-area";
|
|
@@ -19,6 +20,7 @@ export const DrawerScrollArea = forwardRef(
|
|
|
19
20
|
["data-testid"]: dataTestId = "purpur-drawer-scroll-area",
|
|
20
21
|
children,
|
|
21
22
|
className,
|
|
23
|
+
fitToContent = false,
|
|
22
24
|
...props
|
|
23
25
|
}: DrawerScrollAreaProps,
|
|
24
26
|
ref: ForwardedRef<HTMLDivElement>
|
|
@@ -26,7 +28,11 @@ export const DrawerScrollArea = forwardRef(
|
|
|
26
28
|
const classes = cx([className, rootClassName]);
|
|
27
29
|
return (
|
|
28
30
|
<div className={classes} data-testid={dataTestId} ref={ref} {...props}>
|
|
29
|
-
<RadixScrollArea.Root
|
|
31
|
+
<RadixScrollArea.Root
|
|
32
|
+
className={cx(`${rootClassName}__root`, {
|
|
33
|
+
[`${rootClassName}__root--fit-to-content`]: fitToContent,
|
|
34
|
+
})}
|
|
35
|
+
>
|
|
30
36
|
<RadixScrollArea.Viewport className={cx(`${rootClassName}__viewport`)}>
|
|
31
37
|
{children}
|
|
32
38
|
</RadixScrollArea.Viewport>
|
package/src/drawer.stories.tsx
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { Button } from "@purpurds/button";
|
|
3
3
|
import { Heading } from "@purpurds/heading";
|
|
4
|
+
import { IconAiRobot } from "@purpurds/icon/ai-robot";
|
|
4
5
|
import { Paragraph } from "@purpurds/paragraph";
|
|
5
6
|
import { useArgs } from "@storybook/preview-api";
|
|
6
7
|
import type { Meta, StoryObj } from "@storybook/react";
|
|
@@ -142,12 +143,19 @@ const StorybookMultiDrawerTestComponent = () => {
|
|
|
142
143
|
onBackButtonClick={() => {
|
|
143
144
|
return undefined;
|
|
144
145
|
}}
|
|
146
|
+
fitToContent
|
|
145
147
|
footerContent={<StorybookTestFooterContent />}
|
|
148
|
+
headerContent={<IconAiRobot />}
|
|
146
149
|
title="This is drawer 3"
|
|
147
150
|
stickyFooter
|
|
148
151
|
zIndex={20}
|
|
149
152
|
>
|
|
150
|
-
<
|
|
153
|
+
<Heading variant="subsection-100" tag="h3">
|
|
154
|
+
The standard Lorem Ipsum passage, used since the 1500s
|
|
155
|
+
</Heading>
|
|
156
|
+
<Paragraph variant="paragraph-100" style={{ marginBottom: "32px" }}>
|
|
157
|
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
|
158
|
+
</Paragraph>
|
|
151
159
|
</Drawer.Content>
|
|
152
160
|
</Drawer>
|
|
153
161
|
</div>
|
|
@@ -227,7 +235,9 @@ export const ShowcaseForDrawerContent: DrawerContentStory = {
|
|
|
227
235
|
bodyText: "This is the body text",
|
|
228
236
|
closeButtonText: "Close drawer",
|
|
229
237
|
disableCloseOnClickOutside: false,
|
|
238
|
+
fitToContent: false,
|
|
230
239
|
footerContent: <StorybookTestFooterContent />,
|
|
240
|
+
headerContent: undefined,
|
|
231
241
|
onBackButtonClick: () => {
|
|
232
242
|
return undefined;
|
|
233
243
|
},
|