Skip to content

Commit

Permalink
학교 대항전
Browse files Browse the repository at this point in the history
  • Loading branch information
myheyjay committed Feb 19, 2024
1 parent c6de1a0 commit b59d878
Show file tree
Hide file tree
Showing 68 changed files with 1,277 additions and 133 deletions.
53 changes: 53 additions & 0 deletions component/Button/Button.styled.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import styled from '@emotion/styled';
import { css } from '@emotion/react';
import { ButtonProps } from './Button.types';

const getSize = ({ size }: Pick<ButtonProps, 'size'>) => {
switch (size) {
case 'XS':
return css`
width: 72px;
height: 24px;
`;
case 'S':
return css`
width: 84px;
height: 37px;
`;
case 'L':
return css`
width: 320px;
height: 54px;
`;
}
};

export const ButtonWrapper = styled.button<
Omit<ButtonProps, 'children' | 'title'>
>`
${(props) => getSize(props)};
padding-block: 0;
padding-inline: 0;
border: 0;
border-radius: ${(props) => (props.radius ? '12px' : 0)};
background-color: ${(props) => props.backgroundColor};
font-weight: 700;
&:hover {
opacity: 80%;
box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.24);
}
&:active {
opacity: 40%;
}
&:disabled {
pointer-events: none;
}
input[type='submit'] {
display: none;
}
`;
39 changes: 39 additions & 0 deletions component/Button/Button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import React from 'react';
import classNames from 'classnames';

import { ButtonProps } from './Button.types';
import { ButtonWrapper } from './Button.styled';
import { SerializedStyles, css } from '@emotion/react';

export const Button = ({
type = 'button',
className,
size,
disabled = false,
radius = true,
backgroundColor,
onClick,
style,
children,
}: ButtonProps) => {
return (
<>
<ButtonWrapper
type={type}
className={classNames(className)}
size={size}
disabled={disabled}
radius={radius}
onClick={(e) => {
if (onClick) {
onClick(e);
}
}}
backgroundColor={backgroundColor}
css={style as SerializedStyles}
>
{children}
</ButtonWrapper>
</>
);
};
15 changes: 15 additions & 0 deletions component/Button/Button.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { SerializedStyles } from '@emotion/react';
import { Property } from 'csstype';

export interface ButtonProps {
type?: 'submit' | 'reset' | 'button' | undefined;
className?: string;
size: 'XS' | 'S' | 'L';
disabled?: boolean;
radius?: boolean;
backgroundColor: Property.BackgroundColor;
onClick?: React.MouseEventHandler<HTMLButtonElement>;
style?: SerializedStyles | React.CSSProperties;
children?: React.ReactNode;
isSubmit?: boolean;
}
5 changes: 5 additions & 0 deletions component/Button/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { Button } from './Button';
import { ButtonProps } from './Button.types';

export { Button };
export type { ButtonProps };
2 changes: 1 addition & 1 deletion component/Card.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { pallete } from '@/styles/Color';
import { BodyMedium, Headline_02, Subtitle_02 } from '@/styles/Typography';
import { BodyMedium, Headline_02, Subtitle_02 } from '@/component/Typography';
import Image from 'next/image';
import React, { forwardRef } from 'react';

Expand Down
5 changes: 5 additions & 0 deletions component/Collapse/Collapse.styled.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import styled from '@emotion/styled';

export const CollapseWrapper = styled.div`
width: 100%;
`;
53 changes: 53 additions & 0 deletions component/Collapse/Collapse.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import React, { useRef, useState } from 'react';
import { SerializedStyles, css } from '@emotion/react';
import Image from 'next/image';

import { Button } from '../Button';
import { Icon } from '../Icon';
import chevronDown from '../Icon/asset/chevron-down-gray400.svg';

import { CollapseProps } from './Collapse.types';
import { CollapseWrapper } from './Collapse.styled';

export const Collapse = ({
className,
title,
children,
style,
}: CollapseProps) => {
const [isOpen, setIsOpen] = useState(false);
const contentRef = useRef<HTMLDivElement>(null);

const handleClick = () => setIsOpen(!isOpen);

return (
<CollapseWrapper className={className}>
<Button
className='flex items-center justify-center'
size='L'
radius={false}
backgroundColor='--white'
onClick={handleClick}
style={css`
border: 0;
width: unset;
${style as SerializedStyles}
`}
>
<div className='ml-3'>{title}</div>
<Image className='mr-3' src={chevronDown} alt='chevron_down' />
</Button>
<div
ref={contentRef}
className='flex flex-col w-full items-center'
style={{
overflow: 'hidden',
maxHeight: isOpen ? `${contentRef.current?.scrollHeight}px` : '0',
transition: 'max-height 0.3s ease',
}}
>
{children}
</div>
</CollapseWrapper>
);
};
8 changes: 8 additions & 0 deletions component/Collapse/Collapse.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { SerializedStyles } from '@emotion/react';

