@mehdashti/ui
v0.9.3
Published
Enterprise-grade React UI components with enhanced tabs, overflow handling, and declarative APIs
Downloads
943
Maintainers
Readme
@smart/ui
React UI components for Smart Platform
Installation
pnpm add @smart/ui @smart/tokensRequired peer dependencies:
pnpm add react react-domSetup
1. Import Theme CSS
import "@smart/tokens/theme.css";2. Configure Tailwind (if using)
// tailwind.config.js
export default {
content: [
"./src/**/*.{ts,tsx}",
"./node_modules/@smart/ui/dist/**/*.js",
],
theme: {
extend: {
colors: {
border: "var(--border)",
input: "var(--border)",
ring: "var(--primary)",
background: "var(--background)",
foreground: "var(--foreground)",
primary: {
DEFAULT: "var(--primary)",
foreground: "var(--primary-foreground)",
},
secondary: {
DEFAULT: "var(--secondary)",
foreground: "var(--secondary-foreground)",
},
destructive: {
DEFAULT: "var(--destructive)",
foreground: "var(--destructive-foreground)",
},
muted: {
DEFAULT: "var(--muted)",
foreground: "var(--muted-foreground)",
},
accent: {
DEFAULT: "var(--accent)",
foreground: "var(--accent-foreground)",
},
},
},
},
};Components
Button
import { Button } from "@smart/ui";
function App() {
return (
<>
<Button variant="default">Default</Button>
<Button variant="destructive">Delete</Button>
<Button variant="outline">Outline</Button>
<Button variant="secondary">Secondary</Button>
<Button variant="ghost">Ghost</Button>
<Button variant="link">Link</Button>
{/* Sizes */}
<Button size="sm">Small</Button>
<Button size="default">Default</Button>
<Button size="lg">Large</Button>
<Button size="icon">
<svg>...</svg>
</Button>
</>
);
}Input
import { Input } from "@smart/ui";
function App() {
return (
<>
<Input type="text" placeholder="Enter text" />
<Input type="email" placeholder="Enter email" />
<Input type="password" placeholder="Enter password" />
<Input type="file" />
{/* Disabled */}
<Input disabled placeholder="Disabled" />
{/* With error */}
<Input aria-invalid placeholder="Invalid input" />
</>
);
}Select
import {
Select,
SelectTrigger,
SelectValue,
SelectContent,
SelectItem,
SelectGroup,
SelectLabel,
} from "@smart/ui";
function App() {
return (
<Select>
<SelectTrigger className="w-[180px]">
<SelectValue placeholder="Select a fruit" />
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectLabel>Fruits</SelectLabel>
<SelectItem value="apple">Apple</SelectItem>
<SelectItem value="banana">Banana</SelectItem>
<SelectItem value="orange">Orange</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
);
}Utilities
cn (className merger)
import { cn } from "@smart/ui";
// Merge classes with proper precedence
const className = cn(
"base-class",
condition && "conditional-class",
"text-red-500 text-blue-500" // blue wins (last one)
);Styling
All components use CSS variables from @smart/tokens:
--primary,--primary-foreground--secondary,--secondary-foreground--destructive,--destructive-foreground--accent,--accent-foreground--muted,--muted-foreground--background,--foreground--border
Components automatically support dark mode via [data-theme="dark"].
Examples
Form with validation
import { Button, Input } from "@smart/ui";
import { useState } from "react";
function LoginForm() {
const [email, setEmail] = useState("");
const [isInvalid, setIsInvalid] = useState(false);
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
if (!email.includes("@")) {
setIsInvalid(true);
return;
}
// Submit
};
return (
<form onSubmit={handleSubmit} className="space-y-4">
<Input
type="email"
placeholder="Email"
value={email}
onChange={(e) => setEmail(e.target.value)}
aria-invalid={isInvalid}
/>
<Button type="submit">Sign in</Button>
</form>
);
}Architecture
- Radix UI: Accessibility primitives
- class-variance-authority: Variant management
- clsx + tailwind-merge: className merging
- CSS Variables: Theme integration with
@smart/tokens
Browser Support
- Chrome (latest)
- Firefox (latest)
- Safari (latest)
- Edge (latest)
