├── .gitignore ├── README.md ├── dist └── datepicker.js ├── index.html ├── package.json ├── src ├── components │ ├── calendar.js │ ├── date.js │ ├── datepicker.js │ ├── header.js │ └── month.js ├── index.js └── stylesheets │ ├── base │ ├── _all.scss │ ├── _color.scss │ └── _reset.scss │ ├── components │ ├── _all.scss │ ├── _calendar.scss │ ├── _date.scss │ ├── _datepicker.scss │ ├── _header.scss │ └── _month.scss │ ├── main.scss │ ├── themes │ └── _all.scss │ └── utils │ ├── _all.scss │ ├── _clearfix.scss │ └── _variables.scss └── webpack.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .sass-cache 3 | .DS_Store 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-simple-datepicker 2 | Simple datepicker for React. 3 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Document 6 | 7 | 8 | 9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-simple-datepicker", 3 | "version": "1.0.0", 4 | "description": "Simple datepicker for React.", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "sass --watch src/stylesheets/main.scss:dist/stylesheets/main.css", 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/davidkpiano/react-simple-datepicker.git" 13 | }, 14 | "author": "David Khourshid ", 15 | "license": "ISC", 16 | "bugs": { 17 | "url": "https://github.com/davidkpiano/react-simple-datepicker/issues" 18 | }, 19 | "homepage": "https://github.com/davidkpiano/react-simple-datepicker#readme", 20 | "devDependencies": { 21 | "babel": "^5.5.4", 22 | "babel-core": "^5.5.4", 23 | "babel-loader": "^5.1.4", 24 | "classnames": "^2.1.2", 25 | "jsx-loader": "^0.13.2", 26 | "lodash": "^3.9.3", 27 | "node-libs-browser": "^0.5.2", 28 | "react": "^0.13.3", 29 | "webpack": "^1.9.10", 30 | "webpack-dev-server": "^1.9.0" 31 | }, 32 | "dependencies": { 33 | "moment": "^2.10.3" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/components/calendar.js: -------------------------------------------------------------------------------- 1 | import React from 'react/addons'; 2 | import moment from 'moment'; 3 | 4 | import Header from './header'; 5 | import Month from './month'; 6 | 7 | const {CSSTransitionGroup} = React.addons; 8 | 9 | export default class Calendar extends React.Component { 10 | render() { 11 | return ( 12 |
13 |
14 | 15 | 16 | 17 |
18 | ) 19 | } 20 | } -------------------------------------------------------------------------------- /src/components/date.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import classnames from 'classnames'; 3 | 4 | export default class CalendarDate extends React.Component { 5 | render() { 6 | let date = this.props.date; 7 | 8 | let classes = classnames('sd-date', { 9 | 'current': date.month() === this.props.month, 10 | 'future': date.month() > this.props.month, 11 | 'past': date.month() < this.props.month 12 | }); 13 | 14 | return ( 15 |
19 | {date.date()} 20 |
21 | ); 22 | } 23 | } -------------------------------------------------------------------------------- /src/components/datepicker.js: -------------------------------------------------------------------------------- 1 | const React = require('react/addons'); 2 | const moment = require('moment'); 3 | const _ = require('lodash'); 4 | 5 | const {CSSTransitionGroup} = React.addons; 6 | 7 | import Calendar from './calendar'; 8 | 9 | export default class Datepicker extends React.Component { 10 | constructor(props) { 11 | super(props); 12 | let date = moment(); 13 | let month = date.month(); 14 | let year = date.year(); 15 | 16 | this.state = { 17 | month, 18 | year, 19 | date, 20 | dates: this._getDates(month, year), 21 | open: false 22 | }; 23 | } 24 | 25 | _getDates(month, year) { 26 | let firstDate = moment([year, month]).weekday(0); 27 | 28 | let dates = _.range(42).map((val, index) => { 29 | return firstDate.clone().add(index, 'd'); 30 | }); 31 | 32 | return dates; 33 | } 34 | 35 | _updateMonth(month) { 36 | let year = this.state.year; 37 | 38 | if (month >= 12) { 39 | year++; 40 | month %= 12; 41 | } else if (month < 0) { 42 | year--; 43 | month = 12 + month; 44 | } 45 | 46 | this.setState({ 47 | month, 48 | year, 49 | dates: this._getDates(month, year) 50 | }); 51 | } 52 | 53 | _updateDate(date) { 54 | this.setState({ date, open: false }); 55 | } 56 | 57 | _updateYear(year) { 58 | this.setState({ year }); 59 | } 60 | 61 | _open() { 62 | this.setState({ open: true }); 63 | } 64 | 65 | render() { 66 | let calendar = this.state.open ? ( 67 | 73 | ) : null; 74 | 75 | return ( 76 |
77 | 82 | 83 | 84 | 85 | {calendar} 86 | 87 |
88 | ); 89 | } 90 | } -------------------------------------------------------------------------------- /src/components/header.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import moment from 'moment'; 3 | 4 | export default class Header extends React.Component { 5 | render() { 6 | return ( 7 |
8 | 9 |

{moment().month(this.props.month).format('MMMM')} {this.props.year}

10 | 11 |
12 | ); 13 | } 14 | } -------------------------------------------------------------------------------- /src/components/month.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import CalendarDate from './date'; 4 | 5 | export default class Month extends React.Component { 6 | render() { 7 | return ( 8 |
9 |
    10 |
  • Sun
  • 11 |
  • Mon
  • 12 |
  • Tue
  • 13 |
  • Wed
  • 14 |
  • Thu
  • 15 |
  • Fri
  • 16 |
  • Sat
  • 17 |
18 | 19 | {this.props.dates.map((date) => ())} 20 |
21 | ) 22 | } 23 | } -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import Datepicker from './components/datepicker'; 4 | 5 | React.render(, document.querySelector('.my-datepicker-component')); -------------------------------------------------------------------------------- /src/stylesheets/base/_all.scss: -------------------------------------------------------------------------------- 1 | 2 | @import 'reset'; 3 | @import 'color'; -------------------------------------------------------------------------------- /src/stylesheets/base/_color.scss: -------------------------------------------------------------------------------- 1 | 2 | $color-primary: rgb(41, 130, 217) !default; -------------------------------------------------------------------------------- /src/stylesheets/base/_reset.scss: -------------------------------------------------------------------------------- 1 | 2 | 3 | *, *:before, *:after { 4 | box-sizing: border-box; 5 | position: relative; 6 | } 7 | -------------------------------------------------------------------------------- /src/stylesheets/components/_all.scss: -------------------------------------------------------------------------------- 1 | 2 | @import 'calendar'; 3 | @import 'date'; 4 | @import 'datepicker'; 5 | @import 'header'; 6 | @import 'month'; -------------------------------------------------------------------------------- /src/stylesheets/components/_calendar.scss: -------------------------------------------------------------------------------- 1 | 2 | 3 | .sd-calendar { 4 | width: 14rem; 5 | background: map-get($colors, primary); 6 | color: white; 7 | transition: all 0.25s ease-in-out; 8 | overflow: hidden; 9 | 10 | &.calendar-enter { 11 | opacity: 0; 12 | transform: translateY(1rem); 13 | } 14 | 15 | &.calendar-enter-active { 16 | opacity: 1; 17 | transform: translateY(0); 18 | } 19 | 20 | &.calendar-leave-active { 21 | opacity: 0; 22 | transform: translateY(1rem); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/stylesheets/components/_date.scss: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | .sd-date { 5 | width: percentage(1/7); 6 | float: left; 7 | text-align: center; 8 | padding: 0.5rem; 9 | font-size: 0.75rem; 10 | font-weight: 400; 11 | border-radius: 0.25rem; 12 | transition: background-color 0.25s ease-in-out; 13 | 14 | &.past, &.future { 15 | opacity: 0.5; 16 | } 17 | 18 | &:hover { 19 | cursor: pointer; 20 | background-color: rgba(white, 0.3); 21 | } 22 | } -------------------------------------------------------------------------------- /src/stylesheets/components/_datepicker.scss: -------------------------------------------------------------------------------- 1 | @import url(http://fonts.googleapis.com/css?family=Lato:300,400,700); 2 | 3 | .sd-datepicker { 4 | font-family: Lato, sans-serif; 5 | 6 | *, *:before, *:after { 7 | box-sizing: border-box; 8 | position: relative; 9 | } 10 | } -------------------------------------------------------------------------------- /src/stylesheets/components/_header.scss: -------------------------------------------------------------------------------- 1 | 2 | 3 | .sd-header { 4 | display: flex; 5 | flex-direction: row; 6 | padding: 0.5rem; 7 | border-bottom: 1px solid rgba(white, 0.2); 8 | 9 | > .sd-heading { 10 | flex-grow: 1; 11 | text-align: center; 12 | font-size: 0.75rem; 13 | margin: 0; 14 | padding: 0.5rem; 15 | text-transform: uppercase; 16 | } 17 | 18 | > .sd-button { 19 | appearance: none; 20 | -webkit-appearance: none; 21 | background: transparent; 22 | border: none; 23 | color: currentcolor; 24 | font-size: 1rem; 25 | padding: 0 1rem; 26 | border-radius: 0.25rem; 27 | 28 | &:focus { 29 | outline: none; 30 | } 31 | 32 | &:hover { 33 | background: rgba(white, 0.4); 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /src/stylesheets/components/_month.scss: -------------------------------------------------------------------------------- 1 | 2 | 3 | .sd-month { 4 | @include clearfix(); 5 | width: 14rem; 6 | height: auto; 7 | background-color: map-get($colors, primary); 8 | color: white; 9 | padding: 1rem; 10 | transition: all 0.25s ease-in-out; 11 | 12 | &.month-enter { 13 | opacity: 0; 14 | transform: translateY(1rem); 15 | } 16 | 17 | &.month-enter-active { 18 | opacity: 1; 19 | transform: translateY(0); 20 | } 21 | 22 | &.month-leave { 23 | position: absolute; 24 | top: 0; 25 | left: 0; 26 | 27 | + .sd-month { 28 | position: absolute; 29 | } 30 | } 31 | 32 | &.month-leave-active { 33 | opacity: 0; 34 | z-index: -1; 35 | transform: translateY(-1rem); 36 | } 37 | 38 | .sd-days { 39 | @include clearfix(); 40 | margin: 0; 41 | padding: 0; 42 | width: 100%; 43 | padding: 0.5rem 0; 44 | opacity: 0.5; 45 | } 46 | 47 | .sd-day { 48 | width: percentage(1/7); 49 | display: inline-block; 50 | float: left; 51 | font-size: 0.563rem; 52 | text-align: center; 53 | text-transform: uppercase; 54 | } 55 | } 56 | 57 | 58 | -------------------------------------------------------------------------------- /src/stylesheets/main.scss: -------------------------------------------------------------------------------- 1 | 2 | .my-datepicker-component { 3 | @import 'utils/all'; 4 | @import 'base/all'; 5 | @import 'components/all'; 6 | @import 'themes/all'; 7 | } -------------------------------------------------------------------------------- /src/stylesheets/themes/_all.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidkpiano/react-simple-datepicker/d3216ef45b255a1aaa84b66bf8731ff97829e8e6/src/stylesheets/themes/_all.scss -------------------------------------------------------------------------------- /src/stylesheets/utils/_all.scss: -------------------------------------------------------------------------------- 1 | 2 | @import 'clearfix'; 3 | @import 'variables'; -------------------------------------------------------------------------------- /src/stylesheets/utils/_clearfix.scss: -------------------------------------------------------------------------------- 1 | 2 | @mixin clearfix() { 3 | &:before, 4 | &:after { 5 | content: " "; 6 | display: table; 7 | } 8 | 9 | &:after { 10 | clear: both; 11 | } 12 | } -------------------------------------------------------------------------------- /src/stylesheets/utils/_variables.scss: -------------------------------------------------------------------------------- 1 | 2 | 3 | $colors: ( 4 | 'primary': rgb(41, 130, 217) 5 | ); -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | var webpack = require('webpack'); 2 | 3 | module.exports = { 4 | entry: './src/index.js', 5 | output: { 6 | path: './dist', 7 | filename: 'datepicker.js' 8 | }, 9 | module: { 10 | loaders: [ 11 | { 12 | test: /\.js$/, 13 | loader: 'babel' 14 | } 15 | ] 16 | } 17 | }; --------------------------------------------------------------------------------