Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/slimy-pumpkins-type.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"gitbook": patch
---

Fix Search results are not clickable on sites without header
12 changes: 9 additions & 3 deletions packages/gitbook/src/components/Header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { GitBookSiteContext } from '@/lib/context';
import { CONTAINER_STYLE, HEADER_HEIGHT_DESKTOP } from '@/components/layout';
import { getSpaceLanguage, t } from '@/intl/server';
import { tcls } from '@/lib/tailwind';
import { SearchContainer } from '../Search';
import { SiteSectionTabs, encodeClientSiteSections } from '../SiteSections';
import { HeaderLink } from './HeaderLink';
import { HeaderLinkMore } from './HeaderLinkMore';
Expand All @@ -17,9 +18,8 @@ import { SpacesDropdown } from './SpacesDropdown';
export function Header(props: {
context: GitBookSiteContext;
withTopHeader?: boolean;
search?: React.ReactNode;
}) {
const { context, withTopHeader, search } = props;
const { context, withTopHeader } = props;
const { siteSpace, siteSpaces, sections, customization } = context;

return (
Expand Down Expand Up @@ -117,7 +117,13 @@ export function Header(props: {
: ['order-last']
)}
>
{search}
<SearchContainer
style={customization.styling.search}
isMultiVariants={siteSpaces.length > 1}
spaceTitle={siteSpace.title}
siteSpaceId={siteSpace.id}
viewport={!withTopHeader ? 'mobile' : undefined}
/>
</div>

{customization.header.links.length > 0 && (
Expand Down
7 changes: 5 additions & 2 deletions packages/gitbook/src/components/Search/SearchContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,14 @@ interface SearchContainerProps {
isMultiVariants: boolean;
style: CustomizationSearchStyle;
className?: string;
viewport?: 'desktop' | 'mobile';
}

/**
* Client component to render the search input and results.
*/
export function SearchContainer(props: SearchContainerProps) {
const { siteSpaceId, spaceTitle, isMultiVariants, style, className } = props;
const { siteSpaceId, spaceTitle, isMultiVariants, style, className, viewport } = props;

const { assistants } = useAI();

Expand Down Expand Up @@ -145,6 +146,8 @@ export function SearchContainer(props: SearchContainerProps) {

const showAsk = withSearchAI && normalizedAsk; // withSearchAI && normalizedAsk;

const visible = viewport === 'desktop' ? !isMobile : viewport === 'mobile' ? isMobile : true;

return (
<SearchAskProvider value={searchAsk}>
<Popover
Expand All @@ -168,7 +171,7 @@ export function SearchContainer(props: SearchContainerProps) {
) : null
}
rootProps={{
open: state?.open ?? false,
open: visible && (state?.open ?? false),
onOpenChange: (open) => {
open ? onOpen() : onClose();
},
Expand Down
5 changes: 2 additions & 3 deletions packages/gitbook/src/components/Search/SearchInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export const SearchInput = React.forwardRef<HTMLDivElement, SearchInputProps>(
}, [isOpen, value]);

return (
<div className="relative flex size-9 grow">
<div className={tcls('relative flex size-9 grow', className)}>
{/* biome-ignore lint/a11y/useKeyWithClickEvents: this div needs an onClick to show the input on mobile, where it's normally hidden.
Normally you'd also need to add a keyboard trigger to do the same without a pointer, but in this case the input already be focused on its own. */}
<div
Expand All @@ -62,8 +62,7 @@ export const SearchInput = React.forwardRef<HTMLDivElement, SearchInputProps>(
'theme-bold:border-header-link/3 has-[input:focus-visible]:theme-bold:border-header-link/5 has-[input:focus-visible]:theme-bold:bg-header-link/3 has-[input:focus-visible]:theme-bold:ring-header-link/5',
'theme-bold:before:absolute theme-bold:before:inset-0 theme-bold:before:bg-header-background/7 theme-bold:before:backdrop-blur-xl ', // Special overlay to make the transparent colors of theme-bold visible.
'relative z-30 shrink grow justify-start max-md:absolute max-md:right-0',
isOpen ? 'max-md:w-56' : 'max-md:w-[38px]',
className
isOpen ? 'max-md:w-56' : 'max-md:w-[38px]'
)}
>
{value && isOpen ? (
Expand Down
34 changes: 13 additions & 21 deletions packages/gitbook/src/components/SpaceLayout/SpaceLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
CustomizationHeaderPreset,
CustomizationSearchStyle,
} from '@gitbook/api';
import React from 'react';
import type React from 'react';

import { Footer } from '@/components/Footer';
import { Header, HeaderLogo } from '@/components/Header';
Expand Down Expand Up @@ -52,23 +52,6 @@ export function SpaceLayout(props: {
customization.footer.logo ||
customization.footer.groups?.length;

const search = (
<div className="flex grow items-center gap-2">
<React.Suspense fallback={null}>
<SearchContainer
style={
customization.header.preset === CustomizationHeaderPreset.None
? CustomizationSearchStyle.Subtle
: customization.styling.search
}
isMultiVariants={siteSpaces.length > 1}
spaceTitle={siteSpace.title}
siteSpaceId={siteSpace.id}
/>
</React.Suspense>
</div>
);

const eventUrl = new URL(
context.linker.toAbsoluteURL(context.linker.toPathInSite('/~gitbook/__evt'))
);
Expand All @@ -94,7 +77,7 @@ export function SpaceLayout(props: {
visitorCookieTrackingEnabled={customization.insights?.trackingCookie}
>
<Announcement context={context} />
<Header withTopHeader={withTopHeader} context={context} search={search} />
<Header withTopHeader={withTopHeader} context={context} />
{customization.ai?.mode === CustomizationAIMode.Assistant ? (
<AIChat trademark={customization.trademark.enabled} />
) : null}
Expand All @@ -121,7 +104,7 @@ export function SpaceLayout(props: {
className={tcls(
'hidden',
'pr-4',
'md:flex',
'lg:flex',
'grow-0',
'flex-wrap',
'dark:shadow-light/1',
Expand All @@ -135,7 +118,16 @@ export function SpaceLayout(props: {
innerHeader={
// displays the search button and/or the space dropdown in the ToC according to the header/variant settings. E.g if there is no header, the search button will be displayed in the ToC.
<>
{!withTopHeader && search}
{!withTopHeader && (
<SearchContainer
style={CustomizationSearchStyle.Subtle}
isMultiVariants={siteSpaces.length > 1}
spaceTitle={siteSpace.title}
siteSpaceId={siteSpace.id}
className="max-lg:hidden"
viewport="desktop"
/>
)}
{!withTopHeader && withSections && sections && (
<SiteSectionList
className={tcls('hidden', 'lg:block')}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ export async function TableOfContents(props: {
'page-has-toc:[html.sidebar-filled.circular-corners_&]:rounded-3xl'
)}
>
{innerHeader && <div className="px-5 *:my-4">{innerHeader}</div>}
{innerHeader && <div className="flex px-5 *:my-4">{innerHeader}</div>}
<TOCScrollContainer // The scrollview inside the sidebar
className={tcls(
'flex grow flex-col p-2',
Expand Down
2 changes: 1 addition & 1 deletion packages/gitbook/src/components/hooks/useIsMobile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import * as React from 'react';

export function useIsMobile(breakpoint = 640): boolean {
export function useIsMobile(breakpoint = 1024): boolean {
const [isMobile, setIsMobile] = React.useState(false);

React.useEffect(() => {
Expand Down