Skip to contents

Customise the character's colours and light or dark mode. Each character names some roles as leaders (for example body), in order of priority. A role you do not set follows the first of those leaders that has been given a colour; if none has, the role keeps its original colour. Call mascot_colour_roles() to find the roles for a character. A plain named list passed to mascot() or update_mascot() uses one set of colours in every mode. A bslib::bs_theme() fills the character's declared brand leaders with its primary and secondary colours; _brand.yml can be supplied through bs_theme(brand = ). A bs_theme() always uses mode = "auto". Which parts of a character a bs_theme() colours is experimental and may change in a later release.

Usage

mascot_theme(
  ...,
  palette = NULL,
  light = NULL,
  dark = NULL,
  mode = "auto",
  css = NULL
)

Arguments

...

Must be empty. Forces the arguments after it to be named.

palette

A palette id from mascot_palettes(), or NULL (the default) for the character's own colours. Checked against the chosen character when used. An unknown palette id is an error in mascot() (the UI is being built) but only a warning in update_mascot() (a live session, so the mascot keeps running unchanged). "original" also chooses the character's own colours. A palette is applied first, then light and dark roles, then css. Without a dark map, a palette uses its light colours in both modes. A bs_theme() cannot be combined with a palette.

light, dark

Named lists of colour roles, or NULL (the default) to keep the palette's colours (or the character's own colours) in that mode. Values can be colour names, hex strings, grDevices::rgb() output, CSS rgb() or rgba() strings, or three RGB numbers (red, green and blue) in 0–255. Single numeric palette indices are not accepted. Roles use snake case; light, dark and default are reserved. Names follow the character format: a lowercase letter, then lowercase letters or digits separated by single underscores, with an optional final underscore. mascot_theme() checks the form of the names; mascot(), update_mascot() and mascot_preview() check that the chosen character has those roles. Built-in characters keep one outline colour in both modes; their light outer band keeps them readable on any dark page. To use your own dark-mode outline, set dark = list(outline = "#FFC93C").

mode

Light or dark mode: "auto" (the default), "light" or "dark". "auto" follows the nearest valid data-bs-theme attribute around the place where the mascot was written in the page, then Quarto's body classes. With no page signal it uses light mode. An explicit light or dark mode always wins. NULL is not accepted.

css

A named list mapping colour roles to CSS variable names such as list(body = "--team-blue"), or NULL (the default) for no CSS source. This source is experimental. CSS entries override light and dark entries for the same role. Missing or invalid variables use the character's own colour and warn in the browser console; low contrast also warns there and keeps the colour. Variables are read where the mascot was written in the page, also when the mascot floats.

Value

A mascot_theme object describing colours, CSS sources and mode. The returned object's fields are internal; pass the object on rather than reading its fields.

Details

After a character swap, roles you did not set follow their leaders again, and roles the new character does not have are ignored. A palette is kept if the new character has a palette with the same id. If not, R warns, the new character gets its own colours, and role colours you set explicitly stay. An empty mascot_theme() restores the character's own colours. A colour you choose with less than 3:1 contrast gives a warning and is kept (see "Contrast warnings" below). Colours you supply are used exactly as given. Shades worked out from them keep the hue and shift lightness and saturation by tuned amounts. Brand colours are the same in both modes.

Contrast warnings

A warning appears when a colour chosen by the developer (light, dark, or a bslib::bs_theme() brand colour) has contrast below 3:1 against the page background (white in light mode, #212529 in dark mode, or the bslib theme's backgrounds). Contrast is checked when mascot() builds the UI and when update_mascot() applies colours with theme = ; mascot_preview() collects the results in its contrast table. A character's own colours and the built-in palette colours never warn, and the colour is always kept.

R warnings appear only when shiny::in_devmode() is TRUE, and always in mascot_preview() and the studio. Set options(mascot.contrast_warnings = TRUE) or FALSE to force them on or off everywhere. A non-flag value warns once per R session and uses the default. Visitors never see R warnings. Colours from CSS variables (css =) are checked in the browser and warn in its console.

These warnings have the class mascot_contrast. To silence only these warnings:

withCallingHandlers(
  mascot("helper", theme = list(rim = "#f5e6c8")),
  mascot_contrast = function(w) invokeRestart("muffleWarning")
)

suppressWarnings() also works, but it hides every warning.

A bs_theme() or explicit colours

A bslib::bs_theme() cannot be combined with palette, light, dark or css: theme takes either the theme or a mascot_theme(), and a bs_theme() passed to mascot_theme() is an error. It fills only the character's brand roles (the brand column of mascot_colour_roles(): body for primary and rim for secondary on "tessa"), and the roles that follow them change with them. A character with no brand roles, such as "neer", keeps its own colours. The colour is the same in light and dark mode. A brand colour that is dark enough on a white page can fail 3:1 on the dark background. In development mode (or with options(mascot.contrast_warnings = TRUE); see "Contrast warnings") a warning of class mascot_contrast then names the slot and the mode, and the colour is kept. To change it, give those roles for each mode yourself:

mascot("helper", theme = mascot_theme(
  light = list(body = "#1b3a6b", rim = "#5c6770"),
  dark = list(body = "#9ec5fe", rim = "#adb5bd")
))

The example uses the brand roles of "tessa"; other characters name theirs in mascot_colour_roles(). Roles you leave out follow the ones you set, as described above.

Experimental CSS source

Experimental CSS variables are worked out by the browser, so R cannot check their values.

Experimental colour mapping for bs_theme()

Experimental theme = bslib::bs_theme() is accepted, but which parts of a character it colours may change in a later release.

Examples

mascot_theme()
#> mascot_theme()
mascot_theme(palette = "coral_navy", light = list(rim = "#b93664"))
#> mascot_theme(palette = "coral_navy", light = list(rim = "#b93664"))
mascot_theme(light = list(body = "#1f6feb"), dark = list(body = "#9ec5fe"), mode = "auto")
#> mascot_theme(light = list(body = "#1f6feb"), dark = list(body = "#9ec5fe"))
mascot_theme(css = list(body = "--team-blue"))
#> mascot_theme(css = list(body = "--team-blue"))
ui <- mascot("helper", theme = list(body = "#1f6feb"))
ui <- mascot("brand", theme = bslib::bs_theme(primary = "#1f6feb"))