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

[FEAT] 마감기한 공통컴포넌트 퍼블리싱 #39

Merged
merged 7 commits into from
Jul 7, 2024
Merged
Show file tree
Hide file tree
Changes from 6 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
118 changes: 59 additions & 59 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,61 +1,61 @@
{
"name": "client",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc -b && vite build",
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview",
"stylelint": "stylelint './src/**/*.{ts,tsx}' --fix",
"svgr": "npx @svgr/cli -d src/assets/svg --ignore-existing --typescript --no-dimensions public/svg",
"storybook": "storybook dev -p 6006",
"build-storybook": "storybook build"
},
"dependencies": {
"@emotion/react": "^11.11.4",
"@emotion/styled": "^11.11.5",
"@svgr/cli": "^8.1.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-router-dom": "^6.24.1",
"vite-plugin-svgr": "^4.2.0"
},
"devDependencies": {
"@chromatic-com/storybook": "^1.6.1",
"@storybook/addon-essentials": "^8.1.11",
"@storybook/addon-interactions": "^8.1.11",
"@storybook/addon-links": "^8.1.11",
"@storybook/addon-onboarding": "^8.1.11",
"@storybook/blocks": "^8.1.11",
"@storybook/react": "^8.1.11",
"@storybook/react-vite": "^8.1.11",
"@storybook/test": "^8.1.11",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"@typescript-eslint/eslint-plugin": "^7.13.1",
"@typescript-eslint/parser": "^7.13.1",
"@vitejs/plugin-react": "^4.3.1",
"eslint": "^8.57.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-config-airbnb-typescript": "^18.0.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-import": "^2.25.3",
"eslint-plugin-jsx-a11y": "^6.5.1",
"eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-react": "^7.28.0",
"eslint-plugin-react-hooks": "^4.6.2",
"eslint-plugin-react-refresh": "^0.4.7",
"eslint-plugin-storybook": "^0.8.0",
"postcss": "^8.4.21",
"postcss-styled-syntax": "^0.6.4",
"prettier": "^3.3.2",
"storybook": "^8.1.11",
"stylelint": "^16.6.1",
"stylelint-config-standard": "^36.0.1",
"stylelint-order": "^6.0.4",
"typescript": "^5.2.2",
"vite": "^5.3.1"
}
"name": "client",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc -b && vite build",
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview",
"stylelint": "stylelint './src/**/*.{ts,tsx}' --fix",
"svgr": "npx @svgr/cli -d src/assets/svg --ignore-existing --typescript --no-dimensions public/svg",
"storybook": "storybook dev -p 6006",
"build-storybook": "storybook build"
},
"dependencies": {
"@emotion/react": "^11.11.4",
"@emotion/styled": "^11.11.5",
"@svgr/cli": "^8.1.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-router-dom": "^6.24.1",
"vite-plugin-svgr": "^4.2.0"
},
"devDependencies": {
"@chromatic-com/storybook": "^1.6.1",
"@storybook/addon-essentials": "^8.1.11",
"@storybook/addon-interactions": "^8.1.11",
"@storybook/addon-links": "^8.1.11",
"@storybook/addon-onboarding": "^8.1.11",
"@storybook/blocks": "^8.1.11",
"@storybook/react": "^8.1.11",
"@storybook/react-vite": "^8.1.11",
"@storybook/test": "^8.1.11",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"@typescript-eslint/eslint-plugin": "^7.13.1",
"@typescript-eslint/parser": "^7.13.1",
"@vitejs/plugin-react": "^4.3.1",
"eslint": "^8.57.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-config-airbnb-typescript": "^18.0.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-import": "^2.25.3",
"eslint-plugin-jsx-a11y": "^6.5.1",
"eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-react": "^7.28.0",
"eslint-plugin-react-hooks": "^4.6.2",
"eslint-plugin-react-refresh": "^0.4.7",
"eslint-plugin-storybook": "^0.8.0",
"postcss": "^8.4.21",
"postcss-styled-syntax": "^0.6.4",
"prettier": "^3.3.2",
"storybook": "^8.1.11",
"stylelint": "^16.6.1",
"stylelint-config-standard": "^36.0.1",
"stylelint-order": "^6.0.4",
"typescript": "^5.2.2",
"vite": "^5.3.1"
}
}
5 changes: 5 additions & 0 deletions src/assets/svg/calendar-minus-01.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions src/assets/svg/clock.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions src/assets/svg/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,18 @@ import Icn_nav_dashboard from '@/assets/svg/icn_nav_dashboard.svg?react';
import Icn_nav_setting from '@/assets/svg/icn_nav_setting.svg?react';
import Icn_nav_today from '@/assets/svg/icn_nav_today.svg?react';

