emily-js
v0.2.0
Published
Tiny declarative behavior layer for server-rendered HTML, EmilyCSS, and EmilyUI.
Maintainers
Readme
EmilyJS
Tiny declarative behavior layer for server-rendered HTML, EmilyCSS, and EmilyUI.
EmilyJS adds local state, simple events, form bindings, visibility, class/style bindings, and accessibility helpers directly to HTML attributes. It is designed for pages and components that render HTML on the server and need a small amount of client-side behavior without a full application framework.
Install
npm install emily-jsconst EmilyJS = require('emily-js');
new EmilyJS(document);You can also load emily.js directly in the browser. It auto-starts as window.emily when document is ready.
<script src="./emily.js"></script>Example
<div class="em-card" emily-state='{"open": false, "saving": false}'>
<button class="em-button" emily-click="open = !open">
Toggle panel
</button>
<div
class="em-panel"
emily-show="open"
emily-class='{"is-open": "open"}'>
Panel content
</div>
<button class="em-button" emily-disabled="saving">
Save
</button>
</div>Directives
emily-state: JSON object that creates local component state.emily-click: shortcut for click expressions, such asopen = !open.emily-on:event: binds any DOM event to an expression, such asemily-on:change="dirty = true".emily-submit: binds a form submit event and prevents the browser default.emily-show: hides an element when an expression is false.emily-text: writes a state value totextContent.emily-html: writes trusted state HTML toinnerHTML.emily-bind: maps attributes from state or expressions.emily-disabled: syncsdisabledandaria-disabled.emily-model: two-way binding for inputs, selects, and textareas.emily-model.lazy: defers text input updates until blur.emily-class: toggles classes from expressions.emily-style: maps state or expressions to inline style properties.emily-trap: traps focus inside an active container.emily-announce: pushes state updates into a polite live region.
Expressions
EmilyJS intentionally supports a small CSP-safe expression subset:
open
!open
tab === 2
mode !== 'dark'
open = !open
tab = 2
count++
count--There is no eval() or new Function(). Nested paths, function calls, loops, and compound boolean expressions are not part of the expression language.
Security
emily-html writes directly to innerHTML. Only bind trusted or pre-sanitized content.
Dynamic Content
Call refresh() after injecting HTML that contains new emily-state components:
window.emily.refresh(container);License
MIT
