- Presets
- Primary
- Secondary
- Dark
- Font
- Radius
Theme
Compose colors, type, and radius.
Pick a style preset, then tune primary, secondary, and dark colors from the Tailwind palette plus font and radius. Preview updates live — grab the CSS and provider snippet when you are ready.
Theme builder
Changes stay scoped to the preview. Your site chrome and other pages keep the default Bridge theme.
Menu
Live preview
Savings targets
Retirement
$420,000 · 65%
Real estate
$85,000 · 32%
Claimable balance
$0.00
Payout threshold
Recent activity
- BB-$12.40
Blue Bottle
Food & Drink
- PR+$2,400
Payroll
Income
- SP-$10.99
Spotify
Subscription
<script setup lang="ts">
import { Avatar } from "@bridge-ui/vue/Components/Avatar";
import { Badge } from "@bridge-ui/vue/Components/Badge";
import { Button } from "@bridge-ui/vue/Components/Button";
import { Card } from "@bridge-ui/vue/Components/Card";
import { NumberField } from "@bridge-ui/vue/Components/NumberField";
import { Progress } from "@bridge-ui/vue/Components/Progress";
import { Select } from "@bridge-ui/vue/Components/Select";
import { Switch } from "@bridge-ui/vue/Components/Switch";
import { TextField } from "@bridge-ui/vue/Components/TextField";
import { Bell, Plus, Save } from "@lucide/vue";
import { ref } from "vue";
const currencies = [
{ value: "usd", label: "USD" },
{ value: "eur", label: "EUR" },
{ value: "brl", label: "BRL" },
];
const currency = ref("usd");
const amount = ref(2500);
const notify = ref(true);
const notes = ref("");
const activity = [
{
initials: "BB",
amount: "-$12.40",
name: "Blue Bottle",
detail: "Food & Drink",
},
{ initials: "PR", name: "Payroll", detail: "Income", amount: "+$2,400" },
{
initials: "SP",
name: "Spotify",
amount: "-$10.99",
detail: "Subscription",
},
];
</script>
<template>
<div class="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
<Card title="Savings targets" class="sm:col-span-2 lg:col-span-2">
<template #action>
<Button size="xs" variant="outline" :start-icon="Plus">New goal</Button>
</template>
<div class="flex flex-col gap-5">
<div class="flex flex-col gap-2">
<div class="flex items-center justify-between gap-3">
<div>
<p class="m-0 text-sm font-medium">Retirement</p>
<p class="m-0 text-xs text-dark-500">$420,000 · 65%</p>
</div>
<Badge variant="flat" color="primary">65%</Badge>
</div>
<Progress :value="65" color="primary" variant="determinate" />
</div>
<div class="flex flex-col gap-2">
<div class="flex items-center justify-between gap-3">
<div>
<p class="m-0 text-sm font-medium">Real estate</p>
<p class="m-0 text-xs text-dark-500">$85,000 · 32%</p>
</div>
<Badge variant="flat" color="secondary">32%</Badge>
</div>
<Progress :value="32" color="secondary" variant="determinate" />
</div>
</div>
</Card>
<Card title="Claimable balance">
<p class="m-0 mb-4 text-4xl tracking-tight">$0.00</p>
<div class="flex flex-wrap gap-2">
<Button size="sm" color="primary">View all</Button>
<Button size="sm" color="dark" variant="outline" :start-icon="Bell">
Email alerts
</Button>
</div>
</Card>
<Card title="Payout threshold" class="sm:col-span-2 lg:col-span-2">
<div class="grid gap-4 sm:grid-cols-2">
<Select
v-model="currency"
:options="currencies"
without-error-message
label="Preferred currency"
/>
<NumberField v-model="amount" label="Minimum amount" />
<TextField
label="Notes"
v-model="notes"
class="sm:col-span-2"
placeholder="Optional notes…"
/>
<Switch
v-model="notify"
class="sm:col-span-2"
end-label="Email alerts"
/>
</div>
<template #footer>
<div class="flex justify-end">
<Button color="primary" :start-icon="Save">Save threshold</Button>
</div>
</template>
</Card>
<Card title="Recent activity">
<ul class="m-0 flex list-none flex-col gap-3 p-0">
<li
:key="item.name"
v-for="item in activity"
class="flex items-center gap-3"
>
<Avatar size="sm" color="primary" :fallback="item.initials" />
<div class="min-w-0 flex-1">
<p class="m-0 truncate text-sm font-medium">{{ item.name }}</p>
<p class="m-0 truncate text-xs text-dark-500">{{ item.detail }}</p>
</div>
<span class="shrink-0 text-sm font-medium">{{ item.amount }}</span>
</li>
</ul>
<div class="mt-4">
<Button size="sm" color="dark" variant="flat" :start-icon="Plus">
Add
</Button>
</div>
</Card>
</div>
</template>
import { Avatar } from "@bridge-ui/react/Components/Avatar";
import { Badge } from "@bridge-ui/react/Components/Badge";
import { Button } from "@bridge-ui/react/Components/Button";
import { Card } from "@bridge-ui/react/Components/Card";
import { NumberField } from "@bridge-ui/react/Components/NumberField";
import { Progress } from "@bridge-ui/react/Components/Progress";
import { Select } from "@bridge-ui/react/Components/Select";
import { Switch } from "@bridge-ui/react/Components/Switch";
import { TextField } from "@bridge-ui/react/Components/TextField";
import { Bell, Plus, Save } from "lucide-react";
import { useState } from "react";
const currencies = [
{ value: "usd", label: "USD" },
{ value: "eur", label: "EUR" },
{ value: "brl", label: "BRL" },
];
export function Dashboard() {
const [currency, setCurrency] = useState("usd");
const [notify, setNotify] = useState(true);
const [notes, setNotes] = useState("");
return (
<div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
<Card
title="Savings targets"
className="sm:col-span-2 lg:col-span-2"
slots={{
action: (
<Button size="xs" startIcon={Plus} variant="outline">
New goal
</Button>
),
}}
>
<div className="flex flex-col gap-5">
<div className="flex flex-col gap-2">
<div className="flex items-center justify-between gap-3">
<div>
<p className="m-0 text-sm font-medium">Retirement</p>
<p className="m-0 text-xs text-dark-500">$420,000 · 65%</p>
</div>
<Badge variant="flat" color="primary">
65%
</Badge>
</div>
<Progress value={65} color="primary" variant="determinate" />
</div>
<div className="flex flex-col gap-2">
<div className="flex items-center justify-between gap-3">
<div>
<p className="m-0 text-sm font-medium">Real estate</p>
<p className="m-0 text-xs text-dark-500">$85,000 · 32%</p>
</div>
<Badge variant="flat" color="secondary">
32%
</Badge>
</div>
<Progress value={32} color="secondary" variant="determinate" />
</div>
</div>
</Card>
<Card title="Claimable balance">
<p className="m-0 mb-4 text-4xl tracking-tight">$0.00</p>
<div className="flex flex-wrap gap-2">
<Button size="sm" color="primary">
View all
</Button>
<Button size="sm" color="dark" startIcon={Bell} variant="outline">
Email alerts
</Button>
</div>
</Card>
<Card
title="Payout threshold"
className="sm:col-span-2 lg:col-span-2"
slots={{
footer: (
<div className="flex justify-end">
<Button color="primary" startIcon={Save}>
Save threshold
</Button>
</div>
),
}}
>
<div className="grid gap-4 sm:grid-cols-2">
<Select
value={currency}
hideErrorMessage
options={currencies}
label="Preferred currency"
onChange={(value) => {
if (typeof value === "string") setCurrency(value);
}}
/>
<NumberField defaultValue={2500} label="Minimum amount" />
<TextField
value={notes}
label="Notes"
className="sm:col-span-2"
placeholder="Optional notes…"
onChange={(event) => setNotes(event.target.value)}
/>
<Switch
checked={notify}
endLabel="Email alerts"
className="sm:col-span-2"
onChange={(event) => setNotify(event.target.checked)}
/>
</div>
</Card>
<Card title="Recent activity">
<ul className="m-0 flex list-none flex-col gap-3 p-0">
{[
{
initials: "BB",
amount: "-$12.40",
name: "Blue Bottle",
detail: "Food & Drink",
},
{
initials: "PR",
name: "Payroll",
detail: "Income",
amount: "+$2,400",
},
{
initials: "SP",
name: "Spotify",
amount: "-$10.99",
detail: "Subscription",
},
].map((item) => (
<li key={item.name} className="flex items-center gap-3">
<Avatar size="sm" color="primary" fallback={item.initials} />
<div className="min-w-0 flex-1">
<p className="m-0 truncate text-sm font-medium">{item.name}</p>
<p className="m-0 truncate text-xs text-dark-500">
{item.detail}
</p>
</div>
<span className="shrink-0 text-sm font-medium">
{item.amount}
</span>
</li>
))}
</ul>
<div className="mt-4">
<Button size="sm" color="dark" variant="flat" startIcon={Plus}>
Add
</Button>
</div>
</Card>
</div>
);
}