├── .npmignore ├── .eslintignore ├── README.md ├── HISTORY.md ├── less ├── component.less ├── variables.less ├── dateinput.less └── mixins.less ├── example └── src │ ├── .gitignore │ ├── example.js │ ├── example.less │ └── index.html ├── .gitignore ├── .editorconfig ├── dist ├── component.css ├── react-date-input.min.js └── react-date-input.js ├── .eslintrc ├── gulpfile.js ├── src ├── __tests__ │ └── DateInput-test.js └── DateInput.js ├── bower.json ├── LICENSE ├── lib └── DateInput.js └── package.json /.npmignore: -------------------------------------------------------------------------------- 1 | .editorconfig 2 | bower.json 3 | example/dist 4 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | lib/* 2 | dist/* 3 | example/dist/* 4 | node_modules/* 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-date-input 2 | 3 | A React.js Date Input Component 4 | -------------------------------------------------------------------------------- /HISTORY.md: -------------------------------------------------------------------------------- 1 | # React-Date-Select 2 | 3 | ## v0.0.1 / 2015-05-10 4 | 5 | * Initial Release (WIP) 6 | -------------------------------------------------------------------------------- /less/component.less: -------------------------------------------------------------------------------- 1 | @import "dateinput.less"; 2 | @import "mixins.less"; 3 | @import "variables.less"; 4 | -------------------------------------------------------------------------------- /example/src/.gitignore: -------------------------------------------------------------------------------- 1 | ## This file is here to ensure it is included in the gh-pages branch, 2 | ## when `gulp deploy` is used to push updates to the demo site. 3 | 4 | # Dependency directory 5 | node_modules 6 | -------------------------------------------------------------------------------- /less/variables.less: -------------------------------------------------------------------------------- 1 | // 2 | // Variables 3 | // ============================== 4 | 5 | 6 | // Typography 7 | // ------------------------------ 8 | 9 | @DateInput-font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 10 | @DateInput-font-size: 14px; 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Coverage tools 11 | lib-cov 12 | coverage 13 | 14 | # Dependency directory 15 | node_modules 16 | 17 | # Publish directory 18 | .publish 19 | example/dist 20 | 21 | # Other 22 | .DS_Store 23 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # This file is for unifying the coding style for different editors and IDEs 2 | # editorconfig.org 3 | root = true 4 | 5 | [*] 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = false 9 | insert_final_newline = true 10 | indent_style = tab 11 | 12 | [*.json] 13 | indent_style = space 14 | indent_size = 2 15 | 16 | [*.yml] 17 | indent_style = space 18 | indent_size = 2 19 | -------------------------------------------------------------------------------- /dist/component.css: -------------------------------------------------------------------------------- 1 | .DateInput { 2 | font-size: 14px; 3 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 4 | -webkit-font-smoothing: antialiased; 5 | } 6 | .DateInput * { 7 | -webkit-box-sizing: border-box; 8 | -moz-box-sizing: border-box; 9 | box-sizing: border-box; 10 | } 11 | .DateInput button, 12 | .DateInput input, 13 | .DateInput select { 14 | font-size: inherit; 15 | font-family: inherit; 16 | margin: 0; 17 | -webkit-appearance: none; 18 | -moz-appearance: none; 19 | } 20 | -------------------------------------------------------------------------------- /less/dateinput.less: -------------------------------------------------------------------------------- 1 | // 2 | // Date Select 3 | // ============================== 4 | 5 | // Normalize 6 | // ------------------------------ 7 | 8 | .DateInput { 9 | font-size: @DateInput-font-size; 10 | font-family: @DateInput-font-family; 11 | -webkit-font-smoothing: antialiased; 12 | 13 | * { 14 | #DateInput .box-sizing(border-box); 15 | } 16 | button, 17 | input, 18 | select { 19 | font-size: inherit; 20 | font-family: inherit; 21 | margin: 0; 22 | -webkit-appearance: none; 23 | -moz-appearance: none; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "babel-eslint", 3 | "env": { 4 | "browser": true, 5 | "node": true 6 | }, 7 | "plugins": [ 8 | "react" 9 | ], 10 | "rules": { 11 | "curly": [2, "multi-line"], 12 | "no-shadow": 0, 13 | "no-trailing-spaces": 0, 14 | "no-underscore-dangle": 0, 15 | "no-unused-expressions": 0, 16 | "quotes": [2, "single", "avoid-escape"], 17 | "react/jsx-quotes": 1, 18 | "react/jsx-no-undef": 1, 19 | "react/jsx-uses-react": 1, 20 | "react/jsx-uses-vars": 1, 21 | "react/no-did-mount-set-state": 1, 22 | "react/no-did-update-set-state": 1, 23 | "react/self-closing-comp": 1, 24 | "react/wrap-multilines": 1, 25 | "semi": 2, 26 | "strict": 0 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'), 2 | initGulpTasks = require('react-component-gulp-tasks'); 3 | 4 | var taskConfig = { 5 | 6 | component: { 7 | name: 'DateInput', 8 | dependencies: [ 9 | 'blacklist', 10 | 'classnames', 11 | 'moment', 12 | 'react', 13 | 'react/addons' 14 | ], 15 | less: { 16 | path: 'less', 17 | entry: 'component.less' 18 | } 19 | }, 20 | 21 | example: { 22 | src: 'example/src', 23 | dist: 'example/dist', 24 | files: [ 25 | 'index.html', 26 | '.gitignore' 27 | ], 28 | scripts: [ 29 | 'example.js' 30 | ], 31 | less: [ 32 | 'example.less' 33 | ] 34 | } 35 | 36 | }; 37 | 38 | initGulpTasks(gulp, taskConfig); 39 | -------------------------------------------------------------------------------- /src/__tests__/DateInput-test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | /*global describe, it, jest, expect*/ 3 | 4 | jest.dontMock('moment'); 5 | jest.dontMock('../DateInput'); 6 | 7 | var React = require('react/addons'); 8 | var DateInput = require('../DateInput'); 9 | var TestUtils = React.addons.TestUtils; 10 | 11 | describe('DateInput test', function() { 12 | 13 | // TODO: Add Tests 14 | 15 | // Render an instance of the component 16 | var instance = TestUtils.renderIntoDocument( 17 | 18 | ); 19 | 20 | var inputElement = TestUtils.findRenderedDOMComponentWithTag(instance, 'input'); 21 | 22 | it('should be rendered', function() { 23 | expect(inputElement.getDOMNode().parentNode.className).toEqual('DateInput'); 24 | }); 25 | 26 | }); 27 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-date-input", 3 | "main": "dist/react-date-input.min.js", 4 | "version": "0.0.2", 5 | "homepage": "https://github.com/JedWatson/react-date-input", 6 | "authors": [ 7 | "Jed Watson" 8 | ], 9 | "description": "A Date Input Component built with and for React.js", 10 | "moduleType": [ 11 | "amd", 12 | "globals", 13 | "node" 14 | ], 15 | "keywords": [ 16 | "react", 17 | "react-component", 18 | "date", 19 | "datepicker", 20 | "dateinput", 21 | "input", 22 | "form", 23 | "ui" 24 | ], 25 | "license": "MIT", 26 | "ignore": [ 27 | ".editorconfig", 28 | ".gitignore", 29 | "package.json", 30 | "src", 31 | "node_modules", 32 | "example", 33 | "test" 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /example/src/example.js: -------------------------------------------------------------------------------- 1 | var moment = require('moment'); 2 | var React = require('react/addons'); 3 | var DateInput = require('react-date-input'); 4 | 5 | var DateInputExamples = React.createClass({ 6 | getInitialState() { 7 | return { 8 | dateValue: new Date() 9 | }; 10 | }, 11 | onDateChange(key, value) { 12 | this.setState({ dateValue: value }); 13 | console.log('Date changed to: ' + value); 14 | }, 15 | render() { 16 | var value = moment(this.state.dateValue); 17 | return ( 18 |
19 |

Enter a date

20 | 21 |

Date is: {value.isValid() ? value.format('Do MMM YYYY') : '(not set or invalid)'}

22 |
23 | ); 24 | } 25 | }); 26 | 27 | React.render( 28 | , 29 | document.getElementById('example') 30 | ); 31 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Jed Watson 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 | -------------------------------------------------------------------------------- /src/DateInput.js: -------------------------------------------------------------------------------- 1 | var moment = require('moment'); 2 | var React = require('react'); 3 | 4 | var DateSelect = React.createClass({ 5 | propTypes: { 6 | value: React.PropTypes.any 7 | }, 8 | getDefaultProps () { 9 | return { 10 | value: null, 11 | format: 'YYYY-MM-DD' 12 | }; 13 | }, 14 | getInitialState () { 15 | var inputValue = ''; 16 | var dateValue = null; 17 | if (typeof this.props.value === 'string') { 18 | dateValue = moment(this.props.value, this.props.format); 19 | } else { 20 | dateValue = moment(this.props.value); 21 | } 22 | if (dateValue.isValid()) { 23 | inputValue = dateValue.format(this.props.format); 24 | } 25 | return { 26 | inputValue: inputValue 27 | }; 28 | }, 29 | handleInput (e) { 30 | this.setState({ 31 | inputValue: e.target.value 32 | }); 33 | }, 34 | handleBlur () { 35 | var value = moment(this.state.inputValue, this.props.format); 36 | this.props.onChange && this.props.onChange(value.isValid() ? value.toDate() : null); 37 | }, 38 | render () { 39 | return ( 40 | 41 | 42 | 43 | ); 44 | } 45 | }); 46 | 47 | module.exports = DateSelect; 48 | -------------------------------------------------------------------------------- /example/src/example.less: -------------------------------------------------------------------------------- 1 | // 2 | // Common Example Styles 3 | // ------------------------------ 4 | 5 | 6 | 7 | // normalize 8 | html { 9 | font-family: sans-serif; 10 | } 11 | body { 12 | background-color: white; 13 | color: #333; 14 | font-size: 16px; 15 | font-weight: 300; 16 | line-height: 1.4; 17 | margin: 0; 18 | } 19 | 20 | 21 | 22 | // Layout 23 | 24 | .container { 25 | margin-left: auto; 26 | margin-right: auto; 27 | max-width: 400px; 28 | padding: 1em; 29 | } 30 | 31 | .example-header { 32 | margin-bottom: 50px; 33 | border-bottom: 1px solid #ccc; 34 | padding: 20px 0; 35 | } 36 | 37 | .example-footer { 38 | margin-top: 50px; 39 | border-top: 1px solid #ccc; 40 | padding: 20px 0; 41 | font-size: 12px; 42 | color: #999; 43 | } 44 | 45 | 46 | // Type 47 | 48 | a { 49 | color: #08c; 50 | text-decoration: none; 51 | 52 | &:hover { 53 | text-decoration: underline; 54 | } 55 | } 56 | p { 57 | margin-top: 2em; 58 | } 59 | h1, h2, h3, h4, h5, h6 { 60 | color: #222; 61 | margin: 0; 62 | } 63 | 64 | 65 | // Small Devices 66 | 67 | @media (max-width: 480px) { 68 | body { 69 | font-size: 14px; 70 | font-weight: 400; 71 | } 72 | } 73 | 74 | 75 | // 76 | // Select Control 77 | // ------------------------------ 78 | 79 | @import "../../less/component.less"; 80 | -------------------------------------------------------------------------------- /lib/DateInput.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var moment = require('moment'); 4 | var React = require('react'); 5 | 6 | var DateSelect = React.createClass({ 7 | displayName: 'DateSelect', 8 | 9 | propTypes: { 10 | value: React.PropTypes.any 11 | }, 12 | getDefaultProps: function getDefaultProps() { 13 | return { 14 | value: null, 15 | format: 'YYYY-MM-DD' 16 | }; 17 | }, 18 | getInitialState: function getInitialState() { 19 | var inputValue = ''; 20 | var dateValue = null; 21 | if (typeof this.props.value === 'string') { 22 | dateValue = moment(this.props.value, this.props.format); 23 | } else { 24 | dateValue = moment(this.props.value); 25 | } 26 | if (dateValue.isValid()) { 27 | inputValue = dateValue.format(this.props.format); 28 | } 29 | return { 30 | inputValue: inputValue 31 | }; 32 | }, 33 | handleInput: function handleInput(e) { 34 | this.setState({ 35 | inputValue: e.target.value 36 | }); 37 | }, 38 | handleBlur: function handleBlur() { 39 | var value = moment(this.state.inputValue, this.props.format); 40 | this.props.onChange && this.props.onChange(value.isValid() ? value.toDate() : null); 41 | }, 42 | render: function render() { 43 | return React.createElement( 44 | 'span', 45 | { className: 'DateInput' }, 46 | React.createElement('input', { type: 'text', value: this.state.inputValue, onChange: this.handleInput, onBlur: this.handleBlur }) 47 | ); 48 | } 49 | }); 50 | 51 | module.exports = DateSelect; -------------------------------------------------------------------------------- /dist/react-date-input.min.js: -------------------------------------------------------------------------------- 1 | !function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,t.DateInput=e()}}(function(){return function e(t,n,r){function o(u,a){if(!n[u]){if(!t[u]){var p="function"==typeof require&&require;if(!a&&p)return p(u,!0);if(i)return i(u,!0);var s=new Error("Cannot find module '"+u+"'");throw s.code="MODULE_NOT_FOUND",s}var l=n[u]={exports:{}};t[u][0].call(l.exports,function(e){var n=t[u][1][e];return o(n?n:e)},l,l.exports,e,t,n,r)}return n[u].exports}for(var i="function"==typeof require&&require,u=0;u 2 | 3 | 4 | React-Date-Input Example 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 |
19 |

