Angular 标签、Pills 与手风琴组件 | ng-hub-ui-panels

Angular 内容面板组件,可渲染为标签、pills 或手风琴,支持路由、响应式表单、键盘导航和 CSS 变量。

API 参考

这里是 panels 的完整契约:你可以绑定、监听、投影和设置主题的一切,都集中在一处。接入你需要的部分,自定义你想要的样式——它是 standalone 的,且对 signal 友好。

输入

通过 40 个输入项精细调校 panels。像绑定任意 Angular @Input 一样绑定它们。

名称类型默认值描述
type'tabs' | 'pills' | 'accordion' | 'card''tabs'容器的可视化方式:下划线 tabs、圆角 pills、堆叠的 accordion 面板,或始终可见的无边框 cards。
verticalbooleanfalse将头部条垂直堆叠在内容旁边(tabs / pills 视图)。
justifiedbooleanfalse拉伸各头部以平均分配可用宽度。
scrollablebooleanfalse当头部条溢出时,添加前进/后退滚动按钮。
isKeysAllowedbooleantrue启用键盘导航(方向键 / Home / End / Delete)。
multiplebooleanfalse允许多个面板同时处于激活状态。在 accordion 视图中它们会全部展开;在 tabs/pills 视图中,每个激活的头部都会开启一个可见的面板块,随后的未激活头部会分组停留在该块上方,直到下一个激活的头部开启新的块为止。表单值变为数组。
flushbooleanfalseAccordion 视图:无外边框或圆角的贴边面板。
togglePosition'start' | 'end''end'用于 <hub-panels>(手风琴视图):展开箭头位于标题行的哪一侧。"end"(默认)跟在标题之后,"start" 位于标题之前。仅视觉顺序改变——DOM 保持不变——且偏移使用逻辑属性,因此 "start" 在 LTR 中为左边缘,在 RTL 中为右边缘。可通过 HubPanelsConfig.togglePosition 设置全应用默认值。
variantHubPanelVariant | stringundefinedhub-panels:导航条的语义强调色——激活/悬停的标签页、激活的胶囊和激活的手风琴标题都会随之改变。内置值('primary' | 'success' | 'danger' | 'warning' | 'info')使用设计系统色调,但也接受任意字符串:导航条会读取应用中的 --hub-sys-color-<variant>。默认为 primary。
bindValuestringundefined应用于每个面板的 value 的点分路径,用于获取所发出的表单值(例如 'meta.key')。
compareWith(a: unknown, b: unknown) => boolean(a, b) => a === b用于将表单值与面板值进行匹配的相等判断。
headingstringundefinedhub-panel:纯文本头部。当提供 hubPanelHeading 模板时将被忽略。
appearance'card' | 'alert''card'hub-panel:独立面板的外观——'card'(默认)或语义化的 'alert' 提示。在 tabs/pills/accordion 视图中忽略。
variantHubPanelVariant | stringundefinedhub-panel:面板的语义强调色——为 alert 着色,并为整张 card 上色(以 data-variant 反映)。内置值('primary' | 'success' | 'danger' | 'warning' | 'info')使用设计系统色调,但也接受任意字符串:面板会读取应用中的 --hub-sys-color-<variant>。省略则为中性面板。
fillbooleanfalse仅 card 面板:填满父元素高度并让主体滚动,从而使内部的 flex:1/min-height:0 区域(例如标签条 + 滚动窗格)有界。父元素必须是 flex 列。
standaloneboolean (static attribute)false仅 card 面板,静态属性:让同一模板中的独立 <hub-panel> 脱离祖先 tabs/pills/accordion 分组,使其渲染为普通 card,而不是被捕获为隐藏标签页。
idstring'hub-panel-<n>'hub-panel:用于标签页与其面板(或手风琴标题与其区域)之间 ARIA 关联的 id。自动生成为 hub-panel-<n>;当你需要稳定的 id(例如深层链接或自定义 aria-controls)时可自行设置。
valueunknownidhub-panel:当容器用作表单控件时贡献的值。
activeboolean (model)falsehub-panel:双向绑定的激活/展开状态。
disabledbooleanfalsehub-panel:阻止该面板被激活。
removablebooleanfalsehub-panel:显示一个 ✕ 操作提示,并允许使用 Delete 键移除。
removeLabelstring'Remove panel'hub-panel:为 ✕ 移除按钮朗读的无障碍名称(aria-label);覆盖它以本地化该控件。
routerLinkstring | string[]undefinedhub-panel:将面板转变为由 <router-outlet> 支撑的路由面板。
queryParamsParamsundefinedhub-panel:导航到 routerLink 时附加的查询参数。
pathMatch'route' | 'full''route'hub-panel:用于将路由面板标记为激活的 URL 比较。
customClassstringundefinedhub-panel:同时应用于导航项和面板内容区的额外 CSS 类。
itemsHubTabNavItem[][]<hub-tab-nav> 中可选中的标签,按渲染顺序排列。每一项都是一个轻量的 { value, label, disabled?, id? } 描述符——该标签条本身不承载任何内容,因此当标签被选中时,它发出的正是 value。
activeunknown (model)undefined<hub-tab-nav> 的双向绑定选中值。设置它可预先选中某个标签,并通过 activeChange 读回;匹配的项即是其 value 与此值相等的那一项。
appearance'tabs' | 'pills''tabs'<hub-tab-nav> 标签条的视觉外观:经典下划线式 'tabs'(默认)或圆角 'pills'。
justifiedbooleanfalse当为 true 时,<hub-tab-nav> 的各标签会拉伸以均分可用宽度。
verticalbooleanfalse当为 true 时,<hub-tab-nav> 标签条将各标签垂直堆叠,而不是横向排成一行。
modeHubSidePanelMode'side'<hub-side-panel>:'side' 停靠面板并收窄内容为其腾出空间;'over' 让其浮于内容边缘之上,没有遮罩、滚动锁定或焦点陷阱。
positionHubSidePanelPosition'end'<hub-side-panel>:面板所在容器的逻辑行内边缘——'end' 在 LTR 中是右边缘,在 dir="rtl" 下是左边缘。
openboolean (model)false<hub-side-panel>:双向打开状态。关闭只会隐藏面板而不会销毁其投影内容,因此其中的聊天或表单会保留状态。
closeOnEscapebooleantrue<hub-side-panel>:在面板内按下 Escape 是否关闭它。在页面上按下的 Escape 从不被截获;如果内部控件已处理该按键,面板保持打开。
breakpointnumber768<hub-side-panel>:容器行内尺寸(px)低于此值时,side 面板以 over 方式渲染,因为在窄屏上停靠的面板会挤压内容。设为 0 则在任何宽度下保持停靠。
autoFocusbooleanfalse<hub-side-panel>:打开时是否将焦点移入面板——移到第一个 [autofocus] 元素,否则移到第一个可聚焦元素,否则移到面板本身。默认关闭。
roleHubSidePanelRole'complementary'<hub-side-panel>:地标角色——位于页面主内容旁时用 'complementary',位于主内容内部时用 'region'。
ariaLabelstringundefined<hub-side-panel>:地标的无障碍名称。设置此项或 ariaLabelledBy。
ariaLabelledBystringundefined<hub-side-panel>:为地标命名的元素 id,通常是头部插槽中的标题。

