A widget type — the catalog entry that describes a kind of widget that can be placed on a dashboard.
Widgets come from two places:
- Built-in widgets shipped by this module (note, clock, module-stats…).
- Provider widgets contributed by any other PhoenixKit module.
The provider contract (decoupled by design)
A provider module exposes widgets by defining a zero-arity
phoenix_kit_widgets/0 that returns a list of plain maps. It does NOT
depend on phoenix_kit_dashboards at all — the dashboards module normalizes
the maps into %Widget{} structs via from_map/2. This keeps the dependency
arrow pointing one way: data modules know nothing about dashboards.
# in phoenix_kit_emails.ex
def phoenix_kit_widgets do
[
%{
key: "emails.deliverability",
name: "Deliverability",
description: "Bounce / complaint rates over time",
icon: "hero-envelope",
module_key: "emails",
component: PhoenixKitEmails.Widgets.DeliverabilityLive,
default_size: %{w: 6, h: 2},
min_size: %{w: 3, h: 1},
settings_schema: [
%{key: "window", type: :select, label: "Window",
options: ["7d", "30d", "90d"], default: "30d"}
]
}
]
end:component is a Phoenix.LiveComponent module. The dashboard host renders it
with <.live_component module={w.component} id={instance_id} settings={...} view={...} size={%{w: w, h: h}} scope={...} /> — the selected view key and the
instance's current span ride along, so one widget can render several
densities/layouts. Each widget owns its own data loading and refresh
lifecycle.
Settings schema
Each field map drives one input in the generated per-widget settings form:
%{key: "window", type: :select, label: "Window",
options: ["7d", "30d", "90d"], default: "30d"}Supported :type values: :string, :text, :number, :boolean, :select.
Select options may be plain strings or {label, value} tuples (the label is
translated at render when a translation exists).
Summary
Functions
Default settings map derived from a widget type's settings_schema.
The default view key for a widget type: the first declared view, or nil when
the widget has a single intrinsic view.
Normalize a provider-supplied plain map into a %Widget{}.
The minimum size for an instance showing view_key — the view's own
min_size when it declares one (an analog clock needs more room than a text
one), else the widget type's. nil resolves through the default view, so
instances created before a widget declared views get the right floor too.
Types
@type size() :: %{w: pos_integer(), h: pos_integer()}
@type t() :: %PhoenixKitDashboards.Widget{ category: String.t(), component: module(), default_size: size(), description: String.t() | nil, icon: String.t(), key: String.t(), max_size: size(), min_size: size(), module_key: String.t() | nil, name: String.t(), refresh_interval: pos_integer() | nil, settings_schema: [settings_field()], source: module() | nil, views: [view()] }
Functions
Default settings map derived from a widget type's settings_schema.
The default view key for a widget type: the first declared view, or nil when
the widget has a single intrinsic view.
Normalize a provider-supplied plain map into a %Widget{}.
Returns {:ok, widget} or {:error, reason}. Invalid widgets are dropped by
the registry (and logged) rather than crashing discovery.
The minimum size for an instance showing view_key — the view's own
min_size when it declares one (an analog clock needs more room than a text
one), else the widget type's. nil resolves through the default view, so
instances created before a widget declared views get the right floor too.