@rcarls/rc-bottom-sheet 0.4.0 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +65 -0
- package/dist/custom-elements.json +15 -0
- package/dist/{rc-bottom-sheet-DbzpQjd0.js → rc-bottom-sheet-CR2usG4R.js} +47 -38
- package/dist/rc-bottom-sheet-CR2usG4R.js.map +1 -0
- package/dist/rc-bottom-sheet-define.js +1 -1
- package/dist/rc-bottom-sheet.js +1 -1
- package/dist/types/packages/rc-bottom-sheet/src/rc-bottom-sheet.d.ts +3 -0
- package/package.json +4 -4
- package/dist/rc-bottom-sheet-DbzpQjd0.js.map +0 -1
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# @rcarls/rc-bottom-sheet
|
|
2
|
+
|
|
3
|
+
## 0.4.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 5178dcc: Fix `rc-bottom-sheet` snapping to stale geometry after a viewport resize (for example a
|
|
8
|
+
browser window maximize/restore) while open. Snap-point heights are resolved against the
|
|
9
|
+
current viewport at the moment a snap is applied, then frozen as inline `top`/`height`
|
|
10
|
+
styles; nothing re-derived them after that, so a resize with no drag or `snapTo()` call
|
|
11
|
+
in between left the sheet pinned to pre-resize pixel geometry. Now listens for `resize`
|
|
12
|
+
while open and re-applies the last-snapped index against fresh geometry.
|
|
13
|
+
|
|
14
|
+
Also stops pinning the inline axis (`left`/`width`) at all: only `top`/`height` are ever
|
|
15
|
+
read again after the initial pin, and freezing the inline axis as an inline style
|
|
16
|
+
permanently overrides any external stylesheet's `inset-inline`/`inline-size` confinement
|
|
17
|
+
(for example a host page confining a sheet to a layout pane narrower than the viewport)
|
|
18
|
+
regardless of specificity, since inline styles always win that cascade. `rc-bottom-sheet`'s
|
|
19
|
+
own `LIGHT_DOM_CSS` already deliberately leaves the inline axis CSS-owned; the pin just
|
|
20
|
+
wasn't honoring that.
|
|
21
|
+
- @rcarls/rc-common@0.4.2
|
|
22
|
+
- @rcarls/rc-dialog@0.4.2
|
|
23
|
+
|
|
24
|
+
## 0.4.1
|
|
25
|
+
|
|
26
|
+
### Patch Changes
|
|
27
|
+
|
|
28
|
+
- @rcarls/rc-common@0.4.1
|
|
29
|
+
- @rcarls/rc-dialog@0.4.1
|
|
30
|
+
|
|
31
|
+
## 0.4.0
|
|
32
|
+
|
|
33
|
+
### Minor Changes
|
|
34
|
+
|
|
35
|
+
- 48cf73f: Add the rc-bottom-sheet package as a dialog-backed modal bottom-sheet surface.
|
|
36
|
+
- 037b1b3: Add shared drag gesture measurement and numeric snap helpers, migrate bottom
|
|
37
|
+
sheet settling to the shared velocity lifecycle, and add anchored settling and
|
|
38
|
+
swipe-to-collapse behavior to splitters.
|
|
39
|
+
- c40a1be: Add theme-neutral fast, default, and slow effects and spatial motion token
|
|
40
|
+
pairs. Expose bottom-sheet settle easing through
|
|
41
|
+
`--rc-bottom-sheet-snap-easing` and map sheet settling to the Material spatial
|
|
42
|
+
motion scheme.
|
|
43
|
+
|
|
44
|
+
Give direct-child bottom-sheet handles a full-width 48px interaction target
|
|
45
|
+
while preserving the 32 by 4 pixel visual indicator. Replace rectangular
|
|
46
|
+
mobile browser tap highlights on chips with themeable, shape-clipped state
|
|
47
|
+
layers. Keep bottom-sheet snap targets docked to the block-end edge when CSS
|
|
48
|
+
minimum or maximum sizing constrains their requested heights.
|
|
49
|
+
|
|
50
|
+
Mount declaratively assigned textarea plugins at connection time and remount
|
|
51
|
+
them after reconnection, preserving plugin effects and adopted styles in
|
|
52
|
+
framework render lifecycles.
|
|
53
|
+
|
|
54
|
+
### Patch Changes
|
|
55
|
+
|
|
56
|
+
- ebec800: Dock bottom sheets without a theme to the viewport block-end by default and
|
|
57
|
+
support absolute positioning for non-modal sheets contained by a positioned ancestor.
|
|
58
|
+
Center authored drag handles with a splitter-aligned pill treatment. Align the
|
|
59
|
+
Material theme with its surface, elevation, scrim, drag-handle, and contextual
|
|
60
|
+
button treatment.
|
|
61
|
+
- Updated dependencies [e57277f]
|
|
62
|
+
- Updated dependencies [ccca8e2]
|
|
63
|
+
- Updated dependencies [037b1b3]
|
|
64
|
+
- @rcarls/rc-dialog@0.4.0
|
|
65
|
+
- @rcarls/rc-common@0.4.0
|
|
@@ -281,6 +281,21 @@
|
|
|
281
281
|
"privacy": "private",
|
|
282
282
|
"default": "null"
|
|
283
283
|
},
|
|
284
|
+
{
|
|
285
|
+
"kind": "field",
|
|
286
|
+
"name": "_lastSnapIndex",
|
|
287
|
+
"type": {
|
|
288
|
+
"text": "number | null"
|
|
289
|
+
},
|
|
290
|
+
"privacy": "private",
|
|
291
|
+
"default": "null"
|
|
292
|
+
},
|
|
293
|
+
{
|
|
294
|
+
"kind": "field",
|
|
295
|
+
"name": "_onWindowResize",
|
|
296
|
+
"privacy": "private",
|
|
297
|
+
"readonly": true
|
|
298
|
+
},
|
|
284
299
|
{
|
|
285
300
|
"kind": "method",
|
|
286
301
|
"name": "snapTo",
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { property as h } from "lit/decorators.js";
|
|
2
2
|
import { RCDialog as b } from "@rcarls/rc-dialog";
|
|
3
|
-
import { findExtremeSnapIndex as g, findNearestSnapIndex as y
|
|
4
|
-
var _ = Object.defineProperty, c = (
|
|
5
|
-
for (var i = void 0, s =
|
|
6
|
-
(
|
|
3
|
+
import { findExtremeSnapIndex as g, findNearestSnapIndex as y } from "@rcarls/rc-common";
|
|
4
|
+
var _ = Object.defineProperty, c = (o, t, e, n) => {
|
|
5
|
+
for (var i = void 0, s = o.length - 1, r; s >= 0; s--)
|
|
6
|
+
(r = o[s]) && (i = r(t, e, i) || i);
|
|
7
7
|
return i && _(t, e, i), i;
|
|
8
8
|
};
|
|
9
|
-
const
|
|
9
|
+
const v = 300, x = "cubic-bezier(0.4, 0, 0.2, 1)", S = `
|
|
10
10
|
@layer rc-base {
|
|
11
11
|
rc-bottom-sheet > dialog {
|
|
12
12
|
position: var(--rc-bottom-sheet-position, fixed);
|
|
@@ -59,21 +59,30 @@ const f = 300, S = "cubic-bezier(0.4, 0, 0.2, 1)", x = `
|
|
|
59
59
|
outline-offset: -0.25rem;
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
|
-
`,
|
|
63
|
-
|
|
64
|
-
const
|
|
62
|
+
`, f = 24;
|
|
63
|
+
function z(o) {
|
|
64
|
+
const t = o.getBoundingClientRect();
|
|
65
|
+
return getComputedStyle(o).position === "static" && (o.style.position = "fixed"), o.style.translate = "none", o.style.insetBlockStart = "auto", o.style.marginBlock = "0", o.style.boxSizing = "border-box", o.style.top = `${t.top}px`, o.style.height = `${t.height}px`, t;
|
|
66
|
+
}
|
|
67
|
+
var a;
|
|
68
|
+
const l = (a = class extends b {
|
|
65
69
|
constructor() {
|
|
66
|
-
super(...arguments), this.lightDismiss = !0, this.resize = "vertical", this.resizeOrigin = "top", this.resizeHandle = "[data-rc-bottom-sheet-handle]", this.snapPoints = "", this.swipeDismiss = !0, this.swipeVelocity = 500, this._reducedMotion = typeof window < "u" ? window.matchMedia("(prefers-reduced-motion: reduce)") : null, this._activeSnapAnimation = null
|
|
70
|
+
super(...arguments), this.lightDismiss = !0, this.resize = "vertical", this.resizeOrigin = "top", this.resizeHandle = "[data-rc-bottom-sheet-handle]", this.snapPoints = "", this.swipeDismiss = !0, this.swipeVelocity = 500, this._reducedMotion = typeof window < "u" ? window.matchMedia("(prefers-reduced-motion: reduce)") : null, this._activeSnapAnimation = null, this._lastSnapIndex = null, this._onWindowResize = () => {
|
|
71
|
+
!this.open || this._lastSnapIndex === null || this._snapToIndex(this._lastSnapIndex, "instant", "api");
|
|
72
|
+
};
|
|
67
73
|
}
|
|
68
74
|
static _ensureBaseStyles(t) {
|
|
69
|
-
if (
|
|
75
|
+
if (a._styledRoots.has(t))
|
|
70
76
|
return;
|
|
71
|
-
|
|
77
|
+
a._styledRoots.add(t);
|
|
72
78
|
const e = document.createElement("style");
|
|
73
|
-
e.setAttribute("data-rc-light-dom-base", "rc-bottom-sheet"), e.textContent =
|
|
79
|
+
e.setAttribute("data-rc-light-dom-base", "rc-bottom-sheet"), e.textContent = S, t instanceof Document ? t.head.append(e) : t.append(e);
|
|
74
80
|
}
|
|
75
81
|
connectedCallback() {
|
|
76
|
-
super.connectedCallback(),
|
|
82
|
+
super.connectedCallback(), a._ensureBaseStyles(this.getRootNode()), window.addEventListener("resize", this._onWindowResize);
|
|
83
|
+
}
|
|
84
|
+
disconnectedCallback() {
|
|
85
|
+
super.disconnectedCallback(), window.removeEventListener("resize", this._onWindowResize);
|
|
77
86
|
}
|
|
78
87
|
/**
|
|
79
88
|
* Snaps to a declared target by zero-based index.
|
|
@@ -98,7 +107,7 @@ const a = (r = class extends b {
|
|
|
98
107
|
return;
|
|
99
108
|
}
|
|
100
109
|
const e = this._resolvedSnapPoints(), n = t.edge.includes("n") ? -t.velocityY : t.velocityY, i = Math.abs(t.height - t.startHeight);
|
|
101
|
-
if (t.inputType === "pointer" && e.length > 0 && i >=
|
|
110
|
+
if (t.inputType === "pointer" && e.length > 0 && i >= f && Math.abs(n) >= this.swipeVelocity) {
|
|
102
111
|
const s = g(e, n > 0 ? 1 : -1);
|
|
103
112
|
this._snapToIndex(s, "animated", "drag");
|
|
104
113
|
return;
|
|
@@ -106,7 +115,7 @@ const a = (r = class extends b {
|
|
|
106
115
|
this._snapToNearestPoint("drag");
|
|
107
116
|
}
|
|
108
117
|
_shouldSwipeDismiss(t) {
|
|
109
|
-
return t.edge.includes("n") && t.startHeight - t.height >=
|
|
118
|
+
return t.edge.includes("n") && t.startHeight - t.height >= a.swipeDismissThreshold;
|
|
110
119
|
}
|
|
111
120
|
_snapToNearestPoint(t = "api") {
|
|
112
121
|
const e = this._$dialog, n = this._resolvedSnapPoints();
|
|
@@ -119,16 +128,16 @@ const a = (r = class extends b {
|
|
|
119
128
|
const i = this._$dialog, s = this._resolvedSnapPoints();
|
|
120
129
|
if (!i || s.length === 0)
|
|
121
130
|
return;
|
|
122
|
-
const
|
|
123
|
-
this._activeSnapAnimation?.cancel(), this._activeSnapAnimation = null, i.style.height = `${m}px`;
|
|
124
|
-
const
|
|
125
|
-
i.style.top = `${
|
|
126
|
-
const u =
|
|
127
|
-
this._applySnap(i, u,
|
|
131
|
+
const r = z(i), p = Math.max(0, Math.min(t, s.length - 1)), m = s[p];
|
|
132
|
+
this._lastSnapIndex = p, this._activeSnapAnimation?.cancel(), this._activeSnapAnimation = null, i.style.height = `${m}px`;
|
|
133
|
+
const d = i.getBoundingClientRect().height;
|
|
134
|
+
i.style.top = `${r.top}px`, i.style.height = `${r.height}px`;
|
|
135
|
+
const u = r.bottom - d;
|
|
136
|
+
this._applySnap(i, u, d, e), this.dispatchEvent(
|
|
128
137
|
new CustomEvent("rc-bottom-sheet-snap", {
|
|
129
138
|
bubbles: !0,
|
|
130
139
|
composed: !0,
|
|
131
|
-
detail: { index:
|
|
140
|
+
detail: { index: p, height: d, trigger: n }
|
|
132
141
|
})
|
|
133
142
|
);
|
|
134
143
|
}
|
|
@@ -140,7 +149,7 @@ const a = (r = class extends b {
|
|
|
140
149
|
}
|
|
141
150
|
if (s.top === e && s.height === n)
|
|
142
151
|
return;
|
|
143
|
-
const
|
|
152
|
+
const r = t.animate(
|
|
144
153
|
[
|
|
145
154
|
{ top: `${s.top}px`, height: `${s.height}px` },
|
|
146
155
|
{ top: `${e}px`, height: `${n}px` }
|
|
@@ -151,17 +160,17 @@ const a = (r = class extends b {
|
|
|
151
160
|
fill: "forwards"
|
|
152
161
|
}
|
|
153
162
|
);
|
|
154
|
-
this._activeSnapAnimation =
|
|
163
|
+
this._activeSnapAnimation = r, r.finished.then(() => r.commitStyles()).catch(() => {
|
|
155
164
|
}).finally(() => {
|
|
156
|
-
|
|
165
|
+
r.cancel(), this._activeSnapAnimation === r && (this._activeSnapAnimation = null);
|
|
157
166
|
});
|
|
158
167
|
}
|
|
159
168
|
_snapDuration(t) {
|
|
160
169
|
const e = getComputedStyle(t).getPropertyValue("--rc-bottom-sheet-snap-duration").trim(), n = Number.parseFloat(e);
|
|
161
|
-
return Number.isFinite(n) ? n :
|
|
170
|
+
return Number.isFinite(n) ? n : v;
|
|
162
171
|
}
|
|
163
172
|
_snapEasing(t) {
|
|
164
|
-
return getComputedStyle(t).getPropertyValue("--rc-bottom-sheet-snap-easing").trim() ||
|
|
173
|
+
return getComputedStyle(t).getPropertyValue("--rc-bottom-sheet-snap-easing").trim() || x;
|
|
165
174
|
}
|
|
166
175
|
_resolvedSnapPoints() {
|
|
167
176
|
return this.snapPoints.trim() ? this.snapPoints.trim().split(/\s+/).map((t) => this._resolveSnapPoint(t)).filter((t) => Number.isFinite(t) && t > 0) : [];
|
|
@@ -186,30 +195,30 @@ const a = (r = class extends b {
|
|
|
186
195
|
const i = n.getBoundingClientRect().height;
|
|
187
196
|
return n.remove(), i;
|
|
188
197
|
}
|
|
189
|
-
},
|
|
198
|
+
}, a.swipeDismissThreshold = 96, a._styledRoots = /* @__PURE__ */ new Set(), a);
|
|
190
199
|
c([
|
|
191
200
|
h({ type: Boolean, attribute: "light-dismiss" })
|
|
192
|
-
],
|
|
201
|
+
], l.prototype, "lightDismiss");
|
|
193
202
|
c([
|
|
194
203
|
h({ type: String, reflect: !0 })
|
|
195
|
-
],
|
|
204
|
+
], l.prototype, "resize");
|
|
196
205
|
c([
|
|
197
206
|
h({ type: String, attribute: "resize-origin" })
|
|
198
|
-
],
|
|
207
|
+
], l.prototype, "resizeOrigin");
|
|
199
208
|
c([
|
|
200
209
|
h({ type: String, attribute: "resize-handle" })
|
|
201
|
-
],
|
|
210
|
+
], l.prototype, "resizeHandle");
|
|
202
211
|
c([
|
|
203
212
|
h({ type: String, attribute: "snap-points" })
|
|
204
|
-
],
|
|
213
|
+
], l.prototype, "snapPoints");
|
|
205
214
|
c([
|
|
206
215
|
h({ type: Boolean, attribute: "swipe-dismiss" })
|
|
207
|
-
],
|
|
216
|
+
], l.prototype, "swipeDismiss");
|
|
208
217
|
c([
|
|
209
218
|
h({ type: Number, attribute: "swipe-velocity" })
|
|
210
|
-
],
|
|
211
|
-
let
|
|
219
|
+
], l.prototype, "swipeVelocity");
|
|
220
|
+
let I = l;
|
|
212
221
|
export {
|
|
213
|
-
|
|
222
|
+
I as R
|
|
214
223
|
};
|
|
215
|
-
//# sourceMappingURL=rc-bottom-sheet-
|
|
224
|
+
//# sourceMappingURL=rc-bottom-sheet-CR2usG4R.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rc-bottom-sheet-CR2usG4R.js","sources":["../src/rc-bottom-sheet.ts"],"sourcesContent":["import { property } from 'lit/decorators.js';\n\nimport { RCDialog } from '@rcarls/rc-dialog';\nimport {\n findExtremeSnapIndex,\n findNearestSnapIndex,\n type ResizeDirection,\n type ResizeLifecycleDetail,\n type ResizeOrigin,\n} from '@rcarls/rc-common';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'rc-bottom-sheet': RCBottomSheet;\n }\n\n interface HTMLElementEventMap {\n 'rc-bottom-sheet-snap': CustomEvent<RCBottomSheetSnapDetail>;\n }\n}\n\n/** Detail shape for `rc-bottom-sheet-snap`. */\nexport interface RCBottomSheetSnapDetail {\n /** Index into the resolved `snap-points` list selected as the target. */\n index: number;\n\n /** Effective target height in pixels, after CSS size constraints. */\n height: number;\n\n /** Whether the snap came from a drag release or a `snapTo()` call. */\n trigger: 'drag' | 'api';\n}\n\nconst DEFAULT_SNAP_DURATION_MS = 300;\nconst DEFAULT_SNAP_EASING = 'cubic-bezier(0.4, 0, 0.2, 1)';\n\nconst LIGHT_DOM_CSS = `\n@layer rc-base {\n rc-bottom-sheet > dialog {\n position: var(--rc-bottom-sheet-position, fixed);\n inset-block-start: auto;\n inset-block-end: var(--rc-bottom-sheet-inset-block-end, 0px);\n inset-inline: var(--rc-bottom-sheet-inset-inline, 0px);\n box-sizing: border-box;\n inline-size: 100%;\n max-inline-size: var(--rc-bottom-sheet-max-inline-size, 40rem);\n max-block-size: var(--rc-bottom-sheet-max-block-size, 70dvh);\n margin-block: 0;\n margin-inline: auto;\n overflow: auto;\n }\n\n rc-bottom-sheet > dialog [data-rc-bottom-sheet-handle] {\n box-sizing: border-box;\n cursor: ns-resize;\n touch-action: none;\n -webkit-tap-highlight-color: transparent;\n }\n\n rc-bottom-sheet > dialog > [data-rc-bottom-sheet-handle] {\n position: relative;\n display: block;\n inline-size: var(--rc-bottom-sheet-handle-target-inline-size, 100%);\n min-block-size: var(--rc-bottom-sheet-handle-target-block-size, 3rem);\n margin: var(--rc-bottom-sheet-handle-target-margin, 0);\n padding: 0;\n border: 0;\n border-radius: inherit;\n background: transparent;\n appearance: none;\n }\n\n rc-bottom-sheet > dialog > [data-rc-bottom-sheet-handle]::before {\n content: '';\n position: absolute;\n inset-block-start: 50%;\n inset-inline-start: 50%;\n inline-size: var(--rc-bottom-sheet-handle-inline-size, 2rem);\n block-size: var(--rc-bottom-sheet-handle-block-size, 0.25rem);\n border-radius: var(--rc-bottom-sheet-handle-radius, 999px);\n background: var(--rc-bottom-sheet-handle-color, GrayText);\n translate: -50% -50%;\n }\n\n rc-bottom-sheet > dialog [data-rc-bottom-sheet-handle]:focus-visible {\n outline: auto;\n outline-offset: -0.25rem;\n }\n}\n`;\n\n// Floor so a noisy near-zero-distance release can't misread as a decisive\n// fling; a real swipe travels at least this far even if it's very quick.\nconst MIN_SWIPE_DISTANCE = 24;\n\n/**\n * Pins only the block-axis (top/height) geometry as inline styles, leaving\n * the inline axis (left/width) to CSS. `@rcarls/rc-common`'s\n * `pinElementBox` pins all four edges — appropriate for its own drag-resize\n * gesture math, where the inline axis can genuinely change — but a bottom\n * sheet only ever resizes/repositions along the block axis; its own\n * `LIGHT_DOM_CSS` deliberately leaves the inline axis owned by\n * `inset-inline`/`inline-size` custom properties (e.g. so a host page can\n * confine a sheet to a layout pane narrower than the viewport). Pinning\n * `left`/`width` here would freeze whatever the *unconfined* box happened\n * to measure at pin time as an inline style, which — having higher\n * cascade priority than any stylesheet rule — permanently overrides that\n * confinement regardless of specificity or layers.\n */\nfunction pinBlockBox(target: HTMLElement): DOMRect {\n const rect = target.getBoundingClientRect();\n\n if (getComputedStyle(target).position === 'static') {\n target.style.position = 'fixed';\n }\n\n target.style.translate = 'none';\n target.style.insetBlockStart = 'auto';\n target.style.marginBlock = '0';\n target.style.boxSizing = 'border-box';\n target.style.top = `${rect.top}px`;\n target.style.height = `${rect.height}px`;\n\n return rect;\n}\n\n/**\n * Modal bottom-sheet wrapper for a native `<dialog>`, built on `rc-dialog`.\n *\n * The direct child `<dialog>` remains the semantic dialog surface and owns\n * content, labels, and form behavior. `rc-bottom-sheet` supplies the same\n * open/close lifecycle, focus restoration, cancel/request-close events, and\n * light-dismiss affordance as `rc-dialog`. The component docks the sheet to\n * the viewport block-end by default, while themes provide its visual surface.\n *\n * Dragging the resize handle past a decisive velocity in either direction\n * (a \"swipe\" or \"fling,\" distinct from a slow deliberate drag) snaps\n * straight to the extreme `snap-points` entry in that direction — swipe up\n * to fully expand, swipe down to fully collapse — regardless of how close\n * the release position was to some other point. Below that velocity, the\n * sheet settles to whichever declared snap point is nearest the release\n * height. All settling, whether from a drag or from `snapTo()`, animates\n * over `--rc-bottom-sheet-snap-duration`, follows\n * `--rc-bottom-sheet-snap-easing`, and is skipped for\n * `prefers-reduced-motion: reduce`.\n *\n * @see {@link https://richardcarls.github.io/rc-webcomponents/components/rc-bottom-sheet rc-bottom-sheet docs}\n * @see {@link https://m3.material.io/components/bottom-sheets/overview Material Design bottom sheets}\n *\n * @slot - Place a `<dialog>` element with the sheet content and optional\n * `[data-rc-bottom-sheet-handle]` resize handle here.\n *\n * @fires rc-dialog-open - Inherited from `rc-dialog`; fired when the sheet opens.\n * @fires rc-dialog-toggle - Inherited from `rc-dialog`; fired when user/native interaction changes open state.\n * @fires rc-dialog-request-close - Inherited from `rc-dialog`; cancelable close request.\n * @fires rc-dialog-cancel - Inherited from `rc-dialog`; backward-compatible cancel alias.\n * @fires rc-dialog-close - Inherited from `rc-dialog`; fired after the sheet closes.\n * @fires rc-bottom-sheet-snap - Fires when a drag release or `snapTo()` call\n * selects a snap target. `detail: { index, height, trigger }`\n *\n * @attr light-dismiss - When present, a click on the backdrop area calls `requestClose()`.\n * Present by default; inherited from `rc-dialog`.\n * @attr resize - Enables edge resizing, mirroring the CSS `resize` property values.\n * Defaults to `vertical`; inherited from `rc-dialog`.\n * @attr resize-origin - Origin for resize edge hit-testing or explicit handles. Defaults to\n * `top`; inherited from `rc-dialog`.\n * @attr resize-handle - CSS selector, scoped to the inner `<dialog>`, for explicit resize\n * handles. Defaults to `[data-rc-bottom-sheet-handle]`; inherited from `rc-dialog`.\n * @attr snap-points - Whitespace-separated CSS heights, in ascending order, addressable by\n * `snapTo()` and settled to on drag release.\n * @attr swipe-dismiss - Whether a decisive downward swipe of at least 96 pixels requests close.\n * @attr swipe-velocity - Minimum release velocity, in pixels per second, that counts as a\n * decisive swipe rather than a slow deliberate drag.\n *\n * @cssprop [--rc-bottom-sheet-bg=Canvas] - Sheet surface background.\n * @cssprop [--rc-bottom-sheet-color=CanvasText] - Sheet text color.\n * @cssprop [--rc-bottom-sheet-radius=1rem 1rem 0 0] - Sheet corner radius.\n * @cssprop [--rc-bottom-sheet-shadow=none] - Sheet elevation shadow.\n * @cssprop [--rc-bottom-sheet-position=fixed] - Positioning scheme. Use `absolute` with `show()` to dock a non-modal sheet to a positioned ancestor.\n * @cssprop [--rc-bottom-sheet-inset-block-end=0px] - Distance from the positioning container's block-end edge.\n * @cssprop [--rc-bottom-sheet-inset-inline=0px] - Inline-axis inset used with automatic margins.\n * @cssprop [--rc-bottom-sheet-max-inline-size=40rem] - Maximum sheet width.\n * @cssprop [--rc-bottom-sheet-max-block-size=70dvh] - Maximum sheet height.\n * @cssprop [--rc-bottom-sheet-padding=0 1rem 1rem] - Sheet padding.\n * @cssprop [--rc-bottom-sheet-scrim=var(--rc-dialog-scrim)] - Modal backdrop color.\n * @cssprop [--rc-bottom-sheet-handle-color=GrayText] - Resize handle color.\n * @cssprop [--rc-bottom-sheet-handle-inline-size=2rem] - Resize handle width.\n * @cssprop [--rc-bottom-sheet-handle-block-size=0.25rem] - Resize handle height.\n * @cssprop [--rc-bottom-sheet-handle-radius=999px] - Resize handle corner radius.\n * @cssprop [--rc-bottom-sheet-handle-target-inline-size=100%] - Pointer target width for a direct-child handle.\n * @cssprop [--rc-bottom-sheet-handle-target-block-size=3rem] - Pointer target height for a direct-child handle.\n * @cssprop [--rc-bottom-sheet-handle-target-margin=0] - Margin around a direct-child handle target.\n * @cssprop [--rc-bottom-sheet-snap-duration=300ms] - Duration of the settle animation\n * after a drag release or `snapTo()` call.\n * @cssprop [--rc-bottom-sheet-snap-easing=cubic-bezier(0.4, 0, 0.2, 1)] - Easing\n * for the settle animation after a drag release or `snapTo()` call.\n */\nexport class RCBottomSheet extends RCDialog {\n private static readonly swipeDismissThreshold = 96;\n private static readonly _styledRoots = new Set<Document | ShadowRoot>();\n\n private static _ensureBaseStyles(root: Document | ShadowRoot): void {\n if (RCBottomSheet._styledRoots.has(root)) {\n return;\n }\n\n RCBottomSheet._styledRoots.add(root);\n\n const $style = document.createElement('style');\n\n $style.setAttribute('data-rc-light-dom-base', 'rc-bottom-sheet');\n $style.textContent = LIGHT_DOM_CSS;\n\n if (root instanceof Document) {\n root.head.append($style);\n } else {\n root.append($style);\n }\n }\n\n /**\n * Bottom sheets light-dismiss by default.\n *\n * Set `light-dismiss=\"false\"` as a property from JavaScript when a sheet must\n * be closed only by explicit actions.\n */\n @property({ type: Boolean, attribute: 'light-dismiss' })\n override lightDismiss = true;\n\n /** Bottom sheets resize vertically from the top edge by default. */\n @property({ type: String, reflect: true })\n override resize: ResizeDirection = 'vertical';\n\n /** Top-origin resizing keeps the sheet docked to the viewport bottom. */\n @property({ type: String, attribute: 'resize-origin' })\n override resizeOrigin: ResizeOrigin = 'top';\n\n /** Default optional handle selector. Falls back to top-edge resize when absent. */\n @property({ type: String, attribute: 'resize-handle' })\n override resizeHandle = '[data-rc-bottom-sheet-handle]';\n\n /**\n * Whitespace-separated CSS heights in ascending order.\n *\n * Each height becomes an addressable snap target. Slow releases choose the\n * nearest target, while decisive swipes choose the first or last target.\n */\n @property({ type: String, attribute: 'snap-points' })\n snapPoints = '';\n\n /**\n * Whether a downward pointer resize of at least 96 pixels requests close.\n *\n * When false, a decisive downward swipe settles at the first snap point.\n */\n @property({ type: Boolean, attribute: 'swipe-dismiss' })\n swipeDismiss = true;\n\n /**\n * Minimum release velocity, in pixels per second, that counts as a decisive\n * swipe rather than a slow deliberate drag. A swipe jumps straight to the\n * extreme `snap-points` entry in its direction; below this, the release\n * settles to the nearest point instead.\n */\n @property({ type: Number, attribute: 'swipe-velocity' })\n swipeVelocity = 500;\n\n private readonly _reducedMotion =\n typeof window !== 'undefined' ? window.matchMedia('(prefers-reduced-motion: reduce)') : null;\n\n private _activeSnapAnimation: Animation | null = null;\n\n // Snap-point heights are resolved from the *current* viewport at the\n // moment a snap is applied (dvh units, or a probe-element measurement for\n // other CSS units) and then frozen as inline styles by pinBlockBox — nothing\n // re-derives them afterward. A window resize/maximize/restore while a\n // sheet is open (without the user dragging it) otherwise leaves it pinned\n // to stale pre-resize geometry. Track the last-applied index so a resize\n // can re-run the same snap against fresh geometry.\n private _lastSnapIndex: number | null = null;\n private readonly _onWindowResize = (): void => {\n if (!this.open || this._lastSnapIndex === null) {\n return;\n }\n\n this._snapToIndex(this._lastSnapIndex, 'instant', 'api');\n };\n\n override connectedCallback(): void {\n super.connectedCallback();\n RCBottomSheet._ensureBaseStyles(this.getRootNode() as Document | ShadowRoot);\n window.addEventListener('resize', this._onWindowResize);\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n window.removeEventListener('resize', this._onWindowResize);\n }\n\n /**\n * Snaps to a declared target by zero-based index.\n *\n * Finite fractional indices are truncated and out-of-range indices clamp to\n * the nearest endpoint. Non-finite indices and calls without valid snap\n * points have no effect.\n *\n * @param index - zero-based index into `snapPoints`\n * @param behavior - whether to animate the movement\n *\n * @example\n * const sheet = document.querySelector('rc-bottom-sheet');\n * sheet.snapTo(1);\n */\n snapTo(index: number, behavior: 'animated' | 'instant' = 'animated'): void {\n if (!Number.isFinite(index)) {\n return;\n }\n\n this._snapToIndex(Math.trunc(index), behavior, 'api');\n }\n\n protected override _onResizeEnd(detail: ResizeLifecycleDetail): void {\n if (detail.inputType === 'pointer' && this.swipeDismiss && this._shouldSwipeDismiss(detail)) {\n this.requestClose();\n\n return;\n }\n\n const points = this._resolvedSnapPoints();\n const velocity = detail.edge.includes('n') ? -detail.velocityY : detail.velocityY;\n const distance = Math.abs(detail.height - detail.startHeight);\n\n if (\n detail.inputType === 'pointer' &&\n points.length > 0 &&\n distance >= MIN_SWIPE_DISTANCE &&\n Math.abs(velocity) >= this.swipeVelocity\n ) {\n // Decisive fling: jump to the extreme point in the swipe direction,\n // regardless of proximity to some other point. Height grows as the\n // sheet is dragged upward, so a positive velocity is a swipe up.\n const targetIndex = findExtremeSnapIndex(points, velocity > 0 ? 1 : -1);\n\n this._snapToIndex(targetIndex, 'animated', 'drag');\n\n return;\n }\n\n this._snapToNearestPoint('drag');\n }\n\n private _shouldSwipeDismiss(detail: ResizeLifecycleDetail): boolean {\n return (\n detail.edge.includes('n') &&\n detail.startHeight - detail.height >= RCBottomSheet.swipeDismissThreshold\n );\n }\n\n private _snapToNearestPoint(trigger: 'drag' | 'api' = 'api'): void {\n const $dialog = this._$dialog;\n const points = this._resolvedSnapPoints();\n\n if (!$dialog || points.length === 0) {\n return;\n }\n\n const height = $dialog.getBoundingClientRect().height;\n const nearestIndex = findNearestSnapIndex(points, height);\n\n this._snapToIndex(nearestIndex, 'animated', trigger);\n }\n\n private _snapToIndex(\n index: number,\n behavior: 'animated' | 'instant',\n trigger: 'drag' | 'api',\n ): void {\n const $dialog = this._$dialog;\n const points = this._resolvedSnapPoints();\n\n if (!$dialog || points.length === 0) {\n return;\n }\n\n // Pinning (border-box, explicit top/height) is normally established by\n // the first drag gesture; snapTo() must do the same so a sheet that has\n // never been dragged still measures and sets height consistently.\n const rect = pinBlockBox($dialog);\n const clampedIndex = Math.max(0, Math.min(index, points.length - 1));\n const requestedHeight = points[clampedIndex];\n\n this._lastSnapIndex = clampedIndex;\n\n // An in-flight animation wins over inline geometry in the cascade. Pin\n // its current visual box before cancelling so the constrained target can\n // be measured without jumping back to the prior snap point.\n this._activeSnapAnimation?.cancel();\n this._activeSnapAnimation = null;\n\n $dialog.style.height = `${requestedHeight}px`;\n\n const targetHeight = $dialog.getBoundingClientRect().height;\n\n // Restore the current visual box before applying or animating the target.\n // CSS min/max block-size can make targetHeight differ from the authored\n // snap point; anchoring from the effective height keeps the block-end edge\n // fixed in either case.\n $dialog.style.top = `${rect.top}px`;\n $dialog.style.height = `${rect.height}px`;\n\n const targetTop = rect.bottom - targetHeight;\n\n this._applySnap($dialog, targetTop, targetHeight, behavior);\n\n this.dispatchEvent(\n new CustomEvent<RCBottomSheetSnapDetail>('rc-bottom-sheet-snap', {\n bubbles: true,\n composed: true,\n detail: { index: clampedIndex, height: targetHeight, trigger },\n }),\n );\n }\n\n private _applySnap(\n $dialog: HTMLDialogElement,\n top: number,\n height: number,\n behavior: 'animated' | 'instant',\n ): void {\n // Measure before cancelling any in-flight animation. `_snapToIndex()`\n // normally pins and cancels first, while this ordering also keeps direct\n // calls robust if applying a snap is refactored later.\n const fromRect = $dialog.getBoundingClientRect();\n\n this._activeSnapAnimation?.cancel();\n this._activeSnapAnimation = null;\n\n if (behavior === 'instant' || this._reducedMotion?.matches) {\n $dialog.style.top = `${top}px`;\n $dialog.style.height = `${height}px`;\n\n return;\n }\n\n if (fromRect.top === top && fromRect.height === height) {\n return;\n }\n\n const animation = $dialog.animate(\n [\n { top: `${fromRect.top}px`, height: `${fromRect.height}px` },\n { top: `${top}px`, height: `${height}px` },\n ],\n {\n duration: this._snapDuration($dialog),\n easing: this._snapEasing($dialog),\n fill: 'forwards',\n },\n );\n\n this._activeSnapAnimation = animation;\n\n animation.finished\n .then(() => animation.commitStyles())\n .catch(() => {\n // Interrupted by a newer gesture or snapTo() call, which owns applying\n // its own final styles.\n })\n .finally(() => {\n animation.cancel();\n\n if (this._activeSnapAnimation === animation) {\n this._activeSnapAnimation = null;\n }\n });\n }\n\n private _snapDuration($dialog: HTMLDialogElement): number {\n const raw = getComputedStyle($dialog)\n .getPropertyValue('--rc-bottom-sheet-snap-duration')\n .trim();\n const parsed = Number.parseFloat(raw);\n\n return Number.isFinite(parsed) ? parsed : DEFAULT_SNAP_DURATION_MS;\n }\n\n private _snapEasing($dialog: HTMLDialogElement): string {\n return (\n getComputedStyle($dialog).getPropertyValue('--rc-bottom-sheet-snap-easing').trim() ||\n DEFAULT_SNAP_EASING\n );\n }\n\n private _resolvedSnapPoints(): number[] {\n if (!this.snapPoints.trim()) {\n return [];\n }\n\n return this.snapPoints\n .trim()\n .split(/\\s+/)\n .map((point) => this._resolveSnapPoint(point))\n .filter((point): point is number => Number.isFinite(point) && point > 0);\n }\n\n private _resolveSnapPoint(point: string): number {\n const numeric = Number.parseFloat(point);\n\n if (!Number.isFinite(numeric)) {\n return Number.NaN;\n }\n\n if (point.endsWith('%')) {\n return window.innerHeight * (numeric / 100);\n }\n\n if (point.endsWith('px') || String(numeric) === point) {\n return numeric;\n }\n\n const probe = document.createElement('div');\n\n Object.assign(probe.style, {\n position: 'fixed',\n visibility: 'hidden',\n pointerEvents: 'none',\n blockSize: point,\n inlineSize: '0',\n inset: '0 auto auto 0',\n });\n\n document.body.append(probe);\n\n const height = probe.getBoundingClientRect().height;\n\n probe.remove();\n\n return height;\n }\n}\n\nexport default RCBottomSheet;\n"],"names":["DEFAULT_SNAP_DURATION_MS","DEFAULT_SNAP_EASING","LIGHT_DOM_CSS","MIN_SWIPE_DISTANCE","pinBlockBox","target","rect","_RCBottomSheet","_a","RCDialog","root","$style","index","behavior","detail","points","velocity","distance","targetIndex","findExtremeSnapIndex","trigger","$dialog","height","nearestIndex","findNearestSnapIndex","clampedIndex","requestedHeight","targetHeight","targetTop","top","fromRect","animation","raw","parsed","point","numeric","probe","__decorateClass","property","RCBottomSheet"],"mappings":"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"}
|
package/dist/rc-bottom-sheet.js
CHANGED
|
@@ -127,7 +127,10 @@ export declare class RCBottomSheet extends RCDialog {
|
|
|
127
127
|
swipeVelocity: number;
|
|
128
128
|
private readonly _reducedMotion;
|
|
129
129
|
private _activeSnapAnimation;
|
|
130
|
+
private _lastSnapIndex;
|
|
131
|
+
private readonly _onWindowResize;
|
|
130
132
|
connectedCallback(): void;
|
|
133
|
+
disconnectedCallback(): void;
|
|
131
134
|
/**
|
|
132
135
|
* Snaps to a declared target by zero-based index.
|
|
133
136
|
*
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "0.4.
|
|
6
|
+
"version": "0.4.2",
|
|
7
7
|
"description": "Modal bottom-sheet wrapper for a native <dialog>.",
|
|
8
8
|
"repository": {
|
|
9
9
|
"type": "git",
|
|
@@ -45,8 +45,8 @@
|
|
|
45
45
|
"test:browser:firefox": "vitest --run --project=firefox"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@rcarls/rc-common": "
|
|
49
|
-
"@rcarls/rc-dialog": "
|
|
48
|
+
"@rcarls/rc-common": "0.4.2",
|
|
49
|
+
"@rcarls/rc-dialog": "0.4.2"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
52
|
"@custom-elements-manifest/analyzer": "0.11.0",
|
|
@@ -63,4 +63,4 @@
|
|
|
63
63
|
"peerDependencies": {
|
|
64
64
|
"lit": "^3.0.0"
|
|
65
65
|
}
|
|
66
|
-
}
|
|
66
|
+
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"rc-bottom-sheet-DbzpQjd0.js","sources":["../src/rc-bottom-sheet.ts"],"sourcesContent":["import { property } from 'lit/decorators.js';\n\nimport { RCDialog } from '@rcarls/rc-dialog';\nimport {\n findExtremeSnapIndex,\n findNearestSnapIndex,\n pinElementBox,\n type ResizeDirection,\n type ResizeLifecycleDetail,\n type ResizeOrigin,\n} from '@rcarls/rc-common';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'rc-bottom-sheet': RCBottomSheet;\n }\n\n interface HTMLElementEventMap {\n 'rc-bottom-sheet-snap': CustomEvent<RCBottomSheetSnapDetail>;\n }\n}\n\n/** Detail shape for `rc-bottom-sheet-snap`. */\nexport interface RCBottomSheetSnapDetail {\n /** Index into the resolved `snap-points` list selected as the target. */\n index: number;\n\n /** Effective target height in pixels, after CSS size constraints. */\n height: number;\n\n /** Whether the snap came from a drag release or a `snapTo()` call. */\n trigger: 'drag' | 'api';\n}\n\nconst DEFAULT_SNAP_DURATION_MS = 300;\nconst DEFAULT_SNAP_EASING = 'cubic-bezier(0.4, 0, 0.2, 1)';\n\nconst LIGHT_DOM_CSS = `\n@layer rc-base {\n rc-bottom-sheet > dialog {\n position: var(--rc-bottom-sheet-position, fixed);\n inset-block-start: auto;\n inset-block-end: var(--rc-bottom-sheet-inset-block-end, 0px);\n inset-inline: var(--rc-bottom-sheet-inset-inline, 0px);\n box-sizing: border-box;\n inline-size: 100%;\n max-inline-size: var(--rc-bottom-sheet-max-inline-size, 40rem);\n max-block-size: var(--rc-bottom-sheet-max-block-size, 70dvh);\n margin-block: 0;\n margin-inline: auto;\n overflow: auto;\n }\n\n rc-bottom-sheet > dialog [data-rc-bottom-sheet-handle] {\n box-sizing: border-box;\n cursor: ns-resize;\n touch-action: none;\n -webkit-tap-highlight-color: transparent;\n }\n\n rc-bottom-sheet > dialog > [data-rc-bottom-sheet-handle] {\n position: relative;\n display: block;\n inline-size: var(--rc-bottom-sheet-handle-target-inline-size, 100%);\n min-block-size: var(--rc-bottom-sheet-handle-target-block-size, 3rem);\n margin: var(--rc-bottom-sheet-handle-target-margin, 0);\n padding: 0;\n border: 0;\n border-radius: inherit;\n background: transparent;\n appearance: none;\n }\n\n rc-bottom-sheet > dialog > [data-rc-bottom-sheet-handle]::before {\n content: '';\n position: absolute;\n inset-block-start: 50%;\n inset-inline-start: 50%;\n inline-size: var(--rc-bottom-sheet-handle-inline-size, 2rem);\n block-size: var(--rc-bottom-sheet-handle-block-size, 0.25rem);\n border-radius: var(--rc-bottom-sheet-handle-radius, 999px);\n background: var(--rc-bottom-sheet-handle-color, GrayText);\n translate: -50% -50%;\n }\n\n rc-bottom-sheet > dialog [data-rc-bottom-sheet-handle]:focus-visible {\n outline: auto;\n outline-offset: -0.25rem;\n }\n}\n`;\n\n// Floor so a noisy near-zero-distance release can't misread as a decisive\n// fling; a real swipe travels at least this far even if it's very quick.\nconst MIN_SWIPE_DISTANCE = 24;\n\n/**\n * Modal bottom-sheet wrapper for a native `<dialog>`, built on `rc-dialog`.\n *\n * The direct child `<dialog>` remains the semantic dialog surface and owns\n * content, labels, and form behavior. `rc-bottom-sheet` supplies the same\n * open/close lifecycle, focus restoration, cancel/request-close events, and\n * light-dismiss affordance as `rc-dialog`. The component docks the sheet to\n * the viewport block-end by default, while themes provide its visual surface.\n *\n * Dragging the resize handle past a decisive velocity in either direction\n * (a \"swipe\" or \"fling,\" distinct from a slow deliberate drag) snaps\n * straight to the extreme `snap-points` entry in that direction — swipe up\n * to fully expand, swipe down to fully collapse — regardless of how close\n * the release position was to some other point. Below that velocity, the\n * sheet settles to whichever declared snap point is nearest the release\n * height. All settling, whether from a drag or from `snapTo()`, animates\n * over `--rc-bottom-sheet-snap-duration`, follows\n * `--rc-bottom-sheet-snap-easing`, and is skipped for\n * `prefers-reduced-motion: reduce`.\n *\n * @see {@link https://richardcarls.github.io/rc-webcomponents/components/rc-bottom-sheet rc-bottom-sheet docs}\n * @see {@link https://m3.material.io/components/bottom-sheets/overview Material Design bottom sheets}\n *\n * @slot - Place a `<dialog>` element with the sheet content and optional\n * `[data-rc-bottom-sheet-handle]` resize handle here.\n *\n * @fires rc-dialog-open - Inherited from `rc-dialog`; fired when the sheet opens.\n * @fires rc-dialog-toggle - Inherited from `rc-dialog`; fired when user/native interaction changes open state.\n * @fires rc-dialog-request-close - Inherited from `rc-dialog`; cancelable close request.\n * @fires rc-dialog-cancel - Inherited from `rc-dialog`; backward-compatible cancel alias.\n * @fires rc-dialog-close - Inherited from `rc-dialog`; fired after the sheet closes.\n * @fires rc-bottom-sheet-snap - Fires when a drag release or `snapTo()` call\n * selects a snap target. `detail: { index, height, trigger }`\n *\n * @attr light-dismiss - When present, a click on the backdrop area calls `requestClose()`.\n * Present by default; inherited from `rc-dialog`.\n * @attr resize - Enables edge resizing, mirroring the CSS `resize` property values.\n * Defaults to `vertical`; inherited from `rc-dialog`.\n * @attr resize-origin - Origin for resize edge hit-testing or explicit handles. Defaults to\n * `top`; inherited from `rc-dialog`.\n * @attr resize-handle - CSS selector, scoped to the inner `<dialog>`, for explicit resize\n * handles. Defaults to `[data-rc-bottom-sheet-handle]`; inherited from `rc-dialog`.\n * @attr snap-points - Whitespace-separated CSS heights, in ascending order, addressable by\n * `snapTo()` and settled to on drag release.\n * @attr swipe-dismiss - Whether a decisive downward swipe of at least 96 pixels requests close.\n * @attr swipe-velocity - Minimum release velocity, in pixels per second, that counts as a\n * decisive swipe rather than a slow deliberate drag.\n *\n * @cssprop [--rc-bottom-sheet-bg=Canvas] - Sheet surface background.\n * @cssprop [--rc-bottom-sheet-color=CanvasText] - Sheet text color.\n * @cssprop [--rc-bottom-sheet-radius=1rem 1rem 0 0] - Sheet corner radius.\n * @cssprop [--rc-bottom-sheet-shadow=none] - Sheet elevation shadow.\n * @cssprop [--rc-bottom-sheet-position=fixed] - Positioning scheme. Use `absolute` with `show()` to dock a non-modal sheet to a positioned ancestor.\n * @cssprop [--rc-bottom-sheet-inset-block-end=0px] - Distance from the positioning container's block-end edge.\n * @cssprop [--rc-bottom-sheet-inset-inline=0px] - Inline-axis inset used with automatic margins.\n * @cssprop [--rc-bottom-sheet-max-inline-size=40rem] - Maximum sheet width.\n * @cssprop [--rc-bottom-sheet-max-block-size=70dvh] - Maximum sheet height.\n * @cssprop [--rc-bottom-sheet-padding=0 1rem 1rem] - Sheet padding.\n * @cssprop [--rc-bottom-sheet-scrim=var(--rc-dialog-scrim)] - Modal backdrop color.\n * @cssprop [--rc-bottom-sheet-handle-color=GrayText] - Resize handle color.\n * @cssprop [--rc-bottom-sheet-handle-inline-size=2rem] - Resize handle width.\n * @cssprop [--rc-bottom-sheet-handle-block-size=0.25rem] - Resize handle height.\n * @cssprop [--rc-bottom-sheet-handle-radius=999px] - Resize handle corner radius.\n * @cssprop [--rc-bottom-sheet-handle-target-inline-size=100%] - Pointer target width for a direct-child handle.\n * @cssprop [--rc-bottom-sheet-handle-target-block-size=3rem] - Pointer target height for a direct-child handle.\n * @cssprop [--rc-bottom-sheet-handle-target-margin=0] - Margin around a direct-child handle target.\n * @cssprop [--rc-bottom-sheet-snap-duration=300ms] - Duration of the settle animation\n * after a drag release or `snapTo()` call.\n * @cssprop [--rc-bottom-sheet-snap-easing=cubic-bezier(0.4, 0, 0.2, 1)] - Easing\n * for the settle animation after a drag release or `snapTo()` call.\n */\nexport class RCBottomSheet extends RCDialog {\n private static readonly swipeDismissThreshold = 96;\n private static readonly _styledRoots = new Set<Document | ShadowRoot>();\n\n private static _ensureBaseStyles(root: Document | ShadowRoot): void {\n if (RCBottomSheet._styledRoots.has(root)) {\n return;\n }\n\n RCBottomSheet._styledRoots.add(root);\n\n const $style = document.createElement('style');\n\n $style.setAttribute('data-rc-light-dom-base', 'rc-bottom-sheet');\n $style.textContent = LIGHT_DOM_CSS;\n\n if (root instanceof Document) {\n root.head.append($style);\n } else {\n root.append($style);\n }\n }\n\n /**\n * Bottom sheets light-dismiss by default.\n *\n * Set `light-dismiss=\"false\"` as a property from JavaScript when a sheet must\n * be closed only by explicit actions.\n */\n @property({ type: Boolean, attribute: 'light-dismiss' })\n override lightDismiss = true;\n\n /** Bottom sheets resize vertically from the top edge by default. */\n @property({ type: String, reflect: true })\n override resize: ResizeDirection = 'vertical';\n\n /** Top-origin resizing keeps the sheet docked to the viewport bottom. */\n @property({ type: String, attribute: 'resize-origin' })\n override resizeOrigin: ResizeOrigin = 'top';\n\n /** Default optional handle selector. Falls back to top-edge resize when absent. */\n @property({ type: String, attribute: 'resize-handle' })\n override resizeHandle = '[data-rc-bottom-sheet-handle]';\n\n /**\n * Whitespace-separated CSS heights in ascending order.\n *\n * Each height becomes an addressable snap target. Slow releases choose the\n * nearest target, while decisive swipes choose the first or last target.\n */\n @property({ type: String, attribute: 'snap-points' })\n snapPoints = '';\n\n /**\n * Whether a downward pointer resize of at least 96 pixels requests close.\n *\n * When false, a decisive downward swipe settles at the first snap point.\n */\n @property({ type: Boolean, attribute: 'swipe-dismiss' })\n swipeDismiss = true;\n\n /**\n * Minimum release velocity, in pixels per second, that counts as a decisive\n * swipe rather than a slow deliberate drag. A swipe jumps straight to the\n * extreme `snap-points` entry in its direction; below this, the release\n * settles to the nearest point instead.\n */\n @property({ type: Number, attribute: 'swipe-velocity' })\n swipeVelocity = 500;\n\n private readonly _reducedMotion =\n typeof window !== 'undefined' ? window.matchMedia('(prefers-reduced-motion: reduce)') : null;\n\n private _activeSnapAnimation: Animation | null = null;\n\n override connectedCallback(): void {\n super.connectedCallback();\n RCBottomSheet._ensureBaseStyles(this.getRootNode() as Document | ShadowRoot);\n }\n\n /**\n * Snaps to a declared target by zero-based index.\n *\n * Finite fractional indices are truncated and out-of-range indices clamp to\n * the nearest endpoint. Non-finite indices and calls without valid snap\n * points have no effect.\n *\n * @param index - zero-based index into `snapPoints`\n * @param behavior - whether to animate the movement\n *\n * @example\n * const sheet = document.querySelector('rc-bottom-sheet');\n * sheet.snapTo(1);\n */\n snapTo(index: number, behavior: 'animated' | 'instant' = 'animated'): void {\n if (!Number.isFinite(index)) {\n return;\n }\n\n this._snapToIndex(Math.trunc(index), behavior, 'api');\n }\n\n protected override _onResizeEnd(detail: ResizeLifecycleDetail): void {\n if (detail.inputType === 'pointer' && this.swipeDismiss && this._shouldSwipeDismiss(detail)) {\n this.requestClose();\n\n return;\n }\n\n const points = this._resolvedSnapPoints();\n const velocity = detail.edge.includes('n') ? -detail.velocityY : detail.velocityY;\n const distance = Math.abs(detail.height - detail.startHeight);\n\n if (\n detail.inputType === 'pointer' &&\n points.length > 0 &&\n distance >= MIN_SWIPE_DISTANCE &&\n Math.abs(velocity) >= this.swipeVelocity\n ) {\n // Decisive fling: jump to the extreme point in the swipe direction,\n // regardless of proximity to some other point. Height grows as the\n // sheet is dragged upward, so a positive velocity is a swipe up.\n const targetIndex = findExtremeSnapIndex(points, velocity > 0 ? 1 : -1);\n\n this._snapToIndex(targetIndex, 'animated', 'drag');\n\n return;\n }\n\n this._snapToNearestPoint('drag');\n }\n\n private _shouldSwipeDismiss(detail: ResizeLifecycleDetail): boolean {\n return (\n detail.edge.includes('n') &&\n detail.startHeight - detail.height >= RCBottomSheet.swipeDismissThreshold\n );\n }\n\n private _snapToNearestPoint(trigger: 'drag' | 'api' = 'api'): void {\n const $dialog = this._$dialog;\n const points = this._resolvedSnapPoints();\n\n if (!$dialog || points.length === 0) {\n return;\n }\n\n const height = $dialog.getBoundingClientRect().height;\n const nearestIndex = findNearestSnapIndex(points, height);\n\n this._snapToIndex(nearestIndex, 'animated', trigger);\n }\n\n private _snapToIndex(\n index: number,\n behavior: 'animated' | 'instant',\n trigger: 'drag' | 'api',\n ): void {\n const $dialog = this._$dialog;\n const points = this._resolvedSnapPoints();\n\n if (!$dialog || points.length === 0) {\n return;\n }\n\n // Pinning (border-box, explicit left/top/width/height) is normally\n // established by the first drag gesture; snapTo() must do the same so a\n // sheet that has never been dragged still measures and sets height\n // consistently.\n const rect = pinElementBox($dialog);\n const clampedIndex = Math.max(0, Math.min(index, points.length - 1));\n const requestedHeight = points[clampedIndex];\n\n // An in-flight animation wins over inline geometry in the cascade. Pin\n // its current visual box before cancelling so the constrained target can\n // be measured without jumping back to the prior snap point.\n this._activeSnapAnimation?.cancel();\n this._activeSnapAnimation = null;\n\n $dialog.style.height = `${requestedHeight}px`;\n\n const targetHeight = $dialog.getBoundingClientRect().height;\n\n // Restore the current visual box before applying or animating the target.\n // CSS min/max block-size can make targetHeight differ from the authored\n // snap point; anchoring from the effective height keeps the block-end edge\n // fixed in either case.\n $dialog.style.top = `${rect.top}px`;\n $dialog.style.height = `${rect.height}px`;\n\n const targetTop = rect.bottom - targetHeight;\n\n this._applySnap($dialog, targetTop, targetHeight, behavior);\n\n this.dispatchEvent(\n new CustomEvent<RCBottomSheetSnapDetail>('rc-bottom-sheet-snap', {\n bubbles: true,\n composed: true,\n detail: { index: clampedIndex, height: targetHeight, trigger },\n }),\n );\n }\n\n private _applySnap(\n $dialog: HTMLDialogElement,\n top: number,\n height: number,\n behavior: 'animated' | 'instant',\n ): void {\n // Measure before cancelling any in-flight animation. `_snapToIndex()`\n // normally pins and cancels first, while this ordering also keeps direct\n // calls robust if applying a snap is refactored later.\n const fromRect = $dialog.getBoundingClientRect();\n\n this._activeSnapAnimation?.cancel();\n this._activeSnapAnimation = null;\n\n if (behavior === 'instant' || this._reducedMotion?.matches) {\n $dialog.style.top = `${top}px`;\n $dialog.style.height = `${height}px`;\n\n return;\n }\n\n if (fromRect.top === top && fromRect.height === height) {\n return;\n }\n\n const animation = $dialog.animate(\n [\n { top: `${fromRect.top}px`, height: `${fromRect.height}px` },\n { top: `${top}px`, height: `${height}px` },\n ],\n {\n duration: this._snapDuration($dialog),\n easing: this._snapEasing($dialog),\n fill: 'forwards',\n },\n );\n\n this._activeSnapAnimation = animation;\n\n animation.finished\n .then(() => animation.commitStyles())\n .catch(() => {\n // Interrupted by a newer gesture or snapTo() call, which owns applying\n // its own final styles.\n })\n .finally(() => {\n animation.cancel();\n\n if (this._activeSnapAnimation === animation) {\n this._activeSnapAnimation = null;\n }\n });\n }\n\n private _snapDuration($dialog: HTMLDialogElement): number {\n const raw = getComputedStyle($dialog)\n .getPropertyValue('--rc-bottom-sheet-snap-duration')\n .trim();\n const parsed = Number.parseFloat(raw);\n\n return Number.isFinite(parsed) ? parsed : DEFAULT_SNAP_DURATION_MS;\n }\n\n private _snapEasing($dialog: HTMLDialogElement): string {\n return (\n getComputedStyle($dialog).getPropertyValue('--rc-bottom-sheet-snap-easing').trim() ||\n DEFAULT_SNAP_EASING\n );\n }\n\n private _resolvedSnapPoints(): number[] {\n if (!this.snapPoints.trim()) {\n return [];\n }\n\n return this.snapPoints\n .trim()\n .split(/\\s+/)\n .map((point) => this._resolveSnapPoint(point))\n .filter((point): point is number => Number.isFinite(point) && point > 0);\n }\n\n private _resolveSnapPoint(point: string): number {\n const numeric = Number.parseFloat(point);\n\n if (!Number.isFinite(numeric)) {\n return Number.NaN;\n }\n\n if (point.endsWith('%')) {\n return window.innerHeight * (numeric / 100);\n }\n\n if (point.endsWith('px') || String(numeric) === point) {\n return numeric;\n }\n\n const probe = document.createElement('div');\n\n Object.assign(probe.style, {\n position: 'fixed',\n visibility: 'hidden',\n pointerEvents: 'none',\n blockSize: point,\n inlineSize: '0',\n inset: '0 auto auto 0',\n });\n\n document.body.append(probe);\n\n const height = probe.getBoundingClientRect().height;\n\n probe.remove();\n\n return height;\n }\n}\n\nexport default RCBottomSheet;\n"],"names":["DEFAULT_SNAP_DURATION_MS","DEFAULT_SNAP_EASING","LIGHT_DOM_CSS","MIN_SWIPE_DISTANCE","_RCBottomSheet","_a","RCDialog","root","$style","index","behavior","detail","points","velocity","distance","targetIndex","findExtremeSnapIndex","trigger","$dialog","height","nearestIndex","findNearestSnapIndex","rect","pinElementBox","clampedIndex","requestedHeight","targetHeight","targetTop","top","fromRect","animation","raw","parsed","point","numeric","probe","__decorateClass","property","RCBottomSheet"],"mappings":"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"}
|