6
6
* found in the LICENSE file at https://angular.dev/license
7
7
*/
8
8
9
- import { computed } from '@angular/core' ;
9
+ import { computed , signal } from '@angular/core' ;
10
10
import { KeyboardEventManager , PointerEventManager } from '../behaviors/event-manager' ;
11
- import { ListFocus , ListFocusInputs , ListFocusItem } from '../behaviors/list-focus/list-focus' ;
12
- import {
13
- ListNavigation ,
14
- ListNavigationInputs ,
15
- ListNavigationItem ,
16
- } from '../behaviors/list-navigation/list-navigation' ;
11
+ // import {ListFocus, ListFocusInputs, ListFocusItem} from '../behaviors/list-focus/list-focus';
12
+ // import {
13
+ // ListNavigation,
14
+ // ListNavigationInputs,
15
+ // ListNavigationItem,
16
+ // } from '../behaviors/list-navigation/list-navigation';
17
17
import { SignalLike } from '../behaviors/signal-like/signal-like' ;
18
18
19
19
import { RadioButtonPatternType , RadioButtonPattern } from '../radio-group/radio-button' ;
20
20
21
- export type ToolbarInputs < V > = ListNavigationInputs <
22
- RadioButtonPatternType < V > | ToolbarWidgetPattern
23
- > &
24
- ListFocusInputs < RadioButtonPatternType < V > | ToolbarWidgetPattern > & {
25
- /** Whether the toolbar is disabled. */
26
- disabled : SignalLike < boolean > ;
27
- } ;
21
+ import { List , ListInputs , ListItem } from '../behaviors/list/list' ;
28
22
29
- export class ToolbarPattern < V > {
30
- /** Controls navigation for the toolbar. */
31
- navigation : ListNavigation < RadioButtonPatternType < V > | ToolbarWidgetPattern > ;
23
+ // remove typeahead etc.
24
+ export type ToolbarInputs < V > = Omit <
25
+ ListInputs < ToolbarWidgetPattern | RadioButtonPattern < V > , V > ,
26
+ 'multi' | 'typeaheadDelay' | 'value' | 'selectionMode'
27
+ > ;
28
+ // ListInputs<ToolbarWidgetPattern | RadioButtonPattern<V>, V>;
32
29
33
- /** Controls focus for the toolbar. */
34
- focusManager : ListFocus < RadioButtonPatternType < V > | ToolbarWidgetPattern > ;
30
+ export class ToolbarPattern < V > {
31
+ /** The list behavior for the toolbar. */
32
+ listBehavior : List < ToolbarWidgetPattern | RadioButtonPattern < V > , V > ;
35
33
36
34
/** Whether the tablist is vertically or horizontally oriented. */
37
35
readonly orientation : SignalLike < 'vertical' | 'horizontal' > ;
38
36
39
37
/** Whether the toolbar is disabled. */
40
- disabled = computed ( ( ) => this . inputs . disabled ( ) || this . focusManager . isListDisabled ( ) ) ;
38
+ disabled = computed ( ( ) => this . inputs . disabled ( ) || this . listBehavior . disabled ( ) ) ;
41
39
42
40
/** The tabindex of the toolbar (if using activedescendant). */
43
- tabindex = computed ( ( ) => this . focusManager . getListTabindex ( ) ) ;
41
+ tabindex = computed ( ( ) => this . listBehavior . tabindex ( ) ) ;
44
42
45
43
/** The id of the current active widget (if using activedescendant). */
46
- activedescendant = computed ( ( ) => this . focusManager . getActiveDescendant ( ) ) ;
44
+ activedescendant = computed ( ( ) => this . listBehavior . activedescendant ( ) ) ;
47
45
48
46
/** The key used to navigate to the previous widget. */
49
47
prevKey = computed ( ( ) => {
@@ -64,28 +62,44 @@ export class ToolbarPattern<V> {
64
62
/** The keydown event manager for the toolbar. */
65
63
keydown = computed ( ( ) => {
66
64
const manager = new KeyboardEventManager ( ) ;
65
+ console . log ( ' all curent itmes' , this . inputs . items ( ) ) ;
67
66
68
67
return manager
69
68
. on ( ' ' , ( ) => this . toolbarSelectOverride ( ) )
70
69
. on ( 'Enter' , ( ) => this . toolbarSelectOverride ( ) )
71
- . on ( this . prevKey , ( ) => this . navigation . prev ( ) )
72
- . on ( this . nextKey , ( ) => this . navigation . next ( ) )
73
- . on ( 'Home' , ( ) => this . navigation . first ( ) )
74
- . on ( 'End' , ( ) => this . navigation . last ( ) ) ;
70
+ . on ( this . prevKey , ( ) => this . listBehavior . prev ( ) )
71
+ . on ( this . nextKey , ( ) => {
72
+ console . log ( 'next' ) ;
73
+ this . next ( ) ;
74
+ } )
75
+ . on ( 'Home' , ( ) => this . listBehavior . first ( ) )
76
+ . on ( 'End' , ( ) => this . listBehavior . last ( ) ) ;
75
77
} ) ;
78
+ next ( ) {
79
+ const activeItem = this . inputs . activeItem ( ) ;
80
+ // if (activeItem instanceof RadioButtonPattern && activeItem.group()!!) {
81
+ // console.log('let the group move itself');
82
+ // activeItem.group()!!.listBehavior.next();
83
+ // } else
84
+ this . listBehavior . next ( ) ;
85
+ // find what is the next item
86
+ // console.log('next item', this.listBehavior.nextItem());
87
+ }
76
88
77
89
toolbarSelectOverride ( ) {
78
- const activeItem = this . focusManager . activeItem ( ) ;
90
+ const activeItem = this . inputs . activeItem ( ) ;
79
91
80
92
/** If the active item is a Radio Button, indicate to the group the selection */
81
93
if ( activeItem instanceof RadioButtonPattern ) {
82
94
const group = activeItem . group ( ) ;
83
95
if ( group && ! group . readonly ( ) ) {
84
- group . selection . selectOne ( ) ;
96
+ group . listBehavior . selectOne ( ) ;
85
97
}
98
+ // todo fix
86
99
} else {
87
100
/** Item is a Toolbar Widget, manually select it */
88
- if ( activeItem . element ( ) ) activeItem . element ( ) . click ( ) ;
101
+ if ( activeItem && activeItem . element ( ) && ! activeItem . disabled ( ) )
102
+ activeItem . element ( ) . click ( ) ;
89
103
}
90
104
}
91
105
@@ -100,8 +114,12 @@ export class ToolbarPattern<V> {
100
114
/** Navigates to the widget associated with the given pointer event. */
101
115
goto ( event : PointerEvent ) {
102
116
const item = this . _getItem ( event ) ;
117
+ if ( ! item ) return ;
103
118
104
- this . navigation . goto ( item ) ;
119
+ if ( item instanceof RadioButtonPattern ) {
120
+ // have the radio group handle the selection
121
+ }
122
+ this . listBehavior . goto ( item ) ;
105
123
}
106
124
107
125
/** Handles keydown events for the toolbar. */
@@ -113,13 +131,14 @@ export class ToolbarPattern<V> {
113
131
114
132
/** Handles pointerdown events for the toolbar. */
115
133
onPointerdown ( event : PointerEvent ) {
134
+ console . log ( 'this disabled' , this . disabled ( ) ) ;
116
135
if ( ! this . disabled ( ) ) {
117
136
this . pointerdown ( ) . handle ( event ) ;
118
137
}
119
138
}
120
139
121
140
/** Finds the Toolbar Widget associated with a pointer event target. */
122
- private _getItem ( e : PointerEvent ) : RadioButtonPatternType < V > | ToolbarWidgetPattern | undefined {
141
+ private _getItem ( e : PointerEvent ) : RadioButtonPattern < V > | ToolbarWidgetPattern | undefined {
123
142
if ( ! ( e . target instanceof HTMLElement ) ) {
124
143
return undefined ;
125
144
}
@@ -132,10 +151,12 @@ export class ToolbarPattern<V> {
132
151
constructor ( readonly inputs : ToolbarInputs < V > ) {
133
152
this . orientation = inputs . orientation ;
134
153
135
- this . focusManager = new ListFocus ( inputs ) ;
136
- this . navigation = new ListNavigation ( {
154
+ this . listBehavior = new List ( {
137
155
...inputs ,
138
- focusManager : this . focusManager ,
156
+ multi : ( ) => false ,
157
+ selectionMode : ( ) => 'explicit' ,
158
+ value : signal ( [ ] as any ) ,
159
+ typeaheadDelay : ( ) => 0 , // Toolbar widgets do not support typeahead.
139
160
} ) ;
140
161
}
141
162
@@ -146,22 +167,23 @@ export class ToolbarPattern<V> {
146
167
* Otherwise, sets the active index to the first focusable widget.
147
168
*/
148
169
setDefaultState ( ) {
149
- let firstItem : RadioButtonPatternType < V > | ToolbarWidgetPattern | null = null ;
170
+ let firstItem : RadioButtonPattern < V > | ToolbarWidgetPattern | null = null ;
150
171
151
172
for ( const item of this . inputs . items ( ) ) {
152
- if ( this . focusManager . isFocusable ( item ) ) {
173
+ if ( this . listBehavior . isFocusable ( item ) ) {
153
174
if ( ! firstItem ) {
154
175
firstItem = item ;
155
176
}
156
177
if ( item instanceof RadioButtonPattern && item . selected ( ) ) {
157
- this . inputs . activeIndex . set ( item . index ( ) ) ;
178
+ this . inputs . activeItem . set ( item ) ;
158
179
return ;
159
180
}
160
181
}
161
182
}
162
183
163
184
if ( firstItem ) {
164
- this . inputs . activeIndex . set ( firstItem . index ( ) ) ;
185
+ console . log ( 'setting active item to' , firstItem ) ;
186
+ this . inputs . activeItem . set ( firstItem ) ;
165
187
}
166
188
}
167
189
/** Validates the state of the toolbar and returns a list of accessibility violations. */
@@ -183,12 +205,13 @@ export class ToolbarPattern<V> {
183
205
184
206
export type ToolbarWidget = {
185
207
id : SignalLike < string > ;
208
+ index : SignalLike < number > ;
186
209
element : SignalLike < HTMLElement > ;
187
210
disabled : SignalLike < boolean > ;
188
211
} ;
189
212
190
213
/** Represents the required inputs for a toolbar widget in a toolbar. */
191
- export interface ToolbarWidgetInputs extends ListNavigationItem , ListFocusItem {
214
+ export interface ToolbarWidgetInputs extends Omit < ListItem < any > , 'searchTerm' | 'value' | 'index' > {
192
215
/** A reference to the parent toolbar. */
193
216
parentToolbar : SignalLike < ToolbarPattern < null > > ;
194
217
}
@@ -205,18 +228,18 @@ export class ToolbarWidgetPattern {
205
228
parentToolbar : SignalLike < ToolbarPattern < null > | undefined > ;
206
229
207
230
/** The tabindex of the widgdet. */
208
- tabindex = computed ( ( ) => this . inputs . parentToolbar ( ) . focusManager . getItemTabindex ( this ) ) ;
231
+ tabindex = computed ( ( ) => this . inputs . parentToolbar ( ) . listBehavior . getItemTabindex ( this ) ) ;
232
+
233
+ /** The text used by the typeahead search. */
234
+ readonly searchTerm = ( ) => '' ; // Unused because toolbar does not support typeahead.
235
+
236
+ readonly value = ( ) => '' as any ; // Unused because toolbar does not support selection.
209
237
210
238
/** The position of the widget within the group. */
211
- index = computed (
212
- ( ) =>
213
- this . parentToolbar ( )
214
- ?. navigation . inputs . items ( )
215
- . findIndex ( i => i . id ( ) === this . id ( ) ) ?? - 1 ,
216
- ) ;
239
+ index = computed ( ( ) => this . parentToolbar ( ) ?. inputs . items ( ) . indexOf ( this ) ?? - 1 ) ;
217
240
218
- /** Whether the widhet is currently the active one (focused). */
219
- active = computed ( ( ) => this . inputs . parentToolbar ( ) . focusManager . activeItem ( ) === this ) ;
241
+ /** Whether the widget is currently the active one (focused). */
242
+ active = computed ( ( ) => this . parentToolbar ( ) ?. inputs . activeItem ( ) === this ) ;
220
243
221
244
constructor ( readonly inputs : ToolbarWidgetInputs ) {
222
245
this . id = inputs . id ;
@@ -226,4 +249,5 @@ export class ToolbarWidgetPattern {
226
249
}
227
250
}
228
251
252
+ // can remove later
229
253
export type ToolbarPatternType < V > = InstanceType < typeof ToolbarPattern < V > > ;
0 commit comments