wip:milestone 0 fixes
Some checks failed
CI/CD Pipeline / unit-tests (push) Failing after 1m16s
CI/CD Pipeline / integration-tests (push) Failing after 2m32s
CI/CD Pipeline / lint (push) Successful in 5m22s
CI/CD Pipeline / e2e-tests (push) Has been skipped
CI/CD Pipeline / build (push) Has been skipped

This commit is contained in:
2026-03-15 12:35:42 +02:00
parent 6708cf28a7
commit cffdf8af86
61266 changed files with 4511646 additions and 1938 deletions

View File

@@ -0,0 +1,687 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import * as React from 'react';
import PropTypes from 'prop-types';
import { chainPropTypes } from '@mui/utils';
import { GridBody, GridFooterPlaceholder, GridHeader, GridRoot } from '../components';
import { GridContextProvider } from '../context/GridContextProvider';
import { useDataGridComponent } from './useDataGridComponent';
import { useDataGridProps, DATA_GRID_PROPS_DEFAULT_VALUES } from './useDataGridProps';
import { DataGridVirtualScroller } from '../components/DataGridVirtualScroller';
import { jsx as _jsx } from "react/jsx-runtime";
import { jsxs as _jsxs } from "react/jsx-runtime";
const DataGridRaw = /*#__PURE__*/React.forwardRef(function DataGrid(inProps, ref) {
const props = useDataGridProps(inProps);
const privateApiRef = useDataGridComponent(props.apiRef, props);
return /*#__PURE__*/_jsx(GridContextProvider, {
privateApiRef: privateApiRef,
props: props,
children: /*#__PURE__*/_jsxs(GridRoot, _extends({
className: props.className,
style: props.style,
sx: props.sx,
ref: ref
}, props.forwardedProps, {
children: [/*#__PURE__*/_jsx(GridHeader, {}), /*#__PURE__*/_jsx(GridBody, {
VirtualScrollerComponent: DataGridVirtualScroller
}), /*#__PURE__*/_jsx(GridFooterPlaceholder, {})]
}))
});
});
/**
* Demos:
* - [DataGrid](https://mui.com/x/react-data-grid/demo/)
*
* API:
* - [DataGrid API](https://mui.com/x/api/data-grid/data-grid/)
*/
export const DataGrid = /*#__PURE__*/React.memo(DataGridRaw);
/**
* Remove at v7
* @deprecated
*/
export const SUBMIT_FILTER_STROKE_TIME = DATA_GRID_PROPS_DEFAULT_VALUES.filterDebounceMs;
/**
* Remove at v7
* @deprecated
*/
export const SUBMIT_FILTER_DATE_STROKE_TIME = DATA_GRID_PROPS_DEFAULT_VALUES.filterDebounceMs;
DataGridRaw.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
/**
* The ref object that allows Data Grid manipulation. Can be instantiated with `useGridApiRef()`.
*/
apiRef: PropTypes.shape({
current: PropTypes.object.isRequired
}),
/**
* The label of the Data Grid.
*/
'aria-label': PropTypes.string,
/**
* The id of the element containing a label for the Data Grid.
*/
'aria-labelledby': PropTypes.string,
/**
* If `true`, the Data Grid height is dynamic and follow the number of rows in the Data Grid.
* @default false
*/
autoHeight: PropTypes.bool,
/**
* If `true`, the pageSize is calculated according to the container size and the max number of rows to avoid rendering a vertical scroll bar.
* @default false
*/
autoPageSize: PropTypes.bool,
/**
* Controls the modes of the cells.
*/
cellModesModel: PropTypes.object,
/**
* If `true`, the Data Grid will display an extra column with checkboxes for selecting rows.
* @default false
*/
checkboxSelection: PropTypes.bool,
/**
* Override or extend the styles applied to the component.
*/
classes: PropTypes.object,
/**
* The character used to separate cell values when copying to the clipboard.
* @default '\t'
*/
clipboardCopyCellDelimiter: PropTypes.string,
/**
* Number of extra columns to be rendered before/after the visible slice.
* @default 3
*/
columnBuffer: PropTypes.number,
columnGroupingModel: PropTypes.arrayOf(PropTypes.object),
/**
* Sets the height in pixel of the column headers in the Data Grid.
* @default 56
*/
columnHeaderHeight: PropTypes.number,
/**
* Set of columns of type [[GridColDef[]]].
*/
columns: chainPropTypes(PropTypes.array.isRequired, props => {
// @ts-ignore because otherwise `build:api` doesn't work
if (props.columns && props.columns.some(column => column.resizable)) {
return new Error([`MUI: \`column.resizable = true\` is not a valid prop.`, 'Column resizing is not available in the MIT version.', '', 'You need to upgrade to DataGridPro or DataGridPremium component to unlock this feature.'].join('\n'));
}
return null;
}),
/**
* Number of rows from the `columnBuffer` that can be visible before a new slice is rendered.
* @default 3
*/
columnThreshold: PropTypes.number,
/**
* Set the column visibility model of the Data Grid.
* If defined, the Data Grid will ignore the `hide` property in [[GridColDef]].
*/
columnVisibilityModel: PropTypes.object,
/**
* Overridable components.
* @deprecated Use `slots` instead.
*/
components: PropTypes.object,
/**
* Overridable components props dynamically passed to the component at rendering.
* @deprecated Use the `slotProps` prop instead.
*/
componentsProps: PropTypes.object,
/**
* Set the density of the Data Grid.
* @default "standard"
*/
density: PropTypes.oneOf(['comfortable', 'compact', 'standard']),
/**
* If `true`, column filters are disabled.
* @default false
*/
disableColumnFilter: PropTypes.bool,
/**
* If `true`, the column menu is disabled.
* @default false
*/
disableColumnMenu: PropTypes.bool,
/**
* If `true`, hiding/showing columns is disabled.
* @default false
*/
disableColumnSelector: PropTypes.bool,
/**
* If `true`, the density selector is disabled.
* @default false
*/
disableDensitySelector: PropTypes.bool,
/**
* If `true`, `eval()` is not used for performance optimization.
* @default false
*/
disableEval: PropTypes.bool,
/**
* If `true`, the selection on click on a row or cell is disabled.
* @default false
*/
disableRowSelectionOnClick: PropTypes.bool,
/**
* If `true`, the virtualization is disabled.
* @default false
*/
disableVirtualization: PropTypes.bool,
/**
* Controls whether to use the cell or row editing.
* @default "cell"
*/
editMode: PropTypes.oneOf(['cell', 'row']),
/**
* Unstable features, breaking changes might be introduced.
* For each feature, if the flag is not explicitly set to `true`, the feature will be fully disabled and any property / method call will not have any effect.
*/
experimentalFeatures: PropTypes.shape({
ariaV7: PropTypes.bool,
columnGrouping: PropTypes.bool,
warnIfFocusStateIsNotSynced: PropTypes.bool
}),
/**
* The milliseconds delay to wait after a keystroke before triggering filtering.
* @default 150
*/
filterDebounceMs: PropTypes.number,
/**
* Filtering can be processed on the server or client-side.
* Set it to 'server' if you would like to handle filtering on the server-side.
* @default "client"
*/
filterMode: PropTypes.oneOf(['client', 'server']),
/**
* Set the filter model of the Data Grid.
*/
filterModel: PropTypes.shape({
items: PropTypes.arrayOf(PropTypes.shape({
field: PropTypes.string.isRequired,
id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
operator: PropTypes.string.isRequired,
value: PropTypes.any
})).isRequired,
logicOperator: PropTypes.oneOf(['and', 'or']),
quickFilterExcludeHiddenColumns: PropTypes.bool,
quickFilterLogicOperator: PropTypes.oneOf(['and', 'or']),
quickFilterValues: PropTypes.array
}),
/**
* Forwarded props for the Data Grid root element.
* @ignore - do not document.
*/
forwardedProps: PropTypes.object,
/**
* Function that applies CSS classes dynamically on cells.
* @param {GridCellParams} params With all properties from [[GridCellParams]].
* @returns {string} The CSS class to apply to the cell.
*/
getCellClassName: PropTypes.func,
/**
* Function that returns the element to render in row detail.
* @param {GridRowParams} params With all properties from [[GridRowParams]].
* @returns {React.JSX.Element} The row detail element.
*/
getDetailPanelContent: PropTypes.func,
/**
* Function that returns the estimated height for a row.
* Only works if dynamic row height is used.
* Once the row height is measured this value is discarded.
* @param {GridRowHeightParams} params With all properties from [[GridRowHeightParams]].
* @returns {number | null} The estimated row height value. If `null` or `undefined` then the default row height, based on the density, is applied.
*/
getEstimatedRowHeight: PropTypes.func,
/**
* Function that applies CSS classes dynamically on rows.
* @param {GridRowClassNameParams} params With all properties from [[GridRowClassNameParams]].
* @returns {string} The CSS class to apply to the row.
*/
getRowClassName: PropTypes.func,
/**
* Function that sets the row height per row.
* @param {GridRowHeightParams} params With all properties from [[GridRowHeightParams]].
* @returns {GridRowHeightReturnValue} The row height value. If `null` or `undefined` then the default row height is applied. If "auto" then the row height is calculated based on the content.
*/
getRowHeight: PropTypes.func,
/**
* Return the id of a given [[GridRowModel]].
*/
getRowId: PropTypes.func,
/**
* Function that allows to specify the spacing between rows.
* @param {GridRowSpacingParams} params With all properties from [[GridRowSpacingParams]].
* @returns {GridRowSpacing} The row spacing values.
*/
getRowSpacing: PropTypes.func,
/**
* If `true`, the footer component is hidden.
* @default false
*/
hideFooter: PropTypes.bool,
/**
* If `true`, the pagination component in the footer is hidden.
* @default false
*/
hideFooterPagination: PropTypes.bool,
/**
* If `true`, the selected row count in the footer is hidden.
* @default false
*/
hideFooterSelectedRowCount: PropTypes.bool,
/**
* If `true`, the diacritics (accents) are ignored when filtering or quick filtering.
* E.g. when filter value is `cafe`, the rows with `café` will be visible.
* @default false
*/
ignoreDiacritics: PropTypes.bool,
/**
* The initial state of the DataGrid.
* The data in it will be set in the state on initialization but will not be controlled.
* If one of the data in `initialState` is also being controlled, then the control state wins.
*/
initialState: PropTypes.object,
/**
* Callback fired when a cell is rendered, returns true if the cell is editable.
* @param {GridCellParams} params With all properties from [[GridCellParams]].
* @returns {boolean} A boolean indicating if the cell is editable.
*/
isCellEditable: PropTypes.func,
/**
* Determines if a row can be selected.
* @param {GridRowParams} params With all properties from [[GridRowParams]].
* @returns {boolean} A boolean indicating if the cell is selectable.
*/
isRowSelectable: PropTypes.func,
/**
* If `true`, the selection model will retain selected rows that do not exist.
* Useful when using server side pagination and row selections need to be retained
* when changing pages.
* @default false
*/
keepNonExistentRowsSelected: PropTypes.bool,
/**
* If `true`, a loading overlay is displayed.
*/
loading: PropTypes.bool,
/**
* Set the locale text of the Data Grid.
* You can find all the translation keys supported in [the source](https://github.com/mui/mui-x/blob/v6.19.4/packages/grid/x-data-grid/src/constants/localeTextConstants.ts) in the GitHub repository.
*/
localeText: PropTypes.object,
/**
* Pass a custom logger in the components that implements the [[Logger]] interface.
* @default console
*/
logger: PropTypes.shape({
debug: PropTypes.func.isRequired,
error: PropTypes.func.isRequired,
info: PropTypes.func.isRequired,
warn: PropTypes.func.isRequired
}),
/**
* Allows to pass the logging level or false to turn off logging.
* @default "error" ("warn" in dev mode)
*/
logLevel: PropTypes.oneOf(['debug', 'error', 'info', 'warn', false]),
/**
* Nonce of the inline styles for [Content Security Policy](https://www.w3.org/TR/2016/REC-CSP2-20161215/#script-src-the-nonce-attribute).
*/
nonce: PropTypes.string,
/**
* Callback fired when any cell is clicked.
* @param {GridCellParams} params With all properties from [[GridCellParams]].
* @param {MuiEvent<React.MouseEvent>} event The event object.
* @param {GridCallbackDetails} details Additional details for this callback.
*/
onCellClick: PropTypes.func,
/**
* Callback fired when a double click event comes from a cell element.
* @param {GridCellParams} params With all properties from [[GridCellParams]].
* @param {MuiEvent<React.MouseEvent>} event The event object.
* @param {GridCallbackDetails} details Additional details for this callback.
*/
onCellDoubleClick: PropTypes.func,
/**
* Callback fired when the cell turns to edit mode.
* @param {GridCellParams} params With all properties from [[GridCellParams]].
* @param {MuiEvent<React.KeyboardEvent | React.MouseEvent>} event The event that caused this prop to be called.
*/
onCellEditStart: PropTypes.func,
/**
* Callback fired when the cell turns to view mode.
* @param {GridCellParams} params With all properties from [[GridCellParams]].
* @param {MuiEvent<MuiBaseEvent>} event The event that caused this prop to be called.
*/
onCellEditStop: PropTypes.func,
/**
* Callback fired when a keydown event comes from a cell element.
* @param {GridCellParams} params With all properties from [[GridCellParams]].
* @param {MuiEvent<React.KeyboardEvent>} event The event object.
* @param {GridCallbackDetails} details Additional details for this callback.
*/
onCellKeyDown: PropTypes.func,
/**
* Callback fired when the `cellModesModel` prop changes.
* @param {GridCellModesModel} cellModesModel Object containing which cells are in "edit" mode.
* @param {GridCallbackDetails} details Additional details for this callback.
*/
onCellModesModelChange: PropTypes.func,
/**
* Callback called when the data is copied to the clipboard.
* @param {string} data The data copied to the clipboard.
*/
onClipboardCopy: PropTypes.func,
/**
* Callback fired when a click event comes from a column header element.
* @param {GridColumnHeaderParams} params With all properties from [[GridColumnHeaderParams]].
* @param {MuiEvent<React.MouseEvent>} event The event object.
* @param {GridCallbackDetails} details Additional details for this callback.
*/
onColumnHeaderClick: PropTypes.func,
/**
* Callback fired when a double click event comes from a column header element.
* @param {GridColumnHeaderParams} params With all properties from [[GridColumnHeaderParams]].
* @param {MuiEvent<React.MouseEvent>} event The event object.
* @param {GridCallbackDetails} details Additional details for this callback.
*/
onColumnHeaderDoubleClick: PropTypes.func,
/**
* Callback fired when a mouse enter event comes from a column header element.
* @param {GridColumnHeaderParams} params With all properties from [[GridColumnHeaderParams]].
* @param {MuiEvent<React.MouseEvent>} event The event object.
* @param {GridCallbackDetails} details Additional details for this callback.
*/
onColumnHeaderEnter: PropTypes.func,
/**
* Callback fired when a mouse leave event comes from a column header element.
* @param {GridColumnHeaderParams} params With all properties from [[GridColumnHeaderParams]].
* @param {MuiEvent<React.MouseEvent>} event The event object.
* @param {GridCallbackDetails} details Additional details for this callback.
*/
onColumnHeaderLeave: PropTypes.func,
/**
* Callback fired when a mouseout event comes from a column header element.
* @param {GridColumnHeaderParams} params With all properties from [[GridColumnHeaderParams]].
* @param {MuiEvent<React.MouseEvent>} event The event object.
* @param {GridCallbackDetails} details Additional details for this callback.
*/
onColumnHeaderOut: PropTypes.func,
/**
* Callback fired when a mouseover event comes from a column header element.
* @param {GridColumnHeaderParams} params With all properties from [[GridColumnHeaderParams]].
* @param {MuiEvent<React.MouseEvent>} event The event object.
* @param {GridCallbackDetails} details Additional details for this callback.
*/
onColumnHeaderOver: PropTypes.func,
/**
* Callback fired when a column is reordered.
* @param {GridColumnOrderChangeParams} params With all properties from [[GridColumnOrderChangeParams]].
* @param {MuiEvent<{}>} event The event object.
* @param {GridCallbackDetails} details Additional details for this callback.
*/
onColumnOrderChange: PropTypes.func,
/**
* Callback fired when the column visibility model changes.
* @param {GridColumnVisibilityModel} model The new model.
* @param {GridCallbackDetails} details Additional details for this callback.
*/
onColumnVisibilityModelChange: PropTypes.func,
/**
* Callback fired when the Filter model changes before the filters are applied.
* @param {GridFilterModel} model With all properties from [[GridFilterModel]].
* @param {GridCallbackDetails} details Additional details for this callback.
*/
onFilterModelChange: PropTypes.func,
/**
* Callback fired when the menu is closed.
* @param {GridMenuParams} params With all properties from [[GridMenuParams]].
* @param {MuiEvent<{}>} event The event object.
* @param {GridCallbackDetails} details Additional details for this callback.
*/
onMenuClose: PropTypes.func,
/**
* Callback fired when the menu is opened.
* @param {GridMenuParams} params With all properties from [[GridMenuParams]].
* @param {MuiEvent<{}>} event The event object.
* @param {GridCallbackDetails} details Additional details for this callback.
*/
onMenuOpen: PropTypes.func,
/**
* Callback fired when the pagination model has changed.
* @param {GridPaginationModel} model Updated pagination model.
* @param {GridCallbackDetails} details Additional details for this callback.
*/
onPaginationModelChange: PropTypes.func,
/**
* Callback fired when the preferences panel is closed.
* @param {GridPreferencePanelParams} params With all properties from [[GridPreferencePanelParams]].
* @param {MuiEvent<{}>} event The event object.
* @param {GridCallbackDetails} details Additional details for this callback.
*/
onPreferencePanelClose: PropTypes.func,
/**
* Callback fired when the preferences panel is opened.
* @param {GridPreferencePanelParams} params With all properties from [[GridPreferencePanelParams]].
* @param {MuiEvent<{}>} event The event object.
* @param {GridCallbackDetails} details Additional details for this callback.
*/
onPreferencePanelOpen: PropTypes.func,
/**
* Callback called when `processRowUpdate` throws an error or rejects.
* @param {any} error The error thrown.
*/
onProcessRowUpdateError: PropTypes.func,
/**
* Callback fired when the Data Grid is resized.
* @param {ElementSize} containerSize With all properties from [[ElementSize]].
* @param {MuiEvent<{}>} event The event object.
* @param {GridCallbackDetails} details Additional details for this callback.
*/
onResize: PropTypes.func,
/**
* Callback fired when a row is clicked.
* Not called if the target clicked is an interactive element added by the built-in columns.
* @param {GridRowParams} params With all properties from [[GridRowParams]].
* @param {MuiEvent<React.MouseEvent>} event The event object.
* @param {GridCallbackDetails} details Additional details for this callback.
*/
onRowClick: PropTypes.func,
/**
* Callback fired when the row count has changed.
* @param {number} count Updated row count.
*/
onRowCountChange: PropTypes.func,
/**
* Callback fired when a double click event comes from a row container element.
* @param {GridRowParams} params With all properties from [[RowParams]].
* @param {MuiEvent<React.MouseEvent>} event The event object.
* @param {GridCallbackDetails} details Additional details for this callback.
*/
onRowDoubleClick: PropTypes.func,
/**
* Callback fired when the row turns to edit mode.
* @param {GridRowParams} params With all properties from [[GridRowParams]].
* @param {MuiEvent<React.KeyboardEvent | React.MouseEvent>} event The event that caused this prop to be called.
*/
onRowEditStart: PropTypes.func,
/**
* Callback fired when the row turns to view mode.
* @param {GridRowParams} params With all properties from [[GridRowParams]].
* @param {MuiEvent<MuiBaseEvent>} event The event that caused this prop to be called.
*/
onRowEditStop: PropTypes.func,
/**
* Callback fired when the `rowModesModel` prop changes.
* @param {GridRowModesModel} rowModesModel Object containing which rows are in "edit" mode.
* @param {GridCallbackDetails} details Additional details for this callback.
*/
onRowModesModelChange: PropTypes.func,
/**
* Callback fired when the selection state of one or multiple rows changes.
* @param {GridRowSelectionModel} rowSelectionModel With all the row ids [[GridSelectionModel]].
* @param {GridCallbackDetails} details Additional details for this callback.
*/
onRowSelectionModelChange: PropTypes.func,
/**
* Callback fired when the sort model changes before a column is sorted.
* @param {GridSortModel} model With all properties from [[GridSortModel]].
* @param {GridCallbackDetails} details Additional details for this callback.
*/
onSortModelChange: PropTypes.func,
/**
* Callback fired when the state of the Data Grid is updated.
* @param {GridState} state The new state.
* @param {MuiEvent<{}>} event The event object.
* @param {GridCallbackDetails} details Additional details for this callback.
* @ignore - do not document.
*/
onStateChange: PropTypes.func,
/**
* Select the pageSize dynamically using the component UI.
* @default [25, 50, 100]
*/
pageSizeOptions: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.number, PropTypes.shape({
label: PropTypes.string.isRequired,
value: PropTypes.number.isRequired
})]).isRequired),
pagination: props => {
if (props.pagination === false) {
return new Error(['MUI: `<DataGrid pagination={false} />` is not a valid prop.', 'Infinite scrolling is not available in the MIT version.', '', 'You need to upgrade to DataGridPro or DataGridPremium component to disable the pagination.'].join('\n'));
}
return null;
},
/**
* Pagination can be processed on the server or client-side.
* Set it to 'client' if you would like to handle the pagination on the client-side.
* Set it to 'server' if you would like to handle the pagination on the server-side.
* @default "client"
*/
paginationMode: PropTypes.oneOf(['client', 'server']),
/**
* The pagination model of type [[GridPaginationModel]] which refers to current `page` and `pageSize`.
*/
paginationModel: PropTypes.shape({
page: PropTypes.number.isRequired,
pageSize: PropTypes.number.isRequired
}),
/**
* Callback called before updating a row with new values in the row and cell editing.
* @template R
* @param {R} newRow Row object with the new values.
* @param {R} oldRow Row object with the old values.
* @returns {Promise<R> | R} The final values to update the row.
*/
processRowUpdate: PropTypes.func,
/**
* Number of extra rows to be rendered before/after the visible slice.
* @default 3
*/
rowBuffer: PropTypes.number,
/**
* Set the total number of rows, if it is different from the length of the value `rows` prop.
* If some rows have children (for instance in the tree data), this number represents the amount of top level rows.
*/
rowCount: PropTypes.number,
/**
* Sets the height in pixel of a row in the Data Grid.
* @default 52
*/
rowHeight: PropTypes.number,
/**
* Controls the modes of the rows.
*/
rowModesModel: PropTypes.object,
/**
* The milliseconds delay to wait after measuring the row height before recalculating row positions.
* Setting it to a lower value could be useful when using dynamic row height,
* but might reduce performance when displaying a large number of rows.
* @default 166
*/
rowPositionsDebounceMs: PropTypes.number,
/**
* Set of rows of type [[GridRowsProp]].
*/
rows: PropTypes.arrayOf(PropTypes.object).isRequired,
/**
* If `false`, the row selection mode is disabled.
* @default true
*/
rowSelection: PropTypes.bool,
/**
* Sets the row selection model of the Data Grid.
*/
rowSelectionModel: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired), PropTypes.number, PropTypes.string]),
/**
* Sets the type of space between rows added by `getRowSpacing`.
* @default "margin"
*/
rowSpacingType: PropTypes.oneOf(['border', 'margin']),
/**
* Number of rows from the `rowBuffer` that can be visible before a new slice is rendered.
* @default 3
*/
rowThreshold: PropTypes.number,
/**
* Override the height/width of the Data Grid inner scrollbar.
*/
scrollbarSize: PropTypes.number,
/**
* If `true`, the vertical borders of the cells are displayed.
* @default false
*/
showCellVerticalBorder: PropTypes.bool,
/**
* If `true`, the right border of the column headers are displayed.
* @default false
*/
showColumnVerticalBorder: PropTypes.bool,
/**
* Overridable components props dynamically passed to the component at rendering.
*/
slotProps: PropTypes.object,
/**
* Overridable components.
*/
slots: PropTypes.object,
/**
* Sorting can be processed on the server or client-side.
* Set it to 'client' if you would like to handle sorting on the client-side.
* Set it to 'server' if you would like to handle sorting on the server-side.
* @default "client"
*/
sortingMode: PropTypes.oneOf(['client', 'server']),
/**
* The order of the sorting sequence.
* @default ['asc', 'desc', null]
*/
sortingOrder: PropTypes.arrayOf(PropTypes.oneOf(['asc', 'desc'])),
/**
* Set the sort model of the Data Grid.
*/
sortModel: PropTypes.arrayOf(PropTypes.shape({
field: PropTypes.string.isRequired,
sort: PropTypes.oneOf(['asc', 'desc'])
})),
/**
* The system prop that allows defining system overrides as well as additional CSS styles.
*/
sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
/**
* If `true`, the Data Grid will not use `valueFormatter` when exporting to CSV or copying to clipboard.
* If an object is provided, you can choose to ignore the `valueFormatter` for CSV export or clipboard export.
* @default false
*/
unstable_ignoreValueFormatterDuringExport: PropTypes.oneOfType([PropTypes.shape({
clipboardExport: PropTypes.bool,
csvExport: PropTypes.bool
}), PropTypes.bool])
};

View File

@@ -0,0 +1,2 @@
export * from './DataGrid';
export { DATA_GRID_PROPS_DEFAULT_VALUES } from './useDataGridProps';

View File

@@ -0,0 +1,80 @@
import { useGridInitialization } from '../hooks/core/useGridInitialization';
import { useGridInitializeState } from '../hooks/utils/useGridInitializeState';
import { useGridClipboard } from '../hooks/features/clipboard/useGridClipboard';
import { columnMenuStateInitializer, useGridColumnMenu } from '../hooks/features/columnMenu/useGridColumnMenu';
import { useGridColumns, columnsStateInitializer } from '../hooks/features/columns/useGridColumns';
import { densityStateInitializer, useGridDensity } from '../hooks/features/density/useGridDensity';
import { useGridCsvExport } from '../hooks/features/export/useGridCsvExport';
import { useGridPrintExport } from '../hooks/features/export/useGridPrintExport';
import { useGridFilter, filterStateInitializer } from '../hooks/features/filter/useGridFilter';
import { focusStateInitializer, useGridFocus } from '../hooks/features/focus/useGridFocus';
import { useGridKeyboardNavigation } from '../hooks/features/keyboardNavigation/useGridKeyboardNavigation';
import { useGridPagination, paginationStateInitializer } from '../hooks/features/pagination/useGridPagination';
import { useGridPreferencesPanel, preferencePanelStateInitializer } from '../hooks/features/preferencesPanel/useGridPreferencesPanel';
import { useGridEditing, editingStateInitializer } from '../hooks/features/editing/useGridEditing';
import { useGridRows, rowsStateInitializer } from '../hooks/features/rows/useGridRows';
import { useGridRowsPreProcessors } from '../hooks/features/rows/useGridRowsPreProcessors';
import { useGridParamsApi } from '../hooks/features/rows/useGridParamsApi';
import { rowSelectionStateInitializer, useGridRowSelection } from '../hooks/features/rowSelection/useGridRowSelection';
import { useGridRowSelectionPreProcessors } from '../hooks/features/rowSelection/useGridRowSelectionPreProcessors';
import { useGridSorting, sortingStateInitializer } from '../hooks/features/sorting/useGridSorting';
import { useGridScroll } from '../hooks/features/scroll/useGridScroll';
import { useGridEvents } from '../hooks/features/events/useGridEvents';
import { useGridDimensions } from '../hooks/features/dimensions/useGridDimensions';
import { rowsMetaStateInitializer, useGridRowsMeta } from '../hooks/features/rows/useGridRowsMeta';
import { useGridStatePersistence } from '../hooks/features/statePersistence/useGridStatePersistence';
import { useGridColumnSpanning } from '../hooks/features/columns/useGridColumnSpanning';
import { useGridColumnGrouping, columnGroupsStateInitializer } from '../hooks/features/columnGrouping/useGridColumnGrouping';
import { useGridVirtualization, virtualizationStateInitializer } from '../hooks/features/virtualization';
export const useDataGridComponent = (inputApiRef, props) => {
const apiRef = useGridInitialization(inputApiRef, props);
/**
* Register all pre-processors called during state initialization here.
*/
useGridRowSelectionPreProcessors(apiRef, props);
useGridRowsPreProcessors(apiRef);
/**
* Register all state initializers here.
*/
useGridInitializeState(rowSelectionStateInitializer, apiRef, props);
useGridInitializeState(columnsStateInitializer, apiRef, props);
useGridInitializeState(rowsStateInitializer, apiRef, props);
useGridInitializeState(editingStateInitializer, apiRef, props);
useGridInitializeState(focusStateInitializer, apiRef, props);
useGridInitializeState(sortingStateInitializer, apiRef, props);
useGridInitializeState(preferencePanelStateInitializer, apiRef, props);
useGridInitializeState(filterStateInitializer, apiRef, props);
useGridInitializeState(densityStateInitializer, apiRef, props);
useGridInitializeState(paginationStateInitializer, apiRef, props);
useGridInitializeState(rowsMetaStateInitializer, apiRef, props);
useGridInitializeState(columnMenuStateInitializer, apiRef, props);
useGridInitializeState(columnGroupsStateInitializer, apiRef, props);
useGridInitializeState(virtualizationStateInitializer, apiRef, props);
useGridKeyboardNavigation(apiRef, props);
useGridRowSelection(apiRef, props);
useGridColumns(apiRef, props);
useGridRows(apiRef, props);
useGridParamsApi(apiRef, props);
useGridColumnSpanning(apiRef);
useGridColumnGrouping(apiRef, props);
useGridEditing(apiRef, props);
useGridFocus(apiRef, props);
useGridPreferencesPanel(apiRef, props);
useGridFilter(apiRef, props);
useGridSorting(apiRef, props);
useGridDensity(apiRef, props);
useGridPagination(apiRef, props);
useGridRowsMeta(apiRef, props);
useGridScroll(apiRef, props);
useGridColumnMenu(apiRef);
useGridCsvExport(apiRef, props);
useGridPrintExport(apiRef, props);
useGridClipboard(apiRef, props);
useGridDimensions(apiRef, props);
useGridEvents(apiRef, props);
useGridStatePersistence(apiRef);
useGridVirtualization(apiRef, props);
return apiRef;
};

View File

@@ -0,0 +1,92 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import * as React from 'react';
import { useThemeProps } from '@mui/material/styles';
import { GRID_DEFAULT_LOCALE_TEXT } from '../constants';
import { DATA_GRID_DEFAULT_SLOTS_COMPONENTS } from '../constants/defaultGridSlotsComponents';
import { GridEditModes } from '../models';
import { computeSlots, useProps, uncapitalizeObjectKeys } from '../internals/utils';
const DATA_GRID_FORCED_PROPS = {
disableMultipleColumnsFiltering: true,
disableMultipleColumnsSorting: true,
disableMultipleRowSelection: true,
throttleRowsMs: undefined,
hideFooterRowCount: false,
pagination: true,
checkboxSelectionVisibleOnly: false,
disableColumnReorder: true,
disableColumnResize: true,
keepColumnPositionIfDraggedOutside: false,
signature: 'DataGrid'
};
/**
* The default values of `DataGridPropsWithDefaultValues` to inject in the props of DataGrid.
*/
export const DATA_GRID_PROPS_DEFAULT_VALUES = {
autoHeight: false,
autoPageSize: false,
checkboxSelection: false,
checkboxSelectionVisibleOnly: false,
columnBuffer: 3,
rowBuffer: 3,
columnThreshold: 3,
rowThreshold: 3,
rowSelection: true,
density: 'standard',
disableColumnFilter: false,
disableColumnMenu: false,
disableColumnSelector: false,
disableDensitySelector: false,
disableEval: false,
disableMultipleColumnsFiltering: false,
disableMultipleRowSelection: false,
disableMultipleColumnsSorting: false,
disableRowSelectionOnClick: false,
disableVirtualization: false,
editMode: GridEditModes.Cell,
filterMode: 'client',
filterDebounceMs: 150,
columnHeaderHeight: 56,
hideFooter: false,
hideFooterPagination: false,
hideFooterRowCount: false,
hideFooterSelectedRowCount: false,
ignoreDiacritics: false,
logger: console,
logLevel: process.env.NODE_ENV === 'production' ? 'error' : 'warn',
pagination: false,
paginationMode: 'client',
rowHeight: 52,
pageSizeOptions: [25, 50, 100],
rowSpacingType: 'margin',
showCellVerticalBorder: false,
showColumnVerticalBorder: false,
sortingOrder: ['asc', 'desc', null],
sortingMode: 'client',
throttleRowsMs: 0,
disableColumnReorder: false,
disableColumnResize: false,
keepNonExistentRowsSelected: false,
keepColumnPositionIfDraggedOutside: false,
unstable_ignoreValueFormatterDuringExport: false,
clipboardCopyCellDelimiter: '\t',
rowPositionsDebounceMs: 166
};
const defaultSlots = uncapitalizeObjectKeys(DATA_GRID_DEFAULT_SLOTS_COMPONENTS);
export const useDataGridProps = inProps => {
const [components, componentsProps, themedProps] = useProps(useThemeProps({
props: inProps,
name: 'MuiDataGrid'
}));
const localeText = React.useMemo(() => _extends({}, GRID_DEFAULT_LOCALE_TEXT, themedProps.localeText), [themedProps.localeText]);
const slots = React.useMemo(() => computeSlots({
defaultSlots,
slots: themedProps.slots,
components
}), [components, themedProps.slots]);
return React.useMemo(() => _extends({}, DATA_GRID_PROPS_DEFAULT_VALUES, themedProps, {
localeText,
slots,
slotProps: themedProps.slotProps ?? componentsProps
}, DATA_GRID_FORCED_PROPS), [themedProps, localeText, slots, componentsProps]);
};

View File

@@ -0,0 +1,19 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import { GRID_STRING_COL_DEF } from './gridStringColDef';
import { renderActionsCell } from '../components/cell/GridActionsCell';
export const GRID_ACTIONS_COLUMN_TYPE = 'actions';
export const GRID_ACTIONS_COL_DEF = _extends({}, GRID_STRING_COL_DEF, {
sortable: false,
filterable: false,
// @ts-ignore
aggregable: false,
width: 100,
align: 'center',
headerAlign: 'center',
headerName: '',
disableColumnMenu: true,
disableExport: true,
renderCell: renderActionsCell,
getApplyQuickFilterFn: undefined,
getApplyQuickFilterFnV7: undefined
});

View File

@@ -0,0 +1,44 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import { GRID_STRING_COL_DEF } from './gridStringColDef';
import { renderBooleanCell } from '../components/cell/GridBooleanCell';
import { renderEditBooleanCell } from '../components/cell/GridEditBooleanCell';
import { gridNumberComparator } from '../hooks/features/sorting/gridSortingUtils';
import { getGridBooleanOperators } from './gridBooleanOperators';
function gridBooleanFormatter({
value,
api
}) {
return value ? api.getLocaleText('booleanCellTrueLabel') : api.getLocaleText('booleanCellFalseLabel');
}
const stringToBoolean = value => {
switch (value.toLowerCase().trim()) {
case 'true':
case 'yes':
case '1':
return true;
case 'false':
case 'no':
case '0':
case 'null':
case 'undefined':
return false;
default:
return undefined;
}
};
export const GRID_BOOLEAN_COL_DEF = _extends({}, GRID_STRING_COL_DEF, {
type: 'boolean',
align: 'center',
headerAlign: 'center',
renderCell: renderBooleanCell,
renderEditCell: renderEditBooleanCell,
sortComparator: gridNumberComparator,
valueFormatter: gridBooleanFormatter,
filterOperators: getGridBooleanOperators(),
getApplyQuickFilterFn: undefined,
getApplyQuickFilterFnV7: undefined,
// @ts-ignore
aggregable: false,
// @ts-ignore
pastedValueParser: value => stringToBoolean(value)
});

View File

@@ -0,0 +1,15 @@
import { GridFilterInputBoolean } from '../components/panel/filterPanel/GridFilterInputBoolean';
import { convertLegacyOperators } from './utils';
export const getGridBooleanOperators = () => convertLegacyOperators([{
value: 'is',
getApplyFilterFnV7: filterItem => {
if (!filterItem.value) {
return null;
}
const valueAsBoolean = filterItem.value === 'true';
return value => {
return Boolean(value) === valueAsBoolean;
};
},
InputComponent: GridFilterInputBoolean
}]);

View File

@@ -0,0 +1,29 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import * as React from 'react';
import { GridCellCheckboxRenderer } from '../components/columnSelection/GridCellCheckboxRenderer';
import { GridHeaderCheckbox } from '../components/columnSelection/GridHeaderCheckbox';
import { selectedIdsLookupSelector } from '../hooks/features/rowSelection/gridRowSelectionSelector';
import { GRID_BOOLEAN_COL_DEF } from './gridBooleanColDef';
import { jsx as _jsx } from "react/jsx-runtime";
export const GRID_CHECKBOX_SELECTION_FIELD = '__check__';
export const GRID_CHECKBOX_SELECTION_COL_DEF = _extends({}, GRID_BOOLEAN_COL_DEF, {
field: GRID_CHECKBOX_SELECTION_FIELD,
type: 'checkboxSelection',
width: 50,
resizable: false,
sortable: false,
filterable: false,
// @ts-ignore
aggregable: false,
disableColumnMenu: true,
disableReorder: true,
disableExport: true,
getApplyQuickFilterFn: undefined,
getApplyQuickFilterFnV7: undefined,
valueGetter: params => {
const selectionLookup = selectedIdsLookupSelector(params.api.state, params.api.instanceId);
return selectionLookup[params.id] !== undefined;
},
renderHeader: params => /*#__PURE__*/_jsx(GridHeaderCheckbox, _extends({}, params)),
renderCell: params => /*#__PURE__*/_jsx(GridCellCheckboxRenderer, _extends({}, params))
});

View File

@@ -0,0 +1,65 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import { gridDateComparator } from '../hooks/features/sorting/gridSortingUtils';
import { getGridDateOperators } from './gridDateOperators';
import { GRID_STRING_COL_DEF } from './gridStringColDef';
import { renderEditDateCell } from '../components/cell/GridEditDateCell';
function throwIfNotDateObject({
value,
columnType,
rowId,
field
}) {
if (!(value instanceof Date)) {
throw new Error([`MUI: \`${columnType}\` column type only accepts \`Date\` objects as values.`, 'Use `valueGetter` to transform the value into a `Date` object.', `Row ID: ${rowId}, field: "${field}".`].join('\n'));
}
}
export function gridDateFormatter({
value,
field,
id
}) {
if (!value) {
return '';
}
throwIfNotDateObject({
value,
columnType: 'date',
rowId: id,
field
});
return value.toLocaleDateString();
}
export function gridDateTimeFormatter({
value,
field,
id
}) {
if (!value) {
return '';
}
throwIfNotDateObject({
value,
columnType: 'dateTime',
rowId: id,
field
});
return value.toLocaleString();
}
export const GRID_DATE_COL_DEF = _extends({}, GRID_STRING_COL_DEF, {
type: 'date',
sortComparator: gridDateComparator,
valueFormatter: gridDateFormatter,
filterOperators: getGridDateOperators(),
renderEditCell: renderEditDateCell,
// @ts-ignore
pastedValueParser: value => new Date(value)
});
export const GRID_DATETIME_COL_DEF = _extends({}, GRID_STRING_COL_DEF, {
type: 'dateTime',
sortComparator: gridDateComparator,
valueFormatter: gridDateTimeFormatter,
filterOperators: getGridDateOperators(true),
renderEditCell: renderEditDateCell,
// @ts-ignore
pastedValueParser: value => new Date(value)
});

View File

@@ -0,0 +1,95 @@
import { GridFilterInputDate } from '../components/panel/filterPanel/GridFilterInputDate';
import { convertLegacyOperators } from './utils';
const dateRegex = /(\d+)-(\d+)-(\d+)/;
const dateTimeRegex = /(\d+)-(\d+)-(\d+)T(\d+):(\d+)/;
function buildApplyFilterFn(filterItem, compareFn, showTime, keepHours) {
if (!filterItem.value) {
return null;
}
const [year, month, day, hour, minute] = filterItem.value.match(showTime ? dateTimeRegex : dateRegex).slice(1).map(Number);
const time = new Date(year, month - 1, day, hour || 0, minute || 0).getTime();
return value => {
if (!value) {
return false;
}
if (keepHours) {
return compareFn(value.getTime(), time);
}
// Make a copy of the date to not reset the hours in the original object
const dateCopy = new Date(value);
const timeToCompare = dateCopy.setHours(showTime ? value.getHours() : 0, showTime ? value.getMinutes() : 0, 0, 0);
return compareFn(timeToCompare, time);
};
}
export const getGridDateOperators = showTime => convertLegacyOperators([{
value: 'is',
getApplyFilterFnV7: filterItem => {
return buildApplyFilterFn(filterItem, (value1, value2) => value1 === value2, showTime);
},
InputComponent: GridFilterInputDate,
InputComponentProps: {
type: showTime ? 'datetime-local' : 'date'
}
}, {
value: 'not',
getApplyFilterFnV7: filterItem => {
return buildApplyFilterFn(filterItem, (value1, value2) => value1 !== value2, showTime);
},
InputComponent: GridFilterInputDate,
InputComponentProps: {
type: showTime ? 'datetime-local' : 'date'
}
}, {
value: 'after',
getApplyFilterFnV7: filterItem => {
return buildApplyFilterFn(filterItem, (value1, value2) => value1 > value2, showTime);
},
InputComponent: GridFilterInputDate,
InputComponentProps: {
type: showTime ? 'datetime-local' : 'date'
}
}, {
value: 'onOrAfter',
getApplyFilterFnV7: filterItem => {
return buildApplyFilterFn(filterItem, (value1, value2) => value1 >= value2, showTime);
},
InputComponent: GridFilterInputDate,
InputComponentProps: {
type: showTime ? 'datetime-local' : 'date'
}
}, {
value: 'before',
getApplyFilterFnV7: filterItem => {
return buildApplyFilterFn(filterItem, (value1, value2) => value1 < value2, showTime, !showTime);
},
InputComponent: GridFilterInputDate,
InputComponentProps: {
type: showTime ? 'datetime-local' : 'date'
}
}, {
value: 'onOrBefore',
getApplyFilterFnV7: filterItem => {
return buildApplyFilterFn(filterItem, (value1, value2) => value1 <= value2, showTime);
},
InputComponent: GridFilterInputDate,
InputComponentProps: {
type: showTime ? 'datetime-local' : 'date'
}
}, {
value: 'isEmpty',
getApplyFilterFnV7: () => {
return value => {
return value == null;
};
},
requiresFilterValue: false
}, {
value: 'isNotEmpty',
getApplyFilterFnV7: () => {
return value => {
return value != null;
};
},
requiresFilterValue: false
}]);

View File

@@ -0,0 +1,20 @@
import { GRID_STRING_COL_DEF } from './gridStringColDef';
import { GRID_NUMERIC_COL_DEF } from './gridNumericColDef';
import { GRID_DATE_COL_DEF, GRID_DATETIME_COL_DEF } from './gridDateColDef';
import { GRID_BOOLEAN_COL_DEF } from './gridBooleanColDef';
import { GRID_SINGLE_SELECT_COL_DEF } from './gridSingleSelectColDef';
import { GRID_ACTIONS_COL_DEF, GRID_ACTIONS_COLUMN_TYPE } from './gridActionsColDef';
export const DEFAULT_GRID_COL_TYPE_KEY = '__default__';
export const getGridDefaultColumnTypes = () => {
const nativeColumnTypes = {
string: GRID_STRING_COL_DEF,
number: GRID_NUMERIC_COL_DEF,
date: GRID_DATE_COL_DEF,
dateTime: GRID_DATETIME_COL_DEF,
boolean: GRID_BOOLEAN_COL_DEF,
singleSelect: GRID_SINGLE_SELECT_COL_DEF,
[GRID_ACTIONS_COLUMN_TYPE]: GRID_ACTIONS_COL_DEF,
[DEFAULT_GRID_COL_TYPE_KEY]: GRID_STRING_COL_DEF
};
return nativeColumnTypes;
};

View File

@@ -0,0 +1,19 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import { gridNumberComparator } from '../hooks/features/sorting/gridSortingUtils';
import { isNumber } from '../utils/utils';
import { getGridNumericOperators, getGridNumericQuickFilterFn } from './gridNumericOperators';
import { GRID_STRING_COL_DEF } from './gridStringColDef';
import { convertQuickFilterV7ToLegacy } from './utils';
export const GRID_NUMERIC_COL_DEF = _extends({}, GRID_STRING_COL_DEF, {
type: 'number',
align: 'right',
headerAlign: 'right',
sortComparator: gridNumberComparator,
valueParser: value => value === '' ? null : Number(value),
valueFormatter: ({
value
}) => isNumber(value) ? value.toLocaleString() : value || '',
filterOperators: getGridNumericOperators(),
getApplyQuickFilterFn: convertQuickFilterV7ToLegacy(getGridNumericQuickFilterFn),
getApplyQuickFilterFnV7: getGridNumericQuickFilterFn
});

View File

@@ -0,0 +1,144 @@
import { GridFilterInputValue } from '../components/panel/filterPanel/GridFilterInputValue';
import { GridFilterInputMultipleValue } from '../components/panel/filterPanel/GridFilterInputMultipleValue';
import { convertLegacyOperators, tagInternalFilter } from './utils';
const parseNumericValue = value => {
if (value == null) {
return null;
}
return Number(value);
};
export const getGridNumericQuickFilterFn = tagInternalFilter(value => {
if (value == null || Number.isNaN(value) || value === '') {
return null;
}
return columnValue => {
return parseNumericValue(columnValue) === parseNumericValue(value);
};
});
export const getGridNumericOperators = () => convertLegacyOperators([{
value: '=',
getApplyFilterFnV7: filterItem => {
if (filterItem.value == null || Number.isNaN(filterItem.value)) {
return null;
}
return value => {
return parseNumericValue(value) === filterItem.value;
};
},
InputComponent: GridFilterInputValue,
InputComponentProps: {
type: 'number'
}
}, {
value: '!=',
getApplyFilterFnV7: filterItem => {
if (filterItem.value == null || Number.isNaN(filterItem.value)) {
return null;
}
return value => {
return parseNumericValue(value) !== filterItem.value;
};
},
InputComponent: GridFilterInputValue,
InputComponentProps: {
type: 'number'
}
}, {
value: '>',
getApplyFilterFnV7: filterItem => {
if (filterItem.value == null || Number.isNaN(filterItem.value)) {
return null;
}
return value => {
if (value == null) {
return false;
}
return parseNumericValue(value) > filterItem.value;
};
},
InputComponent: GridFilterInputValue,
InputComponentProps: {
type: 'number'
}
}, {
value: '>=',
getApplyFilterFnV7: filterItem => {
if (filterItem.value == null || Number.isNaN(filterItem.value)) {
return null;
}
return value => {
if (value == null) {
return false;
}
return parseNumericValue(value) >= filterItem.value;
};
},
InputComponent: GridFilterInputValue,
InputComponentProps: {
type: 'number'
}
}, {
value: '<',
getApplyFilterFnV7: filterItem => {
if (filterItem.value == null || Number.isNaN(filterItem.value)) {
return null;
}
return value => {
if (value == null) {
return false;
}
return parseNumericValue(value) < filterItem.value;
};
},
InputComponent: GridFilterInputValue,
InputComponentProps: {
type: 'number'
}
}, {
value: '<=',
getApplyFilterFnV7: filterItem => {
if (filterItem.value == null || Number.isNaN(filterItem.value)) {
return null;
}
return value => {
if (value == null) {
return false;
}
return parseNumericValue(value) <= filterItem.value;
};
},
InputComponent: GridFilterInputValue,
InputComponentProps: {
type: 'number'
}
}, {
value: 'isEmpty',
getApplyFilterFnV7: () => {
return value => {
return value == null;
};
},
requiresFilterValue: false
}, {
value: 'isNotEmpty',
getApplyFilterFnV7: () => {
return value => {
return value != null;
};
},
requiresFilterValue: false
}, {
value: 'isAnyOf',
getApplyFilterFnV7: filterItem => {
if (!Array.isArray(filterItem.value) || filterItem.value.length === 0) {
return null;
}
return value => {
return value != null && filterItem.value.includes(Number(value));
};
},
InputComponent: GridFilterInputMultipleValue,
InputComponentProps: {
type: 'number'
}
}]);

View File

@@ -0,0 +1,75 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import { GRID_STRING_COL_DEF } from './gridStringColDef';
import { renderEditSingleSelectCell } from '../components/cell/GridEditSingleSelectCell';
import { getGridSingleSelectOperators } from './gridSingleSelectOperators';
import { isSingleSelectColDef } from '../components/panel/filterPanel/filterPanelUtils';
import { isObject } from '../utils/utils';
const isArrayOfObjects = options => {
return typeof options[0] === 'object';
};
const defaultGetOptionValue = value => {
return isObject(value) ? value.value : value;
};
const defaultGetOptionLabel = value => {
return isObject(value) ? value.label : String(value);
};
export const GRID_SINGLE_SELECT_COL_DEF = _extends({}, GRID_STRING_COL_DEF, {
type: 'singleSelect',
getOptionLabel: defaultGetOptionLabel,
getOptionValue: defaultGetOptionValue,
valueFormatter(params) {
const {
id,
field,
value,
api
} = params;
const colDef = params.api.getColumn(field);
if (!isSingleSelectColDef(colDef)) {
return '';
}
let valueOptions;
if (typeof colDef.valueOptions === 'function') {
valueOptions = colDef.valueOptions({
id,
row: id ? api.getRow(id) : null,
field
});
} else {
valueOptions = colDef.valueOptions;
}
if (value == null) {
return '';
}
if (!valueOptions) {
return value;
}
if (!isArrayOfObjects(valueOptions)) {
return colDef.getOptionLabel(value);
}
const valueOption = valueOptions.find(option => colDef.getOptionValue(option) === value);
return valueOption ? colDef.getOptionLabel(valueOption) : '';
},
renderEditCell: renderEditSingleSelectCell,
filterOperators: getGridSingleSelectOperators(),
// @ts-ignore
pastedValueParser: (value, params) => {
const colDef = params.colDef;
const colDefValueOptions = colDef.valueOptions;
const valueOptions = typeof colDefValueOptions === 'function' ? colDefValueOptions({
field: colDef.field
}) : colDefValueOptions || [];
const getOptionValue = colDef.getOptionValue;
const valueOption = valueOptions.find(option => {
if (getOptionValue(option) === value) {
return true;
}
return false;
});
if (valueOption) {
return value;
}
// do not paste the value if it is not in the valueOptions
return undefined;
}
});

View File

@@ -0,0 +1,39 @@
import { GridFilterInputSingleSelect } from '../components/panel/filterPanel/GridFilterInputSingleSelect';
import { GridFilterInputMultipleSingleSelect } from '../components/panel/filterPanel/GridFilterInputMultipleSingleSelect';
import { isObject } from '../utils/utils';
import { convertLegacyOperators } from './utils';
const parseObjectValue = value => {
if (value == null || !isObject(value)) {
return value;
}
return value.value;
};
export const getGridSingleSelectOperators = () => convertLegacyOperators([{
value: 'is',
getApplyFilterFnV7: filterItem => {
if (filterItem.value == null || filterItem.value === '') {
return null;
}
return value => parseObjectValue(value) === parseObjectValue(filterItem.value);
},
InputComponent: GridFilterInputSingleSelect
}, {
value: 'not',
getApplyFilterFnV7: filterItem => {
if (filterItem.value == null || filterItem.value === '') {
return null;
}
return value => parseObjectValue(value) !== parseObjectValue(filterItem.value);
},
InputComponent: GridFilterInputSingleSelect
}, {
value: 'isAnyOf',
getApplyFilterFnV7: filterItem => {
if (!Array.isArray(filterItem.value) || filterItem.value.length === 0) {
return null;
}
const filterItemValues = filterItem.value.map(parseObjectValue);
return value => filterItemValues.includes(parseObjectValue(value));
},
InputComponent: GridFilterInputMultipleSingleSelect
}]);

View File

@@ -0,0 +1,29 @@
import { renderEditInputCell } from '../components/cell/GridEditInputCell';
import { gridStringOrNumberComparator } from '../hooks/features/sorting/gridSortingUtils';
import { getGridStringOperators, getGridStringQuickFilterFn } from './gridStringOperators';
import { convertQuickFilterV7ToLegacy } from './utils';
/**
* TODO: Move pro and premium properties outside of this Community file
*/
export const GRID_STRING_COL_DEF = {
width: 100,
minWidth: 50,
maxWidth: Infinity,
hideable: true,
sortable: true,
resizable: true,
filterable: true,
groupable: true,
pinnable: true,
// @ts-ignore
aggregable: true,
editable: false,
sortComparator: gridStringOrNumberComparator,
type: 'string',
align: 'left',
filterOperators: getGridStringOperators(),
renderEditCell: renderEditInputCell,
getApplyQuickFilterFn: convertQuickFilterV7ToLegacy(getGridStringQuickFilterFn),
getApplyQuickFilterFnV7: getGridStringQuickFilterFn
};

View File

@@ -0,0 +1,106 @@
import { GridFilterInputValue } from '../components/panel/filterPanel/GridFilterInputValue';
import { escapeRegExp } from '../utils/utils';
import { GridFilterInputMultipleValue } from '../components/panel/filterPanel/GridFilterInputMultipleValue';
import { convertLegacyOperators, tagInternalFilter } from './utils';
import { removeDiacritics } from '../hooks/features/filter/gridFilterUtils';
export const getGridStringQuickFilterFn = tagInternalFilter(value => {
if (!value) {
return null;
}
const filterRegex = new RegExp(escapeRegExp(value), 'i');
return (_, row, column, apiRef) => {
let columnValue = apiRef.current.getRowFormattedValue(row, column);
if (apiRef.current.ignoreDiacritics) {
columnValue = removeDiacritics(columnValue);
}
return columnValue != null ? filterRegex.test(columnValue.toString()) : false;
};
});
export const getGridStringOperators = (disableTrim = false) => convertLegacyOperators([{
value: 'contains',
getApplyFilterFnV7: filterItem => {
if (!filterItem.value) {
return null;
}
const filterItemValue = disableTrim ? filterItem.value : filterItem.value.trim();
const filterRegex = new RegExp(escapeRegExp(filterItemValue), 'i');
return value => {
return value != null ? filterRegex.test(String(value)) : false;
};
},
InputComponent: GridFilterInputValue
}, {
value: 'equals',
getApplyFilterFnV7: filterItem => {
if (!filterItem.value) {
return null;
}
const filterItemValue = disableTrim ? filterItem.value : filterItem.value.trim();
const collator = new Intl.Collator(undefined, {
sensitivity: 'base',
usage: 'search'
});
return value => {
return value != null ? collator.compare(filterItemValue, value.toString()) === 0 : false;
};
},
InputComponent: GridFilterInputValue
}, {
value: 'startsWith',
getApplyFilterFnV7: filterItem => {
if (!filterItem.value) {
return null;
}
const filterItemValue = disableTrim ? filterItem.value : filterItem.value.trim();
const filterRegex = new RegExp(`^${escapeRegExp(filterItemValue)}.*$`, 'i');
return value => {
return value != null ? filterRegex.test(value.toString()) : false;
};
},
InputComponent: GridFilterInputValue
}, {
value: 'endsWith',
getApplyFilterFnV7: filterItem => {
if (!filterItem.value) {
return null;
}
const filterItemValue = disableTrim ? filterItem.value : filterItem.value.trim();
const filterRegex = new RegExp(`.*${escapeRegExp(filterItemValue)}$`, 'i');
return value => {
return value != null ? filterRegex.test(value.toString()) : false;
};
},
InputComponent: GridFilterInputValue
}, {
value: 'isEmpty',
getApplyFilterFnV7: () => {
return value => {
return value === '' || value == null;
};
},
requiresFilterValue: false
}, {
value: 'isNotEmpty',
getApplyFilterFnV7: () => {
return value => {
return value !== '' && value != null;
};
},
requiresFilterValue: false
}, {
value: 'isAnyOf',
getApplyFilterFnV7: filterItem => {
if (!Array.isArray(filterItem.value) || filterItem.value.length === 0) {
return null;
}
const filterItemValue = disableTrim ? filterItem.value : filterItem.value.map(val => val.trim());
const collator = new Intl.Collator(undefined, {
sensitivity: 'base',
usage: 'search'
});
return value => value != null ? filterItemValue.some(filterValue => {
return collator.compare(filterValue, value.toString() || '') === 0;
}) : false;
},
InputComponent: GridFilterInputMultipleValue
}]);

View File

@@ -0,0 +1,13 @@
export * from './gridActionsColDef';
export * from './gridBooleanColDef';
export * from './gridCheckboxSelectionColDef';
export * from './gridDateColDef';
export * from './gridNumericColDef';
export * from './gridSingleSelectColDef';
export * from './gridStringColDef';
export * from './gridBooleanOperators';
export * from './gridDateOperators';
export * from './gridNumericOperators';
export * from './gridSingleSelectOperators';
export * from './gridStringOperators';
export * from './gridDefaultColumnTypes';

View File

@@ -0,0 +1,51 @@
import _extends from "@babel/runtime/helpers/esm/extends";
/**
* A global API ref, for v7-to-legacy converter
*/
export const GLOBAL_API_REF = {
current: null
};
/**
* A tagger to determine if the filter is internal or custom user-supplied.
* To be a valid internal filter, the v7 function *must* be defined/redefined at
* the same time as the legacy one.
* https://github.com/mui/mui-x/pull/9254#discussion_r1231095551
*/
export function tagInternalFilter(fn) {
fn.isInternal = true;
return fn;
}
export function isInternalFilter(fn) {
return fn !== undefined && fn.isInternal === true;
}
export function convertFilterV7ToLegacy(fn) {
return tagInternalFilter((filterItem, column) => {
const filterFn = fn(filterItem, column);
if (!filterFn) {
return filterFn;
}
return cellParams => {
return filterFn(cellParams.value, cellParams.row, column, GLOBAL_API_REF.current);
};
});
}
export function convertLegacyOperators(ops) {
return ops.map(op => {
return _extends({}, op, {
getApplyFilterFn: convertFilterV7ToLegacy(op.getApplyFilterFnV7),
getApplyFilterFnV7: tagInternalFilter(op.getApplyFilterFnV7)
});
});
}
export function convertQuickFilterV7ToLegacy(fn) {
return tagInternalFilter((filterItem, column, apiRef) => {
const filterFn = fn(filterItem, column, apiRef);
if (!filterFn) {
return filterFn;
}
return cellParams => {
return filterFn(cellParams.value, cellParams.row, column, apiRef);
};
});
}

View File

@@ -0,0 +1,35 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
const _excluded = ["className"];
import * as React from 'react';
import { GridVirtualScroller } from './virtualization/GridVirtualScroller';
import { GridVirtualScrollerContent } from './virtualization/GridVirtualScrollerContent';
import { GridVirtualScrollerRenderZone } from './virtualization/GridVirtualScrollerRenderZone';
import { useGridVirtualScroller } from '../hooks/features/virtualization/useGridVirtualScroller';
import { GridOverlays } from './base/GridOverlays';
import { jsx as _jsx } from "react/jsx-runtime";
import { jsxs as _jsxs } from "react/jsx-runtime";
const DataGridVirtualScroller = /*#__PURE__*/React.forwardRef(function DataGridVirtualScroller(props, ref) {
const {
className
} = props,
other = _objectWithoutPropertiesLoose(props, _excluded);
const {
getRootProps,
getContentProps,
getRenderZoneProps,
getRows
} = useGridVirtualScroller({
ref
});
return /*#__PURE__*/_jsxs(GridVirtualScroller, _extends({
className: className
}, getRootProps(other), {
children: [/*#__PURE__*/_jsx(GridOverlays, {}), /*#__PURE__*/_jsx(GridVirtualScrollerContent, _extends({}, getContentProps(), {
children: /*#__PURE__*/_jsx(GridVirtualScrollerRenderZone, _extends({}, getRenderZoneProps(), {
children: getRows()
}))
}))]
}));
});
export { DataGridVirtualScroller };

View File

@@ -0,0 +1,5 @@
import * as React from 'react';
export const GridApiContext = /*#__PURE__*/React.createContext(undefined);
if (process.env.NODE_ENV !== 'production') {
GridApiContext.displayName = 'GridApiContext';
}

View File

@@ -0,0 +1,104 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
const _excluded = ["innerRef", "className", "visibleColumns", "sortColumnLookup", "filterColumnLookup", "columnPositions", "columnHeaderTabIndexState", "columnGroupHeaderTabIndexState", "columnHeaderFocus", "columnGroupHeaderFocus", "densityFactor", "headerGroupingMaxDepth", "columnMenuState", "columnVisibility", "columnGroupsHeaderStructure", "hasOtherElementInTabSequence"];
import * as React from 'react';
import PropTypes from 'prop-types';
import { refType } from '@mui/utils';
import { fastMemo } from '../utils/fastMemo';
import { useGridColumnHeaders } from '../hooks/features/columnHeaders/useGridColumnHeaders';
import { GridBaseColumnHeaders } from './columnHeaders/GridBaseColumnHeaders';
import { GridColumnHeadersInner } from './columnHeaders/GridColumnHeadersInner';
import { jsxs as _jsxs } from "react/jsx-runtime";
import { jsx as _jsx } from "react/jsx-runtime";
const GridColumnHeaders = /*#__PURE__*/React.forwardRef(function GridColumnsHeaders(props, ref) {
const {
innerRef,
visibleColumns,
sortColumnLookup,
filterColumnLookup,
columnPositions,
columnHeaderTabIndexState,
columnGroupHeaderTabIndexState,
columnHeaderFocus,
columnGroupHeaderFocus,
densityFactor,
headerGroupingMaxDepth,
columnMenuState,
columnVisibility,
columnGroupsHeaderStructure,
hasOtherElementInTabSequence
} = props,
other = _objectWithoutPropertiesLoose(props, _excluded);
const {
isDragging,
getRootProps,
getInnerProps,
getColumnHeaders,
getColumnGroupHeaders
} = useGridColumnHeaders({
innerRef,
visibleColumns,
sortColumnLookup,
filterColumnLookup,
columnPositions,
columnHeaderTabIndexState,
columnGroupHeaderTabIndexState,
columnHeaderFocus,
columnGroupHeaderFocus,
densityFactor,
headerGroupingMaxDepth,
columnMenuState,
columnVisibility,
columnGroupsHeaderStructure,
hasOtherElementInTabSequence
});
return /*#__PURE__*/_jsx(GridBaseColumnHeaders, _extends({
ref: ref
}, getRootProps(other), {
children: /*#__PURE__*/_jsxs(GridColumnHeadersInner, _extends({
isDragging: isDragging
}, getInnerProps(), {
children: [getColumnGroupHeaders(), getColumnHeaders()]
}))
}));
});
process.env.NODE_ENV !== "production" ? GridColumnHeaders.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
columnGroupHeaderFocus: PropTypes.shape({
depth: PropTypes.number.isRequired,
field: PropTypes.string.isRequired
}),
columnGroupHeaderTabIndexState: PropTypes.shape({
depth: PropTypes.number.isRequired,
field: PropTypes.string.isRequired
}),
columnGroupsHeaderStructure: PropTypes.arrayOf(PropTypes.arrayOf(PropTypes.shape({
columnFields: PropTypes.arrayOf(PropTypes.string).isRequired,
groupId: PropTypes.string
}))).isRequired,
columnHeaderFocus: PropTypes.shape({
field: PropTypes.string.isRequired
}),
columnHeaderTabIndexState: PropTypes.shape({
field: PropTypes.string.isRequired
}),
columnMenuState: PropTypes.shape({
field: PropTypes.string,
open: PropTypes.bool.isRequired
}).isRequired,
columnPositions: PropTypes.arrayOf(PropTypes.number).isRequired,
columnVisibility: PropTypes.object.isRequired,
densityFactor: PropTypes.number.isRequired,
filterColumnLookup: PropTypes.object.isRequired,
hasOtherElementInTabSequence: PropTypes.bool.isRequired,
headerGroupingMaxDepth: PropTypes.number.isRequired,
innerRef: refType,
minColumnIndex: PropTypes.number,
sortColumnLookup: PropTypes.object.isRequired,
visibleColumns: PropTypes.arrayOf(PropTypes.object).isRequired
} : void 0;
const MemoizedGridColumnHeaders = fastMemo(GridColumnHeaders);
export { MemoizedGridColumnHeaders as GridColumnHeaders };

View File

@@ -0,0 +1,41 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import * as React from 'react';
import PropTypes from 'prop-types';
import { useGridSelector } from '../hooks/utils/useGridSelector';
import { gridTopLevelRowCountSelector } from '../hooks/features/rows/gridRowsSelector';
import { selectedGridRowsCountSelector } from '../hooks/features/rowSelection/gridRowSelectionSelector';
import { gridFilteredTopLevelRowCountSelector } from '../hooks/features/filter/gridFilterSelector';
import { useGridApiContext } from '../hooks/utils/useGridApiContext';
import { GridSelectedRowCount } from './GridSelectedRowCount';
import { GridFooterContainer } from './containers/GridFooterContainer';
import { useGridRootProps } from '../hooks/utils/useGridRootProps';
import { jsx as _jsx } from "react/jsx-runtime";
import { jsxs as _jsxs } from "react/jsx-runtime";
const GridFooter = /*#__PURE__*/React.forwardRef(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 ? /*#__PURE__*/_jsx(GridSelectedRowCount, {
selectedRowCount: selectedRowCount
}) : /*#__PURE__*/_jsx("div", {});
const rowCountElement = !rootProps.hideFooterRowCount && !rootProps.pagination ? /*#__PURE__*/_jsx(rootProps.slots.footerRowCount, _extends({}, rootProps.slotProps?.footerRowCount, {
rowCount: totalTopLevelRowCount,
visibleRowCount: visibleTopLevelRowCount
})) : null;
const paginationElement = rootProps.pagination && !rootProps.hideFooterPagination && rootProps.slots.pagination && /*#__PURE__*/_jsx(rootProps.slots.pagination, _extends({}, rootProps.slotProps?.pagination));
return /*#__PURE__*/_jsxs(GridFooterContainer, _extends({
ref: ref
}, props, {
children: [selectedRowCountElement, rowCountElement, paginationElement]
}));
});
process.env.NODE_ENV !== "production" ? GridFooter.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object])
} : void 0;
export { GridFooter };

View File

@@ -0,0 +1,11 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import * as React from 'react';
import { useGridRootProps } from '../hooks/utils/useGridRootProps';
import { jsx as _jsx } from "react/jsx-runtime";
import { jsxs as _jsxs } from "react/jsx-runtime";
export function GridHeader() {
const rootProps = useGridRootProps();
return /*#__PURE__*/_jsxs(React.Fragment, {
children: [/*#__PURE__*/_jsx(rootProps.slots.preferencesPanel, _extends({}, rootProps.slotProps?.preferencesPanel)), rootProps.slots.toolbar && /*#__PURE__*/_jsx(rootProps.slots.toolbar, _extends({}, rootProps.slotProps?.toolbar))]
});
}

View File

@@ -0,0 +1,21 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import * as React from 'react';
import PropTypes from 'prop-types';
import CircularProgress from '@mui/material/CircularProgress';
import { GridOverlay } from './containers/GridOverlay';
import { jsx as _jsx } from "react/jsx-runtime";
const GridLoadingOverlay = /*#__PURE__*/React.forwardRef(function GridLoadingOverlay(props, ref) {
return /*#__PURE__*/_jsx(GridOverlay, _extends({
ref: ref
}, props, {
children: /*#__PURE__*/_jsx(CircularProgress, {})
}));
});
process.env.NODE_ENV !== "production" ? GridLoadingOverlay.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object])
} : void 0;
export { GridLoadingOverlay };

View File

@@ -0,0 +1,14 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import * as React from 'react';
import { useGridApiContext } from '../hooks/utils/useGridApiContext';
import { GridOverlay } from './containers/GridOverlay';
import { jsx as _jsx } from "react/jsx-runtime";
export const GridNoResultsOverlay = /*#__PURE__*/React.forwardRef(function GridNoResultsOverlay(props, ref) {
const apiRef = useGridApiContext();
const noResultsOverlayLabel = apiRef.current.getLocaleText('noResultsOverlayLabel');
return /*#__PURE__*/_jsx(GridOverlay, _extends({
ref: ref
}, props, {
children: noResultsOverlayLabel
}));
});

View File

@@ -0,0 +1,23 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import * as React from 'react';
import PropTypes from 'prop-types';
import { useGridApiContext } from '../hooks/utils/useGridApiContext';
import { GridOverlay } from './containers/GridOverlay';
import { jsx as _jsx } from "react/jsx-runtime";
const GridNoRowsOverlay = /*#__PURE__*/React.forwardRef(function GridNoRowsOverlay(props, ref) {
const apiRef = useGridApiContext();
const noRowsLabel = apiRef.current.getLocaleText('noRowsLabel');
return /*#__PURE__*/_jsx(GridOverlay, _extends({
ref: ref
}, props, {
children: noRowsLabel
}));
});
process.env.NODE_ENV !== "production" ? GridNoRowsOverlay.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object])
} : void 0;
export { GridNoRowsOverlay };

View File

@@ -0,0 +1,88 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import * as React from 'react';
import PropTypes from 'prop-types';
import TablePagination, { tablePaginationClasses } from '@mui/material/TablePagination';
import { styled } from '@mui/material/styles';
import { useGridSelector } from '../hooks/utils/useGridSelector';
import { useGridApiContext } from '../hooks/utils/useGridApiContext';
import { useGridRootProps } from '../hooks/utils/useGridRootProps';
import { gridPaginationModelSelector, gridPaginationRowCountSelector } from '../hooks/features/pagination/gridPaginationSelector';
import { jsx as _jsx } from "react/jsx-runtime";
const GridPaginationRoot = styled(TablePagination)(({
theme
}) => ({
[`& .${tablePaginationClasses.selectLabel}`]: {
display: 'none',
[theme.breakpoints.up('sm')]: {
display: 'block'
}
},
[`& .${tablePaginationClasses.input}`]: {
display: 'none',
[theme.breakpoints.up('sm')]: {
display: 'inline-flex'
}
}
}));
// A mutable version of a readonly array.
const GridPagination = /*#__PURE__*/React.forwardRef(function GridPagination(props, ref) {
const apiRef = useGridApiContext();
const rootProps = useGridRootProps();
const paginationModel = useGridSelector(apiRef, gridPaginationModelSelector);
const rowCount = useGridSelector(apiRef, gridPaginationRowCountSelector);
const lastPage = React.useMemo(() => Math.floor(rowCount / (paginationModel.pageSize || 1)), [rowCount, paginationModel.pageSize]);
const handlePageSizeChange = React.useCallback(event => {
const pageSize = Number(event.target.value);
apiRef.current.setPageSize(pageSize);
}, [apiRef]);
const handlePageChange = React.useCallback((_, page) => {
apiRef.current.setPage(page);
}, [apiRef]);
const isPageSizeIncludedInPageSizeOptions = pageSize => {
for (let i = 0; i < rootProps.pageSizeOptions.length; i += 1) {
const option = rootProps.pageSizeOptions[i];
if (typeof option === 'number') {
if (option === pageSize) {
return true;
}
} else if (option.value === pageSize) {
return true;
}
}
return false;
};
if (process.env.NODE_ENV !== 'production') {
// eslint-disable-next-line react-hooks/rules-of-hooks
const warnedOnceMissingInPageSizeOptions = React.useRef(false);
const pageSize = rootProps.paginationModel?.pageSize ?? paginationModel.pageSize;
if (!warnedOnceMissingInPageSizeOptions.current && !rootProps.autoPageSize && !isPageSizeIncludedInPageSizeOptions(pageSize)) {
console.warn([`MUI X: The page size \`${paginationModel.pageSize}\` is not preset in the \`pageSizeOptions\`.`, `Add it to show the pagination select.`].join('\n'));
warnedOnceMissingInPageSizeOptions.current = true;
}
}
const pageSizeOptions = isPageSizeIncludedInPageSizeOptions(paginationModel.pageSize) ? rootProps.pageSizeOptions : [];
return /*#__PURE__*/_jsx(GridPaginationRoot, _extends({
ref: ref,
component: "div",
count: rowCount,
page: paginationModel.page <= lastPage ? paginationModel.page : lastPage
// TODO: Remove the cast once the type is fixed in Material UI and that the min Material UI version
// for x-data-grid is past the fix.
// Note that Material UI will not mutate the array, so this is safe.
,
rowsPerPageOptions: pageSizeOptions,
rowsPerPage: paginationModel.pageSize,
onPageChange: handlePageChange,
onRowsPerPageChange: handlePageSizeChange
}, apiRef.current.getLocaleText('MuiTablePagination'), props));
});
process.env.NODE_ENV !== "production" ? GridPagination.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
component: PropTypes.elementType
} : void 0;
export { GridPagination };

View File

@@ -0,0 +1,381 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
const _excluded = ["selected", "hovered", "rowId", "row", "index", "style", "position", "rowHeight", "className", "visibleColumns", "renderedColumns", "containerWidth", "firstColumnToRender", "lastColumnToRender", "isLastVisible", "focusedCellColumnIndexNotInRange", "isNotVisible", "focusedCell", "tabbableCell", "onClick", "onDoubleClick", "onMouseEnter", "onMouseLeave", "onMouseOut", "onMouseOver"];
import * as React from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import { unstable_composeClasses as composeClasses, unstable_useForkRef as useForkRef } from '@mui/utils';
import { fastMemo } from '../utils/fastMemo';
import { GridEditModes, GridRowModes, GridCellModes } from '../models/gridEditRowModel';
import { useGridApiContext } from '../hooks/utils/useGridApiContext';
import { getDataGridUtilityClass, gridClasses } from '../constants/gridClasses';
import { useGridRootProps } from '../hooks/utils/useGridRootProps';
import { gridColumnsTotalWidthSelector } from '../hooks/features/columns/gridColumnsSelector';
import { useGridSelector, objectShallowCompare } from '../hooks/utils/useGridSelector';
import { useGridVisibleRows } from '../hooks/utils/useGridVisibleRows';
import { findParentElementFromClassName, isEventTargetInPortal } from '../utils/domUtils';
import { GRID_CHECKBOX_SELECTION_COL_DEF } from '../colDef/gridCheckboxSelectionColDef';
import { GRID_ACTIONS_COLUMN_TYPE } from '../colDef/gridActionsColDef';
import { GRID_DETAIL_PANEL_TOGGLE_FIELD } from '../constants/gridDetailPanelToggleField';
import { gridSortModelSelector } from '../hooks/features/sorting/gridSortingSelector';
import { gridRowMaximumTreeDepthSelector } from '../hooks/features/rows/gridRowsSelector';
import { gridColumnGroupsHeaderMaxDepthSelector } from '../hooks/features/columnGrouping/gridColumnGroupsSelector';
import { randomNumberBetween } from '../utils/utils';
import { GridCellWrapper, GridCellV7 } from './cell/GridCell';
import { gridEditRowsStateSelector } from '../hooks/features/editing/gridEditingSelectors';
import { jsx as _jsx } from "react/jsx-runtime";
import { jsxs as _jsxs } from "react/jsx-runtime";
const useUtilityClasses = ownerState => {
const {
editable,
editing,
selected,
isLastVisible,
rowHeight,
classes
} = ownerState;
const slots = {
root: ['row', selected && 'selected', editable && 'row--editable', editing && 'row--editing', isLastVisible && 'row--lastVisible', rowHeight === 'auto' && 'row--dynamicHeight']
};
return composeClasses(slots, getDataGridUtilityClass, classes);
};
function EmptyCell({
width
}) {
if (!width) {
return null;
}
const style = {
width
};
return /*#__PURE__*/_jsx("div", {
className: `${gridClasses.cell} ${gridClasses.withBorderColor}`,
style: style
}); // TODO change to .MuiDataGrid-emptyCell or .MuiDataGrid-rowFiller
}
const GridRow = /*#__PURE__*/React.forwardRef(function GridRow(props, refProp) {
const {
selected,
hovered,
rowId,
row,
index,
style: styleProp,
position,
rowHeight,
className,
visibleColumns,
renderedColumns,
containerWidth,
firstColumnToRender,
isLastVisible = false,
focusedCellColumnIndexNotInRange,
isNotVisible,
focusedCell,
onClick,
onDoubleClick,
onMouseEnter,
onMouseLeave,
onMouseOut,
onMouseOver
} = props,
other = _objectWithoutPropertiesLoose(props, _excluded);
const apiRef = useGridApiContext();
const ref = React.useRef(null);
const rootProps = useGridRootProps();
const currentPage = useGridVisibleRows(apiRef, rootProps);
const columnsTotalWidth = useGridSelector(apiRef, gridColumnsTotalWidthSelector);
const sortModel = useGridSelector(apiRef, gridSortModelSelector);
const treeDepth = useGridSelector(apiRef, gridRowMaximumTreeDepthSelector);
const headerGroupingMaxDepth = useGridSelector(apiRef, gridColumnGroupsHeaderMaxDepthSelector);
const editRowsState = useGridSelector(apiRef, gridEditRowsStateSelector);
const handleRef = useForkRef(ref, refProp);
const ariaRowIndex = index + headerGroupingMaxDepth + 2; // 1 for the header row and 1 as it's 1-based
const ownerState = {
selected,
hovered,
isLastVisible,
classes: rootProps.classes,
editing: apiRef.current.getRowMode(rowId) === GridRowModes.Edit,
editable: rootProps.editMode === GridEditModes.Row,
rowHeight
};
const classes = useUtilityClasses(ownerState);
React.useLayoutEffect(() => {
if (rowHeight === 'auto' && ref.current && typeof ResizeObserver === 'undefined') {
// Fallback for IE
apiRef.current.unstable_storeRowHeightMeasurement(rowId, ref.current.clientHeight, position);
}
}, [apiRef, rowHeight, rowId, position]);
React.useLayoutEffect(() => {
if (currentPage.range) {
// The index prop is relative to the rows from all pages. As example, the index prop of the
// first row is 5 if `paginationModel.pageSize=5` and `paginationModel.page=1`. However, the index used by the virtualization
// doesn't care about pagination and considers the rows from the current page only, so the
// first row always has index=0. We need to subtract the index of the first row to make it
// compatible with the index used by the virtualization.
const rowIndex = apiRef.current.getRowIndexRelativeToVisibleRows(rowId);
// pinned rows are not part of the visible rows
if (rowIndex != null) {
apiRef.current.unstable_setLastMeasuredRowIndex(rowIndex);
}
}
const rootElement = ref.current;
const hasFixedHeight = rowHeight !== 'auto';
if (!rootElement || hasFixedHeight || typeof ResizeObserver === 'undefined') {
return undefined;
}
const resizeObserver = new ResizeObserver(entries => {
const [entry] = entries;
const height = entry.borderBoxSize && entry.borderBoxSize.length > 0 ? entry.borderBoxSize[0].blockSize : entry.contentRect.height;
apiRef.current.unstable_storeRowHeightMeasurement(rowId, height, position);
});
resizeObserver.observe(rootElement);
return () => resizeObserver.disconnect();
}, [apiRef, currentPage.range, index, rowHeight, rowId, position]);
const publish = React.useCallback((eventName, propHandler) => event => {
// Ignore portal
if (isEventTargetInPortal(event)) {
return;
}
// The row might have been deleted
if (!apiRef.current.getRow(rowId)) {
return;
}
apiRef.current.publishEvent(eventName, apiRef.current.getRowParams(rowId), event);
if (propHandler) {
propHandler(event);
}
}, [apiRef, rowId]);
const publishClick = React.useCallback(event => {
const cell = findParentElementFromClassName(event.target, gridClasses.cell);
const field = cell?.getAttribute('data-field');
// Check if the field is available because the cell that fills the empty
// space of the row has no field.
if (field) {
// User clicked in the checkbox added by checkboxSelection
if (field === GRID_CHECKBOX_SELECTION_COL_DEF.field) {
return;
}
// User opened a detail panel
if (field === GRID_DETAIL_PANEL_TOGGLE_FIELD) {
return;
}
// User reorders a row
if (field === '__reorder__') {
return;
}
// User is editing a cell
if (apiRef.current.getCellMode(rowId, field) === GridCellModes.Edit) {
return;
}
// User clicked a button from the "actions" column type
const column = apiRef.current.getColumn(field);
if (column?.type === GRID_ACTIONS_COLUMN_TYPE) {
return;
}
}
publish('rowClick', onClick)(event);
}, [apiRef, onClick, publish, rowId]);
const {
slots,
slotProps,
disableColumnReorder
} = rootProps;
const CellComponent = slots.cell === GridCellV7 ? GridCellV7 : GridCellWrapper;
const rowReordering = rootProps.rowReordering;
const getCell = (column, cellProps) => {
const disableDragEvents = disableColumnReorder && column.disableReorder || !rowReordering && !!sortModel.length && treeDepth > 1 && Object.keys(editRowsState).length > 0;
const editCellState = editRowsState[rowId]?.[column.field] ?? null;
let cellIsNotVisible = false;
if (focusedCellColumnIndexNotInRange !== undefined && visibleColumns[focusedCellColumnIndexNotInRange].field === column.field) {
cellIsNotVisible = true;
}
return /*#__PURE__*/_jsx(CellComponent, _extends({
column: column,
width: cellProps.width,
rowId: rowId,
height: rowHeight,
showRightBorder: cellProps.showRightBorder,
align: column.align || 'left',
colIndex: cellProps.indexRelativeToAllColumns,
colSpan: cellProps.colSpan,
disableDragEvents: disableDragEvents,
editCellState: editCellState,
isNotVisible: cellIsNotVisible
}, slotProps?.cell), column.field);
};
const sizes = useGridSelector(apiRef, () => _extends({}, apiRef.current.unstable_getRowInternalSizes(rowId)), objectShallowCompare);
let minHeight = rowHeight;
if (minHeight === 'auto' && sizes) {
let numberOfBaseSizes = 0;
const maximumSize = Object.entries(sizes).reduce((acc, [key, size]) => {
const isBaseHeight = /^base[A-Z]/.test(key);
if (!isBaseHeight) {
return acc;
}
numberOfBaseSizes += 1;
if (size > acc) {
return size;
}
return acc;
}, 0);
if (maximumSize > 0 && numberOfBaseSizes > 1) {
minHeight = maximumSize;
}
}
const style = React.useMemo(() => {
if (isNotVisible) {
return {
opacity: 0,
width: 0,
height: 0
};
}
const rowStyle = _extends({}, styleProp, {
maxHeight: rowHeight === 'auto' ? 'none' : rowHeight,
// max-height doesn't support "auto"
minHeight
});
if (sizes?.spacingTop) {
const property = rootProps.rowSpacingType === 'border' ? 'borderTopWidth' : 'marginTop';
rowStyle[property] = sizes.spacingTop;
}
if (sizes?.spacingBottom) {
const property = rootProps.rowSpacingType === 'border' ? 'borderBottomWidth' : 'marginBottom';
let propertyValue = rowStyle[property];
// avoid overriding existing value
if (typeof propertyValue !== 'number') {
propertyValue = parseInt(propertyValue || '0', 10);
}
propertyValue += sizes.spacingBottom;
rowStyle[property] = propertyValue;
}
return rowStyle;
}, [isNotVisible, rowHeight, styleProp, minHeight, sizes, rootProps.rowSpacingType]);
const rowClassNames = apiRef.current.unstable_applyPipeProcessors('rowClassName', [], rowId);
if (typeof rootProps.getRowClassName === 'function') {
const indexRelativeToCurrentPage = index - (currentPage.range?.firstRowIndex || 0);
const rowParams = _extends({}, apiRef.current.getRowParams(rowId), {
isFirstVisible: indexRelativeToCurrentPage === 0,
isLastVisible: indexRelativeToCurrentPage === currentPage.rows.length - 1,
indexRelativeToCurrentPage
});
rowClassNames.push(rootProps.getRowClassName(rowParams));
}
const randomNumber = randomNumberBetween(10000, 20, 80);
const rowNode = apiRef.current.getRowNode(rowId);
if (!rowNode) {
return null;
}
const rowType = rowNode.type;
const cells = [];
for (let i = 0; i < renderedColumns.length; i += 1) {
const column = renderedColumns[i];
let indexRelativeToAllColumns = firstColumnToRender + i;
if (focusedCellColumnIndexNotInRange !== undefined && focusedCell) {
if (visibleColumns[focusedCellColumnIndexNotInRange].field === column.field) {
indexRelativeToAllColumns = focusedCellColumnIndexNotInRange;
} else {
indexRelativeToAllColumns -= 1;
}
}
const cellColSpanInfo = apiRef.current.unstable_getCellColSpanInfo(rowId, indexRelativeToAllColumns);
if (cellColSpanInfo && !cellColSpanInfo.spannedByColSpan) {
if (rowType !== 'skeletonRow') {
const {
colSpan,
width
} = cellColSpanInfo.cellProps;
const cellProps = {
width,
colSpan,
showRightBorder: rootProps.showCellVerticalBorder,
indexRelativeToAllColumns
};
cells.push(getCell(column, cellProps));
} else {
const {
width
} = cellColSpanInfo.cellProps;
const contentWidth = Math.round(randomNumber());
cells.push( /*#__PURE__*/_jsx(slots.skeletonCell, {
width: width,
contentWidth: contentWidth,
field: column.field,
align: column.align
}, column.field));
}
}
}
const emptyCellWidth = containerWidth - columnsTotalWidth;
const eventHandlers = row ? {
onClick: publishClick,
onDoubleClick: publish('rowDoubleClick', onDoubleClick),
onMouseEnter: publish('rowMouseEnter', onMouseEnter),
onMouseLeave: publish('rowMouseLeave', onMouseLeave),
onMouseOut: publish('rowMouseOut', onMouseOut),
onMouseOver: publish('rowMouseOver', onMouseOver)
} : null;
return /*#__PURE__*/_jsxs("div", _extends({
ref: handleRef,
"data-id": rowId,
"data-rowindex": index,
role: "row",
className: clsx(...rowClassNames, classes.root, className, hovered && 'Mui-hovered'),
"aria-rowindex": ariaRowIndex,
"aria-selected": selected,
style: style
}, eventHandlers, other, {
children: [cells, emptyCellWidth > 0 && /*#__PURE__*/_jsx(EmptyCell, {
width: emptyCellWidth
})]
}));
});
process.env.NODE_ENV !== "production" ? GridRow.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
containerWidth: PropTypes.number.isRequired,
firstColumnToRender: PropTypes.number.isRequired,
/**
* Determines which cell has focus.
* If `null`, no cell in this row has focus.
*/
focusedCell: PropTypes.string,
focusedCellColumnIndexNotInRange: PropTypes.number,
/**
* Index of the row in the whole sorted and filtered dataset.
* If some rows above have expanded children, this index also take those children into account.
*/
index: PropTypes.number.isRequired,
isLastVisible: PropTypes.bool,
isNotVisible: PropTypes.bool,
lastColumnToRender: PropTypes.number.isRequired,
onClick: PropTypes.func,
onDoubleClick: PropTypes.func,
onMouseEnter: PropTypes.func,
onMouseLeave: PropTypes.func,
position: PropTypes.oneOf(['center', 'left', 'right']).isRequired,
renderedColumns: PropTypes.arrayOf(PropTypes.object).isRequired,
row: PropTypes.object,
rowHeight: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.number]).isRequired,
rowId: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,
selected: PropTypes.bool.isRequired,
/**
* Determines which cell should be tabbable by having tabIndex=0.
* If `null`, no cell in this row is in the tab sequence.
*/
tabbableCell: PropTypes.string,
visibleColumns: PropTypes.arrayOf(PropTypes.object).isRequired
} : void 0;
const MemoizedGridRow = fastMemo(GridRow);
export { MemoizedGridRow as GridRow };

View File

@@ -0,0 +1,64 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
const _excluded = ["className", "rowCount", "visibleRowCount"];
import * as React from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import { unstable_composeClasses as composeClasses } from '@mui/utils';
import { styled } from '@mui/system';
import { useGridApiContext } from '../hooks/utils/useGridApiContext';
import { getDataGridUtilityClass } from '../constants/gridClasses';
import { useGridRootProps } from '../hooks/utils/useGridRootProps';
import { jsxs as _jsxs } from "react/jsx-runtime";
const useUtilityClasses = ownerState => {
const {
classes
} = ownerState;
const slots = {
root: ['rowCount']
};
return composeClasses(slots, getDataGridUtilityClass, classes);
};
const GridRowCountRoot = styled('div', {
name: 'MuiDataGrid',
slot: 'RowCount',
overridesResolver: (props, styles) => styles.rowCount
})(({
theme
}) => ({
alignItems: 'center',
display: 'flex',
margin: theme.spacing(0, 2)
}));
const GridRowCount = /*#__PURE__*/React.forwardRef(function GridRowCount(props, ref) {
const {
className,
rowCount,
visibleRowCount
} = props,
other = _objectWithoutPropertiesLoose(props, _excluded);
const apiRef = useGridApiContext();
const ownerState = useGridRootProps();
const classes = useUtilityClasses(ownerState);
if (rowCount === 0) {
return null;
}
const text = visibleRowCount < rowCount ? apiRef.current.getLocaleText('footerTotalVisibleRows')(visibleRowCount, rowCount) : rowCount.toLocaleString();
return /*#__PURE__*/_jsxs(GridRowCountRoot, _extends({
ref: ref,
className: clsx(classes.root, className),
ownerState: ownerState
}, other, {
children: [apiRef.current.getLocaleText('footerTotalRows'), " ", text]
}));
});
process.env.NODE_ENV !== "production" ? GridRowCount.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
rowCount: PropTypes.number.isRequired,
sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
visibleRowCount: PropTypes.number.isRequired
} : void 0;
export { GridRowCount };

View File

@@ -0,0 +1,67 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
const _excluded = ["className", "selectedRowCount"];
import * as React from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import { unstable_composeClasses as composeClasses } from '@mui/utils';
import { styled } from '@mui/system';
import { useGridApiContext } from '../hooks/utils/useGridApiContext';
import { getDataGridUtilityClass } from '../constants/gridClasses';
import { useGridRootProps } from '../hooks/utils/useGridRootProps';
import { jsx as _jsx } from "react/jsx-runtime";
const useUtilityClasses = ownerState => {
const {
classes
} = ownerState;
const slots = {
root: ['selectedRowCount']
};
return composeClasses(slots, getDataGridUtilityClass, classes);
};
const GridSelectedRowCountRoot = styled('div', {
name: 'MuiDataGrid',
slot: 'SelectedRowCount',
overridesResolver: (props, styles) => styles.selectedRowCount
})(({
theme
}) => ({
alignItems: 'center',
display: 'flex',
margin: theme.spacing(0, 2),
visibility: 'hidden',
width: 0,
height: 0,
[theme.breakpoints.up('sm')]: {
visibility: 'visible',
width: 'auto',
height: 'auto'
}
}));
const GridSelectedRowCount = /*#__PURE__*/React.forwardRef(function GridSelectedRowCount(props, ref) {
const {
className,
selectedRowCount
} = props,
other = _objectWithoutPropertiesLoose(props, _excluded);
const apiRef = useGridApiContext();
const ownerState = useGridRootProps();
const classes = useUtilityClasses(ownerState);
const rowSelectedText = apiRef.current.getLocaleText('footerRowSelected')(selectedRowCount);
return /*#__PURE__*/_jsx(GridSelectedRowCountRoot, _extends({
ref: ref,
className: clsx(classes.root, className),
ownerState: ownerState
}, other, {
children: rowSelectedText
}));
});
process.env.NODE_ENV !== "production" ? GridSelectedRowCount.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
selectedRowCount: PropTypes.number.isRequired,
sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object])
} : void 0;
export { GridSelectedRowCount };

View File

@@ -0,0 +1,116 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import * as React from 'react';
import PropTypes from 'prop-types';
import { unstable_useEnhancedEffect as useEnhancedEffect } from '@mui/utils';
import { useGridPrivateApiContext } from '../../hooks/utils/useGridPrivateApiContext';
import { useGridSelector } from '../../hooks/utils/useGridSelector';
import { GridMainContainer } from '../containers/GridMainContainer';
import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
import { gridColumnPositionsSelector, gridColumnVisibilityModelSelector, gridVisibleColumnDefinitionsSelector } from '../../hooks/features/columns/gridColumnsSelector';
import { gridFilterActiveItemsLookupSelector } from '../../hooks/features/filter/gridFilterSelector';
import { gridSortColumnLookupSelector } from '../../hooks/features/sorting/gridSortingSelector';
import { gridTabIndexColumnHeaderSelector, gridTabIndexCellSelector, gridFocusColumnHeaderSelector, unstable_gridTabIndexColumnGroupHeaderSelector, unstable_gridFocusColumnGroupHeaderSelector } from '../../hooks/features/focus/gridFocusStateSelector';
import { gridDensityFactorSelector } from '../../hooks/features/density/densitySelector';
import { gridColumnGroupsHeaderMaxDepthSelector, gridColumnGroupsHeaderStructureSelector } from '../../hooks/features/columnGrouping/gridColumnGroupsSelector';
import { gridColumnMenuSelector } from '../../hooks/features/columnMenu/columnMenuSelector';
import { jsx as _jsx } from "react/jsx-runtime";
import { jsxs as _jsxs } from "react/jsx-runtime";
function GridBody(props) {
const {
VirtualScrollerComponent,
ColumnHeadersProps,
children
} = props;
const apiRef = useGridPrivateApiContext();
const rootProps = useGridRootProps();
const rootRef = React.useRef(null);
const visibleColumns = useGridSelector(apiRef, gridVisibleColumnDefinitionsSelector);
const filterColumnLookup = useGridSelector(apiRef, gridFilterActiveItemsLookupSelector);
const sortColumnLookup = useGridSelector(apiRef, gridSortColumnLookupSelector);
const columnPositions = useGridSelector(apiRef, gridColumnPositionsSelector);
const columnHeaderTabIndexState = useGridSelector(apiRef, gridTabIndexColumnHeaderSelector);
const cellTabIndexState = useGridSelector(apiRef, gridTabIndexCellSelector);
const columnGroupHeaderTabIndexState = useGridSelector(apiRef, unstable_gridTabIndexColumnGroupHeaderSelector);
const columnHeaderFocus = useGridSelector(apiRef, gridFocusColumnHeaderSelector);
const columnGroupHeaderFocus = useGridSelector(apiRef, unstable_gridFocusColumnGroupHeaderSelector);
const densityFactor = useGridSelector(apiRef, gridDensityFactorSelector);
const headerGroupingMaxDepth = useGridSelector(apiRef, gridColumnGroupsHeaderMaxDepthSelector);
const columnMenuState = useGridSelector(apiRef, gridColumnMenuSelector);
const columnVisibility = useGridSelector(apiRef, gridColumnVisibilityModelSelector);
const columnGroupsHeaderStructure = useGridSelector(apiRef, gridColumnGroupsHeaderStructureSelector);
const hasOtherElementInTabSequence = !(columnGroupHeaderTabIndexState === null && columnHeaderTabIndexState === null && cellTabIndexState === null);
useEnhancedEffect(() => {
apiRef.current.computeSizeAndPublishResizeEvent();
const elementToObserve = rootRef.current;
if (typeof ResizeObserver === 'undefined') {
return () => {};
}
let animationFrame;
const observer = new ResizeObserver(() => {
// See https://github.com/mui/mui-x/issues/8733
animationFrame = requestAnimationFrame(() => {
apiRef.current.computeSizeAndPublishResizeEvent();
});
});
if (elementToObserve) {
observer.observe(elementToObserve);
}
return () => {
if (animationFrame) {
window.cancelAnimationFrame(animationFrame);
}
if (elementToObserve) {
observer.unobserve(elementToObserve);
}
};
}, [apiRef]);
const columnHeadersRef = React.useRef(null);
const columnsContainerRef = React.useRef(null);
const virtualScrollerRef = React.useRef(null);
apiRef.current.register('private', {
columnHeadersContainerElementRef: columnsContainerRef,
columnHeadersElementRef: columnHeadersRef,
virtualScrollerRef,
mainElementRef: rootRef
});
const hasDimensions = !!apiRef.current.getRootDimensions();
return /*#__PURE__*/_jsxs(GridMainContainer, {
ref: rootRef,
children: [/*#__PURE__*/_jsx(rootProps.slots.columnHeaders, _extends({
ref: columnsContainerRef,
innerRef: columnHeadersRef,
visibleColumns: visibleColumns,
filterColumnLookup: filterColumnLookup,
sortColumnLookup: sortColumnLookup,
columnPositions: columnPositions,
columnHeaderTabIndexState: columnHeaderTabIndexState,
columnGroupHeaderTabIndexState: columnGroupHeaderTabIndexState,
columnHeaderFocus: columnHeaderFocus,
columnGroupHeaderFocus: columnGroupHeaderFocus,
densityFactor: densityFactor,
headerGroupingMaxDepth: headerGroupingMaxDepth,
columnMenuState: columnMenuState,
columnVisibility: columnVisibility,
columnGroupsHeaderStructure: columnGroupsHeaderStructure,
hasOtherElementInTabSequence: hasOtherElementInTabSequence
}, ColumnHeadersProps)), hasDimensions && /*#__PURE__*/_jsx(VirtualScrollerComponent
// The content is only rendered after dimensions are computed because
// the lazy-loading hook is listening to `renderedRowsIntervalChange`,
// but only does something if the dimensions are also available.
// If this event is published while dimensions haven't been computed,
// the `onFetchRows` prop won't be called during mount.
, {
ref: virtualScrollerRef
}), children]
});
}
process.env.NODE_ENV !== "production" ? GridBody.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
children: PropTypes.node,
ColumnHeadersProps: PropTypes.object,
VirtualScrollerComponent: PropTypes.elementType.isRequired
} : void 0;
export { GridBody };

View File

@@ -0,0 +1,11 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import * as React from 'react';
import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
import { jsx as _jsx } from "react/jsx-runtime";
export function GridFooterPlaceholder() {
const rootProps = useGridRootProps();
if (rootProps.hideFooter) {
return null;
}
return /*#__PURE__*/_jsx(rootProps.slots.footer, _extends({}, rootProps.slotProps?.footer));
}

View File

@@ -0,0 +1,118 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import * as React from 'react';
import PropTypes from 'prop-types';
import { styled } from '@mui/system';
import { unstable_composeClasses as composeClasses, unstable_useEnhancedEffect as useEnhancedEffect } from '@mui/utils';
import clsx from 'clsx';
import { useGridSelector } from '../../hooks/utils/useGridSelector';
import { gridExpandedRowCountSelector } from '../../hooks/features/filter/gridFilterSelector';
import { gridRowCountSelector, gridRowsLoadingSelector } from '../../hooks/features/rows/gridRowsSelector';
import { useGridApiContext } from '../../hooks/utils/useGridApiContext';
import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
import { getMinimalContentHeight } from '../../hooks/features/rows/gridRowsUtils';
import { getDataGridUtilityClass } from '../../constants/gridClasses';
import { jsx as _jsx } from "react/jsx-runtime";
const GridOverlayWrapperRoot = styled('div', {
name: 'MuiDataGrid',
slot: 'OverlayWrapper',
shouldForwardProp: prop => prop !== 'overlayType',
overridesResolver: (props, styles) => styles.overlayWrapper
})(({
overlayType
}) => ({
position: 'sticky',
// To stay in place while scrolling
top: 0,
left: 0,
width: 0,
// To stay above the content instead of shifting it down
height: 0,
// To stay above the content instead of shifting it down
zIndex: overlayType === 'loadingOverlay' ? 5 // Should be above pinned columns, pinned rows, and detail panel
: 4 // Should be above pinned columns and detail panel
}));
const GridOverlayWrapperInner = styled('div', {
name: 'MuiDataGrid',
slot: 'OverlayWrapperInner',
shouldForwardProp: prop => prop !== 'overlayType',
overridesResolver: (props, styles) => styles.overlayWrapperInner
})({});
const useUtilityClasses = ownerState => {
const {
classes
} = ownerState;
const slots = {
root: ['overlayWrapper'],
inner: ['overlayWrapperInner']
};
return composeClasses(slots, getDataGridUtilityClass, classes);
};
function GridOverlayWrapper(props) {
const apiRef = useGridApiContext();
const rootProps = useGridRootProps();
const [viewportInnerSize, setViewportInnerSize] = React.useState(() => apiRef.current.getRootDimensions()?.viewportInnerSize ?? null);
const handleViewportSizeChange = React.useCallback(() => {
setViewportInnerSize(apiRef.current.getRootDimensions()?.viewportInnerSize ?? null);
}, [apiRef]);
useEnhancedEffect(() => {
return apiRef.current.subscribeEvent('viewportInnerSizeChange', handleViewportSizeChange);
}, [apiRef, handleViewportSizeChange]);
let height = viewportInnerSize?.height ?? 0;
if (rootProps.autoHeight && height === 0) {
height = getMinimalContentHeight(apiRef, rootProps.rowHeight); // Give room to show the overlay when there no rows.
}
const classes = useUtilityClasses(_extends({}, props, {
classes: rootProps.classes
}));
if (!viewportInnerSize) {
return null;
}
return /*#__PURE__*/_jsx(GridOverlayWrapperRoot, {
className: clsx(classes.root),
overlayType: props.overlayType,
children: /*#__PURE__*/_jsx(GridOverlayWrapperInner, _extends({
className: clsx(classes.inner),
style: {
height,
width: viewportInnerSize?.width ?? 0
}
}, props))
});
}
process.env.NODE_ENV !== "production" ? GridOverlayWrapper.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
overlayType: PropTypes.string.isRequired
} : void 0;
export function GridOverlays() {
const apiRef = useGridApiContext();
const rootProps = useGridRootProps();
const totalRowCount = useGridSelector(apiRef, gridRowCountSelector);
const visibleRowCount = useGridSelector(apiRef, gridExpandedRowCountSelector);
const loading = useGridSelector(apiRef, gridRowsLoadingSelector);
const showNoRowsOverlay = !loading && totalRowCount === 0;
const showNoResultsOverlay = !loading && totalRowCount > 0 && visibleRowCount === 0;
let overlay = null;
let overlayType = '';
if (showNoRowsOverlay) {
overlay = /*#__PURE__*/_jsx(rootProps.slots.noRowsOverlay, _extends({}, rootProps.slotProps?.noRowsOverlay));
overlayType = 'noRowsOverlay';
}
if (showNoResultsOverlay) {
overlay = /*#__PURE__*/_jsx(rootProps.slots.noResultsOverlay, _extends({}, rootProps.slotProps?.noResultsOverlay));
overlayType = 'noResultsOverlay';
}
if (loading) {
overlay = /*#__PURE__*/_jsx(rootProps.slots.loadingOverlay, _extends({}, rootProps.slotProps?.loadingOverlay));
overlayType = 'loadingOverlay';
}
if (overlay === null) {
return null;
}
return /*#__PURE__*/_jsx(GridOverlayWrapper, {
overlayType: overlayType,
children: overlay
});
}

View File

@@ -0,0 +1,3 @@
export * from './GridBody';
export * from './GridFooterPlaceholder';
export * from './GridOverlays';

View File

@@ -0,0 +1,255 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
const _excluded = ["api", "colDef", "id", "hasFocus", "isEditable", "field", "value", "formattedValue", "row", "rowNode", "cellMode", "tabIndex", "position", "focusElementRef"];
import * as React from 'react';
import PropTypes from 'prop-types';
import MenuList from '@mui/material/MenuList';
import { useTheme } from '@mui/material/styles';
import { unstable_useId as useId } from '@mui/utils';
import { gridClasses } from '../../constants/gridClasses';
import { GridMenu } from '../menu/GridMenu';
import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
import { useGridApiContext } from '../../hooks/utils/useGridApiContext';
import { jsx as _jsx } from "react/jsx-runtime";
import { jsxs as _jsxs } from "react/jsx-runtime";
const hasActions = colDef => typeof colDef.getActions === 'function';
function GridActionsCell(props) {
const {
colDef,
id,
hasFocus,
tabIndex,
position = 'bottom-end',
focusElementRef
} = props,
other = _objectWithoutPropertiesLoose(props, _excluded);
const [focusedButtonIndex, setFocusedButtonIndex] = React.useState(-1);
const [open, setOpen] = React.useState(false);
const apiRef = useGridApiContext();
const rootRef = React.useRef(null);
const buttonRef = React.useRef(null);
const ignoreCallToFocus = React.useRef(false);
const touchRippleRefs = React.useRef({});
const theme = useTheme();
const menuId = useId();
const buttonId = useId();
const rootProps = useGridRootProps();
if (!hasActions(colDef)) {
throw new Error('MUI: Missing the `getActions` property in the `GridColDef`.');
}
const options = colDef.getActions(apiRef.current.getRowParams(id));
const iconButtons = options.filter(option => !option.props.showInMenu);
const menuButtons = options.filter(option => option.props.showInMenu);
const numberOfButtons = iconButtons.length + (menuButtons.length ? 1 : 0);
React.useLayoutEffect(() => {
if (!hasFocus) {
Object.entries(touchRippleRefs.current).forEach(([index, ref]) => {
ref?.stop({}, () => {
delete touchRippleRefs.current[index];
});
});
}
}, [hasFocus]);
React.useEffect(() => {
if (focusedButtonIndex < 0 || !rootRef.current) {
return;
}
if (focusedButtonIndex >= rootRef.current.children.length) {
return;
}
const child = rootRef.current.children[focusedButtonIndex];
child.focus({
preventScroll: true
});
}, [focusedButtonIndex]);
React.useEffect(() => {
if (!hasFocus) {
setFocusedButtonIndex(-1);
ignoreCallToFocus.current = false;
}
}, [hasFocus]);
React.useImperativeHandle(focusElementRef, () => ({
focus() {
// If ignoreCallToFocus is true, then one of the buttons was clicked and the focus is already set
if (!ignoreCallToFocus.current) {
// find the first focusable button and pass the index to the state
const focusableButtonIndex = options.findIndex(o => !o.props.disabled);
setFocusedButtonIndex(focusableButtonIndex);
}
}
}), [options]);
React.useEffect(() => {
if (focusedButtonIndex >= numberOfButtons) {
setFocusedButtonIndex(numberOfButtons - 1);
}
}, [focusedButtonIndex, numberOfButtons]);
const showMenu = () => {
setOpen(true);
setFocusedButtonIndex(numberOfButtons - 1);
ignoreCallToFocus.current = true;
};
const hideMenu = () => {
setOpen(false);
};
const handleTouchRippleRef = index => instance => {
touchRippleRefs.current[index] = instance;
};
const handleButtonClick = (index, onClick) => event => {
setFocusedButtonIndex(index);
ignoreCallToFocus.current = true;
if (onClick) {
onClick(event);
}
};
const handleRootKeyDown = event => {
if (numberOfButtons <= 1) {
return;
}
const getNewIndex = (index, direction) => {
if (index < 0 || index > options.length) {
return index;
}
// for rtl mode we need to reverse the direction
const rtlMod = theme.direction === 'rtl' ? -1 : 1;
const indexMod = (direction === 'left' ? -1 : 1) * rtlMod;
// if the button that should receive focus is disabled go one more step
return options[index + indexMod]?.props.disabled ? getNewIndex(index + indexMod, direction) : index + indexMod;
};
let newIndex = focusedButtonIndex;
if (event.key === 'ArrowRight') {
newIndex = getNewIndex(focusedButtonIndex, 'right');
} else if (event.key === 'ArrowLeft') {
newIndex = getNewIndex(focusedButtonIndex, 'left');
}
if (newIndex < 0 || newIndex >= numberOfButtons) {
return; // We're already in the first or last item = do nothing and let the grid listen the event
}
if (newIndex !== focusedButtonIndex) {
event.preventDefault(); // Prevent scrolling
event.stopPropagation(); // Don't stop propagation for other keys, e.g. ArrowUp
setFocusedButtonIndex(newIndex);
}
};
const handleListKeyDown = event => {
if (event.key === 'Tab') {
event.preventDefault();
}
if (['Tab', 'Escape'].includes(event.key)) {
hideMenu();
}
};
return /*#__PURE__*/_jsxs("div", _extends({
role: "menu",
ref: rootRef,
tabIndex: -1,
className: gridClasses.actionsCell,
onKeyDown: handleRootKeyDown
}, other, {
children: [iconButtons.map((button, index) => /*#__PURE__*/React.cloneElement(button, {
key: index,
touchRippleRef: handleTouchRippleRef(index),
onClick: handleButtonClick(index, button.props.onClick),
tabIndex: focusedButtonIndex === index ? tabIndex : -1
})), menuButtons.length > 0 && buttonId && /*#__PURE__*/_jsx(rootProps.slots.baseIconButton, _extends({
ref: buttonRef,
id: buttonId,
"aria-label": apiRef.current.getLocaleText('actionsCellMore'),
"aria-haspopup": "menu",
"aria-expanded": open,
"aria-controls": open ? menuId : undefined,
role: "menuitem",
size: "small",
onClick: showMenu,
touchRippleRef: handleTouchRippleRef(buttonId),
tabIndex: focusedButtonIndex === iconButtons.length ? tabIndex : -1
}, rootProps.slotProps?.baseIconButton, {
children: /*#__PURE__*/_jsx(rootProps.slots.moreActionsIcon, {
fontSize: "small"
})
})), menuButtons.length > 0 && /*#__PURE__*/_jsx(GridMenu, {
open: open,
target: buttonRef.current,
position: position,
onClose: hideMenu,
children: /*#__PURE__*/_jsx(MenuList, {
id: menuId,
className: gridClasses.menuList,
onKeyDown: handleListKeyDown,
"aria-labelledby": buttonId,
variant: "menu",
autoFocusItem: true,
children: menuButtons.map((button, index) => /*#__PURE__*/React.cloneElement(button, {
key: index,
closeMenu: hideMenu
}))
})
})]
}));
}
process.env.NODE_ENV !== "production" ? GridActionsCell.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
api: PropTypes.object,
/**
* The mode of the cell.
*/
cellMode: PropTypes.oneOf(['edit', 'view']).isRequired,
/**
* The column of the row that the current cell belongs to.
*/
colDef: PropTypes.object.isRequired,
/**
* The column field of the cell that triggered the event.
*/
field: PropTypes.string.isRequired,
/**
* A ref allowing to set imperative focus.
* It can be passed to the element that should receive focus.
* @ignore - do not document.
*/
focusElementRef: PropTypes.oneOfType([PropTypes.func, PropTypes.shape({
current: PropTypes.shape({
focus: PropTypes.func.isRequired
})
})]),
/**
* The cell value formatted with the column valueFormatter.
*/
formattedValue: PropTypes.any,
/**
* If true, the cell is the active element.
*/
hasFocus: PropTypes.bool.isRequired,
/**
* The grid row id.
*/
id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,
/**
* If true, the cell is editable.
*/
isEditable: PropTypes.bool,
position: PropTypes.oneOf(['bottom-end', 'bottom-start', 'bottom', 'left-end', 'left-start', 'left', 'right-end', 'right-start', 'right', 'top-end', 'top-start', 'top']),
/**
* The row model of the row that the current cell belongs to.
*/
row: PropTypes.any.isRequired,
/**
* The node of the row that the current cell belongs to.
*/
rowNode: PropTypes.object.isRequired,
/**
* the tabIndex value.
*/
tabIndex: PropTypes.oneOf([-1, 0]).isRequired,
/**
* The cell value.
* If the column has `valueGetter`, use `params.row` to directly access the fields.
*/
value: PropTypes.any
} : void 0;
export { GridActionsCell };
export const renderActionsCell = params => /*#__PURE__*/_jsx(GridActionsCell, _extends({}, params));

View File

@@ -0,0 +1,73 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
const _excluded = ["label", "icon", "showInMenu", "onClick"],
_excluded2 = ["label", "icon", "showInMenu", "onClick", "closeMenuOnClick", "closeMenu"];
import * as React from 'react';
import PropTypes from 'prop-types';
import MenuItem from '@mui/material/MenuItem';
import ListItemIcon from '@mui/material/ListItemIcon';
import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
import { jsx as _jsx } from "react/jsx-runtime";
import { jsxs as _jsxs } from "react/jsx-runtime";
const GridActionsCellItem = /*#__PURE__*/React.forwardRef((props, ref) => {
const rootProps = useGridRootProps();
if (!props.showInMenu) {
const {
label,
icon,
onClick
} = props,
other = _objectWithoutPropertiesLoose(props, _excluded);
const handleClick = event => {
onClick?.(event);
};
return /*#__PURE__*/_jsx(rootProps.slots.baseIconButton, _extends({
ref: ref,
size: "small",
role: "menuitem",
"aria-label": label
}, other, {
onClick: handleClick
}, rootProps.slotProps?.baseIconButton, {
children: /*#__PURE__*/React.cloneElement(icon, {
fontSize: 'small'
})
}));
}
const {
label,
icon,
onClick,
closeMenuOnClick = true,
closeMenu
} = props,
other = _objectWithoutPropertiesLoose(props, _excluded2);
const handleClick = event => {
onClick?.(event);
if (closeMenuOnClick) {
closeMenu?.();
}
};
return /*#__PURE__*/_jsxs(MenuItem, _extends({
ref: ref
}, other, {
onClick: handleClick,
children: [icon && /*#__PURE__*/_jsx(ListItemIcon, {
children: icon
}), label]
}));
});
process.env.NODE_ENV !== "production" ? GridActionsCellItem.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
/**
* from https://mui.com/material-ui/api/button-base/#ButtonBase-prop-component
*/
component: PropTypes.elementType,
icon: PropTypes.element,
label: PropTypes.string.isRequired,
showInMenu: PropTypes.bool
} : void 0;
export { GridActionsCellItem };

View File

@@ -0,0 +1,112 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
const _excluded = ["id", "value", "formattedValue", "api", "field", "row", "rowNode", "colDef", "cellMode", "isEditable", "hasFocus", "tabIndex"];
import * as React from 'react';
import PropTypes from 'prop-types';
import { unstable_composeClasses as composeClasses } from '@mui/utils';
import { getDataGridUtilityClass } from '../../constants/gridClasses';
import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
import { useGridApiContext } from '../../hooks/utils/useGridApiContext';
import { isAutoGeneratedRow } from '../../hooks/features/rows/gridRowsUtils';
import { jsx as _jsx } from "react/jsx-runtime";
const useUtilityClasses = ownerState => {
const {
classes
} = ownerState;
const slots = {
root: ['booleanCell']
};
return composeClasses(slots, getDataGridUtilityClass, classes);
};
function GridBooleanCellRaw(props) {
const {
value
} = props,
other = _objectWithoutPropertiesLoose(props, _excluded);
const apiRef = useGridApiContext();
const rootProps = useGridRootProps();
const ownerState = {
classes: rootProps.classes
};
const classes = useUtilityClasses(ownerState);
const Icon = React.useMemo(() => value ? rootProps.slots.booleanCellTrueIcon : rootProps.slots.booleanCellFalseIcon, [rootProps.slots.booleanCellFalseIcon, rootProps.slots.booleanCellTrueIcon, value]);
return /*#__PURE__*/_jsx(Icon, _extends({
fontSize: "small",
className: classes.root,
titleAccess: apiRef.current.getLocaleText(value ? 'booleanCellTrueLabel' : 'booleanCellFalseLabel'),
"data-value": Boolean(value)
}, other));
}
process.env.NODE_ENV !== "production" ? GridBooleanCellRaw.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
/**
* GridApi that let you manipulate the grid.
*/
api: PropTypes.object.isRequired,
/**
* The mode of the cell.
*/
cellMode: PropTypes.oneOf(['edit', 'view']).isRequired,
/**
* The column of the row that the current cell belongs to.
*/
colDef: PropTypes.object.isRequired,
/**
* The column field of the cell that triggered the event.
*/
field: PropTypes.string.isRequired,
/**
* A ref allowing to set imperative focus.
* It can be passed to the element that should receive focus.
* @ignore - do not document.
*/
focusElementRef: PropTypes.oneOfType([PropTypes.func, PropTypes.shape({
current: PropTypes.shape({
focus: PropTypes.func.isRequired
})
})]),
/**
* The cell value formatted with the column valueFormatter.
*/
formattedValue: PropTypes.any,
/**
* If true, the cell is the active element.
*/
hasFocus: PropTypes.bool.isRequired,
/**
* The grid row id.
*/
id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,
/**
* If true, the cell is editable.
*/
isEditable: PropTypes.bool,
/**
* The row model of the row that the current cell belongs to.
*/
row: PropTypes.any.isRequired,
/**
* The node of the row that the current cell belongs to.
*/
rowNode: PropTypes.object.isRequired,
/**
* the tabIndex value.
*/
tabIndex: PropTypes.oneOf([-1, 0]).isRequired,
/**
* The cell value.
* If the column has `valueGetter`, use `params.row` to directly access the fields.
*/
value: PropTypes.any
} : void 0;
const GridBooleanCell = /*#__PURE__*/React.memo(GridBooleanCellRaw);
export { GridBooleanCell };
export const renderBooleanCell = params => {
if (isAutoGeneratedRow(params.rowNode)) {
return '';
}
return /*#__PURE__*/_jsx(GridBooleanCell, _extends({}, params));
};

View File

@@ -0,0 +1,648 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
const _excluded = ["changeReason", "unstable_updateValueOnRender"],
_excluded2 = ["align", "children", "editCellState", "colIndex", "column", "cellMode", "field", "formattedValue", "hasFocus", "height", "isEditable", "isSelected", "rowId", "tabIndex", "style", "value", "width", "className", "showRightBorder", "extendRowFullWidth", "row", "colSpan", "disableDragEvents", "isNotVisible", "onClick", "onDoubleClick", "onMouseDown", "onMouseUp", "onMouseOver", "onKeyDown", "onKeyUp", "onDragEnter", "onDragOver"],
_excluded3 = ["column", "rowId", "editCellState", "align", "children", "colIndex", "height", "width", "className", "showRightBorder", "extendRowFullWidth", "row", "colSpan", "disableDragEvents", "isNotVisible", "onClick", "onDoubleClick", "onMouseDown", "onMouseUp", "onMouseOver", "onKeyDown", "onKeyUp", "onDragEnter", "onDragOver", "style"],
_excluded4 = ["changeReason", "unstable_updateValueOnRender"];
import * as React from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import { unstable_useForkRef as useForkRef, unstable_composeClasses as composeClasses, unstable_ownerDocument as ownerDocument, unstable_capitalize as capitalize } from '@mui/utils';
import { fastMemo } from '../../utils/fastMemo';
import { doesSupportPreventScroll } from '../../utils/doesSupportPreventScroll';
import { getDataGridUtilityClass, gridClasses } from '../../constants/gridClasses';
import { GridCellModes } from '../../models';
import { useGridSelector, objectShallowCompare } from '../../hooks/utils/useGridSelector';
import { useGridApiContext } from '../../hooks/utils/useGridApiContext';
import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
import { gridFocusCellSelector } from '../../hooks/features/focus/gridFocusStateSelector';
import { MissingRowIdError } from '../../hooks/features/rows/useGridParamsApi';
import { jsx as _jsx } from "react/jsx-runtime";
const EMPTY_CELL_PARAMS = {
id: -1,
field: '__unset__',
row: {},
rowNode: {
id: -1,
depth: 0,
type: 'leaf',
parent: -1,
groupingKey: null
},
colDef: {
type: 'string',
field: '__unset__',
computedWidth: 0
},
cellMode: GridCellModes.View,
hasFocus: false,
tabIndex: -1,
value: null,
formattedValue: '__unset__',
isEditable: false,
api: {}
};
const useUtilityClasses = ownerState => {
const {
align,
showRightBorder,
isEditable,
isSelected,
isSelectionMode,
classes
} = ownerState;
const slots = {
root: ['cell', `cell--text${capitalize(align)}`, isEditable && 'cell--editable', isSelected && 'selected', showRightBorder && 'cell--withRightBorder', isSelectionMode && !isEditable && 'cell--selectionMode', 'withBorderColor'],
content: ['cellContent']
};
return composeClasses(slots, getDataGridUtilityClass, classes);
};
let warnedOnce = false;
// GridCellWrapper is a compatibility layer for the V6 cell slot. If we can use the more efficient
// `GridCellV7`, we should. That component is a merge of `GridCellWrapper` and `GridCell`.
// TODO(v7): Remove the wrapper & cellV6 and use the cellV7 exclusively.
// TODO(v7): Removing the wrapper will break the docs performance visualization demo.
const GridCellWrapper = /*#__PURE__*/React.forwardRef((props, ref) => {
const {
column,
rowId,
editCellState
} = props;
const apiRef = useGridApiContext();
const rootProps = useGridRootProps();
const field = column.field;
const cellParamsWithAPI = useGridSelector(apiRef, () => {
// This is required because `.getCellParams` tries to get the `state.rows.tree` entry
// associated with `rowId`/`fieldId`, but this selector runs after the state has been
// updated, while `rowId`/`fieldId` reference an entry in the old state.
try {
const cellParams = apiRef.current.getCellParams(rowId, field);
const result = cellParams;
result.api = apiRef.current;
return result;
} catch (e) {
if (e instanceof MissingRowIdError) {
return EMPTY_CELL_PARAMS;
}
throw e;
}
}, objectShallowCompare);
const isSelected = useGridSelector(apiRef, () => apiRef.current.unstable_applyPipeProcessors('isCellSelected', false, {
id: rowId,
field
}));
if (cellParamsWithAPI === EMPTY_CELL_PARAMS) {
return null;
}
const {
cellMode,
hasFocus,
isEditable,
value,
formattedValue
} = cellParamsWithAPI;
const managesOwnFocus = column.type === 'actions';
const tabIndex = (cellMode === 'view' || !isEditable) && !managesOwnFocus ? cellParamsWithAPI.tabIndex : -1;
const {
classes: rootClasses,
getCellClassName
} = rootProps;
const classNames = apiRef.current.unstable_applyPipeProcessors('cellClassName', [], {
id: rowId,
field
});
if (column.cellClassName) {
classNames.push(typeof column.cellClassName === 'function' ? column.cellClassName(cellParamsWithAPI) : column.cellClassName);
}
if (getCellClassName) {
classNames.push(getCellClassName(cellParamsWithAPI));
}
let children;
if (editCellState == null && column.renderCell) {
children = column.renderCell(cellParamsWithAPI);
classNames.push(gridClasses['cell--withRenderer']);
classNames.push(rootClasses?.['cell--withRenderer']);
}
if (editCellState != null && column.renderEditCell) {
const updatedRow = apiRef.current.getRowWithUpdatedValues(rowId, column.field);
// eslint-disable-next-line @typescript-eslint/naming-convention
const editCellStateRest = _objectWithoutPropertiesLoose(editCellState, _excluded);
const params = _extends({}, cellParamsWithAPI, {
row: updatedRow
}, editCellStateRest);
children = column.renderEditCell(params);
classNames.push(gridClasses['cell--editing']);
classNames.push(rootClasses?.['cell--editing']);
}
const {
slots
} = rootProps;
const CellComponent = slots.cell;
const cellProps = _extends({}, props, {
ref,
field,
formattedValue,
hasFocus,
isEditable,
isSelected,
value,
cellMode,
children,
tabIndex,
className: clsx(classNames)
});
return /*#__PURE__*/React.createElement(CellComponent, cellProps);
});
const GridCell = /*#__PURE__*/React.forwardRef((props, ref) => {
const {
align,
children: childrenProp,
colIndex,
column,
cellMode,
field,
formattedValue,
hasFocus,
height,
isEditable,
isSelected,
rowId,
tabIndex,
style: styleProp,
value,
width,
className,
showRightBorder,
colSpan,
disableDragEvents,
isNotVisible,
onClick,
onDoubleClick,
onMouseDown,
onMouseUp,
onMouseOver,
onKeyDown,
onKeyUp,
onDragEnter,
onDragOver
} = props,
other = _objectWithoutPropertiesLoose(props, _excluded2);
const valueToRender = formattedValue == null ? value : formattedValue;
const cellRef = React.useRef(null);
const handleRef = useForkRef(ref, cellRef);
const focusElementRef = React.useRef(null);
const apiRef = useGridApiContext();
const rootProps = useGridRootProps();
const ownerState = {
align,
showRightBorder,
isEditable,
classes: rootProps.classes,
isSelected
};
const classes = useUtilityClasses(ownerState);
const publishMouseUp = React.useCallback(eventName => event => {
const params = apiRef.current.getCellParams(rowId, field || '');
apiRef.current.publishEvent(eventName, params, event);
if (onMouseUp) {
onMouseUp(event);
}
}, [apiRef, field, onMouseUp, rowId]);
const publishMouseDown = React.useCallback(eventName => event => {
const params = apiRef.current.getCellParams(rowId, field || '');
apiRef.current.publishEvent(eventName, params, event);
if (onMouseDown) {
onMouseDown(event);
}
}, [apiRef, field, onMouseDown, rowId]);
const publish = React.useCallback((eventName, propHandler) => event => {
// The row might have been deleted during the click
if (!apiRef.current.getRow(rowId)) {
return;
}
const params = apiRef.current.getCellParams(rowId, field || '');
apiRef.current.publishEvent(eventName, params, event);
if (propHandler) {
propHandler(event);
}
}, [apiRef, field, rowId]);
const style = React.useMemo(() => {
if (isNotVisible) {
return {
padding: 0,
opacity: 0,
width: 0,
border: 0
};
}
const cellStyle = _extends({
minWidth: width,
maxWidth: width,
minHeight: height,
maxHeight: height === 'auto' ? 'none' : height
}, styleProp);
return cellStyle;
}, [width, height, isNotVisible, styleProp]);
React.useEffect(() => {
if (!hasFocus || cellMode === GridCellModes.Edit) {
return;
}
const doc = ownerDocument(apiRef.current.rootElementRef.current);
if (cellRef.current && !cellRef.current.contains(doc.activeElement)) {
const focusableElement = cellRef.current.querySelector('[tabindex="0"]');
const elementToFocus = focusElementRef.current || focusableElement || cellRef.current;
if (doesSupportPreventScroll()) {
elementToFocus.focus({
preventScroll: true
});
} else {
const scrollPosition = apiRef.current.getScrollPosition();
elementToFocus.focus();
apiRef.current.scroll(scrollPosition);
}
}
}, [hasFocus, cellMode, apiRef]);
let handleFocus = other.onFocus;
if (process.env.NODE_ENV === 'test' && rootProps.experimentalFeatures?.warnIfFocusStateIsNotSynced) {
handleFocus = event => {
const focusedCell = gridFocusCellSelector(apiRef);
if (focusedCell?.id === rowId && focusedCell.field === field) {
if (typeof other.onFocus === 'function') {
other.onFocus(event);
}
return;
}
if (!warnedOnce) {
console.warn([`MUI: The cell with id=${rowId} and field=${field} received focus.`, `According to the state, the focus should be at id=${focusedCell?.id}, field=${focusedCell?.field}.`, "Not syncing the state may cause unwanted behaviors since the `cellFocusIn` event won't be fired.", 'Call `fireEvent.mouseUp` before the `fireEvent.click` to sync the focus with the state.'].join('\n'));
warnedOnce = true;
}
};
}
const managesOwnFocus = column.type === 'actions';
let children = childrenProp;
if (children === undefined) {
const valueString = valueToRender?.toString();
children = /*#__PURE__*/_jsx("div", {
className: classes.content,
title: valueString,
role: "presentation",
children: valueString
});
}
if ( /*#__PURE__*/React.isValidElement(children) && managesOwnFocus) {
children = /*#__PURE__*/React.cloneElement(children, {
focusElementRef
});
}
const draggableEventHandlers = disableDragEvents ? null : {
onDragEnter: publish('cellDragEnter', onDragEnter),
onDragOver: publish('cellDragOver', onDragOver)
};
const ariaV7 = rootProps.experimentalFeatures?.ariaV7;
return (
/*#__PURE__*/
// eslint-disable-next-line jsx-a11y/no-static-element-interactions
_jsx("div", _extends({
ref: handleRef,
className: clsx(className, classes.root),
role: ariaV7 ? 'gridcell' : 'cell',
"data-field": field,
"data-colindex": colIndex,
"aria-colindex": colIndex + 1,
"aria-colspan": colSpan,
style: style,
tabIndex: tabIndex,
onClick: publish('cellClick', onClick),
onDoubleClick: publish('cellDoubleClick', onDoubleClick),
onMouseOver: publish('cellMouseOver', onMouseOver),
onMouseDown: publishMouseDown('cellMouseDown'),
onMouseUp: publishMouseUp('cellMouseUp'),
onKeyDown: publish('cellKeyDown', onKeyDown),
onKeyUp: publish('cellKeyUp', onKeyUp)
}, draggableEventHandlers, other, {
onFocus: handleFocus,
children: children
}))
);
});
const MemoizedCellWrapper = fastMemo(GridCellWrapper);
process.env.NODE_ENV !== "production" ? GridCellWrapper.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
align: PropTypes.oneOf(['center', 'left', 'right']),
className: PropTypes.string,
colIndex: PropTypes.number,
colSpan: PropTypes.number,
column: PropTypes.object,
disableDragEvents: PropTypes.bool,
height: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.number]),
onClick: PropTypes.func,
onDoubleClick: PropTypes.func,
onDragEnter: PropTypes.func,
onDragOver: PropTypes.func,
onKeyDown: PropTypes.func,
onMouseDown: PropTypes.func,
onMouseUp: PropTypes.func,
rowId: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
showRightBorder: PropTypes.bool,
width: PropTypes.number
} : void 0;
process.env.NODE_ENV !== "production" ? GridCell.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
align: PropTypes.oneOf(['center', 'left', 'right']),
cellMode: PropTypes.oneOf(['edit', 'view']),
children: PropTypes.node,
className: PropTypes.string,
colIndex: PropTypes.number,
colSpan: PropTypes.number,
column: PropTypes.object,
disableDragEvents: PropTypes.bool,
editCellState: PropTypes.shape({
changeReason: PropTypes.oneOf(['debouncedSetEditCellValue', 'setEditCellValue']),
isProcessingProps: PropTypes.bool,
isValidating: PropTypes.bool,
value: PropTypes.any
}),
isNotVisible: PropTypes.bool,
height: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.number]),
onClick: PropTypes.func,
onDoubleClick: PropTypes.func,
onDragEnter: PropTypes.func,
onDragOver: PropTypes.func,
onKeyDown: PropTypes.func,
onMouseDown: PropTypes.func,
onMouseUp: PropTypes.func,
rowId: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
showRightBorder: PropTypes.bool,
width: PropTypes.number
} : void 0;
export { MemoizedCellWrapper as GridCellWrapper, GridCell };
const GridCellV7 = /*#__PURE__*/React.forwardRef((props, ref) => {
const {
column,
rowId,
editCellState,
align,
colIndex,
height,
width,
className,
showRightBorder,
colSpan,
disableDragEvents,
isNotVisible,
onClick,
onDoubleClick,
onMouseDown,
onMouseUp,
onMouseOver,
onKeyDown,
onKeyUp,
onDragEnter,
onDragOver,
style: styleProp
} = props,
other = _objectWithoutPropertiesLoose(props, _excluded3);
const apiRef = useGridApiContext();
const rootProps = useGridRootProps();
const field = column.field;
const cellParamsWithAPI = useGridSelector(apiRef, () => {
// This is required because `.getCellParams` tries to get the `state.rows.tree` entry
// associated with `rowId`/`fieldId`, but this selector runs after the state has been
// updated, while `rowId`/`fieldId` reference an entry in the old state.
try {
const cellParams = apiRef.current.getCellParams(rowId, field);
const result = cellParams;
result.api = apiRef.current;
return result;
} catch (e) {
if (e instanceof MissingRowIdError) {
return EMPTY_CELL_PARAMS;
}
throw e;
}
}, objectShallowCompare);
const isSelected = useGridSelector(apiRef, () => apiRef.current.unstable_applyPipeProcessors('isCellSelected', false, {
id: rowId,
field
}));
const {
cellMode,
hasFocus,
isEditable,
value,
formattedValue
} = cellParamsWithAPI;
const canManageOwnFocus = column.type === 'actions' && column.getActions?.(apiRef.current.getRowParams(rowId)).some(action => !action.props.disabled);
const tabIndex = (cellMode === 'view' || !isEditable) && !canManageOwnFocus ? cellParamsWithAPI.tabIndex : -1;
const {
classes: rootClasses,
getCellClassName
} = rootProps;
const classNames = apiRef.current.unstable_applyPipeProcessors('cellClassName', [], {
id: rowId,
field
});
if (column.cellClassName) {
classNames.push(typeof column.cellClassName === 'function' ? column.cellClassName(cellParamsWithAPI) : column.cellClassName);
}
if (getCellClassName) {
classNames.push(getCellClassName(cellParamsWithAPI));
}
const valueToRender = formattedValue == null ? value : formattedValue;
const cellRef = React.useRef(null);
const handleRef = useForkRef(ref, cellRef);
const focusElementRef = React.useRef(null);
// @ts-expect-error To access `unstable_cellSelection` flag as it's a `premium` feature
const isSelectionMode = rootProps.unstable_cellSelection ?? false;
const ownerState = {
align,
showRightBorder,
isEditable,
classes: rootProps.classes,
isSelected,
isSelectionMode
};
const classes = useUtilityClasses(ownerState);
const publishMouseUp = React.useCallback(eventName => event => {
const params = apiRef.current.getCellParams(rowId, field || '');
apiRef.current.publishEvent(eventName, params, event);
if (onMouseUp) {
onMouseUp(event);
}
}, [apiRef, field, onMouseUp, rowId]);
const publishMouseDown = React.useCallback(eventName => event => {
const params = apiRef.current.getCellParams(rowId, field || '');
apiRef.current.publishEvent(eventName, params, event);
if (onMouseDown) {
onMouseDown(event);
}
}, [apiRef, field, onMouseDown, rowId]);
const publish = React.useCallback((eventName, propHandler) => event => {
// The row might have been deleted during the click
if (!apiRef.current.getRow(rowId)) {
return;
}
const params = apiRef.current.getCellParams(rowId, field || '');
apiRef.current.publishEvent(eventName, params, event);
if (propHandler) {
propHandler(event);
}
}, [apiRef, field, rowId]);
const style = React.useMemo(() => {
if (isNotVisible) {
return _extends({
padding: 0,
opacity: 0,
width: 0,
border: 0
}, styleProp);
}
const cellStyle = _extends({
minWidth: width,
maxWidth: width,
minHeight: height,
maxHeight: height === 'auto' ? 'none' : height
}, styleProp);
return cellStyle;
}, [width, height, isNotVisible, styleProp]);
React.useEffect(() => {
if (!hasFocus || cellMode === GridCellModes.Edit) {
return;
}
const doc = ownerDocument(apiRef.current.rootElementRef.current);
if (cellRef.current && !cellRef.current.contains(doc.activeElement)) {
const focusableElement = cellRef.current.querySelector('[tabindex="0"]');
const elementToFocus = focusElementRef.current || focusableElement || cellRef.current;
if (doesSupportPreventScroll()) {
elementToFocus.focus({
preventScroll: true
});
} else {
const scrollPosition = apiRef.current.getScrollPosition();
elementToFocus.focus();
apiRef.current.scroll(scrollPosition);
}
}
}, [hasFocus, cellMode, apiRef]);
if (cellParamsWithAPI === EMPTY_CELL_PARAMS) {
return null;
}
let handleFocus = other.onFocus;
if (process.env.NODE_ENV === 'test' && rootProps.experimentalFeatures?.warnIfFocusStateIsNotSynced) {
handleFocus = event => {
const focusedCell = gridFocusCellSelector(apiRef);
if (focusedCell?.id === rowId && focusedCell.field === field) {
if (typeof other.onFocus === 'function') {
other.onFocus(event);
}
return;
}
if (!warnedOnce) {
console.warn([`MUI: The cell with id=${rowId} and field=${field} received focus.`, `According to the state, the focus should be at id=${focusedCell?.id}, field=${focusedCell?.field}.`, "Not syncing the state may cause unwanted behaviors since the `cellFocusIn` event won't be fired.", 'Call `fireEvent.mouseUp` before the `fireEvent.click` to sync the focus with the state.'].join('\n'));
warnedOnce = true;
}
};
}
let children;
if (editCellState == null && column.renderCell) {
children = column.renderCell(cellParamsWithAPI);
classNames.push(gridClasses['cell--withRenderer']);
classNames.push(rootClasses?.['cell--withRenderer']);
}
if (editCellState != null && column.renderEditCell) {
const updatedRow = apiRef.current.getRowWithUpdatedValues(rowId, column.field);
// eslint-disable-next-line @typescript-eslint/naming-convention
const editCellStateRest = _objectWithoutPropertiesLoose(editCellState, _excluded4);
const params = _extends({}, cellParamsWithAPI, {
row: updatedRow
}, editCellStateRest);
children = column.renderEditCell(params);
classNames.push(gridClasses['cell--editing']);
classNames.push(rootClasses?.['cell--editing']);
}
if (children === undefined) {
const valueString = valueToRender?.toString();
children = /*#__PURE__*/_jsx("div", {
className: classes.content,
title: valueString,
role: "presentation",
children: valueString
});
}
if ( /*#__PURE__*/React.isValidElement(children) && canManageOwnFocus) {
children = /*#__PURE__*/React.cloneElement(children, {
focusElementRef
});
}
const draggableEventHandlers = disableDragEvents ? null : {
onDragEnter: publish('cellDragEnter', onDragEnter),
onDragOver: publish('cellDragOver', onDragOver)
};
const ariaV7 = rootProps.experimentalFeatures?.ariaV7;
return (
/*#__PURE__*/
// eslint-disable-next-line jsx-a11y/no-static-element-interactions
_jsx("div", _extends({
ref: handleRef,
className: clsx(className, classNames, classes.root),
role: ariaV7 ? 'gridcell' : 'cell',
"data-field": field,
"data-colindex": colIndex,
"aria-colindex": colIndex + 1,
"aria-colspan": colSpan,
style: style,
tabIndex: tabIndex,
onClick: publish('cellClick', onClick),
onDoubleClick: publish('cellDoubleClick', onDoubleClick),
onMouseOver: publish('cellMouseOver', onMouseOver),
onMouseDown: publishMouseDown('cellMouseDown'),
onMouseUp: publishMouseUp('cellMouseUp'),
onKeyDown: publish('cellKeyDown', onKeyDown),
onKeyUp: publish('cellKeyUp', onKeyUp)
}, draggableEventHandlers, other, {
onFocus: handleFocus,
children: children
}))
);
});
process.env.NODE_ENV !== "production" ? GridCellV7.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
align: PropTypes.oneOf(['center', 'left', 'right']).isRequired,
className: PropTypes.string,
colIndex: PropTypes.number.isRequired,
colSpan: PropTypes.number,
column: PropTypes.object.isRequired,
disableDragEvents: PropTypes.bool,
editCellState: PropTypes.shape({
changeReason: PropTypes.oneOf(['debouncedSetEditCellValue', 'setEditCellValue']),
isProcessingProps: PropTypes.bool,
isValidating: PropTypes.bool,
value: PropTypes.any
}),
height: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.number]).isRequired,
isNotVisible: PropTypes.bool,
onClick: PropTypes.func,
onDoubleClick: PropTypes.func,
onDragEnter: PropTypes.func,
onDragOver: PropTypes.func,
onKeyDown: PropTypes.func,
onMouseDown: PropTypes.func,
onMouseUp: PropTypes.func,
rowId: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,
showRightBorder: PropTypes.bool,
width: PropTypes.number.isRequired
} : void 0;
const MemoizedGridCellV7 = fastMemo(GridCellV7);
export { MemoizedGridCellV7 as GridCellV7 };

View File

@@ -0,0 +1,139 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
const _excluded = ["id", "value", "formattedValue", "api", "field", "row", "rowNode", "colDef", "cellMode", "isEditable", "tabIndex", "className", "hasFocus", "isValidating", "isProcessingProps", "error", "onValueChange"];
import * as React from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import { unstable_composeClasses as composeClasses, unstable_useId as useId, unstable_useEnhancedEffect as useEnhancedEffect } from '@mui/utils';
import { getDataGridUtilityClass } from '../../constants/gridClasses';
import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
import { useGridApiContext } from '../../hooks/utils/useGridApiContext';
import { jsx as _jsx } from "react/jsx-runtime";
const useUtilityClasses = ownerState => {
const {
classes
} = ownerState;
const slots = {
root: ['editBooleanCell']
};
return composeClasses(slots, getDataGridUtilityClass, classes);
};
function GridEditBooleanCell(props) {
const {
id: idProp,
value,
field,
className,
hasFocus,
onValueChange
} = props,
other = _objectWithoutPropertiesLoose(props, _excluded);
const apiRef = useGridApiContext();
const inputRef = React.useRef(null);
const id = useId();
const [valueState, setValueState] = React.useState(value);
const rootProps = useGridRootProps();
const ownerState = {
classes: rootProps.classes
};
const classes = useUtilityClasses(ownerState);
const handleChange = React.useCallback(async event => {
const newValue = event.target.checked;
if (onValueChange) {
await onValueChange(event, newValue);
}
setValueState(newValue);
await apiRef.current.setEditCellValue({
id: idProp,
field,
value: newValue
}, event);
}, [apiRef, field, idProp, onValueChange]);
React.useEffect(() => {
setValueState(value);
}, [value]);
useEnhancedEffect(() => {
if (hasFocus) {
inputRef.current.focus();
}
}, [hasFocus]);
return /*#__PURE__*/_jsx("label", _extends({
htmlFor: id,
className: clsx(classes.root, className)
}, other, {
children: /*#__PURE__*/_jsx(rootProps.slots.baseCheckbox, _extends({
id: id,
inputRef: inputRef,
checked: Boolean(valueState),
onChange: handleChange,
size: "small"
}, rootProps.slotProps?.baseCheckbox))
}));
}
process.env.NODE_ENV !== "production" ? GridEditBooleanCell.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
/**
* GridApi that let you manipulate the grid.
*/
api: PropTypes.object.isRequired,
/**
* The mode of the cell.
*/
cellMode: PropTypes.oneOf(['edit', 'view']).isRequired,
changeReason: PropTypes.oneOf(['debouncedSetEditCellValue', 'setEditCellValue']),
/**
* The column of the row that the current cell belongs to.
*/
colDef: PropTypes.object.isRequired,
/**
* The column field of the cell that triggered the event.
*/
field: PropTypes.string.isRequired,
/**
* The cell value formatted with the column valueFormatter.
*/
formattedValue: PropTypes.any,
/**
* If true, the cell is the active element.
*/
hasFocus: PropTypes.bool.isRequired,
/**
* The grid row id.
*/
id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,
/**
* If true, the cell is editable.
*/
isEditable: PropTypes.bool,
isProcessingProps: PropTypes.bool,
isValidating: PropTypes.bool,
/**
* Callback called when the value is changed by the user.
* @param {React.ChangeEvent<HTMLInputElement>} event The event source of the callback.
* @param {boolean} newValue The value that is going to be passed to `apiRef.current.setEditCellValue`.
* @returns {Promise<void> | void} A promise to be awaited before calling `apiRef.current.setEditCellValue`
*/
onValueChange: PropTypes.func,
/**
* The row model of the row that the current cell belongs to.
*/
row: PropTypes.any.isRequired,
/**
* The node of the row that the current cell belongs to.
*/
rowNode: PropTypes.object.isRequired,
/**
* the tabIndex value.
*/
tabIndex: PropTypes.oneOf([-1, 0]).isRequired,
/**
* The cell value.
* If the column has `valueGetter`, use `params.row` to directly access the fields.
*/
value: PropTypes.any
} : void 0;
export { GridEditBooleanCell };
export const renderEditBooleanCell = params => /*#__PURE__*/_jsx(GridEditBooleanCell, _extends({}, params));

View File

@@ -0,0 +1,188 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
const _excluded = ["id", "value", "formattedValue", "api", "field", "row", "rowNode", "colDef", "cellMode", "isEditable", "tabIndex", "hasFocus", "inputProps", "isValidating", "isProcessingProps", "onValueChange"];
import * as React from 'react';
import PropTypes from 'prop-types';
import { unstable_composeClasses as composeClasses, unstable_useEnhancedEffect as useEnhancedEffect } from '@mui/utils';
import InputBase from '@mui/material/InputBase';
import { styled } from '@mui/material/styles';
import { getDataGridUtilityClass } from '../../constants/gridClasses';
import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
import { useGridApiContext } from '../../hooks/utils/useGridApiContext';
import { jsx as _jsx } from "react/jsx-runtime";
const StyledInputBase = styled(InputBase)({
fontSize: 'inherit'
});
const useUtilityClasses = ownerState => {
const {
classes
} = ownerState;
const slots = {
root: ['editInputCell']
};
return composeClasses(slots, getDataGridUtilityClass, classes);
};
function GridEditDateCell(props) {
const {
id,
value: valueProp,
field,
colDef,
hasFocus,
inputProps,
onValueChange
} = props,
other = _objectWithoutPropertiesLoose(props, _excluded);
const isDateTime = colDef.type === 'dateTime';
const apiRef = useGridApiContext();
const inputRef = React.useRef();
const valueTransformed = React.useMemo(() => {
let parsedDate;
if (valueProp == null) {
parsedDate = null;
} else if (valueProp instanceof Date) {
parsedDate = valueProp;
} else {
parsedDate = new Date((valueProp ?? '').toString());
}
let formattedDate;
if (parsedDate == null || Number.isNaN(parsedDate.getTime())) {
formattedDate = '';
} else {
const localDate = new Date(parsedDate.getTime() - parsedDate.getTimezoneOffset() * 60 * 1000);
formattedDate = localDate.toISOString().substr(0, isDateTime ? 16 : 10);
}
return {
parsed: parsedDate,
formatted: formattedDate
};
}, [valueProp, isDateTime]);
const [valueState, setValueState] = React.useState(valueTransformed);
const rootProps = useGridRootProps();
const ownerState = {
classes: rootProps.classes
};
const classes = useUtilityClasses(ownerState);
const parseValueToDate = React.useCallback(value => {
if (value === '') {
return null;
}
const [date, time] = value.split('T');
const [year, month, day] = date.split('-');
const parsedDate = new Date();
parsedDate.setFullYear(Number(year), Number(month) - 1, Number(day));
parsedDate.setHours(0, 0, 0, 0);
if (time) {
const [hours, minutes] = time.split(':');
parsedDate.setHours(Number(hours), Number(minutes), 0, 0);
}
return parsedDate;
}, []);
const handleChange = React.useCallback(async event => {
const newFormattedDate = event.target.value;
const newParsedDate = parseValueToDate(newFormattedDate);
if (onValueChange) {
await onValueChange(event, newParsedDate);
}
setValueState({
parsed: newParsedDate,
formatted: newFormattedDate
});
apiRef.current.setEditCellValue({
id,
field,
value: newParsedDate
}, event);
}, [apiRef, field, id, onValueChange, parseValueToDate]);
React.useEffect(() => {
setValueState(state => {
if (valueTransformed.parsed !== state.parsed && valueTransformed.parsed?.getTime() !== state.parsed?.getTime()) {
return valueTransformed;
}
return state;
});
}, [valueTransformed]);
useEnhancedEffect(() => {
if (hasFocus) {
inputRef.current.focus();
}
}, [hasFocus]);
return /*#__PURE__*/_jsx(StyledInputBase, _extends({
inputRef: inputRef,
fullWidth: true,
className: classes.root,
type: isDateTime ? 'datetime-local' : 'date',
inputProps: _extends({
max: isDateTime ? '9999-12-31T23:59' : '9999-12-31'
}, inputProps),
value: valueState.formatted,
onChange: handleChange
}, other));
}
process.env.NODE_ENV !== "production" ? GridEditDateCell.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
/**
* GridApi that let you manipulate the grid.
*/
api: PropTypes.object.isRequired,
/**
* The mode of the cell.
*/
cellMode: PropTypes.oneOf(['edit', 'view']).isRequired,
changeReason: PropTypes.oneOf(['debouncedSetEditCellValue', 'setEditCellValue']),
/**
* The column of the row that the current cell belongs to.
*/
colDef: PropTypes.object.isRequired,
/**
* The column field of the cell that triggered the event.
*/
field: PropTypes.string.isRequired,
/**
* The cell value formatted with the column valueFormatter.
*/
formattedValue: PropTypes.any,
/**
* If true, the cell is the active element.
*/
hasFocus: PropTypes.bool.isRequired,
/**
* The grid row id.
*/
id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,
/**
* If true, the cell is editable.
*/
isEditable: PropTypes.bool,
isProcessingProps: PropTypes.bool,
isValidating: PropTypes.bool,
/**
* Callback called when the value is changed by the user.
* @param {React.ChangeEvent<HTMLInputElement>} event The event source of the callback.
* @param {Date | null} newValue The value that is going to be passed to `apiRef.current.setEditCellValue`.
* @returns {Promise<void> | void} A promise to be awaited before calling `apiRef.current.setEditCellValue`
*/
onValueChange: PropTypes.func,
/**
* The row model of the row that the current cell belongs to.
*/
row: PropTypes.any.isRequired,
/**
* The node of the row that the current cell belongs to.
*/
rowNode: PropTypes.object.isRequired,
/**
* the tabIndex value.
*/
tabIndex: PropTypes.oneOf([-1, 0]).isRequired,
/**
* The cell value.
* If the column has `valueGetter`, use `params.row` to directly access the fields.
*/
value: PropTypes.any
} : void 0;
export { GridEditDateCell };
export const renderEditDateCell = params => /*#__PURE__*/_jsx(GridEditDateCell, _extends({}, params));

View File

@@ -0,0 +1,164 @@
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
import _extends from "@babel/runtime/helpers/esm/extends";
const _excluded = ["id", "value", "formattedValue", "api", "field", "row", "rowNode", "colDef", "cellMode", "isEditable", "tabIndex", "hasFocus", "isValidating", "debounceMs", "isProcessingProps", "onValueChange"];
import * as React from 'react';
import PropTypes from 'prop-types';
import { unstable_composeClasses as composeClasses, unstable_useEnhancedEffect as useEnhancedEffect } from '@mui/utils';
import { styled } from '@mui/material/styles';
import InputBase from '@mui/material/InputBase';
import { getDataGridUtilityClass } from '../../constants/gridClasses';
import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
import { useGridApiContext } from '../../hooks/utils/useGridApiContext';
import { jsx as _jsx } from "react/jsx-runtime";
const useUtilityClasses = ownerState => {
const {
classes
} = ownerState;
const slots = {
root: ['editInputCell']
};
return composeClasses(slots, getDataGridUtilityClass, classes);
};
const GridEditInputCellRoot = styled(InputBase, {
name: 'MuiDataGrid',
slot: 'EditInputCell',
overridesResolver: (props, styles) => styles.editInputCell
})(({
theme
}) => _extends({}, theme.typography.body2, {
padding: '1px 0',
'& input': {
padding: '0 16px',
height: '100%'
}
}));
const GridEditInputCell = /*#__PURE__*/React.forwardRef((props, ref) => {
const rootProps = useGridRootProps();
const {
id,
value,
field,
colDef,
hasFocus,
debounceMs = 200,
isProcessingProps,
onValueChange
} = props,
other = _objectWithoutPropertiesLoose(props, _excluded);
const apiRef = useGridApiContext();
const inputRef = React.useRef();
const [valueState, setValueState] = React.useState(value);
const classes = useUtilityClasses(rootProps);
const handleChange = React.useCallback(async event => {
const newValue = event.target.value;
if (onValueChange) {
await onValueChange(event, newValue);
}
const column = apiRef.current.getColumn(field);
let parsedValue = newValue;
if (column.valueParser) {
parsedValue = column.valueParser(newValue, apiRef.current.getCellParams(id, field));
}
setValueState(parsedValue);
apiRef.current.setEditCellValue({
id,
field,
value: parsedValue,
debounceMs,
unstable_skipValueParser: true
}, event);
}, [apiRef, debounceMs, field, id, onValueChange]);
const meta = apiRef.current.unstable_getEditCellMeta(id, field);
React.useEffect(() => {
if (meta?.changeReason !== 'debouncedSetEditCellValue') {
setValueState(value);
}
}, [meta, value]);
useEnhancedEffect(() => {
if (hasFocus) {
inputRef.current.focus();
}
}, [hasFocus]);
return /*#__PURE__*/_jsx(GridEditInputCellRoot, _extends({
ref: ref,
inputRef: inputRef,
className: classes.root,
ownerState: rootProps,
fullWidth: true,
type: colDef.type === 'number' ? colDef.type : 'text',
value: valueState ?? '',
onChange: handleChange,
endAdornment: isProcessingProps ? /*#__PURE__*/_jsx(rootProps.slots.loadIcon, {
fontSize: "small",
color: "action"
}) : undefined
}, other));
});
process.env.NODE_ENV !== "production" ? GridEditInputCell.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
/**
* GridApi that let you manipulate the grid.
*/
api: PropTypes.object.isRequired,
/**
* The mode of the cell.
*/
cellMode: PropTypes.oneOf(['edit', 'view']).isRequired,
changeReason: PropTypes.oneOf(['debouncedSetEditCellValue', 'setEditCellValue']),
/**
* The column of the row that the current cell belongs to.
*/
colDef: PropTypes.object.isRequired,
debounceMs: PropTypes.number,
/**
* The column field of the cell that triggered the event.
*/
field: PropTypes.string.isRequired,
/**
* The cell value formatted with the column valueFormatter.
*/
formattedValue: PropTypes.any,
/**
* If true, the cell is the active element.
*/
hasFocus: PropTypes.bool.isRequired,
/**
* The grid row id.
*/
id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,
/**
* If true, the cell is editable.
*/
isEditable: PropTypes.bool,
isProcessingProps: PropTypes.bool,
isValidating: PropTypes.bool,
/**
* Callback called when the value is changed by the user.
* @param {React.ChangeEvent<HTMLInputElement>} event The event source of the callback.
* @param {Date | null} newValue The value that is going to be passed to `apiRef.current.setEditCellValue`.
* @returns {Promise<void> | void} A promise to be awaited before calling `apiRef.current.setEditCellValue`
*/
onValueChange: PropTypes.func,
/**
* The row model of the row that the current cell belongs to.
*/
row: PropTypes.any.isRequired,
/**
* The node of the row that the current cell belongs to.
*/
rowNode: PropTypes.object.isRequired,
/**
* the tabIndex value.
*/
tabIndex: PropTypes.oneOf([-1, 0]).isRequired,
/**
* The cell value.
* If the column has `valueGetter`, use `params.row` to directly access the fields.
*/
value: PropTypes.any
} : void 0;
export { GridEditInputCell };
export const renderEditInputCell = params => /*#__PURE__*/_jsx(GridEditInputCell, _extends({}, params));

View File

@@ -0,0 +1,213 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
const _excluded = ["id", "value", "formattedValue", "api", "field", "row", "rowNode", "colDef", "cellMode", "isEditable", "tabIndex", "className", "hasFocus", "isValidating", "isProcessingProps", "error", "onValueChange", "initialOpen", "getOptionLabel", "getOptionValue"],
_excluded2 = ["MenuProps"];
import * as React from 'react';
import PropTypes from 'prop-types';
import { unstable_useEnhancedEffect as useEnhancedEffect } from '@mui/utils';
import { GridCellEditStopReasons } from '../../models/params/gridEditCellParams';
import { isEscapeKey } from '../../utils/keyboardUtils';
import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
import { GridEditModes } from '../../models/gridEditRowModel';
import { getValueFromValueOptions, isSingleSelectColDef } from '../panel/filterPanel/filterPanelUtils';
import { useGridApiContext } from '../../hooks/utils/useGridApiContext';
import { createElement as _createElement } from "react";
import { jsx as _jsx } from "react/jsx-runtime";
function isKeyboardEvent(event) {
return !!event.key;
}
function GridEditSingleSelectCell(props) {
const rootProps = useGridRootProps();
const {
id,
value: valueProp,
field,
row,
colDef,
hasFocus,
error,
onValueChange,
initialOpen = rootProps.editMode === GridEditModes.Cell,
getOptionLabel: getOptionLabelProp,
getOptionValue: getOptionValueProp
} = props,
other = _objectWithoutPropertiesLoose(props, _excluded);
const apiRef = useGridApiContext();
const ref = React.useRef();
const inputRef = React.useRef();
const [open, setOpen] = React.useState(initialOpen);
const baseSelectProps = rootProps.slotProps?.baseSelect || {};
const isSelectNative = baseSelectProps.native ?? false;
const _ref = rootProps.slotProps?.baseSelect || {},
{
MenuProps
} = _ref,
otherBaseSelectProps = _objectWithoutPropertiesLoose(_ref, _excluded2);
useEnhancedEffect(() => {
if (hasFocus) {
inputRef.current?.focus();
}
}, [hasFocus]);
if (!isSingleSelectColDef(colDef)) {
return null;
}
let valueOptions;
if (typeof colDef?.valueOptions === 'function') {
valueOptions = colDef?.valueOptions({
id,
row,
field
});
} else {
valueOptions = colDef?.valueOptions;
}
if (!valueOptions) {
return null;
}
const getOptionValue = getOptionValueProp || colDef.getOptionValue;
const getOptionLabel = getOptionLabelProp || colDef.getOptionLabel;
const handleChange = async event => {
if (!isSingleSelectColDef(colDef) || !valueOptions) {
return;
}
setOpen(false);
const target = event.target;
// NativeSelect casts the value to a string.
const formattedTargetValue = getValueFromValueOptions(target.value, valueOptions, getOptionValue);
if (onValueChange) {
await onValueChange(event, formattedTargetValue);
}
await apiRef.current.setEditCellValue({
id,
field,
value: formattedTargetValue
}, event);
};
const handleClose = (event, reason) => {
if (rootProps.editMode === GridEditModes.Row) {
setOpen(false);
return;
}
if (reason === 'backdropClick' || isEscapeKey(event.key)) {
const params = apiRef.current.getCellParams(id, field);
apiRef.current.publishEvent('cellEditStop', _extends({}, params, {
reason: isEscapeKey(event.key) ? GridCellEditStopReasons.escapeKeyDown : GridCellEditStopReasons.cellFocusOut
}));
}
};
const handleOpen = event => {
if (isKeyboardEvent(event) && event.key === 'Enter') {
return;
}
setOpen(true);
};
if (!valueOptions || !colDef) {
return null;
}
return /*#__PURE__*/_jsx(rootProps.slots.baseSelect, _extends({
ref: ref,
inputRef: inputRef,
value: valueProp,
onChange: handleChange,
open: open,
onOpen: handleOpen,
MenuProps: _extends({
onClose: handleClose
}, MenuProps),
error: error,
native: isSelectNative,
fullWidth: true
}, other, otherBaseSelectProps, {
children: valueOptions.map(valueOption => {
const value = getOptionValue(valueOption);
return /*#__PURE__*/_createElement(rootProps.slots.baseSelectOption, _extends({}, rootProps.slotProps?.baseSelectOption || {}, {
native: isSelectNative,
key: value,
value: value
}), getOptionLabel(valueOption));
})
}));
}
process.env.NODE_ENV !== "production" ? GridEditSingleSelectCell.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
/**
* GridApi that let you manipulate the grid.
*/
api: PropTypes.object.isRequired,
/**
* The mode of the cell.
*/
cellMode: PropTypes.oneOf(['edit', 'view']).isRequired,
changeReason: PropTypes.oneOf(['debouncedSetEditCellValue', 'setEditCellValue']),
/**
* The column of the row that the current cell belongs to.
*/
colDef: PropTypes.object.isRequired,
/**
* The column field of the cell that triggered the event.
*/
field: PropTypes.string.isRequired,
/**
* The cell value formatted with the column valueFormatter.
*/
formattedValue: PropTypes.any,
/**
* Used to determine the label displayed for a given value option.
* @param {ValueOptions} value The current value option.
* @returns {string} The text to be displayed.
*/
getOptionLabel: PropTypes.func,
/**
* Used to determine the value used for a value option.
* @param {ValueOptions} value The current value option.
* @returns {string} The value to be used.
*/
getOptionValue: PropTypes.func,
/**
* If true, the cell is the active element.
*/
hasFocus: PropTypes.bool.isRequired,
/**
* The grid row id.
*/
id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,
/**
* If true, the select opens by default.
*/
initialOpen: PropTypes.bool,
/**
* If true, the cell is editable.
*/
isEditable: PropTypes.bool,
isProcessingProps: PropTypes.bool,
isValidating: PropTypes.bool,
/**
* Callback called when the value is changed by the user.
* @param {SelectChangeEvent<any>} event The event source of the callback.
* @param {any} newValue The value that is going to be passed to `apiRef.current.setEditCellValue`.
* @returns {Promise<void> | void} A promise to be awaited before calling `apiRef.current.setEditCellValue`
*/
onValueChange: PropTypes.func,
/**
* The row model of the row that the current cell belongs to.
*/
row: PropTypes.any.isRequired,
/**
* The node of the row that the current cell belongs to.
*/
rowNode: PropTypes.object.isRequired,
/**
* the tabIndex value.
*/
tabIndex: PropTypes.oneOf([-1, 0]).isRequired,
/**
* The cell value.
* If the column has `valueGetter`, use `params.row` to directly access the fields.
*/
value: PropTypes.any
} : void 0;
export { GridEditSingleSelectCell };
export const renderEditSingleSelectCell = params => /*#__PURE__*/_jsx(GridEditSingleSelectCell, _extends({}, params));

View File

@@ -0,0 +1,55 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
const _excluded = ["field", "align", "width", "contentWidth"];
import * as React from 'react';
import PropTypes from 'prop-types';
import Skeleton from '@mui/material/Skeleton';
import { unstable_composeClasses as composeClasses, unstable_capitalize as capitalize } from '@mui/utils';
import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
import { getDataGridUtilityClass } from '../../constants/gridClasses';
import { jsx as _jsx } from "react/jsx-runtime";
const useUtilityClasses = ownerState => {
const {
align,
classes
} = ownerState;
const slots = {
root: ['cell', 'cellSkeleton', `cell--text${capitalize(align)}`, 'withBorderColor']
};
return composeClasses(slots, getDataGridUtilityClass, classes);
};
function GridSkeletonCell(props) {
const {
align,
width,
contentWidth
} = props,
other = _objectWithoutPropertiesLoose(props, _excluded);
const rootProps = useGridRootProps();
const ownerState = {
classes: rootProps.classes,
align
};
const classes = useUtilityClasses(ownerState);
return /*#__PURE__*/_jsx("div", _extends({
className: classes.root,
style: {
width
}
}, other, {
children: /*#__PURE__*/_jsx(Skeleton, {
width: `${contentWidth}%`
})
}));
}
process.env.NODE_ENV !== "production" ? GridSkeletonCell.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
align: PropTypes.string.isRequired,
contentWidth: PropTypes.number.isRequired,
field: PropTypes.string.isRequired,
width: PropTypes.number.isRequired
} : void 0;
export { GridSkeletonCell };

View File

@@ -0,0 +1,9 @@
export { GridCell } from './GridCell';
export * from './GridBooleanCell';
export * from './GridEditBooleanCell';
export * from './GridEditDateCell';
export * from './GridEditInputCell';
export * from './GridEditSingleSelectCell';
export * from './GridActionsCell';
export * from './GridActionsCellItem';
export * from './GridSkeletonCell';

View File

@@ -0,0 +1,62 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import * as React from 'react';
import { unstable_composeClasses as composeClasses } from '@mui/utils';
import { useGridApiContext } from '../../hooks/utils/useGridApiContext';
import { getDataGridUtilityClass } from '../../constants/gridClasses';
import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
import { jsx as _jsx } from "react/jsx-runtime";
const useUtilityClasses = ownerState => {
const {
classes,
open
} = ownerState;
const slots = {
root: ['menuIcon', open && 'menuOpen'],
button: ['menuIconButton']
};
return composeClasses(slots, getDataGridUtilityClass, classes);
};
export const ColumnHeaderMenuIcon = /*#__PURE__*/React.memo(props => {
const {
colDef,
open,
columnMenuId,
columnMenuButtonId,
iconButtonRef
} = props;
const apiRef = useGridApiContext();
const rootProps = useGridRootProps();
const ownerState = _extends({}, props, {
classes: rootProps.classes
});
const classes = useUtilityClasses(ownerState);
const handleMenuIconClick = React.useCallback(event => {
event.preventDefault();
event.stopPropagation();
apiRef.current.toggleColumnMenu(colDef.field);
}, [apiRef, colDef.field]);
return /*#__PURE__*/_jsx("div", {
className: classes.root,
children: /*#__PURE__*/_jsx(rootProps.slots.baseTooltip, _extends({
title: apiRef.current.getLocaleText('columnMenuLabel'),
enterDelay: 1000
}, rootProps.slotProps?.baseTooltip, {
children: /*#__PURE__*/_jsx(rootProps.slots.baseIconButton, _extends({
ref: iconButtonRef,
tabIndex: -1,
className: classes.button,
"aria-label": apiRef.current.getLocaleText('columnMenuLabel'),
size: "small",
onClick: handleMenuIconClick,
"aria-haspopup": "menu",
"aria-expanded": open,
"aria-controls": open ? columnMenuId : undefined,
id: columnMenuButtonId
}, rootProps.slotProps?.baseIconButton, {
children: /*#__PURE__*/_jsx(rootProps.slots.columnMenuIcon, {
fontSize: "small"
})
}))
}))
});
});

View File

@@ -0,0 +1,48 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
const _excluded = ["className"];
import * as React from 'react';
import clsx from 'clsx';
import { unstable_composeClasses as composeClasses } from '@mui/utils';
import { styled } from '@mui/system';
import { getDataGridUtilityClass } from '../../constants/gridClasses';
import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
import { jsx as _jsx } from "react/jsx-runtime";
const useUtilityClasses = ownerState => {
const {
classes
} = ownerState;
const slots = {
root: ['columnHeaders', 'withBorderColor']
};
return composeClasses(slots, getDataGridUtilityClass, classes);
};
const GridColumnHeadersRoot = styled('div', {
name: 'MuiDataGrid',
slot: 'ColumnHeaders',
overridesResolver: (props, styles) => styles.columnHeaders
})({
position: 'relative',
overflow: 'hidden',
display: 'flex',
alignItems: 'center',
boxSizing: 'border-box',
borderBottom: '1px solid',
borderTopLeftRadius: 'var(--unstable_DataGrid-radius)',
borderTopRightRadius: 'var(--unstable_DataGrid-radius)'
});
export const GridBaseColumnHeaders = /*#__PURE__*/React.forwardRef(function GridColumnHeaders(props, ref) {
const {
className
} = props,
other = _objectWithoutPropertiesLoose(props, _excluded);
const rootProps = useGridRootProps();
const classes = useUtilityClasses(rootProps);
return /*#__PURE__*/_jsx(GridColumnHeadersRoot, _extends({
ref: ref,
className: clsx(className, classes.root),
ownerState: rootProps
}, other, {
role: "presentation"
}));
});

View File

@@ -0,0 +1,128 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import * as React from 'react';
import { unstable_useId as useId, unstable_composeClasses as composeClasses } from '@mui/utils';
import { getDataGridUtilityClass } from '../../constants/gridClasses';
import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
import { gridColumnGroupsLookupSelector } from '../../hooks/features/columnGrouping/gridColumnGroupsSelector';
import { useGridApiContext } from '../../hooks/utils/useGridApiContext';
import { useGridSelector } from '../../hooks/utils/useGridSelector';
import { GridGenericColumnHeaderItem } from './GridGenericColumnHeaderItem';
import { isEventTargetInPortal } from '../../utils/domUtils';
import { jsx as _jsx } from "react/jsx-runtime";
const useUtilityClasses = ownerState => {
const {
classes,
headerAlign,
isDragging,
showColumnBorder,
groupId
} = ownerState;
const slots = {
root: ['columnHeader', headerAlign === 'left' && 'columnHeader--alignLeft', headerAlign === 'center' && 'columnHeader--alignCenter', headerAlign === 'right' && 'columnHeader--alignRight', isDragging && 'columnHeader--moving', showColumnBorder && 'columnHeader--showColumnBorder', showColumnBorder && 'columnHeader--withRightBorder', 'withBorderColor', groupId === null ? 'columnHeader--emptyGroup' : 'columnHeader--filledGroup'],
draggableContainer: ['columnHeaderDraggableContainer'],
titleContainer: ['columnHeaderTitleContainer', 'withBorderColor'],
titleContainerContent: ['columnHeaderTitleContainerContent']
};
return composeClasses(slots, getDataGridUtilityClass, classes);
};
function GridColumnGroupHeader(props) {
const {
groupId,
width,
depth,
maxDepth,
fields,
height,
colIndex,
hasFocus,
tabIndex,
isLastColumn
} = props;
const rootProps = useGridRootProps();
const headerCellRef = React.useRef(null);
const apiRef = useGridApiContext();
const columnGroupsLookup = useGridSelector(apiRef, gridColumnGroupsLookupSelector);
const group = groupId ? columnGroupsLookup[groupId] : {};
const {
headerName = groupId ?? '',
description = '',
headerAlign = undefined
} = group;
let headerComponent;
const render = groupId && columnGroupsLookup[groupId]?.renderHeaderGroup;
const renderParams = React.useMemo(() => ({
groupId,
headerName,
description,
depth,
maxDepth,
fields,
colIndex,
isLastColumn
}), [groupId, headerName, description, depth, maxDepth, fields, colIndex, isLastColumn]);
if (groupId && render) {
headerComponent = render(renderParams);
}
const showColumnBorder = rootProps.showColumnVerticalBorder;
const ownerState = _extends({}, props, {
classes: rootProps.classes,
showColumnBorder,
headerAlign,
depth,
isDragging: false
});
const label = headerName ?? groupId;
const id = useId();
const elementId = groupId === null ? `empty-group-cell-${id}` : groupId;
const classes = useUtilityClasses(ownerState);
React.useLayoutEffect(() => {
if (hasFocus) {
const focusableElement = headerCellRef.current.querySelector('[tabindex="0"]');
const elementToFocus = focusableElement || headerCellRef.current;
elementToFocus?.focus();
}
}, [apiRef, hasFocus]);
const publish = React.useCallback(eventName => event => {
// Ignore portal
// See https://github.com/mui/mui-x/issues/1721
if (isEventTargetInPortal(event)) {
return;
}
apiRef.current.publishEvent(eventName, renderParams, event);
},
// For now this is stupid, because renderParams change all the time.
// Need to move it's computation in the api, such that for a given depth+columnField, I can get the group parameters
[apiRef, renderParams]);
const mouseEventsHandlers = React.useMemo(() => ({
onKeyDown: publish('columnGroupHeaderKeyDown'),
onFocus: publish('columnGroupHeaderFocus'),
onBlur: publish('columnGroupHeaderBlur')
}), [publish]);
const headerClassName = typeof group.headerClassName === 'function' ? group.headerClassName(renderParams) : group.headerClassName;
return /*#__PURE__*/_jsx(GridGenericColumnHeaderItem, _extends({
ref: headerCellRef,
classes: classes,
columnMenuOpen: false,
colIndex: colIndex,
height: height,
isResizing: false,
sortDirection: null,
hasFocus: false,
tabIndex: tabIndex,
isDraggable: false,
headerComponent: headerComponent,
headerClassName: headerClassName,
description: description,
elementId: elementId,
width: width,
columnMenuIconButton: null,
columnTitleIconButtons: null,
resizable: false,
label: label,
"aria-colspan": fields.length
// The fields are wrapped between |-...-| to avoid confusion between fields "id" and "id2" when using selector data-fields~=
,
"data-fields": `|-${fields.join('-|-')}-|`
}, mouseEventsHandlers));
}
export { GridColumnGroupHeader };

View File

@@ -0,0 +1,97 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import * as React from 'react';
import PropTypes from 'prop-types';
import { unstable_composeClasses as composeClasses, unstable_useId as useId } from '@mui/utils';
import Badge from '@mui/material/Badge';
import { useGridSelector } from '../../hooks';
import { gridPreferencePanelStateSelector } from '../../hooks/features/preferencesPanel/gridPreferencePanelSelector';
import { GridPreferencePanelsValue } from '../../hooks/features/preferencesPanel/gridPreferencePanelsValue';
import { useGridApiContext } from '../../hooks/utils/useGridApiContext';
import { getDataGridUtilityClass } from '../../constants/gridClasses';
import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
import { GridIconButtonContainer } from './GridIconButtonContainer';
import { jsx as _jsx } from "react/jsx-runtime";
import { jsxs as _jsxs } from "react/jsx-runtime";
const useUtilityClasses = ownerState => {
const {
classes
} = ownerState;
const slots = {
icon: ['filterIcon']
};
return composeClasses(slots, getDataGridUtilityClass, classes);
};
function GridColumnHeaderFilterIconButton(props) {
const {
counter,
field,
onClick
} = props;
const apiRef = useGridApiContext();
const rootProps = useGridRootProps();
const ownerState = _extends({}, props, {
classes: rootProps.classes
});
const classes = useUtilityClasses(ownerState);
const preferencePanel = useGridSelector(apiRef, gridPreferencePanelStateSelector);
const labelId = useId();
const panelId = useId();
const toggleFilter = React.useCallback(event => {
event.preventDefault();
event.stopPropagation();
const {
open,
openedPanelValue
} = gridPreferencePanelStateSelector(apiRef.current.state);
if (open && openedPanelValue === GridPreferencePanelsValue.filters) {
apiRef.current.hideFilterPanel();
} else {
apiRef.current.showFilterPanel(undefined, panelId, labelId);
}
if (onClick) {
onClick(apiRef.current.getColumnHeaderParams(field), event);
}
}, [apiRef, field, onClick, panelId, labelId]);
if (!counter) {
return null;
}
const open = preferencePanel.open && preferencePanel.labelId === labelId;
const iconButton = /*#__PURE__*/_jsx(rootProps.slots.baseIconButton, _extends({
id: labelId,
onClick: toggleFilter,
color: "default",
"aria-label": apiRef.current.getLocaleText('columnHeaderFiltersLabel'),
size: "small",
tabIndex: -1,
"aria-haspopup": "menu",
"aria-expanded": open,
"aria-controls": open ? panelId : undefined
}, rootProps.slotProps?.baseIconButton, {
children: /*#__PURE__*/_jsx(rootProps.slots.columnFilteredIcon, {
className: classes.icon,
fontSize: "small"
})
}));
return /*#__PURE__*/_jsx(rootProps.slots.baseTooltip, _extends({
title: apiRef.current.getLocaleText('columnHeaderFiltersTooltipActive')(counter),
enterDelay: 1000
}, rootProps.slotProps?.baseTooltip, {
children: /*#__PURE__*/_jsxs(GridIconButtonContainer, {
children: [counter > 1 && /*#__PURE__*/_jsx(Badge, {
badgeContent: counter,
color: "default",
children: iconButton
}), counter === 1 && iconButton]
})
}));
}
process.env.NODE_ENV !== "production" ? GridColumnHeaderFilterIconButton.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
counter: PropTypes.number,
field: PropTypes.string.isRequired,
onClick: PropTypes.func
} : void 0;
export { GridColumnHeaderFilterIconButton };

View File

@@ -0,0 +1,199 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import * as React from 'react';
import PropTypes from 'prop-types';
import { unstable_composeClasses as composeClasses, unstable_useId as useId } from '@mui/utils';
import { useGridPrivateApiContext } from '../../hooks/utils/useGridPrivateApiContext';
import { GridColumnHeaderSortIcon } from './GridColumnHeaderSortIcon';
import { ColumnHeaderMenuIcon } from './ColumnHeaderMenuIcon';
import { GridColumnHeaderMenu } from '../menu/columnMenu/GridColumnHeaderMenu';
import { getDataGridUtilityClass } from '../../constants/gridClasses';
import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
import { GridGenericColumnHeaderItem } from './GridGenericColumnHeaderItem';
import { isEventTargetInPortal } from '../../utils/domUtils';
import { jsx as _jsx } from "react/jsx-runtime";
import { jsxs as _jsxs } from "react/jsx-runtime";
const useUtilityClasses = ownerState => {
const {
colDef,
classes,
isDragging,
sortDirection,
showRightBorder,
filterItemsCounter
} = ownerState;
const isColumnSorted = sortDirection != null;
const isColumnFiltered = filterItemsCounter != null && filterItemsCounter > 0;
// todo refactor to a prop on col isNumeric or ?? ie: coltype===price wont work
const isColumnNumeric = colDef.type === 'number';
const slots = {
root: ['columnHeader', colDef.headerAlign === 'left' && 'columnHeader--alignLeft', colDef.headerAlign === 'center' && 'columnHeader--alignCenter', colDef.headerAlign === 'right' && 'columnHeader--alignRight', colDef.sortable && 'columnHeader--sortable', isDragging && 'columnHeader--moving', isColumnSorted && 'columnHeader--sorted', isColumnFiltered && 'columnHeader--filtered', isColumnNumeric && 'columnHeader--numeric', 'withBorderColor', showRightBorder && 'columnHeader--withRightBorder'],
draggableContainer: ['columnHeaderDraggableContainer'],
titleContainer: ['columnHeaderTitleContainer'],
titleContainerContent: ['columnHeaderTitleContainerContent']
};
return composeClasses(slots, getDataGridUtilityClass, classes);
};
function GridColumnHeaderItem(props) {
const {
colDef,
columnMenuOpen,
colIndex,
headerHeight,
isResizing,
sortDirection,
sortIndex,
filterItemsCounter,
hasFocus,
tabIndex,
disableReorder,
separatorSide
} = props;
const apiRef = useGridPrivateApiContext();
const rootProps = useGridRootProps();
const headerCellRef = React.useRef(null);
const columnMenuId = useId();
const columnMenuButtonId = useId();
const iconButtonRef = React.useRef(null);
const [showColumnMenuIcon, setShowColumnMenuIcon] = React.useState(columnMenuOpen);
const isDraggable = React.useMemo(() => !rootProps.disableColumnReorder && !disableReorder && !colDef.disableReorder, [rootProps.disableColumnReorder, disableReorder, colDef.disableReorder]);
let headerComponent;
if (colDef.renderHeader) {
headerComponent = colDef.renderHeader(apiRef.current.getColumnHeaderParams(colDef.field));
}
const ownerState = _extends({}, props, {
classes: rootProps.classes,
showRightBorder: rootProps.showColumnVerticalBorder
});
const classes = useUtilityClasses(ownerState);
const publish = React.useCallback(eventName => event => {
// Ignore portal
// See https://github.com/mui/mui-x/issues/1721
if (isEventTargetInPortal(event)) {
return;
}
apiRef.current.publishEvent(eventName, apiRef.current.getColumnHeaderParams(colDef.field), event);
}, [apiRef, colDef.field]);
const mouseEventsHandlers = React.useMemo(() => ({
onClick: publish('columnHeaderClick'),
onDoubleClick: publish('columnHeaderDoubleClick'),
onMouseOver: publish('columnHeaderOver'),
// TODO remove as it's not used
onMouseOut: publish('columnHeaderOut'),
// TODO remove as it's not used
onMouseEnter: publish('columnHeaderEnter'),
// TODO remove as it's not used
onMouseLeave: publish('columnHeaderLeave'),
// TODO remove as it's not used
onKeyDown: publish('columnHeaderKeyDown'),
onFocus: publish('columnHeaderFocus'),
onBlur: publish('columnHeaderBlur')
}), [publish]);
const draggableEventHandlers = React.useMemo(() => isDraggable ? {
onDragStart: publish('columnHeaderDragStart'),
onDragEnter: publish('columnHeaderDragEnter'),
onDragOver: publish('columnHeaderDragOver'),
onDragEnd: publish('columnHeaderDragEnd')
} : {}, [isDraggable, publish]);
const columnHeaderSeparatorProps = React.useMemo(() => ({
onMouseDown: publish('columnSeparatorMouseDown'),
onDoubleClick: publish('columnSeparatorDoubleClick')
}), [publish]);
React.useEffect(() => {
if (!showColumnMenuIcon) {
setShowColumnMenuIcon(columnMenuOpen);
}
}, [showColumnMenuIcon, columnMenuOpen]);
const handleExited = React.useCallback(() => {
setShowColumnMenuIcon(false);
}, []);
const columnMenuIconButton = !rootProps.disableColumnMenu && !colDef.disableColumnMenu && /*#__PURE__*/_jsx(ColumnHeaderMenuIcon, {
colDef: colDef,
columnMenuId: columnMenuId,
columnMenuButtonId: columnMenuButtonId,
open: showColumnMenuIcon,
iconButtonRef: iconButtonRef
});
const columnMenu = /*#__PURE__*/_jsx(GridColumnHeaderMenu, {
columnMenuId: columnMenuId,
columnMenuButtonId: columnMenuButtonId,
field: colDef.field,
open: columnMenuOpen,
target: iconButtonRef.current,
ContentComponent: rootProps.slots.columnMenu,
contentComponentProps: rootProps.slotProps?.columnMenu,
onExited: handleExited
});
const sortingOrder = colDef.sortingOrder ?? rootProps.sortingOrder;
const columnTitleIconButtons = /*#__PURE__*/_jsxs(React.Fragment, {
children: [!rootProps.disableColumnFilter && /*#__PURE__*/_jsx(rootProps.slots.columnHeaderFilterIconButton, _extends({
field: colDef.field,
counter: filterItemsCounter
}, rootProps.slotProps?.columnHeaderFilterIconButton)), colDef.sortable && !colDef.hideSortIcons && /*#__PURE__*/_jsx(GridColumnHeaderSortIcon, {
direction: sortDirection,
index: sortIndex,
sortingOrder: sortingOrder
})]
});
React.useLayoutEffect(() => {
const columnMenuState = apiRef.current.state.columnMenu;
if (hasFocus && !columnMenuState.open) {
const focusableElement = headerCellRef.current.querySelector('[tabindex="0"]');
const elementToFocus = focusableElement || headerCellRef.current;
elementToFocus?.focus();
if (apiRef.current.columnHeadersContainerElementRef?.current) {
apiRef.current.columnHeadersContainerElementRef.current.scrollLeft = 0;
}
}
}, [apiRef, hasFocus]);
const headerClassName = typeof colDef.headerClassName === 'function' ? colDef.headerClassName({
field: colDef.field,
colDef
}) : colDef.headerClassName;
const label = colDef.headerName ?? colDef.field;
return /*#__PURE__*/_jsx(GridGenericColumnHeaderItem, _extends({
ref: headerCellRef,
classes: classes,
columnMenuOpen: columnMenuOpen,
colIndex: colIndex,
height: headerHeight,
isResizing: isResizing,
sortDirection: sortDirection,
hasFocus: hasFocus,
tabIndex: tabIndex,
separatorSide: separatorSide,
isDraggable: isDraggable,
headerComponent: headerComponent,
description: colDef.description,
elementId: colDef.field,
width: colDef.computedWidth,
columnMenuIconButton: columnMenuIconButton,
columnTitleIconButtons: columnTitleIconButtons,
headerClassName: headerClassName,
label: label,
resizable: !rootProps.disableColumnResize && !!colDef.resizable,
"data-field": colDef.field,
columnMenu: columnMenu,
draggableContainerProps: draggableEventHandlers,
columnHeaderSeparatorProps: columnHeaderSeparatorProps
}, mouseEventsHandlers));
}
process.env.NODE_ENV !== "production" ? GridColumnHeaderItem.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
colDef: PropTypes.object.isRequired,
colIndex: PropTypes.number.isRequired,
columnMenuOpen: PropTypes.bool.isRequired,
disableReorder: PropTypes.bool,
filterItemsCounter: PropTypes.number,
hasFocus: PropTypes.bool,
headerHeight: PropTypes.number.isRequired,
isDragging: PropTypes.bool.isRequired,
isResizing: PropTypes.bool.isRequired,
separatorSide: PropTypes.oneOf(['left', 'right']),
sortDirection: PropTypes.oneOf(['asc', 'desc']),
sortIndex: PropTypes.number,
tabIndex: PropTypes.oneOf([-1, 0]).isRequired
} : void 0;
export { GridColumnHeaderItem };

View File

@@ -0,0 +1,72 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
const _excluded = ["resizable", "resizing", "height", "side"];
import * as React from 'react';
import PropTypes from 'prop-types';
import { unstable_composeClasses as composeClasses, unstable_capitalize as capitalize } from '@mui/utils';
import { getDataGridUtilityClass } from '../../constants/gridClasses';
import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
import { jsx as _jsx } from "react/jsx-runtime";
var GridColumnHeaderSeparatorSides = /*#__PURE__*/function (GridColumnHeaderSeparatorSides) {
GridColumnHeaderSeparatorSides["Left"] = "left";
GridColumnHeaderSeparatorSides["Right"] = "right";
return GridColumnHeaderSeparatorSides;
}(GridColumnHeaderSeparatorSides || {});
const useUtilityClasses = ownerState => {
const {
resizable,
resizing,
classes,
side
} = ownerState;
const slots = {
root: ['columnSeparator', resizable && 'columnSeparator--resizable', resizing && 'columnSeparator--resizing', side && `columnSeparator--side${capitalize(side)}`],
icon: ['iconSeparator']
};
return composeClasses(slots, getDataGridUtilityClass, classes);
};
function GridColumnHeaderSeparatorRaw(props) {
const {
height,
side = GridColumnHeaderSeparatorSides.Right
} = props,
other = _objectWithoutPropertiesLoose(props, _excluded);
const rootProps = useGridRootProps();
const ownerState = _extends({}, props, {
side,
classes: rootProps.classes
});
const classes = useUtilityClasses(ownerState);
const stopClick = React.useCallback(event => {
event.preventDefault();
event.stopPropagation();
}, []);
return (
/*#__PURE__*/
// eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions
_jsx("div", _extends({
className: classes.root,
style: {
minHeight: height,
opacity: rootProps.showColumnVerticalBorder ? 0 : 1
}
}, other, {
onClick: stopClick,
children: /*#__PURE__*/_jsx(rootProps.slots.columnResizeIcon, {
className: classes.icon
})
}))
);
}
const GridColumnHeaderSeparator = /*#__PURE__*/React.memo(GridColumnHeaderSeparatorRaw);
process.env.NODE_ENV !== "production" ? GridColumnHeaderSeparatorRaw.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
height: PropTypes.number.isRequired,
resizable: PropTypes.bool.isRequired,
resizing: PropTypes.bool.isRequired,
side: PropTypes.oneOf(['left', 'right'])
} : void 0;
export { GridColumnHeaderSeparator, GridColumnHeaderSeparatorSides };

View File

@@ -0,0 +1,79 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import * as React from 'react';
import PropTypes from 'prop-types';
import { unstable_composeClasses as composeClasses } from '@mui/utils';
import Badge from '@mui/material/Badge';
import { useGridApiContext } from '../../hooks/utils/useGridApiContext';
import { getDataGridUtilityClass } from '../../constants/gridClasses';
import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
import { GridIconButtonContainer } from './GridIconButtonContainer';
import { jsx as _jsx } from "react/jsx-runtime";
import { jsxs as _jsxs } from "react/jsx-runtime";
const useUtilityClasses = ownerState => {
const {
classes
} = ownerState;
const slots = {
icon: ['sortIcon']
};
return composeClasses(slots, getDataGridUtilityClass, classes);
};
function getIcon(icons, direction, className, sortingOrder) {
let Icon;
const iconProps = {};
if (direction === 'asc') {
Icon = icons.columnSortedAscendingIcon;
} else if (direction === 'desc') {
Icon = icons.columnSortedDescendingIcon;
} else {
Icon = icons.columnUnsortedIcon;
iconProps.sortingOrder = sortingOrder;
}
return Icon ? /*#__PURE__*/_jsx(Icon, _extends({
fontSize: "small",
className: className
}, iconProps)) : null;
}
function GridColumnHeaderSortIconRaw(props) {
const {
direction,
index,
sortingOrder
} = props;
const apiRef = useGridApiContext();
const rootProps = useGridRootProps();
const ownerState = _extends({}, props, {
classes: rootProps.classes
});
const classes = useUtilityClasses(ownerState);
const iconElement = getIcon(rootProps.slots, direction, classes.icon, sortingOrder);
if (!iconElement) {
return null;
}
const iconButton = /*#__PURE__*/_jsx(rootProps.slots.baseIconButton, _extends({
tabIndex: -1,
"aria-label": apiRef.current.getLocaleText('columnHeaderSortIconLabel'),
title: apiRef.current.getLocaleText('columnHeaderSortIconLabel'),
size: "small"
}, rootProps.slotProps?.baseIconButton, {
children: iconElement
}));
return /*#__PURE__*/_jsxs(GridIconButtonContainer, {
children: [index != null && /*#__PURE__*/_jsx(Badge, {
badgeContent: index,
color: "default",
children: iconButton
}), index == null && iconButton]
});
}
const GridColumnHeaderSortIcon = /*#__PURE__*/React.memo(GridColumnHeaderSortIconRaw);
process.env.NODE_ENV !== "production" ? GridColumnHeaderSortIconRaw.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
direction: PropTypes.oneOf(['asc', 'desc']),
index: PropTypes.number,
sortingOrder: PropTypes.arrayOf(PropTypes.oneOf(['asc', 'desc'])).isRequired
} : void 0;
export { GridColumnHeaderSortIcon };

View File

@@ -0,0 +1,83 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
const _excluded = ["className"];
import * as React from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import { unstable_composeClasses as composeClasses } from '@mui/utils';
import { styled } from '@mui/system';
import { isOverflown } from '../../utils/domUtils';
import { getDataGridUtilityClass } from '../../constants/gridClasses';
import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
import { jsx as _jsx } from "react/jsx-runtime";
const useUtilityClasses = ownerState => {
const {
classes
} = ownerState;
const slots = {
root: ['columnHeaderTitle']
};
return composeClasses(slots, getDataGridUtilityClass, classes);
};
const GridColumnHeaderTitleRoot = styled('div', {
name: 'MuiDataGrid',
slot: 'ColumnHeaderTitle',
overridesResolver: (props, styles) => styles.columnHeaderTitle
})({
textOverflow: 'ellipsis',
overflow: 'hidden',
whiteSpace: 'nowrap',
fontWeight: 'var(--unstable_DataGrid-headWeight)'
});
const ColumnHeaderInnerTitle = /*#__PURE__*/React.forwardRef(function ColumnHeaderInnerTitle(props, ref) {
const {
className
} = props,
other = _objectWithoutPropertiesLoose(props, _excluded);
const rootProps = useGridRootProps();
const classes = useUtilityClasses(rootProps);
return /*#__PURE__*/_jsx(GridColumnHeaderTitleRoot, _extends({
ref: ref,
className: clsx(classes.root, className),
ownerState: rootProps
}, other));
});
// No React.memo here as if we display the sort icon, we need to recalculate the isOver
function GridColumnHeaderTitle(props) {
const {
label,
description
} = props;
const rootProps = useGridRootProps();
const titleRef = React.useRef(null);
const [tooltip, setTooltip] = React.useState('');
const handleMouseOver = React.useCallback(() => {
if (!description && titleRef?.current) {
const isOver = isOverflown(titleRef.current);
if (isOver) {
setTooltip(label);
} else {
setTooltip('');
}
}
}, [description, label]);
return /*#__PURE__*/_jsx(rootProps.slots.baseTooltip, _extends({
title: description || tooltip
}, rootProps.slotProps?.baseTooltip, {
children: /*#__PURE__*/_jsx(ColumnHeaderInnerTitle, {
onMouseOver: handleMouseOver,
ref: titleRef,
children: label
})
}));
}
process.env.NODE_ENV !== "production" ? GridColumnHeaderTitle.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
columnWidth: PropTypes.number.isRequired,
description: PropTypes.node,
label: PropTypes.string.isRequired
} : void 0;
export { GridColumnHeaderTitle };

View File

@@ -0,0 +1,58 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
const _excluded = ["isDragging", "className"];
import * as React from 'react';
import clsx from 'clsx';
import { unstable_composeClasses as composeClasses } from '@mui/utils';
import { styled } from '@mui/system';
import { gridClasses, getDataGridUtilityClass } from '../../constants/gridClasses';
import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
import { useGridApiContext } from '../../hooks/utils/useGridApiContext';
import { jsx as _jsx } from "react/jsx-runtime";
const useUtilityClasses = ownerState => {
const {
isDragging,
hasScrollX,
classes
} = ownerState;
const slots = {
root: ['columnHeadersInner', isDragging && 'columnHeaderDropZone', hasScrollX && 'columnHeadersInner--scrollable']
};
return composeClasses(slots, getDataGridUtilityClass, classes);
};
const GridColumnHeadersInnerRoot = styled('div', {
name: 'MuiDataGrid',
slot: 'columnHeadersInner',
overridesResolver: (props, styles) => [{
[`&.${gridClasses.columnHeaderDropZone}`]: styles.columnHeaderDropZone
}, styles.columnHeadersInner]
})(() => ({
display: 'flex',
alignItems: 'flex-start',
flexDirection: 'column',
[`&.${gridClasses.columnHeaderDropZone} .${gridClasses.columnHeaderDraggableContainer}`]: {
cursor: 'move'
},
[`&.${gridClasses['columnHeadersInner--scrollable']} .${gridClasses.columnHeader}:last-child`]: {
borderRight: 'none'
}
}));
export const GridColumnHeadersInner = /*#__PURE__*/React.forwardRef(function GridColumnHeadersInner(props, ref) {
const {
isDragging,
className
} = props,
other = _objectWithoutPropertiesLoose(props, _excluded);
const apiRef = useGridApiContext();
const rootProps = useGridRootProps();
const ownerState = _extends({}, rootProps, {
isDragging,
hasScrollX: apiRef.current.getRootDimensions()?.hasScrollX ?? false
});
const classes = useUtilityClasses(ownerState);
return /*#__PURE__*/_jsx(GridColumnHeadersInnerRoot, _extends({
ref: ref,
className: clsx(className, classes.root),
ownerState: ownerState
}, other));
});

View File

@@ -0,0 +1,101 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
const _excluded = ["classes", "columnMenuOpen", "colIndex", "height", "isResizing", "sortDirection", "hasFocus", "tabIndex", "separatorSide", "isDraggable", "headerComponent", "description", "elementId", "width", "columnMenuIconButton", "columnMenu", "columnTitleIconButtons", "headerClassName", "label", "resizable", "draggableContainerProps", "columnHeaderSeparatorProps"];
import * as React from 'react';
import clsx from 'clsx';
import { unstable_useForkRef as useForkRef } from '@mui/utils';
import { useGridPrivateApiContext } from '../../hooks/utils/useGridPrivateApiContext';
import { GridColumnHeaderTitle } from './GridColumnHeaderTitle';
import { GridColumnHeaderSeparator } from './GridColumnHeaderSeparator';
import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
import { jsx as _jsx } from "react/jsx-runtime";
import { jsxs as _jsxs } from "react/jsx-runtime";
const GridGenericColumnHeaderItem = /*#__PURE__*/React.forwardRef(function GridGenericColumnHeaderItem(props, ref) {
const {
classes,
columnMenuOpen,
colIndex,
height,
isResizing,
sortDirection,
hasFocus,
tabIndex,
separatorSide,
isDraggable,
headerComponent,
description,
width,
columnMenuIconButton = null,
columnMenu = null,
columnTitleIconButtons = null,
headerClassName,
label,
resizable,
draggableContainerProps,
columnHeaderSeparatorProps
} = props,
other = _objectWithoutPropertiesLoose(props, _excluded);
const apiRef = useGridPrivateApiContext();
const rootProps = useGridRootProps();
const headerCellRef = React.useRef(null);
const [showColumnMenuIcon, setShowColumnMenuIcon] = React.useState(columnMenuOpen);
const handleRef = useForkRef(headerCellRef, ref);
let ariaSort = 'none';
if (sortDirection != null) {
ariaSort = sortDirection === 'asc' ? 'ascending' : 'descending';
}
React.useEffect(() => {
if (!showColumnMenuIcon) {
setShowColumnMenuIcon(columnMenuOpen);
}
}, [showColumnMenuIcon, columnMenuOpen]);
React.useLayoutEffect(() => {
const columnMenuState = apiRef.current.state.columnMenu;
if (hasFocus && !columnMenuState.open) {
const focusableElement = headerCellRef.current.querySelector('[tabindex="0"]');
const elementToFocus = focusableElement || headerCellRef.current;
elementToFocus?.focus();
apiRef.current.columnHeadersContainerElementRef.current.scrollLeft = 0;
}
}, [apiRef, hasFocus]);
return /*#__PURE__*/_jsxs("div", _extends({
ref: handleRef,
className: clsx(classes.root, headerClassName),
style: {
height,
width,
minWidth: width,
maxWidth: width
},
role: "columnheader",
tabIndex: tabIndex,
"aria-colindex": colIndex + 1,
"aria-sort": ariaSort,
"aria-label": headerComponent == null ? label : undefined
}, other, {
children: [/*#__PURE__*/_jsxs("div", _extends({
className: classes.draggableContainer,
draggable: isDraggable,
role: "presentation"
}, draggableContainerProps, {
children: [/*#__PURE__*/_jsxs("div", {
className: classes.titleContainer,
role: "presentation",
children: [/*#__PURE__*/_jsx("div", {
className: classes.titleContainerContent,
children: headerComponent !== undefined ? headerComponent : /*#__PURE__*/_jsx(GridColumnHeaderTitle, {
label: label,
description: description,
columnWidth: width
})
}), columnTitleIconButtons]
}), columnMenuIconButton]
})), /*#__PURE__*/_jsx(GridColumnHeaderSeparator, _extends({
resizable: !rootProps.disableColumnResize && !!resizable,
resizing: isResizing,
height: height,
side: separatorSide
}, columnHeaderSeparatorProps)), columnMenu]
}));
});
export { GridGenericColumnHeaderItem };

View File

@@ -0,0 +1,41 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
const _excluded = ["className"];
import * as React from 'react';
import clsx from 'clsx';
import { unstable_composeClasses as composeClasses } from '@mui/utils';
import { styled } from '@mui/system';
import { getDataGridUtilityClass } from '../../constants/gridClasses';
import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
import { jsx as _jsx } from "react/jsx-runtime";
const useUtilityClasses = ownerState => {
const {
classes
} = ownerState;
const slots = {
root: ['iconButtonContainer']
};
return composeClasses(slots, getDataGridUtilityClass, classes);
};
const GridIconButtonContainerRoot = styled('div', {
name: 'MuiDataGrid',
slot: 'IconButtonContainer',
overridesResolver: (props, styles) => styles.iconButtonContainer
})(() => ({
display: 'flex',
visibility: 'hidden',
width: 0
}));
export const GridIconButtonContainer = /*#__PURE__*/React.forwardRef(function GridIconButtonContainer(props, ref) {
const {
className
} = props,
other = _objectWithoutPropertiesLoose(props, _excluded);
const rootProps = useGridRootProps();
const classes = useUtilityClasses(rootProps);
return /*#__PURE__*/_jsx(GridIconButtonContainerRoot, _extends({
ref: ref,
className: clsx(classes.root, className),
ownerState: rootProps
}, other));
});

View File

@@ -0,0 +1,5 @@
export * from './GridColumnHeaderItem';
export * from './GridColumnHeaderSeparator';
export * from './GridColumnHeaderSortIcon';
export * from './GridColumnHeaderFilterIconButton';
export * from './GridColumnHeaderTitle';

View File

@@ -0,0 +1,156 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
const _excluded = ["field", "id", "value", "formattedValue", "row", "rowNode", "colDef", "isEditable", "cellMode", "hasFocus", "tabIndex", "api"];
import * as React from 'react';
import PropTypes from 'prop-types';
import { unstable_composeClasses as composeClasses, unstable_useForkRef as useForkRef } from '@mui/utils';
import { isSpaceKey } from '../../utils/keyboardUtils';
import { useGridApiContext } from '../../hooks/utils/useGridApiContext';
import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
import { getDataGridUtilityClass } from '../../constants/gridClasses';
import { jsx as _jsx } from "react/jsx-runtime";
const useUtilityClasses = ownerState => {
const {
classes
} = ownerState;
const slots = {
root: ['checkboxInput']
};
return composeClasses(slots, getDataGridUtilityClass, classes);
};
const GridCellCheckboxForwardRef = /*#__PURE__*/React.forwardRef(function GridCellCheckboxRenderer(props, ref) {
const {
field,
id,
value: isChecked,
rowNode,
hasFocus,
tabIndex
} = props,
other = _objectWithoutPropertiesLoose(props, _excluded);
const apiRef = useGridApiContext();
const rootProps = useGridRootProps();
const ownerState = {
classes: rootProps.classes
};
const classes = useUtilityClasses(ownerState);
const checkboxElement = React.useRef(null);
const rippleRef = React.useRef(null);
const handleRef = useForkRef(checkboxElement, ref);
const element = apiRef.current.getCellElement(id, field);
const handleChange = event => {
const params = {
value: event.target.checked,
id
};
apiRef.current.publishEvent('rowSelectionCheckboxChange', params, event);
};
React.useLayoutEffect(() => {
if (tabIndex === 0 && element) {
element.tabIndex = -1;
}
}, [element, tabIndex]);
React.useEffect(() => {
if (hasFocus) {
const input = checkboxElement.current?.querySelector('input');
input?.focus({
preventScroll: true
});
} else if (rippleRef.current) {
// Only available in @mui/material v5.4.1 or later
rippleRef.current.stop({});
}
}, [hasFocus]);
const handleKeyDown = React.useCallback(event => {
if (isSpaceKey(event.key)) {
// We call event.stopPropagation to avoid selecting the row and also scrolling to bottom
// TODO: Remove and add a check inside useGridKeyboardNavigation
event.stopPropagation();
}
}, []);
if (rowNode.type === 'footer' || rowNode.type === 'pinnedRow') {
return null;
}
const isSelectable = apiRef.current.isRowSelectable(id);
const label = apiRef.current.getLocaleText(isChecked ? 'checkboxSelectionUnselectRow' : 'checkboxSelectionSelectRow');
return /*#__PURE__*/_jsx(rootProps.slots.baseCheckbox, _extends({
ref: handleRef,
tabIndex: tabIndex,
checked: isChecked,
onChange: handleChange,
className: classes.root,
inputProps: {
'aria-label': label
},
onKeyDown: handleKeyDown,
disabled: !isSelectable,
touchRippleRef: rippleRef
}, rootProps.slotProps?.baseCheckbox, other));
});
process.env.NODE_ENV !== "production" ? GridCellCheckboxForwardRef.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
/**
* GridApi that let you manipulate the grid.
*/
api: PropTypes.object.isRequired,
/**
* The mode of the cell.
*/
cellMode: PropTypes.oneOf(['edit', 'view']).isRequired,
/**
* The column of the row that the current cell belongs to.
*/
colDef: PropTypes.object.isRequired,
/**
* The column field of the cell that triggered the event.
*/
field: PropTypes.string.isRequired,
/**
* A ref allowing to set imperative focus.
* It can be passed to the element that should receive focus.
* @ignore - do not document.
*/
focusElementRef: PropTypes.oneOfType([PropTypes.func, PropTypes.shape({
current: PropTypes.shape({
focus: PropTypes.func.isRequired
})
})]),
/**
* The cell value formatted with the column valueFormatter.
*/
formattedValue: PropTypes.any,
/**
* If true, the cell is the active element.
*/
hasFocus: PropTypes.bool.isRequired,
/**
* The grid row id.
*/
id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,
/**
* If true, the cell is editable.
*/
isEditable: PropTypes.bool,
/**
* The row model of the row that the current cell belongs to.
*/
row: PropTypes.any.isRequired,
/**
* The node of the row that the current cell belongs to.
*/
rowNode: PropTypes.object.isRequired,
/**
* the tabIndex value.
*/
tabIndex: PropTypes.oneOf([-1, 0]).isRequired,
/**
* The cell value.
* If the column has `valueGetter`, use `params.row` to directly access the fields.
*/
value: PropTypes.any
} : void 0;
export { GridCellCheckboxForwardRef };
export const GridCellCheckboxRenderer = GridCellCheckboxForwardRef;

View File

@@ -0,0 +1,122 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
const _excluded = ["field", "colDef"];
import * as React from 'react';
import PropTypes from 'prop-types';
import { unstable_composeClasses as composeClasses } from '@mui/utils';
import { useGridSelector } from '../../hooks/utils/useGridSelector';
import { gridTabIndexColumnHeaderSelector } from '../../hooks/features/focus/gridFocusStateSelector';
import { gridRowSelectionStateSelector } from '../../hooks/features/rowSelection/gridRowSelectionSelector';
import { useGridApiContext } from '../../hooks/utils/useGridApiContext';
import { getDataGridUtilityClass } from '../../constants/gridClasses';
import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
import { gridExpandedSortedRowIdsSelector } from '../../hooks/features/filter/gridFilterSelector';
import { gridPaginatedVisibleSortedGridRowIdsSelector } from '../../hooks/features/pagination/gridPaginationSelector';
import { jsx as _jsx } from "react/jsx-runtime";
const useUtilityClasses = ownerState => {
const {
classes
} = ownerState;
const slots = {
root: ['checkboxInput']
};
return composeClasses(slots, getDataGridUtilityClass, classes);
};
const GridHeaderCheckbox = /*#__PURE__*/React.forwardRef(function GridHeaderCheckbox(props, ref) {
const other = _objectWithoutPropertiesLoose(props, _excluded);
const [, forceUpdate] = React.useState(false);
const apiRef = useGridApiContext();
const rootProps = useGridRootProps();
const ownerState = {
classes: rootProps.classes
};
const classes = useUtilityClasses(ownerState);
const tabIndexState = useGridSelector(apiRef, gridTabIndexColumnHeaderSelector);
const selection = useGridSelector(apiRef, gridRowSelectionStateSelector);
const visibleRowIds = useGridSelector(apiRef, gridExpandedSortedRowIdsSelector);
const paginatedVisibleRowIds = useGridSelector(apiRef, gridPaginatedVisibleSortedGridRowIdsSelector);
const filteredSelection = React.useMemo(() => {
if (typeof rootProps.isRowSelectable !== 'function') {
return selection;
}
return selection.filter(id => {
// The row might have been deleted
if (!apiRef.current.getRow(id)) {
return false;
}
return rootProps.isRowSelectable(apiRef.current.getRowParams(id));
});
}, [apiRef, rootProps.isRowSelectable, selection]);
// All the rows that could be selected / unselected by toggling this checkbox
const selectionCandidates = React.useMemo(() => {
const rowIds = !rootProps.pagination || !rootProps.checkboxSelectionVisibleOnly ? visibleRowIds : paginatedVisibleRowIds;
// Convert to an object to make O(1) checking if a row exists or not
// TODO create selector that returns visibleRowIds/paginatedVisibleRowIds as an object
return rowIds.reduce((acc, id) => {
acc[id] = true;
return acc;
}, {});
}, [rootProps.pagination, rootProps.checkboxSelectionVisibleOnly, paginatedVisibleRowIds, visibleRowIds]);
// Amount of rows selected and that are visible in the current page
const currentSelectionSize = React.useMemo(() => filteredSelection.filter(id => selectionCandidates[id]).length, [filteredSelection, selectionCandidates]);
const isIndeterminate = currentSelectionSize > 0 && currentSelectionSize < Object.keys(selectionCandidates).length;
const isChecked = currentSelectionSize > 0;
const handleChange = event => {
const params = {
value: event.target.checked
};
apiRef.current.publishEvent('headerSelectionCheckboxChange', params);
};
const tabIndex = tabIndexState !== null && tabIndexState.field === props.field ? 0 : -1;
React.useLayoutEffect(() => {
const element = apiRef.current.getColumnHeaderElement(props.field);
if (tabIndex === 0 && element) {
element.tabIndex = -1;
}
}, [tabIndex, apiRef, props.field]);
const handleKeyDown = React.useCallback(event => {
if (event.key === ' ') {
// imperative toggle the checkbox because Space is disable by some preventDefault
apiRef.current.publishEvent('headerSelectionCheckboxChange', {
value: !isChecked
});
}
}, [apiRef, isChecked]);
const handleSelectionChange = React.useCallback(() => {
forceUpdate(p => !p);
}, []);
React.useEffect(() => {
return apiRef.current.subscribeEvent('rowSelectionChange', handleSelectionChange);
}, [apiRef, handleSelectionChange]);
const label = apiRef.current.getLocaleText(isChecked ? 'checkboxSelectionUnselectAllRows' : 'checkboxSelectionSelectAllRows');
return /*#__PURE__*/_jsx(rootProps.slots.baseCheckbox, _extends({
ref: ref,
indeterminate: isIndeterminate,
checked: isChecked,
onChange: handleChange,
className: classes.root,
inputProps: {
'aria-label': label
},
tabIndex: tabIndex,
onKeyDown: handleKeyDown
}, rootProps.slotProps?.baseCheckbox, other));
});
process.env.NODE_ENV !== "production" ? GridHeaderCheckbox.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
/**
* The column of the current header component.
*/
colDef: PropTypes.object.isRequired,
/**
* The column field of the column that triggered the event
*/
field: PropTypes.string.isRequired
} : void 0;
export { GridHeaderCheckbox };

View File

@@ -0,0 +1,2 @@
export * from './GridCellCheckboxRenderer';
export * from './GridHeaderCheckbox';

View File

@@ -0,0 +1,52 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
const _excluded = ["className"];
import * as React from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import { unstable_composeClasses as composeClasses } from '@mui/utils';
import { styled } from '@mui/system';
import { getDataGridUtilityClass } from '../../constants/gridClasses';
import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
import { jsx as _jsx } from "react/jsx-runtime";
const useUtilityClasses = ownerState => {
const {
classes
} = ownerState;
const slots = {
root: ['footerContainer', 'withBorderColor']
};
return composeClasses(slots, getDataGridUtilityClass, classes);
};
const GridFooterContainerRoot = styled('div', {
name: 'MuiDataGrid',
slot: 'FooterContainer',
overridesResolver: (props, styles) => styles.footerContainer
})({
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
minHeight: 52,
borderTop: '1px solid'
});
const GridFooterContainer = /*#__PURE__*/React.forwardRef(function GridFooterContainer(props, ref) {
const {
className
} = props,
other = _objectWithoutPropertiesLoose(props, _excluded);
const rootProps = useGridRootProps();
const classes = useUtilityClasses(rootProps);
return /*#__PURE__*/_jsx(GridFooterContainerRoot, _extends({
ref: ref,
className: clsx(classes.root, className),
ownerState: rootProps
}, other));
});
process.env.NODE_ENV !== "production" ? GridFooterContainer.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object])
} : void 0;
export { GridFooterContainer };

View File

@@ -0,0 +1,42 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import * as React from 'react';
import { unstable_composeClasses as composeClasses } from '@mui/utils';
import { styled } from '@mui/system';
import { getDataGridUtilityClass } from '../../constants/gridClasses';
import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
import { useGridAriaAttributes } from '../../hooks/utils/useGridAriaAttributes';
import { jsx as _jsx } from "react/jsx-runtime";
const useUtilityClasses = ownerState => {
const {
classes
} = ownerState;
const slots = {
root: ['main']
};
return composeClasses(slots, getDataGridUtilityClass, classes);
};
const GridMainContainerRoot = styled('div', {
name: 'MuiDataGrid',
slot: 'Main',
overridesResolver: (props, styles) => styles.main
})(() => ({
position: 'relative',
flexGrow: 1,
display: 'flex',
flexDirection: 'column',
overflow: 'hidden'
}));
export const GridMainContainer = /*#__PURE__*/React.forwardRef((props, ref) => {
const rootProps = useGridRootProps();
const classes = useUtilityClasses(rootProps);
const getAriaAttributes = rootProps.experimentalFeatures?.ariaV7 // ariaV7 should never change
? useGridAriaAttributes : null;
const ariaAttributes = typeof getAriaAttributes === 'function' ? getAriaAttributes() : null;
return /*#__PURE__*/_jsx(GridMainContainerRoot, _extends({
ref: ref,
className: classes.root,
ownerState: rootProps
}, ariaAttributes, {
children: props.children
}));
});

View File

@@ -0,0 +1,54 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
const _excluded = ["className"];
import * as React from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import { unstable_composeClasses as composeClasses } from '@mui/utils';
import { styled } from '@mui/system';
import { getDataGridUtilityClass } from '../../constants/gridClasses';
import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
import { jsx as _jsx } from "react/jsx-runtime";
const useUtilityClasses = ownerState => {
const {
classes
} = ownerState;
const slots = {
root: ['overlay']
};
return composeClasses(slots, getDataGridUtilityClass, classes);
};
const GridOverlayRoot = styled('div', {
name: 'MuiDataGrid',
slot: 'Overlay',
overridesResolver: (_, styles) => styles.overlay
})({
width: '100%',
height: '100%',
display: 'flex',
alignSelf: 'center',
alignItems: 'center',
justifyContent: 'center',
backgroundColor: 'var(--unstable_DataGrid-overlayBackground)'
});
const GridOverlay = /*#__PURE__*/React.forwardRef(function GridOverlay(props, ref) {
const {
className
} = props,
other = _objectWithoutPropertiesLoose(props, _excluded);
const rootProps = useGridRootProps();
const classes = useUtilityClasses(rootProps);
return /*#__PURE__*/_jsx(GridOverlayRoot, _extends({
ref: ref,
className: clsx(classes.root, className),
ownerState: rootProps
}, other));
});
process.env.NODE_ENV !== "production" ? GridOverlay.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object])
} : void 0;
export { GridOverlay };

View File

@@ -0,0 +1,75 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
const _excluded = ["children", "className"];
import * as React from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import { unstable_useForkRef as useForkRef, unstable_useEnhancedEffect as useEnhancedEffect, unstable_capitalize as capitalize, unstable_composeClasses as composeClasses } from '@mui/utils';
import { GridRootStyles } from './GridRootStyles';
import { useGridSelector } from '../../hooks/utils/useGridSelector';
import { useGridPrivateApiContext } from '../../hooks/utils/useGridPrivateApiContext';
import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
import { getDataGridUtilityClass } from '../../constants/gridClasses';
import { gridDensityValueSelector } from '../../hooks/features/density/densitySelector';
import { useGridAriaAttributes } from '../../hooks/utils/useGridAriaAttributes';
import { jsx as _jsx } from "react/jsx-runtime";
const useUtilityClasses = ownerState => {
const {
autoHeight,
density,
classes
} = ownerState;
const slots = {
root: ['root', autoHeight && 'autoHeight', `root--density${capitalize(density)}`, 'withBorderColor']
};
return composeClasses(slots, getDataGridUtilityClass, classes);
};
const GridRoot = /*#__PURE__*/React.forwardRef(function GridRoot(props, ref) {
const rootProps = useGridRootProps();
const {
children,
className
} = props,
other = _objectWithoutPropertiesLoose(props, _excluded);
const apiRef = useGridPrivateApiContext();
const densityValue = useGridSelector(apiRef, gridDensityValueSelector);
const rootContainerRef = React.useRef(null);
const handleRef = useForkRef(rootContainerRef, ref);
const getAriaAttributes = rootProps.experimentalFeatures?.ariaV7 // ariaV7 should never change
? null : useGridAriaAttributes;
const ariaAttributes = typeof getAriaAttributes === 'function' ? getAriaAttributes() : null;
const ownerState = _extends({}, rootProps, {
density: densityValue
});
const classes = useUtilityClasses(ownerState);
apiRef.current.register('public', {
rootElementRef: rootContainerRef
});
// Our implementation of <NoSsr />
const [mountedState, setMountedState] = React.useState(false);
useEnhancedEffect(() => {
setMountedState(true);
}, []);
if (!mountedState) {
return null;
}
return /*#__PURE__*/_jsx(GridRootStyles, _extends({
ref: handleRef,
className: clsx(className, classes.root),
ownerState: ownerState
}, ariaAttributes, other, {
children: children
}));
});
process.env.NODE_ENV !== "production" ? GridRoot.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
/**
* The system prop that allows defining system overrides as well as additional CSS styles.
*/
sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object])
} : void 0;
export { GridRoot };

View File

@@ -0,0 +1,523 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import { alpha, styled, darken, lighten } from '@mui/material/styles';
import { gridClasses } from '../../constants/gridClasses';
function getBorderColor(theme) {
if (theme.vars) {
return theme.vars.palette.TableCell.border;
}
if (theme.palette.mode === 'light') {
return lighten(alpha(theme.palette.divider, 1), 0.88);
}
return darken(alpha(theme.palette.divider, 1), 0.68);
}
const columnHeadersStyles = {
[`.${gridClasses.columnSeparator}, .${gridClasses['columnSeparator--resizing']}`]: {
visibility: 'visible',
width: 'auto'
}
};
const columnHeaderStyles = {
[`& .${gridClasses.iconButtonContainer}`]: {
visibility: 'visible',
width: 'auto'
},
[`& .${gridClasses.menuIcon}`]: {
width: 'auto',
visibility: 'visible'
}
};
export const GridRootStyles = styled('div', {
name: 'MuiDataGrid',
slot: 'Root',
overridesResolver: (props, styles) => [{
[`&.${gridClasses.autoHeight}`]: styles.autoHeight
}, {
[`&.${gridClasses.aggregationColumnHeader}`]: styles.aggregationColumnHeader
}, {
[`&.${gridClasses['aggregationColumnHeader--alignLeft']}`]: styles['aggregationColumnHeader--alignLeft']
}, {
[`&.${gridClasses['aggregationColumnHeader--alignCenter']}`]: styles['aggregationColumnHeader--alignCenter']
}, {
[`&.${gridClasses['aggregationColumnHeader--alignRight']}`]: styles['aggregationColumnHeader--alignRight']
}, {
[`&.${gridClasses.aggregationColumnHeaderLabel}`]: styles.aggregationColumnHeaderLabel
}, {
[`&.${gridClasses['root--disableUserSelection']} .${gridClasses.cell}`]: styles['root--disableUserSelection']
}, {
[`&.${gridClasses.autosizing}`]: styles.autosizing
}, {
[`& .${gridClasses.editBooleanCell}`]: styles.editBooleanCell
}, {
[`& .${gridClasses['cell--editing']}`]: styles['cell--editing']
}, {
[`& .${gridClasses['cell--textCenter']}`]: styles['cell--textCenter']
}, {
[`& .${gridClasses['cell--textLeft']}`]: styles['cell--textLeft']
}, {
[`& .${gridClasses['cell--textRight']}`]: styles['cell--textRight']
},
// TODO v6: Remove
{
[`& .${gridClasses['cell--withRenderer']}`]: styles['cell--withRenderer']
}, {
[`& .${gridClasses.cell}`]: styles.cell
}, {
[`& .${gridClasses['cell--rangeTop']}`]: styles['cell--rangeTop']
}, {
[`& .${gridClasses['cell--rangeBottom']}`]: styles['cell--rangeBottom']
}, {
[`& .${gridClasses['cell--rangeLeft']}`]: styles['cell--rangeLeft']
}, {
[`& .${gridClasses['cell--rangeRight']}`]: styles['cell--rangeRight']
}, {
[`& .${gridClasses['cell--withRightBorder']}`]: styles['cell--withRightBorder']
}, {
[`& .${gridClasses.cellContent}`]: styles.cellContent
}, {
[`& .${gridClasses.cellCheckbox}`]: styles.cellCheckbox
}, {
[`& .${gridClasses.cellSkeleton}`]: styles.cellSkeleton
}, {
[`& .${gridClasses.checkboxInput}`]: styles.checkboxInput
}, {
[`& .${gridClasses['columnHeader--alignCenter']}`]: styles['columnHeader--alignCenter']
}, {
[`& .${gridClasses['columnHeader--alignLeft']}`]: styles['columnHeader--alignLeft']
}, {
[`& .${gridClasses['columnHeader--alignRight']}`]: styles['columnHeader--alignRight']
}, {
[`& .${gridClasses['columnHeader--dragging']}`]: styles['columnHeader--dragging']
}, {
[`& .${gridClasses['columnHeader--moving']}`]: styles['columnHeader--moving']
}, {
[`& .${gridClasses['columnHeader--numeric']}`]: styles['columnHeader--numeric']
}, {
[`& .${gridClasses['columnHeader--sortable']}`]: styles['columnHeader--sortable']
}, {
[`& .${gridClasses['columnHeader--sorted']}`]: styles['columnHeader--sorted']
}, {
[`& .${gridClasses['columnHeader--withRightBorder']}`]: styles['columnHeader--withRightBorder']
}, {
[`& .${gridClasses.columnHeader}`]: styles.columnHeader
}, {
[`& .${gridClasses.headerFilterRow}`]: styles.headerFilterRow
}, {
[`& .${gridClasses.columnHeaderCheckbox}`]: styles.columnHeaderCheckbox
}, {
[`& .${gridClasses.columnHeaderDraggableContainer}`]: styles.columnHeaderDraggableContainer
}, {
[`& .${gridClasses.columnHeaderTitleContainer}`]: styles.columnHeaderTitleContainer
}, {
[`& .${gridClasses['columnSeparator--resizable']}`]: styles['columnSeparator--resizable']
}, {
[`& .${gridClasses['columnSeparator--resizing']}`]: styles['columnSeparator--resizing']
}, {
[`& .${gridClasses.columnSeparator}`]: styles.columnSeparator
}, {
[`& .${gridClasses.filterIcon}`]: styles.filterIcon
}, {
[`& .${gridClasses.iconSeparator}`]: styles.iconSeparator
}, {
[`& .${gridClasses.menuIcon}`]: styles.menuIcon
}, {
[`& .${gridClasses.menuIconButton}`]: styles.menuIconButton
}, {
[`& .${gridClasses.menuOpen}`]: styles.menuOpen
}, {
[`& .${gridClasses.menuList}`]: styles.menuList
}, {
[`& .${gridClasses['row--editable']}`]: styles['row--editable']
}, {
[`& .${gridClasses['row--editing']}`]: styles['row--editing']
}, {
[`& .${gridClasses['row--dragging']}`]: styles['row--dragging']
}, {
[`& .${gridClasses.row}`]: styles.row
}, {
[`& .${gridClasses.rowReorderCellPlaceholder}`]: styles.rowReorderCellPlaceholder
}, {
[`& .${gridClasses.rowReorderCell}`]: styles.rowReorderCell
}, {
[`& .${gridClasses['rowReorderCell--draggable']}`]: styles['rowReorderCell--draggable']
}, {
[`& .${gridClasses.sortIcon}`]: styles.sortIcon
}, {
[`& .${gridClasses.withBorderColor}`]: styles.withBorderColor
}, {
[`& .${gridClasses.treeDataGroupingCell}`]: styles.treeDataGroupingCell
}, {
[`& .${gridClasses.treeDataGroupingCellToggle}`]: styles.treeDataGroupingCellToggle
}, {
[`& .${gridClasses.detailPanelToggleCell}`]: styles.detailPanelToggleCell
}, {
[`& .${gridClasses['detailPanelToggleCell--expanded']}`]: styles['detailPanelToggleCell--expanded']
}, styles.root]
})(({
theme
}) => {
const borderColor = getBorderColor(theme);
const radius = theme.shape.borderRadius;
const gridStyle = _extends({
'--unstable_DataGrid-radius': typeof radius === 'number' ? `${radius}px` : radius,
'--unstable_DataGrid-headWeight': theme.typography.fontWeightMedium,
'--unstable_DataGrid-overlayBackground': theme.vars ? `rgba(${theme.vars.palette.background.defaultChannel} / ${theme.vars.palette.action.disabledOpacity})` : alpha(theme.palette.background.default, theme.palette.action.disabledOpacity),
'--DataGrid-cellOffsetMultiplier': 2,
flex: 1,
boxSizing: 'border-box',
position: 'relative',
borderWidth: '1px',
borderStyle: 'solid',
borderColor,
borderRadius: 'var(--unstable_DataGrid-radius)',
color: (theme.vars || theme).palette.text.primary
}, theme.typography.body2, {
outline: 'none',
height: '100%',
display: 'flex',
minWidth: 0,
// See https://github.com/mui/mui-x/issues/8547
minHeight: 0,
flexDirection: 'column',
overflowAnchor: 'none',
// Keep the same scrolling position
[`&.${gridClasses.autoHeight}`]: {
height: 'auto',
[`& .${gridClasses['row--lastVisible']} .${gridClasses.cell}`]: {
borderBottomColor: 'transparent'
}
},
[`&.${gridClasses.autosizing}`]: {
[`& .${gridClasses.columnHeaderTitleContainerContent} > *`]: {
overflow: 'visible !important'
},
[`& .${gridClasses.cell} > *`]: {
overflow: 'visible !important',
whiteSpace: 'nowrap'
},
[`& .${gridClasses.groupingCriteriaCell}`]: {
width: 'unset'
},
[`& .${gridClasses.treeDataGroupingCell}`]: {
width: 'unset'
}
},
[`& .${gridClasses['virtualScrollerContent--overflowed']} .${gridClasses['row--lastVisible']} .${gridClasses.cell}`]: {
borderBottomColor: 'transparent'
},
[`& .${gridClasses.columnHeader}, & .${gridClasses.cell}`]: {
WebkitTapHighlightColor: 'transparent',
lineHeight: null,
padding: '0 10px',
boxSizing: 'border-box'
},
[`& .${gridClasses.columnHeader}:focus-within, & .${gridClasses.cell}:focus-within`]: {
outline: `solid ${theme.vars ? `rgba(${theme.vars.palette.primary.mainChannel} / 0.5)` : alpha(theme.palette.primary.main, 0.5)} 1px`,
outlineWidth: 1,
outlineOffset: -1
},
[`& .${gridClasses.columnHeader}:focus, & .${gridClasses.cell}:focus`]: {
outline: `solid ${theme.palette.primary.main} 1px`
},
[`& .${gridClasses.columnHeaderCheckbox}, & .${gridClasses.cellCheckbox}`]: {
padding: 0,
justifyContent: 'center',
alignItems: 'center'
},
[`& .${gridClasses.columnHeader}`]: {
position: 'relative',
display: 'flex',
alignItems: 'center'
},
[`& .${gridClasses['columnHeader--sorted']} .${gridClasses.iconButtonContainer}, & .${gridClasses['columnHeader--filtered']} .${gridClasses.iconButtonContainer}`]: {
visibility: 'visible',
width: 'auto'
},
[`& .${gridClasses.columnHeader}:not(.${gridClasses['columnHeader--sorted']}) .${gridClasses.sortIcon}`]: {
opacity: 0,
transition: theme.transitions.create(['opacity'], {
duration: theme.transitions.duration.shorter
})
},
[`& .${gridClasses.columnHeaderTitleContainer}`]: {
display: 'flex',
alignItems: 'center',
minWidth: 0,
flex: 1,
whiteSpace: 'nowrap',
overflow: 'hidden',
// to anchor the aggregation label
position: 'relative'
},
[`& .${gridClasses.columnHeaderTitleContainerContent}`]: {
overflow: 'hidden',
display: 'flex',
alignItems: 'center'
},
[`& .${gridClasses['columnHeader--filledGroup']} .${gridClasses.columnHeaderTitleContainer}`]: {
borderBottomWidth: '1px',
borderBottomStyle: 'solid',
boxSizing: 'border-box'
},
[`& .${gridClasses['columnHeader--filledGroup']}.${gridClasses['columnHeader--showColumnBorder']} .${gridClasses.columnHeaderTitleContainer}`]: {
borderBottom: `none`
},
[`& .${gridClasses['columnHeader--filledGroup']}.${gridClasses['columnHeader--showColumnBorder']}`]: {
borderBottomWidth: '1px',
borderBottomStyle: 'solid',
boxSizing: 'border-box'
},
[`& .${gridClasses.headerFilterRow}`]: {
borderTop: `1px solid ${borderColor}`
},
[`& .${gridClasses.sortIcon}, & .${gridClasses.filterIcon}`]: {
fontSize: 'inherit'
},
[`& .${gridClasses['columnHeader--sortable']}`]: {
cursor: 'pointer'
},
[`& .${gridClasses['columnHeader--alignCenter']} .${gridClasses.columnHeaderTitleContainer}`]: {
justifyContent: 'center'
},
[`& .${gridClasses['columnHeader--alignRight']} .${gridClasses.columnHeaderDraggableContainer}, & .${gridClasses['columnHeader--alignRight']} .${gridClasses.columnHeaderTitleContainer}`]: {
flexDirection: 'row-reverse'
},
[`& .${gridClasses['columnHeader--alignCenter']} .${gridClasses.menuIcon}, & .${gridClasses['columnHeader--alignRight']} .${gridClasses.menuIcon}`]: {
marginRight: 'auto',
marginLeft: -6
},
[`& .${gridClasses['columnHeader--alignRight']} .${gridClasses.menuIcon}, & .${gridClasses['columnHeader--alignRight']} .${gridClasses.menuIcon}`]: {
marginRight: 'auto',
marginLeft: -10
},
[`& .${gridClasses['columnHeader--moving']}`]: {
backgroundColor: (theme.vars || theme).palette.action.hover
},
[`& .${gridClasses.columnSeparator}`]: {
visibility: 'hidden',
position: 'absolute',
zIndex: 100,
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
color: borderColor
},
'@media (hover: hover)': {
[`& .${gridClasses.columnHeaders}:hover`]: columnHeadersStyles,
[`& .${gridClasses.columnHeader}:hover`]: columnHeaderStyles,
[`& .${gridClasses.columnHeader}:not(.${gridClasses['columnHeader--sorted']}):hover .${gridClasses.sortIcon}`]: {
opacity: 0.5
}
},
'@media (hover: none)': {
[`& .${gridClasses.columnHeaders}`]: columnHeadersStyles,
[`& .${gridClasses.columnHeader}`]: columnHeaderStyles
},
[`& .${gridClasses['columnSeparator--sideLeft']}`]: {
left: -12
},
[`& .${gridClasses['columnSeparator--sideRight']}`]: {
right: -12
},
[`& .${gridClasses['columnSeparator--resizable']}`]: {
cursor: 'col-resize',
touchAction: 'none',
'&:hover': {
color: (theme.vars || theme).palette.text.primary,
// Reset on touch devices, it doesn't add specificity
'@media (hover: none)': {
color: borderColor
}
},
[`&.${gridClasses['columnSeparator--resizing']}`]: {
color: (theme.vars || theme).palette.text.primary
},
'& svg': {
pointerEvents: 'none'
}
},
[`& .${gridClasses.iconSeparator}`]: {
color: 'inherit'
},
[`& .${gridClasses.menuIcon}`]: {
width: 0,
visibility: 'hidden',
fontSize: 20,
marginRight: -10,
display: 'flex',
alignItems: 'center'
},
[`.${gridClasses.menuOpen}`]: {
visibility: 'visible',
width: 'auto'
},
[`& .${gridClasses.row}`]: {
display: 'flex',
width: 'fit-content',
breakInside: 'avoid',
// Avoid the row to be broken in two different print pages.
'&:hover, &.Mui-hovered': {
backgroundColor: (theme.vars || theme).palette.action.hover,
// Reset on touch devices, it doesn't add specificity
'@media (hover: none)': {
backgroundColor: 'transparent'
}
},
'&.Mui-selected': {
backgroundColor: theme.vars ? `rgba(${theme.vars.palette.primary.mainChannel} / ${theme.vars.palette.action.selectedOpacity})` : alpha(theme.palette.primary.main, theme.palette.action.selectedOpacity),
'&:hover, &.Mui-hovered': {
backgroundColor: theme.vars ? `rgba(${theme.vars.palette.primary.mainChannel} / calc(
${theme.vars.palette.action.selectedOpacity} +
${theme.vars.palette.action.hoverOpacity}
))` : alpha(theme.palette.primary.main, theme.palette.action.selectedOpacity + theme.palette.action.hoverOpacity),
// Reset on touch devices, it doesn't add specificity
'@media (hover: none)': {
backgroundColor: theme.vars ? `rgba(${theme.vars.palette.primary.mainChannel} / ${theme.vars.palette.action.selectedOpacity})` : alpha(theme.palette.primary.main, theme.palette.action.selectedOpacity)
}
}
}
},
[`& .${gridClasses.cell}`]: {
display: 'flex',
alignItems: 'center',
borderBottom: '1px solid',
'&.Mui-selected': {
backgroundColor: theme.vars ? `rgba(${theme.vars.palette.primary.mainChannel} / ${theme.vars.palette.action.selectedOpacity})` : alpha(theme.palette.primary.main, theme.palette.action.selectedOpacity),
'&:hover, &.Mui-hovered': {
backgroundColor: theme.vars ? `rgba(${theme.vars.palette.primary.mainChannel} / ${theme.vars.palette.action.selectedOpacity + theme.palette.action.hoverOpacity})` : alpha(theme.palette.primary.main, theme.palette.action.selectedOpacity + theme.palette.action.hoverOpacity),
// Reset on touch devices, it doesn't add specificity
'@media (hover: none)': {
backgroundColor: theme.vars ? `rgba(${theme.vars.palette.primary.mainChannel} / ${theme.vars.palette.action.selectedOpacity})` : alpha(theme.palette.primary.main, theme.palette.action.selectedOpacity)
}
}
}
},
[`&.${gridClasses['root--disableUserSelection']} .${gridClasses.cell}`]: {
userSelect: 'none'
},
[`& .${gridClasses.row}:not(.${gridClasses['row--dynamicHeight']}) > .${gridClasses.cell}`]: {
overflow: 'hidden',
whiteSpace: 'nowrap'
},
[`& .${gridClasses.cellContent}`]: {
overflow: 'hidden',
textOverflow: 'ellipsis'
},
[`& .${gridClasses.cell}.${gridClasses['cell--selectionMode']}`]: {
cursor: 'default'
},
[`& .${gridClasses.cell}.${gridClasses['cell--editing']}`]: {
padding: 1,
display: 'flex',
boxShadow: theme.shadows[2],
backgroundColor: (theme.vars || theme).palette.background.paper,
'&:focus-within': {
outline: `solid ${(theme.vars || theme).palette.primary.main} 1px`,
outlineOffset: '-1px'
}
},
[`& .${gridClasses['row--editing']}`]: {
boxShadow: theme.shadows[2]
},
[`& .${gridClasses['row--editing']} .${gridClasses.cell}`]: {
boxShadow: theme.shadows[0],
backgroundColor: (theme.vars || theme).palette.background.paper
},
[`& .${gridClasses.editBooleanCell}`]: {
display: 'flex',
height: '100%',
width: '100%',
alignItems: 'center',
justifyContent: 'center'
},
[`& .${gridClasses.booleanCell}[data-value="true"]`]: {
color: (theme.vars || theme).palette.text.secondary
},
[`& .${gridClasses.booleanCell}[data-value="false"]`]: {
color: (theme.vars || theme).palette.text.disabled
},
[`& .${gridClasses.actionsCell}`]: {
display: 'inline-flex',
alignItems: 'center',
gridGap: theme.spacing(1)
},
[`& .${gridClasses.rowReorderCell}`]: {
display: 'inline-flex',
flex: 1,
alignItems: 'center',
justifyContent: 'center',
opacity: (theme.vars || theme).palette.action.disabledOpacity
},
[`& .${gridClasses['rowReorderCell--draggable']}`]: {
cursor: 'move',
opacity: 1
},
[`& .${gridClasses.rowReorderCellContainer}`]: {
padding: 0,
alignItems: 'stretch'
},
[`.${gridClasses.withBorderColor}`]: {
borderColor
},
[`& .${gridClasses['cell--withRightBorder']}`]: {
borderRightWidth: '1px',
borderRightStyle: 'solid'
},
[`& .${gridClasses['columnHeader--withRightBorder']}`]: {
borderRightWidth: '1px',
borderRightStyle: 'solid'
},
[`& .${gridClasses['cell--textLeft']}`]: {
justifyContent: 'flex-start'
},
[`& .${gridClasses['cell--textRight']}`]: {
justifyContent: 'flex-end'
},
[`& .${gridClasses['cell--textCenter']}`]: {
justifyContent: 'center'
},
[`& .${gridClasses.columnHeaderDraggableContainer}`]: {
display: 'flex',
width: '100%',
height: '100%'
},
[`& .${gridClasses.rowReorderCellPlaceholder}`]: {
display: 'none'
},
[`& .${gridClasses['columnHeader--dragging']}, & .${gridClasses['row--dragging']}`]: {
background: (theme.vars || theme).palette.background.paper,
padding: '0 12px',
borderRadius: 'var(--unstable_DataGrid-radius)',
opacity: (theme.vars || theme).palette.action.disabledOpacity
},
[`& .${gridClasses['row--dragging']}`]: {
background: (theme.vars || theme).palette.background.paper,
padding: '0 12px',
borderRadius: 'var(--unstable_DataGrid-radius)',
opacity: (theme.vars || theme).palette.action.disabledOpacity,
[`& .${gridClasses.rowReorderCellPlaceholder}`]: {
display: 'flex'
}
},
[`& .${gridClasses.treeDataGroupingCell}`]: {
display: 'flex',
alignItems: 'center',
width: '100%'
},
[`& .${gridClasses.treeDataGroupingCellToggle}`]: {
flex: '0 0 28px',
alignSelf: 'stretch',
marginRight: theme.spacing(2)
},
[`& .${gridClasses.groupingCriteriaCell}`]: {
display: 'flex',
alignItems: 'center',
width: '100%'
},
[`& .${gridClasses.groupingCriteriaCellToggle}`]: {
flex: '0 0 28px',
alignSelf: 'stretch',
marginRight: theme.spacing(2)
}
});
return gridStyle;
});

View File

@@ -0,0 +1,60 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
const _excluded = ["className", "children"];
import * as React from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import { styled } from '@mui/system';
import { unstable_composeClasses as composeClasses } from '@mui/utils';
import { getDataGridUtilityClass } from '../../constants/gridClasses';
import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
import { jsx as _jsx } from "react/jsx-runtime";
const useUtilityClasses = ownerState => {
const {
classes
} = ownerState;
const slots = {
root: ['toolbarContainer']
};
return composeClasses(slots, getDataGridUtilityClass, classes);
};
const GridToolbarContainerRoot = styled('div', {
name: 'MuiDataGrid',
slot: 'ToolbarContainer',
overridesResolver: (_, styles) => styles.toolbarContainer
})(({
theme
}) => ({
display: 'flex',
alignItems: 'center',
flexWrap: 'wrap',
gap: theme.spacing(1),
padding: theme.spacing(0.5, 0.5, 0)
}));
const GridToolbarContainer = /*#__PURE__*/React.forwardRef(function GridToolbarContainer(props, ref) {
const {
className,
children
} = props,
other = _objectWithoutPropertiesLoose(props, _excluded);
const rootProps = useGridRootProps();
const classes = useUtilityClasses(rootProps);
if (!children) {
return null;
}
return /*#__PURE__*/_jsx(GridToolbarContainerRoot, _extends({
ref: ref,
className: clsx(className, classes.root),
ownerState: rootProps
}, other, {
children: children
}));
});
process.env.NODE_ENV !== "production" ? GridToolbarContainer.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object])
} : void 0;
export { GridToolbarContainer };

View File

@@ -0,0 +1,4 @@
export * from './GridRoot';
export * from './GridFooterContainer';
export * from './GridOverlay';
export * from './GridToolbarContainer';

View File

@@ -0,0 +1,18 @@
export * from './base';
export * from './cell';
export * from './containers';
export * from './columnHeaders';
export * from './columnSelection';
export * from '../material/icons';
export * from './menu';
export * from './panel';
export * from './toolbar';
export * from './GridApiContext';
export * from './GridFooter';
export * from './GridHeader';
export * from './GridLoadingOverlay';
export * from './GridNoRowsOverlay';
export * from './GridPagination';
export * from './GridRowCount';
export * from './GridRow';
export * from './GridSelectedRowCount';

View File

@@ -0,0 +1,128 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
const _excluded = ["open", "target", "onClose", "children", "position", "className", "onExited"];
import * as React from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import ClickAwayListener from '@mui/material/ClickAwayListener';
import { unstable_composeClasses as composeClasses, unstable_useEnhancedEffect as useEnhancedEffect, HTMLElementType } from '@mui/utils';
import Grow from '@mui/material/Grow';
import Paper from '@mui/material/Paper';
import Popper from '@mui/material/Popper';
import { styled } from '@mui/material/styles';
import { getDataGridUtilityClass, gridClasses } from '../../constants/gridClasses';
import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
import { useGridApiContext } from '../../hooks/utils/useGridApiContext';
import { jsx as _jsx } from "react/jsx-runtime";
const useUtilityClasses = ownerState => {
const {
classes
} = ownerState;
const slots = {
root: ['menu']
};
return composeClasses(slots, getDataGridUtilityClass, classes);
};
const GridMenuRoot = styled(Popper, {
name: 'MuiDataGrid',
slot: 'Menu',
overridesResolver: (_, styles) => styles.menu
})(({
theme
}) => ({
zIndex: theme.zIndex.modal,
[`& .${gridClasses.menuList}`]: {
outline: 0
}
}));
const transformOrigin = {
'bottom-start': 'top left',
'bottom-end': 'top right'
};
function GridMenu(props) {
const {
open,
target,
onClose,
children,
position,
className,
onExited
} = props,
other = _objectWithoutPropertiesLoose(props, _excluded);
const apiRef = useGridApiContext();
const rootProps = useGridRootProps();
const classes = useUtilityClasses(rootProps);
const savedFocusRef = React.useRef(null);
useEnhancedEffect(() => {
if (open) {
savedFocusRef.current = document.activeElement instanceof HTMLElement ? document.activeElement : null;
} else {
savedFocusRef.current?.focus?.();
savedFocusRef.current = null;
}
}, [open]);
React.useEffect(() => {
// Emit menuOpen or menuClose events
const eventName = open ? 'menuOpen' : 'menuClose';
apiRef.current.publishEvent(eventName, {
target
});
}, [apiRef, open, target]);
const handleExited = popperOnExited => node => {
if (popperOnExited) {
popperOnExited();
}
if (onExited) {
onExited(node);
}
};
const handleClickAway = event => {
if (event.target && (target === event.target || target?.contains(event.target))) {
return;
}
onClose(event);
};
return /*#__PURE__*/_jsx(GridMenuRoot, _extends({
as: rootProps.slots.basePopper,
className: clsx(className, classes.root),
ownerState: rootProps,
open: open,
anchorEl: target,
transition: true,
placement: position
}, other, rootProps.slotProps?.basePopper, {
children: ({
TransitionProps,
placement
}) => /*#__PURE__*/_jsx(ClickAwayListener, {
onClickAway: handleClickAway,
mouseEvent: "onMouseDown",
children: /*#__PURE__*/_jsx(Grow, _extends({}, TransitionProps, {
style: {
transformOrigin: transformOrigin[placement]
},
onExited: handleExited(TransitionProps?.onExited),
children: /*#__PURE__*/_jsx(Paper, {
children: children
})
}))
})
}));
}
process.env.NODE_ENV !== "production" ? GridMenu.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
children: PropTypes.node,
onClose: PropTypes.func.isRequired,
onExited: PropTypes.func,
/**
* If `true`, the component is shown.
*/
open: PropTypes.bool.isRequired,
position: PropTypes.oneOf(['bottom-end', 'bottom-start', 'bottom', 'left-end', 'left-start', 'left', 'right-end', 'right-start', 'right', 'top-end', 'top-start', 'top']),
target: HTMLElementType
} : void 0;
export { GridMenu };

View File

@@ -0,0 +1,62 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import * as React from 'react';
import PropTypes from 'prop-types';
import { unstable_useEventCallback as useEventCallback, HTMLElementType } from '@mui/utils';
import { useGridApiContext } from '../../../hooks/utils/useGridApiContext';
import { GridMenu } from '../GridMenu';
import { jsx as _jsx } from "react/jsx-runtime";
function GridColumnHeaderMenu({
columnMenuId,
columnMenuButtonId,
ContentComponent,
contentComponentProps,
field,
open,
target,
onExited
}) {
const apiRef = useGridApiContext();
const colDef = apiRef.current.getColumn(field);
const hideMenu = useEventCallback(event => {
if (event) {
// Prevent triggering the sorting
event.stopPropagation();
if (target?.contains(event.target)) {
return;
}
}
apiRef.current.hideColumnMenu();
});
if (!target || !colDef) {
return null;
}
return /*#__PURE__*/_jsx(GridMenu, {
placement: `bottom-${colDef.align === 'right' ? 'start' : 'end'}`,
open: open,
target: target,
onClose: hideMenu,
onExited: onExited,
children: /*#__PURE__*/_jsx(ContentComponent, _extends({
colDef: colDef,
hideMenu: hideMenu,
open: open,
id: columnMenuId,
labelledby: columnMenuButtonId
}, contentComponentProps))
});
}
process.env.NODE_ENV !== "production" ? GridColumnHeaderMenu.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
columnMenuButtonId: PropTypes.string,
columnMenuId: PropTypes.string,
ContentComponent: PropTypes.elementType.isRequired,
contentComponentProps: PropTypes.any,
field: PropTypes.string.isRequired,
onExited: PropTypes.func,
open: PropTypes.bool.isRequired,
target: HTMLElementType
} : void 0;
export { GridColumnHeaderMenu };

View File

@@ -0,0 +1,77 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
const _excluded = ["defaultSlots", "defaultSlotProps", "slots", "slotProps"];
import * as React from 'react';
import PropTypes from 'prop-types';
import { useGridColumnMenuSlots } from '../../../hooks/features/columnMenu/useGridColumnMenuSlots';
import { GridColumnMenuContainer } from './GridColumnMenuContainer';
import { GridColumnMenuColumnsItem } from './menuItems/GridColumnMenuColumnsItem';
import { GridColumnMenuFilterItem } from './menuItems/GridColumnMenuFilterItem';
import { GridColumnMenuSortItem } from './menuItems/GridColumnMenuSortItem';
import { jsx as _jsx } from "react/jsx-runtime";
export const GRID_COLUMN_MENU_SLOTS = {
columnMenuSortItem: GridColumnMenuSortItem,
columnMenuFilterItem: GridColumnMenuFilterItem,
columnMenuColumnsItem: GridColumnMenuColumnsItem
};
export const GRID_COLUMN_MENU_SLOT_PROPS = {
columnMenuSortItem: {
displayOrder: 10
},
columnMenuFilterItem: {
displayOrder: 20
},
columnMenuColumnsItem: {
displayOrder: 30
}
};
const GridGenericColumnMenu = /*#__PURE__*/React.forwardRef(function GridGenericColumnMenu(props, ref) {
const {
defaultSlots,
defaultSlotProps,
slots,
slotProps
} = props,
other = _objectWithoutPropertiesLoose(props, _excluded);
const orderedSlots = useGridColumnMenuSlots(_extends({}, other, {
defaultSlots,
defaultSlotProps,
slots,
slotProps
}));
return /*#__PURE__*/_jsx(GridColumnMenuContainer, _extends({
ref: ref
}, other, {
children: orderedSlots.map(([Component, otherProps], index) => /*#__PURE__*/_jsx(Component, _extends({}, otherProps), index))
}));
});
const GridColumnMenu = /*#__PURE__*/React.forwardRef(function GridColumnMenu(props, ref) {
return /*#__PURE__*/_jsx(GridGenericColumnMenu, _extends({}, props, {
ref: ref,
defaultSlots: GRID_COLUMN_MENU_SLOTS,
defaultSlotProps: GRID_COLUMN_MENU_SLOT_PROPS
}));
});
process.env.NODE_ENV !== "production" ? GridColumnMenu.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
colDef: PropTypes.object.isRequired,
hideMenu: PropTypes.func.isRequired,
id: PropTypes.string,
labelledby: PropTypes.string,
open: PropTypes.bool.isRequired,
/**
* Could be used to pass new props or override props specific to a column menu component
* e.g. `displayOrder`
*/
slotProps: PropTypes.object,
/**
* `slots` could be used to add new and (or) override default column menu items
* If you register a nee component you must pass it's `displayOrder` in `slotProps`
* or it will be placed in the end of the list
*/
slots: PropTypes.object
} : void 0;
export { GridColumnMenu, GridGenericColumnMenu };

View File

@@ -0,0 +1,55 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
const _excluded = ["hideMenu", "colDef", "id", "labelledby", "className", "children", "open"];
import clsx from 'clsx';
import PropTypes from 'prop-types';
import * as React from 'react';
import MenuList from '@mui/material/MenuList';
import { styled } from '@mui/material/styles';
import { isHideMenuKey, isTabKey } from '../../../utils/keyboardUtils';
import { gridClasses } from '../../../constants/gridClasses';
import { jsx as _jsx } from "react/jsx-runtime";
const StyledMenuList = styled(MenuList)(() => ({
minWidth: 248
}));
const GridColumnMenuContainer = /*#__PURE__*/React.forwardRef(function GridColumnMenuContainer(props, ref) {
const {
hideMenu,
id,
labelledby,
className,
children,
open
} = props,
other = _objectWithoutPropertiesLoose(props, _excluded);
const handleListKeyDown = React.useCallback(event => {
if (isTabKey(event.key)) {
event.preventDefault();
}
if (isHideMenuKey(event.key)) {
hideMenu(event);
}
}, [hideMenu]);
return /*#__PURE__*/_jsx(StyledMenuList, _extends({
id: id,
ref: ref,
className: clsx(gridClasses.menuList, className),
"aria-labelledby": labelledby,
onKeyDown: handleListKeyDown,
autoFocus: open
}, other, {
children: children
}));
});
process.env.NODE_ENV !== "production" ? GridColumnMenuContainer.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
colDef: PropTypes.object.isRequired,
hideMenu: PropTypes.func.isRequired,
id: PropTypes.string,
labelledby: PropTypes.string,
open: PropTypes.bool.isRequired
} : void 0;
export { GridColumnMenuContainer };

View File

@@ -0,0 +1 @@
export {};

View File

@@ -0,0 +1,9 @@
// shared modules
export * from './GridColumnHeaderMenu';
export * from './GridColumnMenuProps';
export * from './GridColumnMenuItemProps';
export * from './GridColumnMenuContainer';
export { GridGenericColumnMenu } from './GridColumnMenu';
// items
export * from './menuItems';

View File

@@ -0,0 +1,21 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import * as React from 'react';
import PropTypes from 'prop-types';
import { GridColumnMenuHideItem } from './GridColumnMenuHideItem';
import { GridColumnMenuManageItem } from './GridColumnMenuManageItem';
import { jsx as _jsx } from "react/jsx-runtime";
import { jsxs as _jsxs } from "react/jsx-runtime";
function GridColumnMenuColumnsItem(props) {
return /*#__PURE__*/_jsxs(React.Fragment, {
children: [/*#__PURE__*/_jsx(GridColumnMenuHideItem, _extends({}, props)), /*#__PURE__*/_jsx(GridColumnMenuManageItem, _extends({}, props))]
});
}
process.env.NODE_ENV !== "production" ? GridColumnMenuColumnsItem.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
colDef: PropTypes.object.isRequired,
onClick: PropTypes.func.isRequired
} : void 0;
export { GridColumnMenuColumnsItem };

View File

@@ -0,0 +1,43 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import MenuItem from '@mui/material/MenuItem';
import ListItemIcon from '@mui/material/ListItemIcon';
import ListItemText from '@mui/material/ListItemText';
import { useGridApiContext } from '../../../../hooks/utils/useGridApiContext';
import { useGridRootProps } from '../../../../hooks/utils/useGridRootProps';
import { jsx as _jsx } from "react/jsx-runtime";
import { jsxs as _jsxs } from "react/jsx-runtime";
function GridColumnMenuFilterItem(props) {
const {
colDef,
onClick
} = props;
const apiRef = useGridApiContext();
const rootProps = useGridRootProps();
const showFilter = React.useCallback(event => {
onClick(event);
apiRef.current.showFilterPanel(colDef.field);
}, [apiRef, colDef.field, onClick]);
if (rootProps.disableColumnFilter || !colDef.filterable) {
return null;
}
return /*#__PURE__*/_jsxs(MenuItem, {
onClick: showFilter,
children: [/*#__PURE__*/_jsx(ListItemIcon, {
children: /*#__PURE__*/_jsx(rootProps.slots.columnMenuFilterIcon, {
fontSize: "small"
})
}), /*#__PURE__*/_jsx(ListItemText, {
children: apiRef.current.getLocaleText('columnMenuFilter')
})]
});
}
process.env.NODE_ENV !== "production" ? GridColumnMenuFilterItem.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
colDef: PropTypes.object.isRequired,
onClick: PropTypes.func.isRequired
} : void 0;
export { GridColumnMenuFilterItem };

View File

@@ -0,0 +1,60 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import MenuItem from '@mui/material/MenuItem';
import ListItemIcon from '@mui/material/ListItemIcon';
import ListItemText from '@mui/material/ListItemText';
import { useGridApiContext } from '../../../../hooks/utils/useGridApiContext';
import { useGridRootProps } from '../../../../hooks/utils/useGridRootProps';
import { gridVisibleColumnDefinitionsSelector } from '../../../../hooks/features/columns';
import { jsx as _jsx } from "react/jsx-runtime";
import { jsxs as _jsxs } from "react/jsx-runtime";
function GridColumnMenuHideItem(props) {
const {
colDef,
onClick
} = props;
const apiRef = useGridApiContext();
const rootProps = useGridRootProps();
const visibleColumns = gridVisibleColumnDefinitionsSelector(apiRef);
const columnsWithMenu = visibleColumns.filter(col => col.disableColumnMenu !== true);
// do not allow to hide the last column with menu
const disabled = columnsWithMenu.length === 1;
const toggleColumn = React.useCallback(event => {
/**
* Disabled `MenuItem` would trigger `click` event
* after imperative `.click()` call on HTML element.
* Also, click is triggered in testing environment as well.
*/
if (disabled) {
return;
}
apiRef.current.setColumnVisibility(colDef.field, false);
onClick(event);
}, [apiRef, colDef.field, onClick, disabled]);
if (rootProps.disableColumnSelector) {
return null;
}
if (colDef.hideable === false) {
return null;
}
return /*#__PURE__*/_jsxs(MenuItem, {
onClick: toggleColumn,
disabled: disabled,
children: [/*#__PURE__*/_jsx(ListItemIcon, {
children: /*#__PURE__*/_jsx(rootProps.slots.columnMenuHideIcon, {
fontSize: "small"
})
}), /*#__PURE__*/_jsx(ListItemText, {
children: apiRef.current.getLocaleText('columnMenuHideColumn')
})]
});
}
process.env.NODE_ENV !== "production" ? GridColumnMenuHideItem.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
colDef: PropTypes.object.isRequired,
onClick: PropTypes.func.isRequired
} : void 0;
export { GridColumnMenuHideItem };

View File

@@ -0,0 +1,43 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import MenuItem from '@mui/material/MenuItem';
import ListItemIcon from '@mui/material/ListItemIcon';
import ListItemText from '@mui/material/ListItemText';
import { GridPreferencePanelsValue } from '../../../../hooks/features/preferencesPanel/gridPreferencePanelsValue';
import { useGridApiContext } from '../../../../hooks/utils/useGridApiContext';
import { useGridRootProps } from '../../../../hooks/utils/useGridRootProps';
import { jsx as _jsx } from "react/jsx-runtime";
import { jsxs as _jsxs } from "react/jsx-runtime";
function GridColumnMenuManageItem(props) {
const {
onClick
} = props;
const apiRef = useGridApiContext();
const rootProps = useGridRootProps();
const showColumns = React.useCallback(event => {
onClick(event); // hide column menu
apiRef.current.showPreferences(GridPreferencePanelsValue.columns);
}, [apiRef, onClick]);
if (rootProps.disableColumnSelector) {
return null;
}
return /*#__PURE__*/_jsxs(MenuItem, {
onClick: showColumns,
children: [/*#__PURE__*/_jsx(ListItemIcon, {
children: /*#__PURE__*/_jsx(rootProps.slots.columnMenuManageColumnsIcon, {
fontSize: "small"
})
}), /*#__PURE__*/_jsx(ListItemText, {
children: apiRef.current.getLocaleText('columnMenuManageColumns')
})]
});
}
process.env.NODE_ENV !== "production" ? GridColumnMenuManageItem.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
colDef: PropTypes.object.isRequired,
onClick: PropTypes.func.isRequired
} : void 0;
export { GridColumnMenuManageItem };

View File

@@ -0,0 +1,77 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import MenuItem from '@mui/material/MenuItem';
import ListItemIcon from '@mui/material/ListItemIcon';
import ListItemText from '@mui/material/ListItemText';
import { useGridSelector } from '../../../../hooks/utils/useGridSelector';
import { gridSortModelSelector } from '../../../../hooks/features/sorting/gridSortingSelector';
import { useGridApiContext } from '../../../../hooks/utils/useGridApiContext';
import { useGridRootProps } from '../../../../hooks/utils/useGridRootProps';
import { jsx as _jsx } from "react/jsx-runtime";
import { jsxs as _jsxs } from "react/jsx-runtime";
function GridColumnMenuSortItem(props) {
const {
colDef,
onClick
} = props;
const apiRef = useGridApiContext();
const sortModel = useGridSelector(apiRef, gridSortModelSelector);
const rootProps = useGridRootProps();
const sortDirection = React.useMemo(() => {
if (!colDef) {
return null;
}
const sortItem = sortModel.find(item => item.field === colDef.field);
return sortItem?.sort;
}, [colDef, sortModel]);
const sortingOrder = colDef.sortingOrder ?? rootProps.sortingOrder;
const onSortMenuItemClick = React.useCallback(event => {
onClick(event);
const direction = event.currentTarget.getAttribute('data-value') || null;
apiRef.current.sortColumn(colDef, direction === sortDirection ? null : direction);
}, [apiRef, colDef, onClick, sortDirection]);
if (!colDef || !colDef.sortable || !sortingOrder.some(item => !!item)) {
return null;
}
const getLabel = key => {
const label = apiRef.current.getLocaleText(key);
return typeof label === 'function' ? label(colDef) : label;
};
return /*#__PURE__*/_jsxs(React.Fragment, {
children: [sortingOrder.includes('asc') && sortDirection !== 'asc' ? /*#__PURE__*/_jsxs(MenuItem, {
onClick: onSortMenuItemClick,
"data-value": "asc",
children: [/*#__PURE__*/_jsx(ListItemIcon, {
children: /*#__PURE__*/_jsx(rootProps.slots.columnMenuSortAscendingIcon, {
fontSize: "small"
})
}), /*#__PURE__*/_jsx(ListItemText, {
children: getLabel('columnMenuSortAsc')
})]
}) : null, sortingOrder.includes('desc') && sortDirection !== 'desc' ? /*#__PURE__*/_jsxs(MenuItem, {
onClick: onSortMenuItemClick,
"data-value": "desc",
children: [/*#__PURE__*/_jsx(ListItemIcon, {
children: /*#__PURE__*/_jsx(rootProps.slots.columnMenuSortDescendingIcon, {
fontSize: "small"
})
}), /*#__PURE__*/_jsx(ListItemText, {
children: getLabel('columnMenuSortDesc')
})]
}) : null, sortingOrder.includes(null) && sortDirection != null ? /*#__PURE__*/_jsxs(MenuItem, {
onClick: onSortMenuItemClick,
children: [/*#__PURE__*/_jsx(ListItemIcon, {}), /*#__PURE__*/_jsx(ListItemText, {
children: apiRef.current.getLocaleText('columnMenuUnsort')
})]
}) : null]
});
}
process.env.NODE_ENV !== "production" ? GridColumnMenuSortItem.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
colDef: PropTypes.object.isRequired,
onClick: PropTypes.func.isRequired
} : void 0;
export { GridColumnMenuSortItem };

View File

@@ -0,0 +1,5 @@
export * from './GridColumnMenuColumnsItem';
export * from './GridColumnMenuManageItem';
export * from './GridColumnMenuFilterItem';
export * from './GridColumnMenuHideItem';
export * from './GridColumnMenuSortItem';

View File

@@ -0,0 +1,2 @@
export * from './columnMenu';
export * from './GridMenu';

View File

@@ -0,0 +1,226 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
const _excluded = ["sort", "searchPredicate", "autoFocusSearchField", "disableHideAllButton", "disableShowAllButton", "getTogglableColumns"];
import * as React from 'react';
import PropTypes from 'prop-types';
import { unstable_composeClasses as composeClasses } from '@mui/utils';
import IconButton from '@mui/material/IconButton';
import { switchClasses } from '@mui/material/Switch';
import FormControlLabel from '@mui/material/FormControlLabel';
import { styled } from '@mui/material/styles';
import { gridColumnDefinitionsSelector, gridColumnVisibilityModelSelector } from '../../hooks/features/columns/gridColumnsSelector';
import { useGridSelector } from '../../hooks/utils/useGridSelector';
import { useGridApiContext } from '../../hooks/utils/useGridApiContext';
import { GridPanelContent } from './GridPanelContent';
import { GridPanelFooter } from './GridPanelFooter';
import { GridPanelHeader } from './GridPanelHeader';
import { GridPanelWrapper } from './GridPanelWrapper';
import { GRID_EXPERIMENTAL_ENABLED } from '../../constants/envConstants';
import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
import { getDataGridUtilityClass } from '../../constants/gridClasses';
import { jsx as _jsx } from "react/jsx-runtime";
import { jsxs as _jsxs } from "react/jsx-runtime";
const useUtilityClasses = ownerState => {
const {
classes
} = ownerState;
const slots = {
root: ['columnsPanel'],
columnsPanelRow: ['columnsPanelRow']
};
return composeClasses(slots, getDataGridUtilityClass, classes);
};
const GridColumnsPanelRoot = styled('div', {
name: 'MuiDataGrid',
slot: 'ColumnsPanel',
overridesResolver: (props, styles) => styles.columnsPanel
})({
padding: '8px 0px 8px 8px'
});
const GridColumnsPanelRowRoot = styled('div', {
name: 'MuiDataGrid',
slot: 'ColumnsPanelRow',
overridesResolver: (props, styles) => styles.columnsPanelRow
})(({
theme
}) => ({
display: 'flex',
justifyContent: 'space-between',
padding: '1px 8px 1px 7px',
[`& .${switchClasses.root}`]: {
marginRight: theme.spacing(0.5)
}
}));
const GridIconButtonRoot = styled(IconButton)({
justifyContent: 'flex-end'
});
const collator = new Intl.Collator();
const defaultSearchPredicate = (column, searchValue) => {
return (column.headerName || column.field).toLowerCase().indexOf(searchValue) > -1;
};
function GridColumnsPanel(props) {
const apiRef = useGridApiContext();
const searchInputRef = React.useRef(null);
const columns = useGridSelector(apiRef, gridColumnDefinitionsSelector);
const columnVisibilityModel = useGridSelector(apiRef, gridColumnVisibilityModelSelector);
const rootProps = useGridRootProps();
const [searchValue, setSearchValue] = React.useState('');
const classes = useUtilityClasses(rootProps);
const {
sort,
searchPredicate = defaultSearchPredicate,
autoFocusSearchField = true,
disableHideAllButton = false,
disableShowAllButton = false,
getTogglableColumns
} = props,
other = _objectWithoutPropertiesLoose(props, _excluded);
const sortedColumns = React.useMemo(() => {
switch (sort) {
case 'asc':
return [...columns].sort((a, b) => collator.compare(a.headerName || a.field, b.headerName || b.field));
case 'desc':
return [...columns].sort((a, b) => -collator.compare(a.headerName || a.field, b.headerName || b.field));
default:
return columns;
}
}, [columns, sort]);
const toggleColumn = event => {
const {
name: field
} = event.target;
apiRef.current.setColumnVisibility(field, columnVisibilityModel[field] === false);
};
const toggleAllColumns = React.useCallback(isVisible => {
const currentModel = gridColumnVisibilityModelSelector(apiRef);
const newModel = _extends({}, currentModel);
const togglableColumns = getTogglableColumns ? getTogglableColumns(columns) : null;
columns.forEach(col => {
if (col.hideable && (togglableColumns == null || togglableColumns.includes(col.field))) {
if (isVisible) {
// delete the key from the model instead of setting it to `true`
delete newModel[col.field];
} else {
newModel[col.field] = false;
}
}
});
return apiRef.current.setColumnVisibilityModel(newModel);
}, [apiRef, columns, getTogglableColumns]);
const handleSearchValueChange = React.useCallback(event => {
setSearchValue(event.target.value);
}, []);
const currentColumns = React.useMemo(() => {
const togglableColumns = getTogglableColumns ? getTogglableColumns(sortedColumns) : null;
const togglableSortedColumns = togglableColumns ? sortedColumns.filter(({
field
}) => togglableColumns.includes(field)) : sortedColumns;
if (!searchValue) {
return togglableSortedColumns;
}
return togglableSortedColumns.filter(column => searchPredicate(column, searchValue.toLowerCase()));
}, [sortedColumns, searchValue, searchPredicate, getTogglableColumns]);
const firstSwitchRef = React.useRef(null);
React.useEffect(() => {
if (autoFocusSearchField) {
searchInputRef.current.focus();
} else if (firstSwitchRef.current && typeof firstSwitchRef.current.focus === 'function') {
firstSwitchRef.current.focus();
}
}, [autoFocusSearchField]);
let firstHideableColumnFound = false;
const isFirstHideableColumn = column => {
if (firstHideableColumnFound === false && column.hideable !== false) {
firstHideableColumnFound = true;
return true;
}
return false;
};
return /*#__PURE__*/_jsxs(GridPanelWrapper, _extends({}, other, {
children: [/*#__PURE__*/_jsx(GridPanelHeader, {
children: /*#__PURE__*/_jsx(rootProps.slots.baseTextField, _extends({
label: apiRef.current.getLocaleText('columnsPanelTextFieldLabel'),
placeholder: apiRef.current.getLocaleText('columnsPanelTextFieldPlaceholder'),
inputRef: searchInputRef,
value: searchValue,
onChange: handleSearchValueChange,
variant: "standard",
fullWidth: true
}, rootProps.slotProps?.baseTextField))
}), /*#__PURE__*/_jsx(GridPanelContent, {
children: /*#__PURE__*/_jsx(GridColumnsPanelRoot, {
className: classes.root,
ownerState: rootProps,
children: currentColumns.map(column => /*#__PURE__*/_jsxs(GridColumnsPanelRowRoot, {
className: classes.columnsPanelRow,
ownerState: rootProps,
children: [/*#__PURE__*/_jsx(FormControlLabel, {
control: /*#__PURE__*/_jsx(rootProps.slots.baseSwitch, _extends({
disabled: column.hideable === false,
checked: columnVisibilityModel[column.field] !== false,
onClick: toggleColumn,
name: column.field,
size: "small",
inputRef: isFirstHideableColumn(column) ? firstSwitchRef : undefined
}, rootProps.slotProps?.baseSwitch)),
label: column.headerName || column.field
}), !rootProps.disableColumnReorder && GRID_EXPERIMENTAL_ENABLED && /*#__PURE__*/_jsx(GridIconButtonRoot, {
draggable: true,
"aria-label": apiRef.current.getLocaleText('columnsPanelDragIconLabel'),
title: apiRef.current.getLocaleText('columnsPanelDragIconLabel'),
size: "small",
disabled: true,
children: /*#__PURE__*/_jsx(rootProps.slots.columnReorderIcon, {})
})]
}, column.field))
})
}), disableShowAllButton && disableHideAllButton ? null : /*#__PURE__*/_jsxs(GridPanelFooter, {
children: [!disableHideAllButton ? /*#__PURE__*/_jsx(rootProps.slots.baseButton, _extends({
onClick: () => toggleAllColumns(false)
}, rootProps.slotProps?.baseButton, {
disabled: disableHideAllButton,
children: apiRef.current.getLocaleText('columnsPanelHideAllButton')
})) : /*#__PURE__*/_jsx("span", {}), !disableShowAllButton ? /*#__PURE__*/_jsx(rootProps.slots.baseButton, _extends({
onClick: () => toggleAllColumns(true)
}, rootProps.slotProps?.baseButton, {
disabled: disableShowAllButton,
children: apiRef.current.getLocaleText('columnsPanelShowAllButton')
})) : null]
})]
}));
}
process.env.NODE_ENV !== "production" ? GridColumnsPanel.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
/**
* If `true`, the column search field will be focused automatically.
* If `false`, the first column switch input will be focused automatically.
* This helps to avoid input keyboard panel to popup automatically on touch devices.
* @default true
*/
autoFocusSearchField: PropTypes.bool,
/**
* If `true`, the `Hide all` button will not be displayed.
* @default false
*/
disableHideAllButton: PropTypes.bool,
/**
* If `true`, the `Show all` button will be disabled
* @default false
*/
disableShowAllButton: PropTypes.bool,
/**
* Returns the list of togglable columns.
* If used, only those columns will be displayed in the panel
* which are passed as the return value of the function.
* @param {GridColDef[]} columns The `ColDef` list of all columns.
* @returns {GridColDef['field'][]} The list of togglable columns' field names.
*/
getTogglableColumns: PropTypes.func,
searchPredicate: PropTypes.func,
slotProps: PropTypes.object,
sort: PropTypes.oneOf(['asc', 'desc'])
} : void 0;
export { GridColumnsPanel };

View File

@@ -0,0 +1,124 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
const _excluded = ["children", "className", "classes"];
import * as React from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import { styled } from '@mui/material/styles';
import { unstable_generateUtilityClasses as generateUtilityClasses } from '@mui/utils';
import ClickAwayListener from '@mui/material/ClickAwayListener';
import Paper from '@mui/material/Paper';
import Popper from '@mui/material/Popper';
import { useGridApiContext } from '../../hooks/utils/useGridApiContext';
import { isEscapeKey } from '../../utils/keyboardUtils';
import { gridClasses } from '../../constants/gridClasses';
import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
import { jsx as _jsx } from "react/jsx-runtime";
export const gridPanelClasses = generateUtilityClasses('MuiDataGrid', ['panel', 'paper']);
const GridPanelRoot = styled(Popper, {
name: 'MuiDataGrid',
slot: 'Panel',
overridesResolver: (props, styles) => styles.panel
})(({
theme
}) => ({
zIndex: theme.zIndex.modal
}));
const GridPaperRoot = styled(Paper, {
name: 'MuiDataGrid',
slot: 'Paper',
overridesResolver: (props, styles) => styles.paper
})(({
theme
}) => ({
backgroundColor: (theme.vars || theme).palette.background.paper,
minWidth: 300,
maxHeight: 450,
display: 'flex'
}));
const GridPanel = /*#__PURE__*/React.forwardRef((props, ref) => {
const {
children,
className
} = props,
other = _objectWithoutPropertiesLoose(props, _excluded);
const apiRef = useGridApiContext();
const rootProps = useGridRootProps();
const classes = gridPanelClasses;
const [isPlaced, setIsPlaced] = React.useState(false);
const handleClickAway = React.useCallback(() => {
apiRef.current.hidePreferences();
}, [apiRef]);
const handleKeyDown = React.useCallback(event => {
if (isEscapeKey(event.key)) {
apiRef.current.hidePreferences();
}
}, [apiRef]);
const modifiers = React.useMemo(() => [{
name: 'flip',
enabled: true,
options: {
rootBoundary: 'document'
}
}, {
name: 'isPlaced',
enabled: true,
phase: 'main',
fn: () => {
setIsPlaced(true);
},
effect: () => () => {
setIsPlaced(false);
}
}], []);
const [anchorEl, setAnchorEl] = React.useState(null);
React.useEffect(() => {
const columnHeadersElement = apiRef.current.rootElementRef?.current?.querySelector(`.${gridClasses.columnHeaders}`);
if (columnHeadersElement) {
setAnchorEl(columnHeadersElement);
}
}, [apiRef]);
if (!anchorEl) {
return null;
}
return /*#__PURE__*/_jsx(GridPanelRoot, _extends({
ref: ref,
placement: "bottom-start",
className: clsx(className, classes.panel),
ownerState: rootProps,
anchorEl: anchorEl,
modifiers: modifiers
}, other, {
children: /*#__PURE__*/_jsx(ClickAwayListener, {
mouseEvent: "onMouseUp",
onClickAway: handleClickAway,
children: /*#__PURE__*/_jsx(GridPaperRoot, {
className: classes.paper,
ownerState: rootProps,
elevation: 8,
onKeyDown: handleKeyDown,
children: isPlaced && children
})
})
}));
});
process.env.NODE_ENV !== "production" ? GridPanel.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
/**
* Popper render function or node.
*/
children: PropTypes.node,
/**
* Override or extend the styles applied to the component.
*/
classes: PropTypes.object,
/**
* If `true`, the component is shown.
*/
open: PropTypes.bool.isRequired,
ownerState: PropTypes.object
} : void 0;
export { GridPanel };

View File

@@ -0,0 +1,51 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
const _excluded = ["className"];
import * as React from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import { styled } from '@mui/system';
import { unstable_composeClasses as composeClasses } from '@mui/utils';
import { getDataGridUtilityClass } from '../../constants/gridClasses';
import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
import { jsx as _jsx } from "react/jsx-runtime";
const useUtilityClasses = ownerState => {
const {
classes
} = ownerState;
const slots = {
root: ['panelContent']
};
return composeClasses(slots, getDataGridUtilityClass, classes);
};
const GridPanelContentRoot = styled('div', {
name: 'MuiDataGrid',
slot: 'PanelContent',
overridesResolver: (props, styles) => styles.panelContent
})({
display: 'flex',
flexDirection: 'column',
overflow: 'auto',
flex: '1 1',
maxHeight: 400
});
function GridPanelContent(props) {
const {
className
} = props,
other = _objectWithoutPropertiesLoose(props, _excluded);
const rootProps = useGridRootProps();
const classes = useUtilityClasses(rootProps);
return /*#__PURE__*/_jsx(GridPanelContentRoot, _extends({
className: clsx(className, classes.root),
ownerState: rootProps
}, other));
}
process.env.NODE_ENV !== "production" ? GridPanelContent.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object])
} : void 0;
export { GridPanelContent };

View File

@@ -0,0 +1,51 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
const _excluded = ["className"];
import * as React from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import { styled } from '@mui/system';
import { unstable_composeClasses as composeClasses } from '@mui/utils';
import { getDataGridUtilityClass } from '../../constants/gridClasses';
import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
import { jsx as _jsx } from "react/jsx-runtime";
const useUtilityClasses = ownerState => {
const {
classes
} = ownerState;
const slots = {
root: ['panelFooter']
};
return composeClasses(slots, getDataGridUtilityClass, classes);
};
const GridPanelFooterRoot = styled('div', {
name: 'MuiDataGrid',
slot: 'PanelFooter',
overridesResolver: (props, styles) => styles.panelFooter
})(({
theme
}) => ({
padding: theme.spacing(0.5),
display: 'flex',
justifyContent: 'space-between'
}));
function GridPanelFooter(props) {
const {
className
} = props,
other = _objectWithoutPropertiesLoose(props, _excluded);
const rootProps = useGridRootProps();
const classes = useUtilityClasses(rootProps);
return /*#__PURE__*/_jsx(GridPanelFooterRoot, _extends({
className: clsx(className, classes.root),
ownerState: rootProps
}, other));
}
process.env.NODE_ENV !== "production" ? GridPanelFooter.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object])
} : void 0;
export { GridPanelFooter };

View File

@@ -0,0 +1,49 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
const _excluded = ["className"];
import * as React from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import { styled } from '@mui/system';
import { unstable_composeClasses as composeClasses } from '@mui/utils';
import { getDataGridUtilityClass } from '../../constants/gridClasses';
import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
import { jsx as _jsx } from "react/jsx-runtime";
const useUtilityClasses = ownerState => {
const {
classes
} = ownerState;
const slots = {
root: ['panelHeader']
};
return composeClasses(slots, getDataGridUtilityClass, classes);
};
const GridPanelHeaderRoot = styled('div', {
name: 'MuiDataGrid',
slot: 'PanelHeader',
overridesResolver: (props, styles) => styles.panelHeader
})(({
theme
}) => ({
padding: theme.spacing(1)
}));
function GridPanelHeader(props) {
const {
className
} = props,
other = _objectWithoutPropertiesLoose(props, _excluded);
const rootProps = useGridRootProps();
const classes = useUtilityClasses(rootProps);
return /*#__PURE__*/_jsx(GridPanelHeaderRoot, _extends({
className: clsx(className, classes.root),
ownerState: rootProps
}, other));
}
process.env.NODE_ENV !== "production" ? GridPanelHeader.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object])
} : void 0;
export { GridPanelHeader };

View File

@@ -0,0 +1,63 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
const _excluded = ["className", "slotProps"];
import * as React from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import FocusTrap from '@mui/material/Unstable_TrapFocus';
import { styled } from '@mui/material/styles';
import { unstable_composeClasses as composeClasses } from '@mui/utils';
import { getDataGridUtilityClass } from '../../constants/gridClasses';
import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
import { jsx as _jsx } from "react/jsx-runtime";
const useUtilityClasses = ownerState => {
const {
classes
} = ownerState;
const slots = {
root: ['panelWrapper']
};
return composeClasses(slots, getDataGridUtilityClass, classes);
};
const GridPanelWrapperRoot = styled('div', {
name: 'MuiDataGrid',
slot: 'PanelWrapper',
overridesResolver: (props, styles) => styles.panelWrapper
})({
display: 'flex',
flexDirection: 'column',
flex: 1,
'&:focus': {
outline: 0
}
});
const isEnabled = () => true;
const GridPanelWrapper = /*#__PURE__*/React.forwardRef(function GridPanelWrapper(props, ref) {
const {
className,
slotProps = {}
} = props,
other = _objectWithoutPropertiesLoose(props, _excluded);
const rootProps = useGridRootProps();
const classes = useUtilityClasses(rootProps);
return /*#__PURE__*/_jsx(FocusTrap, _extends({
open: true,
disableEnforceFocus: true,
isEnabled: isEnabled
}, slotProps.TrapFocus, {
children: /*#__PURE__*/_jsx(GridPanelWrapperRoot, _extends({
ref: ref,
tabIndex: -1,
className: clsx(className, classes.root),
ownerState: rootProps
}, other))
}));
});
process.env.NODE_ENV !== "production" ? GridPanelWrapper.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
slotProps: PropTypes.object
} : void 0;
export { GridPanelWrapper };

View File

@@ -0,0 +1,25 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import * as React from 'react';
import { gridColumnDefinitionsSelector } from '../../hooks/features/columns/gridColumnsSelector';
import { useGridSelector } from '../../hooks/utils/useGridSelector';
import { gridPreferencePanelStateSelector } from '../../hooks/features/preferencesPanel/gridPreferencePanelSelector';
import { GridPreferencePanelsValue } from '../../hooks/features/preferencesPanel/gridPreferencePanelsValue';
import { useGridApiContext } from '../../hooks/utils/useGridApiContext';
import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
import { jsx as _jsx } from "react/jsx-runtime";
export const GridPreferencesPanel = /*#__PURE__*/React.forwardRef(function GridPreferencesPanel(props, ref) {
const apiRef = useGridApiContext();
const columns = useGridSelector(apiRef, gridColumnDefinitionsSelector);
const rootProps = useGridRootProps();
const preferencePanelState = useGridSelector(apiRef, gridPreferencePanelStateSelector);
const panelContent = apiRef.current.unstable_applyPipeProcessors('preferencePanel', null, preferencePanelState.openedPanelValue ?? GridPreferencePanelsValue.filters);
return /*#__PURE__*/_jsx(rootProps.slots.panel, _extends({
ref: ref,
as: rootProps.slots.basePopper,
open: columns.length > 0 && preferencePanelState.open,
id: preferencePanelState.panelId,
"aria-labelledby": preferencePanelState.labelId
}, rootProps.slotProps?.panel, props, rootProps.slotProps?.basePopper, {
children: panelContent
}));
});

View File

@@ -0,0 +1,439 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
const _excluded = ["item", "hasMultipleFilters", "deleteFilter", "applyFilterChanges", "multiFilterOperator", "showMultiFilterOperators", "disableMultiFilterOperator", "applyMultiFilterOperatorChanges", "focusElementRef", "logicOperators", "columnsSort", "filterColumns", "deleteIconProps", "logicOperatorInputProps", "operatorInputProps", "columnInputProps", "valueInputProps", "children"],
_excluded2 = ["InputComponentProps"];
import * as React from 'react';
import PropTypes from 'prop-types';
import { unstable_composeClasses as composeClasses, unstable_useId as useId, unstable_capitalize as capitalize } from '@mui/utils';
import { styled } from '@mui/material/styles';
import clsx from 'clsx';
import { gridFilterableColumnDefinitionsSelector } from '../../../hooks/features/columns/gridColumnsSelector';
import { gridFilterModelSelector } from '../../../hooks/features/filter/gridFilterSelector';
import { useGridSelector } from '../../../hooks/utils/useGridSelector';
import { GridLogicOperator } from '../../../models/gridFilterItem';
import { useGridApiContext } from '../../../hooks/utils/useGridApiContext';
import { useGridRootProps } from '../../../hooks/utils/useGridRootProps';
import { getDataGridUtilityClass } from '../../../constants/gridClasses';
import { jsx as _jsx } from "react/jsx-runtime";
import { createElement as _createElement } from "react";
import { jsxs as _jsxs } from "react/jsx-runtime";
const useUtilityClasses = ownerState => {
const {
classes
} = ownerState;
const slots = {
root: ['filterForm'],
deleteIcon: ['filterFormDeleteIcon'],
logicOperatorInput: ['filterFormLogicOperatorInput'],
columnInput: ['filterFormColumnInput'],
operatorInput: ['filterFormOperatorInput'],
valueInput: ['filterFormValueInput']
};
return composeClasses(slots, getDataGridUtilityClass, classes);
};
const GridFilterFormRoot = styled('div', {
name: 'MuiDataGrid',
slot: 'FilterForm',
overridesResolver: (props, styles) => styles.filterForm
})(({
theme
}) => ({
display: 'flex',
padding: theme.spacing(1)
}));
const FilterFormDeleteIcon = styled('div', {
name: 'MuiDataGrid',
slot: 'FilterFormDeleteIcon',
overridesResolver: (_, styles) => styles.filterFormDeleteIcon
})(({
theme
}) => ({
flexShrink: 0,
justifyContent: 'flex-end',
marginRight: theme.spacing(0.5),
marginBottom: theme.spacing(0.2)
}));
const FilterFormLogicOperatorInput = styled('div', {
name: 'MuiDataGrid',
slot: 'FilterFormLogicOperatorInput',
overridesResolver: (_, styles) => styles.filterFormLogicOperatorInput
})({
minWidth: 55,
marginRight: 5,
justifyContent: 'end'
});
const FilterFormColumnInput = styled('div', {
name: 'MuiDataGrid',
slot: 'FilterFormColumnInput',
overridesResolver: (_, styles) => styles.filterFormColumnInput
})({
width: 150
});
const FilterFormOperatorInput = styled('div', {
name: 'MuiDataGrid',
slot: 'FilterFormOperatorInput',
overridesResolver: (_, styles) => styles.filterFormOperatorInput
})({
width: 120
});
const FilterFormValueInput = styled('div', {
name: 'MuiDataGrid',
slot: 'FilterFormValueInput',
overridesResolver: (_, styles) => styles.filterFormValueInput
})({
width: 190
});
const getLogicOperatorLocaleKey = logicOperator => {
switch (logicOperator) {
case GridLogicOperator.And:
return 'filterPanelOperatorAnd';
case GridLogicOperator.Or:
return 'filterPanelOperatorOr';
default:
throw new Error('MUI: Invalid `logicOperator` property in the `GridFilterPanel`.');
}
};
const getColumnLabel = col => col.headerName || col.field;
const collator = new Intl.Collator();
const GridFilterForm = /*#__PURE__*/React.forwardRef(function GridFilterForm(props, ref) {
const {
item,
hasMultipleFilters,
deleteFilter,
applyFilterChanges,
multiFilterOperator,
showMultiFilterOperators,
disableMultiFilterOperator,
applyMultiFilterOperatorChanges,
focusElementRef,
logicOperators = [GridLogicOperator.And, GridLogicOperator.Or],
columnsSort,
filterColumns,
deleteIconProps = {},
logicOperatorInputProps = {},
operatorInputProps = {},
columnInputProps = {},
valueInputProps = {}
} = props,
other = _objectWithoutPropertiesLoose(props, _excluded);
const apiRef = useGridApiContext();
const filterableColumns = useGridSelector(apiRef, gridFilterableColumnDefinitionsSelector);
const filterModel = useGridSelector(apiRef, gridFilterModelSelector);
const columnSelectId = useId();
const columnSelectLabelId = useId();
const operatorSelectId = useId();
const operatorSelectLabelId = useId();
const rootProps = useGridRootProps();
const classes = useUtilityClasses(rootProps);
const valueRef = React.useRef(null);
const filterSelectorRef = React.useRef(null);
const hasLogicOperatorColumn = hasMultipleFilters && logicOperators.length > 0;
const baseFormControlProps = rootProps.slotProps?.baseFormControl || {};
const baseSelectProps = rootProps.slotProps?.baseSelect || {};
const isBaseSelectNative = baseSelectProps.native ?? true;
const baseInputLabelProps = rootProps.slotProps?.baseInputLabel || {};
const baseSelectOptionProps = rootProps.slotProps?.baseSelectOption || {};
const {
InputComponentProps
} = valueInputProps,
valueInputPropsOther = _objectWithoutPropertiesLoose(valueInputProps, _excluded2);
const filteredColumns = React.useMemo(() => {
if (filterColumns === undefined || typeof filterColumns !== 'function') {
return filterableColumns;
}
const filteredFields = filterColumns({
field: item.field,
columns: filterableColumns,
currentFilters: filterModel?.items || []
});
return filterableColumns.filter(column => filteredFields.includes(column.field));
}, [filterColumns, filterModel?.items, filterableColumns, item.field]);
const sortedFilteredColumns = React.useMemo(() => {
switch (columnsSort) {
case 'asc':
return filteredColumns.sort((a, b) => collator.compare(getColumnLabel(a), getColumnLabel(b)));
case 'desc':
return filteredColumns.sort((a, b) => -collator.compare(getColumnLabel(a), getColumnLabel(b)));
default:
return filteredColumns;
}
}, [filteredColumns, columnsSort]);
const currentColumn = item.field ? apiRef.current.getColumn(item.field) : null;
const currentOperator = React.useMemo(() => {
if (!item.operator || !currentColumn) {
return null;
}
return currentColumn.filterOperators?.find(operator => operator.value === item.operator);
}, [item, currentColumn]);
const changeColumn = React.useCallback(event => {
const field = event.target.value;
const column = apiRef.current.getColumn(field);
if (column.field === currentColumn.field) {
// column did not change
return;
}
// try to keep the same operator when column change
const newOperator = column.filterOperators.find(operator => operator.value === item.operator) || column.filterOperators[0];
// Erase filter value if the input component or filtered column type is modified
const eraseItemValue = !newOperator.InputComponent || newOperator.InputComponent !== currentOperator?.InputComponent || column.type !== currentColumn.type;
applyFilterChanges(_extends({}, item, {
field,
operator: newOperator.value,
value: eraseItemValue ? undefined : item.value
}));
}, [apiRef, applyFilterChanges, item, currentColumn, currentOperator]);
const changeOperator = React.useCallback(event => {
const operator = event.target.value;
const newOperator = currentColumn?.filterOperators.find(op => op.value === operator);
const eraseItemValue = !newOperator?.InputComponent || newOperator?.InputComponent !== currentOperator?.InputComponent;
applyFilterChanges(_extends({}, item, {
operator,
value: eraseItemValue ? undefined : item.value
}));
}, [applyFilterChanges, item, currentColumn, currentOperator]);
const changeLogicOperator = React.useCallback(event => {
const logicOperator = event.target.value === GridLogicOperator.And.toString() ? GridLogicOperator.And : GridLogicOperator.Or;
applyMultiFilterOperatorChanges(logicOperator);
}, [applyMultiFilterOperatorChanges]);
const handleDeleteFilter = () => {
if (rootProps.disableMultipleColumnsFiltering) {
if (item.value === undefined) {
deleteFilter(item);
} else {
// TODO v6: simplify the behavior by always remove the filter form
applyFilterChanges(_extends({}, item, {
value: undefined
}));
}
} else {
deleteFilter(item);
}
};
React.useImperativeHandle(focusElementRef, () => ({
focus: () => {
if (currentOperator?.InputComponent) {
valueRef?.current?.focus();
} else {
filterSelectorRef.current.focus();
}
}
}), [currentOperator]);
return /*#__PURE__*/_jsxs(GridFilterFormRoot, _extends({
ref: ref,
className: classes.root,
"data-id": item.id,
ownerState: rootProps
}, other, {
children: [/*#__PURE__*/_jsx(FilterFormDeleteIcon, _extends({
variant: "standard",
as: rootProps.slots.baseFormControl
}, baseFormControlProps, deleteIconProps, {
className: clsx(classes.deleteIcon, baseFormControlProps.className, deleteIconProps.className),
ownerState: rootProps,
children: /*#__PURE__*/_jsx(rootProps.slots.baseIconButton, _extends({
"aria-label": apiRef.current.getLocaleText('filterPanelDeleteIconLabel'),
title: apiRef.current.getLocaleText('filterPanelDeleteIconLabel'),
onClick: handleDeleteFilter,
size: "small"
}, rootProps.slotProps?.baseIconButton, {
children: /*#__PURE__*/_jsx(rootProps.slots.filterPanelDeleteIcon, {
fontSize: "small"
})
}))
})), /*#__PURE__*/_jsx(FilterFormLogicOperatorInput, _extends({
variant: "standard",
as: rootProps.slots.baseFormControl
}, baseFormControlProps, logicOperatorInputProps, {
sx: _extends({
display: hasLogicOperatorColumn ? 'flex' : 'none',
visibility: showMultiFilterOperators ? 'visible' : 'hidden'
}, baseFormControlProps.sx || {}, logicOperatorInputProps.sx || {}),
className: clsx(classes.logicOperatorInput, baseFormControlProps.className, logicOperatorInputProps.className),
ownerState: rootProps,
children: /*#__PURE__*/_jsx(rootProps.slots.baseSelect, _extends({
inputProps: {
'aria-label': apiRef.current.getLocaleText('filterPanelLogicOperator')
},
value: multiFilterOperator,
onChange: changeLogicOperator,
disabled: !!disableMultiFilterOperator || logicOperators.length === 1,
native: isBaseSelectNative
}, rootProps.slotProps?.baseSelect, {
children: logicOperators.map(logicOperator => /*#__PURE__*/_createElement(rootProps.slots.baseSelectOption, _extends({}, baseSelectOptionProps, {
native: isBaseSelectNative,
key: logicOperator.toString(),
value: logicOperator.toString()
}), apiRef.current.getLocaleText(getLogicOperatorLocaleKey(logicOperator))))
}))
})), /*#__PURE__*/_jsxs(FilterFormColumnInput, _extends({
variant: "standard",
as: rootProps.slots.baseFormControl
}, baseFormControlProps, columnInputProps, {
className: clsx(classes.columnInput, baseFormControlProps.className, columnInputProps.className),
ownerState: rootProps,
children: [/*#__PURE__*/_jsx(rootProps.slots.baseInputLabel, _extends({}, baseInputLabelProps, {
htmlFor: columnSelectId,
id: columnSelectLabelId,
children: apiRef.current.getLocaleText('filterPanelColumns')
})), /*#__PURE__*/_jsx(rootProps.slots.baseSelect, _extends({
labelId: columnSelectLabelId,
id: columnSelectId,
label: apiRef.current.getLocaleText('filterPanelColumns'),
value: item.field || '',
onChange: changeColumn,
native: isBaseSelectNative
}, rootProps.slotProps?.baseSelect, {
children: sortedFilteredColumns.map(col => /*#__PURE__*/_createElement(rootProps.slots.baseSelectOption, _extends({}, baseSelectOptionProps, {
native: isBaseSelectNative,
key: col.field,
value: col.field
}), getColumnLabel(col)))
}))]
})), /*#__PURE__*/_jsxs(FilterFormOperatorInput, _extends({
variant: "standard",
as: rootProps.slots.baseFormControl
}, baseFormControlProps, operatorInputProps, {
className: clsx(classes.operatorInput, baseFormControlProps.className, operatorInputProps.className),
ownerState: rootProps,
children: [/*#__PURE__*/_jsx(rootProps.slots.baseInputLabel, _extends({}, baseInputLabelProps, {
htmlFor: operatorSelectId,
id: operatorSelectLabelId,
children: apiRef.current.getLocaleText('filterPanelOperator')
})), /*#__PURE__*/_jsx(rootProps.slots.baseSelect, _extends({
labelId: operatorSelectLabelId,
label: apiRef.current.getLocaleText('filterPanelOperator'),
id: operatorSelectId,
value: item.operator,
onChange: changeOperator,
native: isBaseSelectNative,
inputRef: filterSelectorRef
}, rootProps.slotProps?.baseSelect, {
children: currentColumn?.filterOperators?.map(operator => /*#__PURE__*/_createElement(rootProps.slots.baseSelectOption, _extends({}, baseSelectOptionProps, {
native: isBaseSelectNative,
key: operator.value,
value: operator.value
}), operator.label || apiRef.current.getLocaleText(`filterOperator${capitalize(operator.value)}`)))
}))]
})), /*#__PURE__*/_jsx(FilterFormValueInput, _extends({
variant: "standard",
as: rootProps.slots.baseFormControl
}, baseFormControlProps, valueInputPropsOther, {
className: clsx(classes.valueInput, baseFormControlProps.className, valueInputPropsOther.className),
ownerState: rootProps,
children: currentOperator?.InputComponent ? /*#__PURE__*/_jsx(currentOperator.InputComponent, _extends({
apiRef: apiRef,
item: item,
applyValue: applyFilterChanges,
focusElementRef: valueRef
}, currentOperator.InputComponentProps, InputComponentProps)) : null
}))]
}));
});
process.env.NODE_ENV !== "production" ? GridFilterForm.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
/**
* Callback called when the operator, column field or value is changed.
* @param {GridFilterItem} item The updated [[GridFilterItem]].
*/
applyFilterChanges: PropTypes.func.isRequired,
/**
* Callback called when the logic operator is changed.
* @param {GridLogicOperator} operator The new logic operator.
*/
applyMultiFilterOperatorChanges: PropTypes.func.isRequired,
/**
* @ignore - do not document.
*/
children: PropTypes.node,
/**
* Props passed to the column input component.
* @default {}
*/
columnInputProps: PropTypes.any,
/**
* Changes how the options in the columns selector should be ordered.
* If not specified, the order is derived from the `columns` prop.
*/
columnsSort: PropTypes.oneOf(['asc', 'desc']),
/**
* Callback called when the delete button is clicked.
* @param {GridFilterItem} item The deleted [[GridFilterItem]].
*/
deleteFilter: PropTypes.func.isRequired,
/**
* Props passed to the delete icon.
* @default {}
*/
deleteIconProps: PropTypes.any,
/**
* If `true`, disables the logic operator field but still renders it.
*/
disableMultiFilterOperator: PropTypes.bool,
/**
* Allows to filter the columns displayed in the filter form.
* @param {FilterColumnsArgs} args The columns of the grid and name of field.
* @returns {GridColDef['field'][]} The filtered fields array.
*/
filterColumns: PropTypes.func,
/**
* A ref allowing to set imperative focus.
* It can be passed to the el
*/
focusElementRef: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.func, PropTypes.object]),
/**
* If `true`, the logic operator field is rendered.
* The field will be invisible if `showMultiFilterOperators` is also `true`.
*/
hasMultipleFilters: PropTypes.bool.isRequired,
/**
* The [[GridFilterItem]] representing this form.
*/
item: PropTypes.shape({
field: PropTypes.string.isRequired,
id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
operator: PropTypes.string.isRequired,
value: PropTypes.any
}).isRequired,
/**
* Props passed to the logic operator input component.
* @default {}
*/
logicOperatorInputProps: PropTypes.any,
/**
* Sets the available logic operators.
* @default [GridLogicOperator.And, GridLogicOperator.Or]
*/
logicOperators: PropTypes.arrayOf(PropTypes.oneOf(['and', 'or']).isRequired),
/**
* The current logic operator applied.
*/
multiFilterOperator: PropTypes.oneOf(['and', 'or']),
/**
* Props passed to the operator input component.
* @default {}
*/
operatorInputProps: PropTypes.any,
/**
* If `true`, the logic operator field is visible.
*/
showMultiFilterOperators: PropTypes.bool,
/**
* Props passed to the value input component.
* @default {}
*/
valueInputProps: PropTypes.any
} : void 0;
/**
* Demos:
* - [Filtering - overview](https://mui.com/x/react-data-grid/filtering/)
*
* API:
* - [GridFilterForm API](https://mui.com/x/api/data-grid/grid-filter-form/)
*/
export { GridFilterForm };

View File

@@ -0,0 +1,112 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
const _excluded = ["item", "applyValue", "apiRef", "focusElementRef", "isFilterActive", "clearButton", "tabIndex", "label", "variant", "InputLabelProps"];
import * as React from 'react';
import PropTypes from 'prop-types';
import { refType, unstable_useId as useId } from '@mui/utils';
import { styled } from '@mui/material/styles';
import { useGridRootProps } from '../../../hooks/utils/useGridRootProps';
import { jsx as _jsx } from "react/jsx-runtime";
import { jsxs as _jsxs } from "react/jsx-runtime";
const BooleanOperatorContainer = styled('div')({
display: 'flex',
alignItems: 'center',
width: '100%',
[`& button`]: {
margin: 'auto 0px 5px 5px'
}
});
function GridFilterInputBoolean(props) {
const {
item,
applyValue,
apiRef,
focusElementRef,
clearButton,
tabIndex,
label: labelProp,
variant = 'standard'
} = props,
others = _objectWithoutPropertiesLoose(props, _excluded);
const [filterValueState, setFilterValueState] = React.useState(item.value || '');
const rootProps = useGridRootProps();
const labelId = useId();
const selectId = useId();
const baseSelectProps = rootProps.slotProps?.baseSelect || {};
const isSelectNative = baseSelectProps.native ?? true;
const baseSelectOptionProps = rootProps.slotProps?.baseSelectOption || {};
const onFilterChange = React.useCallback(event => {
const value = event.target.value;
setFilterValueState(value);
applyValue(_extends({}, item, {
value
}));
}, [applyValue, item]);
React.useEffect(() => {
setFilterValueState(item.value || '');
}, [item.value]);
const label = labelProp ?? apiRef.current.getLocaleText('filterPanelInputLabel');
return /*#__PURE__*/_jsxs(BooleanOperatorContainer, {
children: [/*#__PURE__*/_jsxs(rootProps.slots.baseFormControl, {
fullWidth: true,
children: [/*#__PURE__*/_jsx(rootProps.slots.baseInputLabel, _extends({}, rootProps.slotProps?.baseInputLabel, {
id: labelId,
shrink: true,
variant: variant,
children: label
})), /*#__PURE__*/_jsxs(rootProps.slots.baseSelect, _extends({
labelId: labelId,
id: selectId,
label: label,
value: filterValueState,
onChange: onFilterChange,
variant: variant,
notched: variant === 'outlined' ? true : undefined,
native: isSelectNative,
displayEmpty: true,
inputProps: {
ref: focusElementRef,
tabIndex
}
}, others, baseSelectProps, {
children: [/*#__PURE__*/_jsx(rootProps.slots.baseSelectOption, _extends({}, baseSelectOptionProps, {
native: isSelectNative,
value: "",
children: apiRef.current.getLocaleText('filterValueAny')
})), /*#__PURE__*/_jsx(rootProps.slots.baseSelectOption, _extends({}, baseSelectOptionProps, {
native: isSelectNative,
value: "true",
children: apiRef.current.getLocaleText('filterValueTrue')
})), /*#__PURE__*/_jsx(rootProps.slots.baseSelectOption, _extends({}, baseSelectOptionProps, {
native: isSelectNative,
value: "false",
children: apiRef.current.getLocaleText('filterValueFalse')
}))]
}))]
}), clearButton]
});
}
process.env.NODE_ENV !== "production" ? GridFilterInputBoolean.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
apiRef: PropTypes.shape({
current: PropTypes.object.isRequired
}).isRequired,
applyValue: PropTypes.func.isRequired,
clearButton: PropTypes.node,
focusElementRef: refType,
/**
* It is `true` if the filter either has a value or an operator with no value
* required is selected (e.g. `isEmpty`)
*/
isFilterActive: PropTypes.bool,
item: PropTypes.shape({
field: PropTypes.string.isRequired,
id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
operator: PropTypes.string.isRequired,
value: PropTypes.any
}).isRequired
} : void 0;
export { GridFilterInputBoolean };

View File

@@ -0,0 +1,94 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
const _excluded = ["item", "applyValue", "type", "apiRef", "focusElementRef", "InputProps", "isFilterActive", "clearButton", "tabIndex", "disabled"];
import * as React from 'react';
import PropTypes from 'prop-types';
import { unstable_useId as useId } from '@mui/utils';
import { useTimeout } from '../../../hooks/utils/useTimeout';
import { useGridRootProps } from '../../../hooks/utils/useGridRootProps';
import { jsx as _jsx } from "react/jsx-runtime";
function GridFilterInputDate(props) {
const {
item,
applyValue,
type,
apiRef,
focusElementRef,
InputProps,
clearButton,
tabIndex,
disabled
} = props,
other = _objectWithoutPropertiesLoose(props, _excluded);
const filterTimeout = useTimeout();
const [filterValueState, setFilterValueState] = React.useState(item.value ?? '');
const [applying, setIsApplying] = React.useState(false);
const id = useId();
const rootProps = useGridRootProps();
const onFilterChange = React.useCallback(event => {
const value = event.target.value;
setFilterValueState(String(value));
setIsApplying(true);
filterTimeout.start(rootProps.filterDebounceMs, () => {
applyValue(_extends({}, item, {
value
}));
setIsApplying(false);
});
}, [applyValue, item, rootProps.filterDebounceMs, filterTimeout]);
React.useEffect(() => {
const itemValue = item.value ?? '';
setFilterValueState(String(itemValue));
}, [item.value]);
return /*#__PURE__*/_jsx(rootProps.slots.baseTextField, _extends({
fullWidth: true,
id: id,
label: apiRef.current.getLocaleText('filterPanelInputLabel'),
placeholder: apiRef.current.getLocaleText('filterPanelInputPlaceholder'),
value: filterValueState,
onChange: onFilterChange,
variant: "standard",
type: type || 'text',
InputLabelProps: {
shrink: true
},
inputRef: focusElementRef,
InputProps: _extends({}, applying || clearButton ? {
endAdornment: applying ? /*#__PURE__*/_jsx(rootProps.slots.loadIcon, {
fontSize: "small",
color: "action"
}) : clearButton
} : {}, {
disabled
}, InputProps, {
inputProps: _extends({
max: type === 'datetime-local' ? '9999-12-31T23:59' : '9999-12-31',
tabIndex
}, InputProps?.inputProps)
})
}, other, rootProps.slotProps?.baseTextField));
}
process.env.NODE_ENV !== "production" ? GridFilterInputDate.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
apiRef: PropTypes.shape({
current: PropTypes.object.isRequired
}).isRequired,
applyValue: PropTypes.func.isRequired,
clearButton: PropTypes.node,
focusElementRef: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.func, PropTypes.object]),
/**
* It is `true` if the filter either has a value or an operator with no value
* required is selected (e.g. `isEmpty`)
*/
isFilterActive: PropTypes.bool,
item: PropTypes.shape({
field: PropTypes.string.isRequired,
id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
operator: PropTypes.string.isRequired,
value: PropTypes.any
}).isRequired
} : void 0;
export { GridFilterInputDate };

View File

@@ -0,0 +1,146 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
const _excluded = ["item", "applyValue", "type", "apiRef", "focusElementRef", "color", "error", "helperText", "size", "variant", "getOptionLabel", "getOptionValue"];
import * as React from 'react';
import PropTypes from 'prop-types';
import Autocomplete, { createFilterOptions } from '@mui/material/Autocomplete';
import { unstable_useId as useId } from '@mui/utils';
import { isSingleSelectColDef } from './filterPanelUtils';
import { useGridRootProps } from '../../../hooks/utils/useGridRootProps';
import { jsx as _jsx } from "react/jsx-runtime";
const filter = createFilterOptions();
function GridFilterInputMultipleSingleSelect(props) {
const {
item,
applyValue,
apiRef,
focusElementRef,
color,
error,
helperText,
size,
variant = 'standard',
getOptionLabel: getOptionLabelProp,
getOptionValue: getOptionValueProp
} = props,
other = _objectWithoutPropertiesLoose(props, _excluded);
const TextFieldProps = {
color,
error,
helperText,
size,
variant
};
const id = useId();
const rootProps = useGridRootProps();
let resolvedColumn = null;
if (item.field) {
const column = apiRef.current.getColumn(item.field);
if (isSingleSelectColDef(column)) {
resolvedColumn = column;
}
}
const getOptionValue = getOptionValueProp || resolvedColumn?.getOptionValue;
const getOptionLabel = getOptionLabelProp || resolvedColumn?.getOptionLabel;
const isOptionEqualToValue = React.useCallback((option, value) => getOptionValue(option) === getOptionValue(value), [getOptionValue]);
const resolvedValueOptions = React.useMemo(() => {
if (!resolvedColumn?.valueOptions) {
return [];
}
if (typeof resolvedColumn.valueOptions === 'function') {
return resolvedColumn.valueOptions({
field: resolvedColumn.field
});
}
return resolvedColumn.valueOptions;
}, [resolvedColumn]);
const resolvedFormattedValueOptions = React.useMemo(() => {
return resolvedValueOptions?.map(getOptionValue);
}, [resolvedValueOptions, getOptionValue]);
// The value is computed from the item.value and used directly
// If it was done by a useEffect/useState, the Autocomplete could receive incoherent value and options
const filteredValues = React.useMemo(() => {
if (!Array.isArray(item.value)) {
return [];
}
if (resolvedValueOptions !== undefined) {
const itemValueIndexes = item.value.map(element => {
// Gets the index matching between values and valueOptions
return resolvedFormattedValueOptions?.findIndex(formattedOption => formattedOption === element);
});
return itemValueIndexes.filter(index => index >= 0).map(index => resolvedValueOptions[index]);
}
return item.value;
}, [item.value, resolvedValueOptions, resolvedFormattedValueOptions]);
React.useEffect(() => {
if (!Array.isArray(item.value) || filteredValues.length !== item.value.length) {
// Updates the state if the filter value has been cleaned by the component
applyValue(_extends({}, item, {
value: filteredValues.map(getOptionValue)
}));
}
}, [item, filteredValues, applyValue, getOptionValue]);
const handleChange = React.useCallback((event, value) => {
applyValue(_extends({}, item, {
value: value.map(getOptionValue)
}));
}, [applyValue, item, getOptionValue]);
return /*#__PURE__*/_jsx(Autocomplete, _extends({
multiple: true,
options: resolvedValueOptions,
isOptionEqualToValue: isOptionEqualToValue,
filterOptions: filter,
id: id,
value: filteredValues,
onChange: handleChange,
getOptionLabel: getOptionLabel,
renderTags: (value, getTagProps) => value.map((option, index) => /*#__PURE__*/_jsx(rootProps.slots.baseChip, _extends({
variant: "outlined",
size: "small",
label: getOptionLabel(option)
}, getTagProps({
index
})))),
renderInput: params => /*#__PURE__*/_jsx(rootProps.slots.baseTextField, _extends({}, params, {
label: apiRef.current.getLocaleText('filterPanelInputLabel'),
placeholder: apiRef.current.getLocaleText('filterPanelInputPlaceholder'),
InputLabelProps: _extends({}, params.InputLabelProps, {
shrink: true
}),
inputRef: focusElementRef,
type: "singleSelect"
}, TextFieldProps, rootProps.slotProps?.baseTextField))
}, other));
}
process.env.NODE_ENV !== "production" ? GridFilterInputMultipleSingleSelect.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
apiRef: PropTypes.shape({
current: PropTypes.object.isRequired
}).isRequired,
applyValue: PropTypes.func.isRequired,
focusElementRef: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.func, PropTypes.object]),
/**
* Used to determine the label displayed for a given value option.
* @param {ValueOptions} value The current value option.
* @returns {string} The text to be displayed.
*/
getOptionLabel: PropTypes.func,
/**
* Used to determine the value used for a value option.
* @param {ValueOptions} value The current value option.
* @returns {string} The value to be used.
*/
getOptionValue: PropTypes.func,
item: PropTypes.shape({
field: PropTypes.string.isRequired,
id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
operator: PropTypes.string.isRequired,
value: PropTypes.any
}).isRequired,
type: PropTypes.oneOf(['singleSelect'])
} : void 0;
export { GridFilterInputMultipleSingleSelect };

View File

@@ -0,0 +1,93 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
const _excluded = ["item", "applyValue", "type", "apiRef", "focusElementRef", "color", "error", "helperText", "size", "variant"];
import * as React from 'react';
import PropTypes from 'prop-types';
import Autocomplete from '@mui/material/Autocomplete';
import { unstable_useId as useId } from '@mui/utils';
import { useGridRootProps } from '../../../hooks/utils/useGridRootProps';
import { jsx as _jsx } from "react/jsx-runtime";
function GridFilterInputMultipleValue(props) {
const {
item,
applyValue,
type,
apiRef,
focusElementRef,
color,
error,
helperText,
size,
variant
} = props,
other = _objectWithoutPropertiesLoose(props, _excluded);
const TextFieldProps = {
color,
error,
helperText,
size,
variant
};
const [filterValueState, setFilterValueState] = React.useState(item.value || []);
const id = useId();
const rootProps = useGridRootProps();
React.useEffect(() => {
const itemValue = item.value ?? [];
setFilterValueState(itemValue.map(String));
}, [item.value]);
const handleChange = React.useCallback((event, value) => {
setFilterValueState(value.map(String));
applyValue(_extends({}, item, {
value: [...value]
}));
}, [applyValue, item]);
return /*#__PURE__*/_jsx(Autocomplete, _extends({
multiple: true,
freeSolo: true,
options: [],
filterOptions: (options, params) => {
const {
inputValue
} = params;
return inputValue == null || inputValue === '' ? [] : [inputValue];
},
id: id,
value: filterValueState,
onChange: handleChange,
renderTags: (value, getTagProps) => value.map((option, index) => /*#__PURE__*/_jsx(rootProps.slots.baseChip, _extends({
variant: "outlined",
size: "small",
label: option
}, getTagProps({
index
})))),
renderInput: params => /*#__PURE__*/_jsx(rootProps.slots.baseTextField, _extends({}, params, {
label: apiRef.current.getLocaleText('filterPanelInputLabel'),
placeholder: apiRef.current.getLocaleText('filterPanelInputPlaceholder'),
InputLabelProps: _extends({}, params.InputLabelProps, {
shrink: true
}),
inputRef: focusElementRef,
type: type || 'text'
}, TextFieldProps, rootProps.slotProps?.baseTextField))
}, other));
}
process.env.NODE_ENV !== "production" ? GridFilterInputMultipleValue.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
apiRef: PropTypes.shape({
current: PropTypes.object.isRequired
}).isRequired,
applyValue: PropTypes.func.isRequired,
focusElementRef: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.func, PropTypes.object]),
item: PropTypes.shape({
field: PropTypes.string.isRequired,
id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
operator: PropTypes.string.isRequired,
value: PropTypes.any
}).isRequired,
type: PropTypes.oneOf(['number', 'text'])
} : void 0;
export { GridFilterInputMultipleValue };

View File

@@ -0,0 +1,188 @@
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
import _extends from "@babel/runtime/helpers/esm/extends";
const _excluded = ["item", "applyValue", "type", "apiRef", "focusElementRef", "getOptionLabel", "getOptionValue", "placeholder", "tabIndex", "label", "variant", "isFilterActive", "clearButton", "InputLabelProps"];
import * as React from 'react';
import PropTypes from 'prop-types';
import { unstable_useId as useId } from '@mui/utils';
import { styled } from '@mui/material/styles';
import { useGridRootProps } from '../../../hooks/utils/useGridRootProps';
import { getValueFromValueOptions, isSingleSelectColDef } from './filterPanelUtils';
import { createElement as _createElement } from "react";
import { jsx as _jsx } from "react/jsx-runtime";
import { jsxs as _jsxs } from "react/jsx-runtime";
const renderSingleSelectOptions = ({
column: {
valueOptions,
field
},
OptionComponent,
getOptionLabel,
getOptionValue,
isSelectNative,
baseSelectOptionProps
}) => {
const iterableColumnValues = typeof valueOptions === 'function' ? ['', ...valueOptions({
field
})] : ['', ...(valueOptions || [])];
return iterableColumnValues.map(option => {
const value = getOptionValue(option);
const label = getOptionLabel(option);
return /*#__PURE__*/_createElement(OptionComponent, _extends({}, baseSelectOptionProps, {
native: isSelectNative,
key: value,
value: value
}), label);
});
};
const SingleSelectOperatorContainer = styled('div')({
display: 'flex',
alignItems: 'flex-end',
width: '100%',
[`& button`]: {
margin: 'auto 0px 5px 5px'
}
});
function GridFilterInputSingleSelect(props) {
const {
item,
applyValue,
type,
apiRef,
focusElementRef,
getOptionLabel: getOptionLabelProp,
getOptionValue: getOptionValueProp,
placeholder,
tabIndex,
label: labelProp,
variant = 'standard',
clearButton
} = props,
others = _objectWithoutPropertiesLoose(props, _excluded);
const [filterValueState, setFilterValueState] = React.useState(item.value ?? '');
const id = useId();
const labelId = useId();
const rootProps = useGridRootProps();
const isSelectNative = rootProps.slotProps?.baseSelect?.native ?? true;
let resolvedColumn = null;
if (item.field) {
const column = apiRef.current.getColumn(item.field);
if (isSingleSelectColDef(column)) {
resolvedColumn = column;
}
}
const getOptionValue = getOptionValueProp || resolvedColumn?.getOptionValue;
const getOptionLabel = getOptionLabelProp || resolvedColumn?.getOptionLabel;
const currentValueOptions = React.useMemo(() => {
if (!resolvedColumn) {
return undefined;
}
return typeof resolvedColumn.valueOptions === 'function' ? resolvedColumn.valueOptions({
field: resolvedColumn.field
}) : resolvedColumn.valueOptions;
}, [resolvedColumn]);
const onFilterChange = React.useCallback(event => {
let value = event.target.value;
// NativeSelect casts the value to a string.
value = getValueFromValueOptions(value, currentValueOptions, getOptionValue);
setFilterValueState(String(value));
applyValue(_extends({}, item, {
value
}));
}, [currentValueOptions, getOptionValue, applyValue, item]);
React.useEffect(() => {
let itemValue;
if (currentValueOptions !== undefined) {
// sanitize if valueOptions are provided
itemValue = getValueFromValueOptions(item.value, currentValueOptions, getOptionValue);
if (itemValue !== item.value) {
applyValue(_extends({}, item, {
value: itemValue
}));
return;
}
} else {
itemValue = item.value;
}
itemValue = itemValue ?? '';
setFilterValueState(String(itemValue));
}, [item, currentValueOptions, applyValue, getOptionValue]);
if (!isSingleSelectColDef(resolvedColumn)) {
return null;
}
if (!isSingleSelectColDef(resolvedColumn)) {
return null;
}
const label = labelProp ?? apiRef.current.getLocaleText('filterPanelInputLabel');
return /*#__PURE__*/_jsxs(SingleSelectOperatorContainer, {
children: [/*#__PURE__*/_jsxs(rootProps.slots.baseFormControl, {
children: [/*#__PURE__*/_jsx(rootProps.slots.baseInputLabel, _extends({}, rootProps.slotProps?.baseInputLabel, {
id: labelId,
htmlFor: id,
shrink: true,
variant: variant,
children: label
})), /*#__PURE__*/_jsx(rootProps.slots.baseSelect, _extends({
id: id,
label: label,
labelId: labelId,
value: filterValueState,
onChange: onFilterChange,
variant: variant,
type: type || 'text',
inputProps: {
tabIndex,
ref: focusElementRef,
placeholder: placeholder ?? apiRef.current.getLocaleText('filterPanelInputPlaceholder')
},
native: isSelectNative,
notched: variant === 'outlined' ? true : undefined
}, others /* FIXME: typing error */, rootProps.slotProps?.baseSelect, {
children: renderSingleSelectOptions({
column: resolvedColumn,
OptionComponent: rootProps.slots.baseSelectOption,
getOptionLabel,
getOptionValue,
isSelectNative,
baseSelectOptionProps: rootProps.slotProps?.baseSelectOption
})
}))]
}), clearButton]
});
}
process.env.NODE_ENV !== "production" ? GridFilterInputSingleSelect.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
apiRef: PropTypes.shape({
current: PropTypes.object.isRequired
}).isRequired,
applyValue: PropTypes.func.isRequired,
clearButton: PropTypes.node,
focusElementRef: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.func, PropTypes.object]),
/**
* Used to determine the label displayed for a given value option.
* @param {ValueOptions} value The current value option.
* @returns {string} The text to be displayed.
*/
getOptionLabel: PropTypes.func,
/**
* Used to determine the value used for a value option.
* @param {ValueOptions} value The current value option.
* @returns {string} The value to be used.
*/
getOptionValue: PropTypes.func,
/**
* It is `true` if the filter either has a value or an operator with no value
* required is selected (e.g. `isEmpty`)
*/
isFilterActive: PropTypes.bool,
item: PropTypes.shape({
field: PropTypes.string.isRequired,
id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
operator: PropTypes.string.isRequired,
value: PropTypes.any
}).isRequired
} : void 0;
export { GridFilterInputSingleSelect };

View File

@@ -0,0 +1,99 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
const _excluded = ["item", "applyValue", "type", "apiRef", "focusElementRef", "tabIndex", "disabled", "isFilterActive", "clearButton", "InputProps", "variant"];
import * as React from 'react';
import PropTypes from 'prop-types';
import { unstable_useId as useId } from '@mui/utils';
import { useTimeout } from '../../../hooks/utils/useTimeout';
import { useGridRootProps } from '../../../hooks/utils/useGridRootProps';
import { jsx as _jsx } from "react/jsx-runtime";
function GridFilterInputValue(props) {
const {
item,
applyValue,
type,
apiRef,
focusElementRef,
tabIndex,
disabled,
clearButton,
InputProps,
variant = 'standard'
} = props,
others = _objectWithoutPropertiesLoose(props, _excluded);
const filterTimeout = useTimeout();
const [filterValueState, setFilterValueState] = React.useState(item.value ?? '');
const [applying, setIsApplying] = React.useState(false);
const id = useId();
const rootProps = useGridRootProps();
const onFilterChange = React.useCallback(event => {
const {
value
} = event.target;
setFilterValueState(String(value));
setIsApplying(true);
filterTimeout.start(rootProps.filterDebounceMs, () => {
const newItem = _extends({}, item, {
value,
fromInput: id
});
applyValue(newItem);
setIsApplying(false);
});
}, [id, applyValue, item, rootProps.filterDebounceMs, filterTimeout]);
React.useEffect(() => {
const itemPlusTag = item;
if (itemPlusTag.fromInput !== id || item.value === undefined) {
setFilterValueState(String(item.value ?? ''));
}
}, [id, item]);
return /*#__PURE__*/_jsx(rootProps.slots.baseTextField, _extends({
id: id,
label: apiRef.current.getLocaleText('filterPanelInputLabel'),
placeholder: apiRef.current.getLocaleText('filterPanelInputPlaceholder'),
value: filterValueState,
onChange: onFilterChange,
variant: variant,
type: type || 'text',
InputProps: _extends({}, applying || clearButton ? {
endAdornment: applying ? /*#__PURE__*/_jsx(rootProps.slots.loadIcon, {
fontSize: "small",
color: "action"
}) : clearButton
} : {}, {
disabled
}, InputProps, {
inputProps: _extends({
tabIndex
}, InputProps?.inputProps)
}),
InputLabelProps: {
shrink: true
},
inputRef: focusElementRef
}, others, rootProps.slotProps?.baseTextField));
}
process.env.NODE_ENV !== "production" ? GridFilterInputValue.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
apiRef: PropTypes.shape({
current: PropTypes.object.isRequired
}).isRequired,
applyValue: PropTypes.func.isRequired,
clearButton: PropTypes.node,
focusElementRef: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.func, PropTypes.object]),
/**
* It is `true` if the filter either has a value or an operator with no value
* required is selected (e.g. `isEmpty`)
*/
isFilterActive: PropTypes.bool,
item: PropTypes.shape({
field: PropTypes.string.isRequired,
id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
operator: PropTypes.string.isRequired,
value: PropTypes.any
}).isRequired
} : void 0;
export { GridFilterInputValue };

View File

@@ -0,0 +1,222 @@
import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
const _excluded = ["logicOperators", "columnsSort", "filterFormProps", "getColumnForNewFilter", "children", "disableAddFilterButton", "disableRemoveAllButton"];
import * as React from 'react';
import PropTypes from 'prop-types';
import { GridLogicOperator } from '../../../models/gridFilterItem';
import { useGridApiContext } from '../../../hooks/utils/useGridApiContext';
import { GridPanelContent } from '../GridPanelContent';
import { GridPanelFooter } from '../GridPanelFooter';
import { GridPanelWrapper } from '../GridPanelWrapper';
import { GridFilterForm } from './GridFilterForm';
import { useGridRootProps } from '../../../hooks/utils/useGridRootProps';
import { useGridSelector } from '../../../hooks/utils/useGridSelector';
import { gridFilterModelSelector } from '../../../hooks/features/filter/gridFilterSelector';
import { gridFilterableColumnDefinitionsSelector } from '../../../hooks/features/columns/gridColumnsSelector';
import { jsx as _jsx } from "react/jsx-runtime";
import { jsxs as _jsxs } from "react/jsx-runtime";
const getGridFilter = col => ({
field: col.field,
operator: col.filterOperators[0].value,
id: Math.round(Math.random() * 1e5)
});
const GridFilterPanel = /*#__PURE__*/React.forwardRef(function GridFilterPanel(props, ref) {
const apiRef = useGridApiContext();
const rootProps = useGridRootProps();
const filterModel = useGridSelector(apiRef, gridFilterModelSelector);
const filterableColumns = useGridSelector(apiRef, gridFilterableColumnDefinitionsSelector);
const lastFilterRef = React.useRef(null);
const placeholderFilter = React.useRef(null);
const {
logicOperators = [GridLogicOperator.And, GridLogicOperator.Or],
columnsSort,
filterFormProps,
getColumnForNewFilter,
disableAddFilterButton = false,
disableRemoveAllButton = false
} = props,
other = _objectWithoutPropertiesLoose(props, _excluded);
const applyFilter = apiRef.current.upsertFilterItem;
const applyFilterLogicOperator = React.useCallback(operator => {
apiRef.current.setFilterLogicOperator(operator);
}, [apiRef]);
const getDefaultFilter = React.useCallback(() => {
let nextColumnWithOperator;
if (getColumnForNewFilter && typeof getColumnForNewFilter === 'function') {
// To allow override the column for default (first) filter
const nextFieldName = getColumnForNewFilter({
currentFilters: filterModel?.items || [],
columns: filterableColumns
});
if (nextFieldName === null) {
return null;
}
nextColumnWithOperator = filterableColumns.find(({
field
}) => field === nextFieldName);
} else {
nextColumnWithOperator = filterableColumns.find(colDef => colDef.filterOperators?.length);
}
if (!nextColumnWithOperator) {
return null;
}
return getGridFilter(nextColumnWithOperator);
}, [filterModel?.items, filterableColumns, getColumnForNewFilter]);
const getNewFilter = React.useCallback(() => {
if (getColumnForNewFilter === undefined || typeof getColumnForNewFilter !== 'function') {
return getDefaultFilter();
}
const currentFilters = filterModel.items.length ? filterModel.items : [getDefaultFilter()].filter(Boolean);
// If no items are there in filterModel, we have to pass defaultFilter
const nextColumnFieldName = getColumnForNewFilter({
currentFilters: currentFilters,
columns: filterableColumns
});
if (nextColumnFieldName === null) {
return null;
}
const nextColumnWithOperator = filterableColumns.find(({
field
}) => field === nextColumnFieldName);
if (!nextColumnWithOperator) {
return null;
}
return getGridFilter(nextColumnWithOperator);
}, [filterModel.items, filterableColumns, getColumnForNewFilter, getDefaultFilter]);
const items = React.useMemo(() => {
if (filterModel.items.length) {
return filterModel.items;
}
if (!placeholderFilter.current) {
placeholderFilter.current = getDefaultFilter();
}
return placeholderFilter.current ? [placeholderFilter.current] : [];
}, [filterModel.items, getDefaultFilter]);
const hasMultipleFilters = items.length > 1;
const addNewFilter = () => {
const newFilter = getNewFilter();
if (!newFilter) {
return;
}
apiRef.current.upsertFilterItems([...items, newFilter]);
};
const deleteFilter = React.useCallback(item => {
const shouldCloseFilterPanel = items.length === 1;
apiRef.current.deleteFilterItem(item);
if (shouldCloseFilterPanel) {
apiRef.current.hideFilterPanel();
}
}, [apiRef, items.length]);
const handleRemoveAll = () => {
if (items.length === 1 && items[0].value === undefined) {
apiRef.current.deleteFilterItem(items[0]);
apiRef.current.hideFilterPanel();
}
apiRef.current.setFilterModel(_extends({}, filterModel, {
items: []
}));
};
React.useEffect(() => {
if (logicOperators.length > 0 && filterModel.logicOperator && !logicOperators.includes(filterModel.logicOperator)) {
applyFilterLogicOperator(logicOperators[0]);
}
}, [logicOperators, applyFilterLogicOperator, filterModel.logicOperator]);
React.useEffect(() => {
if (items.length > 0) {
lastFilterRef.current.focus();
}
}, [items.length]);
return /*#__PURE__*/_jsxs(GridPanelWrapper, _extends({
ref: ref
}, other, {
children: [/*#__PURE__*/_jsx(GridPanelContent, {
children: items.map((item, index) => /*#__PURE__*/_jsx(GridFilterForm, _extends({
item: item,
applyFilterChanges: applyFilter,
deleteFilter: deleteFilter,
hasMultipleFilters: hasMultipleFilters,
showMultiFilterOperators: index > 0,
multiFilterOperator: filterModel.logicOperator,
disableMultiFilterOperator: index !== 1,
applyMultiFilterOperatorChanges: applyFilterLogicOperator,
focusElementRef: index === items.length - 1 ? lastFilterRef : null,
logicOperators: logicOperators,
columnsSort: columnsSort
}, filterFormProps), item.id == null ? index : item.id))
}), !rootProps.disableMultipleColumnsFiltering && !(disableAddFilterButton && disableRemoveAllButton) ? /*#__PURE__*/_jsxs(GridPanelFooter, {
children: [!disableAddFilterButton ? /*#__PURE__*/_jsx(rootProps.slots.baseButton, _extends({
onClick: addNewFilter,
startIcon: /*#__PURE__*/_jsx(rootProps.slots.filterPanelAddIcon, {})
}, rootProps.slotProps?.baseButton, {
children: apiRef.current.getLocaleText('filterPanelAddFilter')
})) : /*#__PURE__*/_jsx("span", {}), !disableRemoveAllButton ? /*#__PURE__*/_jsx(rootProps.slots.baseButton, _extends({
onClick: handleRemoveAll,
startIcon: /*#__PURE__*/_jsx(rootProps.slots.filterPanelRemoveAllIcon, {})
}, rootProps.slotProps?.baseButton, {
children: apiRef.current.getLocaleText('filterPanelRemoveAll')
})) : null]
}) : null]
}));
});
process.env.NODE_ENV !== "production" ? GridFilterPanel.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
/**
* @ignore - do not document.
*/
children: PropTypes.node,
/**
* Changes how the options in the columns selector should be ordered.
* If not specified, the order is derived from the `columns` prop.
*/
columnsSort: PropTypes.oneOf(['asc', 'desc']),
/**
* If `true`, the `Add filter` button will not be displayed.
* @default false
*/
disableAddFilterButton: PropTypes.bool,
/**
* If `true`, the `Remove all` button will be disabled
* @default false
*/
disableRemoveAllButton: PropTypes.bool,
/**
* Props passed to each filter form.
*/
filterFormProps: PropTypes.shape({
columnInputProps: PropTypes.any,
columnsSort: PropTypes.oneOf(['asc', 'desc']),
deleteIconProps: PropTypes.any,
filterColumns: PropTypes.func,
logicOperatorInputProps: PropTypes.any,
operatorInputProps: PropTypes.any,
valueInputProps: PropTypes.any
}),
/**
* Function that returns the next filter item to be picked as default filter.
* @param {GetColumnForNewFilterArgs} args Currently configured filters and columns.
* @returns {GridColDef['field']} The field to be used for the next filter or `null` to prevent adding a filter.
*/
getColumnForNewFilter: PropTypes.func,
/**
* Sets the available logic operators.
* @default [GridLogicOperator.And, GridLogicOperator.Or]
*/
logicOperators: PropTypes.arrayOf(PropTypes.oneOf(['and', 'or']).isRequired),
/**
* The system prop that allows defining system overrides as well as additional CSS styles.
*/
sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object])
} : void 0;
/**
* Demos:
* - [Filtering - overview](https://mui.com/x/react-data-grid/filtering/)
*
* API:
* - [GridFilterPanel API](https://mui.com/x/api/data-grid/grid-filter-panel/)
*/
export { GridFilterPanel, getGridFilter };

View File

@@ -0,0 +1,17 @@
export function isSingleSelectColDef(colDef) {
return colDef?.type === 'singleSelect';
}
export function getValueFromValueOptions(value, valueOptions, getOptionValue) {
if (valueOptions === undefined) {
return undefined;
}
const result = valueOptions.find(option => {
const optionValue = getOptionValue(option);
return String(optionValue) === String(value);
});
return getOptionValue(result);
}
export const getLabelFromValueOption = valueOption => {
const label = typeof valueOption === 'object' ? valueOption.label : valueOption;
return label != null ? String(label) : '';
};

View File

@@ -0,0 +1,9 @@
export * from './GridFilterForm';
export * from './GridFilterInputValue';
export * from './GridFilterInputDate';
export * from './GridFilterInputSingleSelect';
export * from './GridFilterInputBoolean';
export * from './GridFilterInputValueProps';
export { GridFilterPanel } from './GridFilterPanel';
export * from './GridFilterInputMultipleValue';
export * from './GridFilterInputMultipleSingleSelect';

Some files were not shown because too many files have changed in this diff Show More