2026-01-30 17:46:21 +03:00
|
|
|
<!--
|
|
|
|
|
Component: Page
|
|
|
|
|
Description: The main page component of the application.
|
|
|
|
|
-->
|
2026-01-12 08:51:36 +03:00
|
|
|
<script lang="ts">
|
2026-02-02 12:21:23 +03:00
|
|
|
import { scrollBreadcrumbsStore } from '$entities/Breadcrumb';
|
2026-02-06 15:56:48 +03:00
|
|
|
import {
|
|
|
|
|
Logo,
|
|
|
|
|
Section,
|
|
|
|
|
} from '$shared/ui';
|
2026-01-26 12:54:40 +03:00
|
|
|
import ComparisonSlider from '$widgets/ComparisonSlider/ui/ComparisonSlider/ComparisonSlider.svelte';
|
2026-01-24 15:39:38 +03:00
|
|
|
import { FontSearch } from '$widgets/FontSearch';
|
2026-02-01 11:53:57 +03:00
|
|
|
import { SampleList } from '$widgets/SampleList';
|
2026-02-04 10:48:40 +03:00
|
|
|
import CodeIcon from '@lucide/svelte/icons/code';
|
2026-02-06 11:54:36 +03:00
|
|
|
import EyeIcon from '@lucide/svelte/icons/eye';
|
2026-01-30 17:46:21 +03:00
|
|
|
import LineSquiggleIcon from '@lucide/svelte/icons/line-squiggle';
|
2026-02-02 12:21:23 +03:00
|
|
|
import ScanSearchIcon from '@lucide/svelte/icons/search';
|
|
|
|
|
import type { Snippet } from 'svelte';
|
2026-02-10 13:09:09 +03:00
|
|
|
import { cubicIn } from 'svelte/easing';
|
|
|
|
|
import { fade } from 'svelte/transition';
|
2026-01-24 15:39:38 +03:00
|
|
|
|
|
|
|
|
let searchContainer: HTMLElement;
|
|
|
|
|
|
|
|
|
|
let isExpanded = $state(false);
|
2026-01-29 14:33:12 +03:00
|
|
|
|
2026-02-10 21:18:49 +03:00
|
|
|
function handleTitleStatusChanged(
|
|
|
|
|
index: number,
|
|
|
|
|
isPast: boolean,
|
|
|
|
|
title?: Snippet<[{ className?: string }]>,
|
|
|
|
|
id?: string,
|
|
|
|
|
) {
|
2026-02-02 12:21:23 +03:00
|
|
|
if (isPast && title) {
|
2026-02-10 21:18:49 +03:00
|
|
|
scrollBreadcrumbsStore.add({ index, title, id });
|
2026-02-02 12:21:23 +03:00
|
|
|
} else {
|
|
|
|
|
scrollBreadcrumbsStore.remove(index);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return () => {
|
|
|
|
|
scrollBreadcrumbsStore.remove(index);
|
|
|
|
|
};
|
|
|
|
|
}
|
2026-01-26 12:54:40 +03:00
|
|
|
|
2026-02-02 12:21:23 +03:00
|
|
|
// $effect(() => {
|
|
|
|
|
// appliedFontsManager.touch(
|
|
|
|
|
// selectedFontsStore.all.map(font => ({
|
|
|
|
|
// slug: font.id,
|
|
|
|
|
// weight: controlManager.weight,
|
|
|
|
|
// })),
|
|
|
|
|
// );
|
|
|
|
|
// });
|
2025-12-30 18:57:58 +03:00
|
|
|
</script>
|
|
|
|
|
|
2026-01-13 20:05:33 +03:00
|
|
|
<!-- Font List -->
|
2026-02-10 13:09:09 +03:00
|
|
|
<div
|
|
|
|
|
class="p-2 sm:p-3 md:p-4 h-full flex flex-col gap-3 sm:gap-4"
|
|
|
|
|
in:fade={{ duration: 500, delay: 150, easing: cubicIn }}
|
|
|
|
|
>
|
2026-02-10 21:18:49 +03:00
|
|
|
<Section class="py-4 sm:py-10 md:py-12 gap-6 sm:gap-8" onTitleStatusChange={handleTitleStatusChanged}>
|
2026-02-04 10:48:40 +03:00
|
|
|
{#snippet icon({ className })}
|
|
|
|
|
<CodeIcon class={className} />
|
|
|
|
|
{/snippet}
|
|
|
|
|
{#snippet description({ className })}
|
|
|
|
|
<span class={className}>
|
|
|
|
|
Project_Codename
|
|
|
|
|
</span>
|
|
|
|
|
{/snippet}
|
2026-02-06 15:56:48 +03:00
|
|
|
<Logo />
|
2026-02-04 10:48:40 +03:00
|
|
|
</Section>
|
2026-02-07 18:15:14 +03:00
|
|
|
|
2026-02-10 21:18:49 +03:00
|
|
|
<Section
|
|
|
|
|
class="py-4 sm:py-10 md:py-12 gap-6 sm:gap-8"
|
|
|
|
|
index={1}
|
|
|
|
|
id="optical_comparator"
|
|
|
|
|
onTitleStatusChange={handleTitleStatusChanged}
|
|
|
|
|
>
|
2026-02-07 18:15:14 +03:00
|
|
|
{#snippet icon({ className })}
|
|
|
|
|
<EyeIcon class={className} />
|
|
|
|
|
{/snippet}
|
|
|
|
|
{#snippet title({ className })}
|
|
|
|
|
<h1 class={className}>
|
|
|
|
|
Optical<br />Comparator
|
|
|
|
|
</h1>
|
|
|
|
|
{/snippet}
|
|
|
|
|
<ComparisonSlider />
|
|
|
|
|
</Section>
|
2026-02-04 10:48:40 +03:00
|
|
|
|
2026-02-10 21:18:49 +03:00
|
|
|
<Section
|
|
|
|
|
class="py-4 sm:py-10 md:py-12 gap-6 sm:gap-8"
|
|
|
|
|
index={2}
|
|
|
|
|
id="query_module"
|
|
|
|
|
onTitleStatusChange={handleTitleStatusChanged}
|
|
|
|
|
>
|
2026-02-02 12:21:23 +03:00
|
|
|
{#snippet icon({ className })}
|
|
|
|
|
<ScanSearchIcon class={className} />
|
|
|
|
|
{/snippet}
|
|
|
|
|
{#snippet title({ className })}
|
|
|
|
|
<h2 class={className}>
|
|
|
|
|
Query<br />Module
|
|
|
|
|
</h2>
|
|
|
|
|
{/snippet}
|
|
|
|
|
<FontSearch bind:showFilters={isExpanded} />
|
|
|
|
|
</Section>
|
|
|
|
|
|
2026-02-10 21:18:49 +03:00
|
|
|
<Section
|
|
|
|
|
class="py-4 sm:py-10 md:py-12 gap-6 sm:gap-8"
|
|
|
|
|
index={3}
|
|
|
|
|
id="sample_set"
|
|
|
|
|
onTitleStatusChange={handleTitleStatusChanged}
|
|
|
|
|
>
|
2026-02-01 11:53:57 +03:00
|
|
|
{#snippet icon({ className })}
|
|
|
|
|
<LineSquiggleIcon class={className} />
|
|
|
|
|
{/snippet}
|
|
|
|
|
{#snippet title({ className })}
|
|
|
|
|
<h2 class={className}>
|
2026-02-02 12:21:23 +03:00
|
|
|
Sample<br />Set
|
2026-02-01 11:53:57 +03:00
|
|
|
</h2>
|
|
|
|
|
{/snippet}
|
|
|
|
|
<SampleList />
|
|
|
|
|
</Section>
|
2026-01-18 15:01:19 +03:00
|
|
|
</div>
|
2026-01-24 15:39:38 +03:00
|
|
|
|
|
|
|
|
<style>
|
|
|
|
|
.content {
|
2026-02-02 12:21:23 +03:00
|
|
|
/* Tells the browser to skip rendering off-screen content */
|
|
|
|
|
content-visibility: auto;
|
|
|
|
|
/* Helps the browser reserve space without calculating everything */
|
|
|
|
|
contain-intrinsic-size: 1px 1000px;
|
2026-01-29 14:33:12 +03:00
|
|
|
|
2026-02-02 12:21:23 +03:00
|
|
|
-webkit-font-smoothing: antialiased;
|
|
|
|
|
-moz-osx-font-smoothing: grayscale;
|
2026-01-29 14:33:12 +03:00
|
|
|
}
|
2026-01-24 15:39:38 +03:00
|
|
|
</style>
|