Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 5 additions & 0 deletions .changeset/sharp-walls-happen.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@musma/react-component": patch
---

feat: Flex Box
30 changes: 30 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
name: "BUG \b템플릿"
about: 어떤 버그를 수정할 예정인가요? (버그의 예상 원인, 해결 방법 등등)
title: '[BUG]'
labels: ''
assignees: ''
---

## :fire: Description

_어떤 버그를 수정할 예정인가요? (버그의 예상 원인, 해결 방법 등등)_

<hr>

## :hammer: TODO

- [ ] 할일1
- [ ] 할일2

<hr>

## :books: Reference

_버그 픽스에 참고한 내용이 있나요? (블로그, 공식문서 등등)_

<hr>

## :bell: ETC

_메모할 사항이 있나요? (다른 개발자가 봤을 때 참고하면 좋을 내용, PR에 전달할 내용 등등)_
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
blank_issues_enabled: false
30 changes: 30 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
name: "FEATURE \b템플릿"
about: 어떤 기능을 만드나요? (기능 설명, 목표 등등)
title: '[FEATURE]'
labels: ''
assignees: ''
---

## :mag: Description

_어떤 기능을 만드나요? (기능 설명, 목표 등등)_

<hr>

## :hammer: TODO

- [ ] 할일1
- [ ] 할일2

<hr>

## :books: Reference

_기능 구현에 참고한 내용이 있나요? (블로그, 공식문서 등등)_

<hr>

## :bell: ETC

_메모할 사항이 있나요? (다른 개발자가 봤을 때 참고하면 좋을 내용, PR에 전달할 내용 등등)_
10 changes: 10 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
## 변경사항

## 이슈 번호 또는 링크

## 리뷰 요청하기전 체크 리스트

- [ ] 내 코드를 스스로 리뷰해봤나요?
- [ ] 로컬 환경에서 빌드 성공했나요?
- [ ] 테스트 실시했나요?
- [ ] 테스트 코드 작성했나요? (추후에..)
140 changes: 140 additions & 0 deletions packages/react-component/src/components/Flex/Flex.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
import { HTMLAttributes, forwardRef, memo, useMemo } from 'react'

import { useTheme } from '@emotion/react'

import { Box } from 'src/elements'
import { Size } from 'src/types'

enum AlignItems {
Start = 'flex-start',
Center = 'center',
End = 'flex-end',
Baseline = 'baseline',
Stretch = 'stretch',
}

enum JustifyContent {
Start = 'flex-start',
Center = 'center',
End = 'flex-end',
Between = 'space-between',
}

type FlexDirectionType = 'row' | 'row-reverse' | 'column' | 'column-reverse'

type JustifyContentType = 'start' | 'center' | 'end' | 'between'

type AlignItemsType = 'start' | 'center' | 'end' | 'baseline' | 'stretch'

interface FlexProps extends HTMLAttributes<HTMLDivElement> {
/**
* Flex Item 간의 간격
*/
spacing?: Size | number
/**
* Flex Item 간의 간격
*/
rowSpacing?: Size | number
/**
* Flex Item 간의 간격
*/
colSpacing?: Size | number
/**
* Flex 컨테이너의 축 변경
*/
direction?: FlexDirectionType
/**
* Flex 컨테이너의 축에 방향에 따라 아이템과의 정렬 방식
*/
justify?: JustifyContentType
/**
* Flex 컨테이너의 축에 방향에 따라 아이템과의 정렬 방식
*/
align?: AlignItemsType
}

/**
* CSS Flex를 사용할 때, 사용하는 박스입니다.
*/
export const Flex = memo(
forwardRef<HTMLDivElement, FlexProps>(
({ spacing, rowSpacing, colSpacing, direction = 'row', justify, align, ...rest }, ref) => {
const theme = useTheme()

const gap = useMemo(() => {
if (spacing) {
if (typeof spacing === 'number') {
return spacing
}
return theme.spacing[spacing]
}
}, [spacing])

const rowGap = useMemo(() => {
if (rowSpacing) {
if (typeof rowSpacing === 'number') {
return rowSpacing
}
return theme.spacing[rowSpacing]
}
}, [rowSpacing])

const columnGap = useMemo(() => {
if (colSpacing) {
if (typeof colSpacing === 'number') {
return colSpacing
}
return theme.spacing[colSpacing]
}
}, [colSpacing])

const alignItems = useMemo(() => {
switch (align) {
case 'start':
return AlignItems.Start
case 'center':
return AlignItems.Center
case 'end':
return AlignItems.End
case 'baseline':
return AlignItems.Baseline
case 'stretch':
return AlignItems.Stretch
default:
}
}, [align])

const justifyContent = useMemo(() => {
switch (justify) {
case 'start':
return JustifyContent.Start
case 'center':
return JustifyContent.Center
case 'end':
return JustifyContent.End
case 'between':
return JustifyContent.Between
default:
}
}, [justify])

return (
<Box
ref={ref}
css={{
display: 'flex',
gap,
rowGap,
columnGap,
flexDirection: direction,
justifyContent,
alignItems,
}}
{...rest}
/>
)
},
),
)

