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

Convert react-dates to use react-with-styles #722

Merged
merged 23 commits into from
Oct 5, 2017

Conversation

majapw
Copy link
Collaborator

@majapw majapw commented Sep 22, 2017

This change moves react-dates onto Airbnb's modern best practices of CSS in your Javascript!

Because this is again a huge change, it is best viewed on a commit by commit level (which I've tried to split up by component).

While this transformation of the code is complete, there are still a number of things to be done.

  • Documentation! How do you use react-with-styles?
  • More customization! I think we should identify overrides that might be useful in the theme since you can't go about overriding everything willy-nilly anymore
  • I think we might want to export a CSS-styles version of the code as well as the vanilla version
  • TESTS DON'T WORK ANYMORE. I need to fix that.
  • Once tests are running, probably some of them will be broken
  • there is a weird flash before the height of the calendar month grid is set now... we should address that.

to: @ljharb @airbnb/webinfra @lencioni @adamrneary @sdjidjev

@coveralls
Copy link

Coverage Status

Coverage decreased (-83.4%) to 3.06% when pulling fc964d6 on maja-implement-with-styles into c464d43 on master.

@majapw majapw force-pushed the maja-implement-with-styles branch 2 times, most recently from b8cf807 to d3d5b3a Compare September 29, 2017 00:13
@coveralls
Copy link

Coverage Status

Coverage increased (+0.6%) to 86.994% when pulling d3d5b3a on maja-implement-with-styles into 0f6cccc on master.

Copy link
Contributor

@lencioni lencioni left a comment

Choose a reason for hiding this comment

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

I haven't looked at the diff very closely yet, but this change should probably also update documentation to help people customize, right?

@majapw
Copy link
Collaborator Author

majapw commented Sep 29, 2017

@lencioni yup! That is on my TODO. :)

@coveralls
Copy link

Coverage Status

Coverage increased (+0.2%) to 86.53% when pulling 52de5ce on maja-implement-with-styles into 0f6cccc on master.

@@ -118,12 +116,44 @@ export default class CalendarDay extends React.Component {
height: daySize - 1,
};

const useDefaultCursor =
Copy link
Collaborator

Choose a reason for hiding this comment

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

As we discussed, maybe worth converting these modifiers to boolean properties or something similar. Might be an easier interface + more intuitive.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think we can do this in a follow-up PR (and one that is slightly less overwhelming to read)

@@ -0,0 +1,8 @@
import PropTypes from 'prop-types';
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why pull this out of react-with-styles?

Copy link
Member

Choose a reason for hiding this comment

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

yeah that's actually a good question; can't we import from there instead?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

react-with-styles doesn't actually have this file. :P We fake it in our own internal repo. Probably the right thing to do is to add it to react-with-styles

Copy link
Member

Choose a reason for hiding this comment

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

aha, yes let's please do that asap :-D