import Icn_calander from '../../assets/svg/calendar-minus-01.svg?react';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기 절대 경로로 바꾸면 더 좋을 것 같아요!

import Icn_date_clock from '../../assets/svg/clock.svg?react';
import Icn_line from '../../assets/svg/line164.svg?react';
import IcnXCricle from '../../assets/svg/x-circle.svg?react';

const Icons = {
Icn_clock,
Icn_arrow_narrow_right,
Icn_calander,
Icn_date_clock,
Icn_line,
IcnXCricle,
Navbar: {
Icn_nav_calendar,
Icn_nav_dashboard,
Expand Down
3 changes: 3 additions & 0 deletions src/assets/svg/line164.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions src/assets/svg/x-circle.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
167 changes: 167 additions & 0 deletions src/components/commons/BtnDate.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
import styled from '@emotion/styled';
import { useState } from 'react';

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

interface BtnDateProps {
date?: string;
time?: string;
size?: string;
}

const BtnDate = (props: BtnDateProps) => {
const { date = '마감 기한', time = '마감 시간', size = 'big' } = props;
const [isPressed, setIsPressed] = useState(false);
const [isClicked, setIsClicked] = useState(false);

const handleMouseDown = () => {
setIsPressed(true);
};

const handleMouseUp = () => {
setIsPressed(false);
setIsClicked((prev) => !prev);
};

const isDefaultDate = date === '마감 기한';
const isDefaultTime = time === '마감 시간';

return (
<BtnDateLayout
isPressed={isPressed}
isClicked={isClicked}
size={size}
isDefaultDate={isDefaultDate}
isDefaultTime={isDefaultTime}
onMouseDown={handleMouseDown}
onMouseUp={handleMouseUp}
>
<BtnDateContainer>
<CalanderIcon />
<TextWrapper isDefault={isDefaultDate} size={size}>
{date}
</TextWrapper>
</BtnDateContainer>
<LineIcon size={size} />
<BtnDateContainer>
<ClockIcon />
<TextWrapper isDefault={isDefaultTime} size={size}>
{time}
</TextWrapper>
</BtnDateContainer>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기 BtnDateContainer 로 감싼 아이콘, date, time 정도만 달라지는 부분이 있는데 컴포넌트로 따로 빼면 코드 중복 줄일 수 있을 것 같습니다! 코드 길이도 짧아져서 가독성에도 더 좋을 것 같아요!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

넵 적용했어요!!

<XIcon isClicked={isClicked} />
</BtnDateLayout>
);
};

export default BtnDate;

const XIcon = styled((props: React.SVGProps<SVGSVGElement> & { isClicked: boolean }) => {
const { isClicked, ...rest } = props;
return <Icons.IcnXCricle {...rest} />;
})<{ isClicked: boolean }>`
width: 2rem;
height: 2rem;
display: ${({ isClicked }) => (isClicked ? 'flex' : 'none')};
`;

const CalanderIcon = styled(Icons.Icn_calander, { target: 'CalanderIcon' })`
display: flex;
width: 1.4rem;
height: 1.4rem;
justify-content: center;
align-items: center;
`;

const ClockIcon = styled(Icons.Icn_date_clock, { target: 'ClockIcon' })`
display: flex;
width: 1.4rem;
height: 1.4rem;
justify-content: center;
align-items: center;
`;

const LineIcon = styled(Icons.Icn_line, { target: 'LineIcon' })<{ size: string }>`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오홍 tartget을 사용하는 방법이 있군요!!

display: flex;
width: 0.1rem;
height: ${({ size }) => (size === 'big' ? '2.2rem' : '1.2rem')};
justify-content: center;
align-items: center;
`;

const TextWrapper = styled('div', { target: 'TextWrapper' })<{ isDefault: boolean; size: string }>`
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 1rem;
color: ${({ isDefault, theme }) => (isDefault ? theme.palette.grey5 : theme.palette.black)};
font-size: ${({ size }) => (size === 'big' ? '1.4rem' : '1.2rem')};
`;

const BtnDateContainer = styled.div`
display: flex;
align-items: center;
gap: 0.4rem;
`;

const BtnDateLayout = styled.div<{
isPressed: boolean;
isClicked: boolean;
size: string;
isDefaultDate: boolean;
isDefaultTime: boolean;
}>`
display: flex;
width: fit-content;
min-width: 1.8rem;
padding: 0.5rem 1rem;
gap: 1rem;
align-items: center;
border-radius: 0.8rem;
border: 0.1rem solid ${({ theme }) => theme.palette.grey3};
background: ${({ theme }) => theme.palette.white};
cursor: pointer;
border-color: ${({ isClicked, theme }) => (isClicked ? theme.palette.primary : theme.palette.grey3)};

${({ isPressed }) =>
isPressed &&
`
border-width: 0rem;
`}

${({ isClicked, size, theme }) =>
isClicked &&
`
padding-right: ${size === 'big' ? '0.6rem' : '0.2rem'};
border-width: 0.2rem;
border-color: ${theme.palette.primary};
`}

&:hover {
background: ${({ isPressed, theme }) => (isPressed ? theme.palette.grey5 : theme.palette.grey4)};
color: ${({ isPressed, theme }) => (isPressed ? theme.palette.white : theme.palette.grey6)};
border-width: 0rem;

${TextWrapper} {
color: ${({ isDefaultDate, isDefaultTime, theme }) =>
isDefaultDate || isDefaultTime ? theme.palette.grey6 : theme.palette.black};
}
}

${({ isPressed, theme }) =>
isPressed &&
`
${TextWrapper} {
color: ${theme.palette.white};
}
`}

&:hover ${CalanderIcon}, &:hover ${ClockIcon}, &:hover ${LineIcon} {
path {
stroke: ${({ isPressed, theme }) => (isPressed ? theme.palette.grey4 : theme.palette.grey5)};
}
line {
stroke: ${({ isPressed, theme }) => (isPressed ? theme.palette.grey4 : theme.palette.grey5)};
}
}
`;
46 changes: 46 additions & 0 deletions src/components/commons/BtnStagingDate.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import styled from '@emotion/styled';

const BtnStagingDate = () => {
return (
<BtnStagingDateLayout>
<BtnStagingDateText>⇥ 마감 기한 설정</BtnStagingDateText>
</BtnStagingDateLayout>
);
};

export default BtnStagingDate;

const BtnStagingDateText = styled('p', { target: 'BtnStagingDateText' })`
color: ${({ theme }) => theme.palette.grey5};
text-align: center;
font-size: 1.2rem;
`;

const BtnStagingDateLayout = styled('div', { target: 'BtnStagingDateLayout' })`
display: flex;
width: fit-content;
height: 2.2rem;
padding: 0.3rem 1.2rem;
justify-content: center;
align-items: center;
gap: 0.8rem;
border-radius: 0.8rem;
background: ${({ theme }) => theme.palette.grey3};
cursor: pointer;

&:hover {
background: ${({ theme }) => theme.palette.grey4};

${BtnStagingDateText} {
color: ${({ theme }) => theme.palette.grey6};
}
}

&:active {
background: ${({ theme }) => theme.palette.grey5};

${BtnStagingDateText} {
color: ${({ theme }) => theme.palette.white};
}
}
`;
4 changes: 4 additions & 0 deletions src/pages/Today.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import TextInputDesc from '@/components/common/textbox/TextInputDesc';
import TextInputStaging from '@/components/common/textbox/TextInputStaging';
import TextInputTime from '@/components/common/textbox/TextInputTime';
import TextInputTitle from '@/components/common/textbox/TextInputTitle';
import BtnDate from '@/components/commons/BtnDate';
import BtnStagingDate from '@/components/commons/BtnStagingDate';

function Today() {
return (
Expand All @@ -23,6 +25,8 @@ function Today() {
<TextInputTime time="end" />
<TextInputTime time="total" />
<TextInputStaging />
<BtnDate date="2024.07.11" size="big" />
<BtnStagingDate />
</div>
);
}
Expand Down
Loading
Loading