import { type IconProp } from '../icon'; import type { ButtonSize, ButtonVariant } from './types'; import type { Snippet } from 'svelte'; type BaseProps = { /** Color variant @default 'primary' */ variant?: ButtonVariant; /** @default 'md' */ size?: ButtonSize; /** Bump the icon one step up the scale relative to `size`, leaving height/text unchanged. @default 'default' */ iconScale?: 'default' | 'large'; disabled?: boolean; /** Renders a spinner in place of the icon (when leading) and blocks clicks. */ loading?: boolean; /** Stretch to fill the parent's inline axis. */ fullWidth?: boolean; /** Icon — string SVG source, `{ src, color?, size? }` object, or custom snippet. Replaced by the spinner when `loading` and `iconPosition='leading'`. */ icon?: IconProp; /** Side of the label where `icon` is rendered. @default 'leading' */ iconPosition?: 'leading' | 'trailing'; /** Label. Omit for icon-only mode (`icon` set + no children + `aria-label` required). */ children?: Snippet; /** Required when icon-only (no children). */ 'aria-label'?: string; }; type ButtonModeProps = BaseProps & { /** Native button mode. */ type: 'button' | 'submit' | 'reset'; href?: never; on?: { click?: (e: MouseEvent) => void; }; form?: string; name?: string; value?: string; }; type AnchorModeProps = BaseProps & { /** Anchor mode — renders as ``. */ type: 'anchor'; href: string; target?: string; rel?: string; download?: string; }; type PresentationalModeProps = BaseProps & { /** Presentational mode — renders a non-interactive `` styled as a button. Use as the visual inside another interactive element (e.g. a Popover trigger) to avoid nesting interactive elements. Accepts no `href` / click callback. */ type: 'presentational'; href?: never; }; type Props = ButtonModeProps | AnchorModeProps | PresentationalModeProps; /** * A button with configurable variant, size, loading state, and an anchor mode. Width is intrinsic by default — use `fullWidth` for inline-axis stretch, or override `--sc-kit--button--{min,max,}width` from CSS for fine-grained control. Overflowing labels are truncated with an ellipsis. * * The `icon` slot accepts an SVG source string or a snippet; `iconPosition` ('leading' / 'trailing', default leading) flips which side of the label the icon renders on. Icon-only mode kicks in automatically when `icon` is set without `children` — the button becomes square and requires an `aria-label`. * * Pass `type="anchor"` to render as `` with `href`, or `type="presentational"` to render a non-interactive `` styled as a button (for use as the visual inside another interactive element, e.g. a Popover trigger). Otherwise `type` is the native `