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

[DataGridPremium] Add support for cell selection #6567

Merged
merged 16 commits into from
Dec 14, 2022

Conversation

m4theushw
Copy link
Member

@m4theushw m4theushw commented Oct 20, 2022

Preview: https://deploy-preview-6567--material-ui-x.netlify.app/x/react-data-grid/selection/#cell-selection

Fixes #208

This PR contains the initial implementation of the cell selection feature. The new feature is opt-in, meaning that users need to enable it with the cellSelection prop. Both row selection and cell selection can work in parallel, however, using keyboard for selection will lead to different selections. I can't see how this feature will be used in real applications, besides to copy and paste cells, so I didn't implement all equivalent props from row selection here, e.g. isRowSelectable. This can be done later as we receive feedback from users.

@m4theushw m4theushw added the component: data grid This is the name of the generic UI component, not the React module! label Oct 20, 2022
@mui-bot
Copy link

mui-bot commented Oct 20, 2022

Messages
📖 Netlify deploy preview: https://deploy-preview-6567--material-ui-x.netlify.app/

These are the results for the performance tests:

Test case Unit Min Max Median Mean σ
Filter 100k rows ms 645.6 943.7 708.2 757.94 107.724
Sort 100k rows ms 603.8 985.5 894.3 850.2 136.408
Select 100k rows ms 211.8 363.6 212.7 244.88 59.538
Deselect 100k rows ms 177.5 237.7 214.7 210.88 24.728

Generated by 🚫 dangerJS against fe3166c

@github-actions github-actions bot added PR: out-of-date The pull request has merge conflicts and can't be merged and removed PR: out-of-date The pull request has merge conflicts and can't be merged labels Oct 31, 2022
@mui mui deleted a comment from github-actions bot Nov 2, 2022
@m4theushw m4theushw added the feature: Selection Related to the data grid Selection feature label Nov 2, 2022
@m4theushw m4theushw marked this pull request as ready for review November 2, 2022 00:10
@joserodolfofreitas
Copy link
Member

At first glance, the selection of multiple cells feels great!
And it's really nice that we can already use the controlled model to update multiple selected cells as well.
As I understand we need a new issue to implement "copy" from selection, right?

@m4theushw
Copy link
Member Author

As I understand we need a new issue to implement "copy" from selection, right?

@joserodolfofreitas I was considering that everything related to clipboard would be done in #199. But I can implement copying the cells here. It will work like the row selection.

@joserodolfofreitas
Copy link
Member

joserodolfofreitas commented Nov 2, 2022

It's fine. It's reasonable to have a separate issue and PR for it, it also reduces the review scope.
Maybe what could be in the scope of the current PR is perhaps an apiRef method to get the selected cells (and values). Would that make sense? Or is it most of the work for copying already?

@m4theushw
Copy link
Member Author

Maybe what could be in the scope of the current PR is perhaps an apiRef method to get the selected cells (and values). Would that make sense?

I already added two methods: getCellSelectionModel and getSelectedCellsAsArray. However, they are not in https://deploy-preview-6567--material-ui-x.netlify.app/x/react-data-grid/selection/#apiref because I don't know if I should merge cell selection methods with row selection or create a separate apiRef-block for each feature.

@MatthijsKok

This comment was marked as resolved.

@m4theushw
Copy link
Member Author

@MatthijsKok Thanks for the feedback! I pushed 7a71703 fixing this.

docs/data/data-grid/selection/CellSelectionFormulaField.js Outdated Show resolved Hide resolved
rowLength: 10,
maxColumns: 6,
});

Copy link
Member

Choose a reason for hiding this comment

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

Is it possible to scroll automatically when selecting cells range?
Currently, using a mouse you can only select cell range within visible cells

Screen.Recording.2022-11-09.at.20.16.22.mov

Copy link
Member

Choose a reason for hiding this comment

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

In terms of UX, from the sources that I could benchmark:

  • Airtable: OK but it feels that it starts scrolling too far away from the bottom of the viewport. It's distracting.
  • Google Sheet: OK but it feels that it starts scrolling too late, only once you are beyond the bottom of the viewport. You don't see what you are going to select next.
  • Notion: The best 🥇. The threshold feels good, and they also have an incremental scrolling speed based on far you are from the bottom of the viewport 👌.

