@syscore/ui-library 1.17.0 → 1.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client/components/ui/mobile-nav.tsx +93 -62
- package/client/global.css +56 -6
- package/client/ui/MobileNav.stories.tsx +106 -84
- package/dist/index.cjs.js +1 -1
- package/dist/index.es.js +77 -51
- package/package.json +1 -1
package/dist/index.es.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
2
2
|
import * as React from "react";
|
|
3
|
-
import React__default, { useState, useEffect, useCallback, useRef, createContext, useMemo, useContext } from "react";
|
|
3
|
+
import React__default, { useState, useEffect, useCallback, useRef, createContext, useMemo, useLayoutEffect, useContext } from "react";
|
|
4
4
|
import { motion, AnimatePresence, useMotionValue, animate } from "motion/react";
|
|
5
5
|
import { clsx } from "clsx";
|
|
6
6
|
import { twMerge } from "tailwind-merge";
|
|
@@ -12410,10 +12410,7 @@ const MobileNavPanel = ({ className, children }) => {
|
|
|
12410
12410
|
return (nav == null ? void 0 : nav.offsetHeight) ?? 0;
|
|
12411
12411
|
};
|
|
12412
12412
|
const getAvailableHeight = () => {
|
|
12413
|
-
|
|
12414
|
-
const parent = (_a = panelRef.current) == null ? void 0 : _a.parentElement;
|
|
12415
|
-
const container = (parent == null ? void 0 : parent.clientHeight) ?? window.innerHeight;
|
|
12416
|
-
return container - getNavBarHeight();
|
|
12413
|
+
return window.innerHeight - getNavBarHeight();
|
|
12417
12414
|
};
|
|
12418
12415
|
const measureContentHeight = () => {
|
|
12419
12416
|
const content = contentRef.current;
|
|
@@ -12432,67 +12429,94 @@ const MobileNavPanel = ({ className, children }) => {
|
|
|
12432
12429
|
});
|
|
12433
12430
|
stopAnimation.current = () => controls.stop();
|
|
12434
12431
|
};
|
|
12435
|
-
|
|
12436
|
-
let cancelled = false;
|
|
12432
|
+
useLayoutEffect(() => {
|
|
12437
12433
|
if (open) {
|
|
12438
12434
|
stateRef.current = "initial";
|
|
12439
|
-
|
|
12440
|
-
|
|
12441
|
-
|
|
12442
|
-
cachedInitialHeight.current = h;
|
|
12443
|
-
springTo(h);
|
|
12444
|
-
});
|
|
12435
|
+
const h = measureContentHeight();
|
|
12436
|
+
cachedInitialHeight.current = h;
|
|
12437
|
+
springTo(h);
|
|
12445
12438
|
} else {
|
|
12446
12439
|
stateRef.current = "closed";
|
|
12447
12440
|
cachedInitialHeight.current = 0;
|
|
12448
12441
|
springTo(0);
|
|
12449
12442
|
}
|
|
12450
|
-
return () => {
|
|
12451
|
-
cancelled = true;
|
|
12452
|
-
};
|
|
12453
12443
|
}, [open]);
|
|
12444
|
+
useLayoutEffect(() => {
|
|
12445
|
+
if (!open) return;
|
|
12446
|
+
const h = measureContentHeight();
|
|
12447
|
+
cachedInitialHeight.current = h;
|
|
12448
|
+
if (stateRef.current !== "full") {
|
|
12449
|
+
stateRef.current = "initial";
|
|
12450
|
+
springTo(h);
|
|
12451
|
+
}
|
|
12452
|
+
}, [activeKey]);
|
|
12454
12453
|
useEffect(() => {
|
|
12455
12454
|
if (!open) return;
|
|
12456
|
-
|
|
12457
|
-
|
|
12458
|
-
requestAnimationFrame(() => {
|
|
12459
|
-
if (cancelled) return;
|
|
12460
|
-
const h = measureContentHeight();
|
|
12461
|
-
cachedInitialHeight.current = h;
|
|
12462
|
-
if (stateRef.current === "initial" || stateRef.current === "closed") {
|
|
12463
|
-
stateRef.current = "initial";
|
|
12464
|
-
springTo(h);
|
|
12465
|
-
}
|
|
12466
|
-
});
|
|
12467
|
-
});
|
|
12468
|
-
return () => {
|
|
12469
|
-
cancelled = true;
|
|
12455
|
+
const handleKeyDown = (e) => {
|
|
12456
|
+
if (e.key === "Escape") close();
|
|
12470
12457
|
};
|
|
12471
|
-
|
|
12472
|
-
|
|
12473
|
-
|
|
12474
|
-
|
|
12458
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
12459
|
+
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
12460
|
+
}, [open, close]);
|
|
12461
|
+
const isDragging = useRef(false);
|
|
12462
|
+
const lastY = useRef(0);
|
|
12463
|
+
const dragStartY = useRef(0);
|
|
12464
|
+
const dragStartTime = useRef(0);
|
|
12465
|
+
const dragMaxHeight = useRef(0);
|
|
12466
|
+
const handlePointerDown = (e) => {
|
|
12467
|
+
var _a;
|
|
12468
|
+
e.currentTarget.setPointerCapture(e.pointerId);
|
|
12469
|
+
(_a = stopAnimation.current) == null ? void 0 : _a.call(stopAnimation);
|
|
12470
|
+
isDragging.current = true;
|
|
12471
|
+
lastY.current = e.clientY;
|
|
12472
|
+
dragStartY.current = e.clientY;
|
|
12473
|
+
dragStartTime.current = Date.now();
|
|
12474
|
+
dragMaxHeight.current = getAvailableHeight();
|
|
12475
12475
|
};
|
|
12476
|
-
const
|
|
12477
|
-
|
|
12476
|
+
const handlePointerMove = (e) => {
|
|
12477
|
+
if (!isDragging.current) return;
|
|
12478
|
+
const dy = e.clientY - lastY.current;
|
|
12479
|
+
lastY.current = e.clientY;
|
|
12480
|
+
const current = heightMV.get();
|
|
12481
|
+
const next = Math.max(0, current - dy);
|
|
12482
|
+
heightMV.set(Math.min(next, dragMaxHeight.current));
|
|
12478
12483
|
};
|
|
12479
|
-
const
|
|
12480
|
-
|
|
12481
|
-
|
|
12482
|
-
|
|
12483
|
-
|
|
12484
|
-
|
|
12485
|
-
|
|
12486
|
-
|
|
12487
|
-
|
|
12484
|
+
const handlePointerUp = (e) => {
|
|
12485
|
+
if (!isDragging.current) return;
|
|
12486
|
+
isDragging.current = false;
|
|
12487
|
+
const currentHeight = heightMV.get();
|
|
12488
|
+
const initial = cachedInitialHeight.current;
|
|
12489
|
+
const full = dragMaxHeight.current;
|
|
12490
|
+
const elapsed = Date.now() - dragStartTime.current;
|
|
12491
|
+
const totalDy = e.clientY - dragStartY.current;
|
|
12492
|
+
const velocity = elapsed > 0 ? totalDy / elapsed * 1e3 : 0;
|
|
12493
|
+
const VELOCITY_THRESHOLD = 500;
|
|
12494
|
+
if (velocity > VELOCITY_THRESHOLD) {
|
|
12488
12495
|
if (stateRef.current === "full") {
|
|
12489
12496
|
stateRef.current = "initial";
|
|
12490
|
-
springTo(
|
|
12491
|
-
} else
|
|
12497
|
+
springTo(initial);
|
|
12498
|
+
} else {
|
|
12492
12499
|
stateRef.current = "closed";
|
|
12493
12500
|
springTo(0);
|
|
12494
12501
|
close();
|
|
12495
12502
|
}
|
|
12503
|
+
} else if (velocity < -VELOCITY_THRESHOLD) {
|
|
12504
|
+
stateRef.current = "full";
|
|
12505
|
+
springTo(full);
|
|
12506
|
+
} else {
|
|
12507
|
+
const midInitial = initial / 2;
|
|
12508
|
+
const midFull = (initial + full) / 2;
|
|
12509
|
+
if (currentHeight < midInitial) {
|
|
12510
|
+
stateRef.current = "closed";
|
|
12511
|
+
springTo(0);
|
|
12512
|
+
close();
|
|
12513
|
+
} else if (currentHeight < midFull) {
|
|
12514
|
+
stateRef.current = "initial";
|
|
12515
|
+
springTo(initial);
|
|
12516
|
+
} else {
|
|
12517
|
+
stateRef.current = "full";
|
|
12518
|
+
springTo(full);
|
|
12519
|
+
}
|
|
12496
12520
|
}
|
|
12497
12521
|
};
|
|
12498
12522
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
@@ -12506,12 +12530,13 @@ const MobileNavPanel = ({ className, children }) => {
|
|
|
12506
12530
|
style: { height: heightMV },
|
|
12507
12531
|
children: [
|
|
12508
12532
|
/* @__PURE__ */ jsx(
|
|
12509
|
-
|
|
12533
|
+
"div",
|
|
12510
12534
|
{
|
|
12511
12535
|
className: "mobile-nav-handle",
|
|
12512
|
-
|
|
12513
|
-
|
|
12514
|
-
|
|
12536
|
+
onPointerDown: handlePointerDown,
|
|
12537
|
+
onPointerMove: handlePointerMove,
|
|
12538
|
+
onPointerUp: handlePointerUp,
|
|
12539
|
+
onPointerCancel: handlePointerUp,
|
|
12515
12540
|
children: /* @__PURE__ */ jsx("div", { className: "mobile-nav-handle-bar" })
|
|
12516
12541
|
}
|
|
12517
12542
|
),
|
|
@@ -12545,6 +12570,7 @@ const MobileNavTrigger = ({
|
|
|
12545
12570
|
onClick: handleClick,
|
|
12546
12571
|
disabled,
|
|
12547
12572
|
"data-active": activeKey === value || void 0,
|
|
12573
|
+
"aria-expanded": activeKey === value && open,
|
|
12548
12574
|
className: cn("mobile-nav-trigger group", className),
|
|
12549
12575
|
"aria-label": label,
|
|
12550
12576
|
children
|