Pure view of a mishka.ui_kit.bundle.v3 for the installer's component picker: groups the
components by type, keeps only the light fields the picker needs (name / label / deps — never
the heavy body/template/examples), and computes the transitive COMPONENT-dependency closure of a
selection so required components can be locked.
The bundle JSON has no "required" flag and UiKitHandler does not resolve dependencies itself, so
the picker must derive "required" = the closure of the user's picks. Picking chelekom-card pulls
in chelekom-icon (depended on by ~80 components), which the user then cannot unmark. *.js hook
deps are ignored here — js_hooks and the stylesheet install in full regardless of the component
selection — and the chelekom-scroll_area (underscore) vs chelekom-scroll-area (hyphen) naming
mismatch is normalized.
Per-component narrowing is offered along the axes variant/color/size/padding/space/rounded/border
(in that display order). An axis is shown for a component only when the kit enumerates string values
for it AND declares a string default — components whose axis (e.g. size) is numeric simply skip it.
The axis name is used verbatim as the :selection per-component key, which UiKitHandler accepts;
the picker pre-checks and locks the kit-declared default. Components install minimal by default
(their own default value), and config_extras widens chosen axes to [default | extras].
See MishkaCmsCore.Runtime.Handlers.UiKitHandler and MishkaCmsWeb.InstallLive.
Summary
Functions
The order the installer shows configurable axes in, most-recognised first.
Builds the picker catalog (groups + name index + dependency graph) from a parsed v3 bundle.
Builds the :selection map for UiKitHandler.install_chelekom!/1 from the picked components and the
per-component variant config.
The same selection, split per kit — what UiKitHandler.install_kits!/2 takes.
The full set of components to install: the user's picks plus their required closure.
A kit's own name, as a person would read it: chelekom_headless -> "Chelekom Headless".
Strips the kit prefix for display (chelekom-card -> card).
The same, told which kit shipped the component.
The components the kit declares the CMS cannot run without, whatever the operator picked.
One catalogue over several bundles, for an installer that offers more than one kit.
The selected components that force name into the required set (for a 'required by …' hint).
The transitive component-dependency closure of selected that the user did NOT explicitly pick —
i.e. the components that must be installed and locked in the UI. install_set/2 adds the picks back.
Sorts axes by axis_order/0, with anything unlisted after, then alphabetically.
Types
Functions
@spec axis_order() :: [String.t()]
The order the installer shows configurable axes in, most-recognised first.
Kept as a SORT KEY rather than a filter — see config_features/1. An axis this list has never
heard of sorts after the ones it has, which is the only thing the order was ever for. Public so
the installer reads it here instead of holding a second copy.
Builds the picker catalog (groups + name index + dependency graph) from a parsed v3 bundle.
Builds the :selection map for UiKitHandler.install_chelekom!/1 from the picked components and the
per-component variant config.
Every component installs minimal by default — narrowed to its OWN default variant/color (the
kit's defaults are not uniform: color defaults to natural for ~half the components, base for
others — so a global "base only" would render those bare). config_extras (%{component_name => %{axis => [extra_values]}}) widens individual components: e.g. adding danger to button's color
installs that component with [natural, danger]. Axes without a usable default, or with no extras
on components that have no enumerable values, simply install full.
The same selection, split per kit — what UiKitHandler.install_kits!/2 takes.
With one kit installed this is the single-kit map under one key, and behaves exactly as before.
With two, each kit gets only its own components: the labels a selection is keyed by (alert,
tree) are unique per kit but not across kits, so a flat map would install one kit's narrowing
onto another kit's component of the same name.
The full set of components to install: the user's picks plus their required closure.
A kit's own name, as a person would read it: chelekom_headless -> "Chelekom Headless".
Used by the installer's kit chips and the badge beside a component, both of which only appear once a second kit is on disk.
Strips the kit prefix for display (chelekom-card -> card).
The same, told which kit shipped the component.
The kit's own name is the prefix, and Component SLUGIFIES what it stores — a bundle named
chelekom_headless installs chelekom-headless-tree, so stripping at the first hyphen would
leave "headless-tree". Given the kit, the whole prefix comes off and the label is "tree".
The components the kit declares the CMS cannot run without, whatever the operator picked.
deps answers "this component needs that one"; required answers "this install needs it at all".
An icon is drawn by half of Chelekom's other components and nothing in the markup says so, so
deselecting it left the rest unable to render — and the picker had no way to know.
Seeded into the dependency closure rather than checked separately, so it is locked in the UI and installed by the same path a dependency is.
One catalogue over several bundles, for an installer that offers more than one kit.
Entries keep their FULL component name, which is unique across kits, so the picker's selection set and dependency closure keep working unchanged; only the labels and the install selection need to know which kit an entry came from.
The selected components that force name into the required set (for a 'required by …' hint).
The transitive component-dependency closure of selected that the user did NOT explicitly pick —
i.e. the components that must be installed and locked in the UI. install_set/2 adds the picks back.
Sorts axes by axis_order/0, with anything unlisted after, then alphabetically.