Skip to content

Commit

Permalink
Merge pull request #293 from TEAM-DAWM/feat/#291/common-controlbutton
Browse files Browse the repository at this point in the history
[FEAT] 공통 컴포넌트 컨트롤버튼 퍼블리싱
  • Loading branch information
seong-hui authored Nov 26, 2024
2 parents b9a8cb9 + 07977f2 commit b2036fd
Show file tree
Hide file tree
Showing 12 changed files with 351 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,20 @@ type ButtonProps = {
leftIcon?: ReactElement;
rightIcon?: ReactElement;
label: string;
onClick: () => void;
additionalCss?: SerializedStyles;
onClick?: () => void;
};

function Button({ type, size = 'medium', disabled = false, leftIcon, rightIcon, label, onClick }: ButtonProps) {
function Button({
type,
size = 'medium',
disabled = false,
leftIcon,
rightIcon,
label,
additionalCss,
onClick,
}: ButtonProps) {
const { font, color } = useTheme();
// 크기별 사이즈
const buttonSizes: Record<SizeType, SerializedStyles> = {
Expand Down Expand Up @@ -49,8 +59,6 @@ function Button({ type, size = 'medium', disabled = false, leftIcon, rightIcon,
background-color: transparent;
${border &&
css`
box-sizing: border-box;
border: solid 1px ${color.Grey.Grey4};
`}
`;
Expand All @@ -61,8 +69,6 @@ function Button({ type, size = 'medium', disabled = false, leftIcon, rightIcon,
background-color: ${bgColor};
${border &&
css`
box-sizing: border-box;
border: solid 1px ${baseColor};
`}
Expand Down Expand Up @@ -103,12 +109,15 @@ function Button({ type, size = 'medium', disabled = false, leftIcon, rightIcon,
display: flex;
gap: 0.8rem;
align-items: center;
box-sizing: border-box;
${buttonSizes[size]};
padding-right: 1.6rem;
padding-left: 1.6rem;
${buttonTypeStyle[type]}
border-radius: 8px;
${additionalCss}
`;
return (
<ButtonLayout onClick={disabled ? () => {} : onClick}>
Expand Down
26 changes: 26 additions & 0 deletions src/components/common/v2/control/CheckButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import Button from '../button/Button';

import Icons from '@/assets/svg/index';

type CheckButtonProps = {
label: string;
size: 'small' | 'large';
checked: boolean;
onClick: () => void;
};

function CheckButton({ label, size = 'small', checked = false, onClick }: CheckButtonProps) {
return (
<Button
type={checked ? 'text-primary' : 'text-assistive'}
size={size}
// TODO: 체크 아이콘으로 바꾸기
leftIcon={checked ? <Icons.Navbar.IcnNavDashboard /> : <Icons.Navbar.IcnNavSetting />}
disabled={false}
label={label}
onClick={onClick}
/>
);
}

export default CheckButton;
58 changes: 58 additions & 0 deletions src/components/common/v2/control/DropdownButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { css, useTheme } from '@emotion/react';
import { useState } from 'react';

import Button from '../button/Button';

import Icons from '@/assets/svg/index';

// 추후 type 로 빼기
type TaskStatus = '미완료' | '진행중' | '완료';
type DropdownButtonProps = {
status: TaskStatus;
};

function DropdownButton({ status }: DropdownButtonProps) {
const { shadow } = useTheme();

/** 임시 state */
// open 은 이 컴포넌트 내부에서 다루어질 state 같아서 우선 props로 받지 않았습니다.
// 필요하면 위치 변경 등 추가 작업 자유롭게 하세요
const [isOpen, setOpen] = useState(false);
const handleOpen = () => setOpen((prev) => !prev);
/** 임시 state */

/** status에 따른 버튼 스타일 타입 설정 */
const getDropdownBtnType = () => {
switch (status) {
case '미완료':
return 'outlined-assistive';
case '진행중':
return 'solid';
case '완료':
return 'outlined-primary';

default:
return 'outlined-assistive';
}
};

const customStyle = css`
justify-content: space-between;
width: 9.6rem;
${isOpen && shadow.FloatingAction1}
`;

return (
<Button
type={getDropdownBtnType()}
label={status}
size="medium"
disabled={false}
rightIcon={isOpen ? <Icons.Navbar.IcnNavDashboard /> : <Icons.Navbar.IcnNavSetting />}
additionalCss={customStyle}
onClick={handleOpen}
/>
);
}

export default DropdownButton;
52 changes: 52 additions & 0 deletions src/components/common/v2/control/ToggleLabelButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { css, useTheme } from '@emotion/react';
import styled from '@emotion/styled';

import Button from '../button/Button';

type ToggleLabelButtonProps = {
active: boolean;
firstLabel: string;
secondLabel: string;
onClick: () => void;
};

function ToggleLabelButton({ active, firstLabel, secondLabel, onClick }: ToggleLabelButtonProps) {
const { color } = useTheme();
const toggleBtnCss = css`
justify-content: center;
width: 100%;
`;
const disabledButtonCss = css`
${toggleBtnCss}
background-color: ${color.Grey.Grey3};
`;
return (
<ToggleLabelButtonContainer onClick={onClick}>
<Button
disabled={false}
label={firstLabel}
size="medium"
type="text-assistive"
additionalCss={active ? toggleBtnCss : disabledButtonCss}
/>
<Button
disabled={false}
label={secondLabel}
size="medium"
type="text-assistive"
additionalCss={!active ? toggleBtnCss : disabledButtonCss}
/>
</ToggleLabelButtonContainer>
);
}
const ToggleLabelButtonContainer = styled.div`
display: flex;
width: 16rem;
height: 3.2rem;
background-color: ${({ theme }) => theme.color.Grey.White};
border: solid 1px ${({ theme }) => theme.color.Grey.Grey3};
border-radius: 8px;
`;

export default ToggleLabelButton;
33 changes: 33 additions & 0 deletions src/components/common/v2/control/ToggleSwitchButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import styled from '@emotion/styled';

type ToggleSwitchButtonProps = {
active: boolean;
onClick: () => void;
};

function ToggleSwitchButton({ active, onClick }: ToggleSwitchButtonProps) {
return (
<ToggleSlot active={active} onClick={onClick}>
<ToggleCircle active={active} />
</ToggleSlot>
);
}
const ToggleCircle = styled.div<{ active: boolean }>`
z-index: 1;
width: 2rem;
height: 2rem;
background-color: ${({ theme }) => theme.color.Grey.White};
border: solid 2px ${({ theme, active }) => (active ? theme.color.Blue.Blue7 : theme.color.Grey.Grey4)};
border-radius: 50%;
`;
const ToggleSlot = styled.div<{ active: boolean }>`
display: flex;
justify-content: ${(props) => (props.active ? 'flex-start' : 'flex-end')};
width: 4.4rem;
height: 2.4rem;
background-color: ${({ theme, active }) => (active ? theme.color.Blue.Blue7 : theme.color.Grey.Grey4)};
border-radius: 14px;
`;
export default ToggleSwitchButton;
4 changes: 2 additions & 2 deletions src/stories/Common/Button/Button.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import type { Meta, StoryObj } from '@storybook/react';
import { fn } from '@storybook/test';

import Icons from '@/assets/svg/index';
import Button from '@/components/common/v2/Button';
import Button from '@/components/common/v2/button/Button';

const meta = {
title: 'Common/Button',
title: 'Common/Button/Button',
component: Button,
parameters: {
layout: 'centered',
Expand Down
51 changes: 51 additions & 0 deletions src/stories/Common/Button/CheckButton.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import type { Meta, StoryObj } from '@storybook/react';
import { fn } from '@storybook/test';

import CheckButton from '@/components/common/v2/control/CheckButton';

const meta = {
title: 'Common/Control/CheckButton',
component: CheckButton,
parameters: {
layout: 'centered',
},
tags: ['autodocs'],
args: { onClick: fn() },
} satisfies Meta<typeof CheckButton>;

export default meta;

type Story = StoryObj<typeof meta>;

export const CheckedLargeButton: Story = {
args: {
label: '하루종일',
size: 'large',
checked: true,
onClick: fn(),
},
};
export const CheckedSmallButton: Story = {
args: {
label: '하루종일',
size: 'small',
checked: true,
onClick: fn(),
},
};
export const NotCheckedLargeButton: Story = {
args: {
label: '하루종일',
size: 'large',
checked: false,
onClick: fn(),
},
};
export const NotCheckedSmallButton: Story = {
args: {
label: '하루종일',
size: 'small',
checked: false,
onClick: fn(),
},
};
33 changes: 33 additions & 0 deletions src/stories/Common/Button/DropdownButton.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import type { Meta, StoryObj } from '@storybook/react';

import DropdownButton from '@/components/common/v2/control/DropdownButton';

const meta = {
title: 'Common/Control/DropdownButton',
component: DropdownButton,
parameters: {
layout: 'centered',
},
tags: ['autodocs'],
} satisfies Meta<typeof DropdownButton>;

export default meta;

type Story = StoryObj<typeof meta>;

export const Incomplete: Story = {
args: {
status: '미완료',
},
};

export const Inprogress: Story = {
args: {
status: '진행중',
},
};
export const Complete: Story = {
args: {
status: '완료',
},
};
36 changes: 36 additions & 0 deletions src/stories/Common/Button/ToggleLabelButton.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import type { Meta, StoryObj } from '@storybook/react';
import { fn } from '@storybook/test';

import ToggleLabelButton from '@/components/common/v2/control/ToggleLabelButton';

const meta = {
title: 'Common/Control/ToggleLabelButton',
component: ToggleLabelButton,
parameters: {
layout: 'centered',
},
tags: ['autodocs'],
args: { onClick: fn() },
} satisfies Meta<typeof ToggleLabelButton>;

export default meta;

type Story = StoryObj<typeof meta>;

export const ToggleLabelOn: Story = {
args: {
active: true,
firstLabel: '주',
secondLabel: '일',
onClick: fn(),
},
};

export const ToggleLabelOff: Story = {
args: {
active: false,
firstLabel: '주',
secondLabel: '일',
onClick: fn(),
},
};
25 changes: 25 additions & 0 deletions src/stories/Common/Button/ToggleSwitchButton.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import type { Meta, StoryObj } from '@storybook/react';
import { fn } from '@storybook/test';

import ToggleSwitchButton from '@/components/common/v2/control/ToggleSwitchButton';

const meta = {
title: 'Common/Control/ToggleSwitchButton',
component: ToggleSwitchButton,
parameters: {
layout: 'centered',
},
tags: ['autodocs'],
args: { onClick: fn() },
} satisfies Meta<typeof ToggleSwitchButton>;

export default meta;

type Story = StoryObj<typeof meta>;

export const ToggleSwitchOnButton: Story = {
args: {
active: true,
onClick: fn(),
},
};
Loading

0 comments on commit b2036fd

Please sign in to comment.