Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix ButtonGroup overflowButton logic #1278

Merged
merged 6 commits into from May 25, 2023
Merged

Conversation

mayank99
Copy link
Contributor

@mayank99 mayank99 commented May 12, 2023

Changes

Our current ButtonGroup overflow logic looks a bit flawed because it doesn't fully take into account the overflowButton itself. So I've adjusted the calculations to assume that overflowButton is one of the visible items.

Additionally, I've adjusted the values so that overflowPlacement=start will remove items from the beginning.

Expected values when overflowPlacement=start:

length visibleCount overflowStart
10 10 -
10 9 (including overflowButton) 1 (2 menu items)
10 8 2 (3 menu items)
10 7 3
10 6 4
10 5 5
10 4 6
10 3 7
10 2 8
10 1 (only overflowButton) 9 (10 items)

Expected values when overflowPlacement=end:

length visibleCount overflowStart
10 10 -
10 9 (including overflowButton) 8 (2 menu items)
10 8 7 (3 menu items)
10 7 6
10 6 5
10 5 4
10 4 3
10 3 2
10 2 1
10 1 (only overflowButton) 0 (10 items)

Testing

Unit tests pending.

Tested in playground using this code:

App.tsx
import * as React from 'react';
import { SvgPlaceholder, SvgMore } from '@itwin/itwinui-icons-react';
import {
  ButtonGroup,
  DropdownMenu,
  IconButton,
  MenuItem,
} from '@itwin/itwinui-react';

export default () => {
  const [overflowPlacement, setOverflowPlacement] = React.useState('end');
  const items = Array.from({ length: 10 }, (_, index) => (
    <IconButton key={index} label={`Item #${index}`}>
      <SvgPlaceholder />
    </IconButton>
  ));

  return (
    <>
      <fieldset>
        <legend>overflowPlacement</legend>
        <label>
          <input
            type='radio'
            name='placement'
            value='start'
            checked={overflowPlacement === 'start'}
            onChange={(e) => setOverflowPlacement(e.currentTarget.value)}
          />{' '}
          start
        </label>{' '}
        <label>
          <input
            type='radio'
            name='placement'
            value='end'
            checked={overflowPlacement === 'end'}
            onChange={(e) => setOverflowPlacement(e.currentTarget.value)}
          />{' '}
          end
        </label>
      </fieldset>

      <div
        style={{
          border: '1px solid',
          padding: 8,
          overflow: 'hidden',
          resize: 'horizontal',
        }}
      >
        <ButtonGroup
          orientation='horizontal'
          overflowPlacement={overflowPlacement as 'start' | 'end'}
          overflowButton={(overflowStart) => {
            return (
              <DropdownMenu
                menuItems={(close) => {
                  const length =
                    overflowPlacement === 'start'
                      ? overflowStart + 1
                      : items.length - overflowStart;

                  return Array.from({ length }, (_, _index) => {
                    const index =
                      overflowPlacement === 'start'
                        ? _index
                        : overflowStart + _index;

                    return (
                      <MenuItem
                        key={index}
                        onClick={close}
                        icon={<SvgPlaceholder />}
                      >
                        Item #{index}
                      </MenuItem>
                    );
                  });
                }}
              >
                <IconButton label='More'>
                  <SvgMore />
                </IconButton>
              </DropdownMenu>
            );
          }}
        >
          {items}
        </ButtonGroup>
      </div>
    </>
  );
};
Screen.Recording.2023-05-12.at.2.46.17.PM.mov

Docs

Briefly mentioned in migration guide: https://github.com/iTwin/iTwinUI/wiki/iTwinUI-react-v3-migration-guide#buttongroup

@mayank99 mayank99 self-assigned this May 12, 2023
@mayank99 mayank99 linked an issue May 12, 2023 that may be closed by this pull request
@mayank99 mayank99 marked this pull request as ready for review May 12, 2023 18:49
@mayank99 mayank99 requested a review from a team as a code owner May 12, 2023 18:49
@mayank99 mayank99 requested review from a team, gretanausedaite and LostABike and removed request for a team May 12, 2023 18:49
@mayank99 mayank99 marked this pull request as draft May 12, 2023 18:49
@mayank99 mayank99 changed the base branch from main to dev May 17, 2023 19:03
@mayank99 mayank99 marked this pull request as ready for review May 17, 2023 20:56
@mayank99 mayank99 added this to the React 3.0 milestone May 17, 2023
Copy link
Contributor

@gretanausedaite gretanausedaite left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you write which v3 task you were working on when noticed this issue?
Also, could you mention related v3 task in all your PRs. It's hard to guess which PR goes with which task.

@mayank99
Copy link
Contributor Author

@gretanausedaite Did you see the linked issue? I was working on this PR for v2 but it would have been a breaking change so moved to major release.

@gretanausedaite
Copy link
Contributor

Did you see the linked issue?

Linked issue was missing v3 milestone so it wasn't in our v3 backlog. Sorry about that.

Copy link
Contributor

@LostABike LostABike left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I saw the original issue and tested this change, it is working as expected and should address the linked issue.

@mayank99
Copy link
Contributor Author

I'll work on adding unit tests. I was looking for feedback on the calculations. Do they make sense? I was a bit unsure about the values in overflowPlacement=start case.

@LostABike
Copy link
Contributor

I'll work on adding unit tests. I was looking for feedback on the calculations. Do they make sense? I was a bit unsure about the values in overflowPlacement=start case.

Yea I think it makes sense that when overflowPlacement=start, overflowButton will contain all the items that are not visible and show the rest (I'm going off the logic on line 115 and 125). Unit test would be great to sanity check the logic too.

Copy link
Contributor

@gretanausedaite gretanausedaite left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think calculations are a bit wrong. Storybook with overflowPlacement start
image

@mayank99
Copy link
Contributor Author

I think calculations are a bit wrong. Storybook with overflowPlacement start image

The values exposed by overflowButton callback should be correct, but the code for using that value will differ between start and end placements. I can update the story to handle both cases, but in the meantime check out the code snippet in PR description.

@gretanausedaite
Copy link
Contributor

check out the code snippet in PR description.

That works perfectly!
It could be awesome if we showcased our users how to achieve certain functionality in docs site or storybook.

Copy link
Contributor

@gretanausedaite gretanausedaite left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe unit tests are still pending.

@mayank99
Copy link
Contributor Author

Updated unit tests and story.

@mayank99 mayank99 enabled auto-merge May 25, 2023 14:41
@mayank99 mayank99 added this pull request to the merge queue May 25, 2023
Merged via the queue into dev with commit a0e73a5 May 25, 2023
12 checks passed
@mayank99 mayank99 deleted the mayank/fix-buttongroup-overflow branch May 25, 2023 15:13
@imodeljs-admin imodeljs-admin mentioned this pull request Oct 23, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Button Group Overflow at Start
3 participants