Commit c6cf210d80e45f7e1bd7190ba0739df7b151a554

Authored by root
1 parent e9ec5fd2

new paper-date

bower_components/paper-date-picker/.gitignore 0 → 100644
  1 +.idea
  2 +.bowerrc
  3 +components
  4 +bower_components
  5 +node_modules
  6 +gulpfile.js
bower_components/paper-date-picker/.jshintrc 0 → 100644
  1 +{
  2 + "node": true,
  3 + "browser": true,
  4 + "esnext": true,
  5 + "bitwise": true,
  6 + "camelcase": true,
  7 + "curly": true,
  8 + "eqeqeq": true,
  9 + "immed": true,
  10 + "indent": 2,
  11 + "latedef": true,
  12 + "noarg": true,
  13 + "quotmark": "single",
  14 + "undef": true,
  15 + "unused": true,
  16 + "globals": {
  17 + "wrap": true,
  18 + "unwrap": true,
  19 + "HTMLImports": true,
  20 + "Polymer": true,
  21 + "Platform": true,
  22 + "moment": true
  23 + }
  24 +}
  25 +
bower_components/paper-date-picker/LICENSE 0 → 100644
  1 +The MIT License (MIT)
  2 +
  3 +Copyright (c) 2015 Ben Davis <bendavis78@gmail.com>
  4 +
  5 +Permission is hereby granted, free of charge, to any person obtaining a copy of
  6 +this software and associated documentation files (the "Software"), to deal in
  7 +the Software without restriction, including without limitation the rights to
  8 +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  9 +the Software, and to permit persons to whom the Software is furnished to do so,
  10 +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, FITNESS
  17 +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  18 +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  19 +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  20 +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
