winduum 2.2.28 → 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.
Files changed (40) hide show
  1. package/package.json +7 -4
  2. package/src/base/reset.css +4 -0
  3. package/src/common.js +9 -1
  4. package/src/components/carousel/content.css +1 -0
  5. package/src/components/carousel/index.js +58 -192
  6. package/src/components/details/default.css +14 -0
  7. package/src/components/details/index.css +1 -0
  8. package/src/components/dialog/content.css +8 -2
  9. package/src/components/dialog/default.css +16 -2
  10. package/src/components/dialog/drawer.css +20 -0
  11. package/src/components/dialog/index.css +1 -0
  12. package/src/components/dialog/index.js +5 -80
  13. package/src/components/dialog/readme.md +1 -5
  14. package/src/components/drawer/content.css +2 -1
  15. package/src/components/drawer/default.css +13 -31
  16. package/src/components/drawer/index.css +3 -0
  17. package/src/components/drawer/index.js +68 -50
  18. package/src/components/drawer/keyframes/default.css +9 -0
  19. package/src/components/drawer/noscript.css +32 -0
  20. package/src/components/drawer/nosnap.css +32 -0
  21. package/src/components/drawer/props/content.css +2 -2
  22. package/src/components/drawer/props/default.css +6 -0
  23. package/src/components/drawer/scroller.css +32 -0
  24. package/src/components/index.css +1 -0
  25. package/src/components/popover/content.css +5 -94
  26. package/src/components/popover/default.css +15 -2
  27. package/src/components/popover/index.css +1 -0
  28. package/src/components/popover/index.d.ts +14 -18
  29. package/src/components/popover/index.js +40 -80
  30. package/src/components/popover/props/content.css +1 -2
  31. package/src/components/popover/props/default.css +4 -0
  32. package/src/components/popover/readme.md +1 -2
  33. package/src/components/tooltip/default.css +8 -8
  34. package/src/supports.js +10 -0
  35. package/tailwindcss/utilities/index.css +1 -0
  36. package/tailwindcss/utilities/position.css +179 -0
  37. package/types/index.d.ts +15 -46
  38. package/src/components/details/index.d.ts +0 -9
  39. package/src/components/details/index.js +0 -78
  40. package/src/components/dialog/index.d.ts +0 -13
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "winduum",
3
- "version": "2.2.28",
3
+ "version": "3.0.0-next.2",
4
4
  "type": "module",
5
5
  "types": "types/index.d.ts",
6
6
  "main": "plugin/index.cjs",
@@ -25,11 +25,13 @@
25
25
  "@stylistic/stylelint-config": "^5.0.0",
26
26
  "@tailwindcss/vite": "^4.3.0",
27
27
  "@vitejs/plugin-vue": "^6.0.7",
28
+ "@webreflection/custom-elements-builtin": "^0.4.1",
28
29
  "autoprefixer": "^10.5.0",
29
30
  "dts-buddy": "^0.8.0",
30
- "eslint": "^10.4.0",
31
+ "eslint": "^10.4.1",
31
32
  "fast-glob": "^3.3.3",
32
33
  "globals": "^17.6.0",
34
+ "invokers-polyfill": "^1.0.3",
33
35
  "postcss": "^8.5.15",
34
36
  "postcss-custom-media": "^12.0.1",
35
37
  "postcss-import": "^16.1.1",
@@ -39,8 +41,9 @@
39
41
  "stylelint-config-standard": "^40.0.0",
40
42
  "tailwindcss": "^4.3.0",
41
43
  "typescript": "^6",
42
- "vite": "^8.0.14",
43
- "vue": "^3.5.34"
44
+ "vite": "^8.0.16",
45
+ "vue": "^3.5.35",
46
+ "webuum": "^0.1.0"
44
47
  },
45
48
  "files": [
46
49
  "index.js",
@@ -48,6 +48,10 @@
48
48
  display: revert;
49
49
  }
50
50
 
