chore(FontSearch): move to widgets layer
This commit is contained in:
@@ -15,5 +15,5 @@ export { filterManager } from './model/state/manager.svelte';
|
||||
export {
|
||||
FilterControls,
|
||||
Filters,
|
||||
FontSearch,
|
||||
SuggestedFonts,
|
||||
} from './ui';
|
||||
|
||||
@@ -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>
|
||||
@@ -1,9 +1,9 @@
|
||||
import Filters from './Filters/Filters.svelte';
|
||||
import FilterControls from './FiltersControl/FilterControls.svelte';
|
||||
import FontSearch from './FontSearch/FontSearch.svelte';
|
||||
import SuggestedFonts from './SuggestedFonts/SuggestedFonts.svelte';
|
||||
|
||||
export {
|
||||
FilterControls,
|
||||
Filters,
|
||||
FontSearch,
|
||||
SuggestedFonts,
|
||||
};
|
||||
|
||||
1
src/widgets/FontSearch/index.ts
Normal file
1
src/widgets/FontSearch/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { FontSearch } from './ui';
|
||||
107
src/widgets/FontSearch/ui/FontSearch/FontSearch.svelte
Normal file
107
src/widgets/FontSearch/ui/FontSearch/FontSearch.svelte
Normal 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>
|
||||
3
src/widgets/FontSearch/ui/index.ts
Normal file
3
src/widgets/FontSearch/ui/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import FontSearch from './FontSearch/FontSearch.svelte';
|
||||
|
||||
export { FontSearch };
|
||||
3
src/widgets/index.ts
Normal file
3
src/widgets/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export { ComparisonSlider } from './ComparisonSlider';
|
||||
export { FontSearch } from './FontSearch';
|
||||
export { TypographyMenu } from './TypographySettings';
|
||||
Reference in New Issue
Block a user