diff --git a/public/icons/Image.tsx b/public/icons/Image.tsx new file mode 100644 index 00000000..7a63650e --- /dev/null +++ b/public/icons/Image.tsx @@ -0,0 +1,16 @@ +/* eslint-disable @next/next/no-img-element */ +import React from "react"; + +type ImageProps = React.ImgHTMLAttributes & { + src: string; + alt: string; +}; + +/** + * 테스트용 Image 컴포넌트 + * - src는 필수 + * - alt 기본값은 빈 문자열 + */ +export default function Image({ src, alt = "", ...rest }: ImageProps) { + return {alt}; +} \ No newline at end of file diff --git a/src/components/wrappers/SearchInput/SearchInput.tsx b/src/components/wrappers/SearchInput/SearchInput.tsx new file mode 100644 index 00000000..e517233f --- /dev/null +++ b/src/components/wrappers/SearchInput/SearchInput.tsx @@ -0,0 +1,50 @@ +'use client'; + +import IconButton from '@/components/basics/IconButton/IconButton'; +import clsx from 'clsx'; +import React from 'react'; + +import CustomImage from '../../Icons/CustomImage'; + +interface SearchInputProps { + value: string; + onChange: (e: React.ChangeEvent) => void; + onSubmit: (e: React.FormEvent) => void; + placeholder?: string; + size?: 'md' | 'lg'; +} + +export default function SearchInput({ + value, + onChange, + onSubmit, + placeholder = '검색하세요', + size = 'md', +}: SearchInputProps) { + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault(); + onSubmit(e); + }; + + const baseStyle = + 'flex justify-between pl-4 h-10 text-gray-800 bg-white placeholder-gray-400 rounded-full'; + const sizes = { + md: 'w-70', + lg: 'w-full', + }; + const classes = clsx(baseStyle, sizes[size]); + + return ( +
+ + + + + ); +} diff --git a/src/stories/SearchInput.stories.tsx b/src/stories/SearchInput.stories.tsx new file mode 100644 index 00000000..a3ee883a --- /dev/null +++ b/src/stories/SearchInput.stories.tsx @@ -0,0 +1,45 @@ +// SearchInput.stories.tsx +import SearchInput from '@/components/wrappers/SearchInput/SearchInput'; +import type { Meta, StoryObj } from '@storybook/react'; +import React, { useState } from 'react'; + +const meta = { + title: 'Components/SearchInput', + component: SearchInput, + tags: ['autodocs'], + argTypes: { + size: { + control: { type: 'select' }, + options: ['md', 'lg'], + }, + }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +function ControlledSearchInput( + args: typeof SearchInput extends React.ComponentType ? P : never +) { + const [value, setValue] = useState(''); + + return ( + setValue(e.target.value)} + onSubmit={e => { + e.preventDefault(); + console.log('Submit:', value); + }} + /> + ); +} + +export const Default: Story = { + render: args => , + args: { + placeholder: '검색하세요', + size: 'md', + }, +};