Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ export function createOverflowManager(): OverflowManager {
// Set as true when resize observer is observing
let observing = false;
// If true, next update will dispatch to onUpdateOverflow even if queue top states don't change
let forceDispatch = false;
// Initially true to force dispatch on first mount
let forceDispatch = true;
const options: Required<ObserveOptions> = {
padding: 10,
overflowAxis: 'horizontal',
Expand Down
32 changes: 32 additions & 0 deletions packages/react-components/react-overflow/src/Overflow.cy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
useIsOverflowGroupVisible,
useOverflowMenu,
useOverflowContext,
useIsOverflowItemVisible,
} from '@fluentui/react-overflow';
import { Portal } from '@fluentui/react-portal';

Expand Down Expand Up @@ -539,4 +540,35 @@ describe('Overflow', () => {
setContainerSize(500);
cy.contains('Update priority').click().get('#foo-visibility').should('have.text', 'visible');
});

it('Should have correct initial visibility state', () => {
const mapHelper = new Array(10).fill(0).map((_, i) => i);
const Assert = () => {
const isVisible = mapHelper.map(i => {
// eslint-disable-next-line react-hooks/rules-of-hooks
return useIsOverflowItemVisible(i.toString());
});

if (isVisible.every(x => x)) {
return <span data-passed="true" />;
}

return null;
};

mount(
<Container minimumVisible={5}>
{mapHelper.map(i => (
<Item key={i} id={i.toString()}>
{i}
</Item>
))}
<Menu />
<Assert />
</Container>,
);

setContainerSize(500);
cy.get('[data-passed="true"]').should('exist');
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ import { OverflowContext } from '../overflowContext';
import { updateVisibilityAttribute, useOverflowContainer } from '../useOverflowContainer';
import { useOverflowStyles } from './useOverflowStyles.styles';

interface OverflowState {
hasOverflow: boolean;
itemVisibility: Record<string, boolean>;
groupVisibility: Record<string, OverflowGroupState>;
}

/**
* Overflow Props
*/
Expand All @@ -24,21 +30,27 @@ export const Overflow = React.forwardRef((props: OverflowProps, ref) => {

const { children, minimumVisible, overflowAxis = 'horizontal', overflowDirection, padding } = props;

const [hasOverflow, setHasOverflow] = React.useState(false);
const [itemVisibility, setItemVisibility] = React.useState<Record<string, boolean>>({});
const [groupVisibility, setGroupVisibility] = React.useState<Record<string, OverflowGroupState>>({});
const [overflowState, setOverflowState] = React.useState<OverflowState>({
hasOverflow: false,
itemVisibility: {},
groupVisibility: {},
});

// useOverflowContainer wraps this method in a useEventCallback.
// TODO: Do we need a useEventCallback here too?
const update: OnUpdateOverflow = data => {
setHasOverflow(() => data.invisibleItems.length > 0);
setItemVisibility(() => {
const newState: Record<string, boolean> = {};
data.visibleItems.forEach(x => (newState[x.id] = true));
data.invisibleItems.forEach(x => (newState[x.id] = false));
return newState;
const { visibleItems, invisibleItems, groupVisibility } = data;

const itemVisibility: Record<string, boolean> = {};
visibleItems.forEach(x => (itemVisibility[x.id] = true));
invisibleItems.forEach(x => (itemVisibility[x.id] = false));

setOverflowState(() => {
return {
hasOverflow: data.invisibleItems.length > 0,
itemVisibility,
groupVisibility,
};
});
setGroupVisibility(data.groupVisibility);
};

const { containerRef, registerItem, updateOverflow, registerOverflowMenu } = useOverflowContainer(update, {
Expand All @@ -57,9 +69,9 @@ export const Overflow = React.forwardRef((props: OverflowProps, ref) => {
return (
<OverflowContext.Provider
value={{
itemVisibility,
groupVisibility,
hasOverflow,
itemVisibility: overflowState.itemVisibility,
groupVisibility: overflowState.groupVisibility,
hasOverflow: overflowState.hasOverflow,
registerItem,
updateOverflow,
registerOverflowMenu,
Expand Down