@nipe-solutions/react-spring-bottom-sheet
Version:
Accessible and composable bottom sheets for React
1,229 lines (1,228 loc) • 34.1 kB
JavaScript
import { Children as e, cloneElement as t, createContext as n, forwardRef as r, isValidElement as i, useCallback as a, useContext as o, useEffect as s, useId as c, useMemo as l, useRef as u, useState as d, useSyncExternalStore as f } from "react";
import { jsx as p, jsxs as m } from "react/jsx-runtime";
import { createPortal as h } from "react-dom";
//#region src/composition/merge-refs.ts
function g(e, t) {
if (typeof e == "function") {
let n = e(t);
return t === null ? void 0 : typeof n == "function" ? n : () => e(null);
}
if (e && (e.current = t, t !== null)) return () => e.current = null;
}
function _(...e) {
return (t) => {
let n = e.map((e) => g(e, t)).filter((e) => e !== void 0);
if (t !== null && n.length > 0) return () => {
for (let e of n) e();
};
};
}
//#endregion
//#region src/composition/Slot.tsx
var v = r(function({ children: n, className: r, onClick: a, onPointerCancel: o, onPointerDown: s, onPointerMove: c, onPointerUp: l, style: u, ...d }, f) {
let p = e.only(n);
if (!i(p)) throw Error("asChild requires exactly one valid element");
let m = p.props.onClick, h = (e) => {
m?.(e), e.defaultPrevented || a?.(e);
}, g = (e, t) => (n) => {
e?.(n), n.defaultPrevented || t?.(n);
}, v = {
...u,
...p.props.style
};
return t(p, {
...d,
...p.props,
className: [r, p.props.className].filter(Boolean).join(" ") || void 0,
onClick: h,
onPointerCancel: g(p.props.onPointerCancel, o),
onPointerDown: g(p.props.onPointerDown, s),
onPointerMove: g(p.props.onPointerMove, c),
onPointerUp: g(p.props.onPointerUp, l),
ref: _(f, p.props.ref),
style: v
});
}), y = n(null);
function b(e) {
let t = o(y);
if (!t) throw Error(`${e} must be used inside Sheet.Root`);
return t;
}
//#endregion
//#region src/components/Backdrop.tsx
var x = r(function({ asChild: e = !1, children: t, className: n, onClick: r, ...i }, a) {
let { dismissible: o, registerBackdrop: s, requestOpenChange: c, transitionPhase: u } = b("Sheet.Backdrop"), d = l(() => _(s, a), [a, s]), f = {
...i,
className: ["rsbs-backdrop", n].filter(Boolean).join(" "),
"data-rsbs-backdrop": "",
"data-rsbs-state": u,
onClick: (e) => {
r?.(e), o && e.target === e.currentTarget && !e.defaultPrevented && c(!1, "backdrop");
}
};
return p(e ? v : "div", {
...f,
ref: d,
children: t
});
}), S = r(function({ asChild: e = !1, children: t, className: n, onClick: r, type: i = "button", ...a }, o) {
let { requestOpenChange: s } = b("Sheet.Close"), c = {
...a,
className: ["rsbs-close", n].filter(Boolean).join(" "),
"data-rsbs-close": "",
onClick: (e) => {
r?.(e), e.defaultPrevented || s(!1, "close");
}
};
return e ? /* @__PURE__ */ p(v, {
...c,
ref: o,
children: t
}) : /* @__PURE__ */ p("button", {
...c,
ref: o,
type: i,
children: t
});
}), C = [
"a[href]",
"button:not([disabled])",
"input:not([disabled])",
"select:not([disabled])",
"textarea:not([disabled])",
"[tabindex]:not([tabindex=\"-1\"])"
].join(",");
function w(e) {
return [...e.querySelectorAll(C)].filter((e) => !e.hidden && e.getAttribute("aria-hidden") !== "true");
}
function T(e) {
(e.querySelector("[autofocus]") ?? w(e)[0] ?? e).focus({ preventScroll: !0 });
}
function E(e, t) {
if (e.key !== "Tab") return;
let n = w(t);
if (n.length === 0) {
e.preventDefault(), t.focus({ preventScroll: !0 });
return;
}
let r = n[0], i = n[n.length - 1];
e.shiftKey && document.activeElement === r ? (e.preventDefault(), i.focus({ preventScroll: !0 })) : !e.shiftKey && document.activeElement === i && (e.preventDefault(), r.focus({ preventScroll: !0 }));
}
//#endregion
//#region src/accessibility/isolation.ts
function ee(e) {
let t = /* @__PURE__ */ new Map(), n = e, r = e.parentElement;
for (; r;) {
for (let e of r.children) e instanceof HTMLElement && e !== n && (e.hasAttribute("data-rsbs-backdrop") || e.querySelector("[data-rsbs-backdrop]") || t.has(e) || (t.set(e, {
element: e,
ariaHidden: e.getAttribute("aria-hidden"),
inert: e.inert
}), e.setAttribute("aria-hidden", "true"), e.inert = !0));
if (r === document.body) break;
n = r, r = r.parentElement;
}
return () => {
for (let { element: e, ariaHidden: n, inert: r } of [...t.values()].reverse()) n === null ? e.removeAttribute("aria-hidden") : e.setAttribute("aria-hidden", n), e.inert = r;
};
}
//#endregion
//#region src/components/Content.tsx
var D = r(function({ asChild: e = !1, children: t, className: n, onPointerCancel: r, onPointerDown: i, onPointerMove: a, onPointerUp: o, style: c, ...l }, d) {
let { descriptionId: f, dismissible: m, modal: h, open: g, requestOpenChange: y, registerContent: x, interactionHandlers: S, position: C, surfaceProgress: w, dragging: D, titleId: O, transitionPhase: k } = b("Sheet.Content"), A = u(null);
s(() => {
let e = A.current;
if (!e || !g) return;
let t = h && document.activeElement instanceof HTMLElement ? document.activeElement : null, n = h ? ee(e) : void 0, r = (t) => {
t.key === "Escape" && m ? (t.preventDefault(), y(!1, "escape")) : h && E(t, e);
}, i = (t) => {
h && t.target instanceof Node && !e.contains(t.target) && T(e);
};
return document.addEventListener("keydown", r), document.addEventListener("focusin", i), h && T(e), () => {
document.removeEventListener("keydown", r), document.removeEventListener("focusin", i), n?.(), t?.focus({ preventScroll: !0 });
};
}, [
m,
h,
g,
y
]), s(() => {
let e = A.current;
if (process.env.NODE_ENV === "production" || !e || !g) return;
let t = !0;
return queueMicrotask(() => {
t && e.isConnected && !e.hasAttribute("aria-label") && !e.getAttribute("aria-labelledby") && console.warn("Sheet.Content requires Sheet.Title or an aria-label.");
}), () => {
t = !1;
};
}, [g, O]);
let j = ["rsbs-content", n].filter(Boolean).join(" "), M = (e, t) => (n) => {
e?.(n), n.defaultPrevented || t(n);
}, N = {
...c,
"--rsbs-position": `${C}px`,
"--rsbs-surface-progress": w
}, P = {
...l,
role: "dialog",
tabIndex: l.tabIndex ?? -1,
inert: !g,
"aria-modal": h || void 0,
"aria-hidden": !g || void 0,
"aria-labelledby": l["aria-label"] ? void 0 : O,
"aria-describedby": f,
className: j,
"data-rsbs-content": "",
"data-rsbs-state": k,
"data-rsbs-dragging": D || void 0,
onPointerDown: M(i, S.onPointerDown),
onPointerMove: M(a, S.onPointerMove),
onPointerUp: M(o, S.onPointerUp),
onPointerCancel: M(r, S.onPointerCancel),
style: N
};
return e ? /* @__PURE__ */ p(v, {
...P,
ref: _(A, x, d),
children: t
}) : /* @__PURE__ */ p("div", {
...P,
ref: _(d, (e) => {
A.current = e, x(e);
}),
children: t
});
}), O = r(function({ asChild: e = !1, children: t, className: n, id: r, ...i }, a) {
let o = c(), l = r ?? o, { registerDescription: u } = b("Sheet.Description");
s(() => u(l), [l, u]);
let d = {
...i,
id: l,
className: ["rsbs-description", n].filter(Boolean).join(" "),
"data-rsbs-description": ""
};
return p(e ? v : "p", {
...d,
ref: a,
children: t
});
});
//#endregion
//#region src/layout/reconcile-active-snap-point.ts
function k(e, t, n) {
if (n.length === 0) return null;
let r = n.find(({ id: t }) => t === e);
if (r) return r;
let i = n[0], a = Math.abs(t - i.position);
for (let e = 1; e < n.length; e += 1) {
let r = n[e], o = Math.abs(t - r.position);
o < a && (i = r, a = o);
}
return i;
}
//#endregion
//#region src/controller/reducer.ts
function A() {
return {
phase: "closed",
open: !1,
activeSnapPoint: null,
position: 0,
targetPosition: 0,
velocity: 0,
dismissReason: null
};
}
function j(e, t) {
return {
state: e,
diagnostic: {
code: "invalid-transition",
event: t.type,
phase: e.phase
}
};
}
function M(e, t) {
if (t.type === "OPEN_REQUESTED") return {
state: {
...e,
phase: "opening",
open: !0,
activeSnapPoint: t.snapPoint,
targetPosition: t.targetPosition,
velocity: 0,
dismissReason: null
},
diagnostic: null
};
if (t.type === "CLOSE_REQUESTED" && e.phase !== "closed") return {
state: {
...e,
phase: "closing",
open: !1,
dismissReason: t.reason,
velocity: t.velocity ?? 0
},
diagnostic: null
};
if (t.type === "DRAG_STARTED" && [
"open",
"opening",
"settling"
].includes(e.phase)) return {
state: {
...e,
phase: "dragging",
position: t.position,
velocity: 0
},
diagnostic: null
};
if (t.type === "DRAG_MOVED" && e.phase === "dragging") return {
state: {
...e,
position: t.position
},
diagnostic: null
};
if (t.type === "DRAG_ENDED" && e.phase === "dragging") return {
state: {
...e,
phase: "settling",
position: t.position,
targetPosition: t.targetPosition,
velocity: t.velocity,
activeSnapPoint: t.snapPoint
},
diagnostic: null
};
if (t.type === "LAYOUT_CHANGED") {
if (e.phase === "closed") return {
state: {
...e,
position: t.layout.closedPosition,
targetPosition: t.layout.closedPosition
},
diagnostic: null
};
if (e.phase === "closing") return {
state: {
...e,
targetPosition: t.layout.closedPosition
},
diagnostic: null
};
let n = k(e.activeSnapPoint, e.position, t.layout.snapPoints);
return n ? {
state: {
...e,
phase: e.phase === "dragging" ? "dragging" : "settling",
activeSnapPoint: n.id,
targetPosition: n.position,
velocity: e.phase === "dragging" ? e.velocity : 0
},
diagnostic: null
} : {
state: e,
diagnostic: null
};
}
return t.type === "SETTLED" && e.phase === "closing" ? {
state: {
...A(),
position: t.position,
targetPosition: t.position,
velocity: 0
},
diagnostic: null
} : t.type === "SETTLED" && (e.phase === "opening" || e.phase === "settling") ? {
state: {
...e,
phase: "open",
position: t.position,
targetPosition: t.position,
velocity: 0
},
diagnostic: null
} : j(e, t);
}
//#endregion
//#region src/controller/invariants.ts
function N(e) {
if (e.phase === "closed" && e.open) throw Error("closed phase requires open to be false");
if ((e.phase === "opening" || e.phase === "open" || e.phase === "dragging" || e.phase === "settling") && !e.activeSnapPoint) throw Error(`${e.phase} phase requires an active snap point`);
if (!Number.isFinite(e.position) || !Number.isFinite(e.targetPosition) || !Number.isFinite(e.velocity)) throw Error("sheet positions must be finite");
}
//#endregion
//#region src/controller/create-controller.ts
function P(e = {}) {
let t = e.initialState ?? A(), n = /* @__PURE__ */ new Set();
return {
getState() {
return t;
},
dispatch(r) {
let i = t, a = M(i, r);
if (a.diagnostic) {
e.onDiagnostic?.(a.diagnostic);
return;
}
if (t = a.state, process.env.NODE_ENV !== "production" && N(t), t !== i) {
let e = t;
for (let t of [...n]) t(e);
}
},
subscribe(e) {
return n.add(e), () => {
n.delete(e);
};
}
};
}
//#endregion
//#region src/hooks/use-reduced-motion.ts
function te() {
let [e, t] = d(() => typeof window > "u" ? !1 : window.matchMedia("(prefers-reduced-motion: reduce)").matches);
return s(() => {
let e = window.matchMedia("(prefers-reduced-motion: reduce)"), n = () => t(e.matches);
return e.addEventListener("change", n), n(), () => e.removeEventListener("change", n);
}, []), e;
}
//#endregion
//#region src/gestures/velocity.ts
function F(e, t = 100) {
if (e.length < 2) return 0;
let n = e[e.length - 1], r = n.time - t, i = e.find(({ time: e }) => e >= r) ?? e[0], a = n.time - i.time;
return a > 0 ? (n.position - i.position) / a : 0;
}
//#endregion
//#region src/gestures/pointer-session.ts
function I(e, t) {
try {
e.setPointerCapture?.(t);
} catch {}
}
function L(e, t) {
try {
(!e.hasPointerCapture || e.hasPointerCapture(t)) && e.releasePointerCapture?.(t);
} catch {}
}
function R(e) {
let t = null, n = 0, r = 0, i = 0, a, o = [], s = () => ({
deltaY: r - n,
deltaSinceLastY: i,
positionY: r,
velocityY: F(o)
}), c = (n) => {
if (t === null) return;
let r = t, i = {
...s(),
cancelled: n
};
t = null, a && L(a, r), a = void 0, o = [], e.onEnd(i);
};
return {
get active() {
return t !== null;
},
start(s, c) {
return t === null && (t = s.pointerId, n = s.clientY, r = s.clientY, i = 0, a = c, o = [{
position: s.clientY,
time: s.timeStamp
}], c && I(c, s.pointerId), e.onStart(s.clientY), !0);
},
capture(e) {
t === null || a || (a = e, I(e, t));
},
move(n) {
n.pointerId === t && (i = n.clientY - r, r = n.clientY, o.push({
position: n.clientY,
time: n.timeStamp
}), e.onMove(s()));
},
end(e) {
e.pointerId === t && (i = e.clientY - r, r = e.clientY, o.push({
position: e.clientY,
time: e.timeStamp
}), c(!1));
},
cancel() {
c(!0);
},
dispose() {
c(!0);
}
};
}
//#endregion
//#region src/gestures/resistance.ts
var z = .35;
function ne(e, t, n = z) {
if (t.min > t.max) throw Error("drag range minimum cannot exceed maximum");
return e < t.min ? t.min + (e - t.min) * n : e > t.max ? t.max + (e - t.max) * n : e;
}
//#endregion
//#region src/gestures/scroll-boundary.ts
function re({ deltaY: e, scrollTop: t, scrollHeight: n, clientHeight: r, startedOnHandle: i }) {
if (i) return "sheet";
let a = Math.max(0, n - r);
return a <= 0 ? "sheet" : e < 0 ? t < a ? "content" : "sheet" : e > 0 ? t > 0 ? "content" : "sheet" : "content";
}
function B(e, t) {
let n = e instanceof HTMLElement ? e : null;
for (; n && n !== t;) {
let e = getComputedStyle(n).overflowY;
if (n.scrollHeight > n.clientHeight && [
"auto",
"scroll",
"overlay"
].includes(e)) return n;
n = n.parentElement;
}
return null;
}
//#endregion
//#region src/layout/select-settle-target.ts
var V = .45;
function ie(e, t) {
let n = 0, r = Math.abs(e - t[0].position);
for (let i = 1; i < t.length; i += 1) {
let a = Math.abs(e - t[i].position);
a < r && (n = i, r = a);
}
return n;
}
function H({ position: e, velocity: t, snapPoints: n, closedPosition: r, dismissible: i }) {
if (n.length === 0) return { type: "none" };
let a = n.length - 1, o = (n[a].position + r) / 2, s = ie(e, n);
return i && (e >= o || s === a && t >= V) ? {
type: "dismiss",
position: r
} : Math.abs(t) >= V ? {
type: "snap",
snapPoint: n[Math.max(0, Math.min(a, s + (t > 0 ? 1 : -1)))]
} : {
type: "snap",
snapPoint: n[s]
};
}
//#endregion
//#region src/hooks/use-sheet-interactions.ts
function ae({ content: e, controller: t, state: n, layout: r, dismissible: i, onDismiss: a, onSnapPointChange: o, onPositionChange: c }) {
let d = u(n), f = u(r), p = u(null), m = u(!1), h = u(!1), g = u(0), _ = u(0), v = u(null);
d.current = n, f.current = r;
let y = l(() => R({
onStart() {
_.current = d.current.position, h.current = m.current, g.current = 0, h.current && [
"open",
"opening",
"settling"
].includes(d.current.phase) && t.dispatch({
type: "DRAG_STARTED",
position: _.current
});
},
onMove(e) {
let n = f.current;
if (!n) return;
if (!h.current) {
let n = p.current;
if (re({
deltaY: e.deltaSinceLastY,
scrollTop: n?.scrollTop ?? 0,
scrollHeight: n?.scrollHeight ?? 0,
clientHeight: n?.clientHeight ?? 0,
startedOnHandle: m.current
}) === "content" || ![
"open",
"opening",
"settling"
].includes(d.current.phase)) return;
h.current = !0, v.current && y.capture(v.current), g.current = e.deltaY, _.current = d.current.position, t.dispatch({
type: "DRAG_STARTED",
position: _.current
});
}
let r = n.snapPoints[0]?.position;
if (r === void 0) return;
let i = ne(_.current + e.deltaY - g.current, {
min: r,
max: n.closedPosition
});
t.dispatch({
type: "DRAG_MOVED",
position: i
}), c(i);
},
onEnd(e) {
let n = f.current;
if (!h.current || !n) return;
let r = d.current, s = H({
position: r.position,
velocity: e.cancelled ? 0 : e.velocityY,
snapPoints: n.snapPoints,
closedPosition: n.closedPosition,
dismissible: i
});
s.type === "dismiss" ? (t.dispatch({
type: "CLOSE_REQUESTED",
reason: "drag",
velocity: e.velocityY
}), a()) : s.type === "snap" && (t.dispatch({
type: "DRAG_ENDED",
position: r.position,
velocity: e.velocityY,
snapPoint: s.snapPoint.id,
targetPosition: s.snapPoint.position
}), o(s.snapPoint.id));
}
}), [
t,
i,
a,
c,
o
]);
return s(() => {
let e = () => y.cancel();
return window.addEventListener("blur", e), () => {
window.removeEventListener("blur", e), y.dispose();
};
}, [y]), {
onPointerDown(t) {
if (!e || !r || ![
"open",
"opening",
"settling"
].includes(n.phase)) return;
if (y.active) {
y.cancel();
return;
}
let i = t.target instanceof HTMLElement ? t.target : null;
m.current = !!i?.closest("[data-rsbs-handle]"), p.current = m.current ? null : B(t.target, e), v.current = t.currentTarget, y.start(t.nativeEvent, m.current ? t.currentTarget : void 0);
},
onPointerMove(e) {
y.move(e.nativeEvent), h.current && e.preventDefault();
},
onPointerUp(e) {
y.end(e.nativeEvent);
},
onPointerCancel() {
y.cancel();
}
};
}
//#endregion
//#region src/layout/observe-layout.ts
function U() {
if (typeof document > "u") return {
top: 0,
bottom: 0
};
let e = document.createElement("div");
e.style.cssText = "position:fixed;visibility:hidden;pointer-events:none;padding-top:env(safe-area-inset-top);padding-bottom:env(safe-area-inset-bottom)", document.body.append(e);
let t = getComputedStyle(e), n = {
top: Number.parseFloat(t.paddingTop) || 0,
bottom: Number.parseFloat(t.paddingBottom) || 0
};
return e.remove(), n;
}
function W({ viewport: e, content: t, onChange: n, getSafeArea: r = U, visualViewport: i = typeof window > "u" ? null : window.visualViewport, createResizeObserver: a = (e) => typeof ResizeObserver > "u" ? null : new ResizeObserver(e) }) {
let o = !1, s = typeof document < "u" && e.parentElement === document.body ? i : null, c = () => {
if (o) return;
let i = r(), a = t.getBoundingClientRect().height;
n({
viewportHeight: s?.height ?? e.clientHeight,
contentHeight: a || t.scrollHeight,
safeAreaTop: i.top,
safeAreaBottom: i.bottom
});
}, l = a(c);
return l?.observe(e), l?.observe(t), s?.addEventListener("resize", c), c(), {
measure: c,
dispose() {
o || (o = !0, l?.disconnect(), s?.removeEventListener("resize", c));
}
};
}
//#endregion
//#region src/layout/resolve-snap-points.ts
function G(e) {
return [
e.viewportHeight,
e.contentHeight,
e.safeAreaTop,
e.safeAreaBottom
].every((e) => Number.isFinite(e) && e >= 0) && e.viewportHeight > e.safeAreaTop + e.safeAreaBottom;
}
function oe(e, t, n) {
if (e === "content") return t.contentHeight;
if (typeof e == "number") return e > 0 && e <= 1 ? e * n : null;
let r = /^(-?(?:\d+\.?\d*|\.\d+))(px|%)$/.exec(e);
if (!r) return null;
let i = Number(r[1]);
return !Number.isFinite(i) || i <= 0 ? null : r[2] === "%" ? i / 100 * n : i;
}
function se(e, t) {
if (!G(t)) return {
snapPoints: [],
diagnostics: [{ code: "invalid-measurements" }]
};
let n = t.viewportHeight - t.safeAreaTop - t.safeAreaBottom, r = /* @__PURE__ */ new Set(), i = [], a = [];
for (let o of e) {
if (r.has(o.id)) {
a.push({
code: "duplicate-id",
id: o.id
});
continue;
}
r.add(o.id);
let e = oe(o.value, t, n);
if (e === null) {
a.push({
code: "invalid-value",
id: o.id,
value: o.value
});
continue;
}
let s = Math.min(e, n);
i.push({
id: o.id,
position: t.viewportHeight - t.safeAreaBottom - s
});
}
return i.sort((e, t) => e.position - t.position), {
snapPoints: i,
diagnostics: a
};
}
//#endregion
//#region src/hooks/use-sheet-layout.ts
function ce({ viewport: e, content: t, snapPoints: n, onLayout: r }) {
s(() => {
if (e && t) return W({
viewport: e,
content: t,
onChange(e) {
let t = se(n, e);
t.snapPoints.length !== 0 && r({
viewportHeight: e.viewportHeight,
closedPosition: e.viewportHeight - e.safeAreaBottom,
snapPoints: t.snapPoints
});
}
}).dispose;
}, [
t,
r,
n,
e
]);
}
//#endregion
//#region src/hooks/use-sheet-motion.ts
function K(e) {
return Math.min(1, Math.max(0, e));
}
function q(e, t, n, r, i = e === "opening" ? 0 : 1) {
if (n === r) return e === "closing" ? 0 : 1;
let a = K((t - n) / (r - n));
return K(i + ((e === "closing" ? 0 : 1) - i) * a);
}
function le({ controller: e, state: t, closedPosition: n, reducedMotion: r, adapter: i, getPosition: a, onUpdate: o, getBackdropProgress: c, onBackdropProgress: l }) {
s(() => {
if (![
"opening",
"settling",
"closing"
].includes(t.phase)) return;
let s = a(), u = t.phase === "closing" ? n : t.targetPosition, d = c(), f = i.start({
from: s,
to: u,
velocity: t.velocity,
reducedMotion: r,
onUpdate(e) {
o(e), l(q(t.phase, e, s, u, d));
},
onComplete: () => e.dispatch({
type: "SETTLED",
position: u
})
});
return () => f.stop();
}, [
i,
n,
e,
a,
c,
l,
o,
r,
t
]);
}
//#endregion
//#region node_modules/motion-utils/dist/es/clamp.mjs
var J = (e, t, n) => n > t ? t : n < e ? e : n;
//#endregion
//#region node_modules/motion-utils/dist/es/format-error-message.mjs
function Y(e, t) {
return t ? `${e}. For more information and steps for solving, visit https://motion.dev/troubleshooting/${t}` : e;
}
//#endregion
//#region node_modules/motion-utils/dist/es/errors.mjs
var X = () => {};
typeof process < "u" && process.env.NODE_ENV !== "production" && (X = (e, t, n) => {
!e && typeof console < "u" && console.warn(Y(t, n));
});
//#endregion
//#region node_modules/motion-utils/dist/es/time-conversion.mjs
var Z = /* @__NO_SIDE_EFFECTS__ */ (e) => e * 1e3, Q = /* @__NO_SIDE_EFFECTS__ */ (e) => e / 1e3, ue = (e, t, n = 10) => {
let r = "", i = Math.max(Math.round(t / n), 2);
for (let t = 0; t < i; t++) r += Math.round(e(t / (i - 1)) * 1e4) / 1e4 + ", ";
return `linear(${r.substring(0, r.length - 2)})`;
}, de = 2e4;
function fe(e, t = 50, n = de, r) {
let i = 0, a = e.next(i);
for (r?.push(a.value); !a.done && i < n;) i += t, a = e.next(i), r?.push(a.value);
return i >= n ? Infinity : i;
}
//#endregion
//#region node_modules/motion-dom/dist/es/animation/generators/utils/create-generator-easing.mjs
function pe(e, t = 100, n) {
let r = n({
...e,
keyframes: [0, t]
}), i = Math.min(fe(r), de);
return {
type: "keyframes",
ease: (e) => r.next(i * e).value / t,
duration: /* @__PURE__ */ Q(i)
};
}
//#endregion
//#region node_modules/motion-dom/dist/es/animation/generators/spring.mjs
var $ = {
stiffness: 100,
damping: 10,
mass: 1,
velocity: 0,
duration: 800,
bounce: .3,
visualDuration: .3,
restSpeed: {
granular: .01,
default: 2
},
restDelta: {
granular: .005,
default: .5
},
minDuration: .01,
maxDuration: 10,
minDamping: .05,
maxDamping: 1
};
function me(e, t) {
return e * Math.sqrt(1 - t * t);
}
var he = 12;
function ge(e, t, n) {
let r = n;
for (let n = 1; n < he; n++) r -= e(r) / t(r);
return r;
}
var _e = .001;
function ve({ duration: e = $.duration, bounce: t = $.bounce, velocity: n = $.velocity, mass: r = $.mass }) {
let i, a;
X(e <= /* @__PURE__ */ Z($.maxDuration), "Spring duration must be 10 seconds or less", "spring-duration-limit");
let o = 1 - t;
o = J($.minDamping, $.maxDamping, o), e = J($.minDuration, $.maxDuration, /* @__PURE__ */ Q(e)), o < 1 ? (i = (t) => {
let r = t * o, i = r * e, a = r - n, s = me(t, o), c = Math.exp(-i);
return _e - a / s * c;
}, a = (t) => {
let r = t * o * e, a = r * n + n, s = o * o * t * t * e, c = Math.exp(-r), l = me(t * t, o);
return (-i(t) + _e > 0 ? -1 : 1) * ((a - s) * c) / l;
}) : (i = (t) => -.001 + Math.exp(-t * e) * ((t - n) * e + 1), a = (t) => Math.exp(-t * e) * ((n - t) * (e * e)));
let s = 5 / e, c = ge(i, a, s);
if (e = /* @__PURE__ */ Z(e), isNaN(c)) return {
stiffness: $.stiffness,
damping: $.damping,
duration: e
};
{
let t = c * c * r;
return {
stiffness: t,
damping: o * 2 * Math.sqrt(r * t),
duration: e
};
}
}
var ye = ["duration", "bounce"], be = [
"stiffness",
"damping",
"mass"
];
function xe(e, t) {
return t.some((t) => e[t] !== void 0);
}
function Se(e) {
let t = {
velocity: $.velocity,
stiffness: $.stiffness,
damping: $.damping,
mass: $.mass,
isResolvedFromDuration: !1,
...e
};
if (!xe(e, be) && xe(e, ye)) {
if (t.velocity = 0, e.visualDuration) {
let n = e.visualDuration, r = 2 * Math.PI / (n * 1.2), i = r * r, a = 2 * J(.05, 1, 1 - (e.bounce || 0)) * Math.sqrt(i);
t = {
...t,
mass: $.mass,
stiffness: i,
damping: a
};
} else {
let n = ve({
...e,
velocity: 0
});
t = {
...t,
...n,
mass: $.mass
}, t.isResolvedFromDuration = !0;
}
}
return t;
}
function Ce(e = $.visualDuration, t = $.bounce) {
let n = typeof e == "object" ? e : {
visualDuration: e,
keyframes: [0, 1],
bounce: t
}, { restSpeed: r, restDelta: i } = n, a = n.keyframes[0], o = n.keyframes[n.keyframes.length - 1], s = {
done: !1,
value: a
}, { stiffness: c, damping: l, mass: u, duration: d, velocity: f, isResolvedFromDuration: p } = Se({
...n,
velocity: -/* @__PURE__ */ Q(n.velocity || 0)
}), m = f || 0, h = l / (2 * Math.sqrt(c * u)), g = o - a, _ = /* @__PURE__ */ Q(Math.sqrt(c / u)), v = h * _, y = Math.abs(g) < 5;
r ||= y ? $.restSpeed.granular : $.restSpeed.default, i ||= y ? $.restDelta.granular : $.restDelta.default;
let b, x;
if (h < 1) {
let e = me(_, h), t = (m + v * g) / e, n = v * t + g * e, r = v * g - t * e, i = -1, a = 0, s = 0, c = (c) => {
if (c !== i) {
i = c;
let l = Math.exp(-v * c), u = Math.sin(e * c), d = Math.cos(e * c);
a = o - l * (t * u + g * d), s = l * (n * u + r * d);
}
};
b = (e) => (c(e), a), x = (e) => (c(e), s);
} else if (h === 1) {
b = (e) => o - Math.exp(-_ * e) * (g + (m + _ * g) * e);
let e = m + _ * g;
x = (t) => Math.exp(-_ * t) * (_ * e * t - m);
} else {
let e = _ * Math.sqrt(h * h - 1);
b = (t) => {
let n = Math.exp(-v * t), r = Math.min(e * t, 300);
return o - n * ((m + v * g) * Math.sinh(r) + e * g * Math.cosh(r)) / e;
};
let t = (m + v * g) / e, n = v * t - g * e, r = v * g - t * e;
x = (t) => {
let i = Math.exp(-v * t), a = Math.min(e * t, 300);
return i * (n * Math.sinh(a) + r * Math.cosh(a));
};
}
let S = {
calculatedDuration: p && d || null,
velocity: (e) => /* @__PURE__ */ Z(x(e)),
next: (e) => {
let t = b(e);
if (p) s.done = e >= d;
else {
let n = /* @__PURE__ */ Z(x(e));
s.done = Math.abs(n) <= r && Math.abs(o - t) <= i;
}
return s.value = s.done ? o : t, s;
},
toString: () => {
let e = Math.min(fe(S), de), t = ue((t) => S.next(e * t).value, e, 30);
return e + "ms " + t;
},
toTransition: () => {}
};
return S;
}
Ce.applyToOptions = (e) => {
let t = pe(e, 100, Ce);
return e.ease = t.ease, e.duration = /* @__PURE__ */ Z(t.duration), e.type = "keyframes", e;
};
//#endregion
//#region src/motion/motion-adapter.ts
var we = (e, t, n) => {
let r = Ce({
keyframes: [e, t],
velocity: n.velocity,
stiffness: n.stiffness,
damping: n.damping
}), i = fe(r), a = performance.now(), o = !1, s, c = (e) => {
if (o) return;
a = Math.min(a, e);
let l = Math.round(e - a), u = l >= i;
n.onUpdate(u ? t : r.next(l).value), !o && (u ? queueMicrotask(() => {
o || (o = !0, n.onComplete());
}) : s = requestAnimationFrame(c));
};
return s = requestAnimationFrame(c), { stop() {
o = !0, cancelAnimationFrame(s);
} };
};
function Te(e = we) {
return { start(t) {
if (t.reducedMotion) return t.onUpdate(t.to), t.onComplete(), { stop() {} };
let n = e(t.from, t.to, {
type: "spring",
velocity: t.velocity * 1e3,
stiffness: 380,
damping: 38,
onUpdate: t.onUpdate,
onComplete: t.onComplete
});
return { stop: () => n.stop() };
} };
}
var Ee = Te(), De = [{
id: "content",
value: "content"
}];
function Oe({ children: e, open: t, defaultOpen: n, onOpenChange: r, snapPoints: i = De, activeSnapPoint: o, defaultSnapPoint: c, onSnapPointChange: m, modal: h = !0, dismissible: g = !0 }) {
let [_, v] = d(n ?? !1), [b, x] = d(), [S, C] = d(), [w, T] = d(null), [E, ee] = d(null), [D, O] = d(null), [k, A] = d(c ?? i[0]?.id), j = u(null);
j.current ||= P();
let M = j.current, N = f(M.subscribe, M.getState, M.getState), F = u(D), I = u(N.position), L = u(null), R = u(0);
F.current = D, N.phase === "closed" && (I.current = N.position);
let z = t ?? _, ne = z || N.phase !== "closed", re = z && N.phase === "closed" ? "open" : N.phase, B = t !== void 0, V = o ?? k, ie = te();
s(() => {
process.env.NODE_ENV !== "production" && t !== void 0 && n !== void 0 && console.warn("Sheet.Root cannot use both open and defaultOpen; open takes precedence.");
}, [t, n]);
let H = a((e, t) => {
e !== z && (B || v(e), r?.(e, { reason: t }));
}, [
B,
r,
z
]), U = a((e) => (x(e), () => x((t) => t === e ? void 0 : t)), []), W = a((e) => (C(e), () => C((t) => t === e ? void 0 : t)), []), G = a((e) => {
I.current = e, E?.style.setProperty("--rsbs-position", `${e}px`);
}, [E]), oe = a(() => I.current, []), se = a((e) => {
R.current = e, L.current?.style.setProperty("--rsbs-backdrop-progress", String(e)), E?.style.setProperty("--rsbs-surface-progress", String(e));
}, [E]), K = a(() => R.current, []), q = a((e) => {
L.current = e, e?.style.setProperty("--rsbs-backdrop-progress", String(R.current));
}, []);
ce({
viewport: w,
content: E,
snapPoints: i,
onLayout: a((e) => {
F.current = e, O(e), M.dispatch({
type: "LAYOUT_CHANGED",
layout: e
});
}, [M])
}), s(() => {
let e = M.getState(), t = F.current;
if (z && t) {
let n = t.snapPoints.find(({ id: e }) => e === V) ?? t.snapPoints[0];
n && (e.phase === "closed" || e.phase === "closing" || e.phase === "open" && e.activeSnapPoint !== n.id) && M.dispatch({
type: "OPEN_REQUESTED",
reason: "imperative",
snapPoint: n.id,
targetPosition: n.position
});
} else !z && !["closed", "closing"].includes(e.phase) && M.dispatch({
type: "CLOSE_REQUESTED",
reason: "imperative"
});
}, [
V,
M,
D,
z
]), le({
controller: M,
state: N,
closedPosition: D?.closedPosition ?? N.position,
reducedMotion: ie,
adapter: Ee,
getPosition: oe,
onUpdate: G,
getBackdropProgress: K,
onBackdropProgress: se
});
let J = a((e) => {
o === void 0 && A(e), m?.(e);
}, [o, m]), Y = ae({
content: E,
controller: M,
state: N,
layout: D,
dismissible: g,
onDismiss: a(() => {
H(!1, "drag");
}, [H]),
onSnapPointChange: J,
onPositionChange: G
}), X = l(() => ({
open: z,
present: ne,
transitionPhase: re,
modal: h,
dismissible: g,
titleId: b,
descriptionId: S,
requestOpenChange: H,
registerTitle: U,
registerDescription: W,
registerViewport: T,
registerContent: ee,
registerBackdrop: q,
interactionHandlers: Y,
position: I.current,
surfaceProgress: R.current,
dragging: N.phase === "dragging"
}), [
S,
g,
h,
z,
ne,
re,
N.phase,
N.position,
Y,
W,
q,
U,
H,
ee,
T,
b
]);
return /* @__PURE__ */ p(y.Provider, {
value: X,
children: e
});
}
//#endregion
//#region src/components/Title.tsx
var ke = r(function({ asChild: e = !1, children: t, className: n, id: r, ...i }, a) {
let o = c(), l = r ?? o, { registerTitle: u } = b("Sheet.Title");
s(() => u(l), [l, u]);
let d = {
...i,
id: l,
className: ["rsbs-title", n].filter(Boolean).join(" "),
"data-rsbs-title": ""
};
return p(e ? v : "h2", {
...d,
ref: a,
children: t
});
}), Ae = r(function({ asChild: e = !1, children: t, className: n, onClick: r, type: i = "button", ...a }, o) {
let { open: s, requestOpenChange: c } = b("Sheet.Trigger"), l = {
...a,
className: ["rsbs-trigger", n].filter(Boolean).join(" "),
"aria-expanded": s,
"data-rsbs-trigger": "",
onClick: (e) => {
r?.(e), e.defaultPrevented || c(!0, "trigger");
}
};
return e ? /* @__PURE__ */ p(v, {
...l,
ref: o,
children: t
}) : /* @__PURE__ */ p("button", {
...l,
ref: o,
type: i,
children: t
});
}), je = r(function({ asChild: e = !1, children: t, className: n, ...r }, i) {
let { registerViewport: a, transitionPhase: o } = b("Sheet.Viewport"), s = {
...r,
className: ["rsbs-viewport", n].filter(Boolean).join(" "),
"data-rsbs-viewport": "",
"data-rsbs-state": o
};
return e ? /* @__PURE__ */ p(v, {
...s,
ref: _(a, i),
children: t
}) : /* @__PURE__ */ p("div", {
...s,
ref: _(i, (e) => a(e)),
children: t
});
}), Me = r(function({ asChild: e = !1, children: t, className: n, ...r }, i) {
let a = {
...r,
className: ["rsbs-handle", n].filter(Boolean).join(" "),
"data-rsbs-handle": ""
};
return p(e ? v : "div", {
...a,
ref: i,
children: t
});
});
//#endregion
//#region src/components/Portal.tsx
function Ne({ children: e, container: t }) {
let { present: n } = b("Sheet.Portal"), [r, i] = d(!1);
return s(() => (i(!0), () => i(!1)), []), !r || !n ? null : h(e, t ?? document.body);
}
//#endregion
//#region src/components/Sheet.ts
var Pe = {
Root: Oe,
Trigger: Ae,
Portal: Ne,
Backdrop: x,
Viewport: je,
Content: D,
Handle: Me,
Title: ke,
Description: O,
Close: S
};
//#endregion
//#region src/components/BottomSheet.tsx
function Fe({ backdropProps: e, children: t, contentProps: n, description: r, title: i, viewportProps: a, ...o }) {
return /* @__PURE__ */ p(Oe, {
...o,
children: /* @__PURE__ */ m(Ne, { children: [/* @__PURE__ */ p(x, { ...e }), /* @__PURE__ */ p(je, {
...a,
children: /* @__PURE__ */ m(D, {
...n,
children: [
/* @__PURE__ */ p(Me, {}),
/* @__PURE__ */ p(ke, { children: i }),
r === void 0 ? null : /* @__PURE__ */ p(O, { children: r }),
t
]
})
})] })
});
}
//#endregion
export { Fe as BottomSheet, Pe as Sheet };
//# sourceMappingURL=index.js.map