Skip to main content

Extend Section component

This guided example shows how you'd add components to your Design System that use a kickstartDS base component pretty directly. But unlike just adapting a component, extending a component also involves adding something to it, or changing the way certain things work under the hood, by composing multiple kickstartDS base components (whereas customizing a component does that by adding changes to the customized components React template). This expands possible applications of existing kickstartDS components greatly.

Even while using the component rather directly from kickstartDS, you'll want to find the correct set of properties for your own use case. Components in kickstartDS come equipped with properties for a wide range of possible use cases, so it makes sense to reduce those to the ones you really need... to make components easier to understand, use and reason about!

We call this type of workflow Extension. Learn more about it in our dedicated guide about it. If you're unsure about something, have a look over there. We go into more background detail there about what we're doing here.

Not touching the actual markup generated by components let's us get by without adding any custom styling (CSS / SCSS) to it. We simply reuse the already existing Design Token and component structure.

Overview

This is how the result of this guide will look like:

It will only need two simple steps for that:

  1. Component Definition, and
  2. Component Creation

For more details about those steps, have a look at the guide about different component processes and their shared structure.

Requirements

This guide assumes that you already have a working Design System, that is based on kickstartDS, running.
If that's not the case, follow our Create your Design System guide.

1. Component Definition

Purpose

We've found that we'd love to use the existing kickstartDS Section, but it's not quite flexible enough for our taste. We'd like to add more call-to-actions to our page, which mostly consists of such Sections, and don't need as much flexibility for the included headline.

We take width, gutter, mode, content, spaceBefore, spaceAfter and inverted directly from the Section, and rename background to style for our version of it. And crucially we add our own property ctas, to hold call-to-actions, into the mix, while reducing the complexity of headline significantly... from mapping to all of the Headline properties, to just a single string type prop setting its content.

We also keep the name Section, as it fits our use case well enough already.

Structure

Defining the structure of a component means finding the component API for it:

PropertyTypeDescription
headlinestringHeadline for the section
widthenumWidth of section to use
gutterenumSize of gutter to use
modeenumLayout mode used for section contents
contentarrayAllowed content for the section
styleenumStyle of section, influences background
spaceBeforeenumAmount of spacing before the section
spaceAfterenumAmount of spacing after the section
invertedbooleanWhether to invert the section
ctasarrayCall-to-actions to show
ctas[].label *stringLabel for the Call to action
ctas[].target *stringTarget for the Call to action

Fields that should be required are marked with a *.

While directly helping us get a better grasp on our new component, these will also be used to write our JSON Schema later!

2. Component Creation

We like to colocate components. This means to have all involved files next to each other in the same folder; the template (.jsx / .tsx), potential CSS / SASS (.css / .scss), JavaScript (.js / .ts), our JSON Schema component definition (.schema.json), and so on.

So we start by creating the directory src/components/section, from our Design System repository root:


_10
mkdir -p src/components/section

This is the folder we'll add new files to in the coming few paragraphs.

JSON Schema definition

First file we'll create is the JSON Schema definition, encoding the structure we've defined for our component before:

Finished JSON Schema

We'll work our way up to this JSON Schema definition.

src/components/section/section.schema.json

_104
{
_104
"$schema": "http://json-schema.org/draft-07/schema#",
_104
"$id": "http://schema.mydesignsystem.com/section.schema.json",
_104
"title": "Section",
_104
"description": "Component used to layout components into pages",
_104
"type": "object",
_104
"properties": {
_104
"headline": {
_104
"type": "string",
_104
"title": "Headline",
_104
"description": "Headline for the section",
_104
"format": "markdown"
_104
},
_104
"width": {
_104
"type": "string",
_104
"title": "Width",
_104
"description": "Width of section to use",
_104
"enum": ["full", "max", "wide", "default", "narrow"],
_104
"default": "default"
_104
},
_104
"gutter": {
_104
"type": "string",
_104
"title": "Gutter",
_104
"description": "Size of gutter to use",
_104
"enum": ["large", "default", "small", "none"],
_104
"default": "default"
_104
},
_104
"mode": {
_104
"type": "string",
_104
"title": "Mode",
_104
"description": "Layout mode used for section contents",
_104
"enum": ["default", "tile", "list"],
_104
"default": "default"
_104
},
_104
"content": {
_104
"type": "array",
_104
"title": "Content",
_104
"description": "Allowed content for the section",
_104
"items": {
_104
"anyOf": [
_104
{
_104
"$ref": "http://schema.mydesignsystem.com/button.schema.json"
_104
},
_104
{
_104
"$ref": "http://schema.mydesignsystem.com/headline.schema.json"
_104
},
_104
{
_104
"$ref": "http://schema.mydesignsystem.com/teaser-card.schema.json"
_104
}
_104
]
_104
}
_104
},
_104
"style": {
_104
"type": "string",
_104
"title": "Style",
_104
"description": "Style of background",
_104
"enum": ["default", "accent", "bold"],
_104
"default": "default"
_104
},
_104
"spaceBefore": {
_104
"type": "string",
_104
"title": "Space Before",
_104
"description": "Amount of spacing before the section",
_104
"enum": ["default", "small", "none"],
_104
"default": "default"
_104
},
_104
"spaceAfter": {
_104
"type": "string",
_104
"title": "Space After",
_104
"description": "Amount of spacing after the section",
_104
"enum": ["default", "small", "none"],
_104
"default": "default"
_104
},
_104
"inverted": {
_104
"type": "boolean",
_104
"title": "Inverted",
_104
"description": "Whether to invert the section",
_104
"default": false
_104
},
_104
"ctas": {
_104
"type": "array",
_104
"title": "Call to actions",
_104
"description": "Add Call to actions to the end of the section",
_104
"items": {
_104
"type": "object",
_104
"properties": {
_104
"label": {
_104
"type": "string",
_104
"title": "Label",
_104
"description": "Label for the Call to action"
_104
},
_104
"target": {
_104
"type": "string",
_104
"title": "Target",
_104
"description": "Target for the Call to action",
_104
"format": "uri"
_104
}
_104
},
_104
"required": ["label", "target"]
_104
}
_104
}
_104
},
_104
"required": []
_104
}

Start with just the boilerplate for a component definition

This includes all necessarily required values for a valid component definition in kickstartDS.

src/components/section/section.schema.json

_10
{
_10
"$schema": "http://json-schema.org/draft-07/schema#",
_10
"$id": "",
_10
"title": "",
_10
"description": "",
_10
"type": "object",
_10
"properties": {}
_10
}

Add basic info describing component

We start by adding a title, description and $id attribute. The correct $id depends on your Design System configuration. We'll assume you've created components before, living under the schema prefix http://schema.mydesignsystem.com.

src/components/section/section.schema.json

_10
{
_10
"$schema": "http://json-schema.org/draft-07/schema#",
_10
"$id": "http://schema.mydesignsystem.com/section.schema.json",
_10
"title": "Section",
_10
"description": "Component used to layout components into pages",
_10
"type": "object",
_10
"properties": {}
_10
}

Create headline field

The headline field is a straight-forward string type properties, so we just document it a bit!
We do mark it by setting format to markdown, though, to enable some light RTE-like formatting options of the rendered text later on.

src/components/section/section.schema.json

_15
{
_15
"$schema": "http://json-schema.org/draft-07/schema#",
_15
"$id": "http://schema.mydesignsystem.com/section.schema.json",
_15
"title": "Section",
_15
"description": "Component used to layout components into pages",
_15
"type": "object",
_15
"properties": {
_15
"headline": {
_15
"type": "string",
_15
"title": "Headline",
_15
"description": "Headline for the section",
_15
"format": "markdown"
_15
}
_15
}
_15
}

Add allowed widths 1/2

We add a width property of type string...

src/components/section/section.schema.json

_20
{
_20
"$schema": "http://json-schema.org/draft-07/schema#",
_20
"$id": "http://schema.mydesignsystem.com/section.schema.json",
_20
"title": "Section",
_20
"description": "Component used to layout components into pages",
_20
"type": "object",
_20
"properties": {
_20
"headline": {
_20
"type": "string",
_20
"title": "Headline",
_20
"description": "Headline for the section",
_20
"format": "markdown"
_20
},
_20
"width": {
_20
"type": "string",
_20
"title": "Width",
_20
"description": "Width of section to use"
_20
}
_20
}
_20
}

Add allowed widths 2/2

... and make it an enum, defining its available options explicitly. We also set a default.

src/components/section/section.schema.json

_22
{
_22
"$schema": "http://json-schema.org/draft-07/schema#",
_22
"$id": "http://schema.mydesignsystem.com/section.schema.json",
_22
"title": "Section",
_22
"description": "Component used to layout components into pages",
_22
"type": "object",
_22
"properties": {
_22
"headline": {
_22
"type": "string",
_22
"title": "Headline",
_22
"description": "Headline for the section",
_22
"format": "markdown"
_22
},
_22
"width": {
_22
"type": "string",
_22
"title": "Width",
_22
"description": "Width of section to use",
_22
"enum": ["full", "max", "wide", "default", "narrow"],
_22
"default": "default"
_22
}
_22
}
_22
}

Add allowed gutters 1/2

We add a gutter property of type string...

src/components/section/section.schema.json

_27
{
_27
"$schema": "http://json-schema.org/draft-07/schema#",
_27
"$id": "http://schema.mydesignsystem.com/section.schema.json",
_27
"title": "Section",
_27
"description": "Component used to layout components into pages",
_27
"type": "object",
_27
"properties": {
_27
"headline": {
_27
"type": "string",
_27
"title": "Headline",
_27
"description": "Headline for the section",
_27
"format": "markdown"
_27
},
_27
"width": {
_27
"type": "string",
_27
"title": "Width",
_27
"description": "Width of section to use",
_27
"enum": ["full", "max", "wide", "default", "narrow"],
_27
"default": "default"
_27
},
_27
"gutter": {
_27
"type": "string",
_27
"title": "Gutter",
_27
"description": "Size of gutter to use"
_27
}
_27
}
_27
}