输出

响应 panels 的行为——有 7 个事件可供你挂接逻辑。

名称类型描述
panelChangeOutputEmitterRef<PanelChangeEvent>hub-panels:当用户激活(打开)不同面板时触发。提供 { current, prev }。
selectPanelOutputEmitterRef<HubPanelComponent>hub-panel:当面板变为激活状态时触发。
deselectPanelOutputEmitterRef<HubPanelComponent>hub-panel:当面板不再处于激活状态时触发。
removedOutputEmitterRef<HubPanelComponent>hub-panel:当面板通过 ✕ 按钮或 Delete 键被移除时触发。
activeChangeOutputEmitterRef<boolean>hub-panel:双向 active 模型中负责变更的一半,携带面板新的激活/展开状态发出。
activeChangeOutputEmitterRef<unknown>每当选中值发生变化时由 <hub-tab-nav> 发出(双向 active 模型中负责变更的一半),携带新选中项的 value。
openChangeOutputEmitterRef<boolean><hub-side-panel>:双向 open 模型的变更部分;无论由谁更改(绑定、Escape、toggle() 或 close()),都会携带新状态发出。

方法

通过代码驱动 panels——其编程接口提供 6 个方法。

名称签名返回值描述
HubPanelsComponent.selectPanelselectPanel(panel: HubPanelComponent): void—像用户点击一样激活一个面板:将其标记为激活、在路由面板上执行导航并发出 panelChange。对禁用的面板不做任何处理。
HubPanelsComponent.togglePaneltogglePanel(panel: HubPanelComponent): void—在手风琴视图中切换一个面板,并遵循 multiple:未开启 multiple 时,打开一个会折叠其余面板。
HubPanelsComponent.removePanelremovePanel(panel: HubPanelComponent, options?: { reselect?: boolean; emit?: boolean }): void—从分组中移除一个面板。reselect 决定是否由另一个面板接替,emit 决定移除是否通过 panelChange 通知。
HubPanelsComponent.removePanelAndRefocusremovePanelAndRefocus(panel: HubPanelComponent): void—移除一个面板,并把键盘焦点交给最近的剩余标题,因此移除永远不会让焦点掉回 body。✕ 按钮和 Delete 键调用的正是它。
HubSidePanelComponent.toggletoggle(force?: boolean): void—打开或关闭面板;传入 true 或 false 可强制设定状态,而不是切换。
HubSidePanelComponent.closeclose(): void—关闭面板。如果焦点在面板内,则返回到面板打开时持有焦点的元素。

模板

打造你自己的样式——3 个模板插槽让你可以投影自定义标记。

名称描述示例
hubPanelHeading将 hub-panel 内的 <ng-template> 标记为该面板的自定义头部(tabs/pills 中的条目链接,accordion 中的展开按钮),以替代纯文本的 heading 输入。<hub-panel> <ng-template hubPanelHeading> <i class="fa-solid fa-gear"></i> Settings <hub-badge color="primary" shape="rounded">3</hub-badge> </ng-template> Panel content </hub-panel>
hubPanelHeader / hubPanelFooter将 hub-panel 内的元素标记为面板内容的页眉/页脚栏。在所有视图(tabs、pills、accordion、card)中均会渲染,区别于 hubPanelHeading。<hub-panel> <div hubPanelHeader>Card title</div> Card content <div hubPanelFooter>Actions</div> </hub-panel>
type="card"无修饰的卡片可视化:没有导航条,每个面板始终可见。hub-panel 也可以独立使用(在任何 hub-panels 之外),此时它会渲染为一张卡片。<hub-panels type="card"> <hub-panel>…</hub-panel> <hub-panel>…</hub-panel> </hub-panels>