defmodule <%= @module %> do @moduledoc """ Headless **progress** — a progress bar for task completion (WAI-ARIA progressbar). `role="progressbar"` with `aria-valuemin` / `aria-valuemax` / `aria-valuenow` (clamped into the range) and `aria-valuetext`. Pass `value={nil}` for an **indeterminate** (loading) bar — `aria-valuenow` is then omitted and no fill ratio is set. The root and every part expose the status as exactly one of `data-indeterminate` / `data-progressing` / `data-complete`, so you can style each state. The inner `data-part="indicator"` carries a `--chelekom-progress` (0..1) ratio for the fill; pass `show_value` for a `data-part="value"` readout. Ships **no** colors or spacing — style via the `chelekom-progress*` classes. WAI-ARIA: https://www.w3.org/TR/wai-aria-1.2/#progressbar """ use Phoenix.Component @doc type: :component attr :id, :string, default: nil, doc: "Optional id (anchors aria-labelledby)" attr :value, :integer, default: nil, doc: "Current value in [min, max]; nil = indeterminate" attr :min, :integer, default: 0, doc: "Lower bound of the range" attr :max, :integer, default: 100, doc: "Upper bound of the range" attr :label, :string, default: nil, doc: "Accessible label (rendered + wired to aria-labelledby)" attr :value_text, :string, default: nil, doc: ~s|Human value for aria-valuetext + readout (defaults to a percent; "Indeterminate" when nil)| attr :show_value, :boolean, default: false, doc: ~s|Render a `data-part="value"` readout| attr :class, :any, default: nil, doc: "Extra classes for the root" attr :label_class, :any, default: nil, doc: ~s|Extra classes for `data-part="label"`| attr :value_class, :any, default: nil, doc: ~s|Extra classes for `data-part="value"`| attr :track_class, :any, default: nil, doc: ~s|Extra classes for `data-part="track"`| attr :indicator_class, :any, default: nil, doc: ~s|Extra classes for `data-part="indicator"`| attr :rest, :global def <%= @component_prefix %>progress(assigns) do lo = assigns.min hi = assigns.max {value, ratio, status} = case assigns.value do nil -> {nil, nil, "indeterminate"} v -> c = v |> Kernel.max(lo) |> Kernel.min(hi) r = if hi > lo, do: (c - lo) / (hi - lo), else: 0.0 {c, r, if(c >= hi, do: "complete", else: "progressing")} end assigns = assigns |> assign(:value, value) |> assign(:ratio, ratio) |> assign(:status, status) |> assign( :value_text, assigns.value_text || if(status == "indeterminate", do: "Indeterminate", else: "#{round(ratio * 100)}%") ) ~H"""