Add allowed gutters 2/2

... and make it an enum, defining its available options explicitly. We also set a default.

src/components/section/section.schema.json

_29
{
_29
"$schema": "http://json-schema.org/draft-07/schema#",
_29
"$id": "http://schema.mydesignsystem.com/section.schema.json",
_29
"title": "Section",
_29
"description": "Component used to layout components into pages",
_29
"type": "object",
_29
"properties": {
_29
"headline": {
_29
"type": "string",
_29
"title": "Headline",
_29
"description": "Headline for the section",
_29
"format": "markdown"
_29
},
_29
"width": {
_29
"type": "string",
_29
"title": "Width",
_29
"description": "Width of section to use",
_29
"enum": ["full", "max", "wide", "default", "narrow"],
_29
"default": "default"
_29
},
_29
"gutter": {
_29
"type": "string",
_29
"title": "Gutter",
_29
"description": "Size of gutter to use",
_29
"enum": ["large", "default", "small", "none"],
_29
"default": "default"
_29
}
_29
}
_29
}

Add allowed modes 1/2

We add a mode property of type string...

src/components/section/section.schema.json

_34
{
_34
"$schema": "http://json-schema.org/draft-07/schema#",
_34
"$id": "http://schema.mydesignsystem.com/section.schema.json",
_34
"title": "Section",
_34
"description": "Component used to layout components into pages",
_34
"type": "object",
_34
"properties": {
_34
"headline": {
_34
"type": "string",
_34
"title": "Headline",
_34
"description": "Headline for the section",
_34
"format": "markdown"
_34
},
_34
"width": {
_34
"type": "string",
_34
"title": "Width",
_34
"description": "Width of section to use",
_34
"enum": ["full", "max", "wide", "default", "narrow"],
_34
"default": "default"
_34
},
_34
"gutter": {
_34
"type": "string",
_34
"title": "Gutter",
_34
"description": "Size of gutter to use",
_34
"enum": ["large", "default", "small", "none"],
_34
"default": "default"
_34
},
_34
"mode": {
_34
"type": "string",
_34
"title": "Mode",
_34
"description": "Layout mode used for section contents"
_34
}
_34
}
_34
}

Add allowed modes 2/2

... and make it an enum, defining its available options explicitly. We also set a default.

src/components/section/section.schema.json

_36
{
_36
"$schema": "http://json-schema.org/draft-07/schema#",
_36
"$id": "http://schema.mydesignsystem.com/section.schema.json",
_36
"title": "Section",
_36
"description": "Component used to layout components into pages",
_36
"type": "object",
_36
"properties": {
_36
"headline": {
_36
"type": "string",
_36
"title": "Headline",
_36
"description": "Headline for the section",
_36
"format": "markdown"
_36
},
_36
"width": {
_36
"type": "string",
_36
"title": "Width",
_36
"description": "Width of section to use",
_36
"enum": ["full", "max", "wide", "default", "narrow"],
_36
"default": "default"
_36
},
_36
"gutter": {
_36
"type": "string",
_36
"title": "Gutter",
_36
"description": "Size of gutter to use",
_36
"enum": ["large", "default", "small", "none"],
_36
"default": "default"
_36
},
_36
"mode": {
_36
"type": "string",
_36
"title": "Mode",
_36
"description": "Layout mode used for section contents",
_36
"enum": ["default", "tile", "list"],
_36
"default": "default"
_36
}
_36
}
_36
}

Add allowed contents

We add a field content of type array´. Let's assume we have three components that can be used as content for the section. We reference each one using anyOfand$ref`.

src/components/section/section.schema.json

_54
{
_54
"$schema": "http://json-schema.org/draft-07/schema#",
_54
"$id": "http://schema.mydesignsystem.com/section.schema.json",
_54
"title": "Section",
_54
"description": "Component used to layout components into pages",
_54
"type": "object",
_54
"properties": {
_54
"headline": {
_54
"type": "string",
_54
"title": "Headline",
_54
"description": "Headline for the section",
_54
"format": "markdown"
_54
},
_54
"width": {
_54
"type": "string",
_54
"title": "Width",
_54
"description": "Width of section to use",
_54
"enum": ["full", "max", "wide", "default", "narrow"],
_54
"default": "default"
_54
},
_54
"gutter": {
_54
"type": "string",
_54
"title": "Gutter",
_54
"description": "Size of gutter to use",
_54
"enum": ["large", "default", "small", "none"],
_54
"default": "default"
_54
},
_54
"mode": {
_54
"type": "string",
_54
"title": "Mode",
_54
"description": "Layout mode used for section contents",
_54
"enum": ["default", "tile", "list"],
_54
"default": "default"
_54
},
_54
"content": {
_54
"type": "array",
_54
"title": "Content",
_54
"description": "Allowed content for the section",
_54
"items": {
_54
"anyOf": [
_54
{
_54
"$ref": "http://schema.mydesignsystem.com/button.schema.json"
_54
},
_54
{
_54
"$ref": "http://schema.mydesignsystem.com/headline.schema.json"
_54
},
_54
{
_54
"$ref": "http://schema.mydesignsystem.com/teaser-card.schema.json"
_54
}
_54
]
_54
}
_54
}
_54
}
_54
}

Add allowed styles 1/2

We add a style property of type string...

src/components/section/section.schema.json

_59
{
_59
"$schema": "http://json-schema.org/draft-07/schema#",
_59
"$id": "http://schema.mydesignsystem.com/section.schema.json",
_59
"title": "Section",
_59
"description": "Component used to layout components into pages",
_59
"type": "object",
_59
"properties": {
_59
"headline": {
_59
"type": "string",
_59
"title": "Headline",
_59
"description": "Headline for the section",
_59
"format": "markdown"
_59
},
_59
"width": {
_59
"type": "string",
_59
"title": "Width",
_59
"description": "Width of section to use",
_59
"enum": ["full", "max", "wide", "default", "narrow"],
_59
"default": "default"
_59
},
_59
"gutter": {
_59
"type": "string",
_59
"title": "Gutter",
_59
"description": "Size of gutter to use",
_59
"enum": ["large", "default", "small", "none"],
_59
"default": "default"
_59
},
_59
"mode": {
_59
"type": "string",
_59
"title": "Mode",
_59
"description": "Layout mode used for section contents",
_59
"enum": ["default", "tile", "list"],
_59
"default": "default"
_59
},
_59
"content": {
_59
"type": "array",
_59
"title": "Content",
_59
"description": "Allowed content for the section",
_59
"items": {
_59
"anyOf": [
_59
{
_59
"$ref": "http://schema.mydesignsystem.com/button.schema.json"
_59
},
_59
{
_59
"$ref": "http://schema.mydesignsystem.com/headline.schema.json"
_59
},
_59
{
_59
"$ref": "http://schema.mydesignsystem.com/teaser-card.schema.json"
_59
}
_59
]
_59
}
_59
},
_59
"style": {
_59
"type": "string",
_59
"title": "Style",
_59
"description": "Style of background"
_59
}
_59
}
_59
}

Add allowed styles 2/2

... and make it an enum, defining its available options explicitly. We also set a default.

src/components/section/section.schema.json

_61
{
_61
"$schema": "http://json-schema.org/draft-07/schema#",
_61
"$id": "http://schema.mydesignsystem.com/section.schema.json",
_61
"title": "Section",
_61
"description": "Component used to layout components into pages",
_61
"type": "object",
_61
"properties": {
_61
"headline": {
_61
"type": "string",
_61
"title": "Headline",
_61
"description": "Headline for the section",
_61
"format": "markdown"
_61
},
_61
"width": {
_61
"type": "string",
_61
"title": "Width",
_61
"description": "Width of section to use",
_61
"enum": ["full", "max", "wide", "default", "narrow"],
_61
"default": "default"
_61
},
_61
"gutter": {
_61
"type": "string",
_61
"title": "Gutter",
_61
"description": "Size of gutter to use",
_61
"enum": ["large", "default", "small", "none"],
_61
"default": "default"
_61
},
_61
"mode": {
_61
"type": "string",
_61
"title": "Mode",
_61
"description": "Layout mode used for section contents",
_61
"enum": ["default", "tile", "list"],
_61
"default": "default"
_61
},
_61
"content": {
_61
"type": "array",
_61
"title": "Content",
_61
"description": "Allowed content for the section",
_61
"items": {
_61
"anyOf": [
_61
{
_61
"$ref": "http://schema.mydesignsystem.com/button.schema.json"
_61
},
_61
{
_61
"$ref": "http://schema.mydesignsystem.com/headline.schema.json"
_61
},
_61
{
_61
"$ref": "http://schema.mydesignsystem.com/teaser-card.schema.json"
_61
}
_61
]
_61
}
_61
},
_61
"style": {
_61
"type": "string",
_61
"title": "Style",
_61
"description": "Style of background",
_61
"enum": ["default", "accent", "bold"],
_61
"default": "default"
_61
}
_61
}
_61
}

Add allowed spaceBefores 1/2

We add a spaceBefore property of type string...

src/components/section/section.schema.json

