Button Component
This Button component is a versatile tool that lets you easily create buttons with consistent styling across your Astro project. By adjusting the props, you can tailor each button to suit your specific design needs.
Creating and using the Button Astro component
1. Component Overview
The Button component is a reusable UI component built in Astro. It allows you to create buttons with various sizes, themes, and styles. This component is highly customizable, supporting different button types, themes, sizes, and other stylistic options like filled backgrounds and rounded corners.
2. Creating the ‘Button’ Component
Step 1:Define the Component Props
In Astro, we can define a component’s properties (props) to make it flexible and reusable. The Button component accepts the following props:
---
import type { HTMLAttributes } from 'astro/types';
interface Props extends HTMLAttributes<'button'> {
type?: 'button' | 'submit'; // Specifies the button type, default is 'button'
size?: 'sm' | 'md' | 'lg'; // Specifies the button size
isfilled?: boolean; // Determines if the button should be filled
isrounded?: boolean; // Determines if the button should have rounded corners
theme?: // Specifies the button theme (color)
| 'primary'
| 'secondary'
| 'success'
| 'danger'
| 'warning'
| 'info'
| 'light'
| 'dark';
classes?: string; // Additional classes for custom styling
}
---
Step 2: Define Default Prop Values
Set default values for the props to make the component easier to use without always specifying all the props:
---
const {
type = 'button', // Default button type is 'button'
size = 'md', // Default size is 'md'
isfilled,
isrounded,
theme = 'light', // Default theme is 'light'
classes,
...rest
} = Astro.props;
---
Step 3: Define Background and Foreground Colors
The background and foreground colors are set based on the selected theme:
---
const background = `var(--${theme})`;
const foreground = theme === 'light' ? 'var(--primary)' : 'var(--light)';
---
Step 4: Create the Button HTML Structure
The button element uses the defined props and spreads any additional props passed to it:
<button
class:list={[classes, { filled: isfilled }, { rounded: isrounded }]}
{type}
data-size={size}
{...rest}
>
<slot />
</button>
Step 5: Define Button Styles
The styles are added within a <style> block, utilizing CSS custom properties for easy theming:
<style
define:vars={{
foreground,
background,
}}
>
*,
*::after,
*::before {
box-sizing: border-box;
}
.cool {
background-color: yellow;
}
button {
/* resets */
font: inherit;
cursor: pointer;
/* variables */
--bkg: var(--background);
--color: var(--foreground);
/* default styles */
display: flex;
gap: 0.2em;
align-items: center;
background-color: var(--light);
color: var(--bkg);
border: 0.2em solid var(--bkg);
padding: 0.2em 1.25em;
transition:
box-shadow 0.2s cubic-bezier(0.075, 0.82, 0.165, 1),
opacity 0.2s cubic-bezier(0.075, 0.82, 0.165, 1),
scale 0.2s cubic-bezier(0.075, 0.82, 0.165, 1);
}
button.filled {
background-color: var(--bkg);
color: var(--color);
border: none;
}
button.rounded {
border-radius: 1em;
}
button:focus {
outline-color: transparent;
}
button:hover {
opacity: 0.8;
scale: 1.05;
}
button:focus-visible {
box-shadow:
0 0 0 0.1em var(--light),
0 0 0 0.3em var(--bkg);
}
[data-size='sm'] {
font-size: 0.8rem;
}
[data-size='md'] {
font-size: 1.1rem;
}
[data-size='lg'] {
font-size: 1.5rem;
}
</style>
3. Using the Button Component
Once the Button component is created, you can use it within your Astro pages or other components. Here are some examples:
---
import Button from '/src/components/Button.astro'
---
<Button theme="success" size="lg" isfilled isrounded>Button</Button>
<Button theme="secondary">Button</Button>
<Button isfilled theme="dark" isrounded size="lg">Button</Button>
<Button isfilled theme="light" isrounded size="lg">Button</Button>
<Button isfilled theme="info" isrounded size="lg">Button</Button>
<Button isfilled theme="warning" isrounded size="lg">Button</Button>
<Button isfilled theme="danger" isrounded size="lg">Button</Button>
<Button isfilled theme="primary" isrounded size="lg">Button</Button>