Triggerable

A specialized Toggleable which also controls a target element. This control-target pattern govern things like Tabs, Accordion, Disclosure, Popover, Carousel etc.

Both the control and target element have attributes that can be correlated and triggered on and off, and the Triggerable class help create headless components orchestrating this.


Example: Disclosure

For a simple headless disclosure we want to toggle a button’s aria-expanded attribute on click, and toggle the target’s hidden property accordingly.

We can create this Disclosure by extending the Triggerable class as follows:


<script lang="ts">
  import { choco } from "chocobytes";
  import { Triggerable } from "chocobytes/blocks/triggerable.svelte.js";
  import { fly } from "svelte/transition";

  class Disclosure extends Triggerable {
    constructor() {
      // We just have to configure the control and target booleanish states
      super({
        control: { "aria-expanded": "false" },
        target: { hidden: true },
        active: false,
        // here we only want to toggle on click
        toggle: "click",
      });

      // We can always add more attributes or new actions to a Choco class
      const targetId = "123";
      this.target.extendAttributes({ id: targetId });
      this.extendAttributes({ "aria-controls": targetId });
    }
  }

  const disclosure = new Disclosure();
</script>

<div class="my-8 grid grid-cols-2 items-center justify-center gap-2 text-center">
  <button class="cursor-pointer py-2 px-4 outline" use:choco={disclosure}>control</button>

  {#if disclosure.active}
    <span class="text-coral" transition:fly={{ y: 100 }} use:choco={disclosure.target}>target</span>
  {/if}
</div>

<!-- Just to see what's going on -->
<div class="grid grid-cols-2">
  <pre>{JSON.stringify(disclosure.attributes, null, 2)}</pre>
  <pre>{JSON.stringify(disclosure.target.attributes, null, 2)}</pre>
</div>

Notice that we used the extendAttribute from the ChocoBase class. Here it allows us to programmatically add correlated aria and attributes between the control and the target. Similarly, there is an extendAction method on ChocoBase which allows to add more behavior to any class.

We’ve just created our simple headless Disclosure in a few lines of code, thanks to the Triggerable building block. We could go further by generating the id automatically and allowing to bind options.


API

Constructor

The options of the Triggerable class are similar to those of the Toggleable. The class has two type constraints Triggerable<C,T> for the control and target HTML tags. By default C="button" and T="generic" for any generic HTMLElement.

control?: Record<string, Booleanish>
Initial booleanish state of the control
target?: Record<string, Booleanish>
Initial booleanish state of the target
Omit<ToggleableOptions, "initial">
active: boolean | () => boolean
Boolean or getter labelling the state as active or not. Can be bound
Default: false
setActive?: (v: boolean) => void
Setter allowing to bind the active state value
toggle?: EventName | EventName[]
Event(s) toggling the state
on?: EventName | EventName[]
Event(s) triggering the active state
off?: EventName | EventName[]
Event(s) triggering the inactive state