|
6 | 6 | * found in the LICENSE file at https://angular.dev/license |
7 | 7 | */ |
8 | 8 |
|
9 | | -import {computed} from '@angular/core'; |
10 | | -import {SignalLike} from '../behaviors/signal-like/signal-like'; |
11 | 9 | import {ListItem} from '../behaviors/list/list'; |
| 10 | +import {SignalLike} from '../behaviors/signal-like/signal-like'; |
12 | 11 | import type {ToolbarPattern} from './toolbar'; |
13 | 12 |
|
14 | | -/** An interface that allows sub patterns to expose the necessary controls for the toolbar. */ |
15 | | -export interface ToolbarWidgetGroupControls { |
16 | | - /** Whether the widget group is currently on the first item. */ |
17 | | - isOnFirstItem(): boolean; |
18 | | - |
19 | | - /** Whether the widget group is currently on the last item. */ |
20 | | - isOnLastItem(): boolean; |
21 | | - |
22 | | - /** Navigates to the next widget in the group. */ |
23 | | - next(wrap: boolean): void; |
24 | | - |
25 | | - /** Navigates to the previous widget in the group. */ |
26 | | - prev(wrap: boolean): void; |
27 | | - |
28 | | - /** Navigates to the first widget in the group. */ |
29 | | - first(): void; |
30 | | - |
31 | | - /** Navigates to the last widget in the group. */ |
32 | | - last(): void; |
33 | | - |
34 | | - /** Removes focus from the widget group. */ |
35 | | - unfocus(): void; |
36 | | - |
37 | | - /** Triggers the action of the currently active widget in the group. */ |
38 | | - trigger(): void; |
39 | | - |
40 | | - /** Navigates to the widget targeted by a pointer event. */ |
41 | | - goto(event: PointerEvent): void; |
42 | | - |
43 | | - /** Sets the widget group to its default initial state. */ |
44 | | - setDefaultState(): void; |
45 | | -} |
46 | | - |
47 | 13 | /** Represents the required inputs for a toolbar widget group. */ |
48 | | -export interface ToolbarWidgetGroupInputs<V> |
49 | | - extends Omit<ListItem<V>, 'searchTerm' | 'value' | 'index' | 'selectable'> { |
| 14 | +export interface ToolbarWidgetGroupInputs<T extends ListItem<V>, V> { |
50 | 15 | /** A reference to the parent toolbar. */ |
51 | 16 | toolbar: SignalLike<ToolbarPattern<V> | undefined>; |
52 | 17 |
|
53 | | - /** The controls for the sub patterns associated with the toolbar. */ |
54 | | - controls: SignalLike<ToolbarWidgetGroupControls | undefined>; |
55 | | -} |
| 18 | + /** Whether the widget group is disabled. */ |
| 19 | + disabled: SignalLike<boolean>; |
56 | 20 |
|
57 | | -/** A group of widgets within a toolbar that provides nested navigation. */ |
58 | | -export class ToolbarWidgetGroupPattern<V> implements ListItem<V> { |
59 | | - /** A unique identifier for the widget. */ |
60 | | - readonly id: SignalLike<string>; |
| 21 | + /** The list of items within the widget group. */ |
| 22 | + items: SignalLike<T[]>; |
61 | 23 |
|
62 | | - /** The html element that should receive focus. */ |
63 | | - readonly element: SignalLike<HTMLElement>; |
| 24 | + /** Whether the group allows multiple widgets to be selected. */ |
| 25 | + multi: SignalLike<boolean>; |
| 26 | +} |
64 | 27 |
|
| 28 | +/** A group of widgets within a toolbar that provides nested navigation. */ |
| 29 | +export class ToolbarWidgetGroupPattern<T extends ListItem<V>, V> { |
65 | 30 | /** Whether the widget is disabled. */ |
66 | | - readonly disabled: SignalLike<boolean>; |
| 31 | + readonly disabled = () => this.inputs.disabled(); |
67 | 32 |
|
68 | 33 | /** A reference to the parent toolbar. */ |
69 | | - readonly toolbar: SignalLike<ToolbarPattern<V> | undefined>; |
| 34 | + readonly toolbar = () => this.inputs.toolbar(); |
70 | 35 |
|
71 | | - /** The text used by the typeahead search. */ |
72 | | - readonly searchTerm = () => ''; // Unused because toolbar does not support typeahead. |
| 36 | + /** Whether the group allows multiple widgets to be selected. */ |
| 37 | + readonly multi = () => this.inputs.multi(); |
73 | 38 |
|
74 | | - /** The value associated with the widget. */ |
| 39 | + readonly searchTerm = () => ''; // Unused because toolbar does not support typeahead. |
75 | 40 | readonly value = () => '' as V; // Unused because toolbar does not support selection. |
76 | | - |
77 | | - /** Whether the widget is selectable. */ |
78 | 41 | readonly selectable = () => true; // Unused because toolbar does not support selection. |
| 42 | + readonly element = () => undefined; // Unused because toolbar does not focus the group element. |
79 | 43 |
|
80 | | - /** The position of the widget within the toolbar. */ |
81 | | - readonly index = computed(() => this.toolbar()?.inputs.items().indexOf(this) ?? -1); |
82 | | - |
83 | | - /** The actions that can be performed on the widget group. */ |
84 | | - readonly controls: SignalLike<ToolbarWidgetGroupControls> = computed( |
85 | | - () => this.inputs.controls() ?? this._defaultControls, |
86 | | - ); |
87 | | - |
88 | | - /** Default toolbar widget group controls when no controls provided. */ |
89 | | - private readonly _defaultControls: ToolbarWidgetGroupControls = { |
90 | | - isOnFirstItem: () => true, |
91 | | - isOnLastItem: () => true, |
92 | | - next: () => {}, |
93 | | - prev: () => {}, |
94 | | - first: () => {}, |
95 | | - last: () => {}, |
96 | | - unfocus: () => {}, |
97 | | - trigger: () => {}, |
98 | | - goto: () => {}, |
99 | | - setDefaultState: () => {}, |
100 | | - }; |
101 | | - |
102 | | - constructor(readonly inputs: ToolbarWidgetGroupInputs<V>) { |
103 | | - this.id = inputs.id; |
104 | | - this.element = inputs.element; |
105 | | - this.disabled = inputs.disabled; |
106 | | - this.toolbar = inputs.toolbar; |
107 | | - } |
| 44 | + constructor(readonly inputs: ToolbarWidgetGroupInputs<T, V>) {} |
108 | 45 | } |
0 commit comments