Skip to content

Components ​

@meddleware/ui exports a Vue 3 component library. All components are styled exclusively via CSS custom properties from @meddleware/design-tokens — no hardcoded values.

Installation ​

bash
npm install @meddleware/ui @meddleware/design-tokens

vue ^3.5.0 is a peer dependency — supply your own.

Layout shell ​

The three shell components share an identical prop API:

vue
<AppHeader variant="dark" />
<AppSidebar variant="light" />
<AppFooter variant="transparent" :docs-url="DOCS_URL" :dev-url="DEV_URL" />
PropTypeDefaultDescription
variant'dark' | 'light' | 'transparent''transparent'Colour scheme for the shell component (theme-independent — 'dark' renders correctly on a light page)
colorsPanelColors—Per-instance override of any --mw-panel-* token
docsUrlstring—AppFooter only — "Documentation" link href
devUrlstring—AppFooter only — "Developer docs" link href

Slots ​

AppHeader and AppSidebar expose named slots for custom content:

vue
<AppHeader variant="dark">
  <template #logo><!-- custom logo --></template>
  <template #nav><!-- nav links --></template>
  <template #actions>
    <ColorModeControl v-model="mode" />
  </template>
</AppHeader>

<AppSidebar variant="light">
  <template #head><!-- sidebar header --></template>
  <template #default>
    <SidebarItem label="Overview" :active="true" />
    <SidebarItem label="Settings" />
  </template>
  <template #foot><!-- sidebar footer --></template>
</AppSidebar>

Colour mode ​

ts
import { useColorMode } from '@meddleware/ui'
import type { ColorMode } from '@meddleware/ui'

const { mode } = useColorMode()   // ColorMode: 'light' | 'dark' | 'system'
mode.value = 'dark'               // sets data-theme="dark" on <html>, persists to localStorage

ColorModeControl is a presentational toggle — bind with v-model:

vue
<ColorModeControl v-model="mode" />

Primitives ​

ComponentPropsNotes
UiButtonnative <button> attrsStyled with --accent, --focus-ring, --transition-base
UiCard—--surface background, --border, --radius
UiSelectnative <select> attrsStyled with scale tokens; --focus-ring on focus
UiNoticevariant: 'info' | 'warning' | 'danger' | 'ok'Uses status role tokens
SidebarItemlabel, icon?, active?, disabled?Navigation item for AppSidebar
CopyableAddressaddress, truncate?, chars?, label?Copy-to-clipboard with icon; slot for link
ExplorerLinkhref, value?External block-explorer link; compose inside CopyableAddress
vue
<CopyableAddress :address="addr">
  <ExplorerLink :href="suiExplorerUrl('account', addr, 'testnet')" :value="addr" />
</CopyableAddress>

Explorer helper ​

ts
import { suiExplorerUrl } from '@meddleware/ui'

const url = suiExplorerUrl('txblock', txDigest, 'testnet')
// → https://suiscan.xyz/testnet/tx/<txDigest>

Supported kinds: 'account', 'object', 'txblock'. Network defaults to 'testnet'.

CSS utilities (base.css) ​

Import @meddleware/ui/base.css to get element-level defaults and opt-in utility classes:

ClassEffect
.mw-noiseApplies --noise-overlay as a ::before layer — controlled imperfection
.mw-spinnerSigil-like ring loader animation (settles on prefers-reduced-motion)
.mw-hand-drawnEmpty positioned hook — drop an <svg> or <canvas> inside for bespoke illustration
.mw-monoMonospace font via --mw-font-mono

All animations respect prefers-reduced-motion.

2026 Meddleware. All jams preserved.