# Elements: Actions

> Plainkit 0.28.0. Generated by scripts/build-skills.mjs from core/dist/elements/api.json. Do not edit: change the source and run the generator.

How to read these tables: see `elements-index.md`. Each element shows its first example; the others are in `references/full/examples-actions.md` (kept apart so the group files stay short).

## `pk-button`

**Button** (Actions). A button in five variants and three sizes, with busy, icon-only, toggle and disclosure forms. type="submit" and "reset" act on the surrounding form, as a native button does. With href it renders a real link that looks like a button.

It is form-associated (takes part in a `<form>` by its `name`) and delegates focus to its inner control.

**Props**

| Attribute | Type | Default | Values | Description |
|---|---|---|---|---|
| `variant` | enum | `"primary"` | `primary` `ghost` `warn` `secondary` `plain` | Visual weight. plain is the bare button (no border, a tinted hover): use it for an icon-only button in an app bar, a drawer header or a toolbar. ghost is the outlined quiet button and keeps its 1px border, with text or an icon alone; secondary is the accent outline. |
| `size` | enum | `"md"` | `md` `mini` `lg` | md is the reading-size control; mini is the compact desktop-density one; lg is the large one. |
| `type` | enum | `"button"` | `button` `submit` `reset` | What a click does inside a form: nothing, submit it, or reset it. |
| `href` | string | `""` |  | Makes the button a link: the control is an <a> that navigates natively (middle and ctrl-click, the status-bar URL). Every variant, size, icon and busy style still applies. A link ignores type, toggle and pressed. |
| `bookmarklet` | boolean | `false` |  | Keeps a script address (a javascript URL) as the href, for a bookmarklet a reader drags to the bookmarks bar. Without it such an href is dropped. The href is then used exactly as written: only for an address you wrote in the page, never one bound to data (a database row, a query string, a parameter). |
| `target` | string | `""` |  | Where a link opens (for example _blank). Only with href. |
| `rel` | string | `""` |  | The link relation. Defaults to noopener when target is _blank. Only with href. |
| `download` | string | `""` |  | Downloads the target instead of opening it, under the file name given (the bare attribute keeps the name from the URL). Only with href. |
| `disabled` | boolean | `false` |  | Blocks interaction and dims the control. Also set by a disabled fieldset. A disabled link loses its href and reports aria-disabled. |
| `label` | string | `""` |  | The accessible name, for a button whose visible content is only an icon. It wins over the words in the slot; leave it off and write the name as the button text with icon set instead. |
| `busy` | boolean | `false` |  | Shows a spinner and ignores clicks without disabling the button, so focus stays put. A busy link loses its href, reports aria-disabled and stays focusable. |
| `busy-text` (property `busyText`) | string | `""` |  | Replaces the label while busy. |
| `block` | boolean | `false` |  | Fills the width of its container. |
| `overflow` | enum | `"visible"` | `visible` `wrap` `truncate` | What a label wider than the container does. visible (the default) keeps one line and may overflow; wrap lets it run over several lines (breaking inside a long word if it must) and the button shrink to its container; truncate keeps one line and cuts it with an ellipsis. The full text stays in the DOM, so the accessible name is unchanged; add a pk-tooltip when sighted users need the whole text. |
| `icon` | boolean | `false` |  | Icon-only mode: a square button that draws only its icon (icon-name, a pk-icon or an svg in the start slot). The words in the default slot are hidden visually but stay the accessible name, and show as the tooltip on hover. The label prop wins over them when both are given. |
| `collapse` | enum | `"none"` | `none` `phone` `tablet` | Folds the label into the icon at and below that breakpoint (phone: icon only on a phone; tablet: icon only on a tablet and a phone; above it, icon and text). The words stay the accessible name. Needs an icon (icon-name or a start-slot icon): a button without one never collapses. |
| `icon-name` (property `iconName`) | string | `""` |  | Draws that symbol of the SDK icon sprite inside the control, before the label (the pk-icon names: plus, search, chevron-left and so on), so an icon button needs no child element. A name that is not in the sprite is reported once through the logger and nothing is drawn. |
| `toggle` | boolean | `false` |  | A button that stays pressed: a click flips pressed. |
| `disclosure` | boolean | `false` |  | A button that shows or hides something else: a click flips pressed, a built-in caret rotates with it, and the control reports aria-expanded instead of aria-pressed. Use it for a row or panel the button itself expands and collapses (a sub-row, a detail block); for a control that stays visually pressed without expanding anything, use toggle instead. Composes with every variant, size and icon. |
| `haspopup` | string | `""` |  | What the button opens, announced as aria-haspopup on the control: menu, listbox, tree, grid, dialog or true. Empty says nothing. |
| `controls` | json | `null` |  | Property only: the element (or array of elements) this button controls, set as aria-controls on the control through ariaControlsElements, so it can name an element in the host's own tree across the shadow boundary. Where the browser lacks ariaControlsElements it does nothing and aria-expanded still announces the state. |
| `pressed` | boolean | `false` |  | The pressed (for toggle) or expanded (for disclosure) state of the button. |
| `value` | string | `""` |  | A value reported by pk-toggle. |

