From b3c360c54fbedd6ce6e7d195c4117ccf08d109b7 Mon Sep 17 00:00:00 2001 From: kyy Date: Thu, 14 May 2026 14:42:11 +0900 Subject: [PATCH] =?UTF-8?q?=EA=B2=80=EC=83=89/=ED=95=84=ED=84=B0=20?= =?UTF-8?q?=EB=B0=94=20=EA=B3=B5=ED=86=A0=20shell=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common/ui/search-filter-bar.tsx | 44 +++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 common/ui/search-filter-bar.tsx diff --git a/common/ui/search-filter-bar.tsx b/common/ui/search-filter-bar.tsx new file mode 100644 index 00000000..0fae5588 --- /dev/null +++ b/common/ui/search-filter-bar.tsx @@ -0,0 +1,44 @@ +import type { HTMLAttributes, ReactNode } from "react"; + +function cx(...classNames: Array) { + return classNames.filter(Boolean).join(" "); +} + +export const commonSearchFilterBarRowClass = + "flex flex-col gap-3 md:flex-row md:items-center md:justify-between"; +export const commonSearchFilterBarPrimaryClass = + "flex min-w-0 flex-1 flex-col gap-3 md:flex-row md:items-center"; +export const commonSearchFilterBarActionsClass = + "flex flex-wrap items-center gap-2"; +export const commonSearchFilterBarAdvancedClass = + "flex flex-col gap-4 rounded-lg border border-border/40 bg-secondary/30 p-4 animate-in fade-in slide-in-from-top-2 duration-200"; + +type SearchFilterBarProps = Omit, "children"> & { + actions?: ReactNode; + advanced?: ReactNode; + advancedOpen?: boolean; + primary: ReactNode; +}; + +export function SearchFilterBar({ + actions, + advanced, + advancedOpen = false, + className, + primary, + ...props +}: SearchFilterBarProps) { + return ( +
+
+
{primary}
+ {actions ? ( +
{actions}
+ ) : null} +
+ {advanced && advancedOpen ? ( +
{advanced}
+ ) : null} +
+ ); +}