Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] #15 공통 컴포넌트 추가 #17

Merged
merged 26 commits into from
Nov 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
b06dd37
✨Feat: ActionButton
shlee9999 Nov 20, 2024
b867070
✨Feat: Input
shlee9999 Nov 20, 2024
40e3045
✨Feat: TwoLineInput
shlee9999 Nov 20, 2024
e20176a
✨Feat: Toggle
shlee9999 Nov 20, 2024
2e84a7d
✨Fix: 기본 배경색
shlee9999 Nov 20, 2024
489f5a9
✨Feat: ToggleBox
shlee9999 Nov 20, 2024
e8c4d30
✨Feat: settingsStore
shlee9999 Nov 20, 2024
c0f4a90
✨Feat: allNotifications(모든 알림 설정)
shlee9999 Nov 20, 2024
3a8fe45
✨Feat: settingsInfo
shlee9999 Nov 20, 2024
ccf3f07
✨Feat: ToggleArea 추가 및 common typos
shlee9999 Nov 20, 2024
1d7352a
Merge branch '13-feature/styled-components-theme' into 15-feature/com…
shlee9999 Nov 20, 2024
c467983
🐛Fix: App.tsx 원복
shlee9999 Nov 20, 2024
67ce7f6
🎨Design: ToggleBox, ToggleArea 디자인 수정
shlee9999 Nov 20, 2024
bb12cb5
Merge branch 'develop' of https://github.com/prgrms-web-devcourse-fin…
shlee9999 Nov 20, 2024
d82c304
🐛Fix: TwoLineInput 오류 해결
shlee9999 Nov 20, 2024
e3c73b7
♻️Refactor: styled.d.ts
shlee9999 Nov 20, 2024
3cfd884
✨Feat: ActionButton 타입 추가
shlee9999 Nov 20, 2024
7638177
🚚Rename: common.styles.ts, common.typos.ts components 폴더로 이동
shlee9999 Nov 20, 2024
9e175eb
♻️Refactor: styled.d.ts type 모두 export
shlee9999 Nov 20, 2024
e5091d2
🚚Rename: common.styles -> common.buttons, common.inputs로 분리
shlee9999 Nov 20, 2024
22b1e22
♻️Refactor: 폴더 구조 변경, ActionButton 개선
shlee9999 Nov 20, 2024
477f5c3
🚚Rename: 폴더 구조 변경
shlee9999 Nov 20, 2024
57c189b
✨Feat: FontWeight 타입
shlee9999 Nov 20, 2024
6d76688
✨Feat: ToggleBox type
shlee9999 Nov 20, 2024
c80804b
🚚Rename: Typo.ts, Input.ts ->
shlee9999 Nov 20, 2024
a3b7592
🐛Fix: ToggleArea type 지정
shlee9999 Nov 20, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions package-lock.json

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

