Skip to content

[Slider][material-next] Add Slider component with Material You design #37520

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 30 commits into from
Jun 15, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
effdf91
[Material You] copy MD2 Slider component
DiegoAndai May 22, 2023
62cf97c
[Material You] add useThemeProps hook
DiegoAndai May 22, 2023
9bf7edf
[Material You] add useTheme
DiegoAndai May 22, 2023
2837b4b
[Material You] add shouldSpreadAdditionalProps
DiegoAndai May 22, 2023
66eb1e6
[Material You] fix Slider capitalize import
DiegoAndai May 22, 2023
aa9a695
[Material You] fix generateUtilityClass import
DiegoAndai May 22, 2023
d1a751e
[Material You] Fix slotShouldForwardProp import
DiegoAndai May 22, 2023
eb04c2d
[MD3][Slider] migrate index to TS
DiegoAndai May 22, 2023
abc85c6
[MD3][Slider] migrate component types to .types
DiegoAndai May 22, 2023
a7b4a3e
[MD3][Slider] migrate component file to .tsx
DiegoAndai May 22, 2023
84ec7f5
[MD3][Slider] Add types to identity function
DiegoAndai May 22, 2023
a39118f
[MD3][Slider] add Slider props and ref types
DiegoAndai May 22, 2023
4bd6fec
[MD3][Slider] fix ownerState typings
DiegoAndai May 24, 2023
a642ae3
[MD3][Slider] add markActive types
DiegoAndai May 24, 2023
9a6c299
[MD3][Slider] Add Forward function children type
DiegoAndai May 24, 2023
8884595
[MD3] Add direction to CssVarsProvider theme
DiegoAndai May 24, 2023
140bffd
[MD3][Slider] Fix StyledSliderValueLabel propTypes
DiegoAndai May 24, 2023
acf3b0d
Apply MD3 slider style
DiegoAndai Jun 6, 2023
f74848f
Add MD3 Slider playground
DiegoAndai Jun 6, 2023
0928ab0
Fix linting from unused eslint disable
DiegoAndai Jun 6, 2023
c59f923
Add missing neutral tones to md2 experiment page
DiegoAndai Jun 6, 2023
9a8668d
Improve Slider disabled colors
DiegoAndai Jun 8, 2023
4c37ec6
Fix incorrect import in tests
DiegoAndai Jun 8, 2023
2af568e
Fix .spec file types
DiegoAndai Jun 9, 2023
744a999
Remove shared mock match media util
DiegoAndai Jun 9, 2023
805227e
Deprecate components and componentsProps
DiegoAndai Jun 12, 2023
1848e1b
[Slider] Add onChange docs missing coma
DiegoAndai Jun 12, 2023
4bfc582
Refactor neutral tones type
DiegoAndai Jun 12, 2023
67b1ac6
Initialize slots ans slotProps to avoid `?.`
DiegoAndai Jun 15, 2023
4b3de78
Remove componentsProps from `.spec`
DiegoAndai Jun 15, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 11 additions & 15 deletions packages/mui-material-next/src/Slider/Slider.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ describe('<Slider />', () => {
testDeepOverrides: { slotName: 'thumb', slotClassName: classes.thumb },
testVariantProps: { color: 'primary', orientation: 'vertical', size: 'small' },
testStateOverrides: { prop: 'color', value: 'secondary', styleKey: 'colorSecondary' },
testLegacyComponentsProp: true,
ThemeProvider: CssVarsProvider,
createTheme: extendTheme,
slots: {
Expand All @@ -80,6 +79,7 @@ describe('<Slider />', () => {
},
},
skip: [
'componentsProp',
'slotPropsCallback', // not supported yet
],
}),
Expand Down Expand Up @@ -313,7 +313,7 @@ describe('<Slider />', () => {
it('should focus the slider when dragging', () => {
const { getByRole, getByTestId, container } = render(
<Slider
componentsProps={{ thumb: { 'data-testid': 'thumb' } }}
slotProps={{ thumb: { 'data-testid': 'thumb' } }}
defaultValue={30}
step={10}
marks
Expand Down Expand Up @@ -801,7 +801,7 @@ describe('<Slider />', () => {
<Slider
valueLabelDisplay="on"
value={50}
componentsProps={{ thumb: { 'data-testid': 'thumb' } }}
slotProps={{ thumb: { 'data-testid': 'thumb' } }}
/>,
);
expect(document.querySelector(`.${classes.valueLabelOpen}`)).not.to.equal(null);
Expand All @@ -818,7 +818,7 @@ describe('<Slider />', () => {
<Slider
valueLabelDisplay="auto"
value={50}
componentsProps={{ thumb: { 'data-testid': 'thumb' } }}
slotProps={{ thumb: { 'data-testid': 'thumb' } }}
/>,
);
const thumb = getByTestId('thumb');
Expand All @@ -841,11 +841,7 @@ describe('<Slider />', () => {
ValueLabelComponent.propTypes = { value: PropTypes.number };

const { setProps } = render(
<Slider
components={{ ValueLabel: ValueLabelComponent }}
valueLabelDisplay="on"
value={50}
/>,
<Slider slots={{ valueLabel: ValueLabelComponent }} valueLabelDisplay="on" value={50} />,
);

expect(screen.queryByTestId('value-label')).to.have.class('open');
Expand Down Expand Up @@ -943,7 +939,7 @@ describe('<Slider />', () => {
<Slider
value={30}
onChange={handleChange}
componentsProps={{ thumb: { 'data-testid': 'thumb' } }}
slotProps={{ thumb: { 'data-testid': 'thumb' } }}
/>
</CssVarsProvider>,
);
Expand Down Expand Up @@ -1105,7 +1101,7 @@ describe('<Slider />', () => {
const { getByTestId } = render(
<Slider
value={10}
components={{ ValueLabel: ValueLabelComponent }}
slots={{ valueLabel: ValueLabelComponent }}
valueLabelDisplay="on"
valueLabelFormat={(n) => n.toString(2)}
/>,
Expand Down Expand Up @@ -1343,7 +1339,7 @@ describe('<Slider />', () => {
});
});

describe('prop: components', () => {
describe('prop: slots', () => {
it('should render custom components if specified', () => {
// ARRANGE
const dataTestId = 'slider-input-testid';
Expand All @@ -1353,22 +1349,22 @@ describe('<Slider />', () => {
}

// ACT
const { getByTestId } = render(<Slider components={{ Input: CustomInput }} />);
const { getByTestId } = render(<Slider slots={{ input: CustomInput }} />);

// ASSERT
expect(getByTestId(dataTestId).name).to.equal(name);
});
});

describe('prop: componentsProps', () => {
describe('prop: slotProps', () => {
it('should forward the props to their respective components', () => {
// ARRANGE
const dataTestId = 'slider-input-testid';
const id = 'slider-input-id';

// ACT
const { getByTestId } = render(
<Slider defaultValue={10} componentsProps={{ input: { 'data-testid': dataTestId, id } }} />,
<Slider defaultValue={10} slotProps={{ input: { 'data-testid': dataTestId, id } }} />,
);

// ASSERT
Expand Down
95 changes: 18 additions & 77 deletions packages/mui-material-next/src/Slider/Slider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -526,8 +526,6 @@ const Slider = React.forwardRef(function Slider<
'aria-valuetext': ariaValuetext,
'aria-labelledby': ariaLabelledby,
component = 'span',
components = {},
componentsProps = {},
color = 'primary',
classes: classesProp,
className,
Expand Down Expand Up @@ -600,29 +598,19 @@ const Slider = React.forwardRef(function Slider<

const classes = useUtilityClasses(ownerState);

// support both `slots` and `components` for backward compatibility
const RootSlot = slots?.root ?? components.Root ?? SliderRoot;
const RailSlot = slots?.rail ?? components.Rail ?? SliderRail;
const TrackSlot = slots?.track ?? components.Track ?? SliderTrack;
const ThumbSlot = slots?.thumb ?? components.Thumb ?? SliderThumb;
const ValueLabelSlot = slots?.valueLabel ?? components.ValueLabel ?? StyledSliderValueLabel;
const MarkSlot = slots?.mark ?? components.Mark ?? SliderMark;
const MarkLabelSlot = slots?.markLabel ?? components.MarkLabel ?? SliderMarkLabel;
const InputSlot = slots?.input ?? components.Input ?? 'input';

const rootSlotProps = slotProps?.root ?? componentsProps.root;
const railSlotProps = slotProps?.rail ?? componentsProps.rail;
const trackSlotProps = slotProps?.track ?? componentsProps.track;
const thumbSlotProps = slotProps?.thumb ?? componentsProps.thumb;
const valueLabelSlotProps = slotProps?.valueLabel ?? componentsProps.valueLabel;
const markSlotProps = slotProps?.mark ?? componentsProps.mark;
const markLabelSlotProps = slotProps?.markLabel ?? componentsProps.markLabel;
const inputSlotProps = slotProps?.input ?? componentsProps.input;
const RootSlot = slots?.root ?? SliderRoot;
const RailSlot = slots?.rail ?? SliderRail;
const TrackSlot = slots?.track ?? SliderTrack;
const ThumbSlot = slots?.thumb ?? SliderThumb;
const ValueLabelSlot = slots?.valueLabel ?? StyledSliderValueLabel;
const MarkSlot = slots?.mark ?? SliderMark;
const MarkLabelSlot = slots?.markLabel ?? SliderMarkLabel;
const InputSlot = slots?.input ?? 'input';

const rootProps = useSlotProps({
elementType: RootSlot,
getSlotProps: getRootProps,
externalSlotProps: rootSlotProps,
externalSlotProps: slotProps?.root,
externalForwardedProps: other,
additionalProps: {
...(shouldSpreadAdditionalProps(RootSlot) && {
Expand All @@ -635,14 +623,14 @@ const Slider = React.forwardRef(function Slider<

const railProps = useSlotProps({
elementType: RailSlot,
externalSlotProps: railSlotProps,
externalSlotProps: slotProps?.rail,
ownerState,
className: classes.rail,
});

const trackProps = useSlotProps({
elementType: TrackSlot,
externalSlotProps: trackSlotProps,
externalSlotProps: slotProps?.track,
additionalProps: {
style: {
...axisProps[axis].offset(trackOffset),
Expand All @@ -656,36 +644,36 @@ const Slider = React.forwardRef(function Slider<
const thumbProps = useSlotProps({
elementType: ThumbSlot,
getSlotProps: getThumbProps,
externalSlotProps: thumbSlotProps,
externalSlotProps: slotProps?.thumb,
ownerState,
className: classes.thumb,
});

const valueLabelProps = useSlotProps({
elementType: ValueLabelSlot,
externalSlotProps: valueLabelSlotProps,
externalSlotProps: slotProps?.valueLabel,
ownerState,
className: classes.valueLabel,
});

const markProps = useSlotProps({
elementType: MarkSlot,
externalSlotProps: markSlotProps,
externalSlotProps: slotProps?.mark,
ownerState,
className: classes.mark,
});

const markLabelProps = useSlotProps({
elementType: MarkLabelSlot,
externalSlotProps: markLabelSlotProps,
externalSlotProps: slotProps?.markLabel,
ownerState,
className: classes.markLabel,
});

const inputSliderProps = useSlotProps({
elementType: InputSlot,
getSlotProps: getHiddenInputProps,
externalSlotProps: inputSlotProps,
externalSlotProps: slotProps?.input,
ownerState,
});

Expand Down Expand Up @@ -856,53 +844,6 @@ Slider.propTypes /* remove-proptypes */ = {
PropTypes.oneOf(['primary', 'secondary']),
PropTypes.string,
]),
/**
* The components used for each slot inside.
*
* This prop is an alias for the `slots` prop.
* It's recommended to use the `slots` prop instead.
*
* @default {}
*/
components: PropTypes.shape({
Input: PropTypes.elementType,
Mark: PropTypes.elementType,
MarkLabel: PropTypes.elementType,
Rail: PropTypes.elementType,
Root: PropTypes.elementType,
Thumb: PropTypes.elementType,
Track: PropTypes.elementType,
ValueLabel: PropTypes.elementType,
}),
/**
* The extra props for the slot components.
* You can override the existing props or add new ones.
*
* This prop is an alias for the `slotProps` prop.
* It's recommended to use the `slotProps` prop instead, as `componentsProps` will be deprecated in the future.
*
* @default {}
*/
componentsProps: PropTypes.shape({
input: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
mark: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
markLabel: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
rail: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
root: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
thumb: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
track: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
valueLabel: PropTypes.oneOfType([
PropTypes.func,
PropTypes.shape({
children: PropTypes.element,
className: PropTypes.string,
open: PropTypes.bool,
style: PropTypes.object,
value: PropTypes.number,
valueLabelDisplay: PropTypes.oneOf(['auto', 'off', 'on']),
}),
]),
}),
/**
* If `true`, the component is disabled.
* @default false
Expand Down Expand Up @@ -964,15 +905,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.
* **Warning**: This is a generic event, not a change event.
* @param {number | number[]} 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 {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.
*/
onChangeCommitted: PropTypes.func,
Expand Down
Loading