Skip to content

Commit

Permalink
fix: Add flex gap to overflow list calculations
Browse files Browse the repository at this point in the history
Adds Flexbox `gap` to overflow list calculations so that a the overflow list doesn't render outside the container. This is more noticeable with higher gap values.

Fixes #3020
  • Loading branch information
NicholasBoll authored Nov 1, 2024
1 parent a8c9591 commit 2473b07
Showing 1 changed file with 34 additions and 6 deletions.
40 changes: 34 additions & 6 deletions modules/react/collection/lib/useOverflowListModel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ import {Item} from './useBaseListModel';

export function getHiddenIds(
containerWidth: number,
containerGap: number,
overflowTargetWidth: number,
itemWidthCache: Record<string, number>,
selectedIds: string[] | 'all',
items?: Item<any>[]
items: Item<any>[]
): string[] {
/** Allows us to prioritize showing the selected item */
let selectedKey: undefined | string;
Expand All @@ -18,17 +19,22 @@ export function getHiddenIds(
/** Tally ids that won't fit inside the container. These will be used by components to hide
* elements that won't fit in the container */
const hiddenIds: string[] = [];
/** Track if gap should be calculated since gap doesn't apply to the width of the first item, only
* consecutive items */
let shouldAddGap = false;

if (selectedIds !== 'all' && selectedIds.length) {
if (items?.length) {
if (items.length) {
// If selectedIds[0] is not in items, use the first id from items
selectedKey = items.find(item => item.id === selectedIds[0]) ? selectedIds[0] : items[0].id;
} else {
selectedKey = selectedIds[0];
}
}

if (
Object.keys(itemWidthCache).reduce((sum, key) => sum + itemWidthCache[key], 0) <= containerWidth
Object.keys(itemWidthCache).reduce(
(sum, key, index) => sum + itemWidthCache[key] + (index > 0 ? containerGap : 0),
0
) <= containerWidth
) {
// All items fit, return empty array
return [];
Expand All @@ -39,14 +45,16 @@ export function getHiddenIds(
} else {
// at least the selected item and overflow target fit. Update our itemWidth with the sum
itemWidth += itemWidthCache[selectedKey] + overflowTargetWidth;
shouldAddGap = true;
}
} else {
itemWidth += overflowTargetWidth;
}

for (const key in itemWidthCache) {
if (key !== selectedKey) {
itemWidth += itemWidthCache[key];
itemWidth += itemWidthCache[key] + (shouldAddGap ? containerGap : 0);
shouldAddGap = true;
if (itemWidth > containerWidth) {
hiddenIds.push(key);
}
Expand Down Expand Up @@ -75,6 +83,7 @@ export const useOverflowListModel = createModelHook({
const [hiddenIds, setHiddenIds] = React.useState(config.initialHiddenIds);
const [itemWidthCache, setItemWidthCache] = React.useState<Record<string, number>>({});
const [containerWidth, setContainerWidth] = React.useState(0);
const [containerGap, setContainerGap] = React.useState(0);
const containerWidthRef = React.useRef(0);
const itemWidthCacheRef = React.useRef(itemWidthCache);
const [overflowTargetWidth, setOverflowTargetWidth] = React.useState(0);
Expand All @@ -96,6 +105,7 @@ export const useOverflowListModel = createModelHook({
hiddenIds: internalHiddenIds,
itemWidthCache,
containerWidth,
containerGap,
overflowTargetWidth,
};

Expand All @@ -105,6 +115,7 @@ export const useOverflowListModel = createModelHook({
const {selectedIds} = model.selection.select(data.id, state);
const ids = getHiddenIds(
containerWidthRef.current,
containerGap,
overflowTargetWidthRef.current,
itemWidthCacheRef.current,
selectedIds,
Expand All @@ -120,6 +131,21 @@ export const useOverflowListModel = createModelHook({

const ids = getHiddenIds(
containerWidthRef.current,
containerGap,
overflowTargetWidthRef.current,
itemWidthCacheRef.current,
state.selectedIds,
config.items
);

setHiddenIds(ids);
},
setContainerGap(data: {size: number}) {
setContainerGap(data.size);

const ids = getHiddenIds(
containerWidthRef.current,
data.size,
overflowTargetWidthRef.current,
itemWidthCacheRef.current,
state.selectedIds,
Expand All @@ -142,6 +168,7 @@ export const useOverflowListModel = createModelHook({

const ids = getHiddenIds(
containerWidthRef.current,
containerGap,
overflowTargetWidthRef.current,
itemWidthCacheRef.current,
state.selectedIds,
Expand All @@ -158,6 +185,7 @@ export const useOverflowListModel = createModelHook({

const ids = getHiddenIds(
containerWidthRef.current,
containerGap,
overflowTargetWidthRef.current,
itemWidthCacheRef.current,
state.selectedIds !== 'all'
Expand Down

0 comments on commit 2473b07

Please sign in to comment.