Add scroll to top button
This commit is contained in:
@@ -1,18 +1,42 @@
|
|||||||
/** @jsxImportSource theme-ui */
|
/** @jsxImportSource theme-ui */
|
||||||
|
|
||||||
import { mdiMenu } from '@mdi/js'
|
import { mdiArrowUp, mdiMenu } from '@mdi/js'
|
||||||
import Icon from '@mdi/react'
|
import Icon from '@mdi/react'
|
||||||
import React, { useCallback, useState } from 'react'
|
import React, { useCallback, useRef, useState } from 'react'
|
||||||
import { Box, Flex, IconButton } from 'theme-ui'
|
import { Box, Flex, IconButton } from 'theme-ui'
|
||||||
import Honkai3rdNavigator from '../organisms/Honkai3rdNavigator'
|
import Honkai3rdNavigator from '../organisms/Honkai3rdNavigator'
|
||||||
|
|
||||||
const Honkai3rdLayout: React.FC = ({ children }) => {
|
const Honkai3rdLayout: React.FC = ({ children }) => {
|
||||||
const [hiddenMobileNav, setHiddenMobileNav] = useState(true)
|
const [hiddenMobileNav, setHiddenMobileNav] = useState(true)
|
||||||
|
const contentBoxRef = useRef<HTMLDivElement>(null)
|
||||||
|
const [scrolled, setScrolled] = useState(false)
|
||||||
|
|
||||||
const close = useCallback(() => {
|
const close = useCallback(() => {
|
||||||
setHiddenMobileNav(true)
|
setHiddenMobileNav(true)
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
|
const handleScroll = useCallback(() => {
|
||||||
|
if (contentBoxRef.current == null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (contentBoxRef.current.scrollTop === 0) {
|
||||||
|
return setScrolled(false)
|
||||||
|
}
|
||||||
|
if (scrolled) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
setScrolled(true)
|
||||||
|
}, [scrolled])
|
||||||
|
|
||||||
|
const scrollToTop = useCallback(() => {
|
||||||
|
if (contentBoxRef.current == null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
contentBoxRef.current.scrollTop = 0
|
||||||
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex
|
<Flex
|
||||||
sx={{
|
sx={{
|
||||||
@@ -33,14 +57,40 @@ const Honkai3rdLayout: React.FC = ({ children }) => {
|
|||||||
>
|
>
|
||||||
<Honkai3rdNavigator close={close} />
|
<Honkai3rdNavigator close={close} />
|
||||||
</Box>
|
</Box>
|
||||||
<Box sx={{ flex: 1, overflowY: 'auto', overflowX: 'hidden' }}>
|
<Box
|
||||||
|
sx={{
|
||||||
|
flex: 1,
|
||||||
|
overflowY: 'auto',
|
||||||
|
overflowX: 'hidden',
|
||||||
|
scrollBehavior: 'smooth',
|
||||||
|
}}
|
||||||
|
onScroll={handleScroll}
|
||||||
|
ref={contentBoxRef}
|
||||||
|
>
|
||||||
|
<IconButton
|
||||||
|
sx={{
|
||||||
|
width: 50,
|
||||||
|
height: 50,
|
||||||
|
position: 'absolute',
|
||||||
|
bottom: 1,
|
||||||
|
right: 1,
|
||||||
|
zIndex: 1000,
|
||||||
|
pointerEvents: scrolled ? 'auto' : 'none',
|
||||||
|
opacity: scrolled ? 1 : 0,
|
||||||
|
transition: 'opacity 200ms ease-in-out',
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
}}
|
||||||
|
onClick={scrollToTop}
|
||||||
|
>
|
||||||
|
<Icon path={mdiArrowUp} size={1} />
|
||||||
|
</IconButton>
|
||||||
<Flex
|
<Flex
|
||||||
sx={{
|
sx={{
|
||||||
position: 'sticky',
|
position: 'sticky',
|
||||||
display: ['block', 'none'],
|
display: ['block', 'none'],
|
||||||
top: 0,
|
top: 0,
|
||||||
height: 50,
|
height: 50,
|
||||||
bg: 'rgba(255,255,255,0.8)',
|
bg: 'transparent',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<IconButton
|
<IconButton
|
||||||
|
|||||||
+3
-2
@@ -19,6 +19,7 @@ export const theme: Theme = {
|
|||||||
light: '#f8f9fa',
|
light: '#f8f9fa',
|
||||||
dark: '#343a40',
|
dark: '#343a40',
|
||||||
textMuted: '#6c757d',
|
textMuted: '#6c757d',
|
||||||
|
transparent: 'transparent',
|
||||||
},
|
},
|
||||||
space: ['0rem', '0.25rem', '0.5rem', '1rem', '1.5rem', '3rem'],
|
space: ['0rem', '0.25rem', '0.5rem', '1rem', '1.5rem', '3rem'],
|
||||||
fonts: {
|
fonts: {
|
||||||
@@ -107,7 +108,7 @@ export const theme: Theme = {
|
|||||||
'box-shadow 200ms ease-in-out, color 200ms ease-in-out, background-color 200ms ease-in-out',
|
'box-shadow 200ms ease-in-out, color 200ms ease-in-out, background-color 200ms ease-in-out',
|
||||||
'&:hover': {
|
'&:hover': {
|
||||||
bg: 'rgba(0, 123, 255, 0.2)',
|
bg: 'rgba(0, 123, 255, 0.2)',
|
||||||
boxShadow: 'rgba(0, 0, 0, 0.2) 0px 4px 8px;',
|
boxShadow: 'default',
|
||||||
},
|
},
|
||||||
'&.hidden': {
|
'&.hidden': {
|
||||||
display: 'none',
|
display: 'none',
|
||||||
@@ -228,7 +229,7 @@ export const theme: Theme = {
|
|||||||
transition:
|
transition:
|
||||||
'box-shadow 200ms ease-in-out, color 200ms ease-in-out, background-color 200ms ease-in-out',
|
'box-shadow 200ms ease-in-out, color 200ms ease-in-out, background-color 200ms ease-in-out',
|
||||||
'&:hover': {
|
'&:hover': {
|
||||||
boxShadow: 'rgba(0, 0, 0, 0.2) 0px 4px 8px;',
|
boxShadow: 'default',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
stigmata: {
|
stigmata: {
|
||||||
|
|||||||
Reference in New Issue
Block a user