PetalComponents.Slider (petal_components v4.15.2)

Copy Markdown View Source

A styled range slider, in single-thumb and dual-thumb (range) forms.

Built on native <input type="range">. That is the whole accessibility story: the browser gives us role="slider", aria-valuemin/valuemax/ valuenow, the full arrow/Home/End/PageUp/PageDown keyboard map, touch and pointer handling, and form posting. None of it is re-implemented here. Everything this module adds is paint: a custom track, a primary fill, tick marks, and an optional value readout.

Single thumb

<.slider name="volume" label="Volume" value={60} value_suffix="%" show_value="inline" />

Dual thumb (a range)

Pass min_field and max_field (or values with min_name/max_name). Two overlaid native inputs post both names, and the fill spans between them.

<.form for={@form} phx-change="filter">
  <.slider
    min_field={@form[:min]}
    max_field={@form[:max]}
    min={0}
    max={1000}
    step={50}
    label="Price"
    value_prefix="$"
    show_value="inline"
  />
</.form>

Marks

marks renders labelled stops under the track. An empty label renders a tick only, so you can mark every step and label a few.

<.slider
  name="year"
  label="Year"
  value={2010}
  min={1990}
  max={2030}
  step={5}
  show_value="tooltip"
  marks={[
    %{value: 1990, label: "1990"},
    %{value: 2010, label: "2010"},
    %{value: 2030, label: "2030"}
  ]}
/>

Listening for changes without a form

Wrapping the slider in a <.form phx-change="..."> is the usual route, and the one the playground's price filter takes. When there is no form to hang it on, the PetalSlider hook also emits a bubbling petal:slider-change CustomEvent on the wrapper, carrying detail: {value} for a single thumb and detail: {values: [min, max]} for a dual one:

// app.js
window.addEventListener("petal:slider-change", (event) => {
  if (event.target.id !== "volume") return
  document.querySelector("audio").volume = event.detail.value / 100
})

It bubbles to window, so one listener can serve every slider on the page and survives LiveView re-rendering the slider itself.

Relationship to the range field types

<.field type="range"> and <.field type="range-dual"> still work and are not going anywhere in this release, but <.slider> supersedes them: it is the same native machinery with marks, a value readout, vertical orientation and sizes on top. Reach for <.slider> in new code.

Summary

Functions

Renders a slider.

Functions

slider(assigns)

Renders a slider.

Single vs dual mode is inferred: min_field/max_field or values means dual, otherwise single. Mixing the two raises ArgumentError.

Attributes

  • field (:any) - a Phoenix.HTML.FormField for single-thumb use; sets name, id and value. Defaults to nil.
  • min_field (:any) - FormField for the lower value; dual-thumb mode when set with max_field. Defaults to nil.
  • max_field (:any) - FormField for the upper value; dual-thumb mode when set with min_field. Defaults to nil.
  • name (:string) - input name when not using field. Defaults to nil.
  • min_name (:string) - lower input name in dual mode when not using min_field; defaults to "#{name}_min". Defaults to nil.
  • max_name (:string) - upper input name in dual mode when not using max_field; defaults to "#{name}_max". Defaults to nil.
  • id (:string) - wrapper id; the inputs derive theirs from it. Defaults to nil.
  • value (:any) - current value (single-thumb). Defaults to nil.
  • values (:list) - [min, max] current values (dual-thumb, when not using min_field/max_field). Defaults to nil.
  • min (:any) - lower bound. Defaults to 0.
  • max (:any) - upper bound. Defaults to 100.
  • step (:any) - step increment; values snap to it natively. Defaults to 1.
  • marks (:list) - labelled stops rendered under the track, e.g. [%{value: 0, label: "Min"}, %{value: 50, label: ""}]; an empty label renders a tick only. Defaults to [].
  • show_value (:string) - tooltip shows the value in a bubble above the thumb while dragging or focus-visible; inline renders it in the label row beside the track. Defaults to "none". Must be one of "tooltip", "inline", or "none".
  • value_prefix (:string) - prepended to displayed values, e.g. "$". Defaults to "".
  • value_suffix (:string) - appended to displayed values, e.g. "%". Defaults to "".
  • label (:string) - visible label above the track, and the base for each input's accessible name (dual thumbs become "<label> minimum" and "<label> maximum"); defaults to the humanised field name. Defaults to nil.
  • orientation (:string) - vertical stands the track up, filling from the bottom. Defaults to "horizontal". Must be one of "horizontal", or "vertical".
  • size (:string) - track thickness and thumb diameter. Defaults to "md". Must be one of "sm", "md", or "lg".
  • disabled (:boolean) - disables every input and dims the control. Defaults to false.
  • class (:any) - CSS class for the outer wrapper. Defaults to nil.
  • Global attributes are accepted. any other HTML attributes, applied to the wrapper.