13 Commits

14 changed files with 1277 additions and 1063 deletions
+3
View File
@@ -10,6 +10,9 @@ node_modules
/build /build
/dist /dist
# IDE settings
.vscode
# Git worktrees (isolated development branches) # Git worktrees (isolated development branches)
.worktrees .worktrees
+4 -5
View File
@@ -13,7 +13,7 @@
"https://plugins.dprint.dev/typescript-0.93.0.wasm", "https://plugins.dprint.dev/typescript-0.93.0.wasm",
"https://plugins.dprint.dev/json-0.19.3.wasm", "https://plugins.dprint.dev/json-0.19.3.wasm",
"https://plugins.dprint.dev/markdown-0.17.8.wasm", "https://plugins.dprint.dev/markdown-0.17.8.wasm",
"https://plugins.dprint.dev/g-plane/markup_fmt-v0.25.3.wasm" "https://plugins.dprint.dev/g-plane/markup_fmt-v0.27.0.wasm"
], ],
"typescript": { "typescript": {
"lineWidth": 120, "lineWidth": 120,
@@ -57,9 +57,8 @@
"quotes": "double", "quotes": "double",
"scriptIndent": false, "scriptIndent": false,
"styleIndent": false, "styleIndent": false,
"formatComments": true,
"vBindStyle": "short", "svelteAttrShorthand": true,
"vOnStyle": "short", "svelteDirectiveShorthand": true
"formatComments": true
} }
} }
+33 -33
View File
@@ -27,45 +27,45 @@
"build-storybook": "storybook build" "build-storybook": "storybook build"
}, },
"devDependencies": { "devDependencies": {
"@chromatic-com/storybook": "^4.1.3", "@chromatic-com/storybook": "5.1.2",
"@internationalized/date": "^3.10.0", "@internationalized/date": "3.12.1",
"@lucide/svelte": "^0.561.0", "@lucide/svelte": "^1.14.0",
"@playwright/test": "^1.57.0", "@playwright/test": "1.59.1",
"@storybook/addon-a11y": "^10.1.11", "@storybook/addon-a11y": "10.3.6",
"@storybook/addon-docs": "^10.1.11", "@storybook/addon-docs": "10.3.6",
"@storybook/addon-svelte-csf": "^5.0.10", "@storybook/addon-svelte-csf": "5.1.2",
"@storybook/addon-vitest": "^10.1.11", "@storybook/addon-vitest": "10.3.6",
"@storybook/svelte-vite": "^10.1.11", "@storybook/svelte-vite": "10.3.6",
"@sveltejs/vite-plugin-svelte": "^6.2.1", "@sveltejs/vite-plugin-svelte": "7.1.0",
"@tailwindcss/vite": "^4.1.18", "@tailwindcss/vite": "4.2.4",
"@testing-library/jest-dom": "^6.9.1", "@testing-library/jest-dom": "^6.9.1",
"@testing-library/svelte": "^5.3.1", "@testing-library/svelte": "^5.3.1",
"@tsconfig/svelte": "^5.0.6", "@tsconfig/svelte": "5.0.8",
"@types/jsdom": "^27", "@types/jsdom": "28.0.1",
"@vitest/browser-playwright": "^4.0.16", "@vitest/browser-playwright": "4.1.5",
"@vitest/coverage-v8": "^4.0.16", "@vitest/coverage-v8": "4.1.5",
"bits-ui": "^2.14.4", "bits-ui": "2.18.1",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"dprint": "^0.50.2", "dprint": "0.54.0",
"jsdom": "^27.4.0", "jsdom": "29.1.1",
"lefthook": "^2.0.13", "lefthook": "2.1.6",
"oxlint": "^1.35.0", "oxlint": "1.62.0",
"playwright": "^1.57.0", "playwright": "1.59.1",
"storybook": "^10.1.11", "storybook": "10.3.6",
"svelte": "^5.45.6", "svelte": "5.55.5",
"svelte-check": "^4.3.4", "svelte-check": "4.4.8",
"svelte-language-server": "^0.17.23", "svelte-language-server": "0.18.0",
"tailwind-merge": "^3.4.0", "tailwind-merge": "3.5.0",
"tailwind-variants": "^3.2.2", "tailwind-variants": "^3.2.2",
"tailwindcss": "^4.1.18", "tailwindcss": "4.2.4",
"tw-animate-css": "^1.4.0", "tw-animate-css": "^1.4.0",
"typescript": "^5.9.3", "typescript": "6.0.3",
"vite": "^7.2.6", "vite": "8.0.10",
"vitest": "^4.0.16", "vitest": "4.1.5",
"vitest-browser-svelte": "^2.0.1" "vitest-browser-svelte": "2.1.1"
}, },
"dependencies": { "dependencies": {
"@chenglou/pretext": "^0.0.5", "@chenglou/pretext": "0.0.6",
"@tanstack/svelte-query": "^6.0.14" "@tanstack/svelte-query": "6.1.28"
} }
} }
+2
View File
@@ -36,6 +36,8 @@ declare module '*.jpg' {
export default content; export default content;
} }
declare module '*.css';
/// <reference types="vite/client" /> /// <reference types="vite/client" />
interface ImportMetaEnv { interface ImportMetaEnv {
@@ -20,6 +20,7 @@ let mockObserverInstances: MockIntersectionObserver[] = [];
class MockIntersectionObserver implements IntersectionObserver { class MockIntersectionObserver implements IntersectionObserver {
root = null; root = null;
rootMargin = ''; rootMargin = '';
scrollMargin = '';
thresholds: number[] = []; thresholds: number[] = [];
readonly callbacks: Array<(entries: IntersectionObserverEntry[], observer: IntersectionObserver) => void> = []; readonly callbacks: Array<(entries: IntersectionObserverEntry[], observer: IntersectionObserver) => void> = [];
readonly observedElements = new Set<Element>(); readonly observedElements = new Set<Element>();
@@ -2,9 +2,7 @@
* Yields to main thread during CPU-intensive parsing. Uses scheduler.yield() where available or MessageChannel fallback. * Yields to main thread during CPU-intensive parsing. Uses scheduler.yield() where available or MessageChannel fallback.
*/ */
export async function yieldToMainThread(): Promise<void> { export async function yieldToMainThread(): Promise<void> {
// @ts-expect-error - scheduler not in TypeScript lib yet
if (typeof scheduler !== 'undefined' && 'yield' in scheduler) { if (typeof scheduler !== 'undefined' && 'yield' in scheduler) {
// @ts-expect-error - scheduler.yield not in TypeScript lib yet
await scheduler.yield(); await scheduler.yield();
} else { } else {
await new Promise<void>(resolve => { await new Promise<void>(resolve => {
@@ -106,7 +106,7 @@ let selected = $state(false);
<div class="flex items-center gap-4"> <div class="flex items-center gap-4">
<ToggleButton <ToggleButton
{...args} {...args}
selected={selected} {selected}
onclick={() => { onclick={() => {
selected = !selected; selected = !selected;
}} }}
+5 -5
View File
@@ -26,11 +26,11 @@ const { children, class: className, render }: Props = $props();
{#if render} {#if render}
{@render render({ {@render render({
class: cn( class: cn(
'font-mono text-3xs sm:text-2xs lowercase tracking-wider-mono text-text-soft', 'font-mono text-3xs sm:text-2xs lowercase tracking-wider-mono text-text-soft',
className, className,
), ),
})} })}
{:else if children} {:else if children}
<span <span
class={cn( class={cn(
+1 -1
View File
@@ -93,7 +93,7 @@ const flyParams: FlyParams = {
> >
<div> <div>
{#if headerTitle} {#if headerTitle}
<SectionHeader title={headerTitle} subtitle={headerSubtitle} index={index} /> <SectionHeader title={headerTitle} subtitle={headerSubtitle} {index} />
{/if} {/if}
<SectionTitle text={title} /> <SectionTitle text={title} />
</div> </div>
+12 -12
View File
@@ -288,24 +288,24 @@ $effect(() => {
> >
{#if itemIndex < items.length} {#if itemIndex < items.length}
{@render children({ {@render children({
item: items[itemIndex], item: items[itemIndex],
index: itemIndex, index: itemIndex,
isFullyVisible: row.isFullyVisible, isFullyVisible: row.isFullyVisible,
isPartiallyVisible: row.isPartiallyVisible, isPartiallyVisible: row.isPartiallyVisible,
proximity: row.proximity, proximity: row.proximity,
})} })}
{/if} {/if}
</div> </div>
{:else} {:else}
<div class="min-h-0"> <div class="min-h-0">
{#if itemIndex < items.length} {#if itemIndex < items.length}
{@render children({ {@render children({
item: items[itemIndex], item: items[itemIndex],
index: itemIndex, index: itemIndex,
isFullyVisible: row.isFullyVisible, isFullyVisible: row.isFullyVisible,
isPartiallyVisible: row.isPartiallyVisible, isPartiallyVisible: row.isPartiallyVisible,
proximity: row.proximity, proximity: row.proximity,
})} })}
{/if} {/if}
</div> </div>
{/if} {/if}
@@ -101,6 +101,7 @@ function isFontReady(font: UnifiedFont): boolean {
data-font-list data-font-list
weight={DEFAULT_FONT_WEIGHT} weight={DEFAULT_FONT_WEIGHT}
itemHeight={44} itemHeight={44}
gap={2}
class="bg-transparent min-h-0 h-full scroll-stable py-2 pl-6 pr-4" class="bg-transparent min-h-0 h-full scroll-stable py-2 pl-6 pr-4"
> >
{#snippet skeleton()} {#snippet skeleton()}
+1 -1
View File
@@ -22,7 +22,7 @@ const currentYear = new Date().getFullYear();
> >
<!-- Project Name (Horizontal) --> <!-- Project Name (Horizontal) -->
{#if isVertical} {#if isVertical}
<div class="pointer-events-auto items-center gap-2 bg-surface/80 dark:bg-dark-bg/80 backdrop-blur-sm px-3 py-1 border border-subtle"> <div class="flex flex-row pointer-events-auto items-center gap-2 bg-surface/80 dark:bg-dark-bg/80 backdrop-blur-sm px-2 py-1 border border-subtle">
<div class="w-1.5 h-1.5 bg-brand"></div> <div class="w-1.5 h-1.5 bg-brand"></div>
<span class="text-2xs font-mono uppercase tracking-wider-mono text-neutral-500 dark:text-neutral-400"> <span class="text-2xs font-mono uppercase tracking-wider-mono text-neutral-500 dark:text-neutral-400">
GlyphDiff © 2025 — {currentYear} GlyphDiff © 2025 — {currentYear}
+1 -1
View File
@@ -1,6 +1,7 @@
{ {
"extends": "@tsconfig/svelte/tsconfig.json", "extends": "@tsconfig/svelte/tsconfig.json",
"compilerOptions": { "compilerOptions": {
"rootDir": ".",
"module": "ESNext", "module": "ESNext",
"moduleResolution": "bundler", "moduleResolution": "bundler",
"target": "ESNext", "target": "ESNext",
@@ -22,7 +23,6 @@
"verbatimModuleSyntax": true, "verbatimModuleSyntax": true,
/* Path Aliases */ /* Path Aliases */
"baseUrl": ".",
"paths": { "paths": {
"$lib/*": ["./src/lib/*"], "$lib/*": ["./src/lib/*"],
"$app/*": ["./src/app/*"], "$app/*": ["./src/app/*"],
+1212 -1002
View File
File diff suppressed because it is too large Load Diff