Tabs, Pills и Accordion для Angular | ng-hub-ui-panels

Компонент панелей контента для Angular, который отображается как вкладки, pills или accordion, с маршрутизацией, реактивными формами, навигацией с клавиатуры и CSS-переменными.

Последнее обновление 17 авг. 2026 г.

Обзор

Почему команды ищут эту библиотеку

Используйте этот компонент панелей для Angular, когда нужны паттерны вкладок, pills и accordion из единого API, с маршрутизируемыми панелями, привязкой к реактивным формам, навигацией с клавиатуры и тематизацией через CSS-переменные.

Установка

npm install ng-hub-ui-panels

Перейти к

Идеально для

  • страницы настроек
  • вкладки деталей товара
  • accordion для FAQ
  • разделы дашборда

О библиотеке panels

ng-hub-ui-panels объединяет вкладки, pills и accordion в единый standalone-компонент Angular, построенный на Signals. Он поддерживает маршрутизируемые панели, привязку форм через ControlValueAccessor, прокручиваемые и вертикальные полосы, а также полную тематизацию через --hub-panels-*. Он заменяет ng-hub-ui-accordion, чьё представление accordion он замещает, сохраняя контракт токенов --hub-accordion-*.

Руководства по возможностям

Визуализации

Один компонент, три представления: классические подчёркнутые tabs, скруглённые pills и стекированные панели раскрытия accordion — переключаемые через один input `type`.

Примеры:
Базовые вкладки

Базовые вкладки

The first enabled panel is activated automatically.
Switch panels with a click or the arrow keys.
Each panel projects its own content.
Pills

Pills

Account settings live here.
Password and two-factor options.
Email and push preferences.
Режим accordion

Режим accordion

Карточки и слоты контента

Карточки и слоты контента

Project summary
No tabs, no pills — every panel is always visible and styled as a card.
Team
The same hubPanelHeader / hubPanelFooter slots work in tabs, pills and accordion too.

A single standalone <hub-panel> (no container):

Standalone card
Dropped on its own, a hub-panel renders as a card by itself.
Слоты карточки (variant, flush, fill)

Слоты карточки (variant, flush, fill)

Success
A plain card honours [variant] — one accent tints the whole frame.
Danger
No colour values added — derived by color-mix like the alert.
Info
Set --hub-panels-card-border-style: dashed for an empty-state look.
Normal padding
Padded body — there is a gap around this strip.
Flush
Flush body — this strip runs edge-to-edge to the card sides.
Fill + scroll

Row 1 — the body scrolls; the header stays put.

Row 2 — the body scrolls; the header stays put.

Row 3 — the body scrolls; the header stays put.

Row 4 — the body scrolls; the header stays put.

Row 5 — the body scrolls; the header stays put.

Row 6 — the body scrolls; the header stays put.

Row 7 — the body scrolls; the header stays put.

Row 8 — the body scrolls; the header stays put.

Row 9 — the body scrolls; the header stays put.

Row 10 — the body scrolls; the header stays put.

Row 11 — the body scrolls; the header stays put.

Row 12 — the body scrolls; the header stays put.

Row 13 — the body scrolls; the header stays put.

Row 14 — the body scrolls; the header stays put.

Row 15 — the body scrolls; the header stays put.

Row 16 — the body scrolls; the header stays put.

Row 17 — the body scrolls; the header stays put.

Row 18 — the body scrolls; the header stays put.

Row 19 — the body scrolls; the header stays put.

Row 20 — the body scrolls; the header stays put.

Семантические оповещения

Семантические оповещения

Heads up — a new version is available.
Your changes were saved successfully.
Your trial ends in 3 days.
Something went wrong while saving.
Tip: you can pin panels for quick access.
A neutral notice with no semantic variant.

An alert can use the same header/footer slots as a card:

Payment failed
We couldn't process your card. Update your billing details to keep your subscription active.
Семантический акцент панели

Семантический акцент панели

The active tab follows the success accent.
Switch tabs to see the accent move.
No per-colour CSS — one accent drives it all.
The active pill fills with the danger accent.
Hover the inactive pills too.
Everything derives from a single token.
A custom or built-in variant works the same way.
Active pill uses the warning accent.
Панель вкладок (полоса без содержимого)

Панель вкладок (полоса без содержимого)

Overview

The tab strip owns no content — this view is rendered by the host from active().

Selected value: overview

Компоновка полосы

Компонуйте полосу заголовков под любой shell: располагайте её вертикально рядом с содержимым, растягивайте заголовки на всю ширину или делайте переполненную полосу прокручиваемой.

Примеры:
Вертикальные вкладки

Вертикальные вкладки

Your public profile information.
Invoices and payment methods.
Manage members and roles.
Выровненные вкладки

