Overview of @react-three/uikit-horizon
main@react-three/uikit-horizon package provides a component kit for @react-three/uikit that implements the Reality Labs Design System (RLDS).repository·main·Indexed 25 days ago
https://github.com/pmndrs/uikitA library for building performant 3D user interfaces for three.js, optimized for games, XR (VR/AR), and spatial computing. It provides tools for vanilla Three.js and React Three Fiber, including layout components like Container and Fullscreen using yoga for flexbox styling. The ecosystem includes pre-styled kits such as the Default kit (based on shadcn) and the Horizon kit (based on RLDS), as well as supporting packages like @pmndrs/msdfonts for base64 MSDF fonts and @pmndrs/uikit-pub-sub for layered property management.
@react-three/uikit-horizon package provides a component kit for @react-three/uikit that implements the Reality Labs Design System (RLDS).The @pmndrs/uikit-pub-sub package provides a persistent, layered Publish-Subscribe implementation designed for managing UI kit properties. It allows you to publish values to specific properties at any time and subscribe to them to receive both the latest persisted value and all subsequent updates.
Key features include:
The AlertDialog component in @react-three/uikit-default allows you to create modal dialogs within a React Three Fiber canvas. It uses a trigger-based pattern where an AlertDialogTrigger controls the visibility of an AlertDialog via a signal or reference.
To implement an Alert Dialog:
@preact/signals-core) to hold the VanillaDialog instance.Button) in an AlertDialogTrigger and pass the signal to the dialog prop.AlertDialog component and use a ref callback to update your signal with the dialog instance.AlertDialogContent, AlertDialogHeader, AlertDialogTitle, AlertDialogDescription, AlertDialogFooter, AlertDialogCancel, and AlertDialogAction.import { useMemo } from 'react'
import { signal } from '@preact/signals-core'
import { Text } from '@react-three/uikit'
import {
Button,
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
AlertDialogTrigger,
VanillaDialog,
} from '@react-three/uikit-default'
function AlertDialogDemo() {
// 1. Create a signal to manage the dialog instance
const ref = useMemo(() => signal<VanillaDialog | undefined>(undefined), [])
return (
<>
{/* 2. The trigger component that opens the dialog */}
<AlertDialogTrigger dialog={ref}>
<Button variant="outline">
<Text>Show Dialog</Text>
</Button>
</AlertDialogTrigger>
{/* 3. The dialog component itself, linked via ref */}
<AlertDialog ref={(dialog) => void (ref.value = dialog ?? undefined)}>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>
<Text>Are you absolutely sure?</Text>
</AlertDialogTitle>
<AlertDialogDescription>
<Text>
This action cannot be undone. This will permanently delete your account.
</Text>
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>
<Text>Cancel</Text>
</AlertDialogCancel>
<AlertDialogAction>
<Text>Continue</Text>
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
</>
)
}To use uikit with plain Three.js, install the core package and three using pnpm:
pnpm add three @pmndrs/uikitYou can explore various implementation patterns and pre-styled component kits using the official uikit examples. These examples demonstrate different use cases such as card layouts, dashboards, market interfaces, icon integration with Lucide, and authentication flows.
The Tooltip component in @react-three/uikit-default follows a pattern similar to modern UI libraries, consisting of a root Tooltip component, a TooltipTrigger to define the interactive element, and TooltipContent to define the information displayed on hover/interaction.
To use it, wrap your trigger element (like a Button) with <TooltipTrigger> and place your content inside <TooltipContent> within the <Tooltip> provider.
import { Button, Tooltip, TooltipContent, TooltipTrigger } from '@react-three/uikit-default'
import { Text } from '@react-three/uikit'
function TooltipDemo() {
return (
<Tooltip>
<TooltipTrigger>
<Button variant="outline">
<Text>Hover</Text>
</Button>
</TooltipTrigger>
<TooltipContent>
<Text>Add to library</Text>
</TooltipContent>
</Tooltip>
)
}The Panel component is part of the @react-three/uikit-horizon package. It is used to create containers within a UI layout. You can customize its appearance using props like padding, width, and color. It also supports a dark prop to define alternative styling for dark mode contexts.
To use it, ensure you have @react-three/uikit-horizon installed and imported.
import { Panel } from "@react-three/uikit-horizon";
function PanelDemo() {
return (
<Panel padding={16} width={300}>
<Container>
<Text>Panel content</Text>
</Container>
</Panel>
)
}You can override the default background and border materials for Text, Container, and Image components by providing a custom material class via the panelMaterialClass prop. This is useful for applying complex materials like MeshPhysicalMaterial or customized MeshPhongMaterial to UI elements.
To use a custom material:
MeshPhongMaterial).panelMaterialClass prop of the component.Additionally, you can use the borderBend property to bend the normals on the border, which can be used to create 3D illusions efficiently.
import { Text } from '@react-three/uikit'
import { MeshPhongMaterial } from 'three'
class FancyMaterial extends MeshPhongMaterial {
constructor() {
super({
specular: 0x111111,
shininess: 100,
})
}
}
export default function App() {
return (
<Text
backgroundColor="black"
color="white"
padding={24}
borderRadius={32}
fontSize={32}
borderColor="black"
borderBend={0.3}
borderWidth={8}
panelMaterialClass={FancyMaterial}
>
I look fancy
</Text>
)
}The RadioGroup component from @react-three/uikit-default allows you to create a group of selectable radio items.
To implement it:
<RadioGroup> component. Use the defaultValue prop to set the initial selected value.<RadioGroupItem> components, providing a unique value prop to each.<Label> and <Text>) inside the <RadioGroupItem> to define the visual representation of the option.import { RadioGroup, RadioGroupItem, Label } from '@react-three/uikit-default'
import { Text } from '@react-three/uikit'
function RadioGroupDemo() {
return (
<RadioGroup defaultValue="comfortable">
<RadioGroupItem value="default">
<Label>
<Text>Default</Text>
</Label>
</RadioGroupItem>
<RadioGroupItem value="comfortable">
<Label>
<Text>Comfortable</Text>
</Label>
</RadioGroupItem>
<RadioGroupItem value="compact">
<Label>
<Text>Compact</Text>
</Label>
</RadioGroupItem>
</RadioGroup>
)
}While zIndex behaves like the browser's z-index, zIndexOffset allows you to manipulate the internal default order deduced from the UI hierarchy. This is useful for shifting specific elements forward or backward relative to their siblings without manually managing absolute z-index values.
zIndexOffset={1} to quickly order sibling elements of the same type (e.g., overlapping panels) that share the same UI hierarchy level.The Toggle component from the @react-three/uikit-default package allows you to wrap elements to create a toggleable interaction. When used, it typically toggles the visibility or state of its children.
To use it, import Toggle from @react-three/uikit-default and wrap the component you wish to toggle.
import { Toggle } from '@react-three/uikit-default'
import { Bold } from '@react-three/uikit-lucide'
function ToggleDemo() {
return (
<Toggle>
<Bold height={16} width={16} />
</Toggle>
)
}To use uikit for building 3D user interfaces in React, install three, @react-three/fiber, and @react-three/uikit via npm.
npm install three @react-three/fiber @react-three/uikit