@angular/aria 21.0.0-next.9 → 21.0.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/_adev_assets/aria-accordion.json +373 -0
  2. package/_adev_assets/aria-combobox.json +383 -0
  3. package/_adev_assets/aria-grid.json +578 -0
  4. package/_adev_assets/aria-listbox.json +511 -0
  5. package/_adev_assets/aria-menu.json +752 -0
  6. package/_adev_assets/aria-radio-group.json +389 -0
  7. package/_adev_assets/aria-tabs.json +987 -0
  8. package/_adev_assets/aria-toolbar.json +717 -0
  9. package/_adev_assets/aria-tree.json +1067 -0
  10. package/fesm2022/_widget-chunk.mjs +827 -0
  11. package/fesm2022/_widget-chunk.mjs.map +1 -0
  12. package/fesm2022/accordion.mjs +371 -172
  13. package/fesm2022/accordion.mjs.map +1 -1
  14. package/fesm2022/aria.mjs +1 -2
  15. package/fesm2022/aria.mjs.map +1 -1
  16. package/fesm2022/combobox.mjs +304 -114
  17. package/fesm2022/combobox.mjs.map +1 -1
  18. package/fesm2022/deferred-content.mjs +89 -50
  19. package/fesm2022/deferred-content.mjs.map +1 -1
  20. package/fesm2022/grid.mjs +517 -0
  21. package/fesm2022/grid.mjs.map +1 -0
  22. package/fesm2022/listbox.mjs +384 -183
  23. package/fesm2022/listbox.mjs.map +1 -1
  24. package/fesm2022/menu.mjs +535 -0
  25. package/fesm2022/menu.mjs.map +1 -0
  26. package/fesm2022/private.mjs +2347 -0
  27. package/fesm2022/private.mjs.map +1 -0
  28. package/fesm2022/radio-group.mjs +320 -179
  29. package/fesm2022/radio-group.mjs.map +1 -1
  30. package/fesm2022/tabs.mjs +483 -274
  31. package/fesm2022/tabs.mjs.map +1 -1
  32. package/fesm2022/toolbar.mjs +330 -199
  33. package/fesm2022/toolbar.mjs.map +1 -1
  34. package/fesm2022/tree.mjs +509 -264
  35. package/fesm2022/tree.mjs.map +1 -1
  36. package/package.json +14 -6
  37. package/types/_grid-chunk.d.ts +546 -0
  38. package/types/accordion.d.ts +4 -4
  39. package/types/combobox.d.ts +18 -5
  40. package/types/grid.d.ts +111 -0
  41. package/types/listbox.d.ts +6 -3
  42. package/types/menu.d.ts +158 -0
  43. package/types/{ui-patterns.d.ts → private.d.ts} +333 -133
  44. package/types/radio-group.d.ts +5 -3
  45. package/types/tabs.d.ts +4 -4
  46. package/types/toolbar.d.ts +4 -4
  47. package/types/tree.d.ts +7 -4
  48. package/fesm2022/ui-patterns.mjs +0 -2504
  49. package/fesm2022/ui-patterns.mjs.map +0 -1