Выровненные вкладки

Today's agenda.
The seven-day view.
The full month at a glance.
Прокручиваемые вкладки

Прокручиваемые вкладки

Content for section 1.
Content for section 2.
Content for section 3.
Content for section 4.
Content for section 5.
Content for section 6.
Content for section 7.
Content for section 8.

Управление панелями

Отключайте отдельные панели и позволяйте пользователям добавлять или удалять панели на лету с помощью элемента ✕ и клавиши Delete.

Примеры:
Отключённые панели

Отключённые панели

This panel is selectable.
This panel is disabled.
Arrow keys skip the disabled panel.
Удаляемые и динамические панели

Удаляемые и динамические панели

Content for Tab 1.
Content for Tab 2.
Content for Tab 3.

Пользовательские шаблоны

Замените текстовый заголовок любым Angular-шаблоном — иконками, бейджами или интерактивными элементами управления — через директиву `hubPanelHeading`.

Примеры:
Пользовательские шаблоны заголовков

Пользовательские шаблоны заголовков

Twelve unread messages.
Messages you have sent.
Recently deleted items.
Действия строки аккордеона

Действия строки аккордеона

Интеграция с формами

Полноценная поддержка ControlValueAccessor привязывает активную панель(и) к реактивным и шаблонным формам Angular.

Примеры:
Интеграция с реактивными формами

Интеграция с реактивными формами

Light theme preview.
Dark theme preview.
Follows the OS setting.
Selected value: "dark"

Множественный выбор

С `multiple` несколько панелей могут быть открыты одновременно. В представлении accordion все они разворачиваются; в представлениях tabs/pills каждый активный заголовок начинает собственную видимую панель, тогда как следующие неактивные заголовки остаются сгруппированными над этой панелью до тех пор, пока следующий активный заголовок не начнёт новый блок.

Примеры:
Множественный выбор

Множественный выбор

Click an inactive tab to split the layout into a new panel block. Click an active tab to merge that block back.

Key metrics and a quick overview of the account.
Detailed statistics and charts for the period.
A chronological feed of recent activity.
Free-form notes shared with the team.
Open panels: [ "summary", "stats" ]
Несколько вертикальных заголовков

Несколько вертикальных заголовков

Each active header starts a new row-like vertical block. The blocks stack top-to-bottom, and the whole layout scrolls horizontally only when one row needs more width.

Tabs
Public profile details and biography.
Invoices, payment methods and VAT details.
Members, roles and access levels.
Shared internal notes for the account.
Open tabs: [ "profile", "team" ]
Pills
Open items waiting for review.
Approvals and pending checks.
Publication options and scheduling.
Historical records and exported snapshots.
Open pills: [ "inbox", "publish" ]

Опции accordion

Представление accordion поддерживает несколько одновременно развёрнутых панелей и компоновку `flush` от края до края без внешнего обрамления.

Примеры:
Аккордеон: множественный режим и без рамок

Аккордеон: множественный режим и без рамок

Standard delivery in 3–5 business days.

Free returns within 30 days.

Доступность

Полная навигация с клавиатуры (стрелки, Home, End, Delete), roving tabindex и корректные ARIA-роли как для паттерна tablist, так и для паттерна раскрытия accordion.

Примеры:
Навигация с клавиатуры

Навигация с клавиатуры

Focus a tab, then use ← → Home End. Press Delete on a removable tab to close it.

Use the arrow keys to move focus between headers.
Home and End jump to the first and last enabled header.
Press Delete while focused to remove this panel.

Ключевые возможности

Последние изменения

Version 22.10.1 - 8/8/26, 12:00 AM

fixed: Documentation links now point at the canonical localized URLs. The README linked to https://hubui.dev/<path> with no locale prefix and no trailing slash, and both forms are 301-redirected, so every reader arriving from npm or GitHub landed on a redirect instead of the canonical page.

Version 22.10.0 - 7/28/26, 12:00 AM

changed: Accent resolution now imports the canonical resolveHubAccent from ng-hub-ui-utils; the private in-library copy was deleted. Behaviour is identical.

added: New required peer dependency: ng-hub-ui-utils >=22.7.0 (home of resolveHubAccent). ng add ng-hub-ui installs it automatically; manual installs need npm i ng-hub-ui-utils.

Version 22.9.0 - 7/28/26, 12:00 AM

added: New removeLabel input on <hub-panel> (default "Remove panel"): the accessible name announced for the ✕ remove button, overridable per panel so consumers can localize it.

fixed: The ✕ remove control was an aria-hidden <span> nested inside the tab / disclosure <button> — unfocusable, unannounced and unreachable by keyboard. It is now a real <button type="button"> with an aria-label, rendered as a SIBLING of the header control (the slot pattern hubPanelHeadingActions introduced): beside the tab button in the strip views, inside the accordion actions area at the row end. Clicking it still removes without toggling or selecting, it is disabled with its panel, and the .hub-panels__remove-btn class and its opacity tokens are unchanged.

