Primitives

Button

The template every presentational component copies. Eight variants, three sizes, an optional icon and a loading state — all of it selected by data attributes, none of it by class names.

data-scope="button"

Usage

import { Button } from "@crosskit-ui/react";
import "@crosskit-ui/styles";

<Button variant="primary" icon="check" onClick={save}>
  Save changes
</Button>
<script setup lang="ts">
import { Button } from "@crosskit-ui/vue";
import "@crosskit-ui/styles";
</script>

<template>
  <Button variant="primary" icon="check" @click="save">Save changes</Button>
</template>
<script lang="ts">
  import { Button } from "@crosskit-ui/svelte";
  import "@crosskit-ui/styles";
</script>

<Button variant="primary" icon="check" onclick={save}>Save changes</Button>
import { CkButton } from "@crosskit-ui/angular";

@Component({
  imports: [CkButton],
  template: `
    <button ckButton variant="primary" icon="check" (click)="save()">
      Save changes
    </button>
  `,
})
export class SaveComponent {}

Props

PropTypeDefaultNotes
variant"primary" | "secondary" | "outline" | "ghost" | "success" | "error" | "warning" | "info""primary"Visual style. Lands on the root as data-variant.
size"sm" | "md" | "lg""md"Control size.
iconIconNameIcon rendered before the label.
iconPosition"start" | "end""start"Which side the icon sits on.
loadingbooleanfalseSwaps the icon for a spinner and disables interaction.
fullWidthbooleanfalseStretches to 100%.
type"button" | "submit" | "reset""button"Defaults to button. v0 set none at all, so a Button inside a form silently submitted it.

Prop names are identical in all four frameworks. Only two-way binding differs, and each framework uses its own idiom over the same underlying prop.

Migrating from react-ui-toolkit

v0v1Notes
no default typetype="button"A Button inside a form used to submit it. Pass type="submit" if you want the old behaviour.