# `Plushie.Widget.Table`
[🔗](https://github.com/plushie-ui/plushie-elixir/blob/v0.6.0/lib/plushie/widget/table.ex#L1)

Data table -- composite widget built from columns, rows, and scrollable containers.

## Props

- `columns` (list of maps) -- column definitions. Each column is a map
  with atom keys from a fixed schema:

      %{key: "name", label: "Name", sortable: true}

  Required fields:
  - `key` (string) -- lookup key into row data maps.
  - `label` (string) -- display text for the column header.

  Optional fields:
  - `align` -- horizontal alignment for column cells (`"left"`,
    `"center"`, `"right"`). Default: `"left"`.
  - `width` -- column width as a `Plushie.Type.Length` value. Default: `:fill`.
  - `sortable` -- whether clicking the header triggers a sort event.
    Default: `false`.

- `rows` (list of maps) -- data rows. Each row is a string-keyed map
  where keys match the column `key` values:

      %{"name" => "Alice", "email" => "alice@example.com"}

  String keys are the convention because row schemas are typically
  user-defined or come from external data (JSON, database queries).
  Atom keys also work (the wire protocol stringifies all keys), but
  string keys avoid dynamic atom creation when data comes from
  external sources.
- `header` (boolean) -- show header row. Default: true.
- `separator` (boolean) -- show separator line below header. Default: true.
- `width` (length) -- table width. Default: fill. See `Plushie.Type.Length`.
- `padding` (number | map) -- table padding. See `Plushie.Type.Padding`.
- `sort_by` (string | nil) -- key of the currently sorted column.
- `sort_order` (`:asc` | `:desc` | nil) -- current sort direction.
- `header_text_size` (number) -- header row text size in pixels.
- `row_text_size` (number) -- body row text size in pixels.
- `cell_spacing` (number) -- horizontal spacing between cells in pixels.
- `row_spacing` (number) -- vertical spacing between rows in pixels.
- `separator_thickness` (number) -- separator line thickness in pixels.
- `separator_color` (color) -- separator line color. See `Plushie.Type.Color`.
- `a11y` (map) -- accessibility overrides. See `Plushie.Type.A11y`.

# `column`

```elixir
@type column() :: %{
  :key =&gt; String.t(),
  :label =&gt; String.t(),
  optional(:align) =&gt; String.t(),
  optional(:width) =&gt; Plushie.Type.Length.t(),
  optional(:sortable) =&gt; boolean()
}
```

A column definition map. Uses atom keys from the fixed SDK schema:
`:key`, `:label`, `:align`, `:width`, `:sortable`.

# `option`

```elixir
@type option() ::
  {:columns, [column()]}
  | {:rows, [row()]}
  | {:header, boolean()}
  | {:separator, boolean()}
  | {:width, Plushie.Type.Length.t()}
  | {:padding, Plushie.Type.Padding.t()}
  | {:sort_by, String.t()}
  | {:sort_order, sort_order()}
  | {:header_text_size, number()}
  | {:row_text_size, number()}
  | {:cell_spacing, number()}
  | {:row_spacing, number()}
  | {:separator_thickness, number()}
  | {:separator_color, Plushie.Type.Color.input()}
  | {:a11y, Plushie.Type.A11y.t() | map() | keyword()}
```

# `row`

```elixir
@type row() :: %{optional(String.t()) =&gt; term()}
```

A data row map. Keys are strings matching column `:key` values.
Values are any term (rendered as text via `to_string/1`).

# `sort_order`

```elixir
@type sort_order() :: :desc | :asc
```

# `t`

```elixir
@type t() :: %Plushie.Widget.Table{
  a11y: Plushie.Type.A11y.t() | nil,
  cell_spacing: number() | nil,
  children: [Plushie.Widget.child()],
  columns: [column()] | nil,
  header: boolean() | nil,
  header_text_size: number() | nil,
  id: String.t(),
  padding: Plushie.Type.Padding.t() | nil,
  row_spacing: number() | nil,
  row_text_size: number() | nil,
  rows: [row()] | nil,
  separator: boolean() | nil,
  separator_color: Plushie.Type.Color.t() | nil,
  separator_thickness: number() | nil,
  sort_by: String.t() | nil,
  sort_order: sort_order() | nil,
  width: Plushie.Type.Length.t() | nil
}
```

# `a11y`

```elixir
@spec a11y(table :: t(), a11y :: Plushie.Type.A11y.t() | map() | keyword()) :: t()
```

Sets accessibility annotations.

# `build`

```elixir
@spec build(table :: t()) :: Plushie.Widget.ui_node()
```

Converts this table struct to a `ui_node()` map via the `Plushie.Widget` protocol.

# `cell_spacing`

```elixir
@spec cell_spacing(table :: t(), cell_spacing :: number()) :: t()
```

Sets the horizontal spacing between cells in pixels.

# `columns`

```elixir
@spec columns(table :: t(), columns :: [column()]) :: t()
```

Sets the column definitions.

# `extend`

```elixir
@spec extend(table :: t(), children :: [Plushie.Widget.child()]) :: t()
```

Appends multiple children to the table.

# `header`

```elixir
@spec header(table :: t(), header :: boolean()) :: t()
```

Sets whether the header row is shown.

# `header_text_size`

```elixir
@spec header_text_size(table :: t(), header_text_size :: number()) :: t()
```

Sets the header text size in pixels.

# `new`

```elixir
@spec new(id :: String.t(), opts :: [option()]) :: t()
```

Creates a new table struct with optional keyword opts.

# `padding`

```elixir
@spec padding(table :: t(), padding :: Plushie.Type.Padding.t()) :: t()
```

Sets the table padding.

# `push`

```elixir
@spec push(table :: t(), child :: Plushie.Widget.child()) :: t()
```

Appends a child to the table.

# `row_spacing`

```elixir
@spec row_spacing(table :: t(), row_spacing :: number()) :: t()
```

Sets the vertical spacing between rows in pixels.

# `row_text_size`

```elixir
@spec row_text_size(table :: t(), row_text_size :: number()) :: t()
```

Sets the row text size in pixels.

# `rows`

```elixir
@spec rows(table :: t(), rows :: [row()]) :: t()
```

Sets the data rows.

Row maps must use string keys matching the column `:key` values.
Raises `ArgumentError` if the first row contains atom keys.

# `separator`

```elixir
@spec separator(table :: t(), separator :: boolean()) :: t()
```

Sets whether the separator line is shown.

# `separator_color`

```elixir
@spec separator_color(table :: t(), separator_color :: Plushie.Type.Color.input()) ::
  t()
```

Sets the separator line color.

# `separator_thickness`

```elixir
@spec separator_thickness(table :: t(), separator_thickness :: number()) :: t()
```

Sets the separator line thickness in pixels.

# `sort_by`

```elixir
@spec sort_by(table :: t(), sort_by :: String.t()) :: t()
```

Sets the currently sorted column key.

# `sort_order`

```elixir
@spec sort_order(table :: t(), sort_order :: sort_order()) :: t()
```

Sets the current sort direction.

# `width`

```elixir
@spec width(table :: t(), width :: Plushie.Type.Length.t()) :: t()
```

Sets the table width.

# `with_options`

```elixir
@spec with_options(table :: t(), opts :: [option()]) :: t()
```

Applies keyword options to an existing table struct.

---

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