Skip to content

Commit

Permalink
Merge pull request #290 from TEAM-DAWM/feat/#289/common-iconbutton
Browse files Browse the repository at this point in the history
[FEAT] 공통 컴포넌트 아이콘버튼 퍼블리싱
  • Loading branch information
seong-hui authored Nov 26, 2024
2 parents b2036fd + 1a7bed6 commit 830dfd8
Show file tree
Hide file tree
Showing 2 changed files with 141 additions and 0 deletions.
94 changes: 94 additions & 0 deletions src/components/common/v2/IconButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import { css, SerializedStyles, useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { ReactElement } from 'react';

type SizeType = 'small' | 'big';
type IconBtnType = 'solid' | 'normal' | 'outlined';
type IconButtonProps = {
type: IconBtnType;
size: SizeType;
disabled: boolean;
Icon: ReactElement;
onClick: () => void;
};

function IconButton({ type, size = 'small', disabled = false, Icon, onClick }: IconButtonProps) {
const { color } = useTheme();
// 사이즈별 분기
const buttonSizes: Record<SizeType, SerializedStyles> = {
big: css`
width: 4rem;
height: 4rem;
`,
small: css`
width: 3.2rem;
height: 3.2rem;
`,
};

// 아이콘 배경 색상 및 테두리
const getIconBtnStyles = (
strokeColor: string,
defaultBG: string,
hoverBG: string,
pressedBG: string,
border: boolean
) => {
if (disabled) {
if (type === 'solid')
return css`
color: ${color.Grey.White};
background-color: ${color.Blue.Blue2};
`;
return css`
color: ${color.Grey.Grey4};
${border &&
css`
box-sizing: border-box;
border: solid 1px ${color.Grey.Grey3};
`};
`;
}
return css`
color: ${strokeColor};
background-color: ${defaultBG};
${border &&
css`
box-sizing: border-box;
border: solid 1px ${color.Grey.Grey4};
`}
:hover {
background-color: ${hoverBG};
}
:active {
background-color: ${pressedBG};
}
`;
};
const buttonStyles: Record<IconBtnType, SerializedStyles> = {
solid: getIconBtnStyles(color.Grey.White, color.Blue.Blue6, color.Blue.Blue7, color.Blue.Blue8, false),
normal: getIconBtnStyles(color.Grey.Grey5, color.Grey.White, color.Grey.Grey2, color.Grey.Grey3, false),
outlined: getIconBtnStyles(color.Grey.Grey5, color.Grey.White, color.Grey.Grey2, color.Grey.Grey3, true),
};

const IconBtnContainer = styled.div`
display: flex;
${buttonSizes[size]}
align-items: center;
justify-content: center;
border-radius: 8px;
${buttonStyles[type]}
`;

return <IconBtnContainer onClick={disabled ? () => {} : onClick}>{Icon}</IconBtnContainer>;
}

export default IconButton;
47 changes: 47 additions & 0 deletions src/stories/Common/Button/IconButton.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import type { Meta, StoryObj } from '@storybook/react';
import { fn } from '@storybook/test';

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

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

export default meta;

type Story = StoryObj<typeof meta>;

export const Solid: Story = {
args: {
type: 'solid',
size: 'big',
disabled: false,
Icon: <Icons.Navbar.IcnNavDashboard />,
onClick: fn(),
},
};
export const Normal: Story = {
args: {
type: 'normal',
size: 'big',
disabled: false,
Icon: <Icons.Navbar.IcnNavDashboard />,
onClick: fn(),
},
};
export const Outlined: Story = {
args: {
type: 'outlined',
size: 'big',
disabled: false,
Icon: <Icons.Navbar.IcnNavDashboard />,
onClick: fn(),
},
};

0 comments on commit 830dfd8

Please sign in to comment.