_66
{
_66
"$schema": "http://json-schema.org/draft-07/schema#",
_66
"$id": "http://schema.mydesignsystem.com/section.schema.json",
_66
"title": "Section",
_66
"description": "Component used to layout components into pages",
_66
"type": "object",
_66
"properties": {
_66
"headline": {
_66
"type": "string",
_66
"title": "Headline",
_66
"description": "Headline for the section",
_66
"format": "markdown"
_66
},
_66
"width": {
_66
"type": "string",
_66
"title": "Width",
_66
"description": "Width of section to use",
_66
"enum": ["full", "max", "wide", "default", "narrow"],
_66
"default": "default"
_66
},
_66
"gutter": {
_66
"type": "string",
_66
"title": "Gutter",
_66
"description": "Size of gutter to use",
_66
"enum": ["large", "default", "small", "none"],
_66
"default": "default"
_66
},
_66
"mode": {
_66
"type": "string",
_66
"title": "Mode",
_66
"description": "Layout mode used for section contents",
_66
"enum": ["default", "tile", "list"],
_66
"default": "default"
_66
},
_66
"content": {
_66
"type": "array",
_66
"title": "Content",
_66
"description": "Allowed content for the section",
_66
"items": {
_66
"anyOf": [
_66
{
_66
"$ref": "http://schema.mydesignsystem.com/button.schema.json"
_66
},
_66
{
_66
"$ref": "http://schema.mydesignsystem.com/headline.schema.json"
_66
},
_66
{
_66
"$ref": "http://schema.mydesignsystem.com/teaser-card.schema.json"
_66
}
_66
]
_66
}
_66
},
_66
"style": {
_66
"type": "string",
_66
"title": "Style",
_66
"description": "Style of background",
_66
"enum": ["default", "accent", "bold"],
_66
"default": "default"
_66
},
_66
"spaceBefore": {
_66
"type": "string",
_66
"title": "Space Before",
_66
"description": "Amount of spacing before the section"
_66
}
_66
}
_66
}

Add allowed spaceBefores 2/2

... and make it an enum, defining its available options explicitly. We also set a default.

src/components/section/section.schema.json

_68
{
_68
"$schema": "http://json-schema.org/draft-07/schema#",
_68
"$id": "http://schema.mydesignsystem.com/section.schema.json",
_68
"title": "Section",
_68
"description": "Component used to layout components into pages",
_68
"type": "object",
_68
"properties": {
_68
"headline": {
_68
"type": "string",
_68
"title": "Headline",
_68
"description": "Headline for the section",
_68
"format": "markdown"
_68
},
_68
"width": {
_68
"type": "string",
_68
"title": "Width",
_68
"description": "Width of section to use",
_68
"enum": ["full", "max", "wide", "default", "narrow"],
_68
"default": "default"
_68
},
_68
"gutter": {
_68
"type": "string",
_68
"title": "Gutter",
_68
"description": "Size of gutter to use",
_68
"enum": ["large", "default", "small", "none"],
_68
"default": "default"
_68
},
_68
"mode": {
_68
"type": "string",
_68
"title": "Mode",
_68
"description": "Layout mode used for section contents",
_68
"enum": ["default", "tile", "list"],
_68
"default": "default"
_68
},
_68
"content": {
_68
"type": "array",
_68
"title": "Content",
_68
"description": "Allowed content for the section",
_68
"items": {
_68
"anyOf": [
_68
{
_68
"$ref": "http://schema.mydesignsystem.com/button.schema.json"
_68
},
_68
{
_68
"$ref": "http://schema.mydesignsystem.com/headline.schema.json"
_68
},
_68
{
_68
"$ref": "http://schema.mydesignsystem.com/teaser-card.schema.json"
_68
}
_68
]
_68
}
_68
},
_68
"style": {
_68
"type": "string",
_68
"title": "Style",
_68
"description": "Style of background",
_68
"enum": ["default", "accent", "bold"],
_68
"default": "default"
_68
},
_68
"spaceBefore": {
_68
"type": "string",
_68
"title": "Space Before",
_68
"description": "Amount of spacing before the section",
_68
"enum": ["default", "small", "none"],
_68
"default": "default"
_68
}
_68
}
_68
}

Add allowed spaceAfters 1/2

We add a spaceAfter property of type string...

src/components/section/section.schema.json

_73
{
_73
"$schema": "http://json-schema.org/draft-07/schema#",
_73
"$id": "http://schema.mydesignsystem.com/section.schema.json",
_73
"title": "Section",
_73
"description": "Component used to layout components into pages",
_73
"type": "object",
_73
"properties": {
_73
"headline": {
_73
"type": "string",
_73
"title": "Headline",
_73
"description": "Headline for the section",
_73
"format": "markdown"
_73
},
_73
"width": {
_73
"type": "string",
_73
"title": "Width",
_73
"description": "Width of section to use",
_73
"enum": ["full", "max", "wide", "default", "narrow"],
_73
"default": "default"
_73
},
_73
"gutter": {
_73
"type": "string",
_73
"title": "Gutter",
_73
"description": "Size of gutter to use",
_73
"enum": ["large", "default", "small", "none"],
_73
"default": "default"
_73
},
_73
"mode": {
_73
"type": "string",
_73
"title": "Mode",
_73
"description": "Layout mode used for section contents",
_73
"enum": ["default", "tile", "list"],
_73
"default": "default"
_73
},
_73
"content": {
_73
"type": "array",
_73
"title": "Content",
_73
"description": "Allowed content for the section",
_73
"items": {
_73
"anyOf": [
_73
{
_73
"$ref": "http://schema.mydesignsystem.com/button.schema.json"
_73
},
_73
{
_73
"$ref": "http://schema.mydesignsystem.com/headline.schema.json"
_73
},
_73
{
_73
"$ref": "http://schema.mydesignsystem.com/teaser-card.schema.json"
_73
}
_73
]
_73
}
_73
},
_73
"style": {
_73
"type": "string",
_73
"title": "Style",
_73
"description": "Style of background",
_73
"enum": ["default", "accent", "bold"],
_73
"default": "default"
_73
},
_73
"spaceBefore": {
_73
"type": "string",
_73
"title": "Space Before",
_73
"description": "Amount of spacing before the section",
_73
"enum": ["default", "small", "none"],
_73
"default": "default"
_73
},
_73
"spaceAfter": {
_73
"type": "string",
_73
"title": "Space After",
_73
"description": "Amount of spacing after the section"
_73
}
_73
}
_73
}

Add allowed spaceAfters 2/2

... and make it an enum, defining its available options explicitly. We also set a default.

src/components/section/section.schema.json

_75
{
_75
"$schema": "http://json-schema.org/draft-07/schema#",
_75
"$id": "http://schema.mydesignsystem.com/section.schema.json",
_75
"title": "Section",
_75
"description": "Component used to layout components into pages",
_75
"type": "object",
_75
"properties": {
_75
"headline": {
_75
"type": "string",
_75
"title": "Headline",
_75
"description": "Headline for the section",
_75
"format": "markdown"
_75
},
_75
"width": {
_75
"type": "string",
_75
"title": "Width",
_75
"description": "Width of section to use",
_75
"enum": ["full", "max", "wide", "default", "narrow"],
_75
"default": "default"
_75
},
_75
"gutter": {
_75
"type": "string",
_75
"title": "Gutter",
_75
"description": "Size of gutter to use",
_75
"enum": ["large", "default", "small", "none"],
_75
"default": "default"
_75
},
_75
"mode": {
_75
"type": "string",
_75
"title": "Mode",
_75
"description": "Layout mode used for section contents",
_75
"enum": ["default", "tile", "list"],
_75
"default": "default"
_75
},
_75
"content": {
_75
"type": "array",
_75
"title": "Content",
_75
"description": "Allowed content for the section",
_75
"items": {
_75
"anyOf": [
_75
{
_75
"$ref": "http://schema.mydesignsystem.com/button.schema.json"
_75
},
_75
{
_75
"$ref": "http://schema.mydesignsystem.com/headline.schema.json"
_75
},
_75
{
_75
"$ref": "http://schema.mydesignsystem.com/teaser-card.schema.json"
_75
}
_75
]
_75
}
_75
},
_75
"style": {
_75
"type": "string",
_75
"title": "Style",
_75
"description": "Style of background",
_75
"enum": ["default", "accent", "bold"],
_75
"default": "default"
_75
},
_75
"spaceBefore": {
_75
"type": "string",
_75
"title": "Space Before",
_75
"description": "Amount of spacing before the section",
_75
"enum": ["default", "small", "none"],
_75
"default": "default"
_75
},
_75
"spaceAfter": {
_75
"type": "string",
_75
"title": "Space After",
_75
"description": "Amount of spacing after the section",
_75
"enum": ["default", "small", "none"],
_75
"default": "default"
_75
}
_75
}
_75
}

Add inverted property

We add a property inverted, as a boolean.

src/components/section/section.schema.json

