Button Component
The Infima CSS framework provides a set of utility classes that can be used to style buttons in Docusaurus. This article will cover how to create a reusable button component for your Docusaurus site that can be customized with different colors and sizes.
Creating the Button component
We're going to start by creating a new component called Button
that will render a button element with the specified text, color, and size. The component will accept the following props:
label
: The text to display on the button.link
: The URL to navigate to when the button is clicked.variant
(optional): The color variant to apply to the button. This will be used to apply different colors to the button based on the Infima CSS utility classes. The default value isprimary
.size
(optional): The size variant to apply to the button. This will be used to apply different sizes to the button based on the Infima CSS utility classes. The default value isnull
(normal size).outline
(optional): A boolean value that determines whether the button should have an outline style. The default value isfalse
.block
(optional): A boolean value that determines whether the button should take up the full width of its container. The default value isfalse
.disabled
(optional): A boolean value that determines whether the button should be disabled. The default value isfalse
.
We're gonna start by creating the file and adding the source code for the component.
- JS
- TS
import React, { CSSProperties } from 'react';
import clsx from 'clsx';
import Link from '@docusaurus/Link';
// Build the Button component with the specified props
const Button = ({
size = null, // The size of the button (e.g., 'sm', 'lg', or null)
outline = false, // Whether the button should be an outline button
variant = 'primary', // The color variant of the button
block = false, // Whether the button should be a block-level button
disabled = false, // Whether the button should be disabled
className, // Custom classes for the button
style, // Custom styles for the button
link, // The URL the button should link to
label // The text of the button
}) => {
const sizeMap = {
sm: 'sm',
small: 'sm',
lg: 'lg',
large: 'lg',
medium: null,
};
const buttonSize = size ? sizeMap[size] : '';
const sizeClass = buttonSize ? `button--${buttonSize}` : '';
const outlineClass = outline ? 'button--outline' : '';
const variantClass = variant ? `button--${variant}` : '';
const blockClass = block ? 'button--block' : '';
const disabledClass = disabled ? 'disabled' : '';
// If the button is disabled, set the destination to null.
const destination = disabled ? null : link;
return (
<Link to={destination}>
<button
className={clsx('button', sizeClass, outlineClass, variantClass, blockClass, disabledClass, className)}
style={style}
role="button"
aria-disabled={disabled}
>
{label}
</button>
</Link>
);
};
export default Button;
import React, { ReactNode, CSSProperties } from 'react';
import clsx from 'clsx';
import Link from '@docusaurus/Link';
// Define the Button type to control the props that can be passed to the Button component.
type Button = {
// The size prop can be one of the following values: 'sm', 'lg', 'small', 'medium', 'large', or null.
// We'll convert 'small' to 'sm' and 'large' to 'lg' in the component. 'medium' will be considered null.
size?: 'sm' | 'lg' | 'small' | 'medium' | 'large' | null;
// The outline prop is a boolean that determines if the button should be an outline button.
outline?: boolean;
// The variant prop is a string that determines the color of the button.
// It can be one of the following values: 'primary', 'secondary', 'danger', 'warning', 'success', 'info', 'link', or any other string.
// The default value is 'primary'.
variant: 'primary' | 'secondary' | 'danger' | 'warning' | 'success' | 'info' | 'link' | string;
// The block prop is a boolean that determines if the button should be a block-level button.
block?: boolean;
// The disabled prop is a boolean that determines if the button should be disabled.
disabled?: boolean;
// The className prop is a string that allows you to add custom classes to the button.
className?: string;
// The style prop is an object that allows you to add custom styles to the button.
style?: CSSProperties;
// The link prop is a string that determines the URL the button should link to.
link: string;
// The label prop is a string that determines the text of the button.
label: string;
}
// Button component that accepts the specified props.
export default function Button ({
size = null,
outline = false,
variant = 'primary',
block = false,
disabled = false,
className,
style,
link,
label
}: Button) {
// Map the size prop values to corresponding CSS classes.
const sizeMap = {
sm: 'sm',
small: 'sm',
lg: 'lg',
large: 'lg',
medium: null,
};
const buttonSize = size ? sizeMap[size] : '';
const sizeClass = buttonSize ? `button--${buttonSize}` : '';
const outlineClass = outline ? 'button--outline' : '';
const variantClass = variant ? `button--${variant}` : '';
const blockClass = block ? 'button--block' : '';
const disabledClass = disabled ? 'disabled' : '';
// If the button is disabled, set the destination to null.
const destination = disabled ? null : link;
return (
<Link to={destination}>
<button
className={clsx(
'button',
sizeClass,
outlineClass,
variantClass,
blockClass,
disabledClass,
className
)}
style={style}
role='button'
aria-disabled={disabled}
>
{label}
</button>
</Link>
);
}
MDX Component Scope
To follow the Docusaurus documentation, we create a theme folder that will host the MDXComponents
file. This gives us src\theme\MDXComponents.*
. You may already have a src\theme
folder or an MDXComponents
file if so - merge the changes described here with yours.
- JS
- TS
import React from 'react';
// Importing the original mapper + our components according to the Docusaurus doc
import MDXComponents from '@theme-original/MDXComponents';
import Button from '@site/src/components/Button';
export default {
// Reusing the default mapping
...MDXComponents,
Button,
};
import React from 'react';
// Importing the original mapper + our components according to the Docusaurus doc
import MDXComponents from '@theme-original/MDXComponents';
import Button from '@site/src/components/Button';
export default {
// Reusing the default mapping
...MDXComponents,
Button,
};
Using the Button Component in an MDX File
Basic
<Button label="Click me" link="#using" />
Customized
<Button label="Click me" link="#using" variant="secondary" size="lg" outline />
Disabled
<Button label="Click me" link="#using" disabled />
Block
<Button label="Click me" link="#using" block />
Custom styles
<Button label="Click me" link="#using" style={{ backgroundColor: 'red', color: 'white', border: 'none', }} />
Combined
<Button label="Click me" link="#using" variant="danger" size="sm" outline block />
Conclusion
In this article, we created a reusable button component for your Docusaurus site that can be customized with different colors and sizes. By using the Infima CSS framework and utility classes, you can easily style buttons in your Docusaurus site without writing custom CSS. You can further extend the Button
component by adding more props and customizing the styles to fit your site's design.