Skip to content
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

[Slider] Port component #11040

Merged
merged 13 commits into from
May 25, 2018
Merged

[Slider] Port component #11040

merged 13 commits into from
May 25, 2018

Conversation

epodivilov
Copy link
Contributor

@epodivilov epodivilov commented Apr 16, 2018

Added implementation of the Slider component according to the Google guidelines

image

PS: Something happened to my previous PR so I created a new one.

Closes #4793

@oliviertassinari oliviertassinari added component: slider This is the name of the generic UI component, not the React module! package: lab Specific to @mui/lab labels Apr 16, 2018
@mbrookes mbrookes self-requested a review April 16, 2018 21:44
@NayanSrivastav
Copy link

Thank @mbrookes for this, when can we expect this merge?

@epodivilov
Copy link
Contributor Author

@mbrookes what about this pull request?

@mbrookes
Copy link
Member

@epodivilov My task for this weekend.

@mbrookes
Copy link
Member

Okay, this is starting to take shape!

Keyboard input in the basic slider is 💯👌 , however mouse / touch input has the same granularity (1% step) as keyboard input, rather than being continuous, which gives a course feel to the movement. v0 had the same issue, so it would be good to address that here. It isn't a show-stopper, but I fear if we don't fix it now, it might get left like this.

Since you're using ButtonBase for the thumb, it would be preferable to use the focus ripple when keyboard focussed rather than a custom style.

The vertical slider seems backwards - I think the default should be from bottom-to-top, with reverse being top-to-bottom.

@Pajn pointed out that the use of top, left etc. for positioning is causing a performance hit. Did you have an opportunity to look at using transform: translate() and transform: scale()?

The testsh ave been renamed from .spec.js to .test.js

Once we get these last bits sorted, we can dig into code review (I have been focussing mostly on functionality).

Thanks for all your hard work! 👏

@epodivilov
Copy link
Contributor Author

@mbrookes Thanks for review.
First of all I would like to note that the ripple effect is not according to the google guidelines.
About performance issue I will try to check.

About mouse / touch behavior I have a question. Right now I round value to step. if you do not do this, then which sign is worth rounding? For example: I clicked roughly in the middle of the slider and got value 0.5987654321. Now I will return the value 0.59. But it same value, which you can get by keyboard.

@mbrookes
Copy link
Member

@epodivilov You're right, no ripple in the spec, or the MCW (or other) implementations. I'm a little surprised at that, as the ripple is designed as a visual affordance to make the focused component more obvious.

Regarding rounding the value - MCW don't round the value returned, so the developer can decide what precision to apply: https://material-components-web.appspot.com/slider.html

However unlike MCW, I believe we should round aria-valuenow to a sensible level of precision (3 digits?), so that a screen-reader user isn't potentially faced with an unending list of spoken digits if the screen-reader doesn't truncate it.

@mbrookes
Copy link
Member

mbrookes commented Apr 29, 2018

One other thing you can do as part of this PR is to update the Supported Components page. You can follow the SpeedDial example, but I think it would be a good idea to add the checkmark to both Slider and SpeedDial.

@mbrookes
Copy link
Member

mbrookes commented May 9, 2018

@epodivilov are you still working on this? It feels like we're very close to final review.

@epodivilov
Copy link
Contributor Author

@mbrookes Yes, I still working on this PR. I had a small vacation. I'll try to fix it this weekend.

@mbrookes
Copy link
Member

Thanks @epodivilov Hope you had a nice break! ☺️

@epodivilov
Copy link
Contributor Author

@mbrookes I fixed rounding of values and updated the Supported Components page. Please, review last updates

@mbrookes
Copy link
Member

@epodivilov Looks like something's gone wrong with the branch. You don't need to create a new PR, just clean up the brach and force push.

Copy link
Member

@mbrookes mbrookes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking great! Thanks for working on it.

import classNames from 'classnames';
import withStyles from '../../../material-ui/src/styles/withStyles';
import ButtonBase from '../../../material-ui/src/ButtonBase';
import { fade } from '../../../material-ui/src/styles/colorManipulator';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These should be imported as:

import withStyles from 'material-ui/styles/withStyles';

etc.

Thought we fixed this already, but hey! 😄

import withStyles from '../../../material-ui/src/styles/withStyles';
import ButtonBase from '../../../material-ui/src/ButtonBase';
import { fade } from '../../../material-ui/src/styles/colorManipulator';
import clamp from '../utils/clamp';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant for this to be in the core material-ui so we can reuse it there, but I can fix it up later.

@epodivilov
Copy link
Contributor Author

@mbrookes What does you mean "clean up the branch"? Like this https://stackoverflow.com/a/25357146 ?

@Pajn
Copy link
Contributor

Pajn commented May 12, 2018

I would personally rebase and squash but that is of coursee up to you what you are most comfortable with. The end result is a nice simple commit on top of the current v1-beta in both cases :)

@mbrookes
Copy link
Member

