Angular 工具库 | ng-hub-ui-utils
Angular 工具库,包含 pipes、焦点管理、overlay、过渡和翻译助手,供可复用 UI 组件共享使用。
最后更新 2026年8月26日
概览
团队为何搜索这个库
使用这个 Angular 工具库,避免重写 overlay、焦点陷阱、翻译助手和常见模板工具背后的底层部件。
安装
npm install ng-hub-ui-utils跳转到
适用于
- 共享 UI 基础设施
- overlay 系统
- 焦点管理
- 模板助手
关于 utils
ng-hub-ui-utils 是众多可复用 UI 模式背后的共享基础。当 Angular 团队希望集中管理那些让 overlay 系统、焦点管理、pipes 和翻译助手在各项目间保持一致的底层部件时,它会非常有用。
功能指南
焦点管理
在元素内捕获并管理键盘焦点
示例:
焦点捕获
使用 hubFocusTrap() 将焦点限定在 modal 或对话框内。
Focus Trap Demo
Click "Enable Focus Trap" and try to Tab outside the blue box. Focus will stay trapped inside.
Focus Trap Area
Status: 🔓 Free
Focusable Elements
The selector FOCUSABLE_ELEMENTS_SELECTOR finds all focusable elements.
getFocusableBoundaryElements(container)→ [first, last] elements可聚焦元素
使用 getFocusableBoundaryElements() 查询边界处的可聚焦元素。
Focus Trap Demo
Click "Enable Focus Trap" and try to Tab outside the blue box. Focus will stay trapped inside.
Focus Trap Area
Status: 🔓 Free
Focusable Elements
The selector FOCUSABLE_ELEMENTS_SELECTOR finds all focusable elements.
getFocusableBoundaryElements(container)→ [first, last] elements国际化(i18n)
用于多语言支持的翻译服务和 pipes
示例:
翻译服务
HubTranslationService 用于管理翻译
TranslatePipe - Basic usage
'welcome' | translate→ Welcome to ng-hub-uiTranslatePipe - With parameters
'greeting' | translate:{ name: 'Carlos' }→ Hello, Carlos!TranslatePipe - Nested keys
'buttons.save' | translate→ Save'buttons.cancel' | translate→ CancelProgrammatic access
translationService.getTranslation('buttons.delete')→ Delete翻译 pipe
TranslatePipe 用于模板中的翻译
TranslatePipe - Basic usage
'welcome' | translate→ Welcome to ng-hub-uiTranslatePipe - With parameters
'greeting' | translate:{ name: 'Carlos' }→ Hello, Carlos!TranslatePipe - Nested keys
'buttons.save' | translate→ Save'buttons.cancel' | translate→ CancelProgrammatic access
translationService.getTranslation('buttons.delete')→ Delete翻译 provider
provideHubTranslations() 用于应用配置
TranslatePipe - Basic usage
'welcome' | translate→ Welcome to ng-hub-uiTranslatePipe - With parameters
'greeting' | translate:{ name: 'Carlos' }→ Hello, Carlos!TranslatePipe - Nested keys
'buttons.save' | translate→ Save'buttons.cancel' | translate→ CancelProgrammatic access
translationService.getTranslation('buttons.delete')→ Delete外部 i18n 适配器
在 app.config.ts 中配置一个响应式翻译桥接器,供所有 Hub UI 库使用。
在 app.config.ts 中配置一个响应式翻译桥接器,供所有 Hub UI 库使用。
代码
导入:
模板:
组件:
覆盖层系统
创建定位的 overlays 和浮动元素
示例:
Overlay 服务
HubOverlayService 用于以编程方式创建 overlay
A connected overlay positioned below the trigger, with a backdrop that closes it on outside click.
Overlay 引用
OverlayRef 用于管理 overlay 的生命周期
A connected overlay positioned below the trigger, with a backdrop that closes it on outside click.
定位
ConnectionPositionPair 用于灵活定位
A connected overlay positioned below the trigger, with a backdrop that closes it on outside click.
Popup 服务
简化的 popup 管理
示例:
Popup 创建
HubPopupService 用于快速创建 popup
A connected overlay positioned below the trigger, with a backdrop that closes it on outside click.
Pipes
用于模板的工具 pipes
示例:
类型检查 pipes
IsStringPipe、IsObjectPipe、IsObservablePipe
GetPipe - Access nested properties
user | get:'profile.name'→ John Doeuser | get:'profile.address.city'→ New YorkIsStringPipe - Type checking
'Hello' | isString→ true123 | isString→ falseIsObjectPipe - Object detection
{ a: 1 } | isObject→ true'string' | isObject→ falseUcfirstPipe - Capitalize first letter
'hello world' | ucfirst→ Hello worldGetPipe
使用点号表示法访问嵌套对象属性
GetPipe - Access nested properties
user | get:'profile.name'→ John Doeuser | get:'profile.address.city'→ New YorkIsStringPipe - Type checking
'Hello' | isString→ true123 | isString→ falseIsObjectPipe - Object detection
{ a: 1 } | isObject→ true'string' | isObject→ falseUcfirstPipe - Capitalize first letter
'hello world' | ucfirst→ Hello worldUcfirstPipe
将字符串的首字母大写
GetPipe - Access nested properties
user | get:'profile.name'→ John Doeuser | get:'profile.address.city'→ New YorkIsStringPipe - Type checking
'Hello' | isString→ true123 | isString→ falseIsObjectPipe - Object detection
{ a: 1 } | isObject→ true'string' | isObject→ falseUcfirstPipe - Capitalize first letter
'hello world' | ucfirst→ Hello worldUnwrapAsyncPipe
在模板中解包 observables 和 promises
GetPipe - Access nested properties
user | get:'profile.name'→ John Doeuser | get:'profile.address.city'→ New YorkIsStringPipe - Type checking
'Hello' | isString→ true123 | isString→ falseIsObjectPipe - Object detection
{ a: 1 } | isObject→ true'string' | isObject→ falseUcfirstPipe - Capitalize first letter
'hello world' | ucfirst→ Hello world工具函数
通用的 helper 函数
示例:
Type guards
isString()、isNumber()、isDefined()、isPromise()
Type Guards
isString('hello')→ trueisNumber(42)→ trueisDefined(null)→ falseisDefined('value')→ trueDeep Equality
equals({a:1}, {a:1})→ trueequals([1,2], [1,2])→ trueObject Access
getValue(user, 'profile.name')→ John DoeString Interpolation
interpolateString('Hello {{name}}', {name: 'World'})→ Hello WorldString Utilities
removeAccents('Ñoño café')→ Nono cafepadNumber(5)→ 05字符串工具
removeAccents()、interpolateString()、regExpEscape()
Type Guards
isString('hello')→ trueisNumber(42)→ trueisDefined(null)→ falseisDefined('value')→ trueDeep Equality
equals({a:1}, {a:1})→ trueequals([1,2], [1,2])→ trueObject Access
getValue(user, 'profile.name')→ John DoeString Interpolation
interpolateString('Hello {{name}}', {name: 'World'})→ Hello WorldString Utilities
removeAccents('Ñoño café')→ Nono cafepadNumber(5)→ 05对象工具
equals() 用于深度比较,getValue() 用于点分表示法
Type Guards
isString('hello')→ trueisNumber(42)→ trueisDefined(null)→ falseisDefined('value')→ trueDeep Equality
equals({a:1}, {a:1})→ trueequals([1,2], [1,2])→ trueObject Access
getValue(user, 'profile.name')→ John DoeString Interpolation
interpolateString('Hello {{name}}', {name: 'World'})→ Hello WorldString Utilities
removeAccents('Ñoño café')→ Nono cafepadNumber(5)→ 05DOM 工具
closest()、reflow()、getActiveElement()
Type Guards
isString('hello')→ trueisNumber(42)→ trueisDefined(null)→ falseisDefined('value')→ trueDeep Equality
equals({a:1}, {a:1})→ trueequals([1,2], [1,2])→ trueObject Access
getValue(user, 'profile.name')→ John DoeString Interpolation
interpolateString('Hello {{name}}', {name: 'World'})→ Hello WorldString Utilities
removeAccents('Ñoño café')→ Nono cafepadNumber(5)→ 05RxJS 工具
runInZone() 操作符,用于 NgZone 集成
Type Guards
isString('hello')→ trueisNumber(42)→ trueisDefined(null)→ falseisDefined('value')→ trueDeep Equality
equals({a:1}, {a:1})→ trueequals([1,2], [1,2])→ trueObject Access
getValue(user, 'profile.name')→ John DoeString Interpolation
interpolateString('Hello {{name}}', {name: 'World'})→ Hello WorldString Utilities
removeAccents('Ñoño café')→ Nono cafepadNumber(5)→ 05Scrollbar 工具
测量并补偿 scrollbar 宽度
示例:
Scrollbar 宽度
scrollbarWidth() 和 scrollbarPadding() 函数
ScrollBar Service
The ScrollBar service helps manage scrollbar visibility and compensate for layout shifts when hiding scrollbars (e.g., when opening modals).
Use Case: Modal Body Lock
When opening a modal, you typically hide the body scrollbar. The ScrollBar.hide() method handles this automatically and returns a reverter function.
Status: 🔓 Normal scrolling
Code Example
import { inject } from '@angular/core';
import { ScrollBar } from 'ng-hub-ui-utils';
export class ModalService {
private scrollBar = inject(ScrollBar);
private revertScrollbar: (() => void) | null = null;
openModal() {
// Hide scrollbar and get reverter function
this.revertScrollbar = this.scrollBar.hide();
}
closeModal() {
// Restore scrollbar
if (this.revertScrollbar) {
this.revertScrollbar();
this.revertScrollbar = null;
}
}
}过渡
CSS 过渡辅助函数
示例:
运行过渡
hubRunTransition() 用于以编程方式实现 CSS 过渡
该示例暂不支持实时预览。
提示
通过 [tooltip] 指令为任意元素提供轻量、可主题化的提示。
示例:
提示指令
为元素应用 [tooltip] 并指定位置,即可在悬停或聚焦时显示定位的标签,并可通过 --hub-tooltip-* 变量设置主题。
--hub-tooltip-* variables核心特性
最近更改
Version 22.8.0 - 8/14/26, 12:00 AM
added: provideHubTranslationAdapter() — the application-wide reactive bridge from an external translation service (transloco, ngx-translate, i18next…) into HubTranslationService. Register it once at bootstrap and every ng-hub-ui library picks up the host dictionary, re-emitting on every language change. Supports optional namespacing and deliberate per-label reactive overrides.
added: HUB_TRANSLATION_PREFIX — injection token that scopes the lookups of a library to a collision-safe HUBUI.<LIBRARY>.* namespace. TranslatePipe resolves the prefixed key first and falls back to the bare key, so existing flat dictionaries keep working untouched.
Version 22.7.2 - 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.7.1 - 7/27/26, 12:00 AM
fixed: --hub-overlay-zindex / --hub-overlay-backdrop-zindex actually work now: OverlayRef resolves its inline z-index through var(--hub-overlay-zindex, 1000) / var(--hub-overlay-backdrop-zindex, 999) instead of literal values, so re-stacking an overlay no longer requires !important. Defaults are unchanged.
added: OverlayConfig.zIndex — optional explicit layer for a single overlay instance; when set it takes precedence over the token.
Version 22.7.0 - 7/7/26, 12:00 AM
added: resolveHubAccent(value) — the canonical "any colour" accent resolver shared across the ng-hub-ui family: barewords map to var(--hub-sys-color-<name>, <name>), literal #hex / rgb() / oklch() / var() values pass through unchanged, empty values yield null.
Version 22.6.1 - 7/2/26, 12:00 AM
fixed: CSS variable fallbacks realigned to the ds light defaults (e.g. --hub-ref-font-family-base falls back to the system-ui stack instead of inherit); fallbacks only apply when ng-hub-ui-ds is not loaded.
Version 22.6.0 - 6/30/26, 12:00 AM
added: HubOverflowTooltipDirective ([hubOverflowTooltip]) — shows a tooltip only while the host label is actually truncated, with live tracking via ResizeObserver + MutationObserver.
added: Agnostic tooltip token — HUB_TOOLTIP_ADAPTER plus provideHubTooltip(adapter) let any tooltip implementation back [hubOverflowTooltip], app-wide or per subtree; defaults to the built-in hubTooltipAdapter.