검색 기능 구현

This commit is contained in:
static committed 2026-01-15 15:11:03 +09:00
1 parent 96d5397cb5
commit 37bd6a9315
26 files changed
+757 -35

No files matched your search

+53
View File
@@ -0,0 +1,53 @@
<script lang="ts">
import type { Snippet } from "svelte";
import type { ClassValue } from "svelte/elements";
import IconClose from "~icons/material-symbols/close";
interface Props {
children: Snippet;
class?: ClassValue;
onclick?: () => void;
onRemoveClick?: () => void;
selected?: boolean;
removable?: boolean;
}
let {
children,
class: className,
onclick = () => (selected = !selected),
onRemoveClick,
removable = false,
selected = $bindable(false),
}: Props = $props();
</script>
<!-- svelte-ignore a11y_no_static_element_interactions -->
<!-- svelte-ignore a11y_click_events_have_key_events -->
<div
onclick={onclick && (() => setTimeout(onclick, 100))}
class={[
"inline-flex cursor-pointer items-center gap-x-1 rounded-lg px-3 py-1.5 text-sm font-medium transition active:scale-95",
selected
? "bg-primary-500 text-white active:bg-primary-400"
: "bg-gray-100 text-gray-700 active:bg-gray-200",
className,
]}
>
<span>
{@render children()}
</span>
{#if selected && removable}
<button
onclick={(e) => {
e.stopPropagation();
if (onRemoveClick) {
setTimeout(onRemoveClick, 100);
}
}}
>
<IconClose />
</button>
{/if}
</div>
+13 -3
View File
@@ -6,13 +6,22 @@
interface Props {
class?: ClassValue;
count: number;
estimateItemHeight: (index: number) => number;
getItemKey?: (index: number) => string | number;
item: Snippet<[index: number]>;
itemHeight: (index: number) => number;
itemGap?: number;
placeholder?: Snippet;
}
let { class: className, count, item, itemHeight, itemGap, placeholder }: Props = $props();
let {
class: className,
count,
estimateItemHeight,
getItemKey,
item,
itemGap,
placeholder,
}: Props = $props();
let element: HTMLElement | undefined = $state();
let scrollMargin = $state(0);
@@ -20,8 +29,9 @@
let virtualizer = $derived(
createWindowVirtualizer({
count,
estimateSize: itemHeight,
estimateSize: estimateItemHeight,
gap: itemGap,
getItemKey: getItemKey,
scrollMargin,
}),
);
@@ -49,7 +49,7 @@
</div>
</div>
<style>
<style lang="postcss">
#container:active:not(:has(#action-button:active)) {
@apply bg-gray-100;
}
+1
View File
@@ -1,5 +1,6 @@
export { default as BottomSheet } from "./BottomSheet.svelte";
export * from "./buttons";
export { default as Chip } from "./Chip.svelte";
export * from "./divs";
export * from "./inputs";
export { default as Modal } from "./Modal.svelte";
@@ -28,7 +28,7 @@
</div>
</div>
<style>
<style lang="postcss">
input:focus,
input:not(:placeholder-shown) {
@apply border-primary-300;
@@ -10,9 +10,9 @@
class?: ClassValue;
info: CategoryInfo;
onSubCategoryClick: (subCategory: SelectedCategory) => void;
onSubCategoryCreateClick: () => void;
onSubCategoryCreateClick?: () => void;
onSubCategoryMenuClick?: (category: SelectedCategory) => void;
subCategoryCreatePosition?: "top" | "bottom";
subCategoryCreatePosition?: "top" | "bottom" | "none";
subCategoryMenuIcon?: Component<SvelteHTMLElements["svg"]>;
}
@@ -22,7 +22,7 @@
onSubCategoryClick,
onSubCategoryCreateClick,
onSubCategoryMenuClick,
subCategoryCreatePosition = "bottom",
subCategoryCreatePosition = "none",
subCategoryMenuIcon,
}: Props = $props();
</script>
+12 -7
View File
@@ -8,10 +8,11 @@
children?: Snippet;
class?: ClassValue;
onBackClick?: () => void;
showBackButton?: boolean;
title?: string;
}
let { children, class: className, onBackClick, title }: Props = $props();
let { children, class: className, onBackClick, showBackButton = true, title }: Props = $props();
</script>
<div
@@ -20,12 +21,16 @@
className,
]}
>
<button
onclick={onBackClick || (() => history.back())}
class="w-[2.3rem] flex-shrink-0 rounded-full p-1 active:bg-black active:bg-opacity-[0.04]"
>
<IconArrowBack class="text-2xl" />
</button>
<div class="w-[2.3rem] flex-shrink-0">
{#if showBackButton}
<button
onclick={onBackClick ?? (() => history.back())}
class="w-[2.3rem] flex-shrink-0 rounded-full p-1 active:bg-black active:bg-opacity-[0.04]"
>
<IconArrowBack class="text-2xl" />
</button>
{/if}
</div>
{#if title}
<p class="flex-grow truncate text-center text-lg font-semibold">{title}</p>
{/if}