feature/comparison-slider #19

Merged
ilia merged 129 commits from feature/comparison-slider into main 2026-02-02 09:23:46 +00:00
7 changed files with 117 additions and 36 deletions
Showing only changes of commit cf08f7adfa - Show all commits

View File

@@ -15,5 +15,5 @@ export { filterManager } from './model/state/manager.svelte';
export { export {
FilterControls, FilterControls,
Filters, Filters,
FontSearch, SuggestedFonts,
} from './ui'; } from './ui';

View File

@@ -1,33 +0,0 @@
<!--
Component: FontSearch
Combines search input with font list display
-->
<script lang="ts">
import { fontshareStore } from '$entities/Font';
import { SearchBar } from '$shared/ui';
import { onMount } from 'svelte';
import { mapManagerToParams } from '../../lib';
import { filterManager } from '../../model';
import SuggestedFonts from '../SuggestedFonts/SuggestedFonts.svelte';
onMount(() => {
/**
* The Pairing:
* We "plug" this manager into the global store.
* addBinding returns a function that removes this binding when the component unmounts.
*/
const unbind = fontshareStore.addBinding(() => mapManagerToParams(filterManager));
return unbind;
});
</script>
<SearchBar
id="font-search"
class="w-full"
placeholder="Search fonts by name..."
bind:value={filterManager.queryValue}
>
<SuggestedFonts />
</SearchBar>

View File

@@ -1,9 +1,9 @@
import Filters from './Filters/Filters.svelte'; import Filters from './Filters/Filters.svelte';
import FilterControls from './FiltersControl/FilterControls.svelte'; import FilterControls from './FiltersControl/FilterControls.svelte';
import FontSearch from './FontSearch/FontSearch.svelte'; import SuggestedFonts from './SuggestedFonts/SuggestedFonts.svelte';
export { export {
FilterControls, FilterControls,
Filters, Filters,
FontSearch, SuggestedFonts,
}; };

View File

@@ -0,0 +1 @@
export { FontSearch } from './ui';

View File

@@ -0,0 +1,107 @@
<!--
Component: FontSearch
Combines search input with font list display
-->
<script lang="ts">
import { fontshareStore } from '$entities/Font';
import {
FilterControls,
Filters,
SuggestedFonts,
filterManager,
mapManagerToParams,
} from '$features/GetFonts';
import { springySlideFade } from '$shared/lib';
import { Button } from '$shared/shadcn/ui/button';
import { cn } from '$shared/shadcn/utils/shadcn-utils';
import { SearchBar } from '$shared/ui';
import FunnelIcon from '@lucide/svelte/icons/funnel';
import { onMount } from 'svelte';
import { cubicOut } from 'svelte/easing';
import {
Tween,
prefersReducedMotion,
} from 'svelte/motion';
import { type SlideParams } from 'svelte/transition';
interface Props {
showFilters?: boolean;
}
let { showFilters = $bindable(false) }: Props = $props();
onMount(() => {
/**
* The Pairing:
* We "plug" this manager into the global store.
* addBinding returns a function that removes this binding when the component unmounts.
*/
const unbind = fontshareStore.addBinding(() => mapManagerToParams(filterManager));
return unbind;
});
const transform = new Tween(
{ scale: 1, rotate: 0 },
{ duration: 250, easing: cubicOut },
);
const slideConfig = $derived<SlideParams>({
duration: prefersReducedMotion.current ? 0 : 200,
easing: cubicOut,
axis: 'y',
});
function toggleFilters() {
showFilters = !showFilters;
transform.set({ scale: 0.9, rotate: 2 }).then(() => {
transform.set({ scale: 1, rotate: 0 });
});
}
</script>
<div class="flex flex-col gap-2 relative">
<SearchBar
id="font-search"
class="w-full"
placeholder="Search fonts by name..."
bind:value={filterManager.queryValue}
>
<SuggestedFonts />
</SearchBar>
<div class="absolute right-5 top-10 translate-y-[-50%] pl-5 border-l-2">
<div style:transform="scale({transform.current.scale}) rotate({transform.current.rotate}deg)">
<Button
class={cn(
'cursor-pointer will-change-transform hover:bg-inherit hover:*:stroke-indigo-500',
showFilters ? 'hover:*:stroke-indigo-500/80' : 'hover:*:stroke-indigo-500',
)}
variant="ghost"
size="icon"
onclick={toggleFilters}
>
<FunnelIcon
class={cn(
'size-8 stroke-indigo-600/50 transition-all duration-150',
showFilters ? 'stroke-indigo-600' : 'stroke-indigo-600/50',
)}
/>
</Button>
</div>
</div>
{#if showFilters}
<div
transition:springySlideFade|local={slideConfig}
class="will-change-[height,opacity] contain-layout overflow-hidden"
>
<div class="grid gap-1 grid-cols-[repeat(auto-fit,minmax(8em,14em))]">
<Filters />
<FilterControls class="ml-auto py-1" />
</div>
</div>
{/if}
</div>

View File

@@ -0,0 +1,3 @@
import FontSearch from './FontSearch/FontSearch.svelte';
export { FontSearch };

3
src/widgets/index.ts Normal file
View File

@@ -0,0 +1,3 @@
export { ComparisonSlider } from './ComparisonSlider';
export { FontSearch } from './FontSearch';
export { TypographyMenu } from './TypographySettings';