Anchor
v0.0.10
The Mishka Chelekom Mob Anchor is a tappable text link for iOS and Android screens built with Mob. It reports the tap and the destination to your screen, which opens a URL or moves to another screen. It is the native port of the headless Anchor.
Overview of the Mob Anchor component for iOS and Android
A device has no <a> element, but it has navigation, so an anchor is a tappable Text with a destination. The component draws the label and, unless you turn it off, a rule under it. The children of the tag replace label when you give them.
The component does not open anything. A node tree only describes the screen, so side effects belong to the screen that receives the event. on_tap carries the destination as {tag, href}, which lets one handler serve every link on a page. Your screen handles it in handle_info/2 and does one of two things:
- For an external URL, call
MishkaAnchor.open/1, which wrapsMob.Device.open_url/1. - For another screen, call
Mob.Socket.push_screen/3.
The underline
The rule is exactly as wide as the link. A Box told to fill its parent would span the whole card, so the component draws the rule the other way round. An outer Box in the link color hugs the text. The text sits on top of it, painted in backdrop, with a 1dp gap at the bottom where the link color shows through.
backdrop defaults to :surface, which is what a card or a sheet is made of. Set it to :background for a link on the bare screen. Without an underline, backdrop is never drawn.
Generate the anchor component
Run this from your Mob app's root to add the component to lib/<app>/components/:
mix mishka.ui.gen.mob anchorThe generator registers the component's tag, so you can use it in ~MOB markup. It also copies the shared Event module. The examples on this page use the mishka_ prefix of the showcase app (--module-prefix mishka_), so the tag is <MishkaAnchor>. Without a prefix the tag is <Anchor>.
Anchor that opens a URL
The anchor shows the label mishka.tools and carries https://mishka.tools as its href. When you tap it, the screen receives {:tap, {:open, href}} and decides what to do with the URL.
In the snippet, handle/2 is the showcase page's shorthand for a handle_info({:tap, {:open, href}}, socket) clause. In your own screen, write the handle_info/2 clause shown under Events.
Anchor that opens a URL
<MishkaAnchor label="mishka.tools" href="https://mishka.tools" on_tap={:open} />
def handle({:open, href}, socket), do: (MishkaAnchor.open(href); socket)Helper functions
MishkaAnchor.open/1 opens an external URL, which is what an href means on a device. It returns :ok after it calls Mob.Device.open_url/1. It returns :error for anything that is not an http or https URL, including nil, so a component never hands an arbitrary string to the platform's URL opener.
MishkaAnchor.open("https://mishka.tools") #=> :ok
MishkaAnchor.open("ftp://example.com") #=> :error
MishkaAnchor.open(nil) #=> :errorProps
| Prop | Type | Default | Description |
|---|---|---|---|
label | string | nil | The link text. Children override it. |
href | string | nil | Sent back with the tap. |
on_tap | event tag (atom) | none | Sends {:tap, {tag, href}}, or {:tap, tag} when there is no href. |
color | color token or ARGB | :primary | Link color. |
underline | boolean | true | Draws a rule under the text, as wide as the link. |
backdrop | color token or ARGB | :surface | The color behind the link. The rule shows through a 1dp gap under it. See The underline. |
text_size | size token | :base | Text size. |
disabled | boolean | false | Mutes the link and removes its handler. |
Events
Your screen receives {:tap, {tag, href}} in handle_info/2, or {:tap, tag} when the anchor has no href. A disabled anchor sends nothing.
def handle_info({:tap, {:open, href}}, socket) do
MishkaAnchor.open(href)
{:noreply, socket}
endDifferences from the web component
The Mob anchor does not port these parts of the headless component:
target,relanddownload.navigateversuspatch. It is a LiveView routing concept, and on a device the screen decides how to navigate.
Attributes
| Name | Type | Default | Values | Required | Description |
|---|---|---|---|---|---|
label
|
string
| — | — | No | The link text. Children override it. |
href
|
string
| — | — | No | Sent back with the tap. |
on_tap
|
event tag (atom)
| — | — | No | `{:tap, {tag, href}}`, or `{:tap, tag}` with no href. |
color
|
color token / ARGB
|
:primary
| — | No | Link colour. |
underline
|
boolean
|
true
| — | No | Draw a rule under the text. |
backdrop
|
color token / ARGB
|
:surface
| — | No | The colour behind the link. See "The underline". |
text_size
|
size token
|
:base
| — | No | Text size. |
disabled
|
boolean
|
false
| — | No | Mutes and unwires. |
Options
Each option takes one or more of its values, separated by commas.
| Option | Values |
|---|---|
--type
|
anchor
|
--module
| A module name of your own |
What it generates
mix mishka.ui.gen.mob anchor