Skip to content
Component installs need the registry setup— the Base UI shadcn project, the @vegastack namespace and the Cloudflare Access service token.
VegaStack Design

Provider

The single app-root wrapper — theme, toasts, tooltip coordination, and text direction. Mount it once; every VegaStack component below it just works.

Status
stable
Since
0.2.0
Accessibility pattern
no rendered UI

Last updated

Install

Add Provider from the VegaStack registry. The CLI verifies the item's integrity hash before writing it.

pnpm dlx shadcn@latest add @vegastack/provider

The same command installs the registry items it composes: @vegastack/toast.

It also adds the sanctioned engine to your package.json: next-themes (theme runtime engine).

Usage

Wrap your app root, exactly once — in Next.js that's app/layout.tsx. The host <html> element needs suppressHydrationWarning because next-themes mutates it on the client before hydration:

// app/layout.tsx
import { VegaStackProvider } from "@/components/ui/provider";

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en" suppressHydrationWarning>
      <body>
        <VegaStackProvider>{children}</VegaStackProvider>
      </body>
    </html>
  );
}

What it wires — and what silently breaks without it

WiringWithout the provider
Dark mode (next-themes, attribute="class", system-aware)Theme toggles do nothing; the .dark class never reaches <html>
Toasts (ToastProvider + the Toaster portal)Every toast(...) call — from CopyButton, forms, anywhere — silently does nothing. No error, no toast.
Tooltip coordination (Base UI Tooltip.Provider)Tooltips lose shared-delay: hover across a toolbar and each tooltip re-waits the full open delay
Text direction (Base UI DirectionProvider)RTL layouts break for direction-aware components

Examples

Theme toggle

useVegaStackTheme() (exported from the same file) is a thin wrapper over next-themes' useTheme() — use it anywhere below the provider:

"use client";
import { useVegaStackTheme } from "@/components/ui/provider";
import { Button } from "@/components/ui/button";

export function ThemeToggle() {
  const { resolvedTheme, setTheme } = useVegaStackTheme();
  return (
    <Button
      variant="ghost"
      onClick={() => setTheme(resolvedTheme === "dark" ? "light" : "dark")}
    >
      Toggle theme
    </Button>
  );
}

Tooltip coordination

Hover the first button, then move across — with the provider mounted, the rest open instantly instead of each re-waiting the open delay:

The mount-once rule

The bundled <Toaster /> is a portal that must exist exactly once. Never nest a second VegaStackProvider, and if some other part of your app already renders a <Toaster />, suppress the bundled one:

<VegaStackProvider toaster={false}>{children}</VegaStackProvider>

You can also hand it a customized element instead:

<VegaStackProvider toaster={<Toaster position="top-center" />}>
  {children}
</VegaStackProvider>

All remaining props pass through to next-themes — e.g. force a default:

<VegaStackProvider defaultTheme="dark" enableSystem={false}>

API Reference

PropTypeDefaultDescription
children*React.ReactNodeThe application subtree that receives theme, direction, tooltip, and toast context.
direction"ltr" | "rtl"'ltr'Text direction for Base UI components.
toasterReact.ReactNodetrueControls the bundled Toaster. Mount-once portal toasters must not be double-mounted, so pass false if you already render a <Toaster /> elsewhere, or pass your own element to override the default.

Accessibility

The provider renders no visible UI of its own — context providers plus the Toaster portal. Toast announcements come from the toast viewport's labelled live region (see Toast); disableTransitionOnChange prevents a full-page transition flash on theme switch, complementing the global prefers-reduced-motion reset in the base layer.

ContractStates tested
Behaviourdefault
Accessibilitynative-or-base-ui-semantics, browser-accessibility-test
Visualdefault

Do / Don't

Do
Mount VegaStackProvider once at the app root and build your theme toggle on useVegaStackTheme.
Don't
Nest providers or mount a second Toaster — toasts will double-render; pass toaster={false} instead.

On this page