Generate a native Mob component for a BEAM-on-device app
Mob components are native: they build a node tree of platform widgets
(Box, Row, Text, Slider, Canvas, …) that Compose and SwiftUI render
directly. There is no HTML, no JS engine and no CSS, so unlike
mix mishka.ui.gen.headless this task installs no npm packages and touches no
stylesheet.
Output goes to lib/<app>/components/<name>.ex (module
<App>.Components.<Name>) — a Mob app is a plain OTP application with no
_web namespace.
What it does that the headless generator does not
Headless components never reference each other in code; you compose them in HEEx. Mob components do — a close button calls an action icon — so two extra things happen here:
necessary:does real work. ~20 components depend on a sibling, and the task generates them too. It does not ask: the dependency is a compile -time one — an alias and a call — so declining it would leave a module that cannot compile.- the composite registry is maintained in
lib/<app>/components.ex, so<Drawer>works in~MOBmarkup. The tag follows--module-prefixlike every other generated name — no prefix gives:drawer,--module-prefix acme_gives:acme_drawerand<AcmeDrawer>. Registration is idempotent: the registry is rebuilt from the components present, not appended to.
Note that Mob.Composite's table is global, so an unprefixed :drawer can
collide with a composite the app already registered under that name. That is
what --module-prefix is for.
Writing components as tags
Registering a composite makes <Drawer> render. It does not make it compile
quietly: ~MOB validates tag names at compile time, and a runtime registration
is invisible to that check, so the sigil warns that the tag is unknown. On
--warnings-as-errors that makes the tag form unusable.
Mob's documented fix is config :mob, :extra_tags, so generating a component
adds its tag to that list in your config/config.exs and queues
mix compile --force (Mob does not track the config read). That is what lets
you write
<AcmeDrawer open={@open} />instead of {drawer(open: @open)}. The tags come from the registry above
rather than from filenames, so --module-prefix is carried through. Only
missing tags are added to the ~w(...) list; entries of yours or of other kits
are left alone, and nothing inside deps/ is touched.
Pass --no-tags to leave :extra_tags alone and call the functions.
The shared Event/Color modules are vendored automatically when a component
needs them (see mix mishka.ui.gen.mob.kit).
Example
mix mishka.ui.gen.mob drawer
mix mishka.ui.gen.mob color_picker --module-prefix mishka_
Options
--moduleor-m- Custom module name for the component--component-prefix- Prefix for the public function name--module-prefix- Prefix for the module name--sub- Marks this as a dependency sub-generation--no-save- Use prefixes without saving them to config--no-register- Do not touch the composite-tag registry--no-tags- Do not add the tags toconfig :mob, :extra_tags--no-kit- Do not vendor the shared support modules--yes- Apply without prompts
Summary
Functions
Callback implementation for Igniter.Mix.Task.igniter/1.
Functions
Callback implementation for Igniter.Mix.Task.igniter/1.