winduum 2.2.21 → 3.0.0-next.1

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "winduum",
3
- "version": "2.2.21",
3
+ "version": "3.0.0-next.1",
4
4
  "type": "module",
5
5
  "types": "types/index.d.ts",
6
6
  "main": "plugin/index.cjs",
@@ -30,8 +30,9 @@
30
30
  "eslint": "^10.0.2",
31
31
  "fast-glob": "^3.3.3",
32
32
  "globals": "^17.4.0",
33
- "postcss": "^8.5.8",
34
- "postcss-custom-media": "^12.0.1",
33
+ "invokers-polyfill": "^0.6.1",
34
+ "postcss": "^8.5.6",
35
+ "postcss-custom-media": "^12.0.0",
35
36
  "postcss-import": "^16.1.1",
36
37
  "postcss-nesting": "^14.0.0",
37
38
  "slide-element": "^2.3.1",
@@ -40,7 +41,8 @@
40
41
  "tailwindcss": "^4.2.1",
41
42
  "typescript": "^5",
42
43
  "vite": "^7.3.1",
43
- "vue": "^3.5.29"
44
+ "vue": "^3.5.29",
45
+ "webuum": "^0.1.0"
44
46
  },
45
47
  "files": [
46
48
  "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')
@@ -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,17 @@
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;
9
+ height: 200vh;
8
10
 
9
- :where(dialog[data-closed]) & {
11
+ @starting-style {
12
+ transform: translateY(-2rem);
13
+ opacity: 0%;
14
+ }
15
+
16
+ :where(dialog:not([open])) & {
10
17
  transform: translateY(-2rem);
11
18
  opacity: 0%;
12
19
  }
@@ -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
 
@@ -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)
@@ -3,6 +3,7 @@
3
3
  @import "./check/index.css";
4
4
  @import "./color/index.css";
5
5
  @import "./control/index.css";
6
+ @import "./details/index.css";
6
7
  @import "./group/index.css";
7
8
  @import "./heading/index.css";
8
9
  @import "./image/index.css";
@@ -2,103 +2,14 @@
2
2
  background-color: var(--x-popover-content-background-color);
3
3
  border-radius: var(--x-popover-content-border-radius);
4
4
  padding: var(--x-popover-content-padding-block) var(--x-popover-content-padding-inline);
5
- z-index: var(--x-popover-content-z-index, var(--z-index-10));
6
- transition-property: var(--default-transition-property);
7
- transition-timing-function: var(--ease-in-out);
8
- transition-duration: var(--default-transition-duration);
9
- transform:
10
- translate(var(--tw-translate-x, 0), var(--tw-translate-y, 0))
11
- scaleX(var(--tw-scale-x, 1)) scaleY(var(--tw-scale-y, 1));
5
+ transition: inherit;
12
6
  will-change: transform;
13
- inline-size: max-content;
14
- position: absolute;
15
7
 
16
- &:where(.bottom),
17
- & {
18
- transform-origin: top;
8
+ @starting-style {
9
+ scale: var(--x-popover-content-starting-scale);
19
10
  }
20
11
 
21
- &:where(.bottom-start) {
22
- transform-origin: top left;
23
- }
24
-
25
- &:where(.bottom-end) {
26
- inset-inline-end: 0;
27
- transform-origin: top right;
28
- }
29
-
30
- &:where(.right) {
31
- inset-block-start: 0;
32
- inset-inline-start: 100%;
33
- transform-origin: left;
34
- }
35
-
36
- &:where(.right-start) {
37
- transform-origin: left top;
38
- }
39
-
40
- &:where(.right-end) {
41
- inset-block: auto 0;
42
- transform-origin: left bottom;
43
- }
44
-
45
- &:where(.left) {
46
- inset-block-start: 0;
47
- inset-inline-end: 100%;
48
- transform-origin: right;
49
- }
50
-
51
- &:where(.left-start) {
52
- transform-origin: right top;
53
- }
54
-
55
- &:where(.left-end) {
56
- inset-block: auto 0;
57
- transform-origin: right bottom;
58
- }
59
-
60
- &:where(.top) {
61
- inset-block-end: 100%;
62
- transform-origin: bottom;
63
- }
64
-
65
- &:where(.top-start) {
66
- transform-origin: bottom left;
67
- }
68
-
69
- &:where(.top-end) {
70
- inset-inline-end: 0;
71
- transform-origin: bottom right;
72
- }
73
-
74
- &:where(.inline-center) {
75
- --tw-translate-x: -50%;
76
-
77
- inset-inline-start: 50%;
78
- }
79
-
80
- &:where(.block-center) {
81
- --tw-translate-y: -50%;
82
-
83
- inset-block-start: 50%;
84
- }
85
-
86
- &[popover]:not([data-open]) {
87
- --tw-scale-x: var(--x-popover-content-scale-x);
88
- --tw-scale-y: var(--x-popover-content-scale-y);
89
-
90
- opacity: 0%;
91
- pointer-events: none;
92
- }
93
-
94
- &:not([popover]) {
95
- .trigger-focus:not(:focus, :focus-within) > &,
96
- .trigger-hover:not(:hover) > & {
97
- --tw-scale-x: var(--x-popover-content-scale-x);
98
- --tw-scale-y: var(--x-popover-content-scale-y);
99
-
100
- opacity: 0%;
101
- visibility: hidden;
102
- }
12
+ :where(.x-popover:not(:popover-open)) > & {
13
+ scale: var(--x-popover-content-starting-scale);
103
14
  }
104
15
  }
@@ -1,4 +1,17 @@
1
1
  .x-popover {
2
- position: relative;
3
- display: inline-block;
2
+ transition-property: var(--default-transition-property);
3
+ transition-timing-function: var(--ease-in-out);
4
+ transition-duration: var(--default-transition-duration);
5
+ transition-behavior: allow-discrete;
6
+ position: fixed;
7
+ inset: auto;
8
+ container-type: anchored;
9
+
10
+ @starting-style {
11
+ opacity: var(--x-popover-starting-opacity);
12
+ }
13
+
14
+ &:not(:popover-open) {
15
+ opacity: var(--x-popover-starting-opacity);
16
+ }
4
17
  }
@@ -1,3 +1,4 @@
1
+ @import "./props/default.css";
1
2
  @import "./props/content.css";
2
3
  @import "./default.css";
3
4
  @import "./content.css";
@@ -1,20 +1,16 @@
1
- import { FlipOptions, Middleware, OffsetOptions, Placement, ShiftOptions } from "@floating-ui/dom";
1
+ import type { ComputePositionConfig } from '@floating-ui/dom'
2
+ import type { Placement } from '@floating-ui/utils'
2
3
 
3
- export interface ShowPopoverOptions {
4
- anchorSelector: string,
5
- openAttribute?: string
6
- compute?: boolean
7
- placement?: Placement
8
- middleware?: Array<Middleware | null | undefined | false>
9
- offset?: OffsetOptions
10
- flip?: FlipOptions
11
- shift?: ShiftOptions
12
- }
4
+ export declare function computePositionPopover(
5
+ referenceElement: HTMLElement,
6
+ floatingElement: HTMLElement & { $currentPlacement?: string },
7
+ placement: Placement,
8
+ options?: ComputePositionConfig | boolean
9
+ ): Promise<void>
13
10
 
14
- export interface HidePopoverOptions {
15
- openAttribute?: string
16
- }
17
-
18
- export function showPopover(element: HTMLElement | Element, options?: ShowPopoverOptions): Promise<void>
19
- export function hidePopover(element: HTMLElement | Element): Promise<void>
20
- export function togglePopover(element: HTMLElement | Element, options?: ShowPopoverOptions): Promise<void>
11
+ export declare function autoUpdatePopover(
12
+ referenceElement: HTMLElement,
13
+ floatingElement: HTMLElement,
14
+ placement: Placement,
15
+ options?: ComputePositionConfig | boolean
16
+ ): Promise<() => void>
@@ -1,93 +1,53 @@
1
- import { animationsFinished, nextRepaint } from '../../common.js'
1
+ import { supportsAnchor } from '../../common.js'
2
2
 
3
3
  /**
4
- * @param {HTMLElement | Element} element
5
- * @param {HTMLElement | Element} popoverElement
6
- * @param {import("./").ShowPopoverOptions} options
7
- * @returns Promise<void>
4
+ * @param {HTMLElement} referenceElement
5
+ * @param {HTMLElement & { _currentPlacement?: import('@floating-ui/utils').Placement }} floatingElement
6
+ * @param {import('@floating-ui/utils').Placement} placement
7
+ * @param {import('@floating-ui/dom').ComputePositionConfig | boolean} [options={}]
8
+ * @returns {Promise<void>}
8
9
  */
9
- export const computePopover = async (element, popoverElement, options = {}) => {
10
- const { computePosition, flip, shift, offset } = await import('@floating-ui/dom')
11
-
12
- popoverElement.classList.remove(popoverElement._placement)
13
-
14
- await computePosition(element, popoverElement, {
15
- placement: options?.placement,
16
- middleware: options?.middleware ?? [offset(options?.offset ?? 12), flip(options?.flip), shift({ padding: 8, ...options?.shift })],
10
+ export const computePositionPopover = async (
11
+ referenceElement,
12
+ floatingElement,
13
+ placement,
14
+ options = {},
15
+ ) => {
16
+ const { computePosition, flip } = await import('@floating-ui/dom')
17
+
18
+ const autoUpdate = options === true
19
+ const middleware = autoUpdate ? [flip()] : []
20
+
21
+ floatingElement.classList.remove(floatingElement._currentPlacement ?? placement)
22
+ floatingElement.style.setProperty('--anchor-size', !supportsAnchor ? `${referenceElement.offsetWidth}px` : '')
23
+
24
+ await computePosition(referenceElement, floatingElement, {
25
+ middleware,
26
+ placement,
27
+ ...(autoUpdate ? {} : options),
17
28
  }).then(({ x, y, placement }) => {
18
- Object.assign(popoverElement.style, {
19
- inset: `${y}px auto auto ${x}px`,
20
- })
21
-
22
- popoverElement._placement = placement
23
- popoverElement.classList.add(popoverElement._placement)
29
+ floatingElement.style.inset = !supportsAnchor ? `${y}px auto auto ${x}px` : ''
30
+ floatingElement.classList.add(placement)
31
+ floatingElement._currentPlacement = placement
24
32
  })
25
33
  }
26
34
 
27
35
  /**
28
- * @param {HTMLElement | Element} element - The HTML content to insert into the dialog.
29
- * @param {import("./").HidePopoverOptions} options
30
- * @returns Promise<void>
36
+ * @param {HTMLElement} referenceElement
37
+ * @param {HTMLElement} floatingElement
38
+ * @param {import('@floating-ui/utils').Placement} placement
39
+ * @param {import('@floating-ui/dom').ComputePositionConfig | boolean} [options={}]
40
+ * @returns {Promise<() => void>}
31
41
  */
32
- export const hidePopover = async (element, options = { openAttribute: 'data-open' }) => {
33
- const popoverElement = document.getElementById(element.getAttribute('popovertarget'))
34
-
35
- popoverElement.removeAttribute(options?.openAttribute)
36
- await animationsFinished(popoverElement)
37
- popoverElement._cleanup && popoverElement._cleanup()
38
- popoverElement.hidePopover && popoverElement.hidePopover()
39
-
40
- element.ariaExpanded = 'false'
41
- }
42
-
43
- /**
44
- * @param {HTMLElement | Element} element
45
- * @param {import("./").ShowPopoverOptions} options
46
- * @returns Promise<void>
47
- */
48
- export const showPopover = async (element, options) => {
49
- options = {
50
- openAttribute: 'data-open',
51
- compute: true,
52
- ...options,
53
- }
54
-
42
+ export const autoUpdatePopover = async (
43
+ referenceElement,
44
+ floatingElement,
45
+ placement,
46
+ options = {},
47
+ ) => {
55
48
  const { autoUpdate } = await import('@floating-ui/dom')
56
49
 
57
- const popoverElement = document.getElementById(element.getAttribute('popovertarget'))
58
-
59
- element.ariaExpanded = 'true'
60
-
61
- if (!element.ariaHasPopup) (element.ariaHasPopup = 'dialog')
62
- if (!popoverElement.role) (popoverElement.role = element.ariaHasPopup)
63
-
64
- popoverElement.showPopover && popoverElement.showPopover()
65
-
66
- await nextRepaint()
67
-
68
- popoverElement.setAttribute(options?.openAttribute, '')
69
-
70
- if (!options.compute) {
71
- return
72
- }
73
-
74
- popoverElement._cleanup = autoUpdate(
75
- element,
76
- popoverElement,
77
- async () => await computePopover(options.anchorSelector ? document.querySelector(options.anchorSelector) : element, popoverElement, options),
50
+ return autoUpdate(referenceElement, floatingElement, () =>
51
+ computePositionPopover(referenceElement, floatingElement, placement, options),
78
52
  )
79
53
  }
80
-
81
- /**
82
- * @param {HTMLElement | Element} element
83
- * @param {import("./").ShowPopoverOptions} options
84
- * @returns Promise<void>
85
- */
86
- export const togglePopover = async (element, options) => {
87
- if (element.ariaExpanded !== 'true') {
88
- await showPopover(element, options)
89
- }
90
- else {
91
- await hidePopover(element)
92
- }
93
- }
@@ -4,6 +4,5 @@
4
4
  --x-popover-content-border-radius: var(--radius-xl);
5
5
  --x-popover-content-padding-block: calc(var(--spacing) * 2);
6
6
  --x-popover-content-padding-inline: calc(var(--spacing) * 2);
7
- --x-popover-content-scale-y: 0.75;
8
- --x-popover-content-scale-x: 0.75;
7
+ --x-popover-content-starting-scale: 0.75;
9
8
  }
@@ -0,0 +1,4 @@
1
+ :root,
2
+ :host {
3
+ --x-popover-starting-opacity: 0;
4
+ }
@@ -14,9 +14,8 @@ Include CSS either globally or to your component _([you can't use TailwindCSS la
14
14
  or modular (you can use your own props or CSS)
15
15
 
16
16
  ```css
17
- @import "winduum/src/components/popover/props/content.css" layer(components);
17
+ @import "winduum/src/components/popover/props/default.css" layer(components);
18
18
  @import "winduum/src/components/popover/default.css" layer(components);
19
- @import "winduum/src/components/popover/content.css" layer(components);
20
19
  ```
21
20
 
22
21
  ### Local imports
@@ -26,8 +26,8 @@
26
26
  pointer-events: none;
27
27
  }
28
28
 
29
- &:where(.top),
30
- &:where(.bottom) {
29
+ &:where(.tooltip-top),
30
+ &:where(.tooltip-bottom) {
31
31
  &::before {
32
32
  --tw-translate-x: -50%;
33
33
 
@@ -36,8 +36,8 @@
36
36
  }
37
37
  }
38
38
 
39
- &:where(.left),
40
- &:where(.right) {
39
+ &:where(.tooltip-left),
40
+ &:where(.tooltip-right) {
41
41
  &::before {
42
42
  --tw-translate-y: -50%;
43
43
 
@@ -46,28 +46,28 @@
46
46
  }
47
47
  }
48
48
 
49
- &:where(.bottom) {
49
+ &:where(.tooltip-bottom) {
50
50
  &::before {
51
51
  inset-block-start: 100%;
52
52
  transform-origin: top;
53
53
  }
54
54
  }
55
55
 
56
- &:where(.top) {
56
+ &:where(.tooltip-top) {
57
57
  &::before {
58
58
  inset-block-end: 100%;
59
59
  transform-origin: bottom;
60
60
  }
61
61
  }
62
62
 
63
- &:where(.left) {
63
+ &:where(.tooltip-left) {
64
64
  &::before {
65
65
  inset-inline-end: 100%;
66
66
  transform-origin: right;
67
67
  }
68
68
  }
69
69
 
70
- &:where(.right) {
70
+ &:where(.tooltip-right) {
71
71
  &::before {
72
72
  inset-inline-start: 100%;
73
73
  transform-origin: left;
@@ -5,6 +5,7 @@
5
5
  @import "./dot.css";
6
6
  @import "./grid-cols-container.css";
7
7
  @import "./link.css";
8
+ @import "./position.css";
8
9
  @import "./ripple.css";
9
10
  @import "./skeleton.css";
10
11
  @import "./spinner.css";
@@ -0,0 +1,179 @@
1
+ @utility bottom {
2
+ position-area: block-end center;
3
+ position-try-fallbacks: flip-block;
4
+
5
+ > * {
6
+ transform-origin: top;
7
+ }
8
+
9
+ @container anchored(fallback: flip-block) {
10
+ > * {
11
+ transform-origin: bottom;
12
+ }
13
+ }
14
+ }
15
+
16
+ @utility bottom-start {
17
+ position-area: block-end span-inline-end;
18
+ position-try-fallbacks: flip-block;
19
+
20
+ > * {
21
+ transform-origin: top left;
22
+ }
23
+
24
+ @container anchored(fallback: flip-block) {
25
+ > * {
26
+ transform-origin: bottom left;
27
+ }
28
+ }
29
+ }
30
+
31
+ @utility bottom-end {
32
+ position-area: block-end span-inline-start;
33
+ position-try-fallbacks: flip-block;
34
+
35
+ > * {
36
+ transform-origin: top right;
37
+ }
38
+
39
+ @container anchored(fallback: flip-block) {
40
+ > * {
41
+ transform-origin: bottom right;
42
+ }
43
+ }
44
+ }
45
+
46
+ @utility top {
47
+ position-area: block-start center;
48
+ position-try-fallbacks: flip-block;
49
+
50
+ > * {
51
+ transform-origin: bottom;
52
+ }
53
+
54
+ @container anchored(fallback: flip-block) {
55
+ > * {
56
+ transform-origin: top;
57
+ }
58
+ }
59
+ }
60
+
61
+ @utility top-start {
62
+ position-area: block-start span-inline-end;
63
+ position-try-fallbacks: flip-block;
64
+
65
+ > * {
66
+ transform-origin: bottom left;
67
+ }
68
+
69
+ @container anchored(fallback: flip-block) {
70
+ > * {
71
+ transform-origin: top left;
72
+ }
73
+ }
74
+ }
75
+
76
+ @utility top-end {
77
+ position-area: block-start span-inline-start;
78
+ position-try-fallbacks: flip-block;
79
+
80
+ > * {
81
+ transform-origin: bottom right;
82
+ }
83
+
84
+ @container anchored(fallback: flip-block) {
85
+ > * {
86
+ transform-origin: top right;
87
+ }
88
+ }
89
+ }
90
+
91
+ @utility left {
92
+ position-area: inline-start center;
93
+ position-try-fallbacks: flip-inline;
94
+
95
+ > * {
96
+ transform-origin: right;
97
+ }
98
+
99
+ @container anchored(fallback: flip-block) {
100
+ > * {
101
+ transform-origin: left;
102
+ }
103
+ }
104
+ }
105
+
106
+ @utility left-start {
107
+ position-area: inline-start span-block-end;
108
+ position-try-fallbacks: flip-inline;
109
+
110
+ > * {
111
+ transform-origin: right top;
112
+ }
113
+
114
+ @container anchored(fallback: flip-block) {
115
+ > * {
116
+ transform-origin: left top;
117
+ }
118
+ }
119
+ }
120
+
121
+ @utility left-end {
122
+ position-area: inline-start span-block-start;
123
+ position-try-fallbacks: flip-inline;
124
+
125
+ > * {
126
+ transform-origin: right bottom;
127
+ }
128
+
129
+ @container anchored(fallback: flip-block) {
130
+ > * {
131
+ transform-origin: left bottom;
132
+ }
133
+ }
134
+ }
135
+
136
+ @utility right {
137
+ position-area: inline-end center;
138
+ position-try-fallbacks: flip-inline;
139
+
140
+ > * {
141
+ transform-origin: left;
142
+ }
143
+
144
+ @container anchored(fallback: flip-block) {
145
+ > * {
146
+ transform-origin: right;
147
+ }
148
+ }
149
+ }
150
+
151
+ @utility right-start {
152
+ position-area: inline-end span-block-end;
153
+ position-try-fallbacks: flip-inline;
154
+
155
+ > * {
156
+ transform-origin: left top;
157
+ }
158
+
159
+ @container anchored(fallback: flip-block) {
160
+ > * {
161
+ transform-origin: right top;
162
+ }
163
+ }
164
+ }
165
+
166
+ @utility right-end {
167
+ position-area: inline-end span-block-start;
168
+ position-try-fallbacks: flip-inline;
169
+
170
+ > * {
171
+ transform-origin: left bottom;
172
+ }
173
+
174
+ @container anchored(fallback: flip-block) {
175
+ > * {
176
+ transform-origin: right bottom;
177
+ }
178
+ }
179
+ }
package/types/index.d.ts CHANGED
@@ -85,34 +85,7 @@ declare module 'winduum/src/components/compare' {
85
85
  export {};
86
86
  }
87
87
 
88
- declare module 'winduum/src/components/details' {
89
- export interface DefaultOptions {
90
- selector?: string
91
- summarySelector?: string
92
- }
93
-
94
- export const defaultOptions: DefaultOptions
95
- export function showDetails(selector: HTMLInputElement | HTMLElement, options?: DefaultOptions): Promise<void>
96
- export function closeDetails(selector: HTMLInputElement | HTMLElement, options?: DefaultOptions): Promise<void>
97
- export function toggleDetails(selector: HTMLInputElement | HTMLElement, options?: DefaultOptions): Promise<void>
98
-
99
- export {};
100
- }
101
-
102
88
  declare module 'winduum/src/components/dialog' {
103
- export interface DefaultOptions {
104
- remove?: boolean | null
105
- closable?: boolean | null
106
- modal?: boolean
107
- openAttribute?: string
108
- closedAttribute?: string
109
- contentSelector?: string
110
- scrollbarWidthProperty?: string | null
111
- }
112
-
113
- export const defaultOptions: DefaultOptions
114
- export function showDialog(element: HTMLDialogElement | HTMLElement, options?: DefaultOptions): Promise<void>
115
- export function closeDialog(element: HTMLDialogElement | HTMLElement, options?: DefaultOptions): Promise<void>
116
89
 
117
90
  export {};
118
91
  }
@@ -215,25 +188,21 @@ declare module 'winduum/src/components/toaster' {
215
188
  }
216
189
 
217
190
  declare module 'winduum/src/components/popover' {
218
- import type { FlipOptions, Middleware, OffsetOptions, Placement, ShiftOptions } from '@floating-ui/dom';
219
- export interface ShowPopoverOptions {
220
- anchorSelector: string,
221
- openAttribute?: string
222
- compute?: boolean
223
- placement?: Placement
224
- middleware?: Array<Middleware | null | undefined | false>
225
- offset?: OffsetOptions
226
- flip?: FlipOptions
227
- shift?: ShiftOptions
228
- }
229
-
230
- export interface HidePopoverOptions {
231
- openAttribute?: string
232
- }
233
-
234
- export function showPopover(element: HTMLElement | Element, options?: ShowPopoverOptions): Promise<void>
235
- export function hidePopover(element: HTMLElement | Element): Promise<void>
236
- export function togglePopover(element: HTMLElement | Element, options?: ShowPopoverOptions): Promise<void>
191
+ import type { ComputePositionConfig } from '@floating-ui/dom';
192
+ import type { Placement } from '@floating-ui/utils';
193
+ export function computePositionPopover(
194
+ referenceElement: HTMLElement,
195
+ floatingElement: HTMLElement & { $currentPlacement?: string },
196
+ placement: Placement,
197
+ options?: ComputePositionConfig | boolean
198
+ ): Promise<void>
199
+
200
+ export function autoUpdatePopover(
201
+ referenceElement: HTMLElement,
202
+ floatingElement: HTMLElement,
203
+ placement: Placement,
204
+ options?: ComputePositionConfig | boolean
205
+ ): Promise<() => void>
237
206
 
238
207
  export {};
239
208
  }
@@ -23,13 +23,6 @@
23
23
  "setPosition",
24
24
  "setKeyboardStep",
25
25
  "setMouseStep",
26
- "DefaultOptions",
27
- "defaultOptions",
28
- "showDetails",
29
- "closeDetails",
30
- "toggleDetails",
31
- "showDialog",
32
- "closeDialog",
33
26
  "ScrollDrawerOptions",
34
27
  "showDrawer",
35
28
  "closeDrawer",
@@ -48,11 +41,8 @@
48
41
  "closeToast",
49
42
  "showToast",
50
43
  "closeToaster",
51
- "ShowPopoverOptions",
52
- "HidePopoverOptions",
53
- "showPopover",
54
- "hidePopover",
55
- "togglePopover",
44
+ "computePositionPopover",
45
+ "autoUpdatePopover",
56
46
  "SetTrackPropertyOptions",
57
47
  "SetValueOptions",
58
48
  "SetOutputOptions",
@@ -67,8 +57,6 @@
67
57
  "../plugin/index.d.ts",
68
58
  "../src/components/carousel/index.d.ts",
69
59
  "../src/components/compare/index.d.ts",
70
- "../src/components/details/index.d.ts",
71
- "../src/components/dialog/index.d.ts",
72
60
  "../src/components/drawer/index.d.ts",
73
61
  "../src/components/form/index.d.ts",
74
62
  "../src/components/tabs/index.d.ts",
@@ -91,10 +79,8 @@
91
79
  null,
92
80
  null,
93
81
  null,
94
- null,
95
- null,
96
82
  null
97
83
  ],
98
- "mappings": ";;kBAEiBA,aAAaA;;;;;;;;;;;;;;;;;;;;cAoBjBC,aAAaA;;yBAEFC,YAAYA;;;;;;kBCxBnBC,sBAAsBA;;;;;;;;kBAQtBC,yBAAyBA;;;;;;kBAMzBC,qBAAqBA;;;;;;;;kBAQrBC,uBAAuBA;;;;;kBAKvBC,mBAAmBA;;;;iBAIpBC,UAAUA;iBACVC,UAAUA;iBACVC,QAAQA;iBACRC,YAAYA;iBACZC,eAAeA;iBACfC,cAAcA;iBACdC,kBAAkBA;iBAClBC,gBAAgBA;iBAChBC,YAAYA;;;;;;kBCvCXC,kBAAkBA;;;;;iBAKnBC,WAAWA;iBACXC,eAAeA;iBACfC,YAAYA;;;;;;kBCPXC,cAAcA;;;;;cAKlBC,cAAcA;iBACXC,WAAWA;iBACXC,YAAYA;iBACZC,aAAaA;;;;;;kBCRZJ,cAAcA;;;;;;;;;;cAUlBC,cAAcA;iBACXI,UAAUA;iBACVC,WAAWA;;;;;;kBCZVC,mBAAmBA;;;;;;;;;;iBAUpBC,UAAUA;iBACVC,WAAWA;iBACXC,gBAAgBA;iBAChBC,sBAAsBA;iBACtBC,iBAAiBA;iBACjBC,YAAYA;;;;;;kBCfXC,mBAAmBA;;;;;;;;kBAQnBC,oBAAoBA;;;;;;;;;;;;;;;;;;;iBAmBrBC,YAAYA;iBACZC,aAAaA;;;;;;WC5BnBC,gBAAgBA;;;;;iBAKVC,SAASA;;;;;;kBCLRC,gBAAgBA;;;;;;;kBAOhBC,iBAAiBA;;;;;;iBAMlBC,UAAUA;iBACVC,SAASA;;;;;;kBCdRF,iBAAiBA;;;;;iBAKlBG,YAAYA;;;;;;;kBCHXC,kBAAkBA;;;;;;;;;;;kBAWlBC,kBAAkBA;;;;iBAInBC,WAAWA;iBACXC,WAAWA;iBACXC,aAAaA;;;;;;kBCnBZC,uBAAuBA;;;;;;;kBAOvBC,eAAeA;;;;;kBAKfC,gBAAgBA;;;;;iBAKjBC,gBAAgBA;iBAChBC,QAAQA;iBACRC,cAAcA;;;;;;kBCnBbC,eAAeA;;;;;;iBAMhBC,UAAUA;;;;;;iBCNVC,UAAUA",
84
+ "mappings": ";;kBAEiBA,aAAaA;;;;;;;;;;;;;;;;;;;;cAoBjBC,aAAaA;;yBAEFC,YAAYA;;;;;;kBCxBnBC,sBAAsBA;;;;;;;;kBAQtBC,yBAAyBA;;;;;;kBAMzBC,qBAAqBA;;;;;;;;kBAQrBC,uBAAuBA;;;;;kBAKvBC,mBAAmBA;;;;iBAIpBC,UAAUA;iBACVC,UAAUA;iBACVC,QAAQA;iBACRC,YAAYA;iBACZC,eAAeA;iBACfC,cAAcA;iBACdC,kBAAkBA;iBAClBC,gBAAgBA;iBAChBC,YAAYA;;;;;;kBCvCXC,kBAAkBA;;;;;iBAKnBC,WAAWA;iBACXC,eAAeA;iBACfC,YAAYA;;;;;;;;;;;kBCPXC,mBAAmBA;;;;;;;;;;iBAUpBC,UAAUA;iBACVC,WAAWA;iBACXC,gBAAgBA;iBAChBC,sBAAsBA;iBACtBC,iBAAiBA;iBACjBC,YAAYA;;;;;;kBCfXC,mBAAmBA;;;;;;;;kBAQnBC,oBAAoBA;;;;;;;;;;;;;;;;;;;iBAmBrBC,YAAYA;iBACZC,aAAaA;;;;;;WC5BnBC,gBAAgBA;;;;;iBAKVC,SAASA;;;;;;kBCLRC,gBAAgBA;;;;;;;kBAOhBC,iBAAiBA;;;;;;iBAMlBC,UAAUA;iBACVC,SAASA;;;;;;kBCdRF,iBAAiBA;;;;;iBAKlBG,YAAYA;;;;;;;;kBCFJC,sBAAsBA;;;;;;;kBAOtBC,iBAAiBA;;;;;;;;;;;kBCVxBC,uBAAuBA;;;;;;;kBAOvBC,eAAeA;;;;;kBAKfC,gBAAgBA;;;;;iBAKjBC,gBAAgBA;iBAChBC,QAAQA;iBACRC,cAAcA;;;;;;kBCnBbC,eAAeA;;;;;;iBAMhBC,UAAUA;;;;;;iBCNVC,UAAUA",
99
85
  "ignoreList": []
100
86
  }
@@ -1,9 +0,0 @@
1
- export interface DefaultOptions {
2
- selector?: string
3
- summarySelector?: string
4
- }
5
-
6
- export const defaultOptions: DefaultOptions
7
- export function showDetails(selector: HTMLInputElement | HTMLElement, options?: DefaultOptions): Promise<void>
8
- export function closeDetails(selector: HTMLInputElement | HTMLElement, options?: DefaultOptions): Promise<void>
9
- export function toggleDetails(selector: HTMLInputElement | HTMLElement, options?: DefaultOptions): Promise<void>
@@ -1,78 +0,0 @@
1
- /**
2
- * @type {import("./").DefaultOptions}
3
- */
4
- export const defaultOptions = {
5
- selector: 'details',
6
- summarySelector: 'summary',
7
- }
8
-
9
- /**
10
- * @param {HTMLInputElement | HTMLElement} element
11
- * @param {import("./").DefaultOptions} options
12
- * @returns Promise<void>
13
- */
14
- export const showDetails = async (element, options = {}) => {
15
- options = {
16
- ...defaultOptions,
17
- ...options,
18
- }
19
-
20
- const details = element.closest(options.selector)
21
- const { down } = await import('slide-element')
22
- const content = details.querySelector(options.summarySelector).nextElementSibling
23
-
24
- details._isHiding = false
25
- details.open = true
26
-
27
- await down(content, {
28
- display: '',
29
- })
30
- }
31
-
32
- /**
33
- * @param {HTMLInputElement | HTMLElement} element
34
- * @param {import("./").DefaultOptions} options
35
- * @returns Promise<void>
36
- */
37
- export const closeDetails = async (element, options = {}) => {
38
- options = {
39
- ...defaultOptions,
40
- ...options,
41
- }
42
-
43
- const details = element.closest(options.selector)
44
- const { up } = await import('slide-element')
45
- const content = details.querySelector(options.summarySelector).nextElementSibling
46
-
47
- details._isHiding = true
48
-
49
- await up(content, {
50
- display: '',
51
- })
52
-
53
- details._isHiding && (details.open = false)
54
- details._isHiding = false
55
- }
56
-
57
- /**
58
- * @param {HTMLInputElement | HTMLElement} element
59
- * @param {import("./").DefaultOptions} options
60
- * @returns Promise<void>
61
- */
62
- export const toggleDetails = async (element, options = {}) => {
63
- options = {
64
- ...defaultOptions,
65
- ...options,
66
- }
67
-
68
- const details = element.closest(options.selector)
69
-
70
- if (details._isHiding && !element.checked) return
71
-
72
- if (element.checked ?? !details.open) {
73
- await showDetails(element, options)
74
- }
75
- else {
76
- await closeDetails(element, options)
77
- }
78
- }
@@ -1,13 +0,0 @@
1
- export interface DefaultOptions {
2
- remove?: boolean | null
3
- closable?: boolean | null
4
- modal?: boolean
5
- openAttribute?: string
6
- closedAttribute?: string
7
- contentSelector?: string
8
- scrollbarWidthProperty?: string | null
9
- }
10
-
11
- export const defaultOptions: DefaultOptions
12
- export function showDialog(element: HTMLDialogElement | HTMLElement, options?: DefaultOptions): Promise<void>
13
- export function closeDialog(element: HTMLDialogElement | HTMLElement, options?: DefaultOptions): Promise<void>