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] Add slot typings #11795

Merged
merged 17 commits into from
Feb 5, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/data/data-grid/components/CustomColumnMenu.tsx
romgrk marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
GridColumnMenuSortItem,
useGridApiRef,
DataGridPro,
GridSlots,
} from '@mui/x-data-grid-pro';
import StarOutlineIcon from '@mui/icons-material/StarOutline';

Expand Down Expand Up @@ -119,7 +120,7 @@ export default function CustomColumnMenu() {
},
]}
slots={{
columnMenu: CustomColumnMenuComponent,
columnMenu: CustomColumnMenuComponent as GridSlots['columnMenu'],
}}
slotProps={{
columnMenu: { color },
Expand Down
4 changes: 2 additions & 2 deletions docs/data/data-grid/components/CustomLoadingOverlayGrid.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from 'react';
import { DataGrid } from '@mui/x-data-grid';
import { DataGrid, GridSlots } from '@mui/x-data-grid';
import LinearProgress from '@mui/material/LinearProgress';
import { useDemoData } from '@mui/x-data-grid-generator';

Expand All @@ -14,7 +14,7 @@ export default function CustomLoadingOverlayGrid() {
<div style={{ height: 400, width: '100%' }}>
<DataGrid
slots={{
loadingOverlay: LinearProgress,
loadingOverlay: LinearProgress as GridSlots['loadingOverlay'],
}}
loading
{...data}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<DataGrid
slots={{
loadingOverlay: LinearProgress,
loadingOverlay: LinearProgress as GridSlots['loadingOverlay'],
}}
loading
{...data}
Expand Down
3 changes: 2 additions & 1 deletion docs/data/data-grid/editing/FullFeaturedCrudGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
GridRowId,
GridRowModel,
GridRowEditStopReasons,
GridSlots,
} from '@mui/x-data-grid';
import {
randomCreatedDate,
Expand Down Expand Up @@ -237,7 +238,7 @@ export default function FullFeaturedCrudGrid() {
onRowEditStop={handleRowEditStop}
processRowUpdate={processRowUpdate}
slots={{
toolbar: EditToolbar,
toolbar: EditToolbar as GridSlots['toolbar'],
}}
slotProps={{
toolbar: { setRows, setRowModesModel },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
onRowEditStop={handleRowEditStop}
processRowUpdate={processRowUpdate}
slots={{
toolbar: EditToolbar,
toolbar: EditToolbar as GridSlots['toolbar'],
}}
slotProps={{
toolbar: { setRows, setRowModesModel },
Expand Down
3 changes: 2 additions & 1 deletion docs/data/data-grid/editing/StartEditButtonGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
GridCellModes,
GridEventListener,
GridCellModesModel,
GridSlots,
} from '@mui/x-data-grid';
import {
randomCreatedDate,
Expand Down Expand Up @@ -147,7 +148,7 @@ export default function StartEditButtonGrid() {
onCellEditStop={handleCellEditStop}
onCellModesModelChange={(model) => setCellModesModel(model)}
slots={{
toolbar: EditToolbar,
toolbar: EditToolbar as GridSlots['toolbar'],
}}
slotProps={{
toolbar: {
Expand Down
3 changes: 2 additions & 1 deletion docs/data/data-grid/filtering/CustomFilterPanelPosition.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as React from 'react';
import {
DataGrid,
GridSlots,
GridToolbarContainer,
GridToolbarFilterButton,
} from '@mui/x-data-grid';
Expand Down Expand Up @@ -35,7 +36,7 @@ export default function CustomFilterPanelPosition() {
<DataGrid
{...data}
slots={{
toolbar: CustomToolbar,
toolbar: CustomToolbar as GridSlots['toolbar'],
}}
slotProps={{
panel: {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<DataGrid
{...data}
slots={{
toolbar: CustomToolbar,
toolbar: CustomToolbar as GridSlots['toolbar'],
}}
slotProps={{
panel: {
Expand Down
4 changes: 2 additions & 2 deletions docs/data/data-grid/row-updates/InfiniteLoadingGrid.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from 'react';
import { DataGridPro, DataGridProProps } from '@mui/x-data-grid-pro';
import { DataGridPro, DataGridProProps, GridSlots } from '@mui/x-data-grid-pro';
import {
useDemoData,
getRealGridData,
Expand Down Expand Up @@ -61,7 +61,7 @@ export default function InfiniteLoadingGrid() {
hideFooterPagination
onRowsScrollEnd={handleOnRowsScrollEnd}
slots={{
loadingOverlay: LinearProgress,
loadingOverlay: LinearProgress as GridSlots['loadingOverlay'],
}}
/>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@
hideFooterPagination
onRowsScrollEnd={handleOnRowsScrollEnd}
slots={{
loadingOverlay: LinearProgress,
loadingOverlay: LinearProgress as GridSlots['loadingOverlay'],
}}
/>
3 changes: 2 additions & 1 deletion docs/data/data-grid/state/RestoreStateInitialState.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Stack from '@mui/material/Stack';
import {
DataGridPro,
GridInitialState,
GridSlots,
GridToolbarContainer,
GridToolbarDensitySelector,
GridToolbarFilterButton,
Expand Down Expand Up @@ -62,7 +63,7 @@ export default function RestoreStateInitialState() {
<DataGridPro
{...data}
loading={loading}
slots={{ toolbar: GridCustomToolbar }}
slots={{ toolbar: GridCustomToolbar as GridSlots['toolbar'] }}
slotProps={{ toolbar: { syncState } }}
/>
</Box>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<DataGridPro
{...data}
loading={loading}
slots={{ toolbar: GridCustomToolbar }}
slots={{ toolbar: GridCustomToolbar as GridSlots['toolbar'] }}
slotProps={{ toolbar: { syncState } }}
/>
</Box>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import {
import { useDataGridPremiumProps } from './useDataGridPremiumProps';
import { getReleaseInfo } from '../utils/releaseInfo';

export type { GridPremiumSlotsComponent as GridSlots } from '../models';

const releaseInfo = getReleaseInfo();

const dataGridPremiumPropValidators: PropValidator<DataGridPremiumProcessedProps>[] = [
Expand Down
2 changes: 2 additions & 0 deletions packages/grid/x-data-grid-pro/src/DataGridPro/DataGridPro.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import { useDataGridProProps } from './useDataGridProProps';
import { getReleaseInfo } from '../utils/releaseInfo';
import { propValidatorsDataGridPro } from '../internals/propValidation';

export type { GridProSlotsComponent as GridSlots } from '../models';

const releaseInfo = getReleaseInfo();

const DataGridProRaw = React.forwardRef(function DataGridPro<R extends GridValidRowModel>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,16 @@ function GridHeaderFilterMenuContainer(props: {
return null;
}

const label = apiRef.current.getLocaleText('filterPanelOperator');
const labelString = label ? String(label) : undefined;

return (
<React.Fragment>
<rootProps.slots.baseIconButton
id={buttonId}
ref={buttonRef}
aria-label={apiRef.current.getLocaleText('filterPanelOperator')}
title={apiRef.current.getLocaleText('filterPanelOperator')}
aria-label={labelString}
title={labelString}
aria-controls={menuId}
aria-expanded={open ? 'true' : undefined}
aria-haspopup="true"
Expand Down
2 changes: 2 additions & 0 deletions packages/grid/x-data-grid/src/DataGrid/DataGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import {
validateProps,
} from '../internals/utils/propValidation';

export type { GridSlotsComponent as GridSlots } from '../models';

const propValidators: PropValidator<DataGridProcessedProps>[] = [
...propValidatorsDataGrid,
// Only validate in MIT version
Expand Down
75 changes: 40 additions & 35 deletions packages/grid/x-data-grid/src/components/GridFooter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,45 +9,50 @@ import { GridSelectedRowCount } from './GridSelectedRowCount';
import { GridFooterContainer, GridFooterContainerProps } from './containers/GridFooterContainer';
import { useGridRootProps } from '../hooks/utils/useGridRootProps';

const GridFooter = React.forwardRef<HTMLDivElement, GridFooterContainerProps>(
function GridFooter(props, ref) {
const apiRef = useGridApiContext();
const rootProps = useGridRootProps();
const totalTopLevelRowCount = useGridSelector(apiRef, gridTopLevelRowCountSelector);
const selectedRowCount = useGridSelector(apiRef, selectedGridRowsCountSelector);
const visibleTopLevelRowCount = useGridSelector(apiRef, gridFilteredTopLevelRowCountSelector);
const GridFooter = React.forwardRef<HTMLDivElement, GridFooterContainerProps>(function GridFooter(
props,
ref,
) {
const apiRef = useGridApiContext();
const rootProps = useGridRootProps();
const totalTopLevelRowCount = useGridSelector(apiRef, gridTopLevelRowCountSelector);
const selectedRowCount = useGridSelector(apiRef, selectedGridRowsCountSelector);
const visibleTopLevelRowCount = useGridSelector(apiRef, gridFilteredTopLevelRowCountSelector);

const selectedRowCountElement =
!rootProps.hideFooterSelectedRowCount && selectedRowCount > 0 ? (
<GridSelectedRowCount selectedRowCount={selectedRowCount} />
) : (
<div />
);

const rowCountElement =
!rootProps.hideFooterRowCount && !rootProps.pagination ? (
<rootProps.slots.footerRowCount
{...rootProps.slotProps?.footerRowCount}
rowCount={totalTopLevelRowCount}
visibleRowCount={visibleTopLevelRowCount}
/>
) : null;
const selectedRowCountElement =
!rootProps.hideFooterSelectedRowCount && selectedRowCount > 0 ? (
<GridSelectedRowCount selectedRowCount={selectedRowCount} />
) : (
<div />
);

const paginationElement = rootProps.pagination &&
!rootProps.hideFooterPagination &&
rootProps.slots.pagination && (
<rootProps.slots.pagination {...rootProps.slotProps?.pagination} />
);
const rowCountElement =
!rootProps.hideFooterRowCount && !rootProps.pagination ? (
<rootProps.slots.footerRowCount
{...rootProps.slotProps?.footerRowCount}
rowCount={totalTopLevelRowCount}
visibleRowCount={visibleTopLevelRowCount}
/>
) : null;

return (
<GridFooterContainer ref={ref} {...props}>
{selectedRowCountElement}
{rowCountElement}
{paginationElement}
</GridFooterContainer>
const paginationElement = rootProps.pagination &&
!rootProps.hideFooterPagination &&
rootProps.slots.pagination && (
<rootProps.slots.pagination
{
...(rootProps.slotProps?.pagination as any) /* FIXME: typing error */
}
/>
);
},
);

return (
<GridFooterContainer ref={ref} {...props}>
{selectedRowCountElement}
{rowCountElement}
{paginationElement}
</GridFooterContainer>
);
});

GridFooter.propTypes = {
// ----------------------------- Warning --------------------------------
Expand Down
8 changes: 4 additions & 4 deletions packages/grid/x-data-grid/src/components/GridRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -211,9 +211,9 @@ const GridRow = React.forwardRef<HTMLDivElement, GridRowProps>(function GridRow(

const publish = React.useCallback(
(
eventName: keyof GridRowEventLookup,
propHandler: React.MouseEventHandler<HTMLDivElement> | undefined,
): React.MouseEventHandler<HTMLDivElement> =>
eventName: keyof GridRowEventLookup,
propHandler: React.MouseEventHandler<HTMLDivElement> | undefined,
): React.MouseEventHandler<HTMLDivElement> =>
(event) => {
// Ignore portal
if (isEventTargetInPortal(event)) {
Expand Down Expand Up @@ -389,7 +389,7 @@ const GridRow = React.forwardRef<HTMLDivElement, GridRowProps>(function GridRow(
width={width}
contentWidth={contentWidth}
field={column.field}
align={column.align}
align={column.align ?? 'left'}
/>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,7 @@ export function GridFooterPlaceholder() {
return null;
}

return <rootProps.slots.footer {...rootProps.slotProps?.footer} />;
return (
<rootProps.slots.footer {...(rootProps.slotProps?.footer as any) /* FIXME: typing error */} />
Copy link
Member

Choose a reason for hiding this comment

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

This one is interesting.
The reason it's failing without as any is this override in the docs examples:

declare module '@mui/x-data-grid' {
interface FooterPropsOverrides {
status: FooterStatus;
}
}

I there something we can do to isolate overrides in docs from the packages?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The way it's setup, the docs is importing the grid through relative imports (behind aliased paths). If the docs were importing code as regular packages, then the skipLibCheck flag would do that iiuc, but it doesn't apply here since it's just regular files. I think it could probably be done, but I'm not sure how long it will take to setup, so I'd skip it for this PR.

);
}
Original file line number Diff line number Diff line change
Expand Up @@ -96,15 +96,15 @@ const GridCellCheckboxForwardRef = React.forwardRef<HTMLInputElement, GridRender

return (
<rootProps.slots.baseCheckbox
ref={handleRef}
ref={handleRef as any /* FIXME: typing error */}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I fixed the straightfoward typing errors, but left FIXME comments for the ones that I couldn't find an easy answer to (mainly because the typings are in MUI core's codebase, so they're harder to fix). For the baseCheckbox refs, the error is often a type mismatch between HTMLInputElement vs HTMLButtonElement which seemed harmless.

tabIndex={tabIndex}
checked={isChecked}
onChange={handleChange}
className={classes.root}
inputProps={{ 'aria-label': label }}
onKeyDown={handleKeyDown}
disabled={!isSelectable}
touchRippleRef={rippleRef}
touchRippleRef={rippleRef as any /* FIXME: typing error */}
{...rootProps.slotProps?.baseCheckbox}
{...other}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ const GridHeaderCheckbox = React.forwardRef<HTMLInputElement, GridColumnHeaderPa

return (
<rootProps.slots.baseCheckbox
ref={ref}
ref={ref as any /* FIXME: typing error */}
indeterminate={isIndeterminate}
checked={isChecked}
onChange={handleChange}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ const GridFilterForm = React.forwardRef<HTMLDivElement, GridFilterFormProps>(
}, [item, currentColumn]);

const changeColumn = React.useCallback(
(event: SelectChangeEvent) => {
(event: SelectChangeEvent<any>) => {
const field = event.target.value as string;
const column = apiRef.current.getColumn(field)!;

Expand Down Expand Up @@ -369,7 +369,7 @@ const GridFilterForm = React.forwardRef<HTMLDivElement, GridFilterFormProps>(
);

const changeOperator = React.useCallback(
(event: SelectChangeEvent) => {
(event: SelectChangeEvent<any>) => {
const operator = event.target.value as string;

const newOperator = currentColumn?.filterOperators!.find((op) => op.value === operator);
Expand All @@ -388,7 +388,7 @@ const GridFilterForm = React.forwardRef<HTMLDivElement, GridFilterFormProps>(
);

const changeLogicOperator = React.useCallback(
(event: SelectChangeEvent) => {
(event: SelectChangeEvent<any>) => {
const logicOperator =
(event.target.value as string) === GridLogicOperator.And.toString()
? GridLogicOperator.And
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,14 @@ function GridFilterInputBoolean(props: GridFilterInputBooleanProps) {
id={selectId}
label={label}
value={filterValueState}
onChange={onFilterChange}
onChange={onFilterChange as any /* FIXME: typing error */}
variant="standard"
native={isSelectNative}
displayEmpty
inputProps={{ ref: focusElementRef, tabIndex }}
{...others}
{
...(others as any) /* FIXME: typing error */
}
{...baseSelectProps}
>
<rootProps.slots.baseSelectOption
Expand Down
Loading
Loading