diff options
| author | Fuwn <[email protected]> | 2026-02-07 03:56:45 -0800 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2026-02-07 03:56:45 -0800 |
| commit | 9f92c90a4ac9500d3a78a4ad0cc558d3531d498c (patch) | |
| tree | f2f5fab23b73121ef9c41858e1138ae0c6911d3e /apps/web/app/reader/_components | |
| parent | fix: include sidebar footer items in min width measurement (diff) | |
| download | asa.news-9f92c90a4ac9500d3a78a4ad0cc558d3531d498c.tar.xz asa.news-9f92c90a4ac9500d3a78a4ad0cc558d3531d498c.zip | |
fix: measure text nodes in sidebar min width calculation
querySelectorAll(':scope > *') misses bare text nodes like
'notifications' in the footer button. Now walks childNodes to
handle mixed text node + element children correctly.
Diffstat (limited to 'apps/web/app/reader/_components')
| -rw-r--r-- | apps/web/app/reader/_components/reader-layout-shell.tsx | 47 | ||||
| -rw-r--r-- | apps/web/app/reader/_components/sidebar-footer.tsx | 2 |
2 files changed, 23 insertions, 26 deletions
diff --git a/apps/web/app/reader/_components/reader-layout-shell.tsx b/apps/web/app/reader/_components/reader-layout-shell.tsx index ac03ce4..6114bd9 100644 --- a/apps/web/app/reader/_components/reader-layout-shell.tsx +++ b/apps/web/app/reader/_components/reader-layout-shell.tsx @@ -59,42 +59,39 @@ export function ReaderLayoutShell({ const canvasContext = canvas.getContext("2d") if (!canvasContext) return - function measureElementTextWidth( + function measureElementContentWidth( element: Element, context: CanvasRenderingContext2D ): number { - const elementChildren = element.querySelectorAll(":scope > *") - if (elementChildren.length === 0) { - const computedStyle = getComputedStyle(element) - context.font = `${computedStyle.fontWeight} ${computedStyle.fontSize} ${computedStyle.fontFamily}` - return Math.ceil( - context.measureText(element.textContent ?? "").width - ) - } + const parentStyle = getComputedStyle(element) + const parentFont = `${parentStyle.fontWeight} ${parentStyle.fontSize} ${parentStyle.fontFamily}` + let width = 0 - for (const child of elementChildren) { - const computedStyle = getComputedStyle(child) - context.font = `${computedStyle.fontWeight} ${computedStyle.fontSize} ${computedStyle.fontFamily}` - width += Math.ceil( - context.measureText(child.textContent ?? "").width - ) + for (const node of element.childNodes) { + if (node.nodeType === Node.TEXT_NODE) { + const text = node.textContent?.trim() + if (text) { + context.font = parentFont + width += Math.ceil(context.measureText(text).width) + } + } else if (node.nodeType === Node.ELEMENT_NODE) { + const childStyle = getComputedStyle(node as Element) + context.font = `${childStyle.fontWeight} ${childStyle.fontSize} ${childStyle.fontFamily}` + width += Math.ceil( + context.measureText(node.textContent ?? "").width + ) + } } return width } let widestRowWidth = 0 - const navigationItems = sidebarElement.querySelectorAll("[data-sidebar-nav-item]") - for (const navigationItem of navigationItems) { - const rowWidth = measureElementTextWidth(navigationItem, canvasContext) - widestRowWidth = Math.max(widestRowWidth, rowWidth) - } - - const footerButtons = sidebarElement.querySelectorAll( - ".border-t a, .border-t button" + const allMeasurableItems = sidebarElement.querySelectorAll( + "[data-sidebar-nav-item], [data-sidebar-footer] a, [data-sidebar-footer] button" ) - for (const footerButton of footerButtons) { - const rowWidth = measureElementTextWidth(footerButton, canvasContext) + for (const item of allMeasurableItems) { + const rowWidth = measureElementContentWidth(item, canvasContext) widestRowWidth = Math.max(widestRowWidth, rowWidth) } diff --git a/apps/web/app/reader/_components/sidebar-footer.tsx b/apps/web/app/reader/_components/sidebar-footer.tsx index 8c520c3..a790332 100644 --- a/apps/web/app/reader/_components/sidebar-footer.tsx +++ b/apps/web/app/reader/_components/sidebar-footer.tsx @@ -28,7 +28,7 @@ export function SidebarFooter() { } return ( - <div className="border-t border-border p-2"> + <div data-sidebar-footer className="border-t border-border p-2"> <Link href="/reader/settings" onClick={() => { |