diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index 2dea8c1..34e2607 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -20268,6 +20268,15 @@
"throttle-debounce": "^2.1.0"
}
},
+ "react-spring": {
+ "version": "8.0.27",
+ "resolved": "https://registry.npmjs.org/react-spring/-/react-spring-8.0.27.tgz",
+ "integrity": "sha512-nDpWBe3ZVezukNRandTeLSPcwwTMjNVu1IDq9qA/AMiUqHuRN4BeSWvKr3eIxxg1vtiYiOLy4FqdfCP5IoP77g==",
+ "requires": {
+ "@babel/runtime": "^7.3.1",
+ "prop-types": "^15.5.8"
+ }
+ },
"react-syntax-highlighter": {
"version": "13.5.3",
"resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-13.5.3.tgz",
diff --git a/frontend/package.json b/frontend/package.json
index f00b888..faf69ae 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -23,6 +23,7 @@
"react-app-rewired": "^2.1.6",
"react-dom": "^17.0.1",
"react-scripts": "^4.0.1",
+ "react-spring": "^8.0.27",
"recoil": "^0.1.2",
"typescript": "^4.1.2",
"web-vitals": "^0.2.4"
diff --git a/frontend/src/components/atoms/HeaderButton/HeaderButton.tsx b/frontend/src/components/atoms/HeaderButton/HeaderButton.tsx
index 087d0f9..a0c0ad0 100644
--- a/frontend/src/components/atoms/HeaderButton/HeaderButton.tsx
+++ b/frontend/src/components/atoms/HeaderButton/HeaderButton.tsx
@@ -8,12 +8,15 @@ const buttonCss = (): SerializedStyles => css`
user-select: none;
cursor: pointer;
color: inherit;
- minwidth: 0px;
+ min-width: 0px;
padding: 6px;
margin: auto;
white-space: nowrap;
border-radius: 3px;
font-size: inherit;
+ border: 0;
+ outline: 0;
+
&:hover {
background-color: #cccccc;
}
diff --git a/frontend/src/components/molecules/Menu/Menu.tsx b/frontend/src/components/molecules/Menu/Menu.tsx
index a7f7ec6..4c24ff8 100644
--- a/frontend/src/components/molecules/Menu/Menu.tsx
+++ b/frontend/src/components/molecules/Menu/Menu.tsx
@@ -16,6 +16,8 @@ import { HeaderButton } from '@atoms/index';
import { ReactComponent as DoubleChevronLeft } from '@assets/doubleChevronLeft.svg';
import { ReactComponent as PlusPage } from '@assets/plusPage.svg';
import { MenuItem } from '@molecules/index';
+import { animated, useSpring } from 'react-spring';
+import styled from '@emotion/styled';
const wrapperCss = (staticMenuToggle: boolean) => css`
position: relative;
@@ -34,7 +36,16 @@ const workspaceCss = () => css`
width: 100%;
color: rgba(55, 53, 47, 0.6);
`;
-const buttonsCss = () => css`
+const plusCss = (staticMenuToggle: boolean) => css`
+ margin-right: ${staticMenuToggle ? 5 : 0}px;
+ border: 1px solid rgba(55, 53, 47, 0.16);
+ border-radius: 3px;
+`;
+const menuListCss = () => css`
+ overflow-y: auto;
+ height: calc(100% - 44px);
+`;
+const AnimatedButtons = styled(animated.div)`
position: absolute;
top: 7px;
right: 0;
@@ -46,11 +57,6 @@ const buttonsCss = () => css`
margin-right: 14px;
min-width: 0;
`;
-const plusCss = (staticMenuToggle: boolean) => css`
- margin-right: ${staticMenuToggle ? 5 : 0}px;
- border: 1px solid rgba(55, 53, 47, 0.16);
- border-radius: 3px;
-`;
function Menu(): JSX.Element {
const [pages, setPages] = useRecoilState(pagesState);
@@ -62,6 +68,9 @@ function Menu(): JSX.Element {
hoveredMenuToggleState,
);
const setBlockMap = useSetRecoilState(blockMapState);
+ const buttonStyleProps = useSpring({
+ opacity: hoveredMenuToggle ? 1 : 0,
+ });
const CreatingPageHandler = async () => {
const { pages: updated, page: created } = await createPage();
@@ -78,26 +87,26 @@ function Menu(): JSX.Element {
return (
- {hoveredMenuToggle && (
-
-
- {staticMenuToggle && (
-
-
-
- )}
+
+
- )}
+ {staticMenuToggle && (
+
+
+
+ )}
+
WORKSPACE
-
Loading...}>
- {pages.map((page) => (
-
- ))}
-
+
+ Loading...
}>
+ {pages.map((page) => (
+
+ ))}
+
+
);
}
diff --git a/frontend/src/components/organisms/HeaderMenu/HeaderMenu.tsx b/frontend/src/components/organisms/HeaderMenu/HeaderMenu.tsx
index f1d632b..4521c2e 100644
--- a/frontend/src/components/organisms/HeaderMenu/HeaderMenu.tsx
+++ b/frontend/src/components/organisms/HeaderMenu/HeaderMenu.tsx
@@ -1,7 +1,9 @@
/** @jsx jsx */
/** @jsxRuntime classic */
import { jsx, css } from '@emotion/react';
+import styled from '@emotion/styled';
import { useRecoilState } from 'recoil';
+import { animated, useSpring, useTransition } from 'react-spring';
import { HeaderButton } from '@components/atoms';
import { ReactComponent as HamburgerMenu } from '@assets/hamburgerMenu.svg';
@@ -9,7 +11,7 @@ import { ReactComponent as DoubleChevronRight } from '@assets/doubleChevronRight
import { hoveredMenuToggleState, staticMenuToggleState } from '@/stores';
import { Menu } from '@molecules/index';
-const wrapperCss = () => css`
+const wrapperCss = css`
position: relative;
display: flex;
align-items: center;
@@ -21,7 +23,7 @@ const wrapperCss = () => css`
margin-right: 8px;
min-width: 0;
`;
-const hoverAreaCss = () => css`
+const hoverAreaCss = css`
position: absolute;
display: inline-block;
top: 45px;
@@ -29,12 +31,17 @@ const hoverAreaCss = () => css`
width: 100%;
height: 100vh;
`;
-const menuCss = (staticMenuToggle: boolean) => css`
+const AnimatedMenu = styled(animated.div)`
position: absolute;
display: inline-block;
- top: ${staticMenuToggle ? 0 : 50}px;
- left: 0;
- margin-top: ${staticMenuToggle ? 0 : 10}px;
+`;
+const buttonWrapper = css`
+ position: relative;
+ width: 16px;
+ height: 16px;
+`;
+const AnimatedButton = styled(animated.div)`
+ position: absolute;
`;
function HeaderMenu(): JSX.Element {
@@ -44,23 +51,41 @@ function HeaderMenu(): JSX.Element {
const [hoveredMenuToggle, setHoveredMenuToggle] = useRecoilState(
hoveredMenuToggleState,
);
+ const menuStyleProps = useSpring({
+ top: staticMenuToggle ? 0 : 50,
+ left: hoveredMenuToggle || staticMenuToggle ? 0 : -240,
+ opacity: hoveredMenuToggle || staticMenuToggle ? 1 : 0,
+ marginTop: staticMenuToggle ? 0 : 10,
+ });
+ const hamburgerMenuStyleProps = useSpring({
+ opacity: hoveredMenuToggle ? 0 : 1,
+ });
+ const doubleChevronRightStyleProps = useSpring({
+ opacity: hoveredMenuToggle ? 1 : 0,
+ });
return (
setHoveredMenuToggle(true)}
onMouseLeave={() => setHoveredMenuToggle(false)}
>
setStaticMenuToggle(!staticMenuToggle)}>
- {staticMenuToggle ||
- (!hoveredMenuToggle ? : )}
+ {staticMenuToggle || (
+
+ )}
-
- {(staticMenuToggle || hoveredMenuToggle) && (
-
-
-
- )}
+
+
+
+
);
}
diff --git a/frontend/src/components/pages/PageComponent/PageComponent.tsx b/frontend/src/components/pages/PageComponent/PageComponent.tsx
index f27b1ed..9778d14 100644
--- a/frontend/src/components/pages/PageComponent/PageComponent.tsx
+++ b/frontend/src/components/pages/PageComponent/PageComponent.tsx
@@ -7,29 +7,28 @@ import { HeaderMenu } from '@components/organisms';
import { useRecoilValue, useSetRecoilState } from 'recoil';
import { blockMapState, pageState, staticMenuToggleState } from '@/stores';
import { createBlock } from '@/utils';
+import styled from '@emotion/styled';
+import { animated, useSpring } from 'react-spring';
-const staticMenuAreaCss = () => css`
+const staticMenuAreaCss = css`
position: fixed;
z-index: 2;
`;
-const staticHeaderAreaCss = (staticMenuToggle: boolean) => css`
+const AnimatedStaticHeaderArea = styled(animated.div)`
position: fixed;
right: 0;
- left: ${staticMenuToggle ? 240 : 0}px;
- width: calc(100% - ${staticMenuToggle ? 240 : 0}px);
background-color: #ffffff;
z-index: 1;
`;
-const staticScrollAreaCss = (staticMenuToggle: boolean) => css`
+const AnimatedStaticScrollArea = styled(animated.div)`
position: fixed;
top: 45px;
right: 0;
- left: ${staticMenuToggle ? 240 : 0}px;
- width: calc(100% - ${staticMenuToggle ? 240 : 0}px);
+ background-color: #ffffff;
height: calc(100% - 45px);
overflow: auto;
`;
-const bottomMarginCss = () => css`
+const bottomMarginCss = css`
display: inline-block;
width: 100%;
height: calc(100% - 200px);
@@ -40,6 +39,10 @@ function PageComponent(): JSX.Element {
const staticMenuToggle = useRecoilValue(staticMenuToggleState);
const page = useRecoilValue(pageState);
const setBlockMap = useSetRecoilState(blockMapState);
+ const staticAreaStyleProps = useSpring({
+ left: staticMenuToggle ? 240 : 0,
+ width: `calc(100% - ${staticMenuToggle ? 240 : 0}px)`,
+ });
const createBlockHandler = async () => {
const { parent, block } = await createBlock({ parentBlockId: page.rootId });
@@ -53,21 +56,21 @@ function PageComponent(): JSX.Element {
return (