mirror of
https://github.com/hanzo-docs/docs.git
synced 2026-10-25 04:20:02 +00:00
UI: Hide TOC Popover on full mode
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
---
|
||||
'fumadocs-openapi': patch
|
||||
'fumadocs-core': patch
|
||||
'fumadocs-ui': patch
|
||||
---
|
||||
|
||||
Change Heading scroll margins
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'fumadocs-ui': patch
|
||||
---
|
||||
|
||||
Hide TOC Popover on full mode
|
||||
@@ -76,7 +76,7 @@ Use the official Tailwind CSS plugin.
|
||||
|
||||
### Layout
|
||||
|
||||
Create a new catch-all route `/app/docs/[[..slugs]]` for our docs, and give it a proper layout.
|
||||
Create a folder `/app/docs` for our docs, and give it a proper layout.
|
||||
|
||||
```tsx title="app/docs/layout.tsx"
|
||||
import { DocsLayout } from 'fumadocs-ui/layout';
|
||||
@@ -96,9 +96,10 @@ export default function RootDocsLayout({ children }: { children: ReactNode }) {
|
||||
|
||||
### Page
|
||||
|
||||
For the `page.tsx`, it may vary depending on your source. You should configure static rendering with `generateStaticParams` and metadata with `generateMetadata`.
|
||||
Create a catch-all route `/app/docs/[[...slug]]` for docs pages.
|
||||
|
||||
Wrap your content in the [Page](/docs/ui/blocks/page) component.
|
||||
In the page, wrap your content in the [Page](/docs/ui/blocks/page) component.
|
||||
It may vary depending on your content source. You should configure static rendering with `generateStaticParams` and metadata with `generateMetadata`.
|
||||
|
||||
<Tabs groupId='content-source' items={['Fumadocs MDX', 'Content Collections']}>
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ export function useAnchorObserver(watch: string[]): string | undefined {
|
||||
return f ?? watch[0];
|
||||
});
|
||||
},
|
||||
{ rootMargin: `-60px 0% -75% 0%`, threshold: 1 },
|
||||
{ rootMargin: `-100px 0% -75% 0%`, threshold: 1 },
|
||||
);
|
||||
|
||||
const scroll = (): void => {
|
||||
|
||||
@@ -9,7 +9,7 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>(
|
||||
<input
|
||||
type={type}
|
||||
className={cn(
|
||||
'flex h-9 w-full rounded-md border bg-transparent px-3 py-1 text-sm text-fd-foreground transition-colors placeholder:text-fd-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-fd-ring disabled:cursor-not-allowed disabled:opacity-50',
|
||||
'flex h-9 w-full rounded-md border bg-transparent px-2 py-1.5 text-sm text-fd-foreground transition-colors placeholder:text-fd-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-fd-ring disabled:cursor-not-allowed disabled:opacity-50',
|
||||
className,
|
||||
)}
|
||||
ref={ref}
|
||||
|
||||
@@ -51,11 +51,14 @@ export function ApiProvider({
|
||||
|
||||
useEffect(() => {
|
||||
setBaseUrl((prev) => localStorage.getItem('apiBaseUrl') ?? prev);
|
||||
if (highlighterInstance) setHighlighter(highlighterInstance);
|
||||
else
|
||||
if (highlighterInstance) {
|
||||
setHighlighter(highlighterInstance);
|
||||
} else {
|
||||
void initHighlighter().then((res) => {
|
||||
highlighterInstance = res;
|
||||
setHighlighter(res);
|
||||
});
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@@ -41,7 +41,7 @@ export function APIInfo({
|
||||
<div className={cn('min-w-0 flex-1', className)} {...props}>
|
||||
<div
|
||||
className={cn(
|
||||
'sticky top-24 z-[2] mb-4 flex flex-row items-center gap-2 rounded-lg border bg-fd-card p-3 md:top-10',
|
||||
'sticky top-24 z-20 mb-4 flex flex-row items-center gap-2 rounded-lg border bg-fd-card px-3 py-2 md:top-12 lg:top-1',
|
||||
)}
|
||||
>
|
||||
<span
|
||||
@@ -70,7 +70,7 @@ export function API({
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
'flex flex-col gap-x-6 gap-y-2 xl:flex-row xl:items-start',
|
||||
'flex flex-col gap-x-6 gap-y-4 xl:flex-row xl:items-start',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
@@ -115,7 +115,10 @@ export function APIExample({
|
||||
}: HTMLAttributes<HTMLDivElement>): React.ReactElement {
|
||||
return (
|
||||
<div
|
||||
className={cn('sticky top-10 prose-no-margin xl:w-[400px]', className)}
|
||||
className={cn(
|
||||
'prose-no-margin md:sticky md:top-12 lg:top-1 xl:w-[400px]',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
|
||||
@@ -179,7 +179,7 @@ export function APIPlayground({
|
||||
)}
|
||||
>
|
||||
<form
|
||||
className="not-prose flex flex-col gap-5 rounded-lg border bg-fd-card p-4"
|
||||
className="not-prose flex flex-col gap-5 rounded-lg border bg-fd-card p-3"
|
||||
onSubmit={onSubmit as React.FormEventHandler}
|
||||
>
|
||||
<div className="flex flex-row gap-2">
|
||||
@@ -199,7 +199,7 @@ export function APIPlayground({
|
||||
<Accordions
|
||||
type="multiple"
|
||||
className={cn(
|
||||
'-m-4 border-0 text-sm',
|
||||
'-m-3 border-0 text-sm',
|
||||
path.length === 0 &&
|
||||
query.length === 0 &&
|
||||
header.length === 0 &&
|
||||
@@ -294,7 +294,7 @@ function RouteDisplay({ route }: { route: string }): ReactElement {
|
||||
);
|
||||
|
||||
return (
|
||||
<code className="flex-1 overflow-auto text-nowrap rounded-lg border bg-fd-muted px-3 py-1.5 text-sm text-fd-muted-foreground">
|
||||
<code className="flex-1 overflow-auto text-nowrap rounded-lg border bg-fd-muted px-2 py-1.5 text-sm text-fd-muted-foreground">
|
||||
{pathname}
|
||||
</code>
|
||||
);
|
||||
|
||||
@@ -18,7 +18,7 @@ export function Heading<T extends Types = 'h1'>({
|
||||
|
||||
return (
|
||||
<As
|
||||
className={cn('flex scroll-m-20 flex-row items-center gap-2', className)}
|
||||
className={cn('flex scroll-m-28 flex-row items-center gap-2', className)}
|
||||
{...props}
|
||||
>
|
||||
<a href={`#${props.id}`} className="peer">
|
||||
|
||||
@@ -73,7 +73,7 @@ export function DynamicSidebar(props: SidebarProps): React.ReactElement {
|
||||
onPointerLeave: onLeave,
|
||||
'aria-hidden': Boolean(collapsed && !hover),
|
||||
className: cn(
|
||||
'md:transition-all',
|
||||
'md:transition-[transform,padding,width,margin]',
|
||||
collapsed && [
|
||||
'md:top-1 md:me-fd-sidebar-offset md:h-[calc(100dvh-4px)] md:w-[var(--fd-sidebar-width)] md:animate-fd-sidebar-collapse md:rounded-xl md:border md:ps-0 md:shadow-md',
|
||||
hover
|
||||
|
||||
@@ -64,7 +64,7 @@ export function TocPopover({ items, header, footer }: TOCProps): ReactElement {
|
||||
|
||||
return (
|
||||
<Popover>
|
||||
<PopoverTrigger className="inline-flex items-center gap-2 text-nowrap px-4 py-2 text-left max-md:size-full md:px-3 md:text-fd-muted-foreground">
|
||||
<PopoverTrigger className="inline-flex size-full items-center gap-2 text-nowrap px-4 py-2 text-left md:px-3">
|
||||
<Text className="size-4 shrink-0" />
|
||||
{text.toc}
|
||||
{current ? (
|
||||
|
||||
+23
-21
@@ -61,7 +61,7 @@ export function DocsPage({
|
||||
toc = [],
|
||||
tableOfContent = {},
|
||||
breadcrumb = {},
|
||||
tableOfContentPopover = {},
|
||||
tableOfContentPopover: tocPopoverOptions = {},
|
||||
lastUpdate,
|
||||
full = false,
|
||||
footer = {},
|
||||
@@ -75,28 +75,30 @@ export function DocsPage({
|
||||
|
||||
return (
|
||||
<TocProvider toc={toc}>
|
||||
<div className="flex min-w-0 flex-1 flex-col">
|
||||
<div
|
||||
className={cn(
|
||||
'sticky top-14 z-10 border-b bg-fd-background/60 text-sm font-medium backdrop-blur-md md:top-0 md:bg-fd-card',
|
||||
!full && 'lg:hidden',
|
||||
)}
|
||||
>
|
||||
{replaceOrDefault(
|
||||
tableOfContentPopover,
|
||||
<div
|
||||
className={cn(
|
||||
'mx-auto flex min-w-0 max-w-[860px] flex-1 flex-col',
|
||||
!tocOptions.enabled &&
|
||||
// ensure it's still centered when toc is hidden
|
||||
'max-w-[1200px] md:ms-[max(0px,calc(50vw-min(50%,600px)-var(--fd-c-sidebar)))]',
|
||||
)}
|
||||
>
|
||||
{replaceOrDefault(
|
||||
tocPopoverOptions,
|
||||
<div
|
||||
className={cn(
|
||||
'sticky top-14 z-10 border-b bg-fd-background/60 text-sm backdrop-blur-md md:top-1 md:mx-3 md:rounded-full md:border md:shadow-md',
|
||||
tocPopoverOptions.enabled !== true && 'lg:hidden',
|
||||
)}
|
||||
>
|
||||
<TocPopover
|
||||
items={toc}
|
||||
header={tableOfContentPopover.header}
|
||||
footer={tableOfContentPopover.footer}
|
||||
/>,
|
||||
)}
|
||||
</div>
|
||||
<article
|
||||
className={cn(
|
||||
'mx-auto flex w-full max-w-[860px] flex-1 flex-col gap-6 px-4 pt-10 md:px-6 md:pt-12',
|
||||
!tocOptions.enabled && 'max-w-[1200px]',
|
||||
)}
|
||||
>
|
||||
header={tocPopoverOptions.header}
|
||||
footer={tocPopoverOptions.footer}
|
||||
/>
|
||||
</div>,
|
||||
)}
|
||||
<article className="flex flex-1 flex-col gap-6 px-4 pt-10 md:px-6 md:pt-12">
|
||||
{replaceOrDefault(breadcrumb, <Breadcrumb {...breadcrumb} />)}
|
||||
{props.children}
|
||||
<div className="mt-auto" />
|
||||
|
||||
Reference in New Issue
Block a user