Click to skip to main content

Component documentation

bottomSheet

Import code

{% from "components/bottomSheet.njk" import bottomSheet %}

Arguments

{% call bottomSheet(
    props={
        triggerProps: {
            toggleValue: "",
            label: {off: "", on: ""},
            icon: {off: "", on: ""},
            tooltip: "",
            type: "button | link",
            size: "base | lg | sm | inherit",
            variant: "",
            iconPosition: "start | end"
        }
    },
    attrs={}

    {% call container({size:"base", type: "cols-1", alignment: "center"}) %}

    {% endcall %}

) %}
{% endcall %}

Implementation notes

  • A wrapper for dialog that's designed specifically to be a bottom sheet / table of contents type component. Can't be visualized because it's fixed position. But resize this page to a narrow width to see the one integrated in the page!
  • props.triggerProps is for the open/close button.

button

Import code

{% from "components/button.njk" import button %}

Arguments

{{ button(
    props={
        label: "",
        icon: "",
        tooltip: "",
        type: "button | link",
        size: "base | lg | sm | inherit",
        variant: "",
        toggleValue: "",
        iconPosition: "start | end"
    },
    attrs={}
) }}

Implementation notes

  • Tag defaults to button unless you provide an attrs.href, then it'll be an a tag.
  • Optionally you can use {% call %} to give custom inner HTML.
  • props.toggleValue is the x-data value that the button looks for to determine its on/off state. If you use this property, the button expects the props.icon and props.label values to be objects with on and off keys.
Vibrant abstract painting with swirling blue and light pink hues on a canvas.
Vibrant abstract painting with swirling blue and light pink hues on a canvas.
Vibrant abstract painting with swirling red, yellow, and pink hues on a canvas.
Vibrant abstract painting with swirling red, yellow, and pink hues on a canvas.
Vibrant abstract painting with swirling blue and purple hues on a canvas.
Vibrant abstract painting with swirling blue and purple hues on a canvas.

Import code

{% from "components/carousel.njk" import carousel %}

Arguments

{{ carousel(
    props={
        macro: figure,
        slides: [{}],
        indicators: true,
        ariaLabel: "",
    },
    attrs={}
) }}

Implementation notes

  • props.macro should be the template each slide uses. In a basic carousel it should probably be figure.
  • Expects props.slides is an array of the props objects for the macro defined in props.macro.
  • props.indicators shows or hides the indicator dots.

checkbox

CheckboxesOptional description
output: []

Import code

{% from "components/checkbox.njk" import checkbox %}

Arguments

{{ checkbox(
    props={
        name: "",
        label: "",
        description: "",
        options: [{label: "", value: ""}],
        fieldAttrs: {}
    },
    attrs={}
) }}

Implementation notes

  • If you want access to an array of the selected checkboxes, define a x-data value in a parent element with the key as the props.name of this component.

container

Import code

{% from "components/container.njk" import container %}

Arguments

{% call container(
    props={
        size: "narrow | base | content | full",
        type: "flex | cols-1 | cols-2 | sidebar"
    },
    attrs={class:""}
) %}
{% endcall %}

Implementation notes

  • Wrapper for most page content sections.
  • props.size to set max-width
  • props.type to define columns or sidebar layouts.

copyToClipboard

Import code

{% from "components/copyToClipboard.njk" import copyToClipboard %}

Arguments

{{ copyToClipboard(
    props={
        input: "" | copyRef: "",
        trigger: { macro:button, props:{}, attrs:{"@click":"copy"} },
        toastMessage: "",
        toasterId: ""
    },
    attrs={}
) }}

Implementation notes

  • Use input or copyRef, not both. copyRef is the x-ref value of an element inside the caller() that you want to copy the innerText value of.
  • Use props.trigger to define the trigger element, or give an element inside the caller() the attribute @click: 'copy' to trigger the copy event.
  • Must have the toaster component somewhere on the page for this component to work.

dialog

Some
content
inside
the dialog
Some
content
inside
the dialog
Some
content
inside
the dialog
Some
content
inside
the dialog
Some
content
inside
the dialog

Import code

{% from "components/dialog.njk" import dialog %}

Arguments

{% call dialog(
    props={
        alignment: "top | bottom | left | right",
        ariaLabel: "",
        teleportedStyles: "",
        triggerProps: {
            toggleValue: "",
            label: {off: "", on: ""},
            icon: {off: "", on: ""},
            tooltip: "",
            type: "button | link",
            size: "base | lg | sm | inherit",
            variant: "",
            iconPosition: "start | end"
        }
    %}
    {% endcall %},
    attrs={}
) }}

Implementation notes

  • props.alignment defines which direction the dialog comes from.
  • props.triggerProps is for the open/close button

Import code

{% from "components/dropdown.njk" import dropdown %}

Arguments

{{ dropdown(
    props={
        position: ["top", "bottom", "left", "right"],
        dropdownItems:[
            { macro:button, props:{}, attrs:{} }
        ],
        triggerProps: {}
    },
    attrs={}
) }}

Implementation notes

  • Defaults to displaying buttons in a list
  • Can use `{% caller() %} instead for more complex inner components
  • position is an array where you can set the relative positions to the trigger element.

figure

Vibrant abstract painting with swirling red, yellow, and pink hues on a canvas.
Vibrant abstract painting with swirling red, yellow, and pink hues on a canvas.

Import code

{% from "components/figure.njk" import figure %}

Arguments

{{ figure(
    props={
        image: "/assets/uploads/" | iframe: "https://www.youtube.com/embed/",
        widths: { mobile: {# below bp-sm #}, tablet: {# below bp-lg #}, desktop: {# above bg-lg #} },
        unstyled: boolean,
        alt: "",
        lazy: boolean,
        caption: "",
        focus: "object-",
        aspect: "aspect-"
    },
    attrs={}
) }}

Implementation notes

  • props.lazy must be set to false if you want the loading to not be lazy.
  • The component is designed to be flexible so the image is set to object-cover.
  • props.focus designates the area to prioritize keeping in view as the image resizes. Default is center.
  • props.aspect designates the preferred aspect ratio for the image. Default is auto.
  • props.aspect and props.focus take the TailwindCSS class name for that property.
  • props.widths is an object of pixel values for the @2x display size of the image at various screen sizes. Estimating is okay.

icon

bug_report close

Import code

{% from "components/icon.njk" import icon %}

Arguments

{{ icon(props={glyph: ""} ,attrs={}) }}

Implementation notes

  • props.glyph should be the name of a glyph from the Material Symbols library. Must include the glyph name in the _data/icons.json file array so the font is loaded properly.
  • The size of the icon is determined by its nearest ancestor's font size. The mutliplier is set in theme.css.
  • The icon color is set by using text-* utility classes, or inherited from an ancestor.

incrementer

Optional description
output: 

Import code

{% from "components/incrementer.njk" import incrementer %}

Arguments

{{ incrementer(
    props={
        name: "",
        label: "",
        description: "",
        fieldAttrs={
            placeholder: "",
            required: boolean,
            min: "",
            max: ""
        },
        direction: "column | row"
    },
    attrs={}
) }}

Implementation notes

  • props.fieldAttrs.type can be most of the types listed here.
  • If you want access to the value, define a x-data value in a parent element with the key as the props.name of this component.

input

Optional description
output: ""

Import code

{% from "components/input.njk" import input %}

Arguments

{{ input(
    props={
        name: "",
        label: "",
        description: "",
        fieldAttrs: {
            type: "",
            placeholder: "",
            required: boolean,
            min: "",
            max: "",
            autocomplete: "on | off"
        },
        direction: "column | row"
    },
    attrs={}
) }}

Implementation notes

  • props.fieldAttrs.type can be most of the types listed here.
  • If you want access to the value, define a x-data value in a parent element with the key as the props.name of this component.
  • If you set props.direction to row, you must define the grid columns too using the attrs object.

markdown

Heading

Body paragraph with a link and italics and bold.

preformatted code
  • an
  • unordered
  • list

Import code

{% from "components/markdown.njk" import markdown %}

Arguments

{{ markdown(
    props={
        content: "",
        transform: true | false,
        overrides: {
            bodySize: "",
            primaryColor: "",
            linkColor: "",
            radius: "",
            headingFont: "",
            headingFontWeight: "",
            scale: ""
        },
        customStyles: ""
    },
    attrs={}
) }}

Implementation notes

  • Use props.content to inject markdown from a data source. Use {{ caller() }} when you want to write the content directly inside the component.
  • props.transform can be turned off when the content will already be transformed by Eleventy, as is the case with .md file content, or when the content you're injecting is already written in HTML.
  • props.overrides can set instance-specific overrides to the styles, such as using a smaller base font size or a different color.
  • customStyles takes in CSS to set instance-specific styles, such as making bolded text appear as a different color instead of bold, but note that you'll need to give the instance an id for it to work.
Some
content
inside
the modal

Import code

{% from "components/modal.njk" import modal %}

Arguments

{% call modal(
    props={
        triggerProps: {
            toggleValue: "",
            label: {off: "", on: ""},
            icon: {off: "", on: ""},
            tooltip: "",
            type: "button | link",
            size: "base | lg | sm | inherit",
            variant: "",
            iconPosition: "start | end"
        }
    },
    attrs={}

    {% call container({size:"base", type: "cols-1", alignment: "center"}) %}

    {% endcall %}

) %}
{% endcall %}

Implementation notes

  • A wrapper for dialog that's designed specifically to be a centered modal type component.
  • props.triggerProps is for the open/close button.

radio

RadioOptional description
output: {}

Import code

{% from "components/radio.njk" import radio %}

Arguments

{{ radio(
    props={
        name: "",
        label: "",
        description: "",
        options: [{label: "", value: ""}],
        fieldAttrs: {}
    },
    attrs={}
) }}

Implementation notes

  • If you want access to the selected radio, define a x-data value in a parent element with the key as the props.name of this component.
    • {{ props.name }}.index will give you the index of the selected radio
    • {{ props.name }}.value will give you the value of the selected radio (what will show up in the form submission.)

section

Import code

{% from "components/section.njk" import section %}

Arguments

{% call section(
    props={
        padding: "base | none",
    },
    attrs={}
) %}
    {% call container({size:"base", type: "cols-1", alignment: "center"}) %}

    {% endcall %}
{% endcall %}

Implementation notes

  • Children just most likely by container or divider
  • props.padding sets whether or not there should be padding inline. Set to false for full-width sections.

select

This area describes the field above!
output: {}

Import code

{% from "components/select.njk" import select %}

Arguments

{{ select(
    props={
        name: "",
        label: "",
        description: "",
        options: [{label:"", value: ""}],
        direction: "column | row",
        fieldAttrs: {
            placeholder: "",
            required: boolean
        }
    },
    attrs={}
) }}

Implementation notes

  • If you want access to the selected option, define a x-data value in a parent element with the key as the props.name of this component.

textarea

Optional description
output: ""

Import code

{% from "components/textarea.njk" import textarea %}

Arguments

{{ textarea(
    props={
        name: "",
        label: "",
        description: "",
        fieldAttrs: {
            value: "",
            placeholder: "",
            required: boolean,
            rows: ""
        },
        direction: "column | row"
    },
    attrs={}
) }}

Implementation notes

  • If you want access to the value, define a x-data value in a parent element with the key as the props.name of this component.

textLockup

Eyebrow

Large size

Large elaboration

Small size

Small elaboration

Import code

{% from "components/textLockup.njk" import textLockup %}

Arguments

{% call textLockup(
    props={
        size: "xl | lg | base | sm",
        textAlignment: "left | center | right",
        titleTag: "h2",
        eyebrow: "",
        title: "",
        elaboration: ""
    },
    attrs={}
) %}
{% endcall %}

Implementation notes

  • Useful most times there is a combination of title, paragraph, and button.
  • Optionally, can insert custom content using {% call %}.
  • props.titleTag defaults to h2, but can be changed.

toaster

Import code

{% from "components/toaster.njk" import toaster %}

Arguments

{{ toaster(
    props={id:""}
) }}

Implementation notes

  • Put this component somewhere in your base layout. In the SBS Starter site, the id defaults to siteToaster.
  • Trigger a new toast with the $dispatch('notify', { content:'{{ message }}' }) function on an element.

toTopFab

Import code

{% from "components/toTopFab.njk" import toTopFab %}

Arguments

{{ toTopFab() }}

Implementation notes

  • Can not be visualized since it's a fixed position element, but it's used on this page! Peep the bottom right corner.
  • No props needed! It does what it says.