8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,21 @@
"format:fix": "prettier --write --ignore-path .gitignore \"**/*.{ts,tsx}\""
},
"dependencies": {
"@types/react-textarea-autosize": "^8.0.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-helmet-async": "^2.0.5",
"react-icons": "^5.3.0",
"react-query": "^3.39.3",
"react-router-dom": "^6.28.0",
"react-textarea-autosize": "^8.5.5",
"styled-components": "^6.1.13",
"styled-reset": "^4.5.2",
"zustand": "^5.0.1"
},
"devDependencies": {
"@types/node": "^22.9.0",
"@eslint/js": "^9.13.0",
"@types/node": "^22.9.0",
"@types/react": "^18.3.1",
"@types/react-dom": "^18.3.0",
"@types/styled-components": "^5.1.34",
Expand All @@ -44,12 +46,12 @@
"typescript": "^5.2.2",
"typescript-eslint": "^8.11.0",
"vite": "^5.2.10",
"vite-plugin-compression2": "^1.3.1",
"vite-plugin-compression": "^0.5.1",
"vite-plugin-compression2": "^1.3.1",
"vite-plugin-dts": "^4.3.0",
"vite-plugin-mkcert": "^1.17.6",
"vite-plugin-svgr": "^4.3.0",
"vite-plugin-pwa": "^0.20.5",
"vite-plugin-svgr": "^4.3.0",
"vite-tsconfig-paths": "^5.1.2",
"workbox-core": "^7.1.0",
"workbox-precaching": "^7.1.0",
Expand Down
52 changes: 52 additions & 0 deletions src/components/Button/ActionButton.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import styled, { BrandColors, GrayscaleColors } from 'styled-components'

type BgColorType =
| Extract<keyof BrandColors, 'default' | 'lighten_2'>
| Extract<keyof GrayscaleColors, 'gc_4' | 'gc_1' | 'font_1'>

type ActionButtonProps = {
$bgColor?: BgColorType
$type?: 'roundedRect' | 'semiRoundedRect' | 'capsule'
}

type ActionButtonStyles = {
padding: string
borderRadius: string
fontSize: string
}

const ACTION_BUTTON_FONT_COLORS: Record<BgColorType, keyof GrayscaleColors> = {
default: 'gc_4',
lighten_2: 'font_1',
font_1: 'gc_4',
gc_4: 'font_1',
gc_1: 'font_4',
} as const

const ACTION_BUTTON_STYLES: Record<string, ActionButtonStyles> = {
roundedRect: {
padding: '15.5px 24px',
borderRadius: '12px',
fontSize: '_14',
},
semiRoundedRect: {
padding: '16.5px 24px',
borderRadius: '20px',
fontSize: '_15',
},
capsule: {
padding: '18px 24px',
borderRadius: '100px',
fontSize: '_17',
},
}

export const ActionButton = styled.button<ActionButtonProps>`
width: 100%;
background-color: ${({ theme, $bgColor = 'default' }) =>
theme.colors.grayscale[$bgColor] || theme.colors.brand[$bgColor]};
color: ${({ theme, $bgColor = 'default' }) => theme.colors.grayscale[ACTION_BUTTON_FONT_COLORS[$bgColor]]};
padding: ${({ $type = 'capsule' }) => ACTION_BUTTON_STYLES[$type]?.padding};
border-radius: ${({ $type = 'capsule' }) => ACTION_BUTTON_STYLES[$type]?.borderRadius};
font-size: ${({ theme, $type = 'capsule' }) => theme.typography[ACTION_BUTTON_STYLES[$type]?.fontSize]};
`
27 changes: 27 additions & 0 deletions src/components/Input/TwoLineInput/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { TEXTAREA_VALIDATION } from '@constants/validations'
import { ChangeEvent, useState } from 'react'
import { TextareaAutosizeProps } from 'react-textarea-autosize'
import * as S from './styles'

type TwoLineInputProps = TextareaAutosizeProps

export default function TwoLineInput({ ...rest }: TwoLineInputProps) {
const [value, setValue] = useState('')

const onChange = (e: ChangeEvent<HTMLTextAreaElement>) => {
const currentValue = e.target.value
const lines = currentValue.split('\n')

if (lines.length > 2) {
const limitedValue = lines.slice(0, 2).join('\n')
setValue(limitedValue)
return
}

setValue(currentValue)
}

return (
<S.TwoLineInput maxRows={2} value={value} onChange={onChange} maxLength={TEXTAREA_VALIDATION.maxLength} {...rest} />
)
}
16 changes: 16 additions & 0 deletions src/components/Input/TwoLineInput/styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { styled } from 'styled-components'
import TextareaAutosize from 'react-textarea-autosize'

export const TwoLineInput = styled(TextareaAutosize)`
width: 100%;
border: none;
text-align: center;
padding: 17px 32px;
border-radius: 12px;
font-size: ${({ theme }) => theme.typography._20};
resize: none; // 수동 리사이즈 방지
overflow: hidden; // 스크롤바 제거
&:focus {
box-shadow: ${({ theme }) => `inset 0 0 0 1px ${theme.colors.grayscale.font_1}`};
}
`
14 changes: 14 additions & 0 deletions src/components/Input/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { styled } from 'styled-components'

export const Input = styled.input`
width: 100%;
border: none;
font-size: ${({ theme }) => theme.typography._20};
text-align: center;
/* transition: 0.15s box-shadow; */
padding: 17px 32px;
border-radius: 12px;
&:focus {
box-shadow: ${({ theme }) => `inset 0 0 0 1px ${theme.colors.grayscale.font_1}`};
}
`
25 changes: 25 additions & 0 deletions src/components/Toggle/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { SettingsStoreKey, useSettingsStore } from '@stores/settingsStore'
import * as S from './styles'

type ToggleProps = {
id: string
setting: SettingsStoreKey
}

export default function Toggle({ id, setting }: ToggleProps) {
const value = useSettingsStore(state => state[setting])
const setSetting = useSettingsStore(state => state.setSetting)

const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setSetting(setting, e.target.checked)
}

return (
<S.Toggle>
<input name={id} id={id} type='checkbox' checked={value} onChange={handleChange} hidden />
<label htmlFor={id}>
<S.Circle />
</label>
</S.Toggle>
)
}
42 changes: 42 additions & 0 deletions src/components/Toggle/styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { styled } from 'styled-components'

