@constela/ui
v0.6.8
Published
Copy-paste UI components for Constela
Readme
@constela/ui
Copy-paste UI components for Constela.
Overview
This package provides a collection of pre-built, accessible UI components written in Constela JSON DSL. Each component is designed to be copied directly into your project and customized as needed.
Installation
npm install @constela/uiUsage
Copy Component Files
Components are located in the components/ directory. Copy the component files you need into your project:
components/
├── button/
│ ├── button.constela.json # Component definition
│ ├── button.styles.json # Style presets
│ └── README.md # Usage documentation
├── input/
├── select/
└── ...Example: Using Button Component
- Copy
components/button/button.constela.jsonto your project - Import styles from
components/button/button.styles.json - Use the component in your Constela program:
{
"kind": "component",
"name": "Button",
"props": {
"variant": { "expr": "lit", "value": "default" },
"size": { "expr": "lit", "value": "default" }
},
"children": [
{ "kind": "text", "value": { "expr": "lit", "value": "Click me" } }
]
}Available Components
Basic (7)
- Button - Clickable button with variants and sizes
- Input - Text input field
- Select - Dropdown select
- Checkbox - Checkbox input
- Radio - Radio button
- Switch - Toggle switch
- Textarea - Multi-line text input
Feedback (6)
- Alert - Alert messages
- Toast - Toast notifications
- Dialog - Modal dialog
- Modal - Modal overlay
- Tooltip - Hover tooltip
- Popover - Click-triggered popover
Data Display (8)
- Card - Card container
- Badge - Inline badge
- Avatar - User avatar
- Skeleton - Loading placeholder
- DataTable - Advanced data table with sorting, filtering, and pagination
- VirtualScroll - Virtualized list for large datasets
- Chart - 7 chart types (bar, line, pie, donut, area, radar, scatter)
Date & Time (2)
- DatePicker - Date selection with calendar popup
- Calendar - Calendar view for date display and selection
Navigation (5)
- Tabs - Tab navigation
- Breadcrumb - Breadcrumb navigation
- Pagination - Page pagination
- Tree - Hierarchical tree view with expand/collapse
- Accordion - Collapsible content sections
Layout (3)
- Container - Max-width container
- Grid - CSS Grid layout
- Stack - Flexbox stack
Style System
Each component uses the CVA-like style system with:
- base - Common styles applied to all variants
- variants - Named variant options (e.g., "variant", "size")
- defaultVariants - Default values when not specified
Example Style Preset
{
"button": {
"base": "inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50",
"variants": {
"variant": {
"default": "bg-primary text-primary-foreground hover:bg-primary/90",
"destructive": "bg-destructive text-destructive-foreground hover:bg-destructive/90",
"outline": "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
"secondary": "bg-secondary text-secondary-foreground hover:bg-secondary/80",
"ghost": "hover:bg-accent hover:text-accent-foreground",
"link": "text-primary underline-offset-4 hover:underline"
},
"size": {
"default": "h-10 px-4 py-2",
"sm": "h-9 rounded-md px-3",
"lg": "h-11 rounded-md px-8",
"icon": "h-10 w-10"
}
},
"defaultVariants": {
"variant": "default",
"size": "default"
}
}
}New Components (2026.02)
DatePicker
Date selection with calendar popup:
{
"kind": "component",
"name": "DatePicker",
"props": {
"value": { "expr": "state", "name": "selectedDate" },
"onChange": { "event": "change", "action": "updateDate" },
"format": { "expr": "lit", "value": "yyyy-MM-dd" },
"minDate": { "expr": "lit", "value": "2024-01-01" },
"maxDate": { "expr": "lit", "value": "2025-12-31" },
"locale": { "expr": "lit", "value": "ja-JP" }
}
}Calendar
Calendar view for date display:
{
"kind": "component",
"name": "Calendar",
"props": {
"value": { "expr": "state", "name": "selectedDate" },
"onSelect": { "event": "select", "action": "handleDateSelect" },
"highlightedDates": { "expr": "state", "name": "events" },
"weekStartsOn": { "expr": "lit", "value": 1 }
}
}Tree
Hierarchical tree view:
{
"kind": "component",
"name": "Tree",
"props": {
"items": { "expr": "state", "name": "treeData" },
"onSelect": { "event": "select", "action": "handleNodeSelect" },
"expandedKeys": { "expr": "state", "name": "expanded" },
"selectedKey": { "expr": "state", "name": "selected" },
"showIcons": { "expr": "lit", "value": true }
}
}Accordion
Collapsible content sections:
{
"kind": "component",
"name": "Accordion",
"props": {
"items": { "expr": "state", "name": "accordionItems" },
"type": { "expr": "lit", "value": "single" },
"collapsible": { "expr": "lit", "value": true },
"defaultValue": { "expr": "lit", "value": "item-1" }
}
}DataTable
Advanced data table with sorting, filtering, and pagination:
{
"kind": "component",
"name": "DataTable",
"props": {
"data": { "expr": "state", "name": "tableData" },
"columns": { "expr": "lit", "value": [
{ "key": "name", "title": "Name", "sortable": true },
{ "key": "email", "title": "Email", "sortable": true, "filterable": true },
{ "key": "status", "title": "Status", "sortable": true }
]},
"pageSize": { "expr": "lit", "value": 10 },
"sortable": { "expr": "lit", "value": true },
"filterable": { "expr": "lit", "value": true },
"selectable": { "expr": "lit", "value": true },
"onSort": { "event": "sort", "action": "handleSort" },
"onFilter": { "event": "filter", "action": "handleFilter" },
"onPageChange": { "event": "pageChange", "action": "handlePageChange" }
}
}VirtualScroll
Virtualized list for large datasets:
{
"kind": "component",
"name": "VirtualScroll",
"props": {
"items": { "expr": "state", "name": "largeList" },
"itemHeight": { "expr": "lit", "value": 50 },
"containerHeight": { "expr": "lit", "value": 400 },
"overscan": { "expr": "lit", "value": 5 },
"renderItem": { "expr": "param", "name": "itemTemplate" }
}
}Chart
7 chart types with Apple Health-inspired design:
{
"kind": "component",
"name": "BarChart",
"props": {
"data": { "expr": "state", "name": "chartData" },
"valueKey": { "expr": "lit", "value": "value" },
"labelKey": { "expr": "lit", "value": "label" },
"showGrid": { "expr": "lit", "value": true },
"showLabels": { "expr": "lit", "value": true }
}
}Chart Components:
| Component | Description |
|-----------|-------------|
| BarChart | Vertical bar chart with rounded corners |
| LineChart | Line chart with optional data points |
| PieChart | Pie chart |
| DonutChart | Donut chart with center cutout |
| AreaChart | Area chart with gradient fill |
| RadarChart | Radar/spider chart |
| ScatterChart | Scatter plot |
Common Props:
| Prop | Type | Description |
|------|------|-------------|
| data | Expression | Chart data array |
| valueKey | Expression | Key for data values |
| labelKey | Expression | Key for labels |
| width | Expression | Chart width |
| height | Expression | Chart height |
| colors | Expression | Color palette array |
| showGrid | Expression | Show grid lines |
| showLabels | Expression | Show axis labels |
Accessibility
All components include proper ARIA attributes:
aria-label- Descriptive labelsaria-disabled- Disabled state indicationrole- Semantic roles for interactive elementsaria-live- Live region announcements
API Reference
validateComponent
Validate a Constela component definition:
import { validateComponent } from '@constela/ui';
const result = validateComponent(componentJson);
if (result.valid) {
console.log('Component is valid');
} else {
console.error('Validation errors:', result.errors);
}Component Types
import type { ButtonComponent, InputComponent } from '@constela/ui';License
MIT
