@@ -84,36 +84,42 @@ function ActionGroup<T extends object>(props: SpectrumActionGroupProps<T>, ref:
84
84
}
85
85
86
86
let computeVisibleItems = ( visibleItems : number ) => {
87
- let listItems = Array . from ( domRef . current . children ) as HTMLLIElement [ ] ;
88
- let containerSize = orientation === 'horizontal' ? wrapperRef . current . offsetWidth : wrapperRef . current . offsetHeight ;
89
- let isShowingMenu = visibleItems < state . collection . size ;
90
- let calculatedSize = 0 ;
91
- let newVisibleItems = 0 ;
92
-
93
- if ( isShowingMenu ) {
94
- calculatedSize += orientation === 'horizontal'
95
- ? outerWidth ( listItems . pop ( ) , false , true )
96
- : outerHeight ( listItems . pop ( ) , false , true ) ;
97
- }
87
+ if ( domRef . current && wrapperRef . current ) {
88
+ let listItems = Array . from ( domRef . current . children ) as HTMLLIElement [ ] ;
89
+ let containerSize = orientation === 'horizontal' ? wrapperRef . current . offsetWidth : wrapperRef . current . offsetHeight ;
90
+ let isShowingMenu = visibleItems < state . collection . size ;
91
+ let calculatedSize = 0 ;
92
+ let newVisibleItems = 0 ;
93
+
94
+ if ( isShowingMenu ) {
95
+ let item = listItems . pop ( ) ;
96
+ if ( item ) {
97
+ calculatedSize += orientation === 'horizontal'
98
+ ? outerWidth ( item , false , true )
99
+ : outerHeight ( item , false , true ) ;
100
+ }
101
+ }
98
102
99
- for ( let [ i , item ] of listItems . entries ( ) ) {
100
- calculatedSize += orientation === 'horizontal'
101
- ? outerWidth ( item , i === 0 , i === listItems . length - 1 )
102
- : outerHeight ( item , i === 0 , i === listItems . length - 1 ) ;
103
- if ( calculatedSize <= containerSize ) {
104
- newVisibleItems ++ ;
105
- } else {
106
- break ;
103
+ for ( let [ i , item ] of listItems . entries ( ) ) {
104
+ calculatedSize += orientation === 'horizontal'
105
+ ? outerWidth ( item , i === 0 , i === listItems . length - 1 )
106
+ : outerHeight ( item , i === 0 , i === listItems . length - 1 ) ;
107
+ if ( calculatedSize <= containerSize ) {
108
+ newVisibleItems ++ ;
109
+ } else {
110
+ break ;
111
+ }
107
112
}
108
- }
109
113
110
- // If selection is enabled, and not all of the items fit, collapse all of them into a dropdown
111
- // immediately rather than having some visible and some not.
112
- if ( selectionMode !== 'none' && newVisibleItems < state . collection . size ) {
113
- return 0 ;
114
- }
114
+ // If selection is enabled, and not all of the items fit, collapse all of them into a dropdown
115
+ // immediately rather than having some visible and some not.
116
+ if ( selectionMode !== 'none' && newVisibleItems < state . collection . size ) {
117
+ return 0 ;
118
+ }
115
119
116
- return newVisibleItems ;
120
+ return newVisibleItems ;
121
+ }
122
+ return visibleItems ;
117
123
} ;
118
124
119
125
setVisibleItems ( function * ( ) {
@@ -166,14 +172,14 @@ function ActionGroup<T extends object>(props: SpectrumActionGroupProps<T>, ref:
166
172
// in all scenarios because it may not shrink when available space is reduced.
167
173
let parentRef = useMemo ( ( ) => ( {
168
174
get current ( ) {
169
- return wrapperRef . current . parentElement ;
175
+ return wrapperRef . current ? .parentElement ;
170
176
}
171
177
} ) , [ wrapperRef ] ) ;
172
- useResizeObserver ( { ref : overflowMode !== 'wrap' ? parentRef : null , onResize : updateOverflow } ) ;
178
+ useResizeObserver ( { ref : overflowMode !== 'wrap' ? parentRef : undefined , onResize : updateOverflow } ) ;
173
179
useLayoutEffect ( updateOverflow , [ updateOverflow , state . collection ] ) ;
174
180
175
181
let children = [ ...state . collection ] ;
176
- let menuItem = null ;
182
+ let menuItem : ReactElement | null = null ;
177
183
let menuProps = { } ;
178
184
179
185
// If there are no visible items, don't apply any props to the action group container
@@ -257,16 +263,16 @@ export {_ActionGroup as ActionGroup};
257
263
interface ActionGroupItemProps < T > extends DOMProps , StyleProps {
258
264
item : Node < T > ,
259
265
state : ListState < T > ,
260
- isDisabled : boolean ,
261
- isEmphasized : boolean ,
266
+ isDisabled ? : boolean ,
267
+ isEmphasized ? : boolean ,
262
268
staticColor ?: 'white' | 'black' ,
263
269
hideButtonText ?: boolean ,
264
270
orientation ?: 'horizontal' | 'vertical' ,
265
- onAction : ( key : Key ) => void
271
+ onAction ? : ( key : Key ) => void
266
272
}
267
273
268
274
function ActionGroupItem < T > ( { item, state, isDisabled, isEmphasized, staticColor, onAction, hideButtonText, orientation} : ActionGroupItemProps < T > ) {
269
- let ref = useRef ( ) ;
275
+ let ref = useRef ( null ) ;
270
276
let { buttonProps} = useActionGroupItem ( { key : item . key } , state ) ;
271
277
isDisabled = isDisabled || state . disabledKeys . has ( item . key ) ;
272
278
let isSelected = state . selectionManager . isSelected ( item . key ) ;
@@ -282,7 +288,7 @@ function ActionGroupItem<T>({item, state, isDisabled, isEmphasized, staticColor,
282
288
// If button text is hidden, we need to show it as a tooltip instead, so
283
289
// go find the text element in the DOM after rendering.
284
290
let textId = useId ( ) ;
285
- let [ textContent , setTextContent ] = useState ( '' ) ;
291
+ let [ textContent , setTextContent ] = useState < string | null | undefined > ( '' ) ;
286
292
useLayoutEffect ( ( ) => {
287
293
if ( hideButtonText ) {
288
294
setTextContent ( document . getElementById ( textId ) ?. textContent ) ;
@@ -359,7 +365,7 @@ interface ActionGroupMenuProps<T> extends AriaLabelingProps {
359
365
summaryIcon ?: ReactNode ,
360
366
isOnlyItem ?: boolean ,
361
367
orientation ?: 'horizontal' | 'vertical' ,
362
- onAction : ( key : Key ) => void
368
+ onAction ? : ( key : Key ) => void
363
369
}
364
370
365
371
function ActionGroupMenu < T > ( { state, isDisabled, isEmphasized, staticColor, items, onAction, summaryIcon, hideButtonText, isOnlyItem, orientation, ...otherProps } : ActionGroupMenuProps < T > ) {
@@ -376,7 +382,7 @@ function ActionGroupMenu<T>({state, isDisabled, isEmphasized, staticColor, items
376
382
let { hoverProps, isHovered} = useHover ( { isDisabled} ) ;
377
383
378
384
// If no aria-label or aria-labelledby is given, provide a default one.
379
- let ariaLabel = otherProps [ 'aria-label' ] || ( otherProps [ 'aria-labelledby' ] ? null : '…' ) ;
385
+ let ariaLabel = otherProps [ 'aria-label' ] || ( otherProps [ 'aria-labelledby' ] ? undefined : '…' ) ;
380
386
let ariaLabelledby = otherProps [ 'aria-labelledby' ] ;
381
387
let textId = useId ( ) ;
382
388
let id = useId ( ) ;
@@ -392,14 +398,14 @@ function ActionGroupMenu<T>({state, isDisabled, isEmphasized, staticColor, items
392
398
let isSelected = state . selectionManager . selectionMode !== 'none' && ! state . selectionManager . isEmpty ;
393
399
394
400
// If single selection and empty selection is not allowed, swap the contents of the button to the selected item (like a Picker).
395
- if ( ! summaryIcon && state . selectionManager . selectionMode === 'single' && state . selectionManager . disallowEmptySelection ) {
401
+ if ( ! summaryIcon && state . selectionManager . selectionMode === 'single' && state . selectionManager . disallowEmptySelection && state . selectionManager . firstSelectedKey != null ) {
396
402
let selectedItem = state . collection . getItem ( state . selectionManager . firstSelectedKey ) ;
397
403
if ( selectedItem ) {
398
404
summaryIcon = selectedItem . rendered ;
399
405
if ( typeof summaryIcon === 'string' ) {
400
406
summaryIcon = < Text > { summaryIcon } </ Text > ;
401
407
}
402
- iconOnly = hideButtonText ;
408
+ iconOnly = ! ! hideButtonText ;
403
409
ariaLabelledby = `${ ariaLabelledby ?? id } ${ textId } ` ;
404
410
}
405
411
}
@@ -453,7 +459,7 @@ function ActionGroupMenu<T>({state, isDisabled, isEmphasized, staticColor, items
453
459
}
454
460
isDisabled = { isDisabled }
455
461
staticColor = { staticColor } >
456
- { summaryIcon || < More /> }
462
+ { summaryIcon ? < More /> : null }
457
463
</ ActionButton >
458
464
</ PressResponder >
459
465
</ SlotProvider >
0 commit comments