# Components: Navigation

> Plainkit 0.28.0. Generated by scripts/build-skills.mjs from Generated/*.razor, blazor/mappings, generated.manifest.json and core/dist/elements/api.json. Do not edit: change the source and run the generator.

Every component renders its element with the parameters you set as attributes. An attribute that is not a parameter (`id`, `class`, `data-*`, `aria-*`, ...) is put on the element as it is, and a `class` is added to the component's own (`ExtraClass` on a component that lists it). Names are `Pk` plus the tag in PascalCase.

## `PkAppBarSearch`

`<pk-app-bar-search>`: **App bar search** (Navigation). A search field for a shell's header row: a pill that fills the space it is given, results in a panel below it; a bare (borderless, plain-variant) icon button (--pk-button-border on the host gives it a border) that expands over the header row below the phone breakpoint or with compact. The host supplies items and reads pk-query and pk-select. Before it upgrades it reserves about 17.75rem of inline space, at most half the row, so the header does not jump; it has no default slot, so a no-JavaScript fallback (a plain search form) goes beside it and is hidden once the element is defined.

**Parameters**

| Parameter | Type | Enum values | Sets | Description |
|---|---|---|---|---|
| `Label` | `string?` |  | attribute `label` | The accessible name of the field and the expand button. |
| `Placeholder` | `string?` |  | attribute `placeholder` | Hint shown while empty. |
| `Debounce` | `int` |  | attribute `debounce` | Milliseconds to wait after the last keystroke before raising pk-query. |
| `Compact` | `bool` |  | attribute `compact` | Icon button at any width; expands over the header row. |
| `Expanded` | `bool` |  | attribute `expanded` | Whether the field covers the header row (phone breakpoint, or compact). |
| `ExpandedChanged` | `EventCallback<bool>` |  | two-way pair of `Expanded` | Raised when Expanded changes (two-way binding: `@bind-Expanded`). |
| `Items` | `IReadOnlyList<PkAppBarSearchItem>?` |  | attribute `items` | Results: { id, label, group?, sub?, thumbnail?, badge?, href? }[]. Adjacent items with the same group share a heading; the host sets the order. An item with an href (http, https, mailto, tel or a same-site path) is a real link: open in a new tab and the status-bar address work; a plain click still raises pk-select, and preventDefault on it keeps the host's own routing (uncancelled, the browser follows the link). An item with no id is a note (a group's "+12 more"): shown, never selectable. The host clears items while the query is too short. |
| `Error` | `string?` |  | attribute `error` | A failed search: while set, the open results panel shows this message instead of the no-results message, so a failure never reads as nothing found, and a Retry button under it. Set it when your search throws (for example "Search is unavailable. Try again.") and clear it with the next result. |
| `ResultsLabel` | `string?` |  | attribute `results-label` | The word announced after the count to assistive technology ("5 results"); set it to localise. The no-results text is the empty slot. |
| `RetryLabel` | `string?` |  | attribute `retry-label` | The text of the Retry button shown with error; set it to localise. |
| `EmptyContent` | `RenderFragment?` |  | slot `empty` | The message shown when items is empty and the field has text. |
| `FooterContent` | `RenderFragment?` |  | slot `footer` | An action pinned to the bottom of the results panel (a Full search link). Hidden when empty. |
| `OnQuery` | `EventCallback<PkQueryEventArgs>` |  | event `pk-query` | The field's text, debounce milliseconds after the last keystroke. The host fetches or filters and sets items in response; this element never searches itself. |
| `OnRetry` | `EventCallback` |  | event `pk-retry` | Retry was pressed on a failed search. pk-query is raised again right after it with the text in the field, so a host that only handles pk-query retries without listening to this; it is for a host that wants to log or reset state. |
| `OnSelect` | `EventCallback<PkSelectEventArgs>` |  | event `pk-select` | A result was chosen (click or Enter). The host decides what happens; this element does not navigate. |
| `OnSubmit` | `EventCallback<PkSubmitEventArgs>` |  | event `pk-submit` | Enter was pressed with a non-empty query and no result highlighted: the host shows a full results page or submits a form. This element never navigates. |

Two-way binding: `@bind-Expanded`.

**Event args**

| Event | Args class | Fields |
|---|---|---|
| `pk-query` | `PkQueryEventArgs` | Query: string? |
| `pk-select` | `PkSelectEventArgs` | Item: JsonElement?, Value: string?, Checked: bool?, Id: string?, Selected: string[]?, Scope: string?, Query: JsonElement? |
| `pk-submit` | `PkSubmitEventArgs` | Query: string? |
| `pk-toggle` | `PkToggleEventArgs` | Open: bool?, Expanded: bool?, Pressed: bool?, Value: string?, Id: string? |

Element details (parts, CSS custom properties, methods, accessibility): `pk-app-bar-search` in the `plainkit-sdk` skill.

## `PkBackToTop`

`<pk-back-to-top>`: **Back to top** (Navigation). A floating button that appears once the reader is well down the page and scrolls the page (or a named scroller) back to the top, smoothly unless reduced motion is on.

**Parameters**

| Parameter | Type | Enum values | Sets | Description |
|---|---|---|---|---|
| `For` | `string?` |  | attribute `for` | Scroll container (default: the window). |
| `Threshold` | `int` |  | attribute `threshold` | Scroll distance in px past which the button appears; below 0 it is always shown (previews, short pages). |
| `Label` | `string?` |  | attribute `label` | Accessible name |
| `Visible` | `bool` |  | attribute `visible` | Set by the element. |
| `ChildContent` | `RenderFragment?` |  | default slot | Label. |

Element details (parts, CSS custom properties, methods, accessibility): `pk-back-to-top` in the `plainkit-sdk` skill.

## `PkBreadcrumb`

`<pk-breadcrumb>`: **Breadcrumb** (Navigation). The path to the current page as a trail of links with chevrons; the middle collapses behind a "..." button when the trail is long, sooner on a phone.

**Parameters**

| Parameter | Type | Enum values | Sets | Description |
|---|---|---|---|---|
| `Label` | `string?` |  | attribute `label` | Landmark name. |
| `Max` | `int` |  | attribute `max` | Crumbs shown before the middle folds (3 on a phone). |
| `ChildContent` | `RenderFragment?` |  | default slot | a elements; the last one is the current page. |
| `OnExpand` | `EventCallback` |  | event `pk-expand` | The fold button revealed the hidden crumbs. |

Element details (parts, CSS custom properties, methods, accessibility): `pk-breadcrumb` in the `plainkit-sdk` skill.

## `PkLink`

`<pk-link>`: **Link** (Navigation). A router-aware text link: a real anchor in prose or a nav row, with href for an ordinary address or to for an app route the app router handles without a full page load.

**Parameters**

| Parameter | Type | Enum values | Sets | Description |
|---|---|---|---|---|
| `Href` | `string?` |  | attribute `href` | An external or same-document address. Navigates natively (middle and ctrl-click, the status-bar URL). Ignored when to is set. |
| `To` | `string?` |  | attribute `to` | A module-relative route. A plain click is intercepted and reported as a cancelable pk-navigate for the app router (js/router.js mountRouter, mounted with mountApp) to handle; a modified click (middle, ctrl, shift, alt), target or download, or a router that does not cancel the event, falls back to a normal navigation. |
| `Navigate` | `string?` |  | attribute `navigate` | Who follows a to link: router (default, empty), host or none. Who follows a To link on a plain click: "router" (default), "host" (OnNavigate is a notification and nothing navigates) or "none" (the browser follows the address). |
| `Target` | `string?` |  | attribute `target` | Where the link opens (for example _blank). _blank adds rel="noopener noreferrer" automatically and a visually hidden "(opens in a new tab)" after the label. |
| `Rel` | `string?` |  | attribute `rel` | The link relation. Defaults to noopener noreferrer when target is _blank. |
| `Download` | `string?` |  | attribute `download` | Downloads the target instead of opening it, under the file name given (the bare attribute keeps the name from the URL). |
| `Current` | `bool` |  | attribute `current` | Marks the link as the current page: sets aria-current="page" on the anchor. |
| `Variant` | `LinkVariant` | `Inline` `Muted` `Plain` | attribute `variant` | inline is a coloured, underlined prose link; muted is a quiet reference (a nav row, a card footer); plain keeps the surrounding text colour. |
| `ChildContent` | `RenderFragment?` |  | default slot | The link text. No decorative glyph belongs inside it (#315); put an icon before or after the element instead. |
| `OnNavigate` | `EventCallback<PkNavigateEventArgs>` |  | event `pk-navigate` | A plain click on a to link, before any navigation. Cancelable: the app router calls preventDefault and handles it; if nothing cancels the event pk-link falls back to a normal navigation to to. The event can be cancelled in the browser (preventDefault); a callback cannot cancel it. |
| `OnClick` | `EventCallback<MouseEventArgs>` |  | event `click` | Any click on the link, href or to (bubbles from the inner anchor, #1747): a host closes a menu or flyout or records the click as the link navigates. It does not change the navigation: a modified click (ctrl, shift, cmd) still opens a new tab or window, and a middle click fires auxclick, not click. preventDefault in a script stops the navigation, as on a native link. Raised for every click, Href links included (#1747), without changing the navigation: ctrl, shift and middle clicks keep their native new-tab behaviour. Close a flyout or menu here. Attached only while bound, so an unbound link costs no round trip. |
| `StopPropagation` | `bool` |  |  | Stops the click here, so an enclosing element's @onclick (a clickable row or card) does not also run. Navigation and OnClick are unchanged. |
| `PreventDefault` | `bool` |  |  | Cancels the browser's own action for the click, so an in-page action link (Href="#" with OnClick) does not follow the address. The link still raises OnClick. |

**Event args**

| Event | Args class | Fields |
|---|---|---|
| `pk-navigate` | `PkNavigateEventArgs` | To: string?, Href: string?, Id: string?, Anchor: string?, Replace: bool? |

Element details (parts, CSS custom properties, methods, accessibility): `pk-link` in the `plainkit-sdk` skill.

## `PkNavItem`

`<pk-nav-item>`: **Nav item** (Navigation). A row of a side nav: a link, or a branch that folds its children; icon, badge, active bar and disabled state. Also works as a horizontal bar item inside pk-navbar (it detects the ancestry itself).

**Parameters**

| Parameter | Type | Enum values | Sets | Description |
|---|---|---|---|---|
| `Href` | `string?` |  | attribute `href` | Makes it a link; omit for a branch. |
| `Current` | `bool` |  | attribute `current` | The current setting |
| `Disabled` | `bool` |  | attribute `disabled` | Prevents interaction |
| `Expanded` | `bool` |  | attribute `expanded` | Branch open. |
| `ExpandedChanged` | `EventCallback<bool>` |  | two-way pair of `Expanded` | Raised when Expanded changes (two-way binding: `@bind-Expanded`). |
| `Rail` | `bool` |  | attribute `rail` | Set by the nav in icon-rail mode, on the top-level rows only: a child inside an open flyout keeps its label. |
| `Flyout` | `bool` |  | attribute `flyout` | In the icon rail, the branch is open as a flyout beside the rail. |
| `Group` | `bool` |  | attribute `group` | A group title instead of a row: static muted text that introduces the rows below it. Not focusable, skipped by the arrow keys and hidden while the filter is used; in the icon rail it shows as a divider. |
| `ChildContent` | `RenderFragment?` |  | default slot | Label. An author-written <a href> child here is the row's link: it works without JavaScript, the element styles it and never changes it (set aria-current on it and `current` on the row yourself). |
| `IconContent` | `RenderFragment?` |  | slot `icon` | Icon. |
| `BadgeContent` | `RenderFragment?` |  | slot `badge` | Count or tag. |
| `ChildrenContent` | `RenderFragment?` |  | slot `children` | Nested pk-nav-item. |
| `OnToggle` | `EventCallback<PkToggleEventArgs>` |  | event `pk-toggle` | A branch folded or unfolded. |

Two-way binding: `@bind-Expanded`.

When you set a named fragment (`IconContent`, `BadgeContent`, `ChildrenContent`), write the body as an explicit `<ChildContent>` tag too: Razor does not allow an implicit body next to a named fragment.

**Event args**

| Event | Args class | Fields |
|---|---|---|
| `pk-toggle` | `PkToggleEventArgs` | Open: bool?, Expanded: bool?, Pressed: bool?, Value: string?, Id: string? |

Element details (parts, CSS custom properties, methods, accessibility): `pk-nav-item` in the `plainkit-sdk` skill.

## `PkNavbar`

`<pk-navbar>`: **Navbar** (Navigation). The top navigation: brand, links, dropdown and mega menus, right-aligned actions, sticky option, and a hamburger that folds the links below 1024px.

**Parameters**

| Parameter | Type | Enum values | Sets | Description |
|---|---|---|---|---|
| `Label` | `string?` |  | attribute `label` | Accessible name |
| `Open` | `bool` |  | attribute `open` | Links unfolded (small screens). |
| `OpenChanged` | `EventCallback<bool>` |  | two-way pair of `Open` | Raised when Open changes (two-way binding: `@bind-Open`). |
| `Sticky` | `bool` |  | attribute `sticky` | The sticky setting |
| `NoFold` | `bool` |  | attribute `no-fold` | For a host that owns the menu on narrow screens (the app shell's drawer): below 1024px the links stay hidden and the hamburger is not shown, and the actions stay at the end of one non-wrapping row while the brand shortens first. |
| `BrandContent` | `RenderFragment?` |  | slot `brand` | Brand link. |
| `ChildContent` | `RenderFragment?` |  | default slot | Links, pk-dropdown menus, or pk-nav-item rows (it detects the navbar itself, no attribute to set). |
| `ActionsContent` | `RenderFragment?` |  | slot `actions` | Right-aligned controls. |
| `OnToggle` | `EventCallback<PkToggleEventArgs>` |  | event `pk-toggle` | Hamburger toggled. |

Two-way binding: `@bind-Open`.

When you set a named fragment (`BrandContent`, `ActionsContent`), write the body as an explicit `<ChildContent>` tag too: Razor does not allow an implicit body next to a named fragment.

**Event args**

| Event | Args class | Fields |
|---|---|---|
| `pk-toggle` | `PkToggleEventArgs` | Open: bool?, Expanded: bool?, Pressed: bool?, Value: string?, Id: string? |

Element details (parts, CSS custom properties, methods, accessibility): `pk-navbar` in the `plainkit-sdk` skill.

## `PkPager`

`<pk-pager>`: **Pager** (Navigation). Page-level previous and next links between sibling pages, with an optional centre note ("Step 2 of 5"); table pagination is a separate control.

**Parameters**

| Parameter | Type | Enum values | Sets | Description |
|---|---|---|---|---|
| `Label` | `string?` |  | attribute `label` | Accessible name |
| `PrevContent` | `RenderFragment?` |  | slot `prev` | The previous-page link. |
| `NextContent` | `RenderFragment?` |  | slot `next` | The next-page link. |
| `ChildContent` | `RenderFragment?` |  | default slot | Centre note. |

When you set a named fragment (`PrevContent`, `NextContent`), write the body as an explicit `<ChildContent>` tag too: Razor does not allow an implicit body next to a named fragment.

Element details (parts, CSS custom properties, methods, accessibility): `pk-pager` in the `plainkit-sdk` skill.

## `PkPagination`

`<pk-pagination>`: **Pagination** (Navigation). Page navigation: numbered with ellipses, a range summary, a page-size select, a simple previous and next form, or load more. On a phone the numbers collapse to previous, Page N of M and next.

**Parameters**

| Parameter | Type | Enum values | Sets | Description |
|---|---|---|---|---|
| `Page` | `int` |  | attribute `page` | Current page, 1-based. |
| `Pages` | `int` |  | attribute `pages` | Page count; 0 derives it from total and pageSize. |
| `Total` | `int` |  | attribute `total` | Item count; enables the range summary. |
| `PageSize` | `int` |  | attribute `page-size` | Items per page. |
| `PageSizeOptions` | `int[]?` |  | attribute `sizes` | Options for the page-size select, for example [10, 25, 50, 100]; empty hides the select. |
| `Siblings` | `int` |  | attribute `siblings` | Pages either side of the current one. |
| `Boundary` | `int` |  | attribute `boundary` | Pages always shown at each end. |
| `Mode` | `PaginationMode?` | `Numbered` `Simple` `LoadMore` | attribute `mode` | Layout. |
| `Label` | `string?` |  | attribute `label` | Accessible name of the nav. |
| `Loading` | `bool` |  | attribute `loading` | Load-more busy state. |
| `PageChanged` | `EventCallback<int>` |  | two-way pair of `Page` | Raised with the new value of Page (two-way: Page follows it). |
| `PageSizeChanged` | `EventCallback<int>` |  | two-way pair of `PageSize` | Raised with the new value of PageSize (two-way: PageSize follows it). |
| `OnLoadMore` | `EventCallback` |  | event `pk-load-more` | Load more was pressed. |
| `Edges` | `bool` |  | attribute `edges` | Show First and Last buttons beside Previous and Next. |

Two-way binding: `@bind-Page`, `@bind-PageSize`.

**Event args**

| Event | Args class | Fields |
|---|---|---|
| `pk-page` | `PkPageEventArgs` | Page: double? |
| `pk-page-size` | `PkPageSizeEventArgs` | PageSize: double? |

Element details (parts, CSS custom properties, methods, accessibility): `pk-pagination` in the `plainkit-sdk` skill.

## `PkScrollProgress`

`<pk-scroll-progress>`: **Scroll progress** (Navigation). A thin bar at the top of the screen that fills as the page (or a named scroller) is read.

**Parameters**

| Parameter | Type | Enum values | Sets | Description |
|---|---|---|---|---|
| `For` | `string?` |  | attribute `for` | Scroll container (default: the window). |

Element details (parts, CSS custom properties, methods, accessibility): `pk-scroll-progress` in the `plainkit-sdk` skill.

## `PkSideNav`

`<pk-side-nav>`: **Side nav** (Navigation). The app’s side navigation: brand, filter box, nested groups with arrow-key tree navigation, collapse to an icon rail (tooltips on rows, branches open as flyouts), persisted state, and an off-canvas drawer with backdrop at 1024px and below.

**Parameters**

| Parameter | Type | Enum values | Sets | Description |
|---|---|---|---|---|
| `Label` | `string?` |  | attribute `label` | Accessible name |
| `Collapsed` | `bool` |  | attribute `collapsed` | Icon rail. |
| `CollapsedChanged` | `EventCallback<bool>` |  | two-way pair of `Collapsed` | Raised when Collapsed changes (two-way binding: `@bind-Collapsed`). |
| `Open` | `bool` |  | attribute `open` | Drawer open (phones and tablets). |
| `OpenChanged` | `EventCallback<bool>` |  | two-way pair of `Open` | Raised when Open changes (two-way binding: `@bind-Open`). |
| `Filterable` | `bool` |  | attribute `filterable` | Show the filter box. |
| `Persist` | `string?` |  | attribute `persist` | Browser storage key for collapsed and open branches. |
| `CurrentPath` | `string?` |  | attribute `current-path` | The host's current URL path. When set, resolves the deepest-matching pk-nav-item (by href) and sets its `current`, clearing every other row; see resolveActiveRoute in nav-logic.js for the algorithm. |
| `AutoExpandActive` | `bool` |  | attribute `auto-expand-active` | With current-path, also opens every ancestor branch of the active row and collapses every other branch. |
| `AllowMultiple` | `bool` |  | attribute `allow-multiple` | Let several branches of one level stay open. By default opening a branch collapses its expanded siblings. |
| `BrandContent` | `RenderFragment?` |  | slot `brand` | Brand link. |
| `ChildContent` | `RenderFragment?` |  | default slot | pk-nav-item children; a pk-nav-item with the group attribute is a group title. |
| `FooterContent` | `RenderFragment?` |  | slot `footer` | Pinned bottom items. |
| `OnToggle` | `EventCallback<bool>` |  | event `pk-nav-toggle` | Rail toggled by the user, or restored from the saved state (persist) on connect. |
| `OnOpen` | `EventCallback` |  |  | Drawer opened. |
| `OnClose` | `EventCallback<PkCloseEventArgs>` |  |  | Drawer closed. |

Two-way binding: `@bind-Collapsed`, `@bind-Open`.

When you set a named fragment (`BrandContent`, `FooterContent`), write the body as an explicit `<ChildContent>` tag too: Razor does not allow an implicit body next to a named fragment.

**Event args**

| Event | Args class | Fields |
|---|---|---|
| `pk-close` | `PkCloseEventArgs` | Reason: string? |
| `pk-nav-toggle` | `PkNavToggleEventArgs` | Open: bool?, Hidden: bool?, Collapsed: bool? |

Element details (parts, CSS custom properties, methods, accessibility): `pk-side-nav` in the `plainkit-sdk` skill.

## `PkSkipLink`

`<pk-skip-link>`: **Skip link** (Navigation). The first focusable element on a page: invisible until it takes focus, then a button that jumps past the navigation to the main content.

**Parameters**

| Parameter | Type | Enum values | Sets | Description |
|---|---|---|---|---|
| `Href` | `string?` |  | attribute `href` | Same-page target. |
| `ChildContent` | `RenderFragment?` |  | default slot | Label (default "Skip to content"). |

Element details (parts, CSS custom properties, methods, accessibility): `pk-skip-link` in the `plainkit-sdk` skill.

## `PkStep`

`<pk-step>`: **Step** (Navigation). One step of a stepper: a marker (number, tick or !), a title, an optional description and the connector to the next step.

**Parameters**

| Parameter | Type | Enum values | Sets | Description |
|---|---|---|---|---|
| `Heading` | `string?` |  | attribute `heading` | The title setting |
| `Description` | `string?` |  | attribute `description` | The description setting |
| `State` | `StepState` | `Todo` `Active` `Done` `Error` | attribute `state` | Set by the stepper. |
| `Index` | `int` |  | attribute `index` | One-based, set by the stepper. |
| `Disabled` | `bool` |  | attribute `disabled` | Prevents interaction |
| `Last` | `bool` |  | attribute `last` | Set by the stepper: the last step draws no connector. |
| `Clickable` | `bool` |  | attribute `clickable` | Set by the stepper: the step can be entered. |
| `Orientation` | `StepOrientation` | `Horizontal` `Vertical` | attribute `orientation` | Set by the stepper. |
| `ChildContent` | `RenderFragment?` |  | default slot | Title (overrides the title prop). |
| `DescriptionContent` | `RenderFragment?` |  | slot `description` | Description. |

When you set a named fragment (`DescriptionContent`), write the body as an explicit `<ChildContent>` tag too: Razor does not allow an implicit body next to a named fragment.

Element details (parts, CSS custom properties, methods, accessibility): `pk-step` in the `plainkit-sdk` skill.

## `PkStepper`

`<pk-stepper>`: **Stepper** (Navigation). A wizard header: numbered steps with done, current, upcoming and error states, horizontal or vertical, optionally clickable (linear: you can go back, not skip ahead).

**Parameters**

| Parameter | Type | Enum values | Sets | Description |
|---|---|---|---|---|
| `Current` | `int` |  | attribute `current` | Zero-based current step. |
| `CurrentChanged` | `EventCallback<int>` |  | two-way pair of `Current` | Raised when Current changes (two-way binding: `@bind-Current`). |
| `Orientation` | `StepperOrientation` | `Horizontal` `Vertical` | attribute `orientation` | The orientation setting |
| `Clickable` | `bool` |  | attribute `clickable` | Steps can be entered by click or key. |
| `Free` | `bool` |  | attribute `free` | Allow skipping ahead of the furthest step reached (non-linear). |
| `Errors` | `string?` |  | attribute `errors` | Comma-separated step indexes with an error. |
| `Label` | `string?` |  | attribute `label` | Accessible name. |
| `ChildContent` | `RenderFragment?` |  | default slot | pk-step children. |
| `OnStepChange` | `EventCallback<PkStepChangeEventArgs>` |  | event `pk-step-change` | A step was entered; cancelable. |

Two-way binding: `@bind-Current`.

**Event args**

| Event | Args class | Fields |
|---|---|---|
| `pk-step-change` | `PkStepChangeEventArgs` | Index: double?, Previous: double? |

Element details (parts, CSS custom properties, methods, accessibility): `pk-stepper` in the `plainkit-sdk` skill.

## `PkTab`

`<pk-tab>`: **Tab** (Navigation). One tab of an pk-tabs. Place it inside pk-tabs; it selects its panel by value. It can show a count, a close button, and appear only on a phone or only on a desktop.

**Parameters**

| Parameter | Type | Enum values | Sets | Description |
|---|---|---|---|---|
| `Value` | `string?` |  | attribute `value` | The key that pairs this tab with the pk-tab-panel of the same value. |
| `Disabled` | `bool` |  | attribute `disabled` | Cannot be selected or focused by arrow keys. |
| `Count` | `string?` |  | attribute `count` | A badge shown in muted parentheses after the label (a queue count); empty shows none. |
| `Closable` | `bool` |  | attribute `closable` | Shows a close button, keyboard reachable on the selected tab; pk-tab-close is raised when it is activated and the page removes the tab. |
| `Only` | `TabOnly?` | `All` `Phone` `Desktop` | attribute `only` | all shows the tab everywhere; phone only at phone width (640px and below); desktop hides it at phone width. |
| `OnClose` | `EventCallback<PkTabCloseEventArgs>` |  | event `pk-tab-close` | The close button of a closable tab was clicked. |
| `ChildContent` | `RenderFragment?` |  | default slot | The tab label. |

**Event args**

| Event | Args class | Fields |
|---|---|---|
| `pk-tab-close` | `PkTabCloseEventArgs` | Value: string? |

Element details (parts, CSS custom properties, methods, accessibility): `pk-tab` in the `plainkit-sdk` skill.

## `PkTabPanel`

`<pk-tab-panel>`: **Tab panel** (Navigation). The content of one tab; shown while its tab is selected.

**Parameters**

| Parameter | Type | Enum values | Sets | Description |
|---|---|---|---|---|
| `Value` | `string?` |  | attribute `value` | The key that pairs this panel with the pk-tab of the same value. |
| `ChildContent` | `RenderFragment?` |  | default slot | The panel content. |

Element details (parts, CSS custom properties, methods, accessibility): `pk-tab-panel` in the `plainkit-sdk` skill.

## `PkTabs`

`<pk-tabs>`: **Tabs** (Navigation). A tab strip with optional panels. Children: pk-tab and pk-tab-panel paired by value. Arrow keys, Home and End move between tabs (roving tabindex). It can show no tab as selected, and hold trailing content after the last tab. When the tabs outgrow the width it slides with edge fades (overflow="scroll", the default), collapses the tabs that do not fit behind a "..." menu button (overflow="menu"), or wraps onto more rows (overflow="wrap").

**Parameters**

| Parameter | Type | Enum values | Sets | Description |
|---|---|---|---|---|
| `Value` | `string?` |  | attribute `value` | The value of the selected tab. Empty selects the first enabled tab. |
| `ValueChanged` | `EventCallback<string?>` |  | two-way pair of `Value` | Raised when Value changes (two-way binding: `@bind-Value`). |
| `Activation` | `TabsActivation?` | `Auto` `Manual` | attribute `activation` | auto selects a tab when arrow keys focus it; manual moves focus and waits for Enter or Space. |
| `NoneActive` | `bool` |  | attribute `none-active` | No tab is shown as selected, and choosing any tab (even the last one chosen) raises pk-tab-change. For a page whose cross-cutting view sits above its tabs. |
| `Overflow` | `TabsOverflow?` | `Scroll` `Menu` `Wrap` | attribute `overflow` | How the strip behaves when the tabs outgrow its width. scroll (the default): one row that slides (touch swipe, mouse wheel, trackpad, drag); a fade marks the edge that has more tabs (it follows the scroll, the tab list and the width, and mirrors in right-to-left), and moving to a tab with the arrow keys, Home, End or a click scrolls it fully into view, clear of the fade, smoothly unless the reader prefers reduced motion. menu: one row, nothing slides; tabs that stop fitting are hidden behind a trailing "..." button (a menu button) whose menu lists them, so a hidden tab is still one click or Enter away and stays selectable; the selected tab is always pinned visible, even when it would otherwise be the one to overflow. wrap: the tabs wrap onto more rows instead of scrolling or collapsing; the explicit opt-in for what used to be the only behavior. |
| `TabParam` | `string?` |  | attribute `tab-param` | A query parameter name ("tab") that keeps the selected tab in the address: the first sync selects the tab the address names (it wins over value; an unknown or disabled one is ignored), and a later change is written with history.replaceState (other parameters and the hash kept, no history entry, no router navigation). Not used with none-active. |
| `OnChange` | `EventCallback<PkTabChangeEventArgs>` |  | event `pk-tab-change` | A tab was chosen. Cancelable: preventDefault keeps the previous tab. Also raised, not cancelable, when the value falls back to the first enabled tab (empty or no matching tab), so the host learns the value the element settled on; that one carries fallback: true, so a host that only reacts to a choice the user made can skip it. |
| `ChildContent` | `RenderFragment?` |  | default slot | The content. The pk-tab and pk-tab-panel children assign themselves to the tab and panel slots; ChildContent holds them. |
| `TrailingContent` | `RenderFragment?` |  | slot `trailing` | Content inside the strip after the last tab: a hint, links or buttons. |

Two-way binding: `@bind-Value`.

When you set a named fragment (`TrailingContent`), write the body as an explicit `<ChildContent>` tag too: Razor does not allow an implicit body next to a named fragment.

**Event args**

| Event | Args class | Fields |
|---|---|---|
| `pk-tab-change` | `PkTabChangeEventArgs` | Value: string?, Previous: string?, Fallback: bool? |

Element details (parts, CSS custom properties, methods, accessibility): `pk-tabs` in the `plainkit-sdk` skill.

## `PkToc`

`<pk-toc>`: **On this page** (Navigation). An anchor list of the headings inside a target element with scroll-spy: the heading in view is marked as you read; works with the window or an inner scroller such as the shell body.

**Parameters**

| Parameter | Type | Enum values | Sets | Description |
|---|---|---|---|---|
| `For` | `string?` |  | attribute `for` | The element whose headings are listed. |
| `Levels` | `string?` |  | attribute `levels` | Which headings to list. |
| `Offset` | `int` |  | attribute `offset` | Distance from the top a heading must reach to count as current. |
| `Scroller` | `string?` |  | attribute `scroller` | Scroll container (default: the window). |
| `Heading` | `string?` |  | attribute `heading` | The title setting |
| `Label` | `string?` |  | attribute `label` | Accessible name |
| `OnSectionChange` | `EventCallback<PkSectionChangeEventArgs>` |  | event `pk-section-change` | The current heading changed. |

**Event args**

| Event | Args class | Fields |
|---|---|---|
| `pk-section-change` | `PkSectionChangeEventArgs` | Section: string?, Previous: string?, Id: string? |

Element details (parts, CSS custom properties, methods, accessibility): `pk-toc` in the `plainkit-sdk` skill.

## `PkTree`

`<pk-tree>`: **Tree** (Navigation). An expandable hierarchy of tree items with roving focus, single selection and type-ahead, following the WAI-ARIA tree pattern.

**Parameters**

| Parameter | Type | Enum values | Sets | Description |
|---|---|---|---|---|
| `Label` | `string?` |  | attribute `label` | Accessible name. |
| `Selection` | `TreeSelection?` | `Single` `None` | attribute `selection` | Selection mode. |
| `Value` | `string?` |  | attribute `value` | The value (or label) of the selected item. |
| `ValueChanged` | `EventCallback<string?>` |  | two-way pair of `Value` | Raised with the new value of Value (two-way: Value follows it). |
| `Navigate` | `string?` |  | attribute `navigate` | The navigate mode of items with an href that set none: router (default), host (the host navigates) or none. Who follows an Href on a plain click: "router" (default), "host" (OnNavigate is a notification and nothing navigates, so your handler uses NavigationManager) or "none" (the browser follows the address). It is the default for the items with an Href that set none. |
| `WrapLabels` | `bool` |  | attribute `wrap-labels` | Let a long item label wrap onto several lines instead of one line cut off with an ellipsis (the item hook is --pk-tree-item-label-white-space). A wrapped row keeps a small padding above and below its label (--pk-tree-item-row-padding-block). Let long item labels wrap onto several lines instead of an ellipsis. |
| `OnToggle` | `EventCallback<PkToggleEventArgs>` |  | event `pk-toggle` | A branch opened or closed (bubbles from the item). |
| `ChildContent` | `RenderFragment?` |  | default slot | Root pk-tree-item children. |

Two-way binding: `@bind-Value`.

**Event args**

| Event | Args class | Fields |
|---|---|---|
| `pk-select` | `PkSelectEventArgs` | Item: JsonElement?, Value: string?, Checked: bool?, Id: string?, Selected: string[]?, Scope: string?, Query: JsonElement? |
| `pk-toggle` | `PkToggleEventArgs` | Open: bool?, Expanded: bool?, Pressed: bool?, Value: string?, Id: string? |

Element details (parts, CSS custom properties, methods, accessibility): `pk-tree` in the `plainkit-sdk` skill.

## `PkTreeItem`

`<pk-tree-item>`: **Tree item** (Navigation). One node of a tree: a toggle, a label and nested child items.

**Parameters**

| Parameter | Type | Enum values | Sets | Description |
|---|---|---|---|---|
| `Label` | `string?` |  | attribute `label` | The text. |
| `Value` | `string?` |  | attribute `value` | The value reported in events; defaults to the label. |
| `Expanded` | `bool` |  | attribute `expanded` | Children visible. |
| `ExpandedChanged` | `EventCallback<bool>` |  | two-way pair of `Expanded` | Raised when Expanded changes (two-way binding: `@bind-Expanded`). |
| `Selected` | `bool` |  | attribute `selected` | The chosen item. |
| `SelectedChanged` | `EventCallback<bool>` |  | two-way pair of `Selected` | Raised when Selected changes (two-way binding: `@bind-Selected`). |
| `Href` | `string?` |  | attribute `href` | Makes the label a real link (middle click, copy link, status-bar URL). A plain click selects the row and is reported as a cancelable pk-navigate; a modified click navigates natively. |
| `Navigate` | `string?` |  | attribute `navigate` | Who follows the href on a click: router (default; cancelable pk-navigate), host (pk-navigate only notifies) or none (the browser follows). Empty takes the pk-tree's. Who follows an Href on a plain click: "router" (default), "host" (OnNavigate is a notification and nothing navigates, so your handler uses NavigationManager) or "none" (the browser follows the address). |
| `Disabled` | `bool` |  | attribute `disabled` | Not selectable. |
| `Expandable` | `bool` |  | attribute `expandable` | Set by the element when it has child items. |
| `ChildContent` | `RenderFragment?` |  | default slot | Child pk-tree-item elements. |
| `LabelContent` | `RenderFragment?` |  | slot `label` | A rich label; overrides label. |
| `IconContent` | `RenderFragment?` |  | slot `icon` | An icon before the label. |
| `OnSelect` | `EventCallback<PkSelectEventArgs>` |  | event `pk-select` | The row was activated. |
| `OnNavigate` | `EventCallback<PkNavigateEventArgs>` |  | event `pk-navigate` | A plain click on a row with href, before any navigation. Cancelable: the app router calls preventDefault and handles it; if nothing cancels it the row navigates normally. The event can be cancelled in the browser (preventDefault); a callback cannot cancel it. |
| `OnToggle` | `EventCallback<PkToggleEventArgs>` |  | event `pk-toggle` | The branch opened or closed. |

Two-way binding: `@bind-Expanded`, `@bind-Selected`.

When you set a named fragment (`LabelContent`, `IconContent`), write the body as an explicit `<ChildContent>` tag too: Razor does not allow an implicit body next to a named fragment.

**Event args**

| Event | Args class | Fields |
|---|---|---|
| `pk-navigate` | `PkNavigateEventArgs` | To: string?, Href: string?, Id: string?, Anchor: string?, Replace: bool? |
| `pk-select` | `PkSelectEventArgs` | Item: JsonElement?, Value: string?, Checked: bool?, Id: string?, Selected: string[]?, Scope: string?, Query: JsonElement? |
| `pk-toggle` | `PkToggleEventArgs` | Open: bool?, Expanded: bool?, Pressed: bool?, Value: string?, Id: string? |

Element details (parts, CSS custom properties, methods, accessibility): `pk-tree-item` in the `plainkit-sdk` skill.
