Skip to content

Commit

Permalink
Merge da0f06f into e433240
Browse files Browse the repository at this point in the history
  • Loading branch information
gpbl committed Feb 14, 2017
2 parents e433240 + da0f06f commit 75e1607
Show file tree
Hide file tree
Showing 4 changed files with 186 additions and 10 deletions.
14 changes: 11 additions & 3 deletions src/DayPicker.js
Expand Up @@ -10,16 +10,24 @@ import * as DateUtils from './DateUtils';
import * as LocaleUtils from './LocaleUtils';

import keys from './keys';
import DayPickerPropTypes from './PropTypes';
import DayPickerPropTypes, { ModifierPropType } from './PropTypes';

export default class DayPicker extends Component {
static VERSION = '4.0.0';

static propTypes = {
initialMonth: PropTypes.instanceOf(Date),
numberOfMonths: PropTypes.number,
selectedDays: PropTypes.func,
disabledDays: PropTypes.func,

selectedDays: PropTypes.oneOfType([
ModifierPropType,
PropTypes.arrayOf(ModifierPropType),
]),

disabledDays: PropTypes.oneOfType([
ModifierPropType,
PropTypes.arrayOf(ModifierPropType),
]),

modifiers: PropTypes.object,

Expand Down
55 changes: 50 additions & 5 deletions src/Helpers.js
@@ -1,5 +1,5 @@

import { clone } from './DateUtils';
import { clone, isSameDay, isDayInRange } from './DateUtils';
import { getFirstDayOfWeek } from './LocaleUtils';

export function cancelEvent(e) {
Expand Down Expand Up @@ -52,10 +52,55 @@ export function getFirstDayOfWeekFromProps(props) {
return 0;
}

export function getModifiersForDay(d, modifierFunctions = {}) {
return Object.keys(modifierFunctions).reduce((modifiers, modifier) => {
const func = modifierFunctions[modifier];
if (func(d)) {
export function isRangeOfDates(value) {
return value && typeof value === 'object' && value.from && value.to;
}

export function getModifiersForDay(d, modifiersObj = {}) {
return Object.keys(modifiersObj).reduce((modifiers, modifier) => {
const value = modifiersObj[modifier];
if (!value) {
return modifiers;
}
if (value instanceof Date && isSameDay(d, value)) {
// modifier's value is a date
modifiers.push(modifier);
} else if (value instanceof Array) {
// modifier's value is an array
if (value.some((day) => {
if (!day) {
return false;
}
if (day instanceof Date) {
// this value of the array is a date
return isSameDay(d, day);
}
if (isRangeOfDates(day)) {
// this value of the array is a range
const range = day;
return isDayInRange(d, range);
}
if (typeof day === 'object' && day.after) {
return d > day.after;
}
if (typeof day === 'object' && day.before) {
return d < day.before;
}
return false;
})) {
modifiers.push(modifier);
}
} else if (isRangeOfDates(value) && isDayInRange(d, value)) {
// modifier's value is a range
modifiers.push(modifier);
} else if (typeof value === 'object' && value.after && d > value.after) {
// modifier's value has an after date
modifiers.push(modifier);
} else if (typeof value === 'object' && value.before && d < value.before) {
// modifier's value has an after date
modifiers.push(modifier);
} else if (typeof value === 'function' && value(d)) {
// modifier's value is a function
modifiers.push(modifier);
}
return modifiers;
Expand Down
22 changes: 21 additions & 1 deletion src/PropTypes.js
@@ -1,10 +1,30 @@
import { PropTypes } from 'react';

export default {
const PrimitiveTypes = {
localeUtils: PropTypes.shape({
formatMonthTitle: PropTypes.func,
formatWeekdayShort: PropTypes.func,
formatWeekdayLong: PropTypes.func,
getFirstDayOfWeek: PropTypes.func,
}),
range: PropTypes.shape({
from: PropTypes.instanceOf(Date),
to: PropTypes.instanceOf(Date),
}),
after: PropTypes.shape({
after: PropTypes.instanceOf(Date),
}),
before: PropTypes.shape({
before: PropTypes.instanceOf(Date),
}),
};

export const ModifierPropType = PropTypes.oneOfType([
PrimitiveTypes.after,
PrimitiveTypes.before,
PrimitiveTypes.range,
PropTypes.func,
PropTypes.array,
]);

export default PrimitiveTypes;
105 changes: 104 additions & 1 deletion test/Helpers.js
Expand Up @@ -88,7 +88,110 @@ describe('Helpers', () => {
expect(modifiers.indexOf('maybe')).to.equal(-1);
expect(modifiers.indexOf('no')).to.equal(-1);
});
it('works without passing modifiers', () => {
it('accepts a single day', () => {
const modifiers = Helpers.getModifiersForDay(
new Date(2015, 8, 19),
{ foo: new Date(2015, 8, 19) },
);
expect(modifiers).to.have.length(1);
expect(modifiers.indexOf('foo')).to.equal(0);
});
it('accepts an array of days', () => {
const modifiersObj = {
foo: [
new Date(2015, 8, 19),
new Date(2015, 8, 20),
new Date(2015, 8, 21),
],
bar: [
new Date(2015, 8, 19),
new Date(2015, 8, 20),
],
};
const modifiers1 = Helpers.getModifiersForDay(new Date(2015, 8, 19), modifiersObj);
expect(modifiers1).to.have.length(2);
expect(modifiers1.indexOf('foo')).to.be.above(-1);
expect(modifiers1.indexOf('bar')).to.be.above(-1);

const modifiers2 = Helpers.getModifiersForDay(new Date(2015, 8, 20), modifiersObj);
expect(modifiers2).to.have.length(2);
expect(modifiers2.indexOf('foo')).to.be.above(-1);
expect(modifiers2.indexOf('bar')).to.be.above(-1);

const modifiers3 = Helpers.getModifiersForDay(new Date(2015, 8, 21), modifiersObj);
expect(modifiers3).to.have.length(1);
expect(modifiers3.indexOf('foo')).to.equal(0);
expect(modifiers3.indexOf('bar')).to.equal(-1);
});
it('accepts a single range of days', () => {
const range = {
foo: {
from: new Date(2015, 8, 18),
to: new Date(2015, 8, 20),
},
};
const modifiers1 = Helpers.getModifiersForDay(new Date(2015, 8, 19), range);
expect(modifiers1).to.have.length(1);
expect(modifiers1.indexOf('foo')).to.equal(0);
const modifiers2 = Helpers.getModifiersForDay(new Date(2015, 8, 17), range);
expect(modifiers2).to.have.length(0);
});
it('accepts multiple ranges of days', () => {
const ranges = {
foo: [{
from: new Date(2015, 8, 18),
to: new Date(2015, 8, 20),
}, {
from: new Date(2015, 9, 18),
to: new Date(2015, 9, 20),
}],
};
const modifiers1 = Helpers.getModifiersForDay(new Date(2015, 8, 19), ranges);
expect(modifiers1.indexOf('foo')).to.equal(0);
const modifiers2 = Helpers.getModifiersForDay(new Date(2015, 9, 18), ranges);
expect(modifiers2.indexOf('foo')).to.equal(0);
});
it('accepts an "after" modifier', () => {
const afterModifier = {
foo: {
after: new Date(2015, 8, 18),
},
};
const modifiers = Helpers.getModifiersForDay(new Date(2015, 8, 19), afterModifier);
expect(modifiers).to.have.length(1);
expect(modifiers.indexOf('foo')).to.equal(0);
});
it('accepts an "after" modifier in an array of days', () => {
const afterModifier = {
foo: [
{ after: new Date(2015, 8, 18) },
],
};
const modifiers = Helpers.getModifiersForDay(new Date(2015, 8, 19), afterModifier);
expect(modifiers).to.have.length(1);
expect(modifiers.indexOf('foo')).to.equal(0);
});
it('accepts a "before" modifier', () => {
const afterModifier = {
foo: {
before: new Date(2015, 8, 15),
},
};
const modifiers = Helpers.getModifiersForDay(new Date(2015, 8, 10), afterModifier);
expect(modifiers).to.have.length(1);
expect(modifiers.indexOf('foo')).to.equal(0);
});
it('accepts a "before" modifier in an array of days', () => {
const afterModifier = {
foo: [
{ before: new Date(2015, 8, 15) },
],
};
const modifiers = Helpers.getModifiersForDay(new Date(2015, 8, 10), afterModifier);
expect(modifiers).to.have.length(1);
expect(modifiers.indexOf('foo')).to.equal(0);
});
it('works even without modifiers', () => {
const modifiers = Helpers.getModifiersForDay(new Date(2015, 8, 19));
expect(modifiers).to.have.length(0);
});
Expand Down

0 comments on commit 75e1607

Please sign in to comment.