Merge branch 'style/icon' into 'develop'
Style/icon See merge request !10
Showing
8 changed files
with
113 additions
and
54 deletions
| ... | @@ -3,20 +3,22 @@ | ... | @@ -3,20 +3,22 @@ |
| 3 | "version": "0.1.0", | 3 | "version": "0.1.0", |
| 4 | "private": true, | 4 | "private": true, |
| 5 | "dependencies": { | 5 | "dependencies": { |
| 6 | + "@mantine/core": "^1.0.6", | ||
| 7 | + "@mantine/hooks": "^1.0.6", | ||
| 6 | "@testing-library/jest-dom": "^5.11.4", | 8 | "@testing-library/jest-dom": "^5.11.4", |
| 7 | "@testing-library/react": "^11.1.0", | 9 | "@testing-library/react": "^11.1.0", |
| 8 | "@testing-library/user-event": "^12.1.10", | 10 | "@testing-library/user-event": "^12.1.10", |
| 9 | "axios": "^0.21.1", | 11 | "axios": "^0.21.1", |
| 10 | "react": "^17.0.2", | 12 | "react": "^17.0.2", |
| 11 | "react-dom": "^17.0.2", | 13 | "react-dom": "^17.0.2", |
| 14 | + "react-icons": "^4.2.0", | ||
| 15 | + "react-jss": "^10.6.0", | ||
| 12 | "react-redux": "^7.2.3", | 16 | "react-redux": "^7.2.3", |
| 13 | "react-router-dom": "^5.2.0", | 17 | "react-router-dom": "^5.2.0", |
| 14 | "react-scripts": "4.0.3", | 18 | "react-scripts": "4.0.3", |
| 15 | "redux": "^4.0.5", | 19 | "redux": "^4.0.5", |
| 16 | "styled-components": "^5.2.3", | 20 | "styled-components": "^5.2.3", |
| 17 | - "web-vitals": "^1.0.1", | 21 | + "web-vitals": "^1.0.1" |
| 18 | - "@mantine/core": "^1.0.6", | ||
| 19 | - "@mantine/hooks": "^1.0.6" | ||
| 20 | }, | 22 | }, |
| 21 | "scripts": { | 23 | "scripts": { |
| 22 | "start": "react-scripts start", | 24 | "start": "react-scripts start", | ... | ... |
| 1 | import React, { useState } from 'react'; | 1 | import React, { useState } from 'react'; |
| 2 | import { NavLink, useHistory } from 'react-router-dom'; | 2 | import { NavLink, useHistory } from 'react-router-dom'; |
| 3 | +import { FaSearch } from 'react-icons/fa'; | ||
| 3 | import styled from 'styled-components'; | 4 | import styled from 'styled-components'; |
| 4 | import InputBlock from './common/Input'; | 5 | import InputBlock from './common/Input'; |
| 5 | import DropDownButton from './common/DropdownButton'; | 6 | import DropDownButton from './common/DropdownButton'; |
| ... | @@ -123,6 +124,8 @@ const Header = () => { | ... | @@ -123,6 +124,8 @@ const Header = () => { |
| 123 | <DropDownContainer> | 124 | <DropDownContainer> |
| 124 | <DropDownWrap> | 125 | <DropDownWrap> |
| 125 | <DropDownButton | 126 | <DropDownButton |
| 127 | + menuPosition={{ top: 40 }} | ||
| 128 | + size={100} | ||
| 126 | color="blue" | 129 | color="blue" |
| 127 | float="left" | 130 | float="left" |
| 128 | fontsize="20px" | 131 | fontsize="20px" |
| ... | @@ -146,20 +149,24 @@ const Header = () => { | ... | @@ -146,20 +149,24 @@ const Header = () => { |
| 146 | <SortOptionContainer> | 149 | <SortOptionContainer> |
| 147 | <DropDownButton | 150 | <DropDownButton |
| 148 | color="white" | 151 | color="white" |
| 149 | - width="85px" | 152 | + width="100px" |
| 150 | fontsize="15px" | 153 | fontsize="15px" |
| 151 | height="36px" | 154 | height="36px" |
| 152 | title="정렬(기본)" | 155 | title="정렬(기본)" |
| 156 | + menuPosition={{ top: 29 }} | ||
| 157 | + size="100" | ||
| 153 | options={[ | 158 | options={[ |
| 154 | { id: 0, name: '정렬(기본)' }, | 159 | { id: 0, name: '정렬(기본)' }, |
| 155 | { id: 1, name: '날짜빠른순' }, | 160 | { id: 1, name: '날짜빠른순' }, |
| 156 | { id: 2, name: '크기높은순' }, | 161 | { id: 2, name: '크기높은순' }, |
| 157 | { id: 3, name: '크기낮은순' }, | 162 | { id: 3, name: '크기낮은순' }, |
| 158 | ]} | 163 | ]} |
| 159 | - /> | 164 | + />{' '} |
| 160 | </SortOptionContainer> | 165 | </SortOptionContainer> |
| 161 | <SearchOptionContainer onClick={openModal}> | 166 | <SearchOptionContainer onClick={openModal}> |
| 162 | - <Button color="gray">고급 검색</Button> | 167 | + <Button color="gray" size="md" icon={<FaSearch />}> |
| 168 | + 고급 검색 | ||
| 169 | + </Button> | ||
| 163 | </SearchOptionContainer> | 170 | </SearchOptionContainer> |
| 164 | <Modal showModal={showModal} setShowModal={setShowModal} /> | 171 | <Modal showModal={showModal} setShowModal={setShowModal} /> |
| 165 | </OptionContainer> | 172 | </OptionContainer> | ... | ... |
| 1 | -import React, { useRef } from 'react'; | 1 | +import React, { useRef, useState } from 'react'; |
| 2 | -import { Card } from '@mantine/core'; | 2 | +import { Card, TextInput } from '@mantine/core'; |
| 3 | +import { useHistory } from 'react-router-dom'; | ||
| 3 | import styled from 'styled-components'; | 4 | import styled from 'styled-components'; |
| 4 | import Button from './common/Button'; | 5 | import Button from './common/Button'; |
| 5 | -import Input from './common/Input'; | ||
| 6 | 6 | ||
| 7 | const Background = styled.div``; | 7 | const Background = styled.div``; |
| 8 | 8 | ||
| ... | @@ -34,13 +34,13 @@ const CloseWrap = styled.div` | ... | @@ -34,13 +34,13 @@ const CloseWrap = styled.div` |
| 34 | 34 | ||
| 35 | const StandardWrap = styled.div` | 35 | const StandardWrap = styled.div` |
| 36 | position: absolute; | 36 | position: absolute; |
| 37 | - width: 50px; | 37 | + width: 250px; |
| 38 | top: 15px; | 38 | top: 15px; |
| 39 | left: 30%; | 39 | left: 30%; |
| 40 | `; | 40 | `; |
| 41 | 41 | ||
| 42 | const AdvancedWrap = styled.div` | 42 | const AdvancedWrap = styled.div` |
| 43 | - width: 50px; | 43 | + width: 250px; |
| 44 | position: absolute; | 44 | position: absolute; |
| 45 | top: 75px; | 45 | top: 75px; |
| 46 | left: 30%; | 46 | left: 30%; |
| ... | @@ -57,6 +57,11 @@ const TextWrap = styled.div` | ... | @@ -57,6 +57,11 @@ const TextWrap = styled.div` |
| 57 | `; | 57 | `; |
| 58 | 58 | ||
| 59 | const Modal = ({ showModal, setShowModal }) => { | 59 | const Modal = ({ showModal, setShowModal }) => { |
| 60 | + const [query, setQuery] = useState(''); | ||
| 61 | + const [keywordQuery, setKeywordQuery] = useState(''); | ||
| 62 | + const [writerQuery, setWriterQuery] = useState(''); | ||
| 63 | + const [dateQuery, setDateQuery] = useState(''); | ||
| 64 | + const history = useHistory(); | ||
| 60 | const modalRef = useRef(); | 65 | const modalRef = useRef(); |
| 61 | const closeModal = e => { | 66 | const closeModal = e => { |
| 62 | if (modalRef.current === e.target) { | 67 | if (modalRef.current === e.target) { |
| ... | @@ -75,47 +80,62 @@ const Modal = ({ showModal, setShowModal }) => { | ... | @@ -75,47 +80,62 @@ const Modal = ({ showModal, setShowModal }) => { |
| 75 | 기본검색 | 80 | 기본검색 |
| 76 | </TextWrap> | 81 | </TextWrap> |
| 77 | <StandardWrap> | 82 | <StandardWrap> |
| 78 | - <Input | 83 | + <TextInput |
| 79 | - float="left" | 84 | + inputStyle={{ |
| 80 | - color="blue" | 85 | + marginBottom: 18, |
| 81 | - width="350px" | 86 | + fontSize: 15, |
| 82 | - height="40px" | 87 | + }} |
| 83 | - paddingsize="3px" | 88 | + placeholder="내용을 입력해 주세요." |
| 84 | - fontsize="15px" | 89 | + type="text" |
| 90 | + value={decodeURIComponent(query)} | ||
| 91 | + onChange={e => setQuery(e.target.value)} | ||
| 92 | + onKeyPress={e => { | ||
| 93 | + if (e.key === 'Enter') { | ||
| 94 | + if (query === '') { | ||
| 95 | + alert('검색어를 입력 해 주세요.'); | ||
| 96 | + return; | ||
| 97 | + } | ||
| 98 | + const params = new URLSearchParams({ query }); | ||
| 99 | + history.push( | ||
| 100 | + `search?${decodeURIComponent(params.toString())}` | ||
| 101 | + ); | ||
| 102 | + } | ||
| 103 | + }} | ||
| 85 | /> | 104 | /> |
| 86 | </StandardWrap> | 105 | </StandardWrap> |
| 87 | <TextWrap top="24%" right="10%" bottom="31%"> | 106 | <TextWrap top="24%" right="10%" bottom="31%"> |
| 88 | 고급검색 | 107 | 고급검색 |
| 89 | </TextWrap> | 108 | </TextWrap> |
| 90 | <AdvancedWrap> | 109 | <AdvancedWrap> |
| 91 | - <Input | 110 | + <TextInput |
| 92 | - float="left" | 111 | + inputStyle={{ |
| 93 | - color="blue" | 112 | + marginBottom: 18, |
| 94 | - width="350px" | 113 | + fontSize: 15, |
| 95 | - height="40px" | 114 | + }} |
| 96 | - paddingsize="3px" | 115 | + placeholder="단어/문장 검색" |
| 97 | - fontsize="15px" | 116 | + type="text" |
| 98 | - placeholder="단어/ 문장검색" | 117 | + value={decodeURIComponent(keywordQuery)} |
| 118 | + onChange={e => setKeywordQuery(e.target.value)} | ||
| 99 | /> | 119 | /> |
| 100 | - <br /> <br /> | 120 | + <TextInput |
| 101 | - <Input | 121 | + inputStyle={{ |
| 102 | - float="left" | 122 | + marginBottom: 18, |
| 103 | - color="blue" | 123 | + fontSize: 15, |
| 104 | - width="350px" | 124 | + }} |
| 105 | - height="40px" | 125 | + placeholder="작성자" |
| 106 | - paddingsize="3px" | 126 | + type="text" |
| 107 | - fontsize="15px" | 127 | + value={decodeURIComponent(writerQuery)} |
| 108 | - placeholder="최초 작성자" | 128 | + onChange={e => setWriterQuery(e.target.value)} |
| 109 | /> | 129 | /> |
| 110 | - <br /> <br /> | 130 | + <TextInput |
| 111 | - <Input | 131 | + inputStyle={{ |
| 112 | - float="left" | 132 | + marginBottom: 18, |
| 113 | - color="blue" | 133 | + fontSize: 15, |
| 114 | - width="350px" | 134 | + }} |
| 115 | - height="40px" | 135 | + placeholder="생성 날짜" |
| 116 | - paddingsize="3px" | 136 | + type="text" |
| 117 | - fontsize="15px" | 137 | + value={decodeURIComponent(dateQuery)} |
| 118 | - placeholder="최종 수정자" | 138 | + onChange={e => setDateQuery(e.target.value)} |
| 119 | /> | 139 | /> |
| 120 | </AdvancedWrap> | 140 | </AdvancedWrap> |
| 121 | </ModalContent> | 141 | </ModalContent> | ... | ... |
| ... | @@ -10,10 +10,18 @@ const ButtonBlock = styled.div` | ... | @@ -10,10 +10,18 @@ const ButtonBlock = styled.div` |
| 10 | cursor: pointer; | 10 | cursor: pointer; |
| 11 | `; | 11 | `; |
| 12 | 12 | ||
| 13 | -const Buttons = ({ children, color, float, width, fontsize }) => { | 13 | +const Buttons = ({ |
| 14 | + children, | ||
| 15 | + size = 'lg', | ||
| 16 | + color, | ||
| 17 | + float, | ||
| 18 | + width, | ||
| 19 | + fontsize, | ||
| 20 | + icon = '', | ||
| 21 | +}) => { | ||
| 14 | return ( | 22 | return ( |
| 15 | <ButtonBlock float={float} width={width} fontsize={fontsize}> | 23 | <ButtonBlock float={float} width={width} fontsize={fontsize}> |
| 16 | - <Button fullWidth size="lg" color={color || 'blue'}> | 24 | + <Button size={size} color={color || 'blue'} rightIcon={icon}> |
| 17 | {children} | 25 | {children} |
| 18 | </Button> | 26 | </Button> |
| 19 | </ButtonBlock> | 27 | </ButtonBlock> | ... | ... |
| 1 | import React, { useState, useEffect } from 'react'; | 1 | import React, { useState, useEffect } from 'react'; |
| 2 | +import { TiArrowSortedDown } from 'react-icons/ti'; | ||
| 2 | import { Menu, MenuItem } from '@mantine/core'; | 3 | import { Menu, MenuItem } from '@mantine/core'; |
| 3 | import styled from 'styled-components'; | 4 | import styled from 'styled-components'; |
| 4 | import { dropdownHeaderColorMap } from '../../lib/styles/palette'; | 5 | import { dropdownHeaderColorMap } from '../../lib/styles/palette'; |
| ... | @@ -10,6 +11,9 @@ const DropDownBlock = styled.div` | ... | @@ -10,6 +11,9 @@ const DropDownBlock = styled.div` |
| 10 | const DropDownHeader = styled(Menu)``; | 11 | const DropDownHeader = styled(Menu)``; |
| 11 | 12 | ||
| 12 | const DropDownWrap = styled.button` | 13 | const DropDownWrap = styled.button` |
| 14 | + display: flex; | ||
| 15 | + justify-content: space-around; | ||
| 16 | + align-items: center; | ||
| 13 | color: ${props => dropdownHeaderColorMap[props.color].color}; | 17 | color: ${props => dropdownHeaderColorMap[props.color].color}; |
| 14 | background-color: ${props => dropdownHeaderColorMap[props.color].background}; | 18 | background-color: ${props => dropdownHeaderColorMap[props.color].background}; |
| 15 | cursor: pointer; | 19 | cursor: pointer; |
| ... | @@ -18,7 +22,6 @@ const DropDownWrap = styled.button` | ... | @@ -18,7 +22,6 @@ const DropDownWrap = styled.button` |
| 18 | dropdownHeaderColorMap[props.color].hoverBackground}; | 22 | dropdownHeaderColorMap[props.color].hoverBackground}; |
| 19 | } | 23 | } |
| 20 | margin-bottom: 0.8em; | 24 | margin-bottom: 0.8em; |
| 21 | - padding: 0.4em; | ||
| 22 | width: ${props => props.width || '100px'}; | 25 | width: ${props => props.width || '100px'}; |
| 23 | height: ${props => props.height || '30px'}; | 26 | height: ${props => props.height || '30px'}; |
| 24 | padding-right: 7%; | 27 | padding-right: 7%; |
| ... | @@ -34,6 +37,8 @@ const DropDown = ({ | ... | @@ -34,6 +37,8 @@ const DropDown = ({ |
| 34 | width, | 37 | width, |
| 35 | height, | 38 | height, |
| 36 | title = '전체', | 39 | title = '전체', |
| 40 | + menuPosition, | ||
| 41 | + size, | ||
| 37 | }) => { | 42 | }) => { |
| 38 | const [menuTitle, setTitle] = useState(''); | 43 | const [menuTitle, setTitle] = useState(''); |
| 39 | useEffect(() => { | 44 | useEffect(() => { |
| ... | @@ -42,6 +47,8 @@ const DropDown = ({ | ... | @@ -42,6 +47,8 @@ const DropDown = ({ |
| 42 | return ( | 47 | return ( |
| 43 | <DropDownBlock float={float} color={color} title={title}> | 48 | <DropDownBlock float={float} color={color} title={title}> |
| 44 | <DropDownHeader | 49 | <DropDownHeader |
| 50 | + menuPosition={menuPosition} | ||
| 51 | + size={size} | ||
| 45 | control={ | 52 | control={ |
| 46 | <DropDownWrap | 53 | <DropDownWrap |
| 47 | options={options} | 54 | options={options} |
| ... | @@ -51,6 +58,7 @@ const DropDown = ({ | ... | @@ -51,6 +58,7 @@ const DropDown = ({ |
| 51 | height={height} | 58 | height={height} |
| 52 | > | 59 | > |
| 53 | {menuTitle} | 60 | {menuTitle} |
| 61 | + <TiArrowSortedDown /> | ||
| 54 | </DropDownWrap> | 62 | </DropDownWrap> |
| 55 | } | 63 | } |
| 56 | > | 64 | > | ... | ... |
| ... | @@ -17,7 +17,6 @@ const InputWrap = styled.div` | ... | @@ -17,7 +17,6 @@ const InputWrap = styled.div` |
| 17 | width: 70%; | 17 | width: 70%; |
| 18 | height: 100%; | 18 | height: 100%; |
| 19 | color: ${props => inputColorMap[props.color].color}; | 19 | color: ${props => inputColorMap[props.color].color}; |
| 20 | - box-shadow: 2px 3px 28px 1px rgba(0, 0, 0, 0.1); | ||
| 21 | outline: none; | 20 | outline: none; |
| 22 | font-size: ${props => props.size}; | 21 | font-size: ${props => props.size}; |
| 23 | border: 3px solid ${props => inputColorMap[props.color].borderColor}; | 22 | border: 3px solid ${props => inputColorMap[props.color].borderColor}; |
| ... | @@ -63,7 +62,7 @@ const MyInput = ({ | ... | @@ -63,7 +62,7 @@ const MyInput = ({ |
| 63 | variant="unstyled" | 62 | variant="unstyled" |
| 64 | placeholder={placeholder} | 63 | placeholder={placeholder} |
| 65 | type="text" | 64 | type="text" |
| 66 | - value={query} | 65 | + value={decodeURIComponent(query)} |
| 67 | onChange={e => setQuery(e.target.value)} | 66 | onChange={e => setQuery(e.target.value)} |
| 68 | onKeyPress={e => { | 67 | onKeyPress={e => { |
| 69 | if (e.key === 'Enter') { | 68 | if (e.key === 'Enter') { |
| ... | @@ -72,15 +71,19 @@ const MyInput = ({ | ... | @@ -72,15 +71,19 @@ const MyInput = ({ |
| 72 | return; | 71 | return; |
| 73 | } | 72 | } |
| 74 | const params = new URLSearchParams({ query }); | 73 | const params = new URLSearchParams({ query }); |
| 75 | - history.push(`search?${params.toString()}`); | 74 | + history.push(`search?${decodeURIComponent(params.toString())}`); |
| 76 | } | 75 | } |
| 77 | }} | 76 | }} |
| 78 | /> | 77 | /> |
| 79 | </InputWrap> | 78 | </InputWrap> |
| 80 | <SearchIconWrap | 79 | <SearchIconWrap |
| 81 | onClick={() => { | 80 | onClick={() => { |
| 81 | + if (query === '') { | ||
| 82 | + alert('검색어를 입력 해 주세요.'); | ||
| 83 | + return; | ||
| 84 | + } | ||
| 82 | const params = new URLSearchParams({ query }); | 85 | const params = new URLSearchParams({ query }); |
| 83 | - history.push(`search?${params.toString()}`); | 86 | + history.push(`search?${decodeURIComponent(params.toString())}`); |
| 84 | }} | 87 | }} |
| 85 | > | 88 | > |
| 86 | <SearchBox color="blue" size="50px" display={display} /> | 89 | <SearchBox color="blue" size="50px" display={display} /> | ... | ... |
| 1 | import React from 'react'; | 1 | import React from 'react'; |
| 2 | import styled from 'styled-components'; | 2 | import styled from 'styled-components'; |
| 3 | +import { AiOutlineSearch } from 'react-icons/ai'; | ||
| 3 | import { searchBoxColorMap } from '../../lib/styles/palette'; | 4 | import { searchBoxColorMap } from '../../lib/styles/palette'; |
| 4 | 5 | ||
| 5 | -const ButtonBlock = styled.button` | 6 | +const ButtonBlock = styled.div` |
| 7 | + text-align: center; | ||
| 8 | + display: table-cell; | ||
| 9 | + vertical-align: middle; | ||
| 6 | width: ${props => props.size}; | 10 | width: ${props => props.size}; |
| 7 | height: ${props => props.size}; | 11 | height: ${props => props.size}; |
| 8 | - background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-2 -3 30 30'%3E%3Cpath d='M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z' fill='white'/%3E%3Cpath d='M0 0h24v24H0z' fill='none'/%3E%3C/svg%3E"); | ||
| 9 | display: ${props => props.display}; | 12 | display: ${props => props.display}; |
| 10 | background-color: ${props => searchBoxColorMap[props.color].background}; | 13 | background-color: ${props => searchBoxColorMap[props.color].background}; |
| 11 | &:hover { | 14 | &:hover { |
| ... | @@ -18,9 +21,17 @@ const ButtonBlock = styled.button` | ... | @@ -18,9 +21,17 @@ const ButtonBlock = styled.button` |
| 18 | cursor: pointer; | 21 | cursor: pointer; |
| 19 | `; | 22 | `; |
| 20 | 23 | ||
| 24 | +const SFaSearch = styled(AiOutlineSearch)` | ||
| 25 | + width: 35px; | ||
| 26 | + height: 35px; | ||
| 27 | + margin-right: 5px; | ||
| 28 | + margin-top: 2px; | ||
| 29 | +`; | ||
| 21 | const SearchBox = ({ color, float, size = '1px', display = 'none' }) => { | 30 | const SearchBox = ({ color, float, size = '1px', display = 'none' }) => { |
| 22 | return ( | 31 | return ( |
| 23 | - <ButtonBlock color={color} float={float} size={size} display={display} /> | 32 | + <ButtonBlock color={color} float={float} size={size} display={display}> |
| 33 | + <SFaSearch /> | ||
| 34 | + </ButtonBlock> | ||
| 24 | ); | 35 | ); |
| 25 | }; | 36 | }; |
| 26 | 37 | ... | ... |
This diff is collapsed. Click to expand it.
-
Please register or login to post a comment