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] 텍스트박스 공통컴포넌트 퍼블리싱 #30

Merged
merged 14 commits into from
Jul 6, 2024
Merged
3 changes: 3 additions & 0 deletions src/assets/svg/arrow-narrow-right.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions src/assets/svg/icn_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
@@ -0,0 +1,9 @@
import Icn_arrow_narrow_right from '@/assets/svg/arrow-narrow-right.svg?react';
import Icn_clock from '@/assets/svg/icn_clock.svg?react';

const Icons = {
Icn_clock,
Icn_arrow_narrow_right,
};

export default Icons;
17 changes: 17 additions & 0 deletions src/components/common/textbox/TextInputDesc.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import styled from '@emotion/styled';

import { SizeType } from '@/types/textInputType';

const TextInputDesc = ({ type }: SizeType) => {
return <TextInputDescLayout placeholder="설명 추가" type={type} />;
};

const TextInputDescLayout = styled.textarea<{ type: string }>`
width: ${({ type }) => (type === 'long' ? '34.8rem' : '30.4rem')};
height: ${({ type }) => (type === 'long' ? '14.5rem' : '18rem')};

${({ theme }) => theme.fontTheme.BODY_02};
border: solid 1px ${({ theme }) => theme.palette.GREY_01};
border-radius: 5px;
`;
export default TextInputDesc;
56 changes: 56 additions & 0 deletions src/components/common/textbox/TextInputStaging.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import styled from '@emotion/styled';

type Props = {};

const TextInputStaging = (props: Props) => {
return (
<StagingLayout>
<TextArea placeholder="해야하는 일들을 쏟아내보세요." />
<BtnWrapper>
<TmpBtn />
<TmpBtn />
</BtnWrapper>
</StagingLayout>
);
};
const StagingLayout = styled.div`
display: flex;
flex-direction: column;
justify-content: space-between;
box-sizing: border-box;
width: 31rem;
height: 7.4rem;
padding: 0.8rem;

border: solid 1px ${({ theme }) => theme.palette.GREY_02};
border-radius: 8px;
`;

const TextArea = styled.textarea`
width: 100%;
height: 100%;

border: none;

${({ theme }) => theme.fontTheme.LABEL_03};
&:focus {
outline: none;
}
`;

const BtnWrapper = styled.div`
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
height: fit-content;
`;

/** 임시 버튼 */
const TmpBtn = styled.div`
width: 5rem;
height: 2.2rem;

background-color: ${({ theme }) => theme.palette.GREY_04};
`;
export default TextInputStaging;
50 changes: 50 additions & 0 deletions src/components/common/textbox/TextInputTime.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import styled from '@emotion/styled';

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

interface TextInputTimeProps {
time: 'start' | 'end' | 'total';
}

const TextInputTime = ({ time }: TextInputTimeProps) => {
const isTotalTime = time === 'total';
return (
<InputTimeLayout time={time}>
{time === 'end' && <ArrowIcon />}
<InputTimeStyle type="text" time={time} maxLength={isTotalTime ? 2 : 10} />
{isTotalTime && <MinuteTxt>분</MinuteTxt>}
</InputTimeLayout>
);
};
const InputTimeLayout = styled.div<{ time: string }>`
display: flex;
align-items: center;
width: ${({ time }) => (time === 'total' ? '3.6rem' : '11.5rem')};
height: 3.2rem;
padding: 0.4rem 1rem;

${({ theme }) => theme.fontTheme.BODY_02};
background-color: ${({ theme, time }) => (time !== 'total' ? theme.palette.GRAY_DISABLED : theme.palette.WITHE)};
border-radius: 8px;
`;
const ArrowIcon = styled(Icons.Icn_arrow_narrow_right)`
width: 1.4rem;
height: 1.4rem;
`;
const MinuteTxt = styled.p`
${({ theme }) => theme.fontTheme.BODY_02};
padding-left: 0.4rem;
`;
const InputTimeStyle = styled.input<{ time: string }>`
width: ${({ time }) => (time === 'total' ? '3.6rem' : '100%')};
height: 100%;

background-color: ${({ theme, time }) => (time === 'total' ? theme.palette.GRAY_DISABLED : 'transparent')};
border: none;
border-radius: 8px;

&:focus {
outline: none;
}
`;
export default TextInputTime;
22 changes: 22 additions & 0 deletions src/components/common/textbox/TextInputTitle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import styled from '@emotion/styled';

import { SizeType } from '@/types/textInputType';

const TextInputTitle = ({ type }: SizeType) => {
return <TextInputTitleLayout placeholder="제목 추가" type={type} />;
};
const TextInputTitleLayout = styled.input<{ type: string }>`
${({ theme }) => theme.fontTheme.BODY_02};
display: flex;
width: ${({ type }) => (type === 'long' ? '34.8rem' : '30.4rem')};
height: 4.8rem;
padding: 1.2rem;

border: 1px solid ${({ theme }) => theme.palette.GREY_01};
border-radius: 5px;

&:focus {
outline: none;
}
`;
export default TextInputTitle;
42 changes: 42 additions & 0 deletions src/components/common/textbox/TextboxDailydate.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import styled from '@emotion/styled';

import { SizeType } from '@/types/textInputType';

