# `MingaEditor.Extension.Sidebar`
[🔗](https://github.com/jsmestad/minga/blob/main/lib/minga_editor/extension/sidebar.ex#L1)

Source-owned registry for extension sidebar contributions.

Extensions register sidebar metadata once, then publish snapshots whenever their content changes. The editor render and layout paths read the cached registry state directly instead of invoking extension callbacks per frame.

# `action_handler`

```elixir
@type action_handler() :: MingaEditor.Extension.Sidebar.Entry.action_handler()
```

Action handler invoked through the editor action pipeline.

# `entry`

```elixir
@type entry() :: MingaEditor.Extension.Sidebar.Entry.t()
```

Registered sidebar entry.

# `placement`

```elixir
@type placement() :: MingaEditor.Extension.Sidebar.Entry.placement()
```

Sidebar placement.

# `register_attrs`

```elixir
@type register_attrs() :: %{
  :id =&gt; String.t(),
  :display_name =&gt; String.t(),
  optional(:description) =&gt; String.t(),
  optional(:placement) =&gt; placement(),
  optional(:priority) =&gt; integer(),
  optional(:preferred_width) =&gt; pos_integer(),
  optional(:visible?) =&gt; boolean(),
  optional(:focused?) =&gt; boolean(),
  optional(:semantic_kind) =&gt; String.t(),
  optional(:icon) =&gt; String.t(),
  optional(:input_handler) =&gt; module() | nil,
  optional(:action_handler) =&gt; action_handler(),
  optional(:badge_count) =&gt; non_neg_integer() | nil,
  optional(:snapshot) =&gt; MingaEditor.Extension.Sidebar.Snapshot.t()
}
```

Registration attributes.

# `source`

```elixir
@type source() :: Minga.Extension.ContributionCleanup.contribution_source()
```

Contribution source that owns a sidebar.

# `table`

```elixir
@type table() :: atom()
```

Registry table name.

# `active_left`

```elixir
@spec active_left() :: entry() | nil
```

Returns the first visible left sidebar, if any.

# `active_left`

```elixir
@spec active_left(table()) :: entry() | nil
```

# `all`

```elixir
@spec all() :: [entry()]
```

Returns all registered sidebars ordered by priority and id.

# `all`

```elixir
@spec all(table()) :: [entry()]
```

# `default_table`

```elixir
@spec default_table() :: table()
```

Returns the default production sidebar registry table.

# `dispatch_action`

```elixir
@spec dispatch_action(MingaEditor.State.t(), String.t(), String.t(), map()) ::
  MingaEditor.State.t()
```

Dispatches a semantic action through the registered action handler.

# `dispatch_action`

```elixir
@spec dispatch_action(table(), MingaEditor.State.t(), String.t(), String.t(), map()) ::
  MingaEditor.State.t()
```

# `focus_left`

```elixir
@spec focus_left(String.t() | nil) :: :ok | {:error, term()}
```

Makes one visible left sidebar focused and clears focus from the rest.

# `focus_left`

```elixir
@spec focus_left(table(), String.t() | nil) :: :ok | {:error, term()}
```

# `get`

```elixir
@spec get(String.t()) :: entry() | nil
```

Returns a sidebar by id.

# `get`

```elixir
@spec get(table(), String.t()) :: entry() | nil
```

# `publish_snapshot`

```elixir
@spec publish_snapshot(
  source(),
  String.t(),
  MingaEditor.Extension.Sidebar.Snapshot.t() | keyword() | map()
) :: :ok | {:error, term()}
```

Publishes a cached snapshot for a sidebar.

# `publish_snapshot`

```elixir
@spec publish_snapshot(
  table(),
  source(),
  String.t(),
  MingaEditor.Extension.Sidebar.Snapshot.t() | keyword() | map()
) :: :ok | {:error, term()}
```

# `register`

```elixir
@spec register(source(), register_attrs() | keyword()) :: :ok | {:error, term()}
```

Registers or replaces a sidebar owned by `source`.

# `register`

```elixir
@spec register(table(), source(), register_attrs() | keyword()) ::
  :ok | {:error, term()}
```

# `set_focused`

```elixir
@spec set_focused(source(), String.t(), boolean()) :: :ok | {:error, term()}
```

Updates sidebar focus state.

# `set_focused`

```elixir
@spec set_focused(table(), source(), String.t(), boolean()) :: :ok | {:error, term()}
```

# `set_visible`

```elixir
@spec set_visible(source(), String.t(), boolean()) :: :ok | {:error, term()}
```

Updates sidebar visibility.

# `set_visible`

```elixir
@spec set_visible(table(), source(), String.t(), boolean()) :: :ok | {:error, term()}
```

# `start_link`

```elixir
@spec start_link(keyword()) :: GenServer.on_start()
```

# `table_for`

```elixir
@spec table_for(map() | nil) :: table()
```

Returns the sidebar registry table for a state-like value.

# `unregister`

```elixir
@spec unregister(source(), String.t()) :: :ok | {:error, term()}
```

Unregisters a sidebar when it is owned by the caller's source.

# `unregister`

```elixir
@spec unregister(table(), source(), String.t()) :: :ok | {:error, term()}
```

# `unregister_source`

```elixir
@spec unregister_source(source()) :: :ok
```

Removes every sidebar owned by a source.

# `unregister_source`

```elixir
@spec unregister_source(table(), source()) :: :ok
```

# `visible`

```elixir
@spec visible() :: [entry()]
```

Returns visible registered sidebars ordered by priority and id.

# `visible`

```elixir
@spec visible(table()) :: [entry()]
```

---

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