fix left skeleton

This commit is contained in:
Michael Freno
2025-12-22 19:12:12 -05:00
parent a9c9ae023c
commit 87168a42ed
6 changed files with 57 additions and 84 deletions

View File

@@ -229,7 +229,6 @@ body {
color: var(--color-text); color: var(--color-text);
transition: background-color 500ms ease-in-out; transition: background-color 500ms ease-in-out;
} }
[data-typewriter="animated"] [data-char-index] { [data-typewriter="animated"] [data-char-index] {
opacity: 0; opacity: 0;
} }
@@ -238,54 +237,6 @@ body {
transition: opacity 0.05s ease-in; transition: opacity 0.05s ease-in;
} }
.bg-base.relative.h-screen {
width: 100vw;
margin-left: 0;
}
@media (min-width: 768px) {
.bg-base.relative.h-screen {
width: calc(100vw - 600px);
margin-left: 300px;
}
}
@media (max-width: 767px) {
nav.fixed.z-50[class*="border-r-2"] {
/* Left sidebar starts off-screen on mobile */
transform: translateX(-100%);
}
}
/* Note: JS will add inline styles and reactive classList that override these defaults */
/* Blog banner fallbacks - similar to main layout */
.blog-banner-image {
/* Full width by default on mobile */
width: 100vw;
margin-left: 0;
}
.blog-banner-text {
/* Full width by default on mobile */
width: 100vw;
margin-left: 0;
}
@media (min-width: 768px) {
.blog-banner-image {
/* Account for sidebars on desktop */
width: calc(100vw - 600px);
margin-left: 300px;
}
.blog-banner-text {
/* Account for sidebars on desktop */
width: calc(100vw - 600px);
margin-left: 300px;
}
}
.cursor-typing { .cursor-typing {
display: inline-block; display: inline-block;
width: 2px; width: 2px;
@@ -302,6 +253,13 @@ body {
vertical-align: text-bottom; vertical-align: text-bottom;
animation: blink 1s infinite; animation: blink 1s infinite;
margin-left: 2px; margin-left: 2px;
position: absolute;
}
@media (max-width: 767px) {
.cursor-block {
position: relative;
}
} }
@keyframes blink { @keyframes blink {

View File

@@ -5,7 +5,9 @@ import {
ErrorBoundary, ErrorBoundary,
onMount, onMount,
onCleanup, onCleanup,
Suspense Suspense,
Show,
createSignal
} from "solid-js"; } from "solid-js";
import "./app.css"; import "./app.css";
import { LeftBar, RightBar } from "./components/Bars"; import { LeftBar, RightBar } from "./components/Bars";
@@ -32,8 +34,12 @@ function AppLayout(props: { children: any }) {
let lastScrollY = 0; let lastScrollY = 0;
const SCROLL_THRESHOLD = 75; const SCROLL_THRESHOLD = 75;
// Track if we're on the client (hydrated) - starts false on server
const [isClient, setIsClient] = createSignal(false);
// Use onMount to avoid hydration issues - window operations are client-only // Use onMount to avoid hydration issues - window operations are client-only
onMount(() => { onMount(() => {
setIsClient(true);
const windowWidth = createWindowWidth(); const windowWidth = createWindowWidth();
createEffect(() => { createEffect(() => {
@@ -188,30 +194,37 @@ function AppLayout(props: { children: any }) {
<> <>
<div class="flex max-w-screen flex-row"> <div class="flex max-w-screen flex-row">
<LeftBar /> <LeftBar />
<div <Show
class="bg-base relative h-screen overflow-x-hidden overflow-y-scroll" when={!isClient() || barsInitialized()}
style={ fallback={<TerminalSplash />}
barsInitialized()
? {
width: `${centerWidth()}px`,
"margin-left": `${leftBarSize()}px`
}
: undefined
}
> >
<noscript>
<div class="bg-yellow text-crust border-text fixed top-0 z-150 ml-16 border-b-2 p-4 text-center font-semibold md:ml-64">
JavaScript is disabled. Features will be limited.
</div>
</noscript>
<div <div
class="py-16" class="bg-base relative h-screen overflow-x-hidden overflow-y-scroll"
onMouseUp={handleCenterTapRelease} style={
onTouchEnd={handleCenterTapRelease} barsInitialized()
? {
width: `${centerWidth()}px`,
"margin-left": `${leftBarSize()}px`
}
: { width: "calc(100vw - 600px)", "margin-left": "300px" }
}
> >
<Suspense fallback={<TerminalSplash />}>{props.children}</Suspense> <noscript>
<div class="bg-yellow text-crust border-text fixed top-0 z-150 ml-16 border-b-2 p-4 text-center font-semibold md:ml-64">
JavaScript is disabled. Features will be limited.
</div>
</noscript>
<div
class="py-16"
onMouseUp={handleCenterTapRelease}
onTouchEnd={handleCenterTapRelease}
>
<Suspense fallback={<TerminalSplash />}>
{props.children}
</Suspense>
</div>
</div> </div>
</div> </Show>
<RightBar /> <RightBar />
</div> </div>
</> </>

View File

@@ -319,7 +319,7 @@ export function LeftBar() {
"translate-x-0": leftBarVisible() "translate-x-0": leftBarVisible()
}} }}
style={{ style={{
"transition-timing-function": "cubic-bezier(0.4, 0, 0.2, 1)", // Smooth for both revealing and hiding "transition-timing-function": "cubic-bezier(0.4, 0, 0.2, 1)",
"min-width": leftBarSize() > 0 ? `${leftBarSize()}px` : undefined, "min-width": leftBarSize() > 0 ? `${leftBarSize()}px` : undefined,
"box-shadow": "inset -6px 0 16px -6px rgba(0, 0, 0, 0.1)", "box-shadow": "inset -6px 0 16px -6px rgba(0, 0, 0, 0.1)",
"padding-top": "env(safe-area-inset-top)", "padding-top": "env(safe-area-inset-top)",
@@ -371,15 +371,15 @@ export function LeftBar() {
fallback={ fallback={
<For each={[1, 2, 3]}> <For each={[1, 2, 3]}>
{() => ( {() => (
<div class="flex flex-col"> <div class="flex w-52 flex-col">
<div class="flex items-start gap-2"> <div class="relative overflow-hidden">
<div class="flex flex-1 flex-col gap-2"> <SkeletonBox class="float-right ml-2 h-12 w-16" />
<SkeletonText class="h-6 w-full" /> <div class="flex flex-col">
<SkeletonText class="h-6 w-full" /> <SkeletonText class="h-6 w-full" />
<SkeletonText class="mt-1.5 h-6 w-2/3" />
</div> </div>
<SkeletonBox class="h-14 w-16 shrink-0" />
</div> </div>
<SkeletonText class="mt-2 h-6 w-full" /> <SkeletonText class="mt-1.5 h-6 w-1/2" />
</div> </div>
)} )}
</For> </For>
@@ -390,7 +390,7 @@ export function LeftBar() {
<a <a
href={`/blog/${post.title}`} href={`/blog/${post.title}`}
onClick={handleLinkClick} onClick={handleLinkClick}
class="hover:text-subtext0 block transition-transform duration-200 ease-in-out hover:-translate-y-0.5 hover:scale-105 hover:font-bold" class="hover:text-subtext0 block w-52 transition-transform duration-200 ease-in-out hover:-translate-y-0.5 hover:scale-105 hover:font-bold"
> >
<Typewriter class="flex flex-col" keepAlive={false}> <Typewriter class="flex flex-col" keepAlive={false}>
<div class="relative overflow-hidden"> <div class="relative overflow-hidden">

View File

@@ -1,4 +1,3 @@
import { JSX } from "solid-js";
import { Spinner } from "~/components/Spinner"; import { Spinner } from "~/components/Spinner";
interface SkeletonProps { interface SkeletonProps {
@@ -8,7 +7,7 @@ interface SkeletonProps {
export function SkeletonBox(props: SkeletonProps) { export function SkeletonBox(props: SkeletonProps) {
return ( return (
<div <div
class={`bg-surface0 text-overlay0 flex items-center justify-center rounded ${props.class || ""}`} class={`bg-surface0 flex items-center justify-center rounded ${props.class || ""}`}
aria-label="Loading..." aria-label="Loading..."
role="status" role="status"
> >
@@ -20,7 +19,7 @@ export function SkeletonBox(props: SkeletonProps) {
export function SkeletonText(props: SkeletonProps) { export function SkeletonText(props: SkeletonProps) {
return ( return (
<div <div
class={`bg-surface0 text-overlay0 inline-flex h-4 items-center rounded px-2 ${props.class || ""}`} class={`bg-surface0 inline-flex items-center rounded px-2 pt-1 ${props.class || ""}`}
aria-label="Loading..." aria-label="Loading..."
role="status" role="status"
> >
@@ -32,7 +31,7 @@ export function SkeletonText(props: SkeletonProps) {
export function SkeletonCircle(props: SkeletonProps) { export function SkeletonCircle(props: SkeletonProps) {
return ( return (
<div <div
class={`bg-surface0 text-overlay0 flex items-center justify-center rounded-full ${props.class || ""}`} class={`bg-surface0 flex items-center justify-center rounded-full ${props.class || ""}`}
aria-label="Loading..." aria-label="Loading..."
role="status" role="status"
> >

View File

@@ -47,7 +47,7 @@ export function Spinner(props: SpinnerProps) {
return ( return (
<span <span
class={`font-mono ${sizeClass()} ${props.class || ""}`} class={`text-overlay2 font-mono ${sizeClass()} ${props.class || ""}`}
style={style()} style={style()}
aria-label={props["aria-label"] || "Loading..."} aria-label={props["aria-label"] || "Loading..."}
role="status" role="status"

View File

@@ -35,7 +35,10 @@ export default function Home() {
> >
LÖVE LÖVE
</a>{" "} </a>{" "}
(an open source game engine for Lua). You can see some of my work{" "} (an open source game engine for Lua).{" "}
</Typewriter>{" "}
<Typewriter speed={100} keepAlive={2000}>
You can see some of my work{" "}
<a <a
href="https://github.com/mikefreno" href="https://github.com/mikefreno"
class="text-blue hover-underline-animation" class="text-blue hover-underline-animation"