Alpha Slider

v0.0.10

v0.0.10StableHeadlessStatelessAccessibleJSApache-2.0
Installation mix mishka.ui.gen.headless alpha_slider
Source View Source

Overview of the Phoenix and LiveView Headless Alpha Slider Component

The Mishka Chelekom Headless Alpha Slider picks an opacity from 0 to 100 with a draggable handle. It is the headless Slider preset to that range, so it uses the same Slider hook and adds no JavaScript of its own. It ships no styling. You get a root div holding a control, a track, an optional fill called the indicator, and a thumb with role="slider".

The base color is written to the root as the --chelekom-alpha-color CSS variable, so your classes can paint a gradient from transparent to that color over a checkerboard. In a Phoenix form the value posts through a hidden input, and in LiveView it can be pushed to the server while it changes. Each part takes its own class attribute: class for the root, then control_class, track_class, indicator_class and thumb_class.

Base UI Alpha Slider example - opacity over a checkerboard (Phoenix headless)

Base UI Alpha Slider example - opacity over a checkerboard (Phoenix headless)

heex
<div class="w-64">
  <.alpha_slider
    id="baseui-alpha-slider"
    value={50}
    color="#e8590c"
    class="block w-full"
    control_class="relative flex h-4 cursor-pointer items-center"
    track_class="relative h-3 w-full overflow-hidden rounded-full [background-image:linear-gradient(to_right,transparent,var(--chelekom-alpha-color)),conic-gradient(#ccc_25%,#fff_0_50%,#ccc_0_75%,#fff_0)] [background-size:100%_100%,10px_10px]"
    indicator_class="hidden"
    thumb_class="size-4 rounded-full border-2 border-white shadow ring-1 ring-black/30 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-neutral-950 dark:focus-visible:outline-white"
  />
</div>

Using the value in forms and LiveView

Give the slider a name and the thumb holds a hidden input with the current value, so the slider posts with its form. The hook dispatches a bubbling input event from that input when the handle is released or a key is lifted, so phx-change on the form runs once per interaction and not on every pixel of a drag. Use form to attach the input to a form elsewhere on the page.

To follow the value while it moves, set on_change to a LiveView event name. The hook pushes it with a payload like %{"value" => 63} on every change. on_commit pushes the same payload once, when the handle is released or a key is lifted. The events go to the LiveView, or to the LiveComponent the slider is rendered in.

heex
<.form for={@form} phx-submit="save">
  <.alpha_slider
    id="fill-opacity"
    name="fill[opacity]"
    value={@opacity}
    color="#6d28d9"
    on_change="opacity"
  />
</.form>
elixir
def handle_event("opacity", %{"value" => value}, socket) do
  {:noreply, assign(socket, :opacity, value)}
end

Step, label and disabled

value is the starting opacity and defaults to 100. step sets how far an arrow key moves the value and defaults to 1. label is the thumb's accessible name and defaults to "Opacity". disabled sets data-disabled, takes the thumb out of the tab order and ignores pointer and keyboard input.

Parts & data attributes

Each part carries a stable data-part and a chelekom-alpha-slider__* class you can target. The hook sets the thumb's position and the indicator's size inline, so give the track relative positioning and let your classes size the thumb. The color is written to the root in an inline style attribute.

Partdata-partState / ARIAPurpose
Root-data-disabled, data-dragging, --chelekom-alpha-color, --chelekom-sliderCarries the Slider hook. The hook reads the range, step and event names from data attributes and keeps the current ratio (0 to 1) in --chelekom-slider.
Controlcontroldata-orientation, data-disabled, data-draggingThe hit area. Press it to jump the handle to the pointer, then drag.
Tracktrackdata-orientationThe bar the handle travels along.
Indicatorindicatordata-orientationThe fill from 0 to the handle. Hidden in the example.
Thumbthumbrole="slider", aria-valuemin, aria-valuemax, aria-valuenow, aria-valuetext, aria-orientation, aria-label, data-index, data-dragging, data-disabledThe handle. It is the focus stop and holds the hidden input.
Inputinput-Hidden value carrier, rendered only when name is set.

Accessibility

Follows the WAI-ARIA Slider pattern. The thumb is the only focus stop, and it leaves the tab order when the slider is disabled. Arrow Right and Arrow Up add one step, Arrow Left and Arrow Down take one away, Shift with an arrow key, Page Up and Page Down move the value by 10, and Home and End jump to 0 and 100. The hook keeps aria-valuenow and aria-valuetext current as the value changes. Name the slider with label.