51
+ :where([popover]) {
52
+ position-anchor: auto;
53
+ }
54
+
51
55
  /* Revert table vertical-align */
52
56
  :where(tr, th, td),
53
57
  :where(thead, tbody, tfoot) {
package/src/common.js CHANGED
@@ -8,4 +8,12 @@ export const nextRepaint = () => {
8
8
  })
9
9
  }
10
10
 
11
- export const animationsFinished = async element => Promise.all(element.getAnimations().map(animation => animation.finished))
11
+ export const animationsFinished = async (element) => {
12
+ const animations = element?.getAnimations?.() || []
13
+ const results = await Promise.allSettled(animations.map(a => a.finished))
14
+
15
+ return results.filter(r => r.status === 'fulfilled').map(r => r.value)
16
+ }
17
+
18
+ export const supportsAnchor = CSS.supports('anchor-name', '--')
19
+ export const supportsAnchoredContainer = CSS.supports('container-type: anchored')
@@ -15,6 +15,7 @@
15
15
  & > :where(*) {
16
16
  flex: 0 0 auto;
17
17
  scroll-snap-align: start;
18
+ scroll-snap-stop: always;
18
19
 
19
20
  &:last-child {
20
21
  scroll-snap-align: end;
@@ -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
  }
@@ -0,0 +1,14 @@
1
+ .x-details {
2
+ &::details-content {
3
+ transition:
4
+ height var(--default-transition-duration) var(--default-transition-timing-function),
5
+ content-visibility var(--default-transition-duration) var(--default-transition-timing-function) allow-discrete;
6
+ height: 0;
7
+ overflow: clip;
8
+ interpolate-size: allow-keywords;
9
+ }
10
+
11
+ &[open]::details-content {
12
+ height: auto;
13
+ }
14
+ }
@@ -0,0 +1 @@
1
+ @import "./default.css";
@@ -3,10 +3,16 @@
3
3
  border-radius: var(--x-dialog-content-border-radius, var(--radius-3xl));
4
4
  padding: var(--x-dialog-content-padding-block) var(--x-dialog-content-padding-inline);
5
5
  inline-size: min(100%, var(--x-dialog-content-inline-size));
6
- transition: var(--transition-transform), var(--transition-opacity);
6
+ transition: var(--transition-transform), var(--transition-opacity) allow-discrete, var(--transition-display) allow-discrete;
7
7
  margin: auto;
8
+ pointer-events: auto;
8
9
 
9
- :where(dialog[data-closed]) & {
10
+ @starting-style {
11
+ transform: translateY(-2rem);
12
+ opacity: 0%;
13
+ }
14
+
15
+ :where(dialog:not([open])) & {
10
16
  transform: translateY(-2rem);
11
17
  opacity: 0%;
12
18
  }
@@ -7,21 +7,35 @@
7
7
  var(--x-dialog-background-color) var(--x-dialog-background-color-opacity),
8
8
  var(--x-dialog-background-color-mix, transparent)
9
9
  );
10
- transition: var(--transition-background);
10
+ transition: var(--transition-background) allow-discrete, var(--transition-display) allow-discrete, var(--transition-overlay) allow-discrete;
11
11
  display: flex;
12
12
  position: fixed;
13
13
  inset: 0;
14
14
  overflow: auto;
15
15
  overscroll-behavior: contain;
16
16
  -webkit-overflow-scrolling: touch;
17
+ scrollbar-gutter: stable;
18
+
19
+ @starting-style {
20
+ background-color: transparent;
21
+ }
17
22
 
18
23
  &::backdrop,
19
24
  &:not([open]) {
20
25
  display: none;
21
26
  }
22
27
 
23
- &[data-closed] {
28
+ &:not([open]) {
24
29
  background-color: transparent;
30
+
31
+ html:not(:has(.x-dialog[open])) & {
32
+ scrollbar-gutter: auto;
33
+ scrollbar-width: none;
34
+
35
+ &::-webkit-scrollbar {
36
+ display: none;
37
+ }
38
+ }
25
39
  }
26
40
  }
27
41
 
@@ -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,82 +1,7 @@
1
- import { animationsFinished, nextRepaint } from '../../common.js'
1
+ document.documentElement.addEventListener('click', ({ target }) => {
2
+ const closedBy = target?.getAttribute('closedby')
2
3
 
3
- /**
4
- * @type {import("./").DefaultOptions}
5
- */
6
- export const defaultOptions = {
7
- closedAttribute: 'data-closed',
8
- openAttribute: 'data-open',
9
- scrollbarWidthProperty: '--default-scrollbar-width',
10
- contentSelector: '.x-dialog-content',
11
- closable: true,
12
- modal: true,
13
- }
14
-
15
- /**
16
- * Shows a dialog.
17
- * @param {HTMLDialogElement | HTMLElement} element - The dialog element to show.
18
- * @param {import("./").DefaultOptions} options - The options for showing the dialog.
19
- * @returns Promise<void>
20
- */
21
- export const showDialog = async (element, options = {}) => {
22
- options = {
23
- ...defaultOptions,
24
- ...options,
25
- }
26
-
27
- if (options.scrollbarWidthProperty) {
28
- document.documentElement.style.setProperty(options.scrollbarWidthProperty, `${window.innerWidth - document.body.clientWidth}px`)
29
- }
30
-
31
- if (!element?._dialogHasEvents) {
32
- element.addEventListener('cancel', (e) => {
33
- e.preventDefault()
34
- options.closable && closeDialog(element, options)
35
- })
36
-
37
- element.addEventListener('click', ({ target }) => {
38
- if (target.nodeName === 'DIALOG' && options.closable) {
39
- closeDialog(element, options)
40
- }
41
- })
42
-
43
- element._dialogHasEvents = true
4
+ if (target?.matches('dialog[open]') && !document.activeElement.matches('input,textarea') && closedBy && closedBy !== 'none') {
5
+ target?.close()
44
6
  }
45
-
46
- element.setAttribute(options.closedAttribute, '')
47
-
48
- options.modal ? element.showModal() : element.show()
49
- element.scroll(0, 0)
50
-
51
- element.removeAttribute(options.closedAttribute)
52
- await animationsFinished(element.querySelector(options.contentSelector))
53
- element.setAttribute(options.openAttribute, '')
54
-
55
- element.dispatchEvent(new CustomEvent('x-dialog:show'))
56
- }
57
-
58
- /**
59
- * Closes and dismisses a dialog.
60
- * @param {HTMLDialogElement | HTMLElement} element - The dialog element to dismiss.
61
- * @param {import("./").DefaultOptions} options - The options for closing the dialog.
62
- * @returns Promise<void>
63
- */
64
- export const closeDialog = async (element, options = {}) => {
65
- options = {
66
- ...defaultOptions,
67
- ...options,
68
- }
69
-
70
- element.dispatchEvent(new CustomEvent('x-dialog:close'))
71
-
72
- element.removeAttribute(options.openAttribute)
73
- element.setAttribute(options.closedAttribute, '')
74
-
75
- await animationsFinished(element.querySelector(options.contentSelector))
76
-
77
- element.close()
78
-
79
- await nextRepaint()
80
-
81
- options.remove && element.remove()
82
- }
7
+ })
@@ -29,12 +29,8 @@ You can also copy and paste the code from this directory to your project and rem
29
29
  @import "@/components/dialog/assets/index.css" layer(components);
30
30
  ```
31
31
 
32
- ```js
33
- import { showDialog } from '@/components/dialog/assets/index.js'
34
- ```
35
-
36
32
  ### Docs
37
- Visit [docs](https://winduum.dev/docs/components/dialog.html) to learn more about Javascript API and see usage examples.
33
+ Visit [docs](https://winduum.dev/docs/components/dialog.html) to learn more about usage examples.
38
34
 
39
35
  ### Frameworks
40
36
  * [winduum/winduum-vue](https://github.com/winduum/winduum-vue/blob/main/src/components/dialog)
@@ -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";