Skip to content

Issue #6: Set Up shadcn/ui Component Library #21

@wheval

Description

@wheval

Set Up shadcn/ui Component Library

Description:
Set up shadcn/ui for the UI component library, customize design tokens for the wallet brand, add wallet-specific components, and configure Storybook for component development.

Context:
The extension wallet needs a consistent, beautiful UI. Instead of building components from scratch, we'll use shadcn/ui - a collection of beautifully designed, accessible components built with Tailwind CSS and Radix UI. shadcn/ui copies components directly into your project (not an npm package), giving us full control to customize for our wallet needs.

Why shadcn/ui?

  • ✅ Built-in accessibility (uses Radix UI primitives)
  • ✅ Dark mode support out of the box
  • ✅ Tailwind CSS integration
  • ✅ Copy/paste components (full ownership)
  • ✅ TypeScript by default
  • ✅ Production-ready and battle-tested

Requirements:

  • Initialize shadcn/ui in packages/ui-kit (npx shadcn@latest init)
  • Customize Tailwind config with wallet brand colors (primary, secondary)
  • Configure dark mode (class-based strategy)
  • Install core shadcn/ui components: button, input, card, badge, separator
  • Create custom wallet-specific components (AmountInput, AddressDisplay)
  • Set up Storybook v7 for component preview
  • Write Storybook stories for all components
  • Add component tests with React Testing Library
  • Document design tokens (colors, spacing, radius)
  • Set up cn() utility for conditional classes

Implementation Guide:

1. Initialize shadcn/ui

cd packages/ui-kit
npx shadcn@latest init

This creates:

  • components.json (config)
  • tailwind.config.js (with design tokens)
  • lib/utils.ts (cn utility)

2. Add Components

npx shadcn@latest add button
npx shadcn@latest add input
npx shadcn@latest add card
npx shadcn@latest add badge
npx shadcn@latest add separator

Components are copied to src/components/ui/.

3. Customize Design Tokens

Edit tailwind.config.js:

module.exports = {
  theme: {
    extend: {
      colors: {
        primary: {
          DEFAULT: 'hsl(262 83% 58%)', // Purple for Stellar
          foreground: 'hsl(210 40% 98%)',
        },
        secondary: {
          DEFAULT: 'hsl(210 40% 96.1%)',
          foreground: 'hsl(222.2 47.4% 11.2%)',
        },
        // ... other tokens
      },
    },
  },
};

4. Usage Example

import { Button } from '@ancore/ui-kit/button';
import { Input } from '@ancore/ui-kit/input';
import { Card, CardHeader, CardContent } from '@ancore/ui-kit/card';

// shadcn/ui Button with variants
<Button variant="default" size="lg" onClick={handleSend}>
  Send Transaction
</Button>

// Input component
<Input
  type="number"
  placeholder="Amount"
  value={amount}
  onChange={(e) => setAmount(e.target.value)}
/>

// Card component
<Card>
  <CardHeader>
    <h3 className="font-semibold">Balance</h3>
  </CardHeader>
  <CardContent>
    <p className="text-2xl">100 XLM</p>
  </CardContent>
</Card>

5. Create Custom Wallet Components

// Custom AmountInput component
import { Input } from './ui/input';
import { Badge } from './ui/badge';

export function AmountInput({ 
  value, 
  onChange, 
  balance,
  asset = 'XLM' 
}: AmountInputProps) {
  return (
    <div className="space-y-2">
      <div className="flex justify-between">
        <label>Amount</label>
        <Badge variant="outline">{asset}</Badge>
      </div>
      <Input
        type="number"
        value={value}
        onChange={onChange}
        placeholder="0.00"
      />
      <p className="text-sm text-muted-foreground">
        Balance: {balance} {asset}
      </p>
    </div>
  );
}

Files to Create/Generate:

  • packages/ui-kit/components.json (shadcn config, generated by init)
  • packages/ui-kit/tailwind.config.js (generated, then customize)
  • packages/ui-kit/src/lib/utils.ts (cn utility, generated)
  • packages/ui-kit/src/components/ui/button.tsx (generated by shadcn)
  • packages/ui-kit/src/components/ui/input.tsx (generated by shadcn)
  • packages/ui-kit/src/components/ui/card.tsx (generated by shadcn)
  • packages/ui-kit/src/components/ui/badge.tsx (generated by shadcn)
  • packages/ui-kit/src/components/amount-input.tsx (custom wallet component)
  • packages/ui-kit/src/components/address-display.tsx (custom wallet component)
  • packages/ui-kit/.storybook/main.ts (Storybook config)
  • packages/ui-kit/src/**/*.stories.tsx (Storybook stories)
  • packages/ui-kit/src/**/*.test.tsx (React Testing Library tests)

Dependencies:

  • tailwindcss (^3.4.0) - CSS framework
  • tailwindcss-animate (^1.0.7) - Animation utilities (added by shadcn)
  • class-variance-authority (^0.7.0) - Variant management (added by shadcn)
  • clsx (^2.1.0) - Class name utility (added by shadcn)
  • tailwind-merge (^2.2.0) - Merge Tailwind classes (added by shadcn)
  • @radix-ui/react-* (various) - Accessible UI primitives (added per component)
  • lucide-react (^0.344.0) - Icon library
  • storybook (^7.6.0) - Component preview
  • @testing-library/react (^14.0.0) - Component testing

Note: shadcn/ui installs dependencies automatically when you add components.

Success Criteria:

  • shadcn/ui initialized and configured correctly
  • All core components (button, input, card, badge) installed
  • Custom wallet components (AmountInput, AddressDisplay) working
  • Dark mode toggles correctly
  • Components accessible (Radix UI primitives provide this)
  • Storybook shows all components with variants
  • Design tokens customized with wallet brand colors

Definition of Done:

  • shadcn/ui initialized (npx shadcn@latest init)
  • Core components added (button, input, card, badge, separator)
  • Tailwind config customized with wallet brand colors
  • Dark mode working (toggle between light/dark)
  • Custom wallet components created and documented
  • Storybook configured and running (pnpm storybook)
  • All components have Storybook stories
  • Component tests written with React Testing Library
  • Design tokens documented in README

Additional Resources:

Labels: ui, design-system, storybook, maintainer-only
Estimated Effort: 2-3 days (with shadcn/ui)
Priority: Critical
Assignee: Maintainers only

⚠️ Note: This issue is reserved for project maintainers. The design system establishes the visual identity and component standards for the entire project. Once established, contributors can help with individual feature screens.


Questions or need help? Join our Telegram community

Metadata

Metadata

Assignees

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions