On this page
- Define properties that will be reused across multiple components
- Provide your components, typically in a components sub-directory in your module or theme
- For each component, write a componentname.variables.yml file
- Write the component as, at minimum, a Twig template
- Detail the component in a modulename.component_schema.yml or themename.component_schema.yml file
Providing components from a module or theme
Providing components from a module or theme via Component Schema involves these basic steps:
- Define properties that will be reused across multiple components.
- Provide your components, typically in a
componentssub-directory in your module or theme. - For each component, write a
componentname.variables.ymlfile. - Write the component as, at minimum, a Twig template.
- Finally, detail the component in a
modulename.component_schema.ymlorthemename.component_schema.ymlfile.
Below we provide more detail on these steps. It's recommended to read the documentation on defining component properties before starting in here.
For purposes of this guide, we'll take as an example a component for the Bulma CSS framework. Full working code for this example can be found in the Bulma Components module, which is built on Component Schema.
One of the elements Bulma provides is a button. At its most basic, a button requires only a single class, button:
<button class="button">Button</button>Besides <button> a button can also apply to other tags such as an <a> tag:
<a class="button">Button</a>So one of the properties of a button is the tag used for the outermost element. In our component, this will be a $tag variable passed to the component template.
A button can have a color applied via one of a set of color classes (is-primary, is-link, and so on). So our component will have a $color variable of type string, leading to a rendered element like:
<button class="button is-primary">Primary</button>Some of the properties of a button are best modelled as boolean variables, such as whether the button is outlined or is rounded. Two further variables in our component will be $is_outlined and $is_rounded, both of type boolean.
And so on. Since there are many properties of a Bulma button, there are many different variables we'll want to define for our component.
Define properties that will be reused across multiple components
Many of the properties that apply to a button are also relevant to various other components. Rather than repeat similar configuration in multiple places, we can take advantage of type inheritance that's built into Component Schema by defining and using a set of specialized and reusable types.
We do this in a .yml file in a component/schema directory--just the came way as you can provide configuration schema/metadata in a config/schema directory.
In our case, color is a property that's used across many Bulma components, so it's an ideal use case for a dedicated type.
bulma_color:
label: 'Color'
description: 'Set to one of a large range of colors'
nullable: true
type: string_attribute_provider
options:
is-white: white
is-black: black
is-light: light
is-dark: dark
is-primary: primary
is-info: info
is-link: link
is-success: success
is-warning: warning
is-danger: danger
is-black-bis: black-bis
is-black-ter: black-ter
is-grey-darker: grey-darker
is-grey-dark: grey-dark
is-grey: grey
is-grey-light: grey-light
is-grey-lighter: grey-lighter
is-white-ter: white-ter
is-white-bis: white-bis
is-primary-light: primary-light
is-link-light: link-light
is-info-light: info-light
is-success-light: success-light
is-warning-light: warning-light
is-danger-light: danger-light
is-primary-dark: primary-dark
is-link-dark: link-dark
is-info-dark: info-dark
is-success-dark: success-dark
is-warning-dark: warning-dark
is-danger-dark: danger-dark
provides_class: trueProvide your components, typically in a components sub-directory in your module or theme
Use the Components! module to support this directory as providing templates by registering the path 'components' in your module's or theme's .info.yml file. Put each component in a sub-directory of components. For example, a button component would be in components/button. Alternately, for more complex component sets, nest the components in an intermediate directory. For example, if you're using atomic design, you might use components/atoms/componentname or similar. In our case we'll follow the pattern used in Bulma documentation, where most components are classed as "layout", "form", "elements", or (yes, confusingly in our case) "components". So a button component would be at components/elements/button.
For each component, write a componentname.variables.yml file
This is where we pull together definitions for all the properties in our component. In many cases, this will be as simple as referencing a property we've already defined as a specialized type.
Here's the definition of a Bulma button component's properties (slightly simplified for purposes of demonstration). See the Bulma button component documentation for more info on each of the properties.
attributes:
type: bulma_attributes
tag:
type: bulma_tag
default: 'button'
url:
label: 'URL'
description: 'Path or URL the button links to'
nullable: true
type: string_attribute_provider
provides_attribute: true
provided_name: 'href'
ui_type: field
size:
type: bulma_size
documentation_url: https://bulma.io/documentation/elements/button/#sizes
preview: is-medium
color:
type: bulma_color
documentation_url: https://bulma.io/documentation/elements/button/#colors
preview: is-danger
button_label:
label: 'Label'
description: 'The text to be used for the button'
nullable: true
type: label
preview: 'My button'
state:
label: 'State'
description: 'The state of the button'
nullable: true
type: string_attribute_provider
options:
is-hovered: hovered
is-focused: focused
is-active: active
is-loading: loading
is-static: static
provides_class: true
documentation_url: https://bulma.io/documentation/elements/button/#states
is_light:
type: bulma_is_light
label: 'Is light'
description: 'Use the light version of a button color'
documentation_url: https://bulma.io/documentation/elements/button/#colors
is_selected:
label: 'Is selected'
description: 'Display a button above any siblings'
nullable: true
type: boolean_attribute_provider
provides_class: true
provided_value: is-selected
documentation_url: https://bulma.io/documentation/elements/button/#list-of-buttons
is_rounded:
type: bulma_is_rounded
description: 'Make a button rounded'
documentation_url: https://bulma.io/documentation/elements/button/#styles
preview: true
is_loading:
label: 'Is loading'
description: 'Turn a button into its loading version'
nullable: true
type: boolean_attribute_provider
provides_class: true
provided_value: is-loading
documentation_url: https://bulma.io/documentation/elements/button/#states
is_outlined:
label: 'Is outlined'
description: 'Outline a button'
nullable: true
type: boolean_attribute_provider
provides_class: true
provided_value: is-outlined
documentation_url: https://bulma.io/documentation/elements/button/#states
disabled:
label: 'Disabled'
description: 'Disable the button, preventing the user from interacting with it'
nullable: true
type: boolean_attribute_provider
provides_attribute: true
provided_name: 'disabled'
provided_value: true
documentation_url: https://bulma.io/documentation/elements/button/#states
is_fullwidth:
type: bulma_is_fullwidth
description: 'Make a buttom take the full width available'
documentation_url: https://bulma.io/documentation/elements/button/#displays
is_inverted:
label: 'Is inverted'
description: 'Make text color becomes the background color, and vice-versa'
nullable: true
type: boolean_attribute_provider
provides_class: true
provided_value: is-inverted
documentation_url: https://bulma.io/documentation/elements/button/#stylesWrite the component as, at minimum, a Twig template
You could name this file componentname.html.twig. You may also wish to include assets such as SCSS/CSS or JavaScript.
In Component Schema, a Twig template begins with two lines that register the component type and call processing, see relevant documentation. From there, the template is very simple: the tag that's been passed in, the attributes, and the closing tag. Since all the other properties are attribute providers of one sort or another, all the rest of the complexity is handled by the process_component() call.
{% set component_type = 'bulma_button' %}
{% process_component() %}
<{{ tag }}{{ attributes }}></{{ tag }}>Optionally, you can also provide a template to be used as an example of the component on a Styeguide page. See the button component in the Bulma Components module for several examples templates.
Detail the component in a modulename.component_schema.yml or themename.component_schema.yml file
Having produced a component and defined its variables, it remains to register it - and your other components - with Component Schema. You do this in a Yaml file in the base directory of your module or theme.
If your component itself uses a CSS class on the outermost HTML element, you can provide this by specifying an html_class property--in our case, 'button'.
components:
bulma_button:
label: 'Button'
description: 'The classic button, in different colors, sizes, and states'
styleguide_template: '@bulma_components/elements/button/_example-buttons-in-columns.html.twig'
component_template: '@bulma_components/elements/button/button.html.twig'
variables_yml: components/elements/button/button.variables.yml
group: 'Bulma - Elements'
documentation_url: https://bulma.io/documentation/elements/button
html_class: 'button'
takes_ui: trueHelp improve this page
You can:
- Log in, click Edit, and edit this page
- Log in, click Discuss, update the Page status value, and suggest an improvement
- Log in and create a Documentation issue with your suggestion