KbqActionsPanel — всплывающая панель с массовыми действиями над выбранными объектами.

Панель массовых действий становится компактной, чтобы помещаться в доступную область экрана. Адаптивность реализована при помощи компонента KbqOverflowItems, который автоматически скрывает элементы с динамической адаптацией под ширину контейнера. Для отслеживания изменений размеров панели используется атрибут additionalResizeObserverTargets, который позволяет отслеживать изменения размеров указанных элементов на странице.

First, the number of records is hidden
Then, the actions are hidden under the dropdown menu
Everything is hidden under the dropdown menu

Компонент поддерживает дополнительный счетчик, который можно настроить под задачи продукта. Например, при группировке элементов списка счетчик отображает общее количество элементов, а не количество групп.

Панель обычно остается открытой после запуска действия. Иногда бывают такие команды, после которых в таблице не остается выбранных элементов, например «Удалить». В подобных случаях предусмотрена возможность закрывать панель.

По умолчанию клавиша ESCAPE закрывает KbqActionsPanel, но вы можете отключить это поведение с помощью свойства disableClose в KbqActionsPanelConfig. Нажатие, которое уже обработал элемент внутри панели, например закрыв свою подсказку, панель не закрывает.

Вы можете использовать опцию data для передачи информации компоненту:

import { Component, inject } from '@angular/core';
import { KbqActionsPanel } from '@koobiq/components/actions-panel';
@Component({
selector: 'your-component',
templateUrl: './your-component.html',
providers: [KbqActionsPanel]
})
export class YourComponent {
private readonly actionsPanel = inject(KbqActionsPanel, { self: true });
openActionsPanel() {
this.actionsPanel.open(YourActionsPanelComponent, {
data: { name: 'koobiq' }
});
}
}

Доступ к данным в компоненте осуществляется при помощи KBQ_ACTIONS_PANEL_DATA токена:

import { Component, inject } from '@angular/core';
import { KBQ_ACTIONS_PANEL_DATA, KbqActionsPanelRef } from '@koobiq/components/actions-panel';
@Component({
selector: 'your-actions-panel',
template: `
<div>{{ data.name }}</div>
<button (click)="actionsPanelRef.close()">close</button>
`
})
export class YourActionsPanelComponent {
readonly data = inject(KBQ_ACTIONS_PANEL_DATA);
readonly actionsPanelRef = inject(KbqActionsPanelRef);
}

Если вы используете TemplateRef для содержимого панели действий, то data и actionsPanelRef доступны в шаблоне:

<ng-template let-data let-actionsPanelRef="actionsPanelRef">
<div>{{ data.name }}</div>
<button (click)="actionsPanelRef.close()">close</button>
</ng-template>

OverlayContainer определяет, где в DOM-дереве будет отображаться панель действий. По умолчанию — в теле документа (document.body).

Если overlayContainer не задан, панель отображается в общем контейнере оверлеев приложения и прижимается к нижнему краю окна поверх страницы — как диалог. Такой вариант подходит, когда действия относятся ко всему экрану, а не к одному блоку на нём.

Если вам необходимо отобразить панель действий в определенном элементе (например, внутри Sidebar), используйте опцию overlayContainer:

import { Component, ElementRef, inject } from '@angular/core';
import { KbqActionsPanel } from '@koobiq/components/actions-panel';
@Component({
selector: 'your-component',
templateUrl: './your-component.html',
providers: [KbqActionsPanel]
})
export class YourComponent {
private readonly actionsPanel = inject(KbqActionsPanel, { self: true });
private readonly customContainer = inject<ElementRef<HTMLElement>>(ElementRef);
openActionsPanel() {
this.actionsPanel.open(YourActionsPanelComponent, {
overlayContainer: this.customContainer
});
}
}

Панель рендерится внутри этого элемента, прижатая к его нижнему краю по центру, и меняет размер вместе с ним. Ширина ограничена шириной элемента, если не задан maxWidth. Элемент с overflow: hidden обрезает панель; при значении по умолчанию overflow: visible анимация появления покажет её ниже элемента.

Пока панель открыта, элемент изменён: у него появляется один дочерний узел с оверлеем, а элементу с position: static проставляется position: relative, потому что оверлей позиционируется относительно него.

OverlayContainer можно переопределить на уровне приложения — тогда все оверлеи окажутся в другом месте DOM:

import { FullscreenOverlayContainer, OverlayContainer } from '@angular/cdk/overlay';
import { bootstrapApplication } from '@angular/platform-browser';
bootstrapApplication(AppComponent, {
providers: [{ provide: OverlayContainer, useClass: FullscreenOverlayContainer }]
});

Опция overlayContainer имеет приоритет: открытая с ней панель глобальный контейнер не использует.

Предложения по улучшению
Если вы нашли ошибку или хотите доработать статью, создайте запрос на GitHub.