diff --git a/.changeset/quick-cougars-mate.md b/.changeset/quick-cougars-mate.md new file mode 100644 index 000000000..bd857d73c --- /dev/null +++ b/.changeset/quick-cougars-mate.md @@ -0,0 +1,5 @@ +--- +'gitbook': patch +--- + +Visual fix for section group in Safari diff --git a/packages/gitbook/src/components/SiteSections/SiteSectionTabs.tsx b/packages/gitbook/src/components/SiteSections/SiteSectionTabs.tsx index 1c9220a54..6d9483aaa 100644 --- a/packages/gitbook/src/components/SiteSections/SiteSectionTabs.tsx +++ b/packages/gitbook/src/components/SiteSections/SiteSectionTabs.tsx @@ -22,26 +22,30 @@ export function SiteSectionTabs(props: { sections: SectionsList }) { } = props; const [value, setValue] = React.useState(); const [offset, setOffset] = React.useState(null); + const scrollableViewRef = React.useRef(null); const onNodeUpdate = ( trigger: HTMLButtonElement | null, itemValue: string, size: number = 0, ) => { - const windowWidth = window.innerWidth; + const windowWidth = document.documentElement.clientWidth; if (windowWidth < 768) { + // if the screen is small don't offset the menu setOffset(0); } else if (trigger && value === itemValue) { + const padding = 16; const viewportWidth = - size < MIN_ITEMS_FOR_COLS ? VIEWPORT_ITEM_WIDTH : VIEWPORT_ITEM_WIDTH * 2; - const halfViewportWidth = viewportWidth / 2; - const viewportFreeZone = 10 /* buffer */ + 8 /* padding */ + halfViewportWidth; - const triggerOffsetRight = trigger.offsetLeft + trigger.offsetWidth / 2; + size < MIN_ITEMS_FOR_COLS + ? VIEWPORT_ITEM_WIDTH + padding + : VIEWPORT_ITEM_WIDTH * 2 + padding; + const scrollLeft = scrollableViewRef.current?.scrollLeft ?? 0; + const triggerOffset = trigger.offsetLeft - scrollLeft; // offset of the trigger from the left edge including scrolling + const bufferLeft = 2; // offset the menu viewport should not pass on the left side of window + const bufferRight = windowWidth - (16 + viewportWidth); // offset the menu viewport should not pass on the right side of the window setOffset( - Math.min( - Math.max(viewportFreeZone, Math.round(triggerOffsetRight)), - windowWidth - viewportFreeZone, - ), + // constrain to within the window with some buffer on the left and right we don't want the menu to enter + Math.min(bufferRight, Math.max(bufferLeft, Math.round(triggerOffset))), ); } else if (!value) { setOffset(null); @@ -55,6 +59,7 @@ export function SiteSectionTabs(props: { sections: SectionsList }) { className="w-full relative z-10 flex flex-nowrap items-center max-w-screen-2xl mx-auto page-full-width:max-w-full" >
@@ -112,7 +117,7 @@ export function SiteSectionTabs(props: { sections: SectionsList }) { ); })}
@@ -120,18 +125,17 @@ export function SiteSectionTabs(props: { sections: SectionsList }) {
@@ -254,7 +258,7 @@ function SectionGroupTile(props: { section: SiteSection; isActive: boolean }) { {icon ? : null} {title}
-

{section.description}

+

{section.description}

);