DEV Community

Yuuichi Eguchi
Yuuichi Eguchi

Posted on

Introducing @constela/ui - Copy-Paste UI Components for Constela JSON DSL

Introducing @constela/ui

I'm excited to announce the release of @constela/ui - a UI component library for Constela JSON DSL.

This library provides copy-paste UI components that you can drop directly into your Constela projects. All components are written in JSON format - no TypeScript or React knowledge required for customization.

Installation

npm install @constela/ui
Enter fullscreen mode Exit fullscreen mode

Available Components

Basic (7)

  • Button - 6 variants, 4 sizes
  • Input - Text input field
  • Textarea - Multi-line text input
  • Select - Dropdown selection
  • Checkbox - Checkbox input
  • Radio - Radio button
  • Switch - Toggle switch

Feedback (5)

  • Alert - Alert messages (default, destructive)
  • Card - Card container
  • Badge - Inline badge
  • Skeleton - Loading placeholder
  • Avatar - User avatar with fallback

Overlay (4)

  • Dialog - Modal dialog with proper ARIA
  • Tooltip - Hover tooltip
  • Popover - Click-triggered popover
  • Toast - Notifications (default, success, error, warning, info)

Navigation/Layout (6)

  • Tabs - Tab navigation
  • Breadcrumb - Breadcrumb navigation
  • Pagination - Page pagination
  • Container - Max-width container
  • Grid - CSS Grid layout
  • Stack - Flexbox stack

How to Use

1. Copy Component Files

Copy the components you need from node_modules/@constela/ui/components/:

button/
├── button.constela.json   # Component definition
└── button.styles.json     # Style preset
Enter fullscreen mode Exit fullscreen mode

2. Import Styles

Add the style preset to your application's styles section.

3. Use the Component

{
  "kind": "component",
  "name": "Button",
  "props": {
    "variant": { "expr": "lit", "value": "default" },
    "size": { "expr": "lit", "value": "lg" }
  },
  "children": [
    { "kind": "text", "value": { "expr": "lit", "value": "Click me" } }
  ]
}
Enter fullscreen mode Exit fullscreen mode

The Style System

Each component uses a CVA-like style system with base classes, variants, and default variants:

{
  "buttonStyles": {
    "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",
        "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"
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Dynamic Styling with StyleExpr

Components use StyleExpr to apply styles dynamically based on props:

{
  "className": {
    "expr": "style",
    "preset": "buttonStyles",
    "props": {
      "variant": { "expr": "param", "name": "variant" },
      "size": { "expr": "param", "name": "size" }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Accessibility First

All components include proper ARIA attributes:

  • aria-label for screen reader labels
  • aria-disabled for disabled state indication
  • role for semantic roles (dialog, alert, tablist, etc.)
  • aria-live for live region announcements

Example: Dialog Component

{
  "params": {
    "open": { "type": "boolean", "required": false },
    "title": { "type": "string", "required": false }
  },
  "view": {
    "kind": "element",
    "tag": "div",
    "props": {
      "role": { "expr": "lit", "value": "dialog" },
      "aria-modal": { "expr": "lit", "value": "true" },
      "className": { "expr": "style", "preset": "dialogStyles" }
    },
    "children": [{ "kind": "slot" }]
  }
}
Enter fullscreen mode Exit fullscreen mode

Customization

Adding New Variants

Edit the style file to add new variants:

{
  "variants": {
    "variant": {
      "success": "bg-green-500 text-white hover:bg-green-600"
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Extending Parameters

Add new parameters to the component definition. All parameters are optional by default, so existing usage won't break.

Modifying Base Styles

Change the base property to modify styles that apply to all variants.

Test Coverage

All components are verified with 563 tests covering:

  • Structure validation
  • Parameter validation
  • Style preset validation
  • Accessibility attributes
cd packages/ui && pnpm test

# Test Files  passed (22)
#      Tests  563 passed (563)
Enter fullscreen mode Exit fullscreen mode

What's Next

  • Component catalog page on the official website
  • More components based on community feedback
  • Enhanced animation support

Links

Conclusion

@constela/ui provides a solid foundation for building UIs with Constela JSON DSL. The copy-paste approach makes it simple to get started, and the JSON-based format makes customization accessible to everyone.

Give it a try and let me know what you think!

Top comments (0)