| 68 | providers: [{provide: GRID, useExisting: Grid}], |
| 69 | }) |
| 70 | export class Grid implements OnDestroy { |
| 71 | /** A reference to the host element. */ |
| 72 | private readonly _elementRef = inject(ElementRef); |
| 73 | |
| 74 | /** A reference to the host element. */ |
| 75 | readonly element = this._elementRef.nativeElement as HTMLElement; |
| 76 | |
| 77 | /** The collection of rows in the grid. */ |
| 78 | readonly _collection = new SortedCollection<GridRow>(); |
| 79 | |
| 80 | /** The UI patterns for the rows in the grid. */ |
| 81 | private readonly _rowPatterns: Signal<GridRowPattern[]> = computed(() => |
| 82 | this._collection.orderedItems().map(r => r._pattern), |
| 83 | ); |
| 84 | |
| 85 | /** Text direction. */ |
| 86 | readonly textDirection = inject(Directionality).valueSignal; |
| 87 | |
| 88 | /** Whether selection is enabled for the grid. */ |
| 89 | readonly enableSelection = input(false, {transform: booleanAttribute}); |
| 90 | |
| 91 | /** Whether the grid is disabled. */ |
| 92 | readonly disabled = input(false, {transform: booleanAttribute}); |
| 93 | |
| 94 | /** |
| 95 | * Whether to allow disabled items to receive focus. When `true`, disabled items are |
| 96 | * focusable but not interactive. When `false`, disabled items are skipped during navigation. |
| 97 | */ |
| 98 | readonly softDisabled = input(true, {transform: booleanAttribute}); |
| 99 | |
| 100 | /** |
| 101 | * The focus strategy used by the grid. |
| 102 | * - `roving`: Focus is moved to the active cell using `tabindex`. |
| 103 | * - `activedescendant`: Focus remains on the grid container, and `aria-activedescendant` is used to indicate the active cell. |
| 104 | */ |
| 105 | readonly focusMode = input<'roving' | 'activedescendant'>('roving'); |
| 106 | |
| 107 | /** |
| 108 | * The wrapping behavior for keyboard navigation along the row axis. |
| 109 | * - `continuous`: Navigation wraps from the last row to the first, and vice-versa. |
| 110 | * - `loop`: Navigation wraps within the current row. |
| 111 | * - `nowrap`: Navigation stops at the first/last item in the row. |
| 112 | */ |
| 113 | readonly rowWrap = input<'continuous' | 'loop' | 'nowrap'>('loop'); |
| 114 | |
| 115 | /** |
| 116 | * The wrapping behavior for keyboard navigation along the column axis. |
| 117 | * - `continuous`: Navigation wraps from the last column to the first, and vice-versa. |
| 118 | * - `loop`: Navigation wraps within the current column. |
| 119 | * - `nowrap`: Navigation stops at the first/last item in the column. |
| 120 | */ |
| 121 | readonly colWrap = input<'continuous' | 'loop' | 'nowrap'>('loop'); |
| 122 | |
| 123 | /** Whether multiple cells in the grid can be selected. */ |
| 124 | readonly multi = input(false, {transform: booleanAttribute}); |
| 125 | |
| 126 | /** |
| 127 | * The selection strategy used by the grid. |