Skip to content

Commit 719b3eb

Browse files
committed
feat: drawer component
Still experimental
1 parent 9a4b71b commit 719b3eb

File tree

16 files changed

+884
-0
lines changed

16 files changed

+884
-0
lines changed

components/drawer/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<!-- @license CC0-1.0 -->
2+
3+
# Drawer component

components/drawer/css/_mixin.scss

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/**
2+
* @license EUPL-1.2
3+
* Copyright (c) 2021 Robbert Broersma
4+
*/
5+
6+
@import "../../backdrop/css/mixin";
7+
8+
@mixin utrecht-drawer {
9+
/* minimum size for backdrop with light-dismiss is 44px x 44px to meet WCAG SC 2.5.5 */
10+
--_utrecht-drawer-backdrop-min-size: max(var(--utrecht-drawer-backdrop-min-size), 44px);
11+
12+
background-color: var(--utrecht-drawer-background-color, Canvas);
13+
border-color: var(--utrecht-drawer-border-color, currentColor);
14+
border-width: var(--utrecht-drawer-border-width, 0);
15+
box-sizing: border-box;
16+
color: var(--utrecht-drawer-color, CanvasText);
17+
overflow: auto;
18+
padding-block-end: var(--utrecht-drawer-padding-block-end);
19+
padding-block-start: var(--utrecht-drawer-padding-block-start);
20+
padding-inline-end: var(--utrecht-drawer-padding-inline-end);
21+
padding-inline-start: var(--utrecht-drawer-padding-inline-start);
22+
position: fixed;
23+
z-index: var(--utrecht-drawer-z-index, 1);
24+
}
25+
26+
@mixin utrecht-drawer--html-dialog {
27+
margin-block-start: 0;
28+
}
29+
30+
@mixin utrecht-drawer__backdrop {
31+
@include utrecht-backdrop;
32+
}
33+
34+
@mixin utrecht-drawer--inline {
35+
block-size: 100%;
36+
inset-block-end: 0;
37+
inset-block-start: 0;
38+
max-block-size: 100%;
39+
max-inline-size: min(
40+
var(--utrecht-drawer-max-inline-size, 100%),
41+
calc(100% - var(--_utrecht-drawer-backdrop-min-size, 44px))
42+
);
43+
min-inline-size: var(--utrecht-drawer-min-inline-size, calc((1280px / 4) - var(--_utrecht-drawer-backdrop-min-size)));
44+
}
45+
46+
@mixin utrecht-drawer--inline-start {
47+
@include utrecht-drawer--inline;
48+
49+
border-end-end-radius: var(--utrecht-drawer-border-radius);
50+
border-inline-start-width: 0;
51+
border-start-end-radius: var(--utrecht-drawer-border-radius);
52+
inset-inline-end: auto;
53+
inset-inline-start: 0;
54+
}
55+
56+
@mixin utrecht-drawer--inline-end {
57+
@include utrecht-drawer--inline;
58+
59+
border-end-start-radius: var(--utrecht-drawer-border-radius);
60+
border-inline-end-width: 0;
61+
border-start-start-radius: var(--utrecht-drawer-border-radius);
62+
inset-inline-end: 0;
63+
inset-inline-start: auto;
64+
}
65+
66+
@mixin utrecht-drawer--block {
67+
block-size: fit-content;
68+
inline-size: 100%;
69+
inset-inline-end: 0;
70+
inset-inline-start: 0;
71+
max-block-size: min(var(--utrecht-drawer-max-block-size), calc(100% - var(--_utrecht-drawer-backdrop-min-size)));
72+
max-inline-size: 100%;
73+
min-block-size: var(--utrecht-drawer-min-block-size, calc((1024px / 4) - var(--_utrecht-drawer-backdrop-min-size)));
74+
}
75+
76+
@mixin utrecht-drawer--block-start {
77+
@include utrecht-drawer--block;
78+
79+
border-block-start-width: 0;
80+
border-end-end-radius: var(--utrecht-drawer-border-radius);
81+
border-end-start-radius: var(--utrecht-drawer-border-radius);
82+
inset-block-end: auto;
83+
inset-block-start: 0;
84+
}
85+
86+
@mixin utrecht-drawer--block-end {
87+
@include utrecht-drawer--block;
88+
89+
border-block-end-width: 0;
90+
border-start-end-radius: var(--utrecht-drawer-border-radius);
91+
border-start-start-radius: var(--utrecht-drawer-border-radius);
92+
inset-block-end: 0;
93+
inset-block-start: auto;
94+
}

