Button component for interface actions. Renders as a regular link when href is provided. Buttons should primarily be used to trigger events or actions.
import { Button, Stack } from "@kesko/components";
import { IconBasketAddTo, IconExternalLink } from "@kesko/iconography/react";
export default () => (
<Stack direction="row" gap="2xs" align="center" wrap>
<Button variant="primary">
<IconBasketAddTo /> Primary
</Button>
<Button variant="primary" iconOnly>
<IconBasketAddTo label="Add to basket" />
</Button>
<Button>
Default <IconExternalLink />
</Button>
<Button disabled>Disabled</Button>
<Button variant="plain">Plain</Button>
<Button variant="text">Text</Button>
</Stack>
);<k-stack direction="row" gap="2xs" align="center" wrap>
<button class="k-button" variant="primary">
<svg viewBox="0 0 24 24" aria-hidden="true" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M17.5 14.748a.75.75 0 0 1 .75.75v2.25h2.25a.75.75 0 0 1 0 1.5h-2.25v2.25a.75.75 0 0 1-1.5 0v-2.25H14.5a.75.75 0 0 1 0-1.5h2.25v-2.25a.75.75 0 0 1 .75-.75zM12 2.25a5.252 5.252 0 0 1 5.251 5.252v.746a.756.756 0 0 1-.012.136.75.75 0 0 1-.739.883L2.961 9.25 5.54 19.559a.25.25 0 0 0 .242.19h7.407a.75.75 0 0 1 0 1.5H5.78a1.75 1.75 0 0 1-1.698-1.326L1.273 8.68A.75.75 0 0 1 2 7.748l4.749.006v-.256A5.248 5.248 0 0 1 12 2.25zm7.006 5.498l3 .02a.75.75 0 0 1 .723.932l-1.625 6.487a.75.75 0 0 1-1.455-.364l1.393-5.562-2.045-.013a.75.75 0 1 1 .01-1.5zM12 3.75a3.749 3.749 0 0 0-3.75 3.748v.258l7.5.01v-.264A3.752 3.752 0 0 0 12 3.75z" fill="currentColor" /></svg>
Primary
</button>
<button class="k-button" variant="primary" icon-only>
<svg role="img" aria-label="Add to basket" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M17.5 14.748a.75.75 0 0 1 .75.75v2.25h2.25a.75.75 0 0 1 0 1.5h-2.25v2.25a.75.75 0 0 1-1.5 0v-2.25H14.5a.75.75 0 0 1 0-1.5h2.25v-2.25a.75.75 0 0 1 .75-.75zM12 2.25a5.252 5.252 0 0 1 5.251 5.252v.746a.756.756 0 0 1-.012.136.75.75 0 0 1-.739.883L2.961 9.25 5.54 19.559a.25.25 0 0 0 .242.19h7.407a.75.75 0 0 1 0 1.5H5.78a1.75 1.75 0 0 1-1.698-1.326L1.273 8.68A.75.75 0 0 1 2 7.748l4.749.006v-.256A5.248 5.248 0 0 1 12 2.25zm7.006 5.498l3 .02a.75.75 0 0 1 .723.932l-1.625 6.487a.75.75 0 0 1-1.455-.364l1.393-5.562-2.045-.013a.75.75 0 1 1 .01-1.5zM12 3.75a3.749 3.749 0 0 0-3.75 3.748v.258l7.5.01v-.264A3.752 3.752 0 0 0 12 3.75z" fill="currentColor" /></svg>
</button>
<button class="k-button">
Default
<svg viewBox="0 0 24 24" aria-hidden="true" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.5 5.75a.75.75 0 0 1 0 1.5H3.25v11.5h17.5V11.5a.75.75 0 0 1 1.5 0v8a.75.75 0 0 1-.75.75h-19a.75.75 0 0 1-.75-.75v-13a.75.75 0 0 1 .75-.75h8zm7.47-2.78a.75.75 0 0 1 1.06 0l3 3a.75.75 0 0 1 0 1.06l-3 3a.75.75 0 1 1-1.06-1.06l1.719-1.72H18.5a5.75 5.75 0 0 0-5.746 5.53l-.004.22a.75.75 0 0 1-1.5 0 7.25 7.25 0 0 1 7.25-7.25h1.189l-1.72-1.72a.75.75 0 0 1-.072-.976l.073-.084z" fill="currentColor"></path></svg>
</button>
<button class="k-button" disabled>Disabled</button>
<button class="k-button" variant="plain">Plain</button>
<button class="k-button" variant="text">Text</button>
</k-stack>import { Button, Stack } from "@kesko/components";
import { IconExternalLink, IconDownload } from "@kesko/iconography/react";
export default () => (
<Stack direction="row" gap="2xs">
<Button href="https://kesko.design" variant="primary" target="_blank">
Visit website <IconExternalLink />
</Button>
<Button href="/file.pdf" download>
Download PDF <IconDownload />
</Button>
</Stack>
);<k-stack direction="row" gap="2xs">
<a class="k-button" variant="primary" href="https://kesko.design" target="_blank">
Visit website <svg viewBox="0 0 24 24" aria-hidden="true" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.5 5.75a.75.75 0 0 1 0 1.5H3.25v11.5h17.5V11.5a.75.75 0 0 1 1.5 0v8a.75.75 0 0 1-.75.75h-19a.75.75 0 0 1-.75-.75v-13a.75.75 0 0 1 .75-.75h8zm7.47-2.78a.75.75 0 0 1 1.06 0l3 3a.75.75 0 0 1 0 1.06l-3 3a.75.75 0 1 1-1.06-1.06l1.719-1.72H18.5a5.75 5.75 0 0 0-5.746 5.53l-.004.22a.75.75 0 0 1-1.5 0 7.25 7.25 0 0 1 7.25-7.25h1.189l-1.72-1.72a.75.75 0 0 1-.072-.976l.073-.084z" fill="currentColor" /></svg>
</a>
<a class="k-button" href="/file.pdf" download>
Download PDF <svg viewBox="0 0 24 24" aria-hidden="true" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M15 3.75a5.75 5.75 0 0 1 5.75 5.699A5.75 5.75 0 0 1 18 20.25h-4.5a.75.75 0 0 1 0-1.5H18a4.25 4.25 0 0 0 1.686-8.153.75.75 0 0 1-.45-.749 4.25 4.25 0 0 0-7.92-2.469.75.75 0 0 1-1.067.25A2.25 2.25 0 0 0 6.75 9.5a.75.75 0 0 1-.749.749 4.25 4.25 0 0 0 0 8.5h4.5a.75.75 0 0 1 0 1.5H6a5.75 5.75 0 0 1-.683-11.46 3.751 3.751 0 0 1 5.1-2.763A5.744 5.744 0 0 1 15 3.75zm-3 6a.75.75 0 0 1 .75.75v4.19l1.22-1.22a.75.75 0 1 1 1.06 1.06l-2.5 2.5-.008.009a.814.814 0 0 1-.046.041l.054-.05a.791.791 0 0 1-.084.073c-.25.192-.608.24-.914-.016a.778.778 0 0 1-.088-.081L8.97 14.53c-.707-.707.353-1.767 1.06-1.06l1.22 1.219V10.5a.75.75 0 0 1 .75-.75z" fill="currentColor" /></svg>
</a>
</k-stack>import type { CSSProperties } from "react";
import { Button, Stack } from "@kesko/components";
export default () => (
<Stack direction="row" gap="2xs" align="center">
<Button
variant="primary"
style={
{
"--k-button-bg": "var(--k-color-status-error)",
"--k-button-text": "var(--k-color-text-on-error)",
"--k-button-border": "var(--k-color-status-error)",
} as CSSProperties
}
>
Delete account
</Button>
<Button
variant="primary"
style={
{
"--k-button-bg": "var(--k-color-status-success)",
"--k-button-text": "var(--k-color-text-on-success)",
"--k-button-border": "var(--k-color-status-success)",
} as CSSProperties
}
>
Confirm order
</Button>
</Stack>
);<k-stack direction="row" gap="2xs" align="center">
<button class="k-button" variant="primary" style="--k-button-bg: var(--k-color-status-error); --k-button-text: var(--k-color-text-on-error); --k-button-border: var(--k-color-status-error);">
Delete account
</button>
<button class="k-button" variant="primary" style="--k-button-bg: var(--k-color-status-success); --k-button-text: var(--k-color-text-on-success); --k-button-border: var(--k-color-status-success);">
Confirm order
</button>
</k-stack>import { Button } from "@kesko/components";
export default () => (
<Button variant="primary" onClick={() => alert("Clicked!")}>
Click me
</Button>
);<button class="k-button" variant="primary" onclick="alert('Clicked!')">
Click me
</button>import { Button, Stack } from "@kesko/components";
import { IconArrowUp } from "@kesko/iconography/react";
export default () => (
<Stack direction="row" gap="2xs" align="center">
<Button variant="primary" expand>
Full width
</Button>
<Button variant="primary" expand>
Back to top <IconArrowUp />
</Button>
</Stack>
);<k-stack direction="row" gap="2xs" align="center">
<button class="k-button" variant="primary" expand>Full width</button>
<button class="k-button" variant="primary" expand>Back to top <svg viewBox="0 0 24 24" aria-hidden="true" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M11.432 1.508a.755.755 0 0 1 .357-.227.736.736 0 0 1 .741.19l9.5 9.5a.75.75 0 0 1-1.06 1.06l-8.22-8.22v18.19a.75.75 0 0 1-1.5 0V3.81l-8.22 8.22a.75.75 0 1 1-1.06-1.06l9.462-9.463z" fill="currentColor" /></svg></button>
</k-stack>import { Fragment } from "react";
import { Button, Stack } from "@kesko/components";
import { IconBasketAddTo } from "@kesko/iconography/react";
const sizes = [
{ size: "sm" as const, label: "Small" },
{ size: "md" as const, label: "Medium" },
{ size: "lg" as const, label: "Large" },
];
export default () => (
<Stack
direction="row"
gap="2xs"
align="center"
wrap
style={{
padding: "0.5rem",
background: "#000",
color: "var(--k-color-text-on-accent)",
borderRadius: "0.5rem",
}}
>
{sizes.map(s => (
<Fragment key={s.size}>
<Button variant="inverted" size={s.size}>
<IconBasketAddTo /> {s.label}
</Button>
<Button iconOnly variant="inverted" size={s.size}>
<IconBasketAddTo label={`Inverted ${s.label}`} />
</Button>
</Fragment>
))}
</Stack>
);<k-stack direction="row" gap="2xs" align="center" wrap style="padding: 0.5rem; background: #000; border-radius: 0.5rem">
<button class="k-button" variant="inverted" size="sm">Small</button>
<button class="k-button" variant="inverted" size="md">Medium</button>
<button class="k-button" variant="inverted" size="lg">Large</button>
</k-stack>import { Button, Stack } from "@kesko/components";
export default () => (
<Stack direction="row" gap="2xs" align="center" wrap>
<Button variant="primary" loading>
Loading
</Button>
<Button loading>Loading</Button>
<Button loading variant="plain">
Loading
</Button>
</Stack>
);<k-stack direction="row" gap="2xs" align="center" wrap>
<button class="k-button" variant="primary" loading disabled>
Loading
<k-spinner></k-spinner>
</button>
<button class="k-button" loading disabled>
Loading
<k-spinner></k-spinner>
</button>
<button class="k-button" variant="plain" loading disabled>
Loading
<k-spinner></k-spinner>
</button>
</k-stack>import { Fragment } from "react";
import { Button, Stack } from "@kesko/components";
import { IconBasketAddTo } from "@kesko/iconography/react";
const variants = [
{ key: "primary", label: "Primary", props: { variant: "primary" as const } },
{ key: "secondary", label: "Secondary", props: { variant: "secondary" as const } },
{ key: "default", label: "Default", props: {} },
{ key: "plain", label: "Plain", props: { variant: "plain" as const } },
{ key: "text", label: "Text", props: { variant: "text" as const } },
];
const sizes = [
{ size: "sm" as const, label: "Small" },
{ size: "md" as const, label: "Medium" },
{ size: "lg" as const, label: "Large" },
];
export default () => (
<Stack gap="2xs">
{variants.map(row => (
<Stack key={row.key} direction="row" gap="2xs" align="center" wrap>
<strong style={{ fontSize: "0.875rem", inlineSize: "6rem" }}>{row.label}</strong>
{sizes.map(s => (
<Fragment key={s.size}>
<Button {...row.props} size={s.size}>
<IconBasketAddTo /> {s.label}
</Button>
<Button iconOnly {...row.props} size={s.size}>
<IconBasketAddTo label={`${row.label} ${s.label}`} />
</Button>
</Fragment>
))}
</Stack>
))}
</Stack>
);<k-stack direction="row" gap="2xs" align="center" wrap>
<button class="k-button" variant="primary" size="sm">Small</button>
<button class="k-button" variant="primary">Medium</button>
<button class="k-button" variant="primary" size="lg">Large</button>
</k-stack>import { Button, Stack } from "@kesko/components";
const variants = [
{ key: "primary", label: "Primary", props: { variant: "primary" as const } },
{ key: "secondary", label: "Secondary", props: { variant: "secondary" as const } },
{ key: "default", label: "Default", props: {} },
{ key: "plain", label: "Plain", props: { variant: "plain" as const } },
{ key: "text", label: "Text", props: { variant: "text" as const } },
];
const sizes = ["sm", "md", "lg"] as const;
export default () => (
<Stack gap="2xs">
{variants.map(row => (
<Stack key={row.key} direction="row" gap="2xs" align="center" wrap>
<strong style={{ fontSize: "0.875rem", inlineSize: "6rem" }}>{row.label}</strong>
{sizes.map(size => (
<Button key={size} {...row.props} size={size} loading>
Loading
</Button>
))}
</Stack>
))}
</Stack>
);<k-stack direction="row" gap="2xs" align="center" wrap>
<button class="k-button" variant="primary" size="sm" loading disabled>
Loading
<k-spinner size="sm"></k-spinner>
</button>
<button class="k-button" variant="primary" loading disabled>
Loading
<k-spinner size="md"></k-spinner>
</button>
<button class="k-button" variant="primary" size="lg" loading disabled>
Loading
<k-spinner size="lg"></k-spinner>
</button>
</k-stack>import { Fragment } from "react";
import { Button, Stack } from "@kesko/components";
import { IconBasketAddTo } from "@kesko/iconography/react";
const sizes = [
{ size: "sm" as const, label: "Small" },
{ size: "md" as const, label: "Medium" },
{ size: "lg" as const, label: "Large" },
];
export default () => (
<Stack
direction="row"
gap="2xs"
align="center"
wrap
style={{ padding: "0.5rem", background: "var(--k-color-bg-hover)", borderRadius: "0.5rem" }}
>
{sizes.map(s => (
<Fragment key={s.size}>
<Button transparent size={s.size}>
<IconBasketAddTo /> {s.label}
</Button>
<Button iconOnly transparent size={s.size}>
<IconBasketAddTo label={`Transparent ${s.label}`} />
</Button>
</Fragment>
))}
</Stack>
);<k-stack direction="row" gap="2xs" align="center" wrap style="padding: 0.5rem; background: var(--k-color-bg-hover); border-radius: 0.5rem">
<button class="k-button" size="sm" transparent>
<svg viewBox="0 0 24 24" aria-hidden="true" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M17.5 14.748a.75.75 0 0 1 .75.75v2.25h2.25a.75.75 0 0 1 0 1.5h-2.25v2.25a.75.75 0 0 1-1.5 0v-2.25H14.5a.75.75 0 0 1 0-1.5h2.25v-2.25a.75.75 0 0 1 .75-.75zM12 2.25a5.252 5.252 0 0 1 5.251 5.252v.746a.756.756 0 0 1-.012.136.75.75 0 0 1-.739.883L2.961 9.25 5.54 19.559a.25.25 0 0 0 .242.19h7.407a.75.75 0 0 1 0 1.5H5.78a1.75 1.75 0 0 1-1.698-1.326L1.273 8.68A.75.75 0 0 1 2 7.748l4.749.006v-.256A5.248 5.248 0 0 1 12 2.25zm7.006 5.498l3 .02a.75.75 0 0 1 .723.932l-1.625 6.487a.75.75 0 0 1-1.455-.364l1.393-5.562-2.045-.013a.75.75 0 1 1 .01-1.5zM12 3.75a3.749 3.749 0 0 0-3.75 3.748v.258l7.5.01v-.264A3.752 3.752 0 0 0 12 3.75z" fill="currentColor" /></svg>
Small
</button>
<button class="k-button" size="sm" icon-only transparent>
<svg role="img" aria-label="Add to basket" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M17.5 14.748a.75.75 0 0 1 .75.75v2.25h2.25a.75.75 0 0 1 0 1.5h-2.25v2.25a.75.75 0 0 1-1.5 0v-2.25H14.5a.75.75 0 0 1 0-1.5h2.25v-2.25a.75.75 0 0 1 .75-.75zM12 2.25a5.252 5.252 0 0 1 5.251 5.252v.746a.756.756 0 0 1-.012.136.75.75 0 0 1-.739.883L2.961 9.25 5.54 19.559a.25.25 0 0 0 .242.19h7.407a.75.75 0 0 1 0 1.5H5.78a1.75 1.75 0 0 1-1.698-1.326L1.273 8.68A.75.75 0 0 1 2 7.748l4.749.006v-.256A5.248 5.248 0 0 1 12 2.25zm7.006 5.498l3 .02a.75.75 0 0 1 .723.932l-1.625 6.487a.75.75 0 0 1-1.455-.364l1.393-5.562-2.045-.013a.75.75 0 1 1 .01-1.5zM12 3.75a3.749 3.749 0 0 0-3.75 3.748v.258l7.5.01v-.264A3.752 3.752 0 0 0 12 3.75z" fill="currentColor" /></svg>
</button>
<button class="k-button" transparent>
<svg viewBox="0 0 24 24" aria-hidden="true" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M17.5 14.748a.75.75 0 0 1 .75.75v2.25h2.25a.75.75 0 0 1 0 1.5h-2.25v2.25a.75.75 0 0 1-1.5 0v-2.25H14.5a.75.75 0 0 1 0-1.5h2.25v-2.25a.75.75 0 0 1 .75-.75zM12 2.25a5.252 5.252 0 0 1 5.251 5.252v.746a.756.756 0 0 1-.012.136.75.75 0 0 1-.739.883L2.961 9.25 5.54 19.559a.25.25 0 0 0 .242.19h7.407a.75.75 0 0 1 0 1.5H5.78a1.75 1.75 0 0 1-1.698-1.326L1.273 8.68A.75.75 0 0 1 2 7.748l4.749.006v-.256A5.248 5.248 0 0 1 12 2.25zm7.006 5.498l3 .02a.75.75 0 0 1 .723.932l-1.625 6.487a.75.75 0 0 1-1.455-.364l1.393-5.562-2.045-.013a.75.75 0 1 1 .01-1.5zM12 3.75a3.749 3.749 0 0 0-3.75 3.748v.258l7.5.01v-.264A3.752 3.752 0 0 0 12 3.75z" fill="currentColor" /></svg>
Medium
</button>
<button class="k-button" icon-only transparent>
<svg role="img" aria-label="Add to basket" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M17.5 14.748a.75.75 0 0 1 .75.75v2.25h2.25a.75.75 0 0 1 0 1.5h-2.25v2.25a.75.75 0 0 1-1.5 0v-2.25H14.5a.75.75 0 0 1 0-1.5h2.25v-2.25a.75.75 0 0 1 .75-.75zM12 2.25a5.252 5.252 0 0 1 5.251 5.252v.746a.756.756 0 0 1-.012.136.75.75 0 0 1-.739.883L2.961 9.25 5.54 19.559a.25.25 0 0 0 .242.19h7.407a.75.75 0 0 1 0 1.5H5.78a1.75 1.75 0 0 1-1.698-1.326L1.273 8.68A.75.75 0 0 1 2 7.748l4.749.006v-.256A5.248 5.248 0 0 1 12 2.25zm7.006 5.498l3 .02a.75.75 0 0 1 .723.932l-1.625 6.487a.75.75 0 0 1-1.455-.364l1.393-5.562-2.045-.013a.75.75 0 1 1 .01-1.5zM12 3.75a3.749 3.749 0 0 0-3.75 3.748v.258l7.5.01v-.264A3.752 3.752 0 0 0 12 3.75z" fill="currentColor" /></svg>
</button>
<button class="k-button" size="lg" transparent>
<svg viewBox="0 0 24 24" aria-hidden="true" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M17.5 14.748a.75.75 0 0 1 .75.75v2.25h2.25a.75.75 0 0 1 0 1.5h-2.25v2.25a.75.75 0 0 1-1.5 0v-2.25H14.5a.75.75 0 0 1 0-1.5h2.25v-2.25a.75.75 0 0 1 .75-.75zM12 2.25a5.252 5.252 0 0 1 5.251 5.252v.746a.756.756 0 0 1-.012.136.75.75 0 0 1-.739.883L2.961 9.25 5.54 19.559a.25.25 0 0 0 .242.19h7.407a.75.75 0 0 1 0 1.5H5.78a1.75 1.75 0 0 1-1.698-1.326L1.273 8.68A.75.75 0 0 1 2 7.748l4.749.006v-.256A5.248 5.248 0 0 1 12 2.25zm7.006 5.498l3 .02a.75.75 0 0 1 .723.932l-1.625 6.487a.75.75 0 0 1-1.455-.364l1.393-5.562-2.045-.013a.75.75 0 1 1 .01-1.5zM12 3.75a3.749 3.749 0 0 0-3.75 3.748v.258l7.5.01v-.264A3.752 3.752 0 0 0 12 3.75z" fill="currentColor" /></svg>
Large
</button>
<button class="k-button" size="lg" icon-only transparent>
<svg role="img" aria-label="Add to basket" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M17.5 14.748a.75.75 0 0 1 .75.75v2.25h2.25a.75.75 0 0 1 0 1.5h-2.25v2.25a.75.75 0 0 1-1.5 0v-2.25H14.5a.75.75 0 0 1 0-1.5h2.25v-2.25a.75.75 0 0 1 .75-.75zM12 2.25a5.252 5.252 0 0 1 5.251 5.252v.746a.756.756 0 0 1-.012.136.75.75 0 0 1-.739.883L2.961 9.25 5.54 19.559a.25.25 0 0 0 .242.19h7.407a.75.75 0 0 1 0 1.5H5.78a1.75 1.75 0 0 1-1.698-1.326L1.273 8.68A.75.75 0 0 1 2 7.748l4.749.006v-.256A5.248 5.248 0 0 1 12 2.25zm7.006 5.498l3 .02a.75.75 0 0 1 .723.932l-1.625 6.487a.75.75 0 0 1-1.455-.364l1.393-5.562-2.045-.013a.75.75 0 1 1 .01-1.5zM12 3.75a3.749 3.749 0 0 0-3.75 3.748v.258l7.5.01v-.264A3.752 3.752 0 0 0 12 3.75z" fill="currentColor" /></svg>
</button>
</div>import { Button, Stack } from "@kesko/components";
import { IconBasketAddTo } from "@kesko/iconography/react";
export default () => (
<Stack direction="row" gap="2xs" align="center" wrap>
<Button variant="primary">
<IconBasketAddTo /> Primary
</Button>
<Button variant="primary" iconOnly>
<IconBasketAddTo label="Add to basket" />
</Button>
<Button variant="secondary">
<IconBasketAddTo /> Secondary
</Button>
<Button>Default</Button>
<Button disabled>Disabled</Button>
<Button variant="plain">Plain</Button>
<Button variant="text">Text</Button>
</Stack>
);<k-stack direction="row" gap="2xs" align="center" wrap>
<button class="k-button" variant="primary">
<svg viewBox="0 0 24 24" aria-hidden="true" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M17.5 14.748a.75.75 0 0 1 .75.75v2.25h2.25a.75.75 0 0 1 0 1.5h-2.25v2.25a.75.75 0 0 1-1.5 0v-2.25H14.5a.75.75 0 0 1 0-1.5h2.25v-2.25a.75.75 0 0 1 .75-.75zM12 2.25a5.252 5.252 0 0 1 5.251 5.252v.746a.756.756 0 0 1-.012.136.75.75 0 0 1-.739.883L2.961 9.25 5.54 19.559a.25.25 0 0 0 .242.19h7.407a.75.75 0 0 1 0 1.5H5.78a1.75 1.75 0 0 1-1.698-1.326L1.273 8.68A.75.75 0 0 1 2 7.748l4.749.006v-.256A5.248 5.248 0 0 1 12 2.25zm7.006 5.498l3 .02a.75.75 0 0 1 .723.932l-1.625 6.487a.75.75 0 0 1-1.455-.364l1.393-5.562-2.045-.013a.75.75 0 1 1 .01-1.5zM12 3.75a3.749 3.749 0 0 0-3.75 3.748v.258l7.5.01v-.264A3.752 3.752 0 0 0 12 3.75z" fill="currentColor" /></svg>
Primary
</button>
<button class="k-button" variant="primary" icon-only>
<svg role="img" aria-label="Add to basket" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M17.5 14.748a.75.75 0 0 1 .75.75v2.25h2.25a.75.75 0 0 1 0 1.5h-2.25v2.25a.75.75 0 0 1-1.5 0v-2.25H14.5a.75.75 0 0 1 0-1.5h2.25v-2.25a.75.75 0 0 1 .75-.75zM12 2.25a5.252 5.252 0 0 1 5.251 5.252v.746a.756.756 0 0 1-.012.136.75.75 0 0 1-.739.883L2.961 9.25 5.54 19.559a.25.25 0 0 0 .242.19h7.407a.75.75 0 0 1 0 1.5H5.78a1.75 1.75 0 0 1-1.698-1.326L1.273 8.68A.75.75 0 0 1 2 7.748l4.749.006v-.256A5.248 5.248 0 0 1 12 2.25zm7.006 5.498l3 .02a.75.75 0 0 1 .723.932l-1.625 6.487a.75.75 0 0 1-1.455-.364l1.393-5.562-2.045-.013a.75.75 0 1 1 .01-1.5zM12 3.75a3.749 3.749 0 0 0-3.75 3.748v.258l7.5.01v-.264A3.752 3.752 0 0 0 12 3.75z" fill="currentColor" /></svg>
</button>
<button class="k-button" variant="secondary">
<svg viewBox="0 0 24 24" aria-hidden="true" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M17.5 14.748a.75.75 0 0 1 .75.75v2.25h2.25a.75.75 0 0 1 0 1.5h-2.25v2.25a.75.75 0 0 1-1.5 0v-2.25H14.5a.75.75 0 0 1 0-1.5h2.25v-2.25a.75.75 0 0 1 .75-.75zM12 2.25a5.252 5.252 0 0 1 5.251 5.252v.746a.756.756 0 0 1-.012.136.75.75 0 0 1-.739.883L2.961 9.25 5.54 19.559a.25.25 0 0 0 .242.19h7.407a.75.75 0 0 1 0 1.5H5.78a1.75 1.75 0 0 1-1.698-1.326L1.273 8.68A.75.75 0 0 1 2 7.748l4.749.006v-.256A5.248 5.248 0 0 1 12 2.25zm7.006 5.498l3 .02a.75.75 0 0 1 .723.932l-1.625 6.487a.75.75 0 0 1-1.455-.364l1.393-5.562-2.045-.013a.75.75 0 1 1 .01-1.5zM12 3.75a3.749 3.749 0 0 0-3.75 3.748v.258l7.5.01v-.264A3.752 3.752 0 0 0 12 3.75z" fill="currentColor" /></svg>
Secondary
</button>
<button class="k-button">Default</button>
<button class="k-button" disabled>Disabled</button>
<button class="k-button" variant="plain">Plain</button>
<button class="k-button" variant="text">Text</button>
</k-stack>Props
| Name | Description | Type | Default |
|---|---|---|---|
variant | The style variant of the button. | "default" | "primary" | "secondary" | "plain" | "text" | "inverted" | "default" |
size | The size of the button. | "sm" | "md" | "lg" | "md" |
expand | Makes the button fit its container. | boolean | false |
transparent | Removes the background from the default and plain variants. | boolean | false |
disabled | Disables the component. Native | boolean | false |
loading | Shows loading state with spinner. | boolean | false |
iconOnly | Renders the button as a square with no horizontal padding for a single icon child. Pair with | boolean | false |
aria-label | Accessible name. Required for | string | — |
aria-labelledby |
| string | — |
aria-describedby |
| string | — |
aria-controls |
| string | — |
aria-expanded | Whether a grouping controlled by this button is expanded. | boolean | "true" | "false" | — |
aria-haspopup | Availability and type of popup this button opens. | boolean | "menu" | "listbox" | "tree" | "grid" | "dialog" | "true" | "false" | — |
href | Renders as an anchor element. | string | — |
target | Where to open the linked URL. | "_self" | "_blank" | "_parent" | "_top" | — |
download | Triggers a file download. Pass | boolean | string | — |
Events
| Name | Description | Type |
|---|---|---|
onClick | Handler called on click (mouse, touch, or keyboard activation). | (event: MouseEvent<ButtonTarget>) => void |
onFocus | Handler called when the element receives focus. | (event: FocusEvent<ButtonTarget>) => void |
onBlur | Handler called when the element loses focus. | (event: FocusEvent<ButtonTarget>) => void |
CSS custom properties
CSS custom properties provide finer-grained control than props. Prefer the props API when it suits your need.
| Name | Description | Default |
|---|---|---|
--k-button-bg | Overrides the background color. | var(--k-color-bg) |
--k-button-text | Overrides the text color. | var(--k-color-text-link) |
--k-button-border | Overrides the border color. | var(--k-color-text-link) |
--k-button-radius | Overrides the border radius. | var(--k-radius-button) |
--k-button-focus | Overrides the focus ring color. | var(--k-color-border-focus) |
--k-button-bg-hover | Overrides the hover background color. | var(--k-button-bg) |
--k-button-bg-active | Overrides the pressed background color. | var(--k-button-bg) |
--k-button-text-hover | Overrides the hover text color. | — |
--k-button-text-active | Overrides the pressed text color. | — |
--k-button-ring-hover | Overrides the grow-ring color on hover. | — |
--k-button-ring-active | Overrides the grow-ring color when pressed. | — |
--k-button-height | Overrides the button height at the active size. | — |