Button

The Button component covers the sizes, colors and themes the library uses. Give it an href and it renders an anchor instead of a button.

About

Give it an href and it renders an <a>; leave it out and you get a <button>. The look comes from two axes, theme and color, with outline as a third option that overrides theme. Anything you pass in class is merged last, so your own styling wins.

Example

Import the Button component into your Svelte file. The following example shows how to use the button component!

Svelte
<script>
  import { Button } from "theui-svelte";
</script>

<Button>Button</Button>

Button Content

The Button component offers beforeLabel and afterLabel snippet blocks that let you add custom content before or after the button's label. This is useful for icons, badges, or other elements, giving you more control over the button's look and behavior. Although you can add elements manually with HTML and CSS, using these snippets keeps the structure cleaner and easier to maintain. It also simplifies layout and styling.

For better structure, flexibility, and consistency, beforeLabel and afterLabel are great options.

Example Using Snippets

Svelte
<Button>
  {#snippet beforeLabel()}
    <Svg size={1.5}>
      <path d="M8 8a3 3 0 ... />
    </Svg>
  {/snippet}

  Button Text

  {#snippet afterLabel()}
    <Svg size={1.5}>
      <path fill-rule="evenodd" d="M1 8a.5.5 0 0 ... />
    </Svg>
  {/snippet}
</Button>

Example Without Snippets

Svelte
<Button>
  <div class="CUSTOM CLASSES">
    <Svg size={1.5}>
      <path d="M8 8a3 3 0 ... />
    </Svg>

    Button Text

    <Svg size={1.5}>
      <path fill-rule="evenodd" d="M1 8a.5.5 0 0 ... />
    </Svg>
  </div>
</Button>

Button Color

The color prop lets you style the button using predefined themes like "brand", "error", "info", "success", and "warning". These match common statuses or actions to keep your app's design consistent. The default is "brand".

Svelte
<Button color="brand">Brand</Button>
<Button color="error">Error</Button>
<Button color="info">Info</Button>
<Button color="success">Success</Button>
<Button color="warning">Warning</Button>

Each color carries a meaning, so a reader can tell a destructive action from a safe one. You can still pass your own classes, but the color prop keeps the whole app on one palette.

Theme

The theme prop controls the button's overall style and background. It supports three values: 'default', 'soft', and 'gradient'. The default theme gives the standard button look, the soft theme uses softer colors, and the gradient theme adds a vibrant background with gradient styling.

Soft Theme

The soft theme is a softer variation of the default button colors, making it suitable for more subtle designs.

Svelte
<Button theme="soft" color="brand">Brand</Button>
<Button theme="soft" color="error">Error</Button>
<Button theme="soft" color="info">Info</Button>
<Button theme="soft" color="success">Success</Button>
<Button theme="soft" color="warning">Warning</Button>

Gradient Theme

The gradient theme fills the button background with a two color gradient.

Svelte
<Button theme="gradient" gradientColor="brand">Brand</Button>
<Button theme="gradient" gradientColor="error">Error</Button>
<Button theme="gradient" gradientColor="info">Info</Button>
<Button theme="gradient" gradientColor="success">Success</Button>
<Button theme="gradient" gradientColor="warning">Warning</Button>

Outline

The outline prop lets you create a button with a modern outline style. It gives the button a transparent background and a border, making it great for secondary actions or a minimalist look.

To use an outline button, set the outline prop to true like this: outline={true}

Svelte
<Button color="brand" outline={true}>Brand</Button>
<Button color="error" outline={true}>Error</Button>
<Button color="info" outline={true}>Info</Button>
<Button color="success" outline={true}>Success</Button>
<Button color="warning" outline={true}>Warning</Button>

Size

The size prop sets the padding and the font size of the button. It takes one of the preset values below.

Available values are "xs", "sm", "md" (default), "lg", "xl", and "auto", allowing flexibility while maintaining consistency.

Svelte
<Button size="xs">Extra small</Button>
<Button size="sm">Small</Button>
<Button size="md">Medium</Button>
<Button size="lg">Large</Button>
<Button size="xl">Extra large</Button>
<Button size="auto">Auto</Button>

Each size option adjusts the button's padding and font size, providing a cohesive look across different screen sizes and use cases. The auto size adapts to the content, has no padding, making it flexible for various layouts.

Square Button

The square prop makes the button's height and width equal, which is what you want for an icon button.

Svelte
<Button square={true}>m</Button>

You can combine the square prop with the size prop to create square buttons of varying dimensions. This flexibility lets you choose the appropriate size for different UI elements while maintaining the square shape.

Svelte
<Button square={true} size="xs"> ... </Button>
<Button square={true} size="sm"> ... </Button>
<Button square={true} size="md"> ... </Button>
<Button square={true} size="lg"> ... </Button>
<Button square={true} size="xl"> ... </Button>

Square buttons follow the same size scale, so an icon button lines up with the text buttons beside it.

Rounded Corner Button

The rounded prop sets the corner radius of the button. Available values are: none, sm, md, lg, xl, 2xl, and full. Default value md.

Svelte
<Button rounded="none">None</Button>
<Button rounded="sm">Small</Button>
<Button rounded="md">Medium</Button>
<Button rounded="lg">Large</Button>
<Button rounded="xl">Extra large</Button>
<Button rounded="full">Full</Button>

Button Shadow

The shadow prop controls the button's shadow. Available values are "none", "xs", "sm", "md" (default), "lg", "xl", "2xl" and "inner". Buttons inside a ButtonGroup don't use it.

Svelte
<Button shadow="none">No shadow</Button>
<Button shadow="sm">Small</Button>
<Button shadow="lg">Large</Button>
<Button shadow="2xl">2xl</Button>

Button Animation Speed

The animationSpeed determines the speed of the button's animation, with options including "none", "slower", "slow", "normal", "fast", and "faster".

Svelte
<Button animationSpeed="slower">Slower animation</Button>
<Button animationSpeed="slow">Slow animation</Button>
<Button animationSpeed="normal">Normal animation</Button>
<Button animationSpeed="fast">Fast animation</Button>
<Button animationSpeed="faster">Faster animation</Button>
<Button animationSpeed="none">No Animation animation</Button>

Each value sets a different transition duration.

Loading State

Set the loading prop to true to show a spinner in the button, for example while a form is being submitted. While loading, the button can't be clicked. The loadingText prop sets the text shown after the button label; the default is "Loading...". Set it to an empty string to show only the spinner.

Svelte
<script>
  let saving = $state(false);
</script>

<Button loading={saving} onclick={() => saving = true}>Save</Button>

<!-- Spinner only -->
<Button loading={true} loadingText="">Save</Button>

Active State

Use the isActive prop to show a button in its pressed style, for example the selected option in a group of buttons or a toggle that is on. The default is false. On a button (not a link), isActive also sets aria-pressed="true" so screen readers announce it as pressed.

Svelte
<Button>Inactive</Button>
<Button isActive={true}>Active</Button>
<Button outline={true} isActive={true}>Active outline</Button>

Disabled Button

Add the disabled attribute to disable a button. A disabled button is dimmed, can't be clicked and gets aria-disabled="true". On a link button, the link is also removed, so it can't be opened with the mouse or the keyboard.

Disabled link
Svelte
<Button disabled>Disabled button</Button>
<Button href="/" disabled>Disabled link</Button>

Actions

The actions prop lets you apply Svelte actions to the button element. Pass an array of [action, params] pairs; params is optional. Each action runs when the button is mounted, and its destroy function runs when the button is removed.

Svelte
<script>
  const tooltip = (node, text) => {
    node.title = text;
    return { destroy: () => node.removeAttribute("title") };
  };
</script>

<Button actions={[[tooltip, "Save your changes"]]}>Save</Button>

Accessibility

The Button carries the ARIA attributes it needs and answers to the keyboard out of the box.

  1. Keyboard Navigation: Use tab to navigate between buttons, and Enter or Space to activate a button.
  2. ARIA Attributes: By default, screen readers use the button's visible text as its name. The ariaLabel prop sets aria-label, which replaces that text, so use it when the button's text or icon alone may not be clear (e.g., icon-only buttons).
    Svelte
    <Button square={true} ariaLabel="Open profile">
      <Svg>...</Svg>
    </Button>
    A disabled button gets aria-disabled="true", and an active button (isActive) gets aria-pressed="true".
  3. Focus Management: focus styles use focus-visible or focus-within, so the ring shows for keyboard users without appearing on every mouse click.
  4. State Indications: Visual cues (hover, focus, active, and disabled states) are provided to communicate the button's interactive state clearly.

Configuration