Skip to content

Commit

Permalink
feat: 현재 참여자 검색 component 생성 (#78)
Browse files Browse the repository at this point in the history
* design: Title Component width 100%로 수정

* design: TopNav width 100%로 수정

* fix: index.tsx export 수정

* chore: v0.1.2 배포

* design: input 좌우 1rem 추가

* feat: MainLayout 추가

* chore: v0.1.3 배포

* feat: search 컴포넌트 구현

* design: input 컴포넌트 마진 추가로 searchTerms 마진 추가

* refactor: 사용하지 않는 onChange 제거

* refactor: setKeyword -> setState로 setter라는 의미 명시

* style: early return 뒤 개행 추가

---------

Co-authored-by: 이태훈 <[email protected]>
  • Loading branch information
jinhokim98 and Todari authored Jul 24, 2024
1 parent 1be9c4e commit fc4138c
Show file tree
Hide file tree
Showing 12 changed files with 192 additions and 4 deletions.
4 changes: 2 additions & 2 deletions HDesign/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion HDesign/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "haengdong-design",
"version": "0.1.0",
"version": "0.1.3",
"description": "",
"main": "./dist/index.js",
"module": "./dist/index.js",
Expand Down
2 changes: 1 addition & 1 deletion HDesign/src/components/Input/Input.style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ const inputBoxBackgroundColorByInputType = (theme: Theme, inputType: InputType =
export const inputBoxStyle = (theme: Theme, inputType: InputType = 'input') =>
css({
display: 'flex',
width: '100%',
justifyContent: 'space-between',
marginInline: '1rem',
padding: '0.75rem 1rem',
borderRadius: '1rem',
backgroundColor: inputBoxBackgroundColorByInputType(theme, inputType),
Expand Down
34 changes: 34 additions & 0 deletions HDesign/src/components/Search/Search.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import React from 'react';
import type {Meta, StoryObj} from '@storybook/react';

import Search from '@components/Search/Search';

const meta = {
title: 'Components/Search',
component: Search,
tags: ['autodocs'],
parameters: {
// layout: 'centered',
},
argTypes: {
value: {
description: '',
control: {type: 'text'},
},
inputType: {
control: {type: 'radio'},
},
},
args: {
disabled: false,
placeholder: 'placeholder',
searchTerms: ['todari', 'cookie'],
setKeyword: keyword => console.log(keyword),
},
} satisfies Meta<typeof Search>;

export default meta;

type Story = StoryObj<typeof meta>;

export const Playground: Story = {};
39 changes: 39 additions & 0 deletions HDesign/src/components/Search/Search.style.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import {Theme} from '@/theme/theme.type';
import {css} from '@emotion/react';

export const searchStyle = css({
position: 'relative',

width: '100%',
});

export const searchTermsStyle = (theme: Theme) =>
css({
position: 'absolute',
top: '3.5rem',

width: 'calc(100% - 2rem)',
margin: '0 1rem',
padding: '0.5rem 0',

borderRadius: '1rem',

backgroundColor: theme.colors.white,
});

export const searchTermStyle = (theme: Theme) =>
css(
{
width: '100%',
padding: '0.5rem 1rem',

color: theme.colors.onTertiary,

'&:hover': {
borderRadius: '0.5rem',

backgroundColor: theme.colors.lightGrayContainer,
},
},
theme.typography.body,
);
42 changes: 42 additions & 0 deletions HDesign/src/components/Search/Search.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/** @jsxImportSource @emotion/react */
import Input from '../Input/Input';
import {InputProps} from '../Input/Input.type';
import {searchStyle, searchTermsStyle} from './Search.style';
import useSearch from './useSearch';
import {searchTermStyle} from './Search.style';
import {useTheme} from '@theme/HDesignProvider';
import Flex from '@components/Flex/Flex';

export interface SearchProps extends InputProps {
searchTerms: string[];
setState: React.Dispatch<React.SetStateAction<string>>;
}

const Search: React.FC<SearchProps> = ({searchTerms, setState, ...inputProps}: SearchProps) => {
const {theme} = useTheme();
const {value, showSearchTerms, handleOnChange, handleOnClick, filterSearchTerms} = useSearch({
searchTerms,
setState,
});

return (
<fieldset css={searchStyle}>
<Input inputType="search" value={value} onChange={handleOnChange} {...inputProps} />
{showSearchTerms && (
<ul css={searchTermsStyle(theme)}>
<Flex flexDirection="column" gap="0.5rem">
{filterSearchTerms(value).map((searchTerm, index) => (
<li key={`${searchTerm}-${index}`}>
<button type="button" css={searchTermStyle(theme)} onClick={() => handleOnClick(searchTerm)}>
{searchTerm}
</button>
</li>
))}
</Flex>
</ul>
)}
</fieldset>
);
};

export default Search;
39 changes: 39 additions & 0 deletions HDesign/src/components/Search/useSearch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import {useState} from 'react';

interface UseSearchProps {
searchTerms: string[];
setState: React.Dispatch<React.SetStateAction<string>>;
}

const useSearch = ({searchTerms, setState}: UseSearchProps) => {
const [value, setValue] = useState('');
const [showSearchTerms, setShowSearchTerms] = useState(false);

const handleOnClick = (searchTerm: string) => {
setValue(searchTerm);
setState(searchTerm);
setShowSearchTerms(false);
};

const handleOnChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const {value} = event.target;
setValue(value);
setShowSearchTerms(value.trim() !== '' && filterSearchTerms(value).length !== 0);
};

const filterSearchTerms = (keyword: string) => {
if (keyword.trim() === '') return [];

return searchTerms.filter(terms => terms.toLocaleLowerCase().indexOf(keyword.toLocaleLowerCase()) > -1);
};

return {
value,
showSearchTerms,
handleOnClick,
handleOnChange,
filterSearchTerms,
};
};

export default useSearch;
1 change: 1 addition & 0 deletions HDesign/src/components/Title/Title.style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export const titleContainerStyle = (theme: Theme) =>
css({
display: 'flex',
flexDirection: 'column',
width: '100%',
gap: '0.5rem',
backgroundColor: theme.colors.white,
padding: '1rem',
Expand Down
1 change: 1 addition & 0 deletions HDesign/src/components/TopNav/TopNav.style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ import {css} from '@emotion/react';
export const topNavStyle = css({
display: 'flex',
padding: '0 1rem',
width: '100%',
});
19 changes: 19 additions & 0 deletions HDesign/src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,45 @@
import BillItem from '@components/BillItem/BillItem';
import BottomSheet from '@components/BottomSheet/BottomSheet';
import Button from '@components/Button/Button';
import DragHandleItem from '@components/DragHandleItem/DragHandleItem';
import ExpenseList from '@components/ExpenseList/ExpenseList';
import FixedButton from '@components/FixedButton/FixedButton';
import Flex from '@components/Flex/Flex';
import IconButton from '@components/IconButton/IconButton';
import InOutItem from '@components/InOutItem/InOutItem';
import Input from '@components/Input/Input';
import Search from '@components/Search/Search';
import StepItem from '@components/StepItem/StepItem';
import Switch from '@components/Switch/Switch';
import Tab from '@components/Tab/Tab';
import Text from '@components/Text/Text';
import TextButton from '@components/TextButton/TextButton';
import Title from '@components/Title/Title';
import TopNav from '@components/TopNav/TopNav';

import {MainLayout} from '@layouts/MainLayout';

import {HDesignProvider} from '@theme/HDesignProvider';

export {
BillItem,
BottomSheet,
Button,
DragHandleItem,
ExpenseList,
FixedButton,
Flex,
IconButton,
InOutItem,
Input,
Search,
StepItem,
Switch,
Tab,
Text,
TextButton,
Title,
TopNav,
MainLayout,
HDesignProvider,
};
12 changes: 12 additions & 0 deletions HDesign/src/layouts/MainLayout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import {PropsWithChildren} from 'react';
import {Flex} from '..';

interface MainLayoutInterface extends PropsWithChildren {}

export const MainLayout = ({children}: MainLayoutInterface) => {
return (
<Flex justifyContent="flexStart" flexDirection="column" margin="1rem 0 0 0" gap="1rem" width="100%" height="100%">
{children}
</Flex>
);
};
1 change: 1 addition & 0 deletions HDesign/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"paths": {
"@/*": ["src/*"],
"@components/*": ["src/components/*"],
"@layouts/*": ["src/layouts/*"],
"@token/*": ["src/token/*"],
"@theme/*": ["src/theme/*"],
"@assets/*": ["src/assets/*"]
Expand Down

0 comments on commit fc4138c

Please sign in to comment.