Skip to main content
The design system is a shared UI component library built with React, Radix UI, and Tailwind CSS. It provides reusable components with consistent styling across the extension.

Package information

Package
string
@hls-downloader/design-system
Location
string
src/design-system/src/components/
Build output
string
dist/design-system.js

Core components

Button

A flexible button component with multiple variants and sizes. Location: src/design-system/src/components/ui/button.tsx:43
variant
string
default:"default"
Button style variant
  • default - Primary button with solid background
  • destructive - Red destructive action button
  • outline - Button with border, transparent background
  • secondary - Secondary button with muted colors
  • ghost - Transparent button that shows on hover
  • link - Text button styled as a link
size
string
default:"default"
Button size preset
  • default - Standard height (h-9, px-4, py-2)
  • sm - Small button (h-8, px-3)
  • lg - Large button (h-10, px-8)
  • icon - Square icon button (h-9, w-9)
asChild
boolean
default:"false"
Render as child element using Radix Slot
import { Button } from "@hls-downloader/design-system";

<Button onClick={handleDownload}>Download</Button>

Badge

Display small status indicators or labels. Location: src/design-system/src/components/ui/badge.tsx:30
variant
string
default:"default"
Badge color scheme
  • default - Primary colored badge
  • secondary - Muted secondary badge
  • destructive - Red warning/error badge
  • outline - Transparent with border
import { Badge } from "@hls-downloader/design-system";

<Badge variant="secondary">Ready</Badge>
<Badge variant="destructive">Failed</Badge>

Input

Standard text input field with consistent styling. Location: src/design-system/src/components/ui/input.tsx:8
type
string
default:"text"
HTML input type attribute
className
string
Additional CSS classes to merge with defaults
Extends all standard HTML input attributes.
import { Input } from "@hls-downloader/design-system";

<Input
  type="text"
  placeholder="https://.../playlist.m3u8"
  value={uri}
  onChange={(e) => setUri(e.target.value)}
/>

Progress

Displays progress indicator for async operations. Location: src/design-system/src/components/ui/progress.tsx:6
value
number
Progress value between 0 and 100
className
string
Additional CSS classes
import { Progress } from "@hls-downloader/design-system";

<Progress value={downloadProgress} />

Card

Container component for grouping related content. Location: src/design-system/src/components/ui/card.tsx:8
interactive
boolean
default:"false"
Enable hover effects and cursor pointer for clickable cards
className
string
Additional CSS classes
import { Card } from "@hls-downloader/design-system";

<Card interactive>
  <h3>Playlist name</h3>
  <p>Details</p>
</Card>

Switch

Toggle switch for boolean settings. Location: src/design-system/src/components/ui/switch.tsx:6 Built on @radix-ui/react-switch, accepts all Radix Switch.Root props.
import { Switch } from "@hls-downloader/design-system";

<Switch
  checked={enabled}
  onCheckedChange={setEnabled}
/>

Select

Dropdown select component with rich features. Location: src/design-system/src/components/ui/select.tsx:7 Composed of multiple sub-components:

Select

Root select component (Radix Select.Root)

SelectTrigger

Button that opens the dropdown

SelectContent

Dropdown container with animations

SelectItem

Individual selectable option

SelectValue

Displays the selected value

SelectGroup

Groups related options

SelectLabel

Label for option groups

SelectSeparator

Visual separator between options
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@hls-downloader/design-system";

<Select value={quality} onValueChange={setQuality}>
  <SelectTrigger>
    <SelectValue placeholder="Select quality" />
  </SelectTrigger>
  <SelectContent>
    <SelectItem value="1080p">1080p</SelectItem>
    <SelectItem value="720p">720p</SelectItem>
  </SelectContent>
</Select>

Tabs

Tabbed interface for organizing content. Location: src/design-system/src/components/ui/tabs.tsx:6
Built on Radix UI Tabs primitive with custom styling.
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@hls-downloader/design-system";

<Tabs defaultValue="sniffer">
  <TabsList>
    <TabsTrigger value="sniffer">Sniffer</TabsTrigger>
    <TabsTrigger value="downloads">Downloads</TabsTrigger>
  </TabsList>
  <TabsContent value="sniffer">
    Sniffer content
  </TabsContent>
  <TabsContent value="downloads">
    Downloads content
  </TabsContent>
</Tabs>

ScrollArea

Scrollable container with custom styled scrollbars. Location: src/design-system/src/components/ui/scroll-area.tsx
import { ScrollArea } from "@hls-downloader/design-system";

<ScrollArea className="h-[400px] w-full">
  {/* Long content */}
</ScrollArea>

Slider

Range input slider for numeric values. Location: src/design-system/src/components/ui/slider.tsx:6
value
number[]
Current slider value(s)
onValueChange
(value: number[]) => void
Callback when value changes
min
number
default:"0"
Minimum value
max
number
default:"100"
Maximum value
step
number
default:"1"
Step increment
import { Slider } from "@hls-downloader/design-system";

<Slider
  value={[concurrency]}
  onValueChange={([value]) => setConcurrency(value)}
  min={1}
  max={10}
  step={1}
/>

Separator

Visual divider between content sections. Location: src/design-system/src/components/ui/separator.tsx:6
orientation
string
default:"horizontal"
Direction of the separator
  • horizontal - Horizontal line (1px height, full width)
  • vertical - Vertical line (full height, 1px width)
decorative
boolean
default:"true"
Whether separator is purely decorative (affects accessibility)
import { Separator } from "@hls-downloader/design-system";

<div>
  <p>Section 1</p>
  <Separator className="my-4" />
  <p>Section 2</p>
</div>

HoverCard

Displays rich content on hover. Location: src/design-system/src/components/ui/hover-card.tsx:6 Composed of sub-components:
  • HoverCard - Root component
  • HoverCardTrigger - Element that triggers the hover
  • HoverCardContent - Content shown on hover
import {
  HoverCard,
  HoverCardContent,
  HoverCardTrigger,
} from "@hls-downloader/design-system";

<HoverCard>
  <HoverCardTrigger>Hover me</HoverCardTrigger>
  <HoverCardContent>
    <p>Additional information</p>
  </HoverCardContent>
</HoverCard>

AspectRatio

Maintains aspect ratio for responsive media. Location: src/design-system/src/components/ui/aspect-ratio.tsx:3
ratio
number
default:"1"
Width to height ratio (e.g., 16/9 for widescreen)
import { AspectRatio } from "@hls-downloader/design-system";

<AspectRatio ratio={16 / 9}>
  <img src="thumbnail.jpg" alt="Video thumbnail" />
</AspectRatio>

Hooks

useLocalStorage

Custom hook for persisting state to localStorage with automatic JSON serialization. Location: src/design-system/src/hooks/use-localstorage.ts:3
key
string
required
localStorage key to store the value under
initialValue
any
required
Default value if no stored value exists
Returns: [storedValue, setValue] - Tuple similar to useState
import { useLocalStorage } from "@hls-downloader/design-system";

const [settings, setSettings] = useLocalStorage("hls-settings", {
  concurrency: 5,
  fetchAttempts: 3,
});

useTheme

Detects and applies browser color scheme preference (light/dark mode). Location: src/design-system/src/hooks/use-theme.ts:9 Returns: { theme: "light" | "dark" } Automatically applies the dark class to document.documentElement when dark mode is preferred and keeps it synchronized with system preference changes.
import { useTheme } from "@hls-downloader/design-system";

function MyComponent() {
  const { theme } = useTheme();
  
  return <p>Current theme: {theme}</p>;
}

Utilities

cn (className merge)

Location: src/design-system/src/lib/utils.ts Utility function for merging Tailwind CSS classes with conflict resolution.
import { cn } from "@hls-downloader/design-system";

const classes = cn(
  "base-class",
  condition && "conditional-class",
  className
);

Dependencies

The design system is built on:
  • React 18.3.1 - UI library
  • Radix UI - Accessible component primitives
  • Tailwind CSS 3.4.14 - Utility-first CSS framework
  • class-variance-authority - Component variant management
  • Lucide React - Icon library

Development

pnpm --filter ./src/design-system run build
All components use two-space indentation. Add Storybook stories for new components.

Build docs developers (and LLMs) love