_81
{
_81
"$schema": "http://json-schema.org/draft-07/schema#",
_81
"$id": "http://schema.mydesignsystem.com/section.schema.json",
_81
"title": "Section",
_81
"description": "Component used to layout components into pages",
_81
"type": "object",
_81
"properties": {
_81
"headline": {
_81
"type": "string",
_81
"title": "Headline",
_81
"description": "Headline for the section",
_81
"format": "markdown"
_81
},
_81
"width": {
_81
"type": "string",
_81
"title": "Width",
_81
"description": "Width of section to use",
_81
"enum": ["full", "max", "wide", "default", "narrow"],
_81
"default": "default"
_81
},
_81
"gutter": {
_81
"type": "string",
_81
"title": "Gutter",
_81
"description": "Size of gutter to use",
_81
"enum": ["large", "default", "small", "none"],
_81
"default": "default"
_81
},
_81
"mode": {
_81
"type": "string",
_81
"title": "Mode",
_81
"description": "Layout mode used for section contents",
_81
"enum": ["default", "tile", "list"],
_81
"default": "default"
_81
},
_81
"content": {
_81
"type": "array",
_81
"title": "Content",
_81
"description": "Allowed content for the section",
_81
"items": {
_81
"anyOf": [
_81
{
_81
"$ref": "http://schema.mydesignsystem.com/button.schema.json"
_81
},
_81
{
_81
"$ref": "http://schema.mydesignsystem.com/headline.schema.json"
_81
},
_81
{
_81
"$ref": "http://schema.mydesignsystem.com/teaser-card.schema.json"
_81
}
_81
]
_81
}
_81
},
_81
"style": {
_81
"type": "string",
_81
"title": "Style",
_81
"description": "Style of background",
_81
"enum": ["default", "accent", "bold"],
_81
"default": "default"
_81
},
_81
"spaceBefore": {
_81
"type": "string",
_81
"title": "Space Before",
_81
"description": "Amount of spacing before the section",
_81
"enum": ["default", "small", "none"],
_81
"default": "default"
_81
},
_81
"spaceAfter": {
_81
"type": "string",
_81
"title": "Space After",
_81
"description": "Amount of spacing after the section",
_81
"enum": ["default", "small", "none"],
_81
"default": "default"
_81
},
_81
"inverted": {
_81
"type": "boolean",
_81
"title": "Inverted",
_81
"description": "Whether to invert the section",
_81
"default": false
_81
}
_81
}
_81
}

Add ctas property 1/2

We add the ctas property of type array, this will hold our call-to-action related properties label and target.

src/components/section/section.schema.json

_86
{
_86
"$schema": "http://json-schema.org/draft-07/schema#",
_86
"$id": "http://schema.mydesignsystem.com/section.schema.json",
_86
"title": "Section",
_86
"description": "Component used to layout components into pages",
_86
"type": "object",
_86
"properties": {
_86
"headline": {
_86
"type": "string",
_86
"title": "Headline",
_86
"description": "Headline for the section",
_86
"format": "markdown"
_86
},
_86
"width": {
_86
"type": "string",
_86
"title": "Width",
_86
"description": "Width of section to use",
_86
"enum": ["full", "max", "wide", "default", "narrow"],
_86
"default": "default"
_86
},
_86
"gutter": {
_86
"type": "string",
_86
"title": "Gutter",
_86
"description": "Size of gutter to use",
_86
"enum": ["large", "default", "small", "none"],
_86
"default": "default"
_86
},
_86
"mode": {
_86
"type": "string",
_86
"title": "Mode",
_86
"description": "Layout mode used for section contents",
_86
"enum": ["default", "tile", "list"],
_86
"default": "default"
_86
},
_86
"content": {
_86
"type": "array",
_86
"title": "Content",
_86
"description": "Allowed content for the section",
_86
"items": {
_86
"anyOf": [
_86
{
_86
"$ref": "http://schema.mydesignsystem.com/button.schema.json"
_86
},
_86
{
_86
"$ref": "http://schema.mydesignsystem.com/headline.schema.json"
_86
},
_86
{
_86
"$ref": "http://schema.mydesignsystem.com/teaser-card.schema.json"
_86
}
_86
]
_86
}
_86
},
_86
"style": {
_86
"type": "string",
_86
"title": "Style",
_86
"description": "Style of background",
_86
"enum": ["default", "accent", "bold"],
_86
"default": "default"
_86
},
_86
"spaceBefore": {
_86
"type": "string",
_86
"title": "Space Before",
_86
"description": "Amount of spacing before the section",
_86
"enum": ["default", "small", "none"],
_86
"default": "default"
_86
},
_86
"spaceAfter": {
_86
"type": "string",
_86
"title": "Space After",
_86
"description": "Amount of spacing after the section",
_86
"enum": ["default", "small", "none"],
_86
"default": "default"
_86
},
_86
"inverted": {
_86
"type": "boolean",
_86
"title": "Inverted",
_86
"description": "Whether to invert the section",
_86
"default": false
_86
},
_86
"ctas": {
_86
"type": "array",
_86
"title": "Call to actions",
_86
"description": "Add Call to actions to the end of the section"
_86
}
_86
}
_86
}

Add ctas property 2/2

We specify the array items type, adding an object with properties label and target to it, both of simple string types (with target having format set to uri to enable resource-like behaviour).

src/components/section/section.schema.json

_103
{
_103
"$schema": "http://json-schema.org/draft-07/schema#",
_103
"$id": "http://schema.mydesignsystem.com/section.schema.json",
_103
"title": "Section",
_103
"description": "Component used to layout components into pages",
_103
"type": "object",
_103
"properties": {
_103
"headline": {
_103
"type": "string",
_103
"title": "Headline",
_103
"description": "Headline for the section",
_103
"format": "markdown"
_103
},
_103
"width": {
_103
"type": "string",
_103
"title": "Width",
_103
"description": "Width of section to use",
_103
"enum": ["full", "max", "wide", "default", "narrow"],
_103
"default": "default"
_103
},
_103
"gutter": {
_103
"type": "string",
_103
"title": "Gutter",
_103
"description": "Size of gutter to use",
_103
"enum": ["large", "default", "small", "none"],
_103
"default": "default"
_103
},
_103
"mode": {
_103
"type": "string",
_103
"title": "Mode",
_103
"description": "Layout mode used for section contents",
_103
"enum": ["default", "tile", "list"],
_103
"default": "default"
_103
},
_103
"content": {
_103
"type": "array",
_103
"title": "Content",
_103
"description": "Allowed content for the section",
_103
"items": {
_103
"anyOf": [
_103
{
_103
"$ref": "http://schema.mydesignsystem.com/button.schema.json"
_103
},
_103
{
_103
"$ref": "http://schema.mydesignsystem.com/headline.schema.json"
_103
},
_103
{
_103
"$ref": "http://schema.mydesignsystem.com/teaser-card.schema.json"
_103
}
_103
]
_103
}
_103
},
_103
"style": {
_103
"type": "string",
_103
"title": "Style",
_103
"description": "Style of background",
_103
"enum": ["default", "accent", "bold"],
_103
"default": "default"
_103
},
_103
"spaceBefore": {
_103
"type": "string",
_103
"title": "Space Before",
_103
"description": "Amount of spacing before the section",
_103
"enum": ["default", "small", "none"],
_103
"default": "default"
_103
},
_103
"spaceAfter": {
_103
"type": "string",
_103
"title": "Space After",
_103
"description": "Amount of spacing after the section",
_103
"enum": ["default", "small", "none"],
_103
"default": "default"
_103
},
_103
"inverted": {
_103
"type": "boolean",
_103
"title": "Inverted",
_103
"description": "Whether to invert the section",
_103
"default": false
_103
},
_103
"ctas": {
_103
"type": "array",
_103
"title": "Call to actions",
_103
"description": "Add Call to actions to the end of the section",
_103
"items": {
_103
"type": "object",
_103
"properties": {
_103
"label": {
_103
"type": "string",
_103
"title": "Label",
_103
"description": "Label for the Call to action"
_103
},
_103
"target": {
_103
"type": "string",
_103
"title": "Target",
_103
"description": "Target for the Call to action",
_103
"format": "uri"
_103
}
_103
},
_103
"required": ["label", "target"]
_103
}
_103
}
_103
}
_103
}

Finished JSON Schema

Let's have a look at our completed JSON Schema definition.

src/components/section/section.schema.json

_104
{
_104
"$schema": "http://json-schema.org/draft-07/schema#",
_104
"$id": "http://schema.mydesignsystem.com/section.schema.json",
_104
"title": "Section",
_104
"description": "Component used to layout components into pages",
_104
"type": "object",
_104
"properties": {
_104
"headline": {
_104
"type": "string",
_104
"title": "Headline",
_104
"description": "Headline for the section",
_104
"format": "markdown"
_104
},
_104
"width": {
_104
"type": "string",
_104
"title": "Width",
_104
"description": "Width of section to use",
_104
"enum": ["full", "max", "wide", "default", "narrow"],
_104
"default": "default"
_104
},
_104
"gutter": {
_104
"type": "string",
_104
"title": "Gutter",
_104
"description": "Size of gutter to use",
_104
"enum": ["large", "default", "small", "none"],
_104
"default": "default"
_104
},
_104
"mode": {
_104
"type": "string",
_104
"title": "Mode",
_104
"description": "Layout mode used for section contents",
_104
"enum": ["default", "tile", "list"],
_104
"default": "default"
_104
},
_104
"content": {
_104
"type": "array",
_104
"title": "Content",
_104
"description": "Allowed content for the section",
_104
"items": {
_104
"anyOf": [
_104
{
_104
"$ref": "http://schema.mydesignsystem.com/button.schema.json"
_104
},
_104
{
_104
"$ref": "http://schema.mydesignsystem.com/headline.schema.json"
_104
},
_104
{
_104
"$ref": "http://schema.mydesignsystem.com/teaser-card.schema.json"
_104
}
_104
]
_104
}
_104
},
_104
"style": {
_104
"type": "string",
_104
"title": "Style",
_104
"description": "Style of background",
_104
"enum": ["default", "accent", "bold"],
_104
"default": "default"
_104
},
_104
"spaceBefore": {
_104
"type": "string",
_104
"title": "Space Before",
_104
"description": "Amount of spacing before the section",
_104
"enum": ["default", "small", "none"],
_104
"default": "default"
_104
},
_104
"spaceAfter": {
_104
"type": "string",
_104
"title": "Space After",
_104
"description": "Amount of spacing after the section",
_104
"enum": ["default", "small", "none"],
_104
"default": "default"
_104
},
_104
"inverted": {
_104
"type": "boolean",
_104
"title": "Inverted",
_104
"description": "Whether to invert the section",
_104
"default": false
_104
},
_104
"ctas": {
_104
"type": "array",
_104
"title": "Call to actions",
_104
"description": "Add Call to actions to the end of the section",
_104
"items": {
_104
"type": "object",
_104
"properties": {
_104
"label": {
_104
"type": "string",
_104
"title": "Label",
_104
"description": "Label for the Call to action"
_104
},
_104
"target": {
_104
"type": "string",
_104
"title": "Target",
_104
"description": "Target for the Call to action",
_104
"format": "uri"
_104
}
_104
},
_104
"required": ["label", "target"]
_104
}
_104
}
_104
},
_104
"required": []
_104
}