@@ -0,0 +1,827 @@
1
+ import { computed, signal, linkedSignal } from '@angular/core';
2
+
3
+ var Modifier;
4
+ (function (Modifier) {
5
+ Modifier[Modifier["None"] = 0] = "None";
6
+ Modifier[Modifier["Ctrl"] = 1] = "Ctrl";
7
+ Modifier[Modifier["Shift"] = 2] = "Shift";
8
+ Modifier[Modifier["Alt"] = 4] = "Alt";
9
+ Modifier[Modifier["Meta"] = 8] = "Meta";
10
+ Modifier["Any"] = "Any";
11
+ })(Modifier || (Modifier = {}));
12
+ class EventManager {
13
+ configs = [];
14
+ handle(event) {
15
+ for (const config of this.configs) {
16
+ if (config.matcher(event)) {
17
+ config.handler(event);
18
+ if (config.preventDefault) {
19
+ event.preventDefault();
20
+ }
21
+ if (config.stopPropagation) {
22
+ event.stopPropagation();
23
+ }
24
+ }
25
+ }
26
+ }
27
+ }
28
+ function getModifiers(event) {
29
+ return (+event.ctrlKey && Modifier.Ctrl) | (+event.shiftKey && Modifier.Shift) | (+event.altKey && Modifier.Alt) | (+event.metaKey && Modifier.Meta);
30
+ }
31
+ function hasModifiers(event, modifiers) {
32
+ const eventModifiers = getModifiers(event);
33
+ const modifiersList = Array.isArray(modifiers) ? modifiers : [modifiers];
34
+ if (modifiersList.includes(Modifier.Any)) {
35
+ return true;
36
+ }
37
+ return modifiersList.some(modifiers => eventModifiers === modifiers);
38
+ }
39
+
40
+ class KeyboardEventManager extends EventManager {
41
+ options = {
42
+ preventDefault: true,
43
+ stopPropagation: true
44
+ };
45
+ on(...args) {
46
+ const {
47
+ modifiers,
48
+ key,
49
+ handler
50
+ } = this._normalizeInputs(...args);
51
+ this.configs.push({
52
+ handler: handler,
53
+ matcher: event => this._isMatch(event, key, modifiers),
54
+ ...this.options
55
+ });
56
+ return this;
57
+ }
58
+ _normalizeInputs(...args) {
59
+ const key = args.length === 3 ? args[1] : args[0];
60
+ const handler = args.length === 3 ? args[2] : args[1];
61
+ const modifiers = args.length === 3 ? args[0] : Modifier.None;
62
+ return {
63
+ key: key,
64
+ handler: handler,
65
+ modifiers: modifiers
66
+ };
67
+ }
68
+ _isMatch(event, key, modifiers) {
69
+ if (!hasModifiers(event, modifiers)) {
70
+ return false;
71
+ }
72
+ if (key instanceof RegExp) {
73
+ return key.test(event.key);
74
+ }
75
+ const keyStr = typeof key === 'string' ? key : key();
76
+ return keyStr.toLowerCase() === event.key.toLowerCase();
77
+ }
78
+ }
79
+
80
+ var MouseButton;
81
+ (function (MouseButton) {
82
+ MouseButton[MouseButton["Main"] = 0] = "Main";
83
+ MouseButton[MouseButton["Auxiliary"] = 1] = "Auxiliary";
84
+ MouseButton[MouseButton["Secondary"] = 2] = "Secondary";
85
+ })(MouseButton || (MouseButton = {}));
86
+ class PointerEventManager extends EventManager {
87
+ options = {
88
+ preventDefault: false,
89
+ stopPropagation: false
90
+ };
91
+ on(...args) {
92
+ const {
93
+ button,
94
+ handler,
95
+ modifiers
96
+ } = this._normalizeInputs(...args);
97
+ this.configs.push({
98
+ handler,
99
+ matcher: event => this._isMatch(event, button, modifiers),
100
+ ...this.options
101
+ });
102
+ return this;
103
+ }
104
+ _normalizeInputs(...args) {
105
+ if (args.length === 3) {
106
+ return {
107
+ button: args[0],
108
+ modifiers: args[1],
109
+ handler: args[2]
110
+ };
111
+ }
112
+ if (args.length === 2) {
113
+ return {
114
+ button: MouseButton.Main,
115
+ modifiers: args[0],
116
+ handler: args[1]
117
+ };
118
+ }
119
+ return {
120
+ button: MouseButton.Main,
121
+ modifiers: Modifier.None,
122
+ handler: args[0]
123
+ };
124
+ }
125
+ _isMatch(event, button, modifiers) {
126
+ return button === (event.button ?? 0) && hasModifiers(event, modifiers);
127
+ }
128
+ }
129
+
130
+ class GridData {
131
+ inputs;
132
+ cells;
133
+ rowCount = computed(() => this.cells().length);
134
+ maxRowCount = computed(() => Math.max(...this._rowCountByCol().values(), 0));
135
+ maxColCount = computed(() => Math.max(...this._colCountsByRow().values(), 0));
136
+ _coordsMap = computed(() => {
137
+ const coordsMap = new Map();
138
+ const visitedCoords = new Set();
139
+ for (let rowIndex = 0; rowIndex < this.cells().length; rowIndex++) {
140
+ let colIndex = 0;
141
+ const row = this.cells()[rowIndex];
142
+ for (const cell of row) {
143
+ while (visitedCoords.has(`${rowIndex}:${colIndex}`)) {
144
+ colIndex++;
145
+ }
146
+ const rowspan = cell.rowSpan();
147
+ const colspan = cell.colSpan();
148
+ const spanCoords = [];
149
+ for (let rowOffset = 0; rowOffset < rowspan; rowOffset++) {
150
+ const row = rowIndex + rowOffset;
151
+ for (let colOffset = 0; colOffset < colspan; colOffset++) {
152
+ const col = colIndex + colOffset;
153
+ visitedCoords.add(`${row}:${col}`);
154
+ spanCoords.push({
155
+ row,
156
+ col
157
+ });
158
+ }
159
+ }
160
+ coordsMap.set(cell, {
161
+ coords: spanCoords[0],
162
+ spanCoords
163
+ });
164
+ colIndex += colspan;
165
+ }
166
+ }
167
+ return coordsMap;
168
+ });
169
+ _cellMap = computed(() => {
170
+ const cellMap = new Map();
171
+ for (const [cell, {
172
+ spanCoords
173
+ }] of this._coordsMap().entries()) {
174
+ for (const {
175
+ row,
176
+ col
177
+ } of spanCoords) {
178
+ cellMap.set(`${row}:${col}`, cell);
179
+ }
180
+ }
181
+ return cellMap;
182
+ });
183
+ _colCountsByRow = computed(() => {
184
+ const colCountByRow = new Map();
185
+ for (const [_, {
186
+ spanCoords
187
+ }] of this._coordsMap().entries()) {
188
+ for (const {
189
+ row,
190
+ col
191
+ } of spanCoords) {
192
+ const colCount = colCountByRow.get(row);
193
+ const newColCount = col + 1;
194
+ if (colCount === undefined || colCount < newColCount) {
195
+ colCountByRow.set(row, newColCount);
196
+ }
197
+ }
198
+ }
199
+ return colCountByRow;
200
+ });
201
+ _rowCountByCol = computed(() => {
202
+ const rowCountByCol = new Map();
203
+ for (const [_, {
204
+ spanCoords
205
+ }] of this._coordsMap().entries()) {
206
+ for (const {
207
+ row,
208
+ col
209
+ } of spanCoords) {
210
+ const rowCount = rowCountByCol.get(col);
211
+ const newRowCount = row + 1;
212
+ if (rowCount === undefined || rowCount < newRowCount) {
213
+ rowCountByCol.set(col, newRowCount);
214
+ }
215
+ }
216
+ }
217
+ return rowCountByCol;
218
+ });
219
+ constructor(inputs) {
220
+ this.inputs = inputs;
221
+ this.cells = this.inputs.cells;
222
+ }
223
+ getCell(rowCol) {
224
+ return this._cellMap().get(`${rowCol.row}:${rowCol.col}`);
225
+ }
226
+ getCoords(cell) {
227
+ return this._coordsMap().get(cell)?.coords;
228
+ }
229
+ getAllCoords(cell) {
230
+ return this._coordsMap().get(cell)?.spanCoords;
231
+ }
232
+ getRowCount(col) {
233
+ return this._rowCountByCol().get(col);
234
+ }
235
+ getColCount(row) {
236
+ return this._colCountsByRow().get(row);
237
+ }
238
+ }
239
+
240
+ class GridFocus {
241
+ inputs;
242
+ activeCell = signal(undefined);
243
+ activeCoords = signal({
244
+ row: -1,
245
+ col: -1
246
+ });
247
+ stateEmpty = computed(() => this.activeCell() === undefined || this.activeCoords().row === -1 && this.activeCoords().col === -1);
248
+ stateStale = computed(() => {
249
+ if (this.stateEmpty()) {
250
+ return true;
251
+ }
252
+ const activeCell = this.activeCell();
253
+ const activeCellCoords = this.inputs.grid.getCoords(activeCell);
254
+ const activeCoords = this.activeCoords();
255
+ const activeCoordsCell = this.inputs.grid.getCell(activeCoords);
256
+ const activeCellNotValid = activeCellCoords === undefined;
257
+ const activeCellMismatch = activeCell !== activeCoordsCell;
258
+ return activeCellNotValid || activeCellMismatch;
259
+ });
260
+ activeDescendant = computed(() => {
261
+ if (this.gridDisabled() || this.inputs.focusMode() === 'roving') {
262
+ return undefined;
263
+ }
264
+ const currentActiveCell = this.activeCell();
265
+ return currentActiveCell ? currentActiveCell.id() : undefined;
266
+ });
267
+ gridDisabled = computed(() => {
268
+ if (this.inputs.disabled()) {
269
+ return true;
270
+ }
271
+ const gridCells = this.inputs.grid.cells();
272
+ return gridCells.length === 0 || gridCells.every(row => row.every(cell => cell.disabled()));
273
+ });
274
+ gridTabIndex = computed(() => {
275
+ if (this.gridDisabled()) {
276
+ return 0;
277
+ }
278
+ return this.inputs.focusMode() === 'activedescendant' ? 0 : -1;
279
+ });
280
+ constructor(inputs) {
281
+ this.inputs = inputs;
282
+ }
283
+ getCellTabindex(cell) {
284
+ if (this.gridDisabled()) {
285
+ return -1;
286
+ }
287
+ if (this.inputs.focusMode() === 'activedescendant') {
288
+ return -1;
289
+ }
290
+ return this.activeCell() === cell ? 0 : -1;
291
+ }
292
+ isFocusable(cell) {
293
+ return !cell.disabled() || !this.inputs.skipDisabled();
294
+ }
295
+ focusCell(cell) {
296
+ if (this.gridDisabled()) {
297
+ return false;
298
+ }
299
+ if (!this.isFocusable(cell)) {
300
+ return false;
301
+ }
302
+ if (this.inputs.grid.getCoords(cell) === undefined) {
303
+ return false;
304
+ }
305
+ this.activeCoords.set(this.inputs.grid.getCoords(cell));
306
+ this.activeCell.set(cell);
307
+ return true;
308
+ }
309
+ focusCoordinates(coords) {
310
+ if (this.gridDisabled()) {
311
+ return false;
312
+ }
313
+ const cell = this.inputs.grid.getCell(coords);
314
+ if (!cell || !this.isFocusable(cell)) {
315
+ return false;
316
+ }
317
+ if (this.inputs.grid.getCell(coords) === undefined) {
318
+ return false;
319
+ }
320
+ this.activeCoords.set(coords);
321
+ this.activeCell.set(this.inputs.grid.getCell(coords));
322
+ return true;
323
+ }
324
+ }
325
+
326
+ const direction = {
327
+ Up: {
328
+ row: -1
329
+ },
330
+ Down: {
331
+ row: 1
332
+ },
333
+ Left: {
334
+ col: -1
335
+ },
336
+ Right: {
337
+ col: 1
338
+ }
339
+ };
340
+ class GridNavigation {
341
+ inputs;
342
+ _maxSteps = computed(() => this.inputs.grid.maxRowCount() * this.inputs.grid.maxColCount());
343
+ constructor(inputs) {
344
+ this.inputs = inputs;
345
+ }
346
+ gotoCell(cell) {
347
+ return this.inputs.gridFocus.focusCell(cell);
348
+ }
349
+ gotoCoords(coords) {
350
+ return this.inputs.gridFocus.focusCoordinates(coords);
351
+ }
352
+ peek(direction, fromCoords, wrap) {
353
+ wrap = wrap ?? (direction.row !== undefined ? this.inputs.rowWrap() : this.inputs.colWrap());
354
+ return this._peekDirectional(direction, fromCoords, wrap);
355
+ }
356
+ advance(direction) {
357
+ const nextCoords = this.peek(direction, this.inputs.gridFocus.activeCoords());
358
+ return !!nextCoords && this.gotoCoords(nextCoords);
359
+ }
360
+ peekFirst(row) {
361
+ const fromCoords = {
362
+ row: row ?? 0,
363
+ col: -1
364
+ };
365
+ return row === undefined ? this._peekDirectional(direction.Right, fromCoords, 'continuous') : this._peekDirectional(direction.Right, fromCoords, 'nowrap');
366
+ }
367
+ first(row) {
368
+ const nextCoords = this.peekFirst(row);
369
+ return !!nextCoords && this.gotoCoords(nextCoords);
370
+ }
371
+ peekLast(row) {
372
+ const fromCoords = {
373
+ row: row ?? this.inputs.grid.maxRowCount() - 1,
374
+ col: this.inputs.grid.maxColCount()
375
+ };
376
+ return row === undefined ? this._peekDirectional(direction.Left, fromCoords, 'continuous') : this._peekDirectional(direction.Left, fromCoords, 'nowrap');
377
+ }
378
+ last(row) {
379
+ const nextCoords = this.peekLast(row);
380
+ return !!nextCoords && this.gotoCoords(nextCoords);
381
+ }
382
+ _peekDirectional(delta, fromCoords, wrap) {
383
+ const fromCell = this.inputs.grid.getCell(fromCoords);
384
+ const maxRowCount = this.inputs.grid.maxRowCount();
385
+ const maxColCount = this.inputs.grid.maxColCount();
386
+ const rowDelta = delta.row ?? 0;
387
+ const colDelta = delta.col ?? 0;
388
+ let nextCoords = {
389
+ ...fromCoords
390
+ };
391
+ for (let step = 0; step < this._maxSteps(); step++) {
392
+ const isWrapping = nextCoords.col + colDelta < 0 || nextCoords.col + colDelta >= maxColCount || nextCoords.row + rowDelta < 0 || nextCoords.row + rowDelta >= maxRowCount;
393
+ if (wrap === 'nowrap' && isWrapping) return;
394
+ if (wrap === 'continuous') {
395
+ const generalDelta = delta.row ?? delta.col;
396
+ const rowStep = isWrapping ? generalDelta : rowDelta;
397
+ const colStep = isWrapping ? generalDelta : colDelta;
398
+ nextCoords = {
399
+ row: (nextCoords.row + rowStep + maxRowCount) % maxRowCount,
400
+ col: (nextCoords.col + colStep + maxColCount) % maxColCount
401
+ };
402
+ }
403
+ if (wrap === 'loop') {
404
+ nextCoords = {
405
+ row: (nextCoords.row + rowDelta + maxRowCount) % maxRowCount,
406
+ col: (nextCoords.col + colDelta + maxColCount) % maxColCount
407
+ };
408
+ }
409
+ if (nextCoords.row === fromCoords.row && nextCoords.col === fromCoords.col) {
410
+ return undefined;
411
+ }
412
+ const nextCell = this.inputs.grid.getCell(nextCoords);
413
+ if (nextCell !== undefined && nextCell !== fromCell && this.inputs.gridFocus.isFocusable(nextCell)) {
414
+ return nextCoords;
415
+ }
416
+ }
417
+ return undefined;
418
+ }
419
+ }
420
+
421
+ class GridSelection {
422
+ inputs;
423
+ constructor(inputs) {
424
+ this.inputs = inputs;
425
+ }
426
+ select(fromCoords, toCoords) {
427
+ for (const cell of this._validCells(fromCoords, toCoords ?? fromCoords)) {
428
+ cell.selected.set(true);
429
+ }
430
+ }
431
+ deselect(fromCoords, toCoords) {
432
+ for (const cell of this._validCells(fromCoords, toCoords ?? fromCoords)) {
433
+ cell.selected.set(false);
434
+ }
435
+ }
436
+ toggle(fromCoords, toCoords) {
437
+ for (const cell of this._validCells(fromCoords, toCoords ?? fromCoords)) {
438
+ cell.selected.update(state => !state);
439
+ }
440
+ }
441
+ selectAll() {
442
+ for (const cell of this._validCells({
443
+ row: 0,
444
+ col: 0
445
+ }, {
446
+ row: this.inputs.grid.maxRowCount(),
447
+ col: this.inputs.grid.maxColCount()
448
+ })) {
449
+ cell.selected.set(true);
450
+ }
451
+ }
452
+ deselectAll() {
453
+ for (const cell of this._validCells({
454
+ row: 0,
455
+ col: 0
456
+ }, {
457
+ row: this.inputs.grid.maxRowCount(),
458
+ col: this.inputs.grid.maxColCount()
459
+ })) {
460
+ cell.selected.set(false);
461
+ }
462
+ }
463
+ *_validCells(fromCoords, toCoords) {
464
+ const startRow = Math.min(fromCoords.row, toCoords.row);
465
+ const startCol = Math.min(fromCoords.col, toCoords.col);
466
+ const endRow = Math.max(fromCoords.row, toCoords.row);
467
+ const endCol = Math.max(fromCoords.col, toCoords.col);
468
+ const visited = new Set();
469
+ for (let row = startRow; row < endRow + 1; row++) {
470
+ for (let col = startCol; col < endCol + 1; col++) {
471
+ const cell = this.inputs.grid.getCell({
472
+ row,
473
+ col
474
+ });
475
+ if (cell === undefined) continue;
476
+ if (!cell.selectable()) continue;
477
+ if (cell.disabled()) continue;
478
+ if (visited.has(cell)) continue;
479
+ visited.add(cell);
480
+ yield cell;
481
+ }
482
+ }
483
+ }
484
+ }
485
+
486
+ class Grid {
487
+ inputs;
488
+ data;
489
+ focusBehavior;
490
+ navigationBehavior;
491
+ selectionBehavior;
492
+ selectionAnchor = linkedSignal(() => this.focusBehavior.activeCoords());
493
+ gridTabIndex = computed(() => this.focusBehavior.gridTabIndex());
494
+ gridDisabled = computed(() => this.focusBehavior.gridDisabled());
495
+ activeDescendant = computed(() => this.focusBehavior.activeDescendant());
496
+ constructor(inputs) {
497
+ this.inputs = inputs;
498
+ this.data = new GridData(inputs);
499
+ this.focusBehavior = new GridFocus({
500
+ ...inputs,
501
+ grid: this.data
502
+ });
503
+ this.navigationBehavior = new GridNavigation({
504
+ ...inputs,
505
+ grid: this.data,
506
+ gridFocus: this.focusBehavior
507
+ });
508
+ this.selectionBehavior = new GridSelection({
509
+ ...inputs,
510
+ grid: this.data,
511
+ gridFocus: this.focusBehavior
512
+ });
513
+ }
514
+ rowIndex(cell) {
515
+ const index = this.data.getCoords(cell)?.row;
516
+ return index !== undefined ? index + 1 : undefined;
517
+ }
518
+ colIndex(cell) {
519
+ const index = this.data.getCoords(cell)?.col;
520
+ return index !== undefined ? index + 1 : undefined;
521
+ }
522
+ cellTabIndex(cell) {
523
+ return this.focusBehavior.getCellTabindex(cell);
524
+ }
525
+ up() {
526
+ return this.navigationBehavior.advance(direction.Up);
527
+ }
528
+ rangeSelectUp() {
529
+ const coords = this.navigationBehavior.peek(direction.Up, this.selectionAnchor());
530
+ if (coords === undefined) return;
531
+ this._rangeSelectCoords(coords);
532
+ }
533
+ down() {
534
+ return this.navigationBehavior.advance(direction.Down);
535
+ }
536
+ rangeSelectDown() {
537
+ const coords = this.navigationBehavior.peek(direction.Down, this.selectionAnchor());
538
+ if (coords === undefined) return;
539
+ this._rangeSelectCoords(coords);
540
+ }
541
+ left() {
542
+ return this.navigationBehavior.advance(direction.Left);
543
+ }
544
+ rangeSelectLeft() {
545
+ const coords = this.navigationBehavior.peek(direction.Left, this.selectionAnchor());
546
+ if (coords === undefined) return;
547
+ this._rangeSelectCoords(coords);
548
+ }
549
+ right() {
550
+ return this.navigationBehavior.advance(direction.Right);
551
+ }
552
+ rangeSelectRight() {
553
+ const coords = this.navigationBehavior.peek(direction.Right, this.selectionAnchor());
554
+ if (coords === undefined) return;
555
+ this._rangeSelectCoords(coords);
556
+ }
557
+ first() {
558
+ return this.navigationBehavior.first();
559
+ }
560
+ firstInRow() {
561
+ return this.navigationBehavior.first(this.focusBehavior.activeCoords().row);
562
+ }
563
+ last() {
564
+ return this.navigationBehavior.last();
565
+ }
566
+ lastInRow() {
567
+ return this.navigationBehavior.last(this.focusBehavior.activeCoords().row);
568
+ }
569
+ selectRow() {
570
+ const row = this.focusBehavior.activeCoords().row;
571
+ this.selectionBehavior.deselectAll();
572
+ this.selectionBehavior.select({
573
+ row,
574
+ col: 0
575
+ }, {
576
+ row,
577
+ col: this.data.maxColCount()
578
+ });
579
+ }
580
+ selectCol() {
581
+ const col = this.focusBehavior.activeCoords().col;
582
+ this.selectionBehavior.deselectAll();
583
+ this.selectionBehavior.select({
584
+ row: 0,
585
+ col
586
+ }, {
587
+ row: this.data.maxRowCount(),
588
+ col
589
+ });
590
+ }
591
+ selectAll() {
592
+ this.selectionBehavior.selectAll();
593
+ }
594
+ gotoCell(cell) {
595
+ return this.navigationBehavior.gotoCell(cell);
596
+ }
597
+ toggleSelect(cell) {
598
+ const coords = this.data.getCoords(cell);
599
+ if (coords === undefined) return;
600
+ this.selectionBehavior.toggle(coords);
601
+ }
602
+ rangeSelect(cell) {
603
+ const coords = this.data.getCoords(cell);
604
+ if (coords === undefined) return;
605
+ this._rangeSelectCoords(coords);
606
+ }
607
+ _rangeSelectCoords(coords) {
608
+ const activeCell = this.focusBehavior.activeCell();
609
+ const anchorCell = this.data.getCell(coords);
610
+ if (activeCell === undefined || anchorCell === undefined) {
611
+ return;
612
+ }
613
+ const allCoords = [...this.data.getAllCoords(activeCell), ...this.data.getAllCoords(anchorCell)];
614
+ const allRows = allCoords.map(c => c.row);
615
+ const allCols = allCoords.map(c => c.col);
616
+ const fromCoords = {
617
+ row: Math.min(...allRows),
618
+ col: Math.min(...allCols)
619
+ };
620
+ const toCoords = {
621
+ row: Math.max(...allRows),
622
+ col: Math.max(...allCols)
623
+ };
624
+ this.selectionBehavior.deselectAll();
625
+ this.selectionBehavior.select(fromCoords, toCoords);
626
+ this.selectionAnchor.set(coords);
627
+ }
628
+ resetState() {
629
+ if (this.focusBehavior.stateEmpty()) {
630
+ const firstFocusableCoords = this.navigationBehavior.peekFirst();
631
+ if (firstFocusableCoords === undefined) {
632
+ return false;
633
+ }
634
+ return this.focusBehavior.focusCoordinates(firstFocusableCoords);
635
+ }
636
+ if (this.focusBehavior.stateStale()) {
637
+ if (this.focusBehavior.focusCell(this.focusBehavior.activeCell())) {
638
+ return true;
639
+ }
640
+ if (this.focusBehavior.focusCoordinates(this.focusBehavior.activeCoords())) {
641
+ return true;
642
+ }
643
+ if (this.focusBehavior.focusCoordinates(this.navigationBehavior.peekFirst())) {
644
+ return true;
645
+ }
646
+ }
647
+ return false;
648
+ }
649
+ }
650
+
651
+ class GridPattern {
652
+ inputs;
653
+ gridBehavior;
654
+ cells = computed(() => this.gridBehavior.data.cells());
655
+ tabIndex = computed(() => this.gridBehavior.gridTabIndex());
656
+ disabled = computed(() => this.gridBehavior.gridDisabled());
657
+ activeDescendant = computed(() => this.gridBehavior.activeDescendant());
658
+ activeCell = computed(() => this.gridBehavior.focusBehavior.activeCell());
659
+ pauseNavigation = computed(() => this.gridBehavior.data.cells().flat().reduce((res, c) => res || c.widgetActivated(), false));
660
+ isFocused = signal(false);
661
+ dragging = signal(false);
662
+ keydown = computed(() => {
663
+ const manager = new KeyboardEventManager();
664
+ if (this.pauseNavigation()) {
665
+ return manager;
666
+ }
667
+ manager.on('ArrowUp', () => this.gridBehavior.up()).on('ArrowDown', () => this.gridBehavior.down()).on('ArrowLeft', () => this.gridBehavior.left()).on('ArrowRight', () => this.gridBehavior.right()).on('Home', () => this.gridBehavior.firstInRow()).on('End', () => this.gridBehavior.lastInRow()).on([Modifier.Ctrl], 'Home', () => this.gridBehavior.first()).on([Modifier.Ctrl], 'End', () => this.gridBehavior.last());
668
+ if (this.inputs.enableSelection()) {
669
+ manager.on(Modifier.Shift, 'ArrowUp', () => this.gridBehavior.rangeSelectUp()).on(Modifier.Shift, 'ArrowDown', () => this.gridBehavior.rangeSelectDown()).on(Modifier.Shift, 'ArrowLeft', () => this.gridBehavior.rangeSelectLeft()).on(Modifier.Shift, 'ArrowRight', () => this.gridBehavior.rangeSelectRight()).on([Modifier.Ctrl, Modifier.Meta], 'A', () => this.gridBehavior.selectAll()).on([Modifier.Shift], ' ', () => this.gridBehavior.selectRow()).on([Modifier.Ctrl, Modifier.Meta], ' ', () => this.gridBehavior.selectCol());
670
+ }
671
+ return manager;
672
+ });
673
+ pointerdown = computed(() => {
674
+ const manager = new PointerEventManager();
675
+ manager.on(e => {
676
+ const cell = this.inputs.getCell(e.target);
677
+ if (!cell) return;
678
+ this.gridBehavior.gotoCell(cell);
679
+ if (this.inputs.enableSelection()) {
680
+ this.dragging.set(true);
681
+ }
682
+ });
683
+ if (this.inputs.enableSelection()) {
684
+ manager.on([Modifier.Ctrl, Modifier.Meta], e => {
685
+ const cell = this.inputs.getCell(e.target);
686
+ if (!cell) return;
687
+ this.gridBehavior.toggleSelect(cell);
688
+ }).on(Modifier.Shift, e => {
689
+ const cell = this.inputs.getCell(e.target);
690
+ if (!cell) return;
691
+ this.gridBehavior.rangeSelect(cell);
692
+ this.dragging.set(true);
693
+ });
694
+ }
695
+ return manager;
696
+ });
697
+ pointerup = computed(() => {
698
+ const manager = new PointerEventManager();
699
+ if (this.inputs.enableSelection()) {
700
+ manager.on([Modifier.Shift, Modifier.None], () => {
701
+ this.dragging.set(false);
702
+ });
703
+ }
704
+ return manager;
705
+ });
706
+ constructor(inputs) {
707
+ this.inputs = inputs;
708
+ this.gridBehavior = new Grid({
709
+ ...inputs,
710
+ cells: computed(() => this.inputs.rows().map(row => row.inputs.cells()))
711
+ });
712
+ }
713
+ onKeydown(event) {
714
+ if (!this.disabled()) {
715
+ this.keydown().handle(event);
716
+ }
717
+ }
718
+ onPointerdown(event) {
719
+ if (!this.disabled()) {
720
+ this.pointerdown().handle(event);
721
+ }
722
+ }
723
+ onPointermove(event) {
724
+ if (this.disabled()) return;
725
+ if (!this.inputs.enableSelection()) return;
726
+ if (!this.dragging()) return;
727
+ const cell = this.inputs.getCell(event.target);
728
+ if (!cell) return;
729
+ this.gridBehavior.rangeSelect(cell);
730
+ }
731
+ onPointerup(event) {
732
+ if (!this.disabled()) {
733
+ this.pointerup().handle(event);
734
+ }
735
+ }
736
+ onFocusIn(event) {
737
+ this.isFocused.set(true);
738
+ const cell = this.inputs.getCell(event.target);
739
+ if (!cell) return;
740
+ this.gridBehavior.gotoCell(cell);
741
+ }
742
+ _maybeDeletion = signal(false);
743
+ onFocusOut(event) {
744
+ const parentEl = this.inputs.element();
745
+ const targetEl = event.relatedTarget;
746
+ if (targetEl === null) {
747
+ this._maybeDeletion.set(true);
748
+ }
749
+ if (parentEl.contains(targetEl)) return;
750
+ this.isFocused.set(false);
751
+ }
752
+ _deletion = signal(false);
753
+ resetStateEffect() {
754
+ const hasReset = this.gridBehavior.resetState();
755
+ if (hasReset && this._maybeDeletion()) {
756
+ this._deletion.set(true);
757
+ }
758
+ if (this._maybeDeletion()) {
759
+ this._maybeDeletion.set(false);
760
+ }
761
+ }
762
+ focusEffect() {
763
+ const activeCell = this.activeCell();
764
+ const hasFocus = this.isFocused();
765
+ const deletion = this._deletion();
766
+ const isRoving = this.inputs.focusMode() === 'roving';
767
+ if (activeCell !== undefined && isRoving && (hasFocus || deletion)) {
768
+ activeCell.element().focus();
769
+ if (deletion) {
770
+ this._deletion.set(false);
771
+ }
772
+ }
773
+ }
774
+ }
775
+
776
+ class GridRowPattern {
777
+ inputs;
778
+ rowIndex;
779
+ constructor(inputs) {
780
+ this.inputs = inputs;
781
+ this.rowIndex = inputs.rowIndex;
782
+ }
783
+ }
784
+
785
+ class GridCellPattern {
786
+ inputs;
787
+ id;
788
+ disabled;
789
+ selected;
790
+ selectable;
791
+ rowSpan;
792
+ colSpan;
793
+ ariaSelected = computed(() => this.inputs.grid().inputs.enableSelection() && this.selectable() ? this.selected() : undefined);
794
+ ariaRowIndex = computed(() => this.inputs.row().rowIndex() ?? this.inputs.rowIndex() ?? this.inputs.grid().gridBehavior.rowIndex(this));
795
+ ariaColIndex = computed(() => this.inputs.colIndex() ?? this.inputs.grid().gridBehavior.colIndex(this));
796
+ element = computed(() => this.inputs.widget()?.element() ?? this.inputs.element());
797
+ active = computed(() => this.inputs.grid().activeCell() === this);
798
+ _tabIndex = computed(() => this.inputs.grid().gridBehavior.cellTabIndex(this));
799
+ tabIndex = computed(() => this.inputs.widget() !== undefined ? -1 : this._tabIndex());
800
+ widgetActivated = computed(() => this.inputs.widget()?.inputs.activate() ?? false);
801
+ constructor(inputs) {
802
+ this.inputs = inputs;
803
+ this.id = inputs.id;
804
+ this.disabled = inputs.disabled;
805
+ this.rowSpan = inputs.rowSpan;
806
+ this.colSpan = inputs.colSpan;
807
+ this.selected = inputs.selected;
808
+ this.selectable = inputs.selectable;
809
+ }
810
+ widgetTabIndex() {
811
+ return this._tabIndex();
812
+ }
813
+ }
814
+
815
+ class GridCellWidgetPattern {
816
+ inputs;
817
+ element;
818
+ tabIndex = computed(() => this.inputs.cell().widgetTabIndex());
819
+ active = computed(() => this.inputs.cell().active());
820
+ constructor(inputs) {
821
+ this.inputs = inputs;
822
+ this.element = inputs.element;
823
+ }
824
+ }
825
+
826
+ export { GridCellPattern, GridCellWidgetPattern, GridPattern, GridRowPattern, KeyboardEventManager, Modifier, PointerEventManager };
827
+ //# sourceMappingURL=_widget-chunk.mjs.map