components/drawer/css/index.scss

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/**
2+
* @license EUPL-1.2
3+
* Copyright (c) 2021 Robbert Broersma
4+
*/
5+
6+
@import "./mixin";
7+
8+
.utrecht-drawer {
9+
@include utrecht-drawer;
10+
}
11+
12+
.utrecht-drawer::backdrop {
13+
@include utrecht-drawer__backdrop;
14+
}
15+
16+
.utrecht-drawer--inline-start {
17+
@include utrecht-drawer--inline-start;
18+
}
19+
20+
.utrecht-drawer--inline-end {
21+
@include utrecht-drawer--inline-end;
22+
}
23+
24+
.utrecht-drawer--block-start {
25+
@include utrecht-drawer--block-start;
26+
}
27+
28+
.utrecht-drawer--block-end {
29+
@include utrecht-drawer--block-end;
30+
}

components/drawer/tokens.json

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
{
2+
"utrecht": {
3+
"drawer": {
4+
"background-color": {
5+
"$extensions": {
6+
"nl.nldesignsystem.css.property": {
7+
"syntax": "<color>",
8+
"inherits": true
9+
}
10+
}
11+
},
12+
"border-color": {
13+
"$extensions": {
14+
"nl.nldesignsystem.css.property": {
15+
"syntax": "<color>",
16+
"inherits": true
17+
}
18+
}
19+
},
20+
"border-radius": {
21+
"$extensions": {
22+
"nl.nldesignsystem.css.property": {
23+
"syntax": "<length>",
24+
"inherits": true
25+
}
26+
}
27+
},
28+
"border-width": {
29+
"$extensions": {
30+
"nl.nldesignsystem.css.property": {
31+
"syntax": "<length>",
32+
"inherits": true
33+
}
34+
}
35+
},
36+
"color": {
37+
"$extensions": {
38+
"nl.nldesignsystem.css.property": {
39+
"syntax": "<color>",
40+
"inherits": true
41+
}
42+
}
43+
},
44+
"max-block-size": {
45+
"$extensions": {
46+
"nl.nldesignsystem.css.property": {
47+
"syntax": "<length>",
48+
"inherits": true
49+
}
50+
}
51+
},
52+
"min-block-size": {
53+
"$extensions": {
54+
"nl.nldesignsystem.css.property": {
55+
"syntax": "<length>",
56+
"inherits": true
57+
}
58+
}
59+
},
60+
"max-inline-size": {
61+
"$extensions": {
62+
"nl.nldesignsystem.css.property": {
63+
"syntax": "<length>",
64+
"inherits": true
65+
}
66+
}
67+
},
68+
"min-inline-size": {
69+
"$extensions": {
70+
"nl.nldesignsystem.css.property": {
71+
"syntax": "<length>",
72+
"inherits": true
73+
}
74+
}
75+
},
76+
"padding-block-end": {
77+
"$extensions": {
78+
"nl.nldesignsystem.css.property": {
79+
"syntax": "<length>",
80+
"inherits": true
81+
}
82+
}
83+
},
84+
"padding-block-start": {
85+
"$extensions": {
86+
"nl.nldesignsystem.css.property": {
87+
"syntax": "<length>",
88+
"inherits": true
89+
}
90+
}
91+
},
92+
"padding-inline-start": {
93+
"$extensions": {
94+
"nl.nldesignsystem.css.property": {
95+
"syntax": "<length>",
96+
"inherits": true
97+
}
98+
}
99+
},
100+
"padding-inline-end": {
101+
"$extensions": {
102+
"nl.nldesignsystem.css.property": {
103+
"syntax": "<length>",
104+
"inherits": true
105+
}
106+
}
107+
},
108+
"z-index": {
109+
"$extensions": {
110+
"nl.nldesignsystem.css.property": {
111+
"syntax": "<number>",
112+
"inherits": true
113+
}
114+
}
115+
},
116+
"backdrop": {
117+
"min-size": {
118+
"$extensions": {
119+
"nl.nldesignsystem.css.property": {
120+
"syntax": "<length>",
121+
"inherits": true
122+
}
123+
}
124+
}
125+
}
126+
}
127+
}
128+
}

