@vielzeug/refine 1.5.4 → 1.7.0
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/dist/accordion.cjs +1 -1
- package/dist/accordion.cjs.map +1 -1
- package/dist/accordion.js +30 -28
- package/dist/accordion.js.map +1 -1
- package/dist/button-group.cjs.map +1 -1
- package/dist/button-group.js.map +1 -1
- package/dist/button.cjs +1 -1
- package/dist/button.cjs.map +1 -1
- package/dist/button.js +1 -0
- package/dist/button.js.map +1 -1
- package/dist/checkbox-group.cjs +3 -3
- package/dist/checkbox-group.cjs.map +1 -1
- package/dist/checkbox-group.js +51 -58
- package/dist/checkbox-group.js.map +1 -1
- package/dist/combobox.cjs +29 -28
- package/dist/combobox.cjs.map +1 -1
- package/dist/combobox.js +201 -195
- package/dist/combobox.js.map +1 -1
- package/dist/content/card/card.css.cjs +1 -1
- package/dist/content/card/card.css.cjs.map +1 -1
- package/dist/content/card/card.css.js +1 -1
- package/dist/content/card/card.css.js.map +1 -1
- package/dist/content/chat-message/chat-message.css.cjs +1 -1
- package/dist/content/chat-message/chat-message.css.cjs.map +1 -1
- package/dist/content/chat-message/chat-message.css.js +1 -1
- package/dist/content/chat-message/chat-message.css.js.map +1 -1
- package/dist/content/icon/icon.d.ts.map +1 -1
- package/dist/content/index.d.ts +4 -0
- package/dist/content/index.d.ts.map +1 -1
- package/dist/content/list/_list-item-reveal.cjs +2 -0
- package/dist/content/list/_list-item-reveal.cjs.map +1 -0
- package/dist/content/list/_list-item-reveal.d.ts +25 -0
- package/dist/content/list/_list-item-reveal.d.ts.map +1 -0
- package/dist/content/list/_list-item-reveal.js +33 -0
- package/dist/content/list/_list-item-reveal.js.map +1 -0
- package/dist/content/list/list-item.css.cjs +2 -0
- package/dist/content/list/list-item.css.cjs.map +1 -0
- package/dist/content/list/list-item.css.js +6 -0
- package/dist/content/list/list-item.css.js.map +1 -0
- package/dist/content/list/list-item.d.ts +111 -0
- package/dist/content/list/list-item.d.ts.map +1 -0
- package/dist/content/list/list.css.cjs +2 -0
- package/dist/content/list/list.css.cjs.map +1 -0
- package/dist/content/list/list.css.js +6 -0
- package/dist/content/list/list.css.js.map +1 -0
- package/dist/content/list/list.d.ts +93 -0
- package/dist/content/list/list.d.ts.map +1 -0
- package/dist/custom-elements.json +6052 -5449
- package/dist/date-picker.cjs +2 -1
- package/dist/date-picker.cjs.map +1 -1
- package/dist/date-picker.js +2 -0
- package/dist/date-picker.js.map +1 -1
- package/dist/disclosure/tab-item/tab-item.d.ts.map +1 -1
- package/dist/disclosure/tab-panel/tab-panel.d.ts.map +1 -1
- package/dist/disclosure/tabs/tabs.d.ts.map +1 -1
- package/dist/drawer.cjs +1 -1
- package/dist/drawer.cjs.map +1 -1
- package/dist/drawer.js +47 -48
- package/dist/drawer.js.map +1 -1
- package/dist/file-input.cjs +111 -45
- package/dist/file-input.cjs.map +1 -1
- package/dist/file-input.js +216 -156
- package/dist/file-input.js.map +1 -1
- package/dist/headless/aria-reflection.cjs +2 -0
- package/dist/headless/aria-reflection.cjs.map +1 -0
- package/dist/headless/aria-reflection.d.ts +27 -0
- package/dist/headless/aria-reflection.d.ts.map +1 -0
- package/dist/headless/aria-reflection.js +18 -0
- package/dist/headless/aria-reflection.js.map +1 -0
- package/dist/headless/checkable.cjs +1 -1
- package/dist/headless/checkable.cjs.map +1 -1
- package/dist/headless/checkable.d.ts +2 -10
- package/dist/headless/checkable.d.ts.map +1 -1
- package/dist/headless/checkable.js +29 -29
- package/dist/headless/checkable.js.map +1 -1
- package/dist/headless/choice-field.cjs +1 -1
- package/dist/headless/choice-field.cjs.map +1 -1
- package/dist/headless/choice-field.d.ts +2 -7
- package/dist/headless/choice-field.d.ts.map +1 -1
- package/dist/headless/choice-field.js +37 -37
- package/dist/headless/choice-field.js.map +1 -1
- package/dist/headless/field-base.cjs +1 -1
- package/dist/headless/field-base.cjs.map +1 -1
- package/dist/headless/field-base.d.ts +17 -0
- package/dist/headless/field-base.d.ts.map +1 -1
- package/dist/headless/field-base.js +21 -6
- package/dist/headless/field-base.js.map +1 -1
- package/dist/headless/focus.cjs +1 -1
- package/dist/headless/focus.cjs.map +1 -1
- package/dist/headless/focus.d.ts +7 -0
- package/dist/headless/focus.d.ts.map +1 -1
- package/dist/headless/focus.js +6 -6
- package/dist/headless/focus.js.map +1 -1
- package/dist/headless/index.d.ts +4 -2
- package/dist/headless/index.d.ts.map +1 -1
- package/dist/headless/nav.cjs +1 -1
- package/dist/headless/nav.cjs.map +1 -1
- package/dist/headless/nav.d.ts +12 -0
- package/dist/headless/nav.d.ts.map +1 -1
- package/dist/headless/nav.js +68 -50
- package/dist/headless/nav.js.map +1 -1
- package/dist/headless/overlay.cjs +1 -1
- package/dist/headless/overlay.cjs.map +1 -1
- package/dist/headless/overlay.d.ts +2 -0
- package/dist/headless/overlay.d.ts.map +1 -1
- package/dist/headless/overlay.js +8 -5
- package/dist/headless/overlay.js.map +1 -1
- package/dist/headless/ref-callback.cjs +2 -0
- package/dist/headless/ref-callback.cjs.map +1 -0
- package/dist/headless/ref-callback.d.ts +26 -0
- package/dist/headless/ref-callback.d.ts.map +1 -0
- package/dist/headless/ref-callback.js +13 -0
- package/dist/headless/ref-callback.js.map +1 -0
- package/dist/headless/swipe.cjs +1 -1
- package/dist/headless/swipe.cjs.map +1 -1
- package/dist/headless/swipe.d.ts +2 -0
- package/dist/headless/swipe.d.ts.map +1 -1
- package/dist/headless/swipe.js +26 -21
- package/dist/headless/swipe.js.map +1 -1
- package/dist/headless.cjs +1 -1
- package/dist/headless.js +28 -26
- package/dist/icon.cjs +1 -1
- package/dist/icon.cjs.map +1 -1
- package/dist/icon.js +36 -38
- package/dist/icon.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.js +63 -61
- package/dist/input.cjs +29 -26
- package/dist/input.cjs.map +1 -1
- package/dist/input.js +91 -79
- package/dist/input.js.map +1 -1
- package/dist/inputs/button/button.css.cjs +1 -1
- package/dist/inputs/button/button.css.cjs.map +1 -1
- package/dist/inputs/button/button.css.js +1 -1
- package/dist/inputs/button/button.css.js.map +1 -1
- package/dist/inputs/button/button.d.ts +8 -0
- package/dist/inputs/button/button.d.ts.map +1 -1
- package/dist/inputs/checkbox/checkbox.css.cjs +1 -1
- package/dist/inputs/checkbox/checkbox.css.cjs.map +1 -1
- package/dist/inputs/checkbox/checkbox.css.js +1 -1
- package/dist/inputs/checkbox/checkbox.css.js.map +1 -1
- package/dist/inputs/combobox/combobox.d.ts +1 -0
- package/dist/inputs/combobox/combobox.d.ts.map +1 -1
- package/dist/inputs/date-picker/date-picker.css.cjs +1 -1
- package/dist/inputs/date-picker/date-picker.css.cjs.map +1 -1
- package/dist/inputs/date-picker/date-picker.css.js +1 -1
- package/dist/inputs/date-picker/date-picker.css.js.map +1 -1
- package/dist/inputs/date-picker/date-picker.d.ts +6 -0
- package/dist/inputs/date-picker/date-picker.d.ts.map +1 -1
- package/dist/inputs/file-input/file-input-upload.cjs +2 -0
- package/dist/inputs/file-input/file-input-upload.cjs.map +1 -0
- package/dist/inputs/file-input/file-input-upload.d.ts +76 -0
- package/dist/inputs/file-input/file-input-upload.d.ts.map +1 -0
- package/dist/inputs/file-input/file-input-upload.js +145 -0
- package/dist/inputs/file-input/file-input-upload.js.map +1 -0
- package/dist/inputs/file-input/file-input.css.cjs +1 -1
- package/dist/inputs/file-input/file-input.css.cjs.map +1 -1
- package/dist/inputs/file-input/file-input.css.js +1 -1
- package/dist/inputs/file-input/file-input.css.js.map +1 -1
- package/dist/inputs/file-input/file-input.d.ts +54 -1
- package/dist/inputs/file-input/file-input.d.ts.map +1 -1
- package/dist/inputs/input/input.css.cjs +1 -1
- package/dist/inputs/input/input.css.cjs.map +1 -1
- package/dist/inputs/input/input.css.js +1 -1
- package/dist/inputs/input/input.css.js.map +1 -1
- package/dist/inputs/input/input.d.ts +13 -0
- package/dist/inputs/input/input.d.ts.map +1 -1
- package/dist/inputs/message-composer/message-composer.css.cjs +1 -1
- package/dist/inputs/message-composer/message-composer.css.cjs.map +1 -1
- package/dist/inputs/message-composer/message-composer.css.js +1 -1
- package/dist/inputs/message-composer/message-composer.css.js.map +1 -1
- package/dist/inputs/message-composer/message-composer.d.ts +7 -0
- package/dist/inputs/message-composer/message-composer.d.ts.map +1 -1
- package/dist/inputs/number-input/number-input.css.cjs +1 -1
- package/dist/inputs/number-input/number-input.css.cjs.map +1 -1
- package/dist/inputs/number-input/number-input.css.js +1 -1
- package/dist/inputs/number-input/number-input.css.js.map +1 -1
- package/dist/inputs/number-input/number-input.d.ts +15 -0
- package/dist/inputs/number-input/number-input.d.ts.map +1 -1
- package/dist/inputs/otp-input/otp-input.css.cjs +1 -1
- package/dist/inputs/otp-input/otp-input.css.cjs.map +1 -1
- package/dist/inputs/otp-input/otp-input.css.js +1 -1
- package/dist/inputs/otp-input/otp-input.css.js.map +1 -1
- package/dist/inputs/radio/radio.d.ts.map +1 -1
- package/dist/inputs/select/select.d.ts +1 -0
- package/dist/inputs/select/select.d.ts.map +1 -1
- package/dist/inputs/shared/index.d.ts +1 -1
- package/dist/inputs/shared/index.d.ts.map +1 -1
- package/dist/inputs/shared/templates.cjs +26 -3
- package/dist/inputs/shared/templates.cjs.map +1 -1
- package/dist/inputs/shared/templates.d.ts +20 -0
- package/dist/inputs/shared/templates.d.ts.map +1 -1
- package/dist/inputs/shared/templates.js +29 -5
- package/dist/inputs/shared/templates.js.map +1 -1
- package/dist/inputs/switch/switch.css.cjs +1 -1
- package/dist/inputs/switch/switch.css.cjs.map +1 -1
- package/dist/inputs/switch/switch.css.js +1 -1
- package/dist/inputs/switch/switch.css.js.map +1 -1
- package/dist/inputs/switch/switch.d.ts.map +1 -1
- package/dist/inputs/textarea/textarea.css.cjs +1 -1
- package/dist/inputs/textarea/textarea.css.cjs.map +1 -1
- package/dist/inputs/textarea/textarea.css.js +1 -1
- package/dist/inputs/textarea/textarea.css.js.map +1 -1
- package/dist/inputs/textarea/textarea.d.ts +14 -0
- package/dist/inputs/textarea/textarea.d.ts.map +1 -1
- package/dist/inputs/time-picker/time-picker.css.cjs +1 -1
- package/dist/inputs/time-picker/time-picker.css.cjs.map +1 -1
- package/dist/inputs/time-picker/time-picker.css.js +1 -1
- package/dist/inputs/time-picker/time-picker.css.js.map +1 -1
- package/dist/inputs/time-picker/time-picker.d.ts +6 -0
- package/dist/inputs/time-picker/time-picker.d.ts.map +1 -1
- package/dist/list-item.cjs +22 -0
- package/dist/list-item.cjs.map +1 -0
- package/dist/list-item.js +91 -0
- package/dist/list-item.js.map +1 -0
- package/dist/list.cjs +2 -0
- package/dist/list.cjs.map +1 -0
- package/dist/list.js +64 -0
- package/dist/list.js.map +1 -0
- package/dist/menu.cjs +4 -4
- package/dist/menu.cjs.map +1 -1
- package/dist/menu.js +60 -59
- package/dist/menu.js.map +1 -1
- package/dist/message-composer.cjs +14 -20
- package/dist/message-composer.cjs.map +1 -1
- package/dist/message-composer.js +63 -64
- package/dist/message-composer.js.map +1 -1
- package/dist/number-input.cjs +5 -3
- package/dist/number-input.cjs.map +1 -1
- package/dist/number-input.js +8 -4
- package/dist/number-input.js.map +1 -1
- package/dist/otp-input.cjs +9 -9
- package/dist/otp-input.cjs.map +1 -1
- package/dist/otp-input.js +70 -62
- package/dist/otp-input.js.map +1 -1
- package/dist/overlay/menu/menu-item.css.cjs +1 -1
- package/dist/overlay/menu/menu-item.css.cjs.map +1 -1
- package/dist/overlay/menu/menu-item.css.js +1 -1
- package/dist/overlay/menu/menu-item.css.js.map +1 -1
- package/dist/overlay/menu/menu-separator.css.cjs +1 -1
- package/dist/overlay/menu/menu-separator.css.cjs.map +1 -1
- package/dist/overlay/menu/menu-separator.css.js +1 -1
- package/dist/overlay/menu/menu-separator.css.js.map +1 -1
- package/dist/overlay/menu/menu.css.cjs +1 -1
- package/dist/overlay/menu/menu.css.cjs.map +1 -1
- package/dist/overlay/menu/menu.css.js +1 -1
- package/dist/overlay/menu/menu.css.js.map +1 -1
- package/dist/overlay/shared/use-dialog.cjs +1 -1
- package/dist/overlay/shared/use-dialog.cjs.map +1 -1
- package/dist/overlay/shared/use-dialog.d.ts.map +1 -1
- package/dist/overlay/shared/use-dialog.js +7 -6
- package/dist/overlay/shared/use-dialog.js.map +1 -1
- package/dist/radio-group.cjs +3 -3
- package/dist/radio-group.cjs.map +1 -1
- package/dist/radio-group.js +64 -70
- package/dist/radio-group.js.map +1 -1
- package/dist/radio.cjs +4 -4
- package/dist/radio.cjs.map +1 -1
- package/dist/radio.js +58 -58
- package/dist/radio.js.map +1 -1
- package/dist/rating.cjs.map +1 -1
- package/dist/rating.js.map +1 -1
- package/dist/refine.cjs +426 -233
- package/dist/refine.cjs.map +1 -1
- package/dist/refine.iife.js +431 -238
- package/dist/refine.iife.js.map +1 -1
- package/dist/refine.js +452 -259
- package/dist/refine.js.map +1 -1
- package/dist/select.cjs +21 -21
- package/dist/select.cjs.map +1 -1
- package/dist/select.js +135 -127
- package/dist/select.js.map +1 -1
- package/dist/shared/size-presets.cjs +1 -1
- package/dist/shared/size-presets.cjs.map +1 -1
- package/dist/shared/size-presets.d.ts +74 -0
- package/dist/shared/size-presets.d.ts.map +1 -1
- package/dist/shared/size-presets.js +48 -1
- package/dist/shared/size-presets.js.map +1 -1
- package/dist/shared/types.d.ts +5 -0
- package/dist/shared/types.d.ts.map +1 -1
- package/dist/styles/index.cjs +1 -1
- package/dist/styles/index.cjs.map +1 -1
- package/dist/styles/index.d.ts +1 -0
- package/dist/styles/index.d.ts.map +1 -1
- package/dist/styles/index.js +5 -4
- package/dist/styles/index.js.map +1 -1
- package/dist/styles/mixins/field-variants.css.cjs +85 -0
- package/dist/styles/mixins/field-variants.css.cjs.map +1 -0
- package/dist/styles/mixins/field-variants.css.d.ts +66 -0
- package/dist/styles/mixins/field-variants.css.d.ts.map +1 -0
- package/dist/styles/mixins/field-variants.css.js +90 -0
- package/dist/styles/mixins/field-variants.css.js.map +1 -0
- package/dist/switch.cjs +3 -3
- package/dist/switch.cjs.map +1 -1
- package/dist/switch.js +38 -36
- package/dist/switch.js.map +1 -1
- package/dist/tab-item.cjs +8 -8
- package/dist/tab-item.cjs.map +1 -1
- package/dist/tab-item.js +38 -28
- package/dist/tab-item.js.map +1 -1
- package/dist/tab-panel.cjs +7 -7
- package/dist/tab-panel.cjs.map +1 -1
- package/dist/tab-panel.js +34 -26
- package/dist/tab-panel.js.map +1 -1
- package/dist/tabs.cjs +4 -4
- package/dist/tabs.cjs.map +1 -1
- package/dist/tabs.js +64 -60
- package/dist/tabs.js.map +1 -1
- package/dist/textarea.cjs +15 -18
- package/dist/textarea.cjs.map +1 -1
- package/dist/textarea.js +83 -74
- package/dist/textarea.js.map +1 -1
- package/dist/time-picker.cjs +34 -31
- package/dist/time-picker.cjs.map +1 -1
- package/dist/time-picker.js +121 -109
- package/dist/time-picker.js.map +1 -1
- package/package.json +21 -9
- package/dist/headless/dialog-focus.cjs +0 -2
- package/dist/headless/dialog-focus.cjs.map +0 -1
- package/dist/headless/dialog-focus.d.ts +0 -40
- package/dist/headless/dialog-focus.d.ts.map +0 -1
- package/dist/headless/dialog-focus.js +0 -22
- package/dist/headless/dialog-focus.js.map +0 -1
- package/dist/headless/focus-trap.cjs +0 -2
- package/dist/headless/focus-trap.cjs.map +0 -1
- package/dist/headless/focus-trap.d.ts +0 -45
- package/dist/headless/focus-trap.d.ts.map +0 -1
- package/dist/headless/focus-trap.js +0 -51
- package/dist/headless/focus-trap.js.map +0 -1
package/dist/drawer.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { coarsePointerMixin as e, reducedMotionMixin as t } from "./styles/mixins/accessibility.css.js";
|
|
2
|
-
import {
|
|
3
|
-
import { createSwipeControl as
|
|
4
|
-
import { useDialogControl as
|
|
5
|
-
import
|
|
6
|
-
import { createStableId as
|
|
7
|
-
import { signal as
|
|
2
|
+
import { forcedColorsMixin as n } from "./styles/mixins/theme.css.js";
|
|
3
|
+
import { createSwipeControl as r } from "./headless/swipe.js";
|
|
4
|
+
import { useDialogControl as i } from "./overlay/shared/use-dialog.js";
|
|
5
|
+
import a from "./overlay/drawer/drawer.css.js";
|
|
6
|
+
import { createStableId as o, define as s, getHost as c, html as l, onCleanup as u, onEvent as d, onMounted as f, prop as p, ref as m, useEmit as h, useSlots as g } from "@vielzeug/ore";
|
|
7
|
+
import { signal as _ } from "@vielzeug/ripple";
|
|
8
8
|
//#region src/overlay/drawer/drawer.ts
|
|
9
|
-
var
|
|
9
|
+
var v = {
|
|
10
10
|
bottom: {
|
|
11
11
|
axis: "y",
|
|
12
12
|
closingDistance: (e) => Math.max(0, e),
|
|
@@ -27,34 +27,34 @@ var y = {
|
|
|
27
27
|
closingDistance: (e) => Math.max(0, -e),
|
|
28
28
|
translate: (e) => `translateY(${e}px)`
|
|
29
29
|
}
|
|
30
|
-
},
|
|
31
|
-
|
|
30
|
+
}, y = "ore-drawer";
|
|
31
|
+
s(y, {
|
|
32
32
|
props: {
|
|
33
|
-
backdrop:
|
|
34
|
-
dismissible:
|
|
35
|
-
"drag-handle-placement":
|
|
36
|
-
"initial-focus":
|
|
37
|
-
label:
|
|
38
|
-
open:
|
|
39
|
-
persistent:
|
|
40
|
-
placement:
|
|
33
|
+
backdrop: p.string(),
|
|
34
|
+
dismissible: p.bool(!0),
|
|
35
|
+
"drag-handle-placement": p.oneOf(["outside", "inset"], "outside"),
|
|
36
|
+
"initial-focus": p.string(),
|
|
37
|
+
label: p.string(),
|
|
38
|
+
open: p.bool(!1),
|
|
39
|
+
persistent: p.bool(!1),
|
|
40
|
+
placement: p.oneOf([
|
|
41
41
|
"left",
|
|
42
42
|
"right",
|
|
43
43
|
"top",
|
|
44
44
|
"bottom"
|
|
45
45
|
], "right"),
|
|
46
|
-
"return-focus":
|
|
47
|
-
size:
|
|
48
|
-
title:
|
|
46
|
+
"return-focus": p.bool(!0),
|
|
47
|
+
size: p.string(),
|
|
48
|
+
title: p.string()
|
|
49
49
|
},
|
|
50
50
|
setup(e) {
|
|
51
|
-
let t =
|
|
51
|
+
let t = c(), n = h(), a = g(), s = o("drawer-label"), p = m(), y = m(), b = _(!1), x, S = () => e.label.value ?? e.title.value ?? "", C = () => a.has("header").value || !!S(), w = () => C() || e.dismissible.value, T = () => a.has("footer").value, E = () => e.placement.value || "right", D = () => v[E()], O = (e, t) => {
|
|
52
52
|
let n = t === "x" ? e.offsetWidth : e.offsetHeight;
|
|
53
53
|
return Math.min(96, Math.max(36, n * .18));
|
|
54
54
|
}, k = (e, t) => D().closingDistance(e) >= t, A = (e) => {
|
|
55
55
|
if (!b.value) return;
|
|
56
56
|
x &&= (clearTimeout(x), void 0);
|
|
57
|
-
let t =
|
|
57
|
+
let t = p.value;
|
|
58
58
|
if (!t) {
|
|
59
59
|
b.value = !1;
|
|
60
60
|
return;
|
|
@@ -76,7 +76,7 @@ c(b, {
|
|
|
76
76
|
}, M = (e) => {
|
|
77
77
|
x &&= (clearTimeout(x), void 0), e.style.transition = "", e.style.transform = "", e.style.opacity = "", e.style.visibility = "", b.value = !1;
|
|
78
78
|
}, N = ({ distance: e, threshold: t }) => {
|
|
79
|
-
let n =
|
|
79
|
+
let n = y.value;
|
|
80
80
|
if (n) {
|
|
81
81
|
if (k(e, t)) {
|
|
82
82
|
j(n, D(), e);
|
|
@@ -84,16 +84,16 @@ c(b, {
|
|
|
84
84
|
}
|
|
85
85
|
M(n);
|
|
86
86
|
}
|
|
87
|
-
}, P =
|
|
87
|
+
}, P = r({
|
|
88
88
|
axis: () => D().axis,
|
|
89
89
|
disabled: b,
|
|
90
90
|
onCancel: N,
|
|
91
91
|
onCommit: ({ distance: e }) => {
|
|
92
|
-
let t =
|
|
92
|
+
let t = y.value;
|
|
93
93
|
t && j(t, D(), e);
|
|
94
94
|
},
|
|
95
95
|
onMove: ({ distance: e, threshold: t }) => {
|
|
96
|
-
let n =
|
|
96
|
+
let n = y.value;
|
|
97
97
|
if (!n) return;
|
|
98
98
|
let r = D(), i = r.closingDistance(e), a = Math.min(i / t, 1);
|
|
99
99
|
n.style.transition = "none", n.style.transform = r.translate(e), n.style.opacity = String(1 - a * .4);
|
|
@@ -101,26 +101,26 @@ c(b, {
|
|
|
101
101
|
onRelease: N,
|
|
102
102
|
shouldCommit: ({ distance: e, threshold: t }) => k(e, t),
|
|
103
103
|
threshold: () => {
|
|
104
|
-
let e =
|
|
104
|
+
let e = y.value;
|
|
105
105
|
return e ? O(e, D().axis) : 48;
|
|
106
106
|
}
|
|
107
|
-
}), { closeWithAnimation: F, handleCancel: I, overlay: L, requestClose: R, watchOpenProp: z } =
|
|
107
|
+
}), { closeWithAnimation: F, handleCancel: I, overlay: L, requestClose: R, watchOpenProp: z } = i({
|
|
108
108
|
beforeOpen: (e) => {
|
|
109
|
-
let t =
|
|
109
|
+
let t = y.value;
|
|
110
110
|
t && M(t);
|
|
111
111
|
},
|
|
112
112
|
closeRequestDetail: (t) => ({ placement: e.placement.value ?? "right" }),
|
|
113
|
-
dialogRef:
|
|
114
|
-
getPanelEl: () =>
|
|
113
|
+
dialogRef: p,
|
|
114
|
+
getPanelEl: () => y.value,
|
|
115
115
|
host: t,
|
|
116
116
|
initialFocus: e["initial-focus"],
|
|
117
117
|
isPersistent: () => !!e.persistent.value,
|
|
118
|
-
onCleanup:
|
|
119
|
-
onEvent:
|
|
118
|
+
onCleanup: u,
|
|
119
|
+
onEvent: d,
|
|
120
120
|
onNativeClose: (t) => {
|
|
121
|
-
let r =
|
|
121
|
+
let r = y.value;
|
|
122
122
|
r && t !== "swipe" && M(r);
|
|
123
|
-
let i =
|
|
123
|
+
let i = p.value;
|
|
124
124
|
i && (i.style.transition = ""), n("close", {
|
|
125
125
|
placement: e.placement.value ?? "right",
|
|
126
126
|
reason: t
|
|
@@ -136,31 +136,31 @@ c(b, {
|
|
|
136
136
|
},
|
|
137
137
|
returnFocus: e["return-focus"]
|
|
138
138
|
});
|
|
139
|
-
return
|
|
140
|
-
let n =
|
|
139
|
+
return f(() => {
|
|
140
|
+
let n = p.value;
|
|
141
141
|
if (!n) return;
|
|
142
142
|
let r = t;
|
|
143
143
|
r.show = () => {
|
|
144
144
|
L.open("programmatic");
|
|
145
145
|
}, r.hide = () => {
|
|
146
146
|
L.close("programmatic", !1);
|
|
147
|
-
}, z(),
|
|
147
|
+
}, z(), d(n, "cancel", I), d(n, "click", (t) => {
|
|
148
148
|
e.persistent.value || P.isActive() || b.value || t.target === n && R("outsideClick");
|
|
149
149
|
});
|
|
150
|
-
let i =
|
|
151
|
-
return i && (
|
|
150
|
+
let i = y.value?.querySelector("[part=\"drag-handle\"]");
|
|
151
|
+
return i && (d(i, "pointerdown", P.handlePointerDown), d(i, "pointermove", P.handlePointerMove), d(i, "pointerup", P.handlePointerUp), d(i, "pointercancel", P.handlePointerCancel)), () => {
|
|
152
152
|
L.dispose();
|
|
153
153
|
};
|
|
154
|
-
}),
|
|
154
|
+
}), l`
|
|
155
155
|
<dialog
|
|
156
|
-
ref=${
|
|
156
|
+
ref=${p}
|
|
157
157
|
aria-modal="true"
|
|
158
158
|
:aria-label="${() => e.label.value ?? null}"
|
|
159
|
-
:aria-labelledby="${() => e.label.value ? null :
|
|
160
|
-
<div class="panel" part="panel" ref=${
|
|
159
|
+
:aria-labelledby="${() => e.label.value ? null : s}">
|
|
160
|
+
<div class="panel" part="panel" ref=${y}>
|
|
161
161
|
<div class="drag-handle" part="drag-handle" aria-label="Drag to close" role="button"></div>
|
|
162
162
|
<div class="header" part="header" ?hidden=${() => !w()}>
|
|
163
|
-
<span class="header-title" id="${
|
|
163
|
+
<span class="header-title" id="${s}" ?hidden=${() => !C()}>
|
|
164
164
|
<slot name="header">${() => S()}</slot>
|
|
165
165
|
</span>
|
|
166
166
|
<button
|
|
@@ -187,13 +187,12 @@ c(b, {
|
|
|
187
187
|
},
|
|
188
188
|
styles: [
|
|
189
189
|
n,
|
|
190
|
-
r,
|
|
191
190
|
e,
|
|
192
191
|
t,
|
|
193
|
-
|
|
192
|
+
a
|
|
194
193
|
]
|
|
195
194
|
});
|
|
196
195
|
//#endregion
|
|
197
|
-
export {
|
|
196
|
+
export { y as DRAWER_TAG };
|
|
198
197
|
|
|
199
198
|
//# sourceMappingURL=drawer.js.map
|
package/dist/drawer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"drawer.js","names":[],"sources":["../src/overlay/drawer/drawer.ts"],"sourcesContent":["import {\n createStableId,\n define,\n html,\n prop,\n ref,\n getHost,\n onCleanup,\n onEvent,\n onMounted,\n useEmit,\n useSlots,\n} from '@vielzeug/ore';\nimport { signal } from '@vielzeug/ripple';\n\nimport type { OverlayCloseDetail, OverlayOpenDetail, SwipeAxis } from '../../headless';\n\nimport { createSwipeControl } from '../../headless';\nimport '../../content/icon/icon';\nimport { coarsePointerMixin, elevationMixin, forcedColorsMixin, reducedMotionMixin } from '../../styles';\nimport { useDialogControl } from '../shared/use-dialog';\nimport styles from './drawer.css?inline';\n\ntype DrawerPlacement = 'left' | 'right' | 'top' | 'bottom';\ntype DrawerSize = 'sm' | 'lg' | 'full';\ntype DrawerBackdrop = 'opaque' | 'blur' | 'transparent';\ntype DrawerDragHandlePlacement = 'outside' | 'inset';\ntype DrawerSwipeConfig = {\n axis: SwipeAxis;\n closingDistance: (distance: number) => number;\n translate: (distance: number) => string;\n};\n\nconst drawerSwipeConfig: Record<DrawerPlacement, DrawerSwipeConfig> = {\n bottom: {\n axis: 'y',\n closingDistance: (distance) => Math.max(0, distance),\n translate: (distance) => `translateY(${distance}px)`,\n },\n left: {\n axis: 'x',\n closingDistance: (distance) => Math.max(0, -distance),\n translate: (distance) => `translateX(${distance}px)`,\n },\n right: {\n axis: 'x',\n closingDistance: (distance) => Math.max(0, distance),\n translate: (distance) => `translateX(${distance}px)`,\n },\n top: {\n axis: 'y',\n closingDistance: (distance) => Math.max(0, -distance),\n translate: (distance) => `translateY(${distance}px)`,\n },\n};\n\n/** Element interface exposing the imperative API for `ore-drawer`. */\nexport interface DrawerElement extends HTMLElement, Omit<OreDrawerProps, 'title'> {\n /** Programmatically open the drawer. Equivalent to setting `open`. */\n show(): void;\n /** Programmatically close the drawer with the exit animation. */\n hide(): void;\n}\n\n/** Drawer component properties */\n\nexport type OreDrawerEvents = {\n close: OverlayCloseDetail & { placement: DrawerPlacement };\n open: OverlayOpenDetail & { placement: DrawerPlacement };\n};\n\nexport type OreDrawerProps = {\n /** Backdrop style — 'opaque' (default), 'blur', or 'transparent' */\n backdrop?: DrawerBackdrop;\n /** Show the close (×) button in the header (default: true) */\n dismissible?: boolean;\n /** Drag handle position used for swipe-to-close gestures */\n 'drag-handle-placement'?: DrawerDragHandlePlacement;\n /**\n * CSS selector for the element inside the drawer that should receive focus on open.\n * Defaults to native dialog focus management (first focusable element).\n * @example '#submit-btn' | 'input[name=\"email\"]'\n */\n 'initial-focus'?: string;\n /**\n * Invisible accessible label for the dialog (`aria-label`).\n * Use when the drawer has no visible title (e.g. image-only content).\n * When omitted, `aria-labelledby` points to the visible header title instead.\n */\n label?: string;\n /** Controlled open state */\n open?: boolean;\n /** When true, backdrop clicks do not close the drawer (default: false) */\n persistent?: boolean;\n /** Side from which the drawer slides in */\n placement?: DrawerPlacement;\n /**\n * When true (default), focus returns to the triggering element after the drawer closes.\n * Set to false to manage focus manually.\n */\n 'return-focus'?: boolean;\n /** Drawer width/height preset */\n size?: DrawerSize;\n /**\n * Visible title text rendered inside the header.\n * Used as the dialog's accessible label via `aria-labelledby` when `label` is not set.\n */\n title?: string;\n};\n\n/**\n * A panel that slides in from any edge of the screen, built on the native `<dialog>` element.\n *\n * @element ore-drawer\n *\n * @attr {boolean} open - Controlled open/close state\n * @attr {string} placement - 'left' | 'right' (default) | 'top' | 'bottom'\n * @attr {string} size - 'sm' | 'lg' | 'full'\n * @attr {string} title - Visible header title text\n * @attr {string} label - Invisible aria-label (for drawers without a visible title)\n * @attr {boolean} dismissible - Show the close (×) button (default: true)\n * @attr {string} drag-handle-placement - 'outside' (default) | 'inset'\n * @attr {string} backdrop - Backdrop style: 'opaque' (default) | 'blur' | 'transparent'\n * @attr {boolean} persistent - Prevent backdrop-click from closing (default: false)\n *\n * @fires open - When the drawer opens with detail: { placement, reason }\n * @fires close - When the drawer closes with detail: { placement, reason }\n *\n * @slot header - Drawer header content\n * @slot - Main body content\n * @slot footer - Drawer footer content\n *\n * @cssprop --drawer-backdrop-bg - Backdrop background color\n * @cssprop --drawer-bg - Panel background color\n * @cssprop --drawer-size - Panel width (horizontal) or height (vertical)\n * @cssprop --drawer-shadow - Panel box-shadow\n * @cssprop --drawer-panel-blur - Panel backdrop blur amount\n *\n * @part drag-handle - Drawer drag handle.\n * @part panel - Panel container.\n * @part header - Header container.\n * @part close-btn - Close button.\n * @part body - Body content container.\n * @part footer - Footer container.\n * @example\n * ```html\n * <!-- With visible title -->\n * <ore-drawer open title=\"Settings\" placement=\"right\">\n * <p>Settings content here.</p>\n * </ore-drawer>\n *\n * <!-- With custom header slot -->\n * <ore-drawer open placement=\"right\">\n * <span slot=\"header\">Settings</span>\n * <p>Settings content here.</p>\n * </ore-drawer>\n * ```\n */\n\nexport const DRAWER_TAG = 'ore-drawer' as const;\ndefine<OreDrawerProps>(DRAWER_TAG, {\n props: {\n backdrop: prop.string<DrawerBackdrop>(),\n dismissible: prop.bool(true),\n 'drag-handle-placement': prop.oneOf(['outside', 'inset'] as const, 'outside'),\n 'initial-focus': prop.string(),\n label: prop.string(),\n open: prop.bool(false),\n persistent: prop.bool(false),\n placement: prop.oneOf(['left', 'right', 'top', 'bottom'] as const, 'right'),\n 'return-focus': prop.bool(true),\n size: prop.string<DrawerSize>(),\n title: prop.string(),\n },\n setup(props) {\n const el = getHost();\n const emit = useEmit<OreDrawerEvents>();\n const slots = useSlots();\n\n const drawerLabelId = createStableId('drawer-label');\n const dialogRef = ref<HTMLDialogElement>();\n const panelRef = ref<HTMLDivElement>();\n\n // Drag-to-close state\n const isSwipeClosing = signal(false);\n let swipeCloseTimer: ReturnType<typeof setTimeout> | undefined;\n\n const getHeaderText = () => props.label.value ?? props.title.value ?? '';\n const hasHeaderTitle = () => slots.has('header').value || !!getHeaderText();\n\n // Header is visible when there is slot content, a text label, or a close button.\n const hasHeader = () => hasHeaderTitle() || props.dismissible.value;\n const hasFooter = () => slots.has('footer').value;\n\n const getPlacement = (): DrawerPlacement => props.placement.value || 'right';\n\n const getSwipeConfig = (): DrawerSwipeConfig => drawerSwipeConfig[getPlacement()];\n\n const getSnapThreshold = (panel: HTMLElement, axis: SwipeAxis) => {\n const panelSize = axis === 'x' ? panel.offsetWidth : panel.offsetHeight;\n\n return Math.min(96, Math.max(36, panelSize * 0.18));\n };\n\n const shouldCommitSwipeClose = (distance: number, threshold: number) => {\n return getSwipeConfig().closingDistance(distance) >= threshold;\n };\n\n const finalizeSwipeClose = (panel: HTMLElement) => {\n if (!isSwipeClosing.value) return;\n\n if (swipeCloseTimer) {\n clearTimeout(swipeCloseTimer);\n swipeCloseTimer = undefined;\n }\n\n const dialog = dialogRef.value;\n\n if (!dialog) {\n isSwipeClosing.value = false;\n\n return;\n }\n\n dialog.style.transition = 'none';\n panel.style.opacity = '0';\n panel.style.visibility = 'hidden';\n void dialog.offsetWidth;\n\n requestClose('swipe');\n };\n\n const startSwipeClose = (panel: HTMLElement, swipe: DrawerSwipeConfig, committedDistance: number) => {\n if (isSwipeClosing.value) return;\n\n isSwipeClosing.value = true;\n\n const panelSize = swipe.axis === 'x' ? panel.offsetWidth : panel.offsetHeight;\n // Preserve overshoot so closing continues from the dragged position instead of snapping back.\n const exitDistance =\n committedDistance >= 0 ? Math.max(committedDistance, panelSize) : Math.min(committedDistance, -panelSize);\n const exitTransform = swipe.translate(exitDistance);\n\n // Commit the current drag position first so the magnetic snap continues\n // from the finger instead of jumping back to rest.\n panel.style.transition = 'transform 180ms cubic-bezier(0.2, 0.9, 0.2, 1), opacity 180ms ease-out';\n void panel.offsetWidth;\n\n const onExitTransitionEnd = (ev: TransitionEvent) => {\n if (ev.target !== panel || ev.propertyName !== 'transform') return;\n\n panel.removeEventListener('transitionend', onExitTransitionEnd);\n finalizeSwipeClose(panel);\n };\n\n panel.addEventListener('transitionend', onExitTransitionEnd);\n\n const durationMs = parseFloat(getComputedStyle(panel).transitionDuration) * 1000;\n\n swipeCloseTimer = setTimeout(() => {\n panel.removeEventListener('transitionend', onExitTransitionEnd);\n finalizeSwipeClose(panel);\n }, durationMs + 50);\n\n panel.style.transform = exitTransform;\n panel.style.opacity = '0.2';\n };\n\n const resetPanelDragStyles = (panel: HTMLElement) => {\n if (swipeCloseTimer) {\n clearTimeout(swipeCloseTimer);\n swipeCloseTimer = undefined;\n }\n\n // Re-enable transitions so the snap-back or exit animates.\n panel.style.transition = '';\n panel.style.transform = '';\n panel.style.opacity = '';\n panel.style.visibility = '';\n isSwipeClosing.value = false;\n };\n\n // Same \"snap back or commit close\" decision whether the swipe was\n // interrupted by the platform (onCancel) or simply released without an\n // intervening move event crossing the threshold (onRelease).\n const handleSwipeRelease = ({ distance, threshold }: { distance: number; threshold: number }): void => {\n const panel = panelRef.value;\n\n if (!panel) return;\n\n // If the release event crosses the threshold (without an intervening\n // move event), commit close instead of snapping back to rest first.\n if (shouldCommitSwipeClose(distance, threshold)) {\n startSwipeClose(panel, getSwipeConfig(), distance);\n\n return;\n }\n\n resetPanelDragStyles(panel);\n };\n\n const swipe = createSwipeControl({\n axis: () => getSwipeConfig().axis,\n disabled: isSwipeClosing,\n onCancel: handleSwipeRelease,\n onCommit: ({ distance }) => {\n const panel = panelRef.value;\n\n if (!panel) return;\n\n startSwipeClose(panel, getSwipeConfig(), distance);\n },\n onMove: ({ distance, threshold }) => {\n const panel = panelRef.value;\n\n if (!panel) return;\n\n const swipeConfig = getSwipeConfig();\n const closingDistance = swipeConfig.closingDistance(distance);\n const progress = Math.min(closingDistance / threshold, 1);\n\n // Kill CSS transitions so the panel tracks the finger instantly.\n panel.style.transition = 'none';\n panel.style.transform = swipeConfig.translate(distance);\n panel.style.opacity = String(1 - progress * 0.4);\n },\n onRelease: handleSwipeRelease,\n shouldCommit: ({ distance, threshold }) => shouldCommitSwipeClose(distance, threshold),\n threshold: () => {\n const panel = panelRef.value;\n\n if (!panel) return 48;\n\n return getSnapThreshold(panel, getSwipeConfig().axis);\n },\n });\n\n // ────────────────────────────────────────────────────────────────\n // Overlay State Management\n // ────────────────────────────────────────────────────────────────\n\n const { closeWithAnimation, handleCancel, overlay, requestClose, watchOpenProp } = useDialogControl({\n beforeOpen: (dialog) => {\n // Clear any inline drag styles from a previous swipe-close so the CSS\n // entry animation starts from the correct base state.\n const panel = panelRef.value;\n\n if (panel) resetPanelDragStyles(panel);\n\n void dialog;\n },\n closeRequestDetail: (_reason) => ({ placement: props.placement.value ?? 'right' }),\n dialogRef,\n getPanelEl: () => panelRef.value,\n host: el,\n initialFocus: props['initial-focus'],\n isPersistent: () => Boolean(props.persistent.value),\n onCleanup,\n onEvent,\n onNativeClose: (reason) => {\n const panelEl = panelRef.value;\n\n // For swipe-close, keep the panel hidden and off-screen until the next\n // open cycle — resetting inline styles during native close can produce\n // a visible frame at the rest position on some browsers.\n if (panelEl && reason !== 'swipe') resetPanelDragStyles(panelEl);\n\n const dialog = dialogRef.value;\n\n if (dialog) dialog.style.transition = '';\n\n emit('close', { placement: props.placement.value ?? 'right', reason });\n },\n onOpen: (reason) => emit('open', { placement: props.placement.value ?? 'right', reason }),\n openProp: props.open,\n performClose: (dialog, reason) => {\n if (reason === 'swipe') {\n dialog.close();\n } else {\n closeWithAnimation();\n }\n },\n returnFocus: props['return-focus'],\n });\n\n const handleCloseButtonClick = () => {\n requestClose('trigger');\n };\n\n // ────────────────────────────────────────────────────────────────\n // Lifecycle: Setup Drawer Integration\n // ────────────────────────────────────────────────────────────────\n\n onMounted(() => {\n const dialog = dialogRef.value;\n\n if (!dialog) return;\n\n // Expose imperative API\n const drawerEl = el as DrawerElement;\n\n drawerEl.show = () => {\n overlay.open('programmatic');\n };\n\n drawerEl.hide = () => {\n overlay.close('programmatic', false);\n };\n\n // ────────────────────────────────────────────────────────────\n // Event Handlers: Cancel, Backdrop Click\n // ────────────────────────────────────────────────────────────\n // `handleCancel` (Escape via the native `cancel` event) is provided by\n // `useDialogControl` above — drawer only needs its own backdrop-click\n // handler since it has swipe-to-dismiss logic the shared dialog helper\n // doesn't know about.\n\n const handleBackdropClick = (e: MouseEvent) => {\n if (props.persistent.value) return;\n\n if (swipe.isActive() || isSwipeClosing.value) return;\n\n if (e.target !== dialog) return; // Click inside panel\n\n requestClose('outsideClick');\n };\n\n watchOpenProp();\n\n onEvent(dialog, 'cancel', handleCancel);\n onEvent(dialog, 'click', handleBackdropClick);\n\n // Drag-to-close handlers — scoped to the handle element only so interactions\n // with panel content don't accidentally start a drag.\n const panel = panelRef.value;\n const dragHandleEl = panel?.querySelector<HTMLElement>('[part=\"drag-handle\"]');\n\n if (dragHandleEl) {\n onEvent(dragHandleEl, 'pointerdown', swipe.handlePointerDown);\n onEvent(dragHandleEl, 'pointermove', swipe.handlePointerMove);\n onEvent(dragHandleEl, 'pointerup', swipe.handlePointerUp);\n onEvent(dragHandleEl, 'pointercancel', swipe.handlePointerCancel);\n }\n\n return () => {\n overlay.dispose();\n };\n });\n\n return html`\n <dialog\n ref=${dialogRef}\n aria-modal=\"true\"\n :aria-label=\"${() => props.label.value ?? null}\"\n :aria-labelledby=\"${() => (!props.label.value ? drawerLabelId : null)}\">\n <div class=\"panel\" part=\"panel\" ref=${panelRef}>\n <div class=\"drag-handle\" part=\"drag-handle\" aria-label=\"Drag to close\" role=\"button\"></div>\n <div class=\"header\" part=\"header\" ?hidden=${() => !hasHeader()}>\n <span class=\"header-title\" id=\"${drawerLabelId}\" ?hidden=${() => !hasHeaderTitle()}>\n <slot name=\"header\">${() => getHeaderText()}</slot>\n </span>\n <button\n class=\"close-btn\"\n part=\"close-btn\"\n type=\"button\"\n aria-label=\"Close\"\n ?hidden=${() => !props.dismissible.value}\n @click=${handleCloseButtonClick}>\n <ore-icon name=\"x\" size=\"16\" stroke-width=\"2.5\" aria-hidden=\"true\"></ore-icon>\n </button>\n </div>\n <div class=\"body\" part=\"body\">\n <slot></slot>\n </div>\n <div class=\"footer\" part=\"footer\" ?hidden=${() => !hasFooter()}>\n <slot name=\"footer\"></slot>\n </div>\n </div>\n </dialog>\n `;\n },\n styles: [elevationMixin, forcedColorsMixin, coarsePointerMixin, reducedMotionMixin, styles],\n});\n"],"mappings":";;;;;;;;AAiCA,IAAM,IAAgE;CACpE,QAAQ;EACN,MAAM;EACN,kBAAkB,MAAa,KAAK,IAAI,GAAG,CAAQ;EACnD,YAAY,MAAa,cAAc,EAAS;CAClD;CACA,MAAM;EACJ,MAAM;EACN,kBAAkB,MAAa,KAAK,IAAI,GAAG,CAAC,CAAQ;EACpD,YAAY,MAAa,cAAc,EAAS;CAClD;CACA,OAAO;EACL,MAAM;EACN,kBAAkB,MAAa,KAAK,IAAI,GAAG,CAAQ;EACnD,YAAY,MAAa,cAAc,EAAS;CAClD;CACA,KAAK;EACH,MAAM;EACN,kBAAkB,MAAa,KAAK,IAAI,GAAG,CAAC,CAAQ;EACpD,YAAY,MAAa,cAAc,EAAS;CAClD;AACF,GAyGa,IAAa;AAC1B,EAAuB,GAAY;CACjC,OAAO;EACL,UAAU,EAAK,OAAuB;EACtC,aAAa,EAAK,KAAK,EAAI;EAC3B,yBAAyB,EAAK,MAAM,CAAC,WAAW,OAAO,GAAY,SAAS;EAC5E,iBAAiB,EAAK,OAAO;EAC7B,OAAO,EAAK,OAAO;EACnB,MAAM,EAAK,KAAK,EAAK;EACrB,YAAY,EAAK,KAAK,EAAK;EAC3B,WAAW,EAAK,MAAM;GAAC;GAAQ;GAAS;GAAO;EAAQ,GAAY,OAAO;EAC1E,gBAAgB,EAAK,KAAK,EAAI;EAC9B,MAAM,EAAK,OAAmB;EAC9B,OAAO,EAAK,OAAO;CACrB;CACA,MAAM,GAAO;EACX,IAAM,IAAK,EAAQ,GACb,IAAO,EAAyB,GAChC,IAAQ,EAAS,GAEjB,IAAgB,EAAe,cAAc,GAC7C,IAAY,EAAuB,GACnC,IAAW,EAAoB,GAG/B,IAAiB,EAAO,EAAK,GAC/B,GAEE,UAAsB,EAAM,MAAM,SAAS,EAAM,MAAM,SAAS,IAChE,UAAuB,EAAM,IAAI,QAAQ,CAAC,CAAC,SAAS,CAAC,CAAC,EAAc,GAGpE,UAAkB,EAAe,KAAK,EAAM,YAAY,OACxD,UAAkB,EAAM,IAAI,QAAQ,CAAC,CAAC,OAEtC,UAAsC,EAAM,UAAU,SAAS,SAE/D,UAA0C,EAAkB,EAAa,IAEzE,KAAoB,GAAoB,MAAoB;GAChE,IAAM,IAAY,MAAS,MAAM,EAAM,cAAc,EAAM;GAE3D,OAAO,KAAK,IAAI,IAAI,KAAK,IAAI,IAAI,IAAY,GAAI,CAAC;EACpD,GAEM,KAA0B,GAAkB,MACzC,EAAe,CAAC,CAAC,gBAAgB,CAAQ,KAAK,GAGjD,KAAsB,MAAuB;GACjD,IAAI,CAAC,EAAe,OAAO;GAE3B,AAEE,OADA,aAAa,CAAe,GACV,KAAA;GAGpB,IAAM,IAAS,EAAU;GAEzB,IAAI,CAAC,GAAQ;IACX,EAAe,QAAQ;IAEvB;GACF;GAOA,AALA,EAAO,MAAM,aAAa,QAC1B,EAAM,MAAM,UAAU,KACtB,EAAM,MAAM,aAAa,UACzB,EAAY,aAEZ,EAAa,OAAO;EACtB,GAEM,KAAmB,GAAoB,GAA0B,MAA8B;GACnG,IAAI,EAAe,OAAO;GAE1B,EAAe,QAAQ;GAEvB,IAAM,IAAY,EAAM,SAAS,MAAM,EAAM,cAAc,EAAM,cAE3D,IACJ,KAAqB,IAAI,KAAK,IAAI,GAAmB,CAAS,IAAI,KAAK,IAAI,GAAmB,CAAC,CAAS,GACpG,IAAgB,EAAM,UAAU,CAAY;GAKlD,AADA,EAAM,MAAM,aAAa,0EACzB,EAAW;GAEX,IAAM,KAAuB,MAAwB;IAC/C,EAAG,WAAW,KAAS,EAAG,iBAAiB,gBAE/C,EAAM,oBAAoB,iBAAiB,CAAmB,GAC9D,EAAmB,CAAK;GAC1B;GAEA,EAAM,iBAAiB,iBAAiB,CAAmB;GAE3D,IAAM,IAAa,WAAW,iBAAiB,CAAK,CAAC,CAAC,kBAAkB,IAAI;GAQ5E,AANA,IAAkB,iBAAiB;IAEjC,AADA,EAAM,oBAAoB,iBAAiB,CAAmB,GAC9D,EAAmB,CAAK;GAC1B,GAAG,IAAa,EAAE,GAElB,EAAM,MAAM,YAAY,GACxB,EAAM,MAAM,UAAU;EACxB,GAEM,KAAwB,MAAuB;GAWnD,AAVA,AAEE,OADA,aAAa,CAAe,GACV,KAAA,IAIpB,EAAM,MAAM,aAAa,IACzB,EAAM,MAAM,YAAY,IACxB,EAAM,MAAM,UAAU,IACtB,EAAM,MAAM,aAAa,IACzB,EAAe,QAAQ;EACzB,GAKM,KAAsB,EAAE,aAAU,mBAA+D;GACrG,IAAM,IAAQ,EAAS;GAElB,OAIL;QAAI,EAAuB,GAAU,CAAS,GAAG;KAC/C,EAAgB,GAAO,EAAe,GAAG,CAAQ;KAEjD;IACF;IAEA,EAAqB,CAAK;GAF1B;EAGF,GAEM,IAAQ,EAAmB;GAC/B,YAAY,EAAe,CAAC,CAAC;GAC7B,UAAU;GACV,UAAU;GACV,WAAW,EAAE,kBAAe;IAC1B,IAAM,IAAQ,EAAS;IAElB,KAEL,EAAgB,GAAO,EAAe,GAAG,CAAQ;GACnD;GACA,SAAS,EAAE,aAAU,mBAAgB;IACnC,IAAM,IAAQ,EAAS;IAEvB,IAAI,CAAC,GAAO;IAEZ,IAAM,IAAc,EAAe,GAC7B,IAAkB,EAAY,gBAAgB,CAAQ,GACtD,IAAW,KAAK,IAAI,IAAkB,GAAW,CAAC;IAKxD,AAFA,EAAM,MAAM,aAAa,QACzB,EAAM,MAAM,YAAY,EAAY,UAAU,CAAQ,GACtD,EAAM,MAAM,UAAU,OAAO,IAAI,IAAW,EAAG;GACjD;GACA,WAAW;GACX,eAAe,EAAE,aAAU,mBAAgB,EAAuB,GAAU,CAAS;GACrF,iBAAiB;IACf,IAAM,IAAQ,EAAS;IAIvB,OAFK,IAEE,EAAiB,GAAO,EAAe,CAAC,CAAC,IAAI,IAFjC;GAGrB;EACF,CAAC,GAMK,EAAE,uBAAoB,iBAAc,YAAS,iBAAc,qBAAkB,EAAiB;GAClG,aAAa,MAAW;IAGtB,IAAM,IAAQ,EAAS;IAEvB,AAAI,KAAO,EAAqB,CAAK;GAGvC;GACA,qBAAqB,OAAa,EAAE,WAAW,EAAM,UAAU,SAAS,QAAQ;GAChF;GACA,kBAAkB,EAAS;GAC3B,MAAM;GACN,cAAc,EAAM;GACpB,oBAAoB,EAAQ,EAAM,WAAW;GAC7C;GACA;GACA,gBAAgB,MAAW;IACzB,IAAM,IAAU,EAAS;IAKzB,AAAI,KAAW,MAAW,WAAS,EAAqB,CAAO;IAE/D,IAAM,IAAS,EAAU;IAIzB,AAFI,MAAQ,EAAO,MAAM,aAAa,KAEtC,EAAK,SAAS;KAAE,WAAW,EAAM,UAAU,SAAS;KAAS;IAAO,CAAC;GACvE;GACA,SAAS,MAAW,EAAK,QAAQ;IAAE,WAAW,EAAM,UAAU,SAAS;IAAS;GAAO,CAAC;GACxF,UAAU,EAAM;GAChB,eAAe,GAAQ,MAAW;IAChC,AAAI,MAAW,UACb,EAAO,MAAM,IAEb,EAAmB;GAEvB;GACA,aAAa,EAAM;EACrB,CAAC;EAkED,OAxDA,QAAgB;GACd,IAAM,IAAS,EAAU;GAEzB,IAAI,CAAC,GAAQ;GAGb,IAAM,IAAW;GA+BjB,AA7BA,EAAS,aAAa;IACpB,EAAQ,KAAK,cAAc;GAC7B,GAEA,EAAS,aAAa;IACpB,EAAQ,MAAM,gBAAgB,EAAK;GACrC,GAoBA,EAAc,GAEd,EAAQ,GAAQ,UAAU,CAAY,GACtC,EAAQ,GAAQ,UAba,MAAkB;IACzC,EAAM,WAAW,SAEjB,EAAM,SAAS,KAAK,EAAe,SAEnC,EAAE,WAAW,KAEjB,EAAa,cAAc;GAC7B,CAK4C;GAK5C,IAAM,IADQ,EAAS,OACK,cAA2B,wBAAsB;GAS7E,OAPI,MACF,EAAQ,GAAc,eAAe,EAAM,iBAAiB,GAC5D,EAAQ,GAAc,eAAe,EAAM,iBAAiB,GAC5D,EAAQ,GAAc,aAAa,EAAM,eAAe,GACxD,EAAQ,GAAc,iBAAiB,EAAM,mBAAmB,UAGrD;IACX,EAAQ,QAAQ;GAClB;EACF,CAAC,GAEM,CAAI;;cAED,EAAU;;6BAEK,EAAM,MAAM,SAAS,KAAK;kCACnB,EAAM,MAAM,QAAwB,OAAhB,EAAsB;8CAChC,EAAS;;4DAEK,CAAC,EAAU,EAAE;6CAC5B,EAAc,kBAAkB,CAAC,EAAe,EAAE;0CACrD,EAAc,EAAE;;;;;;;8BAO5B,CAAC,EAAM,YAAY,MAAM;6BAjFd;GACnC,EAAa,SAAS;EACxB,EAgF0C;;;;;;;4DAOc,CAAC,EAAU,EAAE;;;;;;CAMvE;CACA,QAAQ;EAAC;EAAgB;EAAmB;EAAoB;EAAoB;CAAM;AAC5F,CAAC"}
|
|
1
|
+
{"version":3,"file":"drawer.js","names":[],"sources":["../src/overlay/drawer/drawer.ts"],"sourcesContent":["import {\n createStableId,\n define,\n html,\n prop,\n ref,\n getHost,\n onCleanup,\n onEvent,\n onMounted,\n useEmit,\n useSlots,\n} from '@vielzeug/ore';\nimport { signal } from '@vielzeug/ripple';\n\nimport type { OverlayCloseDetail, OverlayOpenDetail, SwipeAxis } from '../../headless';\n\nimport { createSwipeControl } from '../../headless';\nimport '../../content/icon/icon';\nimport { coarsePointerMixin, forcedColorsMixin, reducedMotionMixin } from '../../styles';\nimport { useDialogControl } from '../shared/use-dialog';\nimport styles from './drawer.css?inline';\n\ntype DrawerPlacement = 'left' | 'right' | 'top' | 'bottom';\ntype DrawerSize = 'sm' | 'lg' | 'full';\ntype DrawerBackdrop = 'opaque' | 'blur' | 'transparent';\ntype DrawerDragHandlePlacement = 'outside' | 'inset';\ntype DrawerSwipeConfig = {\n axis: SwipeAxis;\n closingDistance: (distance: number) => number;\n translate: (distance: number) => string;\n};\n\nconst drawerSwipeConfig: Record<DrawerPlacement, DrawerSwipeConfig> = {\n bottom: {\n axis: 'y',\n closingDistance: (distance) => Math.max(0, distance),\n translate: (distance) => `translateY(${distance}px)`,\n },\n left: {\n axis: 'x',\n closingDistance: (distance) => Math.max(0, -distance),\n translate: (distance) => `translateX(${distance}px)`,\n },\n right: {\n axis: 'x',\n closingDistance: (distance) => Math.max(0, distance),\n translate: (distance) => `translateX(${distance}px)`,\n },\n top: {\n axis: 'y',\n closingDistance: (distance) => Math.max(0, -distance),\n translate: (distance) => `translateY(${distance}px)`,\n },\n};\n\n/** Element interface exposing the imperative API for `ore-drawer`. */\nexport interface DrawerElement extends HTMLElement, Omit<OreDrawerProps, 'title'> {\n /** Programmatically open the drawer. Equivalent to setting `open`. */\n show(): void;\n /** Programmatically close the drawer with the exit animation. */\n hide(): void;\n}\n\n/** Drawer component properties */\n\nexport type OreDrawerEvents = {\n close: OverlayCloseDetail & { placement: DrawerPlacement };\n open: OverlayOpenDetail & { placement: DrawerPlacement };\n};\n\nexport type OreDrawerProps = {\n /** Backdrop style — 'opaque' (default), 'blur', or 'transparent' */\n backdrop?: DrawerBackdrop;\n /** Show the close (×) button in the header (default: true) */\n dismissible?: boolean;\n /** Drag handle position used for swipe-to-close gestures */\n 'drag-handle-placement'?: DrawerDragHandlePlacement;\n /**\n * CSS selector for the element inside the drawer that should receive focus on open.\n * Defaults to native dialog focus management (first focusable element).\n * @example '#submit-btn' | 'input[name=\"email\"]'\n */\n 'initial-focus'?: string;\n /**\n * Invisible accessible label for the dialog (`aria-label`).\n * Use when the drawer has no visible title (e.g. image-only content).\n * When omitted, `aria-labelledby` points to the visible header title instead.\n */\n label?: string;\n /** Controlled open state */\n open?: boolean;\n /** When true, backdrop clicks do not close the drawer (default: false) */\n persistent?: boolean;\n /** Side from which the drawer slides in */\n placement?: DrawerPlacement;\n /**\n * When true (default), focus returns to the triggering element after the drawer closes.\n * Set to false to manage focus manually.\n */\n 'return-focus'?: boolean;\n /** Drawer width/height preset */\n size?: DrawerSize;\n /**\n * Visible title text rendered inside the header.\n * Used as the dialog's accessible label via `aria-labelledby` when `label` is not set.\n */\n title?: string;\n};\n\n/**\n * A panel that slides in from any edge of the screen, built on the native `<dialog>` element.\n *\n * @element ore-drawer\n *\n * @attr {boolean} open - Controlled open/close state\n * @attr {string} placement - 'left' | 'right' (default) | 'top' | 'bottom'\n * @attr {string} size - 'sm' | 'lg' | 'full'\n * @attr {string} title - Visible header title text\n * @attr {string} label - Invisible aria-label (for drawers without a visible title)\n * @attr {boolean} dismissible - Show the close (×) button (default: true)\n * @attr {string} drag-handle-placement - 'outside' (default) | 'inset'\n * @attr {string} backdrop - Backdrop style: 'opaque' (default) | 'blur' | 'transparent'\n * @attr {boolean} persistent - Prevent backdrop-click from closing (default: false)\n *\n * @fires open - When the drawer opens with detail: { placement, reason }\n * @fires close - When the drawer closes with detail: { placement, reason }\n *\n * @slot header - Drawer header content\n * @slot - Main body content\n * @slot footer - Drawer footer content\n *\n * @cssprop --drawer-backdrop-bg - Backdrop background color\n * @cssprop --drawer-bg - Panel background color\n * @cssprop --drawer-size - Panel width (horizontal) or height (vertical)\n * @cssprop --drawer-shadow - Panel box-shadow\n * @cssprop --drawer-panel-blur - Panel backdrop blur amount\n *\n * @part drag-handle - Drawer drag handle.\n * @part panel - Panel container.\n * @part header - Header container.\n * @part close-btn - Close button.\n * @part body - Body content container.\n * @part footer - Footer container.\n * @example\n * ```html\n * <!-- With visible title -->\n * <ore-drawer open title=\"Settings\" placement=\"right\">\n * <p>Settings content here.</p>\n * </ore-drawer>\n *\n * <!-- With custom header slot -->\n * <ore-drawer open placement=\"right\">\n * <span slot=\"header\">Settings</span>\n * <p>Settings content here.</p>\n * </ore-drawer>\n * ```\n */\n\nexport const DRAWER_TAG = 'ore-drawer' as const;\ndefine<OreDrawerProps>(DRAWER_TAG, {\n props: {\n backdrop: prop.string<DrawerBackdrop>(),\n dismissible: prop.bool(true),\n 'drag-handle-placement': prop.oneOf(['outside', 'inset'] as const, 'outside'),\n 'initial-focus': prop.string(),\n label: prop.string(),\n open: prop.bool(false),\n persistent: prop.bool(false),\n placement: prop.oneOf(['left', 'right', 'top', 'bottom'] as const, 'right'),\n 'return-focus': prop.bool(true),\n size: prop.string<DrawerSize>(),\n title: prop.string(),\n },\n setup(props) {\n const el = getHost();\n const emit = useEmit<OreDrawerEvents>();\n const slots = useSlots();\n\n const drawerLabelId = createStableId('drawer-label');\n const dialogRef = ref<HTMLDialogElement>();\n const panelRef = ref<HTMLDivElement>();\n\n // Drag-to-close state\n const isSwipeClosing = signal(false);\n let swipeCloseTimer: ReturnType<typeof setTimeout> | undefined;\n\n const getHeaderText = () => props.label.value ?? props.title.value ?? '';\n const hasHeaderTitle = () => slots.has('header').value || !!getHeaderText();\n\n // Header is visible when there is slot content, a text label, or a close button.\n const hasHeader = () => hasHeaderTitle() || props.dismissible.value;\n const hasFooter = () => slots.has('footer').value;\n\n const getPlacement = (): DrawerPlacement => props.placement.value || 'right';\n\n const getSwipeConfig = (): DrawerSwipeConfig => drawerSwipeConfig[getPlacement()];\n\n const getSnapThreshold = (panel: HTMLElement, axis: SwipeAxis) => {\n const panelSize = axis === 'x' ? panel.offsetWidth : panel.offsetHeight;\n\n return Math.min(96, Math.max(36, panelSize * 0.18));\n };\n\n const shouldCommitSwipeClose = (distance: number, threshold: number) => {\n return getSwipeConfig().closingDistance(distance) >= threshold;\n };\n\n const finalizeSwipeClose = (panel: HTMLElement) => {\n if (!isSwipeClosing.value) return;\n\n if (swipeCloseTimer) {\n clearTimeout(swipeCloseTimer);\n swipeCloseTimer = undefined;\n }\n\n const dialog = dialogRef.value;\n\n if (!dialog) {\n isSwipeClosing.value = false;\n\n return;\n }\n\n dialog.style.transition = 'none';\n panel.style.opacity = '0';\n panel.style.visibility = 'hidden';\n void dialog.offsetWidth;\n\n requestClose('swipe');\n };\n\n const startSwipeClose = (panel: HTMLElement, swipe: DrawerSwipeConfig, committedDistance: number) => {\n if (isSwipeClosing.value) return;\n\n isSwipeClosing.value = true;\n\n const panelSize = swipe.axis === 'x' ? panel.offsetWidth : panel.offsetHeight;\n // Preserve overshoot so closing continues from the dragged position instead of snapping back.\n const exitDistance =\n committedDistance >= 0 ? Math.max(committedDistance, panelSize) : Math.min(committedDistance, -panelSize);\n const exitTransform = swipe.translate(exitDistance);\n\n // Commit the current drag position first so the magnetic snap continues\n // from the finger instead of jumping back to rest.\n panel.style.transition = 'transform 180ms cubic-bezier(0.2, 0.9, 0.2, 1), opacity 180ms ease-out';\n void panel.offsetWidth;\n\n const onExitTransitionEnd = (ev: TransitionEvent) => {\n if (ev.target !== panel || ev.propertyName !== 'transform') return;\n\n panel.removeEventListener('transitionend', onExitTransitionEnd);\n finalizeSwipeClose(panel);\n };\n\n panel.addEventListener('transitionend', onExitTransitionEnd);\n\n const durationMs = parseFloat(getComputedStyle(panel).transitionDuration) * 1000;\n\n swipeCloseTimer = setTimeout(() => {\n panel.removeEventListener('transitionend', onExitTransitionEnd);\n finalizeSwipeClose(panel);\n }, durationMs + 50);\n\n panel.style.transform = exitTransform;\n panel.style.opacity = '0.2';\n };\n\n const resetPanelDragStyles = (panel: HTMLElement) => {\n if (swipeCloseTimer) {\n clearTimeout(swipeCloseTimer);\n swipeCloseTimer = undefined;\n }\n\n // Re-enable transitions so the snap-back or exit animates.\n panel.style.transition = '';\n panel.style.transform = '';\n panel.style.opacity = '';\n panel.style.visibility = '';\n isSwipeClosing.value = false;\n };\n\n // Same \"snap back or commit close\" decision whether the swipe was\n // interrupted by the platform (onCancel) or simply released without an\n // intervening move event crossing the threshold (onRelease).\n const handleSwipeRelease = ({ distance, threshold }: { distance: number; threshold: number }): void => {\n const panel = panelRef.value;\n\n if (!panel) return;\n\n // If the release event crosses the threshold (without an intervening\n // move event), commit close instead of snapping back to rest first.\n if (shouldCommitSwipeClose(distance, threshold)) {\n startSwipeClose(panel, getSwipeConfig(), distance);\n\n return;\n }\n\n resetPanelDragStyles(panel);\n };\n\n const swipe = createSwipeControl({\n axis: () => getSwipeConfig().axis,\n disabled: isSwipeClosing,\n onCancel: handleSwipeRelease,\n onCommit: ({ distance }) => {\n const panel = panelRef.value;\n\n if (!panel) return;\n\n startSwipeClose(panel, getSwipeConfig(), distance);\n },\n onMove: ({ distance, threshold }) => {\n const panel = panelRef.value;\n\n if (!panel) return;\n\n const swipeConfig = getSwipeConfig();\n const closingDistance = swipeConfig.closingDistance(distance);\n const progress = Math.min(closingDistance / threshold, 1);\n\n // Kill CSS transitions so the panel tracks the finger instantly.\n panel.style.transition = 'none';\n panel.style.transform = swipeConfig.translate(distance);\n panel.style.opacity = String(1 - progress * 0.4);\n },\n onRelease: handleSwipeRelease,\n shouldCommit: ({ distance, threshold }) => shouldCommitSwipeClose(distance, threshold),\n threshold: () => {\n const panel = panelRef.value;\n\n if (!panel) return 48;\n\n return getSnapThreshold(panel, getSwipeConfig().axis);\n },\n });\n\n // ────────────────────────────────────────────────────────────────\n // Overlay State Management\n // ────────────────────────────────────────────────────────────────\n\n const { closeWithAnimation, handleCancel, overlay, requestClose, watchOpenProp } = useDialogControl({\n beforeOpen: (dialog) => {\n // Clear any inline drag styles from a previous swipe-close so the CSS\n // entry animation starts from the correct base state.\n const panel = panelRef.value;\n\n if (panel) resetPanelDragStyles(panel);\n\n void dialog;\n },\n closeRequestDetail: (_reason) => ({ placement: props.placement.value ?? 'right' }),\n dialogRef,\n getPanelEl: () => panelRef.value,\n host: el,\n initialFocus: props['initial-focus'],\n isPersistent: () => Boolean(props.persistent.value),\n onCleanup,\n onEvent,\n onNativeClose: (reason) => {\n const panelEl = panelRef.value;\n\n // For swipe-close, keep the panel hidden and off-screen until the next\n // open cycle — resetting inline styles during native close can produce\n // a visible frame at the rest position on some browsers.\n if (panelEl && reason !== 'swipe') resetPanelDragStyles(panelEl);\n\n const dialog = dialogRef.value;\n\n if (dialog) dialog.style.transition = '';\n\n emit('close', { placement: props.placement.value ?? 'right', reason });\n },\n onOpen: (reason) => emit('open', { placement: props.placement.value ?? 'right', reason }),\n openProp: props.open,\n performClose: (dialog, reason) => {\n if (reason === 'swipe') {\n dialog.close();\n } else {\n closeWithAnimation();\n }\n },\n returnFocus: props['return-focus'],\n });\n\n const handleCloseButtonClick = () => {\n requestClose('trigger');\n };\n\n // ────────────────────────────────────────────────────────────────\n // Lifecycle: Setup Drawer Integration\n // ────────────────────────────────────────────────────────────────\n\n onMounted(() => {\n const dialog = dialogRef.value;\n\n if (!dialog) return;\n\n // Expose imperative API\n const drawerEl = el as DrawerElement;\n\n drawerEl.show = () => {\n overlay.open('programmatic');\n };\n\n drawerEl.hide = () => {\n overlay.close('programmatic', false);\n };\n\n // ────────────────────────────────────────────────────────────\n // Event Handlers: Cancel, Backdrop Click\n // ────────────────────────────────────────────────────────────\n // `handleCancel` (Escape via the native `cancel` event) is provided by\n // `useDialogControl` above — drawer only needs its own backdrop-click\n // handler since it has swipe-to-dismiss logic the shared dialog helper\n // doesn't know about.\n\n const handleBackdropClick = (e: MouseEvent) => {\n if (props.persistent.value) return;\n\n if (swipe.isActive() || isSwipeClosing.value) return;\n\n if (e.target !== dialog) return; // Click inside panel\n\n requestClose('outsideClick');\n };\n\n watchOpenProp();\n\n onEvent(dialog, 'cancel', handleCancel);\n onEvent(dialog, 'click', handleBackdropClick);\n\n // Drag-to-close handlers — scoped to the handle element only so interactions\n // with panel content don't accidentally start a drag.\n const panel = panelRef.value;\n const dragHandleEl = panel?.querySelector<HTMLElement>('[part=\"drag-handle\"]');\n\n if (dragHandleEl) {\n onEvent(dragHandleEl, 'pointerdown', swipe.handlePointerDown);\n onEvent(dragHandleEl, 'pointermove', swipe.handlePointerMove);\n onEvent(dragHandleEl, 'pointerup', swipe.handlePointerUp);\n onEvent(dragHandleEl, 'pointercancel', swipe.handlePointerCancel);\n }\n\n return () => {\n overlay.dispose();\n };\n });\n\n return html`\n <dialog\n ref=${dialogRef}\n aria-modal=\"true\"\n :aria-label=\"${() => props.label.value ?? null}\"\n :aria-labelledby=\"${() => (!props.label.value ? drawerLabelId : null)}\">\n <div class=\"panel\" part=\"panel\" ref=${panelRef}>\n <div class=\"drag-handle\" part=\"drag-handle\" aria-label=\"Drag to close\" role=\"button\"></div>\n <div class=\"header\" part=\"header\" ?hidden=${() => !hasHeader()}>\n <span class=\"header-title\" id=\"${drawerLabelId}\" ?hidden=${() => !hasHeaderTitle()}>\n <slot name=\"header\">${() => getHeaderText()}</slot>\n </span>\n <button\n class=\"close-btn\"\n part=\"close-btn\"\n type=\"button\"\n aria-label=\"Close\"\n ?hidden=${() => !props.dismissible.value}\n @click=${handleCloseButtonClick}>\n <ore-icon name=\"x\" size=\"16\" stroke-width=\"2.5\" aria-hidden=\"true\"></ore-icon>\n </button>\n </div>\n <div class=\"body\" part=\"body\">\n <slot></slot>\n </div>\n <div class=\"footer\" part=\"footer\" ?hidden=${() => !hasFooter()}>\n <slot name=\"footer\"></slot>\n </div>\n </div>\n </dialog>\n `;\n },\n styles: [forcedColorsMixin, coarsePointerMixin, reducedMotionMixin, styles],\n});\n"],"mappings":"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"}
|
package/dist/file-input.cjs
CHANGED
|
@@ -1,37 +1,41 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./styles/mixins/shape.css.cjs"),t=require("./styles/mixins/theme.css.cjs"),n=require("./styles/index.cjs"),r=require("./shared/size-presets.cjs"),i=require("./headless/
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./styles/mixins/shape.css.cjs"),t=require("./styles/mixins/theme.css.cjs"),n=require("./styles/index.cjs"),r=require("./shared/size-presets.cjs"),i=require("./headless/ref-callback.cjs"),a=require("./headless/keyboard.cjs"),o=require("./inputs/shared/form-context.cjs"),s=require("./inputs/file-input/file-input-upload.cjs"),c=require("./inputs/file-input/file-input.css.cjs");let l=require("@vielzeug/ore"),u=require("@vielzeug/ore/directives"),d=require("@vielzeug/ripple"),f=require("@vielzeug/ore/forms"),p=require("@vielzeug/dnd");var m=e=>e.type.startsWith(`image/`),h=`ore-file-input`;(0,l.define)(h,{formAssociated:!0,props:{accept:l.prop.string(),color:l.prop.string(),disabled:l.prop.bool(!1),error:l.prop.string(),gallery:l.prop.bool(!1),helper:l.prop.string(),label:l.prop.string(),"max-files":l.prop.number(0),"max-size":l.prop.number(0),multiple:l.prop.bool(!1),name:l.prop.string(),ref:l.prop.data(),required:l.prop.bool(!1),size:l.prop.string(),upload:l.prop.data()},setup(e){let t=(0,l.useEmit)(),n=(0,d.signal)(!1),r=(0,d.signal)(null),c=o.useFormContext(e,(0,l.inject)(o.FORM_CTX)),h=c.disabled,g=(0,d.computed)(()=>e[`max-files`].value??0),_=(0,d.computed)(()=>e[`max-size`].value??0),v=s.createFileQueue({accept:e.accept,disabled:h,maxFiles:g,maxSize:_,multiple:(0,d.computed)(()=>!!e.multiple.value),onChange:(e,n)=>t(`change`,{files:e,originalEvent:n,value:e}),onRemove:(e,n,r)=>t(`remove`,{file:e,files:n,originalEvent:r,value:n}),onUploadError:(e,n)=>t(`upload-error`,{error:n,file:e}),onUploadProgress:(e,n,r)=>t(`upload-progress`,{file:e,loaded:n,total:r}),onUploadSuccess:e=>t(`upload-success`,{file:e}),upload:(0,d.computed)(()=>e.upload.value??void 0)});(0,l.onCleanup)(()=>v.dispose()),(0,f.useField)({disabled:h,toFormValue:t=>{if(t.length===0)return null;let n=e.name.value||`file`,r=new FormData;for(let e of t)r.append(n,e);return r},value:v.files});let y=(0,d.computed)(()=>!!e.error.value);(0,l.bind)({attr:{"drag-over":()=>n.value?!0:void 0,invalid:()=>y.value?!0:void 0,size:c.size}});let b=(0,l.createStableId)(`file-input`),x=`label-${b}`,S=`helper-${b}`,C=`error-${b}`,w=(0,l.ref)(),T=(0,l.ref)(),E=(0,d.computed)(()=>{let t=[];e.accept.value&&t.push(e.accept.value.split(`,`).map(e=>e.trim()).join(`, `));let n=_.value;n>0&&t.push(`max ${s.formatBytes(n)}`);let r=g.value;return r>0&&t.push(`up to ${r} file${r===1?``:`s`}`),t.join(` · `)});function D(e){r.value=e,T.value?.click()}let O=new Map;function k(e){let t=O.get(e);return t||(t=URL.createObjectURL(e),O.set(e,t)),t}function A(e){let t=new Set(e);for(let[e,n]of O)t.has(e)||(URL.revokeObjectURL(n),O.delete(e))}return(0,d.watch)(v.files,A),(0,l.onCleanup)(()=>{for(let e of O.values())URL.revokeObjectURL(e);O.clear()}),(0,l.onElement)(T,t=>i.bindRefCallback(e.ref,t)),(0,l.onMounted)(()=>{let e=T.value,t=w.value,i=!1,o=a.createInteraction({disabled:h,onPress:()=>{e.click()}});(0,l.onEvent)(e,`change`,e=>{let t=e.target,n=r.value;r.value=null,n&&t.files?.[0]?v.replaceFile(n,t.files[0],e):t.files?.length&&v.addFiles(Array.from(t.files),e),t.value=``}),(0,l.onEvent)(t,`click`,t=>{if(t.target!==e){if(i){i=!1;return}h.value||e.click()}}),(0,l.onEvent)(t,`keydown`,e=>{i=o.handleKeydown(e)&&e.key===`Enter`}),(0,d.watch)(h,e=>{let r=(0,p.createDropZone)({disabled:e,element:t,onDrop:e=>v.addFiles(e),onHoverChange:e=>{n.value=e}});return()=>r.dispose()},{immediate:!0})}),l.html`
|
|
2
2
|
<div class="file-input-wrapper" part="wrapper">
|
|
3
|
-
<label class="label-outside" id="${
|
|
3
|
+
<label class="label-outside" id="${x}" part="label" ?hidden=${()=>!e.label.value}
|
|
4
4
|
>${e.label}</label
|
|
5
5
|
>
|
|
6
6
|
<div
|
|
7
7
|
class="dropzone"
|
|
8
8
|
part="dropzone"
|
|
9
|
-
ref=${
|
|
9
|
+
ref=${w}
|
|
10
10
|
role="button"
|
|
11
|
-
:tabindex="${()=>
|
|
12
|
-
:aria-disabled="${()=>String(
|
|
11
|
+
:tabindex="${()=>h.value?`-1`:`0`}"
|
|
12
|
+
:aria-disabled="${()=>String(h.value)}"
|
|
13
13
|
:aria-label="${()=>e.label.value?null:`File upload drop zone`}"
|
|
14
|
-
:aria-labelledby="${()=>e.label.value?
|
|
15
|
-
aria-describedby="${
|
|
14
|
+
:aria-labelledby="${()=>e.label.value?x:null}"
|
|
15
|
+
aria-describedby="${S}">
|
|
16
16
|
<input
|
|
17
17
|
type="file"
|
|
18
|
-
ref=${
|
|
18
|
+
ref=${T}
|
|
19
19
|
part="input"
|
|
20
|
-
id="${
|
|
20
|
+
id="${b}"
|
|
21
21
|
:accept="${e.accept}"
|
|
22
22
|
?multiple="${e.multiple}"
|
|
23
23
|
?required="${e.required}"
|
|
24
|
-
?disabled="${
|
|
24
|
+
?disabled="${h}"
|
|
25
25
|
:name="${e.name}"
|
|
26
26
|
hidden
|
|
27
27
|
inert
|
|
28
28
|
tabindex="-1" />
|
|
29
29
|
<div class="dropzone-content">
|
|
30
|
-
<span class="dropzone-icon" aria-hidden="true">
|
|
31
|
-
|
|
30
|
+
<span class="dropzone-icon" aria-hidden="true" :data-status="${()=>y.value?`error`:null}">
|
|
31
|
+
${()=>y.value?l.html`<ore-icon name="alert-circle" size="36" stroke-width="1.5" aria-hidden="true"></ore-icon>`:l.html`<ore-icon name="upload" size="36" stroke-width="1.5" aria-hidden="true"></ore-icon>`}
|
|
32
32
|
</span>
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
<!-- Signal 01: the copy itself shifts on drag-entry (not just border/glow) — a
|
|
34
|
+
static "Drop files here" during an active drag reads as if the drop target
|
|
35
|
+
hasn't noticed the file yet. -->
|
|
36
|
+
${(0,u.when)(()=>n.value,()=>l.html`<span class="dropzone-title dropzone-title-active">Release to upload</span>`)}
|
|
37
|
+
${(0,u.when)(()=>!n.value,()=>l.html`<span class="dropzone-title">Drop files here or <u>click to browse</u></span>`)}
|
|
38
|
+
<span class="dropzone-hint" ?hidden=${()=>!E.value}>${E}</span>
|
|
35
39
|
</div>
|
|
36
40
|
</div>
|
|
37
41
|
<ul
|
|
@@ -39,54 +43,116 @@ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=requi
|
|
|
39
43
|
part="${()=>e.gallery.value?`gallery`:null}"
|
|
40
44
|
role="list"
|
|
41
45
|
aria-label="Selected files"
|
|
42
|
-
?hidden=${()=>
|
|
43
|
-
${()=>
|
|
44
|
-
<li class="file-card">
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
46
|
+
?hidden=${()=>v.files.value.length===0}>
|
|
47
|
+
${()=>v.files.value.map(t=>e.gallery.value?l.html`
|
|
48
|
+
<li class="file-card" data-status=${()=>v.fileState(t).status}>
|
|
49
|
+
<span class="file-thumb-frame">
|
|
50
|
+
${m(t)?l.html`<img
|
|
51
|
+
class="file-thumb"
|
|
52
|
+
alt=""
|
|
53
|
+
ref="${e=>{e&&(e.src=k(t))}}" />`:l.html`<span class="file-thumb file-thumb-generic" aria-hidden="true">
|
|
54
|
+
<ore-icon name="file" size="28" stroke-width="1.5" aria-hidden="true"></ore-icon>
|
|
55
|
+
</span>`}
|
|
56
|
+
${(0,u.when)(()=>v.fileState(t).status===`success`,()=>l.html`<span class="file-status-badge file-status-badge-success" aria-hidden="true">
|
|
57
|
+
<ore-icon name="check" size="11" stroke-width="3" aria-hidden="true"></ore-icon>
|
|
58
|
+
</span>`)}
|
|
59
|
+
${(0,u.when)(()=>v.fileState(t).status===`error`,()=>l.html`<span class="file-status-badge file-status-badge-error" aria-hidden="true">
|
|
60
|
+
<ore-icon name="alert-circle" size="12" stroke-width="2.5" aria-hidden="true"></ore-icon>
|
|
61
|
+
</span>`)}
|
|
62
|
+
<span class="file-card-actions">
|
|
63
|
+
${(0,u.when)(()=>v.fileState(t).status===`error`,()=>l.html`<button
|
|
64
|
+
class="file-card-action"
|
|
65
|
+
type="button"
|
|
66
|
+
aria-label="${`Retry uploading ${t.name}`}"
|
|
67
|
+
@click=${()=>v.retryUpload(t)}>
|
|
68
|
+
<ore-icon name="refresh-cw" size="12" stroke-width="2.5" aria-hidden="true"></ore-icon>
|
|
69
|
+
</button>`)}
|
|
70
|
+
${(0,u.when)(()=>v.fileState(t).status===`success`&&!!e.multiple.value&&!!e.upload.value,()=>l.html`<button
|
|
71
|
+
class="file-card-action"
|
|
72
|
+
type="button"
|
|
73
|
+
aria-label="${`Replace ${t.name}`}"
|
|
74
|
+
@click=${()=>D(t)}>
|
|
75
|
+
<ore-icon name="upload" size="12" stroke-width="2.5" aria-hidden="true"></ore-icon>
|
|
76
|
+
</button>`)}
|
|
77
|
+
<button
|
|
78
|
+
class="file-card-action file-card-remove"
|
|
79
|
+
type="button"
|
|
80
|
+
aria-label="${`Remove ${t.name}`}"
|
|
81
|
+
@click=${e=>v.removeFile(t,e)}>
|
|
82
|
+
<ore-icon name="x" size="12" stroke-width="2.5" aria-hidden="true"></ore-icon>
|
|
83
|
+
</button>
|
|
84
|
+
</span>
|
|
85
|
+
</span>
|
|
51
86
|
<span class="file-card-name" title="${t.name}">${t.name}</span>
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
87
|
+
${(0,u.when)(()=>v.fileState(t).status===`uploading`,()=>l.html`
|
|
88
|
+
<ore-progress
|
|
89
|
+
type="linear"
|
|
90
|
+
size="sm"
|
|
91
|
+
:value=${()=>v.uploadPercent(t)}
|
|
92
|
+
label=${()=>`${v.uploadPercent(t)}%`}></ore-progress>
|
|
93
|
+
<span class="file-progress-meta">${()=>v.uploadMetaText(t)}</span>
|
|
94
|
+
`)}
|
|
95
|
+
${(0,u.when)(()=>v.fileState(t).status===`error`,()=>l.html`<span class="file-error-text">${()=>v.fileState(t).error}</span>`)}
|
|
59
96
|
</li>
|
|
60
|
-
`:
|
|
61
|
-
<li class="file-item">
|
|
97
|
+
`:l.html`
|
|
98
|
+
<li class="file-item" data-status=${()=>v.fileState(t).status}>
|
|
62
99
|
<span class="file-icon" aria-hidden="true">
|
|
63
|
-
<ore-icon
|
|
100
|
+
<ore-icon
|
|
101
|
+
name=${()=>v.statusIconName(t)}
|
|
102
|
+
size="18"
|
|
103
|
+
stroke-width="1.75"
|
|
104
|
+
aria-hidden="true"></ore-icon>
|
|
64
105
|
</span>
|
|
65
106
|
<span class="file-meta">
|
|
66
107
|
<span class="file-name" title="${t.name}">${t.name}</span>
|
|
67
|
-
|
|
108
|
+
${(0,u.when)(()=>v.fileState(t).status===`uploading`,()=>l.html`
|
|
109
|
+
<ore-progress
|
|
110
|
+
type="linear"
|
|
111
|
+
size="sm"
|
|
112
|
+
:value=${()=>v.uploadPercent(t)}
|
|
113
|
+
label=${()=>`${v.uploadPercent(t)}%`}></ore-progress>
|
|
114
|
+
<span class="file-progress-meta">${()=>v.uploadMetaText(t)}</span>
|
|
115
|
+
`)}
|
|
116
|
+
${(0,u.when)(()=>v.fileState(t).status===`error`,()=>l.html`<span class="file-error-text">${()=>v.fileState(t).error}</span>`)}
|
|
117
|
+
${(0,u.when)(()=>v.fileState(t).status===`idle`||v.fileState(t).status===`success`,()=>l.html`<span class="file-size">${s.formatBytes(t.size)}</span>`)}
|
|
118
|
+
</span>
|
|
119
|
+
<span class="file-actions">
|
|
120
|
+
${(0,u.when)(()=>v.fileState(t).status===`error`,()=>l.html`<button
|
|
121
|
+
class="file-action"
|
|
122
|
+
type="button"
|
|
123
|
+
aria-label="${`Retry uploading ${t.name}`}"
|
|
124
|
+
@click=${()=>v.retryUpload(t)}>
|
|
125
|
+
<ore-icon name="refresh-cw" size="14" stroke-width="2" aria-hidden="true"></ore-icon>
|
|
126
|
+
</button>`)}
|
|
127
|
+
${(0,u.when)(()=>v.fileState(t).status===`success`&&!!e.multiple.value&&!!e.upload.value,()=>l.html`<button
|
|
128
|
+
class="file-action"
|
|
129
|
+
type="button"
|
|
130
|
+
aria-label="${`Replace ${t.name}`}"
|
|
131
|
+
@click=${()=>D(t)}>
|
|
132
|
+
<ore-icon name="upload" size="14" stroke-width="2" aria-hidden="true"></ore-icon>
|
|
133
|
+
</button>`)}
|
|
134
|
+
<button
|
|
135
|
+
class="file-remove"
|
|
136
|
+
type="button"
|
|
137
|
+
aria-label="${`Remove ${t.name}`}"
|
|
138
|
+
@click=${e=>v.removeFile(t,e)}>
|
|
139
|
+
<ore-icon name="x" size="12" stroke-width="2.5" aria-hidden="true"></ore-icon>
|
|
140
|
+
</button>
|
|
68
141
|
</span>
|
|
69
|
-
<button
|
|
70
|
-
class="file-remove"
|
|
71
|
-
type="button"
|
|
72
|
-
aria-label="${`Remove ${t.name}`}"
|
|
73
|
-
@click=${e=>E(t,e)}>
|
|
74
|
-
<ore-icon name="x" size="12" stroke-width="2.5" aria-hidden="true"></ore-icon>
|
|
75
|
-
</button>
|
|
76
142
|
</li>
|
|
77
143
|
`)}
|
|
78
144
|
</ul>
|
|
79
|
-
<div class="helper-text" id="${
|
|
145
|
+
<div class="helper-text" id="${S}" part="helper" ?hidden=${()=>y.value||!e.helper.value}>
|
|
80
146
|
${e.helper}
|
|
81
147
|
</div>
|
|
82
148
|
<div
|
|
83
149
|
class="helper-text helper-text-error"
|
|
84
|
-
id="${
|
|
150
|
+
id="${C}"
|
|
85
151
|
role="alert"
|
|
86
152
|
part="error"
|
|
87
|
-
?hidden=${()=>!
|
|
153
|
+
?hidden=${()=>!y.value}>
|
|
88
154
|
${()=>e.error.value??``}
|
|
89
155
|
</div>
|
|
90
156
|
</div>
|
|
91
|
-
`},shadow:{delegatesFocus:!0},styles:[...n.fieldMixins,e.sizeVariantMixin(r.FILE_INPUT_SIZE_PRESET),t.forcedColorsFocusMixin(`.dropzone`),
|
|
157
|
+
`},shadow:{delegatesFocus:!0},styles:[...n.fieldMixins,e.sizeVariantMixin(r.FILE_INPUT_SIZE_PRESET),t.forcedColorsFocusMixin(`.dropzone`),c.default]}),exports.FILE_INPUT_TAG=h;
|
|
92
158
|
//# sourceMappingURL=file-input.cjs.map
|