Revert "Replace ActionBar overflow calculations with CSS wrapping approach"#7807
Revert "Replace ActionBar overflow calculations with CSS wrapping approach"#7807
ActionBar overflow calculations with CSS wrapping approach"#7807Conversation
…pproach …" This reverts commit f59a1b1.
|
|
|
👋 Hi from github/github-ui! Your integration PR is ready: https://github.com/github/github-ui/pull/20034 |
There was a problem hiding this comment.
Pull request overview
This PR reverts #7655, moving ActionBar overflow handling away from the recent CSS-wrapping approach and back to a JS-driven measurement/overflow-menu model.
Changes:
- Reintroduces overflow calculation logic in
ActionBarusing measured child widths and a resize observer to populate the overflow menu. - Simplifies
ActionBarCSS by removing the prior overflow-detection / wrapping styles. - Updates unit/e2e tests and adds a Storybook example (text-labeled buttons); removes the changeset from the reverted PR.
Show a summary per file
| File | Description |
|---|---|
| packages/react/src/ActionBar/ActionBar.tsx | Restores JS-based overflow logic, introduces width measurement + registry-driven overflow menu rendering. |
| packages/react/src/ActionBar/ActionBar.test.tsx | Updates the zero-width test assertion to query by accessible name instead of test id. |
| packages/react/src/ActionBar/ActionBar.module.css | Removes CSS overflow detection/wrapping styles and tweaks alignment/nowrap behavior. |
| packages/react/src/ActionBar/ActionBar.examples.stories.tsx | Adds a TextLabels example using standard Button children. |
| e2e/components/drafts/ActionBar.test.ts | Updates overflow interaction assertions to count buttons without visible: true filtering. |
| .changeset/many-suns-promise.md | Removes the changeset associated with the reverted change. |
Copilot's findings
- Files reviewed: 6/6 changed files
- Comments generated: 6
| // First, we check if we can fit all the items with their icons | ||
| if (registryEntries.length >= numberOfItemsPossible) { | ||
| /* Below is an accessibility requirement. Never show only one item in the overflow menu. | ||
| * If there is only one item left to display in the overflow menu according to the calculation, | ||
| * we need to pull another item from the list into the overflow menu. | ||
| */ | ||
| const numberOfItemsInMenu = registryEntries.length - numberOfItemsPossibleWithMoreMenu | ||
| const numberOfListItems = | ||
| numberOfItemsInMenu === 1 ? numberOfItemsPossibleWithMoreMenu - 1 : numberOfItemsPossibleWithMoreMenu | ||
| for (const [index, [id, child]] of registryEntries.entries()) { | ||
| if (index < numberOfListItems) { | ||
| continue | ||
| //if the last item is a divider | ||
| } else if (child.type === 'divider') { | ||
| if (index === numberOfListItems - 1 || index === numberOfListItems) { | ||
| continue | ||
| } else { | ||
| menuItems.add(id) | ||
| } | ||
| } else { | ||
| menuItems.add(id) | ||
| } | ||
| } | ||
|
|
||
| const {containerRef} = useFocusZone( | ||
| { | ||
| bindKeys: FocusKeys.ArrowHorizontal | FocusKeys.HomeAndEnd, | ||
| focusOutBehavior: 'wrap', | ||
| focusableElementFilter: element => element.matches(FOCUSABLE_ITEM_SELECTOR), | ||
| return menuItems | ||
| } else if (numberOfItemsPossible > registryEntries.length && hasActiveMenu) { | ||
| /* If the items fit in the list and there are items in the overflow menu, we need to move them back to the list */ | ||
| return new Set() | ||
| } |
| {menuItemIds.size > 0 && ( | ||
| <ActionMenu> | ||
| <ActionMenu.Anchor> | ||
| <IconButton variant="invisible" aria-label={`More ${ariaLabel} items`} icon={KebabHorizontalIcon} /> |
| const moreMenuRef = useRef<HTMLLIElement>(null) | ||
|
|
||
| useResizeObserver((resizeObserverEntries: ResizeObserverEntry[]) => { | ||
| const navWidth = resizeObserverEntries[0].contentRect.width | ||
| const moreMenuWidth = moreMenuRef.current?.getBoundingClientRect().width ?? 0 |
| useIsomorphicLayoutEffect(() => setWidth(ref.current?.getBoundingClientRect().width ?? -1), [ref]) | ||
|
|
| * Registry of descendants to render in the list or menu. To preserve insertion order across updates, children are | ||
| * set to `null` when unregistered rather than fully dropped from the map. | ||
| */ | ||
| type ChildRegistry = ReadonlyMap<string, ChildProps | null> |
| {menuItemIds.size > 0 && ( | ||
| <ActionMenu> | ||
| <ActionMenu.Anchor> | ||
| <IconButton variant="invisible" aria-label={`More ${ariaLabel} items`} icon={KebabHorizontalIcon} /> |
Reverts #7655