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,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';