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

Feature/issue 65 feat 기술스택 팝오버 구현 #79

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
8069bcc
Chore: STACKS 상수 배열 생성
nakyoung98 Mar 15, 2024
a8af40f
Feat: Stack 및 Stack을 사용하는 Position Type 구현
nakyoung98 Mar 15, 2024
566fb8e
Fix: StackType 수정
nakyoung98 Mar 15, 2024
be251ef
Feat: Image관련 타입 구현
nakyoung98 Mar 15, 2024
565b6d2
Chore: Stack 데이터 변경 및 STACK_NAMES만 모은 변수 생성
nakyoung98 Mar 15, 2024
ceb43ba
Refactor: ICONS 변수 Images 타입 할당
nakyoung98 Mar 15, 2024
3aa6747
Chore: stackIcons.ts 삭제
nakyoung98 Mar 15, 2024
cc564f0
Fix: Stack에 맞게 icon 출력 수정 및 style
nakyoung98 Mar 15, 2024
b30ae13
Fix: 변경된 Stack에 따라 Stacks 컴포넌트 수정
nakyoung98 Mar 15, 2024
39973bc
Fix: FilterButton 클릭시 화살표 방향 뒤집어짐
nakyoung98 Mar 15, 2024
d7d7f97
Feat: FilterList 컴포넌트 디자인 기본 구현
nakyoung98 Mar 15, 2024
f05123b
Feat: FilterList내 개별 Filter 디자인 추가
nakyoung98 Mar 15, 2024
9de5f8e
Feat: SelectLayout 컴포넌트 기본 디자인 세팅
nakyoung98 Mar 15, 2024
7cc2a0d
Feat: StackPopover 컴포넌트 기본 구현
nakyoung98 Mar 15, 2024
aa7961a
Chore: reset.svg 추가
nakyoung98 Mar 15, 2024
090b219
Feat: ResetButton 구현
nakyoung98 Mar 15, 2024
abfb205
Chore: 코드 여백 수정
nakyoung98 Mar 15, 2024
b08202e
Fix: 스타일드 상속을 위해 className 프롭 생성
nakyoung98 Mar 15, 2024
46ef5b3
Fix: StackPopover 컴포넌트 position 변경
nakyoung98 Mar 15, 2024
3bd9b26
Fix: DefaultChip 이미지부분 Stack 컴포넌트로 대체
nakyoung98 Mar 15, 2024
d74ef55
Fix: Stack 컴포넌트 prop 변경
nakyoung98 Mar 15, 2024
f2455aa
Feat: StackChipGrid 구현
nakyoung98 Mar 15, 2024
4e63810
Fix: FilterList filter 외부에서 관리
nakyoung98 Mar 15, 2024
10623c0
Fix: StackChip 잘못된 너비 수정
nakyoung98 Mar 15, 2024
0ca2ae3
Feat: DefaultChip 디자인 수정
nakyoung98 Mar 15, 2024
038323e
Feat: StackChip 디자인 수정
nakyoung98 Mar 15, 2024
7fd7772
Feat: Stack 컴포넌트 확장 가능하게 변경
nakyoung98 Mar 15, 2024
2db8d1c
Fix: FilterList 범용성있게 원복
nakyoung98 Mar 15, 2024
79ff50e
Fix: Chip overflow 담당 변경
nakyoung98 Mar 16, 2024
cb538da
Fix: DeleteStackChip onClick으로 prop넘긴 오류 수정
nakyoung98 Mar 16, 2024
3d7aa9d
Feat: DeleteStackChipList 컴포넌트 구현
nakyoung98 Mar 16, 2024
28db387
Chore: StackChipGrid -> StackChipList 이름 변경
nakyoung98 Mar 16, 2024
8092716
Refactor: StacksPopover toogle로 상태 관리
nakyoung98 Mar 16, 2024
844edf9
Chore: StacksPopover에 사용되는 constant 파일 생성
nakyoung98 Mar 16, 2024
43fed1e
Chore: StackPopover 폴더 위치 변경
nakyoung98 Mar 16, 2024
7d944b7
Fix: DefaultChip title 툴팁 추가
nakyoung98 Mar 16, 2024
3843afd
Chore: DetailCard, FilterDropButton 폴더 위치 및 파일 이름 변경
nakyoung98 Mar 16, 2024
4ee4442
Refactor: StackPopover 컴포넌트 변경된 하위 컴포넌트 이름 반영
nakyoung98 Mar 16, 2024
8241597
Feat: FilterValue에서 FilterKey가지고 오는 함수 구현
nakyoung98 Mar 16, 2024
9287a96
Chore: Design_Token 값 추가 및 반영
nakyoung98 Mar 16, 2024
7439bf8
Refactor: filter key가지고 오는 메소드 적용 및 css 조정
nakyoung98 Mar 16, 2024
f8de1a8
Fix: SelectLayout width css 수정
nakyoung98 Mar 16, 2024
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
7 changes: 7 additions & 0 deletions co-kkiri/src/assets/icons/reset.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
57 changes: 38 additions & 19 deletions co-kkiri/src/components/commons/Chips/DefaultChip.tsx
Copy link
Contributor Author

