Common Patterns
Code examples library for typical tasks
Displaying Code Examples
Quick Decision Guide
Need to show code?
├─ Inline snippet? →
└─ Multi-line block?
├─ No syntax colors needed? →
└─ With syntax highlighting? →
├─ Inline snippet? →
<Code>└─ Multi-line block?
├─ No syntax colors needed? →
<Code inline={false}>└─ With syntax highlighting? →
<CollapsibleCodeBlock> ✨Correct - Multi-Color Syntax Highlighting
import { CollapsibleCodeBlock } from '@thesage/ui';
// [Recommended]: Automatic syntax highlighting
<CollapsibleCodeBlock
id="unique-id"
code={`const greeting = "Hello World";
console.log(greeting);`}
defaultCollapsed={false}
showCopy={true}
/>Avoid - Single Color, No Highlighting
import { Code } from '@thesage/ui';
// [Avoid]: Single-color text, no syntax highlighting
<Code inline={false}>{`const greeting = "Hello World";
console.log(greeting);`}</Code>When to Use Each
<Code>- Inline code snippets like useState or single-line commands like pnpm install<Code inline={false}>- Plain text blocks where syntax highlighting isn't needed (configs, plain text output)<CollapsibleCodeBlock>- Multi-line code examples that benefit from syntax highlighting, copy button, and collapsible UIPro tip: CollapsibleCodeBlock automatically tokenizes string code for syntax highlighting. Just pass your code as a string - no manual tokenization needed! Each block needs a unique id prop.
Using Design Tokens
Accessing design tokens via CSS variables
export function MyComponent() {
return (
<div className="bg-[var(--color-primary)] text-[var(--color-primary-foreground)]">
<h1 className="text-[var(--font-size-heading-1)]">
Hello World
</h1>
<p className="text-[var(--color-text-secondary)]">
This component uses design tokens for theming
</p>
</div>
);
}Pro tip: Always use CSS variables (var(--token-name)) instead of hardcoded values. This ensures your component automatically adapts to theme changes.
Creating Theme-Aware Components
Components that adapt to the current theme
import { useTheme } from '@thesage/ui';
export function ThemedCard() {
const { theme } = useTheme();
return (
<div
className="p-6 rounded-lg"
style={{
backgroundColor: 'var(--color-surface)',
border: '1px solid var(--color-border)',
}}
>
<p className="text-[var(--color-text-primary)]">
Current theme: {theme}
</p>
</div>
);
}Adding Motion with Preference Detection
Using useMotionPreference hook with Framer Motion
import { motion } from 'framer-motion';
import { useMotionPreference } from '@thesage/ui';
export function AnimatedCard() {
const { shouldAnimate, scale } = useMotionPreference();
// Scale 5 (default) = 1x duration
// Duration: 0.3 is base duration for this animation
const duration = shouldAnimate && scale > 0
? 0.3 * (5 / scale)
: 0;
return (
<motion.div
initial={shouldAnimate ? { opacity: 0, y: 20 } : false}
animate={{ opacity: 1, y: 0 }}
transition={{ duration, ease: 'easeOut' }}
className="p-6 bg-[var(--color-surface)] rounded-lg"
>
<p>This card respects motion preferences</p>
</motion.div>
);
}Accessibility first: When shouldAnimate is false, set duration to 0 and disable position/scale animations. This respects user preferences and system settings.
Responsive Design Pattern
Mobile-first responsive component
export function ResponsiveGrid() {
return (
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
<Card className="p-4">Item 1</Card>
<Card className="p-4">Item 2</Card>
<Card className="p-4">Item 3</Card>
</div>
);
}Breakpoints:
- •
sm:640px (phones in landscape) - •
md:768px (tablets) - •
lg:1024px (desktops) - •
xl:1280px (large desktops)
Composing Components
Building a SearchBar from Input and Button components
import { Input, Button } from '@thesage/ui';
interface SearchBarProps {
placeholder?: string;
onSearch: (query: string) => void;
}
export function SearchBar({ placeholder, onSearch }: SearchBarProps) {
const [query, setQuery] = useState('');
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
onSearch(query);
};
return (
<form onSubmit={handleSubmit} className="flex gap-2">
<Input
value={query}
onChange={(e) => setQuery(e.target.value)}
placeholder={placeholder || 'Search...'}
className="flex-1"
/>
<Button type="submit" variant="default">
Search
</Button>
</form>
);
}Form Handling Pattern
Using the useForm hook for form validation
import { useForm, TextField, Button } from '@thesage/ui';
export function LoginForm() {
const { values, errors, handleChange, handleSubmit } = useForm({
initialValues: { email: '', password: '' },
validate: (values) => {
const errors: Record<string, string> = {};
if (!values.email) errors.email = 'Email is required';
if (!values.password) errors.password = 'Password is required';
return errors;
},
onSubmit: (values) => {
console.log('Form submitted:', values);
},
});
return (
<form onSubmit={handleSubmit} className="space-y-4">
<TextField
label="Email"
name="email"
type="email"
value={values.email}
onChange={handleChange}
error={errors.email}
/>
<TextField
label="Password"
name="password"
type="password"
value={values.password}
onChange={handleChange}
error={errors.password}
/>
<Button type="submit" variant="default">
Log In
</Button>
</form>
);
}Toast Notifications Pattern
Using the useToast hook for notifications
import { useToast, Button, ToastProvider } from '@thesage/ui';
function MyComponent() {
const { toast } = useToast();
const showSuccess = () => {
toast('Success!', 'success');
};
const showError = () => {
toast('Something went wrong', 'error');
};
return (
<div>
<Button onClick={showSuccess}>Show Success</Button>
<Button onClick={showError}>Show Error</Button>
</div>
);
}
// Wrap your app with ToastProvider
export function App() {
return (
<ToastProvider>
<MyComponent />
</ToastProvider>
);
}Modal Pattern
Using the Modal component with state management
import { useState } from 'react';
import { Modal, Button } from '@thesage/ui';
export function ConfirmDialog() {
const [isOpen, setIsOpen] = useState(false);
const handleConfirm = () => {
console.log('Confirmed!');
setIsOpen(false);
};
return (
<>
<Button onClick={() => setIsOpen(true)}>
Open Dialog
</Button>
<Modal
isOpen={isOpen}
onClose={() => setIsOpen(false)}
title="Confirm Action"
footer={
<>
<Button variant="secondary" onClick={() => setIsOpen(false)}>
Cancel
</Button>
<Button variant="default" onClick={handleConfirm}>
Confirm
</Button>
</>
}
>
<p>Are you sure you want to proceed?</p>
</Modal>
</>
);
}