bower_components/paper-date-picker/README.md 0 → 100644
  1 +paper-date-picker
  2 +=================
  3 +
  4 +**NOTE:** in bower, this package is `polymer-paper-date-picker`
  5 +
  6 +Material Design date picker, compatible with *Polymer 1.0*
  7 +
  8 +Provides a responsive date picker based on the material design spec. This
  9 +component aims to be a clone of the date picker introduced in Android Lollipop.
  10 +
  11 +![wide picker screenshot][wide] ![narrow picker screenshot][narrow]
  12 +
  13 +See the [component page](http://bendavis78.github.io/paper-date-picker/) for
  14 +full documentation.
  15 +
  16 +## Examples:
  17 +
  18 +Default picker:
  19 +
  20 +```html
  21 +<paper-date-picker></paper-date-picker>
  22 +```
  23 +
  24 +Setting the initial date to April 20, 2015:
  25 +```html
  26 +<paper-date-picker date="April 20, 2015"></paper-date-picker>
  27 +```
  28 +
  29 +You may also specify a minimum and/or maximum date allowed in this picker using
  30 +the same date notation:
  31 +```html
  32 +<paper-date-picker min-date="April 1, 2015" max-date="June 30, 2015"></paper-date-picker>
  33 +```
  34 +
  35 +If you include this element as part of `paper-dialog`, use the class
  36 +`"paper-date-picker-dialog"` on the dialog element in order to give it proper
  37 +styling:
  38 +```html
  39 +<paper-dialog id="dialog" class="paper-date-picker-dialog" modal
  40 + on-iron-overlay-closed="dismissDialog">
  41 + <paper-date-picker id="picker" date="[[date]]"></paper-date-picker>
  42 + <div class="buttons">
  43 + <paper-button dialog-dismiss>Cancel</paper-button>
  44 + <paper-button dialog-confirm>OK</paper-button>
  45 + </div>
  46 +</paper-dialog>
  47 +```
  48 +
  49 +# Reporting Bugs
  50 +
  51 +When filing a bug report, please provide an example of how to repoduce using
  52 +plunker, jsbin, jsfiddle, etc. You can use the following plunker as a starting
  53 +point: http://plnkr.co/edit/9c787GHiBzX7zI5x6gsX
  54 +
  55 +# Contributing
  56 +
  57 +Pull requests are welcome and greatly appreciated. However, in order to speed
  58 +up the review process, pull requests will not be merged if they include
  59 +multiple unrelated changes (eg: "Fix for XYZ and other tweaks"). Also, don't
  60 +include "opinionated" changes that aren't necessary for the feature or bugfix.
  61 +
  62 +When submitting a PR for a bugfix, please reference the issue number in the
  63 +commit message. For example: "Fixes issue #123".
  64 +
  65 +
  66 +---
  67 +
  68 +If you find this component useful, please show your support by donating to
  69 +[Bold Idea](http://boldidea.org). Click the button below!
  70 +
  71 +[![ideaSpark campaign button][donate]](https://donorbox.org/bold-idea-make-ideaspark-possible-for-dallas-area-students)
  72 +
  73 +[wide]: http://i.imgur.com/I0SjSWf.png
  74 +[narrow]: http://i.imgur.com/SsrLJDo.png
  75 +[donate]: http://www.boldidea.org/donate-badge-md-1.png
bower_components/paper-date-picker/bower.json 0 → 100644
  1 +{
  2 + "name": "paper-date-picker",
  3 + "version": "1.2.0",
  4 + "authors": [
  5 + "Ben Davis <bendavis78@gmail.com>"
  6 + ],
  7 + "description": "Provides a responsive date picker based on the material design spec",
  8 + "keywords": [
  9 + "web-component",
  10 + "web-components",
  11 + "polymer",
  12 + "datepicker",
  13 + "paper-date-picker"
  14 + ],
  15 + "main": "paper-date-picker.html",
  16 + "license": "MIT",
  17 + "homepage": "http://bendavis78.github.io/paper-date-picker/",
  18 + "ignore": [
  19 + "/.*",
  20 + "/test/"
  21 + ],
  22 + "dependencies": {
  23 + "moment-element": "bendavis78/moment-element#^1.1.1",
  24 + "polymer": "Polymer/polymer#^1.1.0",
  25 + "iron-icon": "PolymerElements/iron-icon#^1.0.7",
  26 + "iron-iconset-svg": "PolymerElements/iron-iconset-svg#^1.0.9",
  27 + "iron-flex-layout": "PolymerElements/iron-flex-layout#^1.0.0",
  28 + "iron-media-query": "PolymerElements/iron-media-query#^1.0.0",
  29 + "iron-resizable": "PolymerElements/iron-resizable-behavior#^1.0.0",
  30 + "iron-selector": "PolymerElements/iron-selector#^1.0.0",
  31 + "neon-animation": "PolymerElements/neon-animation#^1.0.0",
  32 + "paper-ripple": "PolymerElements/paper-ripple#^1.0.5",
  33 + "paper-styles": "PolymerElements/paper-styles#^1.0.0",
  34 + "paper-icon-button": "PolymerElements/paper-icon-button#^1.0.0",
  35 + "iron-list": "PolymerElements/iron-list#^1.2.8"
  36 + },
  37 + "devDependencies": {
  38 + "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
  39 + "paper-dialog": "PolymerElements/paper-dialog#^1.0.0",
  40 + "paper-button": "PolymerElements/paper-button#^1.0.0",
  41 + "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0",
  42 + "web-component-tester": "Polymer/web-component-tester#^4.2.2"
  43 + },
  44 + "resolutions": {
  45 + "polymer": "^1.0.0",
  46 + "webcomponentsjs": "^0.7.2"
  47 + }
  48 +}
bower_components/paper-date-picker/demo/index.html 0 → 100644
  1 +<!doctype html>
  2 +<html>
  3 +<head>
  4 + <meta charset="utf-8">
  5 + <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  6 + <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
  7 +
  8 + <title>paper-date-picker Demo</title>
  9 +
  10 + <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
  11 +
  12 + <link rel="import" href="../paper-date-picker.html">
  13 + <link rel="import" href="../../paper-styles/demo-pages.html">
  14 + <link rel="import" href="../../paper-dialog/paper-dialog.html">
  15 + <link rel="import" href="../../paper-button/paper-button.html">
  16 +
  17 + <style is="custom-style" include="paper-date-picker-dialog-style">
  18 + section {
  19 + margin: 24px;
  20 + }
  21 + </style>
  22 +</head>
  23 +<body unresolved>
  24 + <template is="dom-bind" id="scope">
  25 + <section>
  26 + <h1>{{dateFormat(date, 'LL')}}</h1>
  27 + <paper-button class="btn" on-tap="showDialog" raised>Change Date</paper-button>
  28 + <paper-dialog id="dialog" class="paper-date-picker-dialog" modal on-iron-overlay-closed="dismissDialog">
  29 + <paper-date-picker id="picker" date="[[date]]"></paper-date-picker>
  30 + <div class="buttons">
  31 + <paper-button dialog-dismiss>Cancel</paper-button>
  32 + <paper-button dialog-confirm>OK</paper-button>
  33 + </div>
  34 + </paper-dialog>
  35 + </section>
  36 + </template>
  37 + <script>
  38 + HTMLImports.whenReady(function() {
  39 + var scope = Polymer.dom(document).querySelector('#scope');
  40 + scope.dateFormat = function(date, format) {
  41 + return moment(date).format(format);
  42 + };
  43 + scope.dismissDialog = function(event) {
  44 + if (event.detail.confirmed) {
  45 + scope.date = scope.$.picker.date;
  46 + }
  47 + };
  48 + scope.showDialog = function() {
  49 + this.$.dialog.toggle();
  50 + };
  51 + document.addEventListener('WebComponentsReady', function() {
  52 + scope.date = new Date(2017, 3, 13);
  53 + scope.showDialog();
  54 + });
  55 + });
  56 + </script>
  57 +</body>
  58 +</html>
bower_components/paper-date-picker/demo/paper-calendar.html 0 → 100644
  1 +<!doctype html>
  2 +<html>
  3 +<head>
  4 + <meta charset="utf-8">
  5 + <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  6 + <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
  7 +
  8 + <title>paper-date-picker Demo</title>
  9 +
  10 + <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
  11 +
  12 + <link rel="import" href="../paper-date-picker.html">
  13 + <link rel="import" href="../../paper-styles/demo-pages.html">
  14 + <link rel="import" href="../../paper-dialog/paper-dialog.html">
  15 + <link rel="import" href="../../paper-button/paper-button.html">
  16 +
  17 + <style is="custom-style">
  18 + section {
  19 + margin: 24px;
  20 + }
  21 + h3 {
  22 + text-align: center;
  23 + }
  24 + #container {
  25 + margin: 0 auto;
  26 + height: 300px;
  27 + width: 300px;
  28 + overflow: hidden;
  29 + border: 4px solid #eee;
  30 + padding: 5px;
  31 + resize: both;
  32 + }
  33 + </style>
  34 +</head>
  35 +<body unresolved>
  36 + <template is="dom-bind" id="scope">
  37 + <h3>{{dateFormat(date, 'LLL')}}</h3>
  38 + <section>
  39 + <div id="container" on-track="track">
  40 + <paper-calendar id="picker" date="{{date}}"></paper-calendar>
  41 + </div>
  42 + </section>
  43 + </template>
  44 + <script>
  45 + HTMLImports.whenReady(function() {
  46 + var scope = Polymer.dom(document).querySelector('#scope');
  47 + scope.dateFormat = function(date, format) {
  48 + if (!date) {
  49 + return 'No date selected';
  50 + }
  51 + return moment(date).format(format);
  52 + };
  53 + scope.date = new Date(2017, 3, 13);
  54 + scope.track = function() {
  55 + this.$.picker.fire('iron-resize');
  56 + };
  57 + });
  58 + </script>
  59 +</body>
  60 +</html>
bower_components/paper-date-picker/demo/paper-year-list.html 0 → 100644
  1 +<!doctype html>
  2 +<html>
  3 + <head>
  4 + <meta charset="utf-8">
  5 + <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  6 + <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
  7 +
  8 + <title>paper-year-list Demo</title>
  9 +
  10 + <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
  11 +
  12 + <link rel="import" href="../paper-year-list.html">
  13 + <link rel="import" href="../../paper-styles/demo-pages.html">
  14 +
  15 + </head>
  16 +
  17 + <body unresolved>
  18 + <style>
  19 + paper-year-list {
  20 + height: 400px;
  21 + width: 200px;
  22 + }
  23 + </style>
  24 + <template is="dom-bind" id="scope">
  25 + <paper-year-list id="yearList"></paper-year-list>
  26 + <button on-tap="centerSelected">Center selected year</button>
  27 + </template>
  28 +
  29 + <script>
  30 + var scope = document.getElementById('scope');
  31 + scope.centerSelected = function() {
  32 + this.$.yearList.centerSelected();
  33 + };
  34 + </script>
  35 + </body>
  36 +</html>
bower_components/paper-date-picker/index.html 0 → 100644
  1 +<!doctype html>
  2 +<html>
  3 +<head>
  4 +
  5 + <meta charset="utf-8">
  6 + <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7 +
  8 + <title>paper-date-picker</title>
  9 +
  10 + <script src="../webcomponentsjs/webcomponents-lite.js"></script>
  11 + <link rel="import" href="../iron-component-page/iron-component-page.html">
  12 +
  13 +</head>
  14 +<body>
  15 +
  16 + <iron-component-page></iron-component-page>
  17 +
  18 +</body>
bower_components/paper-date-picker/package.json 0 → 100644
  1 +{
  2 + "name": "paper-date-picker",
  3 + "version": "1.2.0",
  4 + "description": "Provides a responsive date picker based on the material design spec",
  5 + "main": "index.html",
  6 + "devDependencies": {
  7 + "browser-sync": "^2.8.0",
  8 + "del": "^1.2.0",
  9 + "gulp": "^3.9.0",
  10 + "gulp-add": "0.0.2",
  11 + "gulp-bower": "0.0.10",
  12 + "gulp-bump": "^0.3.1",
  13 + "gulp-copy": "0.0.2",
  14 + "gulp-filter": "^2.0.2",
  15 + "gulp-gh-pages": "^0.5.2",
  16 + "gulp-git": "^1.2.4",
  17 + "gulp-tag-version": "^1.3.0",
  18 + "merge-stream": "^0.1.8",
  19 + "portfinder": "^0.4.0",
  20 + "vinyl-paths": "^1.0.0",
  21 + "web-component-tester": "^3.3.3"
  22 + },
  23 + "scripts": {
  24 + "test": "echo \"Error: no test specified\" && exit 1"
  25 + },
  26 + "repository": {
  27 + "type": "git",
  28 + "url": "git+https://github.com/bendavis78/paper-date-picker.git"
  29 + },
  30 + "keywords": [
  31 + "web-component",
  32 + "webcomponents",
  33 + "polymer",
  34 + "datepicker",
  35 + "paper-date-picker"
  36 + ],
  37 + "author": "Ben Davis <bendavis78@gmail.com>",
  38 + "license": "MIT",
  39 + "bugs": {
  40 + "url": "https://github.com/bendavis78/paper-date-picker/issues"
  41 + },
  42 + "homepage": "https://github.com/bendavis78/paper-date-picker#readme"
  43 +}
bower_components/paper-date-picker/paper-calendar.html 0 → 100644
  1 +<link rel="import" href="../polymer/polymer.html">
  2 +<link rel="import" href="../iron-flex-layout/iron-flex-layout.html">
  3 +<link rel="import" href="../iron-icon/iron-icon.html">
  4 +<link rel="import" href="../paper-ripple/paper-ripple.html">
  5 +<link rel="import" href="../paper-styles/color.html">
  6 +<link rel="import" href="../paper-styles/default-theme.html">
  7 +<link rel="import" href="../paper-styles/shadow.html">
  8 +<link rel="import" href="../paper-styles/typography.html">
  9 +<link rel="import" href="../iron-resizable-behavior/iron-resizable-behavior.html">
  10 +<link rel="import" href="../moment-element/moment-import.html">
  11 +<link rel="import" href="paper-date-picker-icons.html">
  12 +
  13 +<dom-module id="paper-calendar">
  14 + <template>
  15 + <style>
  16 + :host {
  17 + display: block;
  18 + box-sizing: border-box;
  19 + padding: 12px 0;
  20 + position: relative;
  21 + width: 100%;
  22 + height: 100%;
  23 + min-width: 160px;
  24 + min-height: 160px;
  25 + color: var(--primary-text-color);
  26 + -webkit-font-smoothing: antialiased;
  27 + -webkit-tap-highlight-color: rgba(0,0,0,0);
  28 + --ease-in-sine: cubic-bezier(0.47, 0, 0.745, 0.715);
  29 + --ease-out-sine: cubic-bezier(0.39, 0.575, 0.565, 1);
  30 + @apply(--paper-font-body1);
  31 + @apply(--paper-calendar);
  32 + overflow: hidden;
  33 + -webkit-touch-callout: none;
  34 + -webkit-user-select: none;
  35 + -khtml-user-select: none;
  36 + -moz-user-select: none;
  37 + -ms-user-select: none;
  38 + user-select: none;
  39 +
  40 + @apply(--paper-calendar);
  41 + }
  42 + #calendar {
  43 + position: relative;
  44 + width: 100%;
  45 + height: 100%;
  46 + @apply(--layout-horizontal);
  47 + }
  48 + #months {
  49 + height: 100%;
  50 + @apply(--layout-horizontal);
  51 + }
  52 + #months.animating .month-nav {
  53 + opacity: 1;
  54 + }
  55 + #months.animating {
  56 + transition-property: transform, opacity;
  57 + transition-duration: 300ms;
  58 + }
  59 + #months.animating.swipe {
  60 + transition-timing-function: var(--ease-in-sine);
  61 + --webkit-transition-timing-function: var(--ease-in-sine);
  62 + }
  63 + #months.animating.reset {
  64 + transition-timing-function: var(--ease-out-sine);
  65 + --webkit-transition-timing-function: var(--ease-out-sine);
  66 + }
  67 + .month {
  68 + height: 100%;
  69 + @apply(--layout-vertical);
  70 + @apply(--layout-justified);
  71 + @apply(--layout-flex);
  72 + }
  73 +
  74 + .month-row, .month-nav {
  75 + height: calc(100%/8);
  76 + box-sizing: border-box;
  77 + padding: 0 calc(100%/36);
  78 + }
  79 +
  80 + .month-col {
  81 + position: relative;
  82 + @apply(--layout-vertical);
  83 + @apply(--layout-flex);
  84 + }
  85 +
  86 + .month-nav {
  87 + position: absolute;
  88 + top: 0;
  89 + left: 0;
  90 + width: 100%;
  91 + opacity: 1;
  92 + @apply(--layout-horizontal);
  93 + @apply(--layout-center);
  94 + }
  95 + .month-nav .col {
  96 + position: relative;
  97 + @apply(--layout-vertical);
  98 + @apply(--layout-center-center);
  99 + }
  100 + .month-nav .btn .icon {
  101 + cursor: pointer;
  102 + }
  103 + .month-nav .btn .ripple {
  104 + position: absolute;
  105 + width: 48px;
  106 + height: 48px;
  107 + top: 50%;
  108 + left: 50%;
  109 + transform: translate(-50%, -50%);
  110 + }
  111 + .month-nav .btn.right {
  112 + text-align: right;
  113 + }
  114 + .month-name {
  115 + line-height: 24px;
  116 + vertical-align: middle;
  117 + text-align: center;
  118 + font-weight: bold;
  119 + @apply(--paper-font-body2);
  120 + @apply(--layout-horizontal);
  121 + @apply(--layout-center);
  122 + @apply(--layout-center-justified);
  123 + @apply(--layout-flex);
  124 + }
  125 + .month-weekdays {
  126 + color: var(--secondary-text-color);
  127 + @apply(--layout-horizontal);
  128 + @apply(--layout-justified);
  129 + @apply(--layout-flex);
  130 + }
  131 + .month-days {
  132 + @apply(--layout-horizontal);
  133 + @apply(--layout-justified);
  134 + @apply(--layout-flex);
  135 + }
  136 + .month-col .day {
  137 + cursor: default;
  138 + pointer-events: none;
  139 + @apply(--layout-fit);
  140 + @apply(--layout-vertical);
  141 + @apply(--layout-center-center);
  142 + }
  143 + .month-col {
  144 + position: relative;
  145 + width: 100%;
  146 + height: 100%;
  147 + @apply(--layout-center-center);
  148 + }
  149 + .day-item {
  150 + border-radius: 100%;
  151 + width: 100%;
  152 + height: 100%;
  153 + }
  154 + .day-item::selection {
  155 + background: none;
  156 + }
  157 + .day-item.selected {
  158 + background: var(--default-primary-color);
  159 + }
  160 + .day-item.selected .day {
  161 + color: var(--text-primary-color);
  162 + }
  163 + .day-item:not([disabled]) {
  164 + cursor: pointer;
  165 + }
  166 + .day-item[disabled] .day {
  167 + color: var(--text-disabled-color, #9d9d9d);
  168 + }
  169 + .day-item.today .day {
  170 + color: var(--default-primary-color);
  171 + }
  172 + .day-item.selected.today .day {
  173 + color: var(--text-primary-color);
  174 + }
  175 + .flex {
  176 + @apply(--layout-flex);
  177 + }
  178 + .flex-5 {
  179 + @apply(--layout-flex-5);
  180 + }
  181 + </style>
  182 + <div id="calendar">
  183 + <div id="months" on-track="_onTrack" class$="{{_contentClass}}">
  184 + <template is="dom-repeat" items="{{_months}}" as="month">
  185 + <div class$="{{_getMonthClass('month', month)}}">
  186 + <div class="month-row month-name">
  187 + <span>{{dateFormat(month.date, 'MMMM YYYY', locale)}}</span>
  188 + </div>
  189 + <div class="month-row month-weekdays week">
  190 + <template is="dom-repeat" items="{{_weekdays}}">
  191 + <div class="month-col layout vertical flex">
  192 + <div class="day">{{item.0}}</div>
  193 + </div>
  194 + </template>
  195 + </div>
  196 + <template is="dom-repeat" items="{{month.weeks}}" as="row">
  197 + <div class="month-row month-days">
  198 + <template is="dom-repeat" items="{{row}}">
  199 + <div class="month-col">
  200 + <div class$="{{_getDayClass('day-item selection', item.date, today, date)}}"
  201 + disabled$="{{_isDisabled(item.day, item.date, minDate, maxDate)}}"
  202 + on-tap="_tapDay" date$="{{item.name}}">
  203 + <div class="day">{{item.day}}</div>
  204 + </div>
  205 + </div>
  206 + </template>
  207 + </div>
  208 + </template>
  209 + </div>
  210 + </template>
  211 + </div>
  212 + <div id="monthNav" class="month-nav">
  213 + <div class="flex col self-stretch">
  214 + <div class="btn" on-tap="_swipePrevMonth">
  215 + <paper-ripple center class="ripple circle"></paper-ripple>
  216 + <iron-icon class="icon flex" icon="date-picker:chevron-left"></iron-icon>
  217 + </div>
  218 + </div>
  219 + <div class="flex-5"></div>
  220 + <div class="flex col self-stretch">
  221 + <div class="btn" on-tap="_swipeNextMonth">
  222 + <paper-ripple center class="ripple circle"></paper-ripple>
  223 + <iron-icon class="icon flex" icon="date-picker:chevron-right"></iron-icon>
  224 + </div>
  225 + </div>
  226 + </div>
  227 + </div>
  228 + </template>
  229 + <script>
  230 + (function() {
  231 +
  232 + // Ignore movement within this distance (px)
  233 + var WIGGLE_THRESHOLD = 4;
  234 + var WIGGLE_THRESHOLD_SQUARE = WIGGLE_THRESHOLD * WIGGLE_THRESHOLD;
  235 +
  236 + // what constitues a flick (px/ms)
  237 + var FLICK_SPEED = 0.5;
  238 +
  239 + // Factor for "springy" resistence effect when swiping too far.
  240 + var RESIST_LENGTH = 40;
  241 + var RESIST_FACTOR = 2;
  242 +
  243 + // Number of months to preload on both sides of the current month
  244 + var PRELOAD_MONTHS = 1;
  245 +
  246 + function dateDiff(a, b) {
  247 + a = new Date(a.getTime());
  248 + b = new Date(b.getTime());
  249 + a.setHours(0, 0, 0, 0);
  250 + b.setHours(0, 0, 0, 0);
  251 + return (a.getTime() - b.getTime()) / 86400000;
  252 + }
  253 +
  254 + Polymer({
  255 + is: 'paper-calendar',
  256 + properties: {
  257 + /*
  258 + * The selected date
  259 + */
  260 + date: {
  261 + type: Date,
  262 + notify: true,
  263 + value: function() {
  264 + return new Date();
  265 + },
  266 + observer: '_dateChanged'
  267 + },
  268 + /**
  269 + * The current locale
  270 + */
  271 + locale: {
  272 + type: String,
  273 + value: 'en',
  274 + notify: true,
  275 + observer: '_localeChanged'
  276 + },
  277 + /**
  278 + * The minimum allowed date
  279 + */
  280 + minDate: {
  281 + type: Date,
  282 + value: null
  283 + },
  284 + /**
  285 + * The maximum allowed date
  286 + */
  287 + maxDate: {
  288 + type: Date,
  289 + value: null
  290 + },
  291 + /**
  292 + * The currently selected month (1-12)
  293 + */
  294 + currentMonth: {
  295 + type: Number
  296 + },
  297 + /**
  298 + * The currently selected year
  299 + */
  300 + currentYear: {
  301 + type: Number
  302 + },
  303 + _contentClass: String,
  304 + _months: Array,
  305 + _firstDayOfWeek: Number,
  306 + },
  307 + behaviors: [
  308 + Polymer.IronResizableBehavior
  309 + ],
  310 + observers: [
  311 + '_populate(currentYear, currentMonth, minDate, maxDate, locale)',
  312 + ],
  313 + listeners: {
  314 + 'iron-resize': '_resizeHandler',
  315 + 'swiped': '_onSwipe'
  316 + },
  317 + ready: function() {
  318 + this._updateToday();
  319 + this.currentMonth = this.date.getMonth() + 1;
  320 + this.currentYear = this.date.getFullYear();
  321 + this._transitionEvent = this._whichTransitionEnd();
  322 + },
  323 + dateFormat: function(date, format, locale) {
  324 + if (!date) {
  325 + return '';
  326 + }
  327 + var value = moment(date);
  328 + value.locale(locale || this.locale);
  329 + return value.format(format);
  330 + },
  331 + _localeChanged: function(locale) {
  332 + var localeMoment = moment();
  333 + localeMoment.locale(locale);
  334 + var weekdays = [];
  335 + for (var i=0; i<7; i++) {
  336 + weekdays.push(localeMoment.weekday(i).format('dd'));
  337 + }
  338 + this._weekdays = weekdays;
  339 + this._firstDayOfWeek = localeMoment.weekday(0).format('d');
  340 + },
  341 + _populate: function(currentYear, currentMonth, minDate, maxDate) {
  342 + var date, month, weeks, day, d, dayInfo, monthData, months = [];
  343 +
  344 + // Make sure currentYear/currentMonth are in min/max range
  345 + if (minDate && new Date(currentYear, currentMonth, 0) < minDate) {
  346 + this.currentYear = minDate.getFullYear();
  347 + this.currentMonth = minDate.getMonth() + 1;
  348 + return;
  349 + } else if (maxDate && new Date(currentYear, currentMonth - 1, 1) > maxDate) {
  350 + this.currentYear = maxDate.getFullYear();
  351 + this.currentMonth = maxDate.getMonth() + 1;
  352 + return;
  353 + }
  354 +
  355 + for (var i=-PRELOAD_MONTHS; i<=PRELOAD_MONTHS; i++) {
  356 + weeks = [[]];
  357 + day = 1;
  358 + date = new Date(currentYear, currentMonth - 1 + i, 1);
  359 + month = date.getMonth();
  360 + monthData = {
  361 + year: date.getFullYear(),
  362 + month: date.getMonth() + 1,
  363 + date: new Date(date)
  364 + };
  365 +
  366 + if (!this._monthWithinValidRange(monthData.year, monthData.month)) {
  367 + continue;
  368 + }
  369 +
  370 + // add "padding" days
  371 + var firstDay = date.getDay() - this._firstDayOfWeek;
  372 + if (firstDay < 0) {
  373 + firstDay = 7 + firstDay;
  374 + }
  375 + for (d=0; d<firstDay; d++) {
  376 + weeks[0].push({day: null, date: null});
  377 + }
  378 +
  379 + // add actual days
  380 + while (date.getMonth() === month) {
  381 + if (weeks[0].length && d % 7 === 0) {
  382 + // start new week
  383 + weeks.push([]);
  384 + }
  385 + dayInfo = {
  386 + date: new Date(date.getFullYear(), month, day),
  387 + name: this.dateFormat(date,'YYYY-MM-DD'),
  388 + year: currentYear,
  389 + month: month,
  390 + day: day,
  391 + };
  392 + weeks[weeks.length-1].push(dayInfo);
  393 + date.setDate(++day);
  394 + d++;
  395 + }
  396 +
  397 + // add remaining "padding" days
  398 + while (d < 42) {
  399 + if (d % 7 === 0) {
  400 + weeks.push([]);
  401 + }
  402 + weeks[weeks.length-1].push({day: null, date: null});
  403 + d += 1;
  404 + }
  405 +
  406 + monthData.weeks = weeks;
  407 + months.push(monthData);
  408 +
  409 + }
  410 + if (!months.length) {
  411 + return;
  412 + }
  413 + this.set('_months', months);
  414 + this.async(function() {
  415 + this._updateSelection();
  416 + this._positionSlider();
  417 + });
  418 + },
  419 + _getDayClass: function(cssClass, date) {
  420 + if (date) {
  421 + if (dateDiff(date, this.today) === 0) {
  422 + cssClass += ' today';
  423 + }
  424 + if (dateDiff(date, this.date) === 0) {
  425 + cssClass += ' selected';
  426 + this.async(function() {
  427 + this._updateSelection();
  428 + });
  429 + }
  430 + }
  431 + return cssClass;
  432 + },
  433 + _isDisabled: function(day, date) {
  434 + return !day || !this._withinValidRange(date);
  435 + },
  436 + _getMonthClass: function(name, month) {
  437 + return name + ' month-' + month.year + '-' + month.month;
  438 + },
  439 + _onTrack: function(event) {
  440 + var dx = event.detail.dx;
  441 + var dy = event.detail.dy;
  442 + var adx = Math.abs(dx);
  443 + var ady = Math.abs(dy);
  444 + var width = this._containerWidth;
  445 +
  446 + switch (event.detail.state) {
  447 + case 'start':
  448 + this._trackStartTime = (new Date()).getTime();
  449 + this._startPos = this._currentPos;
  450 + this._moveQueue = [];
  451 + break;
  452 +
  453 + case 'track':
  454 + if (this._moveQueue.length >= 4) {
  455 + this._moveQueue.shift();
  456 + }
  457 + this._moveQueue.push(event);
  458 +
  459 + // ignore movement within WIGGLE_THRESHOLD
  460 + var distance = (dx * dx) + (dy * dy);
  461 + if (!this._gesture && distance > WIGGLE_THRESHOLD_SQUARE) {
  462 + this._gesture = adx > ady ? 'pan-x' : 'pan-y';
  463 + }
  464 +
  465 + // only drag during pan-x gesture
  466 + if (this._gesture !== 'pan-x') {
  467 + return;
  468 + }
  469 +
  470 + this._dragging = true;
  471 + var fullWidth = width * this._months.length;
  472 + var x = this._startPos + dx;
  473 +
  474 + // If we're dragging outside the bounds, add some resistence
  475 + if (x > 0 || x < (-fullWidth + width)) {
  476 + if (isNaN(parseInt(this._resistStart, 10))) {
  477 + this._resistStart = adx;
  478 + }
  479 + var rdx = adx - this._resistStart;
  480 + var p, d, max = RESIST_LENGTH;
  481 + p = rdx > width ? 1 : rdx / width;
  482 + d = max * (1 - Math.pow(1 - p, RESIST_FACTOR));
  483 + x = (dx < 0 ? -this._scrollWidth + width - d : d);
  484 + } else {
  485 + this._resistStart = null;
  486 + }
  487 + this._translateX(x);
  488 + break;
  489 +
  490 + case 'end':
  491 + this._resistStart = null;
  492 + var lastIdx = this._getMonthIdx(this._startPos);
  493 + var idx = this._getMonthIdx(this._currentPos);
  494 + var speed = this._getFastestMovement(event).v;
  495 + var move = idx !== lastIdx || speed > FLICK_SPEED;
  496 + if (!this._resistStart && this._gesture === 'pan-x' && move) {
  497 + if (speed > FLICK_SPEED) {
  498 + // calculate an ideal transition duration based on current speed of swipe
  499 + var remainingDistance = width - adx;
  500 + var newDuration = remainingDistance / speed;
  501 + if (newDuration > 300) {
  502 + newDuration = 300;
  503 + }
  504 + this._transitionDuration = newDuration;
  505 + }
  506 +
  507 + if (dx > 0) {
  508 + this._swipePrevMonth();
  509 + } else {
  510 + this._swipeNextMonth();
  511 + }
  512 + } else {
  513 + this._translateX(this._startPos, 'reset');
  514 + }
  515 + this._gesture = null;
  516 + }
  517 + },
  518 + _swipePrevMonth: function() {
  519 + this._translateX(0, 'swipe', function() {
  520 + this.set('_contentClass', '');
  521 + this.transform('translateX(' + this._startPos + 'px)', this.$.months);
  522 + this.fire('swiped', {direction: 'right'});
  523 + }.bind(this));
  524 + },
  525 + _swipeNextMonth: function() {
  526 + if (!this.maxDate || this.currentMonth < this.maxDate.getMonth() + 1) {
  527 + this._translateX(-this._containerWidth * 2, 'swipe', function() {
  528 + this.set('_contentClass', '');
  529 + this.transform('translateX(' + this._startPos + 'px)', this.$.months);
  530 + this.fire('swiped', {direction: 'left'});
  531 + }.bind(this));
  532 + }
  533 + },
  534 + _getMonthIdx: function(pos) {
  535 + // returns the index for the visible month according to the given position
  536 + var width = this._containerWidth;
  537 + var i = Math.floor((-pos + (width/2)) / width);
  538 + return i < 0 ? 0 : i;
  539 + },
  540 + _translateX: function(x, transition, cb) {
  541 + if (isNaN(parseInt(x, 10))) {
  542 + throw new Error('Not a number: ' + x);
  543 + }
  544 + this._currentPos = x;
  545 + if (transition) {
  546 + if (this._transitionDuration) {
  547 + this.$.months.style.transitionDuration = this._transitionDuration + 'ms';
  548 + }
  549 + this._once(this._transitionEvent, function() {
  550 + this.set('_contentClass', '');
  551 + this.$.months.style.transitionDuration = '';
  552 + this._transitionDuration = null;
  553 + this.$.monthNav.style.removeProperty('opacity');
  554 + if (cb) {
  555 + cb();
  556 + }
  557 + }.bind(this), this.$.months);
  558 + this.set('_contentClass', 'animating ' + transition);
  559 + this.$.monthNav.style.removeProperty('opacity');
  560 + // Fixes odd bug in chrome where we lose touch-events after changing opacity
  561 + this._once('touchstart', function() {});
  562 + }
  563 + window.requestAnimationFrame(function() {
  564 + if (!transition) {
  565 + var halfWidth = this._containerWidth / 2;
  566 + var dx = Math.abs(this._startPos - x);
  567 + var p = (1 - (dx / halfWidth)) * 100;
  568 + p = (100 - Math.pow(p, 2)) / 100 / 100;
  569 + var opacity = Math.abs(parseFloat(p).toFixed(2));
  570 + this.$.monthNav.style.opacity = opacity;
  571 + }
  572 + this.transform('translateX(' + x + 'px)', this.$.months);
  573 + }.bind(this));
  574 + },
  575 + _getFastestMovement: function(event) {
  576 + // detect flick based on fastest segment of movement
  577 + var l = this._moveQueue.length;
  578 + var dt, tx, ty, tv2, x = 0, y = 0, v2 = 0;
  579 + for (var i = 0, m; i < l && (m = this._moveQueue[i]); i++) {
  580 + dt = event.timeStamp - m.timeStamp;
  581 + tx = (event.detail.x - m.detail.x) / dt;
  582 + ty = (event.detail.y - m.detail.y) / dt;
  583 + tv2 = tx * tx + ty * ty;
  584 + if (tv2 > v2) {
  585 + x = tx;
  586 + y = ty;
  587 + v2 = tv2;
  588 + }
  589 + }
  590 + return {x: x, y: y, v: Math.sqrt(v2)};
  591 + },
  592 + _onSwipe: function(event) {
  593 + if (event.detail.direction === 'right') {
  594 + this._prevMonth();
  595 + } else {
  596 + this._nextMonth();
  597 + }
  598 + },
  599 + _once: function(eventName, callback, node) {
  600 + node = node || this;
  601 + function onceCallback() {
  602 + node.removeEventListener(eventName, onceCallback);
  603 + callback.apply(null, arguments);
  604 + }
  605 + node.addEventListener(eventName, onceCallback);
  606 + },
  607 + _incrMonth: function(i) {
  608 + var date = new Date(this.currentYear, this.currentMonth - 1 + i);
  609 + var year = date.getFullYear();
  610 + var month = date.getMonth() + 1;
  611 + if (this._monthWithinValidRange(year, month)) {
  612 + this.currentYear = year;
  613 + this.currentMonth = month;
  614 + }
  615 + },
  616 + _prevMonth: function() {
  617 + this._incrMonth(-1);
  618 + },
  619 + _nextMonth: function() {
  620 + this._incrMonth(1);
  621 + },
  622 + _dateChanged: function(date, oldValue) {
  623 + if (!this._isValidDate(date)) {
  624 + console.warn('Invalid date: ' + date);
  625 + this.date = date = oldValue;
  626 + }
  627 + if (!this._withinValidRange(date)) {
  628 + console.warn('Date outside of valid range: ' + date);
  629 + this.date = date = oldValue;
  630 + }
  631 + this.currentYear = date.getFullYear();
  632 + this.currentMonth = date.getMonth() + 1;
  633 + // Only trigger a notification if there actually is a difference.
  634 + if (oldValue && date.getTime && oldValue.getTime && date.getTime() === oldValue.getTime()) {
  635 + return;
  636 + }
  637 + this._updateSelection();
  638 + },
  639 + _tapDay: function(event) {
  640 + if (!this._withinValidRange(event.model.item.date)) {
  641 + return false;
  642 + }
  643 + var item = event.model.item;
  644 + var newDate = new Date(this.date.getTime());
  645 + newDate.setYear(item.year);
  646 + newDate.setMonth(item.month);
  647 + newDate.setDate(item.day);
  648 + this.date = newDate;
  649 + },
  650 + _isValidDate: function(date) {
  651 + return date && date.getTime && !isNaN(date.getTime());
  652 + },
  653 + _withinValidRange: function(date) {
  654 + if (this._isValidDate(date)) {
  655 + return (!this.minDate || date >= this.minDate) && (!this.maxDate || date <= this.maxDate);
  656 + }
  657 + return false;
  658 + },
  659 + _monthWithinValidRange: function(year, month) {
  660 + var monthStart = new Date(year, month-1, 1);
  661 + var monthEnd = new Date(year, month, 0);
  662 + return this._withinValidRange(monthStart) || this._withinValidRange(monthEnd);
  663 + },
  664 + _positionSlider: function() {
  665 + if (!this._months || !this._containerWidth) {
  666 + return;
  667 + }
  668 + this._scrollWidth = (this.$.calendar.offsetWidth * this._months.length);
  669 + this.$.months.style.minWidth = this._scrollWidth + 'px';
  670 + var i = ((this.currentYear * 12) + this.currentMonth) -
  671 + ((this._months[0].year * 12) + this._months[0].month);
  672 + this._translateX(-i * this._containerWidth);
  673 + },
  674 + _updateSelection: function() {
  675 + // Force the day selection circle to maintain a 1:1 ratio
  676 + var selected = this.$$('.day-item.selected');
  677 + if (!selected) {
  678 + return;
  679 + }
  680 + selected.style.height = '';
  681 + selected.style.width = '';
  682 + var w = selected.parentElement.offsetWidth;
  683 + var h = selected.parentElement.offsetHeight;
  684 + selected.style.flex = '';
  685 + window.requestAnimationFrame(function() {
  686 + if (w > 0 && w < h) {
  687 + selected.style.height = w + 'px';
  688 + }
  689 + else if (h > 0) {
  690 + selected.style.width = h + 'px';
  691 + }
  692 + });
  693 + },
  694 + _resizeHandler: function() {
  695 + this._containerWidth = this.$.calendar.offsetWidth;
  696 + this._positionSlider();
  697 + this._updateSelection();
  698 + },
  699 + _getDayName: function(date) {
  700 + return date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + date.getDate();
  701 + },
  702 + _updateToday: function() {
  703 + this.today = new Date();
  704 + this.today.setHours(0, 0, 0, 0);
  705 + },
  706 + _whichTransitionEnd: function() {
  707 + var transitions = {
  708 + 'WebkitTransition' : 'webkitTransitionEnd',
  709 + 'MozTransition' : 'transitionend',
  710 + 'OTransition' : 'oTransitionEnd otransitionend',
  711 + 'transition' : 'transitionend'
  712 + };
  713 +
  714 + for (var t in transitions) {
  715 + if (this.style[t] !== undefined){
  716 + return transitions[t];
  717 + }
  718 + }
  719 + }
  720 + });
  721 + })();
  722 + </script>
  723 +</dom-module>
bower_components/paper-date-picker/paper-date-picker-dialog-style.html 0 → 100644
  1 +<style is="custom-style">
  2 +/* mixin definitions */
  3 +:root {
  4 + --paper-date-picker-dialog: {
  5 + margin: 0;
  6 + max-height: 520px !important;
  7 + overflow: hidden;
  8 + };
  9 + --paper-date-picker-dialog-picker: {
  10 + margin-top: 0 !important;
  11 + padding: 0;
  12 + };
  13 + --paper-date-picker-dialog-calendar: {
  14 + padding-bottom: 0;
  15 + };
  16 + --paper-date-picker-dialog-heading: {
  17 + margin-bottom: -62px;
  18 + };
  19 +}
  20 +</style>
  21 +
  22 +<dom-module id="paper-date-picker-dialog-style">
  23 + <template>
  24 + <style>
  25 + /* Application of mixins to local .paper-date-picker-dialog elements */
  26 + .paper-date-picker-dialog {
  27 + @apply(--paper-date-picker-dialog);
  28 + }
  29 + .paper-date-picker-dialog > paper-date-picker {
  30 + --paper-calendar: {
  31 + @apply(--paper-date-picker-dialog-calendar);
  32 + };
  33 + @apply(--paper-date-picker-dialog-picker);
  34 + }
  35 + .paper-date-picker-dialog > paper-date-picker:not([narrow]) {
  36 + --paper-date-picker-heading: {
  37 + @apply(--paper-date-picker-dialog-heading);
  38 + };
  39 + }
  40 + </style>
  41 + </template>
  42 +</dom-module>
bower_components/paper-date-picker/paper-date-picker-icons.html 0 → 100644
  1 +<link rel="import" href="../iron-iconset-svg/iron-iconset-svg.html">
  2 +
  3 +<iron-iconset-svg size="24" name="date-picker">
  4 + <svg>
  5 + <defs>
  6 + <g id="chevron-left"><path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"></path></g>
  7 + <g id="chevron-right"><path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"></path></g>
  8 + </defs>
  9 + </svg>
  10 +</iron-iconset-svg>
bower_components/paper-date-picker/paper-date-picker.html 0 → 100644
  1 +<link rel="import" href="../polymer/polymer.html">
  2 +<link rel="import" href="../iron-media-query/iron-media-query.html">
  3 +<link rel="import" href="../neon-animation/neon-animated-pages.html">
  4 +<link rel="import" href="../neon-animation/neon-animatable.html">
  5 +<link rel="import" href="../neon-animation/animations/fade-in-animation.html">
  6 +<link rel="import" href="../neon-animation/animations/fade-out-animation.html">
  7 +<link rel="import" href="../iron-resizable-behavior/iron-resizable-behavior.html">
  8 +<link rel="import" href="../iron-selector/iron-selector.html">
  9 +<link rel="import" href="../iron-flex-layout/iron-flex-layout.html">
  10 +<link rel="import" href="../paper-styles/color.html">
  11 +<link rel="import" href="../paper-styles/default-theme.html">
  12 +<link rel="import" href="../paper-styles/shadow.html">
  13 +<link rel="import" href="../paper-styles/typography.html">
  14 +<link rel="import" href="../moment-element/moment-with-locales-import.html">
  15 +<link rel="import" href="paper-calendar.html">
  16 +<link rel="import" href="paper-date-picker-dialog-style.html">
  17 +<link rel="import" href="paper-year-list.html">
  18 +
  19 +<!--
  20 +Material Design [Pickers](http://www.google.com/design/spec/components/pickers.html)
  21 +
  22 +Provides a responsive date picker based on the material design spec.
  23 +
  24 +## Examples:
  25 +
  26 +Default picker:
  27 +
  28 + <paper-date-picker></paper-date-picker>
  29 +
  30 +Setting the initial date to April 20, 2015:
  31 +
  32 + <paper-date-picker date="April 20, 2015"></paper-date-picker>
  33 +
  34 +You may also specify a minimum and/or maximum date allowed in this picker using
  35 +the same date notation:
  36 +
  37 + <paper-date-picker min-date="April 1, 2015" max-date="June 30, 2015"></paper-date-picker>
  38 +
  39 +If you include this element as part of `paper-dialog`, use the class
  40 +`"paper-date-picker-dialog"` on the dialog element in order to give it proper
  41 +styling:
  42 +
  43 + <paper-dialog id="dialog" class="paper-date-picker-dialog" modal
  44 + on-iron-overlay-closed="dismissDialog">
  45 + <paper-date-picker id="picker" date="[[date]]"></paper-date-picker>
  46 + <div class="buttons">
  47 + <paper-button dialog-dismiss>Cancel</paper-button>
  48 + <paper-button dialog-confirm>OK</paper-button>
  49 + </div>
  50 + </paper-dialog>
  51 +
  52 +@element paper-date-picker
  53 +@blurb Provides a responsive date picker based on the material design spec.
  54 +@homepage http://bendavis78.github.io/paper-date-picker/
  55 +@demo demo/index.html
  56 +-->
  57 +
  58 +<style is="custom-style" include="paper-date-picker-dialog-style">
  59 + /* includes dialog style at document-level for backward compatibility */
  60 +</style>
  61 +
  62 +<dom-module id="paper-date-picker">
  63 + <template>
  64 + <style>
  65 + :host {
  66 + -webkit-touch-callout: none;
  67 + -webkit-user-select: none;
  68 + -khtml-user-select: none;
  69 + -moz-user-select: none;
  70 + -ms-user-select: none;
  71 + user-select: none;
  72 + display: inline-block;
  73 + color: var(--primary-text-color);
  74 + @apply(--paper-font-body1);
  75 + @apply(--paper-date-picker);
  76 + }
  77 +
  78 + /** Landscape ******************/
  79 + #datePicker {
  80 + width: 512px;
  81 + height: 248px;
  82 + @apply(--layout-horizontal);
  83 + }
  84 + #heading {
  85 + width: 168px;
  86 + @apply(--paper-date-picker-heading);
  87 + }
  88 +
  89 + /** Narrow *********************/
  90 + :host([narrow]) #datePicker {
  91 + width: 328px;
  92 + height: 428px;
  93 + @apply(--layout-vertical);
  94 + }
  95 + :host([narrow]) #heading {
  96 + width: auto;
  97 + height: 96px;
  98 + padding: 16px 24px;
  99 + }
  100 +
  101 + /** Heading ********************/
  102 + #heading {
  103 + padding: 16px;
  104 + box-sizing: border-box;
  105 + color: var(--text-primary-color);
  106 + background: var(--default-primary-color);
  107 + @apply(--layout-vertical);
  108 + @apply(--layout-around-justfied);
  109 + }
  110 + #heading .date,
  111 + #heading .year {
  112 + cursor: pointer;
  113 + }
  114 + #heading .date {
  115 + @apply(--paper-font-display1);
  116 + font-weight: bold;
  117 + margin-top: 2px;
  118 + @apply(--paper-date-picker-heading-date);
  119 + }
  120 + #heading div.date {
  121 + letter-spacing: 0.025em;
  122 + }
  123 + #heading .date span {
  124 + white-space: nowrap;
  125 + }
  126 + #heading .year {
  127 + @apply(--paper-font-body2);
  128 + font-size: 16px;
  129 + @apply(--paper-date-picker-heading-date);
  130 + }
  131 + #heading:not(.pg-chooseYear) .year,
  132 + #heading.pg-chooseYear .date {
  133 + color: var(--light-primary-color);
  134 + }
  135 +
  136 + /** Calendar/Year picker ********/
  137 + :host([isTouch]) paper-year-list::-webkit-scrollbar {
  138 + width: 0 !important;
  139 + }
  140 + #pages {
  141 + @apply(--layout-flex);
  142 + width: auto;
  143 + background: var(--default-background-color);
  144 + }
  145 + #calendar {
  146 + --paper-calendar: {
  147 + @apply(--paper-date-picker-calendar);
  148 + }
  149 + }
  150 + </style>
  151 + <iron-media-query query="{{_getMediaQuery(forceNarrow, responsiveWidth)}}" query-matches="{{_queryMatches}}"></iron-media-query>
  152 + <div id="datePicker">
  153 + <div id="heading" class$="{{_getHeadingClass('heading-content', _selectedPage)}}">
  154 + <div class="year" on-tap="_tapHeadingYear">{{dateFormat(date, 'YYYY', locale)}}</div>
  155 + <div class="date" on-tap="_tapHeadingDate">
  156 + <template is="dom-repeat" items="{{_splitHeadingDate(date, headingFormat, locale)}}">
  157 + <span>{{item}}</span>
  158 + </template>
  159 + </div>
  160 + </div>
  161 + <neon-animated-pages id="pages" selected="{{_selectedPage}}" attr-for-selected="id"
  162 + entry-animation="fade-in-animation" exit-animation="fade-out-animation"
  163 + on-iron-select="_pageSelected">
  164 + <neon-animatable id="chooseDate">
  165 + <paper-calendar id="calendar" locale="{{locale}}" date="{{date}}"
  166 + min-date="{{minDate}}" max-date="{{maxDate}}">
  167 + </paper-calendar>
  168 + </neon-animatable>
  169 + <neon-animatable id="chooseYear">
  170 + <paper-year-list id="yearList" date="{{date}}" on-tap="_tapHeadingDate" min="[[_minYear]]" max="[[_maxYear]]"></paper-year-list>
  171 + </neon-animatable>
  172 + </neon-animated-pages>
  173 + </div>
  174 + </template>
  175 + <script>
  176 +
  177 + Polymer({
  178 + is: 'paper-date-picker',
  179 + properties: {
  180 + /**
  181 + * The selected date (YYYY-MM-DD)
  182 + */
  183 + date: {
  184 + type: Date,
  185 + notify: true
  186 + },
  187 + /**
  188 + * Maximum screen width at which the picker uses a vertical layout
  189 + */
  190 + responsiveWidth: {
  191 + type: String,
  192 + value: '560px'
  193 + },
  194 + /**
  195 + * The current locale
  196 + */
  197 + locale: {
  198 + type: String,
  199 + value: 'en'
  200 + },
  201 + /**
  202 + * The format of the date displayed in the heading.
  203 + * See docuemntation for Moment.js for more info.
  204 + */
  205 + headingFormat: {
  206 + type: String,
  207 + value: 'ddd, MMM D'
  208 + },
  209 + /**
  210 + * The minimum allowed date
  211 + */
  212 + minDate: {
  213 + type: Date,
  214 + value: null
  215 + },
  216 + /**
  217 + * The maximum allowed date
  218 + */
  219 + maxDate: {
  220 + type: Date,
  221 + value: null
  222 + },
  223 + /**
  224 + * Force narrow layout
  225 + */
  226 + forceNarrow: {
  227 + type: Boolean,
  228 + value: false
  229 + },
  230 + narrow: {
  231 + type: Boolean,
  232 + reflectToAttribute: true,
  233 + notify: true,
  234 + computed: '_computeNarrow(forceNarrow, _queryMatches)'
  235 + },
  236 + isTouch: {
  237 + type: Boolean,
  238 + value: false,
  239 + readOnly: true,
  240 + reflectToAttribute: true
  241 + },
  242 + _queryMatches: {
  243 + type: Boolean,
  244 + value: false
  245 + },
  246 + headingBreak: {
  247 + type: String,
  248 + value: '[,]'
  249 + },
  250 + _selectedPage: String,
  251 + _maxYear: {
  252 + type: Number,
  253 + computed: '_getFullYear(maxDate)'
  254 + },
  255 + _minYear: {
  256 + type: Number,
  257 + computed: '_getFullYear(minDate)'
  258 + }
  259 + },
  260 + behaviors: [
  261 + Polymer.IronResizableBehavior
  262 + ],
  263 + listeners: {
  264 + 'iron-resize': '_resizeHandler'
  265 + },
  266 + ready: function() {
  267 + this.today = this.$.calendar.today;
  268 + this.isTouch = 'ontouchstart' in window;
  269 + this._selectPage('chooseDate');
  270 + },
  271 + dateFormat: function() {
  272 + return this.$.calendar.dateFormat.apply(this.$.calendar, arguments);
  273 + },
  274 + _tapHeadingDate: function() {
  275 + if (this.$.pages.selected !== 'chooseDate') {
  276 + this._selectPage('chooseDate');
  277 + } else {
  278 + // tapping the date header while already viewing months brings you back
  279 + // to the selected month
  280 + this.$.calendar.currentMonth = this.date.getMonth() + 1;
  281 + this.$.calendar.currentYear = this.date.getFullYear();
  282 + }
  283 + },
  284 + _tapHeadingYear: function() {
  285 + if (this.$.pages.selected !== 'chooseYear') {
  286 + this._selectPage('chooseYear');
  287 + this.$.yearList.centerSelected();
  288 + }
  289 + },
  290 + _selectPage: function(page) {
  291 + this.$.pages.selected = page;
  292 + },
  293 + _getMediaQuery: function(forceNarrow, responsiveWidth) {
  294 + return '(max-width: ' + (forceNarrow ? '' : responsiveWidth) + ')';
  295 + },
  296 + _getHeadingClass: function(pfx, selectedPage) {
  297 + return pfx + ' pg-' + selectedPage;
  298 + },
  299 + _getFullYear: function(date) {
  300 + return date ? date.getFullYear() : null;
  301 + },
  302 + _splitHeadingDate: function(date, format, locale) {
  303 + var re = new RegExp(this.headingBreak, 'g');
  304 + var text = this.dateFormat(date, format, locale);
  305 + var seps = text.match(re);
  306 + var value;
  307 + if (!seps) {
  308 + value = [text];
  309 + } else {
  310 + value = text.split(re).map(function(s, i) {
  311 + return s + (seps[i] || '');
  312 + });
  313 + }
  314 + return value;
  315 + },
  316 + _computeNarrow: function(queryMatches, forceNarrow) {
  317 + return queryMatches || forceNarrow;
  318 + },
  319 + _pageSelected: function() {
  320 + this._resizeHandler();
  321 + },
  322 + _resizeHandler: function() {
  323 + if (this._resizing) {
  324 + return;
  325 + }
  326 + this._resizing = true;
  327 + this.$.calendar.notifyResize();
  328 + this._resizing = false;
  329 +
  330 + this.updateStyles();
  331 + }
  332 + });
  333 + </script>
  334 +</dom-module>
