Create TeaserCard
component
This guided example show how to find a fitting, existing kickstartDS base component for one of your use cases, to repurpose it. Meaning: you start with some requirements, match an existing component, find a fitting new name for the use case, and give it a new purpose by greatly restricting and rewiring its options for the new context.
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 Creation. 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 three simple steps for that:
- Component Definition,
- Component Mapping, and
- 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 want to be able to flexibly tease content in a unified way. We think it should feel clean and modern, by looking like a card component. Otherwise, we'd just want to add the obvious things to such a card... headline, text, a link and optionally a cover image.
It would also be important to us that the component supports being inverted, as that's a feature we've used in other parts of our Design System extensively (for example our Section
). Components working together nicely, and sharing the same overarching concepts is a key tenant of using a Design System!
We give our component the name TeaserCard
.
Structure
Defining the structure of a component means finding the component API for it:
Property | Type | Description |
---|---|---|
headline * | string | Headline for the teaser card |
text * | string | Body text for the teaser card |
image | string | (Optional) image to display as cover |
inverted | boolean | Show inverted version of card? |
target * | string | Target that should be linked |
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 Mapping
Next we want to search for components that could be of use in assembling this new one. This might be a single, big component that more or less directly fits our use case, or alternatively a combination of components that could serve as the basis by combining them.
This will then serve as our kickstartDS base component, which will be adjusted to fit our needs!
Matching it
From a quick glance, our TeaserBox
component seems like it might fit the bill quite nicely! It has options for a headline
(topic
),text
(text
), inverted
(inverted
) and image
(image
), and we can simplify its link
for our target
.
It's inverted
feature is also based on the general kickstartDS component and Design Token functionality, fulfilling that requirement of ours:
For a complete overview of the available options, take a look at the TeaserBox
component API here:
https://www.kickstartds.com/storybook/?path=/docs/base-teaser-box--linked-with-button
Adjustments
This only gives us a rough sketch, though. We still need to adjust the example code to exactly fit our needs. In the process we will hard-code a bunch of options, because we're only interested in a specific set of them. The rest can be set to default values, which don't need to become part of the component API.
Start with an existing TeaserBox
component variant
We'll start by copying the JSX
code for the Linked With Button
variant of our TeaserBox
component, from here:
https://www.kickstartds.com/storybook/?path=/docs/base-teaser-box--linked-with-button
_21<TeaserBox_21 image="https://picsum.photos/seed/kdsteaserbox/500/300"_21 link={{_21 fillAnimation: false,_21 hidden: false,_21 href: 'https://example.com',_21 icon: {_21 icon: 'chevron-right',_21 },_21 iconAfter: true,_21 iconAnimation: false,_21 iconBefore: false,_21 label: 'learn more',_21 newTab: false,_21 size: 'medium',_21 variant: 'solid',_21 }}_21 ratio="16:9"_21 text="Lorem ipsum dolor sit amet, consectetur adipisicing elit. Lorem ispum dolor distinctio minima unde voluptatum aut. Lorem ipsum dolor sit amet."_21 topic="Lorem Ipsum"_21/>
Remove all of the unneeded stuff
There are a bunch of properties that are completely optional in the copied JSX, or ones which just state the default
value of that property anyway. Those can be freely removed.
In the case of our TeaserCard
, we drop ratio
and some of the link
options!
_10<TeaserBox_10 image="https://picsum.photos/seed/kdsteaserbox/500/300"_10 link={{_10 href: 'https://example.com',_10 label: 'learn more',_10 }}_10 text="Lorem ipsum dolor sit amet, consectetur adipisicing elit. Lorem ispum dolor distinctio minima unde voluptatum aut. Lorem ipsum dolor sit amet."_10 topic="Lorem Ipsum"_10/>
Hard-code static, required properties
We add Read more as the static text for the link included with our TeaserCard
.
_10<TeaserBox_10 image="https://picsum.photos/seed/kdsteaserbox/500/300"_10 link={{_10 href: 'https://example.com',_10 label: 'Read more',_10 }}_10 text="Lorem ipsum dolor sit amet, consectetur adipisicing elit. Lorem ispum dolor distinctio minima unde voluptatum aut. Lorem ipsum dolor sit amet."_10 topic="Lorem Ipsum"_10/>
Add some demo content
Now we just need to enter some "real" content, and we've successfully recreated what we set out to do in the start. At least for the markup part!
_10<TeaserBox_10 image="https://www.kickstartds.com/static/bdfbb12379bfec9128d8849c55f862a7/Blog-Post_design-system-initiative-1.png"_10 link={{_10 href: 'https://mydesignsystem.com/articles',_10 label: 'Read more',_10 }}_10 text="How our initiative workshop series helps customers to decide for or against building a design system."_10 topic="Design System Initiative"_10/>
Start with an existing TeaserBox
component variant
We'll start by copying the JSX
code for the Linked With Button
variant of our TeaserBox
component, from here:
https://www.kickstartds.com/storybook/?path=/docs/base-teaser-box--linked-with-button
Remove all of the unneeded stuff
There are a bunch of properties that are completely optional in the copied JSX, or ones which just state the default
value of that property anyway. Those can be freely removed.
In the case of our TeaserCard
, we drop ratio
and some of the link
options!
Hard-code static, required properties
We add Read more as the static text for the link included with our TeaserCard
.
Add some demo content
Now we just need to enter some "real" content, and we've successfully recreated what we set out to do in the start. At least for the markup part!
_21<TeaserBox_21 image="https://picsum.photos/seed/kdsteaserbox/500/300"_21 link={{_21 fillAnimation: false,_21 hidden: false,_21 href: 'https://example.com',_21 icon: {_21 icon: 'chevron-right',_21 },_21 iconAfter: true,_21 iconAnimation: false,_21 iconBefore: false,_21 label: 'learn more',_21 newTab: false,_21 size: 'medium',_21 variant: 'solid',_21 }}_21 ratio="16:9"_21 text="Lorem ipsum dolor sit amet, consectetur adipisicing elit. Lorem ispum dolor distinctio minima unde voluptatum aut. Lorem ipsum dolor sit amet."_21 topic="Lorem Ipsum"_21/>
With our small component API in place, and this rough sketch for the markup in mind, we can start actually implementing our component!
3. 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/teaser-card
, from our Design System repository root:
_10mkdir -p src/components/teaser-card
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.
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
and text
fields...
Both fields are straight-forward string
type properties, so we just document them a bit!
We do mark headline
and text
by setting format
to markdown
, though, to enable some light RTE-like formatting options of rendered text later on.
... and make both required
We declare headline
and text
as required on the uppermost object
!
Create target
and image
fields...
Both fields are also straight-forward string
type properties!
We do mark target
and image
by setting format
to uri
, this time enable URL-like behaviour for those fields.
... and make target
required
We add target
as required on the uppermost object
!
Add inverted
property
As the last property we add inverted
, as a boolean
.
Finished JSON Schema
Let's have a look at our completed JSON Schema definition.
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
and text
fields...
Both fields are straight-forward string
type properties, so we just document them a bit!
We do mark headline
and text
by setting format
to markdown
, though, to enable some light RTE-like formatting options of rendered text later on.
... and make both required
We declare headline
and text
as required on the uppermost object
!
Create target
and image
fields...
Both fields are also straight-forward string
type properties!
We do mark target
and image
by setting format
to uri
, this time enable URL-like behaviour for those fields.
... and make target
required
We add target
as required on the uppermost object
!
Add inverted
property
As the last property we add inverted
, as a boolean
.
Finished JSON Schema
Let's have a look at our completed JSON Schema definition.
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:
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.
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 TeaserCardProps.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'll just pass through everything HTMLAttributes
related!
Add TeaserCard
component 1/5
Now we'll import and add the kickstartDS TeaserBox
component. To start, we'll use the hard-coded properties of the Linked With Button TeaserBox
variant from our kickstartDS Design System.
Add TeaserCard
component 2/5
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 TeaserCard
component 3/5
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.
Add TeaserCard
component 4/5
We renamed topic
to headline
in our component API, so we add that in its renamed form.
Add TeaserCard
component 5/5
Finally we add our hard coded Read More to the link.label
, and connect target
to link.href
.
Add component Provider
We want our TeaserCard
to replace all default kickstartDS base TeaserBox
es, 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.
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 TeaserCardProps.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'll just pass through everything HTMLAttributes
related!
Add TeaserCard
component 1/5
Now we'll import and add the kickstartDS TeaserBox
component. To start, we'll use the hard-coded properties of the Linked With Button TeaserBox
variant from our kickstartDS Design System.
Add TeaserCard
component 2/5
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 TeaserCard
component 3/5
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.
Add TeaserCard
component 4/5
We renamed topic
to headline
in our component API, so we add that in its renamed form.
Add TeaserCard
component 5/5
Finally we add our hard coded Read More to the link.label
, and connect target
to link.href
.
Add component Provider
We want our TeaserCard
to replace all default kickstartDS base TeaserBox
es, 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.
To complete the template we add the TeaserBoxProvider
to our src/components/Providers.jsx
:
This concludes the creation of our new TeaserCard
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/teaser-card
folder:
Import TeaserCard
component
Import TeaserCard
component and add it to the Template
that we'll bind Stories to.
Import Storybook Controls helpers
Import dereferenced component JSON Schema and getArgsShared
helper to generate Storybook Controls, and parameterize Storybook JSON Schema Addon.
Import re-usable TeaserCard
Stories...
We import the existing TeaserCard
Story part of @kickstartDS/base
, to re-use all the default settings.
... and overwrite 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 TeaserCard
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.
If you reopen your Storybook now, or if you kept it running while following along, you should now see your new TeaserCard
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