Migrated from design-system-swarm with fresh git history.
Old project history preserved in /home/overbits/apps/design-system-swarm
Core components:
- MCP Server (Python FastAPI with mcp 1.23.1)
- Claude Plugin (agents, commands, skills, strategies, hooks, core)
- DSS Backend (dss-mvp1 - token translation, Figma sync)
- Admin UI (Node.js/React)
- Server (Node.js/Express)
- Storybook integration (dss-mvp1/.storybook)
Self-contained configuration:
- All paths relative or use DSS_BASE_PATH=/home/overbits/dss
- PYTHONPATH configured for dss-mvp1 and dss-claude-plugin
- .env file with all configuration
- Claude plugin uses ${CLAUDE_PLUGIN_ROOT} for portability
Migration completed: $(date)
🤖 Clean migration with full functionality preserved
25 KiB
Design System Component API Reference
Version: 1.0.0 Last Updated: December 7, 2025 Status: Complete
Table of Contents
- DsButton
- DsInput
- DsCard
- DsBadge
- DsToast
- DsWorkflow
- DsNotificationCenter
- DsActionBar
- DsToastProvider
- DsComponentBase
DsButton
A versatile button component with multiple variants and sizes.
Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
data-variant |
string | primary |
Button style variant: primary, secondary, outline, ghost, destructive, success, link |
data-size |
string | default |
Button size: sm, default, lg, icon, icon-sm, icon-lg |
disabled |
boolean | false |
Disables the button |
aria-label |
string | - | Accessible label for screen readers |
aria-disabled |
boolean | false |
Announces disabled state to assistive technology |
aria-pressed |
boolean | false |
For toggle buttons, announces pressed state |
Properties
// Read/Write
button.disabled = true;
button.ariaLabel = "Submit form";
// Read-only
button.isLoading; // boolean
button.isDarkMode(); // boolean
Methods
// Focus management
button.focus();
button.blur();
// Event emission
button.emit('custom-event', { detail: data });
// CSS variable access
button.getCSSVariable('--primary');
// Event waiting
await button.waitForEvent('ds-click');
// Utilities
button.debounce(fn, 300);
button.throttle(fn, 100);
Variants
Style Variants: primary, secondary, outline, ghost, destructive, success, link (7 variants) Sizes: sm, default, lg, icon, icon-sm, icon-lg (6 sizes) Total Combinations: 42 variants
CSS Classes
.ds-btn /* Base button */
.ds-btn[data-variant="primary"] /* Primary style */
.ds-btn[data-size="lg"] /* Large size */
.ds-btn:hover /* Hover state */
.ds-btn:active /* Active state */
.ds-btn:disabled /* Disabled state */
.ds-btn:focus-visible /* Focus visible */
Example Usage
<!-- Primary Button -->
<ds-button data-variant="primary" data-size="default">
Click me
</ds-button>
<!-- Icon Button -->
<ds-button data-variant="ghost" data-size="icon">
✕
</ds-button>
<!-- Destructive Button (Disabled) -->
<ds-button data-variant="destructive" disabled>
Delete
</ds-button>
<!-- Link Button -->
<ds-button data-variant="link">
Learn more →
</ds-button>
States
- default: Normal state
- hover: Mouse over or keyboard focus
- active: Pressed/clicked
- disabled: Cannot interact
- loading: Processing action (via aria-busy)
- focus: Keyboard focus
Accessibility
- ✅ WCAG 2.1 Level AA
- ✅ Keyboard navigation (Enter, Space)
- ✅ Screen reader support (aria-label, aria-disabled, aria-pressed)
- ✅ Focus indicators
- ✅ Sufficient color contrast (4.5:1 minimum)
DsInput
Text input component with multiple input types and validation states.
Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
type |
string | text |
Input type: text, password, email, number, search, tel, url |
value |
string | `` | Current input value |
placeholder |
string | `` | Placeholder text |
disabled |
boolean | false |
Disables the input |
data-state |
string | default |
State: default, focus, hover, disabled, error |
aria-invalid |
boolean | false |
Marks input as having invalid value |
aria-describedby |
string | - | ID of error message element |
aria-label |
string | - | Accessible label |
Properties
// Read/Write
input.value = "New value";
input.disabled = true;
input.placeholder = "Enter email";
// Read-only
input.isDarkMode(); // boolean
input.isFocused; // boolean
Methods
// Focus and blur
input.focus();
input.blur();
// Validation
input.validate(); // boolean
input.clear();
// Event handling
input.addEventListener('change', (e) => console.log(e.target.value));
input.addEventListener('input', (e) => console.log(e.target.value));
Input Types
- text - Standard text input
- password - Masked password input
- email - Email validation
- number - Numeric input
- search - Search-optimized input
- tel - Telephone number
- url - URL validation
CSS Classes
.ds-input /* Base input */
.ds-input[type="email"] /* Email input type */
.ds-input[data-state="error"] /* Error state */
.ds-input:disabled /* Disabled state */
.ds-input:focus /* Focus state */
Example Usage
<!-- Standard Text Input -->
<label for="username">Username</label>
<ds-input id="username" type="text" placeholder="Enter username" />
<!-- Email with Error State -->
<label for="email">Email</label>
<ds-input
id="email"
type="email"
data-state="error"
aria-invalid="true"
aria-describedby="email-error"
/>
<span id="email-error">Invalid email format</span>
<!-- Number Input (Disabled) -->
<label for="quantity">Quantity</label>
<ds-input
id="quantity"
type="number"
value="1"
disabled
/>
<!-- Password Input -->
<label for="password">Password</label>
<ds-input id="password" type="password" placeholder="••••••" />
States
- default: Normal state
- focus: Active focus
- hover: Mouse over
- disabled: Cannot interact
- error: Validation error
Accessibility
- ✅ WCAG 2.1 Level AA
- ✅ Proper label association
- ✅ aria-invalid and aria-describedby for errors
- ✅ Keyboard accessible
- ✅ Focus indicators
DsCard
Container component for grouping content.
Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
data-variant |
string | default |
Card style: default, interactive |
aria-label |
string | - | Card title/description |
Properties
// Read-only
card.isDarkMode(); // boolean
Methods
card.focus();
card.emit('card-clicked');
Variants
- default: Static card
- interactive: Clickable/hoverable card
CSS Classes
.ds-card /* Base card */
.ds-card[data-variant="interactive"] /* Interactive card */
.ds-card:hover /* Hover state */
Example Usage
<!-- Default Card -->
<ds-card>
<h3>Card Title</h3>
<p>Card content goes here</p>
</ds-card>
<!-- Interactive Card -->
<ds-card data-variant="interactive" aria-label="User Profile">
<h3>User Name</h3>
<p>Click to view profile</p>
</ds-card>
States
- default: Normal state
- hover: Mouse over (interactive only)
Accessibility
- ✅ WCAG 2.1 Level AA
- ✅ Semantic HTML (article/section)
- ✅ aria-label support
- ✅ Proper contrast ratios
DsBadge
Small label component for status/category indicators.
Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
data-variant |
string | default |
Badge style: default, secondary, outline, destructive, success, warning |
aria-label |
string | - | Badge description |
Properties
badge.isDarkMode(); // boolean
Variants
- default - Primary color badge
- secondary - Secondary color badge
- outline - Outlined badge
- destructive - Error/danger badge
- success - Success/positive badge
- warning - Warning badge
CSS Classes
.ds-badge /* Base badge */
.ds-badge[data-variant="success"] /* Success badge */
.ds-badge[data-variant="warning"] /* Warning badge */
Example Usage
<!-- Default Badge -->
<ds-badge>New</ds-badge>
<!-- Success Badge -->
<ds-badge data-variant="success">Active</ds-badge>
<!-- Destructive Badge -->
<ds-badge data-variant="destructive">Error</ds-badge>
<!-- Warning Badge -->
<ds-badge data-variant="warning">Attention</ds-badge>
Accessibility
- ✅ WCAG 2.1 Level AA
- ✅ aria-label for context
- ✅ Sufficient contrast
DsToast
Notification message displayed temporarily.
Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
data-type |
string | default |
Toast type: default, success, warning, error, info |
data-state |
string | visible |
State: entering, visible, exiting, swiped |
data-duration |
number | 3000 |
Duration in milliseconds |
role |
string | alert |
ARIA role |
aria-live |
string | polite |
Politeness level |
Properties
toast.type = "success";
toast.duration = 5000;
toast.isDarkMode(); // boolean
Methods
// Lifecycle
toast.show();
toast.hide();
toast.dismiss();
// Events
toast.addEventListener('ds-toast-enter', () => {});
toast.addEventListener('ds-toast-exit', () => {});
toast.addEventListener('ds-toast-action', (e) => {});
Types
- default - Default notification
- success - Success message
- warning - Warning message
- error - Error message
- info - Information message
States
- entering: Animating in
- visible: Fully visible
- exiting: Animating out
- swiped: Manually dismissed
Example Usage
<!-- Success Toast -->
<ds-toast data-type="success">
Profile updated successfully!
</ds-toast>
<!-- Error Toast with Action -->
<ds-toast data-type="error">
<span>Failed to load data</span>
<ds-button data-variant="ghost" data-size="sm">
Retry
</ds-button>
</ds-toast>
<!-- Info Toast (5 second duration) -->
<ds-toast data-type="info" data-duration="5000">
This is an informational message
</ds-toast>
Animations
- slideIn: Enter animation (300ms)
- slideOut: Exit animation (300ms)
- swipeOut: Manual dismiss animation (200ms)
Accessibility
- ✅ WCAG 2.1 Level AA
- ✅ role="alert" and aria-live="polite"
- ✅ Keyboard dismissal (Escape key)
- ✅ Screen reader announcement
- ✅ Reduced motion support
DsWorkflow
Step-by-step workflow visualization component.
Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
data-direction |
string | vertical |
Layout: vertical, horizontal |
data-current-step |
number | 0 |
Current step index (0-based) |
Structure
<ds-workflow data-direction="vertical">
<ds-workflow-step data-state="completed">Step 1</ds-workflow-step>
<ds-workflow-step data-state="active">Step 2</ds-workflow-step>
<ds-workflow-step data-state="pending">Step 3</ds-workflow-step>
</ds-workflow>
Step States
- pending - Not yet reached
- active - Currently on this step
- completed - Step finished
- error - Step failed (with pulse animation)
- skipped - Step was skipped
Properties
workflow.direction = "horizontal";
workflow.currentStep = 1;
workflow.steps; // Array of step elements
Methods
workflow.nextStep();
workflow.previousStep();
workflow.setStep(stepIndex);
workflow.completeStep(stepIndex);
workflow.errorStep(stepIndex);
workflow.skipStep(stepIndex);
CSS Classes
.ds-workflow /* Container */
.ds-workflow[data-direction="horizontal"] /* Horizontal layout */
.ds-workflow-step[data-state="active"] /* Active step */
.ds-workflow-step[data-state="error"] /* Error step (pulse animation) */
Example Usage
<!-- Vertical Workflow -->
<ds-workflow data-direction="vertical" data-current-step="1">
<ds-workflow-step data-state="completed">Account Setup</ds-workflow-step>
<ds-workflow-step data-state="active">Verify Email</ds-workflow-step>
<ds-workflow-step data-state="pending">Enable 2FA</ds-workflow-step>
<ds-workflow-step data-state="pending">Profile Complete</ds-workflow-step>
</ds-workflow>
<!-- Horizontal Workflow -->
<ds-workflow data-direction="horizontal">
<ds-workflow-step data-state="completed">1. Review</ds-workflow-step>
<ds-workflow-step data-state="completed">2. Confirm</ds-workflow-step>
<ds-workflow-step data-state="active">3. Processing</ds-workflow-step>
<ds-workflow-step data-state="pending">4. Complete</ds-workflow-step>
</ds-workflow>
<!-- Workflow with Error -->
<ds-workflow>
<ds-workflow-step data-state="completed">Step 1</ds-workflow-step>
<ds-workflow-step data-state="error">Step 2 - Failed</ds-workflow-step>
<ds-workflow-step data-state="skipped">Step 3</ds-workflow-step>
</ds-workflow>
Accessibility
- ✅ WCAG 2.1 Level AA
- ✅ aria-current="step" on active step
- ✅ Semantic step numbering
- ✅ Keyboard navigation
- ✅ Screen reader support
DsNotificationCenter
Notification inbox component for managing messages.
Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
data-layout |
string | compact |
Layout: compact, expanded |
data-group-by |
string | type |
Grouping: type, date, none |
data-state |
string | closed |
State: open, closed, loading |
Properties
notificationCenter.layout = "expanded";
notificationCenter.groupBy = "date";
notificationCenter.notifications; // Array
notificationCenter.unreadCount; // number
Methods
// Notification management
notificationCenter.addNotification(notification);
notificationCenter.removeNotification(id);
notificationCenter.clearAll();
notificationCenter.markAsRead(id);
// State
notificationCenter.open();
notificationCenter.close();
Notification Object
{
id: string, // Unique identifier
type: string, // "info" | "success" | "warning" | "error"
title: string, // Notification title
message: string, // Main message
timestamp: Date, // When it occurred
read: boolean, // Read status
action?: { // Optional action button
label: string,
callback: () => void
}
}
Variants
Layout: compact, expanded (2 layouts) GroupBy: type, date, none (3 grouping options) Total: 6 variants
Example Usage
<!-- Notification Center -->
<ds-notification-center
data-layout="expanded"
data-group-by="date"
data-state="open"
>
</ds-notification-center>
// Add notification
notificationCenter.addNotification({
id: 'notif-1',
type: 'success',
title: 'File uploaded',
message: 'Your file has been uploaded successfully',
timestamp: new Date(),
read: false,
action: {
label: 'View',
callback: () => console.log('View file')
}
});
// Listen to notification events
notificationCenter.addEventListener('ds-notification-click', (e) => {
console.log('Notification clicked:', e.detail);
});
States
- open: Notification center visible
- closed: Hidden
- loading: Fetching notifications
Accessibility
- ✅ WCAG 2.1 Level AA
- ✅ role="region" with aria-label
- ✅ Keyboard navigation
- ✅ aria-live updates
- ✅ Custom scrollbar for accessibility
DsActionBar
Fixed or sticky action bar for primary actions.
Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
data-position |
string | bottom |
Position: top, bottom, floating |
data-alignment |
string | center |
Alignment: left, center, right |
data-state |
string | default |
State: default, expanded, collapsed, dismissing |
Properties
actionBar.position = "bottom";
actionBar.alignment = "right";
actionBar.isDismissed; // boolean
Methods
actionBar.expand();
actionBar.collapse();
actionBar.dismiss();
actionBar.restore();
Variants
Positions: top, bottom, floating (3) Alignments: left, center, right (3) Total: 9 variants
CSS Classes
.ds-action-bar /* Base */
.ds-action-bar[data-position="bottom"] /* Bottom position */
.ds-action-bar[data-alignment="right"] /* Right alignment */
.ds-action-bar[data-state="dismissing"] /* Dismissal animation */
Example Usage
<!-- Bottom Center Action Bar -->
<ds-action-bar data-position="bottom" data-alignment="center">
<ds-button data-variant="primary">Save</ds-button>
<ds-button data-variant="ghost">Cancel</ds-button>
</ds-action-bar>
<!-- Top Right Action Bar (Floating) -->
<ds-action-bar data-position="floating" data-alignment="right">
<ds-button data-variant="primary">Create New</ds-button>
</ds-action-bar>
<!-- Dismissible Action Bar -->
<ds-action-bar
data-position="bottom"
data-alignment="center"
id="action-bar"
>
<ds-button data-variant="primary">Save</ds-button>
<ds-button data-variant="ghost">Dismiss</ds-button>
</ds-action-bar>
<script>
document.getElementById('action-bar').addEventListener('ds-dismiss', () => {
// Handle dismissal
});
</script>
States
- default: Fully visible
- expanded: Expanded state
- collapsed: Minimized state
- dismissing: Being dismissed (animation)
Accessibility
- ✅ WCAG 2.1 Level AA
- ✅ role="toolbar"
- ✅ Keyboard navigation
- ✅ aria-label for context
- ✅ Semantic button structure
DsToastProvider
Container for managing multiple toast notifications.
Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
data-position |
string | bottom-right |
Toast position: top-left, top-center, top-right, bottom-left, bottom-center, bottom-right |
Positions
- top-left - Upper left corner
- top-center - Top center
- top-right - Upper right corner
- bottom-left - Lower left corner
- bottom-center - Bottom center
- bottom-right - Lower right corner (default)
Properties
provider.position = "top-right";
provider.toasts; // Array of toast elements
provider.maxToasts; // number
Methods
// Toast management
provider.show(message, type, duration);
provider.showSuccess(message, duration);
provider.showError(message, duration);
provider.showWarning(message, duration);
provider.showInfo(message, duration);
provider.clearAll();
provider.getToast(id); // Get specific toast
Example Usage
<!-- Toast Provider -->
<ds-toast-provider data-position="bottom-right"></ds-toast-provider>
const provider = document.querySelector('ds-toast-provider');
// Show notifications
provider.showSuccess('Profile saved!', 3000);
provider.showError('Failed to load data', 5000);
provider.showWarning('This action cannot be undone', 4000);
provider.showInfo('New message received', 3000);
// Clear all toasts
provider.clearAll();
Auto-Stack
Toasts automatically stack vertically without overlapping.
Accessibility
- ✅ WCAG 2.1 Level AA
- ✅ aria-live="polite" for announcements
- ✅ Keyboard dismissal support
- ✅ Screen reader compatible
DsComponentBase
Base class for all design system components.
Properties
// Standard properties available on all components
component.disabled; // boolean
component.loading; // boolean
component.ariaLabel; // string
component.ariaDescribedBy; // string
component.ariaBusy; // boolean
component.ariaHidden; // boolean
component.role; // string
component.tabindex; // number
Methods
// Focus management
component.focus();
component.blur();
// Event handling
component.emit(eventName, detail);
component.addEventListener(event, callback);
component.removeEventListener(event, callback);
// CSS variables
component.getCSSVariable(varName); // Get value
component.setCSSVariable(varName, value);
// Theme detection
component.isDarkMode(); // boolean
// Utilities
component.debounce(fn, delay); // Debounce function
component.throttle(fn, interval); // Throttle function
component.waitForEvent(eventName); // Promise-based
// Lifecycle hooks
component.connectedCallback(); // When added to DOM
component.disconnectedCallback(); // When removed from DOM
component.attributeChangedCallback(name, oldValue, newValue);
component.render(); // Render method
Lifecycle Hooks
class CustomComponent extends DsComponentBase {
connectedCallback() {
super.connectedCallback();
console.log('Component mounted');
}
disconnectedCallback() {
super.disconnectedCallback();
console.log('Component unmounted');
}
attributeChangedCallback(name, oldValue, newValue) {
super.attributeChangedCallback(name, oldValue, newValue);
console.log(`${name} changed from ${oldValue} to ${newValue}`);
}
render() {
// Custom render logic
}
}
CSS Variables Available
All components have access to design tokens:
/* Colors */
--primary /* Primary accent color */
--secondary /* Secondary accent color */
--success /* Success/positive color */
--warning /* Warning color */
--destructive /* Error/destructive color */
--info /* Information color */
--foreground /* Text color */
--background /* Background color */
--card /* Card background */
--card-foreground /* Card text */
--muted-foreground /* Muted text */
--border /* Border color */
/* Spacing */
--space-1 through --space-10
/* Typography */
--text-xs, --text-sm, --text-base, --text-lg, --text-xl
/* Radius */
--radius, --radius-sm, --radius-lg
/* Transitions */
--duration-fast (0.1s)
--duration-normal (0.2s)
--duration-slow (0.3s)
--ease-default
/* Shadows */
--shadow-sm, --shadow-md, --shadow-lg
/* Z-index */
--z-toast
Example Custom Component
import { DsComponentBase } from '@company/design-system';
class CustomComponent extends DsComponentBase {
constructor() {
super();
this.attachShadow({ mode: 'open' });
}
connectedCallback() {
super.connectedCallback();
this.render();
this.addEventListener('click', this._onClick.bind(this));
}
attributeChangedCallback(name, oldValue, newValue) {
super.attributeChangedCallback(name, oldValue, newValue);
if (oldValue !== newValue) {
this.render();
}
}
render() {
const template = this.renderTemplate(`
<div class="custom-component">
<button>${this.ariaLabel || 'Click me'}</button>
</div>
`);
this.shadowRoot.innerHTML = '';
this.shadowRoot.appendChild(template);
}
_onClick() {
this.emit('custom-click', { timestamp: Date.now() });
}
static get observedAttributes() {
return ['aria-label', 'disabled', 'data-variant'];
}
}
customElements.define('custom-component', CustomComponent);
Common Patterns
Theme Switching
// Detect dark mode
const isDark = component.isDarkMode();
// Listen for theme changes
document.addEventListener('theme-change', (e) => {
console.log('Theme:', e.detail.theme); // 'light' or 'dark'
});
// Toggle dark mode
document.documentElement.classList.toggle('dark');
Event Handling
// Custom event emission
button.emit('action-complete', {
success: true,
message: 'Action completed'
});
// Event listening
button.addEventListener('action-complete', (e) => {
console.log(e.detail);
});
// Wait for event (Promise-based)
const result = await button.waitForEvent('action-complete');
CSS Customization
/* Override token values */
:root {
--primary: #0066cc;
--success: #10b981;
--space-4: 1.5rem;
}
/* Dark mode overrides */
:root.dark {
--primary: #3b82f6;
--success: #059669;
--foreground: #e5e7eb;
}
/* Component-specific overrides */
.ds-btn[data-variant="primary"] {
background: var(--primary);
padding: var(--space-4) var(--space-6);
}
Accessibility Patterns
<!-- Form with error -->
<label for="email">Email</label>
<ds-input
id="email"
type="email"
aria-invalid="true"
aria-describedby="email-error"
/>
<span id="email-error" role="alert">Invalid email format</span>
<!-- Button with icon -->
<ds-button aria-label="Close dialog">✕</ds-button>
<!-- Disabled state -->
<ds-button aria-disabled="true">Save</ds-button>
<!-- Loading state -->
<ds-button aria-busy="true">Loading...</ds-button>
Browser Support
- Chrome 88+
- Firefox 85+
- Safari 14+
- Edge 88+
Web Components features required:
- Custom Elements v1
- Shadow DOM
- HTML Templates
Version History
- v1.0.0 (December 7, 2025) - Initial production release
- 9 components
- 123 variants
- 42 design tokens
- WCAG 2.1 AA compliance
- Full dark mode support
- 115+ tests
For questions or issues, visit: design-system@company.com