-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
Conversation
b8cf807
to
d3d5b3a
Compare
There was a problem hiding this 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?
@lencioni yup! That is on my TODO. :) |
@@ -118,12 +116,44 @@ export default class CalendarDay extends React.Component { | |||
height: daySize - 1, | |||
}; | |||
|
|||
const useDefaultCursor = |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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)
src/shapes/withStylesPropTypes.js
Outdated
@@ -0,0 +1,8 @@ | |||
import PropTypes from 'prop-types'; |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
src/components/CalendarDay.jsx
Outdated
@@ -174,6 +174,7 @@ class CalendarDay extends React.Component { | |||
CalendarDay.propTypes = propTypes; | |||
CalendarDay.defaultProps = defaultProps; | |||
|
|||
export { CalendarDay as PureCalendarDay }; |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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')
.storybook-css/config.js
Outdated
|
||
addDecorator((story) => { | ||
moment.locale('en'); | ||
return (story()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why the parens?
.storybook-css/config.js
Outdated
overflow: 'scroll', | ||
}} | ||
> | ||
<span dangerouslySetInnerHTML={{ __html: helperText }} /> |
There was a problem hiding this comment.
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?
.storybook/webpack.config.js
Outdated
@@ -4,10 +4,9 @@ module.exports = { | |||
module: { | |||
rules: [ | |||
{ | |||
test: /\.scss$/, | |||
test: /(\.scss$|\.css$)/, |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
src/components/DayPicker.jsx
Outdated
} | ||
|
||
const verticalScrollable = orientation === VERTICAL_SCROLLABLE; | ||
if (verticalScrollable) firstVisibleMonthIndex = 0; |
There was a problem hiding this comment.
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;
?
src/components/DayPicker.jsx
Outdated
this.calendarMonthGridHeight = calendarMonthHeights.reduce((maxHeight, height, i) => { | ||
const isVisible = | ||
(i >= firstVisibleMonthIndex) && (i < firstVisibleMonthIndex + numberOfMonths); | ||
return isVisible ? Math.max(maxHeight, height) : maxHeight; |
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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}`]) + |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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="تقویم فارسی" |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
b9e79be
to
5ec30b3
Compare
yellow_dark: '#ffce71', | ||
}; | ||
|
||
export default { |
There was a problem hiding this comment.
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: ...,
...
},
};
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
882b2b3
to
4407874
Compare
.storybook-css/addons.js
Outdated
@@ -0,0 +1,4 @@ | |||
/* eslint-disable import/no-extraneous-dependencies, import/extensions */ |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(but they are necessary)
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
aren't they separate packages? https://www.npmjs.com/package/@storybook/addon-actions and https://www.npmjs.com/package/@storybook/addon-links
There was a problem hiding this comment.
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.
scripts/buildCSS.js
Outdated
const fs = require('fs'); | ||
const CleanCSS = require('clean-css'); | ||
|
||
const CSSInterface = require('react-with-styles-interface-css').default; |
There was a problem hiding this comment.
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')
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
airbnb/react-with-styles-interface-css#8 should fix some things!
scripts/buildCSS.js
Outdated
|
||
require('../test/_helpers/ignoreSVGStrings'); | ||
|
||
registerMaxSpecificity(11); |
There was a problem hiding this comment.
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?)
There was a problem hiding this comment.
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
scripts/buildCSS.js
Outdated
registerMaxSpecificity(11); | ||
registerInterfaceWithDefaultTheme(CSSInterface); | ||
|
||
const DateRangePickerPath = './src/components/DateRangePicker.jsx'; |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
scripts/buildCSS.js
Outdated
|
||
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; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
src/components/CalendarMonthGrid.jsx
Outdated
setMonthHeight(height, i) { | ||
if (this.calendarMonthHeights[i]) { | ||
if (i === 0) { | ||
this.calendarMonthHeights = [height, ...this.calendarMonthHeights.slice(0, -1)]; |
There was a problem hiding this comment.
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 }; |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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 }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also here
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
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" |
There was a problem hiding this comment.
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
4407874
to
eab055e
Compare
eab055e
to
312cdd0
Compare
|
||
const compileCSS = require('react-with-styles-interface-css/compile'); | ||
|
||
const registerMaxSpecificity = require('react-with-styles-interface-css/dist/utils/registerMaxSpecificity').default; |
There was a problem hiding this comment.
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? :-(
…use react-with-styles
312cdd0
to
177bf03
Compare
This comment has been minimized.
This comment has been minimized.
@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 I'd love to answer more specific questions if you have them in a new issue. :) |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
@adamchenwei can you please open an issue so we can continue this discussion there where it's a bit more discoverable? :) |
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.
I think we might want to export a CSS-styles version of the code as well as the vanilla versionto: @ljharb @airbnb/webinfra @lencioni @adamrneary @sdjidjev