Skip to content
CodeAtlas UI

Inputs

Button

Trigger actions with five visual variants, three sizes, leading and trailing icons, and a loading state.

<script>
  import { Button } from "@codeatlasdev/ui";
</script>

<Button variant="filled" onclick={save}>Save</Button>

On touch devices every size grows to a 44px target and presses scale down slightly, like a native control.

Variants

filled, glass, outlined, ghost and destructive.

Code
svelte
<script lang="ts">
  import { Button } from '@codeatlasdev/ui';
</script>

<Button variant="filled">Filled</Button>
<Button variant="glass">Glass</Button>
<Button variant="outlined">Outlined</Button>
<Button variant="ghost">Ghost</Button>
<Button variant="destructive">Destructive</Button>

Sizes

Code
svelte
<script lang="ts">
  import { Button } from '@codeatlasdev/ui';
</script>

<Button size="sm">Small</Button>
<Button size="md">Medium</Button>
<Button size="lg">Large</Button>

With icons

Leading and trailing snippets.

Code
svelte
<script lang="ts">
  import { Button } from '@codeatlasdev/ui';
  import { ArrowRight, Download, Star } from '@lucide/svelte';
</script>

<Button variant="filled">
  {#snippet leading()}<Star size={15} />{/snippet}
  Starred
</Button>
<Button variant="outlined">
  Continue
  {#snippet trailing()}<ArrowRight size={15} />{/snippet}
</Button>
<Button variant="ghost">
  {#snippet leading()}<Download size={15} />{/snippet}
  Download
</Button>

Loading

Swaps the leading icon for a spinner, sets aria-busy and blocks clicks while keeping the label.

Code
svelte
<script lang="ts">
  import { Button } from '@codeatlasdev/ui';

  let saving = $state(false);

  function save() {
    saving = true;
    setTimeout(() => (saving = false), 2000);
  }
</script>

<Button variant="filled" loading>Saving</Button>
<Button variant="outlined" loading>Outlined</Button>
<Button variant="filled" loading={saving} onclick={save}>
  {saving ? 'Saving…' : 'Save (2s)'}
</Button>

States

Disabled buttons, a destructive action and a link rendered as a button.

Link button
Code
svelte
<script lang="ts">
  import { Button } from '@codeatlasdev/ui';
  import { Trash2 } from '@lucide/svelte';
</script>

<Button variant="filled" disabled>Filled</Button>
<Button variant="outlined" disabled>Outlined</Button>
<Button variant="glass" disabled>Glass</Button>
<Button variant="destructive">
  {#snippet leading()}<Trash2 size={15} stroke-width={2} />{/snippet}
  Delete account
</Button>
<Button variant="outlined" href="https://github.com/codeatlasdev/ui" target="_blank">Link button</Button>

Full width

fullWidth stretches the button to its container.

Code
svelte
<script lang="ts">
  import { Button } from '@codeatlasdev/ui';
</script>

<div class="col">
  <Button fullWidth>Continue</Button>
  <Button fullWidth variant="outlined">Cancel</Button>
</div>

<style>
  .col {
    display: flex;
    flex-direction: column;
    gap: var(--ca-space-2);
    width: 100%;
    max-width: 320px;
  }
</style>

Props

PropTypeDefaultDescription
variant'filled' | 'glass' | 'outlined' | 'ghost' | 'destructive''filled'Visual style.
size'sm' | 'md' | 'lg''md'Height, padding and font size.
disabledbooleanfalsePrevents interaction.
loadingbooleanfalseShows a spinner, sets aria-busy and disables the button. Adds ca-btn--loading.
type'button' | 'submit' | 'reset''button'HTML button type.
fullWidthbooleanfalseStretches the button to the width of its container.
hrefstring–Renders an anchor styled as a button.
targetstring–Anchor target, used with href.
leadingSnippet–Content before the label. Replaced by a spinner while loading.
trailingSnippet–Content after the label.
onclick(e: MouseEvent) => void–Click handler. Not called while disabled or loading.
aria-labelstring–Accessible name for icon-only buttons.
classstring–Extra classes on the root element.