Extending Genesis components
This approach to styling requires writing components using Genesis syntax.
Genesis components are designed to be extensible, enabling you to create custom components with configurable styles and functionality.
In this example, we’ll create a MyButton
component by extending the RapidButton
component from the Rapid Design System.
You can do this in five steps.
Step 1: Import the dependencies
RapidButton
for the base button componentbuttonTemplate
for reusing the existing button templatebuttonShadowOptions
for the button's Shadow DOM configuration- a separate custom styles file,
my-button.styles.ts
import {
Button as RapidButton,
buttonTemplate as template, // Importing RapidButton's template
buttonShadowOptions as rapidButtonShadowOptions,
} from '@genesislcap/rapid-design-system';
import { myButtonStyles as styles } from './my-button.styles';
Step 2: Extend RapidButton
Create a new MyButton
class that extends RapidButton.
This enables you to inherit the functionality of the base button while applying your custom styles and configurations.
/**
* MyButton component, extending RapidButton with custom styles.
*/
export class MyButton extends RapidButton {}
Step 3: Compose the component
The compose method enables you to combine the base button's template, custom styles, and shadow options into a new reusable component.
/**
* Composing MyButton with custom styles while reusing the RapidButton template.
*/
export const myButton = MyButton.compose({
baseName: 'my-button', // Base name for the component
template, // Reusing the RapidButton template
styles, // Your custom styles for MyButton
shadowOptions: rapidButtonShadowOptions, // Shadow DOM configuration
});
Step 4: Define custom styles
Create a my-button.styles.ts
file to define the custom styles for MyButton
. Use CSS custom properties and design tokens for consistency. This simple definition specifies colour, font, border and padding (which sets the space around the button).
import { css } from '@genesislcap/web-core';
export const myButtonStyles = css`
:host {
background-color: lightgray;
color: black;
padding: 10px 20px;
border-radius: 4px;
font-family: Arial, sans-serif;
font-size: 14px;
}
`;
Step 5: Register the component
Finally, in the .ts
file where you register your components, add the MyButton
component`:
import * as rapidDesignSystem from '@genesislcap/rapid-design-system';
import { myButton } from './my-button';
rapidDesignSystem.provideDesignSystem()
.register(
myButton(),
rapidDesignSystem.baseComponents,
);
A common error when registering your customized components is registering them after the base component has already been registered - meaning your change will not be visible.
In the code above, note that myButton()
is registered before rapidDesignSystem.baseComponents
. This ensures that the component with the custom styling you've created takes priority over the base implementation.
A complete example
import {
Button as RapidButton,
buttonTemplate as template,
buttonShadowOptions as rapidButtonShadowOptions,
} from '@genesislcap/rapid-design-system';
import { myButtonStyles as styles } from './my-button.styles';
/**
* MyButton component, extending RapidButton with custom styles.
*/
export class MyButton extends RapidButton {}
/**
* Composing MyButton with custom styles while reusing the RapidButton template.
*/
export const myButton = MyButton.compose({
baseName: 'my-button',
template,
styles,
shadowOptions: rapidButtonShadowOptions,
});
my-button.styles.js
import { css } from '@genesislcap/web-core';
export const myButtonStyles = css`
:host {
background-color: lightgray;
color: black;
padding: 10px 20px;
border-radius: 4px;
font-family: Arial, sans-serif;
font-size: 14px;
}
`;
Registering the component
import * as rapidDesignSystem from '@genesislcap/rapid-design-system';
import { myButton } from './my-button';
rapidDesignSystem.provideDesignSystem()
.register(
myButton(),
rapidDesignSystem.baseComponents,
);