Fix mobile rendering issues (#1022)

This commit is contained in:
Brandon Hopkins
2026-10-05 18:12:39 -07:00
committed by GitHub
parent 1ea7881248
commit 084ff2462c
7 changed files with 59 additions and 21 deletions
+1 -1
View File
@@ -54,7 +54,7 @@ function rehypeInsertLastUpdated() {
type: 'element',
tagName: 'p',
properties: {
className: ['not-prose', 'text-sm', 'text-slate-400', 'dark:text-zinc-500', 'mt-0', 'mb-8', 'ml-2.5'],
className: ['not-prose', 'text-sm', 'text-slate-400', 'dark:text-zinc-500', 'mt-0', 'mb-8', 'md:ml-2.5'],
},
children: [
{ type: 'text', value: 'Updated ' },
+4 -4
View File
@@ -188,7 +188,7 @@ export function Layout({ children, title, tableOfContents }) {
<AnnouncementBanner />
<HeroPattern/>
<div
className="relative mx-auto flex max-w-8xl sm:px-2 lg:px-8 xl:px-12 lg:ml-72 xl:ml-80"
className="relative mx-auto flex max-w-8xl md:px-2 lg:px-8 xl:px-12 lg:ml-72 xl:ml-80"
style={{ paddingTop: bannerHeight }}
>
<header
@@ -206,9 +206,9 @@ export function Layout({ children, title, tableOfContents }) {
</div>
<Header />
</header>
<div className="min-w-0 max-w-2xl flex-auto px-4 py-16 lg:max-w-none lg:pl-8 lg:pr-0 xl:px-5">
<main className="py-16">
<Prose as="article">{children}</Prose>
<div className="min-w-0 flex-auto px-4 py-16 md:max-w-2xl lg:max-w-none lg:pl-8 lg:pr-0 xl:px-5">
<main className="py-8 lg:py-16">
<Prose as="article" className="max-md:max-w-none">{children}</Prose>
</main>
<Footer />
</div>
+8 -2
View File
@@ -7,6 +7,7 @@ import { Header } from '@/components/Header'
import { NavigationAPI } from '@/components/NavigationAPI'
import {NavigationDocs} from "@/components/NavigationDocs";
import {useRouter} from "next/router";
import { useAnnouncements } from '@/components/announcement-banner/AnnouncementBannerProvider'
function MenuIcon(props) {
return (
@@ -52,6 +53,7 @@ export const useMobileNavigationStore = create((set) => ({
export function MobileNavigation() {
let isInsideMobileNavigation = useIsInsideMobileNavigation()
let { isOpen, toggle, close } = useMobileNavigationStore()
let { bannerHeight } = useAnnouncements()
let ToggleIcon = isOpen ? XIcon : MenuIcon
let router = useRouter()
@@ -78,7 +80,10 @@ export function MobileNavigation() {
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<div className="fixed inset-0 top-14 bg-zinc-400/20 backdrop-blur-sm dark:bg-[#181A1D]/40" />
<div
className="fixed inset-0 bg-zinc-400/20 backdrop-blur-sm dark:bg-[#181A1D]/40"
style={{ top: `calc(${bannerHeight}px + 4rem)` }}
/>
</Transition.Child>
<Dialog.Panel>
@@ -105,7 +110,8 @@ export function MobileNavigation() {
>
<motion.div
layoutScroll
className="fixed bottom-0 left-0 top-14 w-full overflow-y-auto bg-white/70 dark:bg-[#181A1D]/95 backdrop-blur-lg px-4 pb-4 pt-6 shadow-lg shadow-zinc-900/10 ring-1 ring-zinc-900/7.5 dark:ring-neutral-500/10 min-[416px]:max-w-sm sm:px-6 sm:pb-10"
className="fixed bottom-0 left-0 w-full overflow-y-auto bg-white/70 dark:bg-[#181A1D]/95 backdrop-blur-lg px-4 pb-4 pt-6 shadow-lg shadow-zinc-900/10 ring-1 ring-zinc-900/7.5 dark:ring-neutral-500/10 min-[416px]:max-w-sm sm:px-6 sm:pb-10"
style={{ top: `calc(${bannerHeight}px + 4rem)` }}
>
{router.route.startsWith("/ipa") ? <NavigationAPI tableOfContents={[]} /> :
<NavigationDocs />}
@@ -1,4 +1,4 @@
import clsx from 'clsx'
import { useLayoutEffect, useRef } from 'react'
import Link from 'next/link'
import { useAnnouncements } from '@/components/announcement-banner/AnnouncementBannerProvider'
@@ -36,19 +36,34 @@ function CloseIcon(props) {
function AnnouncementItem({ announcement, onClose }) {
const announcementLink = useCustomQueryURL(announcement.link || '')
const bannerRef = useRef(null)
const { setBannerHeight } = useAnnouncements()
useLayoutEffect(() => {
const banner = bannerRef.current
// Text wrapping and viewport changes can make the banner taller on phones.
const updateHeight = () => setBannerHeight(banner.getBoundingClientRect().height)
updateHeight()
const observer = new ResizeObserver(updateHeight)
observer.observe(banner)
return () => {
observer.disconnect()
setBannerHeight(0)
}
}, [setBannerHeight])
return (
<div
id="announcement-banner"
className={clsx(
'sticky top-0 z-50 flex w-full items-center justify-center border-b border-zinc-800 bg-netbird/95 px-4 py-1.5 text-[11px] font-medium text-black shadow-sm backdrop-blur'
)}
ref={bannerRef}
className="fixed inset-x-0 top-0 z-50 flex w-full items-center justify-center border-b border-zinc-800 bg-netbird/95 px-4 py-1.5 text-[11px] font-medium text-black shadow-sm backdrop-blur"
>
<div className="flex flex-col items-start gap-1 pr-8 leading-snug md:flex-row md:items-center">
<div className="pr-8 leading-relaxed md:flex md:items-center md:gap-1 md:leading-snug">
{announcement.tag ? (
<div className="mr-2 inline rounded-md bg-black/70 px-2 py-1 text-[9px] font-semibold uppercase tracking-[0.18em] text-white">
<span className="mr-2 inline-block whitespace-nowrap rounded-md bg-black/70 px-2 py-1 align-middle text-[9px] font-semibold uppercase tracking-[0.18em] text-white">
{announcement.tag}
</div>
</span>
) : null}
<span className="mr-2 text-[12px] md:text-[13px]">
{announcement.text}
@@ -101,4 +116,4 @@ export function AnnouncementBanner() {
onClose={closeAnnouncement}
/>
)
}
}
@@ -12,10 +12,10 @@ const ANNOUNCEMENTS_URL =
'https://raw.githubusercontent.com/netbirdio/dashboard/main/announcements.json'
const STORAGE_KEY = 'netbird-announcements'
const CACHE_DURATION_MS = 30 * 60 * 1000
const BANNER_HEIGHT = 33
const AnnouncementContext = createContext({
bannerHeight: 0,
setBannerHeight: () => {},
announcements: undefined,
closeAnnouncement: () => {},
})
@@ -83,6 +83,7 @@ const saveAnnouncements = (closedAnnouncements) => {
export function AnnouncementBannerProvider({ children }) {
const [announcements, setAnnouncements] = useState(undefined)
const [bannerHeight, setBannerHeight] = useState(0)
const fetchingRef = useRef(false)
useEffect(() => {
@@ -108,12 +109,11 @@ export function AnnouncementBannerProvider({ children }) {
[announcements]
)
const bannerHeight = announcements?.some((a) => a.isOpen) ? BANNER_HEIGHT : 0
return (
<AnnouncementContext.Provider
value={{
bannerHeight,
setBannerHeight,
announcements,
closeAnnouncement,
}}
@@ -125,4 +125,4 @@ export function AnnouncementBannerProvider({ children }) {
export function useAnnouncements() {
return useContext(AnnouncementContext)
}
}
+13
View File
@@ -11,6 +11,19 @@ export { Badge } from '@/components/Badge'
export { YouTube }
export { Video } from '@/components/Video'
export const table = function Table(props) {
return (
<div
className="my-8 overflow-x-auto [&>table]:my-0"
role="region"
aria-label="Scrollable table"
tabIndex={0}
>
<table {...props} />
</div>
)
}
export const h2 = function H2(props) {
return <Heading level={2} {...props} />
}
+6 -2
View File
@@ -48,9 +48,13 @@ module.exports = ({ theme }) => ({
// Layout
'> *': {
maxWidth: theme('maxWidth.2xl'),
marginLeft: 10,
maxWidth: '100%',
marginLeft: 0,
marginRight: 'auto',
'@screen md': {
maxWidth: theme('maxWidth.2xl'),
marginLeft: 10,
},
'@screen lg': {
maxWidth: theme('maxWidth.3xl'),
marginLeft: 10,