Finished JSON Schema

We'll work our way up to this JSON Schema definition.

Start with just the boilerplate for a component definition

This includes all necessarily required values for a valid component definition in kickstartDS.

Add basic info describing component

We start by adding a title, description and $id attribute. The correct $id depends on your Design System configuration. We'll assume you've created components before, living under the schema prefix http://schema.mydesignsystem.com.

Create headline field

The headline field is a straight-forward string type properties, so we just document it a bit!
We do mark it by setting format to markdown, though, to enable some light RTE-like formatting options of the rendered text later on.

Add allowed widths 1/2

We add a width property of type string...

Add allowed widths 2/2

... and make it an enum, defining its available options explicitly. We also set a default.

Add allowed gutters 1/2

We add a gutter property of type string...

Add allowed gutters 2/2

... and make it an enum, defining its available options explicitly. We also set a default.

Add allowed modes 1/2

We add a mode property of type string...

Add allowed modes 2/2

... and make it an enum, defining its available options explicitly. We also set a default.

Add allowed contents

We add a field content of type array´. Let's assume we have three components that can be used as content for the section. We reference each one using anyOfand$ref`.

Add allowed styles 1/2

We add a style property of type string...

Add allowed styles 2/2

... and make it an enum, defining its available options explicitly. We also set a default.

Add allowed spaceBefores 1/2

We add a spaceBefore property of type string...

Add allowed spaceBefores 2/2

... and make it an enum, defining its available options explicitly. We also set a default.

Add allowed spaceAfters 1/2

We add a spaceAfter property of type string...

Add allowed spaceAfters 2/2

... and make it an enum, defining its available options explicitly. We also set a default.

Add inverted property

We add a property inverted, as a boolean.

Add ctas property 1/2

We add the ctas property of type array, this will hold our call-to-action related properties label and target.

Add ctas property 2/2

We specify the array items type, adding an object with properties label and target to it, both of simple string types (with target having format set to uri to enable resource-like behaviour).

Finished JSON Schema

Let's have a look at our completed JSON Schema definition.

src/components/section/section.schema.json

_104
{
_104
"$schema": "http://json-schema.org/draft-07/schema#",
_104
"$id": "http://schema.mydesignsystem.com/section.schema.json",
_104
"title": "Section",
_104
"description": "Component used to layout components into pages",
_104
"type": "object",
_104
"properties": {
_104
"headline": {
_104
"type": "string",
_104
"title": "Headline",
_104
"description": "Headline for the section",
_104
"format": "markdown"
_104
},
_104
"width": {
_104
"type": "string",
_104
"title": "Width",
_104
"description": "Width of section to use",
_104
"enum": ["full", "max", "wide", "default", "narrow"],
_104
"default": "default"
_104
},
_104
"gutter": {
_104
"type": "string",
_104
"title": "Gutter",
_104
"description": "Size of gutter to use",
_104
"enum": ["large", "default", "small", "none"],
_104
"default": "default"
_104
},
_104
"mode": {
_104
"type": "string",
_104
"title": "Mode",
_104
"description": "Layout mode used for section contents",
_104
"enum": ["default", "tile", "list"],
_104
"default": "default"
_104
},
_104
"content": {
_104
"type": "array",
_104
"title": "Content",
_104
"description": "Allowed content for the section",
_104
"items": {
_104
"anyOf": [
_104
{
_104
"$ref": "http://schema.mydesignsystem.com/button.schema.json"
_104
},
_104
{
_104
"$ref": "http://schema.mydesignsystem.com/headline.schema.json"
_104
},
_104
{
_104
"$ref": "http://schema.mydesignsystem.com/teaser-card.schema.json"
_104
}
_104
]
_104
}
_104
},
_104
"style": {
_104
"type": "string",
_104
"title": "Style",
_104
"description": "Style of background",
_104
"enum": ["default", "accent", "bold"],
_104
"default": "default"
_104
},
_104
"spaceBefore": {
_104
"type": "string",
_104
"title": "Space Before",
_104
"description": "Amount of spacing before the section",
_104
"enum": ["default", "small", "none"],
_104
"default": "default"
_104
},
_104
"spaceAfter": {
_104
"type": "string",
_104
"title": "Space After",
_104
"description": "Amount of spacing after the section",
_104
"enum": ["default", "small", "none"],
_104
"default": "default"
_104
},
_104
"inverted": {
_104
"type": "boolean",
_104
"title": "Inverted",
_104
"description": "Whether to invert the section",
_104
"default": false
_104
},
_104
"ctas": {
_104
"type": "array",
_104
"title": "Call to actions",
_104
"description": "Add Call to actions to the end of the section",
_104
"items": {
_104
"type": "object",
_104
"properties": {
_104
"label": {
_104
"type": "string",
_104
"title": "Label",
_104
"description": "Label for the Call to action"
_104
},
_104
"target": {
_104
"type": "string",
_104
"title": "Target",
_104
"description": "Target for the Call to action",
_104
"format": "uri"
_104
}
_104
},
_104
"required": ["label", "target"]
_104
}
_104
}
_104
},
_104
"required": []
_104
}

This concludes creating the JSON Schema. When running the schema generation in our Design System again, we should now automatically end up with a corresponding type definition to be used in creation of the template in the next step:

src/components/section/SectionProps.ts
src/components/section/section.schema.json

_176
/* eslint-disable */
_176
/**
_176
* This file was automatically generated by json-schema-to-typescript.
_176
* DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
_176
* and run `yarn run schema` to regenerate this file.
_176
*/
_176
_176
/\*\*
_176
_176
- Headline for the section
_176
\*/
_176
export type Headline = string;
_176
/\*\*
_176
- Width of section to use
_176
\*/
_176
export type Width = "full" | "max" | "wide" | "default" | "narrow";
_176
/\*\*
_176
- Size of gutter to use
_176
\*/
_176
export type Gutter = "large" | "default" | "small" | "none";
_176
/\*\*
_176
- Layout mode used for section contents
_176
\*/
_176
export type Mode = "default" | "tile" | "list";
_176
/\*\*
_176
- Text content to display inside the button
_176
\*/
_176
export type Label = string;
_176
/\*\*
_176
- Target that should be linked, makes the button behave like a link semantically
_176
\*/
_176
export type Target = string;
_176
/\*\*
_176
- Variant of button to be used
_176
\*/
_176
export type Variant = "primary" | "secondary" | "tertiary";
_176
/\*\*
_176
- Size of button to use
_176
\*/
_176
export type Size = "small" | "medium" | "large";
_176
/\*\*
_176
- Whether the button should be disabled
_176
\*/
_176
export type Disabled = boolean;
_176
/\*\*
_176
- Text content of headline
_176
\*/
_176
export type Text = string;
_176
/\*\*
_176
- Subheadline content
_176
\*/
_176
export type Sub = string;
_176
/\*\*
_176
- Switch order of headline and subheadline
_176
\*/
_176
export type SwitchOrder = boolean;
_176
/\*\*
_176
- Level of headline to use
_176
\*/
_176
export type Level = "h1" | "h2" | "h3" | "h4" | "p";
_176
/\*\*
_176
- Style of headline to show
_176
\*/
_176
export type Style = "h1" | "h2" | "h3" | "h4" | "p";
_176
/\*\*
_176
- Whether to display space after headline
_176
\*/
_176
export type SpaceAfter = "minimum" | "small" | "large";
_176
/\*\*
_176
- Headline for the teaser card
_176
\*/
_176
export type Headline2 = string;
_176
/\*\*
_176
- Body text for the teaser card
_176
\*/
_176
export type Text1 = string;
_176
/\*\*
_176
- Target that should be linked
_176
\*/
_176
export type Target1 = string;
_176
/\*\*
_176
- Image to display as cover
_176
\*/
_176
export type Image = string;
_176
/\*\*
_176
- Whether to invert the card
_176
\*/
_176
export type InvertCard = boolean;
_176
/\*\*
_176
- Allowed content for the section
_176
\*/
_176
export type Content = (Button | Headline1 | TeaserCard)[];
_176
/\*\*
_176
- Style of background
_176
\*/
_176
export type Style1 = "default" | "accent" | "bold";
_176
/\*\*
_176
- Amount of spacing before the section
_176
\*/
_176
export type SpaceBefore = "default" | "small" | "none";
_176
/\*\*
_176
- Amount of spacing after the section
_176
\*/
_176
export type SpaceAfter1 = "default" | "small" | "none";
_176
/\*\*
_176
- Whether to invert the section
_176
\*/
_176
export type Inverted = boolean;
_176
/\*\*
_176
- Label for the Call to action
_176
\*/
_176
export type Label1 = string;
_176
/\*\*
_176
- Target for the Call to action
_176
\*/
_176
export type Target2 = string;
_176
/\*\*
_176
- Add Call to actions to the end of the section
_176
\*/
_176
export type CallToActions = {
_176
label: Label1;
_176
target: Target2;
_176
[k: string]: unknown;
_176
}[];
_176
_176
/\*\*
_176
_176
- Component used to layout components into pages
_176
\*/
_176
export interface SectionProps {
_176
headline?: Headline;
_176
width?: Width;
_176
gutter?: Gutter;
_176
mode?: Mode;
_176
content?: Content;
_176
style?: Style1;
_176
spaceBefore?: SpaceBefore;
_176
spaceAfter?: SpaceAfter1;
_176
inverted?: Inverted;
_176
ctas?: CallToActions;
_176
[k: string]: unknown;
_176
}
_176
/\*\*
_176
- Component used for user interaction
_176
\*/
_176
export interface Button {
_176
label: Label;
_176
target?: Target;
_176
variant?: Variant;
_176
size?: Size;
_176
disabled?: Disabled;
_176
[k: string]: unknown;
_176
}
_176
/\*\*
_176
- Component used for headlines
_176
\*/
_176
export interface Headline1 {
_176
text: Text;
_176
sub?: Sub;
_176
switchOrder?: SwitchOrder;
_176
level: Level;
_176
style?: Style;
_176
spaceAfter?: SpaceAfter;
_176
[k: string]: unknown;
_176
}
_176
/\*\*
_176
- Component used to tease content
_176
\*/
_176
export interface TeaserCard {
_176
headline: Headline2;
_176
text: Text1;
_176
target: Target1;
_176
image?: Image;
_176
inverted?: InvertCard;
_176
[k: string]: unknown;
_176
}

