NebulaKit takes care of the UI and leaves other jobs, like routing, forms and animation, to the tools made for them. This page shows how it works together with them.
NebulaKit runs in any React app, whether it is built with Vite or a framework like Next.js or React Router. With the Next.js App Router, every component is client code marked with "use client", so a server component can import and render it directly.
How the components render on the server is covered on Server rendering.
Link turns any component into a real link and hands a plain click to your router through onClick. Clicks with a modifier key or the middle mouse button stay with the browser, so opening a link in a new tab keeps working.
With React Router
const navigate = useNavigate() <Link href="/settings" onClick={() => navigate('/settings')}> <Button>Settings</Button></Link>A full example with cards and pagination is the Router links pattern.
Every form control takes name and required, so it submits its value with a native form, takes part in its validation and returns to its starting value when the form is reset.
With a form library, connect the control's value and change handler and pass the library's ref to elemRef, so it can focus the control with an error.
With React Hook Form
<Controller name="email" control={form.control} render={({ field }) => ( <Input elemRef={field.ref} value={field.value} onChange={field.onChange} onBlur={field.onBlur} /> )}/>A full example with labels and errors is the Basic form pattern.
Animation libraries like Motion animate their own elements. Components take their ref through elemRef instead of ref, so wrap a component in the library's element and animate the wrapper.
With Motion
<AnimatePresence> {items.map(item => ( <motion.div key={item.id} initial={{ opacity: 0, y: 12 }} animate={{ opacity: 1, y: 0 }} exit={{ opacity: 0 }} > <Card heading={item.name}>{item.text}</Card> </motion.div> ))}</AnimatePresence>