Attractive.js

A humble set of declarative HTML actions. Extensible when you need more.

Read the docs
<button
  @action="toggleClass#active"
  @target="panel"
>
  Toggle
</button>

<div id="panel">Content</div>

Included actions

Bundled actions cover the common cases without any JavaScript. Toggle, set and cycle classes, attributes, styles and data attributes. Copy to the clipboard, confirm before destructive actions, focus elements, open dialogs, submit forms and reset the page.

  • Classes, attributes, styles and data attributes
  • Clipboard, confirm, focus and scroll
  • Dialogs, submit, reset and refresh
Browse all actions
<button
  @action="toggleClass#active"
  @target="panel"
>
  Toggle
</button>

<div id="panel">Content</div>

Custom actions

Attractive is made to be extended. Write an action once and use it declaratively everywhere. Start with an inline expression, then grow to a function or a full class as the behavior matures.

  • Inline actions for quick expressions
  • Functions for a little more logic
  • Classes for actions that deserve a home
  • The same interface as the bundled actions
Write your own
const sharePage = (element, { dataset }) => {
  navigator.share({ title: dataset.title, url: dataset.url });
};

Attractive.activate({ addActions: { sharePage } })

<button
  @action="sharePage"
  data-title="Hello"
>
  Share
</button>

Keyboard

Filter @keydown with dot modifiers like .enter or global @hotkey shortcuts such as mod+k.

Read the Keyboard addon
<input
  @keydown.enter="submit"
  placeholder="Press enter"
>

<button @hotkey="mod+s">Save</button>

Reactive

A shared key value store with DOM bindings. Set values from actions and text content updates itself.

Read the Reactive addon
<button
  @action="setStore#count"
  @value="1"
>
  Increment
</button>

<div @text="count">0</div>

Attract

Optimistic UI from a cached <template>. Intercept the form submit, send the request, render the preview immediately.

Read the Attract addon
<form
  action="/messages"
  method="post"
  @attract
  data-attract-template="message"
  data-attract-target="messages"
>
  <input name="title" placeholder="New item">
</form>

<template id="message">…</template>

<ul id="messages">…</ul>