Skip to content

Commit

Permalink
feat(ui-kit): Button 컴포넌트 타입 추가 (#51)
Browse files Browse the repository at this point in the history
* feat(ui-kit): Button 컴포넌트 타입 추가

* refactor(ui-kit): change Combine type to CombineElementProps type
  • Loading branch information
evan-moon authored Feb 21, 2021
1 parent be0fa54 commit f423865
Show file tree
Hide file tree
Showing 12 changed files with 153 additions and 93 deletions.
10 changes: 5 additions & 5 deletions ui-kit/src/components/Accordion/index.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
import React, { forwardRef, HTMLAttributes, useEffect, useRef, useState } from 'react';
import { Combine } from 'src/types/utils';
import React, { forwardRef, useEffect, useRef, useState } from 'react';
import { CombineElementProps } from 'src/types/utils';
import classnames from 'classnames';
import Icon from '../Icon';
import { chevronDown } from 'ionicons/icons';
import Text from '../Text';
import { useResizeObserver } from 'src/hooks/useResizeObserver';
import { colors } from 'src/constants/colors';

type Props = Combine<
type Props = CombineElementProps<
'div',
{
label: string;
defaultOpen?: boolean;
onChange?: (state: boolean) => void;
onOpen?: () => void;
onClose?: () => void;
},
HTMLAttributes<HTMLDivElement>
}
>;
const Accordion = forwardRef<HTMLDivElement, Props>(function Accordion(
{ label, className, children, defaultOpen = false, onChange, onOpen, onClose, ...props },
Expand Down
10 changes: 5 additions & 5 deletions ui-kit/src/components/Alert/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React, { forwardRef, HTMLAttributes } from 'react';
import React, { forwardRef } from 'react';
import { colors, SemanticColor } from 'src/constants/colors';
import classnames from 'classnames';
import Text from '../Text';
import Icon from '../Icon';
import { informationCircle, closeCircle, alertCircle, checkmarkCircle } from 'ionicons/icons';
import { Combine } from 'src/types/utils';
import { CombineElementProps } from 'src/types/utils';

interface AlertIcon {
icon: string;
Expand All @@ -31,12 +31,12 @@ const alertIconMap: {
},
};

type AlertProps = Combine<
type AlertProps = CombineElementProps<
'div',
{
type?: SemanticColor;
title?: string;
},
HTMLAttributes<HTMLDivElement>
}
>;

const Alert = forwardRef<HTMLDivElement, AlertProps>(function Alert(
Expand Down
19 changes: 15 additions & 4 deletions ui-kit/src/components/Button/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,36 @@ import React, { Ref, forwardRef } from 'react';
import classnames from 'classnames';
import { CombineElementProps } from 'src/types/utils';
import Text from '../Text';
import { SemanticColor } from 'src/constants/colors';

interface ButtonBaseProps {
size?: 'small' | 'medium' | 'large';
type?: SemanticColor;
htmlType?: 'button' | 'submit' | 'reset';
}
type ButtonProps = CombineElementProps<'button', ButtonBaseProps>;

const Button = (
{ size = 'small', disabled, style, onClick, ...props }: ButtonProps,
{ size = 'small', disabled, style, type, htmlType, onClick, children, ...props }: ButtonProps,
ref: Ref<HTMLButtonElement>
) => {
return (
<button
className={classnames('lubycon-button', `lubycon-button--${size}`)}
className={classnames(
'lubycon-button',
`lubycon-button--${size}`,
`lubycon-button--type-${type}`
)}
disabled={disabled}
style={style}
style={{ ...style }}
ref={ref}
onClick={onClick}
type={htmlType}
{...props}
>
<Text typography={size === 'large' ? 'p1' : 'p2'} fontWeight="bold" {...props}></Text>
<Text typography={size === 'large' ? 'p1' : 'p2'} fontWeight="bold">
{children}
</Text>
</button>
);
};
Expand Down
10 changes: 5 additions & 5 deletions ui-kit/src/components/Card/CardImageContent.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import React, { HTMLAttributes } from 'react';
import React from 'react';
import classnames from 'classnames';
import { Combine } from 'src/types/utils';
import { CombineElementProps } from 'src/types/utils';

type CardImageContentProps = Combine<
type CardImageContentProps = CombineElementProps<
'img',
{
src: string;
alt: string;
},
HTMLAttributes<HTMLImageElement>
}
>;
const CardImageContent = ({ className, ...props }: CardImageContentProps) => {
return (
Expand Down
17 changes: 5 additions & 12 deletions ui-kit/src/components/Input/index.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,18 @@
import React, {
forwardRef,
InputHTMLAttributes,
isValidElement,
ReactNode,
useMemo,
useState,
} from 'react';
import React, { forwardRef, isValidElement, ReactNode, useMemo, useState } from 'react';
import classnames from 'classnames';
import { Combine } from 'src/types/utils';
import { CombineElementProps } from 'src/types/utils';
import Text from '../Text';

export type TextInputType = 'text' | 'tel' | 'url' | 'email' | 'number' | 'password' | 'search';
type Props = Combine<
type Props = CombineElementProps<
'input',
{
label?: ReactNode;
type?: TextInputType;
right?: ReactNode;
hasError?: boolean;
description?: string;
},
InputHTMLAttributes<HTMLInputElement>
}
>;
const Input = forwardRef<HTMLInputElement, Props>(function Input(
{
Expand Down
25 changes: 14 additions & 11 deletions ui-kit/src/components/List/ListItem.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
import React, { HTMLAttributes, forwardRef, ReactNode } from 'react';
import React, { forwardRef, ReactNode } from 'react';
import classnames from 'classnames';
import { Combine } from 'src/types/utils';
import { CombineElementProps } from 'src/types/utils';
import Text from '../Text';

type Props = Combine<
{
left?: ReactNode;
right?: ReactNode;
title?: string;
content: string;
caption?: string;
},
Omit<HTMLAttributes<HTMLLIElement>, 'children' | 'role'>
type Props = Omit<
CombineElementProps<
'li',
{
left?: ReactNode;
right?: ReactNode;
title?: string;
content: string;
caption?: string;
}
>,
'children' | 'role'
>;
const ListItem = forwardRef<HTMLLIElement, Props>(function ListItem(
{ className, left, right, title, content, caption, onClick, ...props },
Expand Down
9 changes: 8 additions & 1 deletion ui-kit/src/components/Snackbar/SnackbarBody.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { ReactNode, isValidElement } from 'react';
import classnames from 'classnames';
import Text from 'components/Text';
import Button from '../Button';
import { colors } from 'src/constants/colors';

interface Props {
message: string;
Expand All @@ -16,7 +17,13 @@ const SnackbarBody = ({ message, button, onClick }: Props) => {
{message}
</Text>
<div className="lubycon-snackbar__body__buttons">
{isValidElement(button) ? button : <Button onClick={onClick}>{button}</Button>}
{isValidElement(button) ? (
button
) : (
<Button onClick={onClick} style={{ color: colors.blue50 }}>
{button}
</Button>
)}
</div>
</div>
);
Expand Down
29 changes: 16 additions & 13 deletions ui-kit/src/components/Snackbar/index.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
import React, { HTMLAttributes, useEffect, useState, ReactNode } from 'react';
import React, { useEffect, useState, ReactNode } from 'react';
import { animated, useTransition } from 'react-spring';
import classnames from 'classnames';
import SnackbarBody from './SnackbarBody';
import { Combine } from 'src/types/utils';
import { CombineElementProps } from 'src/types/utils';

export type SnackbarProps = Combine<
{
show: boolean;
message: string;
button: ReactNode;
autoHideDuration?: number;
onShow?: () => void;
onHide?: () => void;
onClick?: () => void;
},
Omit<HTMLAttributes<HTMLDivElement>, 'children'>
export type SnackbarProps = Omit<
CombineElementProps<
'div',
{
show: boolean;
message: string;
button: ReactNode;
autoHideDuration?: number;
onShow?: () => void;
onHide?: () => void;
onClick?: () => void;
}
>,
'children'
>;

const Snackbar = ({
Expand Down
36 changes: 31 additions & 5 deletions ui-kit/src/sass/components/_Button.scss
Original file line number Diff line number Diff line change
@@ -1,16 +1,25 @@
@mixin hoverAndActiveStyle($color) {
&:hover,
&:active {
background-color: get-color($color);
}
}

.lubycon-button {
font: inherit;
text-align: inherit;
outline: none;
border: 0;
margin: 0;
background-color: get-color('blue50');
background-color: transparent;
border-radius: 4px;
color: #ffffff;
color: get-color('gray90');
cursor: pointer;
-webkit-font-smoothing: antialiased;
transition: background-color 0.2s ease-in-out;

@include hoverAndActiveStyle('gray20');

&--small {
padding: 4px 16px;
}
Expand All @@ -22,10 +31,27 @@
border-radius: 8px;
}

&:hover,
&:active {
background-color: get-color('blue60');
&--type-informative {
background-color: get-color('blue50');
color: get-color('white');
@include hoverAndActiveStyle('blue60');
}
&--type-positive {
background-color: get-color('green50');
color: get-color('white');
@include hoverAndActiveStyle('green60');
}
&--type-notice {
background-color: get-color('yellow50');
color: get-color('white');
@include hoverAndActiveStyle('yellow60');
}
&--type-negative {
background-color: get-color('red50');
color: get-color('white');
@include hoverAndActiveStyle('red60');
}

&:disabled {
color: get-color('gray60');
background-color: get-color('gray40');
Expand Down
69 changes: 39 additions & 30 deletions ui-kit/src/stories/Button.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import { Button, Text } from 'src';
import { Button, Text, Column, Row } from 'src';
import { Meta } from '@storybook/react/types-6-0';
import { SemanticColor } from 'src/constants/colors';

export default {
title: 'Lubycon UI Kit/Button',
Expand All @@ -12,35 +13,43 @@ const btnText = '버튼 텍스트';
export const Default = () => {
return (
<div>
<Text as="div" typography="h5" style={{ marginBottom: '40px' }}>
Rounded Button
</Text>
<ul style={{ listStyle: 'none' }}>
{sizeList.map((size, index) => (
<li
key={index}
style={{
display: 'grid',
gridTemplateColumns: '100px 150px 150px',
gridGap: '50px',
marginBottom: '30px',
alignItems: 'center',
}}
>
<Text style={{ width: '100px' }}>{size.charAt(0).toUpperCase() + size.slice(1)}</Text>
<div>
<Button size={size} key={index}>
{btnText}
</Button>
</div>
<div>
<Button size={size} key={index + 'disabled'} disabled>
{btnText}
</Button>
</div>
</li>
))}
</ul>
{sizeList.map((size, index) => (
<Row key={index} alignItems="center" style={{ marginBottom: 20 }}>
<Column xs="auto" style={{ width: '100px', marginRight: 40 }}>
<Text>{size.charAt(0).toUpperCase() + size.slice(1)}</Text>
</Column>
<Column>
<Button size={size} key={index}>
{btnText}
</Button>
</Column>
<Column>
<Button size={size} key={index + 'disabled'} disabled>
{btnText}
</Button>
</Column>
</Row>
))}
</div>
);
};

const semanticColors: SemanticColor[] = ['informative', 'negative', 'notice', 'positive'];
export const Types = () => {
return (
<div>
{semanticColors.map((type, index) => (
<Row key={index} alignItems="center" style={{ marginBottom: 20 }}>
<Column xs="auto" style={{ width: '100px', marginRight: 40 }}>
<Text>{type.charAt(0).toUpperCase() + type.slice(1)}</Text>
</Column>
<Column>
<Button key={index} type={type}>
{btnText}
</Button>
</Column>
</Row>
))}
</div>
);
};
Loading

0 comments on commit f423865

Please sign in to comment.