66 * found in the LICENSE file at https://angular.dev/license
77 */
88
9- import { computed } from '@angular/core' ;
9+ import { computed , signal } from '@angular/core' ;
1010import { 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';
1717import { SignalLike } from '../behaviors/signal-like/signal-like' ;
1818
1919import { RadioButtonPatternType , RadioButtonPattern } from '../radio-group/radio-button' ;
2020
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' ;
2822
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>;
3229
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 > ;
3533
3634 /** Whether the tablist is vertically or horizontally oriented. */
3735 readonly orientation : SignalLike < 'vertical' | 'horizontal' > ;
3836
3937 /** Whether the toolbar is disabled. */
40- disabled = computed ( ( ) => this . inputs . disabled ( ) || this . focusManager . isListDisabled ( ) ) ;
38+ disabled = computed ( ( ) => this . inputs . disabled ( ) || this . listBehavior . disabled ( ) ) ;
4139
4240 /** The tabindex of the toolbar (if using activedescendant). */
43- tabindex = computed ( ( ) => this . focusManager . getListTabindex ( ) ) ;
41+ tabindex = computed ( ( ) => this . listBehavior . tabindex ( ) ) ;
4442
4543 /** The id of the current active widget (if using activedescendant). */
46- activedescendant = computed ( ( ) => this . focusManager . getActiveDescendant ( ) ) ;
44+ activedescendant = computed ( ( ) => this . listBehavior . activedescendant ( ) ) ;
4745
4846 /** The key used to navigate to the previous widget. */
4947 prevKey = computed ( ( ) => {
@@ -64,28 +62,44 @@ export class ToolbarPattern<V> {
6462 /** The keydown event manager for the toolbar. */
6563 keydown = computed ( ( ) => {
6664 const manager = new KeyboardEventManager ( ) ;
65+ console . log ( ' all curent itmes' , this . inputs . items ( ) ) ;
6766
6867 return manager
6968 . on ( ' ' , ( ) => this . toolbarSelectOverride ( ) )
7069 . 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 ( ) ) ;
7577 } ) ;
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+ }
7688
7789 toolbarSelectOverride ( ) {
78- const activeItem = this . focusManager . activeItem ( ) ;
90+ const activeItem = this . inputs . activeItem ( ) ;
7991
8092 /** If the active item is a Radio Button, indicate to the group the selection */
8193 if ( activeItem instanceof RadioButtonPattern ) {
8294 const group = activeItem . group ( ) ;
8395 if ( group && ! group . readonly ( ) ) {
84- group . selection . selectOne ( ) ;
96+ group . listBehavior . selectOne ( ) ;
8597 }
98+ // todo fix
8699 } else {
87100 /** 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 ( ) ;
89103 }
90104 }
91105
@@ -100,8 +114,12 @@ export class ToolbarPattern<V> {
100114 /** Navigates to the widget associated with the given pointer event. */
101115 goto ( event : PointerEvent ) {
102116 const item = this . _getItem ( event ) ;
117+ if ( ! item ) return ;
103118
104- this . navigation . goto ( item ) ;
119+ if ( item instanceof RadioButtonPattern ) {
120+ // have the radio group handle the selection
121+ }
122+ this . listBehavior . goto ( item ) ;
105123 }
106124
107125 /** Handles keydown events for the toolbar. */
@@ -113,13 +131,14 @@ export class ToolbarPattern<V> {
113131
114132 /** Handles pointerdown events for the toolbar. */
115133 onPointerdown ( event : PointerEvent ) {
134+ console . log ( 'this disabled' , this . disabled ( ) ) ;
116135 if ( ! this . disabled ( ) ) {
117136 this . pointerdown ( ) . handle ( event ) ;
118137 }
119138 }
120139
121140 /** 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 {
123142 if ( ! ( e . target instanceof HTMLElement ) ) {
124143 return undefined ;
125144 }
@@ -132,10 +151,12 @@ export class ToolbarPattern<V> {
132151 constructor ( readonly inputs : ToolbarInputs < V > ) {
133152 this . orientation = inputs . orientation ;
134153
135- this . focusManager = new ListFocus ( inputs ) ;
136- this . navigation = new ListNavigation ( {
154+ this . listBehavior = new List ( {
137155 ...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.
139160 } ) ;
140161 }
141162
@@ -146,22 +167,23 @@ export class ToolbarPattern<V> {
146167 * Otherwise, sets the active index to the first focusable widget.
147168 */
148169 setDefaultState ( ) {
149- let firstItem : RadioButtonPatternType < V > | ToolbarWidgetPattern | null = null ;
170+ let firstItem : RadioButtonPattern < V > | ToolbarWidgetPattern | null = null ;
150171
151172 for ( const item of this . inputs . items ( ) ) {
152- if ( this . focusManager . isFocusable ( item ) ) {
173+ if ( this . listBehavior . isFocusable ( item ) ) {
153174 if ( ! firstItem ) {
154175 firstItem = item ;
155176 }
156177 if ( item instanceof RadioButtonPattern && item . selected ( ) ) {
157- this . inputs . activeIndex . set ( item . index ( ) ) ;
178+ this . inputs . activeItem . set ( item ) ;
158179 return ;
159180 }
160181 }
161182 }
162183
163184 if ( firstItem ) {
164- this . inputs . activeIndex . set ( firstItem . index ( ) ) ;
185+ console . log ( 'setting active item to' , firstItem ) ;
186+ this . inputs . activeItem . set ( firstItem ) ;
165187 }
166188 }
167189 /** Validates the state of the toolbar and returns a list of accessibility violations. */
@@ -183,12 +205,13 @@ export class ToolbarPattern<V> {
183205
184206export type ToolbarWidget = {
185207 id : SignalLike < string > ;
208+ index : SignalLike < number > ;
186209 element : SignalLike < HTMLElement > ;
187210 disabled : SignalLike < boolean > ;
188211} ;
189212
190213/** 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' > {
192215 /** A reference to the parent toolbar. */
193216 parentToolbar : SignalLike < ToolbarPattern < null > > ;
194217}
@@ -205,18 +228,18 @@ export class ToolbarWidgetPattern {
205228 parentToolbar : SignalLike < ToolbarPattern < null > | undefined > ;
206229
207230 /** 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.
209237
210238 /** 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 ) ;
217240
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 ) ;
220243
221244 constructor ( readonly inputs : ToolbarWidgetInputs ) {
222245 this . id = inputs . id ;
@@ -226,4 +249,5 @@ export class ToolbarWidgetPattern {
226249 }
227250}
228251
252+ // can remove later
229253export type ToolbarPatternType < V > = InstanceType < typeof ToolbarPattern < V > > ;
0 commit comments