winduum 3.0.0-next.1 → 3.0.0-next.2

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.
@@ -1,227 +1,93 @@
1
1
  /**
2
- * @param {HTMLElement | Element} element
3
- * @param {number} index
4
- * @returns void
5
- */
6
- export const scrollTo = (element, index = 0) => {
7
- const scrollPaddingLeft = parseInt(getComputedStyle(element).scrollPaddingLeft)
8
-
9
- element.scroll({ left: element?.children[index]?.offsetLeft - (isNaN(scrollPaddingLeft) ? 0 : scrollPaddingLeft) })
10
- }
11
-
12
- /**
13
- * @param {HTMLElement | Element & { _activeIndex: number }} element
2
+ * @param {HTMLElement} element
3
+ * @param {object} options
4
+ * @param {number} [options.direction=1]
5
+ * @param {number} [options.distance]
6
+ * @param {'left' | 'top'} [options.position='left']
7
+ * @param {number} [options.ratio=0.85]
14
8
  * @returns void
15
9
  */
16
- export const scrollPrev = (element) => {
17
- scrollTo(element, element._activeIndex - 1)
18
- }
19
-
20
- /**
21
- * @param {HTMLElement | Element & { _activeIndex: number }} element
22
- * @returns void
23
- */
24
- export const scrollNext = (element) => {
25
- scrollTo(element, element._activeIndex + 1)
26
- }
27
-
28
- /**
29
- * @param {HTMLElement | Element} element
30
- * @param {number} scrollWidth
31
- * @param {boolean} mathFloor
32
- * @returns number
33
- */
34
- export const getItemCount = (element, scrollWidth = element.scrollWidth - element.clientWidth, mathFloor = false) => {
35
- const gap = parseInt(getComputedStyle(element).rowGap)
36
- const mathRound = (value, floor) => floor ? Math.floor(value) : Math.ceil(value)
37
-
38
- return [...element.children].reduce((count, children) => {
39
- if (mathRound(scrollWidth / (children.offsetWidth + (isNaN(gap) ? 0 : gap)), mathFloor) > count) {
40
- return count + 1
41
- }
42
- else {
43
- return count
44
- }
45
- }, 0) + 1
46
- }
47
-
48
- /**
49
- * @param {HTMLElement | Element} element
50
- * @param {import("./").ObserveCarouselOptions} options
51
- * @returns IntersectionObserver
52
- */
53
- export const observeCarousel = (element, options = {}) => {
54
- options = {
55
- visibleAttribute: 'data-visible',
56
- observerOptions: {},
57
- ...options,
58
- }
59
-
60
- element._observer = new IntersectionObserver((entries) => {
61
- entries.forEach((entry) => {
62
- entry.target.toggleAttribute(options.visibleAttribute, entry.isIntersecting)
63
- })
64
-
65
- const activeElement = [...element.children].find(children => children.hasAttribute(options.visibleAttribute))
66
-
67
- if (activeElement) {
68
- element._activeIndex = [...element.children].indexOf(activeElement)
69
- }
70
- }, {
71
- root: element,
72
- threshold: 0.75,
73
- ...options.observerOptions,
10
+ export const scrollBy = (element, { direction = 1, distance, position = 'left', ratio = 0.85 }) => {
11
+ element.scrollBy({
12
+ [position]: (distance ?? element.clientWidth * ratio) * direction,
74
13
  })
75
-
76
- ;[...element.children].forEach(children => element._observer.observe(children))
77
-
78
- return element._observer
79
14
  }
80
15
 
81
16
  /**
82
- * @param {HTMLElement | Element} element
83
- * @param {import("./").ScrollCarouselOptions} options
17
+ * @param {HTMLElement} element
18
+ * @param {object} options
19
+ * @param {HTMLButtonElement | null} [options.prevElement]
20
+ * @param {HTMLButtonElement | null} [options.nextElement]
21
+ * @param {boolean} [options.scrollStart]
22
+ * @param {boolean} [options.scrollEnd]
23
+ * @param {boolean} [options.scrollNone]
84
24
  * @returns void
85
25
  */
86
- export const scrollCarousel = (element, options = {}) => {
87
- options.pagination = {
88
- activeAttribute: 'data-active',
89
- ...options.pagination,
90
- }
91
-
92
- const activeItem = getItemCount(element, element.scrollLeft, element.scrollLeft < element._lastScrollLeft)
93
- const activeItemMax = getItemCount(element)
26
+ export const toggleScrollState = (element, { prevElement, nextElement, scrollStart, scrollEnd, scrollNone }) => {
27
+ scrollStart ??= element.scrollLeft <= 0
28
+ scrollEnd ??= element.scrollLeft >= element.scrollWidth - element.clientWidth
29
+ scrollNone ??= !(element.scrollWidth - element.clientWidth)
94
30
 
95
- if (options?.pagination?.element) {
96
- ;[...options.pagination.element.children].forEach(children => children.removeAttribute(options.pagination.activeAttribute))
31
+ if (prevElement) prevElement.disabled = scrollStart
32
+ if (nextElement) nextElement.disabled = scrollEnd
97
33
 
98
- options.pagination.element.children[activeItem - 1]?.setAttribute(options.pagination.activeAttribute, '')
99
- }
100
-
101
- if (options.progressElement) {
102
- options.progressElement.value = activeItem / activeItemMax * 100
103
- }
104
-
105
- if (options.counterMinElement) {
106
- options.counterMinElement.innerHTML = `${activeItem}`
107
- }
108
-
109
- if (options.counterMaxElement) {
110
- options.counterMaxElement.innerHTML = `${activeItemMax}`
111
- }
112
-
113
- element._lastScrollLeft = element.scrollLeft <= 0 ? 0 : element.scrollLeft
34
+ element.toggleAttribute('data-scroll-start', scrollStart)
35
+ element.toggleAttribute('data-scroll-end', scrollEnd)
36
+ element.toggleAttribute('data-scroll-none', scrollNone)
114
37
  }
115
38
 
116
39
  /**
117
- * @param {HTMLElement | Element} element
118
- * @param {import("./").PaginationCarouselOptions} options
40
+ * @param {HTMLElement} element
41
+ * @param {number} index
42
+ * @param {string} [attributeName='data-current']
119
43
  * @returns void
120
44
  */
121
- export const paginationCarousel = (element, options = {}) => {
122
- options = {
123
- itemContent: '<div aria-hidden="true"></div>',
124
- activeAttribute: 'data-active',
125
- ...options,
126
- }
127
-
128
- if (!options.element) return
129
-
130
- options.element.insertAdjacentHTML('beforeend', [...Array(getItemCount(element))].map(
131
- () => options.itemContent,
132
- ).join(''))
133
-
134
- ;[...options.element.children].forEach((children, i) => {
135
- (i === 0) && children.setAttribute(options.activeAttribute, '')
136
- children.addEventListener('click', ({ currentTarget }) => {
137
- scrollTo(element, [...options.element.children].indexOf(currentTarget))
138
- })
139
- })
45
+ export const setCurrentAttribute = (element, index, attributeName = 'aria-current') => {
46
+ element.querySelector(`[${attributeName}]`)?.removeAttribute(attributeName)
47
+ element.children[index].setAttribute(attributeName, 'true')
140
48
  }
141
49
 
142
50
  /**
143
- * @param {HTMLElement | Element} element
144
- * @param {import("./").AutoplayCarouselOptions} options
51
+ * @param {HTMLElement & { _markerIndex?: number | null }} element
52
+ * @param {HTMLElement} target
53
+ * @param {HTMLElement | null} markerGroupElement
145
54
  * @returns void
146
55
  */
147
- export const autoplayCarousel = (element, options = {}) => {
148
- options = {
149
- delay: 4000,
150
- pauseElements: [],
151
- ...options,
152
- }
56
+ export const setSnappedAttribute = (element, target, markerGroupElement) => {
57
+ const snappedIndex = [...element.children].indexOf(target)
153
58
 
154
- let paused
59
+ setCurrentAttribute(element, snappedIndex, 'data-snapped')
155
60
 
156
- options.pauseElements.forEach((element) => {
157
- element?.addEventListener('mouseenter', () => (paused = true))
158
- element?.addEventListener('mouseleave', () => (paused = false))
159
- })
61
+ if (markerGroupElement) {
62
+ const markerTarget = markerGroupElement.querySelector(`[href="#${target.id}"]`)
63
+ const index = element._markerIndex ?? (markerTarget && [...markerGroupElement.children].indexOf(markerTarget)) ?? snappedIndex
160
64
 
161
- setInterval(() => {
162
- if (paused) return
65
+ setCurrentAttribute(markerGroupElement, index)
163
66
 
164
- if (element.scrollLeft < element.scrollWidth - element.clientWidth) {
165
- scrollNext(element)
166
- }
167
- else {
168
- scrollTo(element, 0)
169
- }
170
- }, options.delay)
67
+ element._markerIndex = null
68
+ }
171
69
  }
172
70
 
173
71
  /**
174
- * @param {HTMLElement | Element & { _activeIndex: number }} element
175
- * @param {import("./").DragCarouselOptions} options
72
+ * @param {HTMLElement & { _markerIndex?: number | null }} element
73
+ * @param {HTMLElement | HTMLLinkElement} target
74
+ * @param {HTMLElement} markerGroupElement
75
+ * @param {ScrollIntoViewOptions} scrollIntoViewOptions
176
76
  * @returns void
177
77
  */
178
- export const dragCarousel = (element, options = {}) => {
179
- options = {
180
- activeAttribute: 'data-grabbing',
181
- ...options,
182
- }
183
-
184
- if (!matchMedia('(hover: hover) and (pointer: fine)').matches) {
185
- return
186
- }
187
-
188
- let isDown
189
- let startX
190
- let scrollLeft
191
- let timeout
192
-
193
- const endGrabbing = () => {
194
- isDown = false
195
- element.removeAttribute(options.activeAttribute)
196
-
197
- scrollTo(element, element._activeIndex)
198
-
199
- clearTimeout(timeout)
200
-
201
- timeout = setTimeout(() => {
202
- element.style.scrollSnapType = ''
203
- }, 300)
204
- }
205
-
206
- element.addEventListener('mouseleave', endGrabbing)
207
-
208
- element.addEventListener('mouseup', endGrabbing)
209
-
210
- element.addEventListener('mousedown', ({ pageX }) => {
211
- isDown = true
212
- startX = pageX - element.offsetLeft
213
- scrollLeft = element.scrollLeft
214
- })
78
+ export const scrollToMarker = (element, target, markerGroupElement, scrollIntoViewOptions = {}) => {
79
+ const snappedTarget = document.getElementById(target.getAttribute('href').slice(1))
80
+ const markerTargetIndex = [...markerGroupElement.children].indexOf(target)
81
+ const index = snappedTarget ? [...element.children].indexOf(snappedTarget) : markerTargetIndex
215
82
 
216
- element.addEventListener('mousemove', (e) => {
217
- if (!isDown) return
218
- e.preventDefault()
83
+ element._markerIndex = markerTargetIndex
219
84
 
220
- const x = e.pageX - element.offsetLeft
85
+ setCurrentAttribute(markerGroupElement, markerTargetIndex)
221
86
 
222
- element.setAttribute(options.activeAttribute, '')
223
- element.style.scrollSnapType = 'unset'
224
- element.scroll({ left: scrollLeft - ((x - startX) * 1.25), behavior: 'instant' })
225
- element.ondragstart = e => e.preventDefault()
87
+ element.children[index]?.scrollIntoView({
88
+ inline: 'start',
89
+ block: 'nearest',
90
+ container: 'nearest',
91
+ ...scrollIntoViewOptions,
226
92
  })
227
93
  }
@@ -6,7 +6,6 @@
6
6
  transition: var(--transition-transform), var(--transition-opacity) allow-discrete, var(--transition-display) allow-discrete;
7
7
  margin: auto;
8
8
  pointer-events: auto;
9
- height: 200vh;
10
9
 
11
10
  @starting-style {
12
11
  transform: translateY(-2rem);
@@ -0,0 +1,20 @@
1
+ .x-dialog {
2
+ &:is(.drawer) {
3
+ timeline-scope: --x-drawer-backdrop;
4
+ animation: x-drawer-backdrop-opacity linear both;
5
+ animation-timeline: --x-drawer-backdrop;
6
+
7
+ &::backdrop {
8
+ background-color:
9
+ color-mix(
10
+ in var(--x-drawer-background-color-space, srgb),
11
+ var(--color-dark) calc(var(--x-drawer-backdrop-opacity, 0) * var(--x-drawer-background-color-opacity)),
12
+ var(--x-drawer-background-color-mix, transparent)
13
+ );
14
+
15
+ @supports not (animation-timeline: --x) {
16
+ --x-drawer-backdrop-opacity: 1;
17
+ }
18
+ }
19
+ }
20
+ }
@@ -2,3 +2,4 @@
2
2
  @import "./props/content.css";
3
3
  @import "./default.css";
4
4
  @import "./content.css";
5
+ @import "./drawer.css";
@@ -1,7 +1,8 @@
1
1
  .x-drawer-content {
2
+ background-color: var(--x-drawer-content-background-color);
3
+ padding: var(--x-drawer-content-padding-block) var(--x-drawer-content-padding-inline);
2
4
  inline-size: var(--x-drawer-content-inline-size);
3
5
  block-size: var(--x-drawer-content-block-size);
4
- background-color: var(--x-drawer-content-background-color);
5
6
  flex-shrink: 0;
6
7
  scroll-snap-align: end;
7
8
  }
@@ -1,40 +1,22 @@
1
1
  .x-drawer {
2
- z-index: var(--x-drawer-z-index, var(--z-index-30));
3
- background-color:
4
- color-mix(
5
- in var(--x-drawer-background-color-space, srgb),
6
- var(--color-dark) calc(var(--background-color-opacity, 0) * var(--x-drawer-background-color-opacity)),
7
- var(--x-drawer-background-color-mix, transparent)
8
- );
9
2
  position: fixed;
10
3
  inset: 0;
11
- display: flex;
12
- overflow: auto hidden;
13
- scrollbar-width: none;
14
- scroll-behavior: smooth;
15
- -webkit-overflow-scrolling: touch;
16
- overscroll-behavior: contain;
4
+ width: 100dvw;
5
+ height: 100dvh;
6
+ timeline-scope: --x-drawer-backdrop;
7
+ animation: x-drawer-backdrop-opacity linear both;
8
+ animation-timeline: --x-drawer-backdrop;
17
9
 
18
- &:not([open]),
19
10
  &::backdrop {
20
- display: none;
21
- }
22
-
23
- &::-webkit-scrollbar {
24
- display: none;
25
- }
26
-
27
- &::after {
28
- content: "";
29
- min-inline-size: 100vw;
30
- scroll-snap-align: end;
31
- }
32
-
33
- &.flex-col {
34
- overflow: hidden auto;
11
+ background-color:
12
+ color-mix(
13
+ in var(--x-drawer-background-color-space, srgb),
14
+ var(--color-dark) calc(var(--x-drawer-backdrop-opacity, 0) * var(--x-drawer-background-color-opacity)),
15
+ var(--x-drawer-background-color-mix, transparent)
16
+ );
35
17
 
36
- &::after {
37
- min-block-size: 100dvh;
18
+ @supports not (animation-timeline: --x) {
19
+ --x-drawer-backdrop-opacity: 1;
38
20
  }
39
21
  }
40
22
  }
@@ -1,4 +1,7 @@
1
1
  @import "./props/default.css";
2
2
  @import "./props/content.css";
3
+ @import "./keyframes/default.css";
3
4
  @import "./default.css";
4
5
  @import "./content.css";
6
+ @import "./scroller.css";
7
+ @import "./noscript.css";
@@ -1,85 +1,103 @@
1
- import { nextRepaint } from '../../common.js'
1
+ import { supportsScrollInitialTarget } from '/src/supports.js'
2
+ import { nextRepaint } from '/src/common.js'
2
3
 
3
4
  /**
4
- * @param {HTMLElement | Element} element
5
- * @param {number} distance
6
- * @param {'top' | 'left'} direction
7
- * @returns void
5
+ * @param {'left' | 'right' | 'top' | 'bottom'} placement
6
+ * @returns boolean
8
7
  */
9
- export const showDrawer = async (element, distance = 0, direction = 'left') => {
10
- element.scroll({ [direction]: distance })
8
+ export const isVerticalDrawer = (placement) => {
9
+ return ['top', 'bottom'].includes(placement)
11
10
  }
12
11
 
13
12
  /**
14
13
  * @param {HTMLElement | Element} element
15
- * @param {number} distance
16
- * @param {'top' | 'left'} direction
14
+ * @param {'left' | 'right' | 'top' | 'bottom'} placement
15
+ * @param {boolean} reverse
16
+ * @param {'auto' | 'instant'} behavior
17
17
  * @returns void
18
18
  */
19
- export const closeDrawer = (element, distance = element.scrollWidth, direction = 'left') => {
20
- element.scroll({ [direction]: distance })
19
+ export const scrollDrawer = (element, placement, reverse = false, behavior = 'auto') => {
20
+ const [direction, distance, closedDistance] = drawerProperties(element, placement)
21
+
22
+ element.scroll({ [direction]: reverse ? closedDistance : distance, behavior })
21
23
  }
22
24
 
23
25
  /**
24
26
  * @param {HTMLElement | Element} element
25
- * @param {number} distance
26
- * @param {'top' | 'left'} direction
27
+ * @param {'left' | 'right' | 'top' | 'bottom'} placement
27
28
  * @returns void
28
29
  */
29
- export const scrollInitDrawer = async (element, distance = element.scrollWidth, direction = 'left') => {
30
- element.scroll({ [direction]: distance, behavior: 'instant' })
31
- await nextRepaint()
30
+ export const showDrawer = async (element, placement) => {
31
+ if (!supportsScrollInitialTarget) {
32
+ scrollDrawer(element, placement, true, 'instant')
33
+ await nextRepaint()
34
+ }
35
+
36
+ scrollDrawer(element, placement)
32
37
  }
33
38
 
34
39
  /**
35
40
  * @param {HTMLElement | Element} element
36
- * @param {'open' | 'close'} state
37
- * @param {string} snapClass
41
+ * @param {'left' | 'right' | 'top' | 'bottom'} placement
38
42
  * @returns void
39
43
  */
40
- export const toggleDrawerAttributes = (element, state = 'open', snapClass) => {
41
- element.classList[state === 'open' ? 'add' : 'remove'](...snapClass.split(/\s/))
42
- element.inert = state === 'close'
43
- element.dispatchEvent(new CustomEvent(`x-drawer:${state}`))
44
+ export const closeDrawer = (element, placement) => {
45
+ scrollDrawer(element, placement, true)
44
46
  }
45
47
 
46
48
  /**
47
- * @param {number} scrollState
48
- * @param {number} scrollDirection
49
- * @returns boolean
49
+ * @param {HTMLElement | Element} element
50
+ * @param {HTMLElement | Element} contentElement
51
+ * @param {AbortSignal} signal
52
+ * @param {'left' | 'right' | 'top' | 'bottom'} placement
53
+ * @returns void
50
54
  */
51
- export const scrollDrawerState = (scrollState, scrollDirection) => {
52
- return scrollState ? Math.ceil(scrollDirection) >= scrollState : Math.floor(scrollDirection) <= scrollState
55
+ export const drawerEvents = (element, contentElement, placement, signal) => {
56
+ element.addEventListener('cancel', (event) => {
57
+ const scroller = element.firstElementChild
58
+
59
+ if (scroller.scrollHeight > 0 || scroller.scrollWidth > 0) event.preventDefault()
60
+
61
+ closeDrawer(scroller, placement)
62
+ }, { signal })
63
+
64
+ element.addEventListener('click', ({ target }) => {
65
+ if (!contentElement.contains(target) && !contentElement.isEqualNode(target))
66
+ closeDrawer(element.firstElementChild, placement)
67
+ }, { signal })
53
68
  }
54
69
 
55
70
  /**
56
71
  * @param {HTMLDialogElement | Element} element
57
- * @param {import("./").ScrollDrawerOptions} options
58
- * @returns void
72
+ * @param {'left' | 'right' | 'top' | 'bottom'} placement
73
+ * @returns IntersectionObserver
59
74
  */
60
- export const scrollDrawer = (element, options = {}) => {
61
- options = {
62
- snapClass: 'snap-x snap-mandatory',
63
- opacityProperty: '--background-color-opacity',
64
- opacityRatio: 1,
65
- scrollOpen: 0,
66
- scrollClose: element.scrollWidth - element.clientWidth,
67
- scrollSize: element.scrollWidth - element.clientWidth,
68
- scrollDirection: element.scrollLeft,
69
- ...options,
70
- }
75
+ export const drawerObserver = (element, placement) => {
76
+ const visibleThreshold = 1 / (
77
+ isVerticalDrawer(placement) ? window.innerHeight : window.innerWidth
78
+ )
71
79
 
72
- element.style.setProperty(
73
- options.opacityProperty,
74
- `${Math.min(Math.abs((options.scrollDirection / options.scrollSize) - options.opacityRatio), 1)}`,
80
+ return new IntersectionObserver((entries) => {
81
+ if (entries.at(-1).intersectionRatio < visibleThreshold) element.close()
82
+ }, {
83
+ root: element,
84
+ threshold: [visibleThreshold, 1],
85
+ },
75
86
  )
87
+ }
76
88
 
77
- if (scrollDrawerState(options.scrollOpen, options.scrollDirection)) {
78
- toggleDrawerAttributes(element, 'open', options.snapClass)
79
- }
89
+ /**
90
+ * @param {HTMLElement | Element} element
91
+ * @param {'left' | 'right' | 'top' | 'bottom'} placement
92
+ * @returns {['top' | 'left', number, number]}
93
+ */
94
+ export const drawerProperties = (element, placement) => {
95
+ const [openedDistance, closedDistance] = {
96
+ left: [0, element.offsetWidth],
97
+ right: [element.offsetWidth, 0],
98
+ top: [0, element.offsetHeight],
99
+ bottom: [element.offsetHeight, 0],
100
+ }[placement]
80
101
 
81
- if (scrollDrawerState(options.scrollClose, options.scrollDirection) && !element.inert) {
82
- toggleDrawerAttributes(element, 'close', options.snapClass)
83
- element.close && element.close()
84
- }
102
+ return [isVerticalDrawer(placement) ? 'top' : 'left', openedDistance, closedDistance]
85
103
  }
@@ -0,0 +1,9 @@
1
+ @keyframes x-drawer-backdrop-opacity {
2
+ 0% {
3
+ --x-drawer-backdrop-opacity: 1;
4
+ }
5
+
6
+ 100% {
7
+ --x-drawer-backdrop-opacity: 0;
8
+ }
9
+ }
@@ -0,0 +1,32 @@
1
+ .x-drawer {
2
+ @media (scripting: none) {
3
+ --x-drawer-backdrop-opacity: 1;
4
+
5
+ width: fit-content;
6
+ height: fit-content;
7
+ transition-property: var(--default-transition-property);
8
+ transition-timing-function: var(--ease-in-out);
9
+ transition-duration: var(--default-transition-duration);
10
+ transition-behavior: allow-discrete;
11
+
12
+ &::backdrop {
13
+ transition: inherit;
14
+ }
15
+
16
+ &:not([open]) {
17
+ &::backdrop {
18
+ opacity: 0%;
19
+ }
20
+ }
21
+
22
+ @starting-style {
23
+ &[open] {
24
+ opacity: 0%;
25
+
26
+ &::backdrop {
27
+ opacity: 0%;
28
+ }
29
+ }
30
+ }
31
+ }
32
+ }
@@ -0,0 +1,32 @@
1
+ .x-drawer {
2
+ &:is(.no-snap) {
3
+ --x-drawer-backdrop-opacity: 1;
4
+
5
+ width: fit-content;
6
+ height: fit-content;
7
+ transition-property: var(--default-transition-property);
8
+ transition-timing-function: var(--ease-in-out);
9
+ transition-duration: var(--default-transition-duration);
10
+ transition-behavior: allow-discrete;
11
+
12
+ &::backdrop {
13
+ transition: inherit;
14
+ }
15
+
16
+ &:not([open]) {
17
+ &::backdrop {
18
+ opacity: 0%;
19
+ }
20
+ }
21
+
22
+ @starting-style {
23
+ &[open] {
24
+ opacity: 0%;
25
+
26
+ &::backdrop {
27
+ opacity: 0%;
28
+ }
29
+ }
30
+ }
31
+ }
32
+ }
@@ -3,6 +3,6 @@
3
3
  --x-drawer-content-background-color: var(--color-body-primary);
4
4
  --x-drawer-content-padding-block: 2rem;
5
5
  --x-drawer-content-padding-inline: 1.5rem;
6
- --x-drawer-content-inline-size: 100%;
7
- --x-drawer-content-block-size: 100%;
6
+ --x-drawer-content-inline-size: 50dvw;
7
+ --x-drawer-content-block-size: 100dvh;
8
8
  }
@@ -2,3 +2,9 @@
2
2
  :host {
3
3
  --x-drawer-background-color-opacity: 75%;
4
4
  }
5
+
6
+ @property --x-drawer-backdrop-opacity {
7
+ syntax: "<number>";
8
+ inherits: true;
9
+ initial-value: 0;
10
+ }