-
-
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
Feature: add firstDayOfWeek prop #371
Conversation
Oh, I forgot to mention. This implementation also fixes a bug in an edge case I found: // We have Moment's global locale starting the week on Sundays
moment.locale('some-sunday-based-locale');
// For some reason in initialVisibleMonth we return a moment object set
// with another locale that starts the week on Mondays
<DayPicker initialVisibleMonth={() => moment().locale('some-monday-based-locale')} /> In |
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.
A few comments on the implementation.
Looks good overall tho, but it requires test coverage on all affected files.
src/components/CalendarMonth.jsx
Outdated
@@ -44,6 +45,7 @@ const defaultProps = { | |||
onDayMouseEnter() {}, | |||
onDayMouseLeave() {}, | |||
renderDay: null, | |||
firstDayOfWeek: moment.localeData().firstDayOfWeek(), |
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 will freeze the default at parse time (and the locale could be changed at any time) - i think this default needs to be calculated in the render path, and have it default to -1
or null
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.
Yeah, sure. I think null
is better.
src/components/CalendarMonthGrid.jsx
Outdated
@@ -52,6 +53,7 @@ const defaultProps = { | |||
onMonthTransitionEnd() {}, | |||
renderDay: null, | |||
transformValue: 'none', | |||
firstDayOfWeek: moment.localeData().firstDayOfWeek(), |
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.
same here
src/components/DayPicker.jsx
Outdated
@@ -65,6 +66,7 @@ const defaultProps = { | |||
onOutsideClick() {}, | |||
hidden: false, | |||
initialVisibleMonth: () => moment(), | |||
firstDayOfWeek: moment.localeData().firstDayOfWeek(), |
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.
and here
src/utils/getCalendarMonthWeeks.js
Outdated
export default function getCalendarMonthWeeks( | ||
month, | ||
enableOutsideDays, | ||
firstDayOfWeek = moment.localeData().firstDayOfWeek(), |
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.
can something validate that this value is an integer 0-6, and throw a TypeError if not?
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 thought about that, but I didn't see any other example of this kind of validation. Even here we call month.clone()
without knowing if month
is in fact a moment object. Moreover, like all these parameters of utils
functions, values came from component props that already pass by some propTypes
validation in dev.
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.
The propType should ensure that. I think that in general the utils functions should not assume safe inputs.
@daltones would you please rebase this branch to ensure there's no merge commits in it? |
d570d5b
to
4b38335
Compare
@ljharb done! |
src/components/CalendarMonth.jsx
Outdated
weeks: getCalendarMonthWeeks( | ||
props.month, | ||
props.enableOutsideDays, | ||
props.firstDayOfWeek === null ? moment.localeData().firstDayOfWeek() : props.firstDayOfWeek, |
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 should probably use == null
to avoid distinguishing from undefined
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.
Okay, I can do this. But you're saying just because code style? If firstDayOfWeek
has a defaultValue
set to null
, it would never be undefined
, 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.
I do think you're right; that a value of undefined
would trigger the default, and a value of null
would not, so === null would work fine - but in general for style, yes. Not a huge deal, ofc.
src/components/CalendarMonth.jsx
Outdated
weeks: getCalendarMonthWeeks( | ||
month, | ||
enableOutsideDays, | ||
firstDayOfWeek === null ? moment.localeData().firstDayOfWeek() : firstDayOfWeek, |
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
src/components/DayPicker.jsx
Outdated
@@ -350,11 +352,16 @@ export default class DayPicker extends React.Component { | |||
|
|||
const style = this.isHorizontal() ? horizontalStyle : {}; | |||
|
|||
let { firstDayOfWeek } = this.props; | |||
if (firstDayOfWeek === null) { |
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.
And here
@@ -52,6 +52,7 @@ const propTypes = forbidExtraProps({ | |||
onOutsideClick: PropTypes.func, | |||
renderDay: PropTypes.func, | |||
renderCalendarInfo: PropTypes.func, | |||
firstDayOfWeek: PropTypes.oneOf([0, 1, 2, 3, 4, 5, 6]), |
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 this propType should be shared and exported up from the components that need it - ie, this component shouldn't du-locate the definition, it should just import the propType from DayPicker and delegate the authority to it.
Same applies to any component where the prop is merely proxied down.
Effectively I'd prefer the oneOf to only appear in one place.
src/utils/getCalendarMonthWeeks.js
Outdated
const currentDay = firstOfMonth.clone(); | ||
let currentWeek = []; | ||
const weeksInMonth = []; | ||
const WEEKDAYS = [0, 1, 2, 3, 4, 5, 6]; |
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 this array be shared, and used inside the oneOf?
What's the current status of this PR? |
Hi @CarlRosell, I can take a look at this tomorrow/early next week. |
Hi there, is this feature in the todo pipeline? It would be great to see this one working, because our company need to set the first day to monday.... or is there another way to set this? |
dfbf84e
to
071d78b
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.
Seems legit to me!
@ljharb since I updated this PR with my own changes/rebase/etc. can you please sanity-check it for me before I merge it in? |
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.
LGTM pending the one test change
}); | ||
|
||
describe('locale with Monday as first day of week', () => { | ||
before(() => { |
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.
we need to use beforeEach
here; before
is beforeAll, and we don't want that.
const january2017End = january2017Start.clone().endOf('month'); // Tuesday | ||
|
||
describe('locale with Sunday as first day of week', () => { | ||
before(() => { |
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.
we need to use beforeEach
here; before
is beforeAll, and we don't want that.
071d78b
to
a870669
Compare
a870669
to
55c7d37
Compare
@ljharb addressed your comments! |
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.
K last thing, I swear :-)
src/shapes/DayOfWeekShape.js
Outdated
@@ -0,0 +1,5 @@ | |||
import { PropTypes } from 'react'; |
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 needs to use the prop-types package
…stDayOfWeek prop working with the SDP again
55c7d37
to
139e274
Compare
Naw this is good! You're catching all the things I've missed. :) I addressed the prop types issue @ljharb, can you take another look? |
🎉 |
…weekday generated from commit f149c68
Nice! Just in time for a component I'm doing in spanish ^^ Any ideas when this patch will be released? |
Should be live in v12.3.0! :) |
closes #128 Required an upgrade of react-dates, to include react-dates/react-dates#371
This PR tries to provide a solution to fix #363.
We urgently needed this feature in our app. Right now a forked
react-dates
with this implementation is running in production, all good. We use just<DayPicker />
components in two different pages.For now it's missing passing along propfirstDayOfWeek
fromDateRangePicker
andSingleDatePicker
and write some new tests for this functionality.The big change here is the [almost] rewrite of
getCalendarMonthWeeks
. The logic now is that every operation involving weekdays needs thefirstDayOfWeek
parameter (0-Sun...6-Sat locale independent). And thenfirstDayOfWeek
prop from components gets the default value according to Moment's global locale (so we're not breaking anything).I'd be happy if I receive feedback of this implementation. I'll update the PR very soon with the rest.