Component Library Documentation
This document provides a comprehensive inventory of the reusable UI components in the Requests and Offers application.
Component Organization
Components are organized by domain with a feature-based approach, located in ui/src/lib/components:
/components/
├── service-types/ # Service type related components
├── requests/ # Request management components
├── offers/ # Offer management components
├── users/ # User profile components
├── organizations/ # Organization management components
├── tags/ # Tag related components
├── shared/ # Shared utility components
├── hrea/ # hREA integration components
├── moe/ # Medium of Exchange components
└── mediums-of-exchange/ # Medium of Exchange components
Core Components
Service Types Components
ServiceTypeCard.svelte
Purpose: Displays a service type with its metadata in a card format.
Props:
serviceType: ServiceTypeOutput - The service type to displayshowActions: boolean - Whether to show action buttons (edit, delete)compact: boolean - Whether to show a compact version of the card
Events:
edit: When edit button is clickeddelete: When delete button is clickedselect: When the card is selected
ServiceTypeSelector.svelte
Purpose: Multi-select component for choosing service types with search capability.
Props:
selectedServiceTypes: ServiceTypeOutput[] - Currently selected service typesmultiple: boolean - Whether multiple selection is allowedrequired: boolean - Whether selection is requireddisabled: boolean - Whether the component is disabled
Events:
selection: When selection changes, emits array of selected service typessearch: When search text changes
Requests/Offers Components
RequestForm.svelte / OfferForm.svelte
Purpose: Form for creating or editing a request/offer.
Props:
request/offer: Optional - Existing request/offer for editingserviceTypes: ServiceTypeOutput[] - Available service typesorganizations: OrganizationOutput[] - User's organizations
Events:
submit: When form is submitted successfullycancel: When form is cancellederror: When form submission fails
Users Components
UserName.svelte
Purpose: Renders a user's display name with the mononym sentinel stripped via formatUserName. Use wherever user.name would otherwise be interpolated directly.
Props:
user: UIUser | UserInDHT | { name?: string } | null | undefined - The user, or any object carrying anamefallback: string - Text shown when no name is available (default: "User")class: string - Optional CSS class applied to the wrapping<span>
Shared Components
TagAutocomplete.svelte
Purpose: Tag input with autocomplete suggestions.
Props:
selectedTags: string[] - Currently selected tagssuggestTags: boolean - Whether to show tag suggestionsmaxTags: number - Maximum number of tags allowed
Events:
update: When selected tags change
LoadingSpinner.svelte
Purpose: Consistent loading indicator for async operations.
Props:
size: 'small' | 'medium' | 'large' - Size of the spinnermessage: string - Optional loading message
ErrorDisplay.svelte
Purpose: Standardized error display component.
Props:
error: any - Error object to displayretry: () => void - Optional retry function
Styling and Theming
The application uses a combination of TailwindCSS and SkeletonUI for styling, with a custom theme defined in
src/happening_theme.ts.
Custom Theme Configuration
The Happening theme extends the base Skeleton theme with:
- Custom Colors: Brand-specific color palette with primary, secondary, and accent colors
- Typography: Custom font family and size scale
- Component Styling: Customized appearance for buttons, cards, and form elements
Using the Theme
Theme values should be accessed through Skeleton's theme system rather than hard-coding colors:
<!-- Recommended -->
<button class="btn variant-filled-primary">Submit</button>
<!-- Avoid -->
<button class="bg-blue-500 hover:bg-blue-600">Submit</button>
Custom Utility Classes
In addition to Tailwind's utility classes, the application defines several custom utilities for consistent styling:
.card-hover: Standard hover effects for cards.form-input-wrapper: Consistent styling for form inputs.tag-pill: Styling for tag elements
Best Practices
- Component Composition: Prefer composition over complex, monolithic components
- Props Typing: Always define proper TypeScript interfaces for component props
- Error Handling: Use ErrorDisplay component for consistent error presentation
- Loading States: Use LoadingSpinner for all asynchronous operations
- Accessibility: Ensure all components meet WCAG AA standards
Component Development Guidelines
- New Components: Place in appropriate domain folder
- Testing: Create component tests in corresponding test file
- Documentation: Update this document when adding new components
- Composition: Extract reusable logic to composables when appropriate