fixed: Removing a panel through the ✕ now returns keyboard focus to the closest remaining header (as the Delete key already did) instead of dropping it on <body>. New public removePanelAndRefocus(panel) method on PanelsComponent, shared by the Delete-key handlers.

Version 22.8.3 - 7/26/26, 12:00 AM

fixed: Declared the real ng-hub-ui-ds peer range (>=22.0.0); the previous >=1.0.0 floor predates the --hub-ref-*/--hub-sys-* token architecture.

Version 22.8.0 - 7/9/26, 12:00 AM

added: New hubPanelHeadingActions directive: a header-row slot for accordion affordances that must stay usable while the row is collapsed (edit, delete, a menu). It renders as a sibling of the disclosure button, so its controls are real controls, a click never toggles the panel and tab order follows the DOM. hubPanelHeading projects INSIDE that button (a nested <button> is invalid and unreachable by keyboard) and hubPanelHeader projects inside the collapse region (it vanishes when the row closes), so until now there was nowhere to put them.

added: New togglePosition input on <hub-panels> (start | end, default end; also on PanelsConfig): which side of the accordion header row the disclosure chevron sits on. Only the visual order moves — the DOM is untouched — and the offsets are logical, so start is the left edge in LTR and the right edge in RTL. Replaces the ::ng-deep order/margin override consumers were writing by hand. Exports the HubPanelsTogglePosition type.

changed: .hub-panels__accordion-header is now a flex row carrying the row surface (with a new --expanded modifier), the disclosure button being its flex child, so the actions slot shares the background in both states. The button’s own background rules are unchanged.

fixed: RTL in the accordion header: the disclosure button used the physical text-align: left and its chevron margin-left: auto, so under dir="rtl" the label stayed left-aligned and the chevron pinned to the wrong edge. Both are logical now.

Version 22.7.0 - 7/8/26, 12:00 AM

added: New --hub-panels-tab-border-end-radius token: the radius of a vertical tab’s corners on the edge that meets the panel body. They used to be hardcoded to 0, so the active tab always docked flush into the panel. Defaults to 0 (no visual change); raise it to render fully-rounded, standalone rail items such as a routed settings/profile subnav.

Version 22.6.0 - 7/7/26, 12:00 AM

added: New hub-panels-theme(...) SCSS mixin: one-call token theming for <hub-panels>. $accent feeds the single --hub-panels-accent slot (the component derives the emphasis/subtle/on family), alongside the panel surface and the tab appearance. Every parameter is null-defaulted and additive; for any token not exposed, set the --hub-panels-* custom property directly.

changed: Packaging: the library now ships its SCSS at /styles, exposing hub-panels-theme as a first-class package entry (@use 'ng-hub-ui-panels/styles' as *;).

Version 22.5.0 - 7/7/26, 12:00 AM

