diff --git a/directory/src/component/dropdown.jsx b/directory/src/component/dropdown.jsx
index b54ede2..3ab7869 100644
--- a/directory/src/component/dropdown.jsx
+++ b/directory/src/component/dropdown.jsx
@@ -24,29 +24,38 @@ export default function Dropdown(props) {
{
props.menu.map((item) => {
- if (item.type === 'group') {
- return (
-
- )
+ switch (item.type) {
+ case 'date': {
+ return (
+
+ )
+ }
+ case 'custom': {
+ return (
+ item.component
+ )
+ }
+ default: {
+ return (
+ - {
+ props.onClick(item)
+ toggleDropdown()
+ }}
+ >
+
+
+ )
+ }
}
- return (
- - {
- props.onClick(item)
- toggleDropdown()
- }}
- >
-
-
- )
})
}
diff --git a/directory/src/component/scss/dropdown.module.scss b/directory/src/component/scss/dropdown.module.scss
index 36ac819..58afc33 100644
--- a/directory/src/component/scss/dropdown.module.scss
+++ b/directory/src/component/scss/dropdown.module.scss
@@ -56,7 +56,7 @@
color: var(--link-highlight-color);
cursor: auto;
- .group {
+ .date {
font-family: "Bender";
font-weight: bold;
font-size: 24px;
diff --git a/directory/src/component/scss/totop_button.module.scss b/directory/src/component/scss/totop_button.module.scss
new file mode 100644
index 0000000..deb33a5
--- /dev/null
+++ b/directory/src/component/scss/totop_button.module.scss
@@ -0,0 +1,84 @@
+.totop-button {
+ position: fixed;
+ user-select: none;
+ z-index: 2;
+ cursor: pointer;
+ height: 2rem;
+ right: 2rem;
+ bottom: 1rem;
+ display: flex;
+ flex-direction: column;
+ align-items: stretch;
+ justify-content: flex-start;
+ width: 3rem;
+ height: 3rem;
+ opacity: 0;
+ transition: opacity cubic-bezier(0.65, 0.05, 0.36, 1) 0.3s;
+
+ &.show {
+ opacity: 1;
+ }
+
+ .bar {
+ position: absolute;
+ width: 100%;
+ height: 0.3rem;
+ background-color: var(--text-color-full);
+ will-change: auto;
+ }
+
+ .bar:nth-child(1) {
+ transform: rotateZ(45deg) scaleX(0.5) translateX(45%);
+ }
+
+ .bar:nth-child(2) {
+ transform: rotateZ(-45deg) scaleX(0.5) translateX(-45%);
+ }
+
+ .bar:nth-child(3), .bar:nth-child(4) {
+ transform: translateY(450%) rotateZ(90deg) scaleX(0.5);
+ }
+
+ &.clicked {
+ .bar:nth-child(1) {
+ animation: transform-1 2s cubic-bezier(0.65, 0.05, 0.36, 1) infinite;
+ }
+
+ .bar:nth-child(2) {
+ animation: transform-2 2s cubic-bezier(0.65, 0.05, 0.36, 1) infinite;
+ }
+
+ .bar:nth-child(3) {
+ animation: transform-3 2s cubic-bezier(0.65, 0.05, 0.36, 1) infinite;
+ }
+
+ .bar:nth-child(4) {
+ animation: transform-4 2s cubic-bezier(0.65, 0.05, 0.36, 1) infinite;
+ }
+ }
+}
+
+@keyframes transform-1 {
+ 50% {
+ transform: translateY(450%) rotateZ(-90deg) scaleX(0.5);
+ }
+}
+
+@keyframes transform-2 {
+ 50% {
+ transform: translateY(450%) rotateZ(90deg) scaleX(0.5);
+ }
+}
+
+
+@keyframes transform-3 {
+ 50% {
+ transform: rotateZ(225deg) scaleX(0.5) translateX(-45%);
+ }
+}
+
+@keyframes transform-4 {
+ 50% {
+ transform: rotateZ(-45deg) scaleX(0.5) translateX(-45%);
+ }
+}
\ No newline at end of file
diff --git a/directory/src/component/totop_button.jsx b/directory/src/component/totop_button.jsx
new file mode 100644
index 0000000..d4daf97
--- /dev/null
+++ b/directory/src/component/totop_button.jsx
@@ -0,0 +1,67 @@
+import React, {
+ useEffect,
+ useState,
+ useCallback
+} from 'react';
+import PropTypes from 'prop-types';
+import classes from './scss/totop_button.module.scss'
+
+export default function ToTopButton(props) {
+ const [hidden, setHidden] = useState(true)
+ const [clicked, setClicked] = useState(false)
+
+ useEffect(() => {
+ const handleButton = () => {
+ const scrollBarPos = window.pageYOffset || 0;
+ setHidden(!(scrollBarPos > 100))
+ }
+ window.addEventListener('scroll', handleButton)
+ return () => {
+ window.removeEventListener('scroll', handleButton)
+ }
+ }, [])
+
+ const smoothScroll = useCallback(
+ (target) => {
+ const targetElement = document.querySelector(target);
+ const targetPosition = targetElement.getBoundingClientRect().top + window.pageYOffset;
+ const startPosition = window.pageYOffset;
+ const distance = targetPosition - startPosition;
+ const duration = 1000;
+ let start = null;
+ window.requestAnimationFrame(step);
+ function step(timestamp) {
+ if (!start) start = timestamp;
+ const progress = timestamp - start;
+ window.scrollTo(0, easeInOutCubic(progress, startPosition, distance, duration));
+ if (progress < duration) window.requestAnimationFrame(step);
+ }
+ function easeInOutCubic(t, b, c, d) {
+ t /= d / 2;
+ if (t < 1) return c / 2 * t * t * t + b;
+ t -= 2;
+ return c / 2 * (t * t * t + 2) + b;
+ }
+ setClicked(true)
+ setTimeout(() => {
+ setClicked(false)
+ }, duration)
+ }, [])
+
+ return (
+ <>
+ { smoothScroll("#root") }}
+ >
+
+
+
+
+
+ >
+ )
+}
+ToTopButton.propTypes = {
+ onClick: PropTypes.func,
+ className: PropTypes.string,
+};
\ No newline at end of file
diff --git a/directory/src/routes/Root.jsx b/directory/src/routes/Root.jsx
index e316add..581aa8f 100644
--- a/directory/src/routes/Root.jsx
+++ b/directory/src/routes/Root.jsx
@@ -31,6 +31,7 @@ import Popup from '@/component/popup';
import ReturnButton from '@/component/return_button';
import Border from '@/component/border';
import CharIcon from '@/component/char_icon';
+import ToTopButton from '@/component/totop_button';
const currentYear = new Date().getFullYear()
@@ -132,6 +133,7 @@ export default function Root() {
+
@@ -305,7 +307,7 @@ function HeaderButton() {
list.push({
name: key,
value: null,
- type: "group",
+ type: "date",
})
value.forEach((item) => {
list.push({