components/index.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
@import "./data-list/css";
4343
@import "./digid-button/css";
4444
@import "./document/css";
45+
@import "./drawer/css";
4546
@import "./emphasis/css";
4647
@import "./figure/css";
4748
@import "./form/css";
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/**
2+
* @license EUPL-1.2
3+
* Copyright (c) 2021 Robbert Broersma
4+
*/
5+
6+
import clsx from 'clsx';
7+
import {
8+
DialogHTMLAttributes,
9+
ForwardedRef,
10+
forwardRef,
11+
PropsWithChildren,
12+
useEffect,
13+
useImperativeHandle,
14+
useRef,
15+
} from 'react';
16+
17+
export type DrawerAlignType = 'block-end' | 'block-start' | 'inline-end' | 'inline-start';
18+
19+
export interface DrawerProps extends DialogHTMLAttributes<HTMLDialogElement> {
20+
align?: string | DrawerAlignType;
21+
modal?: boolean;
22+
}
23+
24+
export const Drawer = forwardRef(
25+
(
26+
{ align, children, className, modal, ...restProps }: PropsWithChildren<DrawerProps>,
27+
ref: ForwardedRef<HTMLDialogElement>,
28+
) => {
29+
let dialogRef = useRef<HTMLDialogElement>(null);
30+
31+
useImperativeHandle(ref, () => dialogRef.current as HTMLDialogElement);
32+
33+
useEffect(() => {
34+
if (modal && restProps.open && dialogRef?.current) {
35+
// Dialog must not be `open` initially, prevent the following error:
36+
// "Cannot call showModal() on an open non-modal dialog"
37+
dialogRef.current.close();
38+
dialogRef.current.showModal();
39+
}
40+
});
41+
42+
return (
43+
<dialog
44+
{...restProps}
45+
ref={dialogRef}
46+
className={clsx('utrecht-drawer', {
47+
'utrecht-drawer--block-end': align === 'block-end',
48+
'utrecht-drawer--block-start': align === 'block-start',
49+
'utrecht-drawer--inline-end': align === 'inline-end',
50+
'utrecht-drawer--inline-start': align === 'inline-start' || !align,
51+
className,
52+
})}
53+
>
54+
{children}
55+
</dialog>
56+
);
57+
},
58+
);
59+
60+
Drawer.displayName = 'Drawer';
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/**
2+
* @license EUPL-1.2
3+
* Copyright (c) 2021 Robbert Broersma
4+
*/
5+
6+
import '../../../../components/drawer/css/index.scss';
7+
8+
export * from '../Drawer';

packages/component-library-react/src/css-module/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ export type {
4949
} from '../DataList';
5050
export { DataList, DataListItem, DataListActions, DataListKey, DataListValue } from './DataList';
5151
export type { EmphasisProps } from '../Emphasis';
52+
export type { DrawerAlignType, DrawerProps } from './Drawer';
53+
export { Drawer } from './Drawer';
5254
export { Emphasis } from './Emphasis';
5355
export type { FieldsetProps } from '../Fieldset';
5456
export { Fieldset } from './Fieldset';

packages/component-library-react/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ export type {
5555
DataListValueProps,
5656
} from './DataList';
5757
export { DataList, DataListItem, DataListActions, DataListKey, DataListValue } from './DataList';
58+
export type { DrawerAlignType, DrawerProps } from './Drawer';
59+
export { Drawer } from './Drawer';
5860
export type { EmphasisProps } from './Emphasis';
5961
export { Emphasis } from './Emphasis';
6062
export type { FieldsetProps } from './Fieldset';

0 commit comments

Comments
 (0)