VVibeFlui

Themes

Generated UI previewTHEME DEFAULT

Themed users

#ActionsNameEmailStatus
1
Ada Lovelaceada@example.testactive
2
Grace Hoppergrace@example.testsuspended

VibeFlui’s built-in default preset — neutral grays, rounded surfaces, no custom class names.

Generated UI previewTHEME GLASS

Glass users

#ActionsNameEmailStatus
1
Ada Lovelaceada@example.testactive
2
Grace Hoppergrace@example.testsuspended

Same resource and rows as the default preset — only the theme’s class name slots and variants change the look.

This tutorial shows theme customization.

VibeFlui supports Tailwind class slots, variants, color mode classes, conditional class names, and class name resolvers. Theme switching itself is usually host app state that swaps schema or provider configuration.

File structure

TXT
app/
  users/
    page.tsx
schemas/
  users/
    themed-users.schema.ts
    glass-users.schema.ts

Basic theme schema

schemas/users/themed-users.schema.ts

TS
export const themedUsersSchema = {
  resource: "users",
  title: "Themed users",
  theme: {
    preset: "default",
    colorMode: "inherit",
    classNameMergeStrategy: "merge",
    classNames: {
      root: "space-y-4",
      tableWrapper: "rounded-lg border border-gray-200 bg-white shadow-sm",
      tableHeader: "bg-gray-50",
      form: "space-y-4",
      actionButton: "rounded-md"
    },
    variants: {
      actionButton: {
        primary: "bg-slate-900 text-white hover:bg-slate-800",
        danger: "bg-red-600 text-white hover:bg-red-700",
        ghost: "bg-transparent text-gray-700 hover:bg-gray-100"
      }
    }
  },
  table: {
    actionIcon: {
      hoverShape: "circle",
      hoverColor: "brand"
    },
    columns: ["name", "email", "status"]
  },
  form: {
    fields: ["name", "email", "status"]
  }
} as const;

Dark mode

Use theme.colorMode for root-level mode classes:

schemas/users/themed-users.schema.ts

TS
theme: {
  colorMode: "dark"
}

dark adds the dark class to the root. light adds fluikit-light. inherit adds no mode class and lets the host app control the surrounding theme.

Conditional row classes

schemas/users/themed-users.schema.ts

TS
theme: {
  classNameWhen: [
    {
      slot: "tableRow",
      when: { key: "status", operator: "equals", value: "suspended" },
      className: "bg-red-50 text-red-900"
    }
  ]
}

This works because table row theme resolution receives row data.

Custom theme example

This is a custom example, not a built-in preset.

schemas/users/glass-users.schema.ts

TS
export const glassUsersSchema = {
  resource: "users",
  title: "Glass users",
  theme: {
    preset: "custom",
    colorMode: "light",
    classNameMergeStrategy: "merge",
    classNames: {
      root: "rounded-2xl bg-white/60 p-6 text-slate-900 shadow-xl ring-1 ring-violet-200 backdrop-blur",
      layout: "mb-4 flex items-start justify-between gap-4",
      toolbar: "flex flex-wrap gap-2",
      tableWrapper: "overflow-hidden rounded-xl border border-violet-100 bg-white/70 shadow-sm",
      tableHeader: "bg-violet-50/70",
      tableRow: "hover:bg-violet-50/70",
      tableCell: "px-4 py-3 text-sm",
      form: "space-y-4",
      input: "w-full rounded-lg border border-violet-100 bg-white/80 px-3 py-2 text-sm shadow-sm outline-none focus:border-violet-300 focus:ring-2 focus:ring-violet-100",
      actionButton: "inline-flex min-h-9 items-center justify-center gap-2 rounded-lg px-3 py-2 text-sm font-medium transition"
    },
    variants: {
      actionButton: {
        primary: "bg-violet-600 text-white shadow-sm hover:bg-violet-700",
        secondary: "border border-violet-100 bg-white/80 text-violet-900 hover:bg-violet-50",
        danger: "bg-red-600 text-white hover:bg-red-700",
        ghost: "bg-transparent text-violet-900 hover:bg-violet-50"
      }
    }
  },
  table: {
    columns: ["name", "email", "status"]
  },
  form: {
    fields: ["name", "email", "status"]
  }
} as const;

Page usage

app/users/page.tsx

TSX
<FluiKit schema={glassUsersSchema} data={rows} />