How your schema generation is started might change depending on your setup. If you've followed our "Create your Design System" guide before, or want to add it like we do, follow this section of it closely.

React template

As the final step for this example, we'll add the template. This will be a purely functional React component, mapping our component structure (as defined in the JSON Schema) to the original component we're basing our work off of; the kickstartDS Storytelling component.

Finished React template

We'll work our way up to this React template.

src/components/section/SectionComponent.tsx

_61
import { HTMLAttributes, FC, PropsWithChildren } from "react";
_61
_61
import {
_61
SectionContextDefault,
_61
SectionContext,
_61
} from "@kickstartds/base/lib/section";
_61
_61
import { SectionProps } from "./SectionProps";
_61
import { Button } from "../button/ButtonComponent";
_61
_61
export const Section: FC<
_61
SectionProps & HTMLAttributes<HTMLElement>
_61
> = ({
_61
headline,
_61
width = "default",
_61
gutter = "default",
_61
mode = "default",
_61
style = "default",
_61
spaceBefore = "default",
_61
spaceAfter = "default",
_61
inverted = false,
_61
ctas = [],
_61
...props
_61
}) => {
_61
return (
_61
<>
_61
<SectionContextDefault
_61
{...props}
_61
background={style}
_61
headline={{
_61
content: headline
_61
}}
_61
width={width}
_61
gutter={gutter}
_61
mode={mode}
_61
spaceBefore={spaceBefore}
_61
spaceAfter={ctas && ctas.length > 0 ? 'none' : spaceAfter}
_61
inverted={inverted}
_61
/>
_61
{ctas && ctas.length > 0 && (
_61
<SectionContextDefault
_61
background={style}
_61
width="narrow"
_61
gutter={gutter}
_61
mode="default"
_61
spaceBefore="default"
_61
spaceAfter={spaceAfter}
_61
inverted={inverted}
_61
>
_61
{ctas.map((cta, index) => (
_61
<Button label={cta.label} variant={index === 0 ? "primary" : index === 1 ? "secondary": "tertiary" } size="medium" />
_61
))}
_61
</SectionContextDefault>
_61
)}
_61
</>
_61
);
_61
};
_61
_61
export const SectionProvider: FC<PropsWithChildren<any>> = (props) => (
_61
<SectionContext.Provider {...props} value={Section} />
_61
);

Start with a boilerplate

Again we'll start with a very basic skeleton for our React component. We're using TypeScript here (.tsx), but it works the same with plain JSX (.jsx).

src/components/section/SectionComponent.tsx

_10
import { HTMLAttributes, FC } from "react";
_10
_10
export const Section: FC<HTMLAttributes<HTMLDivElement>> = (
_10
props
_10
) => <div {...props}>Lorem ipsum</div>;

Add correct typings

Import and add generated props from SectionProps.ts. Generated by our JSON Schema, these guarantee you're matching your expected component structure while implementing. In combination with TypeScript this enables auto-complete and auto-fix for even better DX! (see here, at the very end of that section, for more details)

We also add HTMLAttributes<HTMLElement> to the type signature for the props that we'll pass through to the native HTML element underneath.

src/components/section/SectionComponent.tsx

_10
import { HTMLAttributes, FC } from "react";
_10
_10
import { SectionProps } from "./SectionProps";
_10
_10
export const Section: FC<
_10
SectionProps & HTMLAttributes<HTMLElement>
_10
> = ({ ...props }) => <div {...props}>Lorem ipsum</div>;

Destructure props

We also need to add our own properties, so we'll destructure props. We add our default values here, too. We'll just pass through everything HTMLAttributes related!

src/components/section/SectionComponent.tsx

_20
import { HTMLAttributes, FC } from "react";
_20
_20
import { SectionProps } from "./SectionProps";
_20
_20
export const Section: FC<
_20
SectionProps & HTMLAttributes<HTMLElement>
_20
> = ({
_20
headline,
_20
width = "default",
_20
gutter = "default",
_20
mode = "default",
_20
style = "default",
_20
spaceBefore = "default",
_20
spaceAfter = "default",
_20
inverted = false,
_20
ctas = [],
_20
...props
_20
}) => (
_20
<div {...props}>Lorem ipsum</div>
_20
));

Add Section component 1/7

Now we'll import and add the kickstartDS Section component. To start, we'll use the hard-coded properties of the Content Boxes Section variant from our kickstartDS Design System.

We'll omit the child components added there (ContentBoxes), as they only exist for illustrative purposes inside that Storybook. We will just pass children through to the original Section, later.

src/components/section/SectionComponent.tsx

_42
import { HTMLAttributes, FC } from "react";
_42
_42
import {
_42
SectionContextDefault,
_42
} from "@kickstartds/base/lib/section";
_42
_42
import { SectionProps } from "./SectionProps";
_42
_42
export const Section: FC<
_42
SectionProps & HTMLAttributes<HTMLElement>
_42
> = ({
_42
headline,
_42
width = "default",
_42
gutter = "default",
_42
mode = "default",
_42
style = "default",
_42
spaceBefore = "default",
_42
spaceAfter = "default",
_42
inverted = false,
_42
ctas = [],
_42
...props
_42
}) => (
_42
<SectionContextDefault
_42
background="default"
_42
headline={{
_42
align: 'center',
_42
className: undefined,
_42
content: 'Headline',
_42
level: 'h2',
_42
spaceAfter: 'none',
_42
styleAs: 'none',
_42
subheadline: undefined
_42
}}
_42
width="default"
_42
gutter="default"
_42
mode="tile"
_42
pattern="none"
_42
spaceBefore="default"
_42
spaceAfter="default"
_42
variant="none"
_42
/>
_42
));

Add Section component 2/7

We remove all of the unneeded stuff, as there are a bunch of properties that are completely optional, mainly those having their values undefined or null in the copied JSX, or ones which just state the default value of that property anyway. Those can be freely removed.

src/components/section/SectionComponent.tsx

_34
import { HTMLAttributes, FC } from "react";
_34
_34
import {
_34
SectionContextDefault,
_34
} from "@kickstartds/base/lib/section";
_34
_34
import { SectionProps } from "./SectionProps";
_34
_34
export const Section: FC<
_34
SectionProps & HTMLAttributes<HTMLElement>
_34
> = ({
_34
headline,
_34
width = "default",
_34
gutter = "default",
_34
mode = "default",
_34
style = "default",
_34
spaceBefore = "default",
_34
spaceAfter = "default",
_34
inverted = false,
_34
ctas = [],
_34
...props
_34
}) => (
_34
<SectionContextDefault
_34
background="default"
_34
headline={{
_34
content: 'Headline',
_34
}}
_34
width="default"
_34
gutter="default"
_34
mode="tile"
_34
spaceBefore="default"
_34
spaceAfter="default"
_34
/>
_34
));

Add Section component 3/7

We now import the component we want to use to display the call-to-actions, in this case a Button included in our own Design System. We also add a second Section (losing its headline) to hold our Buttons, and connect those to cta.label. We choose the variant of Button by index, first equals primary, second means secondary and all others are tertiary.

src/components/section/SectionComponent.tsx

_51
import { HTMLAttributes, FC } from "react";
_51
_51
import {
_51
SectionContextDefault,
_51
} from "@kickstartds/base/lib/section";
_51
_51
import { SectionProps } from "./SectionProps";
_51
import { Button } from "../button/ButtonComponent";
_51
_51
export const Section: FC<
_51
SectionProps & HTMLAttributes<HTMLElement>
_51
> = ({
_51
headline,
_51
width = "default",
_51
gutter = "default",
_51
mode = "default",
_51
style = "default",
_51
spaceBefore = "default",
_51
spaceAfter = "default",
_51
inverted = false,
_51
ctas = [],
_51
...props
_51
}) => (
_51
<>
_51
<SectionContextDefault
_51
background="default"
_51
headline={{
_51
content: 'Headline',
_51
}}
_51
width="default"
_51
gutter="default"
_51
mode="tile"
_51
spaceBefore="default"
_51
spaceAfter="default"
_51
/>
_51
{ctas && ctas.length > 0 && (
_51
<SectionContextDefault
_51
background="default"
_51
width="default"
_51
gutter="default"
_51
mode="tile"
_51
spaceBefore="default"
_51
spaceAfter="default"
_51
>
_51
{ctas.map((cta, index) => (
_51
<Button label={cta.label} variant={index === 0 ? "primary" : index === 1 ? "secondary": "tertiary" } size="medium" />
_51
))}
_51
</SectionContextDefault>
_51
)}
_51
</>
_51
);

Add Section component 4/7