React Date Input

20 |

21 | A flexible Date Text input for React.js. 22 |
23 | View project and documentation on GitHub. 24 |

25 | 26 |
27 | 30 |
31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-date-input", 3 | "version": "0.0.2", 4 | "description": "A Date Input Component built with and for React.js", 5 | "main": "lib/DateInput.js", 6 | "author": "Jed Watson", 7 | "license": "MIT", 8 | "repository": { 9 | "type": "git", 10 | "url": "https://github.com/JedWatson/react-date-input.git" 11 | }, 12 | "dependencies": { 13 | "blacklist": "^1.1.2", 14 | "classnames": "^2.1.2", 15 | "moment": "~2.10.3" 16 | }, 17 | "devDependencies": { 18 | "babel-eslint": "^3.1.14", 19 | "babel-jest": "^5.2.0", 20 | "eslint": "^0.22.1", 21 | "eslint-plugin-react": "^2.5.0", 22 | "gulp": "^3.9.0", 23 | "jest-cli": "^0.4.7", 24 | "react": ">=0.12.0", 25 | "react-component-gulp-tasks": "^0.7.0" 26 | }, 27 | "peerDependencies": { 28 | "react": ">=0.12.0" 29 | }, 30 | "browserify-shim": { 31 | "blacklist": "blobal:blacklist", 32 | "classnames": "global:classNames", 33 | "moment": "global:moment", 34 | "react": "global:React" 35 | }, 36 | "scripts": { 37 | "build": "gulp clean && NODE_ENV=production gulp build", 38 | "bump": "gulp bump", 39 | "bump:major": "gulp bump:major", 40 | "bump:minor": "gulp bump:minor", 41 | "start": "gulp dev", 42 | "examples": "gulp dev:server", 43 | "lint": "eslint ./; true", 44 | "publish:site": "gulp publish:examples", 45 | "release": "gulp release", 46 | "test": "jest; true", 47 | "watch": "gulp watch:lib" 48 | }, 49 | "jest": { 50 | "scriptPreprocessor": "/node_modules/babel-jest", 51 | "unmockedModulePathPatterns": [ 52 | "/node_modules/react" 53 | ], 54 | "testPathDirs": [ 55 | "/src" 56 | ] 57 | }, 58 | "keywords": [ 59 | "react", 60 | "react-component", 61 | "date", 62 | "datepicker", 63 | "dateinput", 64 | "input", 65 | "form", 66 | "ui" 67 | ] 68 | } 69 | -------------------------------------------------------------------------------- /dist/react-date-input.js: -------------------------------------------------------------------------------- 1 | (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.DateInput = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o