Skip to content

Commit d6325fd

Browse files
committed
fix(Toolbar - compat): prevent empty overflow popover (#7185)
If only `ToolbarSeparator` or `ToolbarSpacer` components are passed to the `Toolbar`, the components won't be rendered to prevent an empty overflow popover to show up if the width of the Toolbar is very small.
1 parent 1b497d5 commit d6325fd

File tree

2 files changed

+57
-2
lines changed

2 files changed

+57
-2
lines changed

packages/main/src/components/Toolbar/Toolbar.cy.tsx

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -615,6 +615,45 @@ describe('Toolbar', () => {
615615
cy.get('[data-component-name="ToolbarOverflowPopoverContent"]').should('have.attr', 'role', 'menu');
616616
});
617617

618+
it('no overflow button for spacer- or separator-only children', () => {
619+
cy.mount(
620+
<Toolbar style={{ width: '0px' }}>
621+
<ToolbarSpacer />
622+
<Button>Button</Button>
623+
<ToolbarSeparator />
624+
</Toolbar>,
625+
{ strict: false }
626+
);
627+
cy.get('[data-component-name="ToolbarOverflowButtonContainer"]').should('exist');
628+
629+
cy.mount(
630+
<Toolbar style={{ width: '0px' }}>
631+
<ToolbarSpacer />
632+
<ToolbarSeparator />
633+
</Toolbar>,
634+
{ strict: false }
635+
);
636+
cy.get('[data-component-name="ToolbarOverflowButtonContainer"]').should('not.exist');
637+
cy.mount(
638+
<Toolbar style={{ width: '0px' }}>
639+
<ToolbarSpacer />
640+
<ToolbarSpacer />
641+
<ToolbarSpacer />
642+
</Toolbar>,
643+
{ strict: false }
644+
);
645+
cy.get('[data-component-name="ToolbarOverflowButtonContainer"]').should('not.exist');
646+
cy.mount(
647+
<Toolbar style={{ width: '0px' }}>
648+
<ToolbarSeparator />
649+
<ToolbarSeparator />
650+
<ToolbarSeparator />
651+
</Toolbar>,
652+
{ strict: false }
653+
);
654+
cy.get('[data-component-name="ToolbarOverflowButtonContainer"]').should('not.exist');
655+
});
656+
618657
mountWithCustomTagName(Toolbar);
619658
cypressPassThroughTestsFactory(Toolbar);
620659
});

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

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ export interface ToolbarPropTypes extends Omit<CommonProps, 'onClick' | 'childre
2929
* __Note:__ Although this prop accepts all `ReactNode` types, it is strongly recommended to not pass `string`, `number` or a React Portal to it.
3030
*
3131
* __Note:__ Only components displayed inside the Toolbar are supported as children, i.e. elements positioned outside the normal flow of the document (like dialogs or popovers), can cause undesired behavior.
32+
*
33+
* __Note:__ If only `ToolbarSpacer`s or `ToolbarSeparator`s are added to the Toolbar, the components will not be rendered.
3234
*/
3335
children?: ReactNode | ReactNode[];
3436
/**
@@ -188,14 +190,20 @@ const Toolbar = forwardRef<HTMLDivElement, ToolbarPropTypes>((props, ref) => {
188190
const childrenWithRef = useMemo(() => {
189191
controlMetaData.current = [];
190192

191-
return flatChildren.map((item, index) => {
193+
let hasOnlySpacersOrSeparators = true;
194+
const enrichedChildren = flatChildren.map((item, index) => {
192195
const itemRef: RefObject<HTMLDivElement> = createRef();
193196
// @ts-expect-error: if type is not defined, it's not a spacer
194197
const isSpacer = item?.type?.displayName === 'ToolbarSpacer';
198+
// @ts-expect-error: if type is not defined, it's not a separator
199+
const isSeparator = item?.type?.displayName === 'ToolbarSeparator';
195200
controlMetaData.current.push({
196201
ref: itemRef,
197202
isSpacer
198203
});
204+
if (!isSpacer && !isSeparator) {
205+
hasOnlySpacersOrSeparators = false;
206+
}
199207
if (isSpacer) {
200208
return item;
201209
}
@@ -210,7 +218,15 @@ const Toolbar = forwardRef<HTMLDivElement, ToolbarPropTypes>((props, ref) => {
210218
</div>
211219
);
212220
});
213-
}, [flatChildren, controlMetaData, classNames.childContainer]);
221+
222+
if (hasOnlySpacersOrSeparators) {
223+
return enrichedChildren.filter(
224+
// @ts-expect-error: if type is not defined, it's not a separator or spacer
225+
(item) => item?.type?.displayName !== 'ToolbarSpacer' && item?.type?.displayName === 'ToolbarSeparator'
226+
);
227+
}
228+
return enrichedChildren;
229+
}, [flatChildren, controlMetaData]);
214230

215231
const overflowNeeded =
216232
(lastVisibleIndex || lastVisibleIndex === 0) &&

0 commit comments

Comments
 (0)