fix left skeleton
This commit is contained in:
56
src/app.css
56
src/app.css
@@ -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 {
|
||||||
|
|||||||
19
src/app.tsx
19
src/app.tsx
@@ -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,6 +194,10 @@ function AppLayout(props: { children: any }) {
|
|||||||
<>
|
<>
|
||||||
<div class="flex max-w-screen flex-row">
|
<div class="flex max-w-screen flex-row">
|
||||||
<LeftBar />
|
<LeftBar />
|
||||||
|
<Show
|
||||||
|
when={!isClient() || barsInitialized()}
|
||||||
|
fallback={<TerminalSplash />}
|
||||||
|
>
|
||||||
<div
|
<div
|
||||||
class="bg-base relative h-screen overflow-x-hidden overflow-y-scroll"
|
class="bg-base relative h-screen overflow-x-hidden overflow-y-scroll"
|
||||||
style={
|
style={
|
||||||
@@ -196,7 +206,7 @@ function AppLayout(props: { children: any }) {
|
|||||||
width: `${centerWidth()}px`,
|
width: `${centerWidth()}px`,
|
||||||
"margin-left": `${leftBarSize()}px`
|
"margin-left": `${leftBarSize()}px`
|
||||||
}
|
}
|
||||||
: undefined
|
: { width: "calc(100vw - 600px)", "margin-left": "300px" }
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<noscript>
|
<noscript>
|
||||||
@@ -209,9 +219,12 @@ function AppLayout(props: { children: any }) {
|
|||||||
onMouseUp={handleCenterTapRelease}
|
onMouseUp={handleCenterTapRelease}
|
||||||
onTouchEnd={handleCenterTapRelease}
|
onTouchEnd={handleCenterTapRelease}
|
||||||
>
|
>
|
||||||
<Suspense fallback={<TerminalSplash />}>{props.children}</Suspense>
|
<Suspense fallback={<TerminalSplash />}>
|
||||||
|
{props.children}
|
||||||
|
</Suspense>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</Show>
|
||||||
<RightBar />
|
<RightBar />
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -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 w-52 flex-col">
|
||||||
|
<div class="relative overflow-hidden">
|
||||||
|
<SkeletonBox class="float-right ml-2 h-12 w-16" />
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
<div class="flex items-start gap-2">
|
|
||||||
<div class="flex flex-1 flex-col gap-2">
|
|
||||||
<SkeletonText class="h-6 w-full" />
|
|
||||||
<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">
|
||||||
|
|||||||
@@ -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"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
Reference in New Issue
Block a user