@o269/ui
v0.3.0
Published
Omnia Design System — tokens, components, Tailwind preset, and tenant theming for all Omnia ecosystem apps
Maintainers
Readme
@o269/ui
Omnia Design System — the single source of truth for tokens, components, Tailwind preset, and tenant theming across all Omnia ecosystem repos.
Install
npm install @o269/uiWhat's Inside
| Export | Description |
|--------|------------|
| @o269/ui | Everything (tokens + components + layouts + theme + logo) |
| @o269/ui/tokens | Design tokens as TypeScript objects (colors, typography, spacing) |
| @o269/ui/components | React components (Button, Card, Badge, DataTable, etc.) |
| @o269/ui/layouts | Layout components (DashboardLayout, AuthLayout) |
| @o269/ui/theme | ThemeProvider + useTheme hook for tenant branding |
| @o269/ui/logo | OmniaIcon, OmniaWordmark, OmniaLogo SVG components |
| @o269/ui/styles | CSS custom properties (tokens.css) |
| @o269/ui/styles/shadcn-bridge.css | shadcn/ui HSL compatibility layer |
| @o269/ui/styles/omnia-overrides.css | Focus rings, transitions, tabular nums |
| @o269/ui/styles/theme.css | Base reset + typography |
| @o269/ui/tailwind-preset | Tailwind 3.x JS preset |
| @o269/ui/tailwind-v4 | Tailwind 4.x CSS theme |
Integration by Tailwind Version
Tailwind 3.x (omnia-home-hub, contractor-hub, customer-hub, omnia-landing-page, omnia-logo-engine)
1. tailwind.config.ts
import type { Config } from "tailwindcss";
export default {
content: ["./src/**/*.{ts,tsx}"],
presets: [require("@o269/ui/tailwind-preset")],
} satisfies Config;2. Global CSS (src/index.css)
@import "@o269/ui/styles";
@import "@o269/ui/styles/shadcn-bridge.css";
@import "@o269/ui/styles/omnia-overrides.css";
@tailwind base;
@tailwind components;
@tailwind utilities;Tailwind 4.x (LGM, omnia-meta-agent, Cali-First dashboard)
1. Global CSS (app/globals.css)
@import "tailwindcss";
@import "@o269/ui/tailwind-v4";That's it. The tailwind-v4 import bundles tokens, shadcn bridge, overrides, and the @theme block.
Using Components
import { Button, Card, Badge, DataTable } from "@o269/ui/components";
import { DashboardLayout } from "@o269/ui/layouts";
import { OmniaLogo } from "@o269/ui/logo";
export function App() {
return (
<DashboardLayout sidebar={<Sidebar />}>
<OmniaLogo variant="horizontal" iconSize={28} />
<Card>
<Badge variant="success">Active</Badge>
<Button variant="primary" size="md">Save</Button>
</Card>
</DashboardLayout>
);
}Using Tokens Programmatically
import { colors, typography, spacing } from "@o269/ui/tokens";
console.log(colors.brand.primary); // "#0A0A0A"
console.log(typography.fontFamily.body); // "'Inter', ..."
console.log(spacing.space[4]); // "1rem"Tenant Branding (Client Customization)
Wrap your app in ThemeProvider to override brand colors, fonts, and logo:
import { ThemeProvider } from "@o269/ui/theme";
// Cali First Remodel branding
<ThemeProvider
theme={{
brandPrimary: "#2C5530", // Forest Green
brandPrimaryHover: "#1A3A1F", // Deep Pine
brandPrimaryForeground: "#FFFFFF",
fontHeading: "'Cormorant Garamond', serif",
fontBody: "'Inter', sans-serif",
}}
>
<App />
</ThemeProvider>The ThemeProvider sets CSS custom properties (--ui-brand-primary, etc.) on a wrapper div. All components and Tailwind utilities automatically pick up the overrides.
Fetch branding from API
import { useBranding } from "@o269/ui";
function BrandedApp({ tenantSlug }: { tenantSlug: string }) {
const { branding, loading } = useBranding(tenantSlug);
if (loading) return null;
return (
<ThemeProvider theme={{ brandPrimary: branding.primary_color }}>
<App />
</ThemeProvider>
);
}Migration Guide (for repos with manual token copies)
omnia-home-hub, contractor-hub, customer-hub
These repos currently have local copies of tokens.css, shadcn-bridge.css, and omnia-overrides.css in src/styles/. Replace them:
npm install @o269/ui- Delete
src/styles/tokens.css,src/styles/shadcn-bridge.css,src/styles/omnia-overrides.css - Update
src/index.css:
/* BEFORE (local copies) */
@import "./styles/tokens.css";
@import "./styles/shadcn-bridge.css";
@import "./styles/omnia-overrides.css";
/* AFTER (from package) */
@import "@o269/ui/styles";
@import "@o269/ui/styles/shadcn-bridge.css";
@import "@o269/ui/styles/omnia-overrides.css";- Update
tailwind.config.ts:
/* BEFORE */
presets: [require("../../packages/ui/tailwind.preset")],
/* AFTER */
presets: [require("@o269/ui/tailwind-preset")],Cali-First (brand/tokens.css)
Cali First has its own --cf-* token namespace. To adopt Omnia's system while keeping the Cali First brand:
npm install @o269/ui- In dashboard's
app/globals.css:
@import "tailwindcss";
@import "@o269/ui/tailwind-v4";- Wrap the app in ThemeProvider with Cali First colors:
<ThemeProvider
theme={{
brandPrimary: "#2C5530",
brandPrimaryHover: "#1A3A1F",
brandPrimaryForeground: "#FFFFFF",
fontHeading: "'Cormorant Garamond', serif",
}}
>LGM, omnia-meta-agent
These have minimal tokens. Just add:
@import "tailwindcss";
@import "@o269/ui/tailwind-v4";CSS Custom Properties Reference
All tokens are prefixed with --ui-:
| Namespace | Variables | Example |
|-----------|-----------|---------|
| --ui-bg-* | primary, secondary, tertiary, inverse, hover, active, sidebar | --ui-bg-primary: #FFFFFF |
| --ui-text-* | primary, secondary, tertiary, inverse, link | --ui-text-primary: #0A0A0A |
| --ui-border-* | default, subtle, strong, focus | --ui-border-default: #E5E7EB |
| --ui-status-* | success, warning, error, info | --ui-status-success: #10B981 |
| --ui-brand-* | primary, primary-hover, primary-foreground | Tenant-overridable |
| --ui-font-* | body, heading, mono, size-xs to 4xl, weight-* | --ui-font-body: 'Inter', ... |
| --ui-space-* | 1, 2, 3, 4, 6, 8, 12, 16, 20 | --ui-space-4: 1rem |
| --ui-radius-* | sm, md, lg, xl, full | --ui-radius-lg: 0.75rem |
Design Principles
- Attio-inspired: clean black/white/gray, no glassmorphism
- Borders over shadows: 1px subtle borders are the primary separator
- Sentence case: no uppercase transforms on headings or buttons
- Inter font: universal across all apps
- Tenant-overridable: brand colors and fonts via ThemeProvider + CSS vars