export const Toggle = styled.div`
display: block;
width: fit-content;
border-radius: 100px;
position: relative;
overflow: hidden;
width: 40px;
height: 24px;

& > label {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
z-index: 1;
cursor: pointer;
background-color: ${({ theme }) => theme.colors.grayscale.gc_1};
transition: background-color 0.3s;
}
& > input:checked + label {
background-color: ${({ theme }) => theme.colors.grayscale.font_1};
}
`

export const Circle = styled.div`
position: absolute;
top: 50%;
left: 2px;
translate: 0 -50%;
width: 20px;
height: 20px;
border-radius: 50%;
transition: background-color 0.3s ease;
background-color: ${({ theme }) => theme.colors.grayscale.gc_4};
input:checked + label > & {
translate: 16px -50%;
}
transition: translate 0.3s;
`
13 changes: 13 additions & 0 deletions src/components/ToggleArea/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import ToggleBox from '@components/ToggleBox'
import * as S from './styles'

export default function ToggleArea() {
return (
<S.ToggleArea>
<ToggleBox setting={'friendRequests'} type='lg' />
<ToggleBox setting={'familyWalkNotifications'} type='lg' />
<ToggleBox setting={'myWalkNotifications'} type='lg' />
<ToggleBox setting={'messages'} type='lg' />
</S.ToggleArea>
)
}
3 changes: 3 additions & 0 deletions src/components/ToggleArea/styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { styled } from 'styled-components'

export const ToggleArea = styled.div``
33 changes: 33 additions & 0 deletions src/components/ToggleBox/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import Toggle from '@components/Toggle'
import { Typo14, Typo15, Typo17 } from '@components/Typo'
import { SETTINGS_INFO } from '@constants/settingsInfo'
import { SettingsStoreKey } from '@stores/settingsStore'
import * as S from './styles'

type ToggleBoxProps = {
type: 'sm' | 'md' | 'lg'
setting: SettingsStoreKey
}

const Typo = {
sm: Typo14,
md: Typo15,
lg: Typo17,
}

/**
*주의! 단독으로 사용할 경우, Wrapper로 감싸주셔야 border radius가 적용됩니다.
*/
export default function ToggleBox({ setting, type }: ToggleBoxProps) {
const SelectedTypo = Typo[type]

return (
<S.ToggleBox $type={type}>
<S.MainArea>
<SelectedTypo weight='700'>{SETTINGS_INFO[setting].title}</SelectedTypo>
{SETTINGS_INFO[setting].desc && <Typo15>{SETTINGS_INFO[setting].desc}</Typo15>}
</S.MainArea>
<Toggle id={setting} setting={setting} />
</S.ToggleBox>
)
}
29 changes: 29 additions & 0 deletions src/components/ToggleBox/styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { styled } from 'styled-components'

type ToggleBoxProps = {
$type: 'sm' | 'md' | 'lg'
}

const TOGGLE_BOX_PADDING = {
sm: '15.5px 16px 15.5px 20px',
md: '16.5px 16px 16.5px 20px',
lg: '18px 16px 18px 20px',
}
export const ToggleBox = styled.div<ToggleBoxProps>`
display: flex;
justify-content: space-between;
align-items: center;
padding: ${({ $type }) => TOGGLE_BOX_PADDING[$type]};
background-color: ${({ theme }) => theme.colors.grayscale.gc_4};

&:first-of-type {
border-top-left-radius: 16px;
border-top-right-radius: 16px;
}
&:last-of-type {
border-bottom-left-radius: 16px;
border-bottom-right-radius: 16px;
}
`

export const MainArea = styled.div``
Loading
Loading