At least, my perspective as a user, I would be curious about @gerdadesign take on this UX.

Copy link
Member Author

Choose a reason for hiding this comment

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

We can implement this later but it's possible. It's similar to what we have for the column headers (although it doesn't work).

Copy link
Member

Choose a reason for hiding this comment

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

It's similar to what we have for the column headers (although it doesn't work).

Yes, there's an open issue for it #6236

maxColumns: 6,
});

return (
Copy link
Member

Choose a reason for hiding this comment

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

For the Shift + Click range selection, is it possible to "remember" the first cell that started the range?
Like in spreadsheet:

Screen.Recording.2022-11-09.at.20.24.24.mov

Currently, the grid creates new range selection started from the last click cell:

Screen.Recording.2022-11-09.at.20.20.49.mov

Copy link
Member Author

Choose a reason for hiding this comment

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

With the current focus logic, no. The cell with the border is the cell currently focused. When you click the first cell, then the last cell, the focused cell becomes the last clicked one. We would need to split the concept of focused cell between cell that has the focus and cell that has the border. If you create a selection by dragging, not clicking the last cell, then it behaves more like Google Spreadsheet, because the last cell was not clicked and the focus remains in the first cell.

Copy link
Member

Choose a reason for hiding this comment

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

We agreed on keeping the current behavior for now, as it requires some changes in how we manage the focused/outlined cell state.
@m4theushw will submit a follow-up PR to change the cell focus management so it's possible to always start a new range from a first selected cell of a previous range.
Did I capture it correctly?

const columnsInRange = visibleColumns.slice(finalStartColumnIndex, finalEndColumnIndex + 1);

const newModel = rowsInRange.reduce<GridCellSelectionModel>((acc, row) => {
acc[row.id] = columnsInRange.reduce<Record<GridColDef['field'], boolean>>(
Copy link
Member

Choose a reason for hiding this comment

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

If I understand correctly, the cell selection model keeps track of every selected cell by id + field.
I've noticed a few things related to this:

  • you can create a range selection with gaps
  • you end up with gaps in range selection after sorting

Maybe we should consider a selection model that has only start and end cell coordinates, where coordinates are row and column indices rather than rowId and column field?

Copy link
Member Author

Choose a reason for hiding this comment

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

you can create a range selection with gap

Yes, it's expected. Other spreadsheet apps also allow to start with a range, then use Ctrl to select some cells.

you end up with gaps in range selection after sorting

That's why I prefer to call this feature as "cell selection". Users call select a range of cells, but underneath they are selecting individual cells. I considered only storing the start and end cell coordinates, however, this would bring much more complexity since any cell that is deselected would force a split of the range in many ranges. Also, tracking the selection of individual cells resembles how row selection works.

Copy link
Member

Choose a reason for hiding this comment

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

Since the majority of use cases for cell range selection don't involve sorting and/or filtering, we decided to keep the existing behavior and reconsider it in the future if needed.

Copy link
Member

@oliviertassinari oliviertassinari left a comment

Choose a reason for hiding this comment

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

It looks great, well done 👌

docs/data/data-grid/selection/selection.md Show resolved Hide resolved
docs/data/data-grid/selection/selection.md Outdated Show resolved Hide resolved
docs/data/data-grid/selection/selection.md Outdated Show resolved Hide resolved
docs/data/data-grid/selection/selection.md Outdated Show resolved Hide resolved
} from '@mui/x-data-grid-premium';
import { getBasicGridData } from '@mui/x-data-grid-generator';

describe('<DataGridPremium /> - Cell Selection', () => {
Copy link
Member

Choose a reason for hiding this comment

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

Sentence case, I think in this case.

Suggested change
describe('<DataGridPremium /> - Cell Selection', () => {
describe('<DataGridPremium /> - Cell selection', () => {

Copy link
Member Author

Choose a reason for hiding this comment

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

We were using Pascal case in most cases.

describe('<DataGridPremium /> - Row Grouping', () => {

describe('<DataGridPro /> - Cell Editing', () => {

describe('<DataGridPro /> - Tree Data', () => {

Copy link
Member

Choose a reason for hiding this comment

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

@@ -84,25 +84,89 @@ The following demo shows the prop in action:

{{"demo": "ControlledSelectionServerPaginationGrid.js", "bg": "inline"}}

## apiRef [<span class="plan-pro"></span>](/x/introduction/licensing/#pro-plan)
## Cell selection [<span class="plan-premium"></span>](/x/introduction/licensing/#premium-plan)
Copy link
Member

Choose a reason for hiding this comment

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

Outside of the scope of this PR (maybe for a follow-up)

It might be better to systematically have premium/pro features on a dedicated page if the section is larger than the viewport. My fear is that a developer might land in the middle of the section using the search without being able to easily see that it's a Pro/Premium feature. With a dedicated page, we get a UX benefit, even in the middle of the page, we see:

Screenshot 2022-11-10 at 00 27 59

Copy link
Member Author

Choose a reason for hiding this comment

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

I'll do in a follow-up. Since the pages will be split, we also need to add a redirect from /x/react-data-grid/selection/ to /x/react-data-grid/row-selection/.

Copy link
Member

Choose a reason for hiding this comment

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

Sounds great

@oliviertassinari oliviertassinari added the new feature New feature or request label Nov 9, 2022
@github-actions github-actions bot added the PR: out-of-date The pull request has merge conflicts and can't be merged label Nov 10, 2022
@github-actions

This comment was marked as outdated.

1 similar comment
@github-actions

This comment was marked as outdated.

@MatthijsKok
Copy link
Contributor

Wow! Thanks for the quick response @m4theushw !

Copy link
Member

@cherniavskii cherniavskii left a comment

Choose a reason for hiding this comment

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

Looks great!

Copy link
Member

@DanailH DanailH left a comment

Choose a reason for hiding this comment

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

As we discussed the behavior when you try and make a new selection when there is already one active can be addressed in a separate PR.

Copy link
Member

@oliviertassinari oliviertassinari left a comment

Choose a reason for hiding this comment

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

Maybe it would be great to have a list of the next steps once this PR is merged, maybe for new GitHub issues 🤷‍♂️. Things I'm aware of:

docs/data/data-grid/selection/selection.md Outdated Show resolved Hide resolved
docs/data/data-grid/selection/selection.md Outdated Show resolved Hide resolved
@@ -84,25 +84,89 @@ The following demo shows the prop in action:

{{"demo": "ControlledSelectionServerPaginationGrid.js", "bg": "inline"}}

## apiRef [<span class="plan-pro"></span>](/x/introduction/licensing/#pro-plan)
## Cell selection [<span class="plan-premium"></span>](/x/introduction/licensing/#premium-plan)
Copy link
Member

Choose a reason for hiding this comment

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

Sounds great

@m4theushw
Copy link
Member Author

@MBilalShafi I pushed c3d45b0 fixing the bug you described in #6567 (comment). It only occurs on macOS.

Copy link
Member

@MBilalShafi MBilalShafi left a comment

Choose a reason for hiding this comment

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

🎉

@github-actions
Copy link

This pull request has conflicts, please resolve those before we can evaluate the pull request.

@github-actions github-actions bot added the PR: out-of-date The pull request has merge conflicts and can't be merged label Dec 13, 2022
@oliviertassinari
Copy link
Member

oliviertassinari commented Jan 1, 2023

@m4theushw Awesome 👌, great to see this first iteration!

Design-wise, the customization demo might look better than the default https://next.mui.com/x/react-data-grid/cell-selection/#customize-range-styling, maybe it should be the default 😁

Default

Screenshot 2023-01-01 at 18 15 55

https://codesandbox.io/s/h48tq7?file=/demo.tsx

Customization

Screenshot 2023-01-01 at 18 29 21

https://codesandbox.io/s/4lrfld?file=/demo.tsx

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: data grid This is the name of the generic UI component, not the React module! feature: Selection Related to the data grid Selection feature new feature New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[data grid] Implement cell selection with range
9 participants