Link
A link on its own that runs onClick: text underlined in the primary colour, with the platform's minimum touch target around it. The click is reported to the theme's analytics as a Link click event. When it is not enabled, it keeps its underline, in the disabled text colour, so that it still reads as a link, and does nothing.
import com.pantrixui.components.elements.link.PantrixLink
- Two overloads. A link that takes
onClickruns an action. One that takesurlopens the address with the platform'sUriHandler: in the browser, or in the app that handles the address. - Underlined. A link is not told apart by its colour alone: someone who cannot tell the two colours apart knows it by the line under it. A link that stands in no sentence and is known by its place takes
underline = LinkUnderline.OnHover: it is underlined under a pointer and while it holds the focus, and always where the platform is used by touch. - Its own colour.
colorsets the text, the underline, and the tint that appears under the link while a pointer is over it or it is pressed. Left out, it is the theme'sprimarycolour, on a fill too: there the caller gives the colour that reads. - Text style. Left out,
styleis the theme'slabelstyle, the style of aPantrixTextgiven none: a link beside a text is as large as that text. - Disabled.
enabled = falsedraws the link in the theme's disabled text colour, and the link takes no press. It keeps its underline: it reads as a link that cannot be followed, not as plain text. - Analytics. Every click is reported to the theme's
analyticsas theLinkcomponent'sclickevent. The event says whether the link opens an address, and never the address itself. - Automation.
tagKeysets the test tag: a link giventagKey = "forgot_password"has the tagLink_forgot_password.
Examples
A link that runs an action
At its plainest: a text and an onClick that runs when it is pressed. The link is written underlined, in the theme's primary colour. Press "Forgot my password": the app's snackbar lets you know.
It is given a tagKey: automation finds this link by the tag Link_forgot_password.
val snackbars = LocalPantrixSnackbars.current
val scope = rememberCoroutineScope()
PantrixLink(
text = "Forgot my password",
onClick = { scope.launch { snackbars?.show(message = "Reset link sent") } },
tagKey = "forgot_password"
)
A link that opens an address
The second overload takes url in place of onClick. When it is pressed the address is opened with the platform's UriHandler: in the browser, or in the app that handles the address. Its look and its other parameters are the same as the first overload's.
PantrixLink(text = "Privacy policy", url = "https://example.com/privacy", tagKey = "privacy_policy")
In its own colour
color is the link's own colour: it sets its text, its underline, and the tint that appears under it when a pointer comes over it or presses it. The first link's colour is the app's own purple, which is in none of the theme's roles; the second's is the theme's danger role.
val snackbars = LocalPantrixSnackbars.current
val scope = rememberCoroutineScope()
val own = ownColors()
Row(horizontalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.xl)) {
PantrixLink(
text = "Campaign terms",
onClick = { scope.launch { snackbars?.show(message = "Campaign terms opened") } },
color = own.color,
tagKey = "campaign_terms"
)
PantrixLink(
text = "Delete my account",
onClick = {},
color = PantrixTheme.colors.danger.color,
tagKey = "delete_account"
)
}
On a fill
A link does not look at the content colour around it: given no colour, it is in the theme's primary colour on a fill too. Where the fill is primary itself, that colour cannot be read; the caller gives the colour that reads there with color, here the role's onColor.
The PantrixText beside it is given no colour: it takes the fill's content colour by itself.
val primary = PantrixTheme.colors.primary
PantrixSurface(modifier = Modifier.fillMaxWidth(), color = primary.color) {
Row(
modifier = Modifier.padding(horizontal = PantrixTheme.spacing.lg),
horizontalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.sm),
verticalAlignment = Alignment.CenterVertically
) {
PantrixText(text = "A new version is ready.")
PantrixLink(text = "Learn more", onClick = {}, color = primary.onColor, tagKey = "learn_more")
}
}
Beside a text, and its text style
A link given no style is in the theme's label style, like a PantrixText given no style: in the top row the two stand side by side, at the same size.
The link below is given style = PantrixTheme.typography.footnote: the small link under a form. Though its text is smaller, the link is never shorter than the platform's touch target; it is as wide as its text, and starts where the row above it starts.
Row(
horizontalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.xs),
verticalAlignment = Alignment.CenterVertically
) {
PantrixText(text = "Don't have an account?")
PantrixLink(text = "Sign up", onClick = {}, tagKey = "sign_up")
}
PantrixLink(
text = "Terms of use",
onClick = {},
style = PantrixTheme.typography.footnote,
tagKey = "terms_of_use"
)
Links in a row
Links that do not stand in a sentence: the row at a page's foot. Where they stand already says they are links; with underline = LinkUnderline.OnHover they are underlined only under a pointer and while they hold the keyboard's focus.
Where the platform is used by touch there is neither: on Android and iOS these links too are underlined always. A link inside a sentence stays at the default, LinkUnderline.Always: its colour alone does not reach whoever cannot tell it apart.
Row(horizontalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.lg)) {
PantrixLink(text = "Privacy", onClick = {}, underline = LinkUnderline.OnHover, tagKey = "privacy")
PantrixLink(text = "Terms", onClick = {}, underline = LinkUnderline.OnHover, tagKey = "terms")
PantrixLink(text = "Contact", onClick = {}, underline = LinkUnderline.OnHover, tagKey = "contact")
}
Touch target
The area a link takes up is painted here. It is at least as tall as the platform's touch target: 48dp on Android, 44dp on iOS, and 32dp on desktop and the web when they are used with a mouse. It is as wide as its text.
The second link is in the caption style: the text is smaller, and the area stays as tall. A touch just beside a short link reaches it too.
val area = PantrixTheme.colors.neutral.container
Row(horizontalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.xl)) {
PantrixLink(text = "Help", onClick = {}, modifier = Modifier.background(area), tagKey = "help_body")
PantrixLink(
text = "Help",
onClick = {},
modifier = Modifier.background(area),
style = PantrixTheme.typography.caption,
tagKey = "help_caption"
)
}
Disabled
enabled = false draws the link in the theme's disabled text colour, and the link takes no press. It keeps its underline: without it, it would read as plain text. Press "Resend code": the link is disabled for five seconds.
The second link is given a color as well. A disabled link is in the theme's disabled colour whatever is given.
var waiting by remember { mutableStateOf(false) }
LaunchedEffect(waiting) {
if (waiting) {
delay(5_000)
waiting = false
}
}
Row(horizontalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.xl)) {
PantrixLink(
text = "Resend code",
onClick = { waiting = true },
enabled = !waiting,
tagKey = "resend_code"
)
PantrixLink(
text = "Coming soon",
onClick = {},
color = ownColors().color,
enabled = false,
tagKey = "coming_soon"
)
}
Reporting a click
Every click is reported to the theme's analytics as an event: its component is Link and its action click. The event's external value says whether the link ran an action (false) or opened an address (true); the address itself is not in the event.
The two links here are inside a theme that is given only analytics: the last event to arrive is written under them. Press one.
var lastEvent by remember { mutableStateOf("No event yet") }
val analytics = remember {
PantrixAnalytics { event ->
val external = event.props["external"]
lastEvent = "${event.component} · ${event.action} · ${event.testTag} · external=$external"
}
}
PantrixTheme(analytics = analytics) {
Row(horizontalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.xl)) {
PantrixLink(text = "Help", onClick = {}, tagKey = "help")
PantrixLink(text = "Support page", url = "https://example.com/support", tagKey = "support")
}
}
PantrixText(text = lastEvent, color = PantrixTheme.colors.textSecondary, tagKey = "link_event")
API
text
A link on its own that runs onClick: text underlined in the primary colour, with the platform's minimum touch target around it. The click is reported to the theme's analytics as a Link click event. When it is not enabled, it keeps its underline, in the disabled text colour, so that it still reads as a link, and does nothing.
| Parameter | Type | Default | What it is |
|---|---|---|---|
text | String | ||
onClick | () -> Unit | ||
modifier | Modifier | Modifier | the link's modifier. |
style | TextStyle | LocalPantrixTextStyle.current | |
color | Color | Color.Unspecified | |
enabled | Boolean | true | |
tagKey | String? | null | the link's automation key: the link is Link_<tagKey>, and without one a key of where it is called. Visible text is never the key. |
underline | LinkUnderline | LinkUnderline.Always | when the link is underlined: always unless told; OnHover for a link that stands apart from any sentence, underlined under a pointer and the keyboard's focus, and always where the platform is used by touch. |
text
A link on its own that opens url with the platform's UriHandler: in the browser, or the app that handles the address.
| Parameter | Type | Default | What it is |
|---|---|---|---|
text | String | what the link says. | |
url | String | ||
modifier | Modifier | Modifier | the link's modifier. |
style | TextStyle | LocalPantrixTextStyle.current | the link's type: LocalPantrixTextStyle unless given, so that a link beside a text is as large as the text. |
color | Color | Color.Unspecified | the link's own colour, where it is not the theme's primary. |
enabled | Boolean | true | whether the link can be pressed: one that cannot keeps its underline, in the disabled text colour. |
tagKey | String? | null | the link's automation key: the link is Link_<tagKey>, and without one a key of where it is called. Visible text is never the key. |
underline | LinkUnderline | LinkUnderline.Always | when the link is underlined, as the other PantrixLink has it. |
Accessibility
- Touch target. It is never shorter than the platform's minimum touch target: 48dp on Android, 44dp on iOS, and 32dp on desktop and the web when they are used with a mouse. It is as wide as its text, and starts where a text above it starts.
- Mouse and keyboard. While a pointer is over the link and while it is pressed, a faint tint in the link's colour appears under its text. The link takes the keyboard focus too: with the focus, that tint is in the focus ring's colour.