mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 09:25:06 +03:00
docs contributing layout (#33833)
* contributing layout * contributing layout mobile * gap * Update apps/docs/app/contributing/ContributingToC.tsx Co-authored-by: Charis <26616127+charislam@users.noreply.github.com> * Update apps/docs/app/contributing/ContributingToC.tsx Co-authored-by: Charis <26616127+charislam@users.noreply.github.com> * add missing menu entry * remove feedback anchor from toc * cleanup * sheet height * sheet height * breadcrumb --------- Co-authored-by: Charis <26616127+charislam@users.noreply.github.com>
This commit is contained in:
1 parent
9b34521bed
commit
64ad37a09b
6 files changed
+97
-29
No files matched your search
@@ -5,7 +5,8 @@ import type { HTMLAttributes } from 'react'
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
import { useBreakpoint } from 'common'
|
||||
import { cn, Popover_Shadcn_, PopoverContent_Shadcn_, PopoverTrigger_Shadcn_ } from 'ui'
|
||||
import { cn, Separator, Sheet, SheetContent, SheetHeader, SheetTrigger } from 'ui'
|
||||
import { Feedback } from '~/components/Feedback'
|
||||
|
||||
interface TocItem extends HTMLAttributes<HTMLElement> {
|
||||
label: string
|
||||
@@ -18,7 +19,7 @@ export function ContributingToc({ className }: { className?: string }) {
|
||||
|
||||
useEffect(() => {
|
||||
const headings = [
|
||||
...document.querySelectorAll('article.prose > h2,h3'),
|
||||
...document.querySelectorAll('article.prose > h2,h3:not(#feedback-title)'),
|
||||
] as Array<HTMLHeadingElement>
|
||||
const tocItems = headings
|
||||
.filter((heading) => !!heading.id)
|
||||
@@ -30,20 +31,16 @@ export function ContributingToc({ className }: { className?: string }) {
|
||||
}, [])
|
||||
|
||||
return mobileToc ? (
|
||||
<MobileToc
|
||||
items={tocItems}
|
||||
className={cn(
|
||||
'[--local-top-spacing:2rem]',
|
||||
'fixed top-[calc(var(--header-height)+var(--local-top-spacing))] right-8'
|
||||
)}
|
||||
/>
|
||||
<MobileToc items={tocItems} />
|
||||
) : (
|
||||
<TocBase
|
||||
items={tocItems}
|
||||
className={cn(
|
||||
'[--local-top-spacing:5rem]',
|
||||
'fixed top-[calc(var(--header-height)+var(--local-top-spacing))] right-8 w-36',
|
||||
'xl:border-l border-foreground-muted'
|
||||
'border-l thin-scrollbar overflow-y-auto px-2 hidden lg:block',
|
||||
'col-span-3 self-start sticky',
|
||||
'top-[calc(var(--header-height)+1px+2rem)] max-h-[calc(100vh-var(--header-height)-3rem)]',
|
||||
className
|
||||
)}
|
||||
/>
|
||||
)
|
||||
@@ -52,31 +49,74 @@ export function ContributingToc({ className }: { className?: string }) {
|
||||
function MobileToc({ items, className }: { items: Array<TocItem>; className?: string }) {
|
||||
const [open, setOpen] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
const onHashChanged = () => setOpen(false)
|
||||
|
||||
window.addEventListener('hashchange', onHashChanged)
|
||||
return () => {
|
||||
window.removeEventListener('hashchange', onHashChanged)
|
||||
}
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<Popover_Shadcn_ open={open} onOpenChange={setOpen}>
|
||||
<PopoverTrigger_Shadcn_ className={cn('border rounded p-2', className)}>
|
||||
<Menu />
|
||||
<Sheet open={open} onOpenChange={setOpen}>
|
||||
<SheetTrigger
|
||||
className={cn(
|
||||
'fixed z-0 inset-0 top-auto w-full rounded-t-lg border border-b-0 p-4 bg-studio flex items-center gap-2 text-foreground-light text-sm',
|
||||
className
|
||||
)}
|
||||
>
|
||||
<Menu size={16} strokeWidth={1.5} className="text-foreground-light" />
|
||||
<span className="sr-only">
|
||||
{open ? 'Close table of contents' : 'Open table of contents'}
|
||||
</span>
|
||||
</PopoverTrigger_Shadcn_>
|
||||
<PopoverContent_Shadcn_ align="end" className="w-48">
|
||||
<TocBase items={items} />
|
||||
</PopoverContent_Shadcn_>
|
||||
</Popover_Shadcn_>
|
||||
<span>On this page</span>
|
||||
</SheetTrigger>
|
||||
<SheetContent
|
||||
side="bottom"
|
||||
size="lg"
|
||||
className={cn(
|
||||
'w-full flex flex-col gap-0 p-0 rounded-t-lg overflow-hidden',
|
||||
!open && 'top-[calc(100vh-100px)]'
|
||||
)}
|
||||
>
|
||||
<SheetHeader className="py-0 px-4">
|
||||
<SheetTrigger
|
||||
className={cn(
|
||||
'w-full py-4 flex items-center gap-2 text-foreground-light text-sm',
|
||||
className
|
||||
)}
|
||||
>
|
||||
<Menu size={16} strokeWidth={1.5} className="text-foreground-light" />
|
||||
<span className="sr-only">
|
||||
{open ? 'Close table of contents' : 'Open table of contents'}
|
||||
</span>
|
||||
<span>On this page</span>
|
||||
</SheetTrigger>
|
||||
</SheetHeader>
|
||||
<div className="w-full flex-1 p-4 pb-8 overflow-y-auto thin-scrollbar">
|
||||
<TocBase items={items} />
|
||||
</div>
|
||||
</SheetContent>
|
||||
</Sheet>
|
||||
)
|
||||
}
|
||||
|
||||
function TocBase({ items, className }: { items: Array<TocItem>; className?: string }) {
|
||||
return (
|
||||
<nav aria-label="Table of contents" className={cn('px-4 text-foreground-light', className)}>
|
||||
<ul className="flex flex-col gap-1">
|
||||
<nav aria-label="Table of contents" className={cn('text-foreground-lighter', className)}>
|
||||
<span className="hidden lg:block font-mono text-xs uppercase text-foreground px-5 mb-6">
|
||||
On this page
|
||||
</span>
|
||||
<ul className="toc-menu list-none lg:pl-5 text-[0.8rem] grid gap-2">
|
||||
{items.map((item) => (
|
||||
<li key={item.anchor} className="overflow-hidden truncate">
|
||||
<a href={`#${item.anchor}`}>{item.label}</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<Separator className="lg:w-[calc(100%-2rem)] lg:ml-5 my-4 lg:my-8" />
|
||||
<Feedback className="pl-0 lg:pl-5" />
|
||||
</nav>
|
||||
)
|
||||
}
|
||||
@@ -5,22 +5,30 @@ import { fileURLToPath } from 'node:url'
|
||||
import { ContributingToc } from '~/app/contributing/ContributingToC'
|
||||
import { MDXProviderGuides } from '~/features/docs/GuidesMdx.client'
|
||||
import { MDXRemoteBase } from '~/features/docs/MdxBase'
|
||||
import { LayoutMainContent } from '~/layouts/DefaultLayout'
|
||||
import { SidebarSkeleton } from '~/layouts/MainSkeleton'
|
||||
import Breadcrumbs from '~/components/Breadcrumbs'
|
||||
|
||||
export default async function ContributingPage() {
|
||||
const contentFile = join(dirname(fileURLToPath(import.meta.url)), 'content.mdx')
|
||||
const content = await readFile(contentFile, 'utf-8')
|
||||
|
||||
return (
|
||||
<SidebarSkeleton hideSideNav>
|
||||
<div className="px-8 py-16">
|
||||
<article className="prose mx-auto">
|
||||
<MDXProviderGuides>
|
||||
<MDXRemoteBase source={content} />
|
||||
</MDXProviderGuides>
|
||||
</article>
|
||||
<SidebarSkeleton>
|
||||
<LayoutMainContent className="pb-0 grid grid-cols-12 relative gap-4">
|
||||
<div className="col-span-12 lg:col-span-9">
|
||||
<Breadcrumbs className="mb-2 col-span-full" />
|
||||
<article
|
||||
id="contributing"
|
||||
className="prose max-w-none relative transition-all ease-out duration-100"
|
||||
>
|
||||
<MDXProviderGuides>
|
||||
<MDXRemoteBase source={content} />
|
||||
</MDXProviderGuides>
|
||||
</article>
|
||||
</div>
|
||||
<ContributingToc />
|
||||
</div>
|
||||
</LayoutMainContent>
|
||||
</SidebarSkeleton>
|
||||
)
|
||||
}
|
||||
@@ -1953,6 +1953,13 @@ export const local_development: NavMenuConstant = {
|
||||
],
|
||||
}
|
||||
|
||||
export const contributing: NavMenuConstant = {
|
||||
icon: 'contributing',
|
||||
title: 'Contributing',
|
||||
url: '/contributing',
|
||||
items: [{ name: 'Overview', url: '/contributing' }],
|
||||
}
|
||||
|
||||
export const MIGRATION_PAGES: Partial<NavMenuSection & ComponentProps<typeof IconPanel>>[] = [
|
||||
{
|
||||
name: 'Auth0',
|
||||
|
||||
@@ -24,6 +24,7 @@ enum MenuId {
|
||||
SelfHosting = 'self_hosting',
|
||||
Integrations = 'integrations',
|
||||
LocalDevelopment = 'local_development',
|
||||
Contributing = 'contributing',
|
||||
RefJavaScriptV1 = 'reference_javascript_v1',
|
||||
RefJavaScriptV2 = 'reference_javascript_v2',
|
||||
RefDartV1 = 'reference_dart_v1',
|
||||
@@ -128,6 +129,10 @@ const menus: Menu[] = [
|
||||
id: MenuId.LocalDevelopment,
|
||||
type: 'guide',
|
||||
},
|
||||
{
|
||||
id: MenuId.Contributing,
|
||||
type: 'guide',
|
||||
},
|
||||
{
|
||||
id: MenuId.Deployment,
|
||||
type: 'guide',
|
||||
|
||||
@@ -139,6 +139,8 @@ export const getMenuId = (pathname: string | null) => {
|
||||
return MenuId.SelfHosting
|
||||
case pathname.startsWith('storage'):
|
||||
return MenuId.Storage
|
||||
case pathname.startsWith('/contributing'):
|
||||
return MenuId.Contributing
|
||||
default:
|
||||
return MenuId.GettingStarted
|
||||
}
|
||||
|
||||
@@ -82,6 +82,10 @@ const levelsData = {
|
||||
icon: 'platform',
|
||||
name: 'Platform',
|
||||
},
|
||||
contributing: {
|
||||
icon: 'contributing',
|
||||
name: 'Contributing',
|
||||
},
|
||||
resources: {
|
||||
icon: 'resources',
|
||||
name: 'Resources',
|
||||
@@ -377,6 +381,8 @@ function SidebarSkeleton({
|
||||
|
||||
const mobileMenuOpen = useMenuMobileOpen()
|
||||
|
||||
console.log('menuName', menuName, menuId)
|
||||
|
||||
return (
|
||||
<div className={cn('flex flex-row h-full relative', className)}>
|
||||
{!hideSideNav && (
|
||||
|
||||
Reference in new issue
Block a user