Skip to content

Commit

Permalink
Merge pull request #2899 from Apercu/master
Browse files Browse the repository at this point in the history
[DatePicker] Add firstDayOfWeek and days abbreviations
  • Loading branch information
oliviertassinari committed Jan 18, 2016
2 parents adece6e + 2841775 commit aa059c7
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const DatePickerExampleInternational = () => (
// Intl is supported by most modern browsers, see http://caniuse.com/#search=intl
// for browsers that don't support it use this polyfill https://github.com/andyearnshaw/Intl.js
wordings={{ok: 'OK', cancel: 'Annuler'}}
firstDayOfWeek={1}
locale="fr"
/>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const descriptions = {
ranged: 'This example allows you to set a date range, and to toggle `AutoOk`, and `disableYearSelection`.',
controlled: 'Implements a controlled input, where the value is handled by state in the parent (example) component.',
localised: 'Demonstrates a localised `DatePicker`, in this case in French. ' +
'Note that the buttons must be localised using the `wordings` property.',
'Note that the buttons must be localised using the `wordings` property and we set the `firstDayOfWeek` to Monday.',
};

if (!window.Intl) {
Expand Down
3 changes: 2 additions & 1 deletion src/date-picker/calendar-month.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const CalendarMonth = React.createClass({
propTypes: {
autoOk: React.PropTypes.bool,
displayDate: React.PropTypes.object.isRequired,
firstDayOfWeek: React.PropTypes.number,
maxDate: React.PropTypes.object,
minDate: React.PropTypes.object,
onDayTouchTap: React.PropTypes.func,
Expand All @@ -20,7 +21,7 @@ const CalendarMonth = React.createClass({
},

_getWeekElements() {
let weekArray = DateTime.getWeekArray(this.props.displayDate);
let weekArray = DateTime.getWeekArray(this.props.displayDate, this.props.firstDayOfWeek);

return weekArray.map((week, i) => {
return (
Expand Down
19 changes: 11 additions & 8 deletions src/date-picker/calendar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,14 @@ import ClearFix from '../clearfix';
import ThemeManager from '../styles/theme-manager';
import DefaultRawTheme from '../styles/raw-themes/light-raw-theme';

const daysArray = [...Array(7)];

const Calendar = React.createClass({

propTypes: {
DateTimeFormat: React.PropTypes.func.isRequired,
disableYearSelection: React.PropTypes.bool,
firstDayOfWeek: React.PropTypes.number,
initialDate: React.PropTypes.object,
locale: React.PropTypes.string.isRequired,
maxDate: React.PropTypes.object,
Expand Down Expand Up @@ -243,7 +246,7 @@ const Calendar = React.createClass({

render() {
let yearCount = DateTime.yearDiff(this.props.maxDate, this.props.minDate) + 1;
let weekCount = DateTime.getWeekArray(this.state.displayDate).length;
let weekCount = DateTime.getWeekArray(this.state.displayDate, this.props.firstDayOfWeek).length;
let toolbarInteractions = this._getToolbarInteractions();
let isLandscape = this.props.mode === 'landscape';
let styles = {
Expand Down Expand Up @@ -295,6 +298,7 @@ const Calendar = React.createClass({
const {
DateTimeFormat,
locale,
firstDayOfWeek,
} = this.props;

return (
Expand Down Expand Up @@ -325,13 +329,11 @@ const Calendar = React.createClass({
elementType="ul"
style={styles.weekTitle}
>
<li style={weekTitleDayStyle}>S</li>
<li style={weekTitleDayStyle}>M</li>
<li style={weekTitleDayStyle}>T</li>
<li style={weekTitleDayStyle}>W</li>
<li style={weekTitleDayStyle}>T</li>
<li style={weekTitleDayStyle}>F</li>
<li style={weekTitleDayStyle}>S</li>
{daysArray.map((e, i) => (
<li key={i} style={weekTitleDayStyle}>
{DateTime.localizedWeekday(DateTimeFormat, locale, i, firstDayOfWeek)}
</li>
))}
</ClearFix>
<SlideInTransitionGroup direction={this.state.transitionDirection}>
<CalendarMonth
Expand All @@ -343,6 +345,7 @@ const Calendar = React.createClass({
minDate={this.props.minDate}
maxDate={this.props.maxDate}
shouldDisableDate={this.props.shouldDisableDate}
firstDayOfWeek={this.props.firstDayOfWeek}
/>
</SlideInTransitionGroup>
</div>
Expand Down
3 changes: 3 additions & 0 deletions src/date-picker/date-picker-dialog.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const DatePickerDialog = React.createClass({
autoOk: React.PropTypes.bool,
container: React.PropTypes.oneOf(['dialog', 'inline']),
disableYearSelection: React.PropTypes.bool,
firstDayOfWeek: React.PropTypes.number,
initialDate: React.PropTypes.object,
locale: React.PropTypes.string,
maxDate: React.PropTypes.object,
Expand Down Expand Up @@ -151,6 +152,7 @@ const DatePickerDialog = React.createClass({
onAccept,
style,
container,
firstDayOfWeek,
...other,
} = this.props;

Expand Down Expand Up @@ -216,6 +218,7 @@ const DatePickerDialog = React.createClass({
>
<Calendar
DateTimeFormat={DateTimeFormat}
firstDayOfWeek={firstDayOfWeek}
locale={locale}
ref="calendar"
onDayTouchTap={this._onDayTouchTap}
Expand Down
10 changes: 10 additions & 0 deletions src/date-picker/date-picker.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@ const DatePicker = React.createClass({
*/
disableYearSelection: React.PropTypes.bool,

/**
* Used to change the first day of week. It drastically varies from
* Saturday to Monday (could even be Friday) between different locales.
* The allowed range is 0 (Sunday) to 6 (Saturday).
*/
firstDayOfWeek: React.PropTypes.number,

/**
* This function is called to format the date to display in the input box.
* By default, date objects are formatted to MM/DD/YYYY.
Expand Down Expand Up @@ -158,6 +165,7 @@ const DatePicker = React.createClass({
autoOk: false,
disableYearSelection: false,
style: {},
firstDayOfWeek: 0,
};
},

Expand Down Expand Up @@ -283,6 +291,7 @@ const DatePicker = React.createClass({
style,
textFieldStyle,
valueLink,
firstDayOfWeek,
...other,
} = this.props;

Expand Down Expand Up @@ -312,6 +321,7 @@ const DatePicker = React.createClass({
autoOk={autoOk}
disableYearSelection={disableYearSelection}
shouldDisableDate={this.props.shouldDisableDate}
firstDayOfWeek={firstDayOfWeek}
/>
</div>
);
Expand Down
52 changes: 34 additions & 18 deletions src/utils/date-time.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import warning from 'warning';

const dayAbbreviation = ['S', 'M', 'T', 'W', 'T', 'F', 'S'];
const dayList = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
const monthList = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
'Oct', 'Nov', 'Dec'];
Expand All @@ -20,11 +21,11 @@ function DateTimeFormat(locale, options) {
output = dayList[date.getDay()] + ', ';
output += monthList[date.getMonth()] + ' ';
output += date.getDate();
} else if (options.month === 'long'
&& options.year === 'numeric') {

} else if (options.month === 'long' && options.year === 'numeric') {
output = monthLongList[date.getMonth()];
output += ' ' + date.getFullYear();
} else if (options.weekday === 'narrow') {
output = dayAbbreviation[date.getDay()];
} else {
warning(false, 'Wrong usage of DateTimeFormat');
}
Expand Down Expand Up @@ -77,35 +78,50 @@ export default {
return new Date(d.getFullYear(), d.getMonth(), 1);
},

getWeekArray(d) {
getFirstDayOfWeek() {
const now = new Date();
return new Date(now.setDate(now.getDate() - now.getDay()));
},

getWeekArray(d, firstDayOfWeek) {
let dayArray = [];
let daysInMonth = this.getDaysInMonth(d);
let daysInWeek;
let emptyDays;
let firstDayOfWeek;
let week;
let weekArray = [];
let week = [];

for (let i = 1; i <= daysInMonth; i++) {
dayArray.push(new Date(d.getFullYear(), d.getMonth(), i));
}

while (dayArray.length) {
firstDayOfWeek = dayArray[0].getDay();
daysInWeek = 7 - firstDayOfWeek;
emptyDays = 7 - daysInWeek;
week = dayArray.splice(0, daysInWeek);

for (let i = 0; i < emptyDays; i++) {
week.unshift(null);
const addWeek = week => {
const emptyDays = 7 - week.length;
for (let i = 0; i < emptyDays; ++i) {
week[weekArray.length ? 'push' : 'unshift'](null);
}

weekArray.push(week);
}
};

dayArray.forEach(day => {
if (week.length > 0 && day.getDay() === firstDayOfWeek) {
addWeek(week);
week = [];
}
week.push(day);
if (dayArray.indexOf(day) === dayArray.length - 1) {
addWeek(week);
}
});

return weekArray;
},

localizedWeekday(DateTimeFormat, locale, day, firstDayOfWeek) {
const weekdayFormatter = new DateTimeFormat(locale, {weekday: 'narrow'});
const firstDayDate = this.getFirstDayOfWeek();

return weekdayFormatter.format(this.addDays(firstDayDate, day + firstDayOfWeek));
},

format(date) {
const m = date.getMonth() + 1;
const d = date.getDate();
Expand Down

0 comments on commit aa059c7

Please sign in to comment.