-
Notifications
You must be signed in to change notification settings - Fork 1
template docs #74
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
template docs #74
Conversation
…uch as shadcn integration, improved component addition, and deprecation of the FileMaker Add-on Auth. Enhance layout configuration for better navigation in the home layout.
…for new projects and deprecating legacy Mantine templates. Enhance template documentation and layout configuration for improved navigation. Adjust template category handling in the UI for better organization and clarity.
…y and functionality. Update installation command to use dynamic CLI versioning and streamline template content display. Enhance error handling in tests for better resilience against undefined values.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
You have run out of free Bugbot PR reviews for this billing cycle. This will reset on October 11. To receive reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial. |
@proofkit/better-auth
@proofkit/cli
create-proofkit
@proofkit/fmdapi
@proofkit/typegen
@proofkit/webviewer
commit: |
WalkthroughAdds an in-repo DocsLayout and comprehensive docs UI (sidebar, TOC, page components), template registry pages and helpers, many CLI/v2 and Better-Auth docs updates, CLI version bump to 2.0.0-beta.3, docs CLI/templating wiring, and converts several InferZodPortals imports to type-only. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User
participant Browser
participant Next as Next.js (server)
participant TemplatesLib as apps/docs/src/lib/templates
participant TemplatesPage
participant DocsLayout
Browser->>Next: GET /docs/templates
Next->>TemplatesPage: render TemplatesPage()
TemplatesPage->>TemplatesLib: getAllTemplates(), getTemplatesByCategory()
TemplatesLib-->>TemplatesPage: templates[], byCategory
TemplatesPage->>DocsLayout: render TemplatesLayout with templates
DocsLayout-->>Browser: HTML for templates listing + sidebar
sequenceDiagram
autonumber
participant MDX as MDX page
participant CliCmd as CliCommand component
participant Managers as MANAGERS config
MDX->>CliCmd: render <CliCommand command="add better-auth" exec=true />
CliCmd->>Managers: read manager prefixes & execPrefix
alt exec = true
Managers-->>CliCmd: use execPrefix + execPackage
CliCmd-->>MDX: render e.g. "npx @proofkit/cli@beta add better-auth"
else
Managers-->>CliCmd: use manager prefix
CliCmd-->>MDX: render e.g. "npm add better-auth"
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~75 minutes Possibly related PRs
Suggested reviewers
Pre-merge checks and finishing touches❌ Failed checks (1 inconclusive)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests
📜 Recent review detailsConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
Comment |
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.
Actionable comments posted: 32
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
apps/docs/content/docs/cli/meta.json (1)
7-20: Missing CLI docs pages
The following nav entries reference MDX files that don’t exist:
- apps/docs/content/docs/cli/guides/adding-components.mdx
- apps/docs/content/docs/cli/guides/auth.mdx
- apps/docs/content/docs/cli/webviewer.mdx
Add or correct these files to prevent broken navigation.apps/docs/content/docs/better-auth/installation.mdx (1)
38-39: Grammar: clarify secrets wording.Apply this diff:
-Configure your database connection in your `auth.ts` file. Be sure to set these value secrets in your environment variables. +Configure your database connection in your `auth.ts` file. Be sure to set these values as secrets in your environment variables.
🧹 Nitpick comments (27)
apps/docs/src/app/docs/templates/category-config.ts (1)
7-11: Tighten icon typing to LucideIcon for better type safety.Use lucide’s exported type instead of
ComponentType<any>.Apply this diff:
-import type { ComponentType } from "react"; +import type { ComponentType } from "react"; +import type { LucideIcon } from "lucide-react"; @@ export interface CategoryConfig { category: Category; name: string; - icon: ComponentType<any>; + icon: LucideIcon; }apps/docs/src/components/theme-toggle.tsx (2)
5-5: Prefer useEffect to avoid SSR warnings with useLayoutEffect.This component runs on the client, but React/Next can still warn about useLayoutEffect during SSR. useEffect is sufficient here.
Apply this diff:
-import { type HTMLAttributes, useLayoutEffect, useState } from 'react'; +import { type HTMLAttributes, useEffect, useState } from 'react'; @@ - useLayoutEffect(() => { + useEffect(() => { setMounted(true); }, []);Also applies to: 36-39
49-55: Small a11y/UX tweaks: button type and pressed state.
- Explicitly set type="button" to avoid accidental form submits.
- Expose pressed state for the 3‑option toggle via aria-pressed.
Apply this diff:
<button className={container} aria-label={`Toggle Theme`} + type="button" onClick={() => setTheme(value === 'light' ? 'dark' : 'light')} data-theme-toggle="" {...props} >- {full.map(([key, Icon]) => ( + {full.map(([key, Icon]) => ( <button key={key} aria-label={key} className={cn(itemVariants({ active: value === key }))} + type="button" + aria-pressed={value === key} onClick={() => setTheme(key)} > <Icon className="size-full" fill="currentColor" /> </button> ))}Also applies to: 74-85
apps/docs/src/components/layout/page.tsx (1)
79-82: Prop type/docs mismatch for disabling footer.Docs say “disable by passing false”, but
footertype does not allowfalseand the render path assumes an object. Supportfalseand guard accordingly.Apply this diff:
-export interface DocsPageProps { +export interface DocsPageProps { @@ - /** - * Footer navigation, you can disable it by passing `false` - */ - footer?: Partial<FooterOptions>; + /** + * Footer navigation, you can disable it by passing `false` + */ + footer?: Partial<FooterOptions> | false;- {footer.enabled !== false && - (footer.component ?? <PageFooter items={footer.items} />)} + {footer !== false && + (footer.enabled !== false) && + (footer.component ?? <PageFooter items={footer.items} />)}Also applies to: 189-191
apps/docs/cli.json (1)
1-11: Consider adding a JSON Schema for editor validation.If your CLI provides a schema, add a $schema field so editors can validate keys/paths and provide intellisense. Example key (replace with your actual schema URL/path):
{ + "$schema": "<path-or-url-to-docs-cli.schema.json>", "aliases": { "uiDir": "./components/ui", "componentsDir": "./components", "blockDir": "./components", "cssDir": "./styles", "libDir": "./lib" }, "baseDir": "src", "commands": {} }apps/docs/src/components/redirect.tsx (1)
7-14: Client redirect is fine; add a small guard and a11y hint.Avoid no‑op replaces and expose loading state for AT users.
-import { useRouter } from "next/navigation"; +import { usePathname, useRouter } from "next/navigation"; import { Skeleton } from "./ui/skeleton"; export default function Redirect({ href }: { href: string }) { const router = useRouter(); + const pathname = usePathname(); useEffect(() => { - router.replace(href); - }, [href, router]); + if (pathname !== href) router.replace(href); + }, [href, pathname, router]); - return <Skeleton className="h-8 w-full" />; + return ( + <div role="status" aria-busy="true"> + <Skeleton className="h-8 w-full" /> + </div> + ); }apps/docs/content/docs/cli/guides/adding-components/templates.mdx (1)
1-10: Provide a no‑JS fallback link.Helpful for crawlers and users with JS disabled.
# ProofKit Templates <Redirect href="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/docs/templates" /> +<noscript> + <p> + <a href="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/docs/templates">Continue to Templates</a> + </p> +</noscript>apps/docs/src/app/docs/templates/page.tsx (1)
1-16: Avoid duplicate work: don’t fetch all templates twice.getTemplatesByCategory already calls getAllTemplates; the Promise.all here doubles the IO. Compute categories from the single list instead.
-import { getAllTemplates, getTemplatesByCategory } from "@/lib/templates"; +import { getAllTemplates } from "@/lib/templates"; @@ -export default async function TemplatesPage() { - const [templates, templatesByCategory] = await Promise.all([ - getAllTemplates(), - getTemplatesByCategory(), - ]); +export default async function TemplatesPage() { + const templates = await getAllTemplates(); + const templatesByCategory = groupTemplatesByCategory(templates);Add this helper in the same file (or export it from your templates lib):
function groupTemplatesByCategory<T extends { category: string; title: string }>( templates: T[], ): Record<string, T[]> { const grouped = templates.reduce((acc, t) => { (acc[t.category] ||= []).push(t); return acc; }, {} as Record<string, T[]>); Object.values(grouped).forEach((arr) => arr.sort((a, b) => a.title.localeCompare(b.title))); return grouped; }apps/docs/src/lib/is-active.ts (1)
19-23: Optional: guard against unnormalized tab.urls sources.If upstream SidebarTab.urls isn’t guaranteed normalized, consider checking both normalized and raw pathname to be defensive.
Apply this diff:
export function isTabActive(tab: SidebarTab, pathname: string) { - if (tab.urls) return tab.urls.has(normalize(pathname)); + if (tab.urls) { + const p = normalize(pathname); + return tab.urls.has(p) || tab.urls.has(pathname); + } return isActive(tab.url, pathname, true); }apps/docs/src/components/language-toggle.tsx (1)
37-54: UX: close popover after selecting a language.Keeps the menu open after selection. Close it for a smoother experience.
Apply this diff:
-export function LanguageToggle(props: LanguageSelectProps): React.ReactElement { +export function LanguageToggle(props: LanguageSelectProps): React.ReactElement { const context = useI18n(); if (!context.locales) throw new Error('Missing `<I18nProvider />`'); - return ( - <Popover> + const [open, setOpen] = React.useState(false); + return ( + <Popover open={open} onOpenChange={setOpen}> ... - {context.locales.map((item) => ( + {context.locales.map((item) => ( <button key={item.locale} type="button" ... - onClick={() => { + onClick={() => { context.onChange?.(item.locale); + setOpen(false); }} >apps/docs/src/components/ui/button.tsx (1)
11-26: Optional: set defaultVariants for consistency.Helps avoid missing size/variant when consumers forget to pass them.
Apply this diff:
export const buttonVariants = cva( 'inline-flex items-center justify-center rounded-md p-2 text-sm font-medium transition-colors duration-100 disabled:pointer-events-none disabled:opacity-50 focus-visible:outline-none', { variants: { variant: variants, // fumadocs use `color` instead of `variant` color: variants, size: { sm: 'gap-1 px-2 py-1.5 text-xs', icon: 'p-1.5 [&_svg]:size-5', - 'icon-sm': 'p-1.5 [&_svg]:size-4.5', + 'icon-sm': 'p-1.5 [&_svg]:size-[18px]', 'icon-xs': 'p-1 [&_svg]:size-4', }, }, + defaultVariants: { + size: 'sm', + color: 'ghost', + }, }, );apps/docs/src/components/root-toggle.tsx (2)
28-31: Avoid findLast for broader browser support.findLast is ES2023; replace with a backward-compatible loop to prevent unexpected client errors.
Apply this diff:
- const selected = useMemo(() => { - return options.findLast((item) => isTabActive(item, pathname)); - }, [options, pathname]); + const selected = useMemo(() => { + for (let i = options.length - 1; i >= 0; i--) { + if (isTabActive(options[i], pathname)) return options[i]; + } + return undefined; + }, [options, pathname]);
68-70: Return null explicitly from map when skipping items.Returning undefined is fine, but null is clearer and silences some linters.
Apply this diff:
- if (!isActive && item.unlisted) return; + if (!isActive && item.unlisted) return null;apps/docs/src/components/ui/toc-clerk.tsx (2)
83-93: Add WebKit mask fallback for Safari compatibility.CSS
mask-imagelacks support in some Safari versions without the-webkit-prefixed property.Apply this diff:
style={{ width: svg.width, height: svg.height, - maskImage: `url("data:image/svg+xml,${ + maskImage: `url("data:image/svg+xml,${ // Inline SVG encodeURIComponent( `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${svg.width} ${svg.height}"><path d="${svg.path}" stroke="black" stroke-width="1" fill="none" /></svg>`, ) }")`, + WebkitMaskImage: `url("data:image/svg+xml,${ + encodeURIComponent( + `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${svg.width} ${svg.height}"><path d="${svg.path}" stroke="black" stroke-width="1" fill="none" /></svg>`, + ) + }")`, }}
79-101: Avoid rendering overlay when the SVG path is empty.If no anchors match yet,
svgexists butsvg.pathmay be empty, causing an unnecessary overlay render.Apply this diff:
- {svg ? ( + {svg?.path ? ( <divapps/docs/src/components/search-toggle.tsx (2)
21-43: Disable the button when search is unavailable.Render the control but set it disabled for better accessibility instead of only hiding it via
hideIfDisabled.Apply this diff:
- if (hideIfDisabled && !enabled) return null; + if (hideIfDisabled && !enabled) return null; @@ <button type="button" + disabled={!enabled} + aria-disabled={!enabled || undefined} className={cn(
51-78: Add disabled state to LargeSearchToggle.Improve semantics and UX when search isn’t enabled.
Apply this diff:
- if (hideIfDisabled && !enabled) return null; + if (hideIfDisabled && !enabled) return null; @@ <button type="button" data-search-full="" + disabled={!enabled} + aria-disabled={!enabled || undefined} {...props}apps/docs/src/lib/templates.ts (1)
4-10: Align category type with registry types to avoid drift.Hard-coding the union risks breakage if categories expand. Reuse the registry’s type.
Apply this diff:
-import { getRegistryIndex } from "@proofkit/registry"; +import { getRegistryIndex } from "@proofkit/registry"; +import type { TemplateMetadata } from "@proofkit/registry"; @@ export interface TemplateWithPath { name: string; title: string; description?: string; - category: "component" | "page" | "utility" | "hook" | "email"; + category: TemplateMetadata["category"]; path: string; }apps/docs/src/app/docs/templates/templates-client.tsx (1)
58-66: Small a11y wins: label the search and mark toggle state.
- Add an accessible label to the search input.
- Use aria-pressed on category filter buttons to expose state.
Apply this diff:
<input type="text" placeholder="Search templates..." value={searchQuery} onChange={(e) => setSearchQuery(e.target.value)} + aria-label="Search templates" className="w-full pl-10 pr-4 py-2 border border-border rounded-lg bg-background focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent" /> <button onClick={() => setSelectedCategory(null)} + aria-pressed={selectedCategory === null} className={`px-3 py-1.5 rounded-full text-sm transition-colors ${ selectedCategory === null ? "bg-primary text-primary-foreground" : "bg-secondary text-secondary-foreground hover:bg-secondary/80" }`} > <button key={category} onClick={() => setSelectedCategory(category)} + aria-pressed={selectedCategory === category} className={`flex items-center gap-1.5 px-3 py-1.5 rounded-full text-sm transition-colors ${ selectedCategory === category ? "bg-primary text-primary-foreground" : "bg-secondary text-secondary-foreground hover:bg-secondary/80" }`} >Also applies to: 71-80, 85-96
apps/docs/src/app/docs/templates/[...slug]/page.tsx (1)
58-62: Removeanycasts in category config usage.
template.categoryalready matches the union; noanyneeded.Apply this diff:
- const CategoryIcon = getCategoryConfig( - template.category as any, - ).icon; + const CategoryIcon = getCategoryConfig(template.category).icon;- {getCategoryConfig(template.category as any).name} + {getCategoryConfig(template.category).name}Also applies to: 75-77
apps/docs/src/components/ui/popover.tsx (1)
10-13: Optional: prefer ElementRef typing for forwardRef.Use ElementRef/ComponentPropsWithoutRef for Radix refs for clarity and consistency.
Apply this diff:
-const PopoverContent = React.forwardRef< - React.ComponentRef<typeof PopoverPrimitive.Content>, - React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content> +const PopoverContent = React.forwardRef< + React.ElementRef<typeof PopoverPrimitive.Content>, + React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content> >apps/docs/src/components/layout/docs/index.tsx (1)
134-143: Use stable keys for mapped lists to reduce unnecessary re‑mounts.Prefer semantic keys over array indexes for React lists.
Apply these diffs:
- {links - .filter((v) => v.type !== "icon") - .map((item, i, list) => ( - <SidebarLinkItem - key={i} - item={item} - className={cn(i === list.length - 1 && "mb-4")} - /> - ))} + {links + .filter((v) => v.type !== "icon") + .map((item, i, list) => { + const key = + 'url' in item && item.url ? item.url : `${item.type}-${i}`; + return ( + <SidebarLinkItem + key={key} + item={item} + className={cn(i === list.length - 1 && "mb-4")} + /> + ); + })}- {iconLinks.map((item, i) => ( + {iconLinks.map((item) => ( <BaseLinkItem - key={i} + key={item.url} item={item} className={cn( buttonVariants({ size: "icon-sm", color: "ghost", className: "p-2", }), )} aria-label={item.label} > {item.icon} </BaseLinkItem> ))}- {iconLinks.map((item, i) => ( + {iconLinks.map((item) => ( <BaseLinkItem - key={i} + key={item.url} item={item} className={cn( buttonVariants({ size: "icon-sm", color: "ghost" }), )} aria-label={item.label} > {item.icon} </BaseLinkItem> ))}Also applies to: 152-167, 240-251
apps/docs/src/components/layout/docs/page-client.tsx (2)
284-287: Only write to listCache when needed.Small micro‑opt: avoid redundant Map writes when a cached list exists.
- const cached = listCache.get(root.$id); - const list = cached ?? scanNavigationList(root.children); - listCache.set(root.$id, list); + let list = listCache.get(root.$id); + if (!list) { + list = scanNavigationList(root.children); + listCache.set(root.$id, list); + }
169-182: Outside‑click handler timing nit.Consider listening on 'pointerdown' instead of 'click' for a snappier close on outside interaction, especially when interactive elements inside the popover can re-focus before the window click fires.
apps/docs/src/components/sidebar.tsx (3)
408-423: Expose toggle state via ARIA on SidebarTrigger.Improve a11y by reflecting the open state.
export function SidebarTrigger({ children, ...props }: ComponentProps<'button'>) { - const { setOpen } = useSidebar(); + const { open, setOpen } = useSidebar(); return ( <button {...props} - aria-label="Open Sidebar" + aria-label="Toggle Sidebar" + aria-expanded={open} + aria-pressed={open} onClick={() => setOpen((prev) => !prev)} > {children} </button> ); }
425-441: Reflect collapsed state via ARIA on SidebarCollapseTrigger.Expose toggle semantics to assistive tech.
export function SidebarCollapseTrigger(props: ComponentProps<'button'>) { const { collapsed, setCollapsed } = useSidebar(); return ( <button type="button" aria-label="Collapse Sidebar" + aria-pressed={collapsed} data-collapsed={collapsed} {...props} onClick={() => { setCollapsed((prev) => !prev); }} > {props.children} </button> ); }
474-522: Key stability for separators/folders (optional).Using array indexes as keys can cause unnecessary re‑mounts on reordering. If feasible, derive stable keys (e.g., from item.name + level), keeping the current url key for pages.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (62)
.changeset/quick-ends-drop.md(1 hunks).changeset/ui-default-shadcn.md(1 hunks)apps/docs/cli.json(1 hunks)apps/docs/content/docs/better-auth/installation.mdx(2 hunks)apps/docs/content/docs/cli/guides/adding-components/index.mdx(1 hunks)apps/docs/content/docs/cli/guides/adding-components/meta.json(1 hunks)apps/docs/content/docs/cli/guides/adding-components/templates.mdx(1 hunks)apps/docs/content/docs/cli/guides/auth/add-on.mdx(1 hunks)apps/docs/content/docs/cli/guides/motivation.mdx(3 hunks)apps/docs/content/docs/cli/index.mdx(1 hunks)apps/docs/content/docs/cli/meta.json(1 hunks)apps/docs/content/docs/cli/registry/index.mdx(1 hunks)apps/docs/content/docs/cli/v2.mdx(1 hunks)apps/docs/content/docs/index.mdx(1 hunks)apps/docs/content/docs/meta.json(1 hunks)apps/docs/content/docs/templates/index.mdx(1 hunks)apps/docs/content/docs/templates/meta.json(1 hunks)apps/docs/next.config.ts(2 hunks)apps/docs/package.json(1 hunks)apps/docs/src/app/(home)/layout.tsx(1 hunks)apps/docs/src/app/docs/(docs)/layout.tsx(1 hunks)apps/docs/src/app/docs/templates/[...slug]/page.tsx(1 hunks)apps/docs/src/app/docs/templates/category-config.ts(1 hunks)apps/docs/src/app/docs/templates/layout.tsx(1 hunks)apps/docs/src/app/docs/templates/page.tsx(1 hunks)apps/docs/src/app/docs/templates/templates-client.tsx(1 hunks)apps/docs/src/app/layout.config.tsx(2 hunks)apps/docs/src/components/CliCommand.tsx(2 hunks)apps/docs/src/components/InitCommand.tsx(1 hunks)apps/docs/src/components/language-toggle.tsx(1 hunks)apps/docs/src/components/layout/docs/client.tsx(1 hunks)apps/docs/src/components/layout/docs/index.tsx(1 hunks)apps/docs/src/components/layout/docs/page-client.tsx(1 hunks)apps/docs/src/components/layout/docs/page.tsx(1 hunks)apps/docs/src/components/layout/page.tsx(1 hunks)apps/docs/src/components/layout/shared/client.tsx(1 hunks)apps/docs/src/components/layout/shared/index.tsx(1 hunks)apps/docs/src/components/redirect.tsx(1 hunks)apps/docs/src/components/root-toggle.tsx(1 hunks)apps/docs/src/components/search-toggle.tsx(1 hunks)apps/docs/src/components/sidebar.tsx(1 hunks)apps/docs/src/components/theme-toggle.tsx(1 hunks)apps/docs/src/components/ui/button.tsx(1 hunks)apps/docs/src/components/ui/collapsible.tsx(1 hunks)apps/docs/src/components/ui/popover.tsx(1 hunks)apps/docs/src/components/ui/scroll-area.tsx(1 hunks)apps/docs/src/components/ui/skeleton.tsx(1 hunks)apps/docs/src/components/ui/toc-clerk.tsx(1 hunks)apps/docs/src/components/ui/toc-thumb.tsx(1 hunks)apps/docs/src/components/ui/toc.tsx(1 hunks)apps/docs/src/lib/constants.ts(1 hunks)apps/docs/src/lib/is-active.ts(1 hunks)apps/docs/src/lib/merge-refs.ts(1 hunks)apps/docs/src/lib/templates.ts(1 hunks)packages/cli/package.json(1 hunks)packages/cli/template/nextjs-shadcn/package.json(1 hunks)packages/fmdapi/tests/client-methods.test.ts(4 hunks)packages/fmdapi/tests/tsconfig.json(1 hunks)packages/typegen/src/buildSchema.ts(2 hunks)packages/typegen/tests/__snapshots__/strict-numbers.snap.ts(1 hunks)packages/typegen/tests/__snapshots__/zod-layout-client.snap.ts(1 hunks)packages/typegen/tests/__snapshots__/zod-layout-overrides.snap.ts(1 hunks)
👮 Files not reviewed due to content moderation or server errors (4)
- .changeset/quick-ends-drop.md
- packages/typegen/tests/snapshots/zod-layout-overrides.snap.ts
- packages/typegen/tests/snapshots/zod-layout-client.snap.ts
- packages/typegen/tests/snapshots/strict-numbers.snap.ts
🧰 Additional context used
🧬 Code graph analysis (23)
apps/docs/src/components/InitCommand.tsx (1)
apps/docs/src/lib/constants.ts (1)
cliVersion(2-2)
apps/docs/src/app/docs/templates/templates-client.tsx (2)
apps/docs/src/lib/templates.ts (1)
TemplateWithPath(4-10)apps/docs/src/app/docs/templates/category-config.ts (2)
categoryConfigs(13-39)getCategoryConfig(51-53)
apps/docs/src/components/layout/shared/index.tsx (1)
apps/docs/src/components/layout/docs/index.tsx (1)
LinkItemType(368-368)
apps/docs/src/app/docs/templates/page.tsx (2)
apps/docs/src/lib/templates.ts (2)
getAllTemplates(28-41)getTemplatesByCategory(46-69)apps/docs/src/app/docs/templates/templates-client.tsx (1)
TemplatesPageClient(14-194)
apps/docs/src/components/layout/page.tsx (3)
apps/docs/src/components/layout/docs/page-client.tsx (9)
BreadcrumbProps(340-340)FooterProps(244-252)PageTOCPopover(163-219)PageTOCPopoverTrigger(39-91)PageTOCPopoverContent(151-161)PageBreadcrumb(342-392)PageLastUpdate(221-241)PageFooter(277-310)PageTOC(394-417)apps/docs/src/components/layout/docs/page.tsx (14)
BreadcrumbProps(102-102)FooterProps(101-101)PageRoot(75-91)PageTOCPopover(98-98)PageTOCPopoverTrigger(99-99)PageTOCPopoverContent(100-100)PageTOCPopoverItems(46-55)PageArticle(57-69)PageBreadcrumb(94-94)PageLastUpdate(96-96)PageFooter(95-95)PageTOC(97-97)PageTOCTitle(20-33)PageTOCItems(35-44)apps/docs/src/components/ui/button.tsx (1)
buttonVariants(11-26)
apps/docs/src/components/layout/shared/client.tsx (2)
apps/docs/src/components/layout/shared/index.tsx (1)
BaseLinkType(72-81)apps/docs/src/lib/is-active.ts (1)
isActive(8-17)
apps/docs/src/components/layout/docs/index.tsx (9)
apps/docs/src/components/layout/shared/index.tsx (5)
BaseLayoutProps(20-61)getLinks(156-180)IconItemType(90-102)BaseLinkItem(182-182)LinkItemType(146-151)apps/docs/src/components/sidebar.tsx (15)
SidebarProps(37-62)SidebarComponents(457-461)SidebarViewport(237-254)SidebarPageTree(466-523)SidebarContentMobile(178-213)SidebarHeader(215-224)SidebarFooter(226-235)SidebarContent(111-176)SidebarCollapseTrigger(425-441)Sidebar(89-109)SidebarFolder(294-315)SidebarFolderLink(337-370)SidebarFolderTrigger(317-335)SidebarFolderContent(372-406)SidebarItem(270-292)apps/docs/src/components/root-toggle.tsx (2)
Option(12-14)RootToggle(16-103)apps/docs/src/components/layout/shared/client.tsx (1)
BaseLinkItem(8-30)apps/docs/src/components/ui/button.tsx (1)
buttonVariants(11-26)apps/docs/src/components/language-toggle.tsx (2)
LanguageToggle(14-57)LanguageToggleText(59-68)apps/docs/src/components/theme-toggle.tsx (1)
ThemeToggle(26-87)apps/docs/src/components/search-toggle.tsx (2)
LargeSearchToggle(45-79)SearchToggle(15-43)apps/docs/src/components/layout/docs/client.tsx (3)
CollapsibleControl(54-81)Navbar(12-28)LayoutBody(30-52)
apps/docs/src/app/(home)/layout.tsx (1)
apps/docs/src/app/layout.config.tsx (1)
baseOptions(10-41)
apps/docs/src/components/ui/toc-clerk.tsx (3)
apps/docs/src/components/ui/toc.tsx (1)
useTOCItems(12-14)apps/docs/src/components/ui/toc-thumb.tsx (1)
TocThumb(38-73)apps/docs/src/lib/merge-refs.ts (1)
mergeRefs(3-15)
apps/docs/src/components/layout/docs/client.tsx (3)
apps/docs/src/components/sidebar.tsx (1)
SidebarCollapseTrigger(425-441)apps/docs/src/components/ui/button.tsx (1)
buttonVariants(11-26)apps/docs/src/components/search-toggle.tsx (1)
SearchToggle(15-43)
apps/docs/src/components/sidebar.tsx (1)
apps/docs/src/lib/is-active.ts (1)
isActive(8-17)
apps/docs/src/components/layout/docs/page.tsx (2)
apps/docs/src/components/ui/toc.tsx (3)
TOCScrollArea(30-51)TOCItems(53-85)TOCProvider(16-28)apps/docs/src/components/ui/toc-clerk.tsx (1)
ClerkTOCItems(11-117)
apps/docs/src/app/docs/templates/[...slug]/page.tsx (3)
apps/docs/src/lib/templates.ts (2)
getAllTemplates(28-41)getTemplateByName(74-79)apps/docs/src/app/docs/templates/category-config.ts (1)
getCategoryConfig(51-53)apps/docs/src/components/CliCommand.tsx (1)
CliCommand(33-59)
apps/docs/src/components/search-toggle.tsx (1)
apps/docs/src/components/ui/button.tsx (2)
ButtonProps(28-28)buttonVariants(11-26)
apps/docs/src/lib/templates.ts (1)
packages/registry/lib/utils.ts (1)
getRegistryIndex(72-87)
apps/docs/src/app/docs/templates/category-config.ts (1)
packages/registry/lib/types.ts (1)
TemplateMetadata(179-179)
apps/docs/src/components/root-toggle.tsx (1)
apps/docs/src/lib/is-active.ts (2)
isTabActive(19-23)isActive(8-17)
apps/docs/src/app/layout.config.tsx (1)
apps/docs/src/components/layout/shared/index.tsx (1)
BaseLayoutProps(20-61)
apps/docs/src/components/language-toggle.tsx (1)
apps/docs/src/components/ui/button.tsx (1)
buttonVariants(11-26)
apps/docs/src/components/CliCommand.tsx (1)
apps/docs/src/lib/constants.ts (1)
cliVersion(2-2)
apps/docs/src/app/docs/templates/layout.tsx (4)
packages/registry/lib/types.ts (1)
TemplateMetadata(179-179)apps/docs/src/lib/templates.ts (1)
getTemplatesByCategory(46-69)apps/docs/src/app/docs/templates/category-config.ts (1)
categoryConfigs(13-39)apps/docs/src/lib/source.ts (1)
source(9-49)
apps/docs/src/components/ui/toc.tsx (2)
apps/docs/src/lib/merge-refs.ts (1)
mergeRefs(3-15)apps/docs/src/components/ui/toc-thumb.tsx (1)
TocThumb(38-73)
apps/docs/src/components/layout/docs/page-client.tsx (3)
apps/docs/src/components/ui/toc.tsx (1)
useTOCItems(12-14)apps/docs/src/components/ui/collapsible.tsx (3)
CollapsibleTrigger(39-39)CollapsibleContent(39-39)Collapsible(39-39)apps/docs/src/lib/is-active.ts (1)
isActive(8-17)
🪛 Biome (2.1.2)
apps/docs/src/app/docs/templates/layout.tsx
[error] 90-91: Avoid using target="_blank" without rel="noopener" or rel="noreferrer".
Opening external links in new tabs without rel="noopener" is a security risk. See the explanation for more details.
Safe fix: Add the rel="noopener" attribute.
(lint/security/noBlankTarget)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build
🔇 Additional comments (34)
packages/typegen/src/buildSchema.ts (2)
35-39: Type-only import is the right fixMarking
InferZodPortalsas type-only avoids pulling the runtime module into generated bundles and lines up with how the alias is used later. No further action needed.
350-354: Consistent type-only import here as wellSame as above—keeping this import type-only matches its usage and prevents unnecessary runtime dependencies. Looks good.
packages/fmdapi/tests/tsconfig.json (1)
6-8: ExplicitrootDiravoids TS6059 when importing package sourcesPointing the tests’ config at the package root keeps TypeScript from flagging cross-folder imports and aligns with the parent config. Good addition.
.changeset/ui-default-shadcn.md (1)
5-9: Confirm docs URL and flag/setting availability.
- Verify the docs domain (proofkit.com vs proofkit.dev) is correct and consistent across the repo.
- Ensure
init --ui mantineis actually implemented and thatproofkit.jsonpersistsuias documented.apps/docs/cli.json (1)
2-10: Confirm alias paths resolve as intended with baseDir.With baseDir set to "src", ensure the CLI combines these correctly (e.g., src/components vs ./components). If the CLI expects paths relative to baseDir, consider prefixing with "src/..." for clarity.
apps/docs/content/docs/meta.json (1)
2-3: LGTM: added Templates section to global docs nav.No issues spotted.
apps/docs/src/lib/constants.ts (1)
1-2: Pin docs CLI version or clarify tracking the beta tag
- Update to an explicit version and widen the type:
- // which version of the CLI to use in the docs - export const cliVersion: "latest" | "beta" = "beta"; + // Which version of the CLI to use in docs commands. + // Allow explicit versions in addition to dist-tags to avoid drift. + export type CliVersion = "latest" | "beta" | `${number}.${number}.${number}${string}`; + export const cliVersion: CliVersion = "2.0.0-beta.3";
- Or keep
"beta"and update the comment/tests to note that it tracks a moving dist-tag.Confirm which approach you’d like.
apps/docs/src/lib/is-active.ts (1)
8-17: LGTM: robust active-path check with safe trailing-slash handling.Equality plus prefix match with normalized paths is correct and avoids false positives like /docs vs /docsify.
apps/docs/src/components/ui/button.tsx (1)
19-23: Verify Tailwind class “size-4.5” exists.Tailwind doesn’t ship size-4.5 by default; if you’re not extending theme or using arbitrary values, this won’t compile.
Consider switching to arbitrary values for consistency:
- 'icon-sm': 'p-1.5 [&_svg]:size-4.5', + 'icon-sm': 'p-1.5 [&_svg]:size-[18px]',If you’ve extended the theme to include 4.5, disregard. Please confirm.
apps/docs/src/components/ui/collapsible.tsx (1)
20-33: LGTM: SSR-safe mount gating for animation classes.Delaying animation classes until after mount avoids hydration mismatches; re-exporting Radix parts keeps API familiar.
apps/docs/src/components/layout/docs/client.tsx (3)
12-28: Navbar structure LGTM.
30-52: Layout body spacing logic LGTM.
54-81: Collapsible control implementation LGTM.apps/docs/src/components/layout/docs/page.tsx (3)
20-33: TOC title and i18n wiring LGTM.
35-44: TOC items composition LGTM (relies on TOC forwardRef fix).After applying the TOC forwardRef fix, verify the TOC renders and the thumb updates on scroll.
Also applies to: 46-55
75-91: Conditional TOC provider in PageRoot LGTM.apps/docs/src/components/CliCommand.tsx (1)
6-13: No action needed for npm prefix. All<CliCommand>invocations setexec, soprefix: "npm run"is never applied.apps/docs/src/components/layout/docs/index.tsx (2)
169-174: Guard LanguageToggle against missing I18nProvider.LanguageToggle throws if I18nProvider/locales are absent. Ensure the layout is wrapped in the provider whenever i18n is truthy, or gate rendering on provider presence.
Do you confirm the I18nProvider is always mounted in contexts where i18n is enabled?
Also applies to: 235-239
277-323: Well-structured layout composition.Good separation of concerns (NavProvider, TreeContextProvider, sidebar assembly), sensible defaults, and safe conditional rendering.
apps/docs/src/components/layout/docs/page-client.tsx (1)
39-91: TOC trigger behavior looks solid.Active section detection, progress indicator, and CollapsibleTrigger wiring are coherent.
apps/docs/src/components/sidebar.tsx (1)
111-176: Desktop sidebar hover/collapse behavior LGTM.Good handling of hover timers, touch pointers, and CSS variables for smooth transitions.
packages/cli/package.json (1)
3-3: Align CLI version with docsThe bump to 2.0.0-beta.3 matches the documentation and init-command updates in this stack, keeping releases consistent.
apps/docs/src/app/(home)/layout.tsx (1)
6-15: Docs link restored in home navigationPrepending the CLI docs link here cleanly restores that entry after slimming down
baseOptions.links, without touching other layouts.packages/cli/template/nextjs-shadcn/package.json (1)
18-34: Template dependencies updated coherentlyNext/React patch bumps plus the tooling updates keep the generated project aligned with the CLI’s latest baseline.
apps/docs/package.json (1)
16-42: Docs dependencies track the new UI stackAdding the Radix primitives, next-themes, and refreshed fumadocs versions lines up with the new layout and template browsing features.
apps/docs/content/docs/cli/guides/adding-components/meta.json (1)
1-6: Navigation metadata looks goodTitle, icon, and default expansion all line up with the new guide, so it should slot straight into the sidebar.
apps/docs/src/components/ui/skeleton.tsx (1)
1-8: New skeleton utility looks solidLightweight component, reusable slot attribute, and shared
cnhelper keep loading placeholders consistent.apps/docs/src/app/layout.config.tsx (1)
10-41:satisfieskeeps typing without extra noiseGood call switching to
satisfies; we retain compile-time coverage and stay flexible on the constant shape while trimming the docs link from the shared config.apps/docs/content/docs/templates/meta.json (1)
4-4: Confirm icon casingOther meta entries (e.g., the new “Adding Components” guide) use lowercase
"puzzle". Please double-check whether the icon registry expects lowercase—if so,"Puzzle"may render a fallback.Could you verify the expected casing for this icon in the docs UI before merging?
apps/docs/content/docs/cli/registry/index.mdx (1)
1-12: Registry overview addition looks solidContent is concise and matches the new templates flow.
apps/docs/content/docs/index.mdx (1)
34-36: Nice to see Better Auth listedGreat to surface the new library alongside the existing core packages.
apps/docs/content/docs/templates/index.mdx (1)
1-3: Front matter stub lands cleanlyLooks ready for the templates client to slot content in.
apps/docs/src/app/docs/(docs)/layout.tsx (1)
1-31: Import swap to local DocsLayout looks goodMoving to the in-repo layout keeps everything consistent with the new components.
apps/docs/src/components/InitCommand.tsx (1)
6-8: Dist-tag “beta” exists for create-proofkit —create-proofkit@betaresolves to v0.1.0-beta.1, so the docs commands are correct.
| #### [Shadcn/ui](https://ui.shadcn.com/) <Badge className="bg-blue-200 text-blue-700 dark:bg-blue-500 dark:text-blue-50 ">NEW</Badge> | ||
|
|
||
| A vast, themeable component library for React. We use their default components and styles to build apps very quickly, but with the option of adding custom styles or themes later if needed. Mantine also includes many helpful React hooks, and they provide a Modal and Notification system to ProofKit apps. | ||
| A themeable component library for React. We use their default components and styles to build apps very quickly, but with the option of adding custom styles or themes later if needed. Shadcn/ui also includes many helpful React hooks, and they provide a Modal and Notification system to ProofKit apps. | ||
|
|
||
| Why not tailwind css and/or shadcn/ui? We've chosen to focus on Mantine because it has allowed our team to work much faster for the kinds of web apps that we build for our clients. When you're working on multiple projects at once, it's actually a benefit to **not** own the component code within an individual codebase, so that it can be more easily upgraded when the time comes. However, we have not ruled out other components and style systems and may add support for them in the future. | ||
| Using the shadcn CLI, you can install any component or utility from any compatible library. This makes shadcn the best choice for the most flexible and customizable apps. Some of our favorite shadcn-compatible libraries are: | ||
| - [Kibu Ui](https://www.kibo-ui.com/) | ||
| - [reui](https://reui.io/) | ||
| - [Magic UI](https://magicui.design/) | ||
| - [tweakcn (easily theme your components)](https://tweakcn.com/) | ||
| - [A longer list of more...](https://github.com/birobirobiro/awesome-shadcn-ui) | ||
|
|
||
| #### [Tailwind CSS](https://tailwindcss.com/) <Badge className="bg-blue-200 text-blue-700 dark:bg-blue-500 dark:text-blue-50 ">NEW</Badge> |
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.
Typos/brand casing and a factual correction for TanStack Query.
- Use “shadcn/ui” casing; fix “Kibu Ui” → “Kibo UI”; “neccesary” → “necessary”.
- TanStack Query manages server state/caching; it doesn’t ensure data “shape” — that’s Zod.
Apply this diff:
-#### [Shadcn/ui](https://ui.shadcn.com/) <Badge className="bg-blue-200 text-blue-700 dark:bg-blue-500 dark:text-blue-50 ">NEW</Badge>
+#### [shadcn/ui](https://ui.shadcn.com/) <Badge className="bg-blue-200 text-blue-700 dark:bg-blue-500 dark:text-blue-50 ">NEW</Badge>
…
-Some of our favorite shadcn-compatible libraries are:
-- [Kibu Ui](https://www.kibo-ui.com/)
+Some of our favorite shadcn-compatible libraries are:
+- [Kibo UI](https://www.kibo-ui.com/)
- [reui](https://reui.io/)
- [Magic UI](https://magicui.design/)
- [tweakcn (easily theme your components)](https://tweakcn.com/)
- [A longer list of more...](https://github.com/birobirobiro/awesome-shadcn-ui)
…
-#### [Tanstack Query](https://tanstack.com/query)
+#### [TanStack Query](https://tanstack.com/query)
…
-Sometimes also known as "React Query"; a library for managing server state in React. It's used by ProofKit to fetch data from external sources, such as REST APIs, so we can be certain that the "shape" of our data matches what we expected during development.
+Sometimes also known as "React Query"; a library for managing server state in React. It's used by ProofKit for fetching, caching, deduping, background updates, and invalidation of server data.
…
-For when you need a bit more flexibility or if you want to self-host the authentication layer within your existing FileMaker solution. Better-auth is a great choice for this, and the [proofkit/better-auth](/docs/better-auth) adapter allows you to use FileMaker as your backend database, including automated schema migrations to easily add any neccesary tables and fields to your FileMaker file.
+For when you need a bit more flexibility or if you want to self-host the authentication layer within your existing FileMaker solution. Better-auth is a great choice for this, and the [proofkit/better-auth](/docs/better-auth) adapter allows you to use FileMaker as your backend database, including automated schema migrations to easily add any necessary tables and fields to your FileMaker file.Also applies to: 55-62, 73-76
🤖 Prompt for AI Agents
In apps/docs/content/docs/cli/guides/motivation.mdx around lines 40-51 (and also
apply the same fixes to lines 55-62 and 73-76), fix branding/casing typos and
one factual statement: change “shadcn/ui” to lowercase exactly as "shadcn/ui",
rename “Kibu Ui” to “Kibo UI”, correct “neccesary” to “necessary” wherever
present, and update the TanStack Query sentence to state that TanStack Query
manages server state/caching (not data shape) and attribute validation/ensuring
data shape to Zod (reword the sentence to reflect that distinction).
| 'use client'; | ||
| import type { TOCItemType } from 'fumadocs-core/server'; | ||
| import * as Primitive from 'fumadocs-core/toc'; | ||
| import { type ComponentProps, createContext, useContext, useRef } from 'react'; | ||
| import { cn } from '../../lib/cn'; | ||
| import { useI18n } from 'fumadocs-ui/contexts/i18n'; | ||
| import { TocThumb } from './toc-thumb'; | ||
| import { mergeRefs } from '../../lib/merge-refs'; | ||
|
|
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.
Forward refs correctly; ref isn’t a normal prop.
Destructuring ref from props on function components drops refs and can cause runtime warnings. Convert to forwardRef and merge properly.
Apply this diff:
-'use client';
-import type { TOCItemType } from 'fumadocs-core/server';
-import * as Primitive from 'fumadocs-core/toc';
-import { type ComponentProps, createContext, useContext, useRef } from 'react';
-import { cn } from '../../lib/cn';
-import { useI18n } from 'fumadocs-ui/contexts/i18n';
-import { TocThumb } from './toc-thumb';
-import { mergeRefs } from '../../lib/merge-refs';
+'use client';
+import type { TOCItemType } from 'fumadocs-core/server';
+import * as Primitive from 'fumadocs-core/toc';
+import { type ComponentProps, createContext, useContext, useRef, forwardRef } from 'react';
+import { cn } from '../../lib/cn';
+import { useI18n } from 'fumadocs-ui/contexts/i18n';
+import { TocThumb } from './toc-thumb';
+import { mergeRefs } from '../../lib/merge-refs';-export function TOCScrollArea({
- ref,
- className,
- ...props
-}: ComponentProps<'div'>) {
- const viewRef = useRef<HTMLDivElement>(null);
-
- return (
- <div
- ref={mergeRefs(viewRef, ref)}
- className={cn(
- 'relative min-h-0 text-sm ms-px overflow-auto [scrollbar-width:none] [mask-image:linear-gradient(to_bottom,transparent,white_16px,white_calc(100%-16px),transparent)] py-3',
- className,
- )}
- {...props}
- >
- <Primitive.ScrollProvider containerRef={viewRef}>
- {props.children}
- </Primitive.ScrollProvider>
- </div>
- );
-}
+export const TOCScrollArea = forwardRef<HTMLDivElement, ComponentProps<'div'>>(
+ ({ className, ...props }, ref) => {
+ const viewRef = useRef<HTMLDivElement>(null);
+ return (
+ <div
+ ref={mergeRefs(viewRef, ref)}
+ className={cn(
+ 'relative min-h-0 text-sm ms-px overflow-auto [scrollbar-width:none] [mask-image:linear-gradient(to_bottom,transparent,white_16px,white_calc(100%-16px),transparent)] py-3',
+ className,
+ )}
+ {...props}
+ >
+ <Primitive.ScrollProvider containerRef={viewRef}>
+ {props.children}
+ </Primitive.ScrollProvider>
+ </div>
+ );
+ },
+);-export function TOCItems({ ref, className, ...props }: ComponentProps<'div'>) {
- const containerRef = useRef<HTMLDivElement>(null);
- const items = useTOCItems();
- const { text } = useI18n();
+export const TOCItems = forwardRef<HTMLDivElement, ComponentProps<'div'>>(
+ ({ className, ...props }, ref) => {
+ const containerRef = useRef<HTMLDivElement>(null);
+ const items = useTOCItems();
+ const { text } = useI18n();
- if (items.length === 0)
- return (
- <div className="rounded-lg border bg-fd-card p-3 text-xs text-fd-muted-foreground">
- {text.tocNoHeadings}
- </div>
- );
+ if (items.length === 0)
+ return (
+ <div className="rounded-lg border bg-fd-card p-3 text-xs text-fd-muted-foreground">
+ {text.tocNoHeadings}
+ </div>
+ );
- return (
- <>
- <TocThumb
- containerRef={containerRef}
- className="absolute top-(--fd-top) h-(--fd-height) w-px bg-fd-primary transition-all"
- />
- <div
- ref={mergeRefs(ref, containerRef)}
- className={cn(
- 'flex flex-col border-s border-fd-foreground/10',
- className,
- )}
- {...props}
- >
- {items.map((item) => (
- <TOCItem key={item.url} item={item} />
- ))}
- </div>
- </>
- );
-}
+ return (
+ <>
+ <TocThumb
+ containerRef={containerRef}
+ className="absolute top-(--fd-top) h-(--fd-height) w-px bg-fd-primary transition-all"
+ />
+ <div
+ ref={mergeRefs(ref, containerRef)}
+ className={cn(
+ 'flex flex-col border-s border-fd-foreground/10',
+ className,
+ )}
+ {...props}
+ >
+ {items.map((item) => (
+ <TOCItem key={item.url} item={item} />
+ ))}
+ </div>
+ </>
+ );
+ },
+);Also applies to: 30-51, 53-85
🛠️ Refactor suggestion | 🟠 Major
🧩 Analysis chain
Follow-up: replicate the forwardRef fix in Clerk TOC.
ClerkTOCItems appears to destructure ref similarly. Please update it to use forwardRef too.
Run this to locate occurrences:
🏁 Script executed:
#!/bin/bash
rg -nP --type=tsx -C2 'function\s+\w+\s*\(\s*\{\s*ref\s*,' apps/docs/src/components | sed -n '1,200p'Length of output: 27
🏁 Script executed:
#!/bin/bash
# Locate the ClerkTOCItems component and its signature
rg -n 'ClerkTOCItems' -C3 -g '*.tsx'Length of output: 2249
🏁 Script executed:
#!/bin/bash
# Show ClerkTOCItems implementation
sed -n '1,40p' apps/docs/src/components/ui/toc-clerk.tsx
# Find forwardRef usage in TOCItems
rg -n 'forwardRef' -C3 -g '*.tsx' apps/docs/src/components/ui/toc.tsxLength of output: 1178
Wrap TOCItems and ClerkTOCItems in React.forwardRef
Destructuring ref in the props won’t attach it to the DOM—wrap both components in React.forwardRef and merge the forwarded ref with your internal useRef via mergeRefs.
Files:
• apps/docs/src/components/ui/toc.tsx
• apps/docs/src/components/ui/toc-clerk.tsx
🤖 Prompt for AI Agents
In apps/docs/src/components/ui/toc.tsx (lines 1-9) and
apps/docs/src/components/ui/toc-clerk.tsx, the TOCItem and ClerkTOCItem
components must be wrapped with React.forwardRef so the incoming ref is attached
to the DOM; change the components to accept (props, ref) in forwardRef, type the
ref appropriately, keep your internal useRef but merge it with the forwarded ref
using mergeRefs, and pass the merged ref to the root DOM element (e.g., the
container or list element); ensure props typing accommodates the forwarded ref
(use ComponentProps or appropriate HTML element ref type) and export the
forwardRef-wrapped component.
| return ( | ||
| <TOCContext value={toc}> | ||
| <Primitive.AnchorProvider toc={toc} {...props}> | ||
| {children} | ||
| </Primitive.AnchorProvider> | ||
| </TOCContext> | ||
| ); |
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.
Fix context provider usage.
Use TOCContext.Provider; current code won’t provide context.
Apply this diff:
- <TOCContext value={toc}>
+ <TOCContext.Provider value={toc}>
<Primitive.AnchorProvider toc={toc} {...props}>
{children}
</Primitive.AnchorProvider>
- </TOCContext>
+ </TOCContext.Provider>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| return ( | |
| <TOCContext value={toc}> | |
| <Primitive.AnchorProvider toc={toc} {...props}> | |
| {children} | |
| </Primitive.AnchorProvider> | |
| </TOCContext> | |
| ); | |
| return ( | |
| <TOCContext.Provider value={toc}> | |
| <Primitive.AnchorProvider toc={toc} {...props}> | |
| {children} | |
| </Primitive.AnchorProvider> | |
| </TOCContext.Provider> | |
| ); |
🤖 Prompt for AI Agents
In apps/docs/src/components/ui/toc.tsx around lines 21 to 27, the context
wrapper incorrectly uses TOCContext instead of TOCContext.Provider so the
context value is not actually provided; change the wrapper to use
TOCContext.Provider with the value={toc} prop (i.e., replace <TOCContext
value={toc}>…</TOCContext> with <TOCContext.Provider
value={toc}>…</TOCContext.Provider>) ensuring the children remain wrapped and
imports remain unchanged.
| refs.forEach((ref) => { | ||
| if (typeof ref === 'function') { | ||
| ref(value); | ||
| } else if (ref) { | ||
| ref.current = value; | ||
| } |
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.
Fix TypeScript readonly assignment on object refs
Assigning directly to ref.current fails type-checking because React.Ref<T> unions RefObject<T> (whose current is readonly) with MutableRefObject<T>. Under strict React typings this emits “Cannot assign to 'current' because it is a read-only property.” Wrap the assignment in a cast/narrowing to MutableRefObject<T | null> so the helper compiles.
- } else if (ref) {
- ref.current = value;
+ } else if (ref) {
+ (ref as React.MutableRefObject<T | null>).current = value;📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| refs.forEach((ref) => { | |
| if (typeof ref === 'function') { | |
| ref(value); | |
| } else if (ref) { | |
| ref.current = value; | |
| } | |
| refs.forEach((ref) => { | |
| if (typeof ref === 'function') { | |
| ref(value); | |
| } else if (ref) { | |
| (ref as React.MutableRefObject<T | null>).current = value; | |
| } |
🤖 Prompt for AI Agents
In apps/docs/src/lib/merge-refs.ts around lines 7 to 12, assigning directly to
ref.current fails under strict React typings because React.Ref<T> can be a
readonly RefObject; cast or narrow the ref to MutableRefObject<T | null> before
assignment (e.g. const mutable = ref as MutableRefObject<typeof value | null>;
mutable.current = value) so the compiler accepts the write, keeping the function
branch for function refs unchanged.
| function getTemplatesPath(): string { | ||
| if (process.env.NODE_ENV === "production") { | ||
| // In production, templates are bundled in the public directory | ||
| return path.join(process.cwd(), "public/registry-templates"); | ||
| } else { | ||
| // In development, read directly from registry package | ||
| return path.resolve(process.cwd(), "../../packages/registry/templates"); | ||
| } | ||
| } |
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.
🧩 Analysis chain
Verify templates path resolution across environments.
The dev path assumes a specific monorepo layout; production assumes a public copy. Ensure both exist in CI/build and at runtime, or fall back to getRegistryIndex() default path when missing.
Run this script to check for expected paths and sample contents:
If either path is absent, consider falling back to getRegistryIndex() with no override.
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "NODE_ENV=${NODE_ENV:-unset}"
echo "CWD=$(pwd)"
echo "--- Checking for production path (apps/docs/public/registry-templates) ---"
fd -t d -a 'registry-templates' 2>/dev/null || true
fd -t f -a 'meta.json' public/registry-templates 2>/dev/null || true
echo "--- Checking for registry templates in monorepo dev path ---"
fd -t d -a 'templates' 2>/dev/null | rg -n "/packages/registry/templates$" -n || true
fd -t f -a 'meta.json' packages/registry/templates 2>/dev/null || trueLength of output: 173
Ensure both production and development template paths exist or add a fallback
getTemplatesPath in apps/docs/src/lib/templates.ts references apps/docs/public/registry-templates and ../../packages/registry/templates, but neither directory (nor its meta.json) was found—add these assets or call getRegistryIndex() when the paths are missing.
🤖 Prompt for AI Agents
In apps/docs/src/lib/templates.ts around lines 15 to 23, getTemplatesPath()
returns hard-coded production and development directories but doesn’t verify
they exist or handle missing meta.json; update the function to check for the
presence of the resolved path and its meta.json and, if missing, either throw a
clear error or call getRegistryIndex() as a fallback to obtain templates
programmatically, ensuring any returned path is validated before use and logging
or propagating an explanatory error when neither disk path nor fallback is
available.
| const portalData = | ||
| data[0].portalData["long_and_strange.portalName#forTesting"]; | ||
| data[0]?.portalData["long_and_strange.portalName#forTesting"]; | ||
|
|
||
| expect(portalData.length).toBeGreaterThan(50); | ||
| expect(portalData?.length).toBeGreaterThan(50); | ||
| }); |
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.
Extend optional chaining through the bracket access
data[0]?.portalData["long_and_strange.portalName#forTesting"] still blows up when portalData is undefined because the optional chain stops before the bracket lookup. In the exact scenario this change is trying to guard against, the test will still throw a TypeError instead of failing the assertion. Please propagate the optional chaining to the bracket accessor.
- const portalData =
- data[0]?.portalData["long_and_strange.portalName#forTesting"];
+ const portalData =
+ data[0]?.portalData?.["long_and_strange.portalName#forTesting"];📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const portalData = | |
| data[0].portalData["long_and_strange.portalName#forTesting"]; | |
| data[0]?.portalData["long_and_strange.portalName#forTesting"]; | |
| expect(portalData.length).toBeGreaterThan(50); | |
| expect(portalData?.length).toBeGreaterThan(50); | |
| }); | |
| const portalData = | |
| data[0]?.portalData?.["long_and_strange.portalName#forTesting"]; | |
| expect(portalData?.length).toBeGreaterThan(50); | |
| }); |
🤖 Prompt for AI Agents
In packages/fmdapi/tests/client-methods.test.ts around lines 113 to 117, the
optional chaining stops before the bracket lookup so accessing portalData via
data[0]?.portalData["long_and_strange.portalName#forTesting"] will throw if
portalData is undefined; change the access to propagate optional chaining to the
bracket accessor (e.g.,
data[0]?.portalData?.["long_and_strange.portalName#forTesting"]) so portalData
can be undefined safely and the subsequent length check uses optional chaining
as currently written.
…ss various files. Update CLI command references and enhance error handling in template category management. Ensure consistent formatting in layout components and improve accessibility attributes.
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.
Actionable comments posted: 4
🧹 Nitpick comments (11)
apps/docs/src/components/layout/docs/page-client.tsx (6)
93-101: Use ComponentProps to avoid React namespace dependency.Be consistent with existing imports and avoid relying on ambient React namespace types.
-interface ProgressCircleProps - extends Omit<React.ComponentProps<"svg">, "strokeWidth"> { +interface ProgressCircleProps + extends Omit<ComponentProps<"svg">, "strokeWidth"> {
116-121: Harden ProgressCircle math (avoid NaN/Infinity and negative radius).Handle min/max span and radius safely; also update aria-valuenow variable.
- const normalizedValue = clamp(value, min, max); - const radius = (size - strokeWidth) / 2; - const circumference = 2 * Math.PI * radius; - const progress = (normalizedValue / max) * circumference; + const clamped = clamp(value, min, max); + const radius = Math.max(0, (size - strokeWidth) / 2); + const circumference = 2 * Math.PI * radius; + const span = Math.max(1, max - min); // avoid divide-by-zero + const progress = ((clamped - min) / span) * circumference;- aria-valuenow={normalizedValue} + aria-valuenow={clamped}Also applies to: 132-132
169-175: Type the click handler as MouseEvent for clarity.Minor type cleanup to match the event you listen for.
- const onClick = useEffectEvent((e: Event) => { + const onClick = useEffectEvent((e: MouseEvent) => {
176-183: Close the TOC popover on Escape as well.Improves accessibility and expected behavior.
useEffect(() => { window.addEventListener("click", onClick); return () => { window.removeEventListener("click", onClick); }; }, [onClick]); + + useEffect(() => { + const onKeyDown = (e: KeyboardEvent) => { + if (e.key === "Escape") setOpen(false); + }; + window.addEventListener("keydown", onKeyDown); + return () => window.removeEventListener("keydown", onKeyDown); + }, [setOpen]);
293-296: Bound the listCache to prevent unbounded growth.Small guard to avoid leaking entries across navigations.
const list = cached ?? scanNavigationList(root.children); listCache.set(root.$id, list); + if (listCache.size > 20) { + const firstKey = listCache.keys().next().value as string | undefined; + if (firstKey) listCache.delete(firstKey); + }
377-399: Prefer stable keys for breadcrumb items.Use url/name when available to help React reconcile.
- <Fragment key={i}> + <Fragment key={item.url ?? item.name ?? i}>apps/docs/src/components/layout/page.tsx (1)
187-187: Avoid double-parsing the date.Let PageLastUpdate parse once; pass the original value through.
- {lastUpdate && <PageLastUpdate date={new Date(lastUpdate)} />} + {lastUpdate && <PageLastUpdate date={lastUpdate} />}apps/docs/src/components/layout/shared/index.tsx (1)
156-179: De-dupe and simplify getLinks; avoid redundant nullish coalescing.Prevent duplicate GitHub entries and simplify logic; the default param already ensures
linksis an array.-export function getLinks( - links: LinkItemType[] = [], - githubUrl?: string, -): LinkItemType[] { - let result = links ?? []; - - if (githubUrl) - result = [ - ...result, - { - type: "icon", - url: githubUrl, - text: "GitHub", - label: "GitHub", - icon: ( - <svg role="img" viewBox="0 0 24 24" fill="currentColor"> - <path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12" /> - </svg> - ), - external: true, - }, - ]; - - return result; -} +export function getLinks( + links: LinkItemType[] = [], + githubUrl?: string, +): LinkItemType[] { + const items = links; + if (!githubUrl) return items; + + // Avoid duplicate GitHub entries (by exact URL match) + const hasGitHub = items.some((l) => "url" in l && l.url === githubUrl); + if (hasGitHub) return items; + + return [ + ...items, + { + type: "icon", + url: githubUrl, + text: "GitHub", + label: "GitHub", + icon: ( + <svg role="img" viewBox="0 0 24 24" fill="currentColor"> + <path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12" /> + </svg> + ), + external: true, + }, + ]; +}apps/docs/src/components/root-toggle.tsx (2)
67-68: Use clearer boolean for isActive.Avoid boolean | undefined from
selected && .... Use optional chaining for a strict boolean.- const isActive = selected && item.url === selected.url; + const isActive = selected?.url === item.url;
68-69: Return null explicitly for skipped items.Returning
nullis clearer thanundefinedin React lists.- if (!isActive && item.unlisted) return; + if (!isActive && item.unlisted) return null;apps/docs/content/docs/cli/guides/auth/add-on.mdx (1)
9-11: Unify Callout variant: use "warn" (matches elsewhere in this page).The rest of this doc uses type="warn". Keep variants consistent to avoid styling drift.
Apply this diff:
-<Callout type="warning" title="Deprecated"> +<Callout type="warn" title="Deprecated">
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (16)
apps/docs/content/docs/better-auth/installation.mdx(2 hunks)apps/docs/content/docs/cli/guides/adding-components/index.mdx(1 hunks)apps/docs/content/docs/cli/guides/auth/add-on.mdx(1 hunks)apps/docs/content/docs/cli/guides/motivation.mdx(3 hunks)apps/docs/content/docs/cli/index.mdx(1 hunks)apps/docs/content/docs/cli/v2.mdx(1 hunks)apps/docs/src/app/docs/templates/category-config.ts(1 hunks)apps/docs/src/app/docs/templates/layout.tsx(1 hunks)apps/docs/src/app/docs/templates/templates-client.tsx(1 hunks)apps/docs/src/components/CliCommand.tsx(2 hunks)apps/docs/src/components/layout/docs/page-client.tsx(1 hunks)apps/docs/src/components/layout/page.tsx(1 hunks)apps/docs/src/components/layout/shared/index.tsx(1 hunks)apps/docs/src/components/root-toggle.tsx(1 hunks)apps/docs/src/components/ui/scroll-area.tsx(1 hunks)apps/docs/src/lib/templates.ts(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (7)
- apps/docs/content/docs/cli/v2.mdx
- apps/docs/content/docs/cli/index.mdx
- apps/docs/src/app/docs/templates/category-config.ts
- apps/docs/content/docs/cli/guides/adding-components/index.mdx
- apps/docs/src/app/docs/templates/templates-client.tsx
- apps/docs/src/app/docs/templates/layout.tsx
- apps/docs/src/lib/templates.ts
🧰 Additional context used
🧬 Code graph analysis (5)
apps/docs/src/components/layout/shared/index.tsx (1)
apps/docs/src/components/layout/docs/index.tsx (1)
LinkItemType(368-368)
apps/docs/src/components/layout/page.tsx (3)
apps/docs/src/components/layout/docs/page-client.tsx (8)
BreadcrumbProps(349-349)FooterProps(253-261)PageTOCPopover(163-219)PageTOCPopoverTrigger(39-91)PageTOCPopoverContent(151-161)PageBreadcrumb(351-401)PageLastUpdate(221-250)PageTOC(403-426)apps/docs/src/components/layout/docs/page.tsx (12)
BreadcrumbProps(102-102)FooterProps(101-101)PageRoot(75-91)PageTOCPopover(98-98)PageTOCPopoverTrigger(99-99)PageTOCPopoverContent(100-100)PageArticle(57-69)PageBreadcrumb(94-94)PageLastUpdate(96-96)PageTOC(97-97)PageTOCTitle(20-33)PageTOCItems(35-44)apps/docs/src/components/ui/button.tsx (1)
buttonVariants(11-26)
apps/docs/src/components/layout/docs/page-client.tsx (3)
apps/docs/src/components/ui/toc.tsx (1)
useTOCItems(12-14)apps/docs/src/components/ui/collapsible.tsx (3)
CollapsibleTrigger(39-39)CollapsibleContent(39-39)Collapsible(39-39)apps/docs/src/lib/is-active.ts (1)
isActive(8-17)
apps/docs/src/components/CliCommand.tsx (1)
apps/docs/src/lib/constants.ts (1)
cliVersion(2-2)
apps/docs/src/components/root-toggle.tsx (1)
apps/docs/src/lib/is-active.ts (2)
isTabActive(19-23)isActive(8-17)
🔇 Additional comments (13)
apps/docs/src/components/ui/scroll-area.tsx (1)
53-54: Incorrect Radix thumb component still in placeWe still render
ScrollAreaPrimitive.ScrollAreaThumb, which is not a Radix export; the thumb never mounts, so the scrollbar is invisible. Please swap it forScrollAreaPrimitive.Thumb.- <ScrollAreaPrimitive.ScrollAreaThumb className="relative flex-1 rounded-full bg-fd-border" /> + <ScrollAreaPrimitive.Thumb className="relative flex-1 rounded-full bg-fd-border" />apps/docs/src/components/layout/docs/page-client.tsx (1)
242-249: Don’t render the label when the date is invalid/empty.Avoids showing a dangling “Last update ” with no date. This was raised previously.
- return ( - <p - {...props} - className={cn("text-sm text-fd-muted-foreground", props.className)} - > - {text.lastUpdate} {date || ""} - </p> - ); + if (!date) return null; + return ( + <p + {...props} + className={cn("text-sm text-fd-muted-foreground", props.className)} + > + {text.lastUpdate} {date} + </p> + );apps/docs/src/components/layout/page.tsx (1)
182-185: Good fix: default GitHub ref to ‘main’.Prevents “undefined” in blob URLs and matches prior review feedback.
apps/docs/src/components/layout/shared/index.tsx (3)
162-169: Brand casing fixed; keep it consistent site-wide."GitHub" is correct; previous "Github" issue is resolved.
146-152: Public union type looks solid.Clear, extensible LinkItemType union and separation of concerns via BaseLinkType.
52-54: Ensure external links use rel="noopener noreferrer" and target="_blank
BaseLinkItem forwardsexternaltoLink; verify thatLinkfromfumadocs-core/linksetstarget="_blank"andrel="noopener noreferrer"whenexternal=true. If it doesn’t, add these attributes in BaseLinkItem.apps/docs/src/components/root-toggle.tsx (3)
65-66: Tailwind arbitrary value syntax is now correct.
w-[--radix-popover-trigger-width]fixes the prior issue.
51-63: Good controlled Popover and trigger composition.Accessible trigger with icon and responsive copy looks good.
28-31: Confirm Array.prototype.findLast support
- apps/docs/tsconfig.json already targets ESNext and includes
"esnext"inlib, so TypeScript providesfindLasttypings.- No explicit
browserslistentry found—verify your browsers targets supportfindLastor include a runtime polyfill.apps/docs/src/components/CliCommand.tsx (2)
20-24: Good fix: yarn execPrefix -> ‘yarn dlx’.This corrects prior guidance.
33-41: Clarify pinned CLI version
cliVersion is currently typed"latest" | "beta"and defaults to"beta". If you intend to pin@proofkit/[email protected], update thecliVersionconstant in apps/docs/src/lib/constants.ts (type and default) or passexecPackageexplicitly where needed.apps/docs/content/docs/cli/guides/motivation.mdx (1)
40-49: Fix brand casing/names and clarify TanStack Query role.
- Use “shadcn/ui” (lowercase).
- “Kibu Ui” → “Kibo UI”.
- “Tanstack” → “TanStack”.
- TanStack Query manages server state (fetching/caching/etc.); Zod handles shape/validation.
Apply this diff:
-#### [Shadcn/ui](https://ui.shadcn.com/) <Badge className="bg-blue-200 text-blue-700 dark:bg-blue-500 dark:text-blue-50 ">NEW</Badge> +#### [shadcn/ui](https://ui.shadcn.com/) <Badge className="bg-blue-200 text-blue-700 dark:bg-blue-500 dark:text-blue-50 ">NEW</Badge> -A themeable component library for React. We use their default components and styles to build apps very quickly, but with the option of adding custom styles or themes later if needed. Shadcn/ui also includes many helpful React hooks, and they provide a Modal and Notification system to ProofKit apps. +A themeable component library for React. We use their default components and styles to build apps very quickly, but with the option of adding custom styles or themes later if needed. shadcn/ui also includes many helpful React hooks, and they provide a Modal and Notification system to ProofKit apps. Using the shadcn CLI, you can install any component or utility from any compatible library. This makes shadcn the best choice for the most flexible and customizable apps. Some of our favorite shadcn-compatible libraries are: -- [Kibu Ui](https://www.kibo-ui.com/) +- [Kibo UI](https://www.kibo-ui.com/) - [reui](https://reui.io/) - [Magic UI](https://magicui.design/) - [tweakcn (easily theme your components)](https://tweakcn.com/) - [A longer list of more...](https://github.com/birobirobiro/awesome-shadcn-ui) -#### [Tanstack Query](https://tanstack.com/query) +#### [TanStack Query](https://tanstack.com/query) -Sometimes also known as "React Query"; a library for managing server state in React. It's used by ProofKit to fetch data from external sources, such as REST APIs, so we can be certain that the "shape" of our data matches what we expected during development. +Sometimes also known as "React Query"; a library for managing server state in React. It's used by ProofKit for fetching, caching, deduping, background updates, and invalidation of server data. #### [Zod](https://zod.dev/) A type-safe validation library for JavaScript and TypeScript. It's used by ProofKit to validate all inputs from external sources, such as REST APIs, so we can be certain that the "shape" of our data matches what we expected during development. It's also used in form validation. #### [Better-Auth](https://better-auth.com/) (self-hosted) For when you need a bit more flexibility or if you want to self-host the authentication layer within your existing FileMaker solution. Better-auth is a great choice for this, and the [proofkit/better-auth](/docs/better-auth) adapter allows you to use FileMaker as your backend database, including automated schema migrations to easily add any necessary tables and fields to your FileMaker file.Also applies to: 55-58, 73-76
apps/docs/content/docs/better-auth/installation.mdx (1)
19-26: Typos/wording: set up vs setup; Tailwind CSS; brand casing.
- “setup” (verb) → “set up”.
- “tailwindcss” → “Tailwind CSS”.
- Prefer “Better Auth” in the note.
Apply this diff:
<Callout type="warning"> -This automated setup expects you to have Next.js and shadcn/ui set up in your project. It will also setup various auth pages for you, but these may not work if you have a prefix configured for tailwindcss. You can use this opinionated setup to get you started, or if you need more control you should refer to the manual setup. +This automated setup expects you to have Next.js and shadcn/ui set up in your project. It will also set up various auth pages for you, but these may not work if you have a prefix configured for Tailwind CSS. You can use this opinionated setup to get you started, or if you need more control you should refer to the manual setup. </Callout> @@ -Run the following command to add the necessary packages and config files to your project. You will not need to follow the better-auth installation guide. +Run the following command to add the necessary packages and config files to your project. You won't need to follow the Better Auth installation guide.
| The tables/fields that are created will be dependent on how your `auth.ts` file is setup. If you want to use any of your existing tables, just set [custom table names](https://www.better-auth.com/docs/concepts/database#custom-table-names) in the `auth.ts` file before running the migration command. | ||
|
|
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.
Typos/wording: “is setup” → “is set up”.
Also simplify phrasing.
Apply this diff:
-The tables/fields that are created will be dependent on how your `auth.ts` file is setup. If you want to use any of your existing tables, just set [custom table names](https://www.better-auth.com/docs/concepts/database#custom-table-names) in the `auth.ts` file before running the migration command.
+The tables/fields that are created will depend on how your `auth.ts` file is set up. If you want to use any of your existing tables, set [custom table names](https://www.better-auth.com/docs/concepts/database#custom-table-names) in the `auth.ts` file before running the migration command.📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| The tables/fields that are created will be dependent on how your `auth.ts` file is setup. If you want to use any of your existing tables, just set [custom table names](https://www.better-auth.com/docs/concepts/database#custom-table-names) in the `auth.ts` file before running the migration command. | |
| The tables/fields that are created will depend on how your `auth.ts` file is set up. If you want to use any of your existing tables, set [custom table names](https://www.better-auth.com/docs/concepts/database#custom-table-names) in the `auth.ts` file before running the migration command. |
🤖 Prompt for AI Agents
In apps/docs/content/docs/better-auth/installation.mdx around lines 72-73, fix
the wording "is setup" to "is set up" and simplify the sentence for clarity;
reword the two sentences into a single concise sentence that advises the reader
that created tables/fields depend on their auth.ts configuration and that
existing tables can be used by setting custom table names in auth.ts before
running the migration command.
| prefix: "npm run", | ||
| execPrefix: "npx", |
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.
Fix npm/bun non-exec prefixes.
- npm: “npm run” assumes a package.json script; use npx for binaries.
- bun: “bun” won’t run package binaries; use bunx.
Apply this diff:
- prefix: "npm run",
+ prefix: "npx",
@@
- prefix: "bun",
+ prefix: "bunx",Also applies to: 26-29
🤖 Prompt for AI Agents
In apps/docs/src/components/CliCommand.tsx around lines 10-11 and 26-29, the
non-exec prefixes for npm and bun are incorrect; update the npm non-exec prefix
from "npm run" to "npx" (so binaries use npx instead of assuming a package
script) and update the bun non-exec prefix from "bun" to "bunx" (so bun package
binaries run correctly).
| export function CliCommand({ | ||
| command, | ||
| exec, | ||
| execPackage = `@proofkit/cli@${cliVersion}`, | ||
| }: { | ||
| command: string; | ||
| exec?: boolean; | ||
| execPackage?: string; | ||
| }) { |
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.
🛠️ Refactor suggestion | 🟠 Major
🧩 Analysis chain
Preserve DynamicCodeBlock props (e.g., frame).
CliCommand drops props like frame used across MDX. Accept and forward rest props to avoid breaking existing pages.
Apply this diff:
+import type { ComponentProps } from "react";
@@
-export function CliCommand({
- command,
- exec,
- execPackage = `@proofkit/cli@${cliVersion}`,
-}: {
- command: string;
- exec?: boolean;
- execPackage?: string;
-}) {
+export function CliCommand({
+ command,
+ exec,
+ execPackage = `@proofkit/cli@${cliVersion}`,
+ ...rest
+}: {
+ command: string;
+ exec?: boolean;
+ execPackage?: string;
+} & Partial<ComponentProps<typeof DynamicCodeBlock>>) {
@@
- <DynamicCodeBlock
+ <DynamicCodeBlock
lang="bash"
code={`${exec ? manager.execPrefix + " " + execPackage : manager.prefix} ${command}`}
- />
+ {...rest}
+ />Verification script to find usages passing frame:
Also applies to: 51-54
🏁 Script executed:
#!/bin/bash
rg -n -C2 '<CliCommand[^>]*\bframe=' --glob '!**/node_modules/**'Length of output: 148
🏁 Script executed:
#!/bin/bash
echo "Searching for all <CliCommand> usages in MDX and TSX files:"
rg -n '<CliCommand' -g '*.mdx' -g '*.tsx' --color always || true
echo ""
echo "Searching for <CliCommand> usages with a frame= attribute:"
rg -n '<CliCommand[^>]*frame=' -g '*.mdx' -g '*.tsx' --color always || trueLength of output: 4346
#!/bin/bash
echo "Import of DynamicCodeBlock:"
rg -n "import .*DynamicCodeBlock" -g "apps/docs/src/components/CliCommand.tsx" -C2
echo ""
echo "CliCommand component signature and usage of DynamicCodeBlock:"
rg -n -C3 "export function CliCommand" -g "apps/docs/src/components/CliCommand.tsx"
rg -n -C3 "DynamicCodeBlock" -g "apps/docs/src/components/CliCommand.tsx"🏁 Script executed:
#!/bin/bash
# Verify import of DynamicCodeBlock
rg -nP "import.*DynamicCodeBlock" -g "apps/docs/src/components/CliCommand.tsx"
echo ""
# Show component signature
rg -n -C3 "export function CliCommand" -g "apps/docs/src/components/CliCommand.tsx"
echo ""
# Show usage of DynamicCodeBlock inside CliCommand
rg -n -C3 "DynamicCodeBlock" -g "apps/docs/src/components/CliCommand.tsx"Length of output: 1492
Forward DynamicCodeBlock props in CliCommand
Extend CliCommand to accept ...rest of ComponentProps<typeof DynamicCodeBlock> and spread them into <DynamicCodeBlock> so MDX pages passing frame (and other props) don’t break.
File apps/docs/src/components/CliCommand.tsx
+import type { ComponentProps } from "react";
@@
-export function CliCommand({
+export function CliCommand({
command,
exec,
execPackage = `@proofkit/cli@${cliVersion}`,
+ ...rest
-}: {
+}: { command: string; exec?: boolean; execPackage?: string } & Partial<ComponentProps<typeof DynamicCodeBlock>>) {
@@
- <DynamicCodeBlock
+ <DynamicCodeBlock
lang="bash"
code={`${exec ? manager.execPrefix + " " + execPackage : manager.prefix} ${command}`}
- />
+ {...rest}
+ />📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| export function CliCommand({ | |
| command, | |
| exec, | |
| execPackage = `@proofkit/cli@${cliVersion}`, | |
| }: { | |
| command: string; | |
| exec?: boolean; | |
| execPackage?: string; | |
| }) { | |
| import type { ComponentProps } from "react"; | |
| // … other imports … | |
| import { DynamicCodeBlock } from "./DynamicCodeBlock"; | |
| export function CliCommand({ | |
| command, | |
| exec, | |
| execPackage = `@proofkit/cli@${cliVersion}`, | |
| ...rest | |
| }: { command: string; exec?: boolean; execPackage?: string } | |
| & Partial<ComponentProps<typeof DynamicCodeBlock>> | |
| ) { | |
| const manager = getPackageManager(); // assuming this is defined elsewhere | |
| return ( | |
| <DynamicCodeBlock | |
| lang="bash" | |
| code={`${exec ? manager.execPrefix + " " + execPackage : manager.prefix} ${command}`} | |
| {...rest} | |
| /> | |
| ); | |
| } |
| <Link | ||
| key={item.url} | ||
| href={item.url} | ||
| onClick={onClick} | ||
| {...item.props} | ||
| className={cn( | ||
| "flex items-center gap-2 rounded-lg p-1.5 hover:bg-fd-accent hover:text-fd-accent-foreground", | ||
| item.props?.className, | ||
| )} |
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.
Compose onClick handlers; current spread can override closing logic.
{...item.props} after onClick={onClick} can replace the handler and leave the popover open. Compose both.
- <Link
+ <Link
key={item.url}
href={item.url}
- onClick={onClick}
+ onClick={(e) => {
+ item.props?.onClick?.(e);
+ onClick();
+ }}
{...item.props}
className={cn(
"flex items-center gap-2 rounded-lg p-1.5 hover:bg-fd-accent hover:text-fd-accent-foreground",
item.props?.className,
)}
>Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In apps/docs/src/components/root-toggle.tsx around lines 71 to 79, the current
JSX spreads {...item.props} after onClick={onClick} which allows
item.props.onClick to overwrite the popover-closing onClick; fix by composing
the handlers instead of letting the spread override: create a combinedOnClick
that invokes item.props.onClick (if present) and then the local onClick (or vice
versa depending on desired order), pass combinedOnClick as the onClick prop, and
spread the rest of item.props excluding its onClick and className (merge
className values instead of letting the spread replace them).
- Cast Object.keys(grouped) to Category[] to fix type error - Ensures proper type safety when accessing grouped[category] - Resolves build failure in docs app

template docs
Update documentation for ProofKit CLI v2, highlighting new features such as shadcn integration, improved component addition, and deprecation of the FileMaker Add-on Auth. Enhance layout configuration for better navigation in the home layout.
Update CLI to version 2.0.0-beta.3, changing default UI to shadcn/ui for new projects and deprecating legacy Mantine templates. Enhance template documentation and layout configuration for improved navigation. Adjust template category handling in the UI for better organization and clarity.
Refactor template page and CLI command components for improved clarity and functionality. Update installation command to use dynamic CLI versioning and streamline template content display. Enhance error handling in tests for better resilience against undefined values.
Summary by CodeRabbit
New Features
Documentation
Chores