Skip to content

Commit

Permalink
Feat(web): Introduce Drawer component #DS-1580
Browse files Browse the repository at this point in the history
  • Loading branch information
curdaj committed Jan 7, 2025
1 parent 756e96b commit 078743d
Show file tree
Hide file tree
Showing 11 changed files with 311 additions and 0 deletions.
99 changes: 99 additions & 0 deletions packages/web/src/scss/components/Drawer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# Drawer

The Drawer component is a container that slides in from side of the screen. It can be used to display additional content or actions that are not part of the main view.

The Drawer is a composition of several subcomponents:

- [Drawer](#drawer)
- [DrawerCloseButton](#drawer-close-button)
- [DrawerPanel](#drawer-panel)

👉 The animation effect of this component is dependent on the
`prefers-reduced-motion` media query.

## Drawer

```html
<dialog id="my-drawer-dialog" class="Drawer Drawer--right">
<!-- Drawer close button and Drawer panel goes here -->
</dialog>
```

### Alignment

The `Drawer` component can be aligned to the left or right side of the screen using `--left` or `--right` modifier. By default, the drawer is aligned to the right.

```html
<dialog id="my-drawer-dialog" class="Drawer Drawer--left">
<!-- Drawer close button and Drawer panel goes here -->
</dialog>
```

## DrawerCloseButton

The `DrawerCloseButton` component is a button that closes the drawer when clicked.

```html
<button
type="button"
class="Button Button--tertiary Button--medium Button--symmetrical DrawerCloseButton"
data-spirit-dismiss="offcanvas"
data-spirit-target="#my-drawer-dialog"
aria-controls="my-drawer-dialog"
aria-expanded="false"
>
<svg viewBox="0 0 24 24" fill="none" width="24" height="24" aria-hidden="true">
<path
d="M18.3 5.70997C17.91 5.31997 17.28 5.31997 16.89 5.70997L12 10.59L7.11 5.69997C6.72 5.30997 6.09 5.30997 5.7
5.69997C5.31 6.08997 5.31 6.71997 5.7 7.10997L10.59 12L5.7 16.89C5.31 17.28 5.31 17.91 5.7 18.3C6.09 18.69 6.72 18.69
7.11 18.3L12 13.41L16.89 18.3C17.28 18.69 17.91 18.69 18.3 18.3C18.69 17.91 18.69 17.28 18.3 16.89L13.41 12L18.3
7.10997C18.68 6.72997 18.68 6.08997 18.3 5.70997Z"
fill="currentColor"
></path>
</svg>
<span class="accessibility-hidden">Close</span>
</button>
```

## DrawerPanel

The `DrawerPanel` component is a container for the content that will be displayed in the drawer.

```html
<div class="DrawerPanel">
<div class="DrawerPanel__content">
<!-- Drawer content goes here -->
</div>
</div>
```

## Full implementation

```html
<dialog id="my-drawer-dialog" class="Drawer Drawer--right">
<button
type="button"
aria-expanded="false"
class="Button Button--tertiary Button--medium Button--symmetrical DrawerCloseButton"
data-spirit-dismiss="offcanvas"
data-spirit-target="#drawer-example-1"
aria-controls="drawer-example-1"
>
<svg viewBox="0 0 24 24" fill="none" width="24" height="24" aria-hidden="true">
<path
d="M18.3 5.70997C17.91 5.31997 17.28 5.31997 16.89 5.70997L12 10.59L7.11 5.69997C6.72 5.30997 6.09 5.30997 5.7
5.69997C5.31 6.08997 5.31 6.71997 5.7 7.10997L10.59 12L5.7 16.89C5.31 17.28 5.31 17.91 5.7 18.3C6.09 18.69 6.72 18.69
7.11 18.3L12 13.41L16.89 18.3C17.28 18.69 17.91 18.69 18.3 18.3C18.69 17.91 18.69 17.28 18.3 16.89L13.41 12L18.3
7.10997C18.68 6.72997 18.68 6.08997 18.3 5.70997Z"
fill="currentColor"
></path>
</svg>
<span class="accessibility-hidden">Close</span>
</button>
<div class="DrawerPanel">
<div class="DrawerPanel__content">
<!-- Drawer content goes here -->
</div>
</div>
</dialog>
```
40 changes: 40 additions & 0 deletions packages/web/src/scss/components/Drawer/_Drawer.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
@use '../../tools/typography';
@use 'theme';

.Drawer {
@include typography.generate(theme.$drawer-typography);

all: unset;
position: fixed;
inset: 0;
z-index: 1;
display: flex;
width: 100%;
max-width: none;
height: 100%;
max-height: none;
border: none;
background-color: theme.$drawer-backdrop-background-color;
visibility: hidden;

&::backdrop {
background-color: transparent;
}

@media (prefers-reduced-motion: no-preference) {
transition-property: visibility, opacity;
transition-duration: theme.$drawer-transition-duration;
}
}

.Drawer--left {
justify-content: start;
}

.Drawer--right {
justify-content: end;
}

.Drawer[open] {
visibility: visible;
}
11 changes: 11 additions & 0 deletions packages/web/src/scss/components/Drawer/_DrawerCloseButton.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
@use '../../tools/accessibility';
@use '../../tools/reset';
@use 'theme';

.DrawerCloseButton {
@include accessibility.min-tap-target(theme.$drawer-close-button-size);

align-self: flex-end;
margin-inline-end: theme.$drawer-close-button-padding-x;
margin-block-start: theme.$drawer-close-button-padding-y;
}
43 changes: 43 additions & 0 deletions packages/web/src/scss/components/Drawer/_DrawerPanel.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
@use 'sass:map';
@use 'theme';

.DrawerPanel {
--drawer-translate-x: 0%;

display: flex;
flex-direction: column;
box-sizing: border-box;
width: theme.$drawer-panel-width;
height: theme.$drawer-panel-height;
max-height: theme.$drawer-panel-max-height;
color: theme.$drawer-panel-text-color;
background-color: theme.$drawer-panel-background-color;
box-shadow: theme.$drawer-panel-shadow;
transform: translateX(var(--drawer-translate-x));

@media (prefers-reduced-motion: no-preference) {
transition-property: transform;
transition-duration: theme.$drawer-transition-duration;
transition-timing-function: theme.$drawer-transition-timing;
}
}

.Drawer--left .DrawerPanel {
--drawer-translate-x: -100%;
}

.Drawer--right .DrawerPanel {
--drawer-translate-x: 100%;
}

.Drawer[open] .DrawerPanel {
--drawer-translate-x: 0%;
}

.DrawerPanel__content {
display: flex;
flex-grow: 1;
flex-direction: column;
overflow-y: auto;
overscroll-behavior: contain;
}
22 changes: 22 additions & 0 deletions packages/web/src/scss/components/Drawer/_theme.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
@use '@tokens' as tokens;
@use '../../settings/transitions';

$drawer-typography: tokens.$body-medium-semibold;

// Transition
$drawer-transition-duration: transitions.$duration-200;
$drawer-transition-timing: transitions.$timing-eased-in-out;
$drawer-backdrop-background-color: tokens.$background-backdrop;

// DrawerPanel
$drawer-panel-width: 288px;
$drawer-panel-height: auto;
$drawer-panel-max-height: none;
$drawer-panel-text-color: tokens.$text-primary;
$drawer-panel-background-color: tokens.$background-primary;
$drawer-panel-shadow: tokens.$shadow-400;

// DrawerCloseButton
$drawer-close-button-size: tokens.$space-1200;
$drawer-close-button-padding-x: tokens.$space-900;
$drawer-close-button-padding-y: tokens.$space-700;
92 changes: 92 additions & 0 deletions packages/web/src/scss/components/Drawer/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
{{#> web/layout/default title="Drawer" parentPageName="Components" }}

<script>
document.addEventListener("DOMContentLoaded", () => {
const radios = document.querySelectorAll('input[name="drawer-alignment"]');
const drawer = document.getElementById("drawer-example-1");

radios.forEach(radio => {
radio.addEventListener("change", () => {
if (radio.checked) {
if (radio.value === "left") {
drawer.classList.remove("Drawer--right");
drawer.classList.add("Drawer--left");
} else if (radio.value === "right") {
drawer.classList.remove("Drawer--left");
drawer.classList.add("Drawer--right");
}
}
});
});
});
</script>

<section class="UNSTABLE_Section">

<div class="Container">
<h2 class="docs-Heading">Drawer</h2>

<div class="docs-Stack docs-Stack--start">

<form class="mb-600">
<div>Drawer alignment:</div>
<label for="drawer-alignment-left" class="Radio mr-600">
<input name="drawer-alignment" autocomplete="off" aria-describedby="drawer-alignment-left__helperText" type="radio" id="drawer-alignment-left" class="Radio__input" value="left">
<span class="Radio__text">
<span class="Radio__label">
Left
</span>
</span>
</label>
<label for="drawer-alignment-right" class="Radio mr-600">
<input name="drawer-alignment" autocomplete="off" aria-describedby="drawer-alignment-right__helperText" type="radio" id="drawer-alignment-right" class="Radio__input" value="right" checked>
<span class="Radio__text">
<span class="Radio__label">
Right
</span>
</span>
</label>
</form>
<button
type="button"
data-test-id="drawer-basic"
class="Button Button--primary Button--medium"
data-spirit-toggle="offcanvas"
data-spirit-target="#drawer-example-1"
aria-controls="drawer-example-1"
aria-expanded="false"
>
Open Drawer
</button>

<!-- Drawer: start -->
<dialog id="drawer-example-1" class="Drawer Drawer--right" aria-labelledby="example-basic__title">
<div class="DrawerPanel">
<div class="DrawerPanel__content">
<button
type="button"
aria-expanded="false"
class="Button Button--tertiary Button--medium Button--symmetrical DrawerCloseButton"
data-spirit-dismiss="offcanvas"
data-spirit-target="#drawer-example-1"
aria-controls="drawer-example-1">
<svg viewBox="0 0 24 24" fill="none" width="24" height="24" aria-hidden="true">
<path d="M18.3 5.70997C17.91 5.31997 17.28 5.31997 16.89 5.70997L12 10.59L7.11 5.69997C6.72 5.30997 6.09 5.30997 5.7
5.69997C5.31 6.08997 5.31 6.71997 5.7 7.10997L10.59 12L5.7 16.89C5.31 17.28 5.31 17.91 5.7 18.3C6.09 18.69 6.72 18.69
7.11 18.3L12 13.41L16.89 18.3C17.28 18.69 17.91 18.69 18.3 18.3C18.69 17.91 18.69 17.28 18.3 16.89L13.41 12L18.3
7.10997C18.68 6.72997 18.68 6.08997 18.3 5.70997Z" fill="currentColor">
</path>
</svg>
<span class="accessibility-hidden">Close</span>
</button>
<div class="p-800">Drawer content</div>
</div>
</div>
</dialog>
<!-- Drawer: end -->

</div>
</div>
</section>

{{/web/layout/default }}
3 changes: 3 additions & 0 deletions packages/web/src/scss/components/Drawer/index.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@forward 'Drawer';
@forward 'DrawerPanel';
@forward 'DrawerCloseButton';
1 change: 1 addition & 0 deletions packages/web/src/scss/components/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
@forward 'Collapse';
@forward 'Container';
@forward 'Divider';
@forward 'Drawer';
@forward 'Dropdown';
@forward 'FieldGroup';
@forward 'FileUploader';
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 078743d

Please sign in to comment.