We then connect the props as defined in our component API that are directly taken from the underlying kickstartDS base component by just passing them through. We also destructure props first, so our own properties take precedence when set. We add it to the first Section, that will always be rendered.

src/components/section/SectionComponent.tsx

_56
import { HTMLAttributes, FC } from "react";
_56
_56
import { SectionContextDefault } from '@kickstartds/base/lib/section';
_56
_56
import { SectionProps } from './SectionProps';
_56
import { Button } from '../button/ButtonComponent';
_56
_56
export const Section: FC<SectionProps & HTMLAttributes<HTMLElement>> = ({
_56
headline,
_56
width = 'default',
_56
gutter = 'default',
_56
mode = 'default',
_56
style = 'default',
_56
spaceBefore = 'default',
_56
spaceAfter = 'default',
_56
inverted = false,
_56
ctas = [],
_56
...props
_56
}) => (
_56
<>
_56
<SectionContextDefault
_56
{...props}
_56
background="default"
_56
headline={{
_56
content: 'Headline',
_56
}}
_56
width={width}
_56
gutter={gutter}
_56
mode={mode}
_56
spaceBefore={spaceBefore}
_56
spaceAfter={spaceAfter}
_56
inverted={inverted}
_56
/>
_56
{ctas && ctas.length > 0 && (
_56
<SectionContextDefault
_56
background="default"
_56
width={width}
_56
gutter={gutter}
_56
mode={mode}
_56
spaceBefore={spaceBefore}
_56
spaceAfter={spaceAfter}
_56
inverted={inverted}
_56
>
_56
{ctas.map((cta, index) => (
_56
<Button
_56
label={cta.label}
_56
variant={
_56
index === 0 ? 'primary' : index === 1 ? 'secondary' : 'tertiary'
_56
}
_56
size="medium"
_56
/>
_56
))}
_56
</SectionContextDefault>
_56
)}
_56
</>
_56
);

Add Section component 5/7

We renamed background to style in our component API, so we add that in its renamed form... to both Sections.

src/components/section/SectionComponent.tsx

_54
import { HTMLAttributes, FC } from "react";
_54
_54
import {
_54
SectionContextDefault,
_54
} from "@kickstartds/base/lib/section";
_54
_54
import { SectionProps } from "./SectionProps";
_54
import { Button } from "../button/ButtonComponent";
_54
_54
export const Section: FC<
_54
SectionProps & HTMLAttributes<HTMLElement>
_54
> = ({
_54
headline,
_54
width = "default",
_54
gutter = "default",
_54
mode = "default",
_54
style = "default",
_54
spaceBefore = "default",
_54
spaceAfter = "default",
_54
inverted = false,
_54
ctas = [],
_54
...props
_54
}) => (
_54
<>
_54
<SectionContextDefault
_54
{...props}
_54
background={style}
_54
headline={{
_54
content: 'Headline',
_54
}}
_54
width={width}
_54
gutter={gutter}
_54
mode={mode}
_54
spaceBefore={spaceBefore}
_54
spaceAfter={spaceAfter}
_54
inverted={inverted}
_54
/>
_54
{ctas && ctas.length > 0 && (
_54
<SectionContextDefault
_54
background={style}
_54
width={width}
_54
gutter={gutter}
_54
mode={mode}
_54
spaceBefore={spaceBefore}
_54
spaceAfter={spaceAfter}
_54
inverted={inverted}
_54
>
_54
{ctas.map((cta, index) => (
_54
<Button label={cta.label} variant={index === 0 ? "primary" : index === 1 ? "secondary": "tertiary" } size="medium" />
_54
))}
_54
</SectionContextDefault>
_54
)}
_54
</>
_54
);

Add Section component 6/7

We connect our property headline to the first Sections headline.content.

src/components/section/SectionComponent.tsx

_56
import { HTMLAttributes, FC } from "react";
_56
_56
import { SectionContextDefault } from '@kickstartds/base/lib/section';
_56
_56
import { SectionProps } from './SectionProps';
_56
import { Button } from '../button/ButtonComponent';
_56
_56
export const Section: FC<SectionProps & HTMLAttributes<HTMLElement>> = ({
_56
headline,
_56
width = 'default',
_56
gutter = 'default',
_56
mode = 'default',
_56
style = 'default',
_56
spaceBefore = 'default',
_56
spaceAfter = 'default',
_56
inverted = false,
_56
ctas = [],
_56
...props
_56
}) => (
_56
<>
_56
<SectionContextDefault
_56
{...props}
_56
background={style}
_56
headline={{
_56
content: headline
_56
}}
_56
width={width}
_56
gutter={gutter}
_56
mode={mode}
_56
spaceBefore={spaceBefore}
_56
spaceAfter={spaceAfter}
_56
inverted={inverted}
_56
/>
_56
{ctas && ctas.length > 0 && (
_56
<SectionContextDefault
_56
background={style}
_56
width={width}
_56
gutter={gutter}
_56
mode={mode}
_56
spaceBefore={spaceBefore}
_56
spaceAfter={spaceAfter}
_56
inverted={inverted}
_56
>
_56
{ctas.map((cta, index) => (
_56
<Button
_56
label={cta.label}
_56
variant={
_56
index === 0 ? 'primary' : index === 1 ? 'secondary' : 'tertiary'
_56
}
_56
size="medium"
_56
/>
_56
))}
_56
</SectionContextDefault>
_56
)}
_56
</>
_56
);

Add Section component 7/7

As a final step, we make sure the spacing between the two Sections is optimized, so it will look seamless later on. We also hard code some options of the second Section.

src/components/section/SectionComponent.tsx

_56
import { HTMLAttributes, FC } from "react";
_56
_56
import { SectionContextDefault } from '@kickstartds/base/lib/section';
_56
_56
import { SectionProps } from './SectionProps';
_56
import { Button } from '../button/ButtonComponent';
_56
_56
export const Section: FC<SectionProps & HTMLAttributes<HTMLElement>> = ({
_56
headline,
_56
width = 'default',
_56
gutter = 'default',
_56
mode = 'default',
_56
style = 'default',
_56
spaceBefore = 'default',
_56
spaceAfter = 'default',
_56
inverted = false,
_56
ctas = [],
_56
...props
_56
}) => (
_56
<>
_56
<SectionContextDefault
_56
{...props}
_56
background={style}
_56
headline={{
_56
content: headline
_56
}}
_56
width={width}
_56
gutter={gutter}
_56
mode={mode}
_56
spaceBefore={spaceBefore}
_56
spaceAfter={ctas && ctas.length > 0 ? 'none' : spaceAfter}
_56
inverted={inverted}
_56
/>
_56
{ctas && ctas.length > 0 && (
_56
<SectionContextDefault
_56
background={style}
_56
width="narrow"
_56
gutter={gutter}
_56
mode="default"
_56
spaceBefore="default"
_56
spaceAfter={spaceAfter}
_56
inverted={inverted}
_56
>
_56
{ctas.map((cta, index) => (
_56
<Button
_56
label={cta.label}
_56
variant={
_56
index === 0 ? 'primary' : index === 1 ? 'secondary' : 'tertiary'
_56
}
_56
size="medium"
_56
/>
_56
))}
_56
</SectionContextDefault>
_56
)}
_56
</>
_56
);

Add component Provider

We want our Section to replace all default kickstartDS base Sections, no matter where they appear. We add a Provider for that purpose now!

src/components/section/SectionComponent.tsx

_63
import { HTMLAttributes, FC, PropsWithChildren } from "react";
_63
_63
import {
_63
SectionContextDefault,
_63
SectionContext,
_63
} from '@kickstartds/base/lib/section';
_63
_63
import { SectionProps } from './SectionProps';
_63
import { Button } from '../button/ButtonComponent';
_63
_63
export const Section: FC<SectionProps & HTMLAttributes<HTMLElement>> = ({
_63
headline,
_63
width = 'default',
_63
gutter = 'default',
_63
mode = 'default',
_63
style = 'default',
_63
spaceBefore = 'default',
_63
spaceAfter = 'default',
_63
inverted = false,
_63
ctas = [],
_63
...props
_63
}) => (
_63
<>
_63
<SectionContextDefault
_63
{...props}
_63
background={style}
_63
headline={{
_63
content: headline,
_63
}}
_63
width={width}
_63
gutter={gutter}
_63
mode={mode}
_63
spaceBefore={spaceBefore}
_63
spaceAfter={ctas && ctas.length > 0 ? 'none' : spaceAfter}
_63
inverted={inverted}
_63
/>
_63
{ctas && ctas.length > 0 && (
_63
<SectionContextDefault
_63
background={style}
_63
width="narrow"
_63
gutter={gutter}
_63
mode="default"
_63
spaceBefore="default"
_63
spaceAfter={spaceAfter}
_63
inverted={inverted}
_63
>
_63
{ctas.map((cta, index) => (
_63
<Button
_63
label={cta.label}
_63
variant={
_63
index === 0 ? 'primary' : index === 1 ? 'secondary' : 'tertiary'
_63
}
_63
size="medium"
_63
/>
_63
))}
_63
</SectionContextDefault>
_63
)}
_63
</>
_63
);
_63
_63
export const SectionProvider: FC<PropsWithChildren<any>> = (props) => (
_63
<SectionContext.Provider {...props} value={Section} />
_63
);

Finished React template

Let's have a look at our completed React template.

src/components/section/SectionComponent.tsx

