Constela: Built-in a11y Checks, Plugin System & CSS Transitions
Source: Dev.to
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.
Built‑in Rules
| Rule | 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 (e.g., 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}`));
}
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;
Register It
Add to constela.config.json:
{
"plugins": ["my-analytics", "./src/plugins/local-plugin"]
}
That’s it — your functions are now available in the DSL.
Safety features
- Atomic registration (all‑or‑nothing)
- Prototype‑pollution protection (
__proto__,constructor,prototypeblocked) - Works in both client and server rendering
3. CSS Class‑Based Transitions
Conditional rendering (if nodes) now supports smooth enter/exit animations.
Example JSON
{
"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
}
}
Corresponding 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; }
The runtime handles:
- Enter flow: create element → apply
enter→ next frame: swap toenterActive→ cleanup - Exit flow: apply
exit→ next frame: swap toexitActive→ 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
Check out the Language Specification for the full DSL reference, or browse the Examples to see these features in action.