Hocusable
A specialized Triggerable where the control is triggered on hover or focus. Useful for Tooltips and controls of this type.
Simple Example: Tooltip
For a simple tooltip, we want the target to open on hover and focus, to close when pressing ESC and to stay open when hovering its content. This is precisely the functionality the Hocusable
class brings in.
We only have to extend it by adding a few roles and attributes:
<script lang="ts">
import { Hocusable } from "chocobytes/blocks/hocusable.svelte.js";
import { choco } from "chocobytes/index.js";
import { nanoId } from "chocobytes/utils/index.js";
import { role } from "chocobytes/utils/roles.js";
export class Tooltip extends Hocusable<"generic"> {
constructor(options?: { active: boolean }) {
const active = options?.active ?? false;
super({
active,
// We only toggle a `data-open` attribute on the target
target: { "data-open": active },
});
const id = "tooltip-" + nanoId();
// And extend the attributes for accessibility
this.extendAttributes({
"aria-describedby": id,
});
this.target.extendAttributes({
id,
inert: true,
role: role.tooltip,
});
}
}
const tooltip = new Tooltip();
</script>
<button>A</button>
<div class="grid">
<div class="relative mx-auto">
<span use:choco={tooltip}>HTML*</span>
<!-- `data-open` toggles the display -->
<p
class="invisible absolute top-2 left-1/2 -translate-x-1/2 whitespace-nowrap rounded bg-black px-1 text-xs leading-none data-[open=true]:visible"
use:choco={tooltip.target}
>
Hypertext Markup Language
</p>
</div>
</div>
<button>B</button>
<!-- Just to see what's going on -->
<div class="mt-10 grid">
<p>Control attributes</p>
<pre>{JSON.stringify(tooltip.attributes, null, 2)}</pre>
<p>Target attributes</p>
<pre>{JSON.stringify(tooltip.target.attributes, null, 2)}</pre>
</div>
Try focusing with the keyboard, pressing ESC, hovering over the tooltip etc. In only a
few lines of code, the Hocusable
building block allowed us to setup a full-featured simple
tooltip.
API
Constructor
A Hocusable
is just a specialized Triggerable
, so the constructor options are the
same:
control
?: Record<string, Booleanish>- Initial booleanish state of the control
target
?: Record<string, Booleanish>- Initial booleanish state of the target
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
TriggerableOptions