export interface CollapseProps {
className?: string;
title: React.ReactNode;
children: React.ReactNode;
style?: SerializedStyles | React.CSSProperties;
}
3 changes: 3 additions & 0 deletions component/Collapse/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { Collapse } from './Collapse';

export { Collapse };
11 changes: 11 additions & 0 deletions component/Icon/Icon.styled.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import styled from '@emotion/styled';
import { IconProps } from '.';

export const IconWrapper = styled.div<Pick<IconProps, 'style'>>`
width: fit-content;
height: fit-content;
display: flex;
justify-content: center;
align-items: center;
`;
83 changes: 83 additions & 0 deletions component/Icon/Icon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import React from 'react';
import { SerializedStyles } from '@emotion/react';
import parse, { Element, HTMLReactParserOptions } from 'html-react-parser';

import { IconWrapper } from './Icon.styled';
import { IconProps, SvgProps } from './Icon.types';

/**
* If you set 'type' as 'svg', you should pass raw svg string data to 'src'
* for vite environment, add postfix '?raw' at asset importing
* ref (https://ko.vitejs.dev/guide/assets.html#importing-asset-as-string)
*/
export const Icon = ({
className,
type,
color,
src,
alt,
width,
height,
style,
}: IconProps) => {
return (
<IconWrapper className={className} css={style as SerializedStyles}>
{type === 'svg' ? (
<Svg color={color} width={width} height={height} src={src} />
) : (
<img width={width} height={height} src={src} alt={alt} />
)}
</IconWrapper>
);
};

const Svg = ({ color, width, height, src }: SvgProps) => {
const convertSrc = () => {
const widthToken = 'width';
const heightToken = 'height';
const fillToken = 'fill';

const convertedColor = color;

const option: HTMLReactParserOptions = {
replace: (domNode) => {
if (
domNode instanceof Element &&
domNode.attribs &&
domNode.name === 'svg'
) {
let widthFlag = false;
let heightFlag = false;
let fillFlag = false;

domNode.attributes.forEach((value) => {
if (value.name === widthToken && width && !widthFlag) {
domNode.attribs[widthToken] = String(width);
widthFlag = true;
}
if (value.name === heightToken && height && !heightFlag) {
domNode.attribs[heightToken] = String(height);
heightFlag = true;
}
if (value.name === fillToken && convertedColor && !fillFlag) {
domNode.attribs[fillToken] = convertedColor;
fillFlag = true;
}
});

if (!widthFlag && width) domNode.attribs[widthToken] = String(width);
if (!heightFlag && height)
domNode.attribs[heightToken] = String(height);
if (!fillFlag && convertedColor)
domNode.attribs[fillToken] = convertedColor;
}

return domNode;
},
};

return parse(src, option);
};

return convertSrc();
};
20 changes: 20 additions & 0 deletions component/Icon/Icon.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Property } from 'csstype';
import { SerializedStyles } from '@emotion/react';

export interface IconProps {
className?: string;
type: 'svg' | 'png' | 'jpg';
src: string;
alt: string;
width?: number | string;
height?: number | string;
color?: Property.BackgroundColor;
style?: SerializedStyles | React.CSSProperties;
}

export interface SvgProps {
color?: Property.BackgroundColor;
width?: number | string;
height?: number | string;
src: string;
}
17 changes: 17 additions & 0 deletions component/Icon/asset/add-and-share.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions component/Icon/asset/bell.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions component/Icon/asset/check.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 component/Icon/asset/chevron-down-gray400.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions component/Icon/asset/chevron-down.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions component/Icon/asset/chevron-left.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added component/Icon/asset/chevron-right.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added component/Icon/asset/chevron-right.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions component/Icon/asset/chevron-right.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions component/Icon/asset/dash.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions component/Icon/asset/discussion-outdated.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions component/Icon/asset/gift.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions component/Icon/asset/megaphone.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions component/Icon/asset/message-square.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions component/Icon/asset/person.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions component/Icon/asset/plus.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions component/Icon/asset/project-roadmap.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions component/Icon/asset/ranking-1.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions component/Icon/asset/ranking-2.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit b59d878

Please sign in to comment.