@purpurds/drawer 6.11.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 +4 -4
- package/dist/drawer-content.d.ts +4 -0
- package/dist/drawer-content.d.ts.map +1 -1
- package/dist/drawer-frame.d.ts +1 -0
- package/dist/drawer-frame.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 +11 -11
- package/dist/drawer.cjs.js.map +1 -1
- package/dist/drawer.es.js +373 -351
- package/dist/drawer.es.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +7 -7
- package/src/drawer-content.module.scss +15 -6
- package/src/drawer-content.tsx +11 -1
- package/src/drawer-frame.module.scss +14 -4
- package/src/drawer-frame.tsx +5 -0
- package/src/drawer-scroll-area.module.scss +8 -3
- package/src/drawer-scroll-area.tsx +7 -1
- package/src/drawer.stories.tsx +2 -0
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.11.
|
|
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,12 +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.11.
|
|
22
|
-
"@purpurds/
|
|
23
|
-
"@purpurds/
|
|
24
|
-
"@purpurds/
|
|
25
|
-
"@purpurds/
|
|
26
|
-
"@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"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"eslint": "9.24.0",
|
|
@@ -5,24 +5,33 @@ $animation-settings: var(--purpur-motion-duration-200) var(--purpur-motion-easin
|
|
|
5
5
|
.purpur-drawer-content {
|
|
6
6
|
animation: drawerSmallScreenAnimation $animation-settings;
|
|
7
7
|
bottom: 0;
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
max-height: 90vh; /* Fallback for older browsers */
|
|
11
|
-
max-height: 90dvh;
|
|
8
|
+
height: 90vh; /* Fallback for older browsers */
|
|
9
|
+
height: 90dvh;
|
|
12
10
|
max-width: 100%;
|
|
13
11
|
position: absolute;
|
|
14
12
|
right: 0;
|
|
15
13
|
transition: transform $animation-settings;
|
|
16
14
|
width: 100%;
|
|
17
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
|
+
|
|
18
24
|
@media screen and (min-width: $purpur-breakpoint-md) {
|
|
19
25
|
animation: drawerLargeScreenAnimation $animation-settings;
|
|
20
|
-
max-height: 100vh; /* Fallback for older browsers */
|
|
21
|
-
max-height: 100dvh;
|
|
22
26
|
height: 100vh; /* Fallback for older browsers */
|
|
23
27
|
height: 100dvh;
|
|
24
28
|
max-width: calc(30rem * var(--purpur-rescale));
|
|
25
29
|
top: 0;
|
|
30
|
+
|
|
31
|
+
&--fit-to-content {
|
|
32
|
+
max-height: 100vh; /* Fallback for older browsers */
|
|
33
|
+
max-height: 100dvh;
|
|
34
|
+
}
|
|
26
35
|
}
|
|
27
36
|
|
|
28
37
|
&:focus {
|
package/src/drawer-content.tsx
CHANGED
|
@@ -30,6 +30,10 @@ 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;
|
|
34
38
|
headerContent?: ReactNode;
|
|
35
39
|
stickyFooter?: boolean;
|
|
@@ -51,6 +55,7 @@ export const DrawerContent = forwardRef(
|
|
|
51
55
|
className,
|
|
52
56
|
closeButtonText,
|
|
53
57
|
disableCloseOnClickOutside = false,
|
|
58
|
+
fitToContent = false,
|
|
54
59
|
footerContent,
|
|
55
60
|
headerContent,
|
|
56
61
|
onBackButtonClick,
|
|
@@ -61,7 +66,11 @@ export const DrawerContent = forwardRef(
|
|
|
61
66
|
}: DrawerContentProps,
|
|
62
67
|
ref: ForwardedRef<HTMLDivElement>
|
|
63
68
|
) => {
|
|
64
|
-
const classes = cx([
|
|
69
|
+
const classes = cx([
|
|
70
|
+
className,
|
|
71
|
+
rootClassName,
|
|
72
|
+
{ [`${rootClassName}--fit-to-content`]: fitToContent },
|
|
73
|
+
]);
|
|
65
74
|
|
|
66
75
|
const drawerFrameRef = useRef<HTMLDivElement>(null);
|
|
67
76
|
const onOpenChange = useContext(DrawerContext);
|
|
@@ -94,6 +103,7 @@ export const DrawerContent = forwardRef(
|
|
|
94
103
|
backButtonOnlyIcon={backButtonOnlyIcon}
|
|
95
104
|
closeButtonText={closeButtonText}
|
|
96
105
|
className={cx(`${rootClassName}__drawer-frame`)}
|
|
106
|
+
fitToContent={fitToContent}
|
|
97
107
|
footerContent={footerContent}
|
|
98
108
|
headerContent={headerContent}
|
|
99
109
|
ref={drawerFrameRef}
|
|
@@ -1,14 +1,15 @@
|
|
|
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);
|
|
7
9
|
box-shadow: var(--purpur-shadow-lg);
|
|
8
10
|
display: flex;
|
|
9
11
|
flex-direction: column;
|
|
10
|
-
|
|
11
|
-
overflow: hidden;
|
|
12
|
+
height: 100%;
|
|
12
13
|
position: relative;
|
|
13
14
|
|
|
14
15
|
@media screen and (min-width: $purpur-breakpoint-md) {
|
|
@@ -25,12 +26,21 @@
|
|
|
25
26
|
}
|
|
26
27
|
|
|
27
28
|
&__body {
|
|
28
|
-
display: flex;
|
|
29
29
|
flex: 1 1 auto;
|
|
30
|
-
flex-direction: column;
|
|
31
30
|
overflow: hidden;
|
|
32
31
|
}
|
|
33
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
|
+
|
|
34
44
|
&__footer {
|
|
35
45
|
flex: 0 0 auto;
|
|
36
46
|
}
|
package/src/drawer-frame.tsx
CHANGED
|
@@ -17,6 +17,7 @@ export type DrawerFrameProps = {
|
|
|
17
17
|
children: ReactNode;
|
|
18
18
|
className?: string;
|
|
19
19
|
closeButtonText: string;
|
|
20
|
+
fitToContent?: boolean;
|
|
20
21
|
footerContent?: ReactNode;
|
|
21
22
|
headerContent?: ReactNode;
|
|
22
23
|
onAnimationEnd: (event: React.AnimationEvent<HTMLDivElement>) => void;
|
|
@@ -41,6 +42,7 @@ export const DrawerFrame = forwardRef(
|
|
|
41
42
|
children,
|
|
42
43
|
className,
|
|
43
44
|
closeButtonText,
|
|
45
|
+
fitToContent = false,
|
|
44
46
|
footerContent,
|
|
45
47
|
headerContent,
|
|
46
48
|
onAnimationEnd,
|
|
@@ -59,6 +61,7 @@ export const DrawerFrame = forwardRef(
|
|
|
59
61
|
className,
|
|
60
62
|
rootClassName,
|
|
61
63
|
{
|
|
64
|
+
[`${rootClassName}--fit-to-content`]: fitToContent,
|
|
62
65
|
[`${rootClassName}--sticky-footer`]: stickyFooter,
|
|
63
66
|
},
|
|
64
67
|
]);
|
|
@@ -97,6 +100,7 @@ export const DrawerFrame = forwardRef(
|
|
|
97
100
|
<DrawerScrollArea
|
|
98
101
|
className={cx(`${rootClassName}__body`)}
|
|
99
102
|
data-testid={`${dataTestId}-sticky-footer-scroll-area`}
|
|
103
|
+
fitToContent={fitToContent}
|
|
100
104
|
>
|
|
101
105
|
<DrawerContainer stickyFooter>{children}</DrawerContainer>
|
|
102
106
|
</DrawerScrollArea>
|
|
@@ -115,6 +119,7 @@ export const DrawerFrame = forwardRef(
|
|
|
115
119
|
<DrawerScrollArea
|
|
116
120
|
className={cx(`${rootClassName}__body`)}
|
|
117
121
|
data-testid={`${dataTestId}-scroll-area`}
|
|
122
|
+
fitToContent={fitToContent}
|
|
118
123
|
>
|
|
119
124
|
<div
|
|
120
125
|
className={cx([
|
|
@@ -2,9 +2,14 @@ $animation-settings: var(--purpur-motion-duration-200) var(--purpur-motion-easin
|
|
|
2
2
|
|
|
3
3
|
.purpur-drawer-scroll-area {
|
|
4
4
|
&__root {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
height: 100%;
|
|
6
|
+
|
|
7
|
+
&--fit-to-content {
|
|
8
|
+
display: flex;
|
|
9
|
+
flex-direction: column;
|
|
10
|
+
height: auto;
|
|
11
|
+
overflow: hidden;
|
|
12
|
+
}
|
|
8
13
|
}
|
|
9
14
|
|
|
10
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
|
@@ -143,6 +143,7 @@ const StorybookMultiDrawerTestComponent = () => {
|
|
|
143
143
|
onBackButtonClick={() => {
|
|
144
144
|
return undefined;
|
|
145
145
|
}}
|
|
146
|
+
fitToContent
|
|
146
147
|
footerContent={<StorybookTestFooterContent />}
|
|
147
148
|
headerContent={<IconAiRobot />}
|
|
148
149
|
title="This is drawer 3"
|
|
@@ -234,6 +235,7 @@ export const ShowcaseForDrawerContent: DrawerContentStory = {
|
|
|
234
235
|
bodyText: "This is the body text",
|
|
235
236
|
closeButtonText: "Close drawer",
|
|
236
237
|
disableCloseOnClickOutside: false,
|
|
238
|
+
fitToContent: false,
|
|
237
239
|
footerContent: <StorybookTestFooterContent />,
|
|
238
240
|
headerContent: undefined,
|
|
239
241
|
onBackButtonClick: () => {
|