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(editor): 에디터의 제목, 태그 구현 #19

Merged
merged 22 commits into from
Aug 12, 2024
Merged

Conversation

Collection50
Copy link
Member

@Collection50 Collection50 commented Aug 3, 2024

3. 관련 스크린샷을 첨부해주세요.

image

4. 완료 사항


5. 추가 사항 / 코드 리뷰 받고 싶은 부분

  • PR의 크기가 커져, 이후 PR에서 API 연결을 수행하겠습니다.

Copy link
Member

@qkrdmstlr3 qkrdmstlr3 left a comment

Choose a reason for hiding this comment

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

수고하셨습니다!

>({ name: 'tag-selector' });

function Title({ className, ...props }: StrictPropsWithChildren<{ className?: string }>) {
return <div {...props} className={cn('flex items-center w-28 h-40 text-14 font-semibold', className)} />;
Copy link
Member

Choose a reason for hiding this comment

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

h나 span태그는 어떠신가요?

Copy link
Member Author

Choose a reason for hiding this comment

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

넵 h1 태그로 변경하겠습니다 !

Comment on lines 19 to 21
<li>
<Button {...props} className={cn('py-4 px-8 text-[14px] rounded-4 font-medium leading-20', props.className)} />
</li>
Copy link
Member

Choose a reason for hiding this comment

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

li태그가 컴포넌트 상위에 있는 것이 조금 어색해보여요.
Chakra의 List컴포넌트 같은 경우 ListItem이름에서 li를 유추할 수 있지만, 태그의 경우에는 조금 다를 수 있다고 생각해요..!
context를 통해 Tag가 TagList하위에서만 사용된다는 것을 보장하거나, �TagList컴포넌트에서 Li로 감싸는 것은 어떠신가요??

Copy link
Member Author

Choose a reason for hiding this comment

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

좋습니다 !!
두번째 방법을 사용하겠습니다 !!

label2: '0.0194em',
caption1: '0.0252em',
caption2: '0.0311em',
export const letterSpacing: Record<Typography, `${number}rem`> = {
Copy link
Member

Choose a reason for hiding this comment

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

👍


import { useCallback, useEffect, useRef } from 'react';

export function useCallbackOnce<T extends (...args: any[]) => any>(callback: T): (...args: any[]) => any {
Copy link
Member

Choose a reason for hiding this comment

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

이름만 보았을 때는 callback을 최초 1회만 실행하는 함수인 줄 알았는데요. 구현체를 보니 함수의 주소를 보존하는 방식인 것 같아요. usePreservedCallback 같은 이름은 어떠신가요??

Copy link
Member Author

Choose a reason for hiding this comment

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

좋습니다 !

Comment on lines 22 to 26
if (isOpen) {
setIsOpen(false);
return;
}
setIsOpen(true);
Copy link
Member

@qkrdmstlr3 qkrdmstlr3 Aug 3, 2024

Choose a reason for hiding this comment

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

아래처럼 줄일 수 있을 것 같아요!

Suggested change
if (isOpen) {
setIsOpen(false);
return;
}
setIsOpen(true);
setIsOpen(!isOpen)

function Content({ children }: StrictPropsWithChildren) {
const { isOpen, getContentProps } = useTagSelectorContext();

return isOpen && <article {...getContentProps()}>{children}</article>;
Copy link
Member

Choose a reason for hiding this comment

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

이거 가끔 false로 렌더될 때도 있던데 isOpen이 false면 null을 반환하는 것 어떠신가요?

Copy link
Member Author

Choose a reason for hiding this comment

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

좋습니다 !

export function useTagSelector({ ...props }: UseTagSelectorProps) {
const { as, ref, classNames } = props;
const Component = as || 'div';
const domRef = useDOMRef(ref);
Copy link
Member

Choose a reason for hiding this comment

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

이름을 좀 더 맞게 잘 지어주는 것은 어떠신가요?

Copy link
Member Author

Choose a reason for hiding this comment

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

useDOMRef의 반환값이므로 domRef라고 지었는데, baseDOMRef 네이밍은 어떨까요??

Copy link
Member

Choose a reason for hiding this comment

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

좋아요! 어제 정신이 없어서 너무 막 적었는데, 아래쪽에 ref가 넘어갈 수 있는 다른 요소들도 있어서 이름을 지어주는 것이 좀 더 좋겠다 싶었어요!

Copy link
Member Author

Choose a reason for hiding this comment

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

넵 !

@@ -10,6 +10,7 @@ export const typographyVariant = [
'label2',
'caption1',
'caption2',
'input-title',
Copy link
Member

Choose a reason for hiding this comment

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

이거는 typography에 있는 토큰인가요??

Copy link
Member Author

Choose a reason for hiding this comment

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

어떤 typography를 말씀하시는 건가요?? 코드 폴더를 말씀하시는 걸까요??

Copy link
Member

Choose a reason for hiding this comment

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

디자인 시스템입니다! 약속된 토큰이 아니라면 우선은 별도로 관리하거나 디자이너와 이야기해서 추가해보면 어떨까요??

Copy link
Member Author

Choose a reason for hiding this comment

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

네넵

tailwind.config.ts Show resolved Hide resolved
Copy link
Collaborator

@woo-jk woo-jk left a comment

Choose a reason for hiding this comment

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

고생하셨습니다! 코멘트 확인부탁드려요👍

function Tag({ ...props }: StrictPropsWithChildren<ButtonProps>) {
return (
<li>
<Button {...props} className={cn('py-4 px-8 text-[14px] rounded-4 font-medium leading-20', props.className)} />
Copy link
Collaborator

Choose a reason for hiding this comment

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

공통 컴포넌트에 Tag 컴포넌트가 있는데, 혹시 사용하지 않는 이유가 있을까요?

Copy link
Member Author

Choose a reason for hiding this comment

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

span 태그가 아닌 button이 필요했기 때문입니다

Copy link
Collaborator

Choose a reason for hiding this comment

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

같은 스타일 코드가 중복되면 유지보수에 안좋으니 추후 하나로 합치는게 필요할 것 같아요~

Comment on lines +1 to +12
export const abilityTags = [
{ value: '커뮤니케이션', type: 'ability' },
{ value: '시각화', type: 'ability' },
{ value: '서비스 운영경험', type: 'ability' },
{ value: '프로젝트 경험', type: 'ability' },
{ value: '성능개선', type: 'ability' },
{ value: '코드 품질', type: 'ability' },
{ value: '지식 공유', type: 'ability' },
{ value: '테스트 코드', type: 'ability' },
{ value: 'UX', type: 'ability' },
{ value: 'UI', type: 'ability' },
] as const;
Copy link
Collaborator

Choose a reason for hiding this comment

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

interface InfoCardTag {
  id: number;
  name: string;
  type: '인성' | '역량';
}

서버에서 제공하는 태그의 타입은 위와 같고, 제가 types 폴더에도 정의 해놨었습니다! mock 데이터이긴 하지만, 이 데이터에 맞춰보는건 어떨까요?

Copy link
Member Author

Choose a reason for hiding this comment

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

PR의 크기가 커져, 이후 PR에서 API 연결을 수행하겠습니다.

추후 PR에서 수정해두겠습니다~!

Comment on lines 29 to 36
const getBaseProps = useCallback(
(props = {}) => ({
ref: domRef,
className: cn('w-[660px] flex items-center gap-8 relative', classNames?.base),
...props,
}),
[ref, classNames?.base],
);
Copy link
Collaborator

Choose a reason for hiding this comment

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

컴포넌트에 프롭스를 직접 넣어주는 방식이 아니라 props getter 방식을 선택한 이유가 궁금합니다!

Copy link
Member Author

Choose a reason for hiding this comment

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

props getter + hooks를 사용해서 가독성과 유지보수성이 향상하기 때문입니다

Comment on lines 38 to 49
const getTriggerProps = useCallback(
(props = {}) => ({
className: cn(
'w-[624px] h-52 flex gap-8 items-center py-8 pl-16 pr-16 border-1 border-transparent rounded-8 text-neutral-20',
isOpen && 'rounded-bl-none rounded-br-none border-neutral-5 bg-neutral-1',
classNames?.trigger,
),
onClick: handleTriggerClick,
...props,
}),
[handleTriggerClick, classNames?.trigger, isOpen],
);
Copy link
Collaborator

Choose a reason for hiding this comment

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

트리거 요소는 외부에서 주입하는 형식이 일반적인 것 같은데, 자체적인 스타일 요소가 있어도 될까요??

Copy link
Member Author

Choose a reason for hiding this comment

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

classNames={{ trigger: '' }}을 지정하여 스타일을 자유롭게 커스터마이징할 수 있습니다

);
}

function Trigger({ children }: StrictPropsWithChildren) {
Copy link
Member

Choose a reason for hiding this comment

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

혹시 이 트리거 어떤 상황에서 동작하는 함수인가요??

Copy link
Member Author

Choose a reason for hiding this comment

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

에디터의 태그를 선택할 때 동작하는 트리거입니다 !

() => ({
className: cn(
'absolute top-39 left-116 w-[624px] bg-[white] border-1 rounded-bl-8 rounded-br-8',
isOpen && 'z-[20000]',
Copy link
Member Author

Choose a reason for hiding this comment

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

isOpen && z-${zIndex.overlay}로 사용하게 되면 아래와 같은 오류가 발생합니다.
tailwind에서 템플릿 리터럴을 사용하는 경우 발생하는 오류로 보이는데 일단 위와같이 하면 정상 동작해서, 이렇게 두겠습니다 !
추후 수정하면 좋을 것 같아요

image

Copy link
Member

Choose a reason for hiding this comment

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

맞아요.. 테일윈드가 생각보다 멍청한 부분이 있어서, 저거 처리가 안되더라구요 😢

Comment on lines -67 to +69
<Button ref={ref} disabled={disabled} className={buttonClassName} {...rest}>
<button ref={ref} disabled={disabled} className={buttonClassName} {...rest}>
{children}
</Button>
</button>
Copy link
Member Author

Choose a reason for hiding this comment

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

공통 컴포넌트인 버튼 컴포넌트를 사용하면 팝오버가 발생하지 않는 현상이 발생해 이렇게 두었습니다 !

Copy link
Member

@eunbeann eunbeann left a comment

Choose a reason for hiding this comment

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

멋지십니다

Copy link
Collaborator

@woo-jk woo-jk left a comment

Choose a reason for hiding this comment

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

👍

@Collection50 Collection50 merged commit aa45492 into main Aug 12, 2024
1 check passed
Collection50 added a commit that referenced this pull request Aug 22, 2024
* feat

* feat

* 중복 처리

* fix

* f

* fix

* import

* fix

* a

* fix ui

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* yarn

* fix

* fix
Collection50 added a commit that referenced this pull request Aug 24, 2024
* feat

* feat

* 중복 처리

* fix

* f

* feat

* feat(recruit): 내 공고 생성 모달 구현 (#20)

* feat(recruit): 내 공고 생성 모달 구현

* update

* feat(editor): 에디터의 제목, 태그 구현 (#19)

* feat

* feat

* 중복 처리

* fix

* f

* fix

* import

* fix

* a

* fix ui

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* yarn

* fix

* fix

* feat

* feat

* feat

* feat

* feat

* fix

* fix

* f

* fix

* fix

* f

---------

Co-authored-by: shellboy <[email protected]>
eunbeann pushed a commit that referenced this pull request Aug 24, 2024
* feat

* feat

* 중복 처리

* fix

* f

* feat

* feat(recruit): 내 공고 생성 모달 구현 (#20)

* feat(recruit): 내 공고 생성 모달 구현

* update

* feat(editor): 에디터의 제목, 태그 구현 (#19)

* feat

* feat

* 중복 처리

* fix

* f

* fix

* import

* fix

* a

* fix ui

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* yarn

* fix

* fix

* feat

* feat

* feat

* feat

* feat

* fix

* fix

* f

* fix

* fix

* f

---------

Co-authored-by: shellboy <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants