-
Notifications
You must be signed in to change notification settings - Fork 19
feat: fumadocs - v4 #24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
a22ddbd
e14bb11
f80cc3f
72db389
4e9fd02
4234fa3
606eee4
a46755c
f08a7c7
38ef0d0
ef2d6e1
43c3077
30d3596
1f9c358
4c59831
9f2e959
9a2c514
00d7762
9f3d330
cdc140f
558c3b3
3fb347f
af94f8d
05de658
3b1babe
8041555
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,7 +5,7 @@ | |
| /build | ||
|
|
||
| # Generated files | ||
| .docusaurus | ||
| .react-router | ||
| .cache-loader | ||
|
|
||
| # Misc | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,5 @@ | ||
| # Docusaurus build output | ||
| .docusaurus | ||
| # React router build output | ||
| .react-router | ||
|
|
||
| # Node modules | ||
| node_modules |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,13 @@ | ||
| { | ||
| "cSpell.enabled": true | ||
| "cSpell.enabled": true, | ||
| "cSpell.words": [ | ||
| "appstore", | ||
| "Healthcheck", | ||
| "homelab", | ||
| "homeserver", | ||
| "Runtipi", | ||
| "Tinyauth", | ||
| "TOTP", | ||
| "Traefik" | ||
| ] | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| @import 'tailwindcss'; | ||
| @import 'fumadocs-ui/css/neutral.css'; | ||
| @import 'fumadocs-ui/css/preset.css'; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| { | ||
| "aliases": { | ||
| "uiDir": "./components/ui", | ||
| "componentsDir": "./components", | ||
| "blockDir": "./components", | ||
| "cssDir": "./styles", | ||
| "libDir": "./lib" | ||
| }, | ||
| "baseDir": "", | ||
| "commands": {} | ||
| } | ||
|
Comment on lines
+1
to
+11
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chainVerify the cssDir alias path The Run the following script to check the actual CSS file locations: 🏁 Script executed: #!/bin/bash
# Description: Verify CSS file locations vs. cssDir alias
# Check if ./styles directory exists
fd -t d -d 1 '^styles$' app/
# List all CSS files in the app directory
fd -e css -t f . app/Length of output: 11 Update cssDir alias to match actual CSS location 🤖 Prompt for AI Agents |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| interface FeatureCardProps { | ||
| title: string; | ||
| description: string; | ||
| icon?: React.ReactNode; | ||
| children?: React.ReactNode; | ||
| } | ||
|
|
||
| export const Card = ({ | ||
| title, | ||
| description, | ||
| icon, | ||
| children, | ||
| }: FeatureCardProps) => { | ||
| return ( | ||
| <div className="flex flex-col gap-4 p-4 shadow-xs border border-fd-border rounded-md hover:border-fd-accent transition-colors max-w-xs"> | ||
| {icon} | ||
| <div className="flex flex-col gap-2"> | ||
| <p className="text-md font-semibold">{title}</p> | ||
| <p className="text-sm">{description}</p> | ||
| </div> | ||
| {children} | ||
| </div> | ||
| ); | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| import type { SVGProps } from "react"; | ||
|
|
||
| export function IcBaselineDiscord(props: SVGProps<SVGSVGElement>) { | ||
| return ( | ||
| <svg | ||
| xmlns="http://www.w3.org/2000/svg" | ||
| width={24} | ||
| height={24} | ||
| viewBox="0 0 24 24" | ||
| {...props} | ||
| > | ||
| <path | ||
| fill="currentColor" | ||
| d="M19.27 5.33C17.94 4.71 16.5 4.26 15 4a.1.1 0 0 0-.07.03c-.18.33-.39.76-.53 1.09a16.1 16.1 0 0 0-4.8 0c-.14-.34-.35-.76-.54-1.09c-.01-.02-.04-.03-.07-.03c-1.5.26-2.93.71-4.27 1.33c-.01 0-.02.01-.03.02c-2.72 4.07-3.47 8.03-3.1 11.95c0 .02.01.04.03.05c1.8 1.32 3.53 2.12 5.24 2.65c.03.01.06 0 .07-.02c.4-.55.76-1.13 1.07-1.74c.02-.04 0-.08-.04-.09c-.57-.22-1.11-.48-1.64-.78c-.04-.02-.04-.08-.01-.11c.11-.08.22-.17.33-.25c.02-.02.05-.02.07-.01c3.44 1.57 7.15 1.57 10.55 0c.02-.01.05-.01.07.01c.11.09.22.17.33.26c.04.03.04.09-.01.11c-.52.31-1.07.56-1.64.78c-.04.01-.05.06-.04.09c.32.61.68 1.19 1.07 1.74c.03.01.06.02.09.01c1.72-.53 3.45-1.33 5.25-2.65c.02-.01.03-.03.03-.05c.44-4.53-.73-8.46-3.1-11.95c-.01-.01-.02-.02-.04-.02M8.52 14.91c-1.03 0-1.89-.95-1.89-2.12s.84-2.12 1.89-2.12c1.06 0 1.9.96 1.89 2.12c0 1.17-.84 2.12-1.89 2.12m6.97 0c-1.03 0-1.89-.95-1.89-2.12s.84-2.12 1.89-2.12c1.06 0 1.9.96 1.89 2.12c0 1.17-.83 2.12-1.89 2.12" | ||
| ></path> | ||
| </svg> | ||
| ); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| import type { SVGProps } from "react"; | ||
|
|
||
| export function MdiGithub(props: SVGProps<SVGSVGElement>) { | ||
| return ( | ||
| <svg | ||
| xmlns="http://www.w3.org/2000/svg" | ||
| width={24} | ||
| height={24} | ||
| viewBox="0 0 24 24" | ||
| {...props} | ||
| > | ||
| <path | ||
| fill="currentColor" | ||
| d="M12 2A10 10 0 0 0 2 12c0 4.42 2.87 8.17 6.84 9.5c.5.08.66-.23.66-.5v-1.69c-2.77.6-3.36-1.34-3.36-1.34c-.46-1.16-1.11-1.47-1.11-1.47c-.91-.62.07-.6.07-.6c1 .07 1.53 1.03 1.53 1.03c.87 1.52 2.34 1.07 2.91.83c.09-.65.35-1.09.63-1.34c-2.22-.25-4.55-1.11-4.55-4.92c0-1.11.38-2 1.03-2.71c-.1-.25-.45-1.29.1-2.64c0 0 .84-.27 2.75 1.02c.79-.22 1.65-.33 2.5-.33s1.71.11 2.5.33c1.91-1.29 2.75-1.02 2.75-1.02c.55 1.35.2 2.39.1 2.64c.65.71 1.03 1.6 1.03 2.71c0 3.82-2.34 4.66-4.57 4.91c.36.31.69.92.69 1.85V21c0 .27.16.59.67.5C19.14 20.16 22 16.42 22 12A10 10 0 0 0 12 2" | ||
| ></path> | ||
| </svg> | ||
| ); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| 'use client'; | ||
| import { type ButtonHTMLAttributes, type HTMLAttributes } from 'react'; | ||
| import { useI18n } from 'fumadocs-ui/contexts/i18n'; | ||
| import { | ||
| Popover, | ||
| PopoverContent, | ||
| PopoverTrigger, | ||
| } from './ui/popover'; | ||
| import { cn } from '../lib/cn'; | ||
| import { buttonVariants } from './ui/button'; | ||
|
|
||
| export type LanguageSelectProps = ButtonHTMLAttributes<HTMLButtonElement>; | ||
|
|
||
| export function LanguageToggle(props: LanguageSelectProps): React.ReactElement { | ||
| const context = useI18n(); | ||
| if (!context.locales) throw new Error('Missing `<I18nProvider />`'); | ||
|
|
||
| return ( | ||
| <Popover> | ||
| <PopoverTrigger | ||
| aria-label={context.text.chooseLanguage} | ||
| {...props} | ||
| className={cn( | ||
| buttonVariants({ | ||
| color: 'ghost', | ||
| className: 'gap-1.5 p-1.5', | ||
| }), | ||
| props.className, | ||
| )} | ||
| > | ||
| {props.children} | ||
| </PopoverTrigger> | ||
| <PopoverContent className="flex flex-col overflow-hidden p-0"> | ||
| <p className="mb-1 p-2 text-xs font-medium text-fd-muted-foreground"> | ||
| {context.text.chooseLanguage} | ||
| </p> | ||
| {context.locales.map((item) => ( | ||
| <button | ||
| key={item.locale} | ||
| type="button" | ||
| className={cn( | ||
| 'p-2 text-start text-sm', | ||
| item.locale === context.locale | ||
| ? 'bg-fd-primary/10 font-medium text-fd-primary' | ||
| : 'hover:bg-fd-accent hover:text-fd-accent-foreground', | ||
| )} | ||
| onClick={() => { | ||
| context.onChange?.(item.locale); | ||
| }} | ||
| > | ||
| {item.name} | ||
| </button> | ||
| ))} | ||
| </PopoverContent> | ||
| </Popover> | ||
| ); | ||
| } | ||
|
|
||
| export function LanguageToggleText( | ||
| props: HTMLAttributes<HTMLSpanElement>, | ||
| ): React.ReactElement { | ||
| const context = useI18n(); | ||
| const text = context.locales?.find( | ||
| (item) => item.locale === context.locale, | ||
| )?.name; | ||
|
|
||
| return <span {...props}>{text}</span>; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,81 @@ | ||
| 'use client'; | ||
|
|
||
| import { Sidebar as SidebarIcon } from 'lucide-react'; | ||
| import { type ComponentProps } from 'react'; | ||
| import { cn } from '../../../lib/cn'; | ||
| import { buttonVariants } from '../../ui/button'; | ||
| import { useSidebar } from 'fumadocs-ui/contexts/sidebar'; | ||
| import { useNav } from 'fumadocs-ui/contexts/layout'; | ||
| import { SidebarCollapseTrigger } from '../../sidebar'; | ||
| import { SearchToggle } from '../../search-toggle'; | ||
|
|
||
| export function Navbar(props: ComponentProps<'header'>) { | ||
| const { isTransparent } = useNav(); | ||
|
|
||
| return ( | ||
| <header | ||
| id="nd-subnav" | ||
| {...props} | ||
| className={cn( | ||
| 'fixed top-(--fd-banner-height) left-0 right-(--removed-body-scroll-bar-size,0) z-30 flex items-center ps-4 pe-2.5 border-b transition-colors backdrop-blur-sm', | ||
| !isTransparent && 'bg-fd-background/80', | ||
| props.className, | ||
| )} | ||
| > | ||
| {props.children} | ||
| </header> | ||
| ); | ||
| } | ||
|
|
||
| export function LayoutBody(props: ComponentProps<'main'>) { | ||
| const { collapsed } = useSidebar(); | ||
|
|
||
| return ( | ||
| <main | ||
| id="nd-docs-layout" | ||
| {...props} | ||
| className={cn( | ||
| 'flex flex-1 flex-col pt-(--fd-nav-height) transition-[padding] fd-default-layout', | ||
| !collapsed && 'mx-(--fd-layout-offset)', | ||
| props.className, | ||
| )} | ||
| style={{ | ||
| ...props.style, | ||
| paddingInlineStart: collapsed | ||
| ? 'min(calc(100vw - var(--fd-page-width)), var(--fd-sidebar-width))' | ||
| : 'var(--fd-sidebar-width)', | ||
| }} | ||
| > | ||
| {props.children} | ||
| </main> | ||
| ); | ||
| } | ||
|
|
||
| export function CollapsibleControl() { | ||
| const { collapsed } = useSidebar(); | ||
|
|
||
| return ( | ||
| <div | ||
| className={cn( | ||
| 'fixed flex shadow-lg transition-opacity rounded-xl p-0.5 border bg-fd-muted text-fd-muted-foreground z-10 max-md:hidden xl:start-4 max-xl:end-4', | ||
| !collapsed && 'pointer-events-none opacity-0', | ||
| )} | ||
| style={{ | ||
| top: 'calc(var(--fd-banner-height) + var(--fd-tocnav-height) + var(--spacing) * 4)', | ||
| }} | ||
| > | ||
| <SidebarCollapseTrigger | ||
| className={cn( | ||
| buttonVariants({ | ||
| color: 'ghost', | ||
| size: 'icon-sm', | ||
| className: 'rounded-lg', | ||
| }), | ||
| )} | ||
| > | ||
| <SidebarIcon /> | ||
| </SidebarCollapseTrigger> | ||
| <SearchToggle className="rounded-lg" hideIfDisabled /> | ||
| </div> | ||
| ); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Restore cache key to hash the actual Bun lockfile.
Switching the cache key to
hashFiles('bun.lock')breaks cache busting because Bun still generatesbun.lockbby default, so the hash is now empty and the job falls back to a static key. That means dependency updates will keep reusing stale cache entries. Please keep hashingbun.lockb, or include both patterns if you’re intentionally migrating to the text lockfile.Apply this diff (or equivalent) to fix it:
📝 Committable suggestion
🤖 Prompt for AI Agents