Skip to content

Commit b20395a

Browse files
committed
Fix(Toolbar (compat)): exclude spacer from overflow popover
1 parent ce3972b commit b20395a

File tree

2 files changed

+35
-43
lines changed

2 files changed

+35
-43
lines changed

packages/compat/src/components/Toolbar/OverflowPopover.tsx

Lines changed: 34 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ interface OverflowPopoverProps {
2727
children: ReactNode[];
2828
portalContainer: Element;
2929
overflowContentRef: Ref<HTMLDivElement>;
30-
numberOfAlwaysVisibleItems?: number;
3130
overflowPopoverRef?: Ref<PopoverDomRef>;
3231
overflowButton?: ReactElement<ToggleButtonPropTypes> | ReactElement<ButtonPropTypes>;
3332
setIsMounted: Dispatch<SetStateAction<boolean>>;
@@ -43,7 +42,6 @@ export const OverflowPopover: FC<OverflowPopoverProps> = (props: OverflowPopover
4342
children,
4443
portalContainer,
4544
overflowContentRef,
46-
numberOfAlwaysVisibleItems,
4745
overflowButton,
4846
overflowPopoverRef,
4947
setIsMounted,
@@ -127,49 +125,44 @@ export const OverflowPopover: FC<OverflowPopoverProps> = (props: OverflowPopover
127125

128126
const OverflowPopoverContextProvider = getOverflowPopoverContext().Provider;
129127

130-
let startIndex = null;
131-
const filteredChildrenArray = children
128+
const visibleChildren = (children as ReactElement[])
129+
.slice(lastVisibleIndex)
130+
// @ts-expect-error: if type is not defined, it's not a spacer
131+
.filter((child) => child.type?.displayName !== 'ToolbarSpacer' && isValidElement(child))
132132
.map((item, index, arr) => {
133-
if (index > lastVisibleIndex && index > numberOfAlwaysVisibleItems - 1 && isValidElement(item)) {
134-
if (startIndex === null) {
135-
startIndex = index;
136-
}
137-
const labelProp = item?.props?.['data-accessible-name'] ? 'accessibleName' : 'aria-label';
138-
let labelVal = i18nBundle.getText(X_OF_Y, index + 1 - startIndex, arr.length - startIndex);
139-
if (item?.props?.[labelProp]) {
140-
labelVal += ' ' + item.props[labelProp];
141-
}
133+
const labelProp = item?.props?.['data-accessible-name'] ? 'accessibleName' : 'aria-label';
134+
let labelVal = i18nBundle.getText(X_OF_Y, index + 1, arr.length);
135+
if (item?.props?.[labelProp]) {
136+
labelVal += ' ' + item.props[labelProp];
137+
}
142138

143-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
144-
// @ts-ignore: React 19
145-
if (item?.props?.id) {
146-
return cloneElement<HTMLAttributes<HTMLElement>>(item, {
147-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
148-
// @ts-ignore: React 19
149-
id: `${item.props.id}-overflow`,
150-
[labelProp]: labelVal
151-
});
152-
}
153-
// @ts-expect-error: if type is not defined, it's not a spacer
154-
if (item.type?.displayName === 'ToolbarSeparator') {
155-
return cloneElement(item as ReactElement, {
156-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
157-
// @ts-ignore: React 19
158-
style: {
159-
height: '0.0625rem',
160-
margin: '0.375rem 0.1875rem',
161-
width: '100%'
162-
},
163-
'aria-label': labelVal
164-
});
165-
}
139+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
140+
// @ts-ignore: React 19
141+
if (item?.props?.id) {
166142
return cloneElement<HTMLAttributes<HTMLElement>>(item, {
143+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
144+
// @ts-ignore: React 19
145+
id: `${item.props.id}-overflow`,
167146
[labelProp]: labelVal
168147
});
169148
}
170-
return null;
171-
})
172-
.filter(Boolean);
149+
// @ts-expect-error: if type is not defined, it's not a separator
150+
if (item.type?.displayName === 'ToolbarSeparator') {
151+
return cloneElement(item, {
152+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
153+
// @ts-ignore: React 19
154+
style: {
155+
height: '0.0625rem',
156+
margin: '0.375rem 0.1875rem',
157+
width: '100%'
158+
},
159+
'aria-label': labelVal
160+
});
161+
}
162+
return cloneElement<HTMLAttributes<HTMLElement>>(item, {
163+
[labelProp]: labelVal
164+
});
165+
});
173166

174167
return (
175168
<OverflowPopoverContextProvider value={{ inPopover: true }}>
@@ -200,15 +193,15 @@ export const OverflowPopover: FC<OverflowPopoverProps> = (props: OverflowPopover
200193
onOpen={handleAfterOpen}
201194
hideArrow
202195
accessibleRole={accessibleRole}
203-
accessibleName={i18nBundle.getText(WITH_X_ITEMS, filteredChildrenArray.length)}
196+
accessibleName={i18nBundle.getText(WITH_X_ITEMS, visibleChildren.length)}
204197
>
205198
<div
206199
className={classes.popoverContent}
207200
ref={overflowContentRef}
208201
role={a11yConfig?.overflowPopover?.contentRole}
209202
data-component-name="ToolbarOverflowPopoverContent"
210203
>
211-
{filteredChildrenArray}
204+
{visibleChildren}
212205
</div>
213206
</Popover>,
214207
portalContainer ?? document.body

packages/compat/src/components/Toolbar/index.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -400,11 +400,10 @@ const Toolbar = forwardRef<HTMLDivElement, ToolbarPropTypes>((props, ref) => {
400400
>
401401
<OverflowPopover
402402
overflowPopoverRef={overflowPopoverRef}
403-
lastVisibleIndex={lastVisibleIndex}
403+
lastVisibleIndex={Math.max(lastVisibleIndex, numberOfAlwaysVisibleItems - 1)}
404404
classes={classNames}
405405
portalContainer={portalContainer}
406406
overflowContentRef={overflowContentRef}
407-
numberOfAlwaysVisibleItems={numberOfAlwaysVisibleItems}
408407
overflowButton={overflowButton}
409408
setIsMounted={setIsPopoverMounted}
410409
a11yConfig={a11yConfig}

0 commit comments

Comments
 (0)