**Slots**

| Slot | Description |
|---|---|
| (default) | The label. With icon set it is hidden visually and kept as the accessible name; an element in it (a pk-icon) stays drawn. |
| `start` | An icon before the label. |
| `end` | An icon after the label. |

**Events**

| Event | Detail | Description |
|---|---|---|
| `click` | `native MouseEvent` | A click (not fired while disabled or busy). A link fires it too, so a host can track the navigation; preventDefault stops the navigation. |
| `pk-toggle` | `{ pressed: boolean, value: string }` | A toggle or disclosure button was pressed or released. |

**Methods**

| Method | Description |
|---|---|
| `focus()` | Focuses the inner button or link. |

**CSS parts**

| Part | Description |
|---|---|
| `control` | The inner button element, or the anchor when href is set. |
| `icon` | The svg drawn for icon-name. |
| `spinner` | The busy spinner. |
| `busy-text` | The text shown while busy. |
| `chevron` | The disclosure caret, drawn after the label when disclosure is set. Rotates 180deg with pressed. |

**CSS custom properties**

| Property | Default | Description |
|---|---|---|
| `--pk-button-bg` | `the variant colour` | Background colour. |
| `--pk-button-bg-hover` | `the variant hover colour` | Background colour on hover. |
| `--pk-button-fg` | `the variant text colour` | Text colour. |
| `--pk-button-radius` | `var(--radius-sm)` | Corner radius (a button group sets it to join its buttons). |
| `--pk-button-bw` | `1px` | Border width. |
| `--pk-button-border` | `the variant border colour` | Border colour. |
| `--pk-button-padding` | `var(--space-2) var(--space-4); mini: 0.2rem 0.55rem` | Inner padding. |
| `--pk-button-white-space` | `nowrap` | White-space of the label: set normal so a long label wraps (anywhere, when the surrounding text allows it) inside a narrow container instead of overflowing it. |

**Accessibility.** A native button (with href a native link) lives in the shadow root, so it is focusable and exposes the button (link) role. A button activates on Enter and Space, a link on Enter only, as any link does; its name comes from the slot. An icon button (icon) hides that text visually (a zero-size font, not display:none, so it stays in the accessibility tree) and it remains the name; label overrides it. Every icon-only button needs a name: from its text, label or aria-label (the scorecard flags one without). The name is also the native title tooltip on hover (skipped inside a pk-tooltip, which gives hover and keyboard focus, or when the host has its own title); the title is never the name. A toggle reports aria-pressed; a disclosure reports aria-expanded instead (never both) and draws a caret that rotates with pressed, for a button that itself expands or collapses another part of the page (name the expanded region with aria-controls if it is not adjacent). A busy button reports aria-busy and ignores clicks without dropping focus, and a busy icon button swaps its icon for the spinner and keeps its name; a disabled or busy link drops its href and reports aria-disabled. Focus ring and the 44px phone target are built in. haspopup sets aria-haspopup on the control; controls (property only) sets aria-controls through ariaControlsElements (Chrome 135, Safari 16.4, Firefox 136; a no-op in older browsers, where aria-expanded still announces the state). A bookmarklet link (bookmarklet) is still a native link; say in its text what dragging it to the bookmarks bar does.

Example: Variants

```html
<pk-button>Save</pk-button>
<pk-button variant="ghost">Cancel</pk-button>
<pk-button variant="warn">Delete</pk-button>
<pk-button variant="secondary">Export</pk-button>
<pk-button variant="plain">Skip</pk-button>
```

## `pk-button-group`

**Button group** (Actions). Buttons fused into one bar, horizontal, vertical or full width; with mode="single" its toggle buttons behave as one choice, which makes it the SDK's segmented control (a Dark/Light switch, a view or density picker).

