playbook_ui 14.5.0.pre.rc.12 → 14.5.0.pre.rc.13
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.
- checksums.yaml +4 -4
- data/app/pb_kits/playbook/_playbook.scss +2 -0
- data/app/pb_kits/playbook/pb_advanced_table/advanced_table.test.jsx +1 -1
- data/app/pb_kits/playbook/pb_drawer/_close_icon.tsx +25 -0
- data/app/pb_kits/playbook/pb_drawer/_drawer.scss +465 -0
- data/app/pb_kits/playbook/pb_drawer/_drawer.tsx +195 -0
- data/app/pb_kits/playbook/pb_drawer/_drawer_context.tsx +3 -0
- data/app/pb_kits/playbook/pb_drawer/docs/_drawer_borders.jsx +117 -0
- data/app/pb_kits/playbook/pb_drawer/docs/_drawer_breakpoints.jsx +43 -0
- data/app/pb_kits/playbook/pb_drawer/docs/_drawer_default.html.erb +1 -0
- data/app/pb_kits/playbook/pb_drawer/docs/_drawer_default.jsx +63 -0
- data/app/pb_kits/playbook/pb_drawer/docs/_drawer_overlay.jsx +55 -0
- data/app/pb_kits/playbook/pb_drawer/docs/_drawer_sizes.jsx +113 -0
- data/app/pb_kits/playbook/pb_drawer/docs/example.yml +12 -0
- data/app/pb_kits/playbook/pb_drawer/docs/index.js +5 -0
- data/app/pb_kits/playbook/pb_drawer/drawer.html.erb +12 -0
- data/app/pb_kits/playbook/pb_drawer/drawer.rb +8 -0
- data/app/pb_kits/playbook/pb_drawer/drawer.test.jsx +77 -0
- data/dist/chunks/{_typeahead-C7ICra83.js → _typeahead-D72GNy0y.js} +1 -1
- data/dist/chunks/_weekday_stacked-BDIhh9Z6.js +45 -0
- data/dist/chunks/vendor.js +1 -1
- data/dist/menu.yml +3 -1
- data/dist/playbook-doc.js +1 -1
- data/dist/playbook-rails-react-bindings.js +1 -1
- data/dist/playbook-rails.js +1 -1
- data/dist/playbook.css +1 -1
- data/lib/playbook/version.rb +1 -1
- metadata +18 -3
- data/dist/chunks/_weekday_stacked-DwrIhNbf.js +0 -45
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c48f925d87b9373c2bb1e9f70998d2d01141398419d2adb6b0a8193366eb7923
|
4
|
+
data.tar.gz: a4357ea2e9ef56fb66959708f73dc9fe5174306f901deb6b84df141327f405bd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 518d8bfb962b87cbaabaeea46ebf63908315d83ea167ab946add95a4b5ccfe952dc191a81e594f49bcfbab6633f64cc65044f5b596a67c6b5f4d16f0304267e5
|
7
|
+
data.tar.gz: 0bd271d10113a4b49ea0d9c6f1aad023a51089fab60138a8ebfb083c163f37c44fea029fe5e623b78a768913b8b695fc853b5fcda7f91c25b232388fa55f0b90
|
@@ -1,3 +1,4 @@
|
|
1
|
+
|
1
2
|
@import 'pb_advanced_table/advanced_table';
|
2
3
|
@import 'pb_avatar/avatar';
|
3
4
|
@import 'pb_avatar_action_button/avatar_action_button';
|
@@ -105,6 +106,7 @@
|
|
105
106
|
@import 'pb_user_badge/user_badge';
|
106
107
|
@import 'pb_walkthrough/walkthrough';
|
107
108
|
@import 'pb_weekday_stacked/weekday_stacked';
|
109
|
+
@import 'pb_drawer/drawer';
|
108
110
|
@import 'utilities/mixins';
|
109
111
|
@import 'utilities/spacing';
|
110
112
|
@import 'utilities/cursor';
|
@@ -0,0 +1,25 @@
|
|
1
|
+
import React from 'react'
|
2
|
+
import Icon from '../pb_icon/_icon'
|
3
|
+
|
4
|
+
import { getAllIcons } from "../utilities/icons/allicons"
|
5
|
+
|
6
|
+
type CloseIconProps = {
|
7
|
+
onClose: () => void,
|
8
|
+
}
|
9
|
+
|
10
|
+
export const CloseIcon = (props: CloseIconProps): React.ReactElement => {
|
11
|
+
const { onClose } = props
|
12
|
+
const timesIcon = getAllIcons()["times"]
|
13
|
+
return (
|
14
|
+
<div
|
15
|
+
className="pb_dialog_close_icon"
|
16
|
+
onClick={onClose}
|
17
|
+
>
|
18
|
+
<Icon
|
19
|
+
className="svg-inline--fa"
|
20
|
+
customIcon={timesIcon.icon as unknown as { [key: string]: SVGElement }}
|
21
|
+
fixedWidth
|
22
|
+
/>
|
23
|
+
</div>
|
24
|
+
)
|
25
|
+
}
|
@@ -0,0 +1,465 @@
|
|
1
|
+
@import "../tokens/positioning";
|
2
|
+
@import "../tokens/colors";
|
3
|
+
@import "../pb_card/card_mixin";
|
4
|
+
@import "../tokens/shadows";
|
5
|
+
@import "../tokens/border_radius";
|
6
|
+
@import "../tokens/spacing";
|
7
|
+
@import "../tokens/animation-curves";
|
8
|
+
@import "../tokens/positioning";
|
9
|
+
|
10
|
+
// Drawer animations
|
11
|
+
// Drawer animations for fading in and out from the center
|
12
|
+
@keyframes modalFadeIn {
|
13
|
+
from {
|
14
|
+
transform: translate3d(0, -100%, 0);
|
15
|
+
opacity: 0;
|
16
|
+
}
|
17
|
+
to {
|
18
|
+
transform: translate3d(0, 0, 0);
|
19
|
+
opacity: 1;
|
20
|
+
}
|
21
|
+
}
|
22
|
+
|
23
|
+
@keyframes modalFadeOut {
|
24
|
+
from {
|
25
|
+
transform: translate3d(0, 0, 0);
|
26
|
+
opacity: 1;
|
27
|
+
}
|
28
|
+
to {
|
29
|
+
transform: translate3d(0, -50%, 0);
|
30
|
+
opacity: 0;
|
31
|
+
}
|
32
|
+
}
|
33
|
+
|
34
|
+
// Drawer animations for fading in and out from the right side
|
35
|
+
|
36
|
+
@keyframes overlayFade {
|
37
|
+
from {
|
38
|
+
opacity: 0;
|
39
|
+
transform: translateY(0);
|
40
|
+
}
|
41
|
+
to {
|
42
|
+
opacity: 1;
|
43
|
+
transform: translateY(0);
|
44
|
+
}
|
45
|
+
}
|
46
|
+
|
47
|
+
@keyframes overlayFadeOut {
|
48
|
+
from {
|
49
|
+
opacity: 1;
|
50
|
+
}
|
51
|
+
to {
|
52
|
+
opacity: 0;
|
53
|
+
}
|
54
|
+
}
|
55
|
+
|
56
|
+
body.ReactModal__Body--open {
|
57
|
+
transition: margin-left 0.3s ease-in-out, margin-right 0.3s ease-in-out;
|
58
|
+
}
|
59
|
+
|
60
|
+
.pb_drawer_lg_left.pb_drawer {
|
61
|
+
transform: translateX(-100%);
|
62
|
+
}
|
63
|
+
|
64
|
+
.pb_drawer_lg_right.pb_drawer {
|
65
|
+
transform: translateX(100%);
|
66
|
+
}
|
67
|
+
|
68
|
+
.pb_drawer.pb_drawer_after_open {
|
69
|
+
transform: translateX(0); /* Slide in */
|
70
|
+
}
|
71
|
+
// Drawer Styles
|
72
|
+
.pb_drawer {
|
73
|
+
|
74
|
+
// Local Variables
|
75
|
+
$gutter: $space_lg;
|
76
|
+
$xsmall: 64px;
|
77
|
+
$small: 200px;
|
78
|
+
$medium: 250px;
|
79
|
+
$large: 300px;
|
80
|
+
$xlarge: 365px;
|
81
|
+
$animation-duration: .2s;
|
82
|
+
$z-index: 100;
|
83
|
+
$opacity_visible: 1;
|
84
|
+
$opacity_hidden: 0;
|
85
|
+
|
86
|
+
.drawer {
|
87
|
+
position: sticky;
|
88
|
+
top: 0;
|
89
|
+
background-color: $white;
|
90
|
+
z-index: $z_8;
|
91
|
+
}
|
92
|
+
|
93
|
+
// @include pb_card;
|
94
|
+
background-color: $white;
|
95
|
+
border: 0;
|
96
|
+
box-shadow: $shadow_deepest; // border class here
|
97
|
+
max-height: calc(100vh - #{$gutter * 2});
|
98
|
+
max-width: calc(100vw - #{$gutter * 2});
|
99
|
+
overflow: auto;
|
100
|
+
animation-name: modalFadeIn;
|
101
|
+
animation-duration: $animation-duration;
|
102
|
+
outline: none;
|
103
|
+
animation-timing-function: $easeInOutQuint;
|
104
|
+
transition: transform 0.3s ease-in-out;
|
105
|
+
|
106
|
+
&.drawer_border_full {
|
107
|
+
box-shadow: none;
|
108
|
+
border: 2px solid #f3f7fb;
|
109
|
+
}
|
110
|
+
|
111
|
+
&.drawer_border_right {
|
112
|
+
border-right: 2px solid #f3f7fb;
|
113
|
+
}
|
114
|
+
|
115
|
+
&.drawer_border_left {
|
116
|
+
border-left: 2px solid #f3f7fb;
|
117
|
+
}
|
118
|
+
|
119
|
+
&[class*="_left"] {
|
120
|
+
animation-name: modalFadeInLeft;
|
121
|
+
&[class*="_before_close"] {
|
122
|
+
animation-name: modalFadeOutLeft;
|
123
|
+
animation-duration: $animation-duration;
|
124
|
+
opacity: $opacity_hidden;
|
125
|
+
}
|
126
|
+
}
|
127
|
+
|
128
|
+
&[class*="_right"] {
|
129
|
+
animation-name: modalFadeInRight;
|
130
|
+
&[class*="_before_close"] {
|
131
|
+
animation-name: modalFadeOutRight;
|
132
|
+
animation-duration: $animation-duration;
|
133
|
+
opacity: $opacity_hidden;
|
134
|
+
}
|
135
|
+
}
|
136
|
+
|
137
|
+
&[class*="_xs_"] {
|
138
|
+
width: $xsmall;
|
139
|
+
max-width: $xsmall;
|
140
|
+
}
|
141
|
+
|
142
|
+
&[class*="_sm_"] {
|
143
|
+
width: $small;
|
144
|
+
max-width: $small;
|
145
|
+
}
|
146
|
+
|
147
|
+
&[class*="_md_"] {
|
148
|
+
width: $medium;
|
149
|
+
max-width: $medium;
|
150
|
+
}
|
151
|
+
|
152
|
+
&[class*="_lg_"] {
|
153
|
+
width: $large;
|
154
|
+
max-width: $large;
|
155
|
+
}
|
156
|
+
|
157
|
+
&[class*="_xl_"] {
|
158
|
+
width: $xlarge;
|
159
|
+
max-width: $xlarge;
|
160
|
+
}
|
161
|
+
|
162
|
+
&_body_open {
|
163
|
+
overflow: hidden;
|
164
|
+
}
|
165
|
+
|
166
|
+
&_after_open {
|
167
|
+
opacity: $opacity_visible;
|
168
|
+
}
|
169
|
+
|
170
|
+
&.no-background {
|
171
|
+
background-color: transparent;
|
172
|
+
}
|
173
|
+
|
174
|
+
&[class*="_before_close"] {
|
175
|
+
animation-name: modalFadeOut;
|
176
|
+
animation-duration: $animation-duration;
|
177
|
+
opacity: $opacity_hidden;
|
178
|
+
}
|
179
|
+
|
180
|
+
&_close_icon {
|
181
|
+
cursor: pointer;
|
182
|
+
}
|
183
|
+
|
184
|
+
&_overlay {
|
185
|
+
position: fixed;
|
186
|
+
top: 0;
|
187
|
+
left: 0;
|
188
|
+
right: 0;
|
189
|
+
bottom: 0;
|
190
|
+
display: flex;
|
191
|
+
align-items: center;
|
192
|
+
justify-content: center;
|
193
|
+
background-color: rgba($bg_dark, $opacity_4);
|
194
|
+
z-index: $z-index;
|
195
|
+
animation-name: overlayFade;
|
196
|
+
animation-duration: $animation-duration;
|
197
|
+
|
198
|
+
&_after_open {
|
199
|
+
opacity: $opacity_visible;
|
200
|
+
}
|
201
|
+
&_before_close {
|
202
|
+
animation-name: overlayFadeOut;
|
203
|
+
animation-duration: $animation-duration;
|
204
|
+
opacity: $opacity_hidden;
|
205
|
+
}
|
206
|
+
&[class*="full_height"] {
|
207
|
+
&[class*="_left"]{
|
208
|
+
justify-content: flex-start;
|
209
|
+
}
|
210
|
+
|
211
|
+
&[class*="_center"]{
|
212
|
+
justify-content: center;
|
213
|
+
}
|
214
|
+
|
215
|
+
&[class*="_right"]{
|
216
|
+
justify-content: flex-end;
|
217
|
+
}
|
218
|
+
|
219
|
+
.pb_drawer {
|
220
|
+
height: 100%;
|
221
|
+
max-height: 100%;
|
222
|
+
max-width: none;
|
223
|
+
// This empty div only has height when drawer is full height
|
224
|
+
// Fix for drawer body content disappearing behind sticky footer
|
225
|
+
.drawer-pseudo-footer {
|
226
|
+
height: $space_xl * 2;
|
227
|
+
}
|
228
|
+
.drawer_footer {
|
229
|
+
position: fixed;
|
230
|
+
bottom: 0;
|
231
|
+
background-color: $white;
|
232
|
+
max-width: 100%;
|
233
|
+
}
|
234
|
+
&[class*="_xs_"] {
|
235
|
+
width: $xsmall;
|
236
|
+
.dialog_footer {
|
237
|
+
width: $xsmall;
|
238
|
+
}
|
239
|
+
}
|
240
|
+
&[class*="_sm_"] {
|
241
|
+
width: $small;
|
242
|
+
.dialog_footer {
|
243
|
+
width: $small;
|
244
|
+
}
|
245
|
+
}
|
246
|
+
&[class*="_md_"] {
|
247
|
+
width: $medium;
|
248
|
+
.dialog_footer {
|
249
|
+
width: $medium;
|
250
|
+
}
|
251
|
+
}
|
252
|
+
&[class*="_lg_"] {
|
253
|
+
width: $large;
|
254
|
+
.dialog_footer {
|
255
|
+
width: $large;
|
256
|
+
}
|
257
|
+
}
|
258
|
+
&[class*="_xl_"] {
|
259
|
+
width: $xlarge;
|
260
|
+
.dialog_footer {
|
261
|
+
width: $xlarge;
|
262
|
+
}
|
263
|
+
}
|
264
|
+
}
|
265
|
+
}
|
266
|
+
}
|
267
|
+
|
268
|
+
&_no_overlay {
|
269
|
+
position: fixed;
|
270
|
+
top: 0;
|
271
|
+
left: 0;
|
272
|
+
right: 0;
|
273
|
+
bottom: 0;
|
274
|
+
display: flex;
|
275
|
+
align-items: center;
|
276
|
+
justify-content: center;
|
277
|
+
z-index: $z-index;
|
278
|
+
animation-name: overlayFade;
|
279
|
+
animation-duration: $animation-duration;
|
280
|
+
overflow: none; /* Ensure body remains scrollable */
|
281
|
+
pointer-events: none; /* Allow interaction inside the drawer itself */
|
282
|
+
|
283
|
+
body.ReactModal__Body--open {
|
284
|
+
overflow: none; /* Ensure body remains scrollable */
|
285
|
+
pointer-events: none; /* Allow interaction inside the drawer itself */
|
286
|
+
}
|
287
|
+
|
288
|
+
&_after_open {
|
289
|
+
opacity: $opacity_visible;
|
290
|
+
overflow: none; /* Ensure body remains scrollable */
|
291
|
+
pointer-events: none; /* Allow interaction inside the drawer itself */
|
292
|
+
}
|
293
|
+
&_before_close {
|
294
|
+
animation-name: overlayFadeOut;
|
295
|
+
animation-duration: $animation-duration;
|
296
|
+
opacity: $opacity_hidden;
|
297
|
+
}
|
298
|
+
&[class*="full_height"] {
|
299
|
+
&[class*="_left"]{
|
300
|
+
justify-content: flex-start;
|
301
|
+
}
|
302
|
+
|
303
|
+
&[class*="_center"]{
|
304
|
+
justify-content: center;
|
305
|
+
}
|
306
|
+
|
307
|
+
&[class*="_right"]{
|
308
|
+
justify-content: flex-end;
|
309
|
+
}
|
310
|
+
|
311
|
+
.pb_drawer {
|
312
|
+
height: 100%;
|
313
|
+
max-height: 100%;
|
314
|
+
max-width: none;
|
315
|
+
// This empty div only has height when drawer is full height
|
316
|
+
// Fix for drawer body content disappearing behind sticky footer
|
317
|
+
.drawer-pseudo-footer {
|
318
|
+
height: $space_xl * 2;
|
319
|
+
}
|
320
|
+
.drawer_footer {
|
321
|
+
position: fixed;
|
322
|
+
bottom: 0;
|
323
|
+
background-color: $white;
|
324
|
+
max-width: 100%;
|
325
|
+
}
|
326
|
+
&[class*="_xs_"] {
|
327
|
+
width: $xsmall;
|
328
|
+
.dialog_footer {
|
329
|
+
width: $xsmall;
|
330
|
+
}
|
331
|
+
}
|
332
|
+
&[class*="_sm_"] {
|
333
|
+
width: $small;
|
334
|
+
.dialog_footer {
|
335
|
+
width: $small;
|
336
|
+
}
|
337
|
+
}
|
338
|
+
&[class*="_md_"] {
|
339
|
+
width: $medium;
|
340
|
+
.dialog_footer {
|
341
|
+
width: $medium;
|
342
|
+
}
|
343
|
+
}
|
344
|
+
&[class*="_lg_"] {
|
345
|
+
width: $large;
|
346
|
+
.dialog_footer {
|
347
|
+
width: $large;
|
348
|
+
}
|
349
|
+
}
|
350
|
+
&[class*="_xl_"] {
|
351
|
+
width: $xlarge;
|
352
|
+
.dialog_footer {
|
353
|
+
width: $xlarge;
|
354
|
+
}
|
355
|
+
}
|
356
|
+
}
|
357
|
+
}
|
358
|
+
}
|
359
|
+
|
360
|
+
[class*="drawer_body"] {
|
361
|
+
padding: $space_sm;
|
362
|
+
}
|
363
|
+
|
364
|
+
[class*="drawer_header"] {
|
365
|
+
padding: $space_sm;
|
366
|
+
}
|
367
|
+
|
368
|
+
[class*="drawer_footer"] {
|
369
|
+
padding: $space_sm;
|
370
|
+
}
|
371
|
+
|
372
|
+
//styles specific to rails version of kit
|
373
|
+
// rails version has own wrapper because of the way the overlay functions for the HTML drawer used to create this
|
374
|
+
.pb_drawer_wrapper_rails {
|
375
|
+
$medium: 500px;
|
376
|
+
$large: 800px;
|
377
|
+
$xlarge: 1150px;
|
378
|
+
|
379
|
+
&[class*="full_height"] {
|
380
|
+
&[class*="_left"]{
|
381
|
+
.pb_drawer_rails {
|
382
|
+
margin: unset !important;
|
383
|
+
margin-right: auto !important;
|
384
|
+
}
|
385
|
+
}
|
386
|
+
|
387
|
+
&[class*="_center"]{
|
388
|
+
justify-content: center;
|
389
|
+
}
|
390
|
+
|
391
|
+
&[class*="_right"]{
|
392
|
+
.pb_drawer_rails {
|
393
|
+
margin: unset !important;
|
394
|
+
margin-left: auto !important;
|
395
|
+
}
|
396
|
+
}
|
397
|
+
|
398
|
+
.pb_drawer {
|
399
|
+
height: 100% !important;
|
400
|
+
max-height: 100% !important;
|
401
|
+
max-width: 100%;
|
402
|
+
// This empty div only has height when drawer is full height.
|
403
|
+
// Fix for drawer body content disappearing behind sticky footer
|
404
|
+
.drawer-pseudo-footer {
|
405
|
+
height: $space_xl * 2;
|
406
|
+
}
|
407
|
+
.drawer_footer {
|
408
|
+
position:fixed;
|
409
|
+
bottom: 0;
|
410
|
+
background-color: $white;
|
411
|
+
max-width: 100%;
|
412
|
+
}
|
413
|
+
&[class*="_sm"] {
|
414
|
+
width: $medium;
|
415
|
+
.drawer_footer {
|
416
|
+
width: $medium;
|
417
|
+
}
|
418
|
+
}
|
419
|
+
&[class*="_md"] {
|
420
|
+
width: $large;
|
421
|
+
.drawer_footer {
|
422
|
+
width: $large;
|
423
|
+
}
|
424
|
+
}
|
425
|
+
&[class*="_lg"] {
|
426
|
+
width: $xlarge;
|
427
|
+
.drawer_footer {
|
428
|
+
width: $xlarge;
|
429
|
+
}
|
430
|
+
}
|
431
|
+
}
|
432
|
+
}
|
433
|
+
|
434
|
+
// Fixes for stylesheets in nitro that were conflicting with our kit. DO NOT REMOVE.
|
435
|
+
// Conflicts were only apparent in nitro, not in playbook local env
|
436
|
+
.pb_drawer_rails {
|
437
|
+
position: fixed !important;
|
438
|
+
top: 0 !important;
|
439
|
+
padding: unset !important;
|
440
|
+
margin: auto;
|
441
|
+
|
442
|
+
}
|
443
|
+
|
444
|
+
// Overlay for rails kit
|
445
|
+
drawer::backdrop {
|
446
|
+
position: fixed;
|
447
|
+
top: 0;
|
448
|
+
left: 0;
|
449
|
+
right: 0;
|
450
|
+
bottom: 0;
|
451
|
+
display: flex;
|
452
|
+
align-items: center;
|
453
|
+
justify-content: center;
|
454
|
+
background-color: rgba($bg_dark, $opacity_4);
|
455
|
+
animation-name: overlayFade;
|
456
|
+
animation-duration: 0.2s;
|
457
|
+
}
|
458
|
+
|
459
|
+
.drawer-button-class {
|
460
|
+
background-color: unset;
|
461
|
+
border: none;
|
462
|
+
cursor: pointer;
|
463
|
+
}
|
464
|
+
}
|
465
|
+
}
|
@@ -0,0 +1,195 @@
|
|
1
|
+
import React, { useState, useEffect } from "react";
|
2
|
+
import classnames from "classnames";
|
3
|
+
import Modal from "react-modal";
|
4
|
+
|
5
|
+
import { buildAriaProps, buildCss, buildDataProps, buildHtmlProps } from "../utilities/props";
|
6
|
+
import { globalProps } from "../utilities/globalProps";
|
7
|
+
|
8
|
+
import { DialogContext } from "../pb_dialog/_dialog_context";
|
9
|
+
|
10
|
+
type DrawerProps = {
|
11
|
+
aria?: { [key: string]: string };
|
12
|
+
behavior?: "floating" | "push";
|
13
|
+
border?: "full" | "none" | "right" | "left";
|
14
|
+
breakpoint?: "none" | "xs" | "sm" | "md" | "lg" | "xl";
|
15
|
+
children: React.ReactNode | React.ReactNode[] | string;
|
16
|
+
className?: string;
|
17
|
+
data?: { [key: string]: string };
|
18
|
+
htmlOptions?: { [key: string]: string | number | boolean | (() => void) };
|
19
|
+
id?: string;
|
20
|
+
fullHeight?: boolean;
|
21
|
+
onClose?: () => void;
|
22
|
+
opened: boolean;
|
23
|
+
overlay: boolean;
|
24
|
+
placement?: "left" | "right";
|
25
|
+
size?: "xs" | "sm" | "md" | "lg" | "xl";
|
26
|
+
text?: string;
|
27
|
+
trigger?: string;
|
28
|
+
};
|
29
|
+
|
30
|
+
const Drawer = (props: DrawerProps): React.ReactElement => {
|
31
|
+
const {
|
32
|
+
aria = {},
|
33
|
+
behavior = "floating",
|
34
|
+
border = "none",
|
35
|
+
breakpoint = "none",
|
36
|
+
className,
|
37
|
+
data = {},
|
38
|
+
htmlOptions = {},
|
39
|
+
id,
|
40
|
+
size = "md",
|
41
|
+
children,
|
42
|
+
fullHeight = false,
|
43
|
+
opened,
|
44
|
+
onClose,
|
45
|
+
overlay = true,
|
46
|
+
placement = "left",
|
47
|
+
trigger,
|
48
|
+
} = props;
|
49
|
+
const ariaProps = buildAriaProps(aria);
|
50
|
+
const dataProps = buildDataProps(data);
|
51
|
+
const htmlProps = buildHtmlProps(htmlOptions);
|
52
|
+
|
53
|
+
let globalPropsString: string = globalProps(props);
|
54
|
+
|
55
|
+
// Check if the string contains any of the prefixes
|
56
|
+
const containsPrefix = ['p_', 'pb_', 'pt_', 'pl_', 'pr_', 'px_', 'py_'].some((prefix) =>
|
57
|
+
globalPropsString.includes(prefix)
|
58
|
+
);
|
59
|
+
|
60
|
+
// If none of the prefixes are found, append 'p_sm' to the string
|
61
|
+
if (!containsPrefix) {
|
62
|
+
globalPropsString += ' p_sm';
|
63
|
+
}
|
64
|
+
|
65
|
+
const drawerClassNames = {
|
66
|
+
base: `${classnames(
|
67
|
+
"pb_drawer",
|
68
|
+
buildCss("pb_drawer", size, placement),
|
69
|
+
{
|
70
|
+
"drawer_border_full": border === "full",
|
71
|
+
"drawer_border_right": border === "right",
|
72
|
+
"drawer_border_left": border === "left",
|
73
|
+
}
|
74
|
+
)} ${globalPropsString}`,
|
75
|
+
afterOpen: "pb_drawer_after_open",
|
76
|
+
beforeClose: "pb_drawer_before_close",
|
77
|
+
};
|
78
|
+
|
79
|
+
const fullHeightClassNames = () => {
|
80
|
+
if (!fullHeight) return null;
|
81
|
+
return `full_height_${placement}`;
|
82
|
+
};
|
83
|
+
|
84
|
+
const overlayClassNames = {
|
85
|
+
base: `pb_drawer${overlay ? '_overlay' : '_no_overlay'} ${fullHeight !== null && fullHeightClassNames()} ${!overlay ? 'no-background' : ''}`,
|
86
|
+
afterOpen: "pb_drawer_overlay_after_open",
|
87
|
+
beforeClose: "pb_drawer_overlay_before_close",
|
88
|
+
};
|
89
|
+
|
90
|
+
const classes = classnames(
|
91
|
+
buildCss("pb_drawer_wrapper"),
|
92
|
+
className
|
93
|
+
);
|
94
|
+
|
95
|
+
const [triggerOpened, setTriggerOpened] = useState(false);
|
96
|
+
|
97
|
+
const breakpointWidths: Record<DrawerProps['breakpoint'], number> = {
|
98
|
+
none: 0,
|
99
|
+
xs: 575,
|
100
|
+
sm: 768,
|
101
|
+
md: 992,
|
102
|
+
lg: 1200,
|
103
|
+
xl: 1400,
|
104
|
+
};
|
105
|
+
|
106
|
+
// State to manage opening the drawer based on breakpoint
|
107
|
+
const [isBreakpointOpen, setIsBreakpointOpen] = useState(false);
|
108
|
+
|
109
|
+
useEffect(() => {
|
110
|
+
if (breakpoint === 'none') return;
|
111
|
+
|
112
|
+
const handleResize = () => {
|
113
|
+
const width = window.innerWidth;
|
114
|
+
const breakpointWidth = breakpointWidths[breakpoint];
|
115
|
+
|
116
|
+
if (width <= breakpointWidth) {
|
117
|
+
setIsBreakpointOpen(true);
|
118
|
+
} else {
|
119
|
+
setIsBreakpointOpen(false);
|
120
|
+
}
|
121
|
+
};
|
122
|
+
|
123
|
+
window.addEventListener('resize', handleResize);
|
124
|
+
|
125
|
+
// Call handler once on mount to set initial state
|
126
|
+
handleResize();
|
127
|
+
|
128
|
+
return () => {
|
129
|
+
window.removeEventListener('resize', handleResize);
|
130
|
+
};
|
131
|
+
}, [breakpoint]);
|
132
|
+
|
133
|
+
const modalIsOpened = trigger ? triggerOpened : (opened || isBreakpointOpen);
|
134
|
+
|
135
|
+
useEffect(() => {
|
136
|
+
const sizeMap: Record<DrawerProps['size'], string> = {
|
137
|
+
xl: '365px',
|
138
|
+
lg: '300px',
|
139
|
+
md: '250px',
|
140
|
+
sm: '200px',
|
141
|
+
xs: '64px',
|
142
|
+
};
|
143
|
+
const body = document.querySelector('body');
|
144
|
+
|
145
|
+
if (modalIsOpened && behavior === 'push' && body) {
|
146
|
+
if (placement === 'left') {
|
147
|
+
body.style.cssText = `margin-left: ${sizeMap[size]} !important; margin-right: '' !important;`;
|
148
|
+
} else if (placement === 'right') {
|
149
|
+
body.style.cssText = `margin-right: ${sizeMap[size]} !important; margin-left: '' !important;`;
|
150
|
+
}
|
151
|
+
|
152
|
+
body.classList.add('ReactModal__Body--open');
|
153
|
+
} else if (body) {
|
154
|
+
body.style.cssText = ''; // Clear the styles when modal is closed or behavior is not 'push'
|
155
|
+
body.classList.remove('ReactModal__Body--open');
|
156
|
+
}
|
157
|
+
}, [modalIsOpened, behavior, placement, size]);
|
158
|
+
|
159
|
+
const api = {
|
160
|
+
onClose: trigger
|
161
|
+
? function () {
|
162
|
+
setTriggerOpened(false);
|
163
|
+
}
|
164
|
+
: onClose,
|
165
|
+
};
|
166
|
+
|
167
|
+
return (
|
168
|
+
<DialogContext.Provider value={api}>
|
169
|
+
<div
|
170
|
+
{...ariaProps}
|
171
|
+
{...dataProps}
|
172
|
+
{...htmlProps}
|
173
|
+
className={classes}
|
174
|
+
>
|
175
|
+
<Modal
|
176
|
+
ariaHideApp={false}
|
177
|
+
className={drawerClassNames}
|
178
|
+
closeTimeoutMS={200}
|
179
|
+
contentLabel="Minimal Modal Example"
|
180
|
+
id={id}
|
181
|
+
isOpen={modalIsOpened}
|
182
|
+
onRequestClose={onClose}
|
183
|
+
overlayClassName={overlayClassNames}
|
184
|
+
shouldCloseOnOverlayClick={overlay}
|
185
|
+
>
|
186
|
+
<>
|
187
|
+
{children}
|
188
|
+
</>
|
189
|
+
</Modal>
|
190
|
+
</div>
|
191
|
+
</DialogContext.Provider>
|
192
|
+
);
|
193
|
+
};
|
194
|
+
|
195
|
+
export default Drawer;
|