diff --git a/src/pages/playground.tsx b/src/pages/playground.tsx index 7e9baace..dca52c6d 100644 --- a/src/pages/playground.tsx +++ b/src/pages/playground.tsx @@ -6,6 +6,7 @@ import { Header } from '@shared/ui/Header/Header'; import { Modal } from '@shared/ui/Modal/Modal'; import { Profile } from '@shared/ui/Profile/Profile'; import { RadioButton } from '@shared/ui/RadioButton/RadioButton'; +import { SearchBar } from '@shared/ui/SearchBar'; import { TextField } from '@shared/ui/TextField/TextField'; import { useState } from 'react'; @@ -117,6 +118,11 @@ export default function Playground() { date="1일 전" /> + {/* Search Bar */} +
+

SearchBar

+ {}} /> +
{/* BannerCard */}

Banner Card

diff --git a/src/shared/assets/icons/common/search-magnifying-glass.svg b/src/shared/assets/icons/common/search-magnifying-glass.svg new file mode 100644 index 00000000..292fd756 --- /dev/null +++ b/src/shared/assets/icons/common/search-magnifying-glass.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/shared/assets/icons/index.ts b/src/shared/assets/icons/index.ts index 09af8252..bceccf8f 100644 --- a/src/shared/assets/icons/index.ts +++ b/src/shared/assets/icons/index.ts @@ -1,5 +1,6 @@ import CaretDownMdIcon from './common/caret-down-md.svg?react'; import CheckIcon from './common/check.svg?react'; import DoneIcon from './common/done.svg?react'; +import SearchMagnifyingGlassIcon from './common/search-magnifying-glass.svg?react'; -export { CaretDownMdIcon, CheckIcon, DoneIcon }; +export { CaretDownMdIcon, CheckIcon, DoneIcon, SearchMagnifyingGlassIcon }; diff --git a/src/shared/ui/SearchBar/SearchBar.tsx b/src/shared/ui/SearchBar/SearchBar.tsx new file mode 100644 index 00000000..5a2a7da8 --- /dev/null +++ b/src/shared/ui/SearchBar/SearchBar.tsx @@ -0,0 +1,49 @@ +import { SearchMagnifyingGlassIcon } from '@shared/assets/icons'; +import clsx from 'clsx'; +import { useState, type KeyboardEventHandler } from 'react'; +import { searchBarVariants } from './SearchBar.variants'; + +export const SearchBar = ({ + placeholder, + onSearch, +}: { + placeholder?: string; + onSearch: (query: string) => void; +}) => { + const [query, setQuery] = useState(''); + const [isFocused, setFocused] = useState(false); + + const isFilled = query.length > 0; + + const styles = searchBarVariants({ + state: isFocused ? (isFilled ? 'filled' : 'focused') : 'default', + }); + + const handleChange: React.ChangeEventHandler = (e) => { + setQuery(e.target.value); + }; + + const handleEnterKey: KeyboardEventHandler = (event) => { + if (event.key === 'Enter') { + onSearch(query); + } + }; + + return ( +
+
+
+
+ ); +}; diff --git a/src/shared/ui/SearchBar/SearchBar.variants.ts b/src/shared/ui/SearchBar/SearchBar.variants.ts new file mode 100644 index 00000000..105e42b3 --- /dev/null +++ b/src/shared/ui/SearchBar/SearchBar.variants.ts @@ -0,0 +1,41 @@ +import { tv } from 'tailwind-variants'; + +export const searchBarVariants = tv({ + slots: { + root: ['flex flex-col'], + wrapper: [ + 'flex items-center', + 'w-[550px] h-[44px]', + 'px-[15px] py-[10px]', + 'gap-[25px]', + 'rounded-[var(--radius-m)]', + 'transition-colors', + ], + icon: ['w-[24px] h-[24px] shrink-0', 'transition-colors'], + input: ['w-full bg-transparent outline-none', 'typo-body-1', 'placeholder:typo-body-1'], + }, + + variants: { + state: { + default: { + wrapper: ['bg-[var(--color-green-100)]'], + icon: ['text-[var(--color-gray-500)]'], + input: ['text-[var(--color-gray-500)]', 'placeholder:text-[var(--color-gray-500)]'], + }, + filled: { + wrapper: ['bg-[var(--color-green-300)]'], + icon: ['text-[var(--color-black)]'], + input: ['text-[var(--color-black)]', 'placeholder:text-[var(--color-black)]'], + }, + focused: { + wrapper: ['bg-[var(--color-green-300)]'], + icon: ['text-[var(--color-black)]'], + input: ['text-[var(--color-black)]'], + }, + }, + }, + + defaultVariants: { + state: 'default', + }, +}); diff --git a/src/shared/ui/SearchBar/index.ts b/src/shared/ui/SearchBar/index.ts new file mode 100644 index 00000000..8c193316 --- /dev/null +++ b/src/shared/ui/SearchBar/index.ts @@ -0,0 +1 @@ +export { SearchBar } from './SearchBar';