diff --git a/client/package.json b/client/package.json
index 2f79c064..779c9b76 100644
--- a/client/package.json
+++ b/client/package.json
@@ -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": {
diff --git a/client/src/assets/icons/close.svg b/client/src/assets/icons/close.svg
new file mode 100644
index 00000000..3098f92d
--- /dev/null
+++ b/client/src/assets/icons/close.svg
@@ -0,0 +1,3 @@
+
diff --git a/client/src/assets/icons/expand.svg b/client/src/assets/icons/expand.svg
new file mode 100644
index 00000000..71f2465c
--- /dev/null
+++ b/client/src/assets/icons/expand.svg
@@ -0,0 +1,3 @@
+
diff --git a/client/src/assets/icons/minus.svg b/client/src/assets/icons/minus.svg
new file mode 100644
index 00000000..6dc66acf
--- /dev/null
+++ b/client/src/assets/icons/minus.svg
@@ -0,0 +1,3 @@
+
diff --git a/client/src/assets/images/background.png b/client/src/assets/images/background.png
index 9b9ee52b..9ee392c5 100644
Binary files a/client/src/assets/images/background.png and b/client/src/assets/images/background.png differ
diff --git a/client/src/components/bottomNavigator/BottomNavigator.tsx b/client/src/components/bottomNavigator/BottomNavigator.tsx
index fcfc6f50..23a3f6db 100644
--- a/client/src/components/bottomNavigator/BottomNavigator.tsx
+++ b/client/src/components/bottomNavigator/BottomNavigator.tsx
@@ -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) => {
@@ -25,7 +25,9 @@ export const BottomNavigator = ({ pages, handlePageSelect }: BottomNavigatorProp
icon={page.icon}
size="md"
onClick={() => {
- handlePageSelect(page.id);
+ handlePageSelect({
+ pageId: page.id,
+ });
}}
/>
diff --git a/client/src/components/modal/modal.animation.ts b/client/src/components/modal/modal.animation.ts
index f5f1efb1..a0bdef14 100644
--- a/client/src/components/modal/modal.animation.ts
+++ b/client/src/components/modal/modal.animation.ts
@@ -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 } },
};
diff --git a/client/src/components/modal/modal.style.ts b/client/src/components/modal/modal.style.ts
index 8ed080bd..f0998fea 100644
--- a/client/src/components/modal/modal.style.ts
+++ b/client/src/components/modal/modal.style.ts
@@ -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",
diff --git a/client/src/components/sidebar/MenuButton.style.ts b/client/src/components/sidebar/MenuButton.style.ts
index 72859892..8a3f95e1 100644
--- a/client/src/components/sidebar/MenuButton.style.ts
+++ b/client/src/components/sidebar/MenuButton.style.ts
@@ -14,6 +14,7 @@ export const imageBox = css({
borderRadius: "sm",
width: "50px",
height: "50px",
+ background: "white",
overflow: "hidden",
});
diff --git a/client/src/components/sidebar/MenuButton.tsx b/client/src/components/sidebar/MenuButton.tsx
index 8402c5a2..19c81ff9 100644
--- a/client/src/components/sidebar/MenuButton.tsx
+++ b/client/src/components/sidebar/MenuButton.tsx
@@ -3,9 +3,7 @@ import { menuItemWrapper, imageBox, textBox } from "./MenuButton.style";
export const MenuButton = () => {
return (
-
-
-
+
Noctturn
);
diff --git a/client/src/components/sidebar/PageItem.style.ts b/client/src/components/sidebar/PageItem.style.ts
index 5ee503aa..fc61c4b2 100644
--- a/client/src/components/sidebar/PageItem.style.ts
+++ b/client/src/components/sidebar/PageItem.style.ts
@@ -5,6 +5,7 @@ export const pageItemContainer = css({
gap: "sm",
alignItems: "center",
width: "100%",
+ height: "56px",
paddingInline: "md",
"&:hover": {
background: "white/50",
@@ -14,6 +15,7 @@ export const pageItemContainer = css({
export const iconBox = css({
display: "flex",
+ flexShrink: 0,
justifyContent: "center",
alignItems: "center",
borderRadius: "xs",
@@ -26,4 +28,7 @@ export const iconBox = css({
export const textBox = css({
textStyle: "display-medium20",
color: "gray.700",
+ textOverflow: "ellipsis",
+ overflow: "hidden",
+ whiteSpace: "nowrap",
});
diff --git a/client/src/components/sidebar/Sidebar.style.ts b/client/src/components/sidebar/Sidebar.style.ts
index 6f5c3fad..2cf411d3 100644
--- a/client/src/components/sidebar/Sidebar.style.ts
+++ b/client/src/components/sidebar/Sidebar.style.ts
@@ -16,11 +16,14 @@ export const navWrapper = css({
gap: "md",
flexDirection: "column",
width: "100%",
+ overflowX: "hidden",
+ overflowY: "scroll",
});
export const plusIconBox = css({
display: "flex",
justifyContent: "start",
+ marginBlock: "10px",
paddingInline: "md",
});
diff --git a/client/src/components/sidebar/Sidebar.tsx b/client/src/components/sidebar/Sidebar.tsx
index 596d4e2a..db623778 100644
--- a/client/src/components/sidebar/Sidebar.tsx
+++ b/client/src/components/sidebar/Sidebar.tsx
@@ -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";
@@ -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 (
{isSidebarOpen ? "«" : "»"}
-
-
+
+
+
{pages?.map((item) => (
- handlePageSelect(item.id, true)} />
+ handlePageItemClick(item.id)} />
))}
-
-
-
+
+
+
+
+
+ 최대 {MAX_VISIBLE_PAGE}개의 페이지만 표시할 수 있습니다
+
+ 사용하지 않는 페이지는 닫아주세요.
+
+
);
};
diff --git a/client/src/constants/page.ts b/client/src/constants/page.ts
new file mode 100644
index 00000000..bc01c68f
--- /dev/null
+++ b/client/src/constants/page.ts
@@ -0,0 +1 @@
+export const MAX_VISIBLE_PAGE = 10;
diff --git a/client/src/features/page/Page.animation.ts b/client/src/features/page/Page.animation.ts
index 1ab36da8..63e80890 100644
--- a/client/src/features/page/Page.animation.ts
+++ b/client/src/features/page/Page.animation.ts
@@ -1,6 +1,6 @@
export const pageAnimation = {
initial: {
- x: -300,
+ x: 0,
y: 0,
opacity: 0,
scale: 0.8,
@@ -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 },
},
}),
};
diff --git a/client/src/features/page/Page.style.ts b/client/src/features/page/Page.style.ts
index a286df1f..563c3748 100644
--- a/client/src/features/page/Page.style.ts
+++ b/client/src/features/page/Page.style.ts
@@ -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",
}),
@@ -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",
diff --git a/client/src/features/page/Page.tsx b/client/src/features/page/Page.tsx
index 7c03267a..74272e7b 100644
--- a/client/src/features/page/Page.tsx
+++ b/client/src/features/page/Page.tsx
@@ -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";
@@ -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;
}
@@ -26,7 +25,6 @@ export const Page = ({
handlePageClose,
handleTitleChange,
}: PageProps) => {
- const pageRef = useRef(null);
const { position, size, pageDrag, pageResize, pageMinimize, pageMaximize } = usePage({ x, y });
const onTitleChange = (newTitle: string) => {
@@ -36,7 +34,6 @@ export const Page = ({
return (
handlePageSelect(id)}
+ onPointerDown={() =>
+ handlePageSelect({
+ pageId: id,
+ })
+ }
>
diff --git a/client/src/features/page/components/PageControlButton/PageControlButton.style.ts b/client/src/features/page/components/PageControlButton/PageControlButton.style.ts
index 1aa0c628..417da660 100644
--- a/client/src/features/page/components/PageControlButton/PageControlButton.style.ts
+++ b/client/src/features/page/components/PageControlButton/PageControlButton.style.ts
@@ -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({
@@ -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",
+});
diff --git a/client/src/features/page/components/PageControlButton/PageControlButton.tsx b/client/src/features/page/components/PageControlButton/PageControlButton.tsx
index 8287b117..1224e29b 100644
--- a/client/src/features/page/components/PageControlButton/PageControlButton.tsx
+++ b/client/src/features/page/components/PageControlButton/PageControlButton.tsx
@@ -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";
interface PageControlButtonProps {
onPageMinimize?: () => void;
@@ -13,11 +16,15 @@ export const PageControlButton = ({
}: PageControlButtonProps) => {
return (
-
-
-
-
-
+
+
+
);
};
diff --git a/client/src/features/page/components/PageTitle/PageTitle.style.ts b/client/src/features/page/components/PageTitle/PageTitle.style.ts
index df1cc901..f0d967cd 100644
--- a/client/src/features/page/components/PageTitle/PageTitle.style.ts
+++ b/client/src/features/page/components/PageTitle/PageTitle.style.ts
@@ -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",
});
diff --git a/client/src/features/page/hooks/usePage.ts b/client/src/features/page/hooks/usePage.ts
index 2ec215b0..618edd2c 100644
--- a/client/src/features/page/hooks/usePage.ts
+++ b/client/src/features/page/hooks/usePage.ts
@@ -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;
diff --git a/client/src/features/workSpace/hooks/usePagesManage.ts b/client/src/features/workSpace/hooks/usePagesManage.ts
index 957ce3dc..6229d263 100644
--- a/client/src/features/workSpace/hooks/usePagesManage.ts
+++ b/client/src/features/workSpace/hooks/usePagesManage.ts
@@ -1,18 +1,10 @@
+import { useEffect, useState } from "react";
import { Page } from "@src/types/page";
-import { useState } from "react";
-
-interface usePagesManageProps {
- pages: Page[];
- addPage: () => void;
- selectPage: (pageId: number, isSidebar?: boolean) => void;
- closePage: (pageId: number) => void;
- updatePageTitle: (pageId: number, newTitle: string) => void;
-}
const INIT_ICON = "📄";
const PAGE_OFFSET = 60;
-export const usePagesManage = (): usePagesManageProps => {
+export const usePagesManage = () => {
const [pages, setPages] = useState
([]);
const getZIndex = () => {
@@ -37,14 +29,14 @@ export const usePagesManage = (): usePagesManageProps => {
]);
};
- const selectPage = (pageId: number, isSidebar: boolean = false) => {
+ const selectPage = ({ pageId }: { pageId: number }) => {
setPages((prevPages) =>
prevPages.map((page) => ({
...page,
isActive: page.id === pageId,
...(page.id === pageId && {
zIndex: getZIndex(),
- isVisible: isSidebar ? true : page.isVisible,
+ isVisible: true,
}),
})),
);
@@ -62,6 +54,21 @@ export const usePagesManage = (): usePagesManageProps => {
);
};
+ // 서버에서 처음 불러올때는 좌표를 모르기에, 초기화 과정 필요
+ const initPagePosition = () => {
+ setPages((prevPages) =>
+ prevPages.map((page, index) => ({
+ ...page,
+ x: PAGE_OFFSET * index,
+ y: PAGE_OFFSET * index,
+ })),
+ );
+ };
+
+ useEffect(() => {
+ initPagePosition();
+ }, []);
+
return {
pages,
addPage,
diff --git a/client/src/styles/global.ts b/client/src/styles/global.ts
index 837bd8e5..6ee9c598 100644
--- a/client/src/styles/global.ts
+++ b/client/src/styles/global.ts
@@ -6,4 +6,21 @@ export const globalStyles = defineGlobalStyles({
backgroundSize: "cover",
// TODO 폰트 설정
},
+
+ // 스크롤바 전체
+ "::-webkit-scrollbar": {
+ width: "8px",
+ },
+
+ // 스크롤바 전체 영역
+ "::-webkit-scrollbar-track": {
+ background: "transparent",
+ marginBottom: "12px",
+ },
+
+ // 스크롤바 핸들
+ "::-webkit-scrollbar-thumb": {
+ background: "white/50",
+ borderRadius: "lg",
+ },
});
diff --git a/client/tsconfig.json b/client/tsconfig.json
index 9af798bf..1ed5bc84 100644
--- a/client/tsconfig.json
+++ b/client/tsconfig.json
@@ -16,7 +16,7 @@
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"composite": true,
- "types": ["vite/client"],
+ "types": ["vite/client", "vite-plugin-svgr/client"],
"baseUrl": ".",
"paths": {
"@src/*": ["src/*"],
diff --git a/client/vite-env-override.d.ts b/client/vite-env-override.d.ts
new file mode 100644
index 00000000..3a982e15
--- /dev/null
+++ b/client/vite-env-override.d.ts
@@ -0,0 +1,4 @@
+declare module "*.svg" {
+ const content: React.FC>;
+ export default content;
+}
diff --git a/client/vite.config.ts b/client/vite.config.ts
index c857bc33..12ba9500 100644
--- a/client/vite.config.ts
+++ b/client/vite.config.ts
@@ -2,8 +2,11 @@ import { defineConfig } from "vite";
import path from "path";
import react from "@vitejs/plugin-react";
import tsconfigPaths from "vite-tsconfig-paths";
+import svgr from "vite-plugin-svgr";
export default defineConfig({
- plugins: [react(), tsconfigPaths()],
- resolve: { alias: { "@noctaCrdt": path.resolve(__dirname, "../@noctaCrdt") } },
+ plugins: [react(), tsconfigPaths(), svgr()],
+ resolve: {
+ alias: { "@noctaCrdt": path.resolve(__dirname, "../@noctaCrdt") },
+ },
});
diff --git a/client/vite.env.d.ts b/client/vite.env.d.ts
new file mode 100644
index 00000000..2ca039ea
--- /dev/null
+++ b/client/vite.env.d.ts
@@ -0,0 +1,2 @@
+// /
+// /
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 190afeb2..1572c74b 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -79,6 +79,9 @@ importers:
socket.io-client:
specifier: ^4.8.1
version: 4.8.1
+ vite-plugin-svgr:
+ specifier: ^4.3.0
+ version: 4.3.0(rollup@4.24.3)(typescript@5.3.3)(vite@5.4.10(@types/node@20.17.6)(lightningcss@1.25.1)(terser@5.36.0))
zustand:
specifier: ^5.0.1
version: 5.0.1(@types/react@18.3.12)(react@18.3.1)
@@ -1116,6 +1119,15 @@ packages:
resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==}
engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
+ '@rollup/pluginutils@5.1.3':
+ resolution: {integrity: sha512-Pnsb6f32CD2W3uCaLZIzDmeFyQ2b8UWMFI7xtwUezpcGBDVDW6y9XgAWIlARiGAo6eNF5FK5aQTr0LFyNyqq5A==}
+ engines: {node: '>=14.0.0'}
+ peerDependencies:
+ rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0
+ peerDependenciesMeta:
+ rollup:
+ optional: true
+
'@rollup/rollup-android-arm-eabi@4.24.3':
resolution: {integrity: sha512-ufb2CH2KfBWPJok95frEZZ82LtDl0A6QKTa8MoM+cWwDZvVGl5/jNb79pIhRvAalUu+7LD91VYR0nwRD799HkQ==}
cpu: [arm]
@@ -1228,6 +1240,74 @@ packages:
'@socket.io/component-emitter@3.1.2':
resolution: {integrity: sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==}
+ '@svgr/babel-plugin-add-jsx-attribute@8.0.0':
+ resolution: {integrity: sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==}
+ engines: {node: '>=14'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@svgr/babel-plugin-remove-jsx-attribute@8.0.0':
+ resolution: {integrity: sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==}
+ engines: {node: '>=14'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0':
+ resolution: {integrity: sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==}
+ engines: {node: '>=14'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0':
+ resolution: {integrity: sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==}
+ engines: {node: '>=14'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@svgr/babel-plugin-svg-dynamic-title@8.0.0':
+ resolution: {integrity: sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==}
+ engines: {node: '>=14'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@svgr/babel-plugin-svg-em-dimensions@8.0.0':
+ resolution: {integrity: sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==}
+ engines: {node: '>=14'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@svgr/babel-plugin-transform-react-native-svg@8.1.0':
+ resolution: {integrity: sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q==}
+ engines: {node: '>=14'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@svgr/babel-plugin-transform-svg-component@8.0.0':
+ resolution: {integrity: sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==}
+ engines: {node: '>=12'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@svgr/babel-preset@8.1.0':
+ resolution: {integrity: sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==}
+ engines: {node: '>=14'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@svgr/core@8.1.0':
+ resolution: {integrity: sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==}
+ engines: {node: '>=14'}
+
+ '@svgr/hast-util-to-babel-ast@8.0.0':
+ resolution: {integrity: sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==}
+ engines: {node: '>=14'}
+
+ '@svgr/plugin-jsx@8.1.0':
+ resolution: {integrity: sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==}
+ engines: {node: '>=14'}
+ peerDependencies:
+ '@svgr/core': '*'
+
'@ts-morph/common@0.22.0':
resolution: {integrity: sha512-HqNBuV/oIlMKdkLshXd1zKBqNQCsuPEsgQOkfFQ/eUKjRlwndXW1AjN9LVkBEIukm00gGXSRmfkl0Wv5VXLnlw==}
@@ -2129,6 +2209,9 @@ packages:
resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==}
engines: {node: '>=6.0.0'}
+ dot-case@3.0.4:
+ resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==}
+
dotenv-expand@10.0.0:
resolution: {integrity: sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A==}
engines: {node: '>=12'}
@@ -3353,6 +3436,9 @@ packages:
resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
hasBin: true
+ lower-case@2.0.2:
+ resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==}
+
lru-cache@10.4.3:
resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==}
@@ -3596,6 +3682,9 @@ packages:
resolution: {integrity: sha512-lDcBsjBSMlj3LXH2v/FW3txlh2pYTjmbOXPYJD93HI5EwuLzI11tdHSIpUMmfq/IOsldj4Ps8M8flhm+pCK4Ew==}
engines: {node: '>=12.22.0'}
+ no-case@3.0.4:
+ resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==}
+
node-abort-controller@3.1.1:
resolution: {integrity: sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==}
@@ -3785,6 +3874,10 @@ packages:
resolution: {integrity: sha512-xUXwsxNjwTQ8K3GnT4pCJm+xq3RUPQbmkYJTP5aFIfNIvbcc/4MUxgBaaRSZJ6yGJZiGSyYlM6MzwTsRk8SYCg==}
engines: {node: '>=12'}
+ picomatch@4.0.2:
+ resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==}
+ engines: {node: '>=12'}
+
pify@4.0.1:
resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==}
engines: {node: '>=6'}
@@ -4152,6 +4245,9 @@ packages:
resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==}
engines: {node: '>= 6.0.0', npm: '>= 3.0.0'}
+ snake-case@3.0.4:
+ resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==}
+
socket.io-adapter@2.5.5:
resolution: {integrity: sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg==}
@@ -4301,6 +4397,9 @@ packages:
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
engines: {node: '>= 0.4'}
+ svg-parser@2.0.4:
+ resolution: {integrity: sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==}
+
symbol-observable@4.0.0:
resolution: {integrity: sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==}
engines: {node: '>=0.10'}
@@ -4580,6 +4679,11 @@ packages:
resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==}
engines: {node: '>= 0.8'}
+ vite-plugin-svgr@4.3.0:
+ resolution: {integrity: sha512-Jy9qLB2/PyWklpYy0xk0UU3TlU0t2UMpJXZvf+hWII1lAmRHrOUKi11Uw8N3rxoNk7atZNYO3pR3vI1f7oi+6w==}
+ peerDependencies:
+ vite: '>=2.6.0'
+
vite-tsconfig-paths@5.1.0:
resolution: {integrity: sha512-Y1PLGHCJfAq1Zf4YIGEsmuU/NCX1epoZx9zwSr32Gjn3aalwQHRKr5aUmbo6r0JHeHkqmWpmDg7WOynhYXw1og==}
peerDependencies:
@@ -5939,6 +6043,14 @@ snapshots:
'@pkgr/core@0.1.1': {}
+ '@rollup/pluginutils@5.1.3(rollup@4.24.3)':
+ dependencies:
+ '@types/estree': 1.0.6
+ estree-walker: 2.0.2
+ picomatch: 4.0.2
+ optionalDependencies:
+ rollup: 4.24.3
+
'@rollup/rollup-android-arm-eabi@4.24.3':
optional: true
@@ -6021,6 +6133,76 @@ snapshots:
'@socket.io/component-emitter@3.1.2': {}
+ '@svgr/babel-plugin-add-jsx-attribute@8.0.0(@babel/core@7.26.0)':
+ dependencies:
+ '@babel/core': 7.26.0
+
+ '@svgr/babel-plugin-remove-jsx-attribute@8.0.0(@babel/core@7.26.0)':
+ dependencies:
+ '@babel/core': 7.26.0
+
+ '@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0(@babel/core@7.26.0)':
+ dependencies:
+ '@babel/core': 7.26.0
+
+ '@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0(@babel/core@7.26.0)':
+ dependencies:
+ '@babel/core': 7.26.0
+
+ '@svgr/babel-plugin-svg-dynamic-title@8.0.0(@babel/core@7.26.0)':
+ dependencies:
+ '@babel/core': 7.26.0
+
+ '@svgr/babel-plugin-svg-em-dimensions@8.0.0(@babel/core@7.26.0)':
+ dependencies:
+ '@babel/core': 7.26.0
+
+ '@svgr/babel-plugin-transform-react-native-svg@8.1.0(@babel/core@7.26.0)':
+ dependencies:
+ '@babel/core': 7.26.0
+
+ '@svgr/babel-plugin-transform-svg-component@8.0.0(@babel/core@7.26.0)':
+ dependencies:
+ '@babel/core': 7.26.0
+
+ '@svgr/babel-preset@8.1.0(@babel/core@7.26.0)':
+ dependencies:
+ '@babel/core': 7.26.0
+ '@svgr/babel-plugin-add-jsx-attribute': 8.0.0(@babel/core@7.26.0)
+ '@svgr/babel-plugin-remove-jsx-attribute': 8.0.0(@babel/core@7.26.0)
+ '@svgr/babel-plugin-remove-jsx-empty-expression': 8.0.0(@babel/core@7.26.0)
+ '@svgr/babel-plugin-replace-jsx-attribute-value': 8.0.0(@babel/core@7.26.0)
+ '@svgr/babel-plugin-svg-dynamic-title': 8.0.0(@babel/core@7.26.0)
+ '@svgr/babel-plugin-svg-em-dimensions': 8.0.0(@babel/core@7.26.0)
+ '@svgr/babel-plugin-transform-react-native-svg': 8.1.0(@babel/core@7.26.0)
+ '@svgr/babel-plugin-transform-svg-component': 8.0.0(@babel/core@7.26.0)
+
+ '@svgr/core@8.1.0(typescript@5.3.3)':
+ dependencies:
+ '@babel/core': 7.26.0
+ '@svgr/babel-preset': 8.1.0(@babel/core@7.26.0)
+ camelcase: 6.3.0
+ cosmiconfig: 8.3.6(typescript@5.3.3)
+ snake-case: 3.0.4
+ transitivePeerDependencies:
+ - supports-color
+ - typescript
+
+ '@svgr/hast-util-to-babel-ast@8.0.0':
+ dependencies:
+ '@babel/types': 7.26.0
+ entities: 4.5.0
+
+ '@svgr/plugin-jsx@8.1.0(@svgr/core@8.1.0(typescript@5.3.3))':
+ dependencies:
+ '@babel/core': 7.26.0
+ '@svgr/babel-preset': 8.1.0(@babel/core@7.26.0)
+ '@svgr/core': 8.1.0(typescript@5.3.3)
+ '@svgr/hast-util-to-babel-ast': 8.0.0
+ svg-parser: 2.0.4
+ transitivePeerDependencies:
+ - supports-color
+
'@ts-morph/common@0.22.0':
dependencies:
fast-glob: 3.3.2
@@ -7050,6 +7232,11 @@ snapshots:
dependencies:
esutils: 2.0.3
+ dot-case@3.0.4:
+ dependencies:
+ no-case: 3.0.4
+ tslib: 2.8.1
+
dotenv-expand@10.0.0: {}
dotenv@16.4.5: {}
@@ -8650,6 +8837,10 @@ snapshots:
dependencies:
js-tokens: 4.0.0
+ lower-case@2.0.2:
+ dependencies:
+ tslib: 2.8.1
+
lru-cache@10.4.3: {}
lru-cache@5.1.1:
@@ -8913,6 +9104,11 @@ snapshots:
transitivePeerDependencies:
- supports-color
+ no-case@3.0.4:
+ dependencies:
+ lower-case: 2.0.2
+ tslib: 2.8.1
+
node-abort-controller@3.1.1: {}
node-emoji@1.11.0:
@@ -9084,6 +9280,8 @@ snapshots:
picomatch@4.0.1: {}
+ picomatch@4.0.2: {}
+
pify@4.0.1: {}
pirates@4.0.6: {}
@@ -9500,6 +9698,11 @@ snapshots:
smart-buffer@4.2.0: {}
+ snake-case@3.0.4:
+ dependencies:
+ dot-case: 3.0.4
+ tslib: 2.8.1
+
socket.io-adapter@2.5.5:
dependencies:
debug: 4.3.7
@@ -9717,6 +9920,8 @@ snapshots:
supports-preserve-symlinks-flag@1.0.0: {}
+ svg-parser@2.0.4: {}
+
symbol-observable@4.0.0: {}
synckit@0.9.2:
@@ -9988,6 +10193,17 @@ snapshots:
vary@1.1.2: {}
+ vite-plugin-svgr@4.3.0(rollup@4.24.3)(typescript@5.3.3)(vite@5.4.10(@types/node@20.17.6)(lightningcss@1.25.1)(terser@5.36.0)):
+ dependencies:
+ '@rollup/pluginutils': 5.1.3(rollup@4.24.3)
+ '@svgr/core': 8.1.0(typescript@5.3.3)
+ '@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@5.3.3))
+ vite: 5.4.10(@types/node@20.17.6)(lightningcss@1.25.1)(terser@5.36.0)
+ transitivePeerDependencies:
+ - rollup
+ - supports-color
+ - typescript
+
vite-tsconfig-paths@5.1.0(typescript@5.3.3)(vite@5.4.10(@types/node@20.17.6)(lightningcss@1.25.1)(terser@5.36.0)):
dependencies:
debug: 4.3.7