mix mishka.ui.gen.mob (Mishka Chelekom v0.0.10)

Copy Markdown View Source

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 ~MOB markup. The tag follows --module-prefix like every other generated name — no prefix gives :drawer, --module-prefix acme_ gives :acme_drawer and <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

  • --module or -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 to config :mob, :extra_tags
  • --no-kit - Do not vendor the shared support modules
  • --yes - Apply without prompts

Summary

Functions

igniter(igniter)

Callback implementation for Igniter.Mix.Task.igniter/1.