mbrookes commented May 12, 2018

@epodivilov it wasn't about squashing (we can do that at merge), but there were somehow a bunch of unrelated commits in the PR. I wasn't sure if a rebase would be sufficient, or whether you'd have to cherry-pick your commits back onto a clean branch so "clean up" meaning whatever it needed to get it back into a reviewable, mergeable state.

@oliviertassinari oliviertassinari changed the base branch from v1-beta to master May 12, 2018 18:20
@mbrookes mbrookes requested a review from oliviertassinari May 13, 2018 10:07
import PropTypes from 'prop-types';
import classNames from 'classnames';
import withStyles from '@material-ui/core/styles/withStyles';
import ButtonBase from '@material-ui/core//ButtonBase';
Copy link
Contributor

@goto-bus-stop goto-bus-stop May 13, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

core//ButtonBasecore/ButtonBase

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks.

onMouseDown={this.handleMouseDown}
onTouchStartCapture={this.handleTouchStart}
onTouchMove={this.handleMouseMove}
onKeyboardFocus={this.handleFocus}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

onKeyboardFocus was renamed to onFocusVisible in #11188

@goto-bus-stop
Copy link
Contributor

Just tried this again with @material-ui/[email protected], works great! (except for the onKeyboardFocus thing) Thanks for the work!

@epodivilov
Copy link
Contributor Author

@goto-bus-stop Great news. Should I fix something in my code, or do you fix it yourself? And when you plan to merge the PR?

@goto-bus-stop
Copy link
Contributor

Oh I don't know, I'm not a maintainer, just a user excited for this PR 😛

@mbrookes
Copy link
Member

@epodivilov Yes please, if you could rename that prop as @goto-bus-stop pointed out, that would be great! Sorry I missed it.

Copy link
Member

@oliviertassinari oliviertassinari left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just had a look at the source code. Thanks for taking the time to work on i!

@@ -0,0 +1,3 @@
export default function clamp(value, min = 0, max = 100) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can potentially be shared at some point with colorManipulator.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was the original intention - we have a clamp function in a couple of places. I plan to consolidate them once this is merged.

vertical,
reverse,
disabled,
} = this.props;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be great to spread the other properties on the root element.

onBlur={this.handleBlur}
onKeyDown={this.handleKeyDown}
onMouseDown={this.handleMouseDown}
onTouchStartCapture={this.handleTouchStart}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to trigger the event during the capture phase? It's the first time we do such.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to prevent page scrolling when moving the slider (function preventPageScrolling).I should catch event before preventing, so I use capture phase.

aria-orientation={vertical ? 'vertical' : 'horizontal'}
onClick={this.handleClick}
ref={node => {
this.container = findDOMNode(node);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default component is a div. I don't think that you need to call findDOMNode.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To prevent page scrolling, I need to catch touch events and prevent them from entering outside of the container. So I need get a link to container component.

};
};

const KEY_CODES = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is already packages into the keycode dependency. No need for duplicating it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can find many examples in the codebase.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replaced that code to keycode library

};

return {
/* Styles for wrapper container */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wish we will be able to extra these comments and add it to the API documentation automatically 💯 at some point.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not understand, should I remove this comments?

margin: '10px 0',
padding: '6px 0',
cursor: 'pointer',
'-webkit-tap-highlight-color': 'transparent',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WebkitTapHighlightColor: 'transparent',

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For consistency, like we need everywhere else.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed it

ARROW_DOWN: 40,
};

function addEventListener(node, event, handler, capture) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the capture argument is never used.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By the way. I'm not sure you need this helper function.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is used to detect movement of the mouse outside the component, as well as to detect the termination of interaction with the component. So I can remove unused argument, but I think is not a problem. If this function move to all helpers function somebody might need this parameter.

};
}

const calculatePercent = (node, event, isVertical, isReverted) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are using a function with the other helpers, not an arrow, maybe we should be consistent.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed it

@mbrookes
Copy link
Member

@oliviertassinari Any last comments?

this.globalMouseUpListener = addEventListener(document, 'touchend', this.handleMouseUp);

if (typeof this.props.onDragEnd === 'function') {
this.props.onDragStart(event);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean to test for onDragEnd here? Or onDragStart?

this.globalMouseMoveListener = addEventListener(document, 'mousemove', this.handleMouseMove);

if (typeof this.props.onDragEnd === 'function') {
this.props.onDragStart(event);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean to test for onDragEnd here? Or onDragStart?

@oliviertassinari
Copy link
Member

@mbrookes None :)

@mbrookes mbrookes merged commit 0b63c30 into mui:master May 25, 2018
@mbrookes
Copy link
Member

@epodivilov Thanks for all your hard work, and sticking with it! An amazing contribution for your first!

@acroyear

This comment has been minimized.

@oliviertassinari oliviertassinari added new feature New feature or request and removed package: lab Specific to @mui/lab labels Jan 9, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: slider This is the name of the generic UI component, not the React module! new feature New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants