-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
4c79ecd
commit 934f177
Showing
8 changed files
with
507 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import { cn } from '@/lib/utils.ts' | ||
import { useShowHeader } from '@/hooks/utils/useShowHeader.ts' | ||
import { lightBorderColor } from '@/components/utils/tailwinds.ts' | ||
import TocMenuModalNav from '@/islands/layouts/posts/TocMenuModalNav.tsx' | ||
import { MarkdownHeading } from '@/utils/markdown.ts' | ||
import DocMenuModalNav from '@/islands/layouts/doc/DocMenuModalNav.tsx' | ||
|
||
type Props = { | ||
headings: MarkdownHeading[] | ||
} | ||
|
||
export default function DocHeader({ headings }: Props) { | ||
const showHeader = useShowHeader() | ||
return ( | ||
<> | ||
<div | ||
className={cn( | ||
'sticky top-16 z-20', | ||
'w-full -mt-8 mb-8 px-6 py-2', | ||
'border-b border-t', | ||
lightBorderColor, | ||
'backdrop-blur-xl bg-opacity-70 dark:bg-opacity-20', | ||
'transition-transform duration-300 ease-in-out', | ||
'flex flex-row gap-10 lg:hidden items-center justify-center', | ||
showHeader.value | ||
? '-translate-y-1 md:translate-y-0' | ||
: '-translate-y-96', | ||
)} | ||
> | ||
<div> | ||
<DocMenuModalNav /> | ||
</div> | ||
<div className='flex flex-grow' /> | ||
<div class='md:hidden'> | ||
<TocMenuModalNav headings={headings} /> | ||
</div> | ||
</div> | ||
</> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
import { useSignal } from '@preact/signals' | ||
import { usePathname } from '@/hooks/i18n/usePathname.ts' | ||
import { docMenuData } from '@/islands/layouts/doc/docNavs.ts' | ||
import { Item, Section } from '@/utils/posts.ts' | ||
import { useTranslation } from '@/hooks/i18n/useTranslation.ts' | ||
import Link from '@/components/utils/Link.tsx' | ||
import { cn } from '@/lib/utils.ts' | ||
import { NavArrowDown, NavArrowRight } from 'iconoir-react' | ||
import { | ||
basicTextColor, | ||
lightBorderColor, | ||
linkActiveColor, | ||
linkMenuColor, | ||
} from '@/components/utils/tailwinds.ts' | ||
import { useEffect } from 'preact/hooks' | ||
|
||
const DocMenu = () => { | ||
return ( | ||
<div className='w-full p-3'> | ||
{docMenuData.map((section) => ( | ||
<DocMenuSection key={section.title} section={section} /> | ||
))} | ||
</div> | ||
) | ||
} | ||
|
||
type DocMenuSectionProps = { | ||
section: Section | ||
} | ||
|
||
const DocMenuSection = ({ section }: DocMenuSectionProps) => { | ||
const t = useTranslation() | ||
const { isActivePath } = usePathname() | ||
|
||
return ( | ||
<div className='w-full p-2'> | ||
<div | ||
className={cn( | ||
'flex items-center justify-between', | ||
'cursor-pointer hover:opacity-70', | ||
)} | ||
> | ||
<Link href={section.route} className='w-full'> | ||
<span | ||
className={cn( | ||
isActivePath(section.route) ? linkActiveColor : basicTextColor, | ||
'flex-1 text-sm font-bold', | ||
)} | ||
> | ||
{t(section.title)} | ||
</span> | ||
</Link> | ||
</div> | ||
{section.items && ( | ||
<ul className='my-2 w-full'> | ||
{section.items.map((item) => ( | ||
<DocMenuItem key={item.title} item={item} /> | ||
))} | ||
</ul> | ||
)} | ||
</div> | ||
) | ||
} | ||
|
||
type DocMenuItemProps = { | ||
item: Item | ||
} | ||
|
||
const DocMenuItem = ({ item }: DocMenuItemProps) => { | ||
const t = useTranslation() | ||
const { isActivePath } = usePathname() | ||
const isOpen = useSignal(false) | ||
|
||
useEffect(() => { | ||
const hasActiveSubItem = item.subItems?.some((subItem) => | ||
isActivePath(subItem.route) | ||
) || false | ||
isOpen.value = isActivePath(item.route as string) || hasActiveSubItem | ||
}, [item, isActivePath]) | ||
|
||
return ( | ||
<li className='mt-4 w-full'> | ||
<div | ||
className={cn( | ||
'w-full flex items-center justify-between gap-2 py-0.5', | ||
'cursor-pointer hover:opacity-70', | ||
)} | ||
onClick={() => isOpen.value = !item.subItems ? false : !isOpen.value} | ||
> | ||
{item.subItems | ||
? ( | ||
<div class='flex flex-row justify-between items-center w-full'> | ||
<p | ||
className={cn( | ||
isActivePath(item.route as string) | ||
? linkActiveColor | ||
: linkMenuColor, | ||
'text-sm', | ||
)} | ||
> | ||
{t(item.title)} | ||
</p> | ||
<p | ||
className={cn( | ||
isActivePath(item.route as string) | ||
? linkActiveColor | ||
: linkMenuColor, | ||
'text-sm', | ||
)} | ||
> | ||
{isOpen.value | ||
? <NavArrowDown className='h-4 w-4' /> | ||
: <NavArrowRight className='h-4 w-4' />} | ||
</p> | ||
</div> | ||
) | ||
: ( | ||
<> | ||
<Link href={item.route as string} className='w-full'> | ||
<span | ||
className={cn( | ||
isActivePath(item.route as string) | ||
? linkActiveColor | ||
: linkMenuColor, | ||
'flex-1 text-sm', | ||
)} | ||
> | ||
{t(item.title)} | ||
</span> | ||
</Link> | ||
</> | ||
)} | ||
</div> | ||
{isOpen.value && item.subItems && ( | ||
<ul | ||
className={cn('my-2 ml-1 w-full pl-4', 'border-l', lightBorderColor)} | ||
> | ||
{item.subItems.map((subItem) => ( | ||
<li key={subItem.title} className='mb-1 w-full'> | ||
<Link href={subItem.route} className='w-full'> | ||
<p | ||
className={cn( | ||
isActivePath(subItem.route) | ||
? linkActiveColor | ||
: linkMenuColor, | ||
'w-full py-2 text-sm hover:opacity-70', | ||
)} | ||
> | ||
{t(subItem.title)} | ||
</p> | ||
</Link> | ||
</li> | ||
))} | ||
</ul> | ||
)} | ||
</li> | ||
) | ||
} | ||
|
||
export default DocMenu |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import { useSignal } from '@preact/signals' | ||
import { Modal } from '@/components/ui/Modal.tsx' | ||
import { List } from 'iconoir-react' | ||
import { basicTextColor } from '@/components/utils/tailwinds.ts' | ||
import Button from '@/components/ui/Button.tsx' | ||
import { useTranslation } from '@/hooks/i18n/useTranslation.ts' | ||
import { cn } from '@/lib/utils.ts' | ||
import LogoHorizontalLink from '@/components/common/LogoHorizontalLink.tsx' | ||
import DocMenu from '@/islands/layouts/doc/DocMenu.tsx' | ||
|
||
export default function DocMenuModalNav() { | ||
const isOpen = useSignal(false) | ||
const t = useTranslation() | ||
|
||
return ( | ||
<> | ||
<Button | ||
variant='outline' | ||
buttonType='small' | ||
onClick={() => isOpen.value = true} | ||
class='lg:hidden hover:opacity-70 flex gap-2' | ||
> | ||
<List class={cn('w-4 h-4', basicTextColor)} /> | ||
<span className='text-xs'>{t('doc.nav.title')}</span> | ||
</Button> | ||
<Modal | ||
isOpen={isOpen.value} | ||
onClose={() => isOpen.value = false} | ||
position='fullscreen' | ||
className='flex flex-col' | ||
> | ||
<nav className='grid gap-2'> | ||
<div className='mb-6 flex flex-row items-start'> | ||
<LogoHorizontalLink | ||
className='w-20' | ||
onClick={() => { | ||
isOpen.value = false | ||
}} | ||
/> | ||
</div> | ||
<DocMenu /> | ||
</nav> | ||
</Modal> | ||
</> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import { Section } from '@/utils/posts.ts' | ||
|
||
export const docMenuData: Section[] = [ | ||
{ | ||
title: 'doc.nav.general.getting-started', | ||
route: '/doc/general/getting-started', | ||
items: [ | ||
{ | ||
title: 'doc.nav.general.installation', | ||
route: '/doc/general/installation', | ||
}, | ||
{ | ||
title: 'doc.nav.general.project-structure', | ||
route: '/doc/general/project-structure', | ||
}, | ||
], | ||
}, | ||
{ | ||
title: 'doc.nav.building-your-application.title', | ||
route: '/doc/building-your-application/menu', | ||
items: [ | ||
{ | ||
title: 'doc.nav.building-your-application.api.title', | ||
subItems: [ | ||
{ | ||
title: 'doc.nav.building-your-application.api.http', | ||
route: '/doc/building-your-application/api/http', | ||
}, | ||
{ | ||
title: 'doc.nav.building-your-application.api.rpc', | ||
route: '/doc/building-your-application/api/rpc', | ||
}, | ||
], | ||
}, | ||
{ | ||
title: 'doc.nav.building-your-application.worker.title', | ||
subItems: [ | ||
{ | ||
title: 'doc.nav.building-your-application.worker.cron', | ||
route: '/doc/building-your-application/worker/cron', | ||
}, | ||
{ | ||
title: 'doc.nav.building-your-application.worker.queue', | ||
route: '/doc/building-your-application/worker/queue', | ||
}, | ||
], | ||
}, | ||
{ | ||
title: 'doc.nav.building-your-application.frontend.title', | ||
subItems: [ | ||
{ | ||
title: 'doc.nav.building-your-application.frontend.ssg', | ||
route: '/doc/building-your-application/frontend/ssg', | ||
}, | ||
{ | ||
title: 'doc.nav.building-your-application.frontend.webapp', | ||
route: '/doc/building-your-application/frontend/webapp', | ||
}, | ||
{ | ||
title: 'doc.nav.building-your-application.frontend.solana', | ||
route: '/doc/building-your-application/frontend/solana', | ||
}, | ||
], | ||
}, | ||
{ | ||
title: 'doc.nav.building-your-application.cli.title', | ||
route: '/doc/building-your-application/cli/main', | ||
}, | ||
], | ||
}, | ||
] |
Oops, something went wrong.