Skip to content

Commit

Permalink
[Slider] Narrow onChange value type (mui#44777)
Browse files Browse the repository at this point in the history
  • Loading branch information
good-jinu authored Jan 23, 2025
1 parent 137c02f commit ad4825a
Show file tree
Hide file tree
Showing 15 changed files with 64 additions and 59 deletions.
4 changes: 2 additions & 2 deletions docs/data/material/components/slider/ContinuousSlider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import VolumeUp from '@mui/icons-material/VolumeUp';
export default function ContinuousSlider() {
const [value, setValue] = React.useState<number>(30);

const handleChange = (event: Event, newValue: number | number[]) => {
setValue(newValue as number);
const handleChange = (event: Event, newValue: number) => {
setValue(newValue);
};

return (
Expand Down
4 changes: 2 additions & 2 deletions docs/data/material/components/slider/CustomMarks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ const marks = [

export default function CustomMarks() {
const [val, setVal] = React.useState<number>(MIN);
const handleChange = (_: Event, newValue: number | number[]) => {
setVal(newValue as number);
const handleChange = (_: Event, newValue: number) => {
setVal(newValue);
};

return (
Expand Down
4 changes: 2 additions & 2 deletions docs/data/material/components/slider/InputSlider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ const Input = styled(MuiInput)`
export default function InputSlider() {
const [value, setValue] = React.useState(30);

const handleSliderChange = (event: Event, newValue: number | number[]) => {
setValue(newValue as number);
const handleSliderChange = (event: Event, newValue: number) => {
setValue(newValue);
};

const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
Expand Down
8 changes: 0 additions & 8 deletions docs/data/material/components/slider/MinimumDistanceSlider.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,6 @@ export default function MinimumDistanceSlider() {
const [value1, setValue1] = React.useState([20, 37]);

const handleChange1 = (event, newValue, activeThumb) => {
if (!Array.isArray(newValue)) {
return;
}

if (activeThumb === 0) {
setValue1([Math.min(newValue[0], value1[1] - minDistance), value1[1]]);
} else {
Expand All @@ -26,10 +22,6 @@ export default function MinimumDistanceSlider() {
const [value2, setValue2] = React.useState([20, 37]);

const handleChange2 = (event, newValue, activeThumb) => {
if (!Array.isArray(newValue)) {
return;
}

if (newValue[1] - newValue[0] < minDistance) {
if (activeThumb === 0) {
const clamped = Math.min(newValue[0], 100 - minDistance);
Expand Down
22 changes: 3 additions & 19 deletions docs/data/material/components/slider/MinimumDistanceSlider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,7 @@ const minDistance = 10;
export default function MinimumDistanceSlider() {
const [value1, setValue1] = React.useState<number[]>([20, 37]);

const handleChange1 = (
event: Event,
newValue: number | number[],
activeThumb: number,
) => {
if (!Array.isArray(newValue)) {
return;
}

const handleChange1 = (event: Event, newValue: number[], activeThumb: number) => {
if (activeThumb === 0) {
setValue1([Math.min(newValue[0], value1[1] - minDistance), value1[1]]);
} else {
Expand All @@ -29,15 +21,7 @@ export default function MinimumDistanceSlider() {

const [value2, setValue2] = React.useState<number[]>([20, 37]);

const handleChange2 = (
event: Event,
newValue: number | number[],
activeThumb: number,
) => {
if (!Array.isArray(newValue)) {
return;
}

const handleChange2 = (event: Event, newValue: number[], activeThumb: number) => {
if (newValue[1] - newValue[0] < minDistance) {
if (activeThumb === 0) {
const clamped = Math.min(newValue[0], 100 - minDistance);
Expand All @@ -47,7 +31,7 @@ export default function MinimumDistanceSlider() {
setValue2([clamped - minDistance, clamped]);
}
} else {
setValue2(newValue as number[]);
setValue2(newValue);
}
};

Expand Down
2 changes: 1 addition & 1 deletion docs/data/material/components/slider/MusicPlayerSlider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ export default function MusicPlayerSlider() {
min={0}
step={1}
max={duration}
onChange={(_, value) => setPosition(value as number)}
onChange={(_, value) => setPosition(value)}
sx={(t) => ({
color: 'rgba(0,0,0,0.87)',
height: 4,
Expand Down
4 changes: 1 addition & 3 deletions docs/data/material/components/slider/NonLinearSlider.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,7 @@ export default function NonLinearSlider() {
const [value, setValue] = React.useState(10);

const handleChange = (event, newValue) => {
if (typeof newValue === 'number') {
setValue(newValue);
}
setValue(newValue);
};

return (
Expand Down
6 changes: 2 additions & 4 deletions docs/data/material/components/slider/NonLinearSlider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,8 @@ function calculateValue(value: number) {
export default function NonLinearSlider() {
const [value, setValue] = React.useState<number>(10);

const handleChange = (event: Event, newValue: number | number[]) => {
if (typeof newValue === 'number') {
setValue(newValue);
}
const handleChange = (event: Event, newValue: number) => {
setValue(newValue);
};

return (
Expand Down
4 changes: 2 additions & 2 deletions docs/data/material/components/slider/RangeSlider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ function valuetext(value: number) {
export default function RangeSlider() {
const [value, setValue] = React.useState<number[]>([20, 37]);

const handleChange = (event: Event, newValue: number | number[]) => {
setValue(newValue as number[]);
const handleChange = (event: Event, newValue: number[]) => {
setValue(newValue);
};

return (
Expand Down
4 changes: 2 additions & 2 deletions docs/pages/material-ui/api/slider.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,14 @@
"onChange": {
"type": { "name": "func" },
"signature": {
"type": "function(event: Event, value: number | Array<number>, activeThumb: number) => void",
"type": "function(event: Event, value: Value, activeThumb: number) => void",
"describedArgs": ["event", "value", "activeThumb"]
}
},
"onChangeCommitted": {
"type": { "name": "func" },
"signature": {
"type": "function(event: React.SyntheticEvent | Event, value: number | Array<number>) => void",
"type": "function(event: React.SyntheticEvent | Event, value: Value) => void",
"describedArgs": ["event", "value"]
}
},
Expand Down
2 changes: 1 addition & 1 deletion docs/src/components/productMaterial/MaterialHero.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ function SlideDemo() {
<Slider
aria-labelledby="temperature-slider"
value={value}
onChange={(_, newValue) => setValue(newValue as number[])}
onChange={(_, newValue) => setValue(newValue)}
/>
<LocalFireDepartment
fontSize="small"
Expand Down
4 changes: 2 additions & 2 deletions docs/src/components/x-grid/EditProgress.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ export default function EditProgress(props: GridRenderEditCellParams) {
[updateCellEditProps],
);

const handleChange = (event: Event, newValue: number | number[]) => {
setValueState(newValue as number);
const handleChange = (event: Event, newValue: number) => {
setValueState(newValue);
debouncedUpdateCellEditProps(newValue);
};

Expand Down
27 changes: 18 additions & 9 deletions packages/mui-material/src/Slider/Slider.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export interface SliderOwnerState extends SliderProps {
focusedThumbIndex: number;
}

export interface SliderOwnProps {
export interface SliderOwnProps<Value extends number | number[]> {
/**
* The label of the slider.
*/
Expand Down Expand Up @@ -93,7 +93,7 @@ export interface SliderOwnProps {
/**
* The default value. Use when the component is not controlled.
*/
defaultValue?: number | number[];
defaultValue?: Value;
/**
* If `true`, the component is disabled.
* @default false
Expand Down Expand Up @@ -148,17 +148,17 @@ export interface SliderOwnProps {
* @param {Event} event The event source of the callback.
* You can pull out the new value by accessing `event.target.value` (any).
* **Warning**: This is a generic event not a change event.
* @param {number | number[]} value The new value.
* @param {Value} value The new value.
* @param {number} activeThumb Index of the currently moved thumb.
*/
onChange?: (event: Event, value: number | number[], activeThumb: number) => void;
onChange?: (event: Event, value: Value, activeThumb: number) => void;
/**
* Callback function that is fired when the `mouseup` is triggered.
*
* @param {React.SyntheticEvent | Event} event The event source of the callback. **Warning**: This is a generic event not a change event.
* @param {number | number[]} value The new value.
* @param {Value} value The new value.
*/
onChangeCommitted?: (event: React.SyntheticEvent | Event, value: number | number[]) => void;
onChangeCommitted?: (event: React.SyntheticEvent | Event, value: Value) => void;
/**
* The component orientation.
* @default 'horizontal'
Expand Down Expand Up @@ -246,7 +246,7 @@ export interface SliderOwnProps {
* The value of the slider.
* For ranged sliders, provide an array with two values.
*/
value?: number | number[];
value?: Value;
/**
* Controls when the value label is displayed:
*
Expand Down Expand Up @@ -275,11 +275,20 @@ export interface SliderOwnProps {
export interface SliderTypeMap<
RootComponent extends React.ElementType = 'span',
AdditionalProps = {},
Value extends number | number[] = number | number[],
> {
props: AdditionalProps & SliderOwnProps;
props: AdditionalProps & SliderOwnProps<Value>;
defaultComponent: RootComponent;
}

export type SliderComponent<Value extends number | number[]> = OverridableComponent<
SliderTypeMap<'span', {}, Value>
>;

export type SliderType = SliderComponent<number> &
SliderComponent<number[]> &
SliderComponent<number | number[]>;

export interface SliderValueLabelProps extends React.HTMLAttributes<HTMLSpanElement> {
children: React.ReactElement<unknown>;
index: number;
Expand Down Expand Up @@ -312,7 +321,7 @@ export declare const SliderValueLabel: React.FC<SliderValueLabelProps>;
*
* - [Slider API](https://mui.com/material-ui/api/slider/)
*/
declare const Slider: OverridableComponent<SliderTypeMap>;
declare const Slider: SliderType;

export type SliderProps<
RootComponent extends React.ElementType = SliderTypeMap['defaultComponent'],
Expand Down
4 changes: 2 additions & 2 deletions packages/mui-material/src/Slider/Slider.js
Original file line number Diff line number Diff line change
Expand Up @@ -1037,15 +1037,15 @@ Slider.propTypes /* remove-proptypes */ = {
* @param {Event} event The event source of the callback.
* You can pull out the new value by accessing `event.target.value` (any).
* **Warning**: This is a generic event not a change event.
* @param {number | number[]} value The new value.
* @param {Value} value The new value.
* @param {number} activeThumb Index of the currently moved thumb.
*/
onChange: PropTypes.func,
/**
* Callback function that is fired when the `mouseup` is triggered.
*
* @param {React.SyntheticEvent | Event} event The event source of the callback. **Warning**: This is a generic event not a change event.
* @param {number | number[]} value The new value.
* @param {Value} value The new value.
*/
onChangeCommitted: PropTypes.func,
/**
Expand Down
24 changes: 24 additions & 0 deletions packages/mui-material/src/Slider/Slider.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,27 @@ function testOnChange() {
thumb: ({ orientation }) => ({ className: orientation === 'vertical' ? 'thumb_vertical' : '' }),
}}
/>;

// value, onChange, and onChangeCommitted value type
<Slider
value={5}
onChange={(event, value: number) => {}}
onChangeCommitted={(event, value: number) => {}}
/>;
<Slider
value={[5, 10]}
onChange={(event, value: number[]) => {}}
onChangeCommitted={(event, value: number[]) => {}}
/>;

const CustomComponent: React.FC<{ stringProp: string; numberProp: number }> =
function CustomComponent() {
return <div />;
};

<Slider component="div" />;
<Slider component={CustomComponent} stringProp="a" numberProp={1} />;
/* @ts-expect-error missing stringProp and numberProp */
<Slider component={CustomComponent} />;
/* @ts-expect-error does not allow any prop */
<Slider abc="123" />;

0 comments on commit ad4825a

Please sign in to comment.