bower_components/paper-date-picker/paper-year-list.html 0 → 100644
  1 +<link rel="import" href="../iron-flex-layout/iron-flex-layout.html">
  2 +<link rel="import" href="../iron-list/iron-list.html">
  3 +<link rel="import" href="../iron-resizable-behavior/iron-resizable-behavior.html">
  4 +<link rel="import" href="../paper-ripple/paper-ripple.html">
  5 +<link rel="import" href="../paper-styles/default-theme.html">
  6 +<link rel="import" href="../polymer/polymer.html">
  7 +
  8 +<dom-module id="paper-year-list">
  9 + <template>
  10 + <style>
  11 + :host {
  12 + display: block;
  13 + box-sizing: border-box;
  14 + height: 100%;
  15 + @apply(--paper-font-common-base);
  16 + /* for iron-list to fit */
  17 + position: relative;
  18 + }
  19 + .year {
  20 + cursor: pointer;
  21 + height: var(--paper-year-list-item-height, 44px);
  22 + line-height: var(--paper-year-list-item-height, 44px);
  23 + text-align: center;
  24 + vertical-align: middle;
  25 + }
  26 + .selected {
  27 + color: var(--default-primary-color);
  28 + font-size: 24px;
  29 + }
  30 + iron-list {
  31 + @apply(--layout-fit);
  32 + }
  33 + </style>
  34 + <iron-list id="yearList" items="[[_years]]">
  35 + <template>
  36 + <div class$="year{{_addSelectedClass(selected)}}" on-tap="_tappedYearHandler">
  37 + [[item.year]]
  38 + </div>
  39 + </template>
  40 + </iron-list>
  41 + </template>
  42 + <script>
  43 + Polymer({
  44 + is: 'paper-year-list',
  45 + properties: {
  46 + date: {
  47 + type: Date,
  48 + notify: true,
  49 + observer: '_dateChange'
  50 + },
  51 + /**
  52 + * Maximum allowed year.
  53 + */
  54 + max: {
  55 + type: Number,
  56 + value: 2100,
  57 + observer: '_maxChange'
  58 + },
  59 + /**
  60 + * Minimum allowed year.
  61 + */
  62 + min: {
  63 + type: Number,
  64 + value: 1900,
  65 + observer: '_minChange'
  66 + },
  67 + /**
  68 + * The selected year, sync with the year of the given date
  69 + * or null if year isn't within range.
  70 + */
  71 + selected: {
  72 + type: Number,
  73 + notify: true,
  74 + observer: '_selectedChange'
  75 + },
  76 + /**
  77 + * The allowed years array.
  78 + */
  79 + _years: {
  80 + type: Array,
  81 + computed: '_computeYears(min, max)',
  82 + readOnly: true,
  83 + value: function() {
  84 + return Date.now().getFullYear;
  85 + }
  86 + }
  87 + },
  88 + ready: function() {
  89 + // hack for iron-list not to scroll to the first visible index on resize
  90 + this.$.yearList._resizeHandler = function() {
  91 + this.debounce('resize', function() {
  92 + this._render();
  93 + if (this._itemsRendered && this._physicalItems && this._isVisible) {
  94 + this._resetAverage();
  95 + this.updateViewportBoundaries();
  96 + }
  97 + });
  98 + }.bind(this.$.yearList);
  99 + },
  100 + /**
  101 + * Scroll in the years list to center the selected year.
  102 + */
  103 + centerSelected: function() {
  104 + if (this.selected !== null) {
  105 + var selectedYearIdx = this.selected - this.min;
  106 + this.$.yearList.scrollToIndex(selectedYearIdx);
  107 + this.async(function() {
  108 + var selectedPos = selectedYearIdx * this._physicalAverage + 1;
  109 + if (selectedPos !== this.scrollTop) {
  110 + this._update();
  111 + this.scrollTop = selectedPos;
  112 + }
  113 + if (this.scrollHeight - this.offsetHeight !== this.scrollTop) {
  114 + this.scrollTop += (this._physicalAverage - this.offsetHeight) / 2;
  115 + }
  116 + }.bind(this.$.yearList));
  117 + }
  118 + },
  119 + /**
  120 + * Return the selected class if needed.
  121 + */
  122 + _addSelectedClass: function(selected) {
  123 + if (selected) {
  124 + return ' selected';
  125 + }
  126 + },
  127 + /**
  128 + * Compute the years array passed to the iron-list.
  129 + */
  130 + _computeYears: function(min, max) {
  131 + if (typeof min !== 'number' || typeof max !== 'number') {
  132 + return;
  133 + }
  134 + var years = [];
  135 + for (;min <= max; min++) {
  136 + years.push({year: min});
  137 + }
  138 + return years;
  139 + },
  140 + /**
  141 + * Set 'selected' attribute to the new date's year if it is within range, else set it to null.
  142 + */
  143 + _dateChange: function(date) {
  144 + var newYear = date.getFullYear();
  145 + this.selected = this._withinRange(newYear) ? newYear : null;
  146 + },
  147 + _maxChange: function(max) {
  148 + if (typeof max !== 'number') {
  149 + this.max = 2100;
  150 + }
  151 + },
  152 + _minChange: function(min) {
  153 + if (typeof min !== 'number') {
  154 + this.min = 1900;
  155 + }
  156 + },
  157 + /**
  158 + * If selected is null, clear iron-list selection,
  159 + * else select it in iron-list and synchronize 'date' attribute.
  160 + */
  161 + _selectedChange: function(selected) {
  162 + if (selected === null) {
  163 + this.$.yearList.clearSelection();
  164 + return;
  165 + }
  166 + if (selected !== this.date.getFullYear()) {
  167 + // set the year using a new Date instance for notifying to work
  168 + this.date = new Date(this.date.setFullYear(selected));
  169 + }
  170 + this._selectYearInList(selected);
  171 + },
  172 + /**
  173 + * Select the given year in the years list.
  174 + */
  175 + _selectYearInList: function(year) {
  176 + var yearIdx = year - this.min;
  177 + this.$.yearList.selectItem(yearIdx);
  178 + },
  179 + /**
  180 + * Update 'selected' attribute and select in iron-list
  181 + * from a tapped item's event in the years list.
  182 + */
  183 + _tappedYearHandler: function(e) {
  184 + var yearItem = e.model.__data__.item;
  185 + var year = yearItem.year;
  186 + if (this.selected !== year) {
  187 + this.$.yearList.selectItem(yearItem);
  188 + this.selected = year;
  189 + }
  190 + },
  191 + /**
  192 + * Return true if year is between min and max.
  193 + */
  194 + _withinRange: function(year) {
  195 + return !(this.min && year < this.min || this.max && year > this.max );
  196 + },
  197 + behaviors: [
  198 + Polymer.IronResizableBehavior
  199 + ]
  200 + });
  201 + </script>
  202 +</dom-module>
