Vite / Webpack / etc.
TIP
We recommend starting with our preconfigured Vite template. Otherwise, follow the steps below for manual installation.
Root Provider
This library exports a QuiRoot
component which provides context for global notifications and alerts. It should wrap your component tree.
import {ReactNode} from "@qui/react"import {QuiRoot} from "@qui/react"export function App(): ReactNode {return <QuiRoot>{/* The rest of your app */}</QuiRoot>}
Fonts
Fonts are sourced from Google. Add the links to your application's <head>
element:
<link rel="preconnect" href="https://fonts.googleapis.com" /><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /><linkhref="https://fonts.googleapis.com/css2?family=Roboto+Flex:opsz,wdth,wght@8..144,110,400;8..144,110,560;8..144,114,400;8..144,114,500;8..144,114,520;8..144,114,660;8..144,114,680&family=Roboto+Mono&display=swap"rel="stylesheet"/>
Theme
All components ship with dark
and light
variants.
TIP
The @qui/styles
package applies CSS variables based on the presence of a dark
or light
className on the nearest ancestor element. To manage this, we'll use hooks and context.
import {createContext,useCallback,useContext,Dispatch,SetStateAction,ReactNode,} from "react"import {QuiTheme} from "@qui/base"// this will be used to store the theme in localStorage.export const appThemeKey = "my-qui-app-theme-key"export interface ThemeState {mode: QuiThemesetMode: Dispatch<SetStateAction<QuiTheme>>toggleMode: () => void}const ThemeContext = createContext<ThemeState | null>(null)interface Props {children: ReactNode}export function ThemeProvider({children}: Props) {const [mode, setMode] = useState<QuiTheme>(localStorage.getItem(appThemeKey) === "light" ? "light" : "dark",)const html = document.getElementById("html")if (html && !html.className.includes(mode)) {html.className = mode}const toggleMode = useCallback(() => {const html = document.getElementById("html")if (!html) {console.warn("Error, expecting HTML element but it was not found")return}setMode((prevState) => {const nextState = prevState === "dark" ? "light" : "dark"html.classList.remove(prevState)html.classList.add(nextState)localStorage.setItem(appThemeKey, nextState)return nextState})}, [])const context: ThemeState = useMemo(() => ({mode, setMode, toggleMode}),[mode, setMode, toggleMode],)return (<ThemeContext.Provider value={context}>{children}</ThemeContext.Provider>)}/* Optional: export a helper hook. */export function useTheme() {const themeContext = useContext(ThemeContext)if (!themeContext) {throw new Error("All calls to useTheme can only be performed from a child of a <ThemeProvider>",)}return themeContext}
Next, wrap your application in the theme provider:
import {createRoot} from "react-dom/client"import {ThemeProvider} from "./theme-provider"import App from "./App"import "./index.css"createRoot(document.getElementById("root")!).render(<ThemeProvider><App /></ThemeProvider>,)
Import Styles
Add the following imports to your project's App root or global CSS.
import "@qui/styles/dist/all.min.css"import "@qui/base/dist/all.min.css"
Setup Complete
Now you're ready to start importing and using our components. Continue on to our Component Documentation.