A Shadcn inspired version of RizzUI
bash
Using pnpm (recommended)
pnpm add @somaui/ui @headlessui/react @floating-ui/react @tailwindcss/postcss tailwind-variants tailwind-merge
Using npm
npm install @somaui/ui @headlessui/react @floating-ui/react @tailwindcss/postcss tailwind-variants tailwind-merge
Using yarn
yarn add @somaui/ui @headlessui/react @floating-ui/react @tailwindcss/postcss tailwind-variants tailwind-merge
Using bun
bun add @somaui/ui @headlessui/react @floating-ui/react @tailwindcss/postcss tailwind-variants tailwind-merge
`
$3
SomaUI uses Tailwind CSS v4 with CSS-first configuration. No tailwind.config.js needed! š
Create or update your app/globals.css (or src/app/globals.css for Next.js):
`css
@import 'tailwindcss';
@source '../../node_modules/@somaui/ui/dist';
@plugin '@tailwindcss/forms';
/ ā ļø Required: Dark mode variant /
@custom-variant dark (&:where([data-theme=dark], [data-theme=dark] *));
:root {
/ ā ļø Required: SomaUI color variables /
--background: oklch(100% 0 0); / #ffffff /
--foreground: oklch(40.17% 0 0); / #484848 /
--muted: oklch(91.58% 0 0); / #e3e3e3 /
--muted-foreground: oklch(66% 0 0); / #929292 /
/ Border tokens /
--border-radius: 0.5rem; / 8px /
--border-width: 0.0625rem; / 1px /
--border-color: oklch(90.37% 0 0); / #dfdfdf /
/ Text tokens /
--text-primary: oklch(0% 0 0); / #000000 /
--text-secondary: oklch(40.17% 0 0); / #484848 /
/ Primary colors /
--primary-lighter: oklch(91.58% 0 0); / #e3e3e3 /
--primary: oklch(17.76% 0 0); / #111111 /
--primary-dark: oklch(0% 0 0); / #000000 /
--primary-foreground: oklch(100% 0 0); / #ffffff /
/ Secondary colors /
--secondary-lighter: oklch(91.99% 0.0386 276.02); / #dde3ff /
--secondary: oklch(50.51% 0.2633 276.95); / #4e36f5 /
--secondary-dark: oklch(45.41% 0.2431 277.06); / #432ad8 /
--secondary-foreground: oklch(100% 0 0); / #ffffff /
/ Danger colors /
--red-lighter: oklch(89.99% 0.0393 14); / #f7d4d6 /
--red: oklch(59.6% 0.2445 29.23); / #ee0000 /
--red-dark: oklch(51.71% 0.2121 29.2338); / #c50000 /
/ Warning colors /
--orange-lighter: oklch(95.67% 0.0452 84.5695); / #ffefcf /
--orange: oklch(78.37% 0.1587 72.99); / #f5a623 /
--orange-dark: oklch(54.83% 0.1339 53.95); / #ab570a /
/ Info colors /
--blue-lighter: oklch(91.66% 0.0404 257.5078); / #d3e5ff /
--blue: oklch(57.31% 0.2144 258.25); / #0070f3 /
--blue-dark: oklch(51.58% 0.1888 258.27); / #0761d1 /
/ Success colors /
--green-lighter: oklch(92.79% 0.086 155.61); / #b9f9cf /
--green: oklch(64.01% 0.1776 148.74); / #11a849 /
--green-dark: oklch(53.79% 0.1441 149.52); / #11843c /
}
/ ā ļø Required: Dark theme /
[data-theme='dark'] {
--background: oklch(14.11% 0.0112 275.23); / #08090e /
--foreground: oklch(90.37% 0 0); / #dfdfdf /
--muted: oklch(32.11% 0 0); / #333333 /
--muted-foreground: oklch(51.03% 0 0); / #666666 /
--border-color: oklch(91.58% 0 0); / #e3e3e3 /
--text-primary: oklch(100% 0 0); / #ffffff /
--text-secondary: oklch(51.03% 0 0); / #666666 /
--primary-lighter: oklch(25.2% 0 0); / #222222 /
--primary: oklch(95.81% 0 0); / #f1f1f1 /
--primary-dark: oklch(100% 0 0); / #ffffff /
--primary-foreground: oklch(0% 0 0); / #000000 /
--secondary-lighter: oklch(26.35% 0.1154 280.96); / #1f165a /
--secondary-dark: oklch(85.2% 0.0733 276.238); / #c1cbff /
--red-lighter: oklch(27.08% 0.1111 29.23); / #500000 /
--red-dark: oklch(86.69% 0.0714 18.6304); / #ffc1c1 /
--orange-lighter: oklch(28.29% 0.0698 49.34); / #441d04 /
--orange-dark: oklch(93.15% 0.1175 98.83); / #fcea8b /
--blue-lighter: oklch(32.05% 0.0873 254.4); / #0d335e /
--blue-dark: oklch(90.53% 0.0611 225.72); / #b5e9ff /
--green-lighter: oklch(27.23% 0.0672 152.71); / #033016 /
--green-dark: oklch(92.79% 0.086 155.61); / #b9f9cf /
}
/ ā ļø Required: Map CSS variables to Tailwind colors /
@theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-muted: var(--muted);
--color-muted-foreground: var(--muted-foreground);
--border-radius: var(--border-radius);
--color-border: var(--border-color);
--color-text-primary: var(--text-primary);
--color-text-secondary: var(--text-secondary);
--color-primary-lighter: var(--primary-lighter);
--color-primary: var(--primary);
--color-primary-dark: var(--primary-dark);
--color-primary-foreground: var(--primary-foreground);
--color-secondary-lighter: var(--secondary-lighter);
--color-secondary: var(--secondary);
--color-secondary-dark: var(--secondary-dark);
--color-secondary-foreground: var(--secondary-foreground);
--color-red-lighter: var(--red-lighter);
--color-red: var(--red);
--color-red-dark: var(--red-dark);
--color-orange-lighter: var(--orange-lighter);
--color-orange: var(--orange);
--color-orange-dark: var(--orange-dark);
--color-blue-lighter: var(--blue-lighter);
--color-blue: var(--blue);
--color-blue-dark: var(--blue-dark);
--color-green-lighter: var(--green-lighter);
--color-green: var(--green);
--color-green-dark: var(--green-dark);
}
/ ----------------------------------- /
/ Autofill Styles /
/ ----------------------------------- /
/ Override browser autofill background for all input components /
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
input:-webkit-autofill:active,
textarea:-webkit-autofill,
textarea:-webkit-autofill:hover,
textarea:-webkit-autofill:focus,
textarea:-webkit-autofill:active {
-webkit-box-shadow: 0 0 0 1000px transparent inset !important;
-webkit-text-fill-color: inherit !important;
transition: background-color 5000s ease-in-out 0s;
caret-color: inherit;
}
/ Firefox autofill /
input:-moz-autofill,
input:-moz-autofill:hover,
input:-moz-autofill:focus,
input:-moz-autofill:active,
textarea:-moz-autofill,
textarea:-moz-autofill:hover,
textarea:-moz-autofill:focus,
textarea:-moz-autofill:active {
background-color: transparent !important;
color: inherit !important;
transition: background-color 5000s ease-in-out 0s;
}
`
$3
Update your postcss.config.mjs:
`js
const config = {
plugins: {
'@tailwindcss/postcss': {},
},
};
export default config;
`
Usage
That's it! You're ready to use SomaUI components. Import them individually for optimal tree-shaking:
`jsx
import { Button } from '@somaui/ui/button';
import { Input } from '@somaui/ui/input';
export default function App() {
return (
);
}
`
š” Tip: Import from general path (e.g., @somaui/ui) instead of the specific point for barrell import. Note that this is not condusive for tree-shaking and smaller bundle sizes.
Theme Support
$3
SomaUI works seamlessly with next-themes for theme switching:
`jsx
'use client';
import { ThemeProvider as NextThemeProvider } from 'next-themes';
export function ThemeProvider({ children }: React.PropsWithChildren<{}>) {
return (
enableSystem
defaultTheme="system"
disableTransitionOnChange
>
{children}
);
}
`
$3
Here's a ready-to-use theme switcher:
`jsx
'use client';
import React from 'react';
import { useTheme } from 'next-themes';
import { ActionIcon } from '@somaui/ui/action-icon';
import { Dropdown } from '@somaui/ui/dropdown';
import { MoonIcon, SunIcon } from '@heroicons/react/24/outline';
export function ThemeSwitcher() {
const { setTheme } = useTheme();
return (
Toggle theme
setTheme('light')}>Light
setTheme('dark')}>Dark
setTheme('system')}>System
);
}
``