# Component Patterns - tOS Frontend
## Layout Component Pattern
```tsx
// src/components/layout/sidebar.tsx
'use client';
import { usePathname } from 'next/navigation';
import { motion } from 'framer-motion';
import { useSidebarStore } from '@/stores/sidebar-store';
export function Sidebar({ locale }: { locale: string }) {
const { isExpanded, toggleSidebar } = useSidebarStore();
const pathname = usePathname();
return (
{/* Content */}
);
}
```
## Page with Metadata Pattern
```tsx
// page.tsx (Server Component)
import { Metadata } from 'next';
import { getTranslations } from 'next-intl/server';
import { ContentComponent } from './content-component';
export async function generateMetadata(): Promise {
const t = await getTranslations('namespace');
return { title: t('title') };
}
export default function Page() {
return ;
}
// content-component.tsx (Client Component)
'use client';
import { useTranslations } from 'next-intl';
export function ContentComponent() {
const t = useTranslations('namespace');
return {t('key')}
;
}
```
## Zustand Store Pattern
```tsx
// src/stores/sidebar-store.ts
import { create } from 'zustand';
import { persist } from 'zustand/middleware';
interface SidebarState {
isExpanded: boolean;
toggleSidebar: () => void;
}
export const useSidebarStore = create()(
persist(
(set) => ({
isExpanded: true,
toggleSidebar: () => set((state) => ({ isExpanded: !state.isExpanded })),
}),
{
name: 'tos-sidebar-state',
partialize: (state) => ({ isExpanded: state.isExpanded }),
}
)
);
```
## Animation Pattern with Framer Motion
```tsx
import { motion } from 'framer-motion';
// Staggered list animation
{items.map((item, index) => (
{item.content}
))}
```
## shadcn/ui Component with Variants
```tsx
// src/components/ui/button.tsx
import { cva, type VariantProps } from 'class-variance-authority';
const buttonVariants = cva(
'inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors',
{
variants: {
variant: {
default: 'bg-primary text-primary-foreground hover:bg-primary/90',
destructive: 'bg-destructive text-destructive-foreground',
outline: 'border border-input bg-background hover:bg-accent',
ghost: 'hover:bg-accent hover:text-accent-foreground',
},
size: {
default: 'h-9 px-4 py-2',
sm: 'h-8 px-3 text-xs',
lg: 'h-10 px-8',
icon: 'h-9 w-9',
},
},
defaultVariants: {
variant: 'default',
size: 'default',
},
}
);
export interface ButtonProps
extends React.ButtonHTMLAttributes,
VariantProps {
asChild?: boolean;
}
```
## Provider Composition Pattern
```tsx
// src/components/providers/index.tsx
'use client';
export function Providers({ children }: { children: ReactNode }) {
return (
{children}
);
}
```
## i18n Usage Pattern
```tsx
// In components
import { useTranslations } from 'next-intl';
export function Component() {
const t = useTranslations('namespace');
return {t('key', { param: 'value' })};
}
// In server components
import { getTranslations } from 'next-intl/server';
export async function ServerComponent() {
const t = await getTranslations('namespace');
return {t('key')};
}
```
## Protected Route Layout Pattern
```tsx
// src/app/[locale]/(auth)/layout.tsx
'use client';
export default function AuthLayout({ children, params: { locale } }) {
const { isExpanded } = useSidebarStore();
return (
);
}
```