HQReact UI
DocsThemes
  • Getting Started
  • Introduction
  • Installation
  • Client Side Routing
  • MCP Server
  • LLMs
  • Framework Guides
  • Nextjs
  • Laravel
  • Vite
  • Tanstack Start
  • Components
  • Buttons
  • Button
  • File Trigger
  • Toggle
  • Charts
  • Chart
  • Collections
  • Accordion
  • Bubble
  • Collapsible
  • Context Menu
  • Dropdown Menu
  • Grid List
  • Item
  • List Box
  • Message
  • Table
  • Tag Group
  • Tree
  • Colors
  • Color
  • Controls
  • Command
  • Kbd
  • Slider
  • Switch
  • Toolbar
  • Date And Time
  • Calendar
  • Range Calendar
  • Date Field
  • Date Picker
  • Date Range Picker
  • Time Field
  • Drag And Drop
  • Drop Zone
  • Forms
  • Field
  • Input
  • Combobox
  • Input Group
  • Checkbox
  • Radio
  • Select
  • Text Field
  • Number Field
  • Search Field
  • Input OTP
  • Layouts
  • Container
  • Navbar
  • Sidebar
  • Media
  • Avatar
  • Carousel
  • Navigation
  • Link
  • Breadcrumbs
  • Tabs
  • Pagination
  • Overlays
  • Dialog
  • Alert Dialog
  • Sheet
  • Popover
  • Tooltip
  • Statuses
  • Alert
  • Badge
  • Empty
  • Meter
  • Progress
  • Skeleton
  • Toastalpha
  • Surfaces
  • Card
  • Separator

On this page

Tanstack Start

Create New Project

I recommend using tanstack cli to create new project rather than using shadcn installer, because tanstack cli gives you more options which package you want to install. And if you choose Shadcn in the tanstack cli installation, The component like Theme Toggle are already setup.

npx @tanstack/cli@latest create

Registry

First, add the HQ UI in your components.json:

components.json
  ...
  "registries": {
    "@hq": "https://hq-ui.vercel.app/r/{name}"
  }

Add Components

You can now start adding components to your project.

npx shadcn add @hq/button

Or if you don't wan't to modify components.json, you can use this command

npx shadcn add https://hq-ui.vercel.app/r/button

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. And with Tanstack Router, you'll get the autocomplete which will help you to define the routes typesafely.

Client Provider

To integrate with Tanstack Start, ensure the locale on the server matches the client, and configure React Aria links to use the Tanstack Router.

client-provider.tsx
import { type NavigateOptions, type ToOptions, useRouter, } from "@tanstack/react-router";
import { RouterProvider } from "react-aria-components";
 
declare module "react-aria-components" {
  interface RouterConfig {
    href: ToOptions["to"];
    routerOptions: Omit<NavigateOptions, keyof ToOptions>;
  }
}
 
export function ClientProvider({ children }: { children: React.ReactNode }) {
  const router = useRouter();
 
  return (
    <RouterProvider
      navigate={(to, options) => router.navigate({ to, ...options })}
    >
      {children}
    </RouterProvider>
  );
}
 

Then use in your __root.tsx file.

__root.tsx
import { ClientProvider } from "#/components/client-provider"
 
...
function RootDocument({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en" suppressHydrationWarning>
      //
      <ClientProvider>
        {children}
      </ClientProvider>
      //
    </html>
  )
}

Dark Mode

Theme Provider

If you are using the Tanstack CLI, Theme Provider is already setup. You can skip this step

If the theme-provider isn't setup, or you want to create your own then you have to create one.

npm i @tabler/icons-react

import { IconDeviceDesktop, IconMoon, IconSun } from "@tabler/icons-react";
import { useEffect, useState } from "react";
import { Button } from "#/components/ui/button";
 
type ThemeMode = "light" | "dark" | "auto";
 
function getInitialMode(): ThemeMode {
	if (typeof window === "undefined") {
		return "auto";
	}
 
	const stored = window.localStorage.getItem("theme");
	if (stored === "light" || stored === "dark" || stored === "auto") {
		return stored;
	}
 
	return "auto";
}
 
function applyThemeMode(mode: ThemeMode) {
	const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
	const resolved = mode === "auto" ? (prefersDark ? "dark" : "light") : mode;
 
	document.documentElement.classList.remove("light", "dark");
	document.documentElement.classList.add(resolved);
 
	if (mode === "auto") {
		document.documentElement.removeAttribute("data-theme");
	} else {
		document.documentElement.setAttribute("data-theme", mode);
	}
 
	document.documentElement.style.colorScheme = resolved;
}
 
export default function ThemeToggle() {
	const [mode, setMode] = useState<ThemeMode>("auto");
 
	useEffect(() => {
		const initialMode = getInitialMode();
		setMode(initialMode);
		applyThemeMode(initialMode);
	}, []);
 
	useEffect(() => {
		if (mode !== "auto") {
			return;
		}
 
		const media = window.matchMedia("(prefers-color-scheme: dark)");
		const onChange = () => applyThemeMode("auto");
 
		media.addEventListener("change", onChange);
		return () => {
			media.removeEventListener("change", onChange);
		};
	}, [mode]);
 
	function toggleMode() {
		const nextMode: ThemeMode =
			mode === "light" ? "dark" : mode === "dark" ? "auto" : "light";
		setMode(nextMode);
		applyThemeMode(nextMode);
		window.localStorage.setItem("theme", nextMode);
	}
 
	return (
		<Button
			aria-label={`Switch to ${mode}` === "light" ? "dark" : "light" + "mode"}
			onPress={toggleMode}
			size="icon"
			variant="outline"
		>
			{mode === "auto" ? (
				<IconDeviceDesktop
					aria-hidden
					className="absolute rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0"
				/>
			) : (
				<>
					<IconSun
						aria-hidden
						className="absolute 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>
	);
}
Vite
Button

On this page

  • Create New Project
  • Registry
  • Add Components
  • Client Side Routing
  • Client Provider
  • Dark Mode
  • Theme Provider