changed: variant on <hub-panel> / <hub-panels> now accepts ANY colour: on top of the built-in semantic accents it takes a registered custom accent or a literal colour (#ff0000, rgb(...), oklch(...), a CSS named colour), resolved through the shared resolveHubAccent helper. The single accent slot derives the rest of the family, so built-in colours are unchanged.

changed: Internal: @HostBinding / @HostListener decorators replaced by the host metadata object (Angular style guide). No public API or behaviour change.

Version 22.4.0 - 7/5/26, 12:00 AM

added: New <hub-tab-nav> — a lightweight, content-less, value-bound tab strip (role=tablist) that emits the selected value via a two-way active model, for segmented controls / filter switches / manual tabs-with-external-content. Supports tabs/pills appearances, justified/vertical layouts and roving-tabindex keyboard nav.

added: Card panels now honour [variant]: a plain card reflects data-variant and tints its bg/text/border from a single inline accent (--hub-panels-card-accent) with the same open color-mix + ds-tint model as the alert. New --hub-panels-card-border-style (e.g. dashed empty-state cards).

added: New <hub-panel flush> input (zero card body padding) and <hub-panel fill> input (fill-height card with a scrolling body; the wrappers gain stable classes and --hub-panels-body-gap spaces stacked children).

added: New <hub-panel standalone> static attribute: opts a loose panel out of an ancestor tabs/pills/accordion group in the same template so it renders as a plain card (the case host: true cannot cover).

changed: --hub-panels-card-box-shadow and --hub-panels-panel-header-bg are now inheritable (default moved to the usage-site var() fallback) so an ancestor can set them; identical default, no visual change.

Version 22.3.0 - 7/2/26, 12:00 AM

fixed: A standalone <hub-panel> nested (transitively) inside a tab pane no longer registers as a hidden tab of the outer <hub-panels>: the group injection is now bounded with host: true, so a panel binds only to a group declared in the same template and renders as a card/alert otherwise. The providers: [{ provide: PanelsComponent, useValue: null }] workaround is no longer needed.

changed: Canonical accent-slot derivation: the group role family (emphasis/subtle/on) now derives locally from the single --hub-panels-accent slot with the design-system formulas, so custom accents re-derive the full family at runtime; built-in variants only re-base the accent slot.

changed: The alert open-set default (appearance="alert" with a custom variant) uses the same canonical tints as the built-ins (12% background over surface, 80% text over ink).

Version 22.2.0 - 6/26/26, 12:00 AM

added: Open-set accent variants: <hub-panels variant="…"> and <hub-panel appearance="alert" variant="…"> ship all 9 built-ins (primary…dark) with exact ds tints, and any custom string keeps working at runtime by defining a single --hub-sys-color-<name>.

Version 22.1.0 - 6/22/26, 12:00 AM

added: New variant input on <hub-panels> selecting the semantic accent of the navigation strip (active/hover tab, active pill, active accordion header). Built-in variants (primary | success | danger | warning | info) use the exact design-system tints; any custom string is also accepted and derived with color-mix. Defaults to primary.

added: New group-accent tokens --hub-panels-accent, --hub-panels-accent-emphasis and --hub-panels-accent-subtle; the strip active/hover affordances now resolve through this single accent instead of being hard-wired to --hub-sys-color-primary*.

changed: The outer container chrome now inherits from the --hub-container-* base layer (re-base hook), so overriding a container token on a subtree re-bases the panels chrome. No visual change with default tokens.

Version 21.3.0 - 6/16/26, 12:00 AM

added: New alert appearance for a standalone <hub-panel>: appearance="alert" with a variant renders a semantic callout (role="alert").

added: New variant input (primary | success | danger | warning | info) selecting the alert colour; omit it for a neutral alert. Exported HubPanelAppearance and HubPanelVariant types.

added: New alert tokens (--hub-panels-alert-*); each variant re-points them at the --hub-sys-color-<variant>-{subtle,border-subtle,emphasis} family, so the alert inherits every theme and dark mode automatically.

Version 21.2.0 - 6/14/26, 12:00 AM

added: New card visualization (type="card"): a chromeless format with no navigation strip where every <hub-panel> is always visible and styled as a card.

added: A <hub-panel> can now be used standalone, outside any <hub-panels> container, rendering as a card on its own.

added: New content-slot directives hubPanelHeader and hubPanelFooter, rendering header/footer bands in every view, distinct from the navigational hubPanelHeading.

Version 21.1.1 - 6/12/26, 12:00 AM

added: New token: --hub-panels-header-bg, used by the tabs/pills strip background while defaulting to the panel surface.

added: New token: --hub-panels-pill-content-border-width, which controls the bordered card chrome in the pills content area.

changed: The active header background now defaults to --hub-panels-content-bg so the active tab/panel fusion stays aligned when themes retint the content surface.

changed: The pills content area is borderless by default; themes can opt back into a bordered card by overriding --hub-panels-pill-content-border-width.

Version 21.1.0 - 6/11/26, 12:00 AM

added: Multiple selection in the tabs/pills views: each open pane becomes its own bordered box placed next to the others (side by side when horizontal, stacked when vertical), with a per-pane minimum and scroll on overflow.

added: New tokens: --hub-panels-pane-min-width, --hub-panels-pane-min-height, --hub-panels-pane-gap, --hub-panels-nav-content-gap, --hub-panels-pill-gap.

fixed: Accordion content was always empty (two unselected ng-content slots); replaced with a single projection slot.

fixed: tabs and vertical tabs now render as a single bordered box around the strip and content together (not two boxes); pills gain spacing before a bordered content card.

changed: Smooth strip scrolling, not-allowed cursor on disabled headers, and full-width container.

Version 21.0.0 - 6/11/26, 12:00 AM

added: Initial release of ng-hub-ui-panels with tabs, pills and accordion visualizations.

added: ControlValueAccessor integration with single and multiple selection, bindValue and compareWith.

added: Routed panels via routerLink with route/full pathMatch and a <router-outlet> content area.

added: Keyboard navigation (arrows/Home/End/Delete), scrollable, vertical and justified strips.

added: Accordion view with multiple expansion, flush layout and an animated grid-based collapse.

added: Custom header templates through the hubPanelHeading directive and full --hub-panels-* theming.

changed: Supersedes ng-hub-ui-accordion; the accordion view honours the --hub-accordion-* token contract for theme compatibility.

Связанные библиотеки