Skip to content

Commit

Permalink
Merge pull request #403 from ynmkim/part3-김윤미-week13
Browse files Browse the repository at this point in the history
[김윤미] week13
  • Loading branch information
clianor authored Jan 19, 2024
2 parents c7dec06 + 84d7662 commit e4f2785
Show file tree
Hide file tree
Showing 21 changed files with 659 additions and 88 deletions.
49 changes: 49 additions & 0 deletions components/Button.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
@import '@/styles/mixin.scss';

%button-base {
display: flex;
align-items: center;
justify-content: center;
padding: 1rem 1.6rem;
color: var(--color-white);
text-align: center;
cursor: pointer;
border-radius: 0.8rem;
transition: opacity 300ms ease-in-out;

&:disabled {
cursor: not-allowed;
background-color: rgba(0, 0, 0, 0.2);
}

&:enabled:hover {
opacity: 0.9;
}
}

.primary {
@extend %button-base;
background-image: linear-gradient(
91deg,
var(--color-primary) 0.12%,
#6ae3fe 101.84%
);
}

.large {
height: 3.7rem;
font-size: 1.4rem;
font-weight: 600;

@include tablet {
height: 5.4rem;
font-size: 1.8rem;
font-weight: 600;
}
}

.small {
height: 3.7rem;
font-size: 1.4rem;
font-weight: 600;
}
31 changes: 31 additions & 0 deletions components/Button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { ReactNode } from 'react';
import { MouseEvent } from 'react';
import styles from '@/components/Button.module.scss';
import classNames from 'classnames/bind';
interface ButtonProps {
children: ReactNode;
className?: string;
variant: 'primary';
size: 'large' | 'small';
onClick?: (e: MouseEvent<HTMLButtonElement>) => void;
}
export default function Button({
children,
className = '',
variant = 'primary',
onClick,
size = 'large',
...props
}: ButtonProps) {
const cx = classNames.bind(styles);

return (
<button
className={cx(variant, size, className)}
onClick={onClick}
{...props}
>
{children}
</button>
);
}
23 changes: 23 additions & 0 deletions components/Container.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
.container {
margin: 0 auto;
width: 100%;
max-width: 120rem;
}

.header.container {
display: flex;
justify-content: space-between;
margin: 0 auto;
width: 100%;
max-width: 192rem;
}

.signup.container {
width: 40rem;
margin: 23.8rem auto 0;
@media screen and (max-width: 768px) {
width: 100%;
margin: 12rem auto;
padding: 0 3.2rem;
}
}
13 changes: 13 additions & 0 deletions components/Container.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import styles from './Container.module.scss';

interface ContainerProps {
className?: string;
page?: string;
children?: React.ReactNode;
}

export default function Container({ page, children }: ContainerProps) {
const classNames = `${styles.container} ${page ? styles[page] : ''}`;

return <div className={classNames}>{children}</div>;
}
48 changes: 48 additions & 0 deletions components/Input.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
%input-text {
font-size: 1.6rem;
font-weight: 400;
color: var(--color-gray100);
}

.container {
position: relative;

input {
width: 100%;
height: 6rem;
padding: 0 1.5rem;
border-radius: 0.8rem;
background-color: var(--color-white);
border: 1px solid var(--color-gray20);
@extend %input-text;

&[type='password'] {
padding-right: 4.6rem;
}

&::placeholder {
@extend %input-text;
}

&:focus {
border: 1px solid var(--color-primary);
}
}
}

.toggle-eye {
position: absolute;
top: 50%;
right: 0.3rem;
transform: translateY(-50%);
width: 4rem;
height: 4rem;
background: url('../public/assets/icons/eye-on.svg') no-repeat center/ 1.6rem
1.6rem;
cursor: pointer;
}

.toggle-eye.active {
background: url('../public/assets/icons/eye-off.svg') no-repeat center/ 1.6rem
1.6rem;
}
44 changes: 44 additions & 0 deletions components/Input.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import styles from '@/components/Input.module.scss';
import classNames from 'classnames/bind';
import { useState, useRef, InputHTMLAttributes, RefObject } from 'react';

const cx = classNames.bind(styles);
interface InputRefProps {
inputRef: RefObject<HTMLInputElement>;
}

const ToggleEye = ({ inputRef }: InputRefProps) => {
const [isActive, setActive] = useState(false);

const handleClick = () => {
setActive(!isActive);
if (inputRef.current) {
inputRef.current.type = isActive ? 'text' : 'password';
}
};

const label = isActive ? '비밀번호 숨기기' : '비밀번호 보이기';

const className = cx('toggle-eye', { active: isActive });

return (
<button className={className} onClick={handleClick}>
<span className={cx('visually-hidden')}>{label}</span>
</button>
);
};

interface InputProps extends InputHTMLAttributes<HTMLInputElement> {
className?: string;
}

export default function Input({ className = '', ...props }: InputProps) {
const inputRef = useRef<HTMLInputElement>(null);

return (
<div className={cx('container', className)} {...props}>
<input ref={inputRef} {...props} />
{props.type === 'password' && <ToggleEye inputRef={inputRef} />}
</div>
);
}
97 changes: 97 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
"lint": "next lint"
},
"dependencies": {
"axios": "^1.6.5",
"classnames": "^2.5.1",
"next": "13.5.6",
"react": "^18",
"react-dom": "^18"
Expand Down
Loading

0 comments on commit e4f2785

Please sign in to comment.