@nakyoung98 nakyoung98 Mar 16, 2024

Choose a reason for hiding this comment

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

image

툴팁 표시를 위해서 title={label}이 추가되었습니다

외에는 안보셔도 됩니다

Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { MouseEvent } from "react";
import DESIGN_TOKEN from "@/styles/tokens";
import styled from "styled-components";
import Stack from "../Stack";

interface Icon {
src: string;
Expand All @@ -19,10 +20,25 @@ interface DefaultChipProps {
className?: string;
}

export default function DefaultChip({ label, imgUrl, icon, isSelected, onClick, onIconClick, isVertical, className }: DefaultChipProps) {
export default function DefaultChip({
label,
imgUrl,
icon,
isSelected,
onClick,
onIconClick,
isVertical,
className,
}: DefaultChipProps) {
return (
<Container className={className} $isVertical={isVertical} $isSelected={isSelected} $isClickable={(onClick || onIconClick) ? true : false} onClick={!icon ? onClick : undefined}>
{imgUrl && <div className="image-container"><img className="image" src={imgUrl} alt={label} /></div>}
<Container
title={label}
className={className}
$isVertical={isVertical}
$isSelected={isSelected}
$isClickable={onClick || onIconClick ? true : false}
onClick={!icon ? onClick : undefined}>
{imgUrl && <Image stack={{ name: label, img: imgUrl }} />}
<span className="label">{label}</span>
{icon && <img className="icon" src={icon.src} alt={icon.alt} onClick={onIconClick} />}
</Container>
Expand All @@ -37,10 +53,10 @@ export default function DefaultChip({ label, imgUrl, icon, isSelected, onClick,
export interface DefaultChipContainerStyleProps {
$isVertical?: boolean;
$isSelected?: boolean;
$isClickable?: boolean
$isClickable?: boolean;
}

const { color, typography } = DESIGN_TOKEN;
const { color, typography, mediaQueries } = DESIGN_TOKEN;

const Container = styled.div<DefaultChipContainerStyleProps>`
width: fit-content;
Expand All @@ -56,24 +72,21 @@ const Container = styled.div<DefaultChipContainerStyleProps>`

${typography.font12Semibold}

${({$isClickable}) => $isClickable && `cursor: pointer;`}
${({ $isClickable }) => $isClickable && `cursor: pointer;`}

& .image-container{
width: 3.6rem;
height: 3.6rem;
& > span {
text-align: center;
}

& .image{
object-fit: cover;
}

& .icon{
& .icon {
width: 1.4rem;
height: 1.4rem;
${({$isClickable}) => $isClickable && `cursor: pointer;`}
${({ $isClickable }) => $isClickable && `cursor: pointer;`}
}

${({ $isVertical }) => $isVertical ? `
${({ $isVertical }) =>
$isVertical
? `
flex-direction: column;
border-radius: 1rem;
align-items: center;
Expand All @@ -85,15 +98,21 @@ const Container = styled.div<DefaultChipContainerStyleProps>`
top: .4rem;
right: .4rem;
}
` : `
`
: `
flex-direction: row;
align-items: center;
gap: 1.2rem;
`
}
`}

-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
`;

const Image = styled(Stack)`
${mediaQueries.mobile} {
display: none;
}
`;
17 changes: 10 additions & 7 deletions co-kkiri/src/components/commons/Chips/DeleteStackChip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,18 @@ import { MouseEvent } from "react";
import { ICONS } from "@/constants/icons";

interface DeleteStackChipProps {
label: string;
onClick: (e: MouseEvent<HTMLDivElement>) => void;
label: string;
onDelete: (stack: string) => void;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

onClick이 onDelete로 조금 더 명확한 이름으로 바뀌었습니다
외에는 안보셔도 됩니다

}

export default function DeleteStackChip({ label, onClick }: DeleteStackChipProps
) {
return <Container label={label} icon={ICONS.deleted} onClick={onClick} />;
export default function DeleteStackChip({ label, onDelete }: DeleteStackChipProps) {
const onClick = (e: MouseEvent<HTMLDivElement>) => {
onDelete(label);
};

return <Container label={label} icon={ICONS.deleted} onIconClick={onClick} />;
}

const Container = styled(DefaultChip)`
padding: 0.4rem .8rem .4rem 1.2rem;
`
padding: 0.4rem 0.8rem 0.4rem 1.2rem;
`;
87 changes: 54 additions & 33 deletions co-kkiri/src/components/commons/Chips/StackChip.tsx
Copy link
Contributor Author

Choose a reason for hiding this comment

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

전반적인 CSS 수정이 있었습니다.
안보셔도 괜찮습니다

Original file line number Diff line number Diff line change
Expand Up @@ -4,54 +4,75 @@ import DefaultChip from "./DefaultChip";
import DESIGN_TOKEN from "@/styles/tokens";

interface StackChipProps {
label: string;
imgUrl: string;
isSelected?: boolean;
onClick: (e: MouseEvent<HTMLDivElement>) => void;
label: string;
imgUrl: string;
isSelected?: boolean;
onClick: (e: MouseEvent<HTMLDivElement>) => void;
}

export default function StackChip({ label, imgUrl, isSelected, onClick }: StackChipProps
) {
return <Container label={label} imgUrl={imgUrl} isSelected={isSelected} onClick={onClick} isVertical />;
export default function StackChip({ label, imgUrl, isSelected, onClick }: StackChipProps) {
return <Container label={label} imgUrl={imgUrl} isSelected={isSelected} onClick={onClick} isVertical />;
}

const { color, typography, mediaQueries } = DESIGN_TOKEN;
const Container = styled(DefaultChip)`
width: 7rem;
height: 7.2rem;
width: 7.2rem;
height: 7rem;

padding: .8rem;
gap: .4rem;
padding: 0.8rem;
gap: 0.4rem;

background-color: ${color.white};
border: .1rem solid ${color.gray[2]};
border-radius: 1rem;
color: ${color.black[1]};
background-color: ${color.white};
border: 0.1rem solid ${color.gray[2]};
border-radius: 1rem;
color: ${color.black[1]};

${({ isSelected }) => !isSelected && `opacity: .4;`}
${({ isSelected }) => !isSelected && `opacity: .4;`}
&:hover {
${({ isSelected }) => !isSelected && `opacity: 1;`}
}

${typography.font12Regular}
& > span {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
width: 100%;
}

${typography.font11Regular}


${mediaQueries.mobile}{
width: fit-content;
height: fit-content;
${mediaQueries.mobile} {
width: fit-content;
height: fit-content;

padding: .3rem 1.2rem;
padding: 0.3rem 1.2rem;

border-radius: 9999rem;
border-radius: 9999rem;

& .image-container{
display: none;
}
opacity: 1;

${({ isSelected }) => isSelected && `
background-color: ${color.white};
color: ${color.secondary};
& .image-container {
display: none;
}

${({ isSelected }) =>
isSelected &&
`
background-color: ${color.white};
color: ${color.secondary};

border-color: ${color.secondary};
`}

&:hover {
${({ isSelected }) =>
!isSelected &&
`
background-color: ${color.white};
color: ${color.secondary};

border-color: ${color.secondary};
`}
border-color: ${color.secondary};
`}
}
`
}
`;
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useState } from "react";
import styled from "styled-components";
import FilterButton from "./commons/FilterDropButton";
import FilterButton from "./commons/FilterButton";
import useOpenToggle from "@/hooks/useOpenToggle";
import DropMenu from "./commons/DropMenu";
import { DROPDOWN_INFO } from "@/constants/dropDown";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ interface FilterButtonProps {

const { popover, popoverSelected } = ICONS;

export default function FilterDropButton({ selectOption, onClick, isSelected }: FilterButtonProps) {
export default function FilterButton({ selectOption, onClick, isSelected }: FilterButtonProps) {
return (
<Container $isSelected={isSelected} onClick={onClick}>
{selectOption}
{isSelected ? (
<Arrow src={popoverSelected.src} alt={popoverSelected.alt} />
<Arrow $isSelected src={popoverSelected.src} alt={popoverSelected.alt} />
Copy link
Contributor Author

Choose a reason for hiding this comment

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

toggle Open 상태일 때 화살표 반대로 되도록 해놨습니다
외에는 안보셔도 됩니다

) : (
<Arrow src={popover.src} alt={popover.alt} />
)}
Expand Down Expand Up @@ -48,7 +48,15 @@ const Container = styled.button<Container>`
${typography.font12Semibold}
`;

const Arrow = styled.img`
interface Arrow {
$isSelected?: boolean;
}

const Arrow = styled.img<Arrow>`
width: 1.2rem;
height: 1.2rem;

${({ $isSelected }) =>
$isSelected && `transform: rotate(180deg);`
}
`;
60 changes: 60 additions & 0 deletions co-kkiri/src/components/commons/FilterList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import DESIGN_TOKEN from "@/styles/tokens";
import { MouseEvent } from "react";
import styled from "styled-components";

interface FilterListProps {
currentFilter: string
filters: string[];
onFilterClick(filter: string): void;
className?: string;
}

export default function FilterList({ currentFilter, filters, onFilterClick, className }: FilterListProps) {

const handleFilterClick = (e: MouseEvent<HTMLDivElement>) => {
const filter = e.currentTarget.textContent;
if (filter) {
onFilterClick(filter);
}
};

return (
<Container className={className}>
{filters.map((filter) => (
<Box key={filter} $isSelected={currentFilter === filter} onClick={handleFilterClick}>
{filter}
</Box>
))}
</Container>
);
}

const { color, typography, mediaQueries } = DESIGN_TOKEN;

const Container = styled.div`
display: flex;
gap: 2rem;

color: ${color.gray[1]};

${typography.font16Bold}

${mediaQueries.mobile} {
gap: 1.6rem;

${typography.font14Bold}
}
`;

interface BoxProps {
$isSelected?: boolean;
}

const Box = styled.div<BoxProps>`
${({ $isSelected }) => $isSelected && `color: ${color.black[1]};`}

&:hover {
cursor: pointer;
${({ $isSelected }) => !$isSelected && `color: ${color.black[3]};`}
}
`;
Loading
Loading