From 4f79858c7e5d243e54972e4ec09e2466dfe62b93 Mon Sep 17 00:00:00 2001 From: Armin Mehinovic Date: Fri, 5 Jul 2024 10:57:08 +0200 Subject: [PATCH] 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, },