mui / mui-x

MUI X: Build complex and data-rich applications using a growing list of advanced React components, like the Data Grid, Date and Time Pickers, Charts, and more!
https://mui.com/x/
4.57k stars 1.34k forks source link

[data grid] Wrap default checkbox in tooltip #14331

Open svidskiy opened 3 months ago

svidskiy commented 3 months ago

The problem in depth

How can I wrap a checkbox for the header and a checkbox for the cell? I need a tooltip for the header checkbox select all/deselect all and for the cell checkbox select/deselect.

image

Your environment

`npx @mui/envinfo` ``` System: OS: Windows 11 10.0.22631 Binaries: Node: 18.18.0 - C:\Program Files\nodejs\node.EXE npm: 10.5.2 - C:\Program Files\nodejs\npm.CMD pnpm: 9.6.0 - C:\Program Files\nodejs\pnpm.CMD Browsers: Chrome: Not Found Edge: Chromium (127.0.2651.74) npmPackages: @emotion/react: ^11.11.4 => 11.11.4 @emotion/styled: ^11.11.5 => 11.11.5 @mui/base: 5.0.0-beta.40 @mui/core-downloads-tracker: 5.15.17 @mui/icons-material: ^5.15.17 => 5.15.17 @mui/lab: ^5.0.0-alpha.170 => 5.0.0-alpha.170 @mui/material: ^5.15.17 => 5.15.17 @mui/private-theming: 5.16.6 @mui/styled-engine: 5.16.6 @mui/system: 5.16.7 @mui/types: 7.2.15 @mui/utils: 5.16.6 @mui/x-data-grid: 7.3.2 @mui/x-data-grid-pro: ^7.3.2 => 7.3.2 @mui/x-date-pickers: ^7.4.0 => 7.4.0 @mui/x-date-pickers-pro: ^7.4.0 => 7.4.0 @mui/x-license: 7.2.0 @types/react: ^18.2.66 => 18.2.79 react: ^18.2.0 => 18.2.0 react-dom: ^18.2.0 => 18.2.0 typescript: ^5.2.2 => 5.4.5 ```

Search keywords: data grid Order ID: 89766

michelengelen commented 3 months ago

Hey @svidskiy ... here is an example on how to wrap a slot component:

import * as React from 'react';
import { Checkbox, Tooltip } from '@mui/material';
import { useDemoData } from '@mui/x-data-grid-generator';
import { DataGrid, GridSlotProps } from '@mui/x-data-grid';

// augment the props for the toolbar slot
declare module '@mui/x-data-grid' {
  interface BaseCheckboxPropsOverrides {
    tooltip: string;
  }
}

const WrappedCheckbox = (props: GridSlotProps['baseCheckbox']) => {
  const { tooltip, ...rest } = props;
  return (
    <Tooltip title={tooltip}>
      <Checkbox {...rest} />
    </Tooltip>
  );
};

export default function DisableClickSelectionGrid() {
  const { data } = useDemoData({
    dataSet: 'Commodity',
    rowLength: 10,
    maxColumns: 6,
  });

  return (
    <div style={{ height: 400, width: '100%' }}>
      <DataGrid
        checkboxSelection
        disableRowSelectionOnClick
        slots={{ baseCheckbox: WrappedCheckbox }}
        slotProps={{ baseCheckbox: { tooltip: 'This is a checkbox' } }}
        {...data}
      />
    </div>
  );
}

I hope this helps! 👍🏼

svidskiy commented 3 months ago

@michelengelen, thank you for the example, it works. But is it possible to implement the logic I described?

Tooltip for the header checkbox: select all/deselect all Tooltip for the cell checbox: select/deselect

or only with a custom implementation of the checkbox for the header and cell?

I think it would be great if we could change that here like headerCheckbox, cellCheckbox

image

michelengelen commented 3 months ago

It's a bit hacky, but you can use the aria-label from the checkbox props:

import * as React from 'react';
import { Checkbox, Tooltip } from '@mui/material';
import { DataGrid, GRID_CHECKBOX_SELECTION_COL_DEF, GridSlotProps } from '@mui/x-data-grid';

const WrappedCheckbox = (props: GridSlotProps['baseCheckbox']) => {
  return (
    <Tooltip title={props.inputProps?['aria-label'] || ''}>
      <Checkbox {...props} />
    </Tooltip>
  );
};

const columns = [{ field: 'username' }, { field: 'age' }];

const rows = [
  {
    id: 1,
    username: '@john',
    age: 32,
  },
  {
    id: 2,
    username: '@jane',
    age: 19,
  },
  {
    id: 3,
    username: '@james',
    age: 24,
  },
];

export default function DisableClickSelectionGrid() {
  return (
    <div style={{ height: 400, width: '100%' }}>
      <DataGrid
        columns={columns}
        rows={rows}
        checkboxSelection
        disableRowSelectionOnClick
        slots={{ baseCheckbox: WrappedCheckbox }}
      />
    </div>
  );
}
svidskiy commented 3 months ago

Thanks for the idea 👏 It would be great if we could do it ourselves, as we're limited to just this message inside label

michelengelen commented 3 months ago

Thanks for the idea 👏 It would be great if we could do it ourselves, as we're limited to just this message inside label

I'll treat this as a feature request then. 👍🏼