DEV Community

Yuuichi Eguchi
Yuuichi Eguchi

Posted on

Constela: Built-in a11y Checks, Plugin System & CSS Transitions

What's New in Constela

Constela is a JSON-based declarative UI framework — you write your entire UI in JSON, and the compiler + runtime handles the rest. We're shipping three features that make Constela apps more accessible, extensible, and polished.

1. Compile-Time Accessibility Checks

Accessibility shouldn't be an afterthought. Constela now checks your JSON programs for common a11y issues at compile time and reports them as warnings.

7 Built-in Rules

Code What it catches
IMG_NO_ALT Images without alt text
BUTTON_NO_LABEL Buttons with no text or aria-label
ANCHOR_NO_LABEL Links with no text or aria-label
INPUT_NO_LABEL Inputs without a label
HEADING_SKIP Skipped heading levels (h1 → h3)
POSITIVE_TABINDEX Positive tabindex values
DUPLICATE_ID Duplicate id attributes

These are warnings, not errors — your code still compiles, so you can adopt them gradually.

const result = compile(myProgram);
if (result.ok && result.warnings?.length) {
  result.warnings.forEach(w => console.warn(`[${w.code}] ${w.message}`));
}
Enter fullscreen mode Exit fullscreen mode

2. Plugin System

Want to use custom functions in your JSON DSL? Now you can.

Define a Plugin

import type { ConstelaPlugin } from '@constela/core';

const myPlugin: ConstelaPlugin = {
  name: 'my-analytics',
  version: '1.0.0',
  globalFunctions: {
    trackEvent: (category: string, action: string) => { /* ... */ },
    formatCurrency: (amount: number) => `$${amount.toFixed(2)}`,
  },
};

export default myPlugin;
Enter fullscreen mode Exit fullscreen mode

Register It

Add to constela.config.json:

{
  "plugins": ["my-analytics", "./src/plugins/local-plugin"]
}
Enter fullscreen mode Exit fullscreen mode

That's it — your functions are now available in the DSL.

Safety features:

  • Atomic registration (all-or-nothing)
  • Prototype pollution protection (__proto__, constructor, prototype blocked)
  • Works in both client and server rendering

3. CSS Class-Based Transitions

Conditional rendering (if nodes) now supports smooth enter/exit animations:

{
  "kind": "if",
  "condition": { "expr": "state", "name": "showToast" },
  "then": {
    "kind": "element",
    "tag": "div",
    "children": [
      { "kind": "text", "value": { "expr": "lit", "value": "Saved!" } }
    ]
  },
  "transition": {
    "enter": "slide-in",
    "enterActive": "slide-in-active",
    "exit": "slide-out",
    "exitActive": "slide-out-active",
    "duration": 250
  }
}
Enter fullscreen mode Exit fullscreen mode

Pair it with CSS:

.slide-in { transform: translateY(-20px); opacity: 0; }
.slide-in-active { transition: all 250ms ease; transform: translateY(0); opacity: 1; }
.slide-out { transform: translateY(0); opacity: 1; }
.slide-out-active { transition: all 250ms ease; transform: translateY(-20px); opacity: 0; }
Enter fullscreen mode Exit fullscreen mode

The runtime handles:

  • Enter flow: create element → apply enter → next frame: swap to enterActive → cleanup
  • Exit flow: apply exit → next frame: swap to exitActive → remove element
  • Fast toggling: cancels in-progress animations gracefully
  • SSR: transitions are ignored server-side (no changes needed)

Try It Out

npm install @constela/core @constela/compiler @constela/runtime @constela/start
npx constela dev
Enter fullscreen mode Exit fullscreen mode

Check out the Language Specification for the full DSL reference, or browse the Examples to see these features in action.


Links:

Top comments (0)