**Props**

| Attribute | Type | Default | Values | Description |
|---|---|---|---|---|
| `orientation` | enum | `"horizontal"` | `horizontal` `vertical` | Direction of the bar. |
| `fill` | boolean | `false` |  | Fills the container width and shares it between the buttons. |
| `label` | string | `""` |  | Accessible name of the group (aria-label). |
| `mode` | enum | `"none"` | `none` `single` `multi` | single: the toggle buttons in the group release each other (one is always pressed); multi and none leave each toggle alone. |

**Slots**

| Slot | Description |
|---|---|
| (default) | pk-button elements. |

**CSS parts**

| Part | Description |
|---|---|
| `group` | The role=group container. |

**Accessibility.** role=group with an aria-label (a group of toggle buttons, not a radiogroup: each keeps its own tab stop and Space or Enter presses it). In single mode the pressed state lives in each button's aria-pressed and the group keeps exactly one pressed. Buttons keep their 44px phone height. A segmented control: give each toggle button a value and listen for pk-toggle on the group (it bubbles); the choice is the event whose detail.pressed is true, and pressing the pressed button again also raises pk-toggle with pressed false, which the group immediately undoes, so ignore that one.

Example: Segmented control (Dark and Light)

```html
<pk-button-group label="Theme" mode="single"><pk-button toggle pressed value="dark" variant="ghost">Dark</pk-button><pk-button toggle value="light" variant="ghost">Light</pk-button></pk-button-group>
```

## `pk-split-button`

**Split button** (Actions). A main action beside a caret that opens a menu of related actions, so the common case is one click and the variants stay reachable.

It is form-associated (takes part in a `<form>` by its `name`) and delegates focus to its inner control.

**Props**

| Attribute | Type | Default | Values | Description |
|---|---|---|---|---|
| `variant` | enum | `"primary"` | `primary` `ghost` | Colour of both halves. |
| `type` | enum | `"button"` | `button` `submit` `reset` | What the main action does inside a form. |
| `disabled` | boolean | `false` |  | Blocks interaction; also set by a disabled fieldset. |
| `toggle-label` (property `toggleLabel`) | string | `"More options"` |  | Accessible name of the caret button. |
| `open` | boolean | `false` |  | Whether the menu is open. |
| `menu-align` (property `menuAlign`) | enum | `"start"` | `start` `end` | Which edge the menu lines up with. |

**Slots**

| Slot | Description |
|---|---|
| (default) | The main action label. |
| `menu` | The menu items: buttons (with a value or data-value). |

**Events**

| Event | Detail | Description |
|---|---|---|
| `click` | `native MouseEvent` | The main action was clicked. |
| `pk-split-select` | `{ value: string, label: string }` | A menu item was chosen. |
| `pk-menu-toggle` | `{ open: boolean }` | The menu opened or closed. |

**Methods**

| Method | Description |
|---|---|
| `show()` | Opens the menu. |
| `hide()` | Closes the menu. |

**CSS parts**

| Part | Description |
|---|---|
| `split` | The two buttons side by side. |
| `main` | The main action button. |
| `toggle` | The caret button. |
| `menu` | The menu panel. |

**CSS custom properties**

| Property | Default | Description |
|---|---|---|
| `--pk-split-bg` | `the variant colour` | Background of both halves. |
| `--pk-split-fg` | `the variant text colour` | Text colour of both halves. |

**Writes to host nodes**

| Target | Writes | Why |
|---|---|---|
| the slotted menu items | `role` | Every item slotted into menu gets role=menuitem (overwriting any other) so the menu has the semantics its keyboard handling assumes. Not removed. Kept when the element disconnects. |

**Accessibility.** The caret is a labelled menu button (aria-haspopup="menu", aria-expanded); the items get role=menuitem; ArrowDown/ArrowUp on the caret open the menu on the first/last item, arrows, Home and End move, Escape closes and returns focus to the caret, Tab closes, and a click outside closes. The menu opens upward when there is no room below.

Example: Primary and ghost

```html
<pk-split-button><span>Save</span><button slot="menu" value="close">Save and close</button><button slot="menu" value="new">Save and new</button></pk-split-button>
<pk-split-button variant="ghost" menu-align="end"><span>Export</span><button slot="menu" value="csv">CSV</button><button slot="menu" value="pdf">PDF</button></pk-split-button>
```
