Drawer
Provides a scroll drawer that uses native HTML5 dialog
and CSS scroll-snap
property.
Can be dismissed with touch gestures on touch devices.
Usage
@import "winduum/src/components/drawer/index.css" layer(components);
<button class="x-button" id="showDrawerLeftElement">Show drawer</button>
<dialog class="x-drawer" id="drawerLeftElement" inert>
<nav class="x-drawer-content">
Drawer content
<button class="x-button muted" id="closeDrawerLeftElement">Close drawer</button>
</nav>
</dialog>
<script type="module">
import { showDrawer, closeDrawer, scrollDrawer, scrollInitDrawer } from "winduum/src/components/drawer"
drawerLeftElement.addEventListener('scroll', ({ target }) => scrollDrawer(target))
showDrawerLeftElement.addEventListener('click', async () => {
drawerLeftElement.showModal()
await scrollInitDrawer(drawerLeftElement)
showDrawer(drawerLeftElement)
})
closeDrawerLeftElement.addEventListener('click', () => {
closeDrawer(drawerLeftElement, drawerLeftElement.scrollWidth)
})
</script>
Variants
Props
Installation
Follow instructions for individual framework usage below
Examples
Left
<button class="x-button" id="showDrawerLeftElement">Show drawer</button>
<dialog class="x-drawer" id="drawerLeftElement" inert>
<nav class="x-drawer-content">
Drawer content
<button class="x-button muted" id="closeDrawerLeftElement">Close drawer</button>
</nav>
</dialog>
<script type="module">
import { showDrawer, closeDrawer, scrollDrawer, scrollInitDrawer } from "winduum/src/components/drawer"
drawerLeftElement.addEventListener('scroll', ({ target }) => scrollDrawer(target))
showDrawerLeftElement.addEventListener('click', async () => {
drawerLeftElement.showModal()
await scrollInitDrawer(drawerLeftElement)
showDrawer(drawerLeftElement)
})
closeDrawerLeftElement.addEventListener('click', () => {
closeDrawer(drawerLeftElement, drawerLeftElement.scrollWidth)
})
</script>
Right
<button class="x-button" id="showDrawerRightElement">Show drawer</button>
<dialog class="x-drawer after:-order-last" id="drawerRightElement" inert>
<nav class="x-drawer-content">
Drawer content
<button class="x-button muted" id="closeDrawerRightElement">Close drawer</button>
</nav>
</dialog>
<script type="module">
import { showDrawer, closeDrawer, scrollDrawer, scrollInitDrawer } from "winduum/src/components/drawer"
drawerRightElement.addEventListener('scroll', ({ target }) => scrollDrawer(target, {
scrollOpen: target.scrollWidth - target.clientWidth,
scrollClose: 0,
opacityRatio: 0
}))
showDrawerRightElement.addEventListener('click', async () => {
drawerRightElement.showModal()
await scrollInitDrawer(drawerRightElement, 0)
showDrawer(drawerRightElement, drawerRightElement.scrollWidth)
})
closeDrawerRightElement.addEventListener('click', () => closeDrawer(drawerRightElement, 0))
</script>
Bottom
<button class="x-button" id="showDrawerBottomElement">Show drawer</button>
<dialog class="x-drawer flex flex-col after:-order-last" id="drawerBottomElement" inert>
<nav class="x-drawer-content" style="--x-drawer-content-width: 100%;--x-drawer-content-height: calc(100vh - 4rem);">
Drawer content
<button class="x-button muted" id="closeDrawerBottomElement">Close drawer</button>
</nav>
</dialog>
<script type="module">
import { showDrawer, closeDrawer, scrollDrawer, scrollInitDrawer } from "winduum/src/components/drawer"
drawerBottomElement.addEventListener('scroll', ({ target }) => scrollDrawer(target, {
snapClass: 'snap-y snap-mandatory',
scrollSize: target.scrollHeight - target.clientHeight,
scrollDirection: target.scrollTop,
scrollOpen: target.scrollHeight - target.clientHeight,
scrollClose: 0,
opacityRatio: 0
}))
showDrawerBottomElement.addEventListener('click', async () => {
drawerBottomElement.showModal()
await scrollInitDrawer(drawerBottomElement, 0, 'top')
showDrawer(drawerBottomElement, drawerBottomElement.scrollHeight, 'top')
})
closeDrawerBottomElement.addEventListener('click', () => closeDrawer(drawerBottomElement, 0, 'top'))
</script>
Top
<button class="x-button" id="showDrawerTopElement">Show drawer</button>
<dialog class="x-drawer flex flex-col" id="drawerTopElement" inert>
<nav class="x-drawer-content" style="--x-drawer-content-width: 100%;--x-drawer-content-height: calc(100vh - 4rem);">
Drawer content
<button class="x-button muted" id="closeDrawerTopElement">Close drawer</button>
</nav>
</dialog>
<script type="module">
import { showDrawer, closeDrawer, scrollDrawer, scrollInitDrawer } from "winduum/src/components/drawer"
drawerTopElement.addEventListener('scroll', ({ target }) => scrollDrawer(target, {
snapClass: 'snap-y snap-mandatory',
scrollSize: target.scrollHeight - target.clientHeight,
scrollDirection: target.scrollTop,
scrollOpen: 0,
scrollClose: target.scrollHeight - target.clientHeight
}))
showDrawerTopElement.addEventListener('click', async () => {
drawerTopElement.showModal()
await scrollInitDrawer(drawerTopElement, drawerTopElement?.scrollHeight, 'top')
showDrawer(drawerTopElement, 0, 'top')
})
closeDrawerTopElement.addEventListener('click', () => closeDrawer(drawerTopElement, drawerTopElement.scrollHeight, 'top'))
</script>
Javascript API
showDrawer
- Type:
(element: HTMLElement | Element, distance: number, direction: 'left' | 'top') => void
- Kind:
sync
Scroll the drawer to open state.
closeDrawer
- Type:
(element: HTMLElement | Element, distance: number, direction: 'left' | 'top') => void
- Kind:
sync
Scroll the drawer to closed state.
scrollInitDrawer
- Type:
(element: HTMLElement | Element, distance?: number, direction?: 'left' | 'top') => void
- Kind:
sync
Initializes the scroll position. Call this before showDrawer
method.
scrollDrawer
- Type:
(element: HTMLElement | Element, options: ScrollDrawerOptions) => void
- Kind:
sync
Sets correct classes and attributes upon scroll. Events c-drawer:open
and c-drawer:close
are dispatched upon opening or closing the drawer.
ScrollDrawerOptions
snapClass
- Type:
string
- Default:
snap-x snap-mandatory
A classes that are added for snapping purposes once the drawer is open.
opacityProperty
- Type:
string
- Default:
--tw-bg-opacity
A CSS property for animating the background opacity upon scroll.
opacityRatio
- Type:
number
- Default:
1
You can either set 1
or 0
depending on the direction the drawer is opened. Right and bottom drawer should be set to 0
.
scrollOpen
- Type:
number
- Default:
0
Scroll position indicating that the drawer is opened.
scrollClose
- Type:
number
- Default:
element.scrollWidth - element.clientWidth
Scroll position indicating that the drawer is closed.
scrollSize
- Type:
number
- Default:
element.scrollWidth - element.clientWidth
Maximum scroll size of the drawer.
scrollDirection
- Type:
number
- Default:
element.scrollLeft
Current scroll position of the drawer.