Files
react-test/docs/data/experiments/renderers/renderProgress.js
how2ice 005cf56baf
Some checks failed
No response / noResponse (push) Has been cancelled
CI / Continuous releases (push) Has been cancelled
CI / test-dev (macos-latest) (push) Has been cancelled
CI / test-dev (ubuntu-latest) (push) Has been cancelled
CI / test-dev (windows-latest) (push) Has been cancelled
Maintenance / main (push) Has been cancelled
Scorecards supply-chain security / Scorecards analysis (push) Has been cancelled
CodeQL / Analyze (push) Has been cancelled
init project
2025-12-12 14:26:25 +09:00

181 lines
4.0 KiB
JavaScript

import * as React from 'react';
import clsx from 'clsx';
import { useGridApiContext } from '@mui/x-data-grid';
import Slider, { sliderClasses } from '@mui/material/Slider';
import Tooltip from '@mui/material/Tooltip';
import { alpha, styled } from '@mui/material/styles';
import { debounce } from '@mui/material/utils';
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 (
<Element>
<Value>{`${valueInPercent.toLocaleString()} %`}</Value>
<Bar
className={clsx({
low: valueInPercent < 30,
medium: valueInPercent >= 30 && valueInPercent <= 70,
high: valueInPercent > 70,
})}
style={{ maxWidth: `${valueInPercent}%` }}
/>
</Element>
);
});
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 (
<Tooltip open={open} enterTouchDelay={0} placement="top" title={value}>
{children}
</Tooltip>
);
});
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 (
<StyledSlider
ref={handleRef}
classes={{
track: clsx({
low: valueState < 0.3,
medium: valueState >= 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 (
<Center>
<ProgressBar value={params.value} />
</Center>
);
}
export function renderEditProgress(params) {
return <EditProgress {...params} />;
}
export default renderProgress;