Switch

Switch drives each element's state from a shared set of tags — one call flips every tagged element on or off, hiding and showing by default, or running whatever effect the element defines. Elements carry their tag inside a shared switch-space, and the active set is written to the DOM as switch-state, readable there with no JavaScript variable holding it.

Source: Switch.js

Account settings.
Billing details.
Team members.
<div switch-space switch-state="account">
  <button onclick="Switch.To(this, '[switch-space]', 'account')">Account</button>
  <button onclick="Switch.To(this, '[switch-space]', 'billing')">Billing</button>
  <button onclick="Switch.To(this, '[switch-space]', 'team')">Team</button>

  <section switch-tag="account">Account settings.</section>
  <section switch-tag="billing" style="display:none">Billing details.</section>
  <section switch-tag="team" style="display:none">Team members.</section>
</div>

Signature

< switch-space switch-config-tag="switch-tag" switch-state="a b …">
    < switch-tag="a b" switch-onchange="(on) => …">

Switch.To(this, '[switch-space]', 'a b')            // tags: array or space-separated string
Switch.Toggle(this, '[switch-space]', when, then, otherwise)

The space is the second argument. It is a selector resolved from ctx with closest. There is no default space. Each call names its space. A nested space is never picked by accident.

Switch.To(ctx, space, tags) shows every target whose tag is in tags, hides the others, and writes tags to switch-state. Tags are an array or a space-separated string. A target with several tags is on when any of them matches. Switch.Toggle(ctx, space, when, then, otherwise) reads switch-state. When it includes when, the then set is shown, otherwise otherwise.

Config on the space element, the one the selector matches:

Config on each target:

Accordion

Each header toggles its panel. Opening one closes the rest.

Ships in two days.
Thirty day returns.
<div switch-space switch-state="shipping">
  <button onclick="Switch.Toggle(this, '[switch-space]', 'shipping', '', 'shipping')">Shipping</button>
  <div switch-tag="shipping">Ships in two days.</div>

  <button onclick="Switch.Toggle(this, '[switch-space]', 'returns', '', 'returns')">Returns</button>
  <div switch-tag="returns" style="display:none">Thirty day returns.</div>
</div>

Radio

The extra input shows only when Other is selected.

<div switch-space switch-state="">
  <label><input type="radio" name="reason" onclick="Switch.To(this, '[switch-space]', '')"> Refund</label>
  <label><input type="radio" name="reason" onclick="Switch.To(this, '[switch-space]', '')"> Exchange</label>
  <label><input type="radio" name="reason" onclick="Switch.To(this, '[switch-space]', 'other')"> Other</label>

  <input switch-tag="other" style="display:none" placeholder="Tell us more">
</div>

Effect

Each target sets its own effect in switch-onchange. It runs with the computed boolean, this bound to the element. Left out, the target is shown when on and hidden when off.

<div switch-space>
  <button onclick="Switch.To(this, '[switch-space]', 'a')">A</button>
  <button onclick="Switch.To(this, '[switch-space]', 'b')">B</button>
  <details switch-tag="a" switch-onchange="(on) => this.open = on">Panel A</details>
  <p switch-tag="b" switch-onchange="(on) => this.style.opacity = on ? 1 : .35">Panel B</p>
</div>

Next: Util →