bower_components/paper-date-picker/test/index.html 0 → 100644
  1 +<!DOCTYPE html>
  2 +<!--
  3 +@license
  4 +Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
  5 +This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
  6 +The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
  7 +The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
  8 +Code distributed by Google as part of the polymer project is also
  9 +subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
  10 +-->
  11 +<html>
  12 +<head>
  13 + <meta charset="UTF-8">
  14 + <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
  15 + <title>paper-date-picker tests</title>
  16 + <script src="../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
  17 + <script src="../bower_components/web-component-tester/browser.js"></script>
  18 +</head>
  19 +<body>
  20 + <script>
  21 + WCT.loadSuites([
  22 + 'paper-date-picker.html',
  23 + 'paper-date-picker.html?dom=shadow'
  24 + ]);
  25 + </script>
  26 +</body>
  27 +</html>
bower_components/paper-date-picker/test/paper-date-picker.html 0 → 100644
  1 +<!doctype html>
  2 +<html>
  3 +
  4 +<head>
  5 + <meta charset="utf-8">
  6 + <script src="../bower_components/webcomponentsjs/webcomponents-lite.js"></script>
  7 + <script src="../bower_components/web-component-tester/browser.js"></script>
  8 + <!-- import the element to test -->
  9 + <link rel="import" href="../paper-date-picker.html">
  10 +</head>
  11 +
  12 +<body>
  13 +
  14 + <test-fixture id="max-date-fixture">
  15 + <template>
  16 + <paper-date-picker
  17 + id="picker"
  18 + date="January 1, 2016"
  19 + max-date="February 28, 2016">
  20 + </paper-date-picker>
  21 + </template>
  22 + </test-fixture>
  23 +
  24 + <script>
  25 +
  26 + describe('paper-date-picker', function() {
  27 + var element;
  28 +
  29 + context('with a max-date', function() {
  30 +
  31 + beforeEach(function() {
  32 + element = fixture('max-date-fixture');
  33 + });
  34 +
  35 + it('should not swipe after the max bound', function(done) {
  36 +
  37 + // Check initialization
  38 + expect(element.date).to.be.not.null;
  39 + expect(element.maxDate).to.be.not.null;
  40 +
  41 + // Try to swipe after the max bound
  42 + var calendar = element.$$('paper-calendar');
  43 + calendar._swipeNextMonth();
  44 + calendar._swipeNextMonth();
  45 + calendar._swipeNextMonth();
  46 + calendar._swipeNextMonth();
  47 +
  48 + // Check after all animation that the calendar has been transformed
  49 + // once
  50 + setTimeout(function() {
  51 + // When the max bound is reached, the div `months` contains only two
  52 + // months. So we check that the current position is equal to the
  53 + // half of the width, else it means the calendar has undergone too
  54 + // much transformations
  55 + expect(calendar._currentPos).to.equal(
  56 + -(calendar.$.months.clientWidth / 2)
  57 + );
  58 + done();
  59 + }, 500);
  60 + });
  61 +
  62 + });
  63 +
  64 + });
  65 +
  66 + </script>
  67 +</body>
  68 +
  69 +</html>