_63
import { HTMLAttributes, FC, PropsWithChildren } from "react";
_63
_63
import {
_63
SectionContextDefault,
_63
SectionContext,
_63
} from '@kickstartds/base/lib/section';
_63
_63
import { SectionProps } from './SectionProps';
_63
import { Button } from '../button/ButtonComponent';
_63
_63
export const Section: FC<SectionProps & HTMLAttributes<HTMLElement>> = ({
_63
headline,
_63
width = 'default',
_63
gutter = 'default',
_63
mode = 'default',
_63
style = 'default',
_63
spaceBefore = 'default',
_63
spaceAfter = 'default',
_63
inverted = false,
_63
ctas = [],
_63
...props
_63
}) => (
_63
<>
_63
<SectionContextDefault
_63
{...props}
_63
background={style}
_63
headline={{
_63
content: headline,
_63
}}
_63
width={width}
_63
gutter={gutter}
_63
mode={mode}
_63
spaceBefore={spaceBefore}
_63
spaceAfter={ctas && ctas.length > 0 ? 'none' : spaceAfter}
_63
inverted={inverted}
_63
/>
_63
{ctas && ctas.length > 0 && (
_63
<SectionContextDefault
_63
background={style}
_63
width="narrow"
_63
gutter={gutter}
_63
mode="default"
_63
spaceBefore="default"
_63
spaceAfter={spaceAfter}
_63
inverted={inverted}
_63
>
_63
{ctas.map((cta, index) => (
_63
<Button
_63
label={cta.label}
_63
variant={
_63
index === 0 ? 'primary' : index === 1 ? 'secondary' : 'tertiary'
_63
}
_63
size="medium"
_63
/>
_63
))}
_63
</SectionContextDefault>
_63
)}
_63
</>
_63
);
_63
_63
export const SectionProvider: FC<PropsWithChildren<any>> = (props) => (
_63
<SectionContext.Provider {...props} value={Section} />
_63
);

Finished React template

We'll work our way up to this React template.

Start with a boilerplate

Again we'll start with a very basic skeleton for our React component. We're using TypeScript here (.tsx), but it works the same with plain JSX (.jsx).

Add correct typings

Import and add generated props from SectionProps.ts. Generated by our JSON Schema, these guarantee you're matching your expected component structure while implementing. In combination with TypeScript this enables auto-complete and auto-fix for even better DX! (see here, at the very end of that section, for more details)

We also add HTMLAttributes<HTMLElement> to the type signature for the props that we'll pass through to the native HTML element underneath.

Destructure props

We also need to add our own properties, so we'll destructure props. We add our default values here, too. We'll just pass through everything HTMLAttributes related!

Add Section component 1/7

Now we'll import and add the kickstartDS Section component. To start, we'll use the hard-coded properties of the Content Boxes Section variant from our kickstartDS Design System.

We'll omit the child components added there (ContentBoxes), as they only exist for illustrative purposes inside that Storybook. We will just pass children through to the original Section, later.

Add Section component 2/7

We remove all of the unneeded stuff, as there are a bunch of properties that are completely optional, mainly those having their values undefined or null in the copied JSX, or ones which just state the default value of that property anyway. Those can be freely removed.

Add Section component 3/7

We now import the component we want to use to display the call-to-actions, in this case a Button included in our own Design System. We also add a second Section (losing its headline) to hold our Buttons, and connect those to cta.label. We choose the variant of Button by index, first equals primary, second means secondary and all others are tertiary.

Add Section component 4/7

We then connect the props as defined in our component API that are directly taken from the underlying kickstartDS base component by just passing them through. We also destructure props first, so our own properties take precedence when set. We add it to the first Section, that will always be rendered.

Add Section component 5/7

We renamed background to style in our component API, so we add that in its renamed form... to both Sections.

Add Section component 6/7

We connect our property headline to the first Sections headline.content.

Add Section component 7/7

As a final step, we make sure the spacing between the two Sections is optimized, so it will look seamless later on. We also hard code some options of the second Section.

Add component Provider

We want our Section to replace all default kickstartDS base Sections, no matter where they appear. We add a Provider for that purpose now!

Finished React template

Let's have a look at our completed React template.

src/components/section/SectionComponent.tsx

_61
import { HTMLAttributes, FC, PropsWithChildren } from "react";
_61
_61
import {
_61
SectionContextDefault,
_61
SectionContext,
_61
} from "@kickstartds/base/lib/section";
_61
_61
import { SectionProps } from "./SectionProps";
_61
import { Button } from "../button/ButtonComponent";
_61
_61
export const Section: FC<
_61
SectionProps & HTMLAttributes<HTMLElement>
_61
> = ({
_61
headline,
_61
width = "default",
_61
gutter = "default",
_61
mode = "default",
_61
style = "default",
_61
spaceBefore = "default",
_61
spaceAfter = "default",
_61
inverted = false,
_61
ctas = [],
_61
...props
_61
}) => {
_61
return (
_61
<>
_61
<SectionContextDefault
_61
{...props}
_61
background={style}
_61
headline={{
_61
content: headline
_61
}}
_61
width={width}
_61
gutter={gutter}
_61
mode={mode}
_61
spaceBefore={spaceBefore}
_61
spaceAfter={ctas && ctas.length > 0 ? 'none' : spaceAfter}
_61
inverted={inverted}
_61
/>
_61
{ctas && ctas.length > 0 && (
_61
<SectionContextDefault
_61
background={style}
_61
width="narrow"
_61
gutter={gutter}
_61
mode="default"
_61
spaceBefore="default"
_61
spaceAfter={spaceAfter}
_61
inverted={inverted}
_61
>
_61
{ctas.map((cta, index) => (
_61
<Button label={cta.label} variant={index === 0 ? "primary" : index === 1 ? "secondary": "tertiary" } size="medium" />
_61
))}
_61
</SectionContextDefault>
_61
)}
_61
</>
_61
);
_61
};
_61
_61
export const SectionProvider: FC<PropsWithChildren<any>> = (props) => (
_61
<SectionContext.Provider {...props} value={Section} />
_61
);

To complete the template we add the SectionProvider to our src/components/Providers.jsx:

src/components/Providers.jsx

_14
import { ButtonProvider } from "./button/ButtonComponent";
_14
import { SectionProvider } from "./section/SectionComponent";
_14
import { TeaserBoxProvider } from "./teaser-card/TeaserCardComponent";
_14
import { HeadlineProvider } from "./headline/HeadlineComponent";
_14
_14
export default (props) => (
_14
<ButtonProvider>
_14
<HeadlineProvider>
_14
<SectionProvider>
_14
<TeaserBoxProvider {...props} />
_14
</SectionProvider>
_14
</HeadlineProvider>
_14
</ButtonProvider>
_14
);

This concludes the creation of our new Section component. It's now ready to be used inside your Design System, and available to your down stream consumers... hopefully efficiently closing a gap for them!

Use of Storybook

If you're using Storybook, you can follow this part of the example to get all the integration goodness possible with kickstartDS!

Storybook setup

This guide assumes you're using a set up like described in our Create your Design System guide! Be sure to adapt commands and configuration to your use accordingly, when following this part!

Add the following file to your src/components/section folder:

Import re-usable Section Stories

Import Section component and add it to the Template that we'll bind Stories to.

Import re-usable TeaserCard Stories

Import TeaserCard Stories as demo content for our Section Story. Add them to the Template, too.

Import Storybook Controls helpers

Import dereferenced component JSON Schema and getArgsShared helper to generate Storybook Controls, and parameterize Storybook JSON Schema Addon.

Overwrite Story values where needed

We set all the Story defaults specific to our component.

Convert args to flat keys

We use pack to convert all deep JSON args to flat (. delimited) keys and values. This is the format your Storybook Controls get generated off.

Create Section variants

We do this by binding to our Template, and use pack to convert all deep JSON args to flat (. delimited) keys and values. This is the format your Storybook Controls get generated off.

src/components/section/Section.stories.jsx

_65
import merge from "deepmerge";
_65
import {
_65
pack,
_65
unpack,
_65
getArgsShared,
_65
} from "@kickstartds/core/lib/storybook";
_65
import sectionStories from "@kickstartds/base/lib/section/section.stories";
_65
import TeaserCardStory, {
_65
CardWithImage,
_65
} from "../teaser-card/TeaserCard.stories";
_65
import schema from "./section.schema.dereffed.json";
_65
_65
const Section = sectionStories.component;
_65
CardWithImage.displayName = "Teaser Card";
_65
const Template = (args) => {
_65
return (
_65
<Section {...args}>
_65
<CardWithImage
_65
{...merge(TeaserCardStory.args, unpack(CardWithImage.args))}
_65
/>
_65
<CardWithImage
_65
{...merge(TeaserCardStory.args, unpack(CardWithImage.args))}
_65
/>
_65
<CardWithImage
_65
{...merge(TeaserCardStory.args, unpack(CardWithImage.args))}
_65
/>
_65
</Section>
_65
)
_65
};
_65
_65
const { args, argTypes } = getArgsShared(schema);
_65
_65
export default {
_65
...sectionStories,
_65
title: "Layout/Section",
_65
args,
_65
argTypes,
_65
parameters: {
_65
jsonschema: schema,
_65
},
_65
};
_65
_65
export const TeaserCards = Template.bind({});
_65
TeaserCards.args = pack({
_65
headline: 'Section headline',
_65
mode: "tile",
_65
ctas: [],
_65
});
_65
_65
export const WithCtas = Template.bind({});
_65
WithCtas.args = pack({
_65
headline: 'Section headline',
_65
mode: "tile",
_65
ctas: [{
_65
label: 'Section CTA 1',
_65
target: '#',
_65
}, {
_65
label: 'Section CTA 2',
_65
target: '#',
_65
}, {
_65
label: 'Section CTA 3',
_65
target: '#',
_65
}
_65
]
_65
});

If you reopen your Storybook now, or if you kept it running while following along, you should now see your new Section in all its glory!

Finished Code Sandbox

You can also have a look at the completed component in the following Code Sandbox:

Toggle the file browser with the hamburger icon at the top left, or open it directly in your browser.


_10


_10