From 2e6aa3e79dc1b4de771daaab18be7966671a56e2 Mon Sep 17 00:00:00 2001 From: Valentyna Date: Mon, 12 Jun 2023 16:13:10 +0200 Subject: [PATCH 01/20] Divider fix for overflow --- .../etc/priority-overflow.api.md | 9 + .../priority-overflow/src/index.ts | 1 + .../priority-overflow/src/overflowManager.ts | 195 ++++++++++++------ .../priority-overflow/src/types.ts | 19 ++ .../react-components/src/index.ts | 2 + .../react-overflow/etc/react-overflow.api.md | 16 +- .../react-overflow/src/Overflow.cy.tsx | 90 ++++++++ .../src/components/Overflow.tsx | 22 +- .../OverflowDivider/OverflowDivider.tsx | 17 ++ .../OverflowDivider/OverflowDivider.types.ts | 15 ++ .../react-overflow/src/constants.ts | 1 + .../react-overflow/src/index.ts | 4 +- .../react-overflow/src/overflowContext.ts | 4 +- .../react-overflow/src/types.ts | 2 +- .../src/useOverflowContainer.ts | 18 +- .../react-overflow/src/useOverflowDivider.ts | 25 +++ .../Overflow/CustomDividers.stories.tsx | 169 +++++++++++++++ .../stories/Overflow/index.stories.tsx | 1 + 18 files changed, 526 insertions(+), 84 deletions(-) create mode 100644 packages/react-components/react-overflow/src/components/OverflowDivider/OverflowDivider.tsx create mode 100644 packages/react-components/react-overflow/src/components/OverflowDivider/OverflowDivider.types.ts create mode 100644 packages/react-components/react-overflow/src/useOverflowDivider.ts create mode 100644 packages/react-components/react-overflow/stories/Overflow/CustomDividers.stories.tsx diff --git a/packages/react-components/priority-overflow/etc/priority-overflow.api.md b/packages/react-components/priority-overflow/etc/priority-overflow.api.md index a8a2ef84d50ce2..4ecb000b3bb31c 100644 --- a/packages/react-components/priority-overflow/etc/priority-overflow.api.md +++ b/packages/react-components/priority-overflow/etc/priority-overflow.api.md @@ -37,6 +37,13 @@ export type OverflowAxis = 'horizontal' | 'vertical'; // @public (undocumented) export type OverflowDirection = 'start' | 'end'; +// @public (undocumented) +export interface OverflowDivider { + element: HTMLElement; + // (undocumented) + groupId?: string; +} + // @public export interface OverflowEventPayload { // (undocumented) @@ -61,11 +68,13 @@ export interface OverflowItemEntry { // @internal (undocumented) export interface OverflowManager { + addDivider: (divider: OverflowDivider) => void; addItem: (items: OverflowItemEntry) => void; addOverflowMenu: (element: HTMLElement) => void; disconnect: () => void; forceUpdate: () => void; observe: (container: HTMLElement, options: ObserveOptions) => void; + removeDivider: (groupId: string) => void; removeItem: (itemId: string) => void; removeOverflowMenu: () => void; update: () => void; diff --git a/packages/react-components/priority-overflow/src/index.ts b/packages/react-components/priority-overflow/src/index.ts index 3f7027bfbaeb88..fedb15123401ae 100644 --- a/packages/react-components/priority-overflow/src/index.ts +++ b/packages/react-components/priority-overflow/src/index.ts @@ -9,5 +9,6 @@ export type { OverflowEventPayload, OverflowGroupState, OverflowItemEntry, + OverflowDivider, OverflowManager, } from './types'; diff --git a/packages/react-components/priority-overflow/src/overflowManager.ts b/packages/react-components/priority-overflow/src/overflowManager.ts index 3dece40e104728..ec746e27b74151 100644 --- a/packages/react-components/priority-overflow/src/overflowManager.ts +++ b/packages/react-components/priority-overflow/src/overflowManager.ts @@ -1,6 +1,7 @@ +import { DATA_OVERFLOWING } from '../../react-overflow/src/constants'; import { debounce } from './debounce'; -import { createPriorityQueue } from './priorityQueue'; -import type { OverflowGroupState, OverflowItemEntry, OverflowManager, ObserveOptions } from './types'; +import { createPriorityQueue, PriorityQueue } from './priorityQueue'; +import type { OverflowGroupState, OverflowItemEntry, OverflowManager, ObserveOptions, OverflowDivider } from './types'; /** * @internal @@ -24,7 +25,9 @@ export function createOverflowManager(): OverflowManager { }; const overflowItems: Record = {}; - const overflowGroups: Record; invisibleItemIds: Set }> = {}; + const overflowDividers: Record = {}; + const groups: Record; invisibleItemIds: Set }> = {}; + const groupVisibility: Record = {}; const resizeObserver = new ResizeObserver(entries => { if (!entries[0] || !container) { return; @@ -33,6 +36,60 @@ export function createOverflowManager(): OverflowManager { update(); }); + function updateGroupVisibility(groupId: string) { + const group = groups[groupId]; + if (group.invisibleItemIds.size && group.visibleItemIds.size) { + groupVisibility[groupId] = 'overflow'; + } else if (group.visibleItemIds.size === 0) { + groupVisibility[groupId] = 'hidden'; + } else { + groupVisibility[groupId] = 'visible'; + } + } + + const getNextItem = (queueToDequeue: PriorityQueue, queueToEnqueue: PriorityQueue) => { + const nextItem = queueToDequeue.dequeue(); + queueToEnqueue.enqueue(nextItem); + return overflowItems[nextItem]; + }; + + const groupManager = { + isGroupVisible(groupId: string) { + return groupVisibility[groupId] === 'visible' || groupVisibility[groupId] === 'overflow'; + }, + isSingleVisible(itemId: string, groupId: string) { + return ( + this.isGroupVisible(groupId) && + groups[groupId].visibleItemIds.has(itemId) && + groups[groupId].visibleItemIds.size === 1 + ); + }, + addItem(itemId: string, groupId: string) { + groups[groupId] ??= { + visibleItemIds: new Set(), + invisibleItemIds: new Set(), + }; + + groups[groupId].visibleItemIds.add(itemId); + updateGroupVisibility(groupId); + }, + removeItem(itemId: string, groupId: string) { + groups[groupId].invisibleItemIds.delete(itemId); + groups[groupId].visibleItemIds.delete(itemId); + updateGroupVisibility(groupId); + }, + showItem(itemId: string, groupId: string) { + groups[groupId].invisibleItemIds.delete(itemId); + groups[groupId].visibleItemIds.add(itemId); + updateGroupVisibility(groupId); + }, + hideItem(itemId: string, groupId: string) { + groups[groupId].invisibleItemIds.add(itemId); + groups[groupId].visibleItemIds.delete(itemId); + updateGroupVisibility(groupId); + }, + }; + const invisibleItemQueue = createPriorityQueue((a, b) => { const itemA = overflowItems[a]; const itemB = overflowItems[b]; @@ -72,30 +129,41 @@ export function createOverflowManager(): OverflowManager { return options.overflowAxis === 'horizontal' ? el.offsetWidth : el.offsetHeight; }; - const makeItemVisible = () => { - const nextVisible = invisibleItemQueue.dequeue(); - visibleItemQueue.enqueue(nextVisible); + function computeSizeChange(entry: OverflowItemEntry) { + const dividerWidth = + entry.groupId && groupManager.isSingleVisible(entry.id, entry.groupId) && overflowDividers[entry.groupId] + ? getOffsetSize(overflowDividers[entry.groupId].element) + : 0; + + return getOffsetSize(entry.element) + dividerWidth; + } - const item = overflowItems[nextVisible]; + const showItem = () => { + const item = getNextItem(invisibleItemQueue, visibleItemQueue); options.onUpdateItemVisibility({ item, visible: true }); + if (item.groupId) { - overflowGroups[item.groupId].invisibleItemIds.delete(item.id); - overflowGroups[item.groupId].visibleItemIds.add(item.id); + groupManager.showItem(item.id, item.groupId); + + if (groupManager.isSingleVisible(item.id, item.groupId)) { + overflowDividers[item.groupId]?.element.removeAttribute(DATA_OVERFLOWING); + } } - return getOffsetSize(item.element); + return computeSizeChange(item); }; - const makeItemInvisible = () => { - const nextInvisible = visibleItemQueue.dequeue(); - invisibleItemQueue.enqueue(nextInvisible); - - const item = overflowItems[nextInvisible]; - const width = getOffsetSize(item.element); + const hideItem = () => { + const item = getNextItem(visibleItemQueue, invisibleItemQueue); + const width = computeSizeChange(item); options.onUpdateItemVisibility({ item, visible: false }); + if (item.groupId) { - overflowGroups[item.groupId].visibleItemIds.delete(item.id); - overflowGroups[item.groupId].invisibleItemIds.add(item.id); + if (groupManager.isSingleVisible(item.id, item.groupId)) { + overflowDividers[item.groupId]?.element.setAttribute(DATA_OVERFLOWING, ''); + } + + groupManager.hideItem(item.id, item.groupId); } return width; @@ -108,17 +176,6 @@ export function createOverflowManager(): OverflowManager { const visibleItems = visibleItemIds.map(itemId => overflowItems[itemId]); const invisibleItems = invisibleItemIds.map(itemId => overflowItems[itemId]); - const groupVisibility: Record = {}; - Object.entries(overflowGroups).forEach(([groupId, groupState]) => { - if (groupState.invisibleItemIds.size && groupState.visibleItemIds.size) { - groupVisibility[groupId] = 'overflow'; - } else if (groupState.visibleItemIds.size === 0) { - groupVisibility[groupId] = 'hidden'; - } else { - groupVisibility[groupId] = 'visible'; - } - }); - options.onUpdateOverflow({ visibleItems, invisibleItems, groupVisibility }); }; @@ -126,48 +183,38 @@ export function createOverflowManager(): OverflowManager { if (!container) { return false; } + const totalDividersWidth = Object.values(overflowDividers) + .map(dvdr => (dvdr.groupId ? getOffsetSize(dvdr.element) : 0)) + .reduce((prev, current) => prev + current, 0); - const availableSize = getOffsetSize(container) - options.padding; - const overflowMenuOffset = overflowMenu ? getOffsetSize(overflowMenu) : 0; + const availableSize = + getOffsetSize(container) - + options.padding - + totalDividersWidth - + (overflowMenu ? getOffsetSize(overflowMenu) : 0); // Snapshot of the visible/invisible state to compare for updates const visibleTop = visibleItemQueue.peek(); const invisibleTop = invisibleItemQueue.peek(); - const visibleItemIds = visibleItemQueue.all(); - let currentWidth = visibleItemIds.reduce((sum, visibleItemId) => { - const child = overflowItems[visibleItemId].element; - return sum + getOffsetSize(child); - }, 0); + let currentWidth = visibleItemQueue + .all() + .map(id => overflowItems[id].element) + .map(getOffsetSize) + .reduce((prev, current) => prev + current, 0); // Add items until available width is filled - can result in overflow while (currentWidth < availableSize && invisibleItemQueue.size() > 0) { - currentWidth += makeItemVisible(); + currentWidth += showItem(); } // Remove items until there's no more overflow - while (currentWidth > availableSize && visibleItemQueue.size() > 0) { - if (visibleItemQueue.size() <= options.minimumVisible) { - break; - } - currentWidth -= makeItemInvisible(); - } - - // make sure the overflow menu can fit - if ( - visibleItemQueue.size() > options.minimumVisible && - invisibleItemQueue.size() > 0 && - currentWidth + overflowMenuOffset > availableSize - ) { - makeItemInvisible(); + while (currentWidth > availableSize && visibleItemQueue.size() > options.minimumVisible) { + currentWidth -= hideItem(); } // only update when the state of visible/invisible items has changed - if (visibleItemQueue.peek() !== visibleTop || invisibleItemQueue.peek() !== invisibleTop) { - return true; - } - - return false; + return visibleItemQueue.peek() !== visibleTop || invisibleItemQueue.peek() !== invisibleTop; }; const forceUpdate: OverflowManager['forceUpdate'] = () => { @@ -210,14 +257,8 @@ export function createOverflowManager(): OverflowManager { } if (item.groupId) { - if (!overflowGroups[item.groupId]) { - overflowGroups[item.groupId] = { - visibleItemIds: new Set(), - invisibleItemIds: new Set(), - }; - } - - overflowGroups[item.groupId].visibleItemIds.add(item.id); + groupManager.addItem(item.id, item.groupId); + item.element.setAttribute('data-overflow-group', item.groupId); } update(); @@ -227,10 +268,30 @@ export function createOverflowManager(): OverflowManager { overflowMenu = el; }; + const addDivider: OverflowManager['addDivider'] = divider => { + if (!divider.groupId || overflowDividers[divider.groupId]) { + return; + } + + divider.element.setAttribute('data-overflow-group', divider.groupId); + overflowDividers[divider.groupId] = divider; + }; + const removeOverflowMenu: OverflowManager['removeOverflowMenu'] = () => { overflowMenu = undefined; }; + const removeDivider: OverflowManager['removeDivider'] = groupId => { + if (!overflowDividers[groupId]) { + return; + } + const divider = overflowDividers[groupId]; + if (divider.groupId) { + delete overflowDividers[groupId]; + divider.element.removeAttribute('data-overflow-group'); + } + }; + const removeItem: OverflowManager['removeItem'] = itemId => { if (!overflowItems[itemId]) { return; @@ -241,8 +302,8 @@ export function createOverflowManager(): OverflowManager { invisibleItemQueue.remove(itemId); if (item.groupId) { - overflowGroups[item.groupId].visibleItemIds.delete(item.id); - overflowGroups[item.groupId].invisibleItemIds.delete(item.id); + groupManager.removeItem(item.id, item.groupId); + item.element.removeAttribute('data-overflow-group'); } delete overflowItems[itemId]; @@ -258,5 +319,7 @@ export function createOverflowManager(): OverflowManager { update, addOverflowMenu, removeOverflowMenu, + addDivider, + removeDivider, }; } diff --git a/packages/react-components/priority-overflow/src/types.ts b/packages/react-components/priority-overflow/src/types.ts index 75cb10d193a937..a94aa4fda0a2cb 100644 --- a/packages/react-components/priority-overflow/src/types.ts +++ b/packages/react-components/priority-overflow/src/types.ts @@ -19,6 +19,15 @@ export interface OverflowItemEntry { groupId?: string; } +export interface OverflowDivider { + /** + * HTML element that will be disappear when overflowed + */ + element: HTMLElement; + + groupId?: string; +} + /** * signature similar to standard event listeners, but typed to handle the custom event */ @@ -111,6 +120,16 @@ export interface OverflowManager { */ addOverflowMenu: (element: HTMLElement) => void; + /** + * Add overflow divider + */ + addDivider: (divider: OverflowDivider) => void; + + /** + * Remove overflow divider + */ + removeDivider: (groupId: string) => void; + /** * Unsets the overflow menu element */ diff --git a/packages/react-components/react-components/src/index.ts b/packages/react-components/react-components/src/index.ts index e1a462d7e1d6f2..53e0e52a7e7368 100644 --- a/packages/react-components/react-components/src/index.ts +++ b/packages/react-components/react-components/src/index.ts @@ -832,6 +832,7 @@ export type { ProgressBarProps, ProgressBarState, ProgressBarSlots } from '@flue export { Overflow, OverflowItem, + OverflowDivider, useIsOverflowGroupVisible, useIsOverflowItemVisible, useOverflowCount, @@ -839,6 +840,7 @@ export { DATA_OVERFLOWING, DATA_OVERFLOW_MENU, DATA_OVERFLOW_ITEM, + DATA_OVERFLOW_DIVIDER, } from '@fluentui/react-overflow'; export type { OverflowProps, OverflowItemProps } from '@fluentui/react-overflow'; diff --git a/packages/react-components/react-overflow/etc/react-overflow.api.md b/packages/react-components/react-overflow/etc/react-overflow.api.md index 23ccaca79cc5a6..61d1f149bf69f9 100644 --- a/packages/react-components/react-overflow/etc/react-overflow.api.md +++ b/packages/react-components/react-overflow/etc/react-overflow.api.md @@ -4,13 +4,11 @@ ```ts -import { ContextSelector } from '@fluentui/react-context-selector'; -import type { ObserveOptions } from '@fluentui/priority-overflow'; -import type { OnUpdateOverflow } from '@fluentui/priority-overflow'; -import { OverflowGroupState } from '@fluentui/priority-overflow'; -import type { OverflowItemEntry } from '@fluentui/priority-overflow'; import * as React_2 from 'react'; +// @public (undocumented) +export const DATA_OVERFLOW_DIVIDER = "data-overflow-divider"; + // @public (undocumented) export const DATA_OVERFLOW_ITEM = "data-overflow-item"; @@ -25,6 +23,9 @@ export const Overflow: React_2.ForwardRefExoticComponent>; +// @public +export const OverflowDivider: React_2.ForwardRefExoticComponent>; + // @public export const OverflowItem: React_2.ForwardRefExoticComponent>; @@ -51,7 +52,7 @@ export function useIsOverflowItemVisible(id: string): boolean; export const useOverflowContainer: (update: OnUpdateOverflow, options: Omit) => UseOverflowContainerReturn; // @internal (undocumented) -export interface UseOverflowContainerReturn extends Pick { +export interface UseOverflowContainerReturn extends Pick { containerRef: React_2.RefObject; } @@ -61,6 +62,9 @@ export const useOverflowContext: (selector: ContextSelector number; +// @internal +export function useOverflowDivider(groupId?: string): React_2.RefObject; + // @internal export function useOverflowItem(id: string, priority?: number, groupId?: string): React_2.RefObject; diff --git a/packages/react-components/react-overflow/src/Overflow.cy.tsx b/packages/react-components/react-overflow/src/Overflow.cy.tsx index 66ee268948f971..fae4d28d9abcdf 100644 --- a/packages/react-components/react-overflow/src/Overflow.cy.tsx +++ b/packages/react-components/react-overflow/src/Overflow.cy.tsx @@ -3,6 +3,7 @@ import { mount } from '@cypress/react'; import { Overflow, OverflowItem, + OverflowDivider, OverflowItemProps, OverflowProps, useIsOverflowGroupVisible, @@ -140,6 +141,36 @@ export const Divider: React.FC<{ ); }; +export const CustomDivider: React.FC<{ + groupId: string; + children?: React.ReactNode; +}> = ({ groupId, children }) => { + const isGroupVisible = useIsOverflowGroupVisible(groupId); + + if (isGroupVisible === 'hidden') { + return null; + } + + const selector = { + [selectors.divider]: groupId, + }; + + const style = { + display: 'inline-block', + width: '30px', + backgroundColor: 'red', + height: '20px', + }; + + return ( + +
+ {children} +
+
+ ); +}; + describe('Overflow', () => { before(() => { cy.viewport(700, 700); @@ -456,6 +487,65 @@ describe('Overflow', () => { cy.get(`[${selectors.divider}]`).should('have.length', 1); }); + it('should collapse correctly with custom divider', () => { + mount( + + + 1 + + + + + + 2 + + + + + + 3 + + + 4 + + + + + + 5 + + + 6 + + + 7 + + + + + + 8 + + + , + ); + + cy.get(`[${selectors.item}="8"]`).should('not.be.visible'); + setContainerSize(350); + cy.get(`[${selectors.divider}="4"]`).should('not.exist'); + cy.get(`[${selectors.divider}]`).should('have.length', 3); + cy.get(`[${selectors.item}="5"]`).should('not.be.visible'); + setContainerSize(250); + cy.get(`[${selectors.divider}="3"]`).should('not.exist'); + cy.get(`[${selectors.divider}]`).should('have.length', 2); + cy.get(`[${selectors.item}="3"]`).should('not.be.visible'); + setContainerSize(200); + cy.get(`[${selectors.divider}="1"]`).should('exist'); + cy.get(`[${selectors.divider}]`).should('have.length', 1); + cy.get(`[${selectors.item}="1"]`).should('be.visible'); + cy.get(`[${selectors.item}="2"]`).should('not.be.visible'); + }); + it('should remove overflow menu if the last overflowed item can take its place', () => { const mapHelper = new Array(10).fill(0).map((_, i) => i); mount( diff --git a/packages/react-components/react-overflow/src/components/Overflow.tsx b/packages/react-components/react-overflow/src/components/Overflow.tsx index 1a599fd3c65f36..41382c34a253cd 100644 --- a/packages/react-components/react-overflow/src/components/Overflow.tsx +++ b/packages/react-components/react-overflow/src/components/Overflow.tsx @@ -41,7 +41,9 @@ export const Overflow = React.forwardRef((props: OverflowProps, ref) => { const { visibleItems, invisibleItems, groupVisibility } = data; const itemVisibility: Record = {}; - visibleItems.forEach(x => (itemVisibility[x.id] = true)); + visibleItems.forEach(x => { + itemVisibility[x.id] = true; + }); invisibleItems.forEach(x => (itemVisibility[x.id] = false)); setOverflowState(() => { @@ -53,13 +55,16 @@ export const Overflow = React.forwardRef((props: OverflowProps, ref) => { }); }; - const { containerRef, registerItem, updateOverflow, registerOverflowMenu } = useOverflowContainer(update, { - overflowDirection, - overflowAxis, - padding, - minimumVisible, - onUpdateItemVisibility: updateVisibilityAttribute, - }); + const { containerRef, registerItem, updateOverflow, registerOverflowMenu, registerDivider } = useOverflowContainer( + update, + { + overflowDirection, + overflowAxis, + padding, + minimumVisible, + onUpdateItemVisibility: updateVisibilityAttribute, + }, + ); const clonedChild = applyTriggerPropsToChildren(children, { ref: useMergedRefs(containerRef, ref), @@ -75,6 +80,7 @@ export const Overflow = React.forwardRef((props: OverflowProps, ref) => { registerItem, updateOverflow, registerOverflowMenu, + registerDivider, }} > {clonedChild} diff --git a/packages/react-components/react-overflow/src/components/OverflowDivider/OverflowDivider.tsx b/packages/react-components/react-overflow/src/components/OverflowDivider/OverflowDivider.tsx new file mode 100644 index 00000000000000..2b8c179442147c --- /dev/null +++ b/packages/react-components/react-overflow/src/components/OverflowDivider/OverflowDivider.tsx @@ -0,0 +1,17 @@ +import * as React from 'react'; +import { applyTriggerPropsToChildren, useMergedRefs } from '@fluentui/react-utilities'; +import { useOverflowDivider } from '../../useOverflowDivider'; +import { OverflowDividerProps } from './OverflowDivider.types'; + +/** + * Attaches overflow item behavior to its child registered with the OverflowContext. + * It does not render an element of its own. + */ +export const OverflowDivider = React.forwardRef((props: OverflowDividerProps, ref) => { + const { groupId, children } = props; + + const containerRef = useOverflowDivider(groupId); + return applyTriggerPropsToChildren(children, { + ref: useMergedRefs(containerRef, ref), + }); +}); diff --git a/packages/react-components/react-overflow/src/components/OverflowDivider/OverflowDivider.types.ts b/packages/react-components/react-overflow/src/components/OverflowDivider/OverflowDivider.types.ts new file mode 100644 index 00000000000000..fab621a8ce9ae8 --- /dev/null +++ b/packages/react-components/react-overflow/src/components/OverflowDivider/OverflowDivider.types.ts @@ -0,0 +1,15 @@ +import * as React from 'react'; + +/** + * OverflowDividerProps + */ +export type OverflowDividerProps = { + /** + * Assigns the item to a group, group visibility can be watched. + */ + groupId?: string; + /** + * The single child that has overflow item behavior attached. + */ + children: React.ReactElement; +}; diff --git a/packages/react-components/react-overflow/src/constants.ts b/packages/react-components/react-overflow/src/constants.ts index a4cf687ac9dc35..f4d77032cd191d 100644 --- a/packages/react-components/react-overflow/src/constants.ts +++ b/packages/react-components/react-overflow/src/constants.ts @@ -1,3 +1,4 @@ export const DATA_OVERFLOWING = 'data-overflowing'; export const DATA_OVERFLOW_ITEM = 'data-overflow-item'; export const DATA_OVERFLOW_MENU = 'data-overflow-menu'; +export const DATA_OVERFLOW_DIVIDER = 'data-overflow-divider'; diff --git a/packages/react-components/react-overflow/src/index.ts b/packages/react-components/react-overflow/src/index.ts index 5466d7c6a93a36..dd4f52fbb2134f 100644 --- a/packages/react-components/react-overflow/src/index.ts +++ b/packages/react-components/react-overflow/src/index.ts @@ -1,6 +1,6 @@ export { Overflow } from './components/Overflow'; export type { OverflowProps } from './components/Overflow'; -export { DATA_OVERFLOWING, DATA_OVERFLOW_ITEM, DATA_OVERFLOW_MENU } from './constants'; +export { DATA_OVERFLOWING, DATA_OVERFLOW_ITEM, DATA_OVERFLOW_MENU, DATA_OVERFLOW_DIVIDER } from './constants'; export type { UseOverflowContainerReturn } from './types'; export { useIsOverflowGroupVisible } from './useIsOverflowGroupVisible'; export { useIsOverflowItemVisible } from './useIsOverflowItemVisible'; @@ -8,8 +8,10 @@ export { useOverflowContainer } from './useOverflowContainer'; export { useOverflowCount } from './useOverflowCount'; export { useOverflowItem } from './useOverflowItem'; export { useOverflowMenu } from './useOverflowMenu'; +export { useOverflowDivider } from './useOverflowDivider'; export { useOverflowContext } from './overflowContext'; export type { OverflowItemProps } from './components/OverflowItem/OverflowItem.types'; export { OverflowItem } from './components/OverflowItem/OverflowItem'; +export { OverflowDivider } from './components/OverflowDivider/OverflowDivider'; diff --git a/packages/react-components/react-overflow/src/overflowContext.ts b/packages/react-components/react-overflow/src/overflowContext.ts index 87a53f791f9c27..a43dd30caeb407 100644 --- a/packages/react-components/react-overflow/src/overflowContext.ts +++ b/packages/react-components/react-overflow/src/overflowContext.ts @@ -1,4 +1,4 @@ -import type { OverflowGroupState, OverflowItemEntry } from '@fluentui/priority-overflow'; +import type { OverflowGroupState, OverflowItemEntry, OverflowDivider } from '@fluentui/priority-overflow'; import { ContextSelector, createContext, useContextSelector, Context } from '@fluentui/react-context-selector'; /** @@ -10,6 +10,7 @@ export interface OverflowContextValue { hasOverflow: boolean; registerItem: (item: OverflowItemEntry) => () => void; registerOverflowMenu: (el: HTMLElement) => () => void; + registerDivider: (divider: OverflowDivider) => () => void; updateOverflow: (padding?: number) => void; } @@ -24,6 +25,7 @@ const overflowContextDefaultValue: OverflowContextValue = { registerItem: () => () => null, updateOverflow: () => null, registerOverflowMenu: () => () => null, + registerDivider: () => () => null, }; /** diff --git a/packages/react-components/react-overflow/src/types.ts b/packages/react-components/react-overflow/src/types.ts index 45a60daa71415d..4bf971e67fb3c0 100644 --- a/packages/react-components/react-overflow/src/types.ts +++ b/packages/react-components/react-overflow/src/types.ts @@ -5,7 +5,7 @@ import { OverflowContextValue } from './overflowContext'; * @internal */ export interface UseOverflowContainerReturn - extends Pick { + extends Pick { /** * Ref to apply to the container that will overflow */ diff --git a/packages/react-components/react-overflow/src/useOverflowContainer.ts b/packages/react-components/react-overflow/src/useOverflowContainer.ts index 9eb55e4b5ac368..bc4480f143ee39 100644 --- a/packages/react-components/react-overflow/src/useOverflowContainer.ts +++ b/packages/react-components/react-overflow/src/useOverflowContainer.ts @@ -8,12 +8,13 @@ import type { OnUpdateItemVisibility, OnUpdateOverflow, OverflowItemEntry, + OverflowDivider, OverflowManager, ObserveOptions, } from '@fluentui/priority-overflow'; import { canUseDOM, useEventCallback, useIsomorphicLayoutEffect } from '@fluentui/react-utilities'; import { UseOverflowContainerReturn } from './types'; -import { DATA_OVERFLOWING, DATA_OVERFLOW_ITEM, DATA_OVERFLOW_MENU } from './constants'; +import { DATA_OVERFLOWING, DATA_OVERFLOW_DIVIDER, DATA_OVERFLOW_ITEM, DATA_OVERFLOW_MENU } from './constants'; /** * @internal @@ -78,6 +79,20 @@ export const useOverflowContainer = ( [overflowManager], ); + const registerDivider = React.useCallback( + (divider: OverflowDivider) => { + const el = divider.element; + overflowManager?.addDivider(divider); + el && el.setAttribute(DATA_OVERFLOW_DIVIDER, ''); + + return () => { + divider.groupId && overflowManager?.removeDivider(divider.groupId); + el.removeAttribute(DATA_OVERFLOW_DIVIDER); + }; + }, + [overflowManager], + ); + const updateOverflow = React.useCallback(() => { overflowManager?.update(); }, [overflowManager]); @@ -100,6 +115,7 @@ export const useOverflowContainer = ( registerItem, updateOverflow, registerOverflowMenu, + registerDivider, }; }; diff --git a/packages/react-components/react-overflow/src/useOverflowDivider.ts b/packages/react-components/react-overflow/src/useOverflowDivider.ts new file mode 100644 index 00000000000000..dcb548b29aa4d4 --- /dev/null +++ b/packages/react-components/react-overflow/src/useOverflowDivider.ts @@ -0,0 +1,25 @@ +import * as React from 'react'; +import { useIsomorphicLayoutEffect } from '@fluentui/react-utilities'; +import { useOverflowContext } from './overflowContext'; + +/** + * @internal + * Registers an overflow item + * @param groupId - assigns the item to a group, group visibility can be watched + * @returns ref to assign to an intrinsic HTML element + */ +export function useOverflowDivider(groupId?: string) { + const ref = React.useRef(null); + const registerDivider = useOverflowContext(v => v.registerDivider); + + useIsomorphicLayoutEffect(() => { + if (ref.current) { + return registerDivider({ + element: ref.current, + groupId, + }); + } + }, [registerDivider, groupId]); + + return ref; +} diff --git a/packages/react-components/react-overflow/stories/Overflow/CustomDividers.stories.tsx b/packages/react-components/react-overflow/stories/Overflow/CustomDividers.stories.tsx new file mode 100644 index 00000000000000..98f3a0c8528acc --- /dev/null +++ b/packages/react-components/react-overflow/stories/Overflow/CustomDividers.stories.tsx @@ -0,0 +1,169 @@ +import * as React from 'react'; +import { + makeStyles, + shorthands, + Button, + Menu, + MenuTrigger, + MenuPopover, + MenuList, + MenuItem, + MenuDivider, + MenuButton, + tokens, + mergeClasses, + Overflow, + OverflowItem, + useIsOverflowGroupVisible, + useIsOverflowItemVisible, + useOverflowMenu, + OverflowDivider, +} from '@fluentui/react-components'; +import { ChevronRight20Regular } from '@fluentui/react-icons'; + +const useStyles = makeStyles({ + container: { + display: 'flex', + flexWrap: 'nowrap', + minWidth: 0, + ...shorthands.overflow('hidden'), + }, + + resizableArea: { + minWidth: '200px', + maxWidth: '800px', + ...shorthands.border('2px', 'solid', tokens.colorBrandBackground), + ...shorthands.padding('20px', '10px', '10px', '10px'), + position: 'relative', + resize: 'horizontal', + '::after': { + content: `'Resizable Area'`, + position: 'absolute', + ...shorthands.padding('1px', '4px', '1px'), + top: '-2px', + left: '-2px', + fontFamily: 'monospace', + fontSize: '15px', + fontWeight: 900, + lineHeight: 1, + letterSpacing: '1px', + color: tokens.colorNeutralForegroundOnBrand, + backgroundColor: tokens.colorBrandBackground, + }, + }, +}); + +export const CustomDividers = () => { + const styles = useStyles(); + + return ( + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ ); +}; + +const OverflowGroupDivider: React.FC<{ + groupId: string; +}> = props => { + return ( + +
+ +
+
+ ); +}; + +const OverflowMenu: React.FC<{ itemIds: string[] }> = ({ itemIds }) => { + const { ref, overflowCount, isOverflowing } = useOverflowMenu(); + + if (!isOverflowing) { + return null; + } + + return ( + + + +{overflowCount} items + + + + + {itemIds.map(i => { + // This is purely a simplified convention for documentation examples + // Could be done in other ways too + if (typeof i === 'string' && i.startsWith('divider')) { + const groupId = i.split('-')[1]; + return ; + } + return ; + })} + + + + ); +}; + +const OverflowMenuItem: React.FC<{ id: string }> = props => { + const { id } = props; + const isVisible = useIsOverflowItemVisible(id); + + if (isVisible) { + return null; + } + + return Item {id}; +}; + +const OverflowMenuDivider: React.FC<{ + id: string; +}> = props => { + const isGroupVisible = useIsOverflowGroupVisible(props.id); + + if (isGroupVisible === 'visible') { + return null; + } + + return ; +}; + +CustomDividers.parameters = { + docs: { + description: { + story: ['OverflowDivider should be used for larger dividers to include its width to the calculation.'].join('\n'), + }, + }, +}; diff --git a/packages/react-components/react-overflow/stories/Overflow/index.stories.tsx b/packages/react-components/react-overflow/stories/Overflow/index.stories.tsx index ea07735698c6b3..65009fce75e4e8 100644 --- a/packages/react-components/react-overflow/stories/Overflow/index.stories.tsx +++ b/packages/react-components/react-overflow/stories/Overflow/index.stories.tsx @@ -10,6 +10,7 @@ export { OverflowByPriority } from './OverflowByPriority.stories'; export { Wrapped } from './Wrapped.stories'; export { Pinned } from './Pinned.stories'; export { Dividers } from './Dividers.stories'; +export { CustomDividers } from './CustomDividers.stories'; export { PriorityWithDividers } from './PriorityWithDividers.stories'; export default { From e182d0f6a9e63604a3ae2f262e9b310329c74a5e Mon Sep 17 00:00:00 2001 From: Valentyna Date: Tue, 13 Jun 2023 16:33:14 +0200 Subject: [PATCH 02/20] Change files --- ...rity-overflow-8e128a48-5402-4886-b088-900334ce1883.json | 7 +++++++ ...ct-components-7b21b68d-a82b-4ee6-802c-cdbba6a8b25d.json | 7 +++++++ ...eact-overflow-96369afb-91ef-4417-88b6-bd79e7796730.json | 7 +++++++ 3 files changed, 21 insertions(+) create mode 100644 change/@fluentui-priority-overflow-8e128a48-5402-4886-b088-900334ce1883.json create mode 100644 change/@fluentui-react-components-7b21b68d-a82b-4ee6-802c-cdbba6a8b25d.json create mode 100644 change/@fluentui-react-overflow-96369afb-91ef-4417-88b6-bd79e7796730.json diff --git a/change/@fluentui-priority-overflow-8e128a48-5402-4886-b088-900334ce1883.json b/change/@fluentui-priority-overflow-8e128a48-5402-4886-b088-900334ce1883.json new file mode 100644 index 00000000000000..338e3ceaaf58fc --- /dev/null +++ b/change/@fluentui-priority-overflow-8e128a48-5402-4886-b088-900334ce1883.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "Added support for custom divider", + "packageName": "@fluentui/priority-overflow", + "email": "vkozlova@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/change/@fluentui-react-components-7b21b68d-a82b-4ee6-802c-cdbba6a8b25d.json b/change/@fluentui-react-components-7b21b68d-a82b-4ee6-802c-cdbba6a8b25d.json new file mode 100644 index 00000000000000..1cf6a19f9c3603 --- /dev/null +++ b/change/@fluentui-react-components-7b21b68d-a82b-4ee6-802c-cdbba6a8b25d.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "Added Overflow divider", + "packageName": "@fluentui/react-components", + "email": "vkozlova@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/change/@fluentui-react-overflow-96369afb-91ef-4417-88b6-bd79e7796730.json b/change/@fluentui-react-overflow-96369afb-91ef-4417-88b6-bd79e7796730.json new file mode 100644 index 00000000000000..0e62e403b83156 --- /dev/null +++ b/change/@fluentui-react-overflow-96369afb-91ef-4417-88b6-bd79e7796730.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "Added support for custom divider", + "packageName": "@fluentui/react-overflow", + "email": "vkozlova@microsoft.com", + "dependentChangeType": "patch" +} From b65b8ce938ab60990e9b1104d464967a88ae48e8 Mon Sep 17 00:00:00 2001 From: Valentyna Date: Tue, 13 Jun 2023 17:40:57 +0200 Subject: [PATCH 03/20] fix for overflow in Breadcrumb and api regenerated --- .../Breadcrumb/BreadcrumbWithOverflow.stories.tsx | 12 ++++++------ .../react-overflow/etc/react-overflow.api.md | 6 ++++++ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/packages/react-components/react-breadcrumb/stories/Breadcrumb/BreadcrumbWithOverflow.stories.tsx b/packages/react-components/react-breadcrumb/stories/Breadcrumb/BreadcrumbWithOverflow.stories.tsx index b5a5c1c9d26c0a..2e5f4373e9987d 100644 --- a/packages/react-components/react-breadcrumb/stories/Breadcrumb/BreadcrumbWithOverflow.stories.tsx +++ b/packages/react-components/react-breadcrumb/stories/Breadcrumb/BreadcrumbWithOverflow.stories.tsx @@ -16,6 +16,7 @@ import { Overflow, OverflowItem, MenuItem, + OverflowDivider, } from '@fluentui/react-components'; import { CalendarMonthFilled, @@ -161,12 +162,11 @@ const OverflowBreadcrumbButton: React.FC<{ id: string; item: Item }> = props => const OverflowGroupDivider: React.FC<{ groupId: number; }> = props => { - const groupVisibility = useIsOverflowGroupVisible(props.groupId.toString()); - if (groupVisibility === 'hidden') { - return null; - } - - return ; + return ( + + + + ); }; const ControlledOverflowMenu = (props: PartitionBreadcrumbItems) => { diff --git a/packages/react-components/react-overflow/etc/react-overflow.api.md b/packages/react-components/react-overflow/etc/react-overflow.api.md index 61d1f149bf69f9..f7d5d8253814f1 100644 --- a/packages/react-components/react-overflow/etc/react-overflow.api.md +++ b/packages/react-components/react-overflow/etc/react-overflow.api.md @@ -4,6 +4,12 @@ ```ts +import { ContextSelector } from '@fluentui/react-context-selector'; +import type { ObserveOptions } from '@fluentui/priority-overflow'; +import type { OnUpdateOverflow } from '@fluentui/priority-overflow'; +import type { OverflowDivider as OverflowDivider_2 } from '@fluentui/priority-overflow'; +import { OverflowGroupState } from '@fluentui/priority-overflow'; +import type { OverflowItemEntry } from '@fluentui/priority-overflow'; import * as React_2 from 'react'; // @public (undocumented) From 0f26cfa524b23e44120edf9aa24bc3e7046497b0 Mon Sep 17 00:00:00 2001 From: Valentyna Date: Wed, 14 Jun 2023 11:50:10 +0200 Subject: [PATCH 04/20] fixed test and api generation --- .../react-components/etc/react-components.api.md | 6 ++++++ .../react-overflow/src/useOverflowContainer.test.ts | 2 ++ 2 files changed, 8 insertions(+) diff --git a/packages/react-components/react-components/etc/react-components.api.md b/packages/react-components/react-components/etc/react-components.api.md index 966d033f0de62f..a0503fd40ab55e 100644 --- a/packages/react-components/react-components/etc/react-components.api.md +++ b/packages/react-components/react-components/etc/react-components.api.md @@ -163,6 +163,7 @@ import { createTableColumn } from '@fluentui/react-table'; import { CreateTableColumnOptions } from '@fluentui/react-table'; import { createTeamsDarkTheme } from '@fluentui/react-theme'; import { CurveTokens } from '@fluentui/react-theme'; +import { DATA_OVERFLOW_DIVIDER } from '@fluentui/react-overflow'; import { DATA_OVERFLOW_ITEM } from '@fluentui/react-overflow'; import { DATA_OVERFLOW_MENU } from '@fluentui/react-overflow'; import { DATA_OVERFLOWING } from '@fluentui/react-overflow'; @@ -407,6 +408,7 @@ import { OptionProps } from '@fluentui/react-combobox'; import { OptionSlots } from '@fluentui/react-combobox'; import { OptionState } from '@fluentui/react-combobox'; import { Overflow } from '@fluentui/react-overflow'; +import { OverflowDivider } from '@fluentui/react-overflow'; import { OverflowItem } from '@fluentui/react-overflow'; import { OverflowItemProps } from '@fluentui/react-overflow'; import { OverflowProps } from '@fluentui/react-overflow'; @@ -1341,6 +1343,8 @@ export { createTeamsDarkTheme } export { CurveTokens } +export { DATA_OVERFLOW_DIVIDER } + export { DATA_OVERFLOW_ITEM } export { DATA_OVERFLOW_MENU } @@ -1829,6 +1833,8 @@ export { OptionState } export { Overflow } +export { OverflowDivider } + export { OverflowItem } export { OverflowItemProps } diff --git a/packages/react-components/react-overflow/src/useOverflowContainer.test.ts b/packages/react-components/react-overflow/src/useOverflowContainer.test.ts index 978d95d8db7a1d..ac9854b8c020cc 100644 --- a/packages/react-components/react-overflow/src/useOverflowContainer.test.ts +++ b/packages/react-components/react-overflow/src/useOverflowContainer.test.ts @@ -15,6 +15,8 @@ const mockOverflowManager = (options: Partial = {}) => { removeItem: jest.fn(), removeOverflowMenu: jest.fn(), update: jest.fn(), + addDivider: jest.fn(), + removeDivider: jest.fn(), }; (createOverflowManager as jest.Mock).mockReturnValue({ ...defaultMock, From 179cbfbb3df58ee4b4a94e18141209bb960f5323 Mon Sep 17 00:00:00 2001 From: Valentyna Date: Wed, 14 Jun 2023 13:37:13 +0200 Subject: [PATCH 05/20] build fail fix --- packages/react-components/priority-overflow/src/consts.ts | 1 + .../react-components/priority-overflow/src/overflowManager.ts | 2 +- .../stories/Breadcrumb/BreadcrumbWithOverflow.stories.tsx | 1 - 3 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 packages/react-components/priority-overflow/src/consts.ts diff --git a/packages/react-components/priority-overflow/src/consts.ts b/packages/react-components/priority-overflow/src/consts.ts new file mode 100644 index 00000000000000..85814254c7c812 --- /dev/null +++ b/packages/react-components/priority-overflow/src/consts.ts @@ -0,0 +1 @@ +export const DATA_OVERFLOWING = 'data-overflowing'; diff --git a/packages/react-components/priority-overflow/src/overflowManager.ts b/packages/react-components/priority-overflow/src/overflowManager.ts index ec746e27b74151..c5c11bc11cae9f 100644 --- a/packages/react-components/priority-overflow/src/overflowManager.ts +++ b/packages/react-components/priority-overflow/src/overflowManager.ts @@ -1,4 +1,4 @@ -import { DATA_OVERFLOWING } from '../../react-overflow/src/constants'; +import { DATA_OVERFLOWING } from './consts'; import { debounce } from './debounce'; import { createPriorityQueue, PriorityQueue } from './priorityQueue'; import type { OverflowGroupState, OverflowItemEntry, OverflowManager, ObserveOptions, OverflowDivider } from './types'; diff --git a/packages/react-components/react-breadcrumb/stories/Breadcrumb/BreadcrumbWithOverflow.stories.tsx b/packages/react-components/react-breadcrumb/stories/Breadcrumb/BreadcrumbWithOverflow.stories.tsx index 2e5f4373e9987d..8775694e3482a3 100644 --- a/packages/react-components/react-breadcrumb/stories/Breadcrumb/BreadcrumbWithOverflow.stories.tsx +++ b/packages/react-components/react-breadcrumb/stories/Breadcrumb/BreadcrumbWithOverflow.stories.tsx @@ -11,7 +11,6 @@ import { MenuPopover, MenuTrigger, useIsOverflowItemVisible, - useIsOverflowGroupVisible, useOverflowMenu, Overflow, OverflowItem, From f4a096c1ef1632911365a7a00c426e9a2ff32547 Mon Sep 17 00:00:00 2001 From: Valentina Date: Thu, 15 Jun 2023 13:16:20 +0200 Subject: [PATCH 06/20] Update change/@fluentui-priority-overflow-8e128a48-5402-4886-b088-900334ce1883.json Co-authored-by: ling1726 --- ...-priority-overflow-8e128a48-5402-4886-b088-900334ce1883.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/change/@fluentui-priority-overflow-8e128a48-5402-4886-b088-900334ce1883.json b/change/@fluentui-priority-overflow-8e128a48-5402-4886-b088-900334ce1883.json index 338e3ceaaf58fc..464aa88f4f9af8 100644 --- a/change/@fluentui-priority-overflow-8e128a48-5402-4886-b088-900334ce1883.json +++ b/change/@fluentui-priority-overflow-8e128a48-5402-4886-b088-900334ce1883.json @@ -1,5 +1,5 @@ { - "type": "patch", + "type": "minor", "comment": "Added support for custom divider", "packageName": "@fluentui/priority-overflow", "email": "vkozlova@microsoft.com", From 7ab96e6e87f46bcba8fe0f48ab998d698df859da Mon Sep 17 00:00:00 2001 From: Valentina Date: Thu, 15 Jun 2023 13:16:28 +0200 Subject: [PATCH 07/20] Update change/@fluentui-priority-overflow-8e128a48-5402-4886-b088-900334ce1883.json Co-authored-by: ling1726 --- ...-priority-overflow-8e128a48-5402-4886-b088-900334ce1883.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/change/@fluentui-priority-overflow-8e128a48-5402-4886-b088-900334ce1883.json b/change/@fluentui-priority-overflow-8e128a48-5402-4886-b088-900334ce1883.json index 464aa88f4f9af8..92a84dfb011d20 100644 --- a/change/@fluentui-priority-overflow-8e128a48-5402-4886-b088-900334ce1883.json +++ b/change/@fluentui-priority-overflow-8e128a48-5402-4886-b088-900334ce1883.json @@ -1,6 +1,6 @@ { "type": "minor", - "comment": "Added support for custom divider", + "comment": "feat: Added support for custom divider", "packageName": "@fluentui/priority-overflow", "email": "vkozlova@microsoft.com", "dependentChangeType": "patch" From ba88e365cb6dd9b5f8042d6b5e4ee0b6d53b2506 Mon Sep 17 00:00:00 2001 From: Valentina Date: Thu, 15 Jun 2023 13:16:35 +0200 Subject: [PATCH 08/20] Update change/@fluentui-react-components-7b21b68d-a82b-4ee6-802c-cdbba6a8b25d.json Co-authored-by: ling1726 --- ...i-react-components-7b21b68d-a82b-4ee6-802c-cdbba6a8b25d.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/change/@fluentui-react-components-7b21b68d-a82b-4ee6-802c-cdbba6a8b25d.json b/change/@fluentui-react-components-7b21b68d-a82b-4ee6-802c-cdbba6a8b25d.json index 1cf6a19f9c3603..6e869927f49ef6 100644 --- a/change/@fluentui-react-components-7b21b68d-a82b-4ee6-802c-cdbba6a8b25d.json +++ b/change/@fluentui-react-components-7b21b68d-a82b-4ee6-802c-cdbba6a8b25d.json @@ -1,5 +1,5 @@ { - "type": "patch", + "type": "minor", "comment": "Added Overflow divider", "packageName": "@fluentui/react-components", "email": "vkozlova@microsoft.com", From e066826ef3043982e794b083b7d224d1aca5d20f Mon Sep 17 00:00:00 2001 From: Valentina Date: Thu, 15 Jun 2023 13:16:42 +0200 Subject: [PATCH 09/20] Update change/@fluentui-react-components-7b21b68d-a82b-4ee6-802c-cdbba6a8b25d.json Co-authored-by: ling1726 --- ...i-react-components-7b21b68d-a82b-4ee6-802c-cdbba6a8b25d.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/change/@fluentui-react-components-7b21b68d-a82b-4ee6-802c-cdbba6a8b25d.json b/change/@fluentui-react-components-7b21b68d-a82b-4ee6-802c-cdbba6a8b25d.json index 6e869927f49ef6..208339dac9ef6e 100644 --- a/change/@fluentui-react-components-7b21b68d-a82b-4ee6-802c-cdbba6a8b25d.json +++ b/change/@fluentui-react-components-7b21b68d-a82b-4ee6-802c-cdbba6a8b25d.json @@ -1,6 +1,6 @@ { "type": "minor", - "comment": "Added Overflow divider", + "comment": "feat: Added Overflow divider", "packageName": "@fluentui/react-components", "email": "vkozlova@microsoft.com", "dependentChangeType": "patch" From 894c4b67344699b0acc802e89f42e3e6a1bf379b Mon Sep 17 00:00:00 2001 From: Valentyna Date: Thu, 15 Jun 2023 14:42:05 +0200 Subject: [PATCH 10/20] PR fix --- .../priority-overflow/src/consts.ts | 1 + .../priority-overflow/src/index.ts | 2 +- .../priority-overflow/src/overflowManager.ts | 108 ++++++++++-------- .../priority-overflow/src/types.ts | 6 +- ...stories.tsx => LargerDividers.stories.tsx} | 10 +- .../stories/Overflow/index.stories.tsx | 2 +- 6 files changed, 72 insertions(+), 57 deletions(-) rename packages/react-components/react-overflow/stories/Overflow/{CustomDividers.stories.tsx => LargerDividers.stories.tsx} (89%) diff --git a/packages/react-components/priority-overflow/src/consts.ts b/packages/react-components/priority-overflow/src/consts.ts index 85814254c7c812..cb1c1cad5c1c79 100644 --- a/packages/react-components/priority-overflow/src/consts.ts +++ b/packages/react-components/priority-overflow/src/consts.ts @@ -1 +1,2 @@ export const DATA_OVERFLOWING = 'data-overflowing'; +export const DATA_OVERFLOW_GROUP = 'data-overflow-group'; diff --git a/packages/react-components/priority-overflow/src/index.ts b/packages/react-components/priority-overflow/src/index.ts index fedb15123401ae..ba4668ceab6d56 100644 --- a/packages/react-components/priority-overflow/src/index.ts +++ b/packages/react-components/priority-overflow/src/index.ts @@ -9,6 +9,6 @@ export type { OverflowEventPayload, OverflowGroupState, OverflowItemEntry, - OverflowDivider, + OverflowDividerEntry, OverflowManager, } from './types'; diff --git a/packages/react-components/priority-overflow/src/overflowManager.ts b/packages/react-components/priority-overflow/src/overflowManager.ts index c5c11bc11cae9f..b694c03a319324 100644 --- a/packages/react-components/priority-overflow/src/overflowManager.ts +++ b/packages/react-components/priority-overflow/src/overflowManager.ts @@ -1,7 +1,13 @@ -import { DATA_OVERFLOWING } from './consts'; +import { DATA_OVERFLOWING, DATA_OVERFLOW_GROUP } from './consts'; import { debounce } from './debounce'; import { createPriorityQueue, PriorityQueue } from './priorityQueue'; -import type { OverflowGroupState, OverflowItemEntry, OverflowManager, ObserveOptions, OverflowDivider } from './types'; +import type { + OverflowGroupState, + OverflowItemEntry, + OverflowManager, + ObserveOptions, + OverflowDividerEntry, +} from './types'; /** * @internal @@ -25,9 +31,7 @@ export function createOverflowManager(): OverflowManager { }; const overflowItems: Record = {}; - const overflowDividers: Record = {}; - const groups: Record; invisibleItemIds: Set }> = {}; - const groupVisibility: Record = {}; + const overflowDividers: Record = {}; const resizeObserver = new ResizeObserver(entries => { if (!entries[0] || !container) { return; @@ -37,13 +41,13 @@ export function createOverflowManager(): OverflowManager { }); function updateGroupVisibility(groupId: string) { - const group = groups[groupId]; + const group = groupManager.groups[groupId]; if (group.invisibleItemIds.size && group.visibleItemIds.size) { - groupVisibility[groupId] = 'overflow'; + groupManager.groupVisibility[groupId] = 'overflow'; } else if (group.visibleItemIds.size === 0) { - groupVisibility[groupId] = 'hidden'; + groupManager.groupVisibility[groupId] = 'hidden'; } else { - groupVisibility[groupId] = 'visible'; + groupManager.groupVisibility[groupId] = 'visible'; } } @@ -53,43 +57,49 @@ export function createOverflowManager(): OverflowManager { return overflowItems[nextItem]; }; - const groupManager = { - isGroupVisible(groupId: string) { - return groupVisibility[groupId] === 'visible' || groupVisibility[groupId] === 'overflow'; - }, - isSingleVisible(itemId: string, groupId: string) { - return ( - this.isGroupVisible(groupId) && - groups[groupId].visibleItemIds.has(itemId) && - groups[groupId].visibleItemIds.size === 1 - ); - }, - addItem(itemId: string, groupId: string) { - groups[groupId] ??= { - visibleItemIds: new Set(), - invisibleItemIds: new Set(), - }; - - groups[groupId].visibleItemIds.add(itemId); - updateGroupVisibility(groupId); - }, - removeItem(itemId: string, groupId: string) { - groups[groupId].invisibleItemIds.delete(itemId); - groups[groupId].visibleItemIds.delete(itemId); - updateGroupVisibility(groupId); - }, - showItem(itemId: string, groupId: string) { - groups[groupId].invisibleItemIds.delete(itemId); - groups[groupId].visibleItemIds.add(itemId); - updateGroupVisibility(groupId); - }, - hideItem(itemId: string, groupId: string) { - groups[groupId].invisibleItemIds.add(itemId); - groups[groupId].visibleItemIds.delete(itemId); - updateGroupVisibility(groupId); - }, + const createGroupManager = () => { + return { + groupVisibility: {} as Record, + groups: {} as Record; invisibleItemIds: Set }>, + isGroupVisible(groupId: string) { + return this.groupVisibility[groupId] === 'visible' || this.groupVisibility[groupId] === 'overflow'; + }, + isSingleVisible(itemId: string, groupId: string) { + return ( + this.isGroupVisible(groupId) && + this.groups[groupId].visibleItemIds.has(itemId) && + this.groups[groupId].visibleItemIds.size === 1 + ); + }, + addItem(itemId: string, groupId: string) { + this.groups[groupId] ??= { + visibleItemIds: new Set(), + invisibleItemIds: new Set(), + }; + + this.groups[groupId].visibleItemIds.add(itemId); + updateGroupVisibility(groupId); + }, + removeItem(itemId: string, groupId: string) { + this.groups[groupId].invisibleItemIds.delete(itemId); + this.groups[groupId].visibleItemIds.delete(itemId); + updateGroupVisibility(groupId); + }, + showItem(itemId: string, groupId: string) { + this.groups[groupId].invisibleItemIds.delete(itemId); + this.groups[groupId].visibleItemIds.add(itemId); + updateGroupVisibility(groupId); + }, + hideItem(itemId: string, groupId: string) { + this.groups[groupId].invisibleItemIds.add(itemId); + this.groups[groupId].visibleItemIds.delete(itemId); + updateGroupVisibility(groupId); + }, + }; }; + const groupManager = createGroupManager(); + const invisibleItemQueue = createPriorityQueue((a, b) => { const itemA = overflowItems[a]; const itemB = overflowItems[b]; @@ -176,7 +186,7 @@ export function createOverflowManager(): OverflowManager { const visibleItems = visibleItemIds.map(itemId => overflowItems[itemId]); const invisibleItems = invisibleItemIds.map(itemId => overflowItems[itemId]); - options.onUpdateOverflow({ visibleItems, invisibleItems, groupVisibility }); + options.onUpdateOverflow({ visibleItems, invisibleItems, groupVisibility: groupManager.groupVisibility }); }; const processOverflowItems = (): boolean => { @@ -258,7 +268,7 @@ export function createOverflowManager(): OverflowManager { if (item.groupId) { groupManager.addItem(item.id, item.groupId); - item.element.setAttribute('data-overflow-group', item.groupId); + item.element.setAttribute(DATA_OVERFLOW_GROUP, item.groupId); } update(); @@ -273,7 +283,7 @@ export function createOverflowManager(): OverflowManager { return; } - divider.element.setAttribute('data-overflow-group', divider.groupId); + divider.element.setAttribute(DATA_OVERFLOW_GROUP, divider.groupId); overflowDividers[divider.groupId] = divider; }; @@ -288,7 +298,7 @@ export function createOverflowManager(): OverflowManager { const divider = overflowDividers[groupId]; if (divider.groupId) { delete overflowDividers[groupId]; - divider.element.removeAttribute('data-overflow-group'); + divider.element.removeAttribute(DATA_OVERFLOW_GROUP); } }; @@ -303,7 +313,7 @@ export function createOverflowManager(): OverflowManager { if (item.groupId) { groupManager.removeItem(item.id, item.groupId); - item.element.removeAttribute('data-overflow-group'); + item.element.removeAttribute(DATA_OVERFLOW_GROUP); } delete overflowItems[itemId]; diff --git a/packages/react-components/priority-overflow/src/types.ts b/packages/react-components/priority-overflow/src/types.ts index a94aa4fda0a2cb..a5a9a41d1516df 100644 --- a/packages/react-components/priority-overflow/src/types.ts +++ b/packages/react-components/priority-overflow/src/types.ts @@ -19,13 +19,13 @@ export interface OverflowItemEntry { groupId?: string; } -export interface OverflowDivider { +export interface OverflowDividerEntry { /** * HTML element that will be disappear when overflowed */ element: HTMLElement; - groupId?: string; + groupId: string; } /** @@ -123,7 +123,7 @@ export interface OverflowManager { /** * Add overflow divider */ - addDivider: (divider: OverflowDivider) => void; + addDivider: (divider: OverflowDividerEntry) => void; /** * Remove overflow divider diff --git a/packages/react-components/react-overflow/stories/Overflow/CustomDividers.stories.tsx b/packages/react-components/react-overflow/stories/Overflow/LargerDividers.stories.tsx similarity index 89% rename from packages/react-components/react-overflow/stories/Overflow/CustomDividers.stories.tsx rename to packages/react-components/react-overflow/stories/Overflow/LargerDividers.stories.tsx index 98f3a0c8528acc..fb6ad3a3a44fcf 100644 --- a/packages/react-components/react-overflow/stories/Overflow/CustomDividers.stories.tsx +++ b/packages/react-components/react-overflow/stories/Overflow/LargerDividers.stories.tsx @@ -53,7 +53,7 @@ const useStyles = makeStyles({ }, }); -export const CustomDividers = () => { +export const LargerDividers = () => { const styles = useStyles(); return ( @@ -160,10 +160,14 @@ const OverflowMenuDivider: React.FC<{ return ; }; -CustomDividers.parameters = { +LargerDividers.parameters = { docs: { description: { - story: ['OverflowDivider should be used for larger dividers to include its width to the calculation.'].join('\n'), + story: [ + 'For smaller dividers a padding can be set to take into account the unmeasured space that the divider takes up.', + 'When the larger divider is used its width is not calculated. It causes items to overflow later then it has to be.', + "That's why `OverflowDivider` should be used for larger dividers to include its width to the calculation.", + ].join('\n'), }, }, }; diff --git a/packages/react-components/react-overflow/stories/Overflow/index.stories.tsx b/packages/react-components/react-overflow/stories/Overflow/index.stories.tsx index 65009fce75e4e8..ac995aaa8a1f5d 100644 --- a/packages/react-components/react-overflow/stories/Overflow/index.stories.tsx +++ b/packages/react-components/react-overflow/stories/Overflow/index.stories.tsx @@ -10,7 +10,7 @@ export { OverflowByPriority } from './OverflowByPriority.stories'; export { Wrapped } from './Wrapped.stories'; export { Pinned } from './Pinned.stories'; export { Dividers } from './Dividers.stories'; -export { CustomDividers } from './CustomDividers.stories'; +export { LargerDividers } from './LargerDividers.stories'; export { PriorityWithDividers } from './PriorityWithDividers.stories'; export default { From 09869c82eff76cc358aa93814cae409d6318eb18 Mon Sep 17 00:00:00 2001 From: Valentyna Date: Thu, 15 Jun 2023 23:17:07 +0200 Subject: [PATCH 11/20] PR fix #2 --- .../priority-overflow/src/overflowManager.ts | 56 +++++++++---------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/packages/react-components/priority-overflow/src/overflowManager.ts b/packages/react-components/priority-overflow/src/overflowManager.ts index b694c03a319324..ff7415c66ead87 100644 --- a/packages/react-components/priority-overflow/src/overflowManager.ts +++ b/packages/react-components/priority-overflow/src/overflowManager.ts @@ -40,17 +40,6 @@ export function createOverflowManager(): OverflowManager { update(); }); - function updateGroupVisibility(groupId: string) { - const group = groupManager.groups[groupId]; - if (group.invisibleItemIds.size && group.visibleItemIds.size) { - groupManager.groupVisibility[groupId] = 'overflow'; - } else if (group.visibleItemIds.size === 0) { - groupManager.groupVisibility[groupId] = 'hidden'; - } else { - groupManager.groupVisibility[groupId] = 'visible'; - } - } - const getNextItem = (queueToDequeue: PriorityQueue, queueToEnqueue: PriorityQueue) => { const nextItem = queueToDequeue.dequeue(); queueToEnqueue.enqueue(nextItem); @@ -58,41 +47,52 @@ export function createOverflowManager(): OverflowManager { }; const createGroupManager = () => { + const groupVisibility: Record = {}; + const groups: Record; invisibleItemIds: Set }> = {}; + function updateGroupVisibility(groupId: string) { + const group = groups[groupId]; + if (group.invisibleItemIds.size && group.visibleItemIds.size) { + groupVisibility[groupId] = 'overflow'; + } else if (group.visibleItemIds.size === 0) { + groupVisibility[groupId] = 'hidden'; + } else { + groupVisibility[groupId] = 'visible'; + } + } + function isGroupVisible(groupId: string) { + return groupVisibility[groupId] === 'visible' || groupVisibility[groupId] === 'overflow'; + } return { - groupVisibility: {} as Record, - groups: {} as Record; invisibleItemIds: Set }>, - isGroupVisible(groupId: string) { - return this.groupVisibility[groupId] === 'visible' || this.groupVisibility[groupId] === 'overflow'; - }, + groupVisibility: () => groupVisibility, isSingleVisible(itemId: string, groupId: string) { return ( - this.isGroupVisible(groupId) && - this.groups[groupId].visibleItemIds.has(itemId) && - this.groups[groupId].visibleItemIds.size === 1 + isGroupVisible(groupId) && + groups[groupId].visibleItemIds.has(itemId) && + groups[groupId].visibleItemIds.size === 1 ); }, addItem(itemId: string, groupId: string) { - this.groups[groupId] ??= { + groups[groupId] ??= { visibleItemIds: new Set(), invisibleItemIds: new Set(), }; - this.groups[groupId].visibleItemIds.add(itemId); + groups[groupId].visibleItemIds.add(itemId); updateGroupVisibility(groupId); }, removeItem(itemId: string, groupId: string) { - this.groups[groupId].invisibleItemIds.delete(itemId); - this.groups[groupId].visibleItemIds.delete(itemId); + groups[groupId].invisibleItemIds.delete(itemId); + groups[groupId].visibleItemIds.delete(itemId); updateGroupVisibility(groupId); }, showItem(itemId: string, groupId: string) { - this.groups[groupId].invisibleItemIds.delete(itemId); - this.groups[groupId].visibleItemIds.add(itemId); + groups[groupId].invisibleItemIds.delete(itemId); + groups[groupId].visibleItemIds.add(itemId); updateGroupVisibility(groupId); }, hideItem(itemId: string, groupId: string) { - this.groups[groupId].invisibleItemIds.add(itemId); - this.groups[groupId].visibleItemIds.delete(itemId); + groups[groupId].invisibleItemIds.add(itemId); + groups[groupId].visibleItemIds.delete(itemId); updateGroupVisibility(groupId); }, }; @@ -186,7 +186,7 @@ export function createOverflowManager(): OverflowManager { const visibleItems = visibleItemIds.map(itemId => overflowItems[itemId]); const invisibleItems = invisibleItemIds.map(itemId => overflowItems[itemId]); - options.onUpdateOverflow({ visibleItems, invisibleItems, groupVisibility: groupManager.groupVisibility }); + options.onUpdateOverflow({ visibleItems, invisibleItems, groupVisibility: groupManager.groupVisibility() }); }; const processOverflowItems = (): boolean => { From 77039fd5498f044036e46e5759a66dbedd01b938 Mon Sep 17 00:00:00 2001 From: Valentina Date: Thu, 15 Jun 2023 23:18:28 +0200 Subject: [PATCH 12/20] Update packages/react-components/react-overflow/src/components/Overflow.tsx Co-authored-by: ling1726 --- .../react-overflow/src/components/Overflow.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/react-components/react-overflow/src/components/Overflow.tsx b/packages/react-components/react-overflow/src/components/Overflow.tsx index 41382c34a253cd..bd7fe38d107f23 100644 --- a/packages/react-components/react-overflow/src/components/Overflow.tsx +++ b/packages/react-components/react-overflow/src/components/Overflow.tsx @@ -41,8 +41,8 @@ export const Overflow = React.forwardRef((props: OverflowProps, ref) => { const { visibleItems, invisibleItems, groupVisibility } = data; const itemVisibility: Record = {}; - visibleItems.forEach(x => { - itemVisibility[x.id] = true; + visibleItems.forEach(item => { + itemVisibility[item.id] = true; }); invisibleItems.forEach(x => (itemVisibility[x.id] = false)); From ac068364d9e73eb729b214e2c86ecd97fe99624a Mon Sep 17 00:00:00 2001 From: Valentina Date: Thu, 15 Jun 2023 23:18:49 +0200 Subject: [PATCH 13/20] Update packages/react-components/react-overflow/src/components/OverflowDivider/OverflowDivider.types.ts Co-authored-by: ling1726 --- .../src/components/OverflowDivider/OverflowDivider.types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-components/react-overflow/src/components/OverflowDivider/OverflowDivider.types.ts b/packages/react-components/react-overflow/src/components/OverflowDivider/OverflowDivider.types.ts index fab621a8ce9ae8..c7aecfdfc49858 100644 --- a/packages/react-components/react-overflow/src/components/OverflowDivider/OverflowDivider.types.ts +++ b/packages/react-components/react-overflow/src/components/OverflowDivider/OverflowDivider.types.ts @@ -7,7 +7,7 @@ export type OverflowDividerProps = { /** * Assigns the item to a group, group visibility can be watched. */ - groupId?: string; + groupId: string; /** * The single child that has overflow item behavior attached. */ From 27cf866e5d70942807ce843746e23724724e2889 Mon Sep 17 00:00:00 2001 From: Valentyna Date: Fri, 16 Jun 2023 11:39:33 +0200 Subject: [PATCH 14/20] regenerated api --- .../priority-overflow/etc/priority-overflow.api.md | 6 +++--- .../react-overflow/etc/react-overflow.api.md | 2 +- .../react-components/react-overflow/src/overflowContext.ts | 4 ++-- .../react-overflow/src/useOverflowContainer.ts | 4 ++-- .../react-overflow/src/useOverflowDivider.ts | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/react-components/priority-overflow/etc/priority-overflow.api.md b/packages/react-components/priority-overflow/etc/priority-overflow.api.md index 4ecb000b3bb31c..1889a2cbb621d8 100644 --- a/packages/react-components/priority-overflow/etc/priority-overflow.api.md +++ b/packages/react-components/priority-overflow/etc/priority-overflow.api.md @@ -38,10 +38,10 @@ export type OverflowAxis = 'horizontal' | 'vertical'; export type OverflowDirection = 'start' | 'end'; // @public (undocumented) -export interface OverflowDivider { +export interface OverflowDividerEntry { element: HTMLElement; // (undocumented) - groupId?: string; + groupId: string; } // @public @@ -68,7 +68,7 @@ export interface OverflowItemEntry { // @internal (undocumented) export interface OverflowManager { - addDivider: (divider: OverflowDivider) => void; + addDivider: (divider: OverflowDividerEntry) => void; addItem: (items: OverflowItemEntry) => void; addOverflowMenu: (element: HTMLElement) => void; disconnect: () => void; diff --git a/packages/react-components/react-overflow/etc/react-overflow.api.md b/packages/react-components/react-overflow/etc/react-overflow.api.md index f7d5d8253814f1..5e73d2df4ffe4e 100644 --- a/packages/react-components/react-overflow/etc/react-overflow.api.md +++ b/packages/react-components/react-overflow/etc/react-overflow.api.md @@ -7,7 +7,7 @@ import { ContextSelector } from '@fluentui/react-context-selector'; import type { ObserveOptions } from '@fluentui/priority-overflow'; import type { OnUpdateOverflow } from '@fluentui/priority-overflow'; -import type { OverflowDivider as OverflowDivider_2 } from '@fluentui/priority-overflow'; +import type { OverflowDividerEntry } from '@fluentui/priority-overflow'; import { OverflowGroupState } from '@fluentui/priority-overflow'; import type { OverflowItemEntry } from '@fluentui/priority-overflow'; import * as React_2 from 'react'; diff --git a/packages/react-components/react-overflow/src/overflowContext.ts b/packages/react-components/react-overflow/src/overflowContext.ts index a43dd30caeb407..3f40467a45e15f 100644 --- a/packages/react-components/react-overflow/src/overflowContext.ts +++ b/packages/react-components/react-overflow/src/overflowContext.ts @@ -1,4 +1,4 @@ -import type { OverflowGroupState, OverflowItemEntry, OverflowDivider } from '@fluentui/priority-overflow'; +import type { OverflowGroupState, OverflowItemEntry, OverflowDividerEntry } from '@fluentui/priority-overflow'; import { ContextSelector, createContext, useContextSelector, Context } from '@fluentui/react-context-selector'; /** @@ -10,7 +10,7 @@ export interface OverflowContextValue { hasOverflow: boolean; registerItem: (item: OverflowItemEntry) => () => void; registerOverflowMenu: (el: HTMLElement) => () => void; - registerDivider: (divider: OverflowDivider) => () => void; + registerDivider: (divider: OverflowDividerEntry) => () => void; updateOverflow: (padding?: number) => void; } diff --git a/packages/react-components/react-overflow/src/useOverflowContainer.ts b/packages/react-components/react-overflow/src/useOverflowContainer.ts index bc4480f143ee39..32dc0f44ffa855 100644 --- a/packages/react-components/react-overflow/src/useOverflowContainer.ts +++ b/packages/react-components/react-overflow/src/useOverflowContainer.ts @@ -8,7 +8,7 @@ import type { OnUpdateItemVisibility, OnUpdateOverflow, OverflowItemEntry, - OverflowDivider, + OverflowDividerEntry, OverflowManager, ObserveOptions, } from '@fluentui/priority-overflow'; @@ -80,7 +80,7 @@ export const useOverflowContainer = ( ); const registerDivider = React.useCallback( - (divider: OverflowDivider) => { + (divider: OverflowDividerEntry) => { const el = divider.element; overflowManager?.addDivider(divider); el && el.setAttribute(DATA_OVERFLOW_DIVIDER, ''); diff --git a/packages/react-components/react-overflow/src/useOverflowDivider.ts b/packages/react-components/react-overflow/src/useOverflowDivider.ts index dcb548b29aa4d4..8385ae6ea6f24f 100644 --- a/packages/react-components/react-overflow/src/useOverflowDivider.ts +++ b/packages/react-components/react-overflow/src/useOverflowDivider.ts @@ -13,7 +13,7 @@ export function useOverflowDivider(groupId?: strin const registerDivider = useOverflowContext(v => v.registerDivider); useIsomorphicLayoutEffect(() => { - if (ref.current) { + if (ref.current && groupId) { return registerDivider({ element: ref.current, groupId, From 465c4b934edc17834aba4e5578a2fa9fb7d055ee Mon Sep 17 00:00:00 2001 From: Valentina Date: Fri, 16 Jun 2023 13:51:34 +0200 Subject: [PATCH 15/20] Update packages/react-components/react-overflow/stories/Overflow/LargerDividers.stories.tsx Co-authored-by: ling1726 --- .../react-overflow/stories/Overflow/LargerDividers.stories.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-components/react-overflow/stories/Overflow/LargerDividers.stories.tsx b/packages/react-components/react-overflow/stories/Overflow/LargerDividers.stories.tsx index fb6ad3a3a44fcf..6377546193563b 100644 --- a/packages/react-components/react-overflow/stories/Overflow/LargerDividers.stories.tsx +++ b/packages/react-components/react-overflow/stories/Overflow/LargerDividers.stories.tsx @@ -165,7 +165,7 @@ LargerDividers.parameters = { description: { story: [ 'For smaller dividers a padding can be set to take into account the unmeasured space that the divider takes up.', - 'When the larger divider is used its width is not calculated. It causes items to overflow later then it has to be.', + 'When a larger divider is used its width is not calculated. This causes items to overflow later than needed.', "That's why `OverflowDivider` should be used for larger dividers to include its width to the calculation.", ].join('\n'), }, From 1b4a2eb210908442a932474d9dfe7d16afbb7e88 Mon Sep 17 00:00:00 2001 From: Valentina Date: Fri, 16 Jun 2023 13:51:46 +0200 Subject: [PATCH 16/20] Update packages/react-components/react-overflow/stories/Overflow/LargerDividers.stories.tsx Co-authored-by: ling1726 --- .../react-overflow/stories/Overflow/LargerDividers.stories.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-components/react-overflow/stories/Overflow/LargerDividers.stories.tsx b/packages/react-components/react-overflow/stories/Overflow/LargerDividers.stories.tsx index 6377546193563b..e78b87995d9477 100644 --- a/packages/react-components/react-overflow/stories/Overflow/LargerDividers.stories.tsx +++ b/packages/react-components/react-overflow/stories/Overflow/LargerDividers.stories.tsx @@ -166,7 +166,7 @@ LargerDividers.parameters = { story: [ 'For smaller dividers a padding can be set to take into account the unmeasured space that the divider takes up.', 'When a larger divider is used its width is not calculated. This causes items to overflow later than needed.', - "That's why `OverflowDivider` should be used for larger dividers to include its width to the calculation.", + "The `OverflowDivider` divider component can be used for larger dividers to include its width to the calculation.", ].join('\n'), }, }, From 38d6dcc8c1d38e0fd03183863dc77efa0ca78157 Mon Sep 17 00:00:00 2001 From: Valentina Date: Fri, 16 Jun 2023 13:52:10 +0200 Subject: [PATCH 17/20] Update packages/react-components/react-overflow/stories/Overflow/LargerDividers.stories.tsx Co-authored-by: ling1726 --- .../react-overflow/stories/Overflow/LargerDividers.stories.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-components/react-overflow/stories/Overflow/LargerDividers.stories.tsx b/packages/react-components/react-overflow/stories/Overflow/LargerDividers.stories.tsx index e78b87995d9477..6d57146a41dc09 100644 --- a/packages/react-components/react-overflow/stories/Overflow/LargerDividers.stories.tsx +++ b/packages/react-components/react-overflow/stories/Overflow/LargerDividers.stories.tsx @@ -164,7 +164,7 @@ LargerDividers.parameters = { docs: { description: { story: [ - 'For smaller dividers a padding can be set to take into account the unmeasured space that the divider takes up.', + 'For smaller dividers the `padding` prop can be set to take into account the unmeasured space that the divider takes up.', 'When a larger divider is used its width is not calculated. This causes items to overflow later than needed.', "The `OverflowDivider` divider component can be used for larger dividers to include its width to the calculation.", ].join('\n'), From 9dff18a2b2adad473f058d4a79e0b66aa730e34a Mon Sep 17 00:00:00 2001 From: Valentina Date: Fri, 16 Jun 2023 13:52:34 +0200 Subject: [PATCH 18/20] Update packages/react-components/priority-overflow/src/overflowManager.ts Co-authored-by: ling1726 --- .../react-components/priority-overflow/src/overflowManager.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-components/priority-overflow/src/overflowManager.ts b/packages/react-components/priority-overflow/src/overflowManager.ts index ff7415c66ead87..6d1ac1cb8e9ae1 100644 --- a/packages/react-components/priority-overflow/src/overflowManager.ts +++ b/packages/react-components/priority-overflow/src/overflowManager.ts @@ -64,7 +64,7 @@ export function createOverflowManager(): OverflowManager { } return { groupVisibility: () => groupVisibility, - isSingleVisible(itemId: string, groupId: string) { + isSingleItemVisible(itemId: string, groupId: string) { return ( isGroupVisible(groupId) && groups[groupId].visibleItemIds.has(itemId) && From 1ae6d1fa15cda76e9898dcb1790c8186441f62cf Mon Sep 17 00:00:00 2001 From: Valentyna Date: Fri, 16 Jun 2023 13:56:05 +0200 Subject: [PATCH 19/20] pr fix#3 --- .../priority-overflow/src/overflowManager.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/react-components/priority-overflow/src/overflowManager.ts b/packages/react-components/priority-overflow/src/overflowManager.ts index 6d1ac1cb8e9ae1..445b541e6f0061 100644 --- a/packages/react-components/priority-overflow/src/overflowManager.ts +++ b/packages/react-components/priority-overflow/src/overflowManager.ts @@ -141,7 +141,7 @@ export function createOverflowManager(): OverflowManager { function computeSizeChange(entry: OverflowItemEntry) { const dividerWidth = - entry.groupId && groupManager.isSingleVisible(entry.id, entry.groupId) && overflowDividers[entry.groupId] + entry.groupId && groupManager.isSingleItemVisible(entry.id, entry.groupId) && overflowDividers[entry.groupId] ? getOffsetSize(overflowDividers[entry.groupId].element) : 0; @@ -155,7 +155,7 @@ export function createOverflowManager(): OverflowManager { if (item.groupId) { groupManager.showItem(item.id, item.groupId); - if (groupManager.isSingleVisible(item.id, item.groupId)) { + if (groupManager.isSingleItemVisible(item.id, item.groupId)) { overflowDividers[item.groupId]?.element.removeAttribute(DATA_OVERFLOWING); } } @@ -169,7 +169,7 @@ export function createOverflowManager(): OverflowManager { options.onUpdateItemVisibility({ item, visible: false }); if (item.groupId) { - if (groupManager.isSingleVisible(item.id, item.groupId)) { + if (groupManager.isSingleItemVisible(item.id, item.groupId)) { overflowDividers[item.groupId]?.element.setAttribute(DATA_OVERFLOWING, ''); } From cbf1d8ab14725c60274e4e84002cbc0ece8133a6 Mon Sep 17 00:00:00 2001 From: Valentyna Date: Fri, 16 Jun 2023 14:05:03 +0200 Subject: [PATCH 20/20] fix --- .../react-overflow/stories/Overflow/LargerDividers.stories.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-components/react-overflow/stories/Overflow/LargerDividers.stories.tsx b/packages/react-components/react-overflow/stories/Overflow/LargerDividers.stories.tsx index 6d57146a41dc09..c802641f44ec2e 100644 --- a/packages/react-components/react-overflow/stories/Overflow/LargerDividers.stories.tsx +++ b/packages/react-components/react-overflow/stories/Overflow/LargerDividers.stories.tsx @@ -166,7 +166,7 @@ LargerDividers.parameters = { story: [ 'For smaller dividers the `padding` prop can be set to take into account the unmeasured space that the divider takes up.', 'When a larger divider is used its width is not calculated. This causes items to overflow later than needed.', - "The `OverflowDivider` divider component can be used for larger dividers to include its width to the calculation.", + 'The `OverflowDivider` divider component can be used for larger dividers to include its width to the calculation.', ].join('\n'), }, },