# Widgets

> Framework-agnostic, fully-featured widgets that share one core and ship React and Vue skins.

Widgets are larger, behaviour-rich building blocks that sit a level above the
[components](https://ticketsolutionsptyltd.github.io/roadie/components.md). Where a component is a single UI primitive, a widget
bundles data fetching, state, motion, and accessibility into a complete feature
you drop into an app.

They live in the `@oztix/roadie-widgets` package and follow a **core + skins**
architecture:

- The **core** holds the framework-agnostic logic. That covers types, the cart
  client, URL helpers, totals, grouping, urgency, and formatting. It has no UI.
- The **React skin** is a `'use client'` React component. It's built on
  `@oztix/roadie-components`, `motion`, and `@tanstack/react-query`.
- The **Vue skin** is a Vue 3 SFC with the same props and behaviour. It's built
  on the same core.

Both skins are pixel- and behaviour-equivalent because they share the core. Pick
the skin that matches your app. The props are the same.

> **Use the React skin for new work.** The Vue skins exist solely for the
> **TicketSolutions.OnlineOutlet** app. That app is being folded into
> **TicketSolutions.Oztix.Website**, a React codebase. After that, the Vue
> skins will be retired. Import the `/vue` entry points only inside OnlineOutlet;
> everywhere else, use the React skin.

## Installation

```bash
pnpm add @oztix/roadie-widgets
```

Each skin declares its own peer dependencies (React + react-query + motion, or
Vue + its NumberFlow/Phosphor packages) so you only install what your framework
needs. See each widget's page for the exact list.

Then register the package CSS with Tailwind so it scans the compiled classes.
Without it, the widgets render unstyled.

```css
/* app/globals.css (React) */
@import '@oztix/roadie-core/css';
@import '@oztix/roadie-components/css';
@import '@oztix/roadie-widgets/css';
```

```css
/* app/globals.css (Vue) */
@import '@oztix/roadie-core/css';
@import '@oztix/roadie-widgets/css';
```

Each package's CSS ships its own `@source`, so you never write a `node_modules`
path. The **React** skins render `@oztix/roadie-components`, so React consumers
include its CSS too; the **Vue** skins use core classes only and don't.

## Available widgets

- [**Cart drawer**](https://ticketsolutionsptyltd.github.io/roadie/roadie-widgets/cart-drawer.md) is the docked, expandable cart
  for collection and event pages.
- [**Cart contents**](https://ticketsolutionsptyltd.github.io/roadie/roadie-widgets/cart-contents.md) is the day-grouped cart list
  the drawer renders. It's exported on its own for a standalone `/cart` page.

More widgets will be added here as they graduate from app code into the shared
package.

## When to reach for a widget

Use a widget when you need the **same complex feature in more than one app or
framework** and want a single source of truth for its behaviour. If you only
need a styled primitive, use a [component](https://ticketsolutionsptyltd.github.io/roadie/components.md) instead.

Docs updated 23 Sept 2026.
