# `Plushie.Selection`
[🔗](https://github.com/plushie-ui/plushie-elixir/blob/v0.7.2/lib/plushie/selection.ex#L1)

Selection state for lists and tables. Pure data structure supporting
single, multi, and range selection modes.

## Modes

- `:single` - at most one item selected at a time.
- `:multi` - multiple items selectable; `extend: true` adds to the set.
- `:range` - like multi, but `range_select/2` selects a contiguous
  slice of the `order` list between the anchor and the target.

## Example

    sel = Plushie.Selection.new(mode: :multi, order: ["a", "b", "c", "d"])
    sel = Plushie.Selection.select(sel, "b")
    sel = Plushie.Selection.select(sel, "d", extend: true)
    Plushie.Selection.selected(sel)
    #=> MapSet.new(["b", "d"])

# `t`

```elixir
@type t() :: %Plushie.Selection{
  anchor: term() | nil,
  mode: :single | :multi | :range,
  order: [term()],
  selected: MapSet.t()
}
```

# `clear`

```elixir
@spec clear(sel :: t()) :: t()
```

Clears all selected items and resets the anchor.

# `deselect`

```elixir
@spec deselect(sel :: t(), id :: term()) :: t()
```

Removes `id` from the selection.

# `new`

```elixir
@spec new(opts :: keyword()) :: t()
```

Creates a new selection state.

## Options

- `:mode` - selection mode: `:single` (default), `:multi`, or `:range`.
- `:order` - ordered list of item IDs for range selection.

# `range_select`

```elixir
@spec range_select(sel :: t(), id :: term()) :: t()
```

Selects all items in `order` between the current anchor and `id`
(inclusive). If there is no anchor, selects only `id`.

Requires `order` to have been set at creation time via `new/1`.

# `select`

```elixir
@spec select(sel :: t(), id :: term(), opts :: keyword()) :: t()
```

Selects `id`. In `:single` mode, replaces the selection. In `:multi`
and `:range` modes, replaces unless `extend: true` is passed, in which
case `id` is added to the existing selection.

Sets the anchor to `id` for subsequent range selections.

# `select_all`

```elixir
@spec select_all(sel :: t()) :: t()
```

Selects all items in `order`.

Requires `order` to have been set at creation time via `new/1`.

# `selected`

```elixir
@spec selected(sel :: t()) :: MapSet.t()
```

Returns the `MapSet` of currently selected item IDs.

# `selected?`

```elixir
@spec selected?(sel :: t(), id :: term()) :: boolean()
```

Returns `true` if `id` is currently selected.

# `to_list`

```elixir
@spec to_list(sel :: t()) :: [term()]
```

Returns the selected IDs as a list (for passing to table `selected:` prop).

# `toggle`

```elixir
@spec toggle(sel :: t(), id :: term()) :: t()
```

Toggles `id` in the selection. If already selected, removes it;
otherwise adds it. In `:single` mode, toggling a selected item
clears the selection entirely.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
