diff --git a/README.md b/README.md
index e9fe090d1..1b9453cfe 100644
--- a/README.md
+++ b/README.md
@@ -1,21 +1,21 @@
react-big-calendar
========================
-An event Calendar component built for React. Inspired by [Full Calendar](http://fullcalendar.io/).
+An event Calendar component built for React.
+[__DEMO and Docs__](http://intljusticemission.github.io/react-big-calendar/examples/index.html).
big calendar is built for modern browsers (read: ie10+) and uses flexbox over the classic tables-ception approach.
-[__DEMO__](http://jquense.github.io/react-big-calendar/examples/index.html)
-
To run the example locally, `git clone`, `npm install` and `npm run examples`, hosted at localhost:3000.
+Inspired by [Full Calendar](http://fullcalendar.io/).
+
## Use and Setup
`npm install react-big-calendar --save`
Include `react-big-calendar/lib/css/react-big-calendar.css` for styles.
-
### Localization and Date Formatting
`react-big-calendar` includes two options for handling the date formatting and culture localization, depending
diff --git a/examples/Api.js b/examples/Api.js
index a6fe1add9..93565b55a 100644
--- a/examples/Api.js
+++ b/examples/Api.js
@@ -15,7 +15,7 @@ let Api = React.createClass({
return (
-
+
Props
@@ -35,7 +35,7 @@ let Api = React.createClass({
return (
-
+
{name}
diff --git a/examples/App.js b/examples/App.js
index ff8e372b6..6f5024c27 100644
--- a/examples/App.js
+++ b/examples/App.js
@@ -24,6 +24,7 @@ const Example = React.createClass({
let Current = {
basic: require('./demos/basic'),
selectable: require('./demos/selectable'),
+ cultures: require('./demos/cultures'),
popup: require('./demos/popup'),
rendering: require('./demos/rendering')
}[selected];
@@ -54,6 +55,9 @@ const Example = React.createClass({
Selectable
+
+ I18n and Locales
+
Popup
diff --git a/examples/demos/cultures.js b/examples/demos/cultures.js
new file mode 100644
index 000000000..612bf8d5b
--- /dev/null
+++ b/examples/demos/cultures.js
@@ -0,0 +1,45 @@
+import React from 'react';
+import BigCalendar from 'react-big-calendar';
+import events from '../events';
+
+require('globalize/lib/cultures/globalize.culture.en-GB');
+require('globalize/lib/cultures/globalize.culture.es');
+require('globalize/lib/cultures/globalize.culture.fr');
+require('globalize/lib/cultures/globalize.culture.ar-AE');
+
+let Cultures = React.createClass({
+
+ getInitialState(){
+ return { culture: 'fr' }
+ },
+
+ render(){
+ let cultures = ['en', 'en-GB', 'es', 'fr', 'ar-AE']
+
+ return (
+
+
+ Select a Culture
+ {' '}
+ this.setState({ culture: e.target.value })}
+ >
+ {
+ cultures.map((c, idx) =>
+ {c}
+ )
+ }
+
+
+
+
+ )
+ }
+})
+
+export default Cultures;
diff --git a/examples/static/bundle.js b/examples/static/bundle.js
deleted file mode 100644
index e6c1d1e16..000000000
--- a/examples/static/bundle.js
+++ /dev/null
@@ -1,30937 +0,0 @@
-/******/ (function(modules) { // webpackBootstrap
-/******/ // The module cache
-/******/ var installedModules = {};
-
-/******/ // The require function
-/******/ function __webpack_require__(moduleId) {
-
-/******/ // Check if module is in cache
-/******/ if(installedModules[moduleId])
-/******/ return installedModules[moduleId].exports;
-
-/******/ // Create a new module (and put it into the cache)
-/******/ var module = installedModules[moduleId] = {
-/******/ exports: {},
-/******/ id: moduleId,
-/******/ loaded: false
-/******/ };
-
-/******/ // Execute the module function
-/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
-
-/******/ // Flag the module as loaded
-/******/ module.loaded = true;
-
-/******/ // Return the exports of the module
-/******/ return module.exports;
-/******/ }
-
-
-/******/ // expose the modules object (__webpack_modules__)
-/******/ __webpack_require__.m = modules;
-
-/******/ // expose the module cache
-/******/ __webpack_require__.c = installedModules;
-
-/******/ // __webpack_public_path__
-/******/ __webpack_require__.p = "/static/";
-
-/******/ // Load entry module and return exports
-/******/ return __webpack_require__(0);
-/******/ })
-/************************************************************************/
-/******/ ([
-/* 0 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
-
- var _react = __webpack_require__(10);
-
- var _react2 = _interopRequireDefault(_react);
-
- var _Api = __webpack_require__(162);
-
- var _Api2 = _interopRequireDefault(_Api);
-
- var _classnames = __webpack_require__(210);
-
- var _classnames2 = _interopRequireDefault(_classnames);
-
- var _reactDom = __webpack_require__(211);
-
- var _reactBigCalendarLocalizersGlobalize = __webpack_require__(212);
-
- var _reactBigCalendarLocalizersGlobalize2 = _interopRequireDefault(_reactBigCalendarLocalizersGlobalize);
-
- var _globalize = __webpack_require__(219);
-
- var _globalize2 = _interopRequireDefault(_globalize);
-
- __webpack_require__(220);
-
- __webpack_require__(224);
-
- _reactBigCalendarLocalizersGlobalize2['default'](_globalize2['default']);
-
- var Example = _react2['default'].createClass({
- displayName: 'Example',
-
- getInitialState: function getInitialState() {
- return {
- selected: 'basic'
- };
- },
-
- render: function render() {
- var selected = this.state.selected;
- var Current = ({
- basic: __webpack_require__(226),
- selectable: __webpack_require__(327),
- popup: __webpack_require__(328),
- rendering: __webpack_require__(329)
- })[selected];
-
- return _react2['default'].createElement(
- 'div',
- { className: 'app' },
- _react2['default'].createElement(
- 'div',
- { className: 'jumbotron' },
- _react2['default'].createElement(
- 'div',
- { className: 'container' },
- _react2['default'].createElement(
- 'h1',
- null,
- 'Big Calendar ',
- _react2['default'].createElement('i', { className: 'fa fa-calendar' })
- ),
- _react2['default'].createElement(
- 'p',
- null,
- 'such enterprise, very business.'
- ),
- _react2['default'].createElement(
- 'p',
- null,
- _react2['default'].createElement(
- 'a',
- { href: '#api' },
- _react2['default'].createElement('i', { className: 'fa fa-book' }),
- ' API documentation'
- ),
- ' | ',
- _react2['default'].createElement(
- 'a',
- { target: '_blank', href: 'https://github.com/intljusticemission/react-big-calendar' },
- _react2['default'].createElement('i', { className: 'fa fa-github' }),
- ' github'
- )
- )
- )
- ),
- _react2['default'].createElement(
- 'div',
- { className: 'examples contain' },
- _react2['default'].createElement(
- 'aside',
- null,
- _react2['default'].createElement(
- 'ul',
- { className: 'nav nav-pills nav-stacked' },
- _react2['default'].createElement(
- 'li',
- { className: _classnames2['default']({ active: selected === 'basic' }) },
- _react2['default'].createElement(
- 'a',
- { href: '#', onClick: this.select.bind(null, 'basic') },
- 'Basic'
- )
- ),
- _react2['default'].createElement(
- 'li',
- { className: _classnames2['default']({ active: selected === 'selectable' }) },
- _react2['default'].createElement(
- 'a',
- { href: '#', onClick: this.select.bind(null, 'selectable') },
- 'Selectable'
- )
- ),
- _react2['default'].createElement(
- 'li',
- { className: _classnames2['default']({ active: selected === 'popup' }) },
- _react2['default'].createElement(
- 'a',
- { href: '#', onClick: this.select.bind(null, 'popup') },
- 'Popup'
- )
- ),
- _react2['default'].createElement(
- 'li',
- { className: _classnames2['default']({ active: selected === 'rendering' }) },
- _react2['default'].createElement(
- 'a',
- { href: '#', onClick: this.select.bind(null, 'rendering') },
- 'Custom rendering'
- )
- )
- )
- ),
- _react2['default'].createElement(
- 'div',
- { className: 'example' },
- _react2['default'].createElement(Current, null)
- )
- ),
- _react2['default'].createElement(
- 'div',
- { className: 'docs' },
- _react2['default'].createElement(_Api2['default'], { className: 'contain' })
- )
- );
- },
-
- select: function select(selected, e) {
- e.preventDefault();
- this.setState({ selected: selected });
- }
- });
-
- _reactDom.render(_react2['default'].createElement(Example, null), document.getElementById('root'));
-
-/***/ },
-/* 1 */,
-/* 2 */,
-/* 3 */,
-/* 4 */,
-/* 5 */,
-/* 6 */,
-/* 7 */,
-/* 8 */,
-/* 9 */,
-/* 10 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- module.exports = __webpack_require__(11);
-
-
-/***/ },
-/* 11 */
-/***/ function(module, exports, __webpack_require__) {
-
- /**
- * Copyright 2013-2015, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- *
- * @providesModule React
- */
-
- 'use strict';
-
- var ReactDOM = __webpack_require__(12);
- var ReactDOMServer = __webpack_require__(152);
- var ReactIsomorphic = __webpack_require__(156);
-
- var assign = __webpack_require__(47);
- var deprecated = __webpack_require__(161);
-
- // `version` will be added here by ReactIsomorphic.
- var React = {};
-
- assign(React, ReactIsomorphic);
-
- assign(React, {
- // ReactDOM
- findDOMNode: deprecated('findDOMNode', 'ReactDOM', 'react-dom', ReactDOM, ReactDOM.findDOMNode),
- render: deprecated('render', 'ReactDOM', 'react-dom', ReactDOM, ReactDOM.render),
- unmountComponentAtNode: deprecated('unmountComponentAtNode', 'ReactDOM', 'react-dom', ReactDOM, ReactDOM.unmountComponentAtNode),
-
- // ReactDOMServer
- renderToString: deprecated('renderToString', 'ReactDOMServer', 'react-dom/server', ReactDOMServer, ReactDOMServer.renderToString),
- renderToStaticMarkup: deprecated('renderToStaticMarkup', 'ReactDOMServer', 'react-dom/server', ReactDOMServer, ReactDOMServer.renderToStaticMarkup)
- });
-
- React.__SECRET_DOM_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = ReactDOM;
- React.__SECRET_DOM_SERVER_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = ReactDOMServer;
-
- module.exports = React;
-
-/***/ },
-/* 12 */
-/***/ function(module, exports, __webpack_require__) {
-
- /**
- * Copyright 2013-2015, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- *
- * @providesModule ReactDOM
- */
-
- /* globals __REACT_DEVTOOLS_GLOBAL_HOOK__*/
-
- 'use strict';
-
- var ReactCurrentOwner = __webpack_require__(13);
- var ReactDOMTextComponent = __webpack_require__(14);
- var ReactDefaultInjection = __webpack_require__(79);
- var ReactInstanceHandles = __webpack_require__(53);
- var ReactMount = __webpack_require__(36);
- var ReactPerf = __webpack_require__(26);
- var ReactReconciler = __webpack_require__(58);
- var ReactUpdates = __webpack_require__(62);
- var ReactVersion = __webpack_require__(150);
-
- var findDOMNode = __webpack_require__(99);
- var renderSubtreeIntoContainer = __webpack_require__(151);
- var warning = __webpack_require__(33);
-
- ReactDefaultInjection.inject();
-
- var render = ReactPerf.measure('React', 'render', ReactMount.render);
-
- var React = {
- findDOMNode: findDOMNode,
- render: render,
- unmountComponentAtNode: ReactMount.unmountComponentAtNode,
- version: ReactVersion,
-
- /* eslint-disable camelcase */
- unstable_batchedUpdates: ReactUpdates.batchedUpdates,
- unstable_renderSubtreeIntoContainer: renderSubtreeIntoContainer
- };
-
- // Inject the runtime into a devtools global hook regardless of browser.
- // Allows for debugging when the hook is injected on the page.
- /* eslint-enable camelcase */
- if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined' && typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.inject === 'function') {
- __REACT_DEVTOOLS_GLOBAL_HOOK__.inject({
- CurrentOwner: ReactCurrentOwner,
- InstanceHandles: ReactInstanceHandles,
- Mount: ReactMount,
- Reconciler: ReactReconciler,
- TextComponent: ReactDOMTextComponent
- });
- }
-
- if (false) {
- var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment');
- if (ExecutionEnvironment.canUseDOM && window.top === window.self) {
-
- // First check if devtools is not installed
- if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') {
- // If we're in Chrome or Firefox, provide a download link if not installed.
- if (navigator.userAgent.indexOf('Chrome') > -1 && navigator.userAgent.indexOf('Edge') === -1 || navigator.userAgent.indexOf('Firefox') > -1) {
- console.debug('Download the React DevTools for a better development experience: ' + 'https://fb.me/react-devtools');
- }
- }
-
- // If we're in IE8, check to see if we are in compatibility mode and provide
- // information on preventing compatibility mode
- var ieCompatibilityMode = document.documentMode && document.documentMode < 8;
-
- process.env.NODE_ENV !== 'production' ? warning(!ieCompatibilityMode, 'Internet Explorer is running in compatibility mode; please add the ' + 'following tag to your HTML to prevent this from happening: ' + ' ') : undefined;
-
- var expectedFeatures = [
- // shims
- Array.isArray, Array.prototype.every, Array.prototype.forEach, Array.prototype.indexOf, Array.prototype.map, Date.now, Function.prototype.bind, Object.keys, String.prototype.split, String.prototype.trim,
-
- // shams
- Object.create, Object.freeze];
-
- for (var i = 0; i < expectedFeatures.length; i++) {
- if (!expectedFeatures[i]) {
- console.error('One or more ES5 shim/shams expected by React are not available: ' + 'https://fb.me/react-warning-polyfills');
- break;
- }
- }
- }
- }
-
- module.exports = React;
-
-/***/ },
-/* 13 */
-/***/ function(module, exports) {
-
- /**
- * Copyright 2013-2015, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- *
- * @providesModule ReactCurrentOwner
- */
-
- 'use strict';
-
- /**
- * Keeps track of the current owner.
- *
- * The current owner is the component who should own any components that are
- * currently being constructed.
- */
- var ReactCurrentOwner = {
-
- /**
- * @internal
- * @type {ReactComponent}
- */
- current: null
-
- };
-
- module.exports = ReactCurrentOwner;
-
-/***/ },
-/* 14 */
-/***/ function(module, exports, __webpack_require__) {
-
- /**
- * Copyright 2013-2015, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- *
- * @providesModule ReactDOMTextComponent
- * @typechecks static-only
- */
-
- 'use strict';
-
- var DOMChildrenOperations = __webpack_require__(15);
- var DOMPropertyOperations = __webpack_require__(30);
- var ReactComponentBrowserEnvironment = __webpack_require__(34);
- var ReactMount = __webpack_require__(36);
-
- var assign = __webpack_require__(47);
- var escapeTextContentForBrowser = __webpack_require__(29);
- var setTextContent = __webpack_require__(28);
- var validateDOMNesting = __webpack_require__(78);
-
- /**
- * Text nodes violate a couple assumptions that React makes about components:
- *
- * - When mounting text into the DOM, adjacent text nodes are merged.
- * - Text nodes cannot be assigned a React root ID.
- *
- * This component is used to wrap strings in elements so that they can undergo
- * the same reconciliation that is applied to elements.
- *
- * TODO: Investigate representing React components in the DOM with text nodes.
- *
- * @class ReactDOMTextComponent
- * @extends ReactComponent
- * @internal
- */
- var ReactDOMTextComponent = function (props) {
- // This constructor and its argument is currently used by mocks.
- };
-
- assign(ReactDOMTextComponent.prototype, {
-
- /**
- * @param {ReactText} text
- * @internal
- */
- construct: function (text) {
- // TODO: This is really a ReactText (ReactNode), not a ReactElement
- this._currentElement = text;
- this._stringText = '' + text;
-
- // Properties
- this._rootNodeID = null;
- this._mountIndex = 0;
- },
-
- /**
- * Creates the markup for this text node. This node is not intended to have
- * any features besides containing text content.
- *
- * @param {string} rootID DOM ID of the root node.
- * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
- * @return {string} Markup for this text node.
- * @internal
- */
- mountComponent: function (rootID, transaction, context) {
- if (false) {
- if (context[validateDOMNesting.ancestorInfoContextKey]) {
- validateDOMNesting('span', null, context[validateDOMNesting.ancestorInfoContextKey]);
- }
- }
-
- this._rootNodeID = rootID;
- if (transaction.useCreateElement) {
- var ownerDocument = context[ReactMount.ownerDocumentContextKey];
- var el = ownerDocument.createElement('span');
- DOMPropertyOperations.setAttributeForID(el, rootID);
- // Populate node cache
- ReactMount.getID(el);
- setTextContent(el, this._stringText);
- return el;
- } else {
- var escapedText = escapeTextContentForBrowser(this._stringText);
-
- if (transaction.renderToStaticMarkup) {
- // Normally we'd wrap this in a `span` for the reasons stated above, but
- // since this is a situation where React won't take over (static pages),
- // we can simply return the text as it is.
- return escapedText;
- }
-
- return '' + escapedText + ' ';
- }
- },
-
- /**
- * Updates this component by updating the text content.
- *
- * @param {ReactText} nextText The next text content
- * @param {ReactReconcileTransaction} transaction
- * @internal
- */
- receiveComponent: function (nextText, transaction) {
- if (nextText !== this._currentElement) {
- this._currentElement = nextText;
- var nextStringText = '' + nextText;
- if (nextStringText !== this._stringText) {
- // TODO: Save this as pending props and use performUpdateIfNecessary
- // and/or updateComponent to do the actual update for consistency with
- // other component types?
- this._stringText = nextStringText;
- var node = ReactMount.getNode(this._rootNodeID);
- DOMChildrenOperations.updateTextContent(node, nextStringText);
- }
- }
- },
-
- unmountComponent: function () {
- ReactComponentBrowserEnvironment.unmountIDFromEnvironment(this._rootNodeID);
- }
-
- });
-
- module.exports = ReactDOMTextComponent;
-
-/***/ },
-/* 15 */
-/***/ function(module, exports, __webpack_require__) {
-
- /**
- * Copyright 2013-2015, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- *
- * @providesModule DOMChildrenOperations
- * @typechecks static-only
- */
-
- 'use strict';
-
- var Danger = __webpack_require__(16);
- var ReactMultiChildUpdateTypes = __webpack_require__(24);
- var ReactPerf = __webpack_require__(26);
-
- var setInnerHTML = __webpack_require__(27);
- var setTextContent = __webpack_require__(28);
- var invariant = __webpack_require__(21);
-
- /**
- * Inserts `childNode` as a child of `parentNode` at the `index`.
- *
- * @param {DOMElement} parentNode Parent node in which to insert.
- * @param {DOMElement} childNode Child node to insert.
- * @param {number} index Index at which to insert the child.
- * @internal
- */
- function insertChildAt(parentNode, childNode, index) {
- // By exploiting arrays returning `undefined` for an undefined index, we can
- // rely exclusively on `insertBefore(node, null)` instead of also using
- // `appendChild(node)`. However, using `undefined` is not allowed by all
- // browsers so we must replace it with `null`.
-
- // fix render order error in safari
- // IE8 will throw error when index out of list size.
- var beforeChild = index >= parentNode.childNodes.length ? null : parentNode.childNodes.item(index);
-
- parentNode.insertBefore(childNode, beforeChild);
- }
-
- /**
- * Operations for updating with DOM children.
- */
- var DOMChildrenOperations = {
-
- dangerouslyReplaceNodeWithMarkup: Danger.dangerouslyReplaceNodeWithMarkup,
-
- updateTextContent: setTextContent,
-
- /**
- * Updates a component's children by processing a series of updates. The
- * update configurations are each expected to have a `parentNode` property.
- *
- * @param {array} updates List of update configurations.
- * @param {array} markupList List of markup strings.
- * @internal
- */
- processUpdates: function (updates, markupList) {
- var update;
- // Mapping from parent IDs to initial child orderings.
- var initialChildren = null;
- // List of children that will be moved or removed.
- var updatedChildren = null;
-
- for (var i = 0; i < updates.length; i++) {
- update = updates[i];
- if (update.type === ReactMultiChildUpdateTypes.MOVE_EXISTING || update.type === ReactMultiChildUpdateTypes.REMOVE_NODE) {
- var updatedIndex = update.fromIndex;
- var updatedChild = update.parentNode.childNodes[updatedIndex];
- var parentID = update.parentID;
-
- !updatedChild ? false ? invariant(false, 'processUpdates(): Unable to find child %s of element. This ' + 'probably means the DOM was unexpectedly mutated (e.g., by the ' + 'browser), usually due to forgetting a when using tables, ' + 'nesting tags like