Tabs, Pills y Accordion para Angular | ng-hub-ui-panels
Componente de paneles de contenido para Angular que se renderiza como tabs, pills o accordion, con routing, formularios reactivos, navegación por teclado y variables CSS.
Última actualización 17 ago 2026
Visión General
Por qué los equipos buscan esta librería
Utiliza este componente de paneles para Angular cuando necesites patrones de tabs, pills y accordion desde una sola API, con paneles enrutados, binding con formularios reactivos, navegación por teclado y theming con variables CSS.
Instalación
npm install ng-hub-ui-panelsIr a
Ideal para
- páginas de ajustes
- tabs de detalle de producto
- accordions de FAQ
- secciones de dashboard
Sobre panels
ng-hub-ui-panels unifica tabs, pills y accordion en un único componente standalone de Angular construido sobre Signals. Soporta paneles enrutados, binding de formularios con ControlValueAccessor, tiras scrollables y verticales, y theming completo con --hub-panels-*. Sustituye a ng-hub-ui-accordion, cuya vista accordion reemplaza manteniendo el contrato de tokens --hub-accordion-*.
Guías de uso
Visualizaciones
Un componente, tres vistas: tabs subrayadas clásicas, pills redondeadas y paneles de divulgación de acordeón apilados, intercambiables mediante un único input `type`.
Ejemplos:
Pestañas básicas
Pestañas básicas
Pills
Pills
Vista de accordion
Vista de accordion
Tarjetas y slots de contenido
Tarjetas y slots de contenido
hubPanelHeader / hubPanelFooter slots work in tabs, pills and accordion too. A single standalone <hub-panel> (no container):
hub-panel renders as a card by itself. Slots de card (variant, flush, fill)
Slots de card (variant, flush, fill)
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.
Alertas semánticas
Alertas semánticas
An alert can use the same header/footer slots as a card:
Acento semántico del strip
Acento semántico del strip
Tab nav (tira sin contenido)
Tab nav (tira sin contenido)
Overview
The tab strip owns no content — this view is rendered by the host from active().
Selected value: overview
Disposición de la tira
Dispón la tira de cabeceras para adaptarse a cualquier shell: apílala verticalmente junto al contenido, estira las cabeceras para que ocupen todo el ancho, o haz que una tira que desborda sea desplazable.
Ejemplos:
Pestañas verticales
Pestañas verticales
Pestañas justificadas
Pestañas justificadas
Pestañas desplazables
Pestañas desplazables
Gestión de paneles
Deshabilita paneles individuales y permite a los usuarios añadir o eliminar paneles sobre la marcha con el control ✕ y la tecla Delete.
Ejemplos:
Paneles deshabilitados
Paneles deshabilitados
Paneles eliminables y dinámicos
Paneles eliminables y dinámicos
Plantillas personalizadas
Reemplaza la cabecera de texto plano con cualquier template de Angular —iconos, badges o controles interactivos— mediante la directiva `hubPanelHeading`.
Ejemplos:
Plantillas de cabecera personalizadas
Plantillas de cabecera personalizadas
Acciones de fila del acordeón
Acciones de fila del acordeón
Integración con formularios
El soporte de primer nivel de ControlValueAccessor vincula el panel o paneles activos a los formularios reactivos y basados en template de Angular.
Ejemplos:
Integración con formularios reactivos
Integración con formularios reactivos
Selección múltiple
Con `multiple`, varios paneles pueden estar abiertos a la vez. En la vista de acordeón todos se expanden; en las vistas de tabs/pills, cada cabecera activa inicia su propio panel visible, mientras que las cabeceras inactivas siguientes permanecen agrupadas por encima de ese panel hasta que la siguiente cabecera activa inicia un nuevo bloque.
Ejemplos:
Selección múltiple
Selección múltiple
Click an inactive tab to split the layout into a new panel block. Click an active tab to merge that block back.
Múltiples cabeceras verticales
Múltiples cabeceras verticales
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
Pills
Opciones del acordeón
La vista de acordeón admite varios paneles expandidos simultáneamente y un layout `flush` de borde a borde sin marco exterior.
Ejemplos:
Acordeón múltiple y flush
Acordeón múltiple y flush
Accesibilidad
Navegación completa por teclado (flechas, Home, End, Delete), tabindex móvil y roles ARIA correctos tanto para el patrón de tablist como para el de divulgación de acordeón.
Ejemplos:
Navegación por teclado
Navegación por teclado
Focus a tab, then use ← → Home End. Press Delete on a removable tab to close it.
Características clave
Cambios recientes
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.