From d78d61da365274927c63321e38729863bf2b3f2e Mon Sep 17 00:00:00 2001 From: Armin Mehinovic Date: Mon, 1 Jul 2024 20:30:59 +0200 Subject: [PATCH 01/21] Add custom columns demo with the most common custom renderers --- .../custom-columns/CustomColumnFullExample.js | 174 +++++++++++++++++ .../CustomColumnFullExample.tsx | 180 ++++++++++++++++++ .../CustomColumnFullExample.tsx.preview | 1 + .../custom-columns/custom-columns.md | 6 + 4 files changed, 361 insertions(+) create mode 100644 docs/data/data-grid/custom-columns/CustomColumnFullExample.js create mode 100644 docs/data/data-grid/custom-columns/CustomColumnFullExample.tsx create mode 100644 docs/data/data-grid/custom-columns/CustomColumnFullExample.tsx.preview diff --git a/docs/data/data-grid/custom-columns/CustomColumnFullExample.js b/docs/data/data-grid/custom-columns/CustomColumnFullExample.js new file mode 100644 index 0000000000000..41a43cf5c112f --- /dev/null +++ b/docs/data/data-grid/custom-columns/CustomColumnFullExample.js @@ -0,0 +1,174 @@ +import * as React from 'react'; +import { + generateFilledQuantity, + randomColor, + randomCountry, + randomEmail, + randomIncoterm, + randomInt, + randomName, + randomRating, + randomStatusOptions, + renderAvatar, + renderCountry, + renderEditCountry, + renderEditIncoterm, + renderEditProgress, + renderEditRating, + renderEditStatus, + renderEmail, + renderIncoterm, + renderProgress, + renderRating, + renderStatus, +} from '@mui/x-data-grid-generator'; +import { + COUNTRY_ISO_OPTIONS_SORTED, + INCOTERM_OPTIONS, + STATUS_OPTIONS, +} from '@mui/x-data-grid-generator/services/static-data'; +import { SparkLineChart } from '@mui/x-charts'; +import { DataGrid, gridStringOrNumberComparator } from '@mui/x-data-grid'; + +function GridSparklineCell(params) { + if (params.value == null) { + return ''; + } + + return ( + + ); +} + +const columns = [ + { + field: 'name', + headerName: 'Name', + width: 120, + editable: true, + }, + { + field: 'avatar', + headerName: 'Avatar', + display: 'flex', + renderCell: renderAvatar, + valueGetter: (value, row) => + row.name == null || row.avatar == null + ? null + : { name: row.name, color: row.avatar }, + sortable: false, + filterable: false, + }, + { + field: 'email', + headerName: 'Email', + renderCell: renderEmail, + width: 150, + editable: true, + }, + { + field: 'rating', + headerName: 'Rating', + display: 'flex', + renderCell: renderRating, + renderEditCell: renderEditRating, + width: 180, + type: 'number', + editable: true, + availableAggregationFunctions: ['avg', 'min', 'max', 'size'], + }, + { + field: 'country', + headerName: 'Country', + type: 'singleSelect', + valueOptions: COUNTRY_ISO_OPTIONS_SORTED, + valueFormatter: (value) => value?.label, + renderCell: renderCountry, + renderEditCell: renderEditCountry, + sortComparator: (v1, v2, param1, param2) => + gridStringOrNumberComparator(v1.label, v2.label, param1, param2), + width: 150, + editable: true, + }, + { + field: 'salary', + headerName: 'Salary', + type: 'number', + valueFormatter: (value) => { + if (!value || typeof value !== 'number') { + return value; + } + return `${value.toLocaleString()}$`; + }, + editable: true, + }, + { + field: 'monthlyActivity', + headerName: 'Monthly activity', + type: 'custom', + resizable: false, + filterable: false, + sortable: false, + editable: false, + groupable: false, + display: 'flex', + renderCell: GridSparklineCell, + width: 150, + valueGetter: (value, row) => row.monthlyActivity, + }, + { + field: 'budget', + headerName: 'Budget left', + renderCell: renderProgress, + renderEditCell: renderEditProgress, + availableAggregationFunctions: ['min', 'max', 'avg', 'size'], + type: 'number', + width: 120, + editable: true, + }, + { + field: 'status', + headerName: 'Status', + renderCell: renderStatus, + renderEditCell: renderEditStatus, + type: 'singleSelect', + valueOptions: STATUS_OPTIONS, + width: 150, + editable: true, + }, + { + field: 'incoTerm', + headerName: 'Incoterm', + renderCell: renderIncoterm, + renderEditCell: renderEditIncoterm, + type: 'singleSelect', + valueOptions: INCOTERM_OPTIONS, + editable: true, + }, +]; + +const rows = Array.from({ length: 10 }, (_, index) => ({ + id: index, + name: randomName({}, {}), + avatar: randomColor(), + email: randomEmail(), + rating: randomRating(), + country: randomCountry(), + salary: randomInt(35000, 80000), + monthlyActivity: Array.from({ length: 30 }, () => randomInt(1, 25)), + budget: generateFilledQuantity({ quantity: 100 }), + status: randomStatusOptions(), + incoTerm: randomIncoterm(), +})); + +export default function CustomColumnsFullExample() { + return ( +
+ +
+ ); +} diff --git a/docs/data/data-grid/custom-columns/CustomColumnFullExample.tsx b/docs/data/data-grid/custom-columns/CustomColumnFullExample.tsx new file mode 100644 index 0000000000000..ef82e60aa4821 --- /dev/null +++ b/docs/data/data-grid/custom-columns/CustomColumnFullExample.tsx @@ -0,0 +1,180 @@ +import * as React from 'react'; +import { + generateFilledQuantity, + randomColor, + randomCountry, + randomEmail, + randomIncoterm, + randomInt, + randomName, + randomRating, + randomStatusOptions, + renderAvatar, + renderCountry, + renderEditCountry, + renderEditIncoterm, + renderEditProgress, + renderEditRating, + renderEditStatus, + renderEmail, + renderIncoterm, + renderProgress, + renderRating, + renderStatus, +} from '@mui/x-data-grid-generator'; +import { + COUNTRY_ISO_OPTIONS_SORTED, + CountryIsoOption, + INCOTERM_OPTIONS, + STATUS_OPTIONS, +} from '@mui/x-data-grid-generator/services/static-data'; +import { SparkLineChart } from '@mui/x-charts'; +import { + DataGrid, + GridColDef, + GridRenderCellParams, + gridStringOrNumberComparator, +} from '@mui/x-data-grid'; + +function GridSparklineCell(params: GridRenderCellParams) { + if (params.value == null) { + return ''; + } + + return ( + + ); +} + +const columns: GridColDef<(typeof rows)[number]>[] = [ + { + field: 'name', + headerName: 'Name', + width: 120, + editable: true, + }, + { + field: 'avatar', + headerName: 'Avatar', + display: 'flex', + renderCell: renderAvatar, + valueGetter: (value, row) => + row.name == null || row.avatar == null + ? null + : { name: row.name, color: row.avatar }, + sortable: false, + filterable: false, + } as GridColDef, + { + field: 'email', + headerName: 'Email', + renderCell: renderEmail, + width: 150, + editable: true, + }, + { + field: 'rating', + headerName: 'Rating', + display: 'flex', + renderCell: renderRating, + renderEditCell: renderEditRating, + width: 180, + type: 'number', + editable: true, + availableAggregationFunctions: ['avg', 'min', 'max', 'size'], + }, + { + field: 'country', + headerName: 'Country', + type: 'singleSelect', + valueOptions: COUNTRY_ISO_OPTIONS_SORTED, + valueFormatter: (value: CountryIsoOption) => value?.label, + renderCell: renderCountry, + renderEditCell: renderEditCountry, + sortComparator: (v1, v2, param1, param2) => + gridStringOrNumberComparator(v1.label, v2.label, param1, param2), + width: 150, + editable: true, + } as GridColDef, + { + field: 'salary', + headerName: 'Salary', + type: 'number', + valueFormatter: (value?: number) => { + if (!value || typeof value !== 'number') { + return value; + } + return `${value.toLocaleString()}$`; + }, + editable: true, + }, + { + field: 'monthlyActivity', + headerName: 'Monthly activity', + type: 'custom', + resizable: false, + filterable: false, + sortable: false, + editable: false, + groupable: false, + display: 'flex', + renderCell: GridSparklineCell, + width: 150, + valueGetter: (value, row) => row.monthlyActivity, + }, + { + field: 'budget', + headerName: 'Budget left', + renderCell: renderProgress, + renderEditCell: renderEditProgress, + availableAggregationFunctions: ['min', 'max', 'avg', 'size'], + type: 'number', + width: 120, + editable: true, + }, + { + field: 'status', + headerName: 'Status', + renderCell: renderStatus, + renderEditCell: renderEditStatus, + type: 'singleSelect', + valueOptions: STATUS_OPTIONS, + width: 150, + editable: true, + }, + { + field: 'incoTerm', + headerName: 'Incoterm', + renderCell: renderIncoterm, + renderEditCell: renderEditIncoterm, + type: 'singleSelect', + valueOptions: INCOTERM_OPTIONS, + editable: true, + }, +]; + +const rows = Array.from({ length: 10 }, (_, index) => ({ + id: index, + name: randomName({}, {}), + avatar: randomColor(), + email: randomEmail(), + rating: randomRating(), + country: randomCountry(), + salary: randomInt(35000, 80000), + monthlyActivity: Array.from({ length: 30 }, () => randomInt(1, 25)), + budget: generateFilledQuantity({ quantity: 100 }), + status: randomStatusOptions(), + incoTerm: randomIncoterm(), +})); + +export default function CustomColumnsFullExample() { + return ( +
+ +
+ ); +} diff --git a/docs/data/data-grid/custom-columns/CustomColumnFullExample.tsx.preview b/docs/data/data-grid/custom-columns/CustomColumnFullExample.tsx.preview new file mode 100644 index 0000000000000..074afd47c4411 --- /dev/null +++ b/docs/data/data-grid/custom-columns/CustomColumnFullExample.tsx.preview @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/data/data-grid/custom-columns/custom-columns.md b/docs/data/data-grid/custom-columns/custom-columns.md index 118a6905b663a..4a4af3b326f3e 100644 --- a/docs/data/data-grid/custom-columns/custom-columns.md +++ b/docs/data/data-grid/custom-columns/custom-columns.md @@ -44,6 +44,12 @@ You can change the date format by importing different locale (`en-US` locale is See [Localization](/x/react-date-pickers/localization/) for more information. ::: +## Full example + +The demo below shows the most common custom column renderers. + +{{"demo": "CustomColumnFullExample.js", "bg": "inline"}} + ## API - [DataGrid](/x/api/data-grid/data-grid/) From 1a609bdd34a95eac057e02ea1923a2b2cb432be5 Mon Sep 17 00:00:00 2001 From: Armin Mehinovic Date: Mon, 1 Jul 2024 20:31:24 +0200 Subject: [PATCH 02/21] Add header name for incoTerm column in the generator --- .../x-data-grid-generator/src/columns/commodities.columns.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/x-data-grid-generator/src/columns/commodities.columns.tsx b/packages/x-data-grid-generator/src/columns/commodities.columns.tsx index 60c9f269b87f1..56f6f1e9528a7 100644 --- a/packages/x-data-grid-generator/src/columns/commodities.columns.tsx +++ b/packages/x-data-grid-generator/src/columns/commodities.columns.tsx @@ -174,6 +174,7 @@ export const getCommodityColumns = (editable = false): GridColDefGenerator[] => }, { field: 'incoTerm', + headerName: 'Incoterm', generateData: randomIncoterm, renderCell: renderIncoterm, renderEditCell: renderEditIncoterm, From 8af2630fdd4973d5364d4a59c6adffe0b9923257 Mon Sep 17 00:00:00 2001 From: Armin Mehinovic Date: Mon, 1 Jul 2024 20:34:36 +0200 Subject: [PATCH 03/21] Fix lint issues --- docs/data/data-grid/custom-columns/CustomColumnFullExample.js | 4 ++-- .../data/data-grid/custom-columns/CustomColumnFullExample.tsx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/data/data-grid/custom-columns/CustomColumnFullExample.js b/docs/data/data-grid/custom-columns/CustomColumnFullExample.js index 41a43cf5c112f..5e9f7cef20087 100644 --- a/docs/data/data-grid/custom-columns/CustomColumnFullExample.js +++ b/docs/data/data-grid/custom-columns/CustomColumnFullExample.js @@ -27,7 +27,7 @@ import { INCOTERM_OPTIONS, STATUS_OPTIONS, } from '@mui/x-data-grid-generator/services/static-data'; -import { SparkLineChart } from '@mui/x-charts'; +import { SparkLineChart } from '@mui/x-charts/SparkLineChart'; import { DataGrid, gridStringOrNumberComparator } from '@mui/x-data-grid'; function GridSparklineCell(params) { @@ -165,7 +165,7 @@ const rows = Array.from({ length: 10 }, (_, index) => ({ incoTerm: randomIncoterm(), })); -export default function CustomColumnsFullExample() { +export default function CustomColumnFullExample() { return (
diff --git a/docs/data/data-grid/custom-columns/CustomColumnFullExample.tsx b/docs/data/data-grid/custom-columns/CustomColumnFullExample.tsx index ef82e60aa4821..487b3abe1ab5d 100644 --- a/docs/data/data-grid/custom-columns/CustomColumnFullExample.tsx +++ b/docs/data/data-grid/custom-columns/CustomColumnFullExample.tsx @@ -28,7 +28,7 @@ import { INCOTERM_OPTIONS, STATUS_OPTIONS, } from '@mui/x-data-grid-generator/services/static-data'; -import { SparkLineChart } from '@mui/x-charts'; +import { SparkLineChart } from '@mui/x-charts/SparkLineChart'; import { DataGrid, GridColDef, @@ -171,7 +171,7 @@ const rows = Array.from({ length: 10 }, (_, index) => ({ incoTerm: randomIncoterm(), })); -export default function CustomColumnsFullExample() { +export default function CustomColumnFullExample() { return (
From feb98209347fe9228575663ece4fd55b12e85846 Mon Sep 17 00:00:00 2001 From: Armin Mehinovic Date: Fri, 5 Jul 2024 10:57:08 +0200 Subject: [PATCH 04/21] Add renderers directly to the code example --- .../custom-columns/CustomColumnFullExample.js | 697 ++++++++++++++++- .../CustomColumnFullExample.tsx | 727 +++++++++++++++++- 2 files changed, 1395 insertions(+), 29 deletions(-) diff --git a/docs/data/data-grid/custom-columns/CustomColumnFullExample.js b/docs/data/data-grid/custom-columns/CustomColumnFullExample.js index 5e9f7cef20087..298db79e44586 100644 --- a/docs/data/data-grid/custom-columns/CustomColumnFullExample.js +++ b/docs/data/data-grid/custom-columns/CustomColumnFullExample.js @@ -1,4 +1,5 @@ import * as React from 'react'; +import clsx from 'clsx'; import { generateFilledQuantity, randomColor, @@ -9,28 +10,655 @@ import { randomName, randomRating, randomStatusOptions, - renderAvatar, - renderCountry, - renderEditCountry, - renderEditIncoterm, - renderEditProgress, - renderEditRating, - renderEditStatus, - renderEmail, - renderIncoterm, - renderProgress, - renderRating, - renderStatus, } from '@mui/x-data-grid-generator'; import { + COUNTRY_ISO_OPTIONS, COUNTRY_ISO_OPTIONS_SORTED, INCOTERM_OPTIONS, STATUS_OPTIONS, } from '@mui/x-data-grid-generator/services/static-data'; import { SparkLineChart } from '@mui/x-charts/SparkLineChart'; -import { DataGrid, gridStringOrNumberComparator } from '@mui/x-data-grid'; +import { + DataGrid, + GridEditModes, + gridStringOrNumberComparator, + useGridApiContext, + useGridRootProps, +} from '@mui/x-data-grid'; +import { + alpha, + Autocomplete, + autocompleteClasses, + Avatar, + Box, + Chip, + debounce, + InputBase, + ListItemIcon, + ListItemText, + MenuItem, + Rating, + Select, + Slider, + sliderClasses, + styled, + Tooltip, +} from '@mui/material'; +import ReportProblemIcon from '@mui/icons-material/ReportProblem'; +import InfoIcon from '@mui/icons-material/Info'; +import AutorenewIcon from '@mui/icons-material/Autorenew'; +import DoneIcon from '@mui/icons-material/Done'; + +/** Custom components supporting custom renderers */ +const Link = styled('a')({ + textOverflow: 'ellipsis', + whiteSpace: 'nowrap', + overflow: 'hidden', + color: 'inherit', +}); + +const DemoLink = React.memo(function DemoLink(props) { + const handleClick = (event) => { + event.preventDefault(); + event.stopPropagation(); + }; + + return ( + + {props.children} + + ); +}); + +const RatingValue = React.memo(function RatingValue(props) { + const { value } = props; + return ( + + {' '} + {Math.round(Number(value) * 10) / 10} + + ); +}); + +const EditRating = (props) => { + const { id, value, field } = props; + + const apiRef = useGridApiContext(); + + const changedThroughKeyboard = React.useRef(false); + + const handleChange = async (event) => { + await apiRef.current.setEditCellValue( + { id, field, value: Number(event.target.value) }, + event, + ); + if (!changedThroughKeyboard.current) { + apiRef.current.stopCellEditMode({ id, field }); + } + changedThroughKeyboard.current = false; + }; + + const handleRef = (element) => { + if (element) { + if (value !== 0) { + element.querySelector(`input[value="${value}"]`).focus(); + } else { + element.querySelector('input[value=""]').focus(); + } + } + }; + + const handleKeyDown = (event) => { + if (event.key.startsWith('Arrow')) { + changedThroughKeyboard.current = true; + } else { + changedThroughKeyboard.current = false; + } + }; + + return ( + + + {Number(value)} + + ); +}; + +const Country = React.memo(function Country(props) { + const { value } = props; + + return ( + img': { + mr: 0.5, + flexShrink: 0, + width: '20px', + }, + }} + > + + + {value.label} + + + ); +}); + +const StyledAutocomplete = styled(Autocomplete)(({ theme }) => ({ + height: '100%', + [`& .${autocompleteClasses.inputRoot}`]: { + ...theme.typography.body2, + padding: '1px 0', + height: '100%', + '& input': { + padding: '0 16px', + height: '100%', + }, + }, +})); + +const EditCountry = (props) => { + const { id, value, field } = props; + + const apiRef = useGridApiContext(); + + const handleChange = React.useCallback( + async (event, newValue) => { + await apiRef.current.setEditCellValue({ id, field, value: newValue }, event); + apiRef.current.stopCellEditMode({ id, field }); + }, + [apiRef, field, id], + ); + + return ( + option.label} + autoHighlight + fullWidth + open + disableClearable + renderOption={(optionProps, option) => ( + img': { + mr: 1.5, + flexShrink: 0, + }, + }} + {...optionProps} + > + + {option.label} + + )} + renderInput={(params) => ( + + )} + /> + ); +}; + +const Center = styled('div')({ + height: '100%', + display: 'flex', + alignItems: 'center', +}); + +const Element = styled('div')(({ theme }) => ({ + border: `1px solid ${(theme.vars || theme).palette.divider}`, + position: 'relative', + overflow: 'hidden', + width: '100%', + height: 26, + borderRadius: 2, +})); + +const Value = styled('div')({ + position: 'absolute', + lineHeight: '24px', + width: '100%', + display: 'flex', + justifyContent: 'center', +}); + +const Bar = styled('div')({ + height: '100%', + '&.low': { + backgroundColor: '#f44336', + }, + '&.medium': { + backgroundColor: '#efbb5aa3', + }, + '&.high': { + backgroundColor: '#088208a3', + }, +}); + +const ProgressBar = React.memo(function ProgressBar(props) { + const { value } = props; + const valueInPercent = value * 100; + + return ( + + {`${valueInPercent.toLocaleString()} %`} + = 30 && valueInPercent <= 70, + high: valueInPercent > 70, + })} + style={{ maxWidth: `${valueInPercent}%` }} + /> + + ); +}); + +const StyledSlider = styled(Slider)(({ theme }) => ({ + display: 'flex', + height: '100%', + width: '100%', + alignItems: 'center', + justifyContent: 'center', + padding: 0, + borderRadius: 0, + [`& .${sliderClasses.rail}`]: { + height: '100%', + backgroundColor: 'transparent', + }, + [`& .${sliderClasses.track}`]: { + height: '100%', + transition: theme.transitions.create('background-color', { + duration: theme.transitions.duration.shorter, + }), + '&.low': { + backgroundColor: '#f44336', + }, + '&.medium': { + backgroundColor: '#efbb5aa3', + }, + '&.high': { + backgroundColor: '#088208a3', + }, + }, + [`& .${sliderClasses.thumb}`]: { + height: '100%', + width: 5, + borderRadius: 0, + marginTop: 0, + backgroundColor: alpha('#000000', 0.2), + }, +})); + +const ValueLabelComponent = (props) => { + const { children, open, value } = props; + + return ( + + {children} + + ); +}; + +const EditProgress = (props) => { + const { id, value, field } = props; + const [valueState, setValueState] = React.useState(Number(value)); + + const apiRef = useGridApiContext(); + + const updateCellEditProps = React.useCallback( + (newValue) => { + apiRef.current.setEditCellValue({ id, field, value: newValue }); + }, + [apiRef, field, id], + ); + + const debouncedUpdateCellEditProps = React.useMemo( + () => debounce(updateCellEditProps, 60), + [updateCellEditProps], + ); + + const handleChange = (event, newValue) => { + setValueState(newValue); + debouncedUpdateCellEditProps(newValue); + }; + + React.useEffect(() => { + setValueState(Number(value)); + }, [value]); + + const handleRef = (element) => { + if (element) { + element.querySelector('[type="range"]').focus(); + } + }; + + return ( + = 0.3 && valueState <= 0.7, + high: valueState > 0.7, + }), + }} + value={valueState} + max={1} + step={0.00001} + onChange={handleChange} + components={{ ValueLabel: ValueLabelComponent }} + valueLabelDisplay="auto" + valueLabelFormat={(newValue) => `${(newValue * 100).toLocaleString()} %`} + /> + ); +}; + +const StyledChip = styled(Chip)(({ theme }) => ({ + justifyContent: 'left', + '& .icon': { + color: 'inherit', + }, + '&.Open': { + color: (theme.vars || theme).palette.info.dark, + border: `1px solid ${(theme.vars || theme).palette.info.main}`, + }, + '&.Filled': { + color: (theme.vars || theme).palette.success.dark, + border: `1px solid ${(theme.vars || theme).palette.success.main}`, + }, + '&.PartiallyFilled': { + color: (theme.vars || theme).palette.warning.dark, + border: `1px solid ${(theme.vars || theme).palette.warning.main}`, + }, + '&.Rejected': { + color: (theme.vars || theme).palette.error.dark, + border: `1px solid ${(theme.vars || theme).palette.error.main}`, + }, +})); + +const Status = React.memo((props) => { + const { status } = props; -function GridSparklineCell(params) { + let icon = null; + if (status === 'Rejected') { + icon = ; + } else if (status === 'Open') { + icon = ; + } else if (status === 'PartiallyFilled') { + icon = ; + } else if (status === 'Filled') { + icon = ; + } + + let label = status; + if (status === 'PartiallyFilled') { + label = 'Partially Filled'; + } + + return ( + + ); +}); + +const EditStatus = (props) => { + const { id, value, field } = props; + const rootProps = useGridRootProps(); + const apiRef = useGridApiContext(); + + const handleChange = async (event) => { + const isValid = await apiRef.current.setEditCellValue({ + id, + field, + value: event.target.value, + }); + + if (isValid && rootProps.editMode === GridEditModes.Cell) { + apiRef.current.stopCellEditMode({ id, field, cellToFocusAfter: 'below' }); + } + }; + + const handleClose = (event, reason) => { + if (reason === 'backdropClick') { + apiRef.current.stopCellEditMode({ id, field, ignoreModifications: true }); + } + }; + + return ( + + ); +}; + +const Incoterm = React.memo(function Incoterm(props) { + const { value } = props; + + if (!value) { + return null; + } + + const valueStr = value.toString(); + const tooltip = valueStr.slice(valueStr.indexOf('(') + 1, valueStr.indexOf(')')); + const code = valueStr.slice(0, valueStr.indexOf('(')).trim(); + + return ( + + {code} + + + + + ); +}); + +const EditIncoterm = (props) => { + const { id, value, field } = props; + + const apiRef = useGridApiContext(); + + const handleChange = async (event) => { + await apiRef.current.setEditCellValue( + { id, field, value: event.target.value }, + event, + ); + apiRef.current.stopCellEditMode({ id, field }); + }; + + const handleClose = (event, reason) => { + if (reason === 'backdropClick') { + apiRef.current.stopCellEditMode({ id, field }); + } + }; + + return ( + + ); +}; + +/** Custom cell renderers */ +// Avatar +function renderAvatar(params) { + if (params.value == null) { + return ''; + } + + return ( + + {params.value.name.toUpperCase().substring(0, 1)} + + ); +} + +// Email +function renderEmail(params) { + const email = params.value ?? ''; + + return ( + + {email} + + ); +} + +// Rating +function renderRating(params) { + if (params.value == null) { + return ''; + } + + return ; +} + +function renderEditRating(params) { + return ; +} + +// Country +function renderCountry(params) { + if (params.value == null) { + return ''; + } + + return ; +} + +function renderEditCountry(params) { + return ; +} + +// Sparkline +function renderSparkline(params) { if (params.value == null) { return ''; } @@ -44,6 +672,45 @@ function GridSparklineCell(params) { ); } +// Progress +function renderProgress(params) { + if (params.value == null) { + return ''; + } + + return ( +
+ +
+ ); +} + +function renderEditProgress(params) { + return ; +} + +// Status +function renderStatus(params) { + if (params.value == null) { + return ''; + } + + return ; +} + +function renderEditStatus(params) { + return ; +} + +// Incoterm +function renderIncoterm(params) { + return ; +} + +function renderEditIncoterm(params) { + return ; +} + const columns = [ { field: 'name', @@ -116,7 +783,7 @@ const columns = [ editable: false, groupable: false, display: 'flex', - renderCell: GridSparklineCell, + renderCell: renderSparkline, width: 150, valueGetter: (value, row) => row.monthlyActivity, }, diff --git a/docs/data/data-grid/custom-columns/CustomColumnFullExample.tsx b/docs/data/data-grid/custom-columns/CustomColumnFullExample.tsx index 487b3abe1ab5d..b23b67313e0e8 100644 --- a/docs/data/data-grid/custom-columns/CustomColumnFullExample.tsx +++ b/docs/data/data-grid/custom-columns/CustomColumnFullExample.tsx @@ -1,4 +1,5 @@ import * as React from 'react'; +import clsx from 'clsx'; import { generateFilledQuantity, randomColor, @@ -9,20 +10,9 @@ import { randomName, randomRating, randomStatusOptions, - renderAvatar, - renderCountry, - renderEditCountry, - renderEditIncoterm, - renderEditProgress, - renderEditRating, - renderEditStatus, - renderEmail, - renderIncoterm, - renderProgress, - renderRating, - renderStatus, } from '@mui/x-data-grid-generator'; import { + COUNTRY_ISO_OPTIONS, COUNTRY_ISO_OPTIONS_SORTED, CountryIsoOption, INCOTERM_OPTIONS, @@ -32,11 +22,681 @@ import { SparkLineChart } from '@mui/x-charts/SparkLineChart'; import { DataGrid, GridColDef, + GridEditModes, GridRenderCellParams, + GridRenderEditCellParams, gridStringOrNumberComparator, + useGridApiContext, + useGridRootProps, } from '@mui/x-data-grid'; +import { + alpha, + Autocomplete, + autocompleteClasses, + AutocompleteProps, + Avatar, + Box, + Chip, + debounce, + InputBase, + ListItemIcon, + ListItemText, + MenuItem, + MenuProps, + Rating, + Select, + SelectProps, + Slider, + sliderClasses, + SliderProps, + styled, + Tooltip, +} from '@mui/material'; +import ReportProblemIcon from '@mui/icons-material/ReportProblem'; +import InfoIcon from '@mui/icons-material/Info'; +import AutorenewIcon from '@mui/icons-material/Autorenew'; +import DoneIcon from '@mui/icons-material/Done'; + +interface DemoLinkProps { + href: string; + children: string; + tabIndex: number; +} + +interface RatingValueProps { + value: number; +} + +interface CountryProps { + value: CountryIsoOption; +} + +interface ProgressBarProps { + value: number; +} + +interface StatusProps { + status: string; +} + +interface IncotermProps { + value: string | null | undefined; +} + +/** Custom components supporting custom renderers */ +const Link = styled('a')({ + textOverflow: 'ellipsis', + whiteSpace: 'nowrap', + overflow: 'hidden', + color: 'inherit', +}); + +const DemoLink = React.memo(function DemoLink(props: DemoLinkProps) { + const handleClick = (event: React.MouseEvent) => { + event.preventDefault(); + event.stopPropagation(); + }; + + return ( + + {props.children} + + ); +}); + +const RatingValue = React.memo(function RatingValue(props: RatingValueProps) { + const { value } = props; + return ( + + {' '} + {Math.round(Number(value) * 10) / 10} + + ); +}); + +const EditRating = (props: GridRenderEditCellParams) => { + const { id, value, field } = props; + + const apiRef = useGridApiContext(); + + const changedThroughKeyboard = React.useRef(false); + + const handleChange = async (event: any) => { + await apiRef.current.setEditCellValue( + { id, field, value: Number(event.target.value) }, + event, + ); + if (!changedThroughKeyboard.current) { + apiRef.current.stopCellEditMode({ id, field }); + } + changedThroughKeyboard.current = false; + }; + + const handleRef = (element: HTMLElement | undefined) => { + if (element) { + if (value !== 0) { + element.querySelector(`input[value="${value}"]`)!.focus(); + } else { + element.querySelector('input[value=""]')!.focus(); + } + } + }; + + const handleKeyDown = (event: React.KeyboardEvent) => { + if (event.key.startsWith('Arrow')) { + changedThroughKeyboard.current = true; + } else { + changedThroughKeyboard.current = false; + } + }; + + return ( + + + {Number(value)} + + ); +}; + +const Country = React.memo(function Country(props: CountryProps) { + const { value } = props; + + return ( + img': { + mr: 0.5, + flexShrink: 0, + width: '20px', + }, + }} + > + + + {value.label} + + + ); +}); + +const StyledAutocomplete = styled(Autocomplete)(({ theme }) => ({ + height: '100%', + [`& .${autocompleteClasses.inputRoot}`]: { + ...theme.typography.body2, + padding: '1px 0', + height: '100%', + '& input': { + padding: '0 16px', + height: '100%', + }, + }, +})) as typeof Autocomplete; + +const EditCountry = (props: GridRenderEditCellParams) => { + const { id, value, field } = props; + + const apiRef = useGridApiContext(); + + const handleChange = React.useCallback< + NonNullable['onChange']> + >( + async (event, newValue) => { + await apiRef.current.setEditCellValue({ id, field, value: newValue }, event); + apiRef.current.stopCellEditMode({ id, field }); + }, + [apiRef, field, id], + ); + + return ( + + value={value} + onChange={handleChange} + options={COUNTRY_ISO_OPTIONS} + getOptionLabel={(option: any) => option.label} + autoHighlight + fullWidth + open + disableClearable + renderOption={(optionProps, option: any) => ( + img': { + mr: 1.5, + flexShrink: 0, + }, + }} + {...optionProps} + > + + {option.label} + + )} + renderInput={(params) => ( + + )} + /> + ); +}; + +const Center = styled('div')({ + height: '100%', + display: 'flex', + alignItems: 'center', +}); + +const Element = styled('div')(({ theme }) => ({ + border: `1px solid ${(theme.vars || theme).palette.divider}`, + position: 'relative', + overflow: 'hidden', + width: '100%', + height: 26, + borderRadius: 2, +})); + +const Value = styled('div')({ + position: 'absolute', + lineHeight: '24px', + width: '100%', + display: 'flex', + justifyContent: 'center', +}); + +const Bar = styled('div')({ + height: '100%', + '&.low': { + backgroundColor: '#f44336', + }, + '&.medium': { + backgroundColor: '#efbb5aa3', + }, + '&.high': { + backgroundColor: '#088208a3', + }, +}); + +const ProgressBar = React.memo(function ProgressBar(props: ProgressBarProps) { + const { value } = props; + const valueInPercent = value * 100; + + return ( + + {`${valueInPercent.toLocaleString()} %`} + = 30 && valueInPercent <= 70, + high: valueInPercent > 70, + })} + style={{ maxWidth: `${valueInPercent}%` }} + /> + + ); +}); + +const StyledSlider = styled(Slider)(({ theme }) => ({ + display: 'flex', + height: '100%', + width: '100%', + alignItems: 'center', + justifyContent: 'center', + padding: 0, + borderRadius: 0, + [`& .${sliderClasses.rail}`]: { + height: '100%', + backgroundColor: 'transparent', + }, + [`& .${sliderClasses.track}`]: { + height: '100%', + transition: theme.transitions.create('background-color', { + duration: theme.transitions.duration.shorter, + }), + '&.low': { + backgroundColor: '#f44336', + }, + '&.medium': { + backgroundColor: '#efbb5aa3', + }, + '&.high': { + backgroundColor: '#088208a3', + }, + }, + [`& .${sliderClasses.thumb}`]: { + height: '100%', + width: 5, + borderRadius: 0, + marginTop: 0, + backgroundColor: alpha('#000000', 0.2), + }, +})); + +const ValueLabelComponent = (props: any) => { + const { children, open, value } = props; + + return ( + + {children} + + ); +}; + +const EditProgress = (props: GridRenderEditCellParams) => { + const { id, value, field } = props; + const [valueState, setValueState] = React.useState(Number(value)); + + const apiRef = useGridApiContext(); + + const updateCellEditProps = React.useCallback( + (newValue: number) => { + apiRef.current.setEditCellValue({ id, field, value: newValue }); + }, + [apiRef, field, id], + ); + + const debouncedUpdateCellEditProps = React.useMemo( + () => debounce(updateCellEditProps, 60), + [updateCellEditProps], + ); + + const handleChange = (event: Event, newValue: number | number[]) => { + setValueState(newValue as number); + debouncedUpdateCellEditProps(newValue as number); + }; + + React.useEffect(() => { + setValueState(Number(value)); + }, [value]); + + const handleRef: SliderProps['ref'] = (element) => { + if (element) { + element.querySelector('[type="range"]')!.focus(); + } + }; + + return ( + = 0.3 && valueState <= 0.7, + high: valueState > 0.7, + }), + }} + value={valueState} + max={1} + step={0.00001} + onChange={handleChange} + components={{ ValueLabel: ValueLabelComponent }} + valueLabelDisplay="auto" + valueLabelFormat={(newValue) => `${(newValue * 100).toLocaleString()} %`} + /> + ); +}; + +const StyledChip = styled(Chip)(({ theme }) => ({ + justifyContent: 'left', + '& .icon': { + color: 'inherit', + }, + '&.Open': { + color: (theme.vars || theme).palette.info.dark, + border: `1px solid ${(theme.vars || theme).palette.info.main}`, + }, + '&.Filled': { + color: (theme.vars || theme).palette.success.dark, + border: `1px solid ${(theme.vars || theme).palette.success.main}`, + }, + '&.PartiallyFilled': { + color: (theme.vars || theme).palette.warning.dark, + border: `1px solid ${(theme.vars || theme).palette.warning.main}`, + }, + '&.Rejected': { + color: (theme.vars || theme).palette.error.dark, + border: `1px solid ${(theme.vars || theme).palette.error.main}`, + }, +})); + +const Status = React.memo((props: StatusProps) => { + const { status } = props; + + let icon: any = null; + if (status === 'Rejected') { + icon = ; + } else if (status === 'Open') { + icon = ; + } else if (status === 'PartiallyFilled') { + icon = ; + } else if (status === 'Filled') { + icon = ; + } + + let label: string = status; + if (status === 'PartiallyFilled') { + label = 'Partially Filled'; + } + + return ( + + ); +}); + +const EditStatus = (props: GridRenderEditCellParams) => { + const { id, value, field } = props; + const rootProps = useGridRootProps(); + const apiRef = useGridApiContext(); + + const handleChange: SelectProps['onChange'] = async (event) => { + const isValid = await apiRef.current.setEditCellValue({ + id, + field, + value: event.target.value, + }); + + if (isValid && rootProps.editMode === GridEditModes.Cell) { + apiRef.current.stopCellEditMode({ id, field, cellToFocusAfter: 'below' }); + } + }; + + const handleClose: MenuProps['onClose'] = (event, reason) => { + if (reason === 'backdropClick') { + apiRef.current.stopCellEditMode({ id, field, ignoreModifications: true }); + } + }; + + return ( + + ); +}; + +const Incoterm = React.memo(function Incoterm(props: IncotermProps) { + const { value } = props; + + if (!value) { + return null; + } + + const valueStr = value.toString(); + const tooltip = valueStr.slice(valueStr.indexOf('(') + 1, valueStr.indexOf(')')); + const code = valueStr.slice(0, valueStr.indexOf('(')).trim(); + + return ( + + {code} + + + + + ); +}); + +const EditIncoterm = (props: GridRenderEditCellParams) => { + const { id, value, field } = props; + + const apiRef = useGridApiContext(); + + const handleChange: SelectProps['onChange'] = async (event) => { + await apiRef.current.setEditCellValue( + { id, field, value: event.target.value as any }, + event, + ); + apiRef.current.stopCellEditMode({ id, field }); + }; + + const handleClose: MenuProps['onClose'] = (event, reason) => { + if (reason === 'backdropClick') { + apiRef.current.stopCellEditMode({ id, field }); + } + }; + + return ( + + ); +}; + +/** Custom cell renderers */ +// Avatar +function renderAvatar( + params: GridRenderCellParams<{ name: string; color: string }, any, any>, +) { + if (params.value == null) { + return ''; + } + + return ( + + {params.value.name.toUpperCase().substring(0, 1)} + + ); +} + +// Email +function renderEmail(params: GridRenderCellParams) { + const email = params.value ?? ''; + + return ( + + {email} + + ); +} + +// Rating +function renderRating(params: GridRenderCellParams) { + if (params.value == null) { + return ''; + } + + return ; +} + +function renderEditRating(params: GridRenderEditCellParams) { + return ; +} + +// Country +function renderCountry(params: GridRenderCellParams) { + if (params.value == null) { + return ''; + } + + return ; +} + +function renderEditCountry(params: GridRenderEditCellParams) { + return ; +} -function GridSparklineCell(params: GridRenderCellParams) { +// Sparkline +function renderSparkline(params: GridRenderCellParams) { if (params.value == null) { return ''; } @@ -50,6 +710,45 @@ function GridSparklineCell(params: GridRenderCellParams) { ); } +// Progress +function renderProgress(params: GridRenderCellParams) { + if (params.value == null) { + return ''; + } + + return ( +
+ +
+ ); +} + +function renderEditProgress(params: GridRenderEditCellParams) { + return ; +} + +// Status +function renderStatus(params: GridRenderCellParams) { + if (params.value == null) { + return ''; + } + + return ; +} + +function renderEditStatus(params: GridRenderEditCellParams) { + return ; +} + +// Incoterm +function renderIncoterm(params: GridRenderCellParams) { + return ; +} + +function renderEditIncoterm(params: GridRenderEditCellParams) { + return ; +} + const columns: GridColDef<(typeof rows)[number]>[] = [ { field: 'name', @@ -122,7 +821,7 @@ const columns: GridColDef<(typeof rows)[number]>[] = [ editable: false, groupable: false, display: 'flex', - renderCell: GridSparklineCell, + renderCell: renderSparkline, width: 150, valueGetter: (value, row) => row.monthlyActivity, }, From 7666e0d734510cffcead9c4286ee94cfff8b8bfe Mon Sep 17 00:00:00 2001 From: Armin Mehinovic Date: Fri, 5 Jul 2024 12:03:21 +0200 Subject: [PATCH 05/21] Fix lint issues --- .../custom-columns/CustomColumnFullExample.js | 24 +++++++++---------- .../CustomColumnFullExample.tsx | 24 +++++++++---------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/docs/data/data-grid/custom-columns/CustomColumnFullExample.js b/docs/data/data-grid/custom-columns/CustomColumnFullExample.js index 298db79e44586..fed409ccbd227 100644 --- a/docs/data/data-grid/custom-columns/CustomColumnFullExample.js +++ b/docs/data/data-grid/custom-columns/CustomColumnFullExample.js @@ -87,7 +87,7 @@ const RatingValue = React.memo(function RatingValue(props) { ); }); -const EditRating = (props) => { +function EditRating(props) { const { id, value, field } = props; const apiRef = useGridApiContext(); @@ -145,7 +145,7 @@ const EditRating = (props) => { {Number(value)} ); -}; +} const Country = React.memo(function Country(props) { const { value } = props; @@ -190,7 +190,7 @@ const StyledAutocomplete = styled(Autocomplete)(({ theme }) => ({ }, })); -const EditCountry = (props) => { +function EditCountry(props) { const { id, value, field } = props; const apiRef = useGridApiContext(); @@ -248,7 +248,7 @@ const EditCountry = (props) => { )} /> ); -}; +} const Center = styled('div')({ height: '100%', @@ -341,7 +341,7 @@ const StyledSlider = styled(Slider)(({ theme }) => ({ }, })); -const ValueLabelComponent = (props) => { +const ValueLabelComponent = React.memo(function ValueLabelComponent(props) { const { children, open, value } = props; return ( @@ -349,9 +349,9 @@ const ValueLabelComponent = (props) => { {children} ); -}; +}); -const EditProgress = (props) => { +function EditProgress(props) { const { id, value, field } = props; const [valueState, setValueState] = React.useState(Number(value)); @@ -403,7 +403,7 @@ const EditProgress = (props) => { valueLabelFormat={(newValue) => `${(newValue * 100).toLocaleString()} %`} /> ); -}; +} const StyledChip = styled(Chip)(({ theme }) => ({ justifyContent: 'left', @@ -458,7 +458,7 @@ const Status = React.memo((props) => { ); }); -const EditStatus = (props) => { +function EditStatus(props) { const { id, value, field } = props; const rootProps = useGridRootProps(); const apiRef = useGridApiContext(); @@ -528,7 +528,7 @@ const EditStatus = (props) => { })} ); -}; +} const Incoterm = React.memo(function Incoterm(props) { const { value } = props; @@ -553,7 +553,7 @@ const Incoterm = React.memo(function Incoterm(props) { ); }); -const EditIncoterm = (props) => { +function EditIncoterm(props) { const { id, value, field } = props; const apiRef = useGridApiContext(); @@ -604,7 +604,7 @@ const EditIncoterm = (props) => { })} ); -}; +} /** Custom cell renderers */ // Avatar diff --git a/docs/data/data-grid/custom-columns/CustomColumnFullExample.tsx b/docs/data/data-grid/custom-columns/CustomColumnFullExample.tsx index b23b67313e0e8..c7164bbfcbe17 100644 --- a/docs/data/data-grid/custom-columns/CustomColumnFullExample.tsx +++ b/docs/data/data-grid/custom-columns/CustomColumnFullExample.tsx @@ -121,7 +121,7 @@ const RatingValue = React.memo(function RatingValue(props: RatingValueProps) { ); }); -const EditRating = (props: GridRenderEditCellParams) => { +function EditRating(props: GridRenderEditCellParams) { const { id, value, field } = props; const apiRef = useGridApiContext(); @@ -179,7 +179,7 @@ const EditRating = (props: GridRenderEditCellParams) => { {Number(value)} ); -}; +} const Country = React.memo(function Country(props: CountryProps) { const { value } = props; @@ -224,7 +224,7 @@ const StyledAutocomplete = styled(Autocomplete)(({ theme }) => ({ }, })) as typeof Autocomplete; -const EditCountry = (props: GridRenderEditCellParams) => { +function EditCountry(props: GridRenderEditCellParams) { const { id, value, field } = props; const apiRef = useGridApiContext(); @@ -284,7 +284,7 @@ const EditCountry = (props: GridRenderEditCellParams) => { )} /> ); -}; +} const Center = styled('div')({ height: '100%', @@ -377,7 +377,7 @@ const StyledSlider = styled(Slider)(({ theme }) => ({ }, })); -const ValueLabelComponent = (props: any) => { +const ValueLabelComponent = React.memo(function ValueLabelComponent(props: any) { const { children, open, value } = props; return ( @@ -385,9 +385,9 @@ const ValueLabelComponent = (props: any) => { {children} ); -}; +}); -const EditProgress = (props: GridRenderEditCellParams) => { +function EditProgress(props: GridRenderEditCellParams) { const { id, value, field } = props; const [valueState, setValueState] = React.useState(Number(value)); @@ -439,7 +439,7 @@ const EditProgress = (props: GridRenderEditCellParams) => { valueLabelFormat={(newValue) => `${(newValue * 100).toLocaleString()} %`} /> ); -}; +} const StyledChip = styled(Chip)(({ theme }) => ({ justifyContent: 'left', @@ -494,7 +494,7 @@ const Status = React.memo((props: StatusProps) => { ); }); -const EditStatus = (props: GridRenderEditCellParams) => { +function EditStatus(props: GridRenderEditCellParams) { const { id, value, field } = props; const rootProps = useGridRootProps(); const apiRef = useGridApiContext(); @@ -564,7 +564,7 @@ const EditStatus = (props: GridRenderEditCellParams) => { })} ); -}; +} const Incoterm = React.memo(function Incoterm(props: IncotermProps) { const { value } = props; @@ -589,7 +589,7 @@ const Incoterm = React.memo(function Incoterm(props: IncotermProps) { ); }); -const EditIncoterm = (props: GridRenderEditCellParams) => { +function EditIncoterm(props: GridRenderEditCellParams) { const { id, value, field } = props; const apiRef = useGridApiContext(); @@ -640,7 +640,7 @@ const EditIncoterm = (props: GridRenderEditCellParams) => { })} ); -}; +} /** Custom cell renderers */ // Avatar From 8a93ea66e933c9e9444225c1f48232a1db52261e Mon Sep 17 00:00:00 2001 From: Armin Mehinovic Date: Fri, 5 Jul 2024 13:30:53 +0200 Subject: [PATCH 06/21] Avoid key prop spreading --- docs/data/data-grid/custom-columns/CustomColumnFullExample.js | 1 + docs/data/data-grid/custom-columns/CustomColumnFullExample.tsx | 1 + .../x-data-grid-generator/src/renderer/renderEditCountry.tsx | 1 + 3 files changed, 3 insertions(+) diff --git a/docs/data/data-grid/custom-columns/CustomColumnFullExample.js b/docs/data/data-grid/custom-columns/CustomColumnFullExample.js index fed409ccbd227..d9b67358b9140 100644 --- a/docs/data/data-grid/custom-columns/CustomColumnFullExample.js +++ b/docs/data/data-grid/custom-columns/CustomColumnFullExample.js @@ -223,6 +223,7 @@ function EditCountry(props) { }, }} {...optionProps} + key={option.code} > ) { }, }} {...optionProps} + key={option.code} > ) { }, }} {...optionProps} + key={option.code} > Date: Mon, 8 Jul 2024 11:30:04 +0200 Subject: [PATCH 07/21] Move renderers to separate files to enable easier copy of the relevant code --- .../custom-columns/CustomColumnFullExample.js | 705 +---------------- .../CustomColumnFullExample.tsx | 736 +----------------- .../custom-columns/renderers/avatar.tsx | 16 + .../custom-columns/renderers/country.tsx | 144 ++++ .../custom-columns/renderers/email.tsx | 39 + .../custom-columns/renderers/incoterm.tsx | 110 +++ .../custom-columns/renderers/progress.tsx | 191 +++++ .../custom-columns/renderers/rating.tsx | 100 +++ .../custom-columns/renderers/sparkline.tsx | 16 + .../custom-columns/renderers/status.tsx | 164 ++++ 10 files changed, 797 insertions(+), 1424 deletions(-) create mode 100644 docs/data/data-grid/custom-columns/renderers/avatar.tsx create mode 100644 docs/data/data-grid/custom-columns/renderers/country.tsx create mode 100644 docs/data/data-grid/custom-columns/renderers/email.tsx create mode 100644 docs/data/data-grid/custom-columns/renderers/incoterm.tsx create mode 100644 docs/data/data-grid/custom-columns/renderers/progress.tsx create mode 100644 docs/data/data-grid/custom-columns/renderers/rating.tsx create mode 100644 docs/data/data-grid/custom-columns/renderers/sparkline.tsx create mode 100644 docs/data/data-grid/custom-columns/renderers/status.tsx diff --git a/docs/data/data-grid/custom-columns/CustomColumnFullExample.js b/docs/data/data-grid/custom-columns/CustomColumnFullExample.js index d9b67358b9140..982bccba39f2d 100644 --- a/docs/data/data-grid/custom-columns/CustomColumnFullExample.js +++ b/docs/data/data-grid/custom-columns/CustomColumnFullExample.js @@ -1,5 +1,4 @@ import * as React from 'react'; -import clsx from 'clsx'; import { generateFilledQuantity, randomColor, @@ -12,705 +11,19 @@ import { randomStatusOptions, } from '@mui/x-data-grid-generator'; import { - COUNTRY_ISO_OPTIONS, COUNTRY_ISO_OPTIONS_SORTED, INCOTERM_OPTIONS, STATUS_OPTIONS, } from '@mui/x-data-grid-generator/services/static-data'; -import { SparkLineChart } from '@mui/x-charts/SparkLineChart'; -import { - DataGrid, - GridEditModes, - gridStringOrNumberComparator, - useGridApiContext, - useGridRootProps, -} from '@mui/x-data-grid'; -import { - alpha, - Autocomplete, - autocompleteClasses, - Avatar, - Box, - Chip, - debounce, - InputBase, - ListItemIcon, - ListItemText, - MenuItem, - Rating, - Select, - Slider, - sliderClasses, - styled, - Tooltip, -} from '@mui/material'; -import ReportProblemIcon from '@mui/icons-material/ReportProblem'; -import InfoIcon from '@mui/icons-material/Info'; -import AutorenewIcon from '@mui/icons-material/Autorenew'; -import DoneIcon from '@mui/icons-material/Done'; - -/** Custom components supporting custom renderers */ -const Link = styled('a')({ - textOverflow: 'ellipsis', - whiteSpace: 'nowrap', - overflow: 'hidden', - color: 'inherit', -}); - -const DemoLink = React.memo(function DemoLink(props) { - const handleClick = (event) => { - event.preventDefault(); - event.stopPropagation(); - }; - - return ( - - {props.children} - - ); -}); - -const RatingValue = React.memo(function RatingValue(props) { - const { value } = props; - return ( - - {' '} - {Math.round(Number(value) * 10) / 10} - - ); -}); - -function EditRating(props) { - const { id, value, field } = props; - - const apiRef = useGridApiContext(); - - const changedThroughKeyboard = React.useRef(false); - - const handleChange = async (event) => { - await apiRef.current.setEditCellValue( - { id, field, value: Number(event.target.value) }, - event, - ); - if (!changedThroughKeyboard.current) { - apiRef.current.stopCellEditMode({ id, field }); - } - changedThroughKeyboard.current = false; - }; - - const handleRef = (element) => { - if (element) { - if (value !== 0) { - element.querySelector(`input[value="${value}"]`).focus(); - } else { - element.querySelector('input[value=""]').focus(); - } - } - }; - - const handleKeyDown = (event) => { - if (event.key.startsWith('Arrow')) { - changedThroughKeyboard.current = true; - } else { - changedThroughKeyboard.current = false; - } - }; - - return ( - - - {Number(value)} - - ); -} - -const Country = React.memo(function Country(props) { - const { value } = props; - - return ( - img': { - mr: 0.5, - flexShrink: 0, - width: '20px', - }, - }} - > - - - {value.label} - - - ); -}); - -const StyledAutocomplete = styled(Autocomplete)(({ theme }) => ({ - height: '100%', - [`& .${autocompleteClasses.inputRoot}`]: { - ...theme.typography.body2, - padding: '1px 0', - height: '100%', - '& input': { - padding: '0 16px', - height: '100%', - }, - }, -})); - -function EditCountry(props) { - const { id, value, field } = props; - - const apiRef = useGridApiContext(); - - const handleChange = React.useCallback( - async (event, newValue) => { - await apiRef.current.setEditCellValue({ id, field, value: newValue }, event); - apiRef.current.stopCellEditMode({ id, field }); - }, - [apiRef, field, id], - ); - - return ( - option.label} - autoHighlight - fullWidth - open - disableClearable - renderOption={(optionProps, option) => ( - img': { - mr: 1.5, - flexShrink: 0, - }, - }} - {...optionProps} - key={option.code} - > - - {option.label} - - )} - renderInput={(params) => ( - - )} - /> - ); -} - -const Center = styled('div')({ - height: '100%', - display: 'flex', - alignItems: 'center', -}); - -const Element = styled('div')(({ theme }) => ({ - border: `1px solid ${(theme.vars || theme).palette.divider}`, - position: 'relative', - overflow: 'hidden', - width: '100%', - height: 26, - borderRadius: 2, -})); - -const Value = styled('div')({ - position: 'absolute', - lineHeight: '24px', - width: '100%', - display: 'flex', - justifyContent: 'center', -}); - -const Bar = styled('div')({ - height: '100%', - '&.low': { - backgroundColor: '#f44336', - }, - '&.medium': { - backgroundColor: '#efbb5aa3', - }, - '&.high': { - backgroundColor: '#088208a3', - }, -}); - -const ProgressBar = React.memo(function ProgressBar(props) { - const { value } = props; - const valueInPercent = value * 100; - - return ( - - {`${valueInPercent.toLocaleString()} %`} - = 30 && valueInPercent <= 70, - high: valueInPercent > 70, - })} - style={{ maxWidth: `${valueInPercent}%` }} - /> - - ); -}); - -const StyledSlider = styled(Slider)(({ theme }) => ({ - display: 'flex', - height: '100%', - width: '100%', - alignItems: 'center', - justifyContent: 'center', - padding: 0, - borderRadius: 0, - [`& .${sliderClasses.rail}`]: { - height: '100%', - backgroundColor: 'transparent', - }, - [`& .${sliderClasses.track}`]: { - height: '100%', - transition: theme.transitions.create('background-color', { - duration: theme.transitions.duration.shorter, - }), - '&.low': { - backgroundColor: '#f44336', - }, - '&.medium': { - backgroundColor: '#efbb5aa3', - }, - '&.high': { - backgroundColor: '#088208a3', - }, - }, - [`& .${sliderClasses.thumb}`]: { - height: '100%', - width: 5, - borderRadius: 0, - marginTop: 0, - backgroundColor: alpha('#000000', 0.2), - }, -})); - -const ValueLabelComponent = React.memo(function ValueLabelComponent(props) { - const { children, open, value } = props; - - return ( - - {children} - - ); -}); - -function EditProgress(props) { - const { id, value, field } = props; - const [valueState, setValueState] = React.useState(Number(value)); - - const apiRef = useGridApiContext(); - - const updateCellEditProps = React.useCallback( - (newValue) => { - apiRef.current.setEditCellValue({ id, field, value: newValue }); - }, - [apiRef, field, id], - ); - - const debouncedUpdateCellEditProps = React.useMemo( - () => debounce(updateCellEditProps, 60), - [updateCellEditProps], - ); - - const handleChange = (event, newValue) => { - setValueState(newValue); - debouncedUpdateCellEditProps(newValue); - }; - - React.useEffect(() => { - setValueState(Number(value)); - }, [value]); - - const handleRef = (element) => { - if (element) { - element.querySelector('[type="range"]').focus(); - } - }; - - return ( - = 0.3 && valueState <= 0.7, - high: valueState > 0.7, - }), - }} - value={valueState} - max={1} - step={0.00001} - onChange={handleChange} - components={{ ValueLabel: ValueLabelComponent }} - valueLabelDisplay="auto" - valueLabelFormat={(newValue) => `${(newValue * 100).toLocaleString()} %`} - /> - ); -} - -const StyledChip = styled(Chip)(({ theme }) => ({ - justifyContent: 'left', - '& .icon': { - color: 'inherit', - }, - '&.Open': { - color: (theme.vars || theme).palette.info.dark, - border: `1px solid ${(theme.vars || theme).palette.info.main}`, - }, - '&.Filled': { - color: (theme.vars || theme).palette.success.dark, - border: `1px solid ${(theme.vars || theme).palette.success.main}`, - }, - '&.PartiallyFilled': { - color: (theme.vars || theme).palette.warning.dark, - border: `1px solid ${(theme.vars || theme).palette.warning.main}`, - }, - '&.Rejected': { - color: (theme.vars || theme).palette.error.dark, - border: `1px solid ${(theme.vars || theme).palette.error.main}`, - }, -})); - -const Status = React.memo((props) => { - const { status } = props; - - let icon = null; - if (status === 'Rejected') { - icon = ; - } else if (status === 'Open') { - icon = ; - } else if (status === 'PartiallyFilled') { - icon = ; - } else if (status === 'Filled') { - icon = ; - } - - let label = status; - if (status === 'PartiallyFilled') { - label = 'Partially Filled'; - } - - return ( - - ); -}); - -function EditStatus(props) { - const { id, value, field } = props; - const rootProps = useGridRootProps(); - const apiRef = useGridApiContext(); - - const handleChange = async (event) => { - const isValid = await apiRef.current.setEditCellValue({ - id, - field, - value: event.target.value, - }); - - if (isValid && rootProps.editMode === GridEditModes.Cell) { - apiRef.current.stopCellEditMode({ id, field, cellToFocusAfter: 'below' }); - } - }; - - const handleClose = (event, reason) => { - if (reason === 'backdropClick') { - apiRef.current.stopCellEditMode({ id, field, ignoreModifications: true }); - } - }; - - return ( - - ); -} - -const Incoterm = React.memo(function Incoterm(props) { - const { value } = props; - - if (!value) { - return null; - } - - const valueStr = value.toString(); - const tooltip = valueStr.slice(valueStr.indexOf('(') + 1, valueStr.indexOf(')')); - const code = valueStr.slice(0, valueStr.indexOf('(')).trim(); - - return ( - - {code} - - - - - ); -}); - -function EditIncoterm(props) { - const { id, value, field } = props; - - const apiRef = useGridApiContext(); - - const handleChange = async (event) => { - await apiRef.current.setEditCellValue( - { id, field, value: event.target.value }, - event, - ); - apiRef.current.stopCellEditMode({ id, field }); - }; - - const handleClose = (event, reason) => { - if (reason === 'backdropClick') { - apiRef.current.stopCellEditMode({ id, field }); - } - }; - - return ( - - ); -} - -/** Custom cell renderers */ -// Avatar -function renderAvatar(params) { - if (params.value == null) { - return ''; - } - - return ( - - {params.value.name.toUpperCase().substring(0, 1)} - - ); -} - -// Email -function renderEmail(params) { - const email = params.value ?? ''; - - return ( - - {email} - - ); -} - -// Rating -function renderRating(params) { - if (params.value == null) { - return ''; - } - - return ; -} - -function renderEditRating(params) { - return ; -} - -// Country -function renderCountry(params) { - if (params.value == null) { - return ''; - } - - return ; -} - -function renderEditCountry(params) { - return ; -} - -// Sparkline -function renderSparkline(params) { - if (params.value == null) { - return ''; - } - - return ( - - ); -} - -// Progress -function renderProgress(params) { - if (params.value == null) { - return ''; - } - - return ( -
- -
- ); -} - -function renderEditProgress(params) { - return ; -} - -// Status -function renderStatus(params) { - if (params.value == null) { - return ''; - } - - return ; -} - -function renderEditStatus(params) { - return ; -} - -// Incoterm -function renderIncoterm(params) { - return ; -} - -function renderEditIncoterm(params) { - return ; -} +import { DataGrid, gridStringOrNumberComparator } from '@mui/x-data-grid'; +import { renderAvatar } from './renderers/avatar'; +import { renderEmail } from './renderers/email'; +import { renderEditRating, renderRating } from './renderers/rating'; +import { renderCountry, renderEditCountry } from './renderers/country'; +import { renderSparkline } from './renderers/sparkline'; +import { renderEditProgress, renderProgress } from './renderers/progress'; +import { renderEditStatus, renderStatus } from './renderers/status'; +import { renderEditIncoterm, renderIncoterm } from './renderers/incoterm'; const columns = [ { diff --git a/docs/data/data-grid/custom-columns/CustomColumnFullExample.tsx b/docs/data/data-grid/custom-columns/CustomColumnFullExample.tsx index afef7b87abf46..c89c88f89a714 100644 --- a/docs/data/data-grid/custom-columns/CustomColumnFullExample.tsx +++ b/docs/data/data-grid/custom-columns/CustomColumnFullExample.tsx @@ -1,5 +1,4 @@ import * as React from 'react'; -import clsx from 'clsx'; import { generateFilledQuantity, randomColor, @@ -12,743 +11,24 @@ import { randomStatusOptions, } from '@mui/x-data-grid-generator'; import { - COUNTRY_ISO_OPTIONS, COUNTRY_ISO_OPTIONS_SORTED, CountryIsoOption, INCOTERM_OPTIONS, STATUS_OPTIONS, } from '@mui/x-data-grid-generator/services/static-data'; -import { SparkLineChart } from '@mui/x-charts/SparkLineChart'; import { DataGrid, GridColDef, - GridEditModes, - GridRenderCellParams, - GridRenderEditCellParams, gridStringOrNumberComparator, - useGridApiContext, - useGridRootProps, } from '@mui/x-data-grid'; -import { - alpha, - Autocomplete, - autocompleteClasses, - AutocompleteProps, - Avatar, - Box, - Chip, - debounce, - InputBase, - ListItemIcon, - ListItemText, - MenuItem, - MenuProps, - Rating, - Select, - SelectProps, - Slider, - sliderClasses, - SliderProps, - styled, - Tooltip, -} from '@mui/material'; -import ReportProblemIcon from '@mui/icons-material/ReportProblem'; -import InfoIcon from '@mui/icons-material/Info'; -import AutorenewIcon from '@mui/icons-material/Autorenew'; -import DoneIcon from '@mui/icons-material/Done'; - -interface DemoLinkProps { - href: string; - children: string; - tabIndex: number; -} - -interface RatingValueProps { - value: number; -} - -interface CountryProps { - value: CountryIsoOption; -} - -interface ProgressBarProps { - value: number; -} - -interface StatusProps { - status: string; -} - -interface IncotermProps { - value: string | null | undefined; -} - -/** Custom components supporting custom renderers */ -const Link = styled('a')({ - textOverflow: 'ellipsis', - whiteSpace: 'nowrap', - overflow: 'hidden', - color: 'inherit', -}); - -const DemoLink = React.memo(function DemoLink(props: DemoLinkProps) { - const handleClick = (event: React.MouseEvent) => { - event.preventDefault(); - event.stopPropagation(); - }; - - return ( - - {props.children} - - ); -}); - -const RatingValue = React.memo(function RatingValue(props: RatingValueProps) { - const { value } = props; - return ( - - {' '} - {Math.round(Number(value) * 10) / 10} - - ); -}); - -function EditRating(props: GridRenderEditCellParams) { - const { id, value, field } = props; - - const apiRef = useGridApiContext(); - - const changedThroughKeyboard = React.useRef(false); - - const handleChange = async (event: any) => { - await apiRef.current.setEditCellValue( - { id, field, value: Number(event.target.value) }, - event, - ); - if (!changedThroughKeyboard.current) { - apiRef.current.stopCellEditMode({ id, field }); - } - changedThroughKeyboard.current = false; - }; - - const handleRef = (element: HTMLElement | undefined) => { - if (element) { - if (value !== 0) { - element.querySelector(`input[value="${value}"]`)!.focus(); - } else { - element.querySelector('input[value=""]')!.focus(); - } - } - }; - - const handleKeyDown = (event: React.KeyboardEvent) => { - if (event.key.startsWith('Arrow')) { - changedThroughKeyboard.current = true; - } else { - changedThroughKeyboard.current = false; - } - }; - - return ( - - - {Number(value)} - - ); -} - -const Country = React.memo(function Country(props: CountryProps) { - const { value } = props; - - return ( - img': { - mr: 0.5, - flexShrink: 0, - width: '20px', - }, - }} - > - - - {value.label} - - - ); -}); - -const StyledAutocomplete = styled(Autocomplete)(({ theme }) => ({ - height: '100%', - [`& .${autocompleteClasses.inputRoot}`]: { - ...theme.typography.body2, - padding: '1px 0', - height: '100%', - '& input': { - padding: '0 16px', - height: '100%', - }, - }, -})) as typeof Autocomplete; - -function EditCountry(props: GridRenderEditCellParams) { - const { id, value, field } = props; - - const apiRef = useGridApiContext(); - - const handleChange = React.useCallback< - NonNullable['onChange']> - >( - async (event, newValue) => { - await apiRef.current.setEditCellValue({ id, field, value: newValue }, event); - apiRef.current.stopCellEditMode({ id, field }); - }, - [apiRef, field, id], - ); - - return ( - - value={value} - onChange={handleChange} - options={COUNTRY_ISO_OPTIONS} - getOptionLabel={(option: any) => option.label} - autoHighlight - fullWidth - open - disableClearable - renderOption={(optionProps, option: any) => ( - img': { - mr: 1.5, - flexShrink: 0, - }, - }} - {...optionProps} - key={option.code} - > - - {option.label} - - )} - renderInput={(params) => ( - - )} - /> - ); -} - -const Center = styled('div')({ - height: '100%', - display: 'flex', - alignItems: 'center', -}); - -const Element = styled('div')(({ theme }) => ({ - border: `1px solid ${(theme.vars || theme).palette.divider}`, - position: 'relative', - overflow: 'hidden', - width: '100%', - height: 26, - borderRadius: 2, -})); - -const Value = styled('div')({ - position: 'absolute', - lineHeight: '24px', - width: '100%', - display: 'flex', - justifyContent: 'center', -}); - -const Bar = styled('div')({ - height: '100%', - '&.low': { - backgroundColor: '#f44336', - }, - '&.medium': { - backgroundColor: '#efbb5aa3', - }, - '&.high': { - backgroundColor: '#088208a3', - }, -}); - -const ProgressBar = React.memo(function ProgressBar(props: ProgressBarProps) { - const { value } = props; - const valueInPercent = value * 100; - - return ( - - {`${valueInPercent.toLocaleString()} %`} - = 30 && valueInPercent <= 70, - high: valueInPercent > 70, - })} - style={{ maxWidth: `${valueInPercent}%` }} - /> - - ); -}); - -const StyledSlider = styled(Slider)(({ theme }) => ({ - display: 'flex', - height: '100%', - width: '100%', - alignItems: 'center', - justifyContent: 'center', - padding: 0, - borderRadius: 0, - [`& .${sliderClasses.rail}`]: { - height: '100%', - backgroundColor: 'transparent', - }, - [`& .${sliderClasses.track}`]: { - height: '100%', - transition: theme.transitions.create('background-color', { - duration: theme.transitions.duration.shorter, - }), - '&.low': { - backgroundColor: '#f44336', - }, - '&.medium': { - backgroundColor: '#efbb5aa3', - }, - '&.high': { - backgroundColor: '#088208a3', - }, - }, - [`& .${sliderClasses.thumb}`]: { - height: '100%', - width: 5, - borderRadius: 0, - marginTop: 0, - backgroundColor: alpha('#000000', 0.2), - }, -})); - -const ValueLabelComponent = React.memo(function ValueLabelComponent(props: any) { - const { children, open, value } = props; - - return ( - - {children} - - ); -}); - -function EditProgress(props: GridRenderEditCellParams) { - const { id, value, field } = props; - const [valueState, setValueState] = React.useState(Number(value)); - - const apiRef = useGridApiContext(); - - const updateCellEditProps = React.useCallback( - (newValue: number) => { - apiRef.current.setEditCellValue({ id, field, value: newValue }); - }, - [apiRef, field, id], - ); - - const debouncedUpdateCellEditProps = React.useMemo( - () => debounce(updateCellEditProps, 60), - [updateCellEditProps], - ); - - const handleChange = (event: Event, newValue: number | number[]) => { - setValueState(newValue as number); - debouncedUpdateCellEditProps(newValue as number); - }; - - React.useEffect(() => { - setValueState(Number(value)); - }, [value]); - - const handleRef: SliderProps['ref'] = (element) => { - if (element) { - element.querySelector('[type="range"]')!.focus(); - } - }; - - return ( - = 0.3 && valueState <= 0.7, - high: valueState > 0.7, - }), - }} - value={valueState} - max={1} - step={0.00001} - onChange={handleChange} - components={{ ValueLabel: ValueLabelComponent }} - valueLabelDisplay="auto" - valueLabelFormat={(newValue) => `${(newValue * 100).toLocaleString()} %`} - /> - ); -} - -const StyledChip = styled(Chip)(({ theme }) => ({ - justifyContent: 'left', - '& .icon': { - color: 'inherit', - }, - '&.Open': { - color: (theme.vars || theme).palette.info.dark, - border: `1px solid ${(theme.vars || theme).palette.info.main}`, - }, - '&.Filled': { - color: (theme.vars || theme).palette.success.dark, - border: `1px solid ${(theme.vars || theme).palette.success.main}`, - }, - '&.PartiallyFilled': { - color: (theme.vars || theme).palette.warning.dark, - border: `1px solid ${(theme.vars || theme).palette.warning.main}`, - }, - '&.Rejected': { - color: (theme.vars || theme).palette.error.dark, - border: `1px solid ${(theme.vars || theme).palette.error.main}`, - }, -})); - -const Status = React.memo((props: StatusProps) => { - const { status } = props; - - let icon: any = null; - if (status === 'Rejected') { - icon = ; - } else if (status === 'Open') { - icon = ; - } else if (status === 'PartiallyFilled') { - icon = ; - } else if (status === 'Filled') { - icon = ; - } - - let label: string = status; - if (status === 'PartiallyFilled') { - label = 'Partially Filled'; - } - - return ( - - ); -}); - -function EditStatus(props: GridRenderEditCellParams) { - const { id, value, field } = props; - const rootProps = useGridRootProps(); - const apiRef = useGridApiContext(); - - const handleChange: SelectProps['onChange'] = async (event) => { - const isValid = await apiRef.current.setEditCellValue({ - id, - field, - value: event.target.value, - }); - - if (isValid && rootProps.editMode === GridEditModes.Cell) { - apiRef.current.stopCellEditMode({ id, field, cellToFocusAfter: 'below' }); - } - }; - - const handleClose: MenuProps['onClose'] = (event, reason) => { - if (reason === 'backdropClick') { - apiRef.current.stopCellEditMode({ id, field, ignoreModifications: true }); - } - }; - - return ( - - ); -} - -const Incoterm = React.memo(function Incoterm(props: IncotermProps) { - const { value } = props; - - if (!value) { - return null; - } - - const valueStr = value.toString(); - const tooltip = valueStr.slice(valueStr.indexOf('(') + 1, valueStr.indexOf(')')); - const code = valueStr.slice(0, valueStr.indexOf('(')).trim(); - - return ( - - {code} - - - - - ); -}); - -function EditIncoterm(props: GridRenderEditCellParams) { - const { id, value, field } = props; - - const apiRef = useGridApiContext(); - - const handleChange: SelectProps['onChange'] = async (event) => { - await apiRef.current.setEditCellValue( - { id, field, value: event.target.value as any }, - event, - ); - apiRef.current.stopCellEditMode({ id, field }); - }; - - const handleClose: MenuProps['onClose'] = (event, reason) => { - if (reason === 'backdropClick') { - apiRef.current.stopCellEditMode({ id, field }); - } - }; - - return ( - - ); -} - -/** Custom cell renderers */ -// Avatar -function renderAvatar( - params: GridRenderCellParams<{ name: string; color: string }, any, any>, -) { - if (params.value == null) { - return ''; - } - - return ( - - {params.value.name.toUpperCase().substring(0, 1)} - - ); -} - -// Email -function renderEmail(params: GridRenderCellParams) { - const email = params.value ?? ''; - - return ( - - {email} - - ); -} - -// Rating -function renderRating(params: GridRenderCellParams) { - if (params.value == null) { - return ''; - } - - return ; -} - -function renderEditRating(params: GridRenderEditCellParams) { - return ; -} - -// Country -function renderCountry(params: GridRenderCellParams) { - if (params.value == null) { - return ''; - } - - return ; -} - -function renderEditCountry(params: GridRenderEditCellParams) { - return ; -} - -// Sparkline -function renderSparkline(params: GridRenderCellParams) { - if (params.value == null) { - return ''; - } - - return ( - - ); -} - -// Progress -function renderProgress(params: GridRenderCellParams) { - if (params.value == null) { - return ''; - } - - return ( -
- -
- ); -} - -function renderEditProgress(params: GridRenderEditCellParams) { - return ; -} - -// Status -function renderStatus(params: GridRenderCellParams) { - if (params.value == null) { - return ''; - } - - return ; -} - -function renderEditStatus(params: GridRenderEditCellParams) { - return ; -} - -// Incoterm -function renderIncoterm(params: GridRenderCellParams) { - return ; -} - -function renderEditIncoterm(params: GridRenderEditCellParams) { - return ; -} +import { renderAvatar } from './renderers/avatar'; +import { renderEmail } from './renderers/email'; +import { renderEditRating, renderRating } from './renderers/rating'; +import { renderCountry, renderEditCountry } from './renderers/country'; +import { renderSparkline } from './renderers/sparkline'; +import { renderEditProgress, renderProgress } from './renderers/progress'; +import { renderEditStatus, renderStatus } from './renderers/status'; +import { renderEditIncoterm, renderIncoterm } from './renderers/incoterm'; const columns: GridColDef<(typeof rows)[number]>[] = [ { diff --git a/docs/data/data-grid/custom-columns/renderers/avatar.tsx b/docs/data/data-grid/custom-columns/renderers/avatar.tsx new file mode 100644 index 0000000000000..affcb69456ae0 --- /dev/null +++ b/docs/data/data-grid/custom-columns/renderers/avatar.tsx @@ -0,0 +1,16 @@ +import Avatar from '@mui/material/Avatar'; +import { GridRenderCellParams } from '@mui/x-data-grid'; + +export function renderAvatar( + params: GridRenderCellParams<{ name: string; color: string }, any, any>, +) { + if (params.value == null) { + return ''; + } + + return ( + + {params.value.name.toUpperCase().substring(0, 1)} + + ); +} diff --git a/docs/data/data-grid/custom-columns/renderers/country.tsx b/docs/data/data-grid/custom-columns/renderers/country.tsx new file mode 100644 index 0000000000000..7f92cb9664ed2 --- /dev/null +++ b/docs/data/data-grid/custom-columns/renderers/country.tsx @@ -0,0 +1,144 @@ +import * as React from 'react'; +import { + GridRenderCellParams, + GridRenderEditCellParams, + useGridApiContext, +} from '@mui/x-data-grid'; +import { + COUNTRY_ISO_OPTIONS, + CountryIsoOption, +} from '@mui/x-data-grid-generator/services/static-data'; +import { + Autocomplete, + autocompleteClasses, + AutocompleteProps, + Box, + InputBase, + styled, +} from '@mui/material'; + +interface CountryProps { + value: CountryIsoOption; +} + +const Country = React.memo(function Country(props: CountryProps) { + const { value } = props; + + return ( + img': { + mr: 0.5, + flexShrink: 0, + width: '20px', + }, + }} + > + + + {value.label} + + + ); +}); + +const StyledAutocomplete = styled(Autocomplete)(({ theme }) => ({ + height: '100%', + [`& .${autocompleteClasses.inputRoot}`]: { + ...theme.typography.body2, + padding: '1px 0', + height: '100%', + '& input': { + padding: '0 16px', + height: '100%', + }, + }, +})) as typeof Autocomplete; + +function EditCountry(props: GridRenderEditCellParams) { + const { id, value, field } = props; + + const apiRef = useGridApiContext(); + + const handleChange = React.useCallback< + NonNullable['onChange']> + >( + async (event, newValue) => { + await apiRef.current.setEditCellValue({ id, field, value: newValue }, event); + apiRef.current.stopCellEditMode({ id, field }); + }, + [apiRef, field, id], + ); + + return ( + + value={value} + onChange={handleChange} + options={COUNTRY_ISO_OPTIONS} + getOptionLabel={(option: any) => option.label} + autoHighlight + fullWidth + open + disableClearable + renderOption={(optionProps, option: any) => ( + img': { + mr: 1.5, + flexShrink: 0, + }, + }} + {...optionProps} + key={option.code} + > + + {option.label} + + )} + renderInput={(params) => ( + + )} + /> + ); +} + +export function renderCountry( + params: GridRenderCellParams, +) { + if (params.value == null) { + return ''; + } + + return ; +} + +export function renderEditCountry( + params: GridRenderEditCellParams, +) { + return ; +} diff --git a/docs/data/data-grid/custom-columns/renderers/email.tsx b/docs/data/data-grid/custom-columns/renderers/email.tsx new file mode 100644 index 0000000000000..609ea2c818519 --- /dev/null +++ b/docs/data/data-grid/custom-columns/renderers/email.tsx @@ -0,0 +1,39 @@ +import * as React from 'react'; +import { styled } from '@mui/material'; +import { GridRenderCellParams } from '@mui/x-data-grid'; + +interface DemoLinkProps { + href: string; + children: string; + tabIndex: number; +} + +const Link = styled('a')({ + textOverflow: 'ellipsis', + whiteSpace: 'nowrap', + overflow: 'hidden', + color: 'inherit', +}); + +const DemoLink = React.memo(function DemoLink(props: DemoLinkProps) { + const handleClick = (event: React.MouseEvent) => { + event.preventDefault(); + event.stopPropagation(); + }; + + return ( + + {props.children} + + ); +}); + +export function renderEmail(params: GridRenderCellParams) { + const email = params.value ?? ''; + + return ( + + {email} + + ); +} diff --git a/docs/data/data-grid/custom-columns/renderers/incoterm.tsx b/docs/data/data-grid/custom-columns/renderers/incoterm.tsx new file mode 100644 index 0000000000000..0d2b83821737b --- /dev/null +++ b/docs/data/data-grid/custom-columns/renderers/incoterm.tsx @@ -0,0 +1,110 @@ +import * as React from 'react'; +import { + Box, + ListItemIcon, + ListItemText, + MenuItem, + MenuProps, + Select, + SelectProps, + Tooltip, +} from '@mui/material'; +import InfoIcon from '@mui/icons-material/Info'; +import { + GridRenderCellParams, + GridRenderEditCellParams, + useGridApiContext, +} from '@mui/x-data-grid'; +import { INCOTERM_OPTIONS } from '@mui/x-data-grid-generator/services/static-data'; + +interface IncotermProps { + value: string | null | undefined; +} + +const Incoterm = React.memo(function Incoterm(props: IncotermProps) { + const { value } = props; + + if (!value) { + return null; + } + + const valueStr = value.toString(); + const tooltip = valueStr.slice(valueStr.indexOf('(') + 1, valueStr.indexOf(')')); + const code = valueStr.slice(0, valueStr.indexOf('(')).trim(); + + return ( + + {code} + + + + + ); +}); + +function EditIncoterm(props: GridRenderEditCellParams) { + const { id, value, field } = props; + + const apiRef = useGridApiContext(); + + const handleChange: SelectProps['onChange'] = async (event) => { + await apiRef.current.setEditCellValue( + { id, field, value: event.target.value as any }, + event, + ); + apiRef.current.stopCellEditMode({ id, field }); + }; + + const handleClose: MenuProps['onClose'] = (event, reason) => { + if (reason === 'backdropClick') { + apiRef.current.stopCellEditMode({ id, field }); + } + }; + + return ( + + ); +} + +export function renderIncoterm( + params: GridRenderCellParams, +) { + return ; +} + +export function renderEditIncoterm( + params: GridRenderEditCellParams, +) { + return ; +} diff --git a/docs/data/data-grid/custom-columns/renderers/progress.tsx b/docs/data/data-grid/custom-columns/renderers/progress.tsx new file mode 100644 index 0000000000000..b0495a50a3737 --- /dev/null +++ b/docs/data/data-grid/custom-columns/renderers/progress.tsx @@ -0,0 +1,191 @@ +import * as React from 'react'; +import clsx from 'clsx'; +import { + GridRenderCellParams, + GridRenderEditCellParams, + useGridApiContext, +} from '@mui/x-data-grid'; +import { + alpha, + debounce, + Slider, + sliderClasses, + SliderProps, + styled, + Tooltip, +} from '@mui/material'; + +interface ProgressBarProps { + value: number; +} + +const Center = styled('div')({ + height: '100%', + display: 'flex', + alignItems: 'center', +}); + +const Element = styled('div')(({ theme }) => ({ + border: `1px solid ${(theme.vars || theme).palette.divider}`, + position: 'relative', + overflow: 'hidden', + width: '100%', + height: 26, + borderRadius: 2, +})); + +const Value = styled('div')({ + position: 'absolute', + lineHeight: '24px', + width: '100%', + display: 'flex', + justifyContent: 'center', +}); + +const Bar = styled('div')({ + height: '100%', + '&.low': { + backgroundColor: '#f44336', + }, + '&.medium': { + backgroundColor: '#efbb5aa3', + }, + '&.high': { + backgroundColor: '#088208a3', + }, +}); + +const ProgressBar = React.memo(function ProgressBar(props: ProgressBarProps) { + const { value } = props; + const valueInPercent = value * 100; + + return ( + + {`${valueInPercent.toLocaleString()} %`} + = 30 && valueInPercent <= 70, + high: valueInPercent > 70, + })} + style={{ maxWidth: `${valueInPercent}%` }} + /> + + ); +}); + +const StyledSlider = styled(Slider)(({ theme }) => ({ + display: 'flex', + height: '100%', + width: '100%', + alignItems: 'center', + justifyContent: 'center', + padding: 0, + borderRadius: 0, + [`& .${sliderClasses.rail}`]: { + height: '100%', + backgroundColor: 'transparent', + }, + [`& .${sliderClasses.track}`]: { + height: '100%', + transition: theme.transitions.create('background-color', { + duration: theme.transitions.duration.shorter, + }), + '&.low': { + backgroundColor: '#f44336', + }, + '&.medium': { + backgroundColor: '#efbb5aa3', + }, + '&.high': { + backgroundColor: '#088208a3', + }, + }, + [`& .${sliderClasses.thumb}`]: { + height: '100%', + width: 5, + borderRadius: 0, + marginTop: 0, + backgroundColor: alpha('#000000', 0.2), + }, +})); + +const ValueLabelComponent = React.memo(function ValueLabelComponent(props: any) { + const { children, open, value } = props; + + return ( + + {children} + + ); +}); + +function EditProgress(props: GridRenderEditCellParams) { + const { id, value, field } = props; + const [valueState, setValueState] = React.useState(Number(value)); + + const apiRef = useGridApiContext(); + + const updateCellEditProps = React.useCallback( + (newValue: number) => { + apiRef.current.setEditCellValue({ id, field, value: newValue }); + }, + [apiRef, field, id], + ); + + const debouncedUpdateCellEditProps = React.useMemo( + () => debounce(updateCellEditProps, 60), + [updateCellEditProps], + ); + + const handleChange = (event: Event, newValue: number | number[]) => { + setValueState(newValue as number); + debouncedUpdateCellEditProps(newValue as number); + }; + + React.useEffect(() => { + setValueState(Number(value)); + }, [value]); + + const handleRef: SliderProps['ref'] = (element) => { + if (element) { + element.querySelector('[type="range"]')!.focus(); + } + }; + + return ( + = 0.3 && valueState <= 0.7, + high: valueState > 0.7, + }), + }} + value={valueState} + max={1} + step={0.00001} + onChange={handleChange} + components={{ ValueLabel: ValueLabelComponent }} + valueLabelDisplay="auto" + valueLabelFormat={(newValue) => `${(newValue * 100).toLocaleString()} %`} + /> + ); +} + +export function renderProgress(params: GridRenderCellParams) { + if (params.value == null) { + return ''; + } + + return ( +
+ +
+ ); +} + +export function renderEditProgress(params: GridRenderEditCellParams) { + return ; +} diff --git a/docs/data/data-grid/custom-columns/renderers/rating.tsx b/docs/data/data-grid/custom-columns/renderers/rating.tsx new file mode 100644 index 0000000000000..56372ced407e8 --- /dev/null +++ b/docs/data/data-grid/custom-columns/renderers/rating.tsx @@ -0,0 +1,100 @@ +import * as React from 'react'; +import { Box, Rating } from '@mui/material'; +import { + GridRenderCellParams, + GridRenderEditCellParams, + useGridApiContext, +} from '@mui/x-data-grid'; + +interface RatingValueProps { + value: number; +} + +const RatingValue = React.memo(function RatingValue(props: RatingValueProps) { + const { value } = props; + return ( + + {' '} + {Math.round(Number(value) * 10) / 10} + + ); +}); + +function EditRating(props: GridRenderEditCellParams) { + const { id, value, field } = props; + + const apiRef = useGridApiContext(); + + const changedThroughKeyboard = React.useRef(false); + + const handleChange = async (event: any) => { + await apiRef.current.setEditCellValue( + { id, field, value: Number(event.target.value) }, + event, + ); + if (!changedThroughKeyboard.current) { + apiRef.current.stopCellEditMode({ id, field }); + } + changedThroughKeyboard.current = false; + }; + + const handleRef = (element: HTMLElement | undefined) => { + if (element) { + if (value !== 0) { + element.querySelector(`input[value="${value}"]`)!.focus(); + } else { + element.querySelector('input[value=""]')!.focus(); + } + } + }; + + const handleKeyDown = (event: React.KeyboardEvent) => { + if (event.key.startsWith('Arrow')) { + changedThroughKeyboard.current = true; + } else { + changedThroughKeyboard.current = false; + } + }; + + return ( + + + {Number(value)} + + ); +} + +export function renderRating(params: GridRenderCellParams) { + if (params.value == null) { + return ''; + } + + return ; +} + +export function renderEditRating(params: GridRenderEditCellParams) { + return ; +} diff --git a/docs/data/data-grid/custom-columns/renderers/sparkline.tsx b/docs/data/data-grid/custom-columns/renderers/sparkline.tsx new file mode 100644 index 0000000000000..a2ed4d4efcff8 --- /dev/null +++ b/docs/data/data-grid/custom-columns/renderers/sparkline.tsx @@ -0,0 +1,16 @@ +import { SparkLineChart } from '@mui/x-charts/SparkLineChart'; +import { GridRenderCellParams } from '@mui/x-data-grid'; + +export function renderSparkline(params: GridRenderCellParams) { + if (params.value == null) { + return ''; + } + + return ( + + ); +} diff --git a/docs/data/data-grid/custom-columns/renderers/status.tsx b/docs/data/data-grid/custom-columns/renderers/status.tsx new file mode 100644 index 0000000000000..c4600eaee3fd4 --- /dev/null +++ b/docs/data/data-grid/custom-columns/renderers/status.tsx @@ -0,0 +1,164 @@ +import * as React from 'react'; +import { + Chip, + ListItemIcon, + ListItemText, + MenuItem, + MenuProps, + Select, + SelectProps, + styled, +} from '@mui/material'; +import ReportProblemIcon from '@mui/icons-material/ReportProblem'; +import InfoIcon from '@mui/icons-material/Info'; +import AutorenewIcon from '@mui/icons-material/Autorenew'; +import DoneIcon from '@mui/icons-material/Done'; +import { + GridEditModes, + GridRenderCellParams, + GridRenderEditCellParams, + useGridApiContext, + useGridRootProps, +} from '@mui/x-data-grid'; +import { STATUS_OPTIONS } from '@mui/x-data-grid-generator/services/static-data'; + +interface StatusProps { + status: string; +} + +const StyledChip = styled(Chip)(({ theme }) => ({ + justifyContent: 'left', + '& .icon': { + color: 'inherit', + }, + '&.Open': { + color: (theme.vars || theme).palette.info.dark, + border: `1px solid ${(theme.vars || theme).palette.info.main}`, + }, + '&.Filled': { + color: (theme.vars || theme).palette.success.dark, + border: `1px solid ${(theme.vars || theme).palette.success.main}`, + }, + '&.PartiallyFilled': { + color: (theme.vars || theme).palette.warning.dark, + border: `1px solid ${(theme.vars || theme).palette.warning.main}`, + }, + '&.Rejected': { + color: (theme.vars || theme).palette.error.dark, + border: `1px solid ${(theme.vars || theme).palette.error.main}`, + }, +})); + +const Status = React.memo((props: StatusProps) => { + const { status } = props; + + let icon: any = null; + if (status === 'Rejected') { + icon = ; + } else if (status === 'Open') { + icon = ; + } else if (status === 'PartiallyFilled') { + icon = ; + } else if (status === 'Filled') { + icon = ; + } + + let label: string = status; + if (status === 'PartiallyFilled') { + label = 'Partially Filled'; + } + + return ( + + ); +}); + +function EditStatus(props: GridRenderEditCellParams) { + const { id, value, field } = props; + const rootProps = useGridRootProps(); + const apiRef = useGridApiContext(); + + const handleChange: SelectProps['onChange'] = async (event) => { + const isValid = await apiRef.current.setEditCellValue({ + id, + field, + value: event.target.value, + }); + + if (isValid && rootProps.editMode === GridEditModes.Cell) { + apiRef.current.stopCellEditMode({ id, field, cellToFocusAfter: 'below' }); + } + }; + + const handleClose: MenuProps['onClose'] = (event, reason) => { + if (reason === 'backdropClick') { + apiRef.current.stopCellEditMode({ id, field, ignoreModifications: true }); + } + }; + + return ( + + ); +} + +export function renderStatus(params: GridRenderCellParams) { + if (params.value == null) { + return ''; + } + + return ; +} + +export function renderEditStatus(params: GridRenderEditCellParams) { + return ; +} From 40db12b0b0227799bac8ce6d87728817774b2c63 Mon Sep 17 00:00:00 2001 From: Armin Mehinovic Date: Mon, 15 Jul 2024 10:21:08 +0200 Subject: [PATCH 08/21] Add transpiled files --- .../custom-columns/renderers/avatar.js | 13 ++ .../custom-columns/renderers/country.js | 126 ++++++++++++ .../custom-columns/renderers/email.js | 32 +++ .../custom-columns/renderers/incoterm.js | 96 +++++++++ .../custom-columns/renderers/progress.js | 182 ++++++++++++++++++ .../custom-columns/renderers/rating.js | 92 +++++++++ .../custom-columns/renderers/sparkline.js | 15 ++ .../custom-columns/renderers/status.js | 156 +++++++++++++++ 8 files changed, 712 insertions(+) create mode 100644 docs/data/data-grid/custom-columns/renderers/avatar.js create mode 100644 docs/data/data-grid/custom-columns/renderers/country.js create mode 100644 docs/data/data-grid/custom-columns/renderers/email.js create mode 100644 docs/data/data-grid/custom-columns/renderers/incoterm.js create mode 100644 docs/data/data-grid/custom-columns/renderers/progress.js create mode 100644 docs/data/data-grid/custom-columns/renderers/rating.js create mode 100644 docs/data/data-grid/custom-columns/renderers/sparkline.js create mode 100644 docs/data/data-grid/custom-columns/renderers/status.js diff --git a/docs/data/data-grid/custom-columns/renderers/avatar.js b/docs/data/data-grid/custom-columns/renderers/avatar.js new file mode 100644 index 0000000000000..b6b61f6cb4d01 --- /dev/null +++ b/docs/data/data-grid/custom-columns/renderers/avatar.js @@ -0,0 +1,13 @@ +import Avatar from '@mui/material/Avatar'; + +export function renderAvatar(params) { + if (params.value == null) { + return ''; + } + + return ( + + {params.value.name.toUpperCase().substring(0, 1)} + + ); +} diff --git a/docs/data/data-grid/custom-columns/renderers/country.js b/docs/data/data-grid/custom-columns/renderers/country.js new file mode 100644 index 0000000000000..4742179c31d73 --- /dev/null +++ b/docs/data/data-grid/custom-columns/renderers/country.js @@ -0,0 +1,126 @@ +import * as React from 'react'; +import { useGridApiContext } from '@mui/x-data-grid'; +import { COUNTRY_ISO_OPTIONS } from '@mui/x-data-grid-generator/services/static-data'; +import { + Autocomplete, + autocompleteClasses, + Box, + InputBase, + styled, +} from '@mui/material'; + +const Country = React.memo(function Country(props) { + const { value } = props; + + return ( + img': { + mr: 0.5, + flexShrink: 0, + width: '20px', + }, + }} + > + + + {value.label} + + + ); +}); + +const StyledAutocomplete = styled(Autocomplete)(({ theme }) => ({ + height: '100%', + [`& .${autocompleteClasses.inputRoot}`]: { + ...theme.typography.body2, + padding: '1px 0', + height: '100%', + '& input': { + padding: '0 16px', + height: '100%', + }, + }, +})); + +function EditCountry(props) { + const { id, value, field } = props; + + const apiRef = useGridApiContext(); + + const handleChange = React.useCallback( + async (event, newValue) => { + await apiRef.current.setEditCellValue({ id, field, value: newValue }, event); + apiRef.current.stopCellEditMode({ id, field }); + }, + [apiRef, field, id], + ); + + return ( + option.label} + autoHighlight + fullWidth + open + disableClearable + renderOption={(optionProps, option) => ( + img': { + mr: 1.5, + flexShrink: 0, + }, + }} + {...optionProps} + key={option.code} + > + + {option.label} + + )} + renderInput={(params) => ( + + )} + /> + ); +} + +export function renderCountry(params) { + if (params.value == null) { + return ''; + } + + return ; +} + +export function renderEditCountry(params) { + return ; +} diff --git a/docs/data/data-grid/custom-columns/renderers/email.js b/docs/data/data-grid/custom-columns/renderers/email.js new file mode 100644 index 0000000000000..d0de01a375c6b --- /dev/null +++ b/docs/data/data-grid/custom-columns/renderers/email.js @@ -0,0 +1,32 @@ +import * as React from 'react'; +import { styled } from '@mui/material'; + +const Link = styled('a')({ + textOverflow: 'ellipsis', + whiteSpace: 'nowrap', + overflow: 'hidden', + color: 'inherit', +}); + +const DemoLink = React.memo(function DemoLink(props) { + const handleClick = (event) => { + event.preventDefault(); + event.stopPropagation(); + }; + + return ( + + {props.children} + + ); +}); + +export function renderEmail(params) { + const email = params.value ?? ''; + + return ( + + {email} + + ); +} diff --git a/docs/data/data-grid/custom-columns/renderers/incoterm.js b/docs/data/data-grid/custom-columns/renderers/incoterm.js new file mode 100644 index 0000000000000..b6cf115bd960c --- /dev/null +++ b/docs/data/data-grid/custom-columns/renderers/incoterm.js @@ -0,0 +1,96 @@ +import * as React from 'react'; +import { + Box, + ListItemIcon, + ListItemText, + MenuItem, + Select, + Tooltip, +} from '@mui/material'; +import InfoIcon from '@mui/icons-material/Info'; +import { useGridApiContext } from '@mui/x-data-grid'; +import { INCOTERM_OPTIONS } from '@mui/x-data-grid-generator/services/static-data'; + +const Incoterm = React.memo(function Incoterm(props) { + const { value } = props; + + if (!value) { + return null; + } + + const valueStr = value.toString(); + const tooltip = valueStr.slice(valueStr.indexOf('(') + 1, valueStr.indexOf(')')); + const code = valueStr.slice(0, valueStr.indexOf('(')).trim(); + + return ( + + {code} + + + + + ); +}); + +function EditIncoterm(props) { + const { id, value, field } = props; + + const apiRef = useGridApiContext(); + + const handleChange = async (event) => { + await apiRef.current.setEditCellValue( + { id, field, value: event.target.value }, + event, + ); + apiRef.current.stopCellEditMode({ id, field }); + }; + + const handleClose = (event, reason) => { + if (reason === 'backdropClick') { + apiRef.current.stopCellEditMode({ id, field }); + } + }; + + return ( + + ); +} + +export function renderIncoterm(params) { + return ; +} + +export function renderEditIncoterm(params) { + return ; +} diff --git a/docs/data/data-grid/custom-columns/renderers/progress.js b/docs/data/data-grid/custom-columns/renderers/progress.js new file mode 100644 index 0000000000000..2d68ad9d3c095 --- /dev/null +++ b/docs/data/data-grid/custom-columns/renderers/progress.js @@ -0,0 +1,182 @@ +import * as React from 'react'; +import clsx from 'clsx'; +import { useGridApiContext } from '@mui/x-data-grid'; +import { + alpha, + debounce, + Slider, + sliderClasses, + styled, + Tooltip, +} from '@mui/material'; + +const Center = styled('div')({ + height: '100%', + display: 'flex', + alignItems: 'center', +}); + +const Element = styled('div')(({ theme }) => ({ + border: `1px solid ${(theme.vars || theme).palette.divider}`, + position: 'relative', + overflow: 'hidden', + width: '100%', + height: 26, + borderRadius: 2, +})); + +const Value = styled('div')({ + position: 'absolute', + lineHeight: '24px', + width: '100%', + display: 'flex', + justifyContent: 'center', +}); + +const Bar = styled('div')({ + height: '100%', + '&.low': { + backgroundColor: '#f44336', + }, + '&.medium': { + backgroundColor: '#efbb5aa3', + }, + '&.high': { + backgroundColor: '#088208a3', + }, +}); + +const ProgressBar = React.memo(function ProgressBar(props) { + const { value } = props; + const valueInPercent = value * 100; + + return ( + + {`${valueInPercent.toLocaleString()} %`} + = 30 && valueInPercent <= 70, + high: valueInPercent > 70, + })} + style={{ maxWidth: `${valueInPercent}%` }} + /> + + ); +}); + +const StyledSlider = styled(Slider)(({ theme }) => ({ + display: 'flex', + height: '100%', + width: '100%', + alignItems: 'center', + justifyContent: 'center', + padding: 0, + borderRadius: 0, + [`& .${sliderClasses.rail}`]: { + height: '100%', + backgroundColor: 'transparent', + }, + [`& .${sliderClasses.track}`]: { + height: '100%', + transition: theme.transitions.create('background-color', { + duration: theme.transitions.duration.shorter, + }), + '&.low': { + backgroundColor: '#f44336', + }, + '&.medium': { + backgroundColor: '#efbb5aa3', + }, + '&.high': { + backgroundColor: '#088208a3', + }, + }, + [`& .${sliderClasses.thumb}`]: { + height: '100%', + width: 5, + borderRadius: 0, + marginTop: 0, + backgroundColor: alpha('#000000', 0.2), + }, +})); + +const ValueLabelComponent = React.memo(function ValueLabelComponent(props) { + const { children, open, value } = props; + + return ( + + {children} + + ); +}); + +function EditProgress(props) { + const { id, value, field } = props; + const [valueState, setValueState] = React.useState(Number(value)); + + const apiRef = useGridApiContext(); + + const updateCellEditProps = React.useCallback( + (newValue) => { + apiRef.current.setEditCellValue({ id, field, value: newValue }); + }, + [apiRef, field, id], + ); + + const debouncedUpdateCellEditProps = React.useMemo( + () => debounce(updateCellEditProps, 60), + [updateCellEditProps], + ); + + const handleChange = (event, newValue) => { + setValueState(newValue); + debouncedUpdateCellEditProps(newValue); + }; + + React.useEffect(() => { + setValueState(Number(value)); + }, [value]); + + const handleRef = (element) => { + if (element) { + element.querySelector('[type="range"]').focus(); + } + }; + + return ( + = 0.3 && valueState <= 0.7, + high: valueState > 0.7, + }), + }} + value={valueState} + max={1} + step={0.00001} + onChange={handleChange} + components={{ ValueLabel: ValueLabelComponent }} + valueLabelDisplay="auto" + valueLabelFormat={(newValue) => `${(newValue * 100).toLocaleString()} %`} + /> + ); +} + +export function renderProgress(params) { + if (params.value == null) { + return ''; + } + + return ( +
+ +
+ ); +} + +export function renderEditProgress(params) { + return ; +} diff --git a/docs/data/data-grid/custom-columns/renderers/rating.js b/docs/data/data-grid/custom-columns/renderers/rating.js new file mode 100644 index 0000000000000..5485b67549165 --- /dev/null +++ b/docs/data/data-grid/custom-columns/renderers/rating.js @@ -0,0 +1,92 @@ +import * as React from 'react'; +import { Box, Rating } from '@mui/material'; +import { useGridApiContext } from '@mui/x-data-grid'; + +const RatingValue = React.memo(function RatingValue(props) { + const { value } = props; + return ( + + {' '} + {Math.round(Number(value) * 10) / 10} + + ); +}); + +function EditRating(props) { + const { id, value, field } = props; + + const apiRef = useGridApiContext(); + + const changedThroughKeyboard = React.useRef(false); + + const handleChange = async (event) => { + await apiRef.current.setEditCellValue( + { id, field, value: Number(event.target.value) }, + event, + ); + if (!changedThroughKeyboard.current) { + apiRef.current.stopCellEditMode({ id, field }); + } + changedThroughKeyboard.current = false; + }; + + const handleRef = (element) => { + if (element) { + if (value !== 0) { + element.querySelector(`input[value="${value}"]`).focus(); + } else { + element.querySelector('input[value=""]').focus(); + } + } + }; + + const handleKeyDown = (event) => { + if (event.key.startsWith('Arrow')) { + changedThroughKeyboard.current = true; + } else { + changedThroughKeyboard.current = false; + } + }; + + return ( + + + {Number(value)} + + ); +} + +export function renderRating(params) { + if (params.value == null) { + return ''; + } + + return ; +} + +export function renderEditRating(params) { + return ; +} diff --git a/docs/data/data-grid/custom-columns/renderers/sparkline.js b/docs/data/data-grid/custom-columns/renderers/sparkline.js new file mode 100644 index 0000000000000..274e62a17168f --- /dev/null +++ b/docs/data/data-grid/custom-columns/renderers/sparkline.js @@ -0,0 +1,15 @@ +import { SparkLineChart } from '@mui/x-charts/SparkLineChart'; + +export function renderSparkline(params) { + if (params.value == null) { + return ''; + } + + return ( + + ); +} diff --git a/docs/data/data-grid/custom-columns/renderers/status.js b/docs/data/data-grid/custom-columns/renderers/status.js new file mode 100644 index 0000000000000..2fa4af62db4a1 --- /dev/null +++ b/docs/data/data-grid/custom-columns/renderers/status.js @@ -0,0 +1,156 @@ +import * as React from 'react'; +import { + Chip, + ListItemIcon, + ListItemText, + MenuItem, + Select, + styled, +} from '@mui/material'; +import ReportProblemIcon from '@mui/icons-material/ReportProblem'; +import InfoIcon from '@mui/icons-material/Info'; +import AutorenewIcon from '@mui/icons-material/Autorenew'; +import DoneIcon from '@mui/icons-material/Done'; +import { + GridEditModes, + useGridApiContext, + useGridRootProps, +} from '@mui/x-data-grid'; +import { STATUS_OPTIONS } from '@mui/x-data-grid-generator/services/static-data'; + +const StyledChip = styled(Chip)(({ theme }) => ({ + justifyContent: 'left', + '& .icon': { + color: 'inherit', + }, + '&.Open': { + color: (theme.vars || theme).palette.info.dark, + border: `1px solid ${(theme.vars || theme).palette.info.main}`, + }, + '&.Filled': { + color: (theme.vars || theme).palette.success.dark, + border: `1px solid ${(theme.vars || theme).palette.success.main}`, + }, + '&.PartiallyFilled': { + color: (theme.vars || theme).palette.warning.dark, + border: `1px solid ${(theme.vars || theme).palette.warning.main}`, + }, + '&.Rejected': { + color: (theme.vars || theme).palette.error.dark, + border: `1px solid ${(theme.vars || theme).palette.error.main}`, + }, +})); + +const Status = React.memo((props) => { + const { status } = props; + + let icon = null; + if (status === 'Rejected') { + icon = ; + } else if (status === 'Open') { + icon = ; + } else if (status === 'PartiallyFilled') { + icon = ; + } else if (status === 'Filled') { + icon = ; + } + + let label = status; + if (status === 'PartiallyFilled') { + label = 'Partially Filled'; + } + + return ( + + ); +}); + +function EditStatus(props) { + const { id, value, field } = props; + const rootProps = useGridRootProps(); + const apiRef = useGridApiContext(); + + const handleChange = async (event) => { + const isValid = await apiRef.current.setEditCellValue({ + id, + field, + value: event.target.value, + }); + + if (isValid && rootProps.editMode === GridEditModes.Cell) { + apiRef.current.stopCellEditMode({ id, field, cellToFocusAfter: 'below' }); + } + }; + + const handleClose = (event, reason) => { + if (reason === 'backdropClick') { + apiRef.current.stopCellEditMode({ id, field, ignoreModifications: true }); + } + }; + + return ( + + ); +} + +export function renderStatus(params) { + if (params.value == null) { + return ''; + } + + return ; +} + +export function renderEditStatus(params) { + return ; +} From 31345399fd6f71f1bd4a6255c672e0d8be01235e Mon Sep 17 00:00:00 2001 From: Armin Mehinovic Date: Mon, 15 Jul 2024 10:52:39 +0200 Subject: [PATCH 09/21] Fix lint issues --- docs/data/data-grid/custom-columns/renderers/avatar.js | 1 + docs/data/data-grid/custom-columns/renderers/avatar.tsx | 1 + docs/data/data-grid/custom-columns/renderers/sparkline.js | 1 + docs/data/data-grid/custom-columns/renderers/sparkline.tsx | 1 + 4 files changed, 4 insertions(+) diff --git a/docs/data/data-grid/custom-columns/renderers/avatar.js b/docs/data/data-grid/custom-columns/renderers/avatar.js index b6b61f6cb4d01..a928435e763ce 100644 --- a/docs/data/data-grid/custom-columns/renderers/avatar.js +++ b/docs/data/data-grid/custom-columns/renderers/avatar.js @@ -1,3 +1,4 @@ +import * as React from 'react'; import Avatar from '@mui/material/Avatar'; export function renderAvatar(params) { diff --git a/docs/data/data-grid/custom-columns/renderers/avatar.tsx b/docs/data/data-grid/custom-columns/renderers/avatar.tsx index affcb69456ae0..e2f1f5b5b1a99 100644 --- a/docs/data/data-grid/custom-columns/renderers/avatar.tsx +++ b/docs/data/data-grid/custom-columns/renderers/avatar.tsx @@ -1,3 +1,4 @@ +import * as React from 'react'; import Avatar from '@mui/material/Avatar'; import { GridRenderCellParams } from '@mui/x-data-grid'; diff --git a/docs/data/data-grid/custom-columns/renderers/sparkline.js b/docs/data/data-grid/custom-columns/renderers/sparkline.js index 274e62a17168f..b6b083cf7b549 100644 --- a/docs/data/data-grid/custom-columns/renderers/sparkline.js +++ b/docs/data/data-grid/custom-columns/renderers/sparkline.js @@ -1,3 +1,4 @@ +import * as React from 'react'; import { SparkLineChart } from '@mui/x-charts/SparkLineChart'; export function renderSparkline(params) { diff --git a/docs/data/data-grid/custom-columns/renderers/sparkline.tsx b/docs/data/data-grid/custom-columns/renderers/sparkline.tsx index a2ed4d4efcff8..c5e44fa6c8858 100644 --- a/docs/data/data-grid/custom-columns/renderers/sparkline.tsx +++ b/docs/data/data-grid/custom-columns/renderers/sparkline.tsx @@ -1,3 +1,4 @@ +import * as React from 'react'; import { SparkLineChart } from '@mui/x-charts/SparkLineChart'; import { GridRenderCellParams } from '@mui/x-data-grid'; From 05132a9b15dc5beb05485e7f8225801899a93ce1 Mon Sep 17 00:00:00 2001 From: Armin Mehinovic Date: Mon, 22 Jul 2024 13:40:06 +0200 Subject: [PATCH 10/21] Move custom cell renderers outside of the data grid docs folder --- .../grid-cell-renderers}/avatar.js | 0 .../grid-cell-renderers}/avatar.tsx | 0 .../grid-cell-renderers}/country.js | 0 .../grid-cell-renderers}/country.tsx | 0 .../grid-cell-renderers}/email.js | 0 .../grid-cell-renderers}/email.tsx | 0 .../grid-cell-renderers}/incoterm.js | 0 .../grid-cell-renderers}/incoterm.tsx | 0 .../grid-cell-renderers}/progress.js | 0 .../grid-cell-renderers}/progress.tsx | 0 .../grid-cell-renderers}/rating.js | 0 .../grid-cell-renderers}/rating.tsx | 0 .../grid-cell-renderers}/sparkline.js | 0 .../grid-cell-renderers}/sparkline.tsx | 0 .../grid-cell-renderers}/status.js | 0 .../grid-cell-renderers}/status.tsx | 0 .../custom-columns/CustomColumnFullExample.js | 31 ++++++++++++++----- .../CustomColumnFullExample.tsx | 31 ++++++++++++++----- 18 files changed, 46 insertions(+), 16 deletions(-) rename docs/data/{data-grid/custom-columns/renderers => components/grid-cell-renderers}/avatar.js (100%) rename docs/data/{data-grid/custom-columns/renderers => components/grid-cell-renderers}/avatar.tsx (100%) rename docs/data/{data-grid/custom-columns/renderers => components/grid-cell-renderers}/country.js (100%) rename docs/data/{data-grid/custom-columns/renderers => components/grid-cell-renderers}/country.tsx (100%) rename docs/data/{data-grid/custom-columns/renderers => components/grid-cell-renderers}/email.js (100%) rename docs/data/{data-grid/custom-columns/renderers => components/grid-cell-renderers}/email.tsx (100%) rename docs/data/{data-grid/custom-columns/renderers => components/grid-cell-renderers}/incoterm.js (100%) rename docs/data/{data-grid/custom-columns/renderers => components/grid-cell-renderers}/incoterm.tsx (100%) rename docs/data/{data-grid/custom-columns/renderers => components/grid-cell-renderers}/progress.js (100%) rename docs/data/{data-grid/custom-columns/renderers => components/grid-cell-renderers}/progress.tsx (100%) rename docs/data/{data-grid/custom-columns/renderers => components/grid-cell-renderers}/rating.js (100%) rename docs/data/{data-grid/custom-columns/renderers => components/grid-cell-renderers}/rating.tsx (100%) rename docs/data/{data-grid/custom-columns/renderers => components/grid-cell-renderers}/sparkline.js (100%) rename docs/data/{data-grid/custom-columns/renderers => components/grid-cell-renderers}/sparkline.tsx (100%) rename docs/data/{data-grid/custom-columns/renderers => components/grid-cell-renderers}/status.js (100%) rename docs/data/{data-grid/custom-columns/renderers => components/grid-cell-renderers}/status.tsx (100%) diff --git a/docs/data/data-grid/custom-columns/renderers/avatar.js b/docs/data/components/grid-cell-renderers/avatar.js similarity index 100% rename from docs/data/data-grid/custom-columns/renderers/avatar.js rename to docs/data/components/grid-cell-renderers/avatar.js diff --git a/docs/data/data-grid/custom-columns/renderers/avatar.tsx b/docs/data/components/grid-cell-renderers/avatar.tsx similarity index 100% rename from docs/data/data-grid/custom-columns/renderers/avatar.tsx rename to docs/data/components/grid-cell-renderers/avatar.tsx diff --git a/docs/data/data-grid/custom-columns/renderers/country.js b/docs/data/components/grid-cell-renderers/country.js similarity index 100% rename from docs/data/data-grid/custom-columns/renderers/country.js rename to docs/data/components/grid-cell-renderers/country.js diff --git a/docs/data/data-grid/custom-columns/renderers/country.tsx b/docs/data/components/grid-cell-renderers/country.tsx similarity index 100% rename from docs/data/data-grid/custom-columns/renderers/country.tsx rename to docs/data/components/grid-cell-renderers/country.tsx diff --git a/docs/data/data-grid/custom-columns/renderers/email.js b/docs/data/components/grid-cell-renderers/email.js similarity index 100% rename from docs/data/data-grid/custom-columns/renderers/email.js rename to docs/data/components/grid-cell-renderers/email.js diff --git a/docs/data/data-grid/custom-columns/renderers/email.tsx b/docs/data/components/grid-cell-renderers/email.tsx similarity index 100% rename from docs/data/data-grid/custom-columns/renderers/email.tsx rename to docs/data/components/grid-cell-renderers/email.tsx diff --git a/docs/data/data-grid/custom-columns/renderers/incoterm.js b/docs/data/components/grid-cell-renderers/incoterm.js similarity index 100% rename from docs/data/data-grid/custom-columns/renderers/incoterm.js rename to docs/data/components/grid-cell-renderers/incoterm.js diff --git a/docs/data/data-grid/custom-columns/renderers/incoterm.tsx b/docs/data/components/grid-cell-renderers/incoterm.tsx similarity index 100% rename from docs/data/data-grid/custom-columns/renderers/incoterm.tsx rename to docs/data/components/grid-cell-renderers/incoterm.tsx diff --git a/docs/data/data-grid/custom-columns/renderers/progress.js b/docs/data/components/grid-cell-renderers/progress.js similarity index 100% rename from docs/data/data-grid/custom-columns/renderers/progress.js rename to docs/data/components/grid-cell-renderers/progress.js diff --git a/docs/data/data-grid/custom-columns/renderers/progress.tsx b/docs/data/components/grid-cell-renderers/progress.tsx similarity index 100% rename from docs/data/data-grid/custom-columns/renderers/progress.tsx rename to docs/data/components/grid-cell-renderers/progress.tsx diff --git a/docs/data/data-grid/custom-columns/renderers/rating.js b/docs/data/components/grid-cell-renderers/rating.js similarity index 100% rename from docs/data/data-grid/custom-columns/renderers/rating.js rename to docs/data/components/grid-cell-renderers/rating.js diff --git a/docs/data/data-grid/custom-columns/renderers/rating.tsx b/docs/data/components/grid-cell-renderers/rating.tsx similarity index 100% rename from docs/data/data-grid/custom-columns/renderers/rating.tsx rename to docs/data/components/grid-cell-renderers/rating.tsx diff --git a/docs/data/data-grid/custom-columns/renderers/sparkline.js b/docs/data/components/grid-cell-renderers/sparkline.js similarity index 100% rename from docs/data/data-grid/custom-columns/renderers/sparkline.js rename to docs/data/components/grid-cell-renderers/sparkline.js diff --git a/docs/data/data-grid/custom-columns/renderers/sparkline.tsx b/docs/data/components/grid-cell-renderers/sparkline.tsx similarity index 100% rename from docs/data/data-grid/custom-columns/renderers/sparkline.tsx rename to docs/data/components/grid-cell-renderers/sparkline.tsx diff --git a/docs/data/data-grid/custom-columns/renderers/status.js b/docs/data/components/grid-cell-renderers/status.js similarity index 100% rename from docs/data/data-grid/custom-columns/renderers/status.js rename to docs/data/components/grid-cell-renderers/status.js diff --git a/docs/data/data-grid/custom-columns/renderers/status.tsx b/docs/data/components/grid-cell-renderers/status.tsx similarity index 100% rename from docs/data/data-grid/custom-columns/renderers/status.tsx rename to docs/data/components/grid-cell-renderers/status.tsx diff --git a/docs/data/data-grid/custom-columns/CustomColumnFullExample.js b/docs/data/data-grid/custom-columns/CustomColumnFullExample.js index 982bccba39f2d..d299a21974e11 100644 --- a/docs/data/data-grid/custom-columns/CustomColumnFullExample.js +++ b/docs/data/data-grid/custom-columns/CustomColumnFullExample.js @@ -16,14 +16,29 @@ import { STATUS_OPTIONS, } from '@mui/x-data-grid-generator/services/static-data'; import { DataGrid, gridStringOrNumberComparator } from '@mui/x-data-grid'; -import { renderAvatar } from './renderers/avatar'; -import { renderEmail } from './renderers/email'; -import { renderEditRating, renderRating } from './renderers/rating'; -import { renderCountry, renderEditCountry } from './renderers/country'; -import { renderSparkline } from './renderers/sparkline'; -import { renderEditProgress, renderProgress } from './renderers/progress'; -import { renderEditStatus, renderStatus } from './renderers/status'; -import { renderEditIncoterm, renderIncoterm } from './renderers/incoterm'; +import { renderAvatar } from '../../components/grid-cell-renderers/avatar'; +import { renderEmail } from '../../components/grid-cell-renderers/email'; +import { + renderEditRating, + renderRating, +} from '../../components/grid-cell-renderers/rating'; +import { + renderCountry, + renderEditCountry, +} from '../../components/grid-cell-renderers/country'; +import { renderSparkline } from '../../components/grid-cell-renderers/sparkline'; +import { + renderEditProgress, + renderProgress, +} from '../../components/grid-cell-renderers/progress'; +import { + renderEditStatus, + renderStatus, +} from '../../components/grid-cell-renderers/status'; +import { + renderEditIncoterm, + renderIncoterm, +} from '../../components/grid-cell-renderers/incoterm'; const columns = [ { diff --git a/docs/data/data-grid/custom-columns/CustomColumnFullExample.tsx b/docs/data/data-grid/custom-columns/CustomColumnFullExample.tsx index c89c88f89a714..74043f1fa5a7b 100644 --- a/docs/data/data-grid/custom-columns/CustomColumnFullExample.tsx +++ b/docs/data/data-grid/custom-columns/CustomColumnFullExample.tsx @@ -21,14 +21,29 @@ import { GridColDef, gridStringOrNumberComparator, } from '@mui/x-data-grid'; -import { renderAvatar } from './renderers/avatar'; -import { renderEmail } from './renderers/email'; -import { renderEditRating, renderRating } from './renderers/rating'; -import { renderCountry, renderEditCountry } from './renderers/country'; -import { renderSparkline } from './renderers/sparkline'; -import { renderEditProgress, renderProgress } from './renderers/progress'; -import { renderEditStatus, renderStatus } from './renderers/status'; -import { renderEditIncoterm, renderIncoterm } from './renderers/incoterm'; +import { renderAvatar } from '../../components/grid-cell-renderers/avatar'; +import { renderEmail } from '../../components/grid-cell-renderers/email'; +import { + renderEditRating, + renderRating, +} from '../../components/grid-cell-renderers/rating'; +import { + renderCountry, + renderEditCountry, +} from '../../components/grid-cell-renderers/country'; +import { renderSparkline } from '../../components/grid-cell-renderers/sparkline'; +import { + renderEditProgress, + renderProgress, +} from '../../components/grid-cell-renderers/progress'; +import { + renderEditStatus, + renderStatus, +} from '../../components/grid-cell-renderers/status'; +import { + renderEditIncoterm, + renderIncoterm, +} from '../../components/grid-cell-renderers/incoterm'; const columns: GridColDef<(typeof rows)[number]>[] = [ { From f7114db5c41b6565d3ed2341cd5716956633ebbd Mon Sep 17 00:00:00 2001 From: Armin Mehinovic Date: Mon, 22 Jul 2024 13:40:33 +0200 Subject: [PATCH 11/21] Ignore components folder in regression tests --- test/regressions/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/test/regressions/index.js b/test/regressions/index.js index c444cbddd7472..245bbcea7b131 100644 --- a/test/regressions/index.js +++ b/test/regressions/index.js @@ -14,6 +14,7 @@ Globals.assign({ const blacklist = [ /^docs-(.*)(?<=NoSnap)\.png$/, // Excludes demos that we don't want + /^docs-components-(.*)\.png$/, // Custom components used to build docs pages 'docs-data-grid-filtering/RemoveBuiltInOperators.png', // Needs interaction 'docs-data-grid-filtering/CustomRatingOperator.png', // Needs interaction 'docs-data-grid-filtering/CustomInputComponent.png', // Needs interaction From 2385b249a519178ef88a4db40fa11f96df3a3c12 Mon Sep 17 00:00:00 2001 From: Andrew Cherniavskyi Date: Tue, 27 Aug 2024 17:47:33 +0200 Subject: [PATCH 12/21] lint --- .../components/grid-cell-renderers/country.js | 12 +++++------- .../components/grid-cell-renderers/country.tsx | 13 +++++-------- .../components/grid-cell-renderers/email.js | 2 +- .../components/grid-cell-renderers/email.tsx | 2 +- .../components/grid-cell-renderers/incoterm.js | 15 +++++++-------- .../components/grid-cell-renderers/incoterm.tsx | 17 +++++++---------- .../components/grid-cell-renderers/progress.js | 12 ++++-------- .../components/grid-cell-renderers/progress.tsx | 13 ++++--------- .../components/grid-cell-renderers/rating.js | 3 ++- .../components/grid-cell-renderers/rating.tsx | 3 ++- .../components/grid-cell-renderers/status.js | 15 +++++++-------- .../components/grid-cell-renderers/status.tsx | 17 +++++++---------- 12 files changed, 52 insertions(+), 72 deletions(-) diff --git a/docs/data/components/grid-cell-renderers/country.js b/docs/data/components/grid-cell-renderers/country.js index 4742179c31d73..be792098f2213 100644 --- a/docs/data/components/grid-cell-renderers/country.js +++ b/docs/data/components/grid-cell-renderers/country.js @@ -1,13 +1,11 @@ import * as React from 'react'; import { useGridApiContext } from '@mui/x-data-grid'; import { COUNTRY_ISO_OPTIONS } from '@mui/x-data-grid-generator/services/static-data'; -import { - Autocomplete, - autocompleteClasses, - Box, - InputBase, - styled, -} from '@mui/material'; +import Autocomplete, { autocompleteClasses } from '@mui/material/Autocomplete'; + +import Box from '@mui/material/Box'; +import InputBase from '@mui/material/InputBase'; +import styled from '@mui/material/styles'; const Country = React.memo(function Country(props) { const { value } = props; diff --git a/docs/data/components/grid-cell-renderers/country.tsx b/docs/data/components/grid-cell-renderers/country.tsx index 7f92cb9664ed2..fd64bd4e38fba 100644 --- a/docs/data/components/grid-cell-renderers/country.tsx +++ b/docs/data/components/grid-cell-renderers/country.tsx @@ -8,14 +8,11 @@ import { COUNTRY_ISO_OPTIONS, CountryIsoOption, } from '@mui/x-data-grid-generator/services/static-data'; -import { - Autocomplete, - autocompleteClasses, - AutocompleteProps, - Box, - InputBase, - styled, -} from '@mui/material'; +import Autocomplete, { autocompleteClasses } from '@mui/material/Autocomplete'; +import type { AutocompleteProps } from '@mui/material/Autocomplete'; +import Box from '@mui/material/Box'; +import InputBase from '@mui/material/InputBase'; +import styled from '@mui/material/styles'; interface CountryProps { value: CountryIsoOption; diff --git a/docs/data/components/grid-cell-renderers/email.js b/docs/data/components/grid-cell-renderers/email.js index d0de01a375c6b..a80f6c387fba8 100644 --- a/docs/data/components/grid-cell-renderers/email.js +++ b/docs/data/components/grid-cell-renderers/email.js @@ -1,5 +1,5 @@ import * as React from 'react'; -import { styled } from '@mui/material'; +import { styled } from '@mui/material/styles'; const Link = styled('a')({ textOverflow: 'ellipsis', diff --git a/docs/data/components/grid-cell-renderers/email.tsx b/docs/data/components/grid-cell-renderers/email.tsx index 609ea2c818519..e58fc5d782614 100644 --- a/docs/data/components/grid-cell-renderers/email.tsx +++ b/docs/data/components/grid-cell-renderers/email.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { styled } from '@mui/material'; +import { styled } from '@mui/material/styles'; import { GridRenderCellParams } from '@mui/x-data-grid'; interface DemoLinkProps { diff --git a/docs/data/components/grid-cell-renderers/incoterm.js b/docs/data/components/grid-cell-renderers/incoterm.js index b6cf115bd960c..070d14be6af80 100644 --- a/docs/data/components/grid-cell-renderers/incoterm.js +++ b/docs/data/components/grid-cell-renderers/incoterm.js @@ -1,12 +1,11 @@ import * as React from 'react'; -import { - Box, - ListItemIcon, - ListItemText, - MenuItem, - Select, - Tooltip, -} from '@mui/material'; +import Box from '@mui/material/Box'; +import ListItemIcon from '@mui/material/ListItemIcon'; +import ListItemText from '@mui/material/ListItemText'; +import MenuItem from '@mui/material/MenuItem'; + +import Select from '@mui/material/Select'; +import Tooltip from '@mui/material/Tooltip'; import InfoIcon from '@mui/icons-material/Info'; import { useGridApiContext } from '@mui/x-data-grid'; import { INCOTERM_OPTIONS } from '@mui/x-data-grid-generator/services/static-data'; diff --git a/docs/data/components/grid-cell-renderers/incoterm.tsx b/docs/data/components/grid-cell-renderers/incoterm.tsx index 0d2b83821737b..652544a698011 100644 --- a/docs/data/components/grid-cell-renderers/incoterm.tsx +++ b/docs/data/components/grid-cell-renderers/incoterm.tsx @@ -1,14 +1,11 @@ import * as React from 'react'; -import { - Box, - ListItemIcon, - ListItemText, - MenuItem, - MenuProps, - Select, - SelectProps, - Tooltip, -} from '@mui/material'; +import Box from '@mui/material/Box'; +import ListItemIcon from '@mui/material/ListItemIcon'; +import ListItemText from '@mui/material/ListItemText'; +import MenuItem from '@mui/material/MenuItem'; +import type { MenuProps } from '@mui/material/Menu'; +import Select, { SelectProps } from '@mui/material/Select'; +import Tooltip from '@mui/material/Tooltip'; import InfoIcon from '@mui/icons-material/Info'; import { GridRenderCellParams, diff --git a/docs/data/components/grid-cell-renderers/progress.js b/docs/data/components/grid-cell-renderers/progress.js index 2d68ad9d3c095..d604aaca719af 100644 --- a/docs/data/components/grid-cell-renderers/progress.js +++ b/docs/data/components/grid-cell-renderers/progress.js @@ -1,14 +1,10 @@ import * as React from 'react'; import clsx from 'clsx'; import { useGridApiContext } from '@mui/x-data-grid'; -import { - alpha, - debounce, - Slider, - sliderClasses, - styled, - Tooltip, -} from '@mui/material'; +import { alpha, styled } from '@mui/material/styles'; +import Slider, { sliderClasses } from '@mui/material/Slider'; +import Tooltip from '@mui/material/Tooltip'; +import { debounce } from '@mui/material/utils'; const Center = styled('div')({ height: '100%', diff --git a/docs/data/components/grid-cell-renderers/progress.tsx b/docs/data/components/grid-cell-renderers/progress.tsx index b0495a50a3737..a831d003ff58e 100644 --- a/docs/data/components/grid-cell-renderers/progress.tsx +++ b/docs/data/components/grid-cell-renderers/progress.tsx @@ -5,15 +5,10 @@ import { GridRenderEditCellParams, useGridApiContext, } from '@mui/x-data-grid'; -import { - alpha, - debounce, - Slider, - sliderClasses, - SliderProps, - styled, - Tooltip, -} from '@mui/material'; +import { alpha, styled } from '@mui/material/styles'; +import Slider, { sliderClasses, SliderProps } from '@mui/material/Slider'; +import Tooltip from '@mui/material/Tooltip'; +import { debounce } from '@mui/material/utils'; interface ProgressBarProps { value: number; diff --git a/docs/data/components/grid-cell-renderers/rating.js b/docs/data/components/grid-cell-renderers/rating.js index 5485b67549165..46d1d09ea7516 100644 --- a/docs/data/components/grid-cell-renderers/rating.js +++ b/docs/data/components/grid-cell-renderers/rating.js @@ -1,5 +1,6 @@ import * as React from 'react'; -import { Box, Rating } from '@mui/material'; +import Box from '@mui/material/Box'; +import Rating from '@mui/material/Rating'; import { useGridApiContext } from '@mui/x-data-grid'; const RatingValue = React.memo(function RatingValue(props) { diff --git a/docs/data/components/grid-cell-renderers/rating.tsx b/docs/data/components/grid-cell-renderers/rating.tsx index 56372ced407e8..9eb9c68ce767d 100644 --- a/docs/data/components/grid-cell-renderers/rating.tsx +++ b/docs/data/components/grid-cell-renderers/rating.tsx @@ -1,5 +1,6 @@ import * as React from 'react'; -import { Box, Rating } from '@mui/material'; +import Box from '@mui/material/Box'; +import Rating from '@mui/material/Rating'; import { GridRenderCellParams, GridRenderEditCellParams, diff --git a/docs/data/components/grid-cell-renderers/status.js b/docs/data/components/grid-cell-renderers/status.js index 2fa4af62db4a1..edc6837b1bb89 100644 --- a/docs/data/components/grid-cell-renderers/status.js +++ b/docs/data/components/grid-cell-renderers/status.js @@ -1,12 +1,11 @@ import * as React from 'react'; -import { - Chip, - ListItemIcon, - ListItemText, - MenuItem, - Select, - styled, -} from '@mui/material'; +import Chip from '@mui/material/Chip'; +import ListItemIcon from '@mui/material/ListItemIcon'; +import ListItemText from '@mui/material/ListItemText'; +import MenuItem from '@mui/material/MenuItem'; + +import Select from '@mui/material/Select'; +import styled from '@mui/system/styled'; import ReportProblemIcon from '@mui/icons-material/ReportProblem'; import InfoIcon from '@mui/icons-material/Info'; import AutorenewIcon from '@mui/icons-material/Autorenew'; diff --git a/docs/data/components/grid-cell-renderers/status.tsx b/docs/data/components/grid-cell-renderers/status.tsx index c4600eaee3fd4..49c41c18bd921 100644 --- a/docs/data/components/grid-cell-renderers/status.tsx +++ b/docs/data/components/grid-cell-renderers/status.tsx @@ -1,14 +1,11 @@ import * as React from 'react'; -import { - Chip, - ListItemIcon, - ListItemText, - MenuItem, - MenuProps, - Select, - SelectProps, - styled, -} from '@mui/material'; +import Chip from '@mui/material/Chip'; +import ListItemIcon from '@mui/material/ListItemIcon'; +import ListItemText from '@mui/material/ListItemText'; +import MenuItem from '@mui/material/MenuItem'; +import type { MenuProps } from '@mui/material/Menu'; +import Select, { SelectProps } from '@mui/material/Select'; +import styled from '@mui/system/styled'; import ReportProblemIcon from '@mui/icons-material/ReportProblem'; import InfoIcon from '@mui/icons-material/Info'; import AutorenewIcon from '@mui/icons-material/Autorenew'; From 2a22719d22e033ca7a1c4314211b317f84f74521 Mon Sep 17 00:00:00 2001 From: Andrew Cherniavskyi Date: Tue, 27 Aug 2024 17:49:52 +0200 Subject: [PATCH 13/21] lint --- docs/data/components/grid-cell-renderers/country.js | 4 ++-- docs/data/components/grid-cell-renderers/country.tsx | 4 ++-- docs/data/components/grid-cell-renderers/incoterm.js | 2 +- docs/data/components/grid-cell-renderers/incoterm.tsx | 2 +- docs/data/components/grid-cell-renderers/status.js | 4 ++-- docs/data/components/grid-cell-renderers/status.tsx | 4 ++-- packages/x-data-grid-generator/src/services/index.ts | 1 + 7 files changed, 11 insertions(+), 10 deletions(-) diff --git a/docs/data/components/grid-cell-renderers/country.js b/docs/data/components/grid-cell-renderers/country.js index be792098f2213..1c75b2bb86250 100644 --- a/docs/data/components/grid-cell-renderers/country.js +++ b/docs/data/components/grid-cell-renderers/country.js @@ -1,11 +1,11 @@ import * as React from 'react'; import { useGridApiContext } from '@mui/x-data-grid'; -import { COUNTRY_ISO_OPTIONS } from '@mui/x-data-grid-generator/services/static-data'; +import { COUNTRY_ISO_OPTIONS } from '@mui/x-data-grid-generator/services'; import Autocomplete, { autocompleteClasses } from '@mui/material/Autocomplete'; import Box from '@mui/material/Box'; import InputBase from '@mui/material/InputBase'; -import styled from '@mui/material/styles'; +import { styled } from '@mui/material/styles'; const Country = React.memo(function Country(props) { const { value } = props; diff --git a/docs/data/components/grid-cell-renderers/country.tsx b/docs/data/components/grid-cell-renderers/country.tsx index fd64bd4e38fba..dadda0be171b9 100644 --- a/docs/data/components/grid-cell-renderers/country.tsx +++ b/docs/data/components/grid-cell-renderers/country.tsx @@ -7,12 +7,12 @@ import { import { COUNTRY_ISO_OPTIONS, CountryIsoOption, -} from '@mui/x-data-grid-generator/services/static-data'; +} from '@mui/x-data-grid-generator/services'; import Autocomplete, { autocompleteClasses } from '@mui/material/Autocomplete'; import type { AutocompleteProps } from '@mui/material/Autocomplete'; import Box from '@mui/material/Box'; import InputBase from '@mui/material/InputBase'; -import styled from '@mui/material/styles'; +import { styled } from '@mui/material/styles'; interface CountryProps { value: CountryIsoOption; diff --git a/docs/data/components/grid-cell-renderers/incoterm.js b/docs/data/components/grid-cell-renderers/incoterm.js index 070d14be6af80..2ca0824517e66 100644 --- a/docs/data/components/grid-cell-renderers/incoterm.js +++ b/docs/data/components/grid-cell-renderers/incoterm.js @@ -8,7 +8,7 @@ import Select from '@mui/material/Select'; import Tooltip from '@mui/material/Tooltip'; import InfoIcon from '@mui/icons-material/Info'; import { useGridApiContext } from '@mui/x-data-grid'; -import { INCOTERM_OPTIONS } from '@mui/x-data-grid-generator/services/static-data'; +import { INCOTERM_OPTIONS } from '@mui/x-data-grid-generator/services'; const Incoterm = React.memo(function Incoterm(props) { const { value } = props; diff --git a/docs/data/components/grid-cell-renderers/incoterm.tsx b/docs/data/components/grid-cell-renderers/incoterm.tsx index 652544a698011..ce20112a6d036 100644 --- a/docs/data/components/grid-cell-renderers/incoterm.tsx +++ b/docs/data/components/grid-cell-renderers/incoterm.tsx @@ -12,7 +12,7 @@ import { GridRenderEditCellParams, useGridApiContext, } from '@mui/x-data-grid'; -import { INCOTERM_OPTIONS } from '@mui/x-data-grid-generator/services/static-data'; +import { INCOTERM_OPTIONS } from '@mui/x-data-grid-generator/services'; interface IncotermProps { value: string | null | undefined; diff --git a/docs/data/components/grid-cell-renderers/status.js b/docs/data/components/grid-cell-renderers/status.js index edc6837b1bb89..7aaa493f818a0 100644 --- a/docs/data/components/grid-cell-renderers/status.js +++ b/docs/data/components/grid-cell-renderers/status.js @@ -5,7 +5,7 @@ import ListItemText from '@mui/material/ListItemText'; import MenuItem from '@mui/material/MenuItem'; import Select from '@mui/material/Select'; -import styled from '@mui/system/styled'; +import { styled } from '@mui/material/styles'; import ReportProblemIcon from '@mui/icons-material/ReportProblem'; import InfoIcon from '@mui/icons-material/Info'; import AutorenewIcon from '@mui/icons-material/Autorenew'; @@ -15,7 +15,7 @@ import { useGridApiContext, useGridRootProps, } from '@mui/x-data-grid'; -import { STATUS_OPTIONS } from '@mui/x-data-grid-generator/services/static-data'; +import { STATUS_OPTIONS } from '@mui/x-data-grid-generator/services'; const StyledChip = styled(Chip)(({ theme }) => ({ justifyContent: 'left', diff --git a/docs/data/components/grid-cell-renderers/status.tsx b/docs/data/components/grid-cell-renderers/status.tsx index 49c41c18bd921..5c0e15575a4e5 100644 --- a/docs/data/components/grid-cell-renderers/status.tsx +++ b/docs/data/components/grid-cell-renderers/status.tsx @@ -5,7 +5,7 @@ import ListItemText from '@mui/material/ListItemText'; import MenuItem from '@mui/material/MenuItem'; import type { MenuProps } from '@mui/material/Menu'; import Select, { SelectProps } from '@mui/material/Select'; -import styled from '@mui/system/styled'; +import { styled } from '@mui/material/styles'; import ReportProblemIcon from '@mui/icons-material/ReportProblem'; import InfoIcon from '@mui/icons-material/Info'; import AutorenewIcon from '@mui/icons-material/Autorenew'; @@ -17,7 +17,7 @@ import { useGridApiContext, useGridRootProps, } from '@mui/x-data-grid'; -import { STATUS_OPTIONS } from '@mui/x-data-grid-generator/services/static-data'; +import { STATUS_OPTIONS } from '@mui/x-data-grid-generator/services'; interface StatusProps { status: string; diff --git a/packages/x-data-grid-generator/src/services/index.ts b/packages/x-data-grid-generator/src/services/index.ts index 168db701a2d2f..017e37a9da7c6 100644 --- a/packages/x-data-grid-generator/src/services/index.ts +++ b/packages/x-data-grid-generator/src/services/index.ts @@ -2,3 +2,4 @@ export * from './gridColDefGenerator'; export * from './random-generator'; export * from './real-data-service'; export * from './basic-data-service'; +export * from './static-data'; From 321f4ed8f6217aa73d1a7e352901d10a97da661d Mon Sep 17 00:00:00 2001 From: Andrew Cherniavskyi Date: Tue, 27 Aug 2024 17:50:38 +0200 Subject: [PATCH 14/21] lint --- docs/data/data-grid/custom-columns/CustomColumnFullExample.js | 2 +- docs/data/data-grid/custom-columns/CustomColumnFullExample.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/data/data-grid/custom-columns/CustomColumnFullExample.js b/docs/data/data-grid/custom-columns/CustomColumnFullExample.js index d299a21974e11..56fa73ee3fe51 100644 --- a/docs/data/data-grid/custom-columns/CustomColumnFullExample.js +++ b/docs/data/data-grid/custom-columns/CustomColumnFullExample.js @@ -14,7 +14,7 @@ import { COUNTRY_ISO_OPTIONS_SORTED, INCOTERM_OPTIONS, STATUS_OPTIONS, -} from '@mui/x-data-grid-generator/services/static-data'; +} from '@mui/x-data-grid-generator/services'; import { DataGrid, gridStringOrNumberComparator } from '@mui/x-data-grid'; import { renderAvatar } from '../../components/grid-cell-renderers/avatar'; import { renderEmail } from '../../components/grid-cell-renderers/email'; diff --git a/docs/data/data-grid/custom-columns/CustomColumnFullExample.tsx b/docs/data/data-grid/custom-columns/CustomColumnFullExample.tsx index 74043f1fa5a7b..04e0a051457b8 100644 --- a/docs/data/data-grid/custom-columns/CustomColumnFullExample.tsx +++ b/docs/data/data-grid/custom-columns/CustomColumnFullExample.tsx @@ -15,7 +15,7 @@ import { CountryIsoOption, INCOTERM_OPTIONS, STATUS_OPTIONS, -} from '@mui/x-data-grid-generator/services/static-data'; +} from '@mui/x-data-grid-generator/services'; import { DataGrid, GridColDef, From daae1230cf0718702f744dffc23d476445e74faf Mon Sep 17 00:00:00 2001 From: Andrew Cherniavskyi Date: Mon, 9 Sep 2024 13:00:12 +0200 Subject: [PATCH 15/21] docs:api --- scripts/x-data-grid-generator.exports.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/scripts/x-data-grid-generator.exports.json b/scripts/x-data-grid-generator.exports.json index 06a34db6fa23f..77d12961534cd 100644 --- a/scripts/x-data-grid-generator.exports.json +++ b/scripts/x-data-grid-generator.exports.json @@ -1,7 +1,15 @@ [ { "name": "BASE_URL", "kind": "Variable" }, + { "name": "COLORS", "kind": "Variable" }, { "name": "ColumnsOptions", "kind": "Interface" }, + { "name": "COMMODITY_OPTIONS", "kind": "Variable" }, + { "name": "CONTRACT_TYPE_OPTIONS", "kind": "Variable" }, + { "name": "COUNTRY_ISO_OPTIONS", "kind": "Variable" }, + { "name": "COUNTRY_ISO_OPTIONS_SORTED", "kind": "Variable" }, + { "name": "COUNTRY_OPTIONS", "kind": "Variable" }, + { "name": "CountryIsoOption", "kind": "Interface" }, { "name": "createFakeServer", "kind": "Variable" }, + { "name": "CURRENCY_OPTIONS", "kind": "Variable" }, { "name": "currencyPairs", "kind": "Variable" }, { "name": "deepFreeze", "kind": "Variable" }, { "name": "DemoDataReturnType", "kind": "TypeAlias" }, @@ -19,6 +27,7 @@ { "name": "GridColDefGenerator", "kind": "TypeAlias" }, { "name": "GridDataGeneratorContext", "kind": "Interface" }, { "name": "GridDemoData", "kind": "Interface" }, + { "name": "INCOTERM_OPTIONS", "kind": "Variable" }, { "name": "loadServerRows", "kind": "Variable" }, { "name": "Movie", "kind": "TypeAlias" }, { "name": "QueryOptions", "kind": "Interface" }, @@ -61,6 +70,7 @@ { "name": "randomUpdatedDate", "kind": "Variable" }, { "name": "randomUrl", "kind": "Variable" }, { "name": "randomUserName", "kind": "Variable" }, + { "name": "RATE_TYPE_OPTIONS", "kind": "Variable" }, { "name": "renderAvatar", "kind": "Function" }, { "name": "renderCountry", "kind": "Function" }, { "name": "renderEditCountry", "kind": "Function" }, @@ -77,6 +87,8 @@ { "name": "renderRating", "kind": "Function" }, { "name": "renderStatus", "kind": "Function" }, { "name": "renderTotalPrice", "kind": "Function" }, + { "name": "STATUS_OPTIONS", "kind": "Variable" }, + { "name": "TAXCODE_OPTIONS", "kind": "Variable" }, { "name": "useBasicDemoData", "kind": "Variable" }, { "name": "useDemoData", "kind": "Variable" }, { "name": "UseDemoDataOptions", "kind": "Interface" }, From 4866de8b8c4a2c5c2213ec60f0190696493bd5a9 Mon Sep 17 00:00:00 2001 From: Andrew Cherniavskyi Date: Mon, 9 Sep 2024 13:29:49 +0200 Subject: [PATCH 16/21] link to the custom columns page --- docs/data/data-grid/custom-columns/custom-columns.md | 8 +++++++- docs/data/data-grid/faq/faq.md | 9 ++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/docs/data/data-grid/custom-columns/custom-columns.md b/docs/data/data-grid/custom-columns/custom-columns.md index 4a4af3b326f3e..ebabc45e057fb 100644 --- a/docs/data/data-grid/custom-columns/custom-columns.md +++ b/docs/data/data-grid/custom-columns/custom-columns.md @@ -46,7 +46,13 @@ See [Localization](/x/react-date-pickers/localization/) for more information. ## Full example -The demo below shows the most common custom column renderers. +The demo below shows the most common custom column renderers used across our demos. + +:::success +You can copy the column definitions and custom cell renderers from the demo source code. + +All column definitions are located in the main component file, while each cell renderer is in a separate file. +::: {{"demo": "CustomColumnFullExample.js", "bg": "inline"}} diff --git a/docs/data/data-grid/faq/faq.md b/docs/data/data-grid/faq/faq.md index 7c3d17e7c94b9..2aec0da7e1744 100644 --- a/docs/data/data-grid/faq/faq.md +++ b/docs/data/data-grid/faq/faq.md @@ -124,7 +124,14 @@ It only impacts the rendering part and does not impact the internal calculations ## What is the purpose of useDemoData hook used in the documentation examples? The `useDemoData` hook is a utility hook from the `@mui/x-data-grid-generator` package. -It generates random data for the Data Grid. It is often used in documentation examples to provide realistic data without polluting the code with data generation logic. +It contains columns definitions and generates random data for the Data Grid. +It is often used in our demos to provide realistic data without polluting the code with data generation logic. + +:::success +Looking for the column definitions and custom cell renderers from the `useDemoData` hook? + +Check out the [Custom columns demo](/x/react-data-grid/custom-columns/#full-example) where you can copy them from the demo source code. +::: Here's how it's used: From 3862336c37b5eca4ebecdd16f17435f0a562353c Mon Sep 17 00:00:00 2001 From: Andrew Cherniavskyi Date: Mon, 9 Sep 2024 13:44:21 +0200 Subject: [PATCH 17/21] move cell renderers to shorten the file names --- .../custom-columns/CustomColumnFullExample.js | 31 +++++-------------- .../CustomColumnFullExample.tsx | 31 +++++-------------- .../custom-columns/cell-renderers}/avatar.js | 0 .../custom-columns/cell-renderers}/avatar.tsx | 0 .../custom-columns/cell-renderers}/country.js | 0 .../cell-renderers}/country.tsx | 0 .../custom-columns/cell-renderers}/email.js | 0 .../custom-columns/cell-renderers}/email.tsx | 0 .../cell-renderers}/incoterm.js | 0 .../cell-renderers}/incoterm.tsx | 0 .../cell-renderers}/progress.js | 0 .../cell-renderers}/progress.tsx | 0 .../custom-columns/cell-renderers}/rating.js | 0 .../custom-columns/cell-renderers}/rating.tsx | 0 .../cell-renderers}/sparkline.js | 0 .../cell-renderers}/sparkline.tsx | 0 .../custom-columns/cell-renderers}/status.js | 0 .../custom-columns/cell-renderers}/status.tsx | 0 test/regressions/index.js | 2 +- 19 files changed, 17 insertions(+), 47 deletions(-) rename docs/data/{components/grid-cell-renderers => data-grid/custom-columns/cell-renderers}/avatar.js (100%) rename docs/data/{components/grid-cell-renderers => data-grid/custom-columns/cell-renderers}/avatar.tsx (100%) rename docs/data/{components/grid-cell-renderers => data-grid/custom-columns/cell-renderers}/country.js (100%) rename docs/data/{components/grid-cell-renderers => data-grid/custom-columns/cell-renderers}/country.tsx (100%) rename docs/data/{components/grid-cell-renderers => data-grid/custom-columns/cell-renderers}/email.js (100%) rename docs/data/{components/grid-cell-renderers => data-grid/custom-columns/cell-renderers}/email.tsx (100%) rename docs/data/{components/grid-cell-renderers => data-grid/custom-columns/cell-renderers}/incoterm.js (100%) rename docs/data/{components/grid-cell-renderers => data-grid/custom-columns/cell-renderers}/incoterm.tsx (100%) rename docs/data/{components/grid-cell-renderers => data-grid/custom-columns/cell-renderers}/progress.js (100%) rename docs/data/{components/grid-cell-renderers => data-grid/custom-columns/cell-renderers}/progress.tsx (100%) rename docs/data/{components/grid-cell-renderers => data-grid/custom-columns/cell-renderers}/rating.js (100%) rename docs/data/{components/grid-cell-renderers => data-grid/custom-columns/cell-renderers}/rating.tsx (100%) rename docs/data/{components/grid-cell-renderers => data-grid/custom-columns/cell-renderers}/sparkline.js (100%) rename docs/data/{components/grid-cell-renderers => data-grid/custom-columns/cell-renderers}/sparkline.tsx (100%) rename docs/data/{components/grid-cell-renderers => data-grid/custom-columns/cell-renderers}/status.js (100%) rename docs/data/{components/grid-cell-renderers => data-grid/custom-columns/cell-renderers}/status.tsx (100%) diff --git a/docs/data/data-grid/custom-columns/CustomColumnFullExample.js b/docs/data/data-grid/custom-columns/CustomColumnFullExample.js index 56fa73ee3fe51..6513e96e550bc 100644 --- a/docs/data/data-grid/custom-columns/CustomColumnFullExample.js +++ b/docs/data/data-grid/custom-columns/CustomColumnFullExample.js @@ -16,29 +16,14 @@ import { STATUS_OPTIONS, } from '@mui/x-data-grid-generator/services'; import { DataGrid, gridStringOrNumberComparator } from '@mui/x-data-grid'; -import { renderAvatar } from '../../components/grid-cell-renderers/avatar'; -import { renderEmail } from '../../components/grid-cell-renderers/email'; -import { - renderEditRating, - renderRating, -} from '../../components/grid-cell-renderers/rating'; -import { - renderCountry, - renderEditCountry, -} from '../../components/grid-cell-renderers/country'; -import { renderSparkline } from '../../components/grid-cell-renderers/sparkline'; -import { - renderEditProgress, - renderProgress, -} from '../../components/grid-cell-renderers/progress'; -import { - renderEditStatus, - renderStatus, -} from '../../components/grid-cell-renderers/status'; -import { - renderEditIncoterm, - renderIncoterm, -} from '../../components/grid-cell-renderers/incoterm'; +import { renderAvatar } from './cell-renderers/avatar'; +import { renderEmail } from './cell-renderers/email'; +import { renderEditRating, renderRating } from './cell-renderers/rating'; +import { renderCountry, renderEditCountry } from './cell-renderers/country'; +import { renderSparkline } from './cell-renderers/sparkline'; +import { renderEditProgress, renderProgress } from './cell-renderers/progress'; +import { renderEditStatus, renderStatus } from './cell-renderers/status'; +import { renderEditIncoterm, renderIncoterm } from './cell-renderers/incoterm'; const columns = [ { diff --git a/docs/data/data-grid/custom-columns/CustomColumnFullExample.tsx b/docs/data/data-grid/custom-columns/CustomColumnFullExample.tsx index 04e0a051457b8..e2e8069b47086 100644 --- a/docs/data/data-grid/custom-columns/CustomColumnFullExample.tsx +++ b/docs/data/data-grid/custom-columns/CustomColumnFullExample.tsx @@ -21,29 +21,14 @@ import { GridColDef, gridStringOrNumberComparator, } from '@mui/x-data-grid'; -import { renderAvatar } from '../../components/grid-cell-renderers/avatar'; -import { renderEmail } from '../../components/grid-cell-renderers/email'; -import { - renderEditRating, - renderRating, -} from '../../components/grid-cell-renderers/rating'; -import { - renderCountry, - renderEditCountry, -} from '../../components/grid-cell-renderers/country'; -import { renderSparkline } from '../../components/grid-cell-renderers/sparkline'; -import { - renderEditProgress, - renderProgress, -} from '../../components/grid-cell-renderers/progress'; -import { - renderEditStatus, - renderStatus, -} from '../../components/grid-cell-renderers/status'; -import { - renderEditIncoterm, - renderIncoterm, -} from '../../components/grid-cell-renderers/incoterm'; +import { renderAvatar } from './cell-renderers/avatar'; +import { renderEmail } from './cell-renderers/email'; +import { renderEditRating, renderRating } from './cell-renderers/rating'; +import { renderCountry, renderEditCountry } from './cell-renderers/country'; +import { renderSparkline } from './cell-renderers/sparkline'; +import { renderEditProgress, renderProgress } from './cell-renderers/progress'; +import { renderEditStatus, renderStatus } from './cell-renderers/status'; +import { renderEditIncoterm, renderIncoterm } from './cell-renderers/incoterm'; const columns: GridColDef<(typeof rows)[number]>[] = [ { diff --git a/docs/data/components/grid-cell-renderers/avatar.js b/docs/data/data-grid/custom-columns/cell-renderers/avatar.js similarity index 100% rename from docs/data/components/grid-cell-renderers/avatar.js rename to docs/data/data-grid/custom-columns/cell-renderers/avatar.js diff --git a/docs/data/components/grid-cell-renderers/avatar.tsx b/docs/data/data-grid/custom-columns/cell-renderers/avatar.tsx similarity index 100% rename from docs/data/components/grid-cell-renderers/avatar.tsx rename to docs/data/data-grid/custom-columns/cell-renderers/avatar.tsx diff --git a/docs/data/components/grid-cell-renderers/country.js b/docs/data/data-grid/custom-columns/cell-renderers/country.js similarity index 100% rename from docs/data/components/grid-cell-renderers/country.js rename to docs/data/data-grid/custom-columns/cell-renderers/country.js diff --git a/docs/data/components/grid-cell-renderers/country.tsx b/docs/data/data-grid/custom-columns/cell-renderers/country.tsx similarity index 100% rename from docs/data/components/grid-cell-renderers/country.tsx rename to docs/data/data-grid/custom-columns/cell-renderers/country.tsx diff --git a/docs/data/components/grid-cell-renderers/email.js b/docs/data/data-grid/custom-columns/cell-renderers/email.js similarity index 100% rename from docs/data/components/grid-cell-renderers/email.js rename to docs/data/data-grid/custom-columns/cell-renderers/email.js diff --git a/docs/data/components/grid-cell-renderers/email.tsx b/docs/data/data-grid/custom-columns/cell-renderers/email.tsx similarity index 100% rename from docs/data/components/grid-cell-renderers/email.tsx rename to docs/data/data-grid/custom-columns/cell-renderers/email.tsx diff --git a/docs/data/components/grid-cell-renderers/incoterm.js b/docs/data/data-grid/custom-columns/cell-renderers/incoterm.js similarity index 100% rename from docs/data/components/grid-cell-renderers/incoterm.js rename to docs/data/data-grid/custom-columns/cell-renderers/incoterm.js diff --git a/docs/data/components/grid-cell-renderers/incoterm.tsx b/docs/data/data-grid/custom-columns/cell-renderers/incoterm.tsx similarity index 100% rename from docs/data/components/grid-cell-renderers/incoterm.tsx rename to docs/data/data-grid/custom-columns/cell-renderers/incoterm.tsx diff --git a/docs/data/components/grid-cell-renderers/progress.js b/docs/data/data-grid/custom-columns/cell-renderers/progress.js similarity index 100% rename from docs/data/components/grid-cell-renderers/progress.js rename to docs/data/data-grid/custom-columns/cell-renderers/progress.js diff --git a/docs/data/components/grid-cell-renderers/progress.tsx b/docs/data/data-grid/custom-columns/cell-renderers/progress.tsx similarity index 100% rename from docs/data/components/grid-cell-renderers/progress.tsx rename to docs/data/data-grid/custom-columns/cell-renderers/progress.tsx diff --git a/docs/data/components/grid-cell-renderers/rating.js b/docs/data/data-grid/custom-columns/cell-renderers/rating.js similarity index 100% rename from docs/data/components/grid-cell-renderers/rating.js rename to docs/data/data-grid/custom-columns/cell-renderers/rating.js diff --git a/docs/data/components/grid-cell-renderers/rating.tsx b/docs/data/data-grid/custom-columns/cell-renderers/rating.tsx similarity index 100% rename from docs/data/components/grid-cell-renderers/rating.tsx rename to docs/data/data-grid/custom-columns/cell-renderers/rating.tsx diff --git a/docs/data/components/grid-cell-renderers/sparkline.js b/docs/data/data-grid/custom-columns/cell-renderers/sparkline.js similarity index 100% rename from docs/data/components/grid-cell-renderers/sparkline.js rename to docs/data/data-grid/custom-columns/cell-renderers/sparkline.js diff --git a/docs/data/components/grid-cell-renderers/sparkline.tsx b/docs/data/data-grid/custom-columns/cell-renderers/sparkline.tsx similarity index 100% rename from docs/data/components/grid-cell-renderers/sparkline.tsx rename to docs/data/data-grid/custom-columns/cell-renderers/sparkline.tsx diff --git a/docs/data/components/grid-cell-renderers/status.js b/docs/data/data-grid/custom-columns/cell-renderers/status.js similarity index 100% rename from docs/data/components/grid-cell-renderers/status.js rename to docs/data/data-grid/custom-columns/cell-renderers/status.js diff --git a/docs/data/components/grid-cell-renderers/status.tsx b/docs/data/data-grid/custom-columns/cell-renderers/status.tsx similarity index 100% rename from docs/data/components/grid-cell-renderers/status.tsx rename to docs/data/data-grid/custom-columns/cell-renderers/status.tsx diff --git a/test/regressions/index.js b/test/regressions/index.js index 245bbcea7b131..9c302e4ce5ab8 100644 --- a/test/regressions/index.js +++ b/test/regressions/index.js @@ -14,7 +14,7 @@ Globals.assign({ const blacklist = [ /^docs-(.*)(?<=NoSnap)\.png$/, // Excludes demos that we don't want - /^docs-components-(.*)\.png$/, // Custom components used to build docs pages + /^docs-data-grid-custom-columns-cell-renderers-(.*)\.png$/, // Custom components used to build docs pages 'docs-data-grid-filtering/RemoveBuiltInOperators.png', // Needs interaction 'docs-data-grid-filtering/CustomRatingOperator.png', // Needs interaction 'docs-data-grid-filtering/CustomInputComponent.png', // Needs interaction From 4202abd54d2aa5c6ceba0517e34cd71e37d8ba9d Mon Sep 17 00:00:00 2001 From: Andrew Cherniavskyi Date: Mon, 9 Sep 2024 14:16:06 +0200 Subject: [PATCH 18/21] fix regex --- test/regressions/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/regressions/index.js b/test/regressions/index.js index 9c302e4ce5ab8..06cdb75f6d0b9 100644 --- a/test/regressions/index.js +++ b/test/regressions/index.js @@ -14,7 +14,7 @@ Globals.assign({ const blacklist = [ /^docs-(.*)(?<=NoSnap)\.png$/, // Excludes demos that we don't want - /^docs-data-grid-custom-columns-cell-renderers-(.*)\.png$/, // Custom components used to build docs pages + /^docs-data-grid-custom-columns-cell-renderers\/(.*)\.png$/, // Custom components used to build docs pages 'docs-data-grid-filtering/RemoveBuiltInOperators.png', // Needs interaction 'docs-data-grid-filtering/CustomRatingOperator.png', // Needs interaction 'docs-data-grid-filtering/CustomInputComponent.png', // Needs interaction From 96c65792f91f0194457a37b77a63214d18155248 Mon Sep 17 00:00:00 2001 From: Andrew Cherniavskyi Date: Mon, 9 Sep 2024 14:40:31 +0200 Subject: [PATCH 19/21] only use random fns from the generator package --- .../custom-columns/CustomColumnFullExample.js | 42 ++++++++++-------- .../CustomColumnFullExample.tsx | 44 ++++++++++--------- .../custom-columns/cell-renderers/country.js | 8 +++- .../custom-columns/cell-renderers/country.tsx | 19 ++++++-- .../custom-columns/cell-renderers/incoterm.js | 11 ++++- .../cell-renderers/incoterm.tsx | 11 ++++- .../custom-columns/cell-renderers/status.js | 3 +- .../custom-columns/cell-renderers/status.tsx | 3 +- 8 files changed, 93 insertions(+), 48 deletions(-) diff --git a/docs/data/data-grid/custom-columns/CustomColumnFullExample.js b/docs/data/data-grid/custom-columns/CustomColumnFullExample.js index 6513e96e550bc..4482e579f84f3 100644 --- a/docs/data/data-grid/custom-columns/CustomColumnFullExample.js +++ b/docs/data/data-grid/custom-columns/CustomColumnFullExample.js @@ -1,29 +1,33 @@ import * as React from 'react'; import { - generateFilledQuantity, randomColor, - randomCountry, randomEmail, - randomIncoterm, randomInt, randomName, - randomRating, - randomStatusOptions, + randomArrayItem, + random, } from '@mui/x-data-grid-generator'; -import { - COUNTRY_ISO_OPTIONS_SORTED, - INCOTERM_OPTIONS, - STATUS_OPTIONS, -} from '@mui/x-data-grid-generator/services'; import { DataGrid, gridStringOrNumberComparator } from '@mui/x-data-grid'; import { renderAvatar } from './cell-renderers/avatar'; import { renderEmail } from './cell-renderers/email'; import { renderEditRating, renderRating } from './cell-renderers/rating'; -import { renderCountry, renderEditCountry } from './cell-renderers/country'; +import { + COUNTRY_ISO_OPTIONS, + renderCountry, + renderEditCountry, +} from './cell-renderers/country'; import { renderSparkline } from './cell-renderers/sparkline'; import { renderEditProgress, renderProgress } from './cell-renderers/progress'; -import { renderEditStatus, renderStatus } from './cell-renderers/status'; -import { renderEditIncoterm, renderIncoterm } from './cell-renderers/incoterm'; +import { + renderEditStatus, + renderStatus, + STATUS_OPTIONS, +} from './cell-renderers/status'; +import { + INCOTERM_OPTIONS, + renderEditIncoterm, + renderIncoterm, +} from './cell-renderers/incoterm'; const columns = [ { @@ -66,7 +70,7 @@ const columns = [ field: 'country', headerName: 'Country', type: 'singleSelect', - valueOptions: COUNTRY_ISO_OPTIONS_SORTED, + valueOptions: COUNTRY_ISO_OPTIONS, valueFormatter: (value) => value?.label, renderCell: renderCountry, renderEditCell: renderEditCountry, @@ -137,13 +141,13 @@ const rows = Array.from({ length: 10 }, (_, index) => ({ name: randomName({}, {}), avatar: randomColor(), email: randomEmail(), - rating: randomRating(), - country: randomCountry(), + rating: randomInt(1, 5), + country: randomArrayItem(COUNTRY_ISO_OPTIONS), salary: randomInt(35000, 80000), monthlyActivity: Array.from({ length: 30 }, () => randomInt(1, 25)), - budget: generateFilledQuantity({ quantity: 100 }), - status: randomStatusOptions(), - incoTerm: randomIncoterm(), + budget: random(0, 1).toPrecision(), + status: randomArrayItem(STATUS_OPTIONS), + incoTerm: randomArrayItem(INCOTERM_OPTIONS), })); export default function CustomColumnFullExample() { diff --git a/docs/data/data-grid/custom-columns/CustomColumnFullExample.tsx b/docs/data/data-grid/custom-columns/CustomColumnFullExample.tsx index e2e8069b47086..7bacff043e3a5 100644 --- a/docs/data/data-grid/custom-columns/CustomColumnFullExample.tsx +++ b/docs/data/data-grid/custom-columns/CustomColumnFullExample.tsx @@ -1,21 +1,12 @@ import * as React from 'react'; import { - generateFilledQuantity, randomColor, - randomCountry, randomEmail, - randomIncoterm, randomInt, randomName, - randomRating, - randomStatusOptions, + randomArrayItem, + random, } from '@mui/x-data-grid-generator'; -import { - COUNTRY_ISO_OPTIONS_SORTED, - CountryIsoOption, - INCOTERM_OPTIONS, - STATUS_OPTIONS, -} from '@mui/x-data-grid-generator/services'; import { DataGrid, GridColDef, @@ -24,11 +15,24 @@ import { import { renderAvatar } from './cell-renderers/avatar'; import { renderEmail } from './cell-renderers/email'; import { renderEditRating, renderRating } from './cell-renderers/rating'; -import { renderCountry, renderEditCountry } from './cell-renderers/country'; +import { + COUNTRY_ISO_OPTIONS, + CountryIsoOption, + renderCountry, + renderEditCountry, +} from './cell-renderers/country'; import { renderSparkline } from './cell-renderers/sparkline'; import { renderEditProgress, renderProgress } from './cell-renderers/progress'; -import { renderEditStatus, renderStatus } from './cell-renderers/status'; -import { renderEditIncoterm, renderIncoterm } from './cell-renderers/incoterm'; +import { + renderEditStatus, + renderStatus, + STATUS_OPTIONS, +} from './cell-renderers/status'; +import { + INCOTERM_OPTIONS, + renderEditIncoterm, + renderIncoterm, +} from './cell-renderers/incoterm'; const columns: GridColDef<(typeof rows)[number]>[] = [ { @@ -71,7 +75,7 @@ const columns: GridColDef<(typeof rows)[number]>[] = [ field: 'country', headerName: 'Country', type: 'singleSelect', - valueOptions: COUNTRY_ISO_OPTIONS_SORTED, + valueOptions: COUNTRY_ISO_OPTIONS, valueFormatter: (value: CountryIsoOption) => value?.label, renderCell: renderCountry, renderEditCell: renderEditCountry, @@ -142,13 +146,13 @@ const rows = Array.from({ length: 10 }, (_, index) => ({ name: randomName({}, {}), avatar: randomColor(), email: randomEmail(), - rating: randomRating(), - country: randomCountry(), + rating: randomInt(1, 5), + country: randomArrayItem(COUNTRY_ISO_OPTIONS), salary: randomInt(35000, 80000), monthlyActivity: Array.from({ length: 30 }, () => randomInt(1, 25)), - budget: generateFilledQuantity({ quantity: 100 }), - status: randomStatusOptions(), - incoTerm: randomIncoterm(), + budget: random(0, 1).toPrecision(), + status: randomArrayItem(STATUS_OPTIONS), + incoTerm: randomArrayItem(INCOTERM_OPTIONS), })); export default function CustomColumnFullExample() { diff --git a/docs/data/data-grid/custom-columns/cell-renderers/country.js b/docs/data/data-grid/custom-columns/cell-renderers/country.js index 1c75b2bb86250..d8dbd277fb67e 100644 --- a/docs/data/data-grid/custom-columns/cell-renderers/country.js +++ b/docs/data/data-grid/custom-columns/cell-renderers/country.js @@ -1,12 +1,18 @@ import * as React from 'react'; import { useGridApiContext } from '@mui/x-data-grid'; -import { COUNTRY_ISO_OPTIONS } from '@mui/x-data-grid-generator/services'; import Autocomplete, { autocompleteClasses } from '@mui/material/Autocomplete'; import Box from '@mui/material/Box'; import InputBase from '@mui/material/InputBase'; import { styled } from '@mui/material/styles'; +export const COUNTRY_ISO_OPTIONS = [ + { value: 'DE', code: 'DE', label: 'Germany', phone: '49' }, + { value: 'ES', code: 'ES', label: 'Spain', phone: '34' }, + { value: 'FR', code: 'FR', label: 'France', phone: '33' }, + { value: 'GB', code: 'GB', label: 'United Kingdom', phone: '44' }, +]; + const Country = React.memo(function Country(props) { const { value } = props; diff --git a/docs/data/data-grid/custom-columns/cell-renderers/country.tsx b/docs/data/data-grid/custom-columns/cell-renderers/country.tsx index dadda0be171b9..54a3a293aac9f 100644 --- a/docs/data/data-grid/custom-columns/cell-renderers/country.tsx +++ b/docs/data/data-grid/custom-columns/cell-renderers/country.tsx @@ -4,16 +4,27 @@ import { GridRenderEditCellParams, useGridApiContext, } from '@mui/x-data-grid'; -import { - COUNTRY_ISO_OPTIONS, - CountryIsoOption, -} from '@mui/x-data-grid-generator/services'; import Autocomplete, { autocompleteClasses } from '@mui/material/Autocomplete'; import type { AutocompleteProps } from '@mui/material/Autocomplete'; import Box from '@mui/material/Box'; import InputBase from '@mui/material/InputBase'; import { styled } from '@mui/material/styles'; +export interface CountryIsoOption { + value: string; + code: string; + label: string; + phone: string; + suggested?: boolean; +} + +export const COUNTRY_ISO_OPTIONS: CountryIsoOption[] = [ + { value: 'DE', code: 'DE', label: 'Germany', phone: '49' }, + { value: 'ES', code: 'ES', label: 'Spain', phone: '34' }, + { value: 'FR', code: 'FR', label: 'France', phone: '33' }, + { value: 'GB', code: 'GB', label: 'United Kingdom', phone: '44' }, +]; + interface CountryProps { value: CountryIsoOption; } diff --git a/docs/data/data-grid/custom-columns/cell-renderers/incoterm.js b/docs/data/data-grid/custom-columns/cell-renderers/incoterm.js index 2ca0824517e66..524293d927540 100644 --- a/docs/data/data-grid/custom-columns/cell-renderers/incoterm.js +++ b/docs/data/data-grid/custom-columns/cell-renderers/incoterm.js @@ -8,7 +8,16 @@ import Select from '@mui/material/Select'; import Tooltip from '@mui/material/Tooltip'; import InfoIcon from '@mui/icons-material/Info'; import { useGridApiContext } from '@mui/x-data-grid'; -import { INCOTERM_OPTIONS } from '@mui/x-data-grid-generator/services'; + +export const INCOTERM_OPTIONS = [ + 'EXW (Ex Works)', + 'FAS (Free Alongside Ship)', + 'FCA (Free Carrier)', + 'CPT (Carriage Paid To)', + 'DAP (Delivered at Place)', + 'DPU (Delivered at Place Unloaded)', + 'DDP (Delivered Duty Paid)', +]; const Incoterm = React.memo(function Incoterm(props) { const { value } = props; diff --git a/docs/data/data-grid/custom-columns/cell-renderers/incoterm.tsx b/docs/data/data-grid/custom-columns/cell-renderers/incoterm.tsx index ce20112a6d036..de90756039bfd 100644 --- a/docs/data/data-grid/custom-columns/cell-renderers/incoterm.tsx +++ b/docs/data/data-grid/custom-columns/cell-renderers/incoterm.tsx @@ -12,7 +12,16 @@ import { GridRenderEditCellParams, useGridApiContext, } from '@mui/x-data-grid'; -import { INCOTERM_OPTIONS } from '@mui/x-data-grid-generator/services'; + +export const INCOTERM_OPTIONS = [ + 'EXW (Ex Works)', + 'FAS (Free Alongside Ship)', + 'FCA (Free Carrier)', + 'CPT (Carriage Paid To)', + 'DAP (Delivered at Place)', + 'DPU (Delivered at Place Unloaded)', + 'DDP (Delivered Duty Paid)', +]; interface IncotermProps { value: string | null | undefined; diff --git a/docs/data/data-grid/custom-columns/cell-renderers/status.js b/docs/data/data-grid/custom-columns/cell-renderers/status.js index 7aaa493f818a0..f67ec6746c923 100644 --- a/docs/data/data-grid/custom-columns/cell-renderers/status.js +++ b/docs/data/data-grid/custom-columns/cell-renderers/status.js @@ -15,7 +15,8 @@ import { useGridApiContext, useGridRootProps, } from '@mui/x-data-grid'; -import { STATUS_OPTIONS } from '@mui/x-data-grid-generator/services'; + +export const STATUS_OPTIONS = ['Open', 'PartiallyFilled', 'Filled', 'Rejected']; const StyledChip = styled(Chip)(({ theme }) => ({ justifyContent: 'left', diff --git a/docs/data/data-grid/custom-columns/cell-renderers/status.tsx b/docs/data/data-grid/custom-columns/cell-renderers/status.tsx index 5c0e15575a4e5..85bb29b226994 100644 --- a/docs/data/data-grid/custom-columns/cell-renderers/status.tsx +++ b/docs/data/data-grid/custom-columns/cell-renderers/status.tsx @@ -17,7 +17,8 @@ import { useGridApiContext, useGridRootProps, } from '@mui/x-data-grid'; -import { STATUS_OPTIONS } from '@mui/x-data-grid-generator/services'; + +export const STATUS_OPTIONS = ['Open', 'PartiallyFilled', 'Filled', 'Rejected']; interface StatusProps { status: string; From 520d992d0ac145a48ce832dc53dad7a08a1c1799 Mon Sep 17 00:00:00 2001 From: Andrew Cherniavskyi Date: Mon, 9 Sep 2024 14:42:06 +0200 Subject: [PATCH 20/21] revert generator exports --- packages/x-data-grid-generator/src/services/index.ts | 1 - scripts/x-data-grid-generator.exports.json | 12 ------------ 2 files changed, 13 deletions(-) diff --git a/packages/x-data-grid-generator/src/services/index.ts b/packages/x-data-grid-generator/src/services/index.ts index 017e37a9da7c6..168db701a2d2f 100644 --- a/packages/x-data-grid-generator/src/services/index.ts +++ b/packages/x-data-grid-generator/src/services/index.ts @@ -2,4 +2,3 @@ export * from './gridColDefGenerator'; export * from './random-generator'; export * from './real-data-service'; export * from './basic-data-service'; -export * from './static-data'; diff --git a/scripts/x-data-grid-generator.exports.json b/scripts/x-data-grid-generator.exports.json index 77d12961534cd..06a34db6fa23f 100644 --- a/scripts/x-data-grid-generator.exports.json +++ b/scripts/x-data-grid-generator.exports.json @@ -1,15 +1,7 @@ [ { "name": "BASE_URL", "kind": "Variable" }, - { "name": "COLORS", "kind": "Variable" }, { "name": "ColumnsOptions", "kind": "Interface" }, - { "name": "COMMODITY_OPTIONS", "kind": "Variable" }, - { "name": "CONTRACT_TYPE_OPTIONS", "kind": "Variable" }, - { "name": "COUNTRY_ISO_OPTIONS", "kind": "Variable" }, - { "name": "COUNTRY_ISO_OPTIONS_SORTED", "kind": "Variable" }, - { "name": "COUNTRY_OPTIONS", "kind": "Variable" }, - { "name": "CountryIsoOption", "kind": "Interface" }, { "name": "createFakeServer", "kind": "Variable" }, - { "name": "CURRENCY_OPTIONS", "kind": "Variable" }, { "name": "currencyPairs", "kind": "Variable" }, { "name": "deepFreeze", "kind": "Variable" }, { "name": "DemoDataReturnType", "kind": "TypeAlias" }, @@ -27,7 +19,6 @@ { "name": "GridColDefGenerator", "kind": "TypeAlias" }, { "name": "GridDataGeneratorContext", "kind": "Interface" }, { "name": "GridDemoData", "kind": "Interface" }, - { "name": "INCOTERM_OPTIONS", "kind": "Variable" }, { "name": "loadServerRows", "kind": "Variable" }, { "name": "Movie", "kind": "TypeAlias" }, { "name": "QueryOptions", "kind": "Interface" }, @@ -70,7 +61,6 @@ { "name": "randomUpdatedDate", "kind": "Variable" }, { "name": "randomUrl", "kind": "Variable" }, { "name": "randomUserName", "kind": "Variable" }, - { "name": "RATE_TYPE_OPTIONS", "kind": "Variable" }, { "name": "renderAvatar", "kind": "Function" }, { "name": "renderCountry", "kind": "Function" }, { "name": "renderEditCountry", "kind": "Function" }, @@ -87,8 +77,6 @@ { "name": "renderRating", "kind": "Function" }, { "name": "renderStatus", "kind": "Function" }, { "name": "renderTotalPrice", "kind": "Function" }, - { "name": "STATUS_OPTIONS", "kind": "Variable" }, - { "name": "TAXCODE_OPTIONS", "kind": "Variable" }, { "name": "useBasicDemoData", "kind": "Variable" }, { "name": "useDemoData", "kind": "Variable" }, { "name": "UseDemoDataOptions", "kind": "Interface" }, From adf7ec94dab3ad5afe92259b51987386d30f73ec Mon Sep 17 00:00:00 2001 From: Andrew Cherniavskyi Date: Wed, 11 Sep 2024 23:40:19 +0200 Subject: [PATCH 21/21] fix demo in codesandbox embed https://github.com/codesandbox/codesandbox-client/issues/8607 --- docs/data/data-grid/custom-columns/CustomColumnFullExample.js | 2 +- docs/data/data-grid/custom-columns/CustomColumnFullExample.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/data/data-grid/custom-columns/CustomColumnFullExample.js b/docs/data/data-grid/custom-columns/CustomColumnFullExample.js index 4482e579f84f3..be7c002fb2b74 100644 --- a/docs/data/data-grid/custom-columns/CustomColumnFullExample.js +++ b/docs/data/data-grid/custom-columns/CustomColumnFullExample.js @@ -87,7 +87,7 @@ const columns = [ if (!value || typeof value !== 'number') { return value; } - return `${value.toLocaleString()}$`; + return `$${value.toLocaleString()}`; }, editable: true, }, diff --git a/docs/data/data-grid/custom-columns/CustomColumnFullExample.tsx b/docs/data/data-grid/custom-columns/CustomColumnFullExample.tsx index 7bacff043e3a5..2f0fa78b81a4c 100644 --- a/docs/data/data-grid/custom-columns/CustomColumnFullExample.tsx +++ b/docs/data/data-grid/custom-columns/CustomColumnFullExample.tsx @@ -92,7 +92,7 @@ const columns: GridColDef<(typeof rows)[number]>[] = [ if (!value || typeof value !== 'number') { return value; } - return `${value.toLocaleString()}$`; + return `$${value.toLocaleString()}`; }, editable: true, },