@sprawlify/primitives 0.0.110 → 0.0.112
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/{aria-hidden-BX4SWNE_.mjs → aria-hidden-C72KtklN.mjs} +1 -1
- package/dist/{aria-hidden-BAGrxNHt.cjs → aria-hidden-CIBHXlCy.cjs} +1 -1
- package/dist/aria-hidden.cjs +2 -2
- package/dist/aria-hidden.mjs +2 -2
- package/dist/{auto-resize-B1BDDnp1.cjs → auto-resize-BTTNXiml.cjs} +1 -1
- package/dist/{auto-resize-CN2vAzdj.mjs → auto-resize-CbNgN0OO.mjs} +1 -1
- package/dist/auto-resize.cjs +2 -2
- package/dist/auto-resize.mjs +2 -2
- package/dist/{core-BmIEKqtP.mjs → core-Ci9Yu6QI.mjs} +1 -1
- package/dist/{core-nBg9RC_y.cjs → core-DwdPztGA.cjs} +1 -1
- package/dist/core.cjs +2 -2
- package/dist/core.mjs +2 -2
- package/dist/{dismissable-DWfZGIA7.mjs → dismissable-B9k5K6f9.mjs} +2 -2
- package/dist/{dismissable-ChwcJMHk.cjs → dismissable-DxjbwsOf.cjs} +2 -2
- package/dist/dismissable.cjs +3 -3
- package/dist/dismissable.mjs +3 -3
- package/dist/{dom-query-s2ESLR2U.mjs → dom-query-BFuRs3l4.mjs} +1 -1
- package/dist/{dom-query-Bd63cRVF.cjs → dom-query-BUO7rGsg.cjs} +1 -1
- package/dist/dom-query.cjs +1 -1
- package/dist/dom-query.mjs +1 -1
- package/dist/{focus-trap-fucc6OU_.cjs → focus-trap-BewqTQFt.cjs} +1 -1
- package/dist/{focus-trap-DzBvBlTH.mjs → focus-trap-Do8IUXYh.mjs} +1 -1
- package/dist/focus-trap.cjs +2 -2
- package/dist/focus-trap.mjs +2 -2
- package/dist/{focus-visible-D5qBaAOn.mjs → focus-visible-BuLf8M9F.mjs} +10 -9
- package/dist/{focus-visible-75XTctXf.cjs → focus-visible-Co_9bW09.cjs} +15 -8
- package/dist/focus-visible.cjs +3 -2
- package/dist/focus-visible.d.cts +2 -1
- package/dist/focus-visible.d.mts +2 -1
- package/dist/focus-visible.mjs +3 -3
- package/dist/{i18n-utils-DB-lUfrr.cjs → i18n-utils-BRLqoCq8.cjs} +1 -1
- package/dist/{i18n-utils-oWZyUib_.mjs → i18n-utils-DZs1CPj8.mjs} +1 -1
- package/dist/i18n-utils.cjs +2 -2
- package/dist/i18n-utils.mjs +2 -2
- package/dist/{interact-outside-2qkUnl4N.mjs → interact-outside-Ba50N1a5.mjs} +1 -1
- package/dist/{interact-outside-Cx4J0EBf.cjs → interact-outside-Bg-QSXqp.cjs} +1 -1
- package/dist/interact-outside.cjs +2 -2
- package/dist/interact-outside.mjs +2 -2
- package/dist/machines/accordion/index.cjs +2 -2
- package/dist/machines/accordion/index.d.cts +1 -1
- package/dist/machines/accordion/index.d.mts +1 -1
- package/dist/machines/accordion/index.mjs +2 -2
- package/dist/machines/angle-slider/index.cjs +2 -2
- package/dist/machines/angle-slider/index.d.cts +1 -1
- package/dist/machines/angle-slider/index.d.mts +1 -1
- package/dist/machines/angle-slider/index.mjs +2 -2
- package/dist/machines/aspect-ratio/index.cjs +2 -2
- package/dist/machines/aspect-ratio/index.mjs +2 -2
- package/dist/machines/async-list/index.cjs +2 -2
- package/dist/machines/async-list/index.mjs +2 -2
- package/dist/machines/avatar/index.cjs +2 -2
- package/dist/machines/avatar/index.mjs +2 -2
- package/dist/machines/carousel/index.cjs +3 -3
- package/dist/machines/carousel/index.d.cts +1 -1
- package/dist/machines/carousel/index.d.mts +1 -1
- package/dist/machines/carousel/index.mjs +3 -3
- package/dist/machines/cascade-select/index.cjs +12 -7
- package/dist/machines/cascade-select/index.d.cts +2 -2
- package/dist/machines/cascade-select/index.d.mts +2 -2
- package/dist/machines/cascade-select/index.mjs +12 -7
- package/dist/machines/checkbox/index.cjs +3 -3
- package/dist/machines/checkbox/index.d.cts +1 -1
- package/dist/machines/checkbox/index.d.mts +1 -1
- package/dist/machines/checkbox/index.mjs +3 -3
- package/dist/machines/clipboard/index.cjs +2 -2
- package/dist/machines/clipboard/index.d.cts +1 -1
- package/dist/machines/clipboard/index.d.mts +1 -1
- package/dist/machines/clipboard/index.mjs +2 -2
- package/dist/machines/collapsible/index.cjs +2 -2
- package/dist/machines/collapsible/index.d.cts +1 -1
- package/dist/machines/collapsible/index.d.mts +1 -1
- package/dist/machines/collapsible/index.mjs +2 -2
- package/dist/machines/color-picker/index.cjs +5 -5
- package/dist/machines/color-picker/index.d.cts +1 -1
- package/dist/machines/color-picker/index.d.mts +1 -1
- package/dist/machines/color-picker/index.mjs +5 -5
- package/dist/machines/combobox/index.cjs +14 -8
- package/dist/machines/combobox/index.d.cts +1 -1
- package/dist/machines/combobox/index.d.mts +1 -1
- package/dist/machines/combobox/index.mjs +14 -8
- package/dist/machines/date-picker/index.cjs +5 -5
- package/dist/machines/date-picker/index.d.cts +1 -1
- package/dist/machines/date-picker/index.d.mts +1 -1
- package/dist/machines/date-picker/index.mjs +5 -5
- package/dist/machines/dialog/index.cjs +7 -7
- package/dist/machines/dialog/index.d.cts +1 -1
- package/dist/machines/dialog/index.d.mts +1 -1
- package/dist/machines/dialog/index.mjs +7 -7
- package/dist/machines/drawer/index.cjs +1574 -307
- package/dist/machines/drawer/index.d.cts +217 -35
- package/dist/machines/drawer/index.d.mts +217 -35
- package/dist/machines/drawer/index.mjs +1574 -309
- package/dist/machines/dropdown-menu/index.cjs +12 -7
- package/dist/machines/dropdown-menu/index.d.cts +1 -1
- package/dist/machines/dropdown-menu/index.d.mts +1 -1
- package/dist/machines/dropdown-menu/index.mjs +12 -7
- package/dist/machines/editable/index.cjs +3 -3
- package/dist/machines/editable/index.mjs +3 -3
- package/dist/machines/file-upload/index.cjs +3 -3
- package/dist/machines/file-upload/index.d.cts +1 -1
- package/dist/machines/file-upload/index.d.mts +1 -1
- package/dist/machines/file-upload/index.mjs +3 -3
- package/dist/machines/floating-panel/index.cjs +2 -2
- package/dist/machines/floating-panel/index.d.cts +1 -1
- package/dist/machines/floating-panel/index.d.mts +1 -1
- package/dist/machines/floating-panel/index.mjs +2 -2
- package/dist/machines/hover-card/index.cjs +5 -5
- package/dist/machines/hover-card/index.mjs +5 -5
- package/dist/machines/image-cropper/index.cjs +2 -2
- package/dist/machines/image-cropper/index.d.cts +1 -1
- package/dist/machines/image-cropper/index.d.mts +1 -1
- package/dist/machines/image-cropper/index.mjs +2 -2
- package/dist/machines/listbox/index.cjs +3 -3
- package/dist/machines/listbox/index.d.cts +1 -1
- package/dist/machines/listbox/index.d.mts +1 -1
- package/dist/machines/listbox/index.mjs +3 -3
- package/dist/machines/marquee/index.cjs +2 -2
- package/dist/machines/marquee/index.d.cts +3 -3
- package/dist/machines/marquee/index.d.mts +3 -3
- package/dist/machines/marquee/index.mjs +2 -2
- package/dist/machines/navigation-menu/index.cjs +4 -4
- package/dist/machines/navigation-menu/index.d.cts +1 -1
- package/dist/machines/navigation-menu/index.d.mts +1 -1
- package/dist/machines/navigation-menu/index.mjs +4 -4
- package/dist/machines/number-input/index.cjs +2 -2
- package/dist/machines/number-input/index.mjs +2 -2
- package/dist/machines/pagination/index.cjs +2 -2
- package/dist/machines/pagination/index.d.cts +1 -1
- package/dist/machines/pagination/index.d.mts +1 -1
- package/dist/machines/pagination/index.mjs +2 -2
- package/dist/machines/password-input/index.cjs +2 -2
- package/dist/machines/password-input/index.d.cts +1 -1
- package/dist/machines/password-input/index.d.mts +1 -1
- package/dist/machines/password-input/index.mjs +2 -2
- package/dist/machines/pin-input/index.cjs +2 -2
- package/dist/machines/pin-input/index.mjs +2 -2
- package/dist/machines/popover/index.cjs +8 -8
- package/dist/machines/popover/index.d.cts +1 -1
- package/dist/machines/popover/index.d.mts +1 -1
- package/dist/machines/popover/index.mjs +8 -8
- package/dist/machines/presence/index.cjs +2 -2
- package/dist/machines/presence/index.mjs +2 -2
- package/dist/machines/progress/index.cjs +2 -2
- package/dist/machines/progress/index.d.cts +1 -1
- package/dist/machines/progress/index.d.mts +1 -1
- package/dist/machines/progress/index.mjs +2 -2
- package/dist/machines/qr-code/index.cjs +2 -2
- package/dist/machines/qr-code/index.mjs +2 -2
- package/dist/machines/radio-group/index.cjs +3 -3
- package/dist/machines/radio-group/index.d.cts +1 -1
- package/dist/machines/radio-group/index.d.mts +1 -1
- package/dist/machines/radio-group/index.mjs +3 -3
- package/dist/machines/rating-group/index.cjs +2 -2
- package/dist/machines/rating-group/index.mjs +2 -2
- package/dist/machines/scroll-area/index.cjs +2 -2
- package/dist/machines/scroll-area/index.d.cts +1 -1
- package/dist/machines/scroll-area/index.d.mts +1 -1
- package/dist/machines/scroll-area/index.mjs +2 -2
- package/dist/machines/select/index.cjs +13 -8
- package/dist/machines/select/index.d.cts +1 -1
- package/dist/machines/select/index.d.mts +1 -1
- package/dist/machines/select/index.mjs +13 -8
- package/dist/machines/separator/index.cjs +2 -2
- package/dist/machines/separator/index.mjs +2 -2
- package/dist/machines/signature-pad/index.cjs +2 -2
- package/dist/machines/signature-pad/index.mjs +2 -2
- package/dist/machines/slider/index.cjs +2 -2
- package/dist/machines/slider/index.d.cts +1 -1
- package/dist/machines/slider/index.d.mts +1 -1
- package/dist/machines/slider/index.mjs +2 -2
- package/dist/machines/splitter/index.cjs +2 -2
- package/dist/machines/splitter/index.d.cts +1 -1
- package/dist/machines/splitter/index.d.mts +1 -1
- package/dist/machines/splitter/index.mjs +2 -2
- package/dist/machines/steps/index.cjs +2 -2
- package/dist/machines/steps/index.d.cts +1 -1
- package/dist/machines/steps/index.d.mts +1 -1
- package/dist/machines/steps/index.mjs +2 -2
- package/dist/machines/switch/index.cjs +3 -3
- package/dist/machines/switch/index.mjs +3 -3
- package/dist/machines/tabs/index.cjs +2 -2
- package/dist/machines/tabs/index.d.cts +1 -1
- package/dist/machines/tabs/index.d.mts +1 -1
- package/dist/machines/tabs/index.mjs +2 -2
- package/dist/machines/tags-input/index.cjs +4 -4
- package/dist/machines/tags-input/index.d.cts +1 -1
- package/dist/machines/tags-input/index.d.mts +1 -1
- package/dist/machines/tags-input/index.mjs +4 -4
- package/dist/machines/timer/index.cjs +2 -2
- package/dist/machines/timer/index.d.cts +1 -1
- package/dist/machines/timer/index.d.mts +1 -1
- package/dist/machines/timer/index.mjs +2 -2
- package/dist/machines/toast/index.cjs +4 -4
- package/dist/machines/toast/index.d.cts +3 -3
- package/dist/machines/toast/index.d.mts +3 -3
- package/dist/machines/toast/index.mjs +4 -4
- package/dist/machines/toggle/index.cjs +2 -2
- package/dist/machines/toggle/index.mjs +2 -2
- package/dist/machines/toggle-group/index.cjs +2 -2
- package/dist/machines/toggle-group/index.mjs +2 -2
- package/dist/machines/tooltip/index.cjs +9 -9
- package/dist/machines/tooltip/index.mjs +10 -10
- package/dist/machines/tour/index.cjs +6 -6
- package/dist/machines/tour/index.d.cts +1 -1
- package/dist/machines/tour/index.d.mts +1 -1
- package/dist/machines/tour/index.mjs +6 -6
- package/dist/machines/tree-view/index.cjs +2 -2
- package/dist/machines/tree-view/index.d.cts +1 -1
- package/dist/machines/tree-view/index.d.mts +1 -1
- package/dist/machines/tree-view/index.mjs +2 -2
- package/dist/{popper-BDy37WA0.mjs → popper-BlgbmdAn.mjs} +1 -1
- package/dist/{popper-Cx3KHzeT.cjs → popper-viCrafLC.cjs} +1 -1
- package/dist/popper.cjs +2 -2
- package/dist/popper.mjs +2 -2
- package/dist/{remove-scroll-D9FAOapi.cjs → remove-scroll-D4CMJmU2.cjs} +1 -1
- package/dist/{remove-scroll-HcSiTbd5.mjs → remove-scroll-D55GZoBb.mjs} +1 -1
- package/dist/{scroll-snap-DfSwN3As.mjs → scroll-snap-CdneVP31.mjs} +1 -1
- package/dist/{scroll-snap-Dp_2adEa.cjs → scroll-snap-vZ2q6dcN.cjs} +1 -1
- package/dist/scroll-snap.cjs +2 -2
- package/dist/scroll-snap.mjs +2 -2
- package/package.json +1 -1
|
@@ -1,48 +1,849 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_create_anatomy = require("../../create-anatomy-BnwEmNnc.cjs");
|
|
3
|
-
const require_dom_query = require("../../dom-query-
|
|
3
|
+
const require_dom_query = require("../../dom-query-BUO7rGsg.cjs");
|
|
4
4
|
const require_defineProperty = require("../../defineProperty-8IOBQ1i_.cjs");
|
|
5
|
-
const require_aria_hidden = require("../../aria-hidden-
|
|
5
|
+
const require_aria_hidden = require("../../aria-hidden-CIBHXlCy.cjs");
|
|
6
6
|
const require_utils = require("../../utils-ByNiZU8f.cjs");
|
|
7
|
-
const require_core = require("../../core-
|
|
8
|
-
require("../../interact-outside-
|
|
9
|
-
const require_dismissable = require("../../dismissable-
|
|
10
|
-
const require_focus_trap = require("../../focus-trap-
|
|
7
|
+
const require_core = require("../../core-DwdPztGA.cjs");
|
|
8
|
+
require("../../interact-outside-Bg-QSXqp.cjs");
|
|
9
|
+
const require_dismissable = require("../../dismissable-DxjbwsOf.cjs");
|
|
10
|
+
const require_focus_trap = require("../../focus-trap-BewqTQFt.cjs");
|
|
11
11
|
const require_create_props = require("../../create-props-DP39rHnH.cjs");
|
|
12
|
-
const require_remove_scroll = require("../../remove-scroll-
|
|
12
|
+
const require_remove_scroll = require("../../remove-scroll-D4CMJmU2.cjs");
|
|
13
13
|
//#region src/machines/drawer/drawer.anatomy.ts
|
|
14
|
-
const anatomy = require_create_anatomy.createAnatomy("drawer").parts("content", "title", "trigger", "backdrop", "grabber", "grabberIndicator", "closeTrigger");
|
|
14
|
+
const anatomy = require_create_anatomy.createAnatomy("drawer").parts("positioner", "content", "title", "description", "trigger", "backdrop", "grabber", "grabberIndicator", "closeTrigger", "swipeArea");
|
|
15
15
|
const parts = anatomy.build();
|
|
16
16
|
//#endregion
|
|
17
17
|
//#region src/machines/drawer/drawer.dom.ts
|
|
18
18
|
const getContentId = (ctx) => ctx.ids?.content ?? `drawer:${ctx.id}:content`;
|
|
19
|
+
const getPositionerId = (ctx) => ctx.ids?.positioner ?? `drawer:${ctx.id}:positioner`;
|
|
19
20
|
const getTitleId = (ctx) => ctx.ids?.title ?? `drawer:${ctx.id}:title`;
|
|
21
|
+
const getDescriptionId = (ctx) => ctx.ids?.description ?? `drawer:${ctx.id}:description`;
|
|
20
22
|
const getTriggerId = (ctx) => ctx.ids?.trigger ?? `drawer:${ctx.id}:trigger`;
|
|
21
23
|
const getBackdropId = (ctx) => ctx.ids?.backdrop ?? `drawer:${ctx.id}:backdrop`;
|
|
22
24
|
const getGrabberId = (ctx) => ctx.ids?.grabber ?? `drawer:${ctx.id}:grabber`;
|
|
23
25
|
const getGrabberIndicatorId = (ctx) => ctx.ids?.grabberIndicator ?? `drawer:${ctx.id}:grabber-indicator`;
|
|
24
26
|
const getCloseTriggerId = (ctx) => ctx.ids?.closeTrigger ?? `drawer:${ctx.id}:close-trigger`;
|
|
27
|
+
const getSwipeAreaId = (ctx) => ctx.ids?.swipeArea ?? `drawer:${ctx.id}:swipe-area`;
|
|
25
28
|
const getContentEl = (ctx) => ctx.getById(getContentId(ctx));
|
|
29
|
+
const getTitleEl = (ctx) => ctx.getById(getTitleId(ctx));
|
|
30
|
+
const getDescriptionEl = (ctx) => ctx.getById(getDescriptionId(ctx));
|
|
26
31
|
const getTriggerEl = (ctx) => ctx.getById(getTriggerId(ctx));
|
|
32
|
+
const getBackdropEl = (ctx) => ctx.getById(getBackdropId(ctx));
|
|
27
33
|
const getCloseTriggerEl = (ctx) => ctx.getById(getCloseTriggerId(ctx));
|
|
34
|
+
const getSwipeAreaEl = (ctx) => ctx.getById(getSwipeAreaId(ctx));
|
|
35
|
+
//#endregion
|
|
36
|
+
//#region src/machines/drawer/utils/snap-point.ts
|
|
37
|
+
function resolveSnapPointValue(snapPoint, viewportSize, rootFontSize) {
|
|
38
|
+
if (!Number.isFinite(viewportSize) || viewportSize <= 0) return null;
|
|
39
|
+
if (typeof snapPoint === "number") {
|
|
40
|
+
if (!Number.isFinite(snapPoint)) return null;
|
|
41
|
+
if (snapPoint <= 1) return require_utils.clampValue(snapPoint, 0, 1) * viewportSize;
|
|
42
|
+
return snapPoint;
|
|
43
|
+
}
|
|
44
|
+
const trimmed = snapPoint.trim();
|
|
45
|
+
if (trimmed.endsWith("px")) {
|
|
46
|
+
const value = Number.parseFloat(trimmed);
|
|
47
|
+
return Number.isFinite(value) ? value : null;
|
|
48
|
+
}
|
|
49
|
+
if (trimmed.endsWith("rem")) {
|
|
50
|
+
const value = Number.parseFloat(trimmed);
|
|
51
|
+
return Number.isFinite(value) ? value * rootFontSize : null;
|
|
52
|
+
}
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
function resolveSnapPoint(snapPoint, options) {
|
|
56
|
+
const { contentSize, viewportSize, rootFontSize } = options;
|
|
57
|
+
const maxSize = Math.min(contentSize, viewportSize);
|
|
58
|
+
if (!Number.isFinite(maxSize) || maxSize <= 0) return null;
|
|
59
|
+
const resolvedSize = resolveSnapPointValue(snapPoint, viewportSize, rootFontSize);
|
|
60
|
+
if (resolvedSize === null || !Number.isFinite(resolvedSize)) return null;
|
|
61
|
+
const height = require_utils.clampValue(resolvedSize, 0, maxSize);
|
|
62
|
+
return {
|
|
63
|
+
value: snapPoint,
|
|
64
|
+
height,
|
|
65
|
+
offset: Math.max(0, contentSize - height)
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
const HEIGHT_DEDUP_EPSILON_PX = 1;
|
|
69
|
+
function dedupeSnapPoints(points) {
|
|
70
|
+
if (points.length <= 1) return points;
|
|
71
|
+
const deduped = [];
|
|
72
|
+
const seenHeights = [];
|
|
73
|
+
for (let index = points.length - 1; index >= 0; index -= 1) {
|
|
74
|
+
const point = points[index];
|
|
75
|
+
if (seenHeights.some((height) => Math.abs(height - point.height) <= HEIGHT_DEDUP_EPSILON_PX)) continue;
|
|
76
|
+
seenHeights.push(point.height);
|
|
77
|
+
deduped.push(point);
|
|
78
|
+
}
|
|
79
|
+
deduped.reverse();
|
|
80
|
+
return deduped;
|
|
81
|
+
}
|
|
82
|
+
function findClosestSnapPoint(offset, snapPoints) {
|
|
83
|
+
return snapPoints.reduce((acc, curr) => {
|
|
84
|
+
const closestDiff = Math.abs(offset - acc.offset);
|
|
85
|
+
return Math.abs(offset - curr.offset) < closestDiff ? curr : acc;
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
//#endregion
|
|
89
|
+
//#region src/machines/drawer/utils/session.ts
|
|
90
|
+
const VELOCITY_WINDOW_MS = 100;
|
|
91
|
+
const MAX_RELEASE_VELOCITY_AGE_MS = 80;
|
|
92
|
+
const MIN_GESTURE_DURATION_MS = 50;
|
|
93
|
+
const MIN_VELOCITY_SAMPLES = 2;
|
|
94
|
+
const SAMPLE_BUFFER_COMPACT_THRESHOLD = 8;
|
|
95
|
+
const DEFERRED_DRAG_MIN_MAIN_AXIS_PX = 6;
|
|
96
|
+
const DEFERRED_DRAG_MAIN_OVER_CROSS_RATIO = 1.35;
|
|
97
|
+
function isVerticalSwipeDirection(direction) {
|
|
98
|
+
return direction === "down" || direction === "up";
|
|
99
|
+
}
|
|
100
|
+
function isNegativeSwipeDirection(direction) {
|
|
101
|
+
return direction === "up" || direction === "left";
|
|
102
|
+
}
|
|
103
|
+
var SwipeSession = class {
|
|
104
|
+
constructor() {
|
|
105
|
+
require_defineProperty._defineProperty(this, "startPoint", null);
|
|
106
|
+
require_defineProperty._defineProperty(this, "velocity", null);
|
|
107
|
+
require_defineProperty._defineProperty(this, "samples", []);
|
|
108
|
+
require_defineProperty._defineProperty(this, "sampleStartIndex", 0);
|
|
109
|
+
require_defineProperty._defineProperty(this, "gestureStartAxis", null);
|
|
110
|
+
require_defineProperty._defineProperty(this, "gestureStartTime", null);
|
|
111
|
+
require_defineProperty._defineProperty(this, "gestureSign", 1);
|
|
112
|
+
require_defineProperty._defineProperty(this, "pendingSwipe", null);
|
|
113
|
+
}
|
|
114
|
+
setStartPoint(point) {
|
|
115
|
+
this.startPoint = point;
|
|
116
|
+
}
|
|
117
|
+
clearStartPoint() {
|
|
118
|
+
this.startPoint = null;
|
|
119
|
+
}
|
|
120
|
+
getStartPoint() {
|
|
121
|
+
return this.startPoint;
|
|
122
|
+
}
|
|
123
|
+
getGestureAxis(direction) {
|
|
124
|
+
return direction === "left" || direction === "right" ? "x" : "y";
|
|
125
|
+
}
|
|
126
|
+
getGestureSign(direction) {
|
|
127
|
+
return isNegativeSwipeDirection(direction) ? -1 : 1;
|
|
128
|
+
}
|
|
129
|
+
getAxisValue(point, axis) {
|
|
130
|
+
return point[axis];
|
|
131
|
+
}
|
|
132
|
+
getMainAxisDisplacement(point, axis, sign) {
|
|
133
|
+
if (!this.startPoint) return 0;
|
|
134
|
+
return (this.getAxisValue(this.startPoint, axis) - this.getAxisValue(point, axis)) * sign;
|
|
135
|
+
}
|
|
136
|
+
getCrossAxisDisplacement(point, axis) {
|
|
137
|
+
if (!this.startPoint) return 0;
|
|
138
|
+
const crossAxis = axis === "x" ? "y" : "x";
|
|
139
|
+
const startAxis = this.getAxisValue(this.startPoint, crossAxis);
|
|
140
|
+
return this.getAxisValue(point, crossAxis) - startAxis;
|
|
141
|
+
}
|
|
142
|
+
track(point, axis, sign) {
|
|
143
|
+
const axisValue = this.getAxisValue(point, axis);
|
|
144
|
+
const now = performance.now();
|
|
145
|
+
if (this.gestureStartAxis === null) {
|
|
146
|
+
this.gestureStartAxis = axisValue;
|
|
147
|
+
this.gestureStartTime = now;
|
|
148
|
+
this.gestureSign = sign;
|
|
149
|
+
}
|
|
150
|
+
this.samples.push({
|
|
151
|
+
axis: axisValue,
|
|
152
|
+
time: now
|
|
153
|
+
});
|
|
154
|
+
const cutoff = now - VELOCITY_WINDOW_MS;
|
|
155
|
+
while (this.sampleStartIndex < this.samples.length && this.samples[this.sampleStartIndex].time < cutoff) this.sampleStartIndex += 1;
|
|
156
|
+
if (this.sampleStartIndex >= SAMPLE_BUFFER_COMPACT_THRESHOLD) {
|
|
157
|
+
this.samples = this.samples.slice(this.sampleStartIndex);
|
|
158
|
+
this.sampleStartIndex = 0;
|
|
159
|
+
}
|
|
160
|
+
if (this.samples.length - this.sampleStartIndex < MIN_VELOCITY_SAMPLES) {
|
|
161
|
+
this.velocity = 0;
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
const oldest = this.samples[this.sampleStartIndex];
|
|
165
|
+
const newest = this.samples[this.samples.length - 1];
|
|
166
|
+
const dt = newest.time - oldest.time;
|
|
167
|
+
if (dt <= 0) {
|
|
168
|
+
this.velocity = 0;
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
const velocity = (newest.axis - oldest.axis) * sign / dt * 1e3;
|
|
172
|
+
this.velocity = Number.isFinite(velocity) ? velocity : 0;
|
|
173
|
+
}
|
|
174
|
+
getReleaseVelocity() {
|
|
175
|
+
const now = performance.now();
|
|
176
|
+
if (this.samples.length - this.sampleStartIndex >= MIN_VELOCITY_SAMPLES) {
|
|
177
|
+
if (now - this.samples[this.samples.length - 1].time <= MAX_RELEASE_VELOCITY_AGE_MS) return this.velocity ?? 0;
|
|
178
|
+
}
|
|
179
|
+
if (this.gestureStartAxis !== null && this.gestureStartTime !== null) {
|
|
180
|
+
const lastSample = this.samples[this.samples.length - 1];
|
|
181
|
+
if (lastSample) {
|
|
182
|
+
const dt = Math.max(lastSample.time - this.gestureStartTime, MIN_GESTURE_DURATION_MS);
|
|
183
|
+
const velocity = (lastSample.axis - this.gestureStartAxis) * this.gestureSign / dt * 1e3;
|
|
184
|
+
return Number.isFinite(velocity) ? velocity : 0;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return this.velocity ?? 0;
|
|
188
|
+
}
|
|
189
|
+
clearVelocityTracking() {
|
|
190
|
+
this.samples = [];
|
|
191
|
+
this.sampleStartIndex = 0;
|
|
192
|
+
this.velocity = null;
|
|
193
|
+
this.gestureStartAxis = null;
|
|
194
|
+
this.gestureStartTime = null;
|
|
195
|
+
this.gestureSign = 1;
|
|
196
|
+
}
|
|
197
|
+
clear() {
|
|
198
|
+
this.cancelDeferredSwipe();
|
|
199
|
+
this.clearStartPoint();
|
|
200
|
+
this.clearVelocityTracking();
|
|
201
|
+
}
|
|
202
|
+
startDeferredSwipe(options) {
|
|
203
|
+
const { getWin, pointerId, startPoint, swipeDirection, onCommit, canCommit, onCancel } = options;
|
|
204
|
+
this.cancelDeferredSwipe();
|
|
205
|
+
const win = getWin();
|
|
206
|
+
const vertical = isVerticalSwipeDirection(swipeDirection);
|
|
207
|
+
const onMove = (event) => {
|
|
208
|
+
if (event.pointerId !== pointerId) return;
|
|
209
|
+
const dx = event.clientX - startPoint.x;
|
|
210
|
+
const dy = event.clientY - startPoint.y;
|
|
211
|
+
const mainDelta = vertical ? dy : dx;
|
|
212
|
+
const crossDelta = vertical ? dx : dy;
|
|
213
|
+
const absMain = Math.abs(mainDelta);
|
|
214
|
+
if (absMain >= DEFERRED_DRAG_MIN_MAIN_AXIS_PX && absMain >= Math.abs(crossDelta) * DEFERRED_DRAG_MAIN_OVER_CROSS_RATIO) {
|
|
215
|
+
if (!canCommit || canCommit()) onCommit(startPoint);
|
|
216
|
+
this.cancelDeferredSwipe();
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
const onEnd = (event) => {
|
|
220
|
+
if (event.pointerId !== pointerId) return;
|
|
221
|
+
onCancel?.();
|
|
222
|
+
this.cancelDeferredSwipe();
|
|
223
|
+
};
|
|
224
|
+
this.pendingSwipe = {
|
|
225
|
+
pointerId,
|
|
226
|
+
startPoint,
|
|
227
|
+
cleanups: [
|
|
228
|
+
require_dom_query.addDomEvent(win, "pointermove", onMove, { capture: true }),
|
|
229
|
+
require_dom_query.addDomEvent(win, "pointerup", onEnd, { capture: true }),
|
|
230
|
+
require_dom_query.addDomEvent(win, "pointercancel", onEnd, { capture: true }),
|
|
231
|
+
require_dom_query.addDomEvent(win, "lostpointercapture", onEnd, { capture: true })
|
|
232
|
+
]
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
cancelDeferredSwipe() {
|
|
236
|
+
if (!this.pendingSwipe) return;
|
|
237
|
+
this.pendingSwipe.cleanups.forEach((cleanup) => cleanup());
|
|
238
|
+
this.pendingSwipe = null;
|
|
239
|
+
}
|
|
240
|
+
bind(options) {
|
|
241
|
+
const { getDoc, getSelectionTarget, swipeDirection, onStart, onMove, onEnd, onCancel, preventDefault, cancelOnInterrupt } = options;
|
|
242
|
+
const doc = getDoc();
|
|
243
|
+
let usingTouchEvents = false;
|
|
244
|
+
let restoreSelection;
|
|
245
|
+
const axis = this.getGestureAxis(swipeDirection);
|
|
246
|
+
const sign = this.getGestureSign(swipeDirection);
|
|
247
|
+
const trackPoint = (point) => {
|
|
248
|
+
this.track(point, axis, sign);
|
|
249
|
+
};
|
|
250
|
+
const startSelectionGuard = () => {
|
|
251
|
+
restoreSelection ?? (restoreSelection = require_dom_query.disableTextSelection({
|
|
252
|
+
doc,
|
|
253
|
+
target: getSelectionTarget?.()
|
|
254
|
+
}));
|
|
255
|
+
};
|
|
256
|
+
const stopSelectionGuard = () => {
|
|
257
|
+
restoreSelection?.();
|
|
258
|
+
restoreSelection = void 0;
|
|
259
|
+
};
|
|
260
|
+
function onPointerMove(event) {
|
|
261
|
+
if (event.pointerType === "touch" && usingTouchEvents) return;
|
|
262
|
+
const point = require_dom_query.getEventPoint(event);
|
|
263
|
+
const target = require_dom_query.getEventTarget(event);
|
|
264
|
+
startSelectionGuard();
|
|
265
|
+
trackPoint(point);
|
|
266
|
+
onMove({
|
|
267
|
+
point,
|
|
268
|
+
target,
|
|
269
|
+
event,
|
|
270
|
+
pointerType: event.pointerType,
|
|
271
|
+
axis,
|
|
272
|
+
swipeDirection
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
function onPointerUp(event) {
|
|
276
|
+
if (event.pointerType === "touch" && usingTouchEvents) {
|
|
277
|
+
usingTouchEvents = false;
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
stopSelectionGuard();
|
|
281
|
+
onEnd({
|
|
282
|
+
point: require_dom_query.getEventPoint(event),
|
|
283
|
+
swipeDirection
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
function onPointerCancel(event) {
|
|
287
|
+
if (event.pointerType === "touch" && usingTouchEvents) {
|
|
288
|
+
usingTouchEvents = false;
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
stopSelectionGuard();
|
|
292
|
+
onCancel();
|
|
293
|
+
}
|
|
294
|
+
function onTouchStartEvent(event) {
|
|
295
|
+
if (!event.touches[0]) return;
|
|
296
|
+
usingTouchEvents = true;
|
|
297
|
+
const point = require_dom_query.getEventPoint(event);
|
|
298
|
+
const target = require_dom_query.getEventTarget(event);
|
|
299
|
+
onStart?.({
|
|
300
|
+
point,
|
|
301
|
+
target,
|
|
302
|
+
event,
|
|
303
|
+
pointerType: "touch",
|
|
304
|
+
axis,
|
|
305
|
+
swipeDirection
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
function onTouchMoveEvent(event) {
|
|
309
|
+
if (!event.touches[0]) return;
|
|
310
|
+
usingTouchEvents = true;
|
|
311
|
+
const point = require_dom_query.getEventPoint(event);
|
|
312
|
+
const details = {
|
|
313
|
+
point,
|
|
314
|
+
target: require_dom_query.getEventTarget(event),
|
|
315
|
+
event,
|
|
316
|
+
pointerType: "touch",
|
|
317
|
+
axis,
|
|
318
|
+
swipeDirection
|
|
319
|
+
};
|
|
320
|
+
if (preventDefault?.(details) && event.cancelable) event.preventDefault();
|
|
321
|
+
startSelectionGuard();
|
|
322
|
+
trackPoint(point);
|
|
323
|
+
onMove(details);
|
|
324
|
+
}
|
|
325
|
+
function onTouchEnd(event) {
|
|
326
|
+
if (event.touches.length !== 0) return;
|
|
327
|
+
stopSelectionGuard();
|
|
328
|
+
onEnd({
|
|
329
|
+
point: require_dom_query.getEventPoint(event),
|
|
330
|
+
swipeDirection
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
function onTouchCancel() {
|
|
334
|
+
stopSelectionGuard();
|
|
335
|
+
onCancel();
|
|
336
|
+
}
|
|
337
|
+
function onVisibilityChange() {
|
|
338
|
+
if (doc.visibilityState !== "hidden") return;
|
|
339
|
+
if (cancelOnInterrupt?.({
|
|
340
|
+
reason: "visibility-hidden",
|
|
341
|
+
event: doc,
|
|
342
|
+
target: null,
|
|
343
|
+
pointerType: null
|
|
344
|
+
}) === false) return;
|
|
345
|
+
stopSelectionGuard();
|
|
346
|
+
onCancel();
|
|
347
|
+
}
|
|
348
|
+
function onLostPointerCapture(event) {
|
|
349
|
+
if (event.pointerType === "touch") return;
|
|
350
|
+
const target = require_dom_query.getEventTarget(event);
|
|
351
|
+
if (cancelOnInterrupt?.({
|
|
352
|
+
reason: "lost-pointer-capture",
|
|
353
|
+
event,
|
|
354
|
+
target,
|
|
355
|
+
pointerType: event.pointerType
|
|
356
|
+
}) === false) return;
|
|
357
|
+
onCancel();
|
|
358
|
+
}
|
|
359
|
+
const cleanups = [
|
|
360
|
+
require_dom_query.addDomEvent(doc, "pointermove", onPointerMove),
|
|
361
|
+
require_dom_query.addDomEvent(doc, "pointerup", onPointerUp),
|
|
362
|
+
require_dom_query.addDomEvent(doc, "pointercancel", onPointerCancel),
|
|
363
|
+
require_dom_query.addDomEvent(doc, "touchstart", onTouchStartEvent, {
|
|
364
|
+
capture: true,
|
|
365
|
+
passive: false
|
|
366
|
+
}),
|
|
367
|
+
require_dom_query.addDomEvent(doc, "touchmove", onTouchMoveEvent, {
|
|
368
|
+
capture: true,
|
|
369
|
+
passive: false
|
|
370
|
+
}),
|
|
371
|
+
require_dom_query.addDomEvent(doc, "touchend", onTouchEnd, { capture: true }),
|
|
372
|
+
require_dom_query.addDomEvent(doc, "touchcancel", onTouchCancel, { capture: true }),
|
|
373
|
+
require_dom_query.addDomEvent(doc, "visibilitychange", onVisibilityChange),
|
|
374
|
+
require_dom_query.addDomEvent(doc, "lostpointercapture", onLostPointerCapture, true)
|
|
375
|
+
];
|
|
376
|
+
return () => {
|
|
377
|
+
stopSelectionGuard();
|
|
378
|
+
cleanups.forEach((cleanup) => cleanup());
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
};
|
|
382
|
+
//#endregion
|
|
383
|
+
//#region src/machines/drawer/utils/drawer-session.ts
|
|
384
|
+
const RELEASE_DISPLACEMENT_TRUST_PX = 24;
|
|
385
|
+
const OPEN_SWIPE_HIDDEN_VISIBLE_RATIO = .22;
|
|
386
|
+
const OPEN_SWIPE_HIDDEN_VELOCITY_MULTIPLIER = 1.25;
|
|
387
|
+
const OPEN_SWIPE_REVEALED_VISIBLE_RATIO = .5;
|
|
388
|
+
const OPEN_SWIPE_REVEALED_OPPOSING_MAX_ABS_VELOCITY = 650;
|
|
389
|
+
const DRAG_START_THRESHOLD = .3;
|
|
390
|
+
const CROSS_AXIS_BIAS = .58;
|
|
391
|
+
const SCROLL_SLACK_GATE = .5;
|
|
392
|
+
const SCROLL_SLACK_EPSILON = 1;
|
|
393
|
+
const SEQUENTIAL_THRESHOLD = 24;
|
|
394
|
+
const SNAP_VELOCITY_THRESHOLD = 400;
|
|
395
|
+
const SNAP_VELOCITY_MULTIPLIER = .4;
|
|
396
|
+
const MAX_SNAP_VELOCITY = 4e3;
|
|
397
|
+
const SWIPE_STRENGTH_MAX_DURATION_MS = 360;
|
|
398
|
+
const SWIPE_STRENGTH_MIN_SCALAR = .1;
|
|
399
|
+
const SWIPE_STRENGTH_MAX_SCALAR = 1;
|
|
400
|
+
const SWIPE_AREA_OPEN_INTENT_MIN_PX = 5;
|
|
401
|
+
const NO_DRAG_DATA_ATTR = "data-no-drag";
|
|
402
|
+
const NO_DRAG_SELECTOR = `[${NO_DRAG_DATA_ATTR}]`;
|
|
403
|
+
var DrawerSwipeSession = class {
|
|
404
|
+
constructor(options) {
|
|
405
|
+
require_defineProperty._defineProperty(this, "session", new SwipeSession());
|
|
406
|
+
require_defineProperty._defineProperty(this, "dragOffset", null);
|
|
407
|
+
require_defineProperty._defineProperty(this, "preventDragOnScroll", void 0);
|
|
408
|
+
this.preventDragOnScroll = options.preventDragOnScroll;
|
|
409
|
+
}
|
|
410
|
+
contentPointerDown(options) {
|
|
411
|
+
const { event, getDoc, getContentEl, getWin, swipeDirection, canCommit, onCommit } = options;
|
|
412
|
+
if (shouldIgnorePointerDownForDrag(event)) return;
|
|
413
|
+
if (isTextSelectionInDrawer(getDoc(), getContentEl())) return;
|
|
414
|
+
if (!canCommit()) return;
|
|
415
|
+
const point = require_dom_query.getEventPoint(event);
|
|
416
|
+
if (!(event.pointerType === "mouse" || event.pointerType === "pen")) {
|
|
417
|
+
onCommit(point);
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
420
|
+
this.session.startDeferredSwipe({
|
|
421
|
+
getWin,
|
|
422
|
+
pointerId: event.pointerId,
|
|
423
|
+
startPoint: point,
|
|
424
|
+
swipeDirection,
|
|
425
|
+
onCommit,
|
|
426
|
+
canCommit
|
|
427
|
+
});
|
|
428
|
+
}
|
|
429
|
+
grabberPointerDown(options) {
|
|
430
|
+
const { event, point, canCommit, onCommit } = options;
|
|
431
|
+
if (shouldIgnorePointerDownForDrag(event)) return;
|
|
432
|
+
this.session.cancelDeferredSwipe();
|
|
433
|
+
if (!canCommit()) return;
|
|
434
|
+
onCommit(point);
|
|
435
|
+
}
|
|
436
|
+
adjustReleaseVelocityAgainstDisplacement(velocity, displacementFromSnap) {
|
|
437
|
+
const displacementSign = Math.sign(displacementFromSnap);
|
|
438
|
+
const velocitySign = Math.sign(velocity);
|
|
439
|
+
if (displacementSign !== 0 && Math.abs(displacementFromSnap) >= RELEASE_DISPLACEMENT_TRUST_PX && velocitySign !== 0 && velocitySign !== displacementSign) return 0;
|
|
440
|
+
return velocity;
|
|
441
|
+
}
|
|
442
|
+
adjustReleaseVelocityForOpenSwipe(velocity, visibleRatio, swipeVelocityThreshold) {
|
|
443
|
+
if (visibleRatio < OPEN_SWIPE_HIDDEN_VISIBLE_RATIO && velocity < 0 && Math.abs(velocity) < swipeVelocityThreshold * OPEN_SWIPE_HIDDEN_VELOCITY_MULTIPLIER) return 0;
|
|
444
|
+
if (visibleRatio > OPEN_SWIPE_REVEALED_VISIBLE_RATIO && velocity > 0 && Math.abs(velocity) < OPEN_SWIPE_REVEALED_OPPOSING_MAX_ABS_VELOCITY) return 0;
|
|
445
|
+
return velocity;
|
|
446
|
+
}
|
|
447
|
+
beginSwipe(point) {
|
|
448
|
+
this.session.setStartPoint(point);
|
|
449
|
+
}
|
|
450
|
+
clearSwipeStart() {
|
|
451
|
+
this.session.clearStartPoint();
|
|
452
|
+
}
|
|
453
|
+
getSwipeStart() {
|
|
454
|
+
return this.session.getStartPoint();
|
|
455
|
+
}
|
|
456
|
+
getDragOffset() {
|
|
457
|
+
return this.dragOffset;
|
|
458
|
+
}
|
|
459
|
+
resetDragOffset() {
|
|
460
|
+
this.dragOffset = null;
|
|
461
|
+
}
|
|
462
|
+
resetVelocity() {
|
|
463
|
+
this.session.clearVelocityTracking();
|
|
464
|
+
}
|
|
465
|
+
reset() {
|
|
466
|
+
this.dragOffset = null;
|
|
467
|
+
this.session.clear();
|
|
468
|
+
}
|
|
469
|
+
setDragOffset(point, resolvedActiveSnapPointOffset, direction) {
|
|
470
|
+
if (!this.session.getStartPoint()) {
|
|
471
|
+
this.dragOffset = null;
|
|
472
|
+
return;
|
|
473
|
+
}
|
|
474
|
+
const axis = this.session.getGestureAxis(direction);
|
|
475
|
+
const sign = this.session.getGestureSign(direction);
|
|
476
|
+
let delta = this.session.getMainAxisDisplacement(point, axis, sign) - resolvedActiveSnapPointOffset;
|
|
477
|
+
if (delta > 0) delta = Math.sqrt(delta);
|
|
478
|
+
this.dragOffset = -delta;
|
|
479
|
+
}
|
|
480
|
+
setSwipeOpenOffset(point, contentSize, direction) {
|
|
481
|
+
if (!this.session.getStartPoint()) {
|
|
482
|
+
this.dragOffset = null;
|
|
483
|
+
return;
|
|
484
|
+
}
|
|
485
|
+
const axis = this.session.getGestureAxis(direction);
|
|
486
|
+
const sign = this.session.getGestureSign(direction);
|
|
487
|
+
const openDisplacement = this.session.getMainAxisDisplacement(point, axis, sign);
|
|
488
|
+
let dragOffset = contentSize - Math.max(0, openDisplacement);
|
|
489
|
+
if (dragOffset < 0) dragOffset = -Math.sqrt(Math.abs(dragOffset));
|
|
490
|
+
this.dragOffset = dragOffset;
|
|
491
|
+
}
|
|
492
|
+
canStartDrag(point, target, container, preventDragOnScroll, direction) {
|
|
493
|
+
if (!require_dom_query.isHTMLElement(target)) return false;
|
|
494
|
+
if (isDragExemptElement(target)) return false;
|
|
495
|
+
if (!this.session.getStartPoint() || !container) return false;
|
|
496
|
+
if (!preventDragOnScroll) return true;
|
|
497
|
+
const axis = this.session.getGestureAxis(direction);
|
|
498
|
+
const sign = this.session.getGestureSign(direction);
|
|
499
|
+
const delta = this.session.getMainAxisDisplacement(point, axis, sign);
|
|
500
|
+
if (Math.abs(delta) < DRAG_START_THRESHOLD) return false;
|
|
501
|
+
if (Math.abs(this.session.getCrossAxisDisplacement(point, axis)) > Math.abs(delta) * CROSS_AXIS_BIAS) {
|
|
502
|
+
const crossScroll = getScrollInfo(target, container, isVerticalSwipeDirection(direction) ? "right" : "down");
|
|
503
|
+
if (crossScroll.availableForwardScroll > SCROLL_SLACK_GATE || crossScroll.availableBackwardScroll > SCROLL_SLACK_GATE) return false;
|
|
504
|
+
}
|
|
505
|
+
const { availableForwardScroll, availableBackwardScroll } = getScrollInfo(target, container, direction);
|
|
506
|
+
if (delta > 0 && availableForwardScroll > SCROLL_SLACK_GATE || delta < 0 && availableBackwardScroll > SCROLL_SLACK_GATE) return false;
|
|
507
|
+
return true;
|
|
508
|
+
}
|
|
509
|
+
resolveSnapPointOnRelease(snapPoints, snapPoint, snapToSequentialPoints, contentSize) {
|
|
510
|
+
const dragOffset = this.dragOffset;
|
|
511
|
+
if (dragOffset === null) return snapPoints[0]?.value ?? 1;
|
|
512
|
+
const releaseVelocity = this.session.getReleaseVelocity();
|
|
513
|
+
if (snapToSequentialPoints && snapPoint) {
|
|
514
|
+
const ordered = [...snapPoints].sort((a, b) => a.offset - b.offset);
|
|
515
|
+
let currentIndex = 0;
|
|
516
|
+
let closestDist = Math.abs(snapPoint.offset - ordered[0].offset);
|
|
517
|
+
for (let i = 1; i < ordered.length; i++) {
|
|
518
|
+
const dist = Math.abs(snapPoint.offset - ordered[i].offset);
|
|
519
|
+
if (dist < closestDist) {
|
|
520
|
+
closestDist = dist;
|
|
521
|
+
currentIndex = i;
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
const currentPoint = ordered[currentIndex];
|
|
525
|
+
const delta = dragOffset - currentPoint.offset;
|
|
526
|
+
const dragDirection = Math.sign(delta);
|
|
527
|
+
const velocityAdjusted = this.adjustReleaseVelocityAgainstDisplacement(releaseVelocity, delta);
|
|
528
|
+
const velocityDirection = Math.sign(velocityAdjusted);
|
|
529
|
+
let targetSnapPoint = currentPoint;
|
|
530
|
+
let effectiveTargetOffset = dragOffset;
|
|
531
|
+
if (dragDirection !== 0 && velocityDirection === dragDirection && Math.abs(velocityAdjusted) >= SNAP_VELOCITY_THRESHOLD) {
|
|
532
|
+
const adjacentIndex = Math.min(Math.max(currentIndex + dragDirection, 0), ordered.length - 1);
|
|
533
|
+
if (adjacentIndex !== currentIndex) {
|
|
534
|
+
targetSnapPoint = ordered[adjacentIndex];
|
|
535
|
+
effectiveTargetOffset = targetSnapPoint.offset;
|
|
536
|
+
} else if (dragDirection > 0) return null;
|
|
537
|
+
} else if (delta > SEQUENTIAL_THRESHOLD) {
|
|
538
|
+
const nextPoint = ordered[Math.min(currentIndex + 1, ordered.length - 1)];
|
|
539
|
+
if (nextPoint) {
|
|
540
|
+
targetSnapPoint = nextPoint;
|
|
541
|
+
effectiveTargetOffset = nextPoint.offset;
|
|
542
|
+
}
|
|
543
|
+
} else if (delta < -SEQUENTIAL_THRESHOLD) {
|
|
544
|
+
const prevPoint = ordered[Math.max(currentIndex - 1, 0)];
|
|
545
|
+
if (prevPoint) {
|
|
546
|
+
targetSnapPoint = prevPoint;
|
|
547
|
+
effectiveTargetOffset = prevPoint.offset;
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
if (Math.abs(effectiveTargetOffset - contentSize) < Math.abs(effectiveTargetOffset - targetSnapPoint.offset)) return null;
|
|
551
|
+
return targetSnapPoint.value;
|
|
552
|
+
}
|
|
553
|
+
const snapRestOffset = snapPoint?.offset ?? 0;
|
|
554
|
+
const velocity = this.adjustReleaseVelocityAgainstDisplacement(releaseVelocity, dragOffset - snapRestOffset);
|
|
555
|
+
let targetOffset = dragOffset;
|
|
556
|
+
if (Math.abs(velocity) >= SNAP_VELOCITY_THRESHOLD) {
|
|
557
|
+
const clamped = require_utils.clampValue(velocity, -MAX_SNAP_VELOCITY, MAX_SNAP_VELOCITY);
|
|
558
|
+
targetOffset += clamped * SNAP_VELOCITY_MULTIPLIER;
|
|
559
|
+
targetOffset = Math.max(0, targetOffset);
|
|
560
|
+
}
|
|
561
|
+
return findClosestSnapPoint(targetOffset, snapPoints).value;
|
|
562
|
+
}
|
|
563
|
+
shouldOpenOnRelease(contentSize, swipeVelocityThreshold, openThreshold) {
|
|
564
|
+
const dragOffset = this.dragOffset;
|
|
565
|
+
if (dragOffset === null || contentSize === null) return false;
|
|
566
|
+
const visibleSize = contentSize - dragOffset;
|
|
567
|
+
const visibleRatio = visibleSize / contentSize;
|
|
568
|
+
const velocity = this.adjustReleaseVelocityForOpenSwipe(this.session.getReleaseVelocity(), visibleRatio, swipeVelocityThreshold);
|
|
569
|
+
return velocity < 0 && Math.abs(velocity) >= swipeVelocityThreshold || visibleSize >= contentSize * openThreshold;
|
|
570
|
+
}
|
|
571
|
+
shouldDismissOnRelease(contentSize, snapPoints, resolvedSnapOffset) {
|
|
572
|
+
const dragOffset = this.dragOffset;
|
|
573
|
+
if (dragOffset === null || contentSize === null) return false;
|
|
574
|
+
const velocity = this.adjustReleaseVelocityAgainstDisplacement(this.session.getReleaseVelocity(), dragOffset - resolvedSnapOffset);
|
|
575
|
+
if (contentSize - dragOffset <= 0) return true;
|
|
576
|
+
let targetOffset = dragOffset;
|
|
577
|
+
if (Math.abs(velocity) >= SNAP_VELOCITY_THRESHOLD) {
|
|
578
|
+
const clamped = require_utils.clampValue(velocity, -MAX_SNAP_VELOCITY, MAX_SNAP_VELOCITY);
|
|
579
|
+
targetOffset += clamped * SNAP_VELOCITY_MULTIPLIER;
|
|
580
|
+
targetOffset = Math.max(0, targetOffset);
|
|
581
|
+
}
|
|
582
|
+
const closeDistance = Math.abs(targetOffset - contentSize);
|
|
583
|
+
const closest = findClosestSnapPoint(targetOffset, snapPoints);
|
|
584
|
+
return closeDistance < Math.abs(targetOffset - closest.offset);
|
|
585
|
+
}
|
|
586
|
+
getSwipeStrength(targetOffset, resolvedSnapOffset = null) {
|
|
587
|
+
const dragOffset = this.dragOffset;
|
|
588
|
+
if (dragOffset === null) return SWIPE_STRENGTH_MAX_SCALAR;
|
|
589
|
+
let velocity = this.session.getReleaseVelocity();
|
|
590
|
+
if (resolvedSnapOffset != null) velocity = this.adjustReleaseVelocityAgainstDisplacement(velocity, dragOffset - resolvedSnapOffset);
|
|
591
|
+
const distance = Math.abs(dragOffset - targetOffset);
|
|
592
|
+
const absVelocity = Math.abs(velocity);
|
|
593
|
+
if (absVelocity <= 0 || distance <= 0) return SWIPE_STRENGTH_MAX_SCALAR;
|
|
594
|
+
return SWIPE_STRENGTH_MIN_SCALAR + require_utils.clampValue(distance / absVelocity * 1e3 / SWIPE_STRENGTH_MAX_DURATION_MS, 0, 1) * (SWIPE_STRENGTH_MAX_SCALAR - SWIPE_STRENGTH_MIN_SCALAR);
|
|
595
|
+
}
|
|
596
|
+
bindDragTracking(options) {
|
|
597
|
+
const { getDoc, getContentEl, getSwipeAreaEl, swipeDirection, onMove, onEnd, onCancel } = options;
|
|
598
|
+
const preventDragOnScroll = this.preventDragOnScroll;
|
|
599
|
+
const isVertical = isVerticalSwipeDirection(swipeDirection);
|
|
600
|
+
let lastAxis = 0;
|
|
601
|
+
return this.session.bind({
|
|
602
|
+
getDoc,
|
|
603
|
+
getSelectionTarget: getContentEl,
|
|
604
|
+
swipeDirection,
|
|
605
|
+
onMove,
|
|
606
|
+
onEnd,
|
|
607
|
+
onCancel,
|
|
608
|
+
cancelOnInterrupt: ({ reason, target }) => {
|
|
609
|
+
if (reason !== "lost-pointer-capture") return true;
|
|
610
|
+
return isWithinDrawerInteractionSurface(target, getContentEl(), getSwipeAreaEl());
|
|
611
|
+
},
|
|
612
|
+
onStart({ pointerType, point }) {
|
|
613
|
+
if (pointerType !== "touch") return;
|
|
614
|
+
lastAxis = isVertical ? point.y : point.x;
|
|
615
|
+
},
|
|
616
|
+
preventDefault({ event, pointerType, point, target }) {
|
|
617
|
+
if (pointerType !== "touch") return false;
|
|
618
|
+
const contentEl = getContentEl();
|
|
619
|
+
const resolvedTarget = target ?? event.target;
|
|
620
|
+
if (!preventDragOnScroll()) return false;
|
|
621
|
+
if (!contentEl || !resolvedTarget || isDragExemptElement(resolvedTarget)) return false;
|
|
622
|
+
const scrollParent = findClosestScrollableAncestorOnSwipeAxis(resolvedTarget, contentEl, swipeDirection);
|
|
623
|
+
if (scrollParent) {
|
|
624
|
+
const currentAxis = isVertical ? point.y : point.x;
|
|
625
|
+
const shouldPrevent = shouldPreventTouchScroll({
|
|
626
|
+
scrollParent,
|
|
627
|
+
swipeDirection,
|
|
628
|
+
lastMainAxis: lastAxis,
|
|
629
|
+
currentMainAxis: currentAxis
|
|
630
|
+
});
|
|
631
|
+
lastAxis = currentAxis;
|
|
632
|
+
return shouldPrevent;
|
|
633
|
+
}
|
|
634
|
+
lastAxis = isVertical ? point.y : point.x;
|
|
635
|
+
return false;
|
|
636
|
+
}
|
|
637
|
+
});
|
|
638
|
+
}
|
|
639
|
+
bindSwipeOpenTracking(options) {
|
|
640
|
+
const { getDoc, getContentEl, getSwipeAreaEl, swipeDirection, onMove, onEnd, onCancel } = options;
|
|
641
|
+
return this.session.bind({
|
|
642
|
+
getDoc,
|
|
643
|
+
getSelectionTarget: getSwipeAreaEl,
|
|
644
|
+
swipeDirection,
|
|
645
|
+
onMove({ point }) {
|
|
646
|
+
onMove({ point });
|
|
647
|
+
},
|
|
648
|
+
onEnd,
|
|
649
|
+
onCancel,
|
|
650
|
+
cancelOnInterrupt: ({ reason, target }) => {
|
|
651
|
+
if (reason !== "lost-pointer-capture") return true;
|
|
652
|
+
return isWithinDrawerInteractionSurface(target, getContentEl(), getSwipeAreaEl());
|
|
653
|
+
}
|
|
654
|
+
});
|
|
655
|
+
}
|
|
656
|
+
};
|
|
657
|
+
function isWithinDrawerInteractionSurface(target, contentEl, swipeAreaEl) {
|
|
658
|
+
if (!target) return false;
|
|
659
|
+
return require_dom_query.contains(contentEl, target) || require_dom_query.contains(swipeAreaEl, target);
|
|
660
|
+
}
|
|
661
|
+
const oppositeSwipeDirection = {
|
|
662
|
+
up: "down",
|
|
663
|
+
down: "up",
|
|
664
|
+
start: "end",
|
|
665
|
+
end: "start"
|
|
666
|
+
};
|
|
667
|
+
function resolveSwipeDirection(direction, dir) {
|
|
668
|
+
if (direction === "start") return dir === "rtl" ? "right" : "left";
|
|
669
|
+
if (direction === "end") return dir === "rtl" ? "left" : "right";
|
|
670
|
+
return direction;
|
|
671
|
+
}
|
|
672
|
+
function getSwipeDirectionSize(rect, direction) {
|
|
673
|
+
return isVerticalSwipeDirection(direction) ? rect.height : rect.width;
|
|
674
|
+
}
|
|
675
|
+
function resolveSwipeProgress(contentSize, dragOffset, snapPointOffset) {
|
|
676
|
+
if (!contentSize || contentSize <= 0) return 0;
|
|
677
|
+
return require_utils.clampValue(1 - (dragOffset ?? snapPointOffset) / contentSize, 0, 1);
|
|
678
|
+
}
|
|
679
|
+
function hasOpeningSwipeIntent(start, current, direction) {
|
|
680
|
+
const axis = isVerticalSwipeDirection(direction) ? "y" : "x";
|
|
681
|
+
const sign = isNegativeSwipeDirection(direction) ? -1 : 1;
|
|
682
|
+
return (start[axis] - current[axis]) * sign > SWIPE_AREA_OPEN_INTENT_MIN_PX;
|
|
683
|
+
}
|
|
684
|
+
function overflowAllowsScroll(overflow) {
|
|
685
|
+
return overflow === "auto" || overflow === "scroll" || overflow === "overlay";
|
|
686
|
+
}
|
|
687
|
+
function canScrollAlongY(el) {
|
|
688
|
+
if (!overflowAllowsScroll(require_dom_query.getComputedStyle(el).overflowY)) return false;
|
|
689
|
+
return el.scrollHeight > el.clientHeight + SCROLL_SLACK_EPSILON;
|
|
690
|
+
}
|
|
691
|
+
function canScrollAlongX(el) {
|
|
692
|
+
if (!overflowAllowsScroll(require_dom_query.getComputedStyle(el).overflowX)) return false;
|
|
693
|
+
return el.scrollWidth > el.clientWidth + SCROLL_SLACK_EPSILON;
|
|
694
|
+
}
|
|
695
|
+
function canScrollOnSwipeAxis(el, direction) {
|
|
696
|
+
return isVerticalSwipeDirection(direction) ? canScrollAlongY(el) : canScrollAlongX(el);
|
|
697
|
+
}
|
|
698
|
+
function findClosestScrollableAncestorOnSwipeAxis(target, container, direction) {
|
|
699
|
+
if (!container) return null;
|
|
700
|
+
let el = target;
|
|
701
|
+
while (el && el !== container) {
|
|
702
|
+
if (canScrollOnSwipeAxis(el, direction)) return el;
|
|
703
|
+
el = el.parentElement;
|
|
704
|
+
}
|
|
705
|
+
return null;
|
|
706
|
+
}
|
|
707
|
+
function getScrollInfo(target, container, direction) {
|
|
708
|
+
let availableForwardScroll = 0;
|
|
709
|
+
let availableBackwardScroll = 0;
|
|
710
|
+
if (!container) return {
|
|
711
|
+
availableForwardScroll,
|
|
712
|
+
availableBackwardScroll
|
|
713
|
+
};
|
|
714
|
+
const vertical = isVerticalSwipeDirection(direction);
|
|
715
|
+
let element = target;
|
|
716
|
+
while (element) {
|
|
717
|
+
if (vertical ? canScrollAlongY(element) : canScrollAlongX(element)) {
|
|
718
|
+
const clientSize = vertical ? element.clientHeight : element.clientWidth;
|
|
719
|
+
const scrollPos = vertical ? element.scrollTop : element.scrollLeft;
|
|
720
|
+
const scrolled = (vertical ? element.scrollHeight : element.scrollWidth) - scrollPos - clientSize;
|
|
721
|
+
availableForwardScroll += scrolled;
|
|
722
|
+
availableBackwardScroll += scrollPos;
|
|
723
|
+
}
|
|
724
|
+
if (element === container || element === element.ownerDocument.documentElement) break;
|
|
725
|
+
element = element.parentElement;
|
|
726
|
+
}
|
|
727
|
+
return {
|
|
728
|
+
availableForwardScroll,
|
|
729
|
+
availableBackwardScroll
|
|
730
|
+
};
|
|
731
|
+
}
|
|
732
|
+
function shouldPreventTouchScroll(options) {
|
|
733
|
+
const { scrollParent, swipeDirection, lastMainAxis, currentMainAxis } = options;
|
|
734
|
+
const vertical = isVerticalSwipeDirection(swipeDirection);
|
|
735
|
+
const movingPositive = currentMainAxis > lastMainAxis;
|
|
736
|
+
if (vertical) {
|
|
737
|
+
const scrollPos = scrollParent.scrollTop;
|
|
738
|
+
const maxScroll = Math.max(0, scrollParent.scrollHeight - scrollParent.clientHeight);
|
|
739
|
+
if (swipeDirection === "down") return scrollPos <= SCROLL_SLACK_EPSILON && movingPositive;
|
|
740
|
+
if (swipeDirection === "up") return scrollPos >= maxScroll - SCROLL_SLACK_EPSILON && !movingPositive;
|
|
741
|
+
} else {
|
|
742
|
+
const scrollPos = scrollParent.scrollLeft;
|
|
743
|
+
const maxScroll = Math.max(0, scrollParent.scrollWidth - scrollParent.clientWidth);
|
|
744
|
+
if (swipeDirection === "right") return scrollPos <= SCROLL_SLACK_EPSILON && movingPositive;
|
|
745
|
+
if (swipeDirection === "left") return scrollPos >= maxScroll - SCROLL_SLACK_EPSILON && !movingPositive;
|
|
746
|
+
}
|
|
747
|
+
return false;
|
|
748
|
+
}
|
|
749
|
+
function isDragExemptElement(el) {
|
|
750
|
+
if (!require_dom_query.isHTMLElement(el)) return false;
|
|
751
|
+
if (el.closest(NO_DRAG_SELECTOR)) return true;
|
|
752
|
+
let node = el;
|
|
753
|
+
while (node) {
|
|
754
|
+
if (require_dom_query.isEditableElement(node)) return true;
|
|
755
|
+
node = node.parentElement;
|
|
756
|
+
}
|
|
757
|
+
const input = el.closest("input");
|
|
758
|
+
if (require_dom_query.isInputElement(input)) {
|
|
759
|
+
const type = input.type;
|
|
760
|
+
if (type === "range" || type === "file") return true;
|
|
761
|
+
}
|
|
762
|
+
return false;
|
|
763
|
+
}
|
|
764
|
+
function isTextSelectionInDrawer(doc, contentEl) {
|
|
765
|
+
if (!contentEl) return false;
|
|
766
|
+
const selection = doc.getSelection();
|
|
767
|
+
if (!selection || selection.rangeCount === 0 || selection.isCollapsed) return false;
|
|
768
|
+
try {
|
|
769
|
+
const range = selection.getRangeAt(0);
|
|
770
|
+
if (require_dom_query.contains(contentEl, range.commonAncestorContainer)) return true;
|
|
771
|
+
if (require_dom_query.contains(contentEl, selection.anchorNode)) return true;
|
|
772
|
+
if (require_dom_query.contains(contentEl, selection.focusNode)) return true;
|
|
773
|
+
if (typeof range.intersectsNode === "function" && range.intersectsNode(contentEl)) return true;
|
|
774
|
+
} catch {
|
|
775
|
+
return false;
|
|
776
|
+
}
|
|
777
|
+
return false;
|
|
778
|
+
}
|
|
779
|
+
function isDragExemptFromComposedPath(event) {
|
|
780
|
+
const path = typeof event.composedPath === "function" ? event.composedPath() : [];
|
|
781
|
+
for (const node of path) if (isDragExemptElement(node)) return true;
|
|
782
|
+
return isDragExemptElement(event.target);
|
|
783
|
+
}
|
|
784
|
+
function shouldIgnorePointerDownForDrag(event) {
|
|
785
|
+
if (!require_dom_query.isLeftClick(event)) return true;
|
|
786
|
+
const target = require_dom_query.getEventTarget(event);
|
|
787
|
+
if (target?.hasAttribute(NO_DRAG_DATA_ATTR) || target?.closest(NO_DRAG_SELECTOR)) return true;
|
|
788
|
+
return isDragExemptFromComposedPath(event);
|
|
789
|
+
}
|
|
28
790
|
//#endregion
|
|
29
791
|
//#region src/machines/drawer/drawer.connect.ts
|
|
792
|
+
const SWIPE_OPEN_HIDDEN_OFFSET = 9999;
|
|
793
|
+
function getSwipeOpenOffset(swipingOpen, dragOffset, contentSize) {
|
|
794
|
+
if (!swipingOpen || dragOffset !== null) return null;
|
|
795
|
+
return contentSize ?? SWIPE_OPEN_HIDDEN_OFFSET;
|
|
796
|
+
}
|
|
30
797
|
function connect(service, normalize) {
|
|
31
|
-
const { state, send, context, scope, prop } = service;
|
|
798
|
+
const { state, send, context, scope, prop, refs } = service;
|
|
32
799
|
const open = state.hasTag("open");
|
|
800
|
+
const closed = state.matches("closed");
|
|
801
|
+
const swipingOpen = state.matches("swiping-open");
|
|
33
802
|
const dragOffset = context.get("dragOffset");
|
|
34
803
|
const dragging = dragOffset !== null;
|
|
35
|
-
const
|
|
804
|
+
const snapPoint = context.get("snapPoint");
|
|
805
|
+
const swipeDirection = prop("swipeDirection");
|
|
806
|
+
const physicalDirection = resolveSwipeDirection(swipeDirection, prop("dir"));
|
|
807
|
+
const contentSize = context.get("contentSize");
|
|
808
|
+
const swipeStrength = context.get("swipeStrength");
|
|
36
809
|
const resolvedActiveSnapPoint = context.get("resolvedActiveSnapPoint");
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
810
|
+
const snapPointOffset = resolvedActiveSnapPoint?.offset ?? 0;
|
|
811
|
+
const currentOffset = getSwipeOpenOffset(swipingOpen, dragOffset, contentSize) ?? dragOffset ?? snapPointOffset;
|
|
812
|
+
const signedSnapPointOffset = isNegativeSwipeDirection(physicalDirection) ? -snapPointOffset : snapPointOffset;
|
|
813
|
+
const isActivelySwiping = dragging || swipingOpen;
|
|
814
|
+
const swipeMovement = dragging || swipingOpen ? currentOffset - snapPointOffset : 0;
|
|
815
|
+
const signedMovement = isNegativeSwipeDirection(physicalDirection) ? -swipeMovement : swipeMovement;
|
|
816
|
+
const swipeProgress = isActivelySwiping && contentSize && contentSize > 0 ? require_utils.clampValue(Math.abs(signedMovement) / contentSize, 0, 1) : swipingOpen ? 1 : 0;
|
|
817
|
+
const signedCurrentOffset = isNegativeSwipeDirection(physicalDirection) ? -currentOffset : currentOffset;
|
|
818
|
+
const translateX = isVerticalSwipeDirection(physicalDirection) ? 0 : signedCurrentOffset;
|
|
819
|
+
const translateY = isVerticalSwipeDirection(physicalDirection) ? signedCurrentOffset : 0;
|
|
820
|
+
function onContentPointerDown(event) {
|
|
821
|
+
refs.get("swipeSession").contentPointerDown({
|
|
822
|
+
event,
|
|
823
|
+
getDoc: () => scope.getDoc(),
|
|
824
|
+
getContentEl: () => getContentEl(scope),
|
|
825
|
+
getWin: () => scope.getWin(),
|
|
826
|
+
swipeDirection: physicalDirection,
|
|
827
|
+
canCommit: () => state.hasTag("open") && !state.matches("closing"),
|
|
828
|
+
onCommit(point) {
|
|
829
|
+
send({
|
|
830
|
+
type: "POINTER_DOWN",
|
|
831
|
+
point
|
|
832
|
+
});
|
|
833
|
+
}
|
|
834
|
+
});
|
|
835
|
+
}
|
|
836
|
+
function onGrabberPointerDown(event) {
|
|
837
|
+
refs.get("swipeSession").grabberPointerDown({
|
|
838
|
+
event,
|
|
839
|
+
point: require_dom_query.getEventPoint(event),
|
|
840
|
+
canCommit: () => state.hasTag("open") && !state.matches("closing"),
|
|
841
|
+
onCommit(point) {
|
|
842
|
+
send({
|
|
843
|
+
type: "POINTER_DOWN",
|
|
844
|
+
point
|
|
845
|
+
});
|
|
846
|
+
}
|
|
46
847
|
});
|
|
47
848
|
}
|
|
48
849
|
return {
|
|
@@ -53,47 +854,74 @@ function connect(service, normalize) {
|
|
|
53
854
|
send({ type: nextOpen ? "OPEN" : "CLOSE" });
|
|
54
855
|
},
|
|
55
856
|
snapPoints: prop("snapPoints"),
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
857
|
+
swipeDirection,
|
|
858
|
+
snapPoint,
|
|
859
|
+
setSnapPoint(snapPoint) {
|
|
860
|
+
if (context.get("snapPoint") === snapPoint) return;
|
|
59
861
|
send({
|
|
60
|
-
type: "
|
|
862
|
+
type: "SNAP_POINT.SET",
|
|
61
863
|
snapPoint
|
|
62
864
|
});
|
|
63
865
|
},
|
|
64
866
|
getOpenPercentage() {
|
|
65
|
-
if (!open) return 0;
|
|
66
|
-
|
|
67
|
-
if (!contentHeight) return 0;
|
|
68
|
-
const currentOffset = translate ?? 0;
|
|
69
|
-
return Math.max(0, Math.min(1, 1 - currentOffset / contentHeight));
|
|
867
|
+
if (!open || !contentSize) return 0;
|
|
868
|
+
return require_utils.clampValue(1 - currentOffset / contentSize, 0, 1);
|
|
70
869
|
},
|
|
71
|
-
|
|
72
|
-
|
|
870
|
+
getSnapPointIndex() {
|
|
871
|
+
if (snapPoint === null) return -1;
|
|
872
|
+
return prop("snapPoints").indexOf(snapPoint);
|
|
73
873
|
},
|
|
74
|
-
|
|
75
|
-
return
|
|
874
|
+
getContentSize() {
|
|
875
|
+
return contentSize;
|
|
876
|
+
},
|
|
877
|
+
getPositionerProps() {
|
|
878
|
+
return normalize.element({
|
|
879
|
+
...parts.positioner.attrs,
|
|
880
|
+
id: getPositionerId(scope),
|
|
881
|
+
dir: prop("dir"),
|
|
882
|
+
hidden: closed,
|
|
883
|
+
"data-state": open ? "open" : "closed",
|
|
884
|
+
"data-swipe-direction": physicalDirection,
|
|
885
|
+
style: require_utils.compact({ pointerEvents: prop("modal") ? void 0 : "none" })
|
|
886
|
+
});
|
|
76
887
|
},
|
|
77
888
|
getContentProps(props = { draggable: true }) {
|
|
889
|
+
const movementX = isVerticalSwipeDirection(physicalDirection) ? 0 : signedMovement;
|
|
890
|
+
const movementY = isVerticalSwipeDirection(physicalDirection) ? signedMovement : 0;
|
|
891
|
+
const rendered = context.get("rendered");
|
|
78
892
|
return normalize.element({
|
|
79
893
|
...parts.content.attrs,
|
|
80
894
|
dir: prop("dir"),
|
|
81
895
|
id: getContentId(scope),
|
|
82
896
|
tabIndex: -1,
|
|
83
|
-
role: "
|
|
897
|
+
role: prop("role"),
|
|
84
898
|
"aria-modal": prop("modal"),
|
|
85
|
-
"aria-labelledby": getTitleId(scope),
|
|
899
|
+
"aria-labelledby": rendered.title ? getTitleId(scope) : void 0,
|
|
900
|
+
"aria-describedby": rendered.description ? getDescriptionId(scope) : void 0,
|
|
86
901
|
hidden: !open,
|
|
87
902
|
"data-state": open ? "open" : "closed",
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
903
|
+
"data-expanded": resolvedActiveSnapPoint?.offset === 0 ? "" : void 0,
|
|
904
|
+
"data-swipe-direction": physicalDirection,
|
|
905
|
+
"data-swiping": dragging || swipingOpen ? "" : void 0,
|
|
906
|
+
"data-dragging": dragging ? "" : void 0,
|
|
907
|
+
style: require_utils.compact({
|
|
908
|
+
pointerEvents: prop("modal") ? void 0 : "auto",
|
|
909
|
+
visibility: swipingOpen && dragOffset === null ? "hidden" : void 0,
|
|
910
|
+
transform: "translate3d(var(--drawer-translate-x, 0px), var(--drawer-translate-y, 0px), 0)",
|
|
911
|
+
transitionDuration: dragging || swipingOpen ? "0s" : void 0,
|
|
912
|
+
"--drawer-translate": require_utils.toPx(translateY),
|
|
913
|
+
"--drawer-translate-x": require_utils.toPx(translateX),
|
|
914
|
+
"--drawer-translate-y": require_utils.toPx(translateY),
|
|
915
|
+
"--drawer-snap-point-offset-x": isVerticalSwipeDirection(physicalDirection) ? "0px" : require_utils.toPx(signedSnapPointOffset),
|
|
916
|
+
"--drawer-snap-point-offset-y": isVerticalSwipeDirection(physicalDirection) ? require_utils.toPx(signedSnapPointOffset) : "0px",
|
|
917
|
+
"--drawer-swipe-movement-x": require_utils.toPx(movementX),
|
|
918
|
+
"--drawer-swipe-movement-y": require_utils.toPx(movementY),
|
|
919
|
+
"--drawer-swipe-strength": `${swipeStrength}`,
|
|
92
920
|
willChange: "transform"
|
|
93
|
-
},
|
|
921
|
+
}),
|
|
94
922
|
onPointerDown(event) {
|
|
95
923
|
if (!props.draggable) return;
|
|
96
|
-
|
|
924
|
+
onContentPointerDown(event);
|
|
97
925
|
}
|
|
98
926
|
});
|
|
99
927
|
},
|
|
@@ -104,6 +932,13 @@ function connect(service, normalize) {
|
|
|
104
932
|
dir: prop("dir")
|
|
105
933
|
});
|
|
106
934
|
},
|
|
935
|
+
getDescriptionProps() {
|
|
936
|
+
return normalize.element({
|
|
937
|
+
...parts.description.attrs,
|
|
938
|
+
id: getDescriptionId(scope),
|
|
939
|
+
dir: prop("dir")
|
|
940
|
+
});
|
|
941
|
+
},
|
|
107
942
|
getTriggerProps() {
|
|
108
943
|
return normalize.button({
|
|
109
944
|
...parts.trigger.attrs,
|
|
@@ -118,9 +953,14 @@ function connect(service, normalize) {
|
|
|
118
953
|
return normalize.element({
|
|
119
954
|
...parts.backdrop.attrs,
|
|
120
955
|
id: getBackdropId(scope),
|
|
121
|
-
hidden: !open,
|
|
956
|
+
hidden: !open || swipingOpen && dragOffset === null,
|
|
122
957
|
"data-state": open ? "open" : "closed",
|
|
123
|
-
|
|
958
|
+
"data-swiping": dragging || swipingOpen ? "" : void 0,
|
|
959
|
+
style: {
|
|
960
|
+
willChange: "opacity",
|
|
961
|
+
"--drawer-swipe-progress": `${swipeProgress}`,
|
|
962
|
+
"--drawer-swipe-strength": `${swipeStrength}`
|
|
963
|
+
}
|
|
124
964
|
});
|
|
125
965
|
},
|
|
126
966
|
getGrabberProps() {
|
|
@@ -128,7 +968,7 @@ function connect(service, normalize) {
|
|
|
128
968
|
...parts.grabber.attrs,
|
|
129
969
|
id: getGrabberId(scope),
|
|
130
970
|
onPointerDown(event) {
|
|
131
|
-
|
|
971
|
+
onGrabberPointerDown(event);
|
|
132
972
|
},
|
|
133
973
|
style: { touchAction: "none" }
|
|
134
974
|
});
|
|
@@ -147,143 +987,121 @@ function connect(service, normalize) {
|
|
|
147
987
|
send({ type: "CLOSE" });
|
|
148
988
|
}
|
|
149
989
|
});
|
|
990
|
+
},
|
|
991
|
+
getSwipeAreaProps(props = {}) {
|
|
992
|
+
const disabled = props.disabled ?? false;
|
|
993
|
+
const physicalOpenDirection = resolveSwipeDirection(props.swipeDirection ?? oppositeSwipeDirection[swipeDirection], prop("dir"));
|
|
994
|
+
return normalize.element({
|
|
995
|
+
...parts.swipeArea.attrs,
|
|
996
|
+
id: getSwipeAreaId(scope),
|
|
997
|
+
role: "presentation",
|
|
998
|
+
"aria-hidden": true,
|
|
999
|
+
"data-state": open ? "open" : "closed",
|
|
1000
|
+
"data-swiping": swipingOpen ? "" : void 0,
|
|
1001
|
+
"data-swipe-direction": physicalOpenDirection,
|
|
1002
|
+
"data-disabled": disabled ? "" : void 0,
|
|
1003
|
+
style: {
|
|
1004
|
+
touchAction: isVerticalSwipeDirection(physicalOpenDirection) ? "pan-x" : "pan-y",
|
|
1005
|
+
pointerEvents: disabled || open && !swipingOpen ? "none" : void 0
|
|
1006
|
+
},
|
|
1007
|
+
onPointerDown(event) {
|
|
1008
|
+
if (disabled) return;
|
|
1009
|
+
if (!require_dom_query.isLeftClick(event)) return;
|
|
1010
|
+
if (event.pointerType === "touch") return;
|
|
1011
|
+
if (open && !swipingOpen) return;
|
|
1012
|
+
send({
|
|
1013
|
+
type: "SWIPE_AREA.START",
|
|
1014
|
+
point: require_dom_query.getEventPoint(event)
|
|
1015
|
+
});
|
|
1016
|
+
if (event.cancelable) event.preventDefault();
|
|
1017
|
+
},
|
|
1018
|
+
onTouchStart(event) {
|
|
1019
|
+
if (disabled) return;
|
|
1020
|
+
if (open && !swipingOpen) return;
|
|
1021
|
+
const touch = event.touches[0];
|
|
1022
|
+
if (!touch) return;
|
|
1023
|
+
send({
|
|
1024
|
+
type: "SWIPE_AREA.START",
|
|
1025
|
+
point: {
|
|
1026
|
+
x: touch.clientX,
|
|
1027
|
+
y: touch.clientY
|
|
1028
|
+
}
|
|
1029
|
+
});
|
|
1030
|
+
}
|
|
1031
|
+
});
|
|
150
1032
|
}
|
|
151
1033
|
};
|
|
152
1034
|
}
|
|
153
1035
|
//#endregion
|
|
154
|
-
//#region src/machines/drawer/
|
|
155
|
-
|
|
156
|
-
return snapPoints.reduce((acc, curr) => {
|
|
157
|
-
const closestDiff = Math.abs(offset - acc.offset);
|
|
158
|
-
return Math.abs(offset - curr.offset) < closestDiff ? curr : acc;
|
|
159
|
-
});
|
|
160
|
-
}
|
|
161
|
-
//#endregion
|
|
162
|
-
//#region src/machines/drawer/utils/get-scroll-info.ts
|
|
163
|
-
function isScrollContainer(element) {
|
|
164
|
-
const overflow = getComputedStyle(element).overflowY;
|
|
165
|
-
return overflow === "auto" || overflow === "scroll";
|
|
166
|
-
}
|
|
167
|
-
function getScrollInfo(target, container) {
|
|
168
|
-
let element = target;
|
|
169
|
-
let availableScroll = 0;
|
|
170
|
-
let availableScrollTop = 0;
|
|
171
|
-
while (element) {
|
|
172
|
-
const { clientHeight, scrollTop, scrollHeight } = element;
|
|
173
|
-
const scrolled = scrollHeight - scrollTop - clientHeight;
|
|
174
|
-
if ((scrollTop !== 0 || scrolled !== 0) && isScrollContainer(element)) {
|
|
175
|
-
availableScroll += scrolled;
|
|
176
|
-
availableScrollTop += scrollTop;
|
|
177
|
-
}
|
|
178
|
-
if (element === container || element === document.documentElement) break;
|
|
179
|
-
element = element.parentNode;
|
|
180
|
-
}
|
|
181
|
-
return {
|
|
182
|
-
availableScroll,
|
|
183
|
-
availableScrollTop
|
|
184
|
-
};
|
|
185
|
-
}
|
|
186
|
-
//#endregion
|
|
187
|
-
//#region src/machines/drawer/utils/drag-manager.ts
|
|
188
|
-
const DRAG_START_THRESHOLD = .3;
|
|
189
|
-
var DragManager = class {
|
|
1036
|
+
//#region src/machines/drawer/drawer.registry.ts
|
|
1037
|
+
var DrawerRegistry = class {
|
|
190
1038
|
constructor() {
|
|
191
|
-
require_defineProperty._defineProperty(this, "
|
|
192
|
-
require_defineProperty._defineProperty(this, "
|
|
193
|
-
require_defineProperty._defineProperty(this, "
|
|
194
|
-
require_defineProperty._defineProperty(this, "
|
|
195
|
-
require_defineProperty._defineProperty(this, "velocity", null);
|
|
1039
|
+
require_defineProperty._defineProperty(this, "elements", /* @__PURE__ */ new Map());
|
|
1040
|
+
require_defineProperty._defineProperty(this, "swipingIds", /* @__PURE__ */ new Set());
|
|
1041
|
+
require_defineProperty._defineProperty(this, "swipeProgress", /* @__PURE__ */ new Map());
|
|
1042
|
+
require_defineProperty._defineProperty(this, "listeners", /* @__PURE__ */ new Set());
|
|
196
1043
|
}
|
|
197
|
-
|
|
198
|
-
this.
|
|
199
|
-
}
|
|
200
|
-
clearPointerStart() {
|
|
201
|
-
this.pointerStart = null;
|
|
202
|
-
}
|
|
203
|
-
getPointerStart() {
|
|
204
|
-
return this.pointerStart;
|
|
205
|
-
}
|
|
206
|
-
setDragOffset(point, resolvedActiveSnapPointOffset) {
|
|
207
|
-
if (!this.pointerStart) return;
|
|
208
|
-
const currentTimestamp = (/* @__PURE__ */ new Date()).getTime();
|
|
209
|
-
if (this.lastPoint) {
|
|
210
|
-
const dy = point.y - this.lastPoint.y;
|
|
211
|
-
if (this.lastTimestamp) {
|
|
212
|
-
const dt = currentTimestamp - this.lastTimestamp;
|
|
213
|
-
if (dt > 0) {
|
|
214
|
-
const calculatedVelocity = dy / dt * 1e3;
|
|
215
|
-
this.velocity = Number.isFinite(calculatedVelocity) ? calculatedVelocity : 0;
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
this.lastPoint = point;
|
|
220
|
-
this.lastTimestamp = currentTimestamp;
|
|
221
|
-
let delta = this.pointerStart.y - point.y - resolvedActiveSnapPointOffset;
|
|
222
|
-
if (delta > 0) delta = 0;
|
|
223
|
-
this.dragOffset = -delta;
|
|
1044
|
+
notify() {
|
|
1045
|
+
this.listeners.forEach((fn) => fn());
|
|
224
1046
|
}
|
|
225
|
-
|
|
226
|
-
|
|
1047
|
+
register(id, el) {
|
|
1048
|
+
this.elements.set(id, el);
|
|
1049
|
+
this.notify();
|
|
227
1050
|
}
|
|
228
|
-
|
|
229
|
-
this.
|
|
1051
|
+
unregister(id) {
|
|
1052
|
+
this.swipingIds.delete(id);
|
|
1053
|
+
this.swipeProgress.delete(id);
|
|
1054
|
+
if (!this.elements.delete(id)) return;
|
|
1055
|
+
this.notify();
|
|
230
1056
|
}
|
|
231
|
-
|
|
232
|
-
|
|
1057
|
+
setSwiping(id, swiping) {
|
|
1058
|
+
if (!(swiping ? !this.swipingIds.has(id) : this.swipingIds.has(id)) && swiping) return;
|
|
1059
|
+
if (swiping) this.swipingIds.add(id);
|
|
1060
|
+
else {
|
|
1061
|
+
this.swipingIds.delete(id);
|
|
1062
|
+
this.swipeProgress.delete(id);
|
|
1063
|
+
}
|
|
1064
|
+
this.notify();
|
|
233
1065
|
}
|
|
234
|
-
|
|
235
|
-
this.
|
|
236
|
-
this.
|
|
237
|
-
this.velocity = null;
|
|
1066
|
+
setSwipeProgress(id, progress) {
|
|
1067
|
+
this.swipeProgress.set(id, progress);
|
|
1068
|
+
this.notify();
|
|
238
1069
|
}
|
|
239
|
-
|
|
240
|
-
this.
|
|
241
|
-
|
|
242
|
-
|
|
1070
|
+
getSwipeProgressAfter(id) {
|
|
1071
|
+
const keys = [...this.elements.keys()];
|
|
1072
|
+
const myIndex = keys.indexOf(id);
|
|
1073
|
+
if (myIndex === -1) return 0;
|
|
1074
|
+
for (let i = keys.length - 1; i > myIndex; i -= 1) if (this.swipingIds.has(keys[i])) return this.swipeProgress.get(keys[i]) ?? 0;
|
|
1075
|
+
return 0;
|
|
243
1076
|
}
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
const { availableScroll, availableScrollTop } = getScrollInfo(target, container);
|
|
250
|
-
if (delta > 0 && Math.abs(availableScroll) > 1 || delta < 0 && Math.abs(availableScrollTop) > 0) return false;
|
|
251
|
-
}
|
|
252
|
-
return true;
|
|
1077
|
+
hasSwipingAfter(id) {
|
|
1078
|
+
const keys = [...this.elements.keys()];
|
|
1079
|
+
const myIndex = keys.indexOf(id);
|
|
1080
|
+
if (myIndex === -1) return false;
|
|
1081
|
+
return keys.slice(myIndex + 1).some((key) => this.swipingIds.has(key));
|
|
253
1082
|
}
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
return findClosestSnapPoint(this.dragOffset, snapPoints).value;
|
|
1083
|
+
getEntries() {
|
|
1084
|
+
return this.elements;
|
|
257
1085
|
}
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
const closeThresholdInPixels = contentHeight * (1 - closeThreshold);
|
|
264
|
-
const isBelowSmallestSnapPoint = visibleHeight < contentHeight - smallestSnapPoint.offset;
|
|
265
|
-
return isFastSwipe || visibleHeight < closeThresholdInPixels && isBelowSmallestSnapPoint || visibleHeight === 0;
|
|
1086
|
+
subscribe(fn) {
|
|
1087
|
+
this.listeners.add(fn);
|
|
1088
|
+
return () => {
|
|
1089
|
+
this.listeners.delete(fn);
|
|
1090
|
+
};
|
|
266
1091
|
}
|
|
267
1092
|
};
|
|
268
|
-
|
|
269
|
-
//#region src/machines/drawer/utils/resolve-snap-point.ts
|
|
270
|
-
function resolveSnapPoint(snapPoint, containerHeight) {
|
|
271
|
-
if (typeof snapPoint === "number") return {
|
|
272
|
-
value: snapPoint,
|
|
273
|
-
offset: containerHeight - snapPoint * containerHeight
|
|
274
|
-
};
|
|
275
|
-
if (typeof snapPoint === "string") return {
|
|
276
|
-
value: snapPoint,
|
|
277
|
-
offset: containerHeight - parseFloat(snapPoint)
|
|
278
|
-
};
|
|
279
|
-
throw new Error(`Invalid snap point: ${snapPoint}`);
|
|
280
|
-
}
|
|
1093
|
+
const drawerRegistry = new DrawerRegistry();
|
|
281
1094
|
//#endregion
|
|
282
1095
|
//#region src/machines/drawer/drawer.machine.ts
|
|
1096
|
+
const { and } = require_core.createGuards();
|
|
1097
|
+
const getActiveSnapOffset = (context) => context.get("resolvedActiveSnapPoint")?.offset ?? 0;
|
|
1098
|
+
const hasRemSnapPoints = (snapPoints) => snapPoints.some((snapPoint) => typeof snapPoint === "string" && snapPoint.trim().endsWith("rem"));
|
|
1099
|
+
const DEFAULT_SNAP_POINTS = [1];
|
|
283
1100
|
const machine = require_core.createMachine({
|
|
284
1101
|
props({ props, scope }) {
|
|
285
1102
|
const initialFocusEl = props.role === "alertdialog" ? () => getCloseTriggerEl(scope) : void 0;
|
|
286
1103
|
const modal = typeof props.modal === "boolean" ? props.modal : true;
|
|
1104
|
+
const snapPoints = props.snapPoints ?? DEFAULT_SNAP_POINTS;
|
|
287
1105
|
return {
|
|
288
1106
|
modal,
|
|
289
1107
|
trapFocus: modal,
|
|
@@ -291,11 +1109,14 @@ const machine = require_core.createMachine({
|
|
|
291
1109
|
closeOnInteractOutside: true,
|
|
292
1110
|
closeOnEscape: true,
|
|
293
1111
|
restoreFocus: true,
|
|
1112
|
+
role: "dialog",
|
|
294
1113
|
initialFocusEl,
|
|
295
|
-
snapPoints
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
1114
|
+
snapPoints,
|
|
1115
|
+
defaultSnapPoint: props.defaultSnapPoint ?? snapPoints[0] ?? null,
|
|
1116
|
+
swipeDirection: "down",
|
|
1117
|
+
snapToSequentialPoints: false,
|
|
1118
|
+
swipeVelocityThreshold: 500,
|
|
1119
|
+
closeThreshold: .5,
|
|
299
1120
|
preventDragOnScroll: true,
|
|
300
1121
|
...props
|
|
301
1122
|
};
|
|
@@ -303,88 +1124,198 @@ const machine = require_core.createMachine({
|
|
|
303
1124
|
context({ bindable, prop }) {
|
|
304
1125
|
return {
|
|
305
1126
|
dragOffset: bindable(() => ({ defaultValue: null })),
|
|
306
|
-
|
|
307
|
-
defaultValue: prop("
|
|
308
|
-
value: prop("
|
|
309
|
-
onChange(
|
|
310
|
-
return prop("
|
|
1127
|
+
snapPoint: bindable(() => ({
|
|
1128
|
+
defaultValue: prop("defaultSnapPoint"),
|
|
1129
|
+
value: prop("snapPoint"),
|
|
1130
|
+
onChange(snapPoint) {
|
|
1131
|
+
return prop("onSnapPointChange")?.({ snapPoint });
|
|
311
1132
|
}
|
|
312
1133
|
})),
|
|
313
1134
|
resolvedActiveSnapPoint: bindable(() => ({ defaultValue: null })),
|
|
314
|
-
|
|
1135
|
+
contentSize: bindable(() => ({ defaultValue: null })),
|
|
1136
|
+
viewportSize: bindable(() => ({ defaultValue: 0 })),
|
|
1137
|
+
rootFontSize: bindable(() => ({ defaultValue: 16 })),
|
|
1138
|
+
swipeStrength: bindable(() => ({ defaultValue: 1 })),
|
|
1139
|
+
rendered: bindable(() => ({ defaultValue: {
|
|
1140
|
+
title: true,
|
|
1141
|
+
description: true
|
|
1142
|
+
} }))
|
|
315
1143
|
};
|
|
316
1144
|
},
|
|
317
|
-
refs() {
|
|
318
|
-
return {
|
|
1145
|
+
refs({ prop }) {
|
|
1146
|
+
return { swipeSession: new DrawerSwipeSession({ preventDragOnScroll: () => prop("preventDragOnScroll") }) };
|
|
319
1147
|
},
|
|
320
|
-
computed: {
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
const
|
|
329
|
-
|
|
330
|
-
const
|
|
331
|
-
|
|
1148
|
+
computed: {
|
|
1149
|
+
drawerId({ prop, scope }) {
|
|
1150
|
+
return String(prop("id") ?? scope.id);
|
|
1151
|
+
},
|
|
1152
|
+
physicalSwipeDirection({ prop }) {
|
|
1153
|
+
return resolveSwipeDirection(prop("swipeDirection"), prop("dir"));
|
|
1154
|
+
},
|
|
1155
|
+
resolvedSnapPoints({ context, prop }) {
|
|
1156
|
+
const contentSize = context.get("contentSize");
|
|
1157
|
+
const viewportSize = context.get("viewportSize");
|
|
1158
|
+
const rootFontSize = context.get("rootFontSize");
|
|
1159
|
+
if (contentSize === null) return [];
|
|
1160
|
+
return dedupeSnapPoints(prop("snapPoints").map((snapPoint) => resolveSnapPoint(snapPoint, {
|
|
1161
|
+
contentSize,
|
|
1162
|
+
viewportSize,
|
|
1163
|
+
rootFontSize
|
|
1164
|
+
})).filter((point) => point !== null));
|
|
1165
|
+
}
|
|
1166
|
+
},
|
|
1167
|
+
watch({ track, context, prop, action, computed }) {
|
|
1168
|
+
track([
|
|
1169
|
+
() => context.get("snapPoint"),
|
|
1170
|
+
() => context.get("contentSize"),
|
|
1171
|
+
() => context.get("viewportSize"),
|
|
1172
|
+
() => context.get("rootFontSize"),
|
|
1173
|
+
() => prop("snapPoints").join("|")
|
|
1174
|
+
], () => {
|
|
1175
|
+
const snapPoint = context.get("snapPoint");
|
|
1176
|
+
const contentSize = context.get("contentSize");
|
|
1177
|
+
const viewportSize = context.get("viewportSize");
|
|
1178
|
+
const rootFontSize = context.get("rootFontSize");
|
|
1179
|
+
if (snapPoint === null || contentSize === null) {
|
|
1180
|
+
context.set("resolvedActiveSnapPoint", null);
|
|
1181
|
+
return;
|
|
1182
|
+
}
|
|
1183
|
+
const resolvedPoints = computed("resolvedSnapPoints");
|
|
1184
|
+
const matchedPoint = resolvedPoints.find((point) => Object.is(point.value, snapPoint));
|
|
1185
|
+
if (matchedPoint) {
|
|
1186
|
+
context.set("resolvedActiveSnapPoint", matchedPoint);
|
|
1187
|
+
return;
|
|
1188
|
+
}
|
|
1189
|
+
const resolvedActiveSnapPoint = resolveSnapPoint(snapPoint, {
|
|
1190
|
+
contentSize,
|
|
1191
|
+
viewportSize,
|
|
1192
|
+
rootFontSize
|
|
1193
|
+
});
|
|
1194
|
+
if (resolvedActiveSnapPoint) {
|
|
1195
|
+
context.set("resolvedActiveSnapPoint", resolvedActiveSnapPoint);
|
|
1196
|
+
return;
|
|
1197
|
+
}
|
|
1198
|
+
const fallbackPoint = resolvedPoints[0];
|
|
1199
|
+
if (!fallbackPoint) {
|
|
1200
|
+
context.set("resolvedActiveSnapPoint", null);
|
|
1201
|
+
return;
|
|
1202
|
+
}
|
|
1203
|
+
context.set("snapPoint", fallbackPoint.value);
|
|
1204
|
+
context.set("resolvedActiveSnapPoint", fallbackPoint);
|
|
332
1205
|
});
|
|
333
1206
|
track([() => prop("open")], () => {
|
|
334
1207
|
action(["toggleVisibility"]);
|
|
335
1208
|
});
|
|
1209
|
+
track([
|
|
1210
|
+
() => context.get("dragOffset"),
|
|
1211
|
+
() => context.get("contentSize"),
|
|
1212
|
+
() => getActiveSnapOffset(context)
|
|
1213
|
+
], () => {
|
|
1214
|
+
action(["syncDrawerStack"]);
|
|
1215
|
+
});
|
|
336
1216
|
},
|
|
337
1217
|
initialState({ prop }) {
|
|
338
1218
|
return prop("open") || prop("defaultOpen") ? "open" : "closed";
|
|
339
1219
|
},
|
|
340
|
-
on: { "
|
|
1220
|
+
on: { "SNAP_POINT.SET": { actions: ["setSnapPoint"] } },
|
|
341
1221
|
states: {
|
|
342
1222
|
open: {
|
|
343
1223
|
tags: ["open"],
|
|
1224
|
+
entry: [
|
|
1225
|
+
"checkRenderedElements",
|
|
1226
|
+
"setInitialFocus",
|
|
1227
|
+
"deferClearDragOffset"
|
|
1228
|
+
],
|
|
344
1229
|
effects: [
|
|
345
1230
|
"trackDismissableElement",
|
|
346
1231
|
"preventScroll",
|
|
347
1232
|
"trapFocus",
|
|
348
1233
|
"hideContentBelow",
|
|
349
1234
|
"trackPointerMove",
|
|
350
|
-
"
|
|
1235
|
+
"trackSizeMeasurements",
|
|
1236
|
+
"trackNestedDrawerMetrics",
|
|
1237
|
+
"trackDrawerStack"
|
|
351
1238
|
],
|
|
352
1239
|
on: {
|
|
353
|
-
"CONTROLLED.CLOSE": {
|
|
1240
|
+
"CONTROLLED.CLOSE": {
|
|
1241
|
+
target: "closing",
|
|
1242
|
+
actions: ["clearSwipeOpenAnimation", "resetSwipeStrength"]
|
|
1243
|
+
},
|
|
354
1244
|
POINTER_DOWN: { actions: ["setPointerStart"] },
|
|
355
1245
|
POINTER_MOVE: [{
|
|
356
1246
|
guard: "isDragging",
|
|
357
1247
|
actions: ["setDragOffset"]
|
|
358
1248
|
}, {
|
|
359
1249
|
guard: "shouldStartDragging",
|
|
360
|
-
actions: ["setDragOffset"]
|
|
1250
|
+
actions: ["setRegistrySwiping", "setDragOffset"]
|
|
361
1251
|
}],
|
|
362
1252
|
POINTER_UP: [
|
|
1253
|
+
{
|
|
1254
|
+
guard: and("shouldCloseOnSwipe", "isOpenControlled"),
|
|
1255
|
+
actions: [
|
|
1256
|
+
"clearSwipeOpenAnimation",
|
|
1257
|
+
"clearRegistrySwiping",
|
|
1258
|
+
"clearPointerStart",
|
|
1259
|
+
"clearDragOffset",
|
|
1260
|
+
"invokeOnClose"
|
|
1261
|
+
]
|
|
1262
|
+
},
|
|
363
1263
|
{
|
|
364
1264
|
guard: "shouldCloseOnSwipe",
|
|
365
|
-
target: "closing"
|
|
1265
|
+
target: "closing",
|
|
1266
|
+
actions: [
|
|
1267
|
+
"clearSwipeOpenAnimation",
|
|
1268
|
+
"clearRegistrySwiping",
|
|
1269
|
+
"setDismissSwipeStrength"
|
|
1270
|
+
]
|
|
366
1271
|
},
|
|
367
1272
|
{
|
|
368
1273
|
guard: "isDragging",
|
|
369
1274
|
actions: [
|
|
1275
|
+
"clearRegistrySwiping",
|
|
1276
|
+
"suppressBackdropAnimation",
|
|
1277
|
+
"setSnapSwipeStrength",
|
|
370
1278
|
"setClosestSnapPoint",
|
|
371
1279
|
"clearPointerStart",
|
|
372
|
-
"clearDragOffset"
|
|
1280
|
+
"clearDragOffset",
|
|
1281
|
+
"clearVelocityTracking"
|
|
373
1282
|
]
|
|
374
1283
|
},
|
|
375
|
-
{ actions: [
|
|
1284
|
+
{ actions: [
|
|
1285
|
+
"clearRegistrySwiping",
|
|
1286
|
+
"clearPointerStart",
|
|
1287
|
+
"clearDragOffset",
|
|
1288
|
+
"clearVelocityTracking"
|
|
1289
|
+
] }
|
|
376
1290
|
],
|
|
1291
|
+
POINTER_CANCEL: [{
|
|
1292
|
+
guard: "isDragging",
|
|
1293
|
+
actions: [
|
|
1294
|
+
"clearRegistrySwiping",
|
|
1295
|
+
"clearPointerStart",
|
|
1296
|
+
"clearDragOffset",
|
|
1297
|
+
"clearVelocityTracking"
|
|
1298
|
+
]
|
|
1299
|
+
}, { actions: [
|
|
1300
|
+
"clearRegistrySwiping",
|
|
1301
|
+
"clearPointerStart",
|
|
1302
|
+
"clearVelocityTracking"
|
|
1303
|
+
] }],
|
|
377
1304
|
CLOSE: [{
|
|
378
1305
|
guard: "isOpenControlled",
|
|
379
|
-
actions: ["invokeOnClose"]
|
|
1306
|
+
actions: ["clearSwipeOpenAnimation", "invokeOnClose"]
|
|
380
1307
|
}, {
|
|
381
1308
|
target: "closing",
|
|
382
|
-
actions: [
|
|
1309
|
+
actions: [
|
|
1310
|
+
"clearSwipeOpenAnimation",
|
|
1311
|
+
"resetSwipeStrength",
|
|
1312
|
+
"invokeOnClose"
|
|
1313
|
+
]
|
|
383
1314
|
}]
|
|
384
1315
|
}
|
|
385
1316
|
},
|
|
386
1317
|
closing: {
|
|
387
|
-
effects: ["trackExitAnimation"],
|
|
1318
|
+
effects: ["trackExitAnimation", "trackDrawerStack"],
|
|
388
1319
|
on: { ANIMATION_END: {
|
|
389
1320
|
target: "closed",
|
|
390
1321
|
actions: [
|
|
@@ -393,11 +1324,73 @@ const machine = require_core.createMachine({
|
|
|
393
1324
|
"clearDragOffset",
|
|
394
1325
|
"clearActiveSnapPoint",
|
|
395
1326
|
"clearResolvedActiveSnapPoint",
|
|
396
|
-
"
|
|
1327
|
+
"clearSizeMeasurements",
|
|
397
1328
|
"clearVelocityTracking"
|
|
398
1329
|
]
|
|
399
1330
|
} }
|
|
400
1331
|
},
|
|
1332
|
+
"swipe-area-dragging": {
|
|
1333
|
+
tags: ["closed"],
|
|
1334
|
+
effects: ["trackSwipeOpenPointerMove"],
|
|
1335
|
+
on: {
|
|
1336
|
+
POINTER_MOVE: {
|
|
1337
|
+
guard: "hasSwipeIntent",
|
|
1338
|
+
target: "swiping-open"
|
|
1339
|
+
},
|
|
1340
|
+
POINTER_UP: {
|
|
1341
|
+
target: "closed",
|
|
1342
|
+
actions: ["clearPointerStart", "clearVelocityTracking"]
|
|
1343
|
+
},
|
|
1344
|
+
POINTER_CANCEL: {
|
|
1345
|
+
target: "closed",
|
|
1346
|
+
actions: ["clearPointerStart", "clearVelocityTracking"]
|
|
1347
|
+
}
|
|
1348
|
+
}
|
|
1349
|
+
},
|
|
1350
|
+
"swiping-open": {
|
|
1351
|
+
tags: ["open"],
|
|
1352
|
+
effects: ["trackSwipeOpenPointerMove", "trackSizeMeasurements"],
|
|
1353
|
+
on: {
|
|
1354
|
+
POINTER_MOVE: { actions: ["setSwipeOpenDragOffset"] },
|
|
1355
|
+
POINTER_UP: [
|
|
1356
|
+
{
|
|
1357
|
+
guard: and("shouldOpenOnSwipe", "isOpenControlled"),
|
|
1358
|
+
actions: ["clearPointerStart", "invokeOnOpen"]
|
|
1359
|
+
},
|
|
1360
|
+
{
|
|
1361
|
+
guard: "shouldOpenOnSwipe",
|
|
1362
|
+
target: "open",
|
|
1363
|
+
actions: ["clearPointerStart", "invokeOnOpen"]
|
|
1364
|
+
},
|
|
1365
|
+
{
|
|
1366
|
+
target: "closed",
|
|
1367
|
+
actions: [
|
|
1368
|
+
"clearPointerStart",
|
|
1369
|
+
"clearDragOffset",
|
|
1370
|
+
"clearSizeMeasurements"
|
|
1371
|
+
]
|
|
1372
|
+
}
|
|
1373
|
+
],
|
|
1374
|
+
POINTER_CANCEL: {
|
|
1375
|
+
target: "closed",
|
|
1376
|
+
actions: [
|
|
1377
|
+
"clearPointerStart",
|
|
1378
|
+
"clearDragOffset",
|
|
1379
|
+
"clearSizeMeasurements",
|
|
1380
|
+
"clearVelocityTracking"
|
|
1381
|
+
]
|
|
1382
|
+
},
|
|
1383
|
+
"CONTROLLED.OPEN": { target: "open" },
|
|
1384
|
+
CLOSE: {
|
|
1385
|
+
target: "closed",
|
|
1386
|
+
actions: [
|
|
1387
|
+
"clearPointerStart",
|
|
1388
|
+
"clearDragOffset",
|
|
1389
|
+
"clearSizeMeasurements"
|
|
1390
|
+
]
|
|
1391
|
+
}
|
|
1392
|
+
}
|
|
1393
|
+
},
|
|
401
1394
|
closed: {
|
|
402
1395
|
tags: ["closed"],
|
|
403
1396
|
on: {
|
|
@@ -408,7 +1401,11 @@ const machine = require_core.createMachine({
|
|
|
408
1401
|
}, {
|
|
409
1402
|
target: "open",
|
|
410
1403
|
actions: ["invokeOnOpen"]
|
|
411
|
-
}]
|
|
1404
|
+
}],
|
|
1405
|
+
"SWIPE_AREA.START": {
|
|
1406
|
+
target: "swipe-area-dragging",
|
|
1407
|
+
actions: ["setPointerStart"]
|
|
1408
|
+
}
|
|
412
1409
|
}
|
|
413
1410
|
}
|
|
414
1411
|
},
|
|
@@ -418,71 +1415,204 @@ const machine = require_core.createMachine({
|
|
|
418
1415
|
isDragging({ context }) {
|
|
419
1416
|
return context.get("dragOffset") !== null;
|
|
420
1417
|
},
|
|
421
|
-
shouldStartDragging({ prop, refs, event, scope }) {
|
|
422
|
-
return refs.get("
|
|
1418
|
+
shouldStartDragging({ computed, prop, refs, event, scope }) {
|
|
1419
|
+
return refs.get("swipeSession").canStartDrag(event.point, event.target, getContentEl(scope), prop("preventDragOnScroll"), computed("physicalSwipeDirection"));
|
|
423
1420
|
},
|
|
424
1421
|
shouldCloseOnSwipe({ prop, context, computed, refs }) {
|
|
425
|
-
|
|
1422
|
+
if (prop("snapToSequentialPoints")) return false;
|
|
1423
|
+
return refs.get("swipeSession").shouldDismissOnRelease(context.get("contentSize"), computed("resolvedSnapPoints"), getActiveSnapOffset(context));
|
|
1424
|
+
},
|
|
1425
|
+
hasSwipeIntent({ refs, computed, event }) {
|
|
1426
|
+
const start = refs.get("swipeSession").getSwipeStart();
|
|
1427
|
+
if (!start || !event.point) return false;
|
|
1428
|
+
return hasOpeningSwipeIntent(start, event.point, computed("physicalSwipeDirection"));
|
|
1429
|
+
},
|
|
1430
|
+
shouldOpenOnSwipe({ context, refs, prop }) {
|
|
1431
|
+
return refs.get("swipeSession").shouldOpenOnRelease(context.get("contentSize"), prop("swipeVelocityThreshold"), prop("closeThreshold"));
|
|
426
1432
|
}
|
|
427
1433
|
},
|
|
428
1434
|
actions: {
|
|
1435
|
+
setInitialFocus({ prop, scope }) {
|
|
1436
|
+
if (prop("trapFocus")) return;
|
|
1437
|
+
require_dom_query.raf(() => {
|
|
1438
|
+
require_dom_query.getInitialFocus({
|
|
1439
|
+
root: getContentEl(scope),
|
|
1440
|
+
getInitialEl: prop("initialFocusEl")
|
|
1441
|
+
})?.focus({ preventScroll: true });
|
|
1442
|
+
});
|
|
1443
|
+
},
|
|
1444
|
+
checkRenderedElements({ context, scope }) {
|
|
1445
|
+
require_dom_query.raf(() => {
|
|
1446
|
+
context.set("rendered", {
|
|
1447
|
+
title: !!getTitleEl(scope),
|
|
1448
|
+
description: !!getDescriptionEl(scope)
|
|
1449
|
+
});
|
|
1450
|
+
});
|
|
1451
|
+
},
|
|
1452
|
+
deferClearDragOffset({ context, refs, scope }) {
|
|
1453
|
+
if (context.get("dragOffset") === null) return;
|
|
1454
|
+
const contentEl = getContentEl(scope);
|
|
1455
|
+
const backdropEl = getBackdropEl(scope);
|
|
1456
|
+
if (contentEl) contentEl.style.setProperty("animation", "none", "important");
|
|
1457
|
+
if (backdropEl) backdropEl.style.setProperty("animation", "none", "important");
|
|
1458
|
+
require_dom_query.raf(() => {
|
|
1459
|
+
refs.get("swipeSession").resetDragOffset();
|
|
1460
|
+
context.set("dragOffset", null);
|
|
1461
|
+
});
|
|
1462
|
+
},
|
|
1463
|
+
suppressBackdropAnimation({ scope }) {
|
|
1464
|
+
const backdropEl = getBackdropEl(scope);
|
|
1465
|
+
if (!backdropEl) return;
|
|
1466
|
+
backdropEl.style.setProperty("animation", "none", "important");
|
|
1467
|
+
},
|
|
1468
|
+
clearSwipeOpenAnimation({ scope }) {
|
|
1469
|
+
const contentEl = getContentEl(scope);
|
|
1470
|
+
const backdropEl = getBackdropEl(scope);
|
|
1471
|
+
if (contentEl) contentEl.style.removeProperty("animation");
|
|
1472
|
+
if (backdropEl) backdropEl.style.removeProperty("animation");
|
|
1473
|
+
},
|
|
429
1474
|
invokeOnOpen({ prop }) {
|
|
430
1475
|
prop("onOpenChange")?.({ open: true });
|
|
431
1476
|
},
|
|
432
1477
|
invokeOnClose({ prop }) {
|
|
433
1478
|
prop("onOpenChange")?.({ open: false });
|
|
434
1479
|
},
|
|
435
|
-
|
|
436
|
-
context.set("
|
|
1480
|
+
setSnapPoint({ context, event }) {
|
|
1481
|
+
context.set("snapPoint", event.snapPoint);
|
|
437
1482
|
},
|
|
438
1483
|
setPointerStart({ event, refs }) {
|
|
439
|
-
refs.get("
|
|
1484
|
+
refs.get("swipeSession").beginSwipe(event.point);
|
|
440
1485
|
},
|
|
441
|
-
setDragOffset({ context, event, refs }) {
|
|
442
|
-
const
|
|
443
|
-
|
|
444
|
-
|
|
1486
|
+
setDragOffset({ context, event, refs, computed }) {
|
|
1487
|
+
const swipeSession = refs.get("swipeSession");
|
|
1488
|
+
const physicalSwipeDirection = event.swipeDirection ?? computed("physicalSwipeDirection");
|
|
1489
|
+
swipeSession.setDragOffset(event.point, getActiveSnapOffset(context), physicalSwipeDirection);
|
|
1490
|
+
context.set("dragOffset", swipeSession.getDragOffset());
|
|
445
1491
|
},
|
|
446
|
-
|
|
1492
|
+
setSwipeOpenDragOffset({ context, event, refs, computed }) {
|
|
1493
|
+
const swipeSession = refs.get("swipeSession");
|
|
1494
|
+
const contentSize = context.get("contentSize");
|
|
1495
|
+
if (!contentSize) return;
|
|
1496
|
+
swipeSession.setSwipeOpenOffset(event.point, contentSize, computed("physicalSwipeDirection"));
|
|
1497
|
+
context.set("dragOffset", swipeSession.getDragOffset());
|
|
1498
|
+
},
|
|
1499
|
+
setClosestSnapPoint({ computed, context, refs, prop, send }) {
|
|
447
1500
|
const snapPoints = computed("resolvedSnapPoints");
|
|
448
|
-
const
|
|
449
|
-
|
|
450
|
-
const
|
|
451
|
-
|
|
452
|
-
const
|
|
1501
|
+
const contentSize = context.get("contentSize");
|
|
1502
|
+
const viewportSize = context.get("viewportSize");
|
|
1503
|
+
const rootFontSize = context.get("rootFontSize");
|
|
1504
|
+
if (!snapPoints.length || contentSize === null) return;
|
|
1505
|
+
const closestSnapPoint = refs.get("swipeSession").resolveSnapPointOnRelease(snapPoints, context.get("resolvedActiveSnapPoint"), prop("snapToSequentialPoints"), contentSize);
|
|
1506
|
+
if (closestSnapPoint === null) {
|
|
1507
|
+
send({ type: "CLOSE" });
|
|
1508
|
+
return;
|
|
1509
|
+
}
|
|
1510
|
+
context.set("snapPoint", closestSnapPoint);
|
|
1511
|
+
const resolved = resolveSnapPoint(closestSnapPoint, {
|
|
1512
|
+
contentSize,
|
|
1513
|
+
viewportSize,
|
|
1514
|
+
rootFontSize
|
|
1515
|
+
});
|
|
453
1516
|
context.set("resolvedActiveSnapPoint", resolved);
|
|
454
1517
|
},
|
|
455
1518
|
clearDragOffset({ context, refs }) {
|
|
456
|
-
refs.get("
|
|
1519
|
+
refs.get("swipeSession").resetDragOffset();
|
|
457
1520
|
context.set("dragOffset", null);
|
|
458
1521
|
},
|
|
459
|
-
clearActiveSnapPoint({ context
|
|
460
|
-
context.set("
|
|
1522
|
+
clearActiveSnapPoint({ context }) {
|
|
1523
|
+
context.set("snapPoint", context.initial("snapPoint"));
|
|
1524
|
+
},
|
|
1525
|
+
clearSizeMeasurements({ context }) {
|
|
1526
|
+
context.set("contentSize", null);
|
|
1527
|
+
context.set("viewportSize", 0);
|
|
1528
|
+
context.set("rootFontSize", 16);
|
|
461
1529
|
},
|
|
462
1530
|
clearResolvedActiveSnapPoint({ context }) {
|
|
463
1531
|
context.set("resolvedActiveSnapPoint", null);
|
|
464
1532
|
},
|
|
465
1533
|
clearPointerStart({ refs }) {
|
|
466
|
-
refs.get("
|
|
467
|
-
},
|
|
468
|
-
clearContentHeight({ context }) {
|
|
469
|
-
context.set("contentHeight", null);
|
|
1534
|
+
refs.get("swipeSession").clearSwipeStart();
|
|
470
1535
|
},
|
|
471
1536
|
clearVelocityTracking({ refs }) {
|
|
472
|
-
refs.get("
|
|
1537
|
+
refs.get("swipeSession").resetVelocity();
|
|
1538
|
+
},
|
|
1539
|
+
setSnapSwipeStrength({ context, refs, computed, prop }) {
|
|
1540
|
+
const swipeSession = refs.get("swipeSession");
|
|
1541
|
+
const snapPoints = computed("resolvedSnapPoints");
|
|
1542
|
+
const contentSize = context.get("contentSize");
|
|
1543
|
+
const closestSnapPoint = swipeSession.resolveSnapPointOnRelease(snapPoints, context.get("resolvedActiveSnapPoint"), prop("snapToSequentialPoints"), contentSize ?? 0);
|
|
1544
|
+
if (closestSnapPoint === null) return;
|
|
1545
|
+
const viewportSize = context.get("viewportSize");
|
|
1546
|
+
const rootFontSize = context.get("rootFontSize");
|
|
1547
|
+
const resolved = resolveSnapPoint(closestSnapPoint, {
|
|
1548
|
+
contentSize: contentSize ?? 0,
|
|
1549
|
+
viewportSize,
|
|
1550
|
+
rootFontSize
|
|
1551
|
+
});
|
|
1552
|
+
const restOffset = getActiveSnapOffset(context);
|
|
1553
|
+
context.set("swipeStrength", swipeSession.getSwipeStrength(resolved?.offset ?? 0, restOffset));
|
|
1554
|
+
},
|
|
1555
|
+
setDismissSwipeStrength({ context, refs }) {
|
|
1556
|
+
const swipeSession = refs.get("swipeSession");
|
|
1557
|
+
const contentSize = context.get("contentSize");
|
|
1558
|
+
const restOffset = getActiveSnapOffset(context);
|
|
1559
|
+
context.set("swipeStrength", swipeSession.getSwipeStrength(contentSize ?? 0, restOffset));
|
|
1560
|
+
},
|
|
1561
|
+
resetSwipeStrength({ context }) {
|
|
1562
|
+
context.set("swipeStrength", 1);
|
|
1563
|
+
},
|
|
1564
|
+
setRegistrySwiping({ computed }) {
|
|
1565
|
+
drawerRegistry.setSwiping(computed("drawerId"), true);
|
|
1566
|
+
},
|
|
1567
|
+
clearRegistrySwiping({ computed }) {
|
|
1568
|
+
drawerRegistry.setSwiping(computed("drawerId"), false);
|
|
473
1569
|
},
|
|
474
1570
|
toggleVisibility({ event, send, prop }) {
|
|
475
1571
|
send({
|
|
476
1572
|
type: prop("open") ? "CONTROLLED.OPEN" : "CONTROLLED.CLOSE",
|
|
477
1573
|
previousEvent: event
|
|
478
1574
|
});
|
|
1575
|
+
},
|
|
1576
|
+
syncDrawerStack({ context, prop, computed }) {
|
|
1577
|
+
const contentSize = context.get("contentSize");
|
|
1578
|
+
if (contentSize === null) return;
|
|
1579
|
+
const dragOffset = context.get("dragOffset");
|
|
1580
|
+
const progress = resolveSwipeProgress(contentSize, dragOffset, getActiveSnapOffset(context));
|
|
1581
|
+
const id = computed("drawerId");
|
|
1582
|
+
if (dragOffset !== null) drawerRegistry.setSwipeProgress(id, progress);
|
|
1583
|
+
const stack = prop("stack");
|
|
1584
|
+
if (!stack) return;
|
|
1585
|
+
stack.setHeight(id, contentSize);
|
|
1586
|
+
stack.setSwipe(id, dragOffset !== null, progress);
|
|
479
1587
|
}
|
|
480
1588
|
},
|
|
481
1589
|
effects: {
|
|
1590
|
+
trackDrawerStack({ context, prop, computed }) {
|
|
1591
|
+
const stack = prop("stack");
|
|
1592
|
+
if (!stack) return;
|
|
1593
|
+
const id = computed("drawerId");
|
|
1594
|
+
stack.register(id);
|
|
1595
|
+
stack.setOpen(id, true);
|
|
1596
|
+
const sync = () => {
|
|
1597
|
+
const contentSize = context.get("contentSize");
|
|
1598
|
+
const dragOffset = context.get("dragOffset");
|
|
1599
|
+
const snapPointOffset = getActiveSnapOffset(context);
|
|
1600
|
+
stack.setHeight(id, contentSize ?? 0);
|
|
1601
|
+
stack.setSwipe(id, dragOffset !== null, resolveSwipeProgress(contentSize, dragOffset, snapPointOffset));
|
|
1602
|
+
};
|
|
1603
|
+
sync();
|
|
1604
|
+
return () => {
|
|
1605
|
+
stack.setSwipe(id, false, 0);
|
|
1606
|
+
stack.setOpen(id, false);
|
|
1607
|
+
stack.unregister(id);
|
|
1608
|
+
};
|
|
1609
|
+
},
|
|
482
1610
|
trackDismissableElement({ scope, prop, send }) {
|
|
483
1611
|
const getContentEl$1 = () => getContentEl(scope);
|
|
484
1612
|
return require_dismissable.trackDismissableElement(getContentEl$1, {
|
|
1613
|
+
type: "drawer",
|
|
485
1614
|
defer: true,
|
|
1615
|
+
pointerBlocking: prop("modal"),
|
|
486
1616
|
exclude: [getTriggerEl(scope)],
|
|
487
1617
|
onInteractOutside(event) {
|
|
488
1618
|
prop("onInteractOutside")?.(event);
|
|
@@ -514,7 +1644,7 @@ const machine = require_core.createMachine({
|
|
|
514
1644
|
preventScroll: true,
|
|
515
1645
|
returnFocusOnDeactivate: !!prop("restoreFocus"),
|
|
516
1646
|
initialFocus: prop("initialFocusEl"),
|
|
517
|
-
setReturnFocus: (el) => prop("finalFocusEl")?.()
|
|
1647
|
+
setReturnFocus: (el) => prop("finalFocusEl")?.() ?? getTriggerEl(scope) ?? el,
|
|
518
1648
|
getShadowRoot: true
|
|
519
1649
|
});
|
|
520
1650
|
},
|
|
@@ -523,105 +1653,115 @@ const machine = require_core.createMachine({
|
|
|
523
1653
|
const getElements = () => [getContentEl(scope)];
|
|
524
1654
|
return require_aria_hidden.ariaHidden(getElements, { defer: true });
|
|
525
1655
|
},
|
|
526
|
-
trackPointerMove({ scope, send,
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
});
|
|
534
|
-
}
|
|
535
|
-
function onPointerUp(event) {
|
|
536
|
-
if (event.pointerType === "touch") return;
|
|
537
|
-
send({
|
|
538
|
-
type: "POINTER_UP",
|
|
539
|
-
point: require_dom_query.getEventPoint(event)
|
|
540
|
-
});
|
|
541
|
-
}
|
|
542
|
-
function onTouchStart(event) {
|
|
543
|
-
if (!event.touches[0]) return;
|
|
544
|
-
lastY = event.touches[0].clientY;
|
|
545
|
-
}
|
|
546
|
-
function onTouchMove(event) {
|
|
547
|
-
if (!event.touches[0]) return;
|
|
548
|
-
const point = require_dom_query.getEventPoint(event);
|
|
549
|
-
const target = event.target;
|
|
550
|
-
if (!prop("preventDragOnScroll")) {
|
|
1656
|
+
trackPointerMove({ scope, send, refs, computed }) {
|
|
1657
|
+
return refs.get("swipeSession").bindDragTracking({
|
|
1658
|
+
getDoc: () => scope.getDoc(),
|
|
1659
|
+
getContentEl: () => getContentEl(scope),
|
|
1660
|
+
getSwipeAreaEl: () => getSwipeAreaEl(scope),
|
|
1661
|
+
swipeDirection: computed("physicalSwipeDirection"),
|
|
1662
|
+
onMove(details) {
|
|
551
1663
|
send({
|
|
552
1664
|
type: "POINTER_MOVE",
|
|
553
|
-
|
|
554
|
-
target
|
|
1665
|
+
...details
|
|
555
1666
|
});
|
|
556
|
-
|
|
1667
|
+
},
|
|
1668
|
+
onEnd(details) {
|
|
1669
|
+
send({
|
|
1670
|
+
type: "POINTER_UP",
|
|
1671
|
+
...details
|
|
1672
|
+
});
|
|
1673
|
+
},
|
|
1674
|
+
onCancel() {
|
|
1675
|
+
send({ type: "POINTER_CANCEL" });
|
|
557
1676
|
}
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
1677
|
+
});
|
|
1678
|
+
},
|
|
1679
|
+
trackSizeMeasurements({ context, scope, computed, prop }) {
|
|
1680
|
+
const contentEl = getContentEl(scope);
|
|
1681
|
+
if (!contentEl) return;
|
|
1682
|
+
const html = scope.getDoc().documentElement;
|
|
1683
|
+
const shouldMeasureRootFontSize = hasRemSnapPoints(prop("snapPoints"));
|
|
1684
|
+
const updateSize = () => {
|
|
1685
|
+
const direction = computed("physicalSwipeDirection");
|
|
1686
|
+
const rect = contentEl.getBoundingClientRect();
|
|
1687
|
+
const viewportSize = isVerticalSwipeDirection(direction) ? html.clientHeight : html.clientWidth;
|
|
1688
|
+
context.set("contentSize", getSwipeDirectionSize(rect, direction));
|
|
1689
|
+
context.set("viewportSize", viewportSize);
|
|
1690
|
+
if (shouldMeasureRootFontSize) {
|
|
1691
|
+
const rootFontSize = Number.parseFloat(getComputedStyle(html).fontSize);
|
|
1692
|
+
if (Number.isFinite(rootFontSize)) context.set("rootFontSize", rootFontSize);
|
|
567
1693
|
}
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
target
|
|
572
|
-
});
|
|
573
|
-
}
|
|
574
|
-
function onTouchEnd(event) {
|
|
575
|
-
if (event.touches.length !== 0) return;
|
|
576
|
-
send({
|
|
577
|
-
type: "POINTER_UP",
|
|
578
|
-
point: require_dom_query.getEventPoint(event)
|
|
579
|
-
});
|
|
580
|
-
}
|
|
581
|
-
const doc = scope.getDoc();
|
|
582
|
-
const cleanups = [
|
|
583
|
-
require_dom_query.addDomEvent(doc, "pointermove", onPointerMove),
|
|
584
|
-
require_dom_query.addDomEvent(doc, "pointerup", onPointerUp),
|
|
585
|
-
require_dom_query.addDomEvent(doc, "touchstart", onTouchStart, { passive: false }),
|
|
586
|
-
require_dom_query.addDomEvent(doc, "touchmove", onTouchMove, { passive: false }),
|
|
587
|
-
require_dom_query.addDomEvent(doc, "touchend", onTouchEnd)
|
|
588
|
-
];
|
|
1694
|
+
};
|
|
1695
|
+
updateSize();
|
|
1696
|
+
const cleanups = [require_dom_query.resizeObserverBorderBox.observe(contentEl, updateSize), require_dom_query.addDomEvent(scope.getWin(), "resize", updateSize)];
|
|
589
1697
|
return () => {
|
|
590
|
-
cleanups.forEach((cleanup) => cleanup());
|
|
1698
|
+
cleanups.forEach((cleanup) => cleanup?.());
|
|
591
1699
|
};
|
|
592
1700
|
},
|
|
593
|
-
|
|
1701
|
+
trackNestedDrawerMetrics({ scope, computed }) {
|
|
594
1702
|
const contentEl = getContentEl(scope);
|
|
595
1703
|
if (!contentEl) return;
|
|
596
|
-
const
|
|
597
|
-
|
|
598
|
-
|
|
1704
|
+
const id = computed("drawerId");
|
|
1705
|
+
drawerRegistry.register(id, contentEl);
|
|
1706
|
+
const sync = () => {
|
|
1707
|
+
const entries = [...drawerRegistry.getEntries().entries()];
|
|
1708
|
+
const myIndex = entries.findIndex(([entryId]) => entryId === id);
|
|
1709
|
+
if (myIndex === -1) return;
|
|
1710
|
+
const nestedCount = entries.length - 1 - myIndex;
|
|
1711
|
+
const frontmostHeight = (entries[entries.length - 1]?.[1])?.getBoundingClientRect().height ?? 0;
|
|
1712
|
+
const myHeight = contentEl.getBoundingClientRect().height;
|
|
1713
|
+
contentEl.style.setProperty("--nested-drawers", `${nestedCount}`);
|
|
1714
|
+
contentEl.style.setProperty("--drawer-height", `${myHeight}px`);
|
|
1715
|
+
contentEl.style.setProperty("--drawer-frontmost-height", `${frontmostHeight}px`);
|
|
1716
|
+
if (nestedCount > 0 && frontmostHeight > 0) contentEl.setAttribute("data-nested-drawer-open", "");
|
|
1717
|
+
else if (nestedCount === 0) contentEl.removeAttribute("data-nested-drawer-open");
|
|
1718
|
+
if (drawerRegistry.hasSwipingAfter(id)) contentEl.setAttribute("data-nested-drawer-swiping", "");
|
|
1719
|
+
else contentEl.removeAttribute("data-nested-drawer-swiping");
|
|
1720
|
+
};
|
|
1721
|
+
sync();
|
|
1722
|
+
const cleanups = [
|
|
1723
|
+
drawerRegistry.subscribe(sync),
|
|
1724
|
+
require_dom_query.resizeObserverBorderBox.observe(contentEl, () => drawerRegistry.notify()),
|
|
1725
|
+
require_dom_query.addDomEvent(scope.getWin(), "resize", () => drawerRegistry.notify())
|
|
1726
|
+
];
|
|
1727
|
+
return () => {
|
|
1728
|
+
cleanups.forEach((cleanup) => cleanup?.());
|
|
1729
|
+
contentEl.removeAttribute("data-nested-drawer-open");
|
|
1730
|
+
contentEl.removeAttribute("data-nested-drawer-swiping");
|
|
1731
|
+
contentEl.style.setProperty("--nested-drawers", "0");
|
|
1732
|
+
contentEl.style.removeProperty("--drawer-frontmost-height");
|
|
1733
|
+
drawerRegistry.unregister(id);
|
|
599
1734
|
};
|
|
600
|
-
updateHeight();
|
|
601
|
-
return require_dom_query.resizeObserverBorderBox.observe(contentEl, updateHeight);
|
|
602
1735
|
},
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
send({
|
|
611
|
-
|
|
1736
|
+
trackSwipeOpenPointerMove({ scope, send, refs, computed }) {
|
|
1737
|
+
return refs.get("swipeSession").bindSwipeOpenTracking({
|
|
1738
|
+
getDoc: () => scope.getDoc(),
|
|
1739
|
+
getContentEl: () => getContentEl(scope),
|
|
1740
|
+
getSwipeAreaEl: () => getSwipeAreaEl(scope),
|
|
1741
|
+
swipeDirection: computed("physicalSwipeDirection"),
|
|
1742
|
+
onMove(details) {
|
|
1743
|
+
send({
|
|
1744
|
+
type: "POINTER_MOVE",
|
|
1745
|
+
...details
|
|
1746
|
+
});
|
|
1747
|
+
},
|
|
1748
|
+
onEnd(details) {
|
|
1749
|
+
send({
|
|
1750
|
+
type: "POINTER_UP",
|
|
1751
|
+
...details
|
|
1752
|
+
});
|
|
1753
|
+
},
|
|
1754
|
+
onCancel() {
|
|
1755
|
+
send({ type: "POINTER_CANCEL" });
|
|
612
1756
|
}
|
|
613
|
-
const onEnd = (event) => {
|
|
614
|
-
if (require_dom_query.getEventTarget(event) === contentEl) send({ type: "ANIMATION_END" });
|
|
615
|
-
};
|
|
616
|
-
contentEl.addEventListener("animationend", onEnd);
|
|
617
|
-
cleanup = () => {
|
|
618
|
-
contentEl.removeEventListener("animationend", onEnd);
|
|
619
|
-
};
|
|
620
1757
|
});
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
1758
|
+
},
|
|
1759
|
+
trackExitAnimation({ send, scope }) {
|
|
1760
|
+
const contentEl = getContentEl(scope);
|
|
1761
|
+
if (!contentEl) return;
|
|
1762
|
+
return require_dom_query.addDomEvent(contentEl, "exitcomplete", () => {
|
|
1763
|
+
send({ type: "ANIMATION_END" });
|
|
1764
|
+
});
|
|
625
1765
|
}
|
|
626
1766
|
}
|
|
627
1767
|
}
|
|
@@ -639,6 +1779,8 @@ const props = require_create_props.createProps()([
|
|
|
639
1779
|
"defaultOpen",
|
|
640
1780
|
"getRootNode",
|
|
641
1781
|
"snapPoints",
|
|
1782
|
+
"swipeDirection",
|
|
1783
|
+
"snapToSequentialPoints",
|
|
642
1784
|
"swipeVelocityThreshold",
|
|
643
1785
|
"closeThreshold",
|
|
644
1786
|
"preventDragOnScroll",
|
|
@@ -654,14 +1796,139 @@ const props = require_create_props.createProps()([
|
|
|
654
1796
|
"restoreFocus",
|
|
655
1797
|
"role",
|
|
656
1798
|
"trapFocus",
|
|
657
|
-
"
|
|
658
|
-
"
|
|
659
|
-
"
|
|
1799
|
+
"defaultSnapPoint",
|
|
1800
|
+
"snapPoint",
|
|
1801
|
+
"onSnapPointChange",
|
|
1802
|
+
"stack"
|
|
660
1803
|
]);
|
|
661
1804
|
const splitProps = require_utils.createSplitProps(props);
|
|
662
1805
|
//#endregion
|
|
1806
|
+
//#region src/machines/drawer/drawer.stack.ts
|
|
1807
|
+
function resolveSnapshot(entries) {
|
|
1808
|
+
let openCount = 0;
|
|
1809
|
+
let frontmostHeight = 0;
|
|
1810
|
+
let swipeProgress = 0;
|
|
1811
|
+
let frontmostOrder = -1;
|
|
1812
|
+
entries.forEach((entry) => {
|
|
1813
|
+
if (!entry.open) return;
|
|
1814
|
+
openCount += 1;
|
|
1815
|
+
if (entry.order < frontmostOrder) return;
|
|
1816
|
+
frontmostOrder = entry.order;
|
|
1817
|
+
frontmostHeight = entry.height > 0 ? entry.height : 0;
|
|
1818
|
+
swipeProgress = entry.swiping ? require_utils.clampValue(entry.swipeProgress, 0, 1) : 0;
|
|
1819
|
+
});
|
|
1820
|
+
return {
|
|
1821
|
+
active: openCount > 0,
|
|
1822
|
+
openCount,
|
|
1823
|
+
swipeProgress,
|
|
1824
|
+
frontmostHeight
|
|
1825
|
+
};
|
|
1826
|
+
}
|
|
1827
|
+
function createStack() {
|
|
1828
|
+
const entries = /* @__PURE__ */ new Map();
|
|
1829
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
1830
|
+
let order = 0;
|
|
1831
|
+
let pendingNotify = false;
|
|
1832
|
+
let snapshot = Object.freeze({
|
|
1833
|
+
active: false,
|
|
1834
|
+
openCount: 0,
|
|
1835
|
+
swipeProgress: 0,
|
|
1836
|
+
frontmostHeight: 0
|
|
1837
|
+
});
|
|
1838
|
+
const scheduleNotify = () => {
|
|
1839
|
+
if (pendingNotify) return;
|
|
1840
|
+
pendingNotify = true;
|
|
1841
|
+
queueMicrotask(() => {
|
|
1842
|
+
pendingNotify = false;
|
|
1843
|
+
listeners.forEach((listener) => listener());
|
|
1844
|
+
});
|
|
1845
|
+
};
|
|
1846
|
+
const notify = () => {
|
|
1847
|
+
const nextSnapshot = resolveSnapshot(entries);
|
|
1848
|
+
if (snapshot.active === nextSnapshot.active && snapshot.openCount === nextSnapshot.openCount && snapshot.swipeProgress === nextSnapshot.swipeProgress && snapshot.frontmostHeight === nextSnapshot.frontmostHeight) return;
|
|
1849
|
+
snapshot = Object.freeze(nextSnapshot);
|
|
1850
|
+
scheduleNotify();
|
|
1851
|
+
};
|
|
1852
|
+
const ensureEntry = (id) => {
|
|
1853
|
+
let entry = entries.get(id);
|
|
1854
|
+
if (!entry) {
|
|
1855
|
+
entry = {
|
|
1856
|
+
order: ++order,
|
|
1857
|
+
open: false,
|
|
1858
|
+
height: 0,
|
|
1859
|
+
swiping: false,
|
|
1860
|
+
swipeProgress: 0
|
|
1861
|
+
};
|
|
1862
|
+
entries.set(id, entry);
|
|
1863
|
+
}
|
|
1864
|
+
return entry;
|
|
1865
|
+
};
|
|
1866
|
+
return {
|
|
1867
|
+
getSnapshot() {
|
|
1868
|
+
return snapshot;
|
|
1869
|
+
},
|
|
1870
|
+
subscribe(listener) {
|
|
1871
|
+
listeners.add(listener);
|
|
1872
|
+
return () => {
|
|
1873
|
+
listeners.delete(listener);
|
|
1874
|
+
};
|
|
1875
|
+
},
|
|
1876
|
+
register(id) {
|
|
1877
|
+
ensureEntry(id);
|
|
1878
|
+
notify();
|
|
1879
|
+
},
|
|
1880
|
+
unregister(id) {
|
|
1881
|
+
if (!entries.delete(id)) return;
|
|
1882
|
+
notify();
|
|
1883
|
+
},
|
|
1884
|
+
setOpen(id, open) {
|
|
1885
|
+
const entry = ensureEntry(id);
|
|
1886
|
+
if (entry.open === open) return;
|
|
1887
|
+
entry.open = open;
|
|
1888
|
+
if (!open) {
|
|
1889
|
+
entry.swiping = false;
|
|
1890
|
+
entry.swipeProgress = 0;
|
|
1891
|
+
}
|
|
1892
|
+
notify();
|
|
1893
|
+
},
|
|
1894
|
+
setHeight(id, height) {
|
|
1895
|
+
const entry = ensureEntry(id);
|
|
1896
|
+
const nextHeight = Number.isFinite(height) && height > 0 ? height : 0;
|
|
1897
|
+
if (entry.height === nextHeight) return;
|
|
1898
|
+
entry.height = nextHeight;
|
|
1899
|
+
notify();
|
|
1900
|
+
},
|
|
1901
|
+
setSwipe(id, swiping, progress) {
|
|
1902
|
+
const entry = ensureEntry(id);
|
|
1903
|
+
const nextProgress = swiping ? require_utils.clampValue(Number.isFinite(progress) ? progress : 0, 0, 1) : 0;
|
|
1904
|
+
if (entry.swiping === swiping && entry.swipeProgress === nextProgress) return;
|
|
1905
|
+
entry.swiping = swiping;
|
|
1906
|
+
entry.swipeProgress = nextProgress;
|
|
1907
|
+
notify();
|
|
1908
|
+
}
|
|
1909
|
+
};
|
|
1910
|
+
}
|
|
1911
|
+
function connectStack(snapshot, normalize) {
|
|
1912
|
+
const getIndentProps = () => {
|
|
1913
|
+
return normalize.element({
|
|
1914
|
+
"data-active": snapshot.active ? "" : void 0,
|
|
1915
|
+
"data-inactive": snapshot.active ? void 0 : "",
|
|
1916
|
+
style: {
|
|
1917
|
+
"--drawer-swipe-progress": `${require_utils.clampValue(snapshot.swipeProgress, 0, 1)}`,
|
|
1918
|
+
"--drawer-frontmost-height": snapshot.frontmostHeight > 0 ? `${snapshot.frontmostHeight}px` : void 0
|
|
1919
|
+
}
|
|
1920
|
+
});
|
|
1921
|
+
};
|
|
1922
|
+
return {
|
|
1923
|
+
getIndentProps,
|
|
1924
|
+
getIndentBackgroundProps: getIndentProps
|
|
1925
|
+
};
|
|
1926
|
+
}
|
|
1927
|
+
//#endregion
|
|
663
1928
|
exports.anatomy = anatomy;
|
|
664
1929
|
exports.connect = connect;
|
|
1930
|
+
exports.connectStack = connectStack;
|
|
1931
|
+
exports.createStack = createStack;
|
|
665
1932
|
exports.machine = machine;
|
|
666
1933
|
exports.props = props;
|
|
667
1934
|
exports.splitProps = splitProps;
|