Dashboard Widgets & Components
The Fuwafuwa Framework includes a comprehensive library of UI components accessible via custom HTML tags. These components provide consistent styling, responsive behavior, and Alpine.js integration, making it easy to build professional-looking dashboards and interfaces.
Each component is designed to be reusable, accessible, and customizable. They follow the latest web design standards and include support for both light and dark modes.
- Custom
<ff:*>tag syntax - Automatic dark mode support
- Alpine.js integration
- Responsive design
- Semantic CSS classes
Stats Card <ff:stats>
A card displaying a statistic with optional trend indicator and icon. The stats card is perfect for highlighting key metrics on your dashboard or interface.
It supports optional trend indicators to show whether the statistic is increasing or decreasing, and you can add icons to make the card more visually appealing.
Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
title | string | required | Label for the statistic |
value | string | required | Main value to display |
trend | string | empty | Trend percentage (e.g., "+12.5%") |
trendUp | boolean | false | true for positive trend (green) |
icon | string | empty | Icon name from heroicons |
color | string | blue | Color variant |
href | string | empty | Optional URL for clickable card |
coattr | string | empty | Container attributes |
Examples
<!-- Basic Stats Card -->
<ff:stats title="Total Users" value="1,234" />
<!-- With Trend -->
<ff:stats
title="Revenue"
value="$45,678"
trend="+12.5%"
trendUp="true"
/>
<!-- With Icon and Link -->
<ff:stats
title="Active Sessions"
value="456"
icon="users"
href="/sessions"
/>
Chart <ff:chart>
A wrapper for ApexCharts displaying data visualizations. The chart component allows you to create a variety of chart types, including line charts, bar charts, pie charts, and doughnut charts.
It's built on top of ApexCharts, a modern charting library that provides beautiful, responsive charts with minimal configuration.
Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
type | string | line | line, bar, pie, doughnut, area |
title | string | empty | Chart title |
xdata | string | required | X-axis labels (JSON array) |
ydata | string | required | Y-axis values (JSON array) |
height | number | 300 | Chart height in pixels |
color | string | empty | Theme color |
Examples
<!-- Line Chart -->
<ff:chart
type="line"
title="Sales Over Time"
xdata='["Jan", "Feb", "Mar", "Apr"]'
ydata='[100, 150, 200, 175]'
height="300"
/>
<!-- Bar Chart -->
<ff:chart
type="bar"
title="Monthly Revenue"
xdata='["Q1", "Q2", "Q3", "Q4"]'
ydata='[10000, 15000, 12000, 18000]'
height="250"
color="#3b82f6"
/>
Avatar <ff:avatar>
User avatar with image fallback using initials. The avatar component is perfect for displaying user profiles or other types of entities with images.
If no image is provided, it will automatically generate a placeholder using the user's initials. It also supports status indicators to show whether a user is online, offline, away, or busy.
Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
src | string | empty | Image URL |
name | string | required | Name for initials |
size | string | md | xs, sm, md, lg, xl |
status | string | empty | online, offline, away, busy |
rounded | boolean | true | true=circle, false=square |
Size Reference
| Size | Dimensions |
|---|---|
| xs | 24px |
| sm | 32px |
| md | 40px |
| lg | 48px |
| xl | 64px |
Examples
<!-- Basic with Initials -->
<ff:avatar name="John Doe" size="md" />
<!-- With Image -->
<ff:avatar src="/images/user.jpg" name="John Doe" size="lg" />
<!-- With Status -->
<ff:avatar
src="/images/user.jpg"
name="Jane Smith"
size="xl"
status="online"
/>
Skeleton <ff:skeleton>
Loading placeholder for various content types. Skeleton loaders are used to indicate that content is being loaded, providing a better user experience than traditional loading spinners.
They simulate the layout of the content that will be displayed, reducing the perceived loading time and making the interface feel more responsive.
Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
type | string | card | card, list, avatar, text, input |
count | number | 1 | Number of items (list/text) |
width | string | empty | Custom width |
height | string | empty | Custom height |
Examples
<!-- Card Skeleton -->
<ff:skeleton type="card" />
<!-- List Skeleton -->
<ff:skeleton type="list" count="3" />
<!-- Text Skeleton -->
<ff:skeleton type="text" count="2" width="75%" />
<!-- Input Skeleton -->
<ff:skeleton type="input" width="100%" />
Switch <ff:switch>
Toggle switch for binary state selection. The switch component is perfect for settings or preferences that have two possible states, such as enabling/disabling features or toggling between options.
It supports custom colors, sizes, and disabled states, making it versatile for a wide range of use cases.
Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
label | string | empty | Switch label |
xmodel | string | empty | Alpine.js binding |
size | string | md | sm, md, lg |
color | string | blue | blue, green, red |
disabled | boolean | false | Disable switch |
Size Reference
| Size | Dimensions |
|---|---|
| sm | 32px x 16px |
| md | 44px x 24px |
| lg | 56px x 28px |
Examples
<!-- Basic Switch -->
<ff:switch
label="Enable Notifications"
xmodel="settings.notifications"
/>
<!-- Small Switch -->
<ff:switch
label="Dark Mode"
xmodel="settings.darkMode"
size="sm"
color="blue"
/>
<!-- Large Disabled -->
<ff:switch
label="Feature Flag"
xmodel="features.beta"
size="lg"
disabled="true"
/>
Timeline <ff:timeline>
Container for timeline items with optional compact mode. The timeline component is perfect for displaying a sequence of events in chronological order, such as a project history or user activity log.
It supports optional compact mode for displaying events in a more condensed format, and you can customize the colors and icons of each timeline item.
Timeline Container Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
compact | boolean | false | Use compact spacing |
Timeline Item Attributes <ff:timelineItem>
| Attribute | Type | Default | Description |
|---|---|---|---|
title | string | required | Event title |
date | string | required | Event date |
description | string | empty | Description text |
icon | string | empty | Icon name |
color | string | blue | blue, green, red, yellow |
Examples
<!-- Standard Timeline -->
<ff:timeline>
<ff:timelineItem
title="Project Started"
date="2024-01-01"
description="Initial planning phase began"
icon="rocket"
color="blue"
/>
<ff:timelineItem
title="First Milestone"
date="2024-01-15"
description="Completed MVP development"
icon="check"
color="green"
/>
</ff:timeline>
<!-- Compact Timeline -->
<ff:timeline compact="true">
<ff:timelineItem title="Event 1" date="2024-01-01" />
<ff:timelineItem title="Event 2" date="2024-01-02" />
</ff:timeline>
Progress Card <ff:progress-card>
Card displaying a progress bar with value and percentage. The progress card is perfect for visualizing progress toward a goal, such as completing a task, uploading a file, or reaching a quota.
It supports custom colors, labels, and show/hide percentage options, making it versatile for a wide range of use cases.
Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
title | string | empty | Card title |
value | number | required | Current progress |
max | number | 100 | Maximum value |
label | string | empty | Label below bar |
color | string | blue | blue, green, red, yellow |
showPercentage | boolean | true | Show percentage |
Examples
<!-- Basic Progress -->
<ff:progress-card
title="Storage Usage"
value="75"
max="100"
color="blue"
/>
<!-- With Label -->
<ff:progress-card
title="Upload Progress"
value="45"
max="100"
label="45 MB of 100 MB"
color="green"
/>
<!-- Warning Style -->
<ff:progress-card
title="Quota"
value="90"
max="100"
color="red"
/>
Alpine.js Integration
All widgets support Alpine.js bindings, making them dynamic and interactive. Alpine.js is a lightweight JavaScript framework that allows you to add interactivity to your pages with minimal code.
You can use Alpine.js to bind widget properties to data, dynamically show/hide widgets, and update widget values based on user input.
All widgets support Alpine.js bindings:
<!-- Data binding -->
<ff:switch xmodel="settings.darkMode" label="Dark Mode" />
<!-- Dynamic attributes -->
<ff:stats title="Users" :coattr="'x-show=showStats'" />
<!-- Conditional rendering -->
<div x-show="showChart">
<ff:chart type="line" xdata="xAxis" ydata="yAxis" />
</div>
<!-- Dynamic values -->
<ff:stats
title="Total Users"
:value="userCount"
:trend="growthRate"
:trendUp="isPositive"
/>
Semantic CSS Classes
All widgets use semantic CSS classes for theming, making them easy to customize and maintain. Semantic classes describe the purpose of the element rather than its appearance, which makes your code more readable and consistent.
These classes automatically adapt to light/dark mode, ensuring that your widgets look great in all scenarios.
All widgets use semantic CSS classes for theming:
| Class | Purpose |
|---|---|
text-primary | Primary text color |
text-secondary | Secondary text |
text-tertiary | Tertiary/muted text |
bg-surface | Surface background |
bg-surface-muted | Muted surface |
bg-input | Input background |
border-primary | Primary border |
text-success | Success state |
text-error | Error state |
text-warning | Warning state |
These automatically adapt to light/dark mode.
Best Practices
To get the most out of Fuwafuwa's components, it's important to follow best practices. These practices will help ensure that your components are accessible, maintainable, and consistent.
- Use semantic classes - Prefer
text-primaryover hardcoded colors - Provide fallbacks - Always include text labels for accessibility
- Loading states - Use skeleton widgets during data fetching
- Consistent sizing - Stick to defined size variants
- Color semantics - Use blue for primary, green for success, red for error, yellow for warning
- Dark mode - Test components in both light and dark modes