Responsiveness and tabs #179

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

View File

@ -43,21 +43,27 @@
position: sticky; position: sticky;
top: $header-height + $body-vertical-padding; top: $header-height + $body-vertical-padding;
} }
> :first-child {
max-height: calc(
100svh - $header-height - $body-vertical-padding * 2 - $tabs-height
);
}
} }
.files { .scrollAdjust {
display: flex; @media only screen and (max-width: 767px) {
flex-direction: column; max-height: calc(
grid-gap: 15px; 100svh - $header-height - $body-vertical-padding * 2 - $tabs-height
);
overflow-y: auto;
}
} }
.content { .content {
@media only screen and (min-width: 768px) {
padding: 10px; padding: 10px;
border: 10px solid $overlay-background-color; border: 10px solid $overlay-background-color;
border-radius: 4px; border-radius: 4px;
@media only screen and (max-width: 767px) {
max-height: calc(100svh - $header-height + $body-vertical-padding * 2);
overflow-y: auto;
} }
} }
@ -67,6 +73,7 @@
left: 0; left: 0;
bottom: 0; bottom: 0;
right: 0; right: 0;
height: $tabs-height;
z-index: 2; z-index: 2;
background: $overlay-background-color; background: $overlay-background-color;
box-shadow: 0 0 4px 0 rgb(0, 0, 0, 0.1); box-shadow: 0 0 4px 0 rgb(0, 0, 0, 0.1);

View File

@ -21,18 +21,17 @@ interface StickySideColumnsProps {
} }
const DEFAULT_TAB = 'nav-content' const DEFAULT_TAB = 'nav-content'
export const StickySideColumns = ({ export const StickySideColumns = ({
left, left,
right, right,
children children
}: PropsWithChildren<StickySideColumnsProps>) => { }: PropsWithChildren<StickySideColumnsProps>) => {
const ref = useRef<HTMLDivElement>(null)
const [tab, setTab] = useState(DEFAULT_TAB) const [tab, setTab] = useState(DEFAULT_TAB)
const ref = useRef<HTMLDivElement>(null)
const tabsRefs = useRef<{ [id: string]: HTMLDivElement | null }>({})
const handleNavClick = (id: string) => { const handleNavClick = (id: string) => {
setTab(id) if (ref.current && tabsRefs.current) {
const x = document.getElementById(id)?.offsetLeft const x = tabsRefs.current[id]?.offsetLeft
if (ref.current) {
ref.current.scrollTo({ ref.current.scrollTo({
left: x, left: x,
behavior: 'smooth' behavior: 'smooth'
@ -42,21 +41,67 @@ export const StickySideColumns = ({
const isActive = (id: string) => id === tab const isActive = (id: string) => id === tab
useEffect(() => { useEffect(() => {
setTab(DEFAULT_TAB)
handleNavClick(DEFAULT_TAB) handleNavClick(DEFAULT_TAB)
}, []) }, [])
useEffect(() => {
const tabs = tabsRefs.current
// Set up the observer
const observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
setTab(entry.target.id)
}
})
},
{
root: ref.current,
threshold: 0.5,
rootMargin: '-20px'
}
)
if (tabs) {
Object.values(tabs).forEach((tab) => {
if (tab) observer.observe(tab)
})
}
return () => {
if (tabs) {
Object.values(tabs).forEach((tab) => {
if (tab) observer.unobserve(tab)
})
}
}
}, [])
return ( return (
<> <>
<div className={styles.container} ref={ref}> <div className={styles.container} ref={ref}>
<div id="nav-left" className={`${styles.sidesWrap} ${styles.files}`}> <div
id="nav-left"
className={styles.sidesWrap}
ref={(tab) => (tabsRefs.current['nav-left'] = tab)}
>
<div className={styles.sides}>{left}</div> <div className={styles.sides}>{left}</div>
</div> </div>
<div id="nav-content"> <div
id="nav-content"
className={styles.scrollAdjust}
ref={(tab) => (tabsRefs.current['nav-content'] = tab)}
>
<div id="content-preview" className={styles.content}> <div id="content-preview" className={styles.content}>
{children} {children}
</div> </div>
</div> </div>
<div id="nav-right" className={styles.sidesWrap}> <div
id="nav-right"
className={styles.sidesWrap}
ref={(tab) => (tabsRefs.current['nav-right'] = tab)}
>
<div className={styles.sides}>{right}</div> <div className={styles.sides}>{right}</div>
</div> </div>
</div> </div>

View File

@ -999,7 +999,7 @@ export const CreatePage = () => {
</Button> </Button>
</div> </div>
<div className={styles.paperGroup}> <div className={`${styles.paperGroup} ${styles.users}`}>
<DisplayUser <DisplayUser
metadata={metadata} metadata={metadata}
users={users} users={users}

View File

@ -69,10 +69,6 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 15px; gap: 15px;
// Automatic scrolling if paper-group gets large enough
// used for files on the left and users on the right
max-height: 350px;
overflow-x: hidden; overflow-x: hidden;
overflow-y: auto; overflow-y: auto;
} }
@ -80,6 +76,7 @@
.inputWrapper { .inputWrapper {
display: flex; display: flex;
align-items: center; align-items: center;
flex-shrink: 0;
height: 34px; height: 34px;
overflow: hidden; overflow: hidden;
@ -94,6 +91,11 @@
} }
} }
.users {
flex-shrink: 0;
max-height: 33vh;
}
.user { .user {
display: flex; display: flex;
gap: 10px; gap: 10px;
@ -144,7 +146,6 @@
gap: 15px; gap: 15px;
max-height: 450px;
overflow-x: hidden; overflow-x: hidden;
overflow-y: auto; overflow-y: auto;

View File

@ -53,7 +53,6 @@ import { convertToSigitFile, SigitFile } from '../../utils/file.ts'
import { FileDivider } from '../../components/FileDivider.tsx' import { FileDivider } from '../../components/FileDivider.tsx'
import { ExtensionFileBox } from '../../components/ExtensionFileBox.tsx' import { ExtensionFileBox } from '../../components/ExtensionFileBox.tsx'
import { useScale } from '../../hooks/useScale.tsx' import { useScale } from '../../hooks/useScale.tsx'
import { Footer } from '../../components/Footer/Footer.tsx'
interface PdfViewProps { interface PdfViewProps {
files: CurrentUserFile[] files: CurrentUserFile[]
@ -581,7 +580,6 @@ export const VerifyPage = () => {
</StickySideColumns> </StickySideColumns>
)} )}
</Container> </Container>
<Footer />
</> </>
) )
} }

View File

@ -2,3 +2,5 @@ $header-height: 65px;
$body-vertical-padding: 25px; $body-vertical-padding: 25px;
$default-container-padding-inline: 10px; $default-container-padding-inline: 10px;
$tabs-height: 40px;