Skip to content

Commit 1773d9d

Browse files
authored
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 5a9d20c commit 1773d9d

File tree

2 files changed

+57
-2
lines changed

2 files changed

+57
-2
lines changed

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

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

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

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

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ export interface ToolbarPropTypes extends Omit<CommonProps, 'onClick' | 'childre
3232
* __Note:__ Although this prop accepts all `ReactNode` types, it is strongly recommended to not pass `string`, `number` or a React Portal to it.
3333
*
3434
* __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.
35+
*
36+
* __Note:__ If only `ToolbarSpacer`s or `ToolbarSeparator`s are added to the Toolbar, the components will not be rendered.
3537
*/
3638
children?: ReactNode | ReactNode[];
3739
/**
@@ -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)