StatsHub Docs
Packages

ui-web

Web design-system primitives on Base UI, consumed by web and admin — including the Radix-to-Base-UI prop translation every wrapper performs.

@statshub/ui-web holds the web primitives shared out of apps/statshub-web. The React Native counterpart is ui-native, and the two cannot merge — see why.

Components are published from TypeScript source through an exports map, so Turbopack, tsc and the editor all read the same files:

import { Button } from "@statshub/ui-web/components/button";
import { cn } from "@statshub/ui-web/lib/utils";

Base UI, not Radix

These are built on Base UI. shadcn serves a Base UI variant of its registry under the base-vega style, which apps/statshub-web's components.json is pinned to — so shadcn add <name> run from apps/statshub-web writes a Base UI component straight into this package.

Base UI renamed or dropped a number of Radix props. Rather than rewrite hundreds of call sites, the wrappers accept the Radix spelling and translate it:

RadixBase UIHandled by
asChildrender proplib/as-child.tsx, applied in every wrapper
<Accordion type collapsible>multiple, array valuecomponents/accordion.tsx
onValueChange(value)(value, eventDetails), string | nullcomponents/select.tsx
delayDuration, skipDelayDurationdelay on the Providercomponents/tooltip.tsx
openDelay / closeDelaydelay / closeDelaycomponents/hover-card.tsx
avoidCollisionscollisionAvoidancepopup wrappers
onOpenAutoFocus and friendshandled on the Rootaccepted, not forwarded
delayMs on avatar fallbackno equivalentaccepted, not forwarded

Check this table before adding a primitive

A new wrapper that forwards asChild straight through will render nothing and raise no error.

lib/slot.tsx is the one piece of @radix-ui/react-slot that survived, as a local implementation — plain DOM wrappers (sidebar, breadcrumb) still want an asChild escape hatch, and Base UI's render only exists on its own primitives.

What else is in here

Beyond the Base UI wrappers, the package carries the pieces web and admin share that are not primitives: @silk-hq/components sheets (bottom-sheet, long-sheet), Embla carousels, react-day-picker calendars, cmdk command menus, and a handful of motion components on Framer Motion. See Silk components for the sheet conventions.

On this page