├── .babelrc ├── .editorconfig ├── .gitignore ├── .npmignore ├── .travis.yml ├── LICENSE ├── README.md ├── cover.js ├── demo ├── Example.js ├── bundle.js ├── favicon.png └── index.html ├── docs ├── cap1.png ├── cap2.png ├── cap3.png └── cap4.png ├── index.js ├── package-lock.json ├── package.json ├── src ├── Calendar.js ├── Day.js ├── DayOfWeek.js └── Week.js └── test ├── Calendar-test.js └── assertions └── Asserter.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "react", 4 | "es2015" 5 | ], 6 | "plugins": [ 7 | "add-module-exports", 8 | "transform-object-assign" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # Compiled binary addons (http://nodejs.org/api/addons.html) 20 | build/Release 21 | 22 | # Dependency directory 23 | # Commenting this out is preferred by some people, see 24 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git- 25 | node_modules 26 | 27 | # Users Environment Variables 28 | .lock-wscript 29 | 30 | .idea 31 | *.iml 32 | /lib 33 | lcov.info -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | src/ -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | sudo: required 3 | dist: trusty 4 | node_js: 5 | - stable 6 | script: 7 | - npm test 8 | after_script: 9 | - npm run test:coverage 10 | - '[ "${TRAVIS_PULL_REQUEST}" = "false" ] && npm run demo:publish || false' 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 tomkp 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # React Calendar Pane 2 | 3 | [![build status](https://img.shields.io/travis/tomkp/react-calendar-pane/master.svg?style=flat-square)](https://travis-ci.org/tomkp/react-calendar-pane) 4 | [![Coverage Status](https://img.shields.io/coveralls/tomkp/react-calendar-pane/master.svg?style=flat-square)](https://coveralls.io/r/tomkp/react-calendar-pane?branch=master) 5 | 6 | 7 | React calendar component in ES6 8 | 9 | Check out the [demo](http://react-calendar-pane.surge.sh/) 10 | 11 | 12 | install 13 | ```npm install``` 14 | 15 | run tests 16 | ```npm test``` 17 | 18 | build the demo 19 | ```npm run demo``` 20 | 21 | 22 | ## Usage 23 | 24 | 25 | ```html 26 | 27 | ``` 28 | 29 |
30 | 31 | 32 | 33 |
34 | 35 | ### Example css 36 | 37 | ```css 38 | .Calendar { 39 | border-collapse: collapse; 40 | padding: 0; 41 | margin: 4rem auto 0; 42 | } 43 | 44 | .Calendar th, 45 | .Calendar td { 46 | padding: 1rem; 47 | text-align: center; 48 | } 49 | 50 | .Day:hover { 51 | background: #eee; 52 | color: #000; 53 | } 54 | 55 | .Day.today { 56 | background: #666; 57 | color: #fff; 58 | } 59 | 60 | .Day.selected { 61 | background: #2980b9; 62 | color: #fff; 63 | } 64 | 65 | .Day.other-month { 66 | background: #fafafa; 67 | color: #aaa; 68 | } 69 | ``` 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /cover.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | var mochify = require('mochify'); 4 | var istanbul = require('mochify-istanbul'); 5 | 6 | mochify('./test/*.js', { 7 | reporter: 'dot', 8 | transform: ['babelify'] 9 | }).plugin(istanbul, { 10 | report: ['lcovonly'] 11 | }).bundle(); -------------------------------------------------------------------------------- /demo/Example.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import Calendar from '../lib/Calendar.js'; 4 | import moment from 'moment'; 5 | import momentFr from 'moment/locale/fr'; 6 | 7 | const customDayRenderer = ({ handleClick, date }) => { 8 | return ( 9 | handleClick(date)} 13 | > 14 | {date.format('D')} 15 | 16 | ); 17 | }; 18 | 19 | class Example extends Component { 20 | onSelect(date, previousDate, currentMonth) { 21 | if (moment(date).isSame(previousDate)) { 22 | console.info('onSelect: false', date); 23 | return false; 24 | } else if (currentMonth.isSame(date, 'month')) { 25 | console.info('onSelect: true', date); 26 | return true; 27 | } else { 28 | console.info('onSelect: none', date); 29 | } 30 | } 31 | 32 | render() { 33 | let dayClasses = function(date) { 34 | let day = date.isoWeekday(); 35 | if (day === 6 || day === 7) { 36 | return ['weekend']; 37 | } 38 | return []; 39 | }; 40 | return ( 41 |
42 |

Calendar with weekend

43 | 44 |

Calendar without nav

45 | 50 |

French calendar

51 | 57 |

Calendar with custom day renderer

58 | 59 |
60 | ); 61 | } 62 | } 63 | 64 | ReactDOM.render(, document.getElementById('container')); 65 | -------------------------------------------------------------------------------- /demo/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomkp/react-calendar-pane/68de06bedfa2a5ad64b2846155ef0f29836e44b1/demo/favicon.png -------------------------------------------------------------------------------- /demo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | React Calendar 9 | 10 | 11 | 115 | 116 | 117 |
118 | 119 |
120 | 121 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /docs/cap1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomkp/react-calendar-pane/68de06bedfa2a5ad64b2846155ef0f29836e44b1/docs/cap1.png -------------------------------------------------------------------------------- /docs/cap2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomkp/react-calendar-pane/68de06bedfa2a5ad64b2846155ef0f29836e44b1/docs/cap2.png -------------------------------------------------------------------------------- /docs/cap3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomkp/react-calendar-pane/68de06bedfa2a5ad64b2846155ef0f29836e44b1/docs/cap3.png -------------------------------------------------------------------------------- /docs/cap4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomkp/react-calendar-pane/68de06bedfa2a5ad64b2846155ef0f29836e44b1/docs/cap4.png -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | var Calendar = require('./src/Calendar.js'); 2 | 3 | module.exports = Calendar; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-calendar-pane", 3 | "description": "React calendar component", 4 | "main": "./lib/Calendar.js", 5 | "version": "1.0.5", 6 | "repository": { 7 | "type": "git", 8 | "url": "https://github.com/tomkp/react-calendar-pane" 9 | }, 10 | "bugs": { 11 | "url": "https://github.com/tomkp/react-calendar-pane" 12 | }, 13 | "homepage": "https://github.com/tomkp/react-calendar-pane", 14 | "license": "MIT", 15 | "author": "tomkp ", 16 | "keywords": [ 17 | "react", 18 | "react-component", 19 | "calendar", 20 | "date-picker", 21 | "react-date-picker", 22 | "calendar-pane", 23 | "react-calendar", 24 | "react-calendar-pane", 25 | "es6" 26 | ], 27 | "dependencies": { 28 | "moment": "^2.23.0" 29 | }, 30 | "peerDependencies": { 31 | "react": "^16.7.0", 32 | "react-dom": "^16.7.0", 33 | "prop-types": "^15.6.2" 34 | }, 35 | "devDependencies": { 36 | "babel-cli": "^6.26.0", 37 | "babel-plugin-add-module-exports": "^1.0.0", 38 | "babel-plugin-transform-object-assign": "^6.22.0", 39 | "babel-preset-es2015": "^6.24.1", 40 | "babel-preset-react": "^6.24.1", 41 | "babelify": "^7.3.0", 42 | "browserify": "^16.2.3", 43 | "chai": "^4.2.0", 44 | "core-js": "^2.6.1", 45 | "coveralls": "^3.0.2", 46 | "create-react-class": "^15.6.3", 47 | "husky": "^1.3.1", 48 | "lint-staged": "^8.1.0", 49 | "mochify": "^6.0.4", 50 | "mochify-istanbul": "^2.4.2", 51 | "prettier": "^1.15.3", 52 | "prop-types": "^15.6.2", 53 | "react": "^16.7.0", 54 | "react-dom": "^16.7.0", 55 | "react-test-renderer": "^16.7.0", 56 | "surge": "^0.20.1", 57 | "watchify": "^3.11.0" 58 | }, 59 | "scripts": { 60 | "compile": "babel -d lib/ src/", 61 | "compile:watch": "babel -w -d lib/ src/", 62 | "prepublish": "npm run compile", 63 | "test": "npm run compile && mochify -R spec", 64 | "test:watch": "npm run compile:watch & mochify -R spec --watch", 65 | "test:coverage": "node cover.js && cat lcov.info | coveralls && rm lcov.info", 66 | "demo": "npm run compile && browserify demo/Example.js -t -o demo/bundle.js", 67 | "demo:watch": "npm run compile:watch & watchify demo/Example.js -t -o demo/bundle.js", 68 | "demo:publish": "npm run compile && browserify demo/Example.js -t -o demo/bundle.js && surge demo react-calendar-pane.surge.sh", 69 | "prettier": "prettier --single-quote --trailing-comma es5 --write './{src,test,demo}/**/*.js'", 70 | "release:patch": "npm test && npm run compile && npm version patch && git push && npm publish" 71 | }, 72 | "browserify": { 73 | "transform": [ 74 | [ 75 | "babelify" 76 | ] 77 | ] 78 | }, 79 | "false": {} 80 | } 81 | -------------------------------------------------------------------------------- /src/Calendar.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | import moment from 'moment'; 5 | import Day from './Day'; 6 | import DayOfWeek from './DayOfWeek'; 7 | import Week from './Week'; 8 | 9 | class Calendar extends Component { 10 | constructor(props) { 11 | super(props); 12 | let date = props.date; 13 | let month; 14 | if (date) { 15 | month = props.date; 16 | } else { 17 | month = props.month; 18 | } 19 | this.state = { 20 | date: date, 21 | month: month, 22 | }; 23 | 24 | this.previous = this.previous.bind(this); 25 | this.next = this.next.bind(this); 26 | this.handleClick = this.handleClick.bind(this); 27 | } 28 | 29 | componentWillMount() { 30 | moment.locale(this.props.locale); 31 | 32 | if (!!this.state.date) { 33 | this.state.date.locale(this.props.locale); 34 | } 35 | 36 | this.state.month.locale(this.props.locale); 37 | } 38 | 39 | componentWillUpdate(nextProps, nextState) { 40 | moment.locale(this.props.locale); 41 | 42 | if (!!nextState.date) { 43 | nextState.date.locale(this.props.locale); 44 | } 45 | 46 | nextState.month.locale(this.props.locale); 47 | } 48 | 49 | handleClick(date) { 50 | const flag = this.props.onSelect(date, this.state.date, this.state.month); 51 | 52 | if (flag === true) { 53 | this.setState({ 54 | date: moment(date), 55 | }); 56 | } else if (flag === false) { 57 | this.setState({ 58 | date: null, 59 | }); 60 | } 61 | } 62 | 63 | previous() { 64 | this.setState({ 65 | month: moment(this.state.month).subtract(1, 'month'), 66 | }); 67 | } 68 | 69 | next() { 70 | this.setState({ 71 | month: moment(this.state.month).add(1, 'month'), 72 | }); 73 | } 74 | 75 | render() { 76 | const { startOfWeekIndex, dayRenderer, dayOfWeekFormat } = this.props; 77 | 78 | const classes = ['Calendar', this.props.className].join(' '); 79 | 80 | const today = moment(); 81 | 82 | const format = dayOfWeekFormat && 83 | dayOfWeekFormat !== '' && 84 | moment(today, dayOfWeekFormat).isValid() ? dayOfWeekFormat : 'dd' 85 | 86 | const date = this.state.date; 87 | const month = this.state.month; 88 | 89 | const current = month 90 | .clone() 91 | .startOf('month') 92 | .day(startOfWeekIndex); 93 | if (current.date() > 1 && current.date() < 7) { 94 | current.subtract(7, 'd'); 95 | } 96 | 97 | const end = month 98 | .clone() 99 | .endOf('month') 100 | .day(7 + startOfWeekIndex); 101 | 102 | if (end.date() > 7) { 103 | end.subtract(7, 'd'); 104 | } 105 | 106 | const elements = []; 107 | let days = []; 108 | let week = 1; 109 | let i = 1; 110 | const daysOfWeek = []; 111 | const day = current.clone(); 112 | for (let j = 0; j < 7; j++) { 113 | const dayOfWeekKey = 'dayOfWeek' + j; 114 | daysOfWeek.push(); 115 | day.add(1, 'days'); 116 | } 117 | while (current.isBefore(end)) { 118 | let dayClasses = this.props.dayClasses(current); 119 | if (!current.isSame(month, 'month')) { 120 | dayClasses = dayClasses.concat(['other-month']); 121 | } 122 | let props = { 123 | date: current.clone(), 124 | selected: date, 125 | month: month, 126 | today: today, 127 | classes: dayClasses, 128 | handleClick: this.handleClick, 129 | }; 130 | 131 | let children; 132 | if (!!dayRenderer) { 133 | children = dayRenderer(props); 134 | } 135 | 136 | days.push( 137 | 138 | {children} 139 | 140 | ); 141 | current.add(1, 'days'); 142 | if (current.day() === startOfWeekIndex) { 143 | let weekKey = 'week' + week++; 144 | elements.push({days}); 145 | days = []; 146 | } 147 | } 148 | 149 | let nav; 150 | 151 | if (this.props.useNav) { 152 | nav = ( 153 | 154 | 155 | 158 | 159 | 160 | {month.format('MMMM')}{' '} 161 | {month.format('YYYY')} 162 | 163 | 164 | 167 | 168 | 169 | ); 170 | } else { 171 | nav = ( 172 | 173 | 174 | {month.format('MMMM')}{' '} 175 | {month.format('YYYY')} 176 | 177 | 178 | ); 179 | } 180 | 181 | return ( 182 | 183 | {nav} 184 | 185 | {daysOfWeek} 186 | 187 | {elements} 188 |
189 | ); 190 | } 191 | } 192 | Calendar.defaultProps = { 193 | month: moment(), 194 | dayClasses: () => [], 195 | useNav: true, 196 | locale: 'en', 197 | startOfWeekIndex: 0, 198 | dayOfWeekFormat: 'dd', 199 | }; 200 | Calendar.propTypes = { 201 | onSelect: PropTypes.func.isRequired, 202 | date: PropTypes.object, 203 | month: PropTypes.object, 204 | dayClasses: PropTypes.func, 205 | useNav: PropTypes.bool, 206 | locale: PropTypes.string, 207 | startOfWeekIndex: PropTypes.number, 208 | dayRenderer: PropTypes.func, 209 | dayOfWeekFormat: PropTypes.string, 210 | }; 211 | 212 | export default Calendar; 213 | -------------------------------------------------------------------------------- /src/Day.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | class Day extends Component { 5 | render() { 6 | const { 7 | today, 8 | date, 9 | selected, 10 | classes, 11 | handleClick, 12 | children, 13 | } = this.props; 14 | 15 | const classNames = ['Day']; 16 | if (today.isSame(date, 'day')) { 17 | classNames.push('today'); 18 | } 19 | if (selected && selected.isSame(date, 'day')) { 20 | classNames.push('selected'); 21 | } 22 | 23 | let body; 24 | if (!!children) { 25 | body = children; 26 | } else { 27 | body = ( 28 | 35 | ); 36 | } 37 | 38 | return ( 39 | 44 | {body} 45 | 46 | ); 47 | } 48 | } 49 | 50 | Day.propTypes = { 51 | handleClick: PropTypes.func.isRequired, 52 | date: PropTypes.object.isRequired, 53 | today: PropTypes.object.isRequired, 54 | selected: PropTypes.object, 55 | children: PropTypes.node, 56 | }; 57 | 58 | export default Day; 59 | -------------------------------------------------------------------------------- /src/DayOfWeek.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import moment from 'moment'; 4 | 5 | const DayOfWeek = (props) => { 6 | const { date, format } = props; 7 | 8 | return ( 9 | 10 | {date.format(format)} 11 | 12 | ); 13 | }; 14 | 15 | DayOfWeek.propTypes = { 16 | date: PropTypes.instanceOf(moment).isRequired, 17 | format: PropTypes.string, 18 | }; 19 | 20 | export default DayOfWeek; 21 | -------------------------------------------------------------------------------- /src/Week.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Week = ({ children }) => {children}; 4 | 5 | export default Week; 6 | -------------------------------------------------------------------------------- /test/Calendar-test.js: -------------------------------------------------------------------------------- 1 | import 'core-js/es6/map'; 2 | import 'core-js/es6/set'; 3 | 4 | import moment from 'moment'; 5 | import React from 'react'; 6 | import Calendar from '../src/Calendar'; 7 | import asserter from './assertions/Asserter'; 8 | import chai from 'chai'; 9 | 10 | const expect = chai.expect; 11 | 12 | describe('Calendar', () => { 13 | const onSelect = () => true; 14 | 15 | it('displays the correct year', () => { 16 | const calendar = ( 17 | 18 | ); 19 | 20 | asserter(calendar).assertYear('2015'); 21 | }); 22 | 23 | it('displays the correct month', () => { 24 | const calendar = ( 25 | 26 | ); 27 | 28 | asserter(calendar).assertMonth('April'); 29 | }); 30 | 31 | it('should be able to go to previous month', () => { 32 | const calendar = ( 33 | 34 | ); 35 | 36 | asserter(calendar) 37 | .previousMonth() 38 | .assertMonth('March'); 39 | }); 40 | 41 | it('should be able to go to next month', () => { 42 | const calendar = ( 43 | 44 | ); 45 | 46 | asserter(calendar) 47 | .nextMonth() 48 | .assertMonth('May'); 49 | }); 50 | 51 | it('should trigger the callback with selected date when clicking a day', done => { 52 | const callback = selectedDate => { 53 | expect(moment(selectedDate).format('DD/MM/YYYY')).to.equal('08/04/2015'); 54 | done(); 55 | }; 56 | 57 | const calendar = ( 58 | 59 | ); 60 | 61 | asserter(calendar).clickDay(8); 62 | }); 63 | 64 | it('should set selected date to selected', () => { 65 | const calendar = ( 66 | 67 | ); 68 | 69 | asserter(calendar) 70 | .clickDay(8) 71 | .assertSelectedDay(8); 72 | }); 73 | 74 | it('should add class to today', () => { 75 | const calendar = ; 76 | 77 | asserter(calendar).assertToday(); 78 | }); 79 | 80 | it("day of week format defaults to 'dd' when format is invalid", () => { 81 | const formats = ['', null]; 82 | 83 | formats.forEach((format) => { 84 | const calendar = ( 85 | 86 | ); 87 | 88 | asserter(calendar).assertDayOfTheWeek(format); 89 | }); 90 | }); 91 | 92 | it('displays day of the week following a given format', () => { 93 | const formats = ['d', 'dd', 'ddd', 'dddd']; 94 | 95 | formats.forEach((format) => { 96 | const calendar = ( 97 | 98 | ); 99 | 100 | asserter(calendar).assertDayOfTheWeek(format); 101 | }); 102 | }); 103 | }); 104 | -------------------------------------------------------------------------------- /test/assertions/Asserter.js: -------------------------------------------------------------------------------- 1 | import moment from 'moment'; 2 | import React from 'react'; 3 | import { 4 | findDOMNode 5 | } from 'react-dom'; 6 | import { 7 | Simulate, 8 | scryRenderedDOMComponentsWithClass, 9 | findRenderedDOMComponentWithClass, 10 | renderIntoDocument, 11 | } from 'react-dom/test-utils'; 12 | 13 | import chai from 'chai'; 14 | 15 | const expect = chai.expect; 16 | 17 | export default jsx => { 18 | const calendar = renderIntoDocument(jsx); 19 | 20 | return { 21 | assertYear(expectedYear) { 22 | const year = findRenderedDOMComponentWithClass(calendar, 'year'); 23 | expect(findDOMNode(year).textContent).to.equal(expectedYear); 24 | return this; 25 | }, 26 | 27 | assertMonth(expectedMonth) { 28 | const month = findRenderedDOMComponentWithClass(calendar, 'month'); 29 | expect(findDOMNode(month).textContent).to.equal(expectedMonth); 30 | return this; 31 | }, 32 | 33 | previousMonth() { 34 | const previous = findRenderedDOMComponentWithClass(calendar, 'previous'); 35 | Simulate.click(previous.firstChild); 36 | return this; 37 | }, 38 | 39 | nextMonth() { 40 | const next = findRenderedDOMComponentWithClass(calendar, 'next'); 41 | Simulate.click(next.firstChild); 42 | return this; 43 | }, 44 | 45 | assertSelectedDay(expectedDay) { 46 | const selected = findRenderedDOMComponentWithClass(calendar, 'selected'); 47 | const value = findDOMNode(selected).textContent; 48 | expect(+value).to.equal(expectedDay); 49 | return this; 50 | }, 51 | 52 | assertToday() { 53 | const today = findRenderedDOMComponentWithClass(calendar, 'today'); 54 | const value = findDOMNode(today).textContent; 55 | expect(value).to.equal(moment().format('D')); 56 | return this; 57 | }, 58 | 59 | clickDay(date) { 60 | const days = scryRenderedDOMComponentsWithClass(calendar, 'Day'); 61 | const found = days.filter(day => { 62 | const value = findDOMNode(day).dataset.day; 63 | return +value === date; 64 | }); 65 | Simulate.click(found[0].firstChild); 66 | return this; 67 | }, 68 | 69 | assertDayOfTheWeek(dayOfWeekFormat) { 70 | const daysOfTheWeek = scryRenderedDOMComponentsWithClass(calendar, 'DayOfWeek'); 71 | let currentDayOfTheWeek = 0; 72 | 73 | daysOfTheWeek.forEach((dayOfTheWeek) => { 74 | const currentDate = moment(currentDayOfTheWeek, 'd'); 75 | const format = dayOfWeekFormat && dayOfWeekFormat !== '' && 76 | moment(currentDate, dayOfWeekFormat).isValid() ? dayOfWeekFormat : 'dd'; 77 | const value = findDOMNode(dayOfTheWeek).textContent; 78 | 79 | expect(value).to.equal(moment(currentDate).format(format)); 80 | 81 | currentDayOfTheWeek++; 82 | }) 83 | 84 | return this; 85 | }, 86 | }; 87 | }; 88 | --------------------------------------------------------------------------------