Компонент навигационного меню для Angular | ng-hub-ui-nav
Навигационный компонент для Angular с выпадающими меню, панелями drill-down, адаптивным сворачиванием, интеграцией с Router и тематизацией через CSS-переменные.
Справочник API
Вот полный контракт nav: всё, что можно привязать, прослушать, спроецировать и тематизировать, собрано в одном месте. Подключите то, что нужно, и оформите так, как хотите — это standalone и дружит с сигналами.
Входные свойства
Настройте nav с помощью 40 входных свойств. Привязывайте их, как любой @Input в Angular.
| Имя | Тип | По умолчанию | Описание |
|---|---|---|---|
itemsОбязательно | HubNavItem[] | — | Массив элементов навигации для отрисовки. Каждый элемент определяет свой тип (link, dropdown, header, separator, custom), label, route, icon, badge, children и многое другое. |
config | Partial<HubNavConfig> | {} | Частичные переопределения конфигурации, объединяемые с глобальными значениями по умолчанию. Управляет ориентацией, триггером выпадающего списка, режимом сворачивания, breakpoint, позицией и многим другим. |
navClass | string | '' | Дополнительный CSS-класс, применяемый к элементу контейнера nav. |
itemTemplate | TemplateRef<unknown> | null | null | Необязательный пользовательский шаблон для отрисовки элементов nav через input-привязку. Директива hubNavItemTemplate имеет приоритет над этим input. |
iconTemplate | TemplateRef<HubNavItemIconContext> | null | null | Шаблон, отрисовываемый вместо класса иконки, для пунктов с icon. Получает HubNavItemIconContext с $implicit (пункт) и rail. Директива hubNavItemIcon имеет приоритет над этим входом. |
autoOpenFromRoute | boolean | false | Если true, nav автоматически открывает dropdown и панели drill-down, соответствующие активному URL роутера, при инициализации и после каждой навигации. Полезно для боковых навигаций, где состояние открытия определяется URL. В меню, корни которого раскрываются по-разному, открытым остаётся только один раздел: при переходе к корню-аккордеону панель покинутого корня закрывается, и наоборот. |
color | 'primary' | 'success' | 'danger' | 'warning' | 'info' | string | undefined | Семантический акцент, применяемый к состояниям hover/active. Принимает семантическое имя (primary, success, danger, warning, info), имя зарегистрированного акцента, именованный цвет CSS или буквальное значение #hex / rgb() / oklch() / var(). Простые имена разрешаются в токен --hub-sys-color-<name>; если опущено, используется primary. |
rail | boolean (two-way: model) | false | Панель значков только для настольного режима. При true вертикальная навигация отображается шириной панели и показывает только значки. Ниже collapseBreakpoint игнорируется — там всегда действует offcanvas. Двусторонняя привязка через [(rail)]. |
activeItemId | string | null (two-way: model) | null | Пункт, помечаемый активным, — по его `id` или `fragment`, — когда о местоположении читателя говорит не маршрутизатор. Пока значение задано, оно отвечает за всё меню: сопоставление маршрутов отступает, а помеченный пункт сообщает `aria-current="location"`, а не `page`. Двусторонняя привязка — именно так скролл-шпион двигает отметку. |
orientation (config) | 'horizontal' | 'vertical' | 'horizontal' | Ориентация навигации: horizontal отрисовывает верхнюю панель, vertical — боковую. |
verticalExpandMode (config) | 'accordion' | 'flyout' | 'panel' | 'accordion' | Как раскрываются дочерние элементы в вертикальной ориентации: accordion разворачивает их на месте, flyout открывает позиционированное боковое подменю, panel открывает наложенные стопкой панели drill-down. |
dropdownTrigger (config) | 'hover' | 'click' | 'both' | 'click' | Механизм открытия меню dropdown: по hover, по click или обоими способами. |
dropdownRenderMode (config) | 'inline' | 'overlay' | 'inline' | Стратегия отрисовки меню dropdown и flyout: inline внутри DOM nav или overlay в слое на уровне body, чтобы избежать обрезки. Режим drill-down (panel) не затрагивается. |
position (config) | 'static' | 'sticky' | 'fixed' | 'static' | Стратегия CSS-позиционирования контейнера nav. Sticky-позиционирование активируется только для вертикальной навигации. |
stickyTop (config) | string | '0px' | Верхний отступ, используемый при включённом sticky-позиционировании. Принимает любое корректное значение длины CSS. |
collapseMode (config) | 'offcanvas' | 'dropdown' | 'fullscreen' | 'offcanvas' | Режим отображения, когда меню сворачивается на небольших экранах: выдвижная панель offcanvas, dropdown под кнопкой-переключателем или полноэкранный оверлей fullscreen. |
collapseBreakpoint (config) | number | 992 | Ширина области просмотра в пикселях, ниже которой меню сворачивается. Установите 0, чтобы отключить адаптивное сворачивание. |
offcanvasPosition (config) | 'start' | 'end' | 'top' | 'bottom' | 'start' | Сторона, с которой выдвигается панель offcanvas. Применяется, только когда collapseMode равен offcanvas. |
ariaLabel (config) | string | 'Navigation' | Доступное имя, применяемое к элементу nav. |
panelMaxVisible (config) | number | 3 | Максимальное число одновременно видимых панелей в режиме раскрытия panel. При превышении последняя панель углубляется (drill-down) на месте с навигацией «назад». |
sidebarSide (config) | 'left' | 'right' | 'left' | Физическая сторона боковой панели: left (панели раскрываются вправо) или right (панели раскрываются влево). |
panelWidth (config) | string | '16rem' | Ширина каждой панели drill-down. Принимает любое корректное значение ширины CSS. |
railToggle (config) | boolean | true | Отображать ли встроенный переключатель на краю основной колонки вертикальной настольной навигации. Отключите, если приложение поставляет собственный переключатель. Полностью настраивается токенами --hub-nav-rail-toggle-*, включая заменяемую SVG-стрелку. |
followReplacedUrls (config) | boolean | number | true | Насколько активно навигация следует за scroll spy, который сообщает позицию читателя заменой URL: true следует за каждым сообщением, число миллисекунд — только после паузы, false — никогда. |
activeIndicator (config) | boolean | false | Перемещается ли активная метка между пунктами вместо появления на месте. По умолчанию выключено; учитывает prefers-reduced-motion. |
labels (config) | Partial<HubNavLabels> | undefined | Переопределения встроенных доступных подписей на уровне экземпляра. Пропущенные подписи берутся из общих ключей HUBUI.NAV.*, затем из английских значений по умолчанию. |
enabled (hubNavScrollSpy) — bound as [hubNavScrollSpy] | boolean | true | Включает или отключает отслеживание секций. Привязывается через сам селектор: [hubNavScrollSpy]="false" выключает наблюдатель. |
offset (hubNavScrollSpy) | number | 120 | Верхний отступ в пикселях, компенсирующий закреплённые (sticky) шапки при вычислении активной секции. |
sectionSelector (hubNavScrollSpy) | string | '[data-hub-nav-scroll-spy-section]' | CSS-селектор, используемый для поиска отслеживаемых элементов секций внутри контейнера-хоста. |
nav (hubNavScrollSpy) | HubNavComponent | null | null | Меню, за которое отвечает этот шпион. Связанные, обе половины сходятся: раздел перед читателем отмечает соответствующий пункт, а клик по пункту прокручивает сюда. URL не пишется, запись в историю не добавляется. Без связи шпион только сообщает через `activeSectionChange`. |
scrollContainer (hubNavScrollSpy) | HTMLElement | null | null | Элемент, в котором эти разделы действительно прокручиваются, когда это не тот, что шпион нашёл бы, поднимаясь от них. Его же двигает `scrollTo` — именно это не даёт переходу утащить за собой каждого прокручиваемого предка. |
clickSettleMs (hubNavScrollSpy) | number | 0 | Сколько миллисекунд ответ на клик переживает то, что читатель как будто взял управление на себя. В этом окне колесо, касание и клавиша игнорируются, чтобы ещё летящий переход не был отменён посреди анимации. `0` по умолчанию сохраняет прежнее поведение. |
sectionId (hubNavScrollSpySection) | string | null | null | Необязательный id отслеживаемой секции. Если опущен, используется атрибут id элемента-хоста. |
item (hub-nav-item)Обязательно | HubNavItem | — | Элемент навигации, отрисовываемый внутренним дочерним hub-nav-item. Управляется автоматически со стороны hub-nav; напрямую привязывается редко. |
depth / isActive / isExpanded / forceAccordionMode (hub-nav-item; depth and forceAccordionMode also on hub-nav-item-list) | number / boolean / boolean / boolean | 0 / false / false / false | Внутренние input состояния hub-nav-item: глубина вложенности, флаги active и expanded и принудительное поведение accordion внутри мобильного или панельного контекста. У hub-nav-item-list тоже есть depth и forceAccordionMode, чтобы задать целый уровень сразу. |
items (hub-nav-item-list)Обязательно | HubNavItem[] | — | Элементы, отрисовываемые внутренним дочерним hub-nav-item-list. Управляются автоматически со стороны hub-nav. |
panels (hub-nav-panel-container)Обязательно | HubNavPanelState[] | — | Стек состояний открытых панелей, отрисовываемый внутренним hub-nav-panel-container в режиме раскрытия panel. |
panel (hub-nav-panel)Обязательно | HubNavPanelState | — | Состояние одной панели drill-down, отрисовываемой внутренним дочерним hub-nav-panel. |
itemTemplate / dropdownRenderMode / panelWidth / sidebarSide / showHeader / hideFirstPanelHeader / isLast (hub-nav-item-list / hub-nav-panel / hub-nav-panel-container) | TemplateRef<unknown> | null / HubNavDropdownRenderMode / string / HubNavSidebarSide / boolean / boolean / boolean | — | Внутренние служебные input, которые корневой hub-nav передаёт своим дочерним компонентам; каждый существует у того подмножества этих компонентов, которому он нужен, а isLast отмечает крайнюю панель стопки, чтобы она закрыла его край. Настраивайте их через input config на hub-nav, а не привязывайте напрямую. |
overlayOwnerClass / overlayOrientationClass (hub-nav-item-list / hub-nav-panel / hub-nav-panel-container) | string / 'hub-nav--horizontal' | 'hub-nav--vertical' | '' / 'hub-nav--vertical' ('hub-nav--horizontal' on hub-nav-item-list) | Служебные input оверлея, которые корневой hub-nav передаёт, когда подменю рендерятся в оверлее на уровне body: overlayOwnerClass — уникальный класс, привязывающий оверлей к своей навигации для обработки клика снаружи, а overlayOrientationClass несёт ориентацию навигации, чтобы стили контекста хоста работали и вне дерева компонента. |
События
Реагируйте на то, что делает nav, — 12 событий, к которым можно подключить вашу логику.
| Имя | Тип | Описание |
|---|---|---|
itemClick | OutputEmitterRef<HubNavItem> | Вызывается при клике по элементу link. Предоставляет нажатый HubNavItem. |
dropdownOpen | OutputEmitterRef<HubNavItem> | Вызывается при открытии элемента dropdown. |
dropdownClose | OutputEmitterRef<HubNavItem> | Вызывается при закрытии элемента dropdown. |
mobileToggle | OutputEmitterRef<boolean> | Вызывается при переключении мобильной панели. Предоставляет true при открытии, false при закрытии. |
panelChange | OutputEmitterRef<HubNavPanelEvent> | Вызывается при открытии, закрытии, углублении (drill-down) или возврате панели. Предоставляет элемент, индекс панели и тип действия. |
railChange | OutputEmitterRef<boolean> | Срабатывает при переключении значения модели rail, обеспечивая двустороннюю привязку [(rail)] и сохранение на стороне приложения. |
activeItemIdChange | OutputEmitterRef<string | null> | Срабатывает при смене помеченного пункта — именно это делает `activeItemId` двусторонним. Скролл-шпион, связанный через `[nav]`, сообщает здесь раздел, на котором он остановился. |
activeSectionChange (hubNavScrollSpy) | OutputEmitterRef<string> | Испускает id новой активной секции при каждом изменении видимой секции. |
clicked / toggleDropdown (hub-nav-item) | OutputEmitterRef<{ item: HubNavItem; event: Event }> / OutputEmitterRef<HubNavItem> | Внутренние события hub-nav-item: clicked испускает элемент вместе с исходным DOM-событием, toggleDropdown испускает переключаемый элемент dropdown. Оба всплывают к output hub-nav. |
itemClick / dropdownToggle / panelOpen (hub-nav-item-list / hub-nav-panel / hub-nav-panel-container) | OutputEmitterRef<{ item: HubNavItem; event: Event }> / OutputEmitterRef<HubNavItem> / OutputEmitterRef<HubNavItem> | События взаимодействия с элементами, повторно испускаемые внутренними дочерними списками и панелями по пути всплытия к hub-nav: itemClick (элемент плюс DOM-событие), dropdownToggle (переключаемый элемент) и panelOpen (элемент, чьи дочерние элементы должны открыть панель). |
closePanel / backClick (hub-nav-panel) | OutputEmitterRef<string> | Испускаются внутренним hub-nav-panel с id панели при нажатии кнопки закрытия (closePanel) или кнопки «назад» (backClick). |
panelClose / panelBack (hub-nav-panel-container) | OutputEmitterRef<string> | Испускаются внутренним hub-nav-panel-container с id панели, ретранслируя запросы закрытия (panelClose) и возврата (panelBack) к hub-nav. |
Шаблоны
Сделайте его своим — 4 слотов шаблона позволяют проецировать собственную разметку.
| Имя | Описание | Пример |
|---|---|---|
hubNavStart | Проецирует пользовательское содержимое в слот start. Горизонтально: визуальное начало (слева в LTR, справа в RTL). Вертикально: верх основной колонки. | <hub-nav [items]="items">
<ng-template hubNavStart let-collapsed="collapsed">
<img src="logo.svg" alt="Brand" />
@if (!collapsed) { <span>App Name</span> }
</ng-template>
</hub-nav> |
hubNavEnd | Проецирует пользовательское содержимое в слот end. Горизонтально: визуальный конец (справа в LTR, слева в RTL). Вертикально: низ основной колонки. | <hub-nav [items]="items">
<ng-template hubNavEnd>
<button type="button">Sign out</button>
</ng-template>
</hub-nav> |
hubNavItemTemplate | Переопределяет отрисовку элемента по умолчанию пользовательским шаблоном. Получает HubNavItemTemplateContext со свойствами $implicit (item), active, expanded и depth. | <hub-nav [items]="items">
<ng-template hubNavItemTemplate let-item let-active="active">
<span [class.fw-bold]="active">{{ item.label }}</span>
@if (item.badge) { <hub-badge shape="rounded">{{ item.badge }}</hub-badge> }
</ng-template>
</hub-nav> |
hubNavItemIcon | Заменяет глиф каждого пункта, объявляющего icon, и больше ничего. Получает HubNavItemIconContext с $implicit (пункт) и rail, поэтому меню может рисовать иконки через ng-hub-ui-icons — или любой другой набор — без зависимости библиотеки от какого-либо из них. Пункты без icon не затрагиваются. | <hub-nav [items]="items">
<ng-template hubNavItemIcon let-item let-rail="rail">
<hub-icon [name]="item.icon" [size]="rail ? 'lg' : 'md'" />
</ng-template>
</hub-nav> |