mirror of
https://github.com/GitbookIO/gitbook.git
synced 2026-09-16 15:45:13 +00:00
Fixes
This commit is contained in:
@@ -7,6 +7,7 @@ import { useState } from 'react';
|
||||
import { type ClassValue, tcls } from '@/lib/tailwind';
|
||||
|
||||
import * as RadixDropdownMenu from '@radix-ui/react-dropdown-menu';
|
||||
import { Slot } from '@radix-ui/react-slot';
|
||||
|
||||
import { Link, type LinkInsightsProps } from '../primitives';
|
||||
|
||||
@@ -25,13 +26,21 @@ export function DropdownMenu(props: {
|
||||
children: React.ReactNode;
|
||||
/** Custom styles */
|
||||
className?: ClassValue;
|
||||
/** Open the dropdown on hover */
|
||||
/** Open the dropdown on hover
|
||||
* @default false
|
||||
*/
|
||||
openOnHover?: boolean;
|
||||
/** Whether to render the dropdown menu in a portal
|
||||
* @default true
|
||||
*/
|
||||
withPortal?: boolean;
|
||||
}) {
|
||||
const { button, children, className, openOnHover = false } = props;
|
||||
const { button, children, className, openOnHover = false, withPortal = true } = props;
|
||||
const [hovered, setHovered] = useState(false);
|
||||
const [clicked, setClicked] = useState(false);
|
||||
|
||||
const Portal = withPortal ? RadixDropdownMenu.Portal : Slot;
|
||||
|
||||
return (
|
||||
<RadixDropdownMenu.Root
|
||||
modal={false}
|
||||
@@ -48,24 +57,27 @@ export function DropdownMenu(props: {
|
||||
{button}
|
||||
</RadixDropdownMenu.Trigger>
|
||||
|
||||
<RadixDropdownMenu.Content
|
||||
data-testid="dropdown-menu"
|
||||
hideWhenDetached
|
||||
collisionPadding={8}
|
||||
onMouseEnter={() => setHovered(true)}
|
||||
onMouseLeave={() => setHovered(false)}
|
||||
align="start"
|
||||
className="z-[9999] animate-present pt-2"
|
||||
>
|
||||
<div
|
||||
className={tcls(
|
||||
'flex max-h-80 min-w-40 max-w-[40vw] flex-col gap-1 overflow-auto rounded-lg straight-corners:rounded-sm bg-tint-base p-2 shadow-lg ring-1 ring-tint-subtle sm:min-w-52 sm:max-w-80',
|
||||
className
|
||||
)}
|
||||
<Portal>
|
||||
<RadixDropdownMenu.Content
|
||||
data-testid="dropdown-menu"
|
||||
hideWhenDetached
|
||||
collisionPadding={8}
|
||||
onMouseEnter={() => setHovered(true)}
|
||||
onMouseLeave={() => setHovered(false)}
|
||||
align="start"
|
||||
sideOffset={8}
|
||||
className="z-40 animate-present"
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
</RadixDropdownMenu.Content>
|
||||
<div
|
||||
className={tcls(
|
||||
'flex max-h-80 min-w-40 max-w-[40vw] flex-col gap-1 overflow-auto rounded-lg straight-corners:rounded-sm bg-tint-base p-2 shadow-lg ring-1 ring-tint-subtle sm:min-w-52 sm:max-w-80',
|
||||
className
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
</RadixDropdownMenu.Content>
|
||||
</Portal>
|
||||
</RadixDropdownMenu.Root>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -77,7 +77,6 @@ export function Header(props: { context: GitBookSiteContext; withTopHeader?: boo
|
||||
)}
|
||||
>
|
||||
<HeaderMobileMenuButton
|
||||
pages={context.pages}
|
||||
className={tcls(
|
||||
'lg:hidden',
|
||||
'-ml-2',
|
||||
|
||||
@@ -6,18 +6,14 @@ import { useEffect } from 'react';
|
||||
import { useMobileMenuSheet } from '@/components/Header/mobile-menu/useMobileMenuSheet';
|
||||
import { tString, useLanguage } from '@/intl/client';
|
||||
import { tcls } from '@/lib/tailwind';
|
||||
import type { GitBookSiteContext } from '@v2/lib/context';
|
||||
import { usePathname } from 'next/navigation';
|
||||
|
||||
/**
|
||||
* Button to show/hide the table of content on mobile.
|
||||
*/
|
||||
export function HeaderMobileMenuButton({
|
||||
pages,
|
||||
...props
|
||||
}: Partial<React.ButtonHTMLAttributes<HTMLButtonElement>> & {
|
||||
pages: GitBookSiteContext['pages'];
|
||||
}) {
|
||||
export function HeaderMobileMenuButton(
|
||||
props: Partial<React.ButtonHTMLAttributes<HTMLButtonElement>>
|
||||
) {
|
||||
const language = useLanguage();
|
||||
const pathname = usePathname();
|
||||
const { open, setOpen } = useMobileMenuSheet();
|
||||
@@ -26,7 +22,7 @@ export function HeaderMobileMenuButton({
|
||||
setOpen(!open);
|
||||
};
|
||||
|
||||
// Close the navigation when navigating to a page
|
||||
// biome-ignore lint/correctness/useExhaustiveDependencies: Close the navigation when navigating to a page
|
||||
useEffect(() => {
|
||||
if (!open) return;
|
||||
setOpen(false);
|
||||
|
||||
@@ -11,8 +11,9 @@ export function SpacesDropdown(props: {
|
||||
siteSpace: SiteSpace;
|
||||
siteSpaces: SiteSpace[];
|
||||
className?: string;
|
||||
withPortal?: boolean;
|
||||
}) {
|
||||
const { context, siteSpace, siteSpaces, className } = props;
|
||||
const { context, siteSpace, siteSpaces, className, withPortal } = props;
|
||||
|
||||
return (
|
||||
<DropdownMenu
|
||||
@@ -20,6 +21,7 @@ export function SpacesDropdown(props: {
|
||||
'group-hover/dropdown:invisible', // Prevent hover from opening the dropdown, as it's annoying in this context
|
||||
'group-focus-within/dropdown:group-hover/dropdown:visible' // When the dropdown is already open, it should remain visible when hovered
|
||||
)}
|
||||
withPortal={withPortal}
|
||||
button={
|
||||
<div
|
||||
data-testid="space-dropdown-button"
|
||||
|
||||
@@ -9,7 +9,8 @@ import {
|
||||
} from '@/components/utils/Sheet';
|
||||
import { useMobileMenuSheet } from './useMobileMenuSheet';
|
||||
|
||||
export function MobileMenuSheet({ children }: { children: React.ReactNode }) {
|
||||
export function MobileMenuSheet(props: { children: React.ReactNode }) {
|
||||
const { children } = props;
|
||||
const { open, setOpen } = useMobileMenuSheet();
|
||||
|
||||
return (
|
||||
@@ -17,7 +18,7 @@ export function MobileMenuSheet({ children }: { children: React.ReactNode }) {
|
||||
<SheetContent
|
||||
aria-label="Mobile menu"
|
||||
overlayClassName="lg:hidden"
|
||||
className="lg:hidden"
|
||||
className="pb-2 lg:hidden"
|
||||
>
|
||||
{/** Needed for screen readers */}
|
||||
<SheetHeader className="sr-only">
|
||||
|
||||
@@ -73,13 +73,15 @@ export function SpaceLayout(props: {
|
||||
innerHeader={
|
||||
isMultiVariants ? (
|
||||
<SpacesDropdown
|
||||
withPortal={false}
|
||||
context={context}
|
||||
siteSpace={siteSpace}
|
||||
siteSpaces={siteSpaces}
|
||||
className={tcls(
|
||||
'w-full',
|
||||
'page-no-toc:hidden',
|
||||
'site-header-none:page-no-toc:flex'
|
||||
'site-header-none:page-no-toc:flex',
|
||||
'h-8'
|
||||
)}
|
||||
/>
|
||||
) : null
|
||||
|
||||
@@ -29,8 +29,8 @@ export function PageGroupItem(props: {
|
||||
'[html.sidebar-filled.theme-bold.tint_&]:bg-tint-subtle',
|
||||
'[html.sidebar-filled.theme-muted_&]:bg-tint-base',
|
||||
'[html.sidebar-filled.theme-bold.tint_&]:bg-tint-base',
|
||||
'[html.sidebar-default.theme-gradient_&]:bg-gradient-primary',
|
||||
'[html.sidebar-default.theme-gradient.tint_&]:bg-gradient-tint'
|
||||
'lg:[html.sidebar-default.theme-gradient_&]:bg-gradient-primary',
|
||||
'lg:[html.sidebar-default.theme-gradient.tint_&]:bg-gradient-tint'
|
||||
)}
|
||||
>
|
||||
<TOCPageIcon page={page} />
|
||||
|
||||
@@ -32,14 +32,14 @@ export function TOCScrollContent(props: {
|
||||
)}
|
||||
>
|
||||
{!!innerHeader && (
|
||||
<div className="inline-flex w-full flex-col gap-2 px-3 *:mt-0.5 max-lg:mt-3 max-lg:pr-12 lg:px-2 lg:pr-4">
|
||||
<div className="inline-flex w-full flex-col gap-2 px-2 max-lg:mt-2 max-lg:pr-12 lg:pr-4 lg:*:mt-0.5">
|
||||
{innerHeader}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<TOCScrollContainer // The scrollview inside the sidebar
|
||||
className={tcls(
|
||||
'flex flex-grow flex-col p-3 lg:p-2',
|
||||
'flex flex-grow flex-col p-2',
|
||||
innerHeader ? 'mt-0' : 'mt-8',
|
||||
customization.trademark.enabled && 'pb-20',
|
||||
'gutter-stable overflow-y-auto',
|
||||
|
||||
@@ -24,14 +24,13 @@ export function Trademark(props: {
|
||||
'z-[2]',
|
||||
'absolute',
|
||||
|
||||
'lg:left-0',
|
||||
'lg:bottom-0',
|
||||
'left-2',
|
||||
'right-2',
|
||||
'bottom-2',
|
||||
'bottom-0',
|
||||
'lg:left-0',
|
||||
|
||||
'pt-2',
|
||||
'lg:py-0',
|
||||
'lg:pt-0',
|
||||
|
||||
'pointer-events-none',
|
||||
'sidebar-filled:pl-2',
|
||||
|
||||
@@ -64,7 +64,7 @@ export function Button({
|
||||
const sizes = {
|
||||
default: ['text-base', 'py-2', 'circular-corners:px-6', iconOnly ? '!px-2' : 'px-5'],
|
||||
medium: ['text-sm', 'py-1.5', 'circular-corners:px-4', iconOnly ? '!px-1.5' : 'px-3.5'],
|
||||
small: ['text-xs', 'py-2', iconOnly ? 'px-2' : 'px-3'],
|
||||
small: ['text-xs', 'py-2', iconOnly ? '!px-2' : 'px-3'],
|
||||
};
|
||||
|
||||
const sizeClasses = sizes[size] || sizes.default;
|
||||
|
||||
@@ -49,23 +49,38 @@ export function SheetContent({
|
||||
side?: 'right' | 'left';
|
||||
}) {
|
||||
return (
|
||||
<>
|
||||
<SheetPortal>
|
||||
<SheetOverlay className={overlayClassName} />
|
||||
<SheetPrimitive.Content
|
||||
data-slot="sheet-content"
|
||||
className={tcls(
|
||||
'fixed z-30 flex flex-col rounded-xl shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500',
|
||||
'fixed',
|
||||
'z-30',
|
||||
'flex',
|
||||
'flex-col',
|
||||
'shadow-lg',
|
||||
'depth-flat:shadow-none',
|
||||
|
||||
'transition ease-in-out',
|
||||
'data-[state=closed]:duration-300 data-[state=open]:duration-500',
|
||||
|
||||
'border',
|
||||
'border-tint-subtle',
|
||||
'inset-x-1.5 inset-y-1.5 w-10/12 border sm:max-w-sm',
|
||||
|
||||
'inset-x-1.5',
|
||||
'inset-y-1.5',
|
||||
|
||||
'w-10/12',
|
||||
'sm:max-w-sm',
|
||||
|
||||
'bg-tint-base',
|
||||
'theme-gradient:bg-gradient-primary',
|
||||
'sidebar-filled:bg-tint-subtle',
|
||||
'theme-muted:bg-tint-subtle',
|
||||
'sidebar-filled:bg-tint-subtle',
|
||||
'theme-muted:bg-tint-subtle',
|
||||
'[html.sidebar-filled.theme-bold.tint_&]:bg-tint-subtle',
|
||||
'[html.sidebar-filled.theme-muted_&]:bg-tint-base',
|
||||
'[html.sidebar-filled.theme-bold.tint_&]:bg-tint-base',
|
||||
|
||||
'rounded-xl',
|
||||
'circular-corners:rounded-2xl',
|
||||
'straight-corners:rounded-none',
|
||||
side === 'right' &&
|
||||
@@ -80,18 +95,17 @@ export function SheetContent({
|
||||
|
||||
<SheetClose asChild>
|
||||
<Button
|
||||
data-slot="sheet-close"
|
||||
variant="blank"
|
||||
variant="secondary"
|
||||
icon="close"
|
||||
iconOnly
|
||||
size="default"
|
||||
className="absolute top-3 right-2 z-50"
|
||||
autoFocus={false}
|
||||
className="absolute top-2 right-2 z-50 bg-transparent text-tint opacity-8 shadow-none ring-transparent"
|
||||
>
|
||||
<span className="sr-only">Close</span>
|
||||
</Button>
|
||||
</SheetClose>
|
||||
</SheetPrimitive.Content>
|
||||
</>
|
||||
</SheetPortal>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user