@trackunit/react-drawer 0.0.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/README.md +21 -0
- package/index.cjs.d.ts +1 -0
- package/index.cjs.js +443 -0
- package/index.esm.d.ts +1 -0
- package/index.esm.js +437 -0
- package/package.json +21 -0
- package/src/components/Drawer/Drawer.d.ts +57 -0
- package/src/components/Drawer/Drawer.stories.d.ts +12 -0
- package/src/components/Drawer/Drawer.variants.d.ts +7 -0
- package/src/components/DrawerToggle/DrawerToggle.d.ts +19 -0
- package/src/components/Overlay/Overlay.d.ts +14 -0
- package/src/components/SwipeableDrawer/DrawerPuller.d.ts +10 -0
- package/src/components/SwipeableDrawer/SwipeableDrawer.d.ts +15 -0
- package/src/components/index.d.ts +3 -0
- package/src/hooks/index.d.ts +1 -0
- package/src/hooks/useSwipeHandlers.d.ts +23 -0
- package/src/index.d.ts +1 -0
- package/src/translation.d.ts +33 -0
- package/src/types.d.ts +2 -0
- package/translation.cjs.js +7 -0
- package/translation.cjs10.js +7 -0
- package/translation.cjs11.js +7 -0
- package/translation.cjs12.js +7 -0
- package/translation.cjs13.js +7 -0
- package/translation.cjs14.js +7 -0
- package/translation.cjs15.js +7 -0
- package/translation.cjs16.js +7 -0
- package/translation.cjs17.js +7 -0
- package/translation.cjs2.js +7 -0
- package/translation.cjs3.js +7 -0
- package/translation.cjs4.js +7 -0
- package/translation.cjs5.js +7 -0
- package/translation.cjs6.js +7 -0
- package/translation.cjs7.js +7 -0
- package/translation.cjs8.js +7 -0
- package/translation.cjs9.js +7 -0
- package/translation.esm.js +5 -0
- package/translation.esm10.js +5 -0
- package/translation.esm11.js +5 -0
- package/translation.esm12.js +5 -0
- package/translation.esm13.js +5 -0
- package/translation.esm14.js +5 -0
- package/translation.esm15.js +5 -0
- package/translation.esm16.js +5 -0
- package/translation.esm17.js +5 -0
- package/translation.esm2.js +5 -0
- package/translation.esm3.js +5 -0
- package/translation.esm4.js +5 -0
- package/translation.esm5.js +5 -0
- package/translation.esm6.js +5 -0
- package/translation.esm7.js +5 -0
- package/translation.esm8.js +5 -0
- package/translation.esm9.js +5 -0
package/README.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Trackunit react-drawer
|
|
2
|
+
|
|
3
|
+
The `@trackunit/react-drawer` package is the home of Trackunits public react components used for...
|
|
4
|
+
|
|
5
|
+
This library is exposed publicly for use in the the Trackunit [Iris App SDK](https://www.npmjs.com/package/@trackunit/iris-app).
|
|
6
|
+
|
|
7
|
+
To browse all avaliable components visit our [Public Storybook](https://apps.iris.trackunit.com/storybook/).
|
|
8
|
+
|
|
9
|
+
For more info and a full guide on Iris App SDK Development, please visit our [Developer Hub](https://developers.trackunit.com/).
|
|
10
|
+
|
|
11
|
+
## Development
|
|
12
|
+
|
|
13
|
+
At this point this library is only developed by Trackunit Employees.
|
|
14
|
+
For development related information see the [development readme](https://github.com/Trackunit/manager/blob/master/libs/react/components/DEVELOPMENT.md).
|
|
15
|
+
|
|
16
|
+
## Trackunit
|
|
17
|
+
|
|
18
|
+
This package was developed by Trackunit ApS.
|
|
19
|
+
Trackunit is the leading SaaS-based IoT solution for the construction industry, offering an ecosystem of hardware, fleet management software & telematics.
|
|
20
|
+
|
|
21
|
+

|
package/index.cjs.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./src/index";
|
package/index.cjs.js
ADDED
|
@@ -0,0 +1,443 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
var i18nLibraryTranslation = require('@trackunit/i18n-library-translation');
|
|
5
|
+
var react = require('react');
|
|
6
|
+
var usePortal = require('react-useportal');
|
|
7
|
+
var reactComponents = require('@trackunit/react-components');
|
|
8
|
+
var cssClassVarianceUtilities = require('@trackunit/css-class-variance-utilities');
|
|
9
|
+
var reactSwipeable = require('react-swipeable');
|
|
10
|
+
|
|
11
|
+
var defaultTranslations = {
|
|
12
|
+
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
/** The translation namespace for this library */
|
|
16
|
+
const namespace = "react.react-drawer";
|
|
17
|
+
/**
|
|
18
|
+
* The TranslationResource for this Library.
|
|
19
|
+
* Holds lazy loaded imports for all languages supported by the library.
|
|
20
|
+
*
|
|
21
|
+
* This is used to register the translations for this library before initializing i18next.
|
|
22
|
+
*/
|
|
23
|
+
const translations = {
|
|
24
|
+
ns: namespace,
|
|
25
|
+
default: defaultTranslations,
|
|
26
|
+
languages: {
|
|
27
|
+
de: () => Promise.resolve().then(function () { return require('./translation.cjs.js'); }),
|
|
28
|
+
da: () => Promise.resolve().then(function () { return require('./translation.cjs2.js'); }),
|
|
29
|
+
cs: () => Promise.resolve().then(function () { return require('./translation.cjs3.js'); }),
|
|
30
|
+
nl: () => Promise.resolve().then(function () { return require('./translation.cjs4.js'); }),
|
|
31
|
+
fr: () => Promise.resolve().then(function () { return require('./translation.cjs5.js'); }),
|
|
32
|
+
fi: () => Promise.resolve().then(function () { return require('./translation.cjs6.js'); }),
|
|
33
|
+
hu: () => Promise.resolve().then(function () { return require('./translation.cjs7.js'); }),
|
|
34
|
+
it: () => Promise.resolve().then(function () { return require('./translation.cjs8.js'); }),
|
|
35
|
+
nb: () => Promise.resolve().then(function () { return require('./translation.cjs9.js'); }),
|
|
36
|
+
pl: () => Promise.resolve().then(function () { return require('./translation.cjs10.js'); }),
|
|
37
|
+
pt: () => Promise.resolve().then(function () { return require('./translation.cjs11.js'); }),
|
|
38
|
+
ru: () => Promise.resolve().then(function () { return require('./translation.cjs12.js'); }),
|
|
39
|
+
ro: () => Promise.resolve().then(function () { return require('./translation.cjs13.js'); }),
|
|
40
|
+
es: () => Promise.resolve().then(function () { return require('./translation.cjs14.js'); }),
|
|
41
|
+
sv: () => Promise.resolve().then(function () { return require('./translation.cjs15.js'); }),
|
|
42
|
+
ja: () => Promise.resolve().then(function () { return require('./translation.cjs16.js'); }),
|
|
43
|
+
th: () => Promise.resolve().then(function () { return require('./translation.cjs17.js'); }),
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Registers the translations for this library
|
|
48
|
+
*/
|
|
49
|
+
const setupLibraryTranslations = () => {
|
|
50
|
+
i18nLibraryTranslation.registerTranslations(translations);
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Overlay Component
|
|
55
|
+
*
|
|
56
|
+
* @param {object} props - The Overlay component properties
|
|
57
|
+
* @param {boolean} props.open - Open status of the Overlay
|
|
58
|
+
* @param {Function} props.onClose - Callback function when Overlay is closed
|
|
59
|
+
* @returns {JSX.Element|null} The Overlay component
|
|
60
|
+
*/
|
|
61
|
+
const Overlay = ({ open, onClose }) => {
|
|
62
|
+
react.useEffect(() => {
|
|
63
|
+
if (!onClose) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
const handleEscape = (event) => {
|
|
67
|
+
if (event.key === "Escape") {
|
|
68
|
+
onClose();
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
if (open) {
|
|
72
|
+
window.addEventListener("keyup", handleEscape);
|
|
73
|
+
}
|
|
74
|
+
return () => {
|
|
75
|
+
window.removeEventListener("keyup", handleEscape);
|
|
76
|
+
};
|
|
77
|
+
}, [open, onClose]);
|
|
78
|
+
const handleClick = () => {
|
|
79
|
+
if (onClose) {
|
|
80
|
+
onClose();
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
return (jsxRuntime.jsx("div", { "aria-hidden": open, className: cvaOverlayContainer({ open }), "data-testid": "drawer-overlay", onClick: handleClick }));
|
|
84
|
+
};
|
|
85
|
+
const cvaOverlayContainer = cssClassVarianceUtilities.cvaMerge([
|
|
86
|
+
"absolute",
|
|
87
|
+
"flex",
|
|
88
|
+
"items-center",
|
|
89
|
+
"justify-center",
|
|
90
|
+
"inset-0",
|
|
91
|
+
"bg-black/30",
|
|
92
|
+
"bg-opacity-50",
|
|
93
|
+
"transition-opacity",
|
|
94
|
+
"duration-200",
|
|
95
|
+
"ease-[cubic-bezier(0.32,0.72,0,1)]",
|
|
96
|
+
"opacity-0",
|
|
97
|
+
], {
|
|
98
|
+
variants: {
|
|
99
|
+
open: {
|
|
100
|
+
true: "z-popover opacity-100",
|
|
101
|
+
false: "z-[-1] opacity-0",
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
const cvaDrawer = cssClassVarianceUtilities.cvaMerge([
|
|
107
|
+
"z-toast",
|
|
108
|
+
"pointer-events-auto",
|
|
109
|
+
"absolute",
|
|
110
|
+
"transform",
|
|
111
|
+
"flex-col",
|
|
112
|
+
"transition-transform",
|
|
113
|
+
"duration-300",
|
|
114
|
+
"ease-[cubic-bezier(0.32,0.72,0,1)]",
|
|
115
|
+
], {
|
|
116
|
+
variants: {
|
|
117
|
+
position: {
|
|
118
|
+
left: "left-0 top-0 h-full w-fit",
|
|
119
|
+
right: "right-0 top-0 h-full w-fit",
|
|
120
|
+
top: "left-0 top-0 h-fit w-full pb-2",
|
|
121
|
+
bottom: "bottom-0 left-0 right-0 max-h-screen w-full pt-3",
|
|
122
|
+
},
|
|
123
|
+
mode: {
|
|
124
|
+
open: "", // No additional classes needed; position determines translation
|
|
125
|
+
closed: "", // Translation handled in compoundVariants
|
|
126
|
+
},
|
|
127
|
+
},
|
|
128
|
+
compoundVariants: [
|
|
129
|
+
{
|
|
130
|
+
mode: "open",
|
|
131
|
+
position: "left",
|
|
132
|
+
className: "translate-x-0",
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
mode: "closed",
|
|
136
|
+
position: "left",
|
|
137
|
+
className: "-translate-x-full",
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
mode: "open",
|
|
141
|
+
position: "right",
|
|
142
|
+
className: "translate-x-0",
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
mode: "closed",
|
|
146
|
+
position: "right",
|
|
147
|
+
className: "translate-x-full",
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
mode: "open",
|
|
151
|
+
position: "top",
|
|
152
|
+
className: "translate-y-0",
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
mode: "closed",
|
|
156
|
+
position: "top",
|
|
157
|
+
className: "-translate-y-full",
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
mode: "open",
|
|
161
|
+
position: "bottom",
|
|
162
|
+
className: "translate-y-0",
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
mode: "closed",
|
|
166
|
+
position: "bottom",
|
|
167
|
+
className: "translate-y-full",
|
|
168
|
+
},
|
|
169
|
+
],
|
|
170
|
+
defaultVariants: {
|
|
171
|
+
position: "left",
|
|
172
|
+
mode: "closed",
|
|
173
|
+
},
|
|
174
|
+
});
|
|
175
|
+
const cvaDrawerContent = cssClassVarianceUtilities.cvaMerge(["flex", "h-full", "shadow-lg", "bg-white"], {
|
|
176
|
+
variants: {
|
|
177
|
+
position: {
|
|
178
|
+
left: " rounded-r-lg",
|
|
179
|
+
right: " rounded-l-lg",
|
|
180
|
+
top: " flex-col rounded-b-lg",
|
|
181
|
+
bottom: " max-h-[calc(100vh-10px)] flex-col rounded-t-lg sm:max-h-none",
|
|
182
|
+
},
|
|
183
|
+
},
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
const TRANSITION_DURATION = 100;
|
|
187
|
+
const DEFAULT_POSITION = "left";
|
|
188
|
+
const NOOP$1 = () => void 0;
|
|
189
|
+
/**
|
|
190
|
+
* Drawers components can be switched between open and closed states.
|
|
191
|
+
* They start closed but can be temporarily opened, appearing on top of other content until the user chooses a section.
|
|
192
|
+
* To close the drawer, users can either click outside of it or press the Esc key.
|
|
193
|
+
*
|
|
194
|
+
* @param {DrawerProps} props - The props for the Drawer component
|
|
195
|
+
* @returns {JSX.Element | null} Drawer component
|
|
196
|
+
*/
|
|
197
|
+
const Drawer = react.forwardRef(({ open = false, // Default to closed
|
|
198
|
+
onClose = NOOP$1, hasOverlay = true, position = DEFAULT_POSITION, children, dataTestId, className, renderInPortal = false, keepMountedWhenClosed = false, containerClassName, ...others }, ref) => {
|
|
199
|
+
const { isSm } = reactComponents.useViewportSize();
|
|
200
|
+
const { Portal } = usePortal();
|
|
201
|
+
const shouldUsePortal = !isSm || renderInPortal;
|
|
202
|
+
const [shouldRender, setShouldRender] = react.useState(open);
|
|
203
|
+
const [mode, setMode] = react.useState(open ? "open" : "closed");
|
|
204
|
+
react.useEffect(() => {
|
|
205
|
+
if (open) {
|
|
206
|
+
setShouldRender(true);
|
|
207
|
+
setTimeout(() => setMode("open"), TRANSITION_DURATION);
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
setMode("closed");
|
|
211
|
+
}
|
|
212
|
+
}, [open]);
|
|
213
|
+
const handleAnimationEnd = react.useCallback(() => {
|
|
214
|
+
if (mode === "closed") {
|
|
215
|
+
setShouldRender(false);
|
|
216
|
+
}
|
|
217
|
+
}, [mode, setShouldRender]);
|
|
218
|
+
if (!shouldRender && !keepMountedWhenClosed) {
|
|
219
|
+
return null;
|
|
220
|
+
}
|
|
221
|
+
const content = (jsxRuntime.jsxs("div", { className: containerClassName, children: [hasOverlay ? jsxRuntime.jsx(Overlay, { onClose: onClose, open: mode === "open" }) : null, jsxRuntime.jsx("div", { className: cvaDrawer({
|
|
222
|
+
mode,
|
|
223
|
+
position: position,
|
|
224
|
+
className,
|
|
225
|
+
}), "data-testid": dataTestId, onTransitionEnd: handleAnimationEnd, ref: ref, ...others, children: jsxRuntime.jsx("div", { className: cvaDrawerContent({ position }), children: children }) })] }));
|
|
226
|
+
return shouldUsePortal ? jsxRuntime.jsx(Portal, { children: content }) : content;
|
|
227
|
+
});
|
|
228
|
+
Drawer.displayName = "Drawer";
|
|
229
|
+
|
|
230
|
+
const NOOP = () => void 0;
|
|
231
|
+
const getIconName = (open, position) => {
|
|
232
|
+
switch (position) {
|
|
233
|
+
case "left":
|
|
234
|
+
return open ? "ChevronLeft" : "ChevronRight";
|
|
235
|
+
case "right":
|
|
236
|
+
return open ? "ChevronRight" : "ChevronLeft";
|
|
237
|
+
case "top":
|
|
238
|
+
return open ? "ChevronUp" : "ChevronDown";
|
|
239
|
+
case "bottom":
|
|
240
|
+
return open ? "ChevronDown" : "ChevronUp";
|
|
241
|
+
default:
|
|
242
|
+
return open ? "ChevronLeft" : "ChevronRight";
|
|
243
|
+
}
|
|
244
|
+
};
|
|
245
|
+
/**
|
|
246
|
+
* DrawerToggle is a React functional component that returns a button with a chevron icon.
|
|
247
|
+
* The direction of the chevron changes depending on the state of the 'open' prop and
|
|
248
|
+
* the side the button is positioned ('position' prop).
|
|
249
|
+
* The button might be disabled based on the 'disableButton' prop.
|
|
250
|
+
*
|
|
251
|
+
* @param {object} props - The properties passed to the component
|
|
252
|
+
* @param {boolean} props.open - Indicates if the button is in "open" state
|
|
253
|
+
* @param {Function} [props.onClick] - Optional callback function for when the button is clicked
|
|
254
|
+
* @param {DrawerPosition} props.position - The position of the button relative to its container
|
|
255
|
+
*/
|
|
256
|
+
const DrawerToggle = ({ open, position, onClick = NOOP }) => {
|
|
257
|
+
const name = getIconName(open, position);
|
|
258
|
+
return (jsxRuntime.jsx("div", { className: cvaToggleContainer({ position }), children: jsxRuntime.jsx("button", { className: cvaDrawerToggle({ position }), "data-testid": "toggle-button", onClick: onClick, children: jsxRuntime.jsx(reactComponents.Icon, { name: name }) }) }));
|
|
259
|
+
};
|
|
260
|
+
const cvaDrawerToggle = cssClassVarianceUtilities.cvaMerge([
|
|
261
|
+
"flex",
|
|
262
|
+
"cursor-pointer",
|
|
263
|
+
"items-center",
|
|
264
|
+
"justify-center",
|
|
265
|
+
"border-gray-300",
|
|
266
|
+
"bg-neutral-50",
|
|
267
|
+
"bg-center",
|
|
268
|
+
"bg-no-repeat",
|
|
269
|
+
"shadow-md",
|
|
270
|
+
], {
|
|
271
|
+
variants: {
|
|
272
|
+
position: {
|
|
273
|
+
left: "h-12 w-6 rounded-r-lg",
|
|
274
|
+
right: "h-12 w-6 rounded-l-lg",
|
|
275
|
+
top: "h-6 w-12 rounded-b-lg",
|
|
276
|
+
bottom: "h-6 w-12 rounded-t-lg",
|
|
277
|
+
},
|
|
278
|
+
},
|
|
279
|
+
defaultVariants: {
|
|
280
|
+
position: "left",
|
|
281
|
+
},
|
|
282
|
+
});
|
|
283
|
+
const cvaToggleContainer = cssClassVarianceUtilities.cvaMerge(["z-8", "absolute"], {
|
|
284
|
+
variants: {
|
|
285
|
+
position: {
|
|
286
|
+
left: "right-[-24px] top-[calc(50%-24px)]",
|
|
287
|
+
right: "left-[-24px] top-[calc(50%-24px)]",
|
|
288
|
+
top: "bottom-[-24px] left-[calc(50%-24px)]",
|
|
289
|
+
bottom: "left-[calc(50%-24px)] top-[-24px]",
|
|
290
|
+
},
|
|
291
|
+
},
|
|
292
|
+
defaultVariants: {
|
|
293
|
+
position: "left",
|
|
294
|
+
},
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Retrieves the Y-axis translation value of a given HTML element.
|
|
299
|
+
*
|
|
300
|
+
* @param element - The HTML element for which to get the Y translation. If not provided or null, returns 0.
|
|
301
|
+
* @returns {number} - The Y translation value of the element. Returns 0 if the element is not provided or if the transform style is "none".
|
|
302
|
+
*/
|
|
303
|
+
const getElementYTranslation = (element) => {
|
|
304
|
+
if (!element) {
|
|
305
|
+
return 0;
|
|
306
|
+
}
|
|
307
|
+
const style = window.getComputedStyle(element);
|
|
308
|
+
const transform = style.transform;
|
|
309
|
+
if (transform === "none") {
|
|
310
|
+
return 0;
|
|
311
|
+
}
|
|
312
|
+
const matrix = new DOMMatrix(transform);
|
|
313
|
+
return matrix.m42;
|
|
314
|
+
};
|
|
315
|
+
/**
|
|
316
|
+
* Hook for handling swipe events on the drawer.
|
|
317
|
+
*/
|
|
318
|
+
const useSwipeHandlers = ({ ref, closingThreshold, onCloseGesture, onOpenGesture }) => {
|
|
319
|
+
const [isDragging, setIsDragging] = react.useState(false);
|
|
320
|
+
const [dragDistance, setDragDistance] = react.useState(0);
|
|
321
|
+
const currentY = react.useRef(0);
|
|
322
|
+
const currentHeight = react.useRef(0);
|
|
323
|
+
const geometry = reactComponents.useGeometry(ref);
|
|
324
|
+
const handlers = reactSwipeable.useSwipeable({
|
|
325
|
+
onTouchStartOrOnMouseDown: () => {
|
|
326
|
+
const y = getElementYTranslation(ref.current);
|
|
327
|
+
const height = geometry.height;
|
|
328
|
+
currentY.current = y;
|
|
329
|
+
currentHeight.current = height;
|
|
330
|
+
setDragDistance(y);
|
|
331
|
+
setIsDragging(true);
|
|
332
|
+
},
|
|
333
|
+
onSwiping: (e) => {
|
|
334
|
+
const newY = currentY.current + e.deltaY;
|
|
335
|
+
if (newY >= 0) {
|
|
336
|
+
setDragDistance(newY);
|
|
337
|
+
}
|
|
338
|
+
},
|
|
339
|
+
onSwipedDown: (e) => {
|
|
340
|
+
const threshold = currentHeight.current * closingThreshold;
|
|
341
|
+
if (e.absY > threshold && onCloseGesture) {
|
|
342
|
+
onCloseGesture();
|
|
343
|
+
}
|
|
344
|
+
setIsDragging(false);
|
|
345
|
+
setDragDistance(0);
|
|
346
|
+
},
|
|
347
|
+
onSwipedUp: (e) => {
|
|
348
|
+
const threshold = currentHeight.current * closingThreshold;
|
|
349
|
+
if (e.absY > threshold && onOpenGesture) {
|
|
350
|
+
onOpenGesture();
|
|
351
|
+
}
|
|
352
|
+
setIsDragging(false);
|
|
353
|
+
setDragDistance(0);
|
|
354
|
+
},
|
|
355
|
+
onSwiped: () => void 0,
|
|
356
|
+
trackMouse: true,
|
|
357
|
+
trackTouch: true,
|
|
358
|
+
preventScrollOnSwipe: true,
|
|
359
|
+
});
|
|
360
|
+
return { handlers, isDragging, dragDistance };
|
|
361
|
+
};
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* DrawerPuller is a React component that renders a puller element for a swipeable drawer.
|
|
365
|
+
*
|
|
366
|
+
* @param {CommonProps} props - The props for the DrawerPuller component.
|
|
367
|
+
* @param {string} [props.className] - Additional class names to apply to the puller element.
|
|
368
|
+
* @param {Ref<HTMLDivElement>} ref - The ref to be forwarded to the root div element.
|
|
369
|
+
* @returns {JSX.Element} The rendered DrawerPuller component.
|
|
370
|
+
*/
|
|
371
|
+
const DrawerPuller = react.forwardRef(({ className, ...props }, ref) => {
|
|
372
|
+
return (jsxRuntime.jsx("div", { className: cvaPuller({ className }), "data-testid": "drawer-puller", ...props, ref: ref, children: jsxRuntime.jsx("div", { className: cvaPullerIcon() }) }));
|
|
373
|
+
});
|
|
374
|
+
DrawerPuller.displayName = "DrawerPuller";
|
|
375
|
+
const cvaPuller = cssClassVarianceUtilities.cvaMerge(["pt-2", "pb-4", "flex", "items-center", "justify-center"]);
|
|
376
|
+
const cvaPullerIcon = cssClassVarianceUtilities.cvaMerge(["block", "h-1", "w-8", "rounded-full", "bg-gray-400"]);
|
|
377
|
+
|
|
378
|
+
const CLOSING_THRESHOLD = 0.15;
|
|
379
|
+
/**
|
|
380
|
+
*
|
|
381
|
+
* SwipeableDrawer is a component that wraps the Drawer component to add swipeable functionality.
|
|
382
|
+
* It uses swipe handlers to detect swipe gestures for opening and closing the drawer.
|
|
383
|
+
* The component manages its docked state based on the open prop and keepMountedWhenClosed prop.
|
|
384
|
+
* It also applies styles dynamically based on whether the drawer is being dragged.
|
|
385
|
+
*/
|
|
386
|
+
const SwipeableDrawer = ({ open, onClose, onOpenGesture, children, keepMountedWhenClosed, className, position = "bottom", ...others }) => {
|
|
387
|
+
const drawerRefs = react.useRef(null);
|
|
388
|
+
const [isDocked, setIsDocked] = react.useState(keepMountedWhenClosed && !open);
|
|
389
|
+
const { handlers, isDragging, dragDistance } = useSwipeHandlers({
|
|
390
|
+
ref: drawerRefs,
|
|
391
|
+
closingThreshold: CLOSING_THRESHOLD,
|
|
392
|
+
onCloseGesture: onClose,
|
|
393
|
+
onOpenGesture,
|
|
394
|
+
});
|
|
395
|
+
const drawerStyle = react.useMemo(() => isDragging
|
|
396
|
+
? {
|
|
397
|
+
transform: `translateY(${dragDistance}px)`,
|
|
398
|
+
transition: "none",
|
|
399
|
+
}
|
|
400
|
+
: {}, [isDragging, dragDistance]);
|
|
401
|
+
react.useEffect(() => {
|
|
402
|
+
if (!keepMountedWhenClosed) {
|
|
403
|
+
return;
|
|
404
|
+
}
|
|
405
|
+
if (isDocked && open) {
|
|
406
|
+
setIsDocked(false);
|
|
407
|
+
}
|
|
408
|
+
else if (!isDocked && !open) {
|
|
409
|
+
setIsDocked(true);
|
|
410
|
+
}
|
|
411
|
+
}, [open, isDocked, keepMountedWhenClosed]);
|
|
412
|
+
react.useEffect(() => {
|
|
413
|
+
var _a, _b;
|
|
414
|
+
if (drawerRefs.current) {
|
|
415
|
+
drawerRefs.current.style.transform = (_a = drawerStyle.transform) !== null && _a !== void 0 ? _a : "";
|
|
416
|
+
drawerRefs.current.style.transition = (_b = drawerStyle.transition) !== null && _b !== void 0 ? _b : "";
|
|
417
|
+
}
|
|
418
|
+
}, [drawerStyle, drawerRefs]);
|
|
419
|
+
return (jsxRuntime.jsxs(Drawer, { className: cvaSwipeableDrawer({ docked: isDocked, className }), "data-docked": isDocked, keepMountedWhenClosed: keepMountedWhenClosed, onClose: onClose, open: open, position: position, ref: drawerRefs, ...others, children: [jsxRuntime.jsx(DrawerPuller, { ...handlers }), children] }));
|
|
420
|
+
};
|
|
421
|
+
const cvaSwipeableDrawer = cssClassVarianceUtilities.cvaMerge([], {
|
|
422
|
+
variants: {
|
|
423
|
+
docked: {
|
|
424
|
+
true: "translate-y-[calc(100%-30px)]",
|
|
425
|
+
false: "",
|
|
426
|
+
},
|
|
427
|
+
},
|
|
428
|
+
});
|
|
429
|
+
|
|
430
|
+
/*
|
|
431
|
+
* ----------------------------
|
|
432
|
+
* | SETUP TRANSLATIONS START |
|
|
433
|
+
* ----------------------------
|
|
434
|
+
* This import and function call is needed to register translations for this library.
|
|
435
|
+
* Do not remove this if this library has translations.
|
|
436
|
+
*/
|
|
437
|
+
setupLibraryTranslations();
|
|
438
|
+
|
|
439
|
+
exports.Drawer = Drawer;
|
|
440
|
+
exports.DrawerToggle = DrawerToggle;
|
|
441
|
+
exports.SwipeableDrawer = SwipeableDrawer;
|
|
442
|
+
exports.TRANSITION_DURATION = TRANSITION_DURATION;
|
|
443
|
+
exports.cvaSwipeableDrawer = cvaSwipeableDrawer;
|
package/index.esm.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./src/index";
|