From be9bfc28c8dbd9b7221f9ae899d4a4ce4543b5ac Mon Sep 17 00:00:00 2001 From: enes Date: Fri, 30 Aug 2024 17:39:32 +0200 Subject: [PATCH] refactor(mobile): tabs navigation, observer active for tabs, tabs layout scrolling --- src/layouts/StickySideColumns.module.scss | 29 +++++++---- src/layouts/StickySideColumns.tsx | 61 ++++++++++++++++++++--- src/pages/create/index.tsx | 2 +- src/pages/create/style.module.scss | 11 ++-- src/pages/verify/index.tsx | 2 - src/styles/sizes.scss | 2 + 6 files changed, 80 insertions(+), 27 deletions(-) diff --git a/src/layouts/StickySideColumns.module.scss b/src/layouts/StickySideColumns.module.scss index 212e281..b591447 100644 --- a/src/layouts/StickySideColumns.module.scss +++ b/src/layouts/StickySideColumns.module.scss @@ -43,30 +43,37 @@ position: sticky; top: $header-height + $body-vertical-padding; } + > :first-child { + max-height: calc( + 100svh - $header-height - $body-vertical-padding * 2 - $tabs-height + ); + } } -.files { - display: flex; - flex-direction: column; - grid-gap: 15px; -} -.content { - padding: 10px; - border: 10px solid $overlay-background-color; - border-radius: 4px; - +.scrollAdjust { @media only screen and (max-width: 767px) { - max-height: calc(100svh - $header-height + $body-vertical-padding * 2); + max-height: calc( + 100svh - $header-height - $body-vertical-padding * 2 - $tabs-height + ); overflow-y: auto; } } +.content { + @media only screen and (min-width: 768px) { + padding: 10px; + border: 10px solid $overlay-background-color; + border-radius: 4px; + } +} + .navTabs { display: none; position: fixed; left: 0; bottom: 0; right: 0; + height: $tabs-height; z-index: 2; background: $overlay-background-color; box-shadow: 0 0 4px 0 rgb(0, 0, 0, 0.1); diff --git a/src/layouts/StickySideColumns.tsx b/src/layouts/StickySideColumns.tsx index 43561de..2e233ae 100644 --- a/src/layouts/StickySideColumns.tsx +++ b/src/layouts/StickySideColumns.tsx @@ -21,18 +21,17 @@ interface StickySideColumnsProps { } const DEFAULT_TAB = 'nav-content' - export const StickySideColumns = ({ left, right, children }: PropsWithChildren) => { - const ref = useRef(null) const [tab, setTab] = useState(DEFAULT_TAB) + const ref = useRef(null) + const tabsRefs = useRef<{ [id: string]: HTMLDivElement | null }>({}) const handleNavClick = (id: string) => { - setTab(id) - const x = document.getElementById(id)?.offsetLeft - if (ref.current) { + if (ref.current && tabsRefs.current) { + const x = tabsRefs.current[id]?.offsetLeft ref.current.scrollTo({ left: x, behavior: 'smooth' @@ -42,21 +41,67 @@ export const StickySideColumns = ({ const isActive = (id: string) => id === tab useEffect(() => { + setTab(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 ( <>
-