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

[Dialog] create responsive HOC withResponsiveFullScreen #6898

Merged
merged 4 commits into from May 20, 2017

Conversation

rosskevin
Copy link
Member

@rosskevin rosskevin commented May 18, 2017

The spec discusses that Dialogs should be full screen on mobile. As such, I have defaulted the Dialog to be responsively fullScreen at or below the sm breakpoint.

You may specify a different breakpoint or force it fullScreen with true.

Other changes:

  • flow - configured suppression comments and converted a few more components
  • mocha/package.json - specifying file patterns in mocha.opts means that all these files are processed every time - good for CI, really bad when you are trying to debug a single test. I have moved the spec file patterns back to the scripts section in package.json accordingly.

  • PR has tests / docs demo, and is linted.
  • Commit and PR titles begin with [ComponentName], and are in imperative form: "[Component] Fix leaky abstraction".
  • Description explains the issue / use-case resolved, and auto-closes the related issue(s) (http://tr.im/vFqem).

@rosskevin rosskevin added component: dialog This is the name of the generic UI component, not the React module! next labels May 18, 2017
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.

Some early feedback (haven't look in detail).
Also, I'm not convinced about the new default behaviour of the Dialog. Taking my Android phone, there is many screens where the Dialog isn't full screen on mobile.

@@ -1,14 +1,15 @@
// @flow weak

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import React, { PureComponent, Element } from 'react';
Copy link
Member

Choose a reason for hiding this comment

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

I don't think that we need any pure logic inside Material-UI, our components are too low level to be efficient.

@@ -46,6 +47,111 @@ export const styleSheet = createStyleSheet('MuiDialog', (theme) => {
};
});

type MaxWidthBreakpoints = 'xs' | 'sm' | 'md';
Copy link
Member

Choose a reason for hiding this comment

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

To verify but I don't think that https://github.com/brigand/babel-plugin-flow-react-proptypes can handle the indirection resulting in .any.

@oliviertassinari
Copy link
Member

oliviertassinari commented May 18, 2017

really bad when you are trying to debug a single test.

You can use the .only helper, actually, I'm using that everytime.

@oliviertassinari
Copy link
Member

From my perspective, the fullscreen mode is an escape hatch for people looking for a quick way to implement that on mobile. That's why I'm not 100% regarding promoting it as a default. From my work on the mobile version of https://www.doctolib.fr/, I would definitely not use it when implementing transitions between my routes or even for the layout of my screens. Still, I understand that it's quite useful!

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.

Did an in-depth review. Think that we have the opportunity to build a great Higher-order Component with that breakpoint concern 😄 . I'm happy to see that concern raised! Also, great to see more propTypes migrated to flow.

## Full-screen dialogs
## Responsive full-screen dialogs

By default, dialogs are responsively full screened *at or below* the `sm` [screen size](/layout/basics). You may alter the breakpoint or force it to be full screen at all times as shown here.
Copy link
Member

Choose a reason for hiding this comment

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

Double spaces?

*/
children?: Element<*>,
/**
* The CSS class name of the root element.
Copy link
Member

Choose a reason for hiding this comment

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

What do you think about using @ignore? This is quite idiomatic and standard in the ecosystem. Why documenting it?

static defaultProps = {
fullScreen: false,
static defaultProps: DefaultProps = {
fullScreen: 'sm',
Copy link
Member

Choose a reason for hiding this comment

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

What do you think of the UI? I'm not sure it's in the specification.
mai-19-2017 09-15-29

Copy link
Member

Choose a reason for hiding this comment

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

Also, this default value isn't SSR compliant.

@@ -237,3 +265,5 @@ export default class Dialog extends Component {
);
}
}

export default withWidth()(Dialog);
Copy link
Member

Choose a reason for hiding this comment

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

What about using a decorator instead? Something that we could be using to switch properties off and on based on the breakpoint? I see many use cases for that new Higher-order Component.

@muibot muibot added the PR: out-of-date The pull request has merge conflicts and can't be merged label May 19, 2017
@rosskevin
Copy link
Member Author

Ok, I was trying to be incremental @oliviertassinari ;), but now is as good of a time as any to review and revise.

Types of Dialogs:

  • Alert - requires button press (no backdrop click listener for dismissal), not fullScreen.
  • Simple - no cancelation, no buttons, not fullScreen
  • Confirmation - requires cancel/ok, not fullScreen
  • FullScreen - is fullScreen!

Responsive

So the fullScreen spec cases do look very intentional, which makes me think the responsiveDialog HOC makes a great deal of sense, that's a good suggestion.

Back to types

It seems like it makes sense for /Dialog to export at least a spec compliant Alert (with ignoreBackdropClick: true and perhaps others as-needed if we spot something in the spec.

I'll start revising.

@muibot muibot added PR: needs revision The pull request can't be merged. More details is available on the code review or fails in the CI PR: Needs Review and removed PR: out-of-date The pull request has merge conflicts and can't be merged labels May 19, 2017
@rosskevin rosskevin changed the title [Dialog] make fullScreen responsive WIP [Dialog] make fullScreen responsive May 19, 2017
* Dialog will responsively be full screen _at or below_ the given breakpoint
* (defaults to 'sm' for mobile devices).
*/
function withResponsiveFullScreen(options: Options = { breakpoint: 'sm' }) {
Copy link
Member

Choose a reason for hiding this comment

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

Yeah, I like this Higher-order Component ❤️ . We could imagine making it even more generic with a property modifier function. Some idead I have in mind. I'm not saying it should be like this.

import Dialog from 'material-ui/Dialog'
import withResponsiveProps from 'material-ui/utils/withResponsiveProps'

const ResponsiveDialog = withResponsiveProps({
  breakpoints: 'md',
  switch: (props, match) => ({
    fullscrean: match ? true : false,
    ...props,
  })
})(Dialog)

or

import Dialog from 'material-ui/Dialog'
import ResponsiveProps from 'material-ui/utils/withResponsiveProps'

<ResponsiveProps
  breakpoints="md"
  switch={(props, match) => ({
    fullscrean: match ? true : false,
  })}
>
  <Dialog />
</ResponsiveProps>

Copy link
Member

Choose a reason for hiding this comment

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

Still, I think that we can merge that HOC as already providing value and elegant 😄 .

@oliviertassinari
Copy link
Member

A rebase would be great, I'm a bit lost in the diff. Aside from that, I don't have much feedback. I think that we are going in the right direction 😄 .

@rosskevin
Copy link
Member Author

The only with the solution up is that you have to think about only | isWidthUp | isWidthDown. While it might make sense to have something internal, I think the external facing usages need to be concrete. The future may prove me wrong though.

I'm going to get this rebase figured out.

@rosskevin rosskevin changed the title WIP [Dialog] make fullScreen responsive [Dialog] create responsive HOC withResponsiveFullScreen May 19, 2017
@rosskevin
Copy link
Member Author

I'm working on spec Alert vs Confirmation vs Simple Dialog in another PR, but it will be branched from this.

@rosskevin rosskevin removed the PR: needs revision The pull request can't be merged. More details is available on the code review or fails in the CI label May 19, 2017
@rosskevin rosskevin dismissed oliviertassinari’s stale review May 19, 2017 22:16

Review items implemented.

@@ -2,5 +2,3 @@
--reporter dot
--recursive
test/utils/setup.js
test/integration/{,**/}*.spec.js
Copy link
Member

Choose a reason for hiding this comment

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

Did you try the only thing? Now we have that config at three different locations, not great.

Copy link
Member Author

Choose a reason for hiding this comment

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

I use a jetbrains IDE, and that doesn't seem to be an option. Up to this point I have been deleting the offending code and avoiding committing it. While I very much dislike duplication, it seems necessary here.

onExited?: Function, // eslint-disable-line react/sort-prop-types
};

export default class Fade extends PureComponent<DefaultProps, Props, void> {
Copy link
Member

Choose a reason for hiding this comment

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

As a rule of thumb, we should not use any pure logic with components accepting react elements. They are created at each render, making strict comparison always negative (in some rare cases true when the element is hoisted outside of the render method), hence, wasted CPU cycles.

Copy link
Member Author

Choose a reason for hiding this comment

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

This was a Component as was the other you mentioned, so you could say this is an improvement over there former. This time there is quite more in the body of the class where I much prefer class closure from a source perspective. Let's be a bit incremental about the codebase, I unfortunately don't always have time to take the former code and make every PR exactly inline. Each PR author needs to be able to improve the code an increment without taking on a burden of everything that might be wrong with a file.

* Dialog will responsively be full screen _at or below_ the given breakpoint
* (defaults to 'sm' for mobile devices).
*/
function withResponsiveFullScreen(options: Options = { breakpoint: 'sm' }) {
Copy link
Member

Choose a reason for hiding this comment

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

Still, I think that we can merge that HOC as already providing value and elegant 😄 .

@@ -46,6 +45,92 @@ export const styleSheet = createStyleSheet('MuiDialog', (theme) => {
};
});

type Props = {
Copy link
Member

Choose a reason for hiding this comment

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

Hold on with the flow migration, I'm refactoring all the components to use withStyles. Let's try to avoid conflict 🙈 .

Copy link
Member Author

Choose a reason for hiding this comment

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

I'm going to merge this as I've already had a rebase nightmare with it. Will hold off on more, and we can discuss any other things that need to be done on gutter and I'll get to it on Monday. Thanks for all the feedback, all good things and this code is better for it!

@rosskevin rosskevin merged commit e004435 into mui:next May 20, 2017
@rosskevin rosskevin deleted the responsive-dialog branch June 14, 2017 15:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: dialog This is the name of the generic UI component, not the React module!
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants