Some changes ported from the work on the makerkit.dev website related… (#89)
* Some changes ported from the work on the makerkit.dev website related to the marketing sections of the kit, such as documentation * Added slight background hue to make darker theme better looking * Support more complex configurations for documentation navigations. * Do not fetch content from Keystatic when non-needed * Add cursor pointers in dropdown * Updated packages
This commit is contained in:
committed by
GitHub
parent
a682b991f3
commit
079a8f857a
@@ -61,13 +61,15 @@ async function DocumentationPage({ params }: DocumentationPageProps) {
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={'flex flex-1 flex-col space-y-4'}>
|
||||
<div className={'flex'}>
|
||||
<article className={cn(styles.HTML, 'container space-y-12')}>
|
||||
<div className={'flex flex-1 flex-col space-y-4 overflow-y-hidden'}>
|
||||
<div className={'flex overflow-y-hidden'}>
|
||||
<article
|
||||
className={cn(styles.HTML, 'container space-y-12 overflow-y-auto')}
|
||||
>
|
||||
<section className={'flex flex-col space-y-4 pt-6'}>
|
||||
<h1 className={'!my-0'}>{page.title}</h1>
|
||||
|
||||
<h2 className={'!mb-0 !font-normal text-muted-foreground'}>
|
||||
<h2 className={'!mb-0 !font-normal !text-muted-foreground'}>
|
||||
{description}
|
||||
</h2>
|
||||
</section>
|
||||
|
||||
@@ -1,13 +1,20 @@
|
||||
'use client';
|
||||
|
||||
import { useRef } from 'react';
|
||||
|
||||
import Link from 'next/link';
|
||||
import { usePathname } from 'next/navigation';
|
||||
|
||||
import { SidebarMenuButton, SidebarMenuItem } from '@kit/ui/shadcn-sidebar';
|
||||
import { cn, isRouteActive } from '@kit/ui/utils';
|
||||
|
||||
export function DocsNavLink({ label, url }: { label: string; url: string }) {
|
||||
export function DocsNavLink({
|
||||
label,
|
||||
url,
|
||||
children,
|
||||
}: React.PropsWithChildren<{ label: string; url: string }>) {
|
||||
const currentPath = usePathname();
|
||||
const ref = useRef<HTMLElement>(null);
|
||||
const isCurrent = isRouteActive(url, currentPath, true);
|
||||
|
||||
return (
|
||||
@@ -15,10 +22,16 @@ export function DocsNavLink({ label, url }: { label: string; url: string }) {
|
||||
<SidebarMenuButton
|
||||
asChild
|
||||
isActive={isCurrent}
|
||||
className={cn('border-l-3 transition-background !font-normal')}
|
||||
className={cn('border-l-3 transition-background !font-normal', {
|
||||
'font-bold text-secondary-foreground': isCurrent,
|
||||
})}
|
||||
>
|
||||
<Link href={url}>
|
||||
<span className="block max-w-full truncate">{label}</span>
|
||||
<span ref={ref} className="block max-w-full truncate">
|
||||
{label}
|
||||
</span>
|
||||
|
||||
{children}
|
||||
</Link>
|
||||
</SidebarMenuButton>
|
||||
</SidebarMenuItem>
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
'use client';
|
||||
|
||||
import { usePathname } from 'next/navigation';
|
||||
|
||||
import { Cms } from '@kit/cms';
|
||||
import { Collapsible } from '@kit/ui/collapsible';
|
||||
import { isRouteActive } from '@kit/ui/utils';
|
||||
|
||||
export function DocsNavigationCollapsible(
|
||||
props: React.PropsWithChildren<{
|
||||
node: Cms.ContentItem;
|
||||
prefix: string;
|
||||
}>,
|
||||
) {
|
||||
const currentPath = usePathname();
|
||||
const prefix = props.prefix;
|
||||
|
||||
const isChildActive = props.node.children.some((child) =>
|
||||
isRouteActive(prefix + '/' + child.url, currentPath, false),
|
||||
);
|
||||
|
||||
return (
|
||||
<Collapsible
|
||||
className={'group/collapsible'}
|
||||
defaultOpen={isChildActive ? true : !props.node.collapsed}
|
||||
>
|
||||
{props.children}
|
||||
</Collapsible>
|
||||
);
|
||||
}
|
||||
@@ -1,66 +1,137 @@
|
||||
import { ChevronDown } from 'lucide-react';
|
||||
|
||||
import { Cms } from '@kit/cms';
|
||||
import { CollapsibleContent, CollapsibleTrigger } from '@kit/ui/collapsible';
|
||||
import {
|
||||
Sidebar,
|
||||
SidebarGroup,
|
||||
SidebarGroupContent,
|
||||
SidebarMenu,
|
||||
SidebarMenuButton,
|
||||
SidebarMenuItem,
|
||||
SidebarMenuSub,
|
||||
} from '@kit/ui/shadcn-sidebar';
|
||||
|
||||
import { DocsNavLink } from '~/(marketing)/docs/_components/docs-nav-link';
|
||||
import { DocsNavigationCollapsible } from '~/(marketing)/docs/_components/docs-navigation-collapsible';
|
||||
|
||||
import { FloatingDocumentationNavigation } from './floating-docs-navigation';
|
||||
|
||||
function Node({ node, level }: { node: Cms.ContentItem; level: number }) {
|
||||
const pathPrefix = `/docs`;
|
||||
const url = `${pathPrefix}/${node.slug}`;
|
||||
function Node({
|
||||
node,
|
||||
level,
|
||||
prefix,
|
||||
}: {
|
||||
node: Cms.ContentItem;
|
||||
level: number;
|
||||
prefix: string;
|
||||
}) {
|
||||
const url = `${prefix}/${node.slug}`;
|
||||
const label = node.label ? node.label : node.title;
|
||||
|
||||
const Container = (props: React.PropsWithChildren) => {
|
||||
if (node.collapsible) {
|
||||
return (
|
||||
<DocsNavigationCollapsible node={node} prefix={prefix}>
|
||||
{props.children}
|
||||
</DocsNavigationCollapsible>
|
||||
);
|
||||
}
|
||||
|
||||
return props.children;
|
||||
};
|
||||
|
||||
const ContentContainer = (props: React.PropsWithChildren) => {
|
||||
if (node.collapsible) {
|
||||
return <CollapsibleContent>{props.children}</CollapsibleContent>;
|
||||
}
|
||||
|
||||
return props.children;
|
||||
};
|
||||
|
||||
const Trigger = () => {
|
||||
if (node.collapsible) {
|
||||
return (
|
||||
<CollapsibleTrigger asChild>
|
||||
<SidebarMenuItem>
|
||||
<SidebarMenuButton>
|
||||
{label}
|
||||
<ChevronDown className="ml-auto transition-transform group-data-[state=open]/collapsible:rotate-180" />
|
||||
</SidebarMenuButton>
|
||||
</SidebarMenuItem>
|
||||
</CollapsibleTrigger>
|
||||
);
|
||||
}
|
||||
|
||||
return <DocsNavLink label={label} url={url} />;
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<DocsNavLink label={node.title} url={url} />
|
||||
<Container>
|
||||
<Trigger />
|
||||
|
||||
{(node.children ?? []).length > 0 && (
|
||||
<Tree pages={node.children ?? []} level={level + 1} />
|
||||
)}
|
||||
</>
|
||||
<ContentContainer>
|
||||
<Tree pages={node.children ?? []} level={level + 1} prefix={prefix} />
|
||||
</ContentContainer>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
function Tree({ pages, level }: { pages: Cms.ContentItem[]; level: number }) {
|
||||
function Tree({
|
||||
pages,
|
||||
level,
|
||||
prefix,
|
||||
}: {
|
||||
pages: Cms.ContentItem[];
|
||||
level: number;
|
||||
prefix: string;
|
||||
}) {
|
||||
if (level === 0) {
|
||||
return pages.map((treeNode, index) => (
|
||||
<SidebarGroup key={index}>
|
||||
<SidebarGroupContent>
|
||||
<SidebarMenu>
|
||||
<Node key={index} node={treeNode} level={level} />
|
||||
</SidebarMenu>
|
||||
</SidebarGroupContent>
|
||||
</SidebarGroup>
|
||||
<Node key={index} node={treeNode} level={level} prefix={prefix} />
|
||||
));
|
||||
}
|
||||
|
||||
return (
|
||||
<SidebarMenuSub>
|
||||
{pages.map((treeNode, index) => (
|
||||
<Node key={index} node={treeNode} level={level} />
|
||||
<Node key={index} node={treeNode} level={level} prefix={prefix} />
|
||||
))}
|
||||
</SidebarMenuSub>
|
||||
);
|
||||
}
|
||||
|
||||
export function DocsNavigation({ pages }: { pages: Cms.ContentItem[] }) {
|
||||
export function DocsNavigation({
|
||||
pages,
|
||||
prefix = '/docs',
|
||||
}: {
|
||||
pages: Cms.ContentItem[];
|
||||
prefix?: string;
|
||||
}) {
|
||||
return (
|
||||
<>
|
||||
<Sidebar
|
||||
variant={'ghost'}
|
||||
className={'z-1 sticky max-h-full overflow-y-auto'}
|
||||
>
|
||||
<Tree pages={pages} level={0} />
|
||||
<SidebarGroup>
|
||||
<SidebarGroupContent>
|
||||
<SidebarMenu>
|
||||
<Tree pages={pages} level={0} prefix={prefix} />
|
||||
</SidebarMenu>
|
||||
</SidebarGroupContent>
|
||||
</SidebarGroup>
|
||||
</Sidebar>
|
||||
|
||||
<div className={'lg:hidden'}>
|
||||
<FloatingDocumentationNavigation>
|
||||
<Tree pages={pages} level={0} />
|
||||
<SidebarGroup>
|
||||
<SidebarGroupContent>
|
||||
<SidebarMenu>
|
||||
<Tree pages={pages} level={0} prefix={prefix} />
|
||||
</SidebarMenu>
|
||||
</SidebarGroupContent>
|
||||
</SidebarGroup>
|
||||
</FloatingDocumentationNavigation>
|
||||
</div>
|
||||
</>
|
||||
|
||||
@@ -18,7 +18,8 @@ async function docsLoader(language: string | undefined) {
|
||||
const data = await cms.getContentItems({
|
||||
collection: 'documentation',
|
||||
language,
|
||||
limit: 500,
|
||||
limit: Infinity,
|
||||
content: false,
|
||||
});
|
||||
|
||||
return data.items;
|
||||
|
||||
@@ -15,7 +15,7 @@ async function DocsLayout({ children }: React.PropsWithChildren) {
|
||||
return (
|
||||
<SidebarProvider
|
||||
style={{ '--sidebar-width': '20em' } as React.CSSProperties}
|
||||
className={'lg:container'}
|
||||
className={'h-[calc(100vh-72px)] overflow-y-hidden lg:container'}
|
||||
>
|
||||
<DocsNavigation pages={tree} />
|
||||
|
||||
|
||||
Reference in New Issue
Block a user