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/#127 탭 브라우징 피드백 반영 #129

Merged
merged 20 commits into from
Nov 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
473da03
feat: 배경 이미지 해상도 변경
pipisebastian Nov 15, 2024
aca483a
Merge branch 'Feature/#119_모달_공통_컴포넌트_구현' of https://github.com/boost…
pipisebastian Nov 15, 2024
e30425d
feat: menu button 흰색 배경 추가
pipisebastian Nov 15, 2024
e566a00
feat: svg 파일 추가
pipisebastian Nov 16, 2024
b0a7fff
chore: svgr 플러그인 설정
pipisebastian Nov 16, 2024
308115e
refactor: 페이지 타이틀 반응형 적용
pipisebastian Nov 16, 2024
14a7f98
refactor: 페이지 이동 애니메이션 마우스 따라가도록 수정
pipisebastian Nov 16, 2024
3d4ac43
feat: 모달 애니메이션 추가
pipisebastian Nov 16, 2024
052bebb
feat: 최소화, 최대화, 창닫기 버튼 아이콘 추가 및 순서 변경
pipisebastian Nov 16, 2024
aafc551
refactor: 사이드바 반응형 추가
pipisebastian Nov 16, 2024
a458d52
feat: 좌표 초기화 함수 구현 및 return 타입 제거
pipisebastian Nov 16, 2024
384e959
refactor: 타입 수정
pipisebastian Nov 16, 2024
beb608d
feat: 최대 보여줄 수 있는 페이지 상수 추가
pipisebastian Nov 16, 2024
9b437c5
refactor: import 순서 정렬
pipisebastian Nov 16, 2024
1778ada
Merge branch 'dev' of https://github.com/boostcampwm-2024/web33-Nocta…
pipisebastian Nov 16, 2024
22299ac
feat: pnpm lock 추가
pipisebastian Nov 16, 2024
1c33455
feat: 10개 페이지 초과시 모달창 추가
pipisebastian Nov 16, 2024
7d62760
refactor: 모달창 문구 수정
pipisebastian Nov 17, 2024
7d3fd54
refactor: x 스크롤 안보이도록
pipisebastian Nov 17, 2024
1f153ec
feat: 스크롤바 webkit 디자인 적용
pipisebastian Nov 17, 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
1 change: 1 addition & 0 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"react": "^18.3.1",
"react-dom": "^18.3.1",
"socket.io-client": "^4.8.1",
"vite-plugin-svgr": "^4.3.0",
"zustand": "^5.0.1"
},
"devDependencies": {
Expand Down
3 changes: 3 additions & 0 deletions client/src/assets/icons/close.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 client/src/assets/icons/expand.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 client/src/assets/icons/minus.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 modified client/src/assets/images/background.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 5 additions & 3 deletions client/src/components/bottomNavigator/BottomNavigator.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { Page } from "@src/types/page";
import { motion } from "framer-motion";
import { IconButton } from "@components/button/IconButton";
import { Page } from "@src/types/page";
import { animation } from "./BottomNavigator.animation";
import { bottomNavigatorContainer } from "./BottomNavigator.style";

interface BottomNavigatorProps {
pages: Page[];
handlePageSelect: (pageId: number) => void;
handlePageSelect: ({ pageId, isSidebar }: { pageId: number; isSidebar?: boolean }) => void;
}

export const BottomNavigator = ({ pages, handlePageSelect }: BottomNavigatorProps) => {
Expand All @@ -25,7 +25,9 @@ export const BottomNavigator = ({ pages, handlePageSelect }: BottomNavigatorProp
icon={page.icon}
size="md"
onClick={() => {
handlePageSelect(page.id);
handlePageSelect({
pageId: page.id,
});
}}
/>
</motion.div>
Expand Down
18 changes: 3 additions & 15 deletions client/src/components/modal/modal.animation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,7 @@ export const overlayAnimation = {
};

export const modalContainerAnimation = {
initial: {
scale: 0.7,
opacity: 0,
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
},
animate: {
scale: 1,
opacity: 1,
},
exit: {
scale: 0.7,
opacity: 0,
},
initial: { opacity: 0, y: 50, scale: 0.3 },
animate: { opacity: 1, y: 0, scale: 1 },
exit: { opacity: 0, scale: 0.5, transition: { duration: 0.2 } },
};
2 changes: 0 additions & 2 deletions client/src/components/modal/modal.style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ export const modalContainer = cx(
display: "flex",
zIndex: 10001,
position: "absolute",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
flexDirection: "column",
width: "400px",
Expand Down
1 change: 1 addition & 0 deletions client/src/components/sidebar/MenuButton.style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export const imageBox = css({
borderRadius: "sm",
width: "50px",
height: "50px",
background: "white",
overflow: "hidden",
});

Expand Down
4 changes: 1 addition & 3 deletions client/src/components/sidebar/MenuButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@ import { menuItemWrapper, imageBox, textBox } from "./MenuButton.style";
export const MenuButton = () => {
return (
<div className={menuItemWrapper}>
<div className={imageBox}>
<img src="https://via.placeholder.com/50" />
</div>
<div className={imageBox}></div>
<p className={textBox}>Noctturn</p>
</div>
);
Expand Down
5 changes: 5 additions & 0 deletions client/src/components/sidebar/PageItem.style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export const pageItemContainer = css({
gap: "sm",
alignItems: "center",
width: "100%",
height: "56px",
paddingInline: "md",
"&:hover": {
background: "white/50",
Expand All @@ -14,6 +15,7 @@ export const pageItemContainer = css({

export const iconBox = css({
display: "flex",
flexShrink: 0,
justifyContent: "center",
alignItems: "center",
borderRadius: "xs",
Expand All @@ -26,4 +28,7 @@ export const iconBox = css({
export const textBox = css({
textStyle: "display-medium20",
color: "gray.700",
textOverflow: "ellipsis",
overflow: "hidden",
whiteSpace: "nowrap",
});
3 changes: 3 additions & 0 deletions client/src/components/sidebar/Sidebar.style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,14 @@ export const navWrapper = css({
gap: "md",
flexDirection: "column",
width: "100%",
overflowX: "hidden",
overflowY: "scroll",
Copy link
Collaborator

Choose a reason for hiding this comment

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

page가 잠깐 생길때 x축에도 스크롤이 발생하네요.
x축 스크롤은 안보이는게 처리하는게 좋을까요?

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 const plusIconBox = css({
display: "flex",
justifyContent: "start",
marginBlock: "10px",
paddingInline: "md",
});

Expand Down
49 changes: 40 additions & 9 deletions client/src/components/sidebar/Sidebar.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { useIsSidebarOpen, useSidebarActions } from "@src/stores/useSidebarStore";
import { Page } from "@src/types/page";
import { motion } from "framer-motion";
import { IconButton } from "@components/button/IconButton";
import { Modal } from "@components/modal/modal";
import { useModal } from "@components/modal/useModal";
import { MAX_VISIBLE_PAGE } from "@src/constants/page";
import { useIsSidebarOpen, useSidebarActions } from "@src/stores/useSidebarStore";
import { Page } from "@src/types/page";
import { MenuButton } from "./MenuButton";
import { PageItem } from "./PageItem";
import { animation, contentVariants, sidebarVariants } from "./Sidebar.animation";
Expand All @@ -14,10 +17,30 @@ export const Sidebar = ({
}: {
pages: Page[];
handlePageAdd: () => void;
handlePageSelect: (pageId: number, isSidebar: boolean) => void;
handlePageSelect: ({ pageId }: { pageId: number }) => void;
}) => {
const visiblePages = pages.filter((page) => page.isVisible);
const isMaxVisiblePage = visiblePages.length >= MAX_VISIBLE_PAGE;

const isSidebarOpen = useIsSidebarOpen();
const { toggleSidebar } = useSidebarActions();
const { isOpen, openModal, closeModal } = useModal();

const handlePageItemClick = (id: number) => {
if (isMaxVisiblePage) {
openModal();
return;
}
handlePageSelect({ pageId: id });
};

const handleAddPageButtonClick = () => {
if (isMaxVisiblePage) {
openModal();
return;
}
handlePageAdd();
};

return (
<motion.aside
Expand All @@ -29,23 +52,31 @@ export const Sidebar = ({
<div className={sidebarToggleButton} onClick={toggleSidebar}>
{isSidebarOpen ? "«" : "»"}
</div>

<motion.nav className={navWrapper} variants={contentVariants}>
<motion.div variants={contentVariants}>
<MenuButton />
</motion.div>
<motion.nav className={navWrapper} variants={contentVariants}>
{pages?.map((item) => (
<motion.div
key={item.id}
initial={animation.initial}
animate={animation.animate}
transition={animation.transition}
>
<PageItem {...item} onClick={() => handlePageSelect(item.id, true)} />
<PageItem {...item} onClick={() => handlePageItemClick(item.id)} />
</motion.div>
))}
<div className={plusIconBox}>
<IconButton icon="➕" size="sm" onClick={handlePageAdd} />
</div>
</motion.nav>
<motion.div className={plusIconBox} variants={contentVariants}>
<IconButton icon="➕" onClick={handleAddPageButtonClick} size="sm" />
</motion.div>
<Modal isOpen={isOpen} primaryButtonLabel="확인" primaryButtonOnClick={closeModal}>
<p>
최대 {MAX_VISIBLE_PAGE}개의 페이지만 표시할 수 있습니다
<br />
사용하지 않는 페이지는 닫아주세요.
</p>
</Modal>
</motion.aside>
);
};
1 change: 1 addition & 0 deletions client/src/constants/page.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const MAX_VISIBLE_PAGE = 10;
6 changes: 4 additions & 2 deletions client/src/features/page/Page.animation.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export const pageAnimation = {
initial: {
x: -300,
x: 0,
y: 0,
opacity: 0,
scale: 0.8,
Expand All @@ -12,7 +12,9 @@ export const pageAnimation = {
scale: 1,
boxShadow: isActive ? "0 8px 30px rgba(0,0,0,0.15)" : "0 2px 10px rgba(0,0,0,0.1)",
transition: {
boxShadow: { duration: 0.2 },
x: { type: "tween", duration: 0.03, ease: "linear" },
y: { type: "tween", duration: 0.03, ease: "linear" },
scale: { type: "spring", stiffness: 300, damping: 15 },
Copy link
Collaborator

Choose a reason for hiding this comment

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

묵직하게 움직이는 애니메이션이 빠르게 바뀌었군요. 지금이 UX적으로 반응이더 좋은 듯 하네요!

},
}),
};
Expand Down
7 changes: 2 additions & 5 deletions client/src/features/page/Page.style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import { glassContainer } from "@styled-system/recipes";
export const pageContainer = cx(
glassContainer({ border: "lg" }),
css({
display: "flex",
position: "absolute",
flexDirection: "column",
width: "450px",
height: "400px",
}),
Expand All @@ -24,11 +26,6 @@ export const pageHeader = css({
},
});

export const pageTitle = css({
textStyle: "display-medium24",
color: "gray.500",
});

export const resizeHandle = css({
position: "absolute",
right: "-10px",
Expand Down
13 changes: 7 additions & 6 deletions client/src/features/page/Page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { Page as PageType } from "@src/types/page";
import { motion, AnimatePresence } from "framer-motion";
import { useRef } from "react";
import { Editor } from "@features/editor/Editor";
import { Page as PageType } from "@src/types/page";
import { pageAnimation, resizeHandleAnimation } from "./Page.animation";
import { pageContainer, pageHeader, resizeHandle } from "./Page.style";

Expand All @@ -10,7 +9,7 @@ import { PageTitle } from "./components/PageTitle/PageTitle";
import { usePage } from "./hooks/usePage";

interface PageProps extends PageType {
handlePageSelect: (pageId: number) => void;
handlePageSelect: ({ pageId, isSidebar }: { pageId: number; isSidebar?: boolean }) => void;
handlePageClose: (pageId: number) => void;
handleTitleChange: (pageId: number, newTitle: string) => void;
}
Expand All @@ -26,7 +25,6 @@ export const Page = ({
handlePageClose,
handleTitleChange,
}: PageProps) => {
const pageRef = useRef<HTMLDivElement>(null);
const { position, size, pageDrag, pageResize, pageMinimize, pageMaximize } = usePage({ x, y });

const onTitleChange = (newTitle: string) => {
Expand All @@ -36,7 +34,6 @@ export const Page = ({
return (
<AnimatePresence>
<motion.div
ref={pageRef}
className={pageContainer}
initial={pageAnimation.initial}
animate={pageAnimation.animate({
Expand All @@ -49,7 +46,11 @@ export const Page = ({
height: `${size.height}px`,
zIndex,
}}
onPointerDown={() => handlePageSelect(id)}
onPointerDown={() =>
handlePageSelect({
pageId: id,
})
}
>
<div className={pageHeader} onPointerDown={pageDrag}>
<PageTitle title={title} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ import { css, cva } from "@styled-system/css";
export const pageControlContainer = css({
display: "flex",
gap: "sm",
_hover: {
"& svg": {
transform: "scale(1)", // 추가 효과
opacity: 1,
},
},
});

export const pageControlButton = cva({
Expand All @@ -20,3 +26,11 @@ export const pageControlButton = cva({
},
},
});

export const iconBox = css({
transform: "scale(0.8)",
strokeWidth: "2.5px",
color: "white/90",
opacity: 0,
transition: "all 0.1s ease",
});
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { pageControlContainer, pageControlButton } from "./PageControlButton.style";
import CloseIcon from "@assets/icons/close.svg?react";
import ExpandIcon from "@assets/icons/expand.svg?react";
import MinusIcon from "@assets/icons/minus.svg?react";
import { pageControlContainer, pageControlButton, iconBox } from "./PageControlButton.style";
Comment on lines +1 to +3
Copy link
Collaborator

Choose a reason for hiding this comment

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

svg 이미지를 컴포넌트로 사용하는 방식이네요!


interface PageControlButtonProps {
onPageMinimize?: () => void;
Expand All @@ -13,11 +16,15 @@ export const PageControlButton = ({
}: PageControlButtonProps) => {
return (
<div className={pageControlContainer}>
<button className={pageControlButton({ color: "yellow" })} onClick={onPageMinimize} />

<button className={pageControlButton({ color: "red" })} onClick={onPageClose} />

<button className={pageControlButton({ color: "green" })} onClick={onPageMaximize} />
<button className={pageControlButton({ color: "yellow" })} onClick={onPageMinimize}>
<MinusIcon className={iconBox} />
</button>
<button className={pageControlButton({ color: "green" })} onClick={onPageMaximize}>
<ExpandIcon className={iconBox} />
</button>
<button className={pageControlButton({ color: "red" })} onClick={onPageClose}>
<CloseIcon className={iconBox} />
</button>
</div>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,7 @@ import { css } from "@styled-system/css";
export const pageTitle = css({
textStyle: "display-medium24",
color: "gray.500",
textOverflow: "ellipsis",
overflow: "hidden",
whiteSpace: "nowrap",
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
Collaborator

Choose a reason for hiding this comment

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

다만 placeholder 는 여전히 보이네요 ..!
image

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
Collaborator

Choose a reason for hiding this comment

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

webkit을 통해 우측 스크롤바 디자인을 변경해봐도 좋을것 같습니다!

Copy link
Member Author

Choose a reason for hiding this comment

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

스크롤바 디자인 간단하게 수정해봤습니다!

2024-11-17.8.03.02.mov

Copy link
Collaborator

Choose a reason for hiding this comment

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

이게 훨씬 깔끔하네요! 너무좋습니다 !!

});
4 changes: 2 additions & 2 deletions client/src/features/page/hooks/usePage.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { useIsSidebarOpen } from "@src/stores/useSidebarStore";
import { Position, Size } from "@src/types/page";
import { useEffect, useState } from "react";
import { PAGE, SIDE_BAR } from "@constants/size";
import { SPACING } from "@constants/spacing";
import { useIsSidebarOpen } from "@src/stores/useSidebarStore";
import { Position, Size } from "@src/types/page";

const PADDING = SPACING.MEDIUM * 2;

Expand Down
Loading
Loading