├── .gitignore
├── index.js
├── screenshot.gif
├── .babelrc
├── dist
├── datepicker.min.css.map
├── datepicker.min.css
├── datepicker.min.js
└── datepicker.min.js.map
├── src
├── scripts
│ ├── util.js
│ ├── index.js
│ ├── decorators.js
│ ├── date.js
│ ├── DatePickerRange.js
│ ├── Calendar.js
│ └── DatePicker.js
└── styles
│ └── datepicker.css
├── .editorconfig
├── example
├── index.js
└── index.html
├── webpack.config.js
├── LICENSE.md
├── package.json
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .idea
3 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | module.exports = require("./dist/datepicker");
2 |
--------------------------------------------------------------------------------
/screenshot.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/evangilo/light-datepicker/HEAD/screenshot.gif
--------------------------------------------------------------------------------
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["es2015", "stage-0"],
3 | "plugins": ["transform-object-rest-spread"]
4 | }
5 |
--------------------------------------------------------------------------------
/dist/datepicker.min.css.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":[],"names":[],"mappings":"","file":"datepicker.min.css","sourceRoot":""}
--------------------------------------------------------------------------------
/src/scripts/util.js:
--------------------------------------------------------------------------------
1 | export function createNode(name, className, html) {
2 | let node = document.createElement(name);
3 | node.className = className;
4 | node.innerHTML = html;
5 | return node;
6 | }
7 |
--------------------------------------------------------------------------------
/src/scripts/index.js:
--------------------------------------------------------------------------------
1 | import { Calendar } from './Calendar';
2 | import { DatePicker } from './DatePicker';
3 | import { DatePickerRange } from './DatePickerRange';
4 |
5 | export {
6 | Calendar,
7 | DatePicker,
8 | DatePickerRange
9 | };
10 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # editorconfig.org
2 | root = true
3 |
4 | [*]
5 | charset = utf-8
6 | end_of_line = lf
7 | indent_size = 2
8 | indent_style = space
9 | insert_final_newline = true
10 | trim_trailing_whitespace = true
11 | draw_white_space = true
12 |
13 | [*.md]
14 | trim_trailing_whitespace = false
15 |
--------------------------------------------------------------------------------
/example/index.js:
--------------------------------------------------------------------------------
1 | const single = new datepicker.DatePicker({ selector: '#datepicker' });
2 | const range = new datepicker.DatePickerRange({
3 | language: 'pt-BR',
4 | leftSelector: '#left-datepicker',
5 | rightSelector: '#right-datepicker',
6 | appendTo: '.jumbotron'
7 | });
8 |
9 | single.calendar.on('clickDate', event => console.log('single:date', event.detail));
10 | range.leftDatePicker.calendar.on('clickDate', event => console.log('left:date', event.detail));
11 | range.rightDatePicker.calendar.on('clickDate', event => console.log('right:date', event.detail));
12 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | var webpack = require("webpack");
2 | var ExtractTextPlugin = require('extract-text-webpack-plugin');
3 |
4 | module.exports = {
5 | entry: "./src/scripts",
6 | devtool: "source-map",
7 | output: {
8 | path: `${__dirname}/dist`,
9 | filename: "datepicker.min.js",
10 | watch: true,
11 | libraryTarget: "var",
12 | library: 'datepicker'
13 | },
14 | module: {
15 | loaders: [
16 | {test: /\.js$/, exclude: /node_modules/, loader: "babel-loader"},
17 | { test: /\.css$/, loader: ExtractTextPlugin.extract("style-loader", "css-loader") }
18 | ]
19 | },
20 | plugins: [
21 | new webpack.optimize.UglifyJsPlugin({minimize: true}),
22 | new ExtractTextPlugin("datepicker.min.css")
23 | ]
24 | };
25 |
26 |
--------------------------------------------------------------------------------
/src/scripts/decorators.js:
--------------------------------------------------------------------------------
1 | import { isSame } from './date';
2 |
3 | export const todayDecorator = () => ({
4 | shouldApply: (nodeDate) => isSame(nodeDate, new Date()),
5 | className: 'today'
6 | });
7 |
8 | export const outMonthDecorator = (cb) => ({
9 | shouldApply: (nodeDate) => !isSame(nodeDate, cb(), 'year month'),
10 | className: 'out-month'
11 | });
12 |
13 | export const thisMonthDecorator = (cb) => ({
14 | shouldApply: (nodeDate) => isSame(nodeDate, cb(), 'year month'),
15 | className: 'enabled'
16 | });
17 |
18 | export const selectedDecorator = (cb) => ({
19 | shouldApply: (nodeDate) => isSame(nodeDate, cb()),
20 | className: 'selected'
21 | });
22 |
23 | export const disabledRangeDecorator = (cb) => ({
24 | shouldApply: (nodeDate) => nodeDate < cb(),
25 | className: 'disabled'
26 | });
27 |
28 | export const rangeDecorator = (startCB, endCB) => ({
29 | shouldApply: (nodeDate) => nodeDate >= startCB() && nodeDate <= endCB(),
30 | className: 'range'
31 | });
32 |
--------------------------------------------------------------------------------
/src/scripts/date.js:
--------------------------------------------------------------------------------
1 | export function nextMonth(date) {
2 | return new Date(date.getFullYear(), date.getMonth() + 1);
3 | }
4 |
5 | export function prevMonth(date) {
6 | return new Date(date.getFullYear(), date.getMonth() - 1);
7 | }
8 |
9 | export function startMonth(date) {
10 | return new Date(date.getFullYear(), date.getMonth(), 1);
11 | }
12 |
13 | export function endMonth(date) {
14 | return new Date(date.getFullYear(), date.getMonth() + 1, 0);
15 | }
16 |
17 | export function datesInMonth(date) {
18 | let length = {length: endMonth(date).getDate()};
19 | return Array.from(length, (_, day) => new Date(date.getFullYear(), date.getMonth(), day + 1));
20 | }
21 |
22 | export function isSame(date, other, filter='year month day') {
23 | if (!date || !other) return false;
24 | return (!filter.includes('year') || date.getFullYear() === other.getFullYear()) &&
25 | (!filter.includes('month') || date.getMonth() === other.getMonth()) &&
26 | (!filter.includes('day') || date.getDate() === other.getDate())
27 | }
28 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Evangilo
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 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "light-datepicker",
3 | "version": "0.1.1",
4 | "description": "Light DatePicker",
5 | "main": "index",
6 | "scripts": {
7 | "start": "webpack-dev-server --inline --hot --content-base ./",
8 | "build": "webpack"
9 | },
10 | "devDependencies": {
11 | "babel-cli": "^6.11.4",
12 | "babel-core": "^6.11.4",
13 | "babel-loader": "^6.2.4",
14 | "babel-plugin-transform-object-rest-spread": "^6.8.0",
15 | "babel-preset-es2015": "^6.9.0",
16 | "babel-preset-stage-0": "^6.5.0",
17 | "babel-runtime": "^6.11.6",
18 | "css-loader": "^0.23.1",
19 | "extract-text-webpack-plugin": "^1.0.1",
20 | "style-loader": "^0.13.1",
21 | "webpack": "^1.13.2",
22 | "webpack-dev-server": "^1.14.1"
23 | },
24 | "dependencies": {},
25 | "repository": {
26 | "type": "git",
27 | "url": "git+https://github.com/evangilo/light-datepicker.git"
28 | },
29 | "author": "Evangilo Morais",
30 | "email": "evangilo@gmail.com",
31 | "license": "MIT",
32 | "keywords": [
33 | "Calendar",
34 | "DatePicker",
35 | "DateRangePicker"
36 | ],
37 | "bugs": {
38 | "url": "https://github.com/evangilo/light-datepicker/issues"
39 | },
40 | "homepage": "https://github.com/evangilo/light-datepicker#readme"
41 | }
42 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Light Datepicker
2 |
3 | > Ultra light and minimalist Datepicker with zero dependencies.
4 |
5 | ## Preview
6 | 
7 |
8 |
9 | ## Install
10 | ```
11 | npm install light-datepicker --save
12 | ```
13 |
14 | ## Basic Usage
15 |
16 | ```HTML
17 | // HTML
18 |
19 |
20 |
21 | ```
22 |
23 | ```JS
24 | // Javascript
25 | const single = new datepicker.DatePicker({ selector: '#datepicker' });
26 |
27 | const range = new datepicker.DatePickerRange({
28 | leftSelector: '#left-datepicker',
29 | rightSelector: '#right-datepicker',
30 | });
31 |
32 | single.calendar.on('clickDate', event => console.log('single:date', event.detail));
33 | range.leftDatePicker.calendar.on('clickDate', event => console.log('left:date', event.detail));
34 | range.rightDatePicker.calendar.on('clickDate', event => console.log('right:date', event.detail));
35 | ```
36 |
37 | ## Run Example
38 | ```
39 | git clone https://github.com/evangilo/light-datepicker.git
40 |
41 | npm install
42 |
43 | npm start
44 | ```
45 |
46 | Open url in your browser: http://localhost:8080/example/
47 |
48 | License
49 | Light Datepicker is released under the MIT License. See [LICENSE](https://github.com/evangilo/light-datepicker/blob/master/LICENSE.md) file for details.
50 |
51 | ## Browser Support
52 |
53 | @TODO
54 |
--------------------------------------------------------------------------------
/dist/datepicker.min.css:
--------------------------------------------------------------------------------
1 | .datepicker{position:absolute;width:260px;box-shadow:0 0 10px rgba(0,0,0,.4);padding:15px;z-index:9999;background-color:#fff}.datepicker,.datepicker span{box-sizing:content-box}.datepicker .arrow{position:relative;background:#fff}.datepicker .arrow:after{content:"";position:absolute;width:0;height:0;border:10px solid rgba(0,0,0,.4);border-color:#fff #fff transparent transparent;transform:rotate(-45deg);top:-23px;left:15px;box-shadow:3px -3px 3px 0 rgba(0,0,0,.15)}.datepicker .weekdays{width:260px}.datepicker .calendar span,.datepicker .weekdays span{display:inline-block;background-color:#fff;text-align:center;text-transform:capitalize;margin:3px;padding:5px;border:1px solid #fff;width:calc(1 / 7 * 100% - 18px)}.datepicker .weekdays span{padding:0!important}.calendar span.out-month{visibility:hidden}.calendar span.enabled{background-color:#eee;border:1px solid #eee;cursor:pointer}.calendar span.enabled:hover,.calendar span.range{background-color:#fff;border:1px solid #ff690f;color:#ff690f}.calendar span.disabled,.calendar span.disabled:hover{background-color:#fff;color:#ccc;border:1px solid #fff;cursor:default}.calendar span.selected,.calendar span.selected:hover{background-color:#ff690f;color:#fff;font-weight:600}.datepicker .header{display:flex;flex-direction:row;justify-content:space-between;line-height:28px}.datepicker .header .next,.datepicker .header .prev{background-color:transparent;border:none;font-size:1.5em;font-weight:900;padding:0;cursor:pointer;line-height:18px}.datepicker .header .next:hover,.datepicker .header .prev:hover{color:#ff690f;cursor:pointer}.datepicker .header .next.disabled,.datepicker .header .prev.disabled{visibility:hidden}
2 | /*# sourceMappingURL=datepicker.min.css.map*/
--------------------------------------------------------------------------------
/src/scripts/DatePickerRange.js:
--------------------------------------------------------------------------------
1 | import { DatePicker } from './DatePicker';
2 | import { disabledRangeDecorator, rangeDecorator } from './decorators';
3 |
4 | export class DatePickerRange {
5 |
6 | constructor(options) {
7 | this.leftDatePicker = new DatePicker({ ...options, ...{ selector: options.leftSelector } });
8 | this.rightDatePicker = new DatePicker({ ...options, ...{ selector: options.rightSelector } });
9 | this.leftDatePicker.calendar.on('clickDate', (event) => this.onLeftSelectDate(event.detail));
10 | this.rightDatePicker.calendar.on('clickDate', (event) => this.onRightSelectDate(event.detail));
11 |
12 | this.rightDatePicker.parentElement.addEventListener('focus', e => this.leftDatePicker.hide());
13 | this.leftDatePicker.parentElement.addEventListener('focus', e => this.rightDatePicker.hide());
14 |
15 | this.setupDecorators();
16 | }
17 |
18 | onLeftSelectDate(date) {
19 | let leftDate = this.leftDatePicker.options.currentDate;
20 | let rightDate = this.rightDatePicker.options.currentDate;
21 | if (rightDate < leftDate) {
22 | this.rightDatePicker.options.currentMonth = leftDate;
23 | this.rightDatePicker.options.currentDate = leftDate;
24 | this.rightDatePicker.updateInputValue();
25 | this.rightDatePicker.draw();
26 | }
27 | this.leftDatePicker.hide();
28 | this.rightDatePicker.show();
29 | }
30 |
31 | onRightSelectDate(date) {
32 | this.rightDatePicker.hide(300);
33 | }
34 |
35 | setupDecorators() {
36 | const getStartDate = () => this.leftDatePicker.options.currentDate;
37 | const getEndDate = () => this.rightDatePicker.options.currentDate;
38 | const rangeDec = rangeDecorator(getStartDate, getEndDate);
39 | this.leftDatePicker.calendar.addDecorator(rangeDec);
40 | this.rightDatePicker.calendar.addDecorator(rangeDec);
41 | this.rightDatePicker.calendar.addDecorator(disabledRangeDecorator(() => this.leftDatePicker.options.currentDate));
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/example/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | DatePicker
5 |
6 |
7 |
8 |
9 |
10 |
11 |
DatePicker
12 |
13 |
14 |
15 |
26 |
27 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/src/scripts/Calendar.js:
--------------------------------------------------------------------------------
1 | import { createNode } from './util';
2 | import {
3 | nextMonth,
4 | prevMonth,
5 | startMonth,
6 | datesInMonth
7 | } from './date';
8 |
9 | const MAXIMUM_NUMBER_OF_DAYS = 42;
10 |
11 | export class Calendar {
12 | constructor() {
13 | this.decorators = [];
14 | this.container = createNode('div', 'calendar', null);
15 | this.nodes = new Array(MAXIMUM_NUMBER_OF_DAYS);
16 | this.render();
17 | }
18 |
19 | render() {
20 | const container = this.container;
21 | const nodes = this.nodes;
22 | const fragment = document.createDocumentFragment();
23 | // TODO: Evited assign and use immutability
24 | for (let i = 0; i < MAXIMUM_NUMBER_OF_DAYS; i++) {
25 | nodes[i] = this.createDateNode();
26 | fragment.appendChild(nodes[i]);
27 | }
28 | container.appendChild(fragment);
29 | }
30 |
31 | createDateNode() {
32 | const node = createNode('span', '');
33 | node.addEventListener('click', (event) => this.emit('clickDate', node));
34 | node.addEventListener('mouseover', (event) => this.emit('hoverDate', node));
35 | return node;
36 | }
37 |
38 | on(eventName, callback) {
39 | this.container.addEventListener(eventName, callback);
40 | }
41 |
42 | emit(eventName, node) {
43 | if (!node.classList.contains('disabled')) {
44 | const event = new CustomEvent(eventName, { detail: node.date });
45 | this.container.dispatchEvent(event);
46 | }
47 | }
48 |
49 | addDecorator(decorator) {
50 | this.decorators.push(decorator);
51 | }
52 |
53 | applyDecorators() {
54 | this.nodes.forEach(node => {
55 | this.decorators.forEach(decorator => {
56 | if (decorator.shouldApply(node.date)) {
57 | node.classList.add(decorator.className);
58 | } else {
59 | node.classList.remove(decorator.className);
60 | }
61 | });
62 | });
63 | }
64 |
65 | datesOfCalendar(date) {
66 | const month = datesInMonth(date);
67 | const leftPadding = startMonth(date).getDay() || 7;
68 | const paddingLeftItems = datesInMonth(prevMonth(date))
69 | .reverse()
70 | .slice(0, leftPadding)
71 | .reverse();
72 | const paddingRightItems = datesInMonth(nextMonth(date))
73 | .slice(0, 42 - leftPadding - month.length);
74 | return [...paddingLeftItems, ...month, ...paddingRightItems];
75 | }
76 |
77 | draw(date) {
78 | const dates = this.datesOfCalendar(date);
79 | // TODO: Evited assign and use immutability
80 | this.nodes.forEach((node, index) => {
81 | node.date = dates[index];
82 | node.innerText = dates[index].getDate();
83 | });
84 | this.applyDecorators();
85 | return this.container;
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/src/styles/datepicker.css:
--------------------------------------------------------------------------------
1 | .datepicker {
2 | position: absolute;
3 | width: 260px;
4 | box-shadow: 0 0 10px rgba(0, 0, 0, 0.4);
5 | padding: 15px;
6 | z-index: 9999;
7 | background-color: #fff;
8 | }
9 |
10 | .datepicker, .datepicker span {
11 | -webkit-box-sizing: content-box;
12 | -moz-box-sizing: content-box;
13 | box-sizing: content-box;
14 | }
15 |
16 | .datepicker .arrow {
17 | position: relative;
18 | background: #fff;
19 | }
20 |
21 | .datepicker .arrow:after{
22 | content: "";
23 | position: absolute;
24 | width: 0;
25 | height: 0;
26 | border: 10px solid rgba(0, 0, 0, 0.4);
27 | border-color: #ffffff #ffffff transparent transparent;
28 | transform: rotate(-45deg);
29 | top: -23px;
30 | left: 15px;
31 | box-shadow: 3px -3px 3px 0 rgba(0, 0, 0, 0.15);
32 | }
33 |
34 | .datepicker .days {
35 | display: inline;
36 | padding: 0;
37 | }
38 |
39 | .datepicker .weekdays {
40 | width: 260px;
41 | }
42 |
43 | .datepicker .weekdays span,
44 | .datepicker .calendar span {
45 | display: inline-block;
46 | background-color: #ffffff;
47 | text-align: center;
48 | text-transform: capitalize;
49 | margin: 3px;
50 | padding: 5px;
51 | border: 1px solid #ffffff;
52 | width: calc(1 / 7 * 100% - 18px);
53 | }
54 |
55 | .datepicker .header {
56 | display: flex;
57 | align-items: center;
58 | justify-content: space-between;
59 | }
60 |
61 | .datepicker .header .prev {
62 | background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAQAAABKfvVzAAAAOUlEQVR4AWMYxqABCElS/p/hN4MWacpDSFMeSlPlYaQo/0OScnyQYg0IJ4XjcsLI0KJFmpa64Zt3AdTaQlFOlKYFAAAAAElFTkSuQmCC');
63 | background-position: left center;
64 | }
65 |
66 | .datepicker .header .next {
67 | background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAQAAABKfvVzAAAAOUlEQVR4AWMYxqCRoYEU5boMfxj+k6YlgnQtkXTREkW6lmjcWv7jhQ3kayDspGGrnPLE1wCEwxYAABNmQoikBfhoAAAAAElFTkSuQmCC');
68 | background-position: right center;
69 | }
70 |
71 | .datepicker .header .prev,
72 | .datepicker .header .next {
73 | width: 30px;
74 | height: 30px;
75 | margin: 2.5px;
76 | background-repeat: no-repeat;
77 | cursor: pointer;
78 | }
79 |
80 | .datepicker .header .prev.disabled,
81 | .datepicker .header .next.disabled {
82 | visibility: hidden;
83 | }
84 |
85 | .calendar span.out-month {
86 | visibility: hidden;
87 | }
88 |
89 | .calendar span.enabled {
90 | background-color: #eee;
91 | border: 1px solid #eee;
92 | cursor: pointer;
93 | }
94 |
95 | .calendar span.range,
96 | .calendar span.enabled:hover {
97 | background-color: #ffffff;
98 | border: 1px solid #ff690f;
99 | color: #ff690f;
100 | }
101 |
102 | .calendar span.disabled,
103 | .calendar span.disabled:hover {
104 | background-color: #ffffff;
105 | color: #cccccc;
106 | border: 1px solid #ffffff;
107 | cursor: default;
108 | }
109 |
110 | .calendar span.selected,
111 | .calendar span.selected:hover {
112 | background-color: #ff690f;
113 | color: #fff;
114 | font-weight: 600;
115 | }
116 |
--------------------------------------------------------------------------------
/src/scripts/DatePicker.js:
--------------------------------------------------------------------------------
1 | import '../styles/datepicker.css';
2 | import { Calendar } from './Calendar';
3 | import { isSame, prevMonth, nextMonth } from './date';
4 | import { todayDecorator, outMonthDecorator, thisMonthDecorator, selectedDecorator} from './decorators';
5 | import { createNode } from './util';
6 |
7 | const LANGUAGE = window.navigator.language;
8 | const WEEKDAYS = 'sun_mon_tue_wed_thu_fri_sat'.split('_');
9 | const TEMPLATE =
10 | `
11 |
16 |
17 | `;
18 |
19 | const doc = window.document;
20 |
21 | export class DatePicker {
22 |
23 | constructor(options) {
24 | const initalState = {
25 | currentDate: new Date(),
26 | selector: null,
27 | updateInput: true,
28 | appendTo: 'body',
29 | language: LANGUAGE,
30 | weekdays: WEEKDAYS,
31 | template: TEMPLATE,
32 | formatInputDate: date => this.formatInputDate(date),
33 | formatTitleDate: date => this.formatTitleDate(date)
34 | };
35 | this.options = { ...initalState, ...options };
36 | this.options.currentMonth = Object.assign(this.options.currentDate);
37 |
38 | this.setupParentElement();
39 | this.updateInputDate(this.options.currentDate);
40 | this.setupCalendar();
41 | this.setupDatePicker();
42 | this.setupOutClick();
43 | this.draw();
44 | this.hide();
45 | }
46 |
47 | setupParentElement() {
48 | this.parentElement = doc.querySelector(this.options.selector);
49 | this.parentElement.addEventListener('focus', event => this.show());
50 | }
51 |
52 | setupCalendar() {
53 | let options = this.options;
54 | this.calendar = new Calendar(options.weekdays);
55 | this.calendar.addDecorator(todayDecorator())
56 | this.calendar.addDecorator(outMonthDecorator(() => options.currentMonth));
57 | this.calendar.addDecorator(thisMonthDecorator(() => options.currentMonth));
58 | this.calendar.addDecorator(selectedDecorator(() => options.currentDate));
59 | this.calendar.on('clickDate', event => this.selectDate(event.detail));
60 | }
61 |
62 | setupDatePicker() {
63 | this.datepicker = createNode('div', 'datepicker', this.options.template);
64 | this.datepicker.querySelector('.days').appendChild(this.calendar.container);
65 | this.datepicker.querySelector('.prev').addEventListener('click', event => this.setMonth(prevMonth(this.options.currentMonth)));
66 | this.datepicker.querySelector('.next').addEventListener('click', event => this.setMonth(nextMonth(this.options.currentMonth)));
67 | this.datepicker.style.display = 'none';
68 |
69 | let weekdays = this.datepicker.querySelector('.weekdays');
70 | for (let weekday of this.options.weekdays) {
71 | weekdays.appendChild(createNode('span', 'weekday', weekday));
72 | }
73 |
74 | doc.querySelector(this.options.appendTo).appendChild(this.datepicker);
75 | }
76 |
77 | setupOutClick() {
78 | doc.addEventListener('click', event => {
79 | const target = event.target;
80 | const isOutsideClick = this.isOpened &&
81 | !this.parentElement.isEqualNode(target) &&
82 | !this.datepicker.isEqualNode(target) &&
83 | !this.datepicker.contains(target);
84 | if (isOutsideClick) {
85 | this.hide();
86 | }
87 | }, true);
88 | }
89 |
90 | show() {
91 | const parentOffset = this.parentElement.getBoundingClientRect();
92 | const topOffset = parentOffset.top + 55;
93 | const leftOffset = parentOffset.left;
94 | this.isOpened = true;
95 | this.datepicker.style.cssText = `display: block; top: ${(topOffset)}px; left: ${leftOffset}px;`;
96 | this.calendar.applyDecorators();
97 | }
98 |
99 | hide(delay=0) {
100 | setTimeout(() => {
101 | this.isOpened = false;
102 | this.datepicker.style.display = 'none';
103 | }, delay);
104 | }
105 |
106 | selectDate(date) {
107 | let options = this.options;
108 | if (isSame(date, options.currentMonth, 'year month')) {
109 | options.currentDate = date;
110 | this.updateInputDate(date);
111 | this.calendar.applyDecorators();
112 | }
113 | }
114 |
115 | updateInputDate(date) {
116 | const options = this.options;
117 | if (!options.updateInput) {
118 | return;
119 | }
120 | this.parentElement.value = options.formatInputDate(date);
121 | }
122 |
123 | setMonth(date) {
124 | this.options.currentMonth = date;
125 | this.draw();
126 | }
127 |
128 | updateTitle() {
129 | const options = this.options;
130 | const title = options.formatTitleDate(options.currentMonth);
131 | this.datepicker.querySelector('.title').innerText = title;
132 | }
133 |
134 | draw() {
135 | this.updateTitle();
136 | this.calendar.draw(this.options.currentMonth);
137 | }
138 |
139 | formatInputDate(date) {
140 | return date.toLocaleDateString(this.options.language, {
141 | weekday: 'short',
142 | day: 'numeric',
143 | month: 'numeric'
144 | });
145 | }
146 |
147 | formatTitleDate(date) {
148 | return date.toLocaleDateString(this.options.language, {
149 | month: 'long',
150 | year: 'numeric'
151 | });
152 | }
153 | }
154 |
--------------------------------------------------------------------------------
/dist/datepicker.min.js:
--------------------------------------------------------------------------------
1 | var datepicker=function(e){function t(r){if(n[r])return n[r].exports;var a=n[r]={exports:{},id:r,loaded:!1};return e[r].call(a.exports,a,a.exports,t),a.loaded=!0,a.exports}var n={};return t.m=e,t.c=n,t.p="",t(0)}([function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.DatePickerRange=t.DatePicker=t.Calendar=void 0;var r=n(1),a=n(4),i=n(9);t.Calendar=r.Calendar,t.DatePicker=a.DatePicker,t.DatePickerRange=i.DatePickerRange},function(e,t,n){"use strict";function r(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);t\n ';this.datepicker=(0,s.createNode)("div","datepicker",t),this.datepicker.style.display="none",this.datepicker.appendChild(this.calendar.container),this.datepicker.querySelector(".prev").addEventListener("click",function(t){return e.onClickPrevMonth()}),this.datepicker.querySelector(".next").addEventListener("click",function(t){return e.onClickNextMonth()}),l.querySelector(this.options.appendTo).appendChild(this.datepicker),l.addEventListener("click",function(t){var n=t.target,r=e.isOpened&&!e.parentElement.isEqualNode(n)&&!e.datepicker.isEqualNode(n)&&!e.datepicker.contains(n);r&&e.hide()},!0)}},{key:"show",value:function(){var e=this.parentElement.getBoundingClientRect();this.isOpened=!0,this.datepicker.style.cssText="display: block; top: "+(e.top+55)+"px; left: "+e.left+"px;",this.calendar.applyDecorators()}},{key:"hide",value:function(){var e=this,t=arguments.length<=0||void 0===arguments[0]?0:arguments[0];setTimeout(function(){e.isOpened=!1,e.datepicker.style.display="none"},t)}},{key:"selectDate",value:function(e){var t=this.options;(0,c.isSame)(e,t.currentMonth,"year month")&&(t.currentDate=e,this.updateInputValue(),this.calendar.applyDecorators())}},{key:"updateInputValue",value:function(){var e=this.options;if(e.updateInput){var t=e.currentDate.toLocaleDateString(e.language,{weekday:"short",day:"numeric",month:"numeric"});this.parentElement.value=t}}},{key:"onClickPrevMonth",value:function(){var e=this.options;e.currentMonth=(0,c.prevMonth)(e.currentMonth),this.draw()}},{key:"onClickNextMonth",value:function(){var e=this.options;e.currentMonth=(0,c.nextMonth)(e.currentMonth),this.draw()}},{key:"updateTitle",value:function(){var e=this.options,t=e.currentMonth.toLocaleDateString(e.language,{month:"long",year:"numeric"});this.datepicker.querySelector(".title").innerText=t}},{key:"draw",value:function(){this.updateTitle(),this.calendar.draw(this.options.currentMonth)}}]),e}()},function(e,t){},,,,function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0}),t.DatePickerRange=void 0;var a=Object.assign||function(e){for(var t=1;t=e.leftDatePicker.options.currentDate&&t<=e.rightDatePicker.options.currentDate};this.rightDatePicker.calendar.addDecorator(t,"disabled"),this.leftDatePicker.calendar.addDecorator(n,"range"),this.rightDatePicker.calendar.addDecorator(n,"range")}}]),e}()}]);
2 | //# sourceMappingURL=datepicker.min.js.map
--------------------------------------------------------------------------------
/dist/datepicker.min.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["webpack:///datepicker.min.js","webpack:///webpack/bootstrap 678774a63f25d645055c","webpack:///./src/scripts/index.js","webpack:///./src/scripts/calendar.js","webpack:///./src/scripts/util.js","webpack:///./src/scripts/date.js","webpack:///./src/scripts/datepicker.js","webpack:///./src/scripts/datepickerRange.js"],"names":["datepicker","modules","__webpack_require__","moduleId","installedModules","exports","module","id","loaded","call","m","c","p","Object","defineProperty","value","DatePickerRange","DatePicker","Calendar","undefined","_calendar","_datepicker","_datepickerRange","_toConsumableArray","arr","Array","isArray","i","arr2","length","from","_classCallCheck","instance","Constructor","TypeError","_createClass","defineProperties","target","props","descriptor","enumerable","configurable","writable","key","protoProps","staticProps","prototype","_util","_date","MAXIMUM_NUMBER_OF_DAYS","weekdays","this","decorators","listeners","container","createNode","nodes","render","forEach","weekday","appendChild","fragment","document","createDocumentFragment","createDateNode","_this","node","addEventListener","event","emit","eventName","callback","classList","contains","CustomEvent","detail","date","dispatchEvent","filter","className","push","_this2","some","decorator","add","remove","month","datesInMonth","leftPadding","startMonth","getDay","paddingLeftItems","prevMonth","reverse","slice","paddingRightItems","nextMonth","concat","dates","datesOfCalendar","index","innerText","getDate","applyDecorators","name","html","createElement","innerHTML","Date","getFullYear","getMonth","endMonth","_","day","isSame","other","arguments","includes","_extends","assign","source","hasOwnProperty","WEEKDAYS","window","navigator","language","split","doc","options","currentDate","selector","updateInput","appendTo","currentMonth","setupParentElement","updateInputValue","setupCalendar","setupDatePicker","draw","hide","parentElement","querySelector","show","calendar","addDecorator","on","selectDate","_this3","template","style","display","onClickPrevMonth","onClickNextMonth","isOutsideClick","isOpened","isEqualNode","parentOffset","getBoundingClientRect","cssText","top","left","_this4","delay","setTimeout","toLocaleDateString","title","year","updateTitle","rightDateSelected","leftDatePicker","leftSelector","rightDatePicker","rightSelector","onLeftSelectDate","onRightSelectDate","e","setupDecorators","leftDate","rightDate","rangeDisableRightDecorator","rangeDecorator"],"mappings":"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","file":"datepicker.min.js","sourcesContent":["var datepicker =\n/******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId])\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\texports: {},\n/******/ \t\t\tid: moduleId,\n/******/ \t\t\tloaded: false\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.loaded = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(0);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\texports.DatePickerRange = exports.DatePicker = exports.Calendar = undefined;\n\t\n\tvar _calendar = __webpack_require__(1);\n\t\n\tvar _datepicker = __webpack_require__(4);\n\t\n\tvar _datepickerRange = __webpack_require__(9);\n\t\n\texports.Calendar = _calendar.Calendar;\n\texports.DatePicker = _datepicker.DatePicker;\n\texports.DatePickerRange = _datepickerRange.DatePickerRange;\n\n/***/ },\n/* 1 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\texports.Calendar = undefined;\n\t\n\tvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\t\n\tvar _util = __webpack_require__(2);\n\t\n\tvar _date = __webpack_require__(3);\n\t\n\tfunction _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\t\n\tvar MAXIMUM_NUMBER_OF_DAYS = 42;\n\t\n\tvar Calendar = exports.Calendar = function () {\n\t function Calendar(weekdays) {\n\t _classCallCheck(this, Calendar);\n\t\n\t this.decorators = [];\n\t this.listeners = [];\n\t this.container = (0, _util.createNode)('div', 'calendar', null);\n\t this.nodes = new Array(MAXIMUM_NUMBER_OF_DAYS);\n\t this.weekdays = weekdays;\n\t\n\t this.render();\n\t }\n\t\n\t _createClass(Calendar, [{\n\t key: 'render',\n\t value: function render() {\n\t var container = this.container;\n\t var nodes = this.nodes;\n\t this.weekdays.forEach(function (weekday) {\n\t return container.appendChild((0, _util.createNode)('span', 'weekday', weekday));\n\t });\n\t\n\t var fragment = document.createDocumentFragment();\n\t // TODO: Evited assign and use immutability\n\t for (var i = 0; i < MAXIMUM_NUMBER_OF_DAYS; i++) {\n\t nodes[i] = this.createDateNode();\n\t fragment.appendChild(nodes[i]);\n\t }\n\t container.appendChild(fragment);\n\t }\n\t }, {\n\t key: 'createDateNode',\n\t value: function createDateNode() {\n\t var _this = this;\n\t\n\t var node = (0, _util.createNode)('span', '');\n\t node.addEventListener('click', function (event) {\n\t return _this.emit('clickDate', node);\n\t });\n\t node.addEventListener('mouseover', function (event) {\n\t return _this.emit('hoverDate', node);\n\t });\n\t return node;\n\t }\n\t }, {\n\t key: 'on',\n\t value: function on(eventName, callback) {\n\t this.container.addEventListener(eventName, callback);\n\t }\n\t }, {\n\t key: 'emit',\n\t value: function emit(eventName, node) {\n\t if (!node.classList.contains('disabled')) {\n\t var event = new CustomEvent(eventName, { detail: node.date });\n\t this.container.dispatchEvent(event);\n\t }\n\t }\n\t }, {\n\t key: 'addDecorator',\n\t value: function addDecorator(filter, className) {\n\t this.decorators.push({ filter: filter, className: className });\n\t }\n\t }, {\n\t key: 'applyDecorators',\n\t value: function applyDecorators() {\n\t var _this2 = this;\n\t\n\t this.nodes.forEach(function (node) {\n\t _this2.decorators.some(function (decorator) {\n\t if (decorator.filter(node.date)) {\n\t node.classList.add(decorator.className);\n\t } else {\n\t node.classList.remove(decorator.className);\n\t }\n\t });\n\t });\n\t }\n\t }, {\n\t key: 'datesOfCalendar',\n\t value: function datesOfCalendar(date) {\n\t var month = (0, _date.datesInMonth)(date);\n\t var leftPadding = (0, _date.startMonth)(date).getDay() || 7;\n\t var paddingLeftItems = (0, _date.datesInMonth)((0, _date.prevMonth)(date)).reverse().slice(0, leftPadding).reverse();\n\t var paddingRightItems = (0, _date.datesInMonth)((0, _date.nextMonth)(date)).slice(0, 42 - leftPadding - month.length);\n\t return [].concat(_toConsumableArray(paddingLeftItems), _toConsumableArray(month), _toConsumableArray(paddingRightItems));\n\t }\n\t }, {\n\t key: 'draw',\n\t value: function draw(date) {\n\t var dates = this.datesOfCalendar(date);\n\t // TODO: Evited assign and use immutability\n\t this.nodes.forEach(function (node, index) {\n\t node.date = dates[index];\n\t node.innerText = dates[index].getDate();\n\t });\n\t this.applyDecorators();\n\t return this.container;\n\t }\n\t }]);\n\n\t return Calendar;\n\t}();\n\n/***/ },\n/* 2 */\n/***/ function(module, exports) {\n\n\t\"use strict\";\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\texports.createNode = createNode;\n\tfunction createNode(name, className, html) {\n\t var node = document.createElement(name);\n\t node.className = className;\n\t node.innerHTML = html;\n\t return node;\n\t}\n\n/***/ },\n/* 3 */\n/***/ function(module, exports) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\texports.nextMonth = nextMonth;\n\texports.prevMonth = prevMonth;\n\texports.startMonth = startMonth;\n\texports.endMonth = endMonth;\n\texports.datesInMonth = datesInMonth;\n\texports.isSame = isSame;\n\tfunction nextMonth(date) {\n\t return new Date(date.getFullYear(), date.getMonth() + 1);\n\t}\n\t\n\tfunction prevMonth(date) {\n\t return new Date(date.getFullYear(), date.getMonth() - 1);\n\t}\n\t\n\tfunction startMonth(date) {\n\t return new Date(date.getFullYear(), date.getMonth(), 1);\n\t}\n\t\n\tfunction endMonth(date) {\n\t return new Date(date.getFullYear(), date.getMonth() + 1, 0);\n\t}\n\t\n\tfunction datesInMonth(date) {\n\t var length = { length: endMonth(date).getDate() };\n\t return Array.from(length, function (_, day) {\n\t return new Date(date.getFullYear(), date.getMonth(), day + 1);\n\t });\n\t}\n\t\n\tfunction isSame(date, other) {\n\t var filter = arguments.length <= 2 || arguments[2] === undefined ? 'year month day' : arguments[2];\n\t\n\t if (!date || !other) return false;\n\t return (!filter.includes('year') || date.getFullYear() === other.getFullYear()) && (!filter.includes('month') || date.getMonth() === other.getMonth()) && (!filter.includes('day') || date.getDate() === other.getDate());\n\t}\n\n/***/ },\n/* 4 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\texports.DatePicker = undefined;\n\t\n\tvar _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };\n\t\n\tvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\t\n\t__webpack_require__(5);\n\t\n\tvar _calendar = __webpack_require__(1);\n\t\n\tvar _date = __webpack_require__(3);\n\t\n\tvar _util = __webpack_require__(2);\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\t\n\tvar LANGUAGE = window.navigator.language;\n\tvar WEEKDAYS = 'sun_mon_tue_wed_thu_fri_sat'.split('_');\n\t\n\tvar doc = window.document;\n\t\n\tvar DatePicker = exports.DatePicker = function () {\n\t function DatePicker(options) {\n\t _classCallCheck(this, DatePicker);\n\t\n\t this.options = {\n\t currentDate: new Date(),\n\t language: 'en-Us',\n\t selector: null,\n\t updateInput: true,\n\t weekdays: WEEKDAYS,\n\t appendTo: 'body'\n\t };\n\t this.options = _extends({}, this.options, options);\n\t this.options.currentMonth = Object.assign(this.options.currentDate);\n\t\n\t this.setupParentElement();\n\t this.updateInputValue();\n\t this.setupCalendar();\n\t this.setupDatePicker();\n\t this.draw();\n\t this.hide();\n\t }\n\t\n\t _createClass(DatePicker, [{\n\t key: 'setupParentElement',\n\t value: function setupParentElement() {\n\t var _this = this;\n\t\n\t this.parentElement = doc.querySelector(this.options.selector);\n\t this.parentElement.addEventListener('focus', function (event) {\n\t return _this.show();\n\t });\n\t }\n\t }, {\n\t key: 'setupCalendar',\n\t value: function setupCalendar() {\n\t var _this2 = this;\n\t\n\t var options = this.options;\n\t this.calendar = new _calendar.Calendar(options.weekdays);\n\t this.calendar.addDecorator(function (date) {\n\t return !(0, _date.isSame)(date, options.currentMonth, 'year month');\n\t }, 'out-month');\n\t this.calendar.addDecorator(function (date) {\n\t return (0, _date.isSame)(date, options.currentMonth, 'year month');\n\t }, 'enabled');\n\t this.calendar.addDecorator(function (date) {\n\t return (0, _date.isSame)(date, options.currentDate);\n\t }, 'selected');\n\t this.calendar.on('clickDate', function (event) {\n\t return _this2.selectDate(event.detail);\n\t });\n\t }\n\t }, {\n\t key: 'setupDatePicker',\n\t value: function setupDatePicker() {\n\t var _this3 = this;\n\t\n\t var template = '\\n ';\n\t this.datepicker = (0, _util.createNode)('div', 'datepicker', template);\n\t this.datepicker.style.display = 'none';\n\t this.datepicker.appendChild(this.calendar.container);\n\t this.datepicker.querySelector('.prev').addEventListener('click', function (event) {\n\t return _this3.onClickPrevMonth();\n\t });\n\t this.datepicker.querySelector('.next').addEventListener('click', function (event) {\n\t return _this3.onClickNextMonth();\n\t });\n\t\n\t doc.querySelector(this.options.appendTo).appendChild(this.datepicker);\n\t doc.addEventListener('click', function (event) {\n\t var target = event.target;\n\t var isOutsideClick = _this3.isOpened && !_this3.parentElement.isEqualNode(target) && !_this3.datepicker.isEqualNode(target) && !_this3.datepicker.contains(target);\n\t if (isOutsideClick) {\n\t _this3.hide();\n\t }\n\t }, true);\n\t }\n\t }, {\n\t key: 'show',\n\t value: function show() {\n\t var parentOffset = this.parentElement.getBoundingClientRect();\n\t this.isOpened = true;\n\t this.datepicker.style.cssText = 'display: block; top: ' + (parentOffset.top + 55) + 'px; left: ' + parentOffset.left + 'px;';\n\t this.calendar.applyDecorators();\n\t }\n\t }, {\n\t key: 'hide',\n\t value: function hide() {\n\t var _this4 = this;\n\t\n\t var delay = arguments.length <= 0 || arguments[0] === undefined ? 0 : arguments[0];\n\t\n\t setTimeout(function () {\n\t _this4.isOpened = false;\n\t _this4.datepicker.style.display = 'none';\n\t }, delay);\n\t }\n\t }, {\n\t key: 'selectDate',\n\t value: function selectDate(date) {\n\t var options = this.options;\n\t if ((0, _date.isSame)(date, options.currentMonth, 'year month')) {\n\t options.currentDate = date;\n\t this.updateInputValue();\n\t this.calendar.applyDecorators();\n\t }\n\t }\n\t }, {\n\t key: 'updateInputValue',\n\t value: function updateInputValue() {\n\t var options = this.options;\n\t if (!options.updateInput) {\n\t return;\n\t }\n\t var date = options.currentDate.toLocaleDateString(options.language, {\n\t weekday: 'short',\n\t day: 'numeric',\n\t month: 'numeric'\n\t });\n\t this.parentElement.value = date;\n\t }\n\t }, {\n\t key: 'onClickPrevMonth',\n\t value: function onClickPrevMonth() {\n\t var options = this.options;\n\t options.currentMonth = (0, _date.prevMonth)(options.currentMonth);\n\t this.draw();\n\t }\n\t }, {\n\t key: 'onClickNextMonth',\n\t value: function onClickNextMonth() {\n\t var options = this.options;\n\t options.currentMonth = (0, _date.nextMonth)(options.currentMonth);\n\t this.draw();\n\t }\n\t }, {\n\t key: 'updateTitle',\n\t value: function updateTitle() {\n\t var options = this.options;\n\t var title = options.currentMonth.toLocaleDateString(options.language, {\n\t month: 'long',\n\t year: 'numeric'\n\t });\n\t this.datepicker.querySelector('.title').innerText = title;\n\t }\n\t }, {\n\t key: 'draw',\n\t value: function draw() {\n\t this.updateTitle();\n\t this.calendar.draw(this.options.currentMonth);\n\t }\n\t }]);\n\t\n\t return DatePicker;\n\t}();\n\t\n\t;\n\n/***/ },\n/* 5 */\n/***/ function(module, exports) {\n\n\t// removed by extract-text-webpack-plugin\n\n/***/ },\n/* 6 */,\n/* 7 */,\n/* 8 */,\n/* 9 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\texports.DatePickerRange = undefined;\n\t\n\tvar _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };\n\t\n\tvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\t\n\tvar _datepicker = __webpack_require__(4);\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\t\n\tvar DatePickerRange = exports.DatePickerRange = function () {\n\t function DatePickerRange(options) {\n\t var _this = this;\n\t\n\t _classCallCheck(this, DatePickerRange);\n\t\n\t this.rightDateSelected = false;\n\t\n\t this.leftDatePicker = new _datepicker.DatePicker(_extends({}, this.options, { selector: options.leftSelector }));\n\t this.rightDatePicker = new _datepicker.DatePicker(_extends({}, this.options, { selector: options.rightSelector }));\n\t this.leftDatePicker.calendar.on('clickDate', function (event) {\n\t return _this.onLeftSelectDate(event.detail);\n\t });\n\t this.rightDatePicker.calendar.on('clickDate', function (event) {\n\t return _this.onRightSelectDate(event.detail);\n\t });\n\t\n\t this.rightDatePicker.parentElement.addEventListener('focus', function (e) {\n\t return _this.leftDatePicker.hide();\n\t });\n\t this.leftDatePicker.parentElement.addEventListener('focus', function (e) {\n\t return _this.rightDatePicker.hide();\n\t });\n\t\n\t this.setupDecorators();\n\t }\n\t\n\t _createClass(DatePickerRange, [{\n\t key: 'onLeftSelectDate',\n\t value: function onLeftSelectDate(date) {\n\t var leftDate = this.leftDatePicker.options.currentDate;\n\t var rightDate = this.rightDatePicker.options.currentDate;\n\t if (rightDate < leftDate) {\n\t this.rightDatePicker.options.currentMonth = leftDate;\n\t this.rightDatePicker.options.currentDate = leftDate;\n\t this.rightDatePicker.updateInputValue();\n\t this.rightDatePicker.draw();\n\t }\n\t this.leftDatePicker.hide();\n\t this.rightDatePicker.show();\n\t }\n\t }, {\n\t key: 'onRightSelectDate',\n\t value: function onRightSelectDate(date) {\n\t this.rightDatePicker.hide(300);\n\t this.rightDateSelected = true;\n\t }\n\t }, {\n\t key: 'setupDecorators',\n\t value: function setupDecorators() {\n\t var _this2 = this;\n\t\n\t var rangeDisableRightDecorator = function rangeDisableRightDecorator(date) {\n\t return date < _this2.leftDatePicker.options.currentDate;\n\t };\n\t var rangeDecorator = function rangeDecorator(date) {\n\t return date >= _this2.leftDatePicker.options.currentDate && date <= _this2.rightDatePicker.options.currentDate;\n\t };\n\t this.rightDatePicker.calendar.addDecorator(rangeDisableRightDecorator, 'disabled');\n\t this.leftDatePicker.calendar.addDecorator(rangeDecorator, 'range');\n\t this.rightDatePicker.calendar.addDecorator(rangeDecorator, 'range');\n\t }\n\t }]);\n\t\n\t return DatePickerRange;\n\t}();\n\t\n\t;\n\n/***/ }\n/******/ ]);\n\n\n/** WEBPACK FOOTER **\n ** datepicker.min.js\n **/"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n/** WEBPACK FOOTER **\n ** webpack/bootstrap 678774a63f25d645055c\n **/","import { Calendar } from './calendar';\nimport { DatePicker } from './datepicker';\nimport { DatePickerRange } from './datepickerRange';\n\nexport {\n Calendar,\n DatePicker,\n DatePickerRange\n};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/scripts/index.js\n **/","import { createNode } from './util';\nimport {\n nextMonth,\n prevMonth,\n startMonth,\n datesInMonth,\n isSame\n} from './date';\n\nconst MAXIMUM_NUMBER_OF_DAYS = 42;\n\nexport class Calendar {\n constructor(weekdays) {\n this.decorators = [];\n this.listeners = [];\n this.container = createNode('div', 'calendar', null);\n this.nodes = new Array(MAXIMUM_NUMBER_OF_DAYS);\n this.weekdays = weekdays;\n\n this.render();\n }\n\n render() {\n let container = this.container;\n let nodes = this.nodes;\n this.weekdays.forEach(weekday => container.appendChild(createNode('span', 'weekday', weekday)));\n\n let fragment = document.createDocumentFragment();\n // TODO: Evited assign and use immutability\n for (let i = 0; i < MAXIMUM_NUMBER_OF_DAYS; i++) {\n nodes[i] = this.createDateNode();\n fragment.appendChild(nodes[i]);\n }\n container.appendChild(fragment);\n }\n\n createDateNode() {\n let node = createNode('span', '');\n node.addEventListener('click', (event) => this.emit('clickDate', node));\n node.addEventListener('mouseover', (event) => this.emit('hoverDate', node));\n return node;\n }\n\n on(eventName, callback) {\n this.container.addEventListener(eventName, callback);\n }\n\n emit(eventName, node) {\n if (!node.classList.contains('disabled')) {\n const event = new CustomEvent(eventName, { detail: node.date });\n this.container.dispatchEvent(event);\n }\n }\n\n addDecorator(filter, className) {\n this.decorators.push({filter: filter, className: className});\n }\n\n applyDecorators() {\n this.nodes.forEach(node => {\n this.decorators.some(decorator => {\n if (decorator.filter(node.date)) {\n node.classList.add(decorator.className);\n } else {\n node.classList.remove(decorator.className);\n }\n });\n });\n }\n\n datesOfCalendar(date) {\n let month = datesInMonth(date);\n let leftPadding = startMonth(date).getDay() || 7;\n let paddingLeftItems = datesInMonth(prevMonth(date))\n .reverse()\n .slice(0, leftPadding)\n .reverse();\n let paddingRightItems = datesInMonth(nextMonth(date))\n .slice(0, 42 - leftPadding - month.length);\n return [...paddingLeftItems, ...month, ...paddingRightItems];\n }\n\n draw(date) {\n let dates = this.datesOfCalendar(date);\n // TODO: Evited assign and use immutability\n this.nodes.forEach((node, index) => {\n node.date = dates[index];\n node.innerText = dates[index].getDate();\n });\n this.applyDecorators();\n return this.container;\n }\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/scripts/calendar.js\n **/","export function createNode(name, className, html) {\n let node = document.createElement(name);\n node.className = className;\n node.innerHTML = html;\n return node;\n}\n\n\n/** WEBPACK FOOTER **\n ** ./src/scripts/util.js\n **/","export function nextMonth(date) {\n return new Date(date.getFullYear(), date.getMonth() + 1);\n}\n\nexport function prevMonth(date) {\n return new Date(date.getFullYear(), date.getMonth() - 1);\n}\n\nexport function startMonth(date) {\n return new Date(date.getFullYear(), date.getMonth(), 1);\n}\n\nexport function endMonth(date) {\n return new Date(date.getFullYear(), date.getMonth() + 1, 0);\n}\n\nexport function datesInMonth(date) {\n let length = {length: endMonth(date).getDate()};\n return Array.from(length, (_, day) => new Date(date.getFullYear(), date.getMonth(), day + 1));\n}\n\nexport function isSame(date, other, filter='year month day') {\n if (!date || !other) return false;\n return (!filter.includes('year') || date.getFullYear() === other.getFullYear()) &&\n (!filter.includes('month') || date.getMonth() === other.getMonth()) &&\n (!filter.includes('day') || date.getDate() === other.getDate())\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/scripts/date.js\n **/","import '../styles/datepicker.css';\nimport { Calendar } from './calendar';\nimport { isSame, prevMonth, nextMonth } from './date';\nimport { createNode } from './util';\n\nconst LANGUAGE = window.navigator.language;\nconst WEEKDAYS = 'sun_mon_tue_wed_thu_fri_sat'.split('_');\n\nconst doc = window.document;\n\nexport class DatePicker {\n\n constructor(options) {\n this.options = {\n currentDate: new Date(),\n language: 'en-Us',\n selector: null,\n updateInput: true,\n weekdays: WEEKDAYS,\n appendTo: 'body'\n };\n this.options = { ...this.options, ...options };\n this.options.currentMonth = Object.assign(this.options.currentDate);\n\n this.setupParentElement();\n this.updateInputValue();\n this.setupCalendar();\n this.setupDatePicker();\n this.draw();\n this.hide();\n }\n\n setupParentElement() {\n this.parentElement = doc.querySelector(this.options.selector);\n this.parentElement.addEventListener('focus', event => this.show());\n }\n\n setupCalendar() {\n let options = this.options;\n this.calendar = new Calendar(options.weekdays);\n this.calendar.addDecorator(date => !isSame(date, options.currentMonth, 'year month'), 'out-month');\n this.calendar.addDecorator(date => isSame(date, options.currentMonth, 'year month'), 'enabled');\n this.calendar.addDecorator(date => isSame(date, options.currentDate), 'selected');\n this.calendar.on('clickDate', event => this.selectDate(event.detail));\n }\n\n setupDatePicker() {\n let template = `\n `\n this.datepicker = createNode('div', 'datepicker', template);\n this.datepicker.style.display = 'none';\n this.datepicker.appendChild(this.calendar.container);\n this.datepicker.querySelector('.prev').addEventListener('click', event => this.onClickPrevMonth());\n this.datepicker.querySelector('.next').addEventListener('click', event => this.onClickNextMonth());\n\n doc.querySelector(this.options.appendTo).appendChild(this.datepicker);\n doc.addEventListener('click', event => {\n let target = event.target;\n let isOutsideClick = this.isOpened &&\n !this.parentElement.isEqualNode(target) &&\n !this.datepicker.isEqualNode(target) &&\n !this.datepicker.contains(target);\n if (isOutsideClick) {\n this.hide();\n }\n }, true);\n }\n\n show() {\n let parentOffset = this.parentElement.getBoundingClientRect();\n this.isOpened = true;\n this.datepicker.style.cssText = `display: block; top: ${(parentOffset.top + 55)}px; left: ${parentOffset.left}px;`;\n this.calendar.applyDecorators();\n }\n\n hide(delay=0) {\n setTimeout(() => {\n this.isOpened = false;\n this.datepicker.style.display = 'none';\n }, delay);\n }\n\n selectDate(date) {\n let options = this.options;\n if (isSame(date, options.currentMonth, 'year month')) {\n options.currentDate = date;\n this.updateInputValue();\n this.calendar.applyDecorators();\n }\n }\n\n updateInputValue() {\n let options = this.options;\n if (!options.updateInput) {\n return;\n }\n let date = options\n .currentDate\n .toLocaleDateString(options.language, {\n weekday: 'short',\n day: 'numeric',\n month: 'numeric'\n });\n this.parentElement.value = date;\n }\n\n onClickPrevMonth() {\n let options = this.options;\n options.currentMonth = prevMonth(options.currentMonth);\n this.draw();\n }\n\n onClickNextMonth() {\n let options = this.options;\n options.currentMonth = nextMonth(options.currentMonth);\n this.draw();\n }\n\n updateTitle() {\n let options = this.options;\n let title = options\n .currentMonth\n .toLocaleDateString(options.language, {\n month : 'long',\n year : 'numeric'\n });\n this.datepicker.querySelector('.title').innerText = title;\n }\n\n draw() {\n this.updateTitle();\n this.calendar.draw(this.options.currentMonth);\n }\n};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/scripts/datepicker.js\n **/","import { DatePicker } from './datepicker';\n\nexport class DatePickerRange {\n\n constructor(options) {\n this.rightDateSelected = false;\n\n this.leftDatePicker = new DatePicker({ ...this.options, ...{ selector: options.leftSelector } });\n this.rightDatePicker = new DatePicker({ ...this.options, ...{ selector: options.rightSelector } });\n this.leftDatePicker.calendar.on('clickDate', (event) => this.onLeftSelectDate(event.detail));\n this.rightDatePicker.calendar.on('clickDate', (event) => this.onRightSelectDate(event.detail));\n\n this.rightDatePicker.parentElement.addEventListener('focus', e => this.leftDatePicker.hide());\n this.leftDatePicker.parentElement.addEventListener('focus', e => this.rightDatePicker.hide());\n\n this.setupDecorators();\n }\n\n onLeftSelectDate(date) {\n let leftDate = this.leftDatePicker.options.currentDate;\n let rightDate = this.rightDatePicker.options.currentDate;\n if (rightDate < leftDate) {\n this.rightDatePicker.options.currentMonth = leftDate;\n this.rightDatePicker.options.currentDate = leftDate;\n this.rightDatePicker.updateInputValue();\n this.rightDatePicker.draw();\n }\n this.leftDatePicker.hide();\n this.rightDatePicker.show();\n }\n\n onRightSelectDate(date) {\n this.rightDatePicker.hide(300);\n this.rightDateSelected = true;\n }\n\n setupDecorators() {\n let rangeDisableRightDecorator = (date) => date < this.leftDatePicker.options.currentDate;\n let rangeDecorator = (date) => date >= this.leftDatePicker.options.currentDate &&\n date <= this.rightDatePicker.options.currentDate;\n this.rightDatePicker.calendar.addDecorator(rangeDisableRightDecorator, 'disabled');\n this.leftDatePicker.calendar.addDecorator(rangeDecorator, 'range');\n this.rightDatePicker.calendar.addDecorator(rangeDecorator, 'range');\n }\n};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/scripts/datepickerRange.js\n **/"],"sourceRoot":""}
--------------------------------------------------------------------------------