T45c Site · Home: a route change ends the glide, full screen holds against the wheel, each skip control focuses its own target
This commit is contained in:
2 files changed
+14
-7
No files matched your search
@@ -14,6 +14,7 @@ export function Live({ page, story, title }: { page: string; story: string; titl
|
|||||||
const [state, setState] = useState<State>("starting");
|
const [state, setState] = useState<State>("starting");
|
||||||
const [full, setFull] = useState(false);
|
const [full, setFull] = useState(false);
|
||||||
const [run, setRun] = useState(0);
|
const [run, setRun] = useState(0);
|
||||||
|
const after = useRef<HTMLSpanElement>(null);
|
||||||
// Each new frame opens in the current mode.
|
// Each new frame opens in the current mode.
|
||||||
const start = useMemo(() => mode(), [run]);
|
const start = useMemo(() => mode(), [run]);
|
||||||
const src = (t: string) => `/gallery/?page=${page}&story=${story}&theme=${t}`;
|
const src = (t: string) => `/gallery/?page=${page}&story=${story}&theme=${t}`;
|
||||||
@@ -57,10 +58,10 @@ export function Live({ page, story, title }: { page: string; story: string; titl
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<a className="skip-live" href="#after-live">
|
<button className="skip-live" onClick={() => after.current?.focus()}>
|
||||||
Skip the live example
|
Skip the live example
|
||||||
</a>
|
</button>
|
||||||
<div className={full ? "live full" : "live"}>
|
<div className={full ? "live full" : "live"} data-lenis-prevent={full || undefined}>
|
||||||
<iframe key={run} ref={frame} title={`${title}, live`} src={src(start)} />
|
<iframe key={run} ref={frame} title={`${title}, live`} src={src(start)} />
|
||||||
{state !== "ready" && (
|
{state !== "ready" && (
|
||||||
<div className="live-state" role="status">
|
<div className="live-state" role="status">
|
||||||
@@ -89,7 +90,7 @@ export function Live({ page, story, title }: { page: string; story: string; titl
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<span id="after-live" tabIndex={-1} />
|
<span ref={after} tabIndex={-1} />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Link, Outlet } from "@tanstack/react-router";
|
import { Link, Outlet, useRouter } from "@tanstack/react-router";
|
||||||
import Lenis from "lenis";
|
import Lenis from "lenis";
|
||||||
import "lenis/dist/lenis.css";
|
import "lenis/dist/lenis.css";
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
@@ -58,11 +58,17 @@ function Footer() {
|
|||||||
|
|
||||||
export function Shell() {
|
export function Shell() {
|
||||||
const still = useStill();
|
const still = useStill();
|
||||||
|
const router = useRouter();
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (still) return;
|
if (still) return;
|
||||||
const lenis = new Lenis({ autoRaf: true });
|
const lenis = new Lenis({ autoRaf: true });
|
||||||
return () => lenis.destroy();
|
// A glide in flight must not outlive its page.
|
||||||
}, [still]);
|
const off = router.subscribe("onBeforeNavigate", () => lenis.scrollTo(lenis.animatedScroll, { immediate: true, force: true }));
|
||||||
|
return () => {
|
||||||
|
off();
|
||||||
|
lenis.destroy();
|
||||||
|
};
|
||||||
|
}, [still, router]);
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<a className="skip" href="#main">
|
<a className="skip" href="#main">
|
||||||
|
|||||||
Reference in new issue
Block a user