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

[DataGrid] Refactor: create base Checkbox #16445

Merged
merged 12 commits into from
Feb 11, 2025
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,9 @@ const GridCellCheckboxForwardRef = forwardRef<HTMLInputElement, GridRenderCellPa
checked={isChecked && !isIndeterminate}
onChange={handleChange}
className={classes.root}
inputProps={{ 'aria-label': label, name: 'select_row' }}
slotProps={{
htmlInput: { 'aria-label': label, name: 'select_row' },
}}
onKeyDown={handleKeyDown}
indeterminate={isIndeterminate}
disabled={!isSelectable}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,9 @@ const GridHeaderCheckbox = forwardRef<HTMLButtonElement, GridColumnHeaderParams>
checked={isChecked && !isIndeterminate}
onChange={handleChange}
className={classes.root}
inputProps={{ 'aria-label': label, name: 'select_all_rows' }}
slotProps={{
htmlInput: { 'aria-label': label, name: 'select_all_rows' },
}}
tabIndex={tabIndex}
onKeyDown={handleKeyDown}
disabled={!isMultipleRowSelectionEnabled(rootProps)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import composeClasses from '@mui/utils/composeClasses';
import FormControlLabel from '@mui/material/FormControlLabel';
import { styled } from '@mui/material/styles';
import { inputBaseClasses } from '@mui/material/InputBase';
import { TextFieldProps } from '../../models/gridBaseSlots';
Expand Down Expand Up @@ -272,21 +271,17 @@ function GridColumnsManagement(props: GridColumnsManagementProps) {
</GridColumnsManagementHeader>
<GridColumnsManagementBody className={classes.root} ownerState={rootProps}>
{currentColumns.map((column) => (
<FormControlLabel
<rootProps.slots.baseCheckbox
key={column.field}
className={classes.row}
control={
<rootProps.slots.baseCheckbox
disabled={column.hideable === false}
checked={columnVisibilityModel[column.field] !== false}
onClick={toggleColumn}
name={column.field}
sx={{ p: 0.5 }}
inputRef={isFirstHideableColumn(column) ? firstSwitchRef : undefined}
{...rootProps.slotProps?.baseCheckbox}
/>
}
disabled={column.hideable === false}
checked={columnVisibilityModel[column.field] !== false}
onClick={toggleColumn}
name={column.field}
inputRef={isFirstHideableColumn(column) ? firstSwitchRef : undefined}
label={column.headerName || column.field}
size='medium'
{...rootProps.slotProps?.baseCheckbox}
/>
))}
{currentColumns.length === 0 && (
Expand All @@ -298,19 +293,14 @@ function GridColumnsManagement(props: GridColumnsManagementProps) {
{(!disableShowHideToggle || !disableResetButton) && currentColumns.length > 0 ? (
<GridColumnsManagementFooter ownerState={rootProps} className={classes.footer}>
{!disableShowHideToggle ? (
<FormControlLabel
control={
<rootProps.slots.baseCheckbox
disabled={hideableColumns.length === 0}
checked={allHideableColumnsVisible}
indeterminate={!allHideableColumnsVisible && !allHideableColumnsHidden}
onClick={() => toggleAllColumns(!allHideableColumnsVisible)}
name={apiRef.current.getLocaleText('columnsManagementShowHideAllText')}
sx={{ p: 0.5 }}
{...rootProps.slotProps?.baseCheckbox}
/>
}
<rootProps.slots.baseCheckbox
disabled={hideableColumns.length === 0}
checked={allHideableColumnsVisible}
indeterminate={!allHideableColumnsVisible && !allHideableColumnsHidden}
onClick={() => toggleAllColumns(!allHideableColumnsVisible)}
name={apiRef.current.getLocaleText('columnsManagementShowHideAllText')}
label={apiRef.current.getLocaleText('columnsManagementShowHideAllText')}
{...rootProps.slotProps?.baseCheckbox}
/>
) : (
<span />
Expand Down
17 changes: 16 additions & 1 deletion packages/x-data-grid/src/material/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import MUIMenuList from '@mui/material/MenuList';
import MUIMenuItem from '@mui/material/MenuItem';
import MUITextField from '@mui/material/TextField';
import MUIFormControl from '@mui/material/FormControl';
import MUIFormControlLabel from '@mui/material/FormControlLabel';
import MUISelect from '@mui/material/Select';
import MUIButton from '@mui/material/Button';
import MUIIconButton from '@mui/material/IconButton';
Expand Down Expand Up @@ -93,7 +94,7 @@ const iconSlots: GridIconSlotsComponent = {

const baseSlots: GridBaseSlots = {
baseBadge: MUIBadge,
baseCheckbox: MUICheckbox,
baseCheckbox: BaseCheckbox,
baseCircularProgress: MUICircularProgress,
baseDivider: MUIDivider,
baseLinearProgress: MUILinearProgress,
Expand All @@ -120,6 +121,20 @@ const materialSlots: GridBaseSlots & GridIconSlotsComponent = {

export default materialSlots;

function BaseCheckbox(props: GridSlotProps['baseCheckbox']) {
const { label, slotProps, className, ...other } = props;
if (!label) {
return <MUICheckbox {...other} className={className} inputProps={slotProps?.htmlInput} />;
}
return (
<MUIFormControlLabel
className={className}
control={<MUICheckbox {...other} inputProps={slotProps?.htmlInput} />}
label={label}
/>
);
}

function BaseMenuList(props: GridSlotProps['baseMenuList']) {
return <MUIMenuList {...props} />;
}
Expand Down
22 changes: 22 additions & 0 deletions packages/x-data-grid/src/models/gridBaseSlots.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,28 @@ export type ButtonProps = {
touchRippleRef?: any; // FIXME(v8:romgrk): find a way to remove
};

export type CheckboxProps = {
ref?: Ref<HTMLButtonElement>;
id?: string;
checked?: boolean;
className?: string;
disabled?: boolean;
indeterminate?: boolean;
inputRef?: React.Ref<HTMLInputElement>;
name?: string;
label?: React.ReactNode;
onClick?: React.MouseEventHandler;
onChange?: React.ChangeEventHandler;
onKeyDown?: React.KeyboardEventHandler;
size?: 'small' | 'medium';
slotProps?: {
htmlInput?: React.InputHTMLAttributes<HTMLInputElement>;
};
style?: React.CSSProperties;
tabIndex?: number;
touchRippleRef?: any; // FIXME(v8:romgrk): find a way to remove
romgrk marked this conversation as resolved.
Show resolved Hide resolved
};

export type IconButtonProps = Omit<ButtonProps, 'startIcon'> & {
label?: string;
color?: 'default' | 'inherit' | 'primary';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import * as React from 'react';
import type { BadgeProps as MUIBadgeProps } from '@mui/material/Badge';
import type { ButtonProps as MUIButtonProps } from '@mui/material/Button';
import type { CheckboxProps } from '@mui/material/Checkbox';
import type { CircularProgressProps as MUICircularProgressProps } from '@mui/material/CircularProgress';
import type { LinearProgressProps as MUILinearProgressProps } from '@mui/material/LinearProgress';
import type { MenuItemProps as MUIMenuItemProps } from '@mui/material/MenuItem';
Expand Down Expand Up @@ -36,6 +35,7 @@ import type { GridColumnHeaderSortIconProps } from '../components/columnHeaders/
import type {
BadgeProps,
ButtonProps,
CheckboxProps,
CircularProgressProps,
DividerProps,
IconButtonProps,
Expand Down