defmodule Corex.ToggleGroup do @moduledoc ~S''' Phoenix implementation of [Zag.js Toggle Group](https://zagjs.com/components/react/toggle-group). ### Minimal ```heex <.toggle_group class="toggle-group"> <:item value="a"> A <:item value="b"> B <:item value="c"> C ``` ### Extended This example assumes the import of `.icon` from `Core Components` ```heex <.toggle_group multiple={false} on_value_change="on_value_change" id="toggle-group-id" value=["center"] class="toggle-group"> <:item value="left"> <.icon name="hero-bars-3-bottom-left" /> <:item value="center"> <.icon name="hero-bars-3" /> <:item value="right"> <.icon name="hero-bars-3-bottom-right" /> ``` ### Controlled ```elixir defmodule MyAppWeb.ToggleGroupLive do use MyAppWeb, :live_view def mount(_params, _session, socket) do {:ok, assign(socket, :value, ["lorem"])} end def handle_event("on_value_change", %{"value" => value}, socket) do {:noreply, assign(socket, :value, value)} end def render(assigns) do ~H""" <.toggle_group class="toggle-group" controlled value={@value} on_value_change="on_value_change" > <:item value="a"> A <:item value="b"> B <:item value="c"> C """ end end ``` ## Programmatic Control ***Client-side*** ```heex ``` ***Server-side*** ```elixir def handle_event("open_item", _, socket) do {:noreply, Corex.ToggleGroup.set_value(socket, "my-toggle-group", ["item-1"])} end ``` ## Styling Use data attributes to target elements: - `[data-scope="toggle-group"][data-part="root"]` - Container - `[data-scope="toggle-group"][data-part="item"]` - Item wrapper If you wish to use the default Corex styling, you can use the class `toggle-group` on the component. This requires to install mix corex.design first and import the component css file. ```css @import "../corex/main.css"; @import "../corex/tokens/themes/neo/light.css"; @import "../corex/components/toggle-group.css"; ``` You can then use modifiers ```heex <.toggle_group class="toggle-group toggle-group--accent toggle-group--lg"> ``` Learn more about modifiers and [Corex Design](https://corex-ui.com/components/toggle-group#modifiers) ''' @doc type: :component use Phoenix.Component alias Corex.ToggleGroup.Anatomy.{Props, Root, Item} alias Corex.ToggleGroup.Connect @doc """ Renders a toggle group component. """ attr(:id, :string, required: false, doc: "The id of the toggle group, useful for API to identify the toggle group" ) attr(:value, :list, default: [], doc: "The initial value or the controlled value of the toggle group, must be a list of strings" ) attr(:controlled, :boolean, default: false, doc: "Whether the toggle group is controlled") attr(:deselectable, :boolean, default: false, doc: "Whether the toggle group is deselectable") attr(:loopFocus, :boolean, default: true, doc: "Whether the toggle group is loopFocus") attr(:rovingFocus, :boolean, default: true, doc: "Whether the toggle group is rovingFocus") attr(:disabled, :boolean, default: false, doc: "Whether the toggle group is disabled") attr(:multiple, :boolean, default: true, doc: "Whether the toggle group allows multiple items to be selected" ) attr(:orientation, :string, default: "horizontal", values: ["horizontal", "vertical"], doc: "The orientation of the toggle group" ) attr(:dir, :string, default: nil, values: [nil, "ltr", "rtl"], doc: "The direction of the toggle group. When nil, derived from document (html lang + config :rtl_locales)" ) attr(:on_value_change, :string, default: nil, doc: "The server event name when the value change" ) attr(:on_value_change_client, :string, default: nil, doc: "The client event name when the value change" ) attr(:rest, :global) slot :item, required: true do attr(:value, :string, doc: "The value of the item, useful in controlled mode and for API to identify the item" ) attr(:disabled, :boolean, doc: "Whether the item is disabled") attr(:class, :string, doc: "The class of the item") attr(:aria_label, :string, doc: "Accessibility label for the item button. If not provided, the value will be used as a fallback." ) end def toggle_group(assigns) do assigns = assign_new(assigns, :id, fn -> "toggle-group-#{System.unique_integer([:positive])}" end) ~H"""