@@ -174,6 +174,7 @@ class CalendarDay extends React.Component {
CalendarDay.propTypes = propTypes;
CalendarDay.defaultProps = defaultProps;

export { CalendarDay as PureCalendarDay };
Copy link
Collaborator

Choose a reason for hiding this comment

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

Could Pure be a misleading term here? Maybe overloaded

Copy link
Member

Choose a reason for hiding this comment

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

wait, why are we exporting this at all? best practice is to only use .dive() to get at the unwrapped component

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

because we are spying on prototype methods. dive doesn't solve that issue afaik, does 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 have me there.

any way we could avoid the spying?

it'd be ugly but we could const Pure = shallow(<Wrapped />).dive().type(); sinon.spy(Pure.prototype, 'foo')


addDecorator((story) => {
moment.locale('en');
return (story());
Copy link
Member

Choose a reason for hiding this comment

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

why the parens?

overflow: 'scroll',
}}
>
<span dangerouslySetInnerHTML={{ __html: helperText }} />
Copy link
Member

Choose a reason for hiding this comment

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

why inside the span, and not directly inside the div?

@@ -4,10 +4,9 @@ module.exports = {
module: {
rules: [
{
test: /\.scss$/,
test: /(\.scss$|\.css$)/,
Copy link
Member

Choose a reason for hiding this comment

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

/\.s?css$/? (if we're going to use the parens, we'd want (?: to make the group non-capturing)

css/styles.css Outdated
@@ -0,0 +1,18876 @@
.DateRangePicker {
position: relative;
display: inline-block
Copy link
Member

Choose a reason for hiding this comment

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

super sad that this output lacks a final semicolon

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This file is autogenerated and that process still needs some improvements --- namely on collapsing style definitions as well as best practices for styling. X_x

I think I have also committed the unoptimized version here which I ... probably don't want?

I think I should just .gitignore this file tbh.

Copy link
Member

Choose a reason for hiding this comment

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

yeah that's a good idea, good call

css/styles.css Outdated
direction: rtl
}
.DateRangePicker_picker__directionLeft {
left: 0px
Copy link
Member

Choose a reason for hiding this comment

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

also that zero values have units

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

again this is due partly to the autogeneration of this file and i need to... probably clean it up a bit more/read more into clean-css options.

}

const verticalScrollable = orientation === VERTICAL_SCROLLABLE;
if (verticalScrollable) firstVisibleMonthIndex = 0;
Copy link
Member

Choose a reason for hiding this comment

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

if (orientation === VERTICAL_SCROLLABLE) return 0;?

this.calendarMonthGridHeight = calendarMonthHeights.reduce((maxHeight, height, i) => {
const isVisible =
(i >= firstVisibleMonthIndex) && (i < firstVisibleMonthIndex + numberOfMonths);
return isVisible ? Math.max(maxHeight, height) : maxHeight;
Copy link
Member

Choose a reason for hiding this comment

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

Math.max(...calendarMonthHeights.filter((, i) => (i >= firstVisibleMonthIndex) && (i < firstVisibleMonthIndex + numberOfMonths))?

@@ -128,42 +105,61 @@ export default class DayPickerKeyboardShortcuts extends React.Component {
? phrases.hideKeyboardShortcutsPanel
: phrases.showKeyboardShortcutsPanel;

const bottomRight = (buttonLocation === BOTTOM_RIGHT);
Copy link
Member

Choose a reason for hiding this comment

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

all these parens are redundant

// Get the inner size
if (!borderBox) {
size -= (
parseFloat(style[`padding${axisStart}`]) +
Copy link
Member

Choose a reason for hiding this comment

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

does this need to pivot based on RTL?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I do not believe so (or at the least, react-dates currently still works as expected with the isRTL prop). However, I am pegging to the old version of RWS-IA for this change and will come back to the question of RTL support with the new interface in a follow-up PR. :)

@@ -83,7 +83,6 @@ storiesOf('DateRangePicker (DRP)', module)
moment.locale('fa');
return (
<DateRangePickerWrapper
placeholder="تقویم فارسی"
Copy link
Member

Choose a reason for hiding this comment

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

isn't the goal here to have farsi/arabic in the example? why remove the placeholder?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This didn't actually do anything. placeholder is not a valid prop on the DRP and the text itself translates to Farsi Calendar which is not a meaningful value for the startDatePlaceholderText or the endDatePlaceholderText props.

Copy link
Member

Choose a reason for hiding this comment

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

👍

@majapw majapw force-pushed the maja-implement-with-styles branch 2 times, most recently from b9e79be to 5ec30b3 Compare October 4, 2017 22:06
@majapw
Copy link
Collaborator Author

majapw commented Oct 4, 2017

@ljharb @gabergg I believe I've addressed all of your comments.

yellow_dark: '#ffce71',
};

export default {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

One of the things I was thinking about was that... if we're importing this into a project that uses many react-with-styles packages and we need to register the theme, we should probably namespace the theme so that there are no collisions. Something like:

export default {
  reactDates: { 
    color: ...,
    zIndex: ...,
    ...
  },
};

@gabergg @lencioni @ljharb what do you think?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yep, I think it should definitely be namespaced.

Copy link
Member

Choose a reason for hiding this comment

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

I'm confused, why should it be namespaced?

This module exports a theme directly; wouldn't whoever registered the theme be able to install it under a key themselves?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

But the components themselves would be expecting the color, zIndex, etc. keys directly and there'd be no way to change that.

Copy link
Member

Choose a reason for hiding this comment

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

gotcha. maybe it'd be better to have withStyles support a "namespace" option or something, but this is fine for now i guess.

@coveralls
Copy link

Coverage Status

Coverage increased (+0.3%) to 86.695% when pulling 5ec30b3 on maja-implement-with-styles into a7747ea on master.

@coveralls
Copy link

Coverage Status

Coverage increased (+0.3%) to 86.695% when pulling 5ec30b3 on maja-implement-with-styles into a7747ea on master.

@majapw majapw force-pushed the maja-implement-with-styles branch 2 times, most recently from 882b2b3 to 4407874 Compare October 4, 2017 22:45
@coveralls
Copy link

Coverage Status

Coverage increased (+0.3%) to 86.695% when pulling 4407874 on maja-implement-with-styles into a7747ea on master.

@coveralls
Copy link

Coverage Status

Coverage increased (+0.3%) to 86.695% when pulling 4407874 on maja-implement-with-styles into a7747ea on master.

@@ -0,0 +1,4 @@
/* eslint-disable import/no-extraneous-dependencies, import/extensions */
Copy link
Member

Choose a reason for hiding this comment

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

why are these deps extraneous?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

They're never used directly!

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

(but they are necessary)

Copy link
Member

Choose a reason for hiding this comment

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

They're imported here; "extraneous" means they're not in package.json. If they're necessary, why can't they be in package.json?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

So the thing is... they come with @storybook/react but they have namespacing that makes eslint think they're separate packages. idk man, i blame storybook for this one, but this is what you have to do to get them to work.

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I don't believe they were when I first put together this addons.js file/updated storybook in this package. It's possible this has changed in newer versions.

This is literally just a copy of what's in .storybook which is the default config.

const fs = require('fs');
const CleanCSS = require('clean-css');

const CSSInterface = require('react-with-styles-interface-css').default;
Copy link
Member

Choose a reason for hiding this comment

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

wait; this is a bug in the css interface. There should never be a default property on module.exports for a package's entry point :-/

It's possible your addition of registerMaxSpecificity caused this; if so, maybe we should remove it and have it be under a different entry point (require('react-with-styles-interface-css/registerMaxSpecificity'))

Copy link
Collaborator Author

Choose a reason for hiding this comment

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


require('../test/_helpers/ignoreSVGStrings');

registerMaxSpecificity(11);
Copy link
Member

Choose a reason for hiding this comment

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

why is this turned up to eleven?

(no but seriously, why the magic number?)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I should leave a comment. The number comes from the maximum number of styles passed into any css call in this repo

registerMaxSpecificity(11);
registerInterfaceWithDefaultTheme(CSSInterface);

const DateRangePickerPath = './src/components/DateRangePicker.jsx';
Copy link
Member

Choose a reason for hiding this comment

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

don't you want to pull in the babel output, not the raw code?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I don't... think so. At least, that's not what the css interface uses as its tests.


const CSSInterface = require('react-with-styles-interface-css').default;
const registerMaxSpecificity = require('react-with-styles-interface-css').registerMaxSpecificity;
const compileCSS = require('react-with-styles-interface-css/compile').default;
Copy link
Member

Choose a reason for hiding this comment

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

also here

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

setMonthHeight(height, i) {
if (this.calendarMonthHeights[i]) {
if (i === 0) {
this.calendarMonthHeights = [height, ...this.calendarMonthHeights.slice(0, -1)];
Copy link
Member

Choose a reason for hiding this comment

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

it's slightly more efficient here to do [height].concat(this.calendarMonthHeights.slice(0, -1))

@@ -898,3 +813,110 @@ export default class DayPicker extends React.Component {

DayPicker.propTypes = propTypes;
DayPicker.defaultProps = defaultProps;

export { DayPicker as PureDayPicker };
Copy link
Member

Choose a reason for hiding this comment

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

i think i called this out before; this is just to spy on instance methods in tests, yes?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes

@@ -479,3 +472,82 @@ export default class SingleDatePicker extends React.Component {

SingleDatePicker.propTypes = propTypes;
SingleDatePicker.defaultProps = defaultProps;

export { SingleDatePicker as PureSingleDatePicker };
Copy link
Member

Choose a reason for hiding this comment

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

also here

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Also yes

yellow_dark: '#ffce71',
};

export default {
Copy link
Member

Choose a reason for hiding this comment

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

I'm confused, why should it be namespaced?

This module exports a theme directly; wouldn't whoever registered the theme be able to install it under a key themselves?

test/.eslintrc Outdated
"indent": [2, 2, {
"MemberExpression": "off"
}],
"MemberExpression": "off"
Copy link
Member

Choose a reason for hiding this comment

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

these two lines have tab chars; please make them spaces

@coveralls
Copy link

Coverage Status

Coverage increased (+0.3%) to 86.695% when pulling eab055e on maja-implement-with-styles into a7747ea on master.

@majapw
Copy link
Collaborator Author

majapw commented Oct 5, 2017

@ljharb @gabergg @lencioni I am fishing for a stamp! :) I think I have addressed all comments.

@coveralls
Copy link

Coverage Status

Coverage increased (+0.3%) to 86.695% when pulling 312cdd0 on maja-implement-with-styles into a7747ea on master.

ljharb
ljharb previously approved these changes Oct 5, 2017

const compileCSS = require('react-with-styles-interface-css/compile');

const registerMaxSpecificity = require('react-with-styles-interface-css/dist/utils/registerMaxSpecificity').default;
Copy link
Member

Choose a reason for hiding this comment

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

oh noes, there's still dot defaults? :-(

@coveralls
Copy link

Coverage Status

Coverage increased (+0.3%) to 86.733% when pulling 177bf03 on maja-implement-with-styles into b737a8e on master.

@majapw majapw merged commit a569622 into master Oct 5, 2017
@majapw majapw deleted the maja-implement-with-styles branch October 5, 2017 23:45
@adamchenwei

This comment has been minimized.

@majapw
Copy link
Collaborator Author

majapw commented Mar 20, 2018

@adamchenwei this PR was merged in in October and has been in active use since then... Have you read through the README, specifically this section: https://github.com/airbnb/react-dates#initialize?

There's also a bit more context on the transition to react-with-styles in https://github.com/airbnb/react-dates#advanced.

I'd love to answer more specific questions if you have them in a new issue. :)

@adamchenwei

This comment has been minimized.

@adamchenwei

This comment has been minimized.

@majapw
Copy link
Collaborator Author

majapw commented Mar 21, 2018

@adamchenwei can you please open an issue so we can continue this discussion there where it's a bit more discoverable? :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants