Components
A component is a named piece of slide that you define once and use as many times as you like. It takes parameters, like a template: the text changes, the look stays the same.
Components have no logic. There are no loops, conditions or calculations: Folio simply replaces each parameter with the value you give it.
Defining a component
Section titled “Defining a component”Write the definition at the start of the document, together with @title, @theme and the other definitions, before the first slide:
@component metric {value label color=accent}::: box {.card align=center}$value {size=5xl weight=bold color=$color}$label {.muted}:::@end@componentis followed by the name and, in braces, the list of parameters.- Everything between that line and
@endis the component body, written in the same language as your slides. - The name uses lowercase letters, numbers and hyphens, such as
metricorteam-card.
Required parameters and default values
Section titled “Required parameters and default values”| Form | Meaning |
|---|---|
value | Required parameter. Using the component without it is an error. |
color=accent | Parameter with a default value. If you leave it out, it is accent. |
title="Untitled" | Default value with spaces, in quotes. |
Using the parameters
Section titled “Using the parameters”Inside the body, $name is replaced by the parameter value. This works anywhere:
- in text:
## $titleorOwner: $name; - in attribute values:
{color=$color}or{bg=$background}; - on a line of its own:
$labelbecomes a paragraph with the value.
The value can contain text formatting, such as **bold**, and it is applied on the slide.
Using a component
Section titled “Using a component”There are two ways to use a component, the same as for language blocks:
- Single line, with
::, when it has no content::: metric {value=38% label="revenue growth"}. - Container, with
:::and a closing:::, when it takes content (see the next section).
Parameters go in braces, always by name. Values with spaces go in quotes.
@component metric {value label color=accent}::: box {.card align=center}$value {size=5xl weight=bold color=$color}$label {.muted}:::@end
# Quarterly results::: grid {cols=3 gap=lg}:: metric {value=38% label="revenue growth"}:: metric {value=94 label="new customers" color=green}:: metric {value=4.8 label="satisfaction score" color=violet}:::Content with $content
Section titled “Content with $content”When you use the component as a container, everything between the opening and closing lines goes into $content. Put $content on a line of its own, at the point in the body where the content should appear:
@component highlight {title}::: box {.card gap=sm}## $title$content:::@end
::: highlight {title="Next steps"}- Review the budget with the board- Hire two people for support- Launch the new plan in March:::The content can be anything: text, lists, images, other blocks and other components.
Named slots
Section titled “Named slots”Sometimes a component needs more than one content area, such as the two columns of a comparison. That is what named slots are for:
- In the component body, write
$slot-nameon a line of its own, using a name that is not a parameter. - When using the component, fill the slot with a
::: slot slot-name…:::block. - The rest of the content still goes into
$content.
@component comparison {before after}::: columns {gap=xl}::: box {.card gap=sm}## $before$content:::::: box {.card gap=sm bg=accent color=white}## $after$result::::::@end
::: comparison {before="Scattered spreadsheets" after="A single dashboard"}Each team exports, pastes and formats the numbers by hand.::: slot resultThe data arrives on its own and the report refreshes every hour.::::::Slots you do not fill stay empty, with no error. Filling a slot the component does not have is an error, and the editor suggests the closest name.
Components inside components
Section titled “Components inside components”A component body can use other components, and so can the content you pass to a component:
@component badge {text}::: box {bg=accent color=white pad=sm radius=lg}$text {size=sm weight=bold uppercase}:::@end
@component plan {name price}::: box {.card gap=sm}:: badge {text=$name}## $price$content:::@end
::: grid {cols=2 gap=lg}::: plan {name=Essential price="$9"}Up to 5 users:::::: plan {name=Team price="$29"}Unlimited users::::::A component cannot use itself, either directly or indirectly (for example, a uses b and b uses a). Folio detects the cycle and shows an error. Components can be nested up to 16 levels deep.
Revealing a component step by step
Section titled “Revealing a component step by step”The step attribute also works on a component call. The whole component appears at the given step:
:: metric {value=38% label="growth" step=1}:: metric {value=94 label="new customers" step=2}Learn more in Step-by-step reveal.
Styling a component
Section titled “Styling a component”Components only accept parameters. Styles such as .card and #id on the call are an error. To change how one particular use looks, wrap the component in a box:
::: box {.dark pad=lg}:: metric {value=38% label="growth"}:::If the change should always apply, create a parameter instead, like color=accent in the metric example.
Common errors
Section titled “Common errors”| Code | When it happens |
|---|---|
| F401 | $content was used outside a @component. |
| F404 | The component uses itself, directly or indirectly. |
| F405 | Components nested more than 16 levels deep. |
| F406 | The call has a .style or #id. Wrap the component in a box. |
| F407 | The call passes a parameter the component does not have. |
| F408 | The call has loose text instead of parameters in braces. |
| F409 | A required parameter is missing. |
| F410 | The body uses $name, but name was not declared as a parameter. |
| F411 | Warning: the component received content but does not use $content. |
| F412 | The component name is the name of a language block. |
| F413 | The same component was defined twice in the document. |
| F414 | ::: slot fills a slot the component does not have. |
| F415 | ::: slot without the slot name. |
| F416 | ::: slot outside a component call. |
| F417 | The same slot was filled twice. |
| F504 | @component without a matching @end. |
| F511 | Invalid component name (use lowercase letters, numbers and hyphens). |
Errors inside a component body are reported on the line where the component is used, with the note “(in component name)”. The full list is in Error messages.