Create New Project
Run the init command to create a new Next.js project or to setup an existing one:
Registry
First, add the HQ UI in your components.json:
...
"registries": {
"@hq": "https://hq-ui.vercel.app/r/{name}"
}Add Components
You can now start adding components to your project.
Or if you don't wan't to modify components.json, you can use this command
Client Side Routing
React Aria components such as Link, Menu, Tabs, and Table transform elements into clickable links that navigate when clicked. These components utilize the href prop to render as an <a> tag, supporting attributes like target and download.
Client Provider
To integrate with Next.js (App Router), ensure the locale on the server matches the client, and configure React Aria links to use the Next.js router.
"use client"
import { useRouter } from 'next/navigation'
import { RouterProvider } from 'react-aria-components'
declare module 'react-aria-components' {
interface RouterConfig {
routerOptions: NonNullable<Parameters<ReturnType<typeof useRouter>['push']>[1]>
}
}
export function ClientProviders({ children }: { children: React.ReactNode }) {
const router = useRouter()
return (
<RouterProvider navigate={router.push}>
{children}
</RouterProvider>
)
}Then use in your root layout
import { Geist, Geist_Mono } from "next/font/google"
import "./globals.css"
import { ThemeProvider } from "@/components/theme-provider"
import { ClientProvider } from '@/components/client-provider'
const fontSans = Geist({
subsets: ["latin"],
variable: "--font-sans",
})
const fontMono = Geist_Mono({
subsets: ["latin"],
variable: "--font-mono",
})
export default async function RootLayout({
children
}: Readonly<{
children: React.ReactNode
}>){
return (
<html
lang='en'
suppressHydrationWarning
className={`${fontSans.variable} ${fontMono.variable} font-sans antialiased`}
>
<body>
<ThemeProvider>
<ClientProvider>
{children}
</ClientProvider>
</ThemeProvider>
</body>
</html>
)
}Dark Mode
Theme Provider
If you are using the New Shadcn CLI, Theme Provider is already added. You can skip this step
Theme Switcher
'use client'
import { useTheme } from 'next-themes'
import { IconMoon, IconSun } from '@tabler/icons-react'
import { Button } from '@/components/ui/button'
export function ThemeSwitcher({ variant = 'outline' }: { variant?: 'outline' | 'ghost' }) {
const { resolvedTheme, setTheme } = useTheme()
return (
<Button
aria-label={`Switch to ${resolvedTheme}` === 'light' ? 'dark' : 'light' + 'mode'}
onPress={() => setTheme(resolvedTheme === 'light' ? 'dark' : 'light')}
size='icon'
variant={variant}
>
<IconSun aria-hidden className='rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0' />
<IconMoon aria-hidden className='absolute rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100' />
</Button>
)
}