@titan-design/react-ui
v0.1.1
Published
Cross-platform design system built on Gluestack UI
Maintainers
Readme
@titan-design/react-ui
A cross-platform design system built on React Native primitives with NativeWind (Tailwind CSS). Works on web and React Native.
Features
- Cross-platform: Components work on web (via react-native-web) and React Native
- Dark mode first: Dark theme by default with light mode support
- Accessible: Built with accessibility in mind (WCAG 2.1 AA)
- Customizable: Theme tokens and component styles are easy to override
- Type-safe: Full TypeScript support with strict mode
- Compound components: Flexible composition following Gluestack patterns
Installation
pnpm add @titan-design/react-uiPeer Dependencies
# For web
pnpm add react react-dom react-native-web lucide-react
# For React Native
pnpm add react react-native lucide-react-nativeSetup
1. Import Global CSS
// App.tsx or entry point
import '@titan-design/react-ui/theme/global.css'2. Configure Tailwind (optional, for custom styling)
// tailwind.config.js
module.exports = {
content: [
'./src/**/*.{js,jsx,ts,tsx}',
'./node_modules/@titan-design/react-ui/dist/**/*.{js,mjs}',
],
presets: [require('nativewind/preset')],
// Your customizations...
}Usage
import {
Button,
ButtonText,
ButtonIcon,
Typography,
Card,
CardHeader,
CardTitle,
CardContent,
Input,
InputGroup,
} from '@titan-design/react-ui'
import { Plus } from 'lucide-react'
function App() {
return (
<Card variant="elevated">
<CardHeader>
<CardTitle>Welcome</CardTitle>
</CardHeader>
<CardContent className="gap-4">
<Typography variant="body1">
This is a cross-platform card component.
</Typography>
<InputGroup>
<Input
placeholder="Enter your email"
label="Email"
/>
</InputGroup>
<Button color="primary" variant="solid">
<ButtonIcon as={Plus} />
<ButtonText>Get Started</ButtonText>
</Button>
</CardContent>
</Card>
)
}Components
Core UI Components
| Component | Description | |-----------|-------------| | Button | Primary action component with variants: solid, outline, ghost, link | | Input | Text input with label, helper text, and error states | | Card | Container component with header, content, footer | | Badge | Status indicator labels | | Spinner | Loading indicator | | Avatar | User/entity representation | | Divider | Visual separator | | Checkbox | Boolean input with group support | | Switch | Toggle input | | Modal | Dialog/overlay component |
Custom Components
| Component | Description | |-----------|-------------| | Typography | Consistent text styling (h1-h6, body, caption, etc.) | | Sidebar | Navigation sidebar with collapsible support | | Table | Data table with sorting and pagination | | EmptyState | Placeholder for empty data states |
Component API
Button
<Button
variant="solid" | "outline" | "ghost" | "link"
color="primary" | "secondary" | "success" | "error" | "warning" | "info"
size="sm" | "md" | "lg"
isDisabled={false}
isLoading={false}
onPress={() => {}}
>
<ButtonIcon as={IconComponent} />
<ButtonText>Button Text</ButtonText>
</Button>Input
<Input
label="Field Label"
placeholder="Placeholder text"
helperText="Helper text"
errorMessage="Error message"
variant="outline" | "filled" | "underlined"
size="sm" | "md" | "lg"
isDisabled={false}
isInvalid={false}
isReadOnly={false}
isRequired={false}
value={value}
onChangeText={setValue}
/>Typography
<Typography
variant="h1" | "h2" | "h3" | "h4" | "h5" | "h6" |
"body1" | "body2" | "caption" | "overline"
color="primary" | "secondary" | "tertiary" | "disabled"
>
Text content
</Typography>Card
<Card variant="default" | "elevated" | "outline" | "filled">
<CardHeader>
<CardTitle>Title</CardTitle>
</CardHeader>
<CardContent>
Content here
</CardContent>
<CardFooter>
<Button>Action</Button>
</CardFooter>
</Card>Theme
The design system uses CSS custom properties for theming. Dark mode is the default.
Using the Theme
Import the global CSS in your app:
import '@titan-design/react-ui/theme/global.css'Switching Themes
Add the light class to your root element for light mode:
// Dark mode (default)
<div>
{/* Your app */}
</div>
// Light mode
<div className="light">
{/* Your app */}
</div>Programmatic Theme Switching
function toggleTheme() {
document.documentElement.classList.toggle('light')
}Design Tokens
The design system uses a two-tier token system following DTCG conventions:
Token Categories
| Category | Pattern | Description |
|----------|---------|-------------|
| brand-* | brand-primary, brand-secondary | Brand identity colors |
| status-* | status-success, status-error, status-warning, status-info | Feedback colors |
| text-* | text-primary, text-secondary, text-tertiary | Text hierarchy |
| surface-* | surface-base, surface-elevated, surface-raised | Container backgrounds |
| background-* | background-base, background-default | Page backgrounds |
| border-* | border-default, border-subtle, border-strong | Border colors |
| interactive-* | interactive-hover, interactive-focus, interactive-active | State colors |
Using Tokens
// In components
<View className="bg-surface-elevated border border-border-default rounded-lg">
<Text className="text-text-primary">Primary text</Text>
<Text className="text-text-secondary">Secondary text</Text>
</View>Development
Storybook
pnpm storybookOpen http://localhost:6006 to view component documentation.
Testing
# Run tests
pnpm test
# Run tests with coverage
pnpm test:coverageBuild
pnpm buildStorybook Configuration
This package uses Storybook 10 with @storybook/react-native-web-vite for proper NativeWind support. Key configuration:
// .storybook/main.ts
framework: {
name: '@storybook/react-native-web-vite',
options: {
pluginReactOptions: {
jsxImportSource: 'nativewind',
},
},
}See the Storybook Setup Guide for detailed configuration.
Cross-Platform Notes
React Native Primitives
All components use React Native primitives for cross-platform compatibility:
| Web Element | React Native Equivalent |
|-------------|------------------------|
| div | View |
| span, p | Text |
| button | Pressable |
| input | TextInput |
| img | Image |
Platform-Specific Styles
Use NativeWind platform modifiers when needed:
<View className="p-4 web:hover:bg-gray-100 native:active:opacity-80">License
MIT