import getNameOfDay from '@/utils/getNameOfDay';

const TextboxDailydate = ({ type }: SizeType) => {
const today = new Date();
const date = today.getDate();
const dayOfTheWeek = today.getDay();

return (
<DailydateLayout type={type}>
<DailydateContainer>
<DateText>{date}일</DateText>
{/* CAPTION_02 추가 후 수정 필요 */}
<DayText>{getNameOfDay(dayOfTheWeek)}</DayText>
Copy link
Contributor

Choose a reason for hiding this comment

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

getDay 쓰면 dayOfTheWeek가 숫자로 반환되는건가요??? 😯

Copy link
Member Author

Choose a reason for hiding this comment

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

https://www.w3schools.com/jsref/jsref_getday.asp

0-6으로 요일이 반환됩니다!

Copy link
Contributor

Choose a reason for hiding this comment

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

옹 참고하겠습니당

</DailydateContainer>
</DailydateLayout>
);
};

const DailydateLayout = styled.div<{ type: string }>`
display: flex;
align-items: center;
width: ${({ type }) => (type === 'long' ? '84rem' : '53.2rem')};
height: 5.6rem;
padding: 4px 8px;
`;
const DailydateContainer = styled.div`
display: flex;
gap: 1.2rem;
align-items: baseline;
`;
const DateText = styled.h1`
${({ theme }) => theme.fontTheme.HEADLINE_01};
`;
const DayText = styled.p`
${({ theme }) => theme.fontTheme.CAPTION_01};
color: ${({ theme }) => theme.palette.GREY_04};
`;
export default TextboxDailydate;
75 changes: 75 additions & 0 deletions src/components/common/textbox/TextboxInput.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { css } from '@emotion/react';
import styled from '@emotion/styled';

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

import { theme } from '@/styles/theme';

interface TextboxInputProps {
variant: 'date' | 'time' | 'smallDate';
}
const TextboxInput = ({ variant }: TextboxInputProps) => {
return (
<InputContainer variant={variant}>
{variant === 'time' && <ClockIcon />}
<StyledInput
type="text"
placeholder={variant === 'time' ? '시간 없음' : '2024.07.11'}
maxLength={10}
variant={variant}
/>
</InputContainer>
);
};
const smallDateStyle = css`
width: 7.5rem;
padding: 0;
`;
const smallDateInputStyle = css`
padding: 0;

text-align: center;

&:focus {
outline: solid 1px ${theme.palette.BLUE_DEFAULT};
}
`;
const InputContainer = styled.div<{ variant: 'date' | 'time' | 'smallDate' }>`
display: flex;
gap: 0.5rem;
align-items: center;
width: 15.4rem;
height: 2.6rem;
padding: 0.3rem 1rem;

background-color: ${({ theme }) => theme.palette.GRAY_DISABLED};
border-radius: 8px;

&:focus-within {
background-color: ${({ theme }) => theme.palette.BLUE_DISABLED};
}

${({ variant }) => variant === 'smallDate' && smallDateStyle}
`;
const StyledInput = styled.input<{ variant: 'date' | 'time' | 'smallDate' }>`
width: 100%;
height: 100%;

${({ theme }) => theme.fontTheme.CAPTION_01};
background-color: transparent;
border: none;
border-radius: 8px;

&:focus {
outline: none;
}

${({ variant }) => variant === 'smallDate' && smallDateInputStyle}
`;

const ClockIcon = styled(Icons.Icn_clock)`
width: 1.4rem;
height: 1.4rem;
`;

export default TextboxInput;
26 changes: 25 additions & 1 deletion src/pages/Today.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,31 @@
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 TextboxDailydate from '@/components/common/textbox/TextboxDailydate';
import TextboxInput from '@/components/common/textbox/TextboxInput';

type Props = {};

const Today = (props: Props) => {
return <div>Today</div>;
return (
<div>
Today
<TextboxInput variant="date" />
<TextboxInput variant="time" />
<TextboxInput variant="smallDate" />
<TextInputTitle type="long" />
<TextInputTitle type="short" />
<TextInputDesc type="long" />
<TextInputDesc type="short" />
<TextboxDailydate type="long" day="weekday" />
<TextboxDailydate type="short" day="weekday" />
<TextInputTime time="start" />
<TextInputTime time="end" />
<TextInputTime time="total" />
<TextInputStaging />
</div>
);
};

export default Today;
3 changes: 3 additions & 0 deletions src/types/textInputType.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export interface SizeType {
type: 'long' | 'short';
}
24 changes: 24 additions & 0 deletions src/utils/getNameOfDay.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//0:일, 1:월, 2:화, 3:수, 4:목, 5:금, 6:토
/** 0-6 number를 요일로 변환 */
const getNameOfDay = (dayOfTheWeek: number) => {
switch (dayOfTheWeek) {
case 0:
return 'SUNDAY';
case 1:
return 'MONDAY';
case 2:
return 'TUESDAY';
case 3:
return 'WEDNESDAY';
case 4:
return 'THURSDAY';
case 5:
return 'FRIDAY';
case 6:
return 'SATURDAY';
default:
return 'UNKNOWN';
}
};

export default getNameOfDay;
Loading