Flex.displayName = 'Flex'
1 change: 1 addition & 0 deletions packages/react-component/src/components/Flex/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './Flex'
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ export function TableBody<T extends TableDataProps>({
css={[
{
backgroundColor: theme.colors.white.main,
borderBottom: `1px solid ${theme.colors.white.lighter}`,
borderBottom: `1px solid ${theme.colors.gray.lighter}`,
color: theme.colors.black.dark,
'&:last-of-type': {
borderBottom: 'none',
Expand All @@ -105,7 +105,7 @@ export function TableBody<T extends TableDataProps>({
onRowClick && {
'&:hover': {
cursor: 'pointer',
backgroundColor: theme.colors.white.darker,
backgroundColor: theme.colors.blue.lighter,
},
},
]}
Expand Down
94 changes: 23 additions & 71 deletions packages/react-component/src/components/TextInput/TextInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,119 +22,71 @@ import { handleRegExpText, InputType, RulesType } from './helpers'
export interface TextInputProps
extends Omit<InputHTMLAttributes<HTMLInputElement>, 'type' | 'size'> {
/**
* @optional
* @type {string}
* @default text
*
* 'text' | 'password'
*
* @description
* Input의 타입을 정합니다 'password'가 입력되면, endAdornment가 활성화됩니다
* 입력 필드의 타입을 정합니다 'password'가 입력되면, Password Eye가 활성화됩니다
*/
type?: InputType
/**
* @optional
* @type {string}
* @default md
*
* 'sm' | 'md' | 'lg'
*
* @description
* Input 구성요소들의 사이즈입니다
* 입력 필드 구성요소들의 사이즈입니다
*/
size?: Size
/**
* @optional
*
* @description
* Input 위에 표시될 라벨입니다
* 입력 필드 위에 표시될 라벨입니다
*/
label?: string
/**
* @optional
* @returns JSX.Element
*
* @description
* Input 시작지점 아이콘 버튼입니다
* 입력 필드 시작지점 아이콘입니다.
*/
startAdornment?: ReactNode | ((props: SVGProps<SVGSVGElement>) => JSX.Element)
/**
* @optional
* @returns JSX.Element
*
* @description
* Input 종료지점 아이콘 버튼입니다
* 입력 필드 종료지점 아이콘입니다.
*/
endAdornment?: ReactNode | ((props: SVGProps<SVGSVGElement>) => JSX.Element)
/**
* @optional
* @type {boolean}
*
* false이면, borderColor에 'red'가 적용됩니다
* || true이면, borderColor에 'gray'가 적용됩니다
* 1. 값이 false이면, borderColor에 'gray'가 적용됩니다
* 2. 값이 true이면, borderColor에 'red'가 적용됩니다
*
* @description
* 에러 발생시 borderColor를 불린 값에 따라 변경합니다
* error의 불린 값에 따라 입력 필드의 borderColor와 helperText의 텍스트 컬러를 제어합니다.
*/
error?: boolean
/**
* @optional
*
* @description
* Input 밑에 나타나는 도움 글입니다
* @description
* default color는 'green'이며, error props의 값이 true이면, 'red'가 적용됩니다
* 1. error Props의 값이 false이면, 텍스트와 아이콘의 컬러가 'green'으로 적용됩니다.
* 2. error props의 값이 true이면, 텍스트와 아이콘의 컬러가 'red'로 적용됩니다.
*
* 입력 필드 밑에 나타나는 도움 글입니다 error와 같이 사용 됩니다.
*/
helperText?: string
/**
* @optional
* @type {boolean}
* false이면, 사용하지 않습니다
* || true이면, label 옆에 *가 표시됩니다
*
* @description
* Input의 label에 표시될 *의 사용여부입니다
* 1. 값을 입력하지 않으면, *가 표시되지 않습니다.
* 2. true이면, label 옆에 *가 표시됩니다
*
* 입력 필드의 label에 표시될 *의 사용여부입니다
*/
withAsterisk?: boolean
/**
* @optional
* @type {string}
*
* @value
* 'onlyDigit' | 'onlyDigitAndDash' | 'onlyDigitAndDot' | 'onlyDigitAndDotDash'
* | 'onlyEnglish' | 'onlyEnglishAndDash' | 'onlyEnglishAndDot' | 'onlyEnglishAndDotDash'
* | 'onlyEnglishAndDigit'
*
* @description
* 입력하는 값을 rules에 따라 제한합니다
*/
rules?: RulesType
/**
* @default
* false
*
* 1. 값이 false이면, 텍스트의 양 사이드에 비어있는 텍스트 값이 제거됩니다.
* 2. 값이 true이면, 텍스트의 양 사이드에 비어있는 텍스트 값이 제거되지 않습니다.
*
* value에 trim() 처리 여부입니다.
*/
disabledTrim?: boolean
}

/**
* @param InputHTMLAttributes(optional)
* @param type(optional) Input의 타입을 정합니다 'password'가 입력되면, endAdornment가 활성화됩니다
* @param size(optional) Input 구성요소들의 사이즈입니다
* @param label(optional) Input 위에 표시될 라벨입니다
* @param startAdornment(optional) Input 시작지점 아이콘 버튼입니다
* @param endAdornment(optional) Input 종료지점 아이콘 버튼입니다
* @param error(optional) 에러 발생시 borderColor를 불린 값에 따라 변경합니다
* @param helperText(optional) default color는 'green'이며, error props의 값이 true이면, 'red'가 적용됩니다
* @param required(optional) Input의 label에 표시될 *의 사용여부입니다
* @param rules(optional) Input에 입력하는 값을 rules에 따라 제한합니다
* @example
* <TextInput
* label='ID'
* rules='onlyEmail'
* value={value}
* onChange={onChange}
* />
* https://www.developers.musma.net/docs/react-components/textinput
*
* @description
* Text를 입력할 수 있는 Input입니다
*/
export const TextInput = forwardRef<HTMLInputElement, TextInputProps>(
Expand Down
Loading