summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFuwn <[email protected]>2026-02-07 03:46:53 -0800
committerFuwn <[email protected]>2026-02-07 03:46:53 -0800
commit6bbcebf6f8da631bf6d94bab2a5078896034e62f (patch)
treed76b1a8c08a852168d582b2556bd90106370457f
parentfix: persist detail panel sizes with panelIds-keyed storage (diff)
downloadasa.news-6bbcebf6f8da631bf6d94bab2a5078896034e62f.tar.xz
asa.news-6bbcebf6f8da631bf6d94bab2a5078896034e62f.zip
feat: derive sidebar min/default width from measured content
Measures the first sidebar nav item (all entries + unread badge) after mount and uses its scrollWidth + padding as minSize. Default is 1.4x the minimum for comfortable reading of feed titles.
-rw-r--r--apps/web/app/reader/_components/reader-layout-shell.tsx21
1 files changed, 19 insertions, 2 deletions
diff --git a/apps/web/app/reader/_components/reader-layout-shell.tsx b/apps/web/app/reader/_components/reader-layout-shell.tsx
index 8c6db8b..0795780 100644
--- a/apps/web/app/reader/_components/reader-layout-shell.tsx
+++ b/apps/web/app/reader/_components/reader-layout-shell.tsx
@@ -1,6 +1,6 @@
"use client"
-import { Suspense, useEffect, useState } from "react"
+import { Suspense, useCallback, useEffect, useState } from "react"
import { Group, Panel, Separator, useDefaultLayout } from "react-resizable-panels"
import { useUserInterfaceStore } from "@/lib/stores/user-interface-store"
import { classNames } from "@/lib/utilities"
@@ -48,6 +48,17 @@ export function ReaderLayoutShell({
(state) => state.focusFollowsInteraction
)
const isMobile = useIsMobile()
+ const [sidebarMinimumWidth, setSidebarMinimumWidth] = useState("150px")
+ const [sidebarDefaultWidth, setSidebarDefaultWidth] = useState("220px")
+
+ const measureSidebarWidths = useCallback(() => {
+ const firstNavigationItem = document.querySelector("[data-sidebar-nav-item]")
+ if (!firstNavigationItem) return
+ const navigationContainerPadding = 16
+ const measuredMinimumWidth = firstNavigationItem.scrollWidth + navigationContainerPadding
+ setSidebarMinimumWidth(`${measuredMinimumWidth}px`)
+ setSidebarDefaultWidth(`${Math.round(measuredMinimumWidth * 1.4)}px`)
+ }, [])
const sidebarLayout = useDefaultLayout({
id: "asa-sidebar-layout",
@@ -58,6 +69,12 @@ export function ReaderLayoutShell({
useKeyboardNavigation()
useEffect(() => {
+ if (isSidebarCollapsed || isMobile) return
+ const timeoutIdentifier = setTimeout(measureSidebarWidths, 100)
+ return () => clearTimeout(timeoutIdentifier)
+ }, [isSidebarCollapsed, isMobile, measureSidebarWidths])
+
+ useEffect(() => {
async function checkAssuranceLevel() {
const supabaseClient = createSupabaseBrowserClient()
const { data } = await supabaseClient.auth.mfa.getAuthenticatorAssuranceLevel()
@@ -207,7 +224,7 @@ export function ReaderLayoutShell({
>
{!isSidebarCollapsed && (
<>
- <Panel id="sidebar" defaultSize="20%" minSize="15%" maxSize="35%">
+ <Panel id="sidebar" defaultSize={sidebarDefaultWidth} minSize={sidebarMinimumWidth} maxSize="35%">
<aside
data-panel-zone="sidebar"
className={classNames(