Overview
The BaseButton component is the foundation of Popui’s button system. It provides a comprehensive set of variants, sizes, and configuration options for building interactive user interfaces.
Import
import { BaseButton } from '@invopop/popui'
Props
variant
ButtonVariant
default:"outline"
The visual style variant of the button. Available options:
primary - Accent background with inverse text
secondary - Tertiary background with default text
danger - Critical styling for destructive actions
warning - Warning background for caution actions
outline - Border with transparent background
ghost - No border, transparent background
selected - Selected state styling
dark - Dark theme variant
dark-ghost - Dark theme ghost variant
size
'sm' | 'md' | 'lg'
default:"md"
The size of the button:
sm - Height 24px (6)
md - Height 28px (7)
lg - Height 32px (8)
Icon to display in the button. Uses @steeze-ui/svelte-icon format. When used alone (without children), the button becomes icon-only.
iconTheme
'default' | 'solid' | 'mini'
default:"default"
The icon theme variant to use.
iconPosition
'left' | 'right'
default:"left"
Position of the icon relative to the text content.
type
'button' | 'submit' | 'reset'
default:"button"
HTML button type attribute.
Whether the button is disabled. Disabled buttons have reduced opacity (30%) and no pointer events.
Applies critical icon styling (text-icon-critical) to the icon.
Wraps the icon in a shortcut wrapper component.
Makes the button take up the full width of its container (w-full).
Adds notification indicator styling to the button.
Removes left border radius for stacking buttons horizontally.
Removes right border radius for stacking buttons horizontally.
onclick
(event: MouseEvent) => void
Click event handler.
Additional CSS classes to apply to the button.
Variants
Primary
Secondary
Danger
Warning
Outline
Ghost
Selected
Primary buttons are used for the main action on a page. They have an accent background with inverse text.<BaseButton variant="primary">
Save Changes
</BaseButton>
Source reference: /home/daytona/workspace/source/svelte/src/lib/button/button.svelte:11-12 Secondary buttons are used for less prominent actions. They have a tertiary background.<BaseButton variant="secondary">
Cancel
</BaseButton>
Source reference: /home/daytona/workspace/source/svelte/src/lib/button/button.svelte:21-22 Danger buttons are used for destructive actions like deleting. They have critical styling with hover effects.<BaseButton variant="danger">
Delete Account
</BaseButton>
Source reference: /home/daytona/workspace/source/svelte/src/lib/button/button.svelte:15-16 Warning buttons are used for actions that require caution.<BaseButton variant="warning">
Proceed with Caution
</BaseButton>
Source reference: /home/daytona/workspace/source/svelte/src/lib/button/button.svelte:13-14 Outline buttons have a border with transparent background. This is the default variant.<BaseButton variant="outline">
View Details
</BaseButton>
Source reference: /home/daytona/workspace/source/svelte/src/lib/button/button.svelte:17-18 Ghost buttons have no border and a transparent background. They show background on hover.<BaseButton variant="ghost">
Learn More
</BaseButton>
Source reference: /home/daytona/workspace/source/svelte/src/lib/button/button.svelte:19-20 Selected buttons indicate an active or selected state.<BaseButton variant="selected">
Active Tab
</BaseButton>
Source reference: /home/daytona/workspace/source/svelte/src/lib/button/button.svelte:23-24
Icon Support
Icon with Text
Buttons can include icons alongside text. By default, icons appear on the left.
<script>
import { Plus } from '@invopop/ui-icons'
</script>
<BaseButton icon={Plus} variant="primary">
Add Item
</BaseButton>
Icon Position
Control icon placement with the iconPosition prop:
<script>
import { ChevronRight } from '@invopop/ui-icons'
</script>
<BaseButton icon={ChevronRight} iconPosition="right" variant="outline">
Next
</BaseButton>
Source reference: /home/daytona/workspace/source/svelte/src/lib/button/button.svelte:211-214
When no children are provided, the button automatically becomes icon-only with appropriate sizing:
<script>
import { Search } from '@invopop/ui-icons'
</script>
<BaseButton icon={Search} variant="ghost" />
Source reference: /home/daytona/workspace/source/svelte/src/lib/button/button.svelte:200-201
Danger Icon
Apply critical styling to icons for destructive actions:
<script>
import { Trash } from '@invopop/ui-icons'
</script>
<BaseButton icon={Trash} dangerIcon variant="secondary">
Delete
</BaseButton>
Source reference: /home/daytona/workspace/source/svelte/src/lib/BaseButton.svelte:25
Sizes
<BaseButton size="sm" variant="primary">
Small Button
</BaseButton>
Height: 24px (h-6)<BaseButton size="md" variant="primary">
Medium Button
</BaseButton>
Height: 28px (h-7) - Default size<BaseButton size="lg" variant="primary">
Large Button
</BaseButton>
Height: 32px (h-8)
Source reference: /home/daytona/workspace/source/svelte/src/lib/button/button.svelte:29-33
States
Disabled State
Disabled buttons have reduced opacity and no pointer interaction:
<BaseButton disabled variant="primary">
Disabled Button
</BaseButton>
Source reference: /home/daytona/workspace/source/svelte/src/lib/button/button.svelte:8
Full Width
Make buttons span the full width of their container:
<BaseButton fullwidth variant="primary">
Full Width Button
</BaseButton>
Source reference: /home/daytona/workspace/source/svelte/src/lib/BaseButton.svelte:26
Create button groups by removing border radius on adjacent sides:
<div class="flex">
<BaseButton stackedRight variant="outline">
Left
</BaseButton>
<BaseButton stackedLeft stackedRight variant="outline">
Middle
</BaseButton>
<BaseButton stackedLeft variant="outline">
Right
</BaseButton>
</div>
Source reference: /home/daytona/workspace/source/svelte/src/lib/button/button.svelte:142-150
Event Handlers
Click Handler
<script>
let count = $state(0)
function handleClick() {
count++
}
</script>
<BaseButton onclick={handleClick} variant="primary">
Clicked {count} times
</BaseButton>
Source reference: /home/daytona/workspace/source/svelte/src/lib/types.ts:224
Advanced Examples
<form onsubmit={handleSubmit}>
<input type="text" name="email" />
<BaseButton type="submit" variant="primary">
Subscribe
</BaseButton>
</form>
<BaseButton
variant="primary"
class="shadow-lg hover:shadow-xl"
>
Custom Styled
</BaseButton>
Loading State with Disabled
<script>
let isLoading = $state(false)
async function handleSave() {
isLoading = true
await saveData()
isLoading = false
}
</script>
<BaseButton
onclick={handleSave}
disabled={isLoading}
variant="primary"
>
{isLoading ? 'Saving...' : 'Save'}
</BaseButton>
Accessibility
- Disabled buttons set
pointer-events-none and reduce opacity to 30%
- Focus visible states use ring styling for keyboard navigation
- Button type defaults to
"button" to prevent unintended form submissions
- All interactive elements maintain minimum touch target sizes
Type Definitions
The component uses TypeScript interfaces defined in types.ts:208-225:
export interface BaseButtonProps {
icon?: IconSource;
iconTheme?: IconTheme;
iconPosition?: IconPosition;
type?: 'button' | 'submit' | 'reset' | null;
variant?: ButtonVariant;
disabled?: boolean;
size?: 'sm' | 'md' | 'lg';
dangerIcon?: boolean;
shortcut?: boolean;
fullwidth?: boolean;
notification?: boolean;
stackedLeft?: boolean;
stackedRight?: boolean;
children?: Snippet;
onclick?: (event: MouseEvent) => void;
}