/
githubmirror
/
components
Обзор
Документация
Войти
/
githubmirror
/
components
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/aria/grid/grid-cell-widget.ts
125 строк
3 KB
Kristiyan Kostadinov
fix(multiple): remove developer preview tag from aria (#33232)
09 май 2026, 12:40
Не верифицирован
09 май 2026, 12:40
0070780
Код
Авторство
О чём код?
/** * @license * Copyright Google LLC All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.dev/license */ import {_IdGenerator} from '@angular/cdk/a11y'; import { afterRenderEffect, booleanAttribute, computed, Directive, ElementRef, inject, input, output, Signal, } from '@angular/core'; import {GridCellWidgetPattern, ElementResolver} from '../private'; import {GRID_CELL} from './grid-tokens'; /** * Represents an interactive element inside a `GridCell`. It allows for pausing grid navigation to * interact with the widget. * * When the user interacts with the widget (e.g., by typing in an input or opening a menu), grid * navigation is temporarily suspended to allow the widget to handle keyboard * events. * * ```html * <td ngGridCell> * <button ngGridCellWidget>Click Me</button> * </td> * ``` * * @see [Grid](guide/aria/grid) */ @Directive({ selector: '[ngGridCellWidget]', exportAs: 'ngGridCellWidget', host: { '[attr.data-active]': 'active()', '[attr.data-active-control]': 'isActivated() ? "widget" : "cell"', '[tabindex]': '_tabIndex()', '[attr.id]': 'id()', }, }) export class GridCellWidget { /** A reference to the host element. */ private readonly _elementRef = inject(ElementRef); /** A reference to the host element. */ readonly element = this._elementRef.nativeElement as HTMLElement; /** Whether the widget is currently active (focused). */ readonly active = computed(() => this._pattern.active()); /** The parent cell. */ private readonly _cell = inject(GRID_CELL); /** A unique identifier for the widget. */ readonly id = input(inject(_IdGenerator).getId('ng-grid-cell-widget-', true)); /** The type of widget, which determines how it is activated. */ readonly widgetType = input<'simple' | 'complex' | 'editable'>('simple'); /** Whether the widget is disabled. */ readonly disabled = input(false, {transform: booleanAttribute}); /** The target that will receive focus instead of the widget. */ readonly focusTarget = input<ElementResolver<HTMLElement>>(); /** Emits when the widget is activated. */ readonly activated = output<KeyboardEvent | FocusEvent | undefined>(); /** Emits when the widget is deactivated. */ readonly deactivated = output<KeyboardEvent | FocusEvent | undefined>(); /** The tabindex override. */ readonly tabindex = input<number | undefined>(); /** * The tabindex value set to the element. * If a focus target exists then return -1. Unless an override. */ protected readonly _tabIndex: Signal<number> = computed( () => this.tabindex() ?? this._pattern.tabIndex(), ); /** The UI pattern for the grid cell widget. */ readonly _pattern = new GridCellWidgetPattern({ ...this, element: () => this.element, cell: () => this._cell._pattern, onActivate: e => this.activated.emit(e), onDeactivate: e => this.deactivated.emit(e), }); /** Whether the widget is activated. */ get isActivated(): Signal<boolean> { return computed(() => this._pattern.isActivated()); } constructor() { afterRenderEffect({ write: () => this._pattern.activationEffect(), }); afterRenderEffect({ write: () => this._pattern.deactivationEffect(), }); } /** Activates the widget. */ activate(): void { this._pattern.activate(); } /** Deactivates the widget. */ deactivate(): void { this._pattern.deactivate(); } }