Skip to main content

Overview

The @trendingsociety/ui package is the single source of truth for all UI components. It contains 42 shadcn/ui components consolidated from across the monorepo.
Rule: Never duplicate components in apps. Always import from @trendingsociety/ui.

Installation

Already included in all apps via workspace dependency:
{
  "dependencies": {
    "@trendingsociety/ui": "workspace:*"
  }
}

Usage

import {
  Button,
  Card,
  CardHeader,
  CardTitle,
  CardContent,
  Dialog,
  DialogTrigger,
  DialogContent
} from '@trendingsociety/ui';

export function MyComponent() {
  return (
    <Card>
      <CardHeader>
        <CardTitle>Title</CardTitle>
      </CardHeader>
      <CardContent>
        <Dialog>
          <DialogTrigger asChild>
            <Button>Open</Button>
          </DialogTrigger>
          <DialogContent>
            Content here
          </DialogContent>
        </Dialog>
      </CardContent>
    </Card>
  );
}

Available Components

Layout

ComponentDescription
CardContainer with header, content, footer
AccordionExpandable sections
TabsTabbed interface
SeparatorVisual divider
ScrollAreaCustom scrollbar
CollapsibleToggle visibility

Forms

ComponentDescription
ButtonPrimary action button
InputText input field
TextareaMulti-line input
SelectDropdown selection
CheckboxToggle option
SwitchOn/off toggle
RadioGroupSingle selection
LabelForm labels
FormReact Hook Form wrapper

Feedback

ComponentDescription
AlertInline messages
BadgeStatus indicators
ProgressLoading progress
SkeletonLoading placeholder
ToastNotifications
TooltipHover hints

Overlays

ComponentDescription
DialogModal dialog
SheetSlide-out panel
DrawerBottom sheet
PopoverFloating content
AlertDialogConfirmation modal
ComponentDescription
SidebarApp navigation
BreadcrumbPath navigation
DropdownMenuAction menus
CommandCommand palette

Data Display

ComponentDescription
TableData tables
AvatarUser images
CalendarDate picker
ChartRecharts wrapper

Data Table Components

ComponentDescription
DataTableColumnHeaderSortable column headers
DataTableFacetedFilterMulti-select filters
DataTablePaginationPage controls
DataTableViewOptionsColumn visibility

Variants

Button Variants

<Button variant="default">Default</Button>
<Button variant="secondary">Secondary</Button>
<Button variant="outline">Outline</Button>
<Button variant="ghost">Ghost</Button>
<Button variant="destructive">Delete</Button>
<Button variant="link">Link</Button>
Never use variant="danger". Use variant="destructive" instead.

Button Sizes

<Button size="default">Default</Button>
<Button size="sm">Small</Button>
<Button size="lg">Large</Button>
<Button size="icon">Icon</Button>

Common Patterns

Card with Actions

<Card>
  <CardHeader className="flex flex-row items-center justify-between">
    <CardTitle>Users</CardTitle>
    <Button size="sm">Add User</Button>
  </CardHeader>
  <CardContent>
    <Table>...</Table>
  </CardContent>
</Card>

Confirmation Dialog

<AlertDialog>
  <AlertDialogTrigger asChild>
    <Button variant="destructive">Delete</Button>
  </AlertDialogTrigger>
  <AlertDialogContent>
    <AlertDialogHeader>
      <AlertDialogTitle>Are you sure?</AlertDialogTitle>
      <AlertDialogDescription>
        This action cannot be undone.
      </AlertDialogDescription>
    </AlertDialogHeader>
    <AlertDialogFooter>
      <AlertDialogCancel>Cancel</AlertDialogCancel>
      <AlertDialogAction onClick={handleDelete}>Delete</AlertDialogAction>
    </AlertDialogFooter>
  </AlertDialogContent>
</AlertDialog>

Form with Validation

import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';
import { Form, FormField, FormItem, FormLabel, FormControl, FormMessage } from '@trendingsociety/ui';

const schema = z.object({
  email: z.string().email(),
  name: z.string().min(2)
});

export function UserForm() {
  const form = useForm({
    resolver: zodResolver(schema)
  });

  return (
    <Form {...form}>
      <form onSubmit={form.handleSubmit(onSubmit)}>
        <FormField
          control={form.control}
          name="email"
          render={({ field }) => (
            <FormItem>
              <FormLabel>Email</FormLabel>
              <FormControl>
                <Input {...field} />
              </FormControl>
              <FormMessage />
            </FormItem>
          )}
        />
        <Button type="submit">Submit</Button>
      </form>
    </Form>
  );
}

Adding New Components

1

Check if it exists

Look in packages/ui/src/components/ first
2

Install via shadcn

cd packages/ui
npx shadcn@latest add [component]
3

Export from index

Add to packages/ui/src/index.ts
4

Use in apps

import { NewComponent } from '@trendingsociety/ui';

Icons

Use Lucide React or Tabler Icons:
import { Home, Settings, User } from 'lucide-react';
import { IconBrandShopify } from '@tabler/icons-react';

<Button>
  <Home className="w-4 h-4 mr-2" />
  Home
</Button>