@stanfordspezi/spezi-web-design-system
Version:
Stanford Biodesign Digital Health Spezi Web Design System
606 lines (605 loc) • 19.9 kB
JavaScript
import { jsx as h, jsxs as $, Fragment as ae } from "react/jsx-runtime";
import { c as j } from "./index-2NvaPZWc.mjs";
import * as c from "react";
import "react-dom";
import { c as se, u as A } from "./index-D2LZVjSn.mjs";
import { P as I } from "./index-DlW0DMEl.mjs";
import { c as ie } from "./index-DFZozV_h.mjs";
import { u as C } from "./index-0ioNhtNM.mjs";
import { u as de } from "./index-ByaXH_ih.mjs";
import { c as R, u as ue } from "./index-hURUNS5V.mjs";
function fe(e, [o, r]) {
return Math.min(r, Math.max(o, e));
}
var he = [
"a",
"button",
"div",
"form",
"h2",
"h3",
"img",
"input",
"label",
"li",
"nav",
"ol",
"p",
"select",
"span",
"svg",
"ul"
], L = he.reduce((e, o) => {
const r = se(`Primitive.${o}`), n = c.forwardRef((t, l) => {
const { asChild: a, ...s } = t, i = a ? r : o;
return typeof window < "u" && (window[/* @__PURE__ */ Symbol.for("radix-ui")] = !0), /* @__PURE__ */ h(i, { ...s, ref: l });
});
return n.displayName = `Primitive.${o}`, { ...e, [o]: n };
}, {});
function be(e, o) {
return c.useReducer((r, n) => o[r][n] ?? r, e);
}
var V = "ScrollArea", [q] = ie(V), [me, v] = q(V), G = c.forwardRef(
(e, o) => {
const {
__scopeScrollArea: r,
type: n = "hover",
dir: t,
scrollHideDelay: l = 600,
...a
} = e, [s, i] = c.useState(null), [f, d] = c.useState(null), [b, u] = c.useState(null), [m, w] = c.useState(null), [y, Y] = c.useState(null), [P, _] = c.useState(0), [U, D] = c.useState(0), [N, x] = c.useState(!1), [W, H] = c.useState(!1), S = A(o, (E) => i(E)), p = de(t);
return /* @__PURE__ */ h(
me,
{
scope: r,
type: n,
dir: p,
scrollHideDelay: l,
scrollArea: s,
viewport: f,
onViewportChange: d,
content: b,
onContentChange: u,
scrollbarX: m,
onScrollbarXChange: w,
scrollbarXEnabled: N,
onScrollbarXEnabledChange: x,
scrollbarY: y,
onScrollbarYChange: Y,
scrollbarYEnabled: W,
onScrollbarYEnabledChange: H,
onCornerWidthChange: _,
onCornerHeightChange: D,
children: /* @__PURE__ */ h(
L.div,
{
dir: p,
...a,
ref: S,
style: {
position: "relative",
// Pass corner sizes as CSS vars to reduce re-renders of context consumers
"--radix-scroll-area-corner-width": P + "px",
"--radix-scroll-area-corner-height": U + "px",
...e.style
}
}
)
}
);
}
);
G.displayName = V;
var J = "ScrollAreaViewport", K = c.forwardRef(
(e, o) => {
const { __scopeScrollArea: r, children: n, nonce: t, ...l } = e, a = v(J, r), s = c.useRef(null), i = A(o, s, a.onViewportChange);
return /* @__PURE__ */ $(ae, { children: [
/* @__PURE__ */ h(
"style",
{
dangerouslySetInnerHTML: {
__html: "[data-radix-scroll-area-viewport]{scrollbar-width:none;-ms-overflow-style:none;-webkit-overflow-scrolling:touch;}[data-radix-scroll-area-viewport]::-webkit-scrollbar{display:none}"
},
nonce: t
}
),
/* @__PURE__ */ h(
L.div,
{
"data-radix-scroll-area-viewport": "",
...l,
ref: i,
style: {
/**
* We don't support `visible` because the intention is to have at least one scrollbar
* if this component is used and `visible` will behave like `auto` in that case
* https://developer.mozilla.org/en-US/docs/Web/CSS/overflow#description
*
* We don't handle `auto` because the intention is for the native implementation
* to be hidden if using this component. We just want to ensure the node is scrollable
* so could have used either `scroll` or `auto` here. We picked `scroll` to prevent
* the browser from having to work out whether to render native scrollbars or not,
* we tell it to with the intention of hiding them in CSS.
*/
overflowX: a.scrollbarXEnabled ? "scroll" : "hidden",
overflowY: a.scrollbarYEnabled ? "scroll" : "hidden",
...e.style
},
children: /* @__PURE__ */ h("div", { ref: a.onContentChange, style: { minWidth: "100%", display: "table" }, children: n })
}
)
] });
}
);
K.displayName = J;
var g = "ScrollAreaScrollbar", Q = c.forwardRef(
(e, o) => {
const { forceMount: r, ...n } = e, t = v(g, e.__scopeScrollArea), { onScrollbarXEnabledChange: l, onScrollbarYEnabledChange: a } = t, s = e.orientation === "horizontal";
return c.useEffect(() => (s ? l(!0) : a(!0), () => {
s ? l(!1) : a(!1);
}), [s, l, a]), t.type === "hover" ? /* @__PURE__ */ h(Se, { ...n, ref: o, forceMount: r }) : t.type === "scroll" ? /* @__PURE__ */ h(ve, { ...n, ref: o, forceMount: r }) : t.type === "auto" ? /* @__PURE__ */ h(Z, { ...n, ref: o, forceMount: r }) : t.type === "always" ? /* @__PURE__ */ h(B, { ...n, ref: o }) : null;
}
);
Q.displayName = g;
var Se = c.forwardRef((e, o) => {
const { forceMount: r, ...n } = e, t = v(g, e.__scopeScrollArea), [l, a] = c.useState(!1);
return c.useEffect(() => {
const s = t.scrollArea;
let i = 0;
if (s) {
const f = () => {
window.clearTimeout(i), a(!0);
}, d = () => {
i = window.setTimeout(() => a(!1), t.scrollHideDelay);
};
return s.addEventListener("pointerenter", f), s.addEventListener("pointerleave", d), () => {
window.clearTimeout(i), s.removeEventListener("pointerenter", f), s.removeEventListener("pointerleave", d);
};
}
}, [t.scrollArea, t.scrollHideDelay]), /* @__PURE__ */ h(I, { present: r || l, children: /* @__PURE__ */ h(
Z,
{
"data-state": l ? "visible" : "hidden",
...n,
ref: o
}
) });
}), ve = c.forwardRef((e, o) => {
const { forceMount: r, ...n } = e, t = v(g, e.__scopeScrollArea), l = e.orientation === "horizontal", a = X(() => i("SCROLL_END"), 100), [s, i] = be("hidden", {
hidden: {
SCROLL: "scrolling"
},
scrolling: {
SCROLL_END: "idle",
POINTER_ENTER: "interacting"
},
interacting: {
SCROLL: "interacting",
POINTER_LEAVE: "idle"
},
idle: {
HIDE: "hidden",
SCROLL: "scrolling",
POINTER_ENTER: "interacting"
}
});
return c.useEffect(() => {
if (s === "idle") {
const f = window.setTimeout(() => i("HIDE"), t.scrollHideDelay);
return () => window.clearTimeout(f);
}
}, [s, t.scrollHideDelay, i]), c.useEffect(() => {
const f = t.viewport, d = l ? "scrollLeft" : "scrollTop";
if (f) {
let b = f[d];
const u = () => {
const m = f[d];
b !== m && (i("SCROLL"), a()), b = m;
};
return f.addEventListener("scroll", u), () => f.removeEventListener("scroll", u);
}
}, [t.viewport, l, i, a]), /* @__PURE__ */ h(I, { present: r || s !== "hidden", children: /* @__PURE__ */ h(
B,
{
"data-state": s === "hidden" ? "hidden" : "visible",
...n,
ref: o,
onPointerEnter: R(e.onPointerEnter, () => i("POINTER_ENTER")),
onPointerLeave: R(e.onPointerLeave, () => i("POINTER_LEAVE"))
}
) });
}), Z = c.forwardRef((e, o) => {
const r = v(g, e.__scopeScrollArea), { forceMount: n, ...t } = e, [l, a] = c.useState(!1), s = e.orientation === "horizontal", i = X(() => {
if (r.viewport) {
const f = r.viewport.offsetWidth < r.viewport.scrollWidth, d = r.viewport.offsetHeight < r.viewport.scrollHeight;
a(s ? f : d);
}
}, 10);
return T(r.viewport, i), T(r.content, i), /* @__PURE__ */ h(I, { present: n || l, children: /* @__PURE__ */ h(
B,
{
"data-state": l ? "visible" : "hidden",
...t,
ref: o
}
) });
}), B = c.forwardRef((e, o) => {
const { orientation: r = "vertical", ...n } = e, t = v(g, e.__scopeScrollArea), l = c.useRef(null), a = c.useRef(0), [s, i] = c.useState({
content: 0,
viewport: 0,
scrollbar: { size: 0, paddingStart: 0, paddingEnd: 0 }
}), f = ne(s.viewport, s.content), d = {
...n,
sizes: s,
onSizesChange: i,
hasThumb: f > 0 && f < 1,
onThumbChange: (u) => l.current = u,
onThumbPointerUp: () => a.current = 0,
onThumbPointerDown: (u) => a.current = u
};
function b(u, m) {
return Re(u, a.current, s, m);
}
return r === "horizontal" ? /* @__PURE__ */ h(
pe,
{
...d,
ref: o,
onThumbPositionChange: () => {
if (t.viewport && l.current) {
const u = t.viewport.scrollLeft, m = F(u, s, t.dir);
l.current.style.transform = `translate3d(${m}px, 0, 0)`;
}
},
onWheelScroll: (u) => {
t.viewport && (t.viewport.scrollLeft = u);
},
onDragScroll: (u) => {
t.viewport && (t.viewport.scrollLeft = b(u, t.dir));
}
}
) : r === "vertical" ? /* @__PURE__ */ h(
we,
{
...d,
ref: o,
onThumbPositionChange: () => {
if (t.viewport && l.current) {
const u = t.viewport.scrollTop, m = F(u, s);
l.current.style.transform = `translate3d(0, ${m}px, 0)`;
}
},
onWheelScroll: (u) => {
t.viewport && (t.viewport.scrollTop = u);
},
onDragScroll: (u) => {
t.viewport && (t.viewport.scrollTop = b(u));
}
}
) : null;
}), pe = c.forwardRef((e, o) => {
const { sizes: r, onSizesChange: n, ...t } = e, l = v(g, e.__scopeScrollArea), [a, s] = c.useState(), i = c.useRef(null), f = A(o, i, l.onScrollbarXChange);
return c.useEffect(() => {
i.current && s(getComputedStyle(i.current));
}, [i]), /* @__PURE__ */ h(
re,
{
"data-orientation": "horizontal",
...t,
ref: f,
sizes: r,
style: {
bottom: 0,
left: l.dir === "rtl" ? "var(--radix-scroll-area-corner-width)" : 0,
right: l.dir === "ltr" ? "var(--radix-scroll-area-corner-width)" : 0,
"--radix-scroll-area-thumb-width": M(r) + "px",
...e.style
},
onThumbPointerDown: (d) => e.onThumbPointerDown(d.x),
onDragScroll: (d) => e.onDragScroll(d.x),
onWheelScroll: (d, b) => {
if (l.viewport) {
const u = l.viewport.scrollLeft + d.deltaX;
e.onWheelScroll(u), ce(u, b) && d.preventDefault();
}
},
onResize: () => {
i.current && l.viewport && a && n({
content: l.viewport.scrollWidth,
viewport: l.viewport.offsetWidth,
scrollbar: {
size: i.current.clientWidth,
paddingStart: O(a.paddingLeft),
paddingEnd: O(a.paddingRight)
}
});
}
}
);
}), we = c.forwardRef((e, o) => {
const { sizes: r, onSizesChange: n, ...t } = e, l = v(g, e.__scopeScrollArea), [a, s] = c.useState(), i = c.useRef(null), f = A(o, i, l.onScrollbarYChange);
return c.useEffect(() => {
i.current && s(getComputedStyle(i.current));
}, [i]), /* @__PURE__ */ h(
re,
{
"data-orientation": "vertical",
...t,
ref: f,
sizes: r,
style: {
top: 0,
right: l.dir === "ltr" ? 0 : void 0,
left: l.dir === "rtl" ? 0 : void 0,
bottom: "var(--radix-scroll-area-corner-height)",
"--radix-scroll-area-thumb-height": M(r) + "px",
...e.style
},
onThumbPointerDown: (d) => e.onThumbPointerDown(d.y),
onDragScroll: (d) => e.onDragScroll(d.y),
onWheelScroll: (d, b) => {
if (l.viewport) {
const u = l.viewport.scrollTop + d.deltaY;
e.onWheelScroll(u), ce(u, b) && d.preventDefault();
}
},
onResize: () => {
i.current && l.viewport && a && n({
content: l.viewport.scrollHeight,
viewport: l.viewport.offsetHeight,
scrollbar: {
size: i.current.clientHeight,
paddingStart: O(a.paddingTop),
paddingEnd: O(a.paddingBottom)
}
});
}
}
);
}), [ge, ee] = q(g), re = c.forwardRef((e, o) => {
const {
__scopeScrollArea: r,
sizes: n,
hasThumb: t,
onThumbChange: l,
onThumbPointerUp: a,
onThumbPointerDown: s,
onThumbPositionChange: i,
onDragScroll: f,
onWheelScroll: d,
onResize: b,
...u
} = e, m = v(g, r), [w, y] = c.useState(null), Y = A(o, (S) => y(S)), P = c.useRef(null), _ = c.useRef(""), U = m.viewport, D = n.content - n.viewport, N = C(d), x = C(i), W = X(b, 10);
function H(S) {
if (P.current) {
const p = S.clientX - P.current.left, E = S.clientY - P.current.top;
f({ x: p, y: E });
}
}
return c.useEffect(() => {
const S = (p) => {
const E = p.target;
w?.contains(E) && N(p, D);
};
return document.addEventListener("wheel", S, { passive: !1 }), () => document.removeEventListener("wheel", S, { passive: !1 });
}, [U, w, D, N]), c.useEffect(x, [n, x]), T(w, W), T(m.content, W), /* @__PURE__ */ h(
ge,
{
scope: r,
scrollbar: w,
hasThumb: t,
onThumbChange: C(l),
onThumbPointerUp: C(a),
onThumbPositionChange: x,
onThumbPointerDown: C(s),
children: /* @__PURE__ */ h(
L.div,
{
...u,
ref: Y,
style: { position: "absolute", ...u.style },
onPointerDown: R(e.onPointerDown, (S) => {
S.button === 0 && (S.target.setPointerCapture(S.pointerId), P.current = w.getBoundingClientRect(), _.current = document.body.style.webkitUserSelect, document.body.style.webkitUserSelect = "none", m.viewport && (m.viewport.style.scrollBehavior = "auto"), H(S));
}),
onPointerMove: R(e.onPointerMove, H),
onPointerUp: R(e.onPointerUp, (S) => {
const p = S.target;
p.hasPointerCapture(S.pointerId) && p.releasePointerCapture(S.pointerId), document.body.style.webkitUserSelect = _.current, m.viewport && (m.viewport.style.scrollBehavior = ""), P.current = null;
})
}
)
}
);
}), z = "ScrollAreaThumb", oe = c.forwardRef(
(e, o) => {
const { forceMount: r, ...n } = e, t = ee(z, e.__scopeScrollArea);
return /* @__PURE__ */ h(I, { present: r || t.hasThumb, children: /* @__PURE__ */ h(Pe, { ref: o, ...n }) });
}
), Pe = c.forwardRef(
(e, o) => {
const { __scopeScrollArea: r, style: n, ...t } = e, l = v(z, r), a = ee(z, r), { onThumbPositionChange: s } = a, i = A(
o,
(b) => a.onThumbChange(b)
), f = c.useRef(void 0), d = X(() => {
f.current && (f.current(), f.current = void 0);
}, 100);
return c.useEffect(() => {
const b = l.viewport;
if (b) {
const u = () => {
if (d(), !f.current) {
const m = Ee(b, s);
f.current = m, s();
}
};
return s(), b.addEventListener("scroll", u), () => b.removeEventListener("scroll", u);
}
}, [l.viewport, d, s]), /* @__PURE__ */ h(
L.div,
{
"data-state": a.hasThumb ? "visible" : "hidden",
...t,
ref: i,
style: {
width: "var(--radix-scroll-area-thumb-width)",
height: "var(--radix-scroll-area-thumb-height)",
...n
},
onPointerDownCapture: R(e.onPointerDownCapture, (b) => {
const m = b.target.getBoundingClientRect(), w = b.clientX - m.left, y = b.clientY - m.top;
a.onThumbPointerDown({ x: w, y });
}),
onPointerUp: R(e.onPointerUp, a.onThumbPointerUp)
}
);
}
);
oe.displayName = z;
var k = "ScrollAreaCorner", te = c.forwardRef(
(e, o) => {
const r = v(k, e.__scopeScrollArea), n = !!(r.scrollbarX && r.scrollbarY);
return r.type !== "scroll" && n ? /* @__PURE__ */ h(Ce, { ...e, ref: o }) : null;
}
);
te.displayName = k;
var Ce = c.forwardRef((e, o) => {
const { __scopeScrollArea: r, ...n } = e, t = v(k, r), [l, a] = c.useState(0), [s, i] = c.useState(0), f = !!(l && s);
return T(t.scrollbarX, () => {
const d = t.scrollbarX?.offsetHeight || 0;
t.onCornerHeightChange(d), i(d);
}), T(t.scrollbarY, () => {
const d = t.scrollbarY?.offsetWidth || 0;
t.onCornerWidthChange(d), a(d);
}), f ? /* @__PURE__ */ h(
L.div,
{
...n,
ref: o,
style: {
width: l,
height: s,
position: "absolute",
right: t.dir === "ltr" ? 0 : void 0,
left: t.dir === "rtl" ? 0 : void 0,
bottom: 0,
...e.style
}
}
) : null;
});
function O(e) {
return e ? parseInt(e, 10) : 0;
}
function ne(e, o) {
const r = e / o;
return isNaN(r) ? 0 : r;
}
function M(e) {
const o = ne(e.viewport, e.content), r = e.scrollbar.paddingStart + e.scrollbar.paddingEnd, n = (e.scrollbar.size - r) * o;
return Math.max(n, 18);
}
function Re(e, o, r, n = "ltr") {
const t = M(r), l = t / 2, a = o || l, s = t - a, i = r.scrollbar.paddingStart + a, f = r.scrollbar.size - r.scrollbar.paddingEnd - s, d = r.content - r.viewport, b = n === "ltr" ? [0, d] : [d * -1, 0];
return le([i, f], b)(e);
}
function F(e, o, r = "ltr") {
const n = M(o), t = o.scrollbar.paddingStart + o.scrollbar.paddingEnd, l = o.scrollbar.size - t, a = o.content - o.viewport, s = l - n, i = r === "ltr" ? [0, a] : [a * -1, 0], f = fe(e, i);
return le([0, a], [0, s])(f);
}
function le(e, o) {
return (r) => {
if (e[0] === e[1] || o[0] === o[1]) return o[0];
const n = (o[1] - o[0]) / (e[1] - e[0]);
return o[0] + n * (r - e[0]);
};
}
function ce(e, o) {
return e > 0 && e < o;
}
var Ee = (e, o = () => {
}) => {
let r = { left: e.scrollLeft, top: e.scrollTop }, n = 0;
return (function t() {
const l = { left: e.scrollLeft, top: e.scrollTop }, a = r.left !== l.left, s = r.top !== l.top;
(a || s) && o(), r = l, n = window.requestAnimationFrame(t);
})(), () => window.cancelAnimationFrame(n);
};
function X(e, o) {
const r = C(e), n = c.useRef(0);
return c.useEffect(() => () => window.clearTimeout(n.current), []), c.useCallback(() => {
window.clearTimeout(n.current), n.current = window.setTimeout(r, o);
}, [r, o]);
}
function T(e, o) {
const r = C(o);
ue(() => {
let n = 0;
if (e) {
const t = new ResizeObserver(() => {
cancelAnimationFrame(n), n = window.requestAnimationFrame(r);
});
return t.observe(e), () => {
window.cancelAnimationFrame(n), t.unobserve(e);
};
}
}, [e, r]);
}
var Te = G, Ae = K, ye = te;
const Xe = ({
scrollViewRef: e,
className: o,
children: r,
onScroll: n,
...t
}) => /* @__PURE__ */ $(
Te,
{
"data-testid": "scroll-area",
"data-slot": "scroll-area",
className: j("relative", o),
...t,
children: [
/* @__PURE__ */ h(
Ae,
{
ref: e,
"data-testid": "scroll-area-viewport",
"data-slot": "scroll-area-viewport",
className: "focus-ring size-full rounded-[inherit] transition focus-visible:ring-2",
onScroll: n,
children: r
}
),
/* @__PURE__ */ h(xe, {}),
/* @__PURE__ */ h(ye, {})
]
}
), xe = ({
className: e,
orientation: o = "vertical",
...r
}) => /* @__PURE__ */ h(
Q,
{
"data-testid": "scroll-area-scrollbar",
"data-slot": "scroll-area-scrollbar",
orientation: o,
className: j(
"flex touch-none p-px transition select-none",
o === "vertical" ? "h-full w-2.5 border-l border-l-transparent" : "h-2.5 flex-col border-t border-t-transparent",
e
),
...r,
children: /* @__PURE__ */ h(
oe,
{
"data-slot": "scroll-area-thumb",
className: "bg-border relative flex-1 rounded-full"
}
)
}
);
export {
Xe as S,
xe as a
};