Responsiveness and tabs #179

Merged
enes merged 23 commits from 177-sticky-side-columns into staging 2024-09-05 07:30:55 +00:00
2 changed files with 99 additions and 13 deletions
Showing only changes of commit d9be05165f - Show all commits

View File

@ -9,12 +9,18 @@
grid-auto-flow: column; grid-auto-flow: column;
grid-auto-columns: 100%; grid-auto-columns: 100%;
// Hide Scrollbar and let's use tabs to navigate
-ms-overflow-style: none; /* Internet Explorer 10+ */
scrollbar-width: none; /* Firefox */
&::-webkit-scrollbar {
display: none; /* Safari and Chrome */
}
overflow-x: auto; overflow-x: auto;
overscroll-behavior-inline: contain; overscroll-behavior-inline: contain;
scroll-snap-type: inline mandatory; scroll-snap-type: inline mandatory;
> * { > * {
scroll-margin-top: $header-height + $body-vertical-padding;
scroll-snap-align: start; scroll-snap-align: start;
} }
} }
@ -54,3 +60,25 @@
overflow-y: auto; overflow-y: auto;
} }
} }
.navTabs {
display: none;
position: fixed;
left: 0;
bottom: 0;
right: 0;
z-index: 2;
background: $overlay-background-color;
box-shadow: 0 0 4px 0 rgb(0, 0, 0, 0.1);
padding: 5px;
gap: 5px;
@media only screen and (max-width: 767px) {
display: flex;
}
> li {
flex-grow: 1;
}
}

View File

@ -1,6 +1,13 @@
import { PropsWithChildren, ReactNode } from 'react' import { PropsWithChildren, ReactNode, useRef, useState } from 'react'
import styles from './StickySideColumns.module.scss' import styles from './StickySideColumns.module.scss'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import {
faFile,
faFileCirclePlus,
faToolbox
} from '@fortawesome/free-solid-svg-icons'
import { Button } from '@mui/material'
interface StickySideColumnsProps { interface StickySideColumnsProps {
left?: ReactNode left?: ReactNode
@ -12,19 +19,70 @@ export const StickySideColumns = ({
right, right,
children children
}: PropsWithChildren<StickySideColumnsProps>) => { }: PropsWithChildren<StickySideColumnsProps>) => {
const ref = useRef<HTMLDivElement>(null)
const [tab, setTab] = useState('nav-content')
const handleNavClick = (id: string) => {
setTab(id)
const x = document.getElementById(id)?.offsetLeft
if (ref.current) {
ref.current.scrollTo({
left: x,
behavior: 'smooth'
})
}
}
const isActive = (id: string) => id === tab
return ( return (
<div className={styles.container}> <>
<div className={`${styles.sidesWrap} ${styles.files}`}> <div className={styles.container} ref={ref}>
<div id="nav-left" className={`${styles.sidesWrap} ${styles.files}`}>
<div className={styles.sides}>{left}</div> <div className={styles.sides}>{left}</div>
</div> </div>
<div> <div id="nav-content">
<div id="content-preview" className={styles.content}> <div id="content-preview" className={styles.content}>
{children} {children}
</div> </div>
</div> </div>
<div className={styles.sidesWrap}> <div id="nav-right" className={styles.sidesWrap}>
<div className={styles.sides}>{right}</div> <div className={styles.sides}>{right}</div>
</div> </div>
</div> </div>
<ul className={styles.navTabs}>
<li>
<Button
fullWidth
variant="text"
onClick={() => handleNavClick('nav-left')}
className={`${isActive('nav-left') && styles.active}`}
aria-label="nav left"
>
<FontAwesomeIcon icon={faFileCirclePlus} />
</Button>
</li>
<li>
<Button
fullWidth
variant="text"
onClick={() => handleNavClick('nav-content')}
className={`${isActive('nav-content') && styles.active}`}
aria-label="nav middle"
>
<FontAwesomeIcon icon={faFile} />
</Button>
</li>
<li>
<Button
fullWidth
variant="text"
onClick={() => handleNavClick('nav-right')}
className={`${isActive('nav-right') && styles.active}`}
aria-label="nav right"
>
<FontAwesomeIcon icon={faToolbox} />
</Button>
</li>
</ul>
</>
) )
} }