diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
index b5ac19e8bd..c41f9afed8 100644
--- a/CONTRIBUTORS.md
+++ b/CONTRIBUTORS.md
@@ -311,6 +311,7 @@ All definitions files include a header with the author and editors, so at some p
* [PhantomJS](http://phantomjs.org) (by [Jed Hunsaker](https://github.com/jedhunsaker))
* [PhoneGap](http://phonegap.com) (by [Boris Yankov](https://github.com/borisyankov))
* [Physijs](http://chandlerprall.github.io/Physijs/) (by [gyoh_k](https://github.com/gyohk))
+* [Pickadate.js](https://github.com/amsul/pickadate.js) (by [Adi Dahiya](https://github.com/adidahiya))
* [PixiJS](https://github.com/GoodBoyDigital/pixi.js) (by [Pedro Casaubon](https://github.com/xperiments))
* [Platform](https://github.com/bestiejs/platform.js) (by [Jake Hickman](https://github.com/JakeH))
* [PouchDB](http://pouchdb.com) (by [Bill Sears](https://github.com/MrBigDog2U/))
diff --git a/pickadate/pickadate-tests.ts b/pickadate/pickadate-tests.ts
new file mode 100644
index 0000000000..ac48a98569
--- /dev/null
+++ b/pickadate/pickadate-tests.ts
@@ -0,0 +1,243 @@
+///
+///
+
+function testApiMethods(api: Pickadate.Api) {
+ api.clear();
+ api.close();
+ api.close(true);
+ api.get('value');
+ api.get('value', 'yyyy-mm-dd');
+ api.off('open');
+ api.off('open', 'close', 'render');
+ api.on('set', (context: {[key: string]: any}) => { });
+ api.on('get', () => { });
+ api.open();
+ api.open(true);
+ api.render();
+ api.render(true);
+ api.set('value', '2014-09-23');
+ api.set({
+ value: '2014-09-23',
+ max: new Date(2014, 12, 1)
+ });
+ api.start();
+ api.stop();
+ api.trigger('open');
+
+ api.start().open().close().stop();
+
+ var pickerInputElement = api.$node;
+ pickerInputElement.show();
+
+ var pickerRootElement = api.$root;
+ pickerRootElement.show();
+}
+
+var datePickerInput = $("input.date");
+
+datePickerInput.pickadate();
+
+datePickerInput.pickadate({
+ monthsFull: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
+ monthsShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
+ weekdaysFull: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
+ weekdaysShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
+ showMonthsShort: true,
+ showWeekdaysFull: true,
+
+ today: 'Today',
+ clear: 'Clear',
+ close: 'Close',
+
+ labelMonthNext: 'Next month',
+ labelMonthPrev: 'Previous month',
+ labelMonthSelect: 'Select a month',
+ labelYearSelect: 'Select a year',
+
+ // Formats
+ format: 'd mmmm, yyyy',
+ formatSubmit: 'yyyy-mm-dd',
+ hiddenPrefix: 'foo',
+ hiddenSuffix: '_submit',
+ hiddenName: 'bar',
+
+ // Editable input
+ editable: true,
+
+ // Dropdown selectors
+ selectYears: true,
+ selectMonths: 10,
+
+ // First day of the week
+ firstDay: 0,
+
+ // Date limits
+ min: new Date(2013, 3, 20),
+ max: [2013, 7, 14],
+
+ // Disable dates
+ disable: [ new Date(2013, 3, 21) ],
+
+ // Root container
+ container: '.root-container',
+
+ // Events
+ onStart: () => { },
+ onRender: () => { },
+ onOpen: () => { },
+ onClose: () => { },
+ onSet: (context: {[key: string]: any}) => { },
+ onStop: () => { }
+});
+
+datePickerInput.pickadate({
+ klass: {
+ // The element states
+ input: 'picker__input',
+ active: 'picker__input--active',
+
+ // The root picker and states *
+ picker: 'picker',
+ opened: 'picker--opened',
+ focused: 'picker--focused',
+
+ // The picker holder
+ holder: 'picker__holder',
+
+ // The picker frame, wrapper, and box
+ frame: 'picker__frame',
+ wrap: 'picker__wrap',
+ box: 'picker__box',
+
+ // The picker header
+ header: 'picker__header',
+
+ // Month navigation
+ navPrev: 'picker__nav--prev',
+ navNext: 'picker__nav--next',
+ navDisabled: 'picker__nav--disabled',
+
+ // Month & year labels
+ month: 'picker__month',
+ year: 'picker__year',
+
+ // Month & year dropdowns
+ selectMonth: 'picker__select--month',
+ selectYear: 'picker__select--year',
+
+ // Table of dates
+ table: 'picker__table',
+
+ // Weekday labels
+ weekdays: 'picker__weekday',
+
+ // Day states
+ day: 'picker__day',
+ disabled: 'picker__day--disabled',
+ selected: 'picker__day--selected',
+ highlighted: 'picker__day--highlighted',
+ now: 'picker__day--today',
+ infocus: 'picker__day--infocus',
+ outfocus: 'picker__day--outfocus',
+
+ // The picker footer
+ footer: 'picker__footer',
+
+ // Today, clear, & close buttons
+ buttonClear: 'picker__button--clear',
+ buttonClose: 'picker__button--close',
+ buttonToday: 'picker__button--today'
+ }
+});
+
+var datePickerApi = datePickerInput.pickadate('picker');
+
+datePickerInput.pickadate('open');
+datePickerInput.pickadate('get', 'value');
+
+testApiMethods(datePickerApi);
+
+// ====================================================================================================================
+
+var timePickerInput = $("input.time");
+
+timePickerInput.pickatime();
+
+timePickerInput.pickatime({
+ // Translations and clear button
+ clear: 'Clear',
+
+ // Formats
+ format: 'h:i A',
+ formatLabel: 'h:i a!i>',
+ formatSubmit: 'HH:i',
+ hiddenPrefix: 'prefix__',
+ hiddenSuffix: '__suffix',
+
+ // Editable input
+ editable: true,
+
+ // Time intervals
+ interval: 30,
+
+ // Time limits
+ min: new Date(2013, 3, 20, 7),
+ max: [7, 14],
+
+ // Disable times
+ disable: [ new Date(2013, 3, 21, 7) ],
+
+ // Root container
+ container: '.root-container',
+
+ // Events
+ onStart: () => { },
+ onRender: () => { },
+ onOpen: () => { },
+ onClose: () => { },
+ onSet: (context: {[key: string]: any}) => { },
+ onStop: () => { }
+});
+
+timePickerInput.pickatime({
+ klass: {
+ // The element states
+ input: 'picker__input',
+ active: 'picker__input--active',
+
+ // The root picker and states *
+ picker: 'picker picker--time',
+ opened: 'picker--opened',
+ focused: 'picker--focused',
+
+ // The picker holder
+ holder: 'picker__holder',
+
+ // The picker frame, wrapper, and box
+ frame: 'picker__frame',
+ wrap: 'picker__wrap',
+ box: 'picker__box',
+
+ // List of times
+ list: 'picker__list',
+ listItem: 'picker__list-item',
+
+ // Time states
+ disabled: 'picker__list-item--disabled',
+ selected: 'picker__list-item--selected',
+ highlighted: 'picker__list-item--highlighted',
+ viewset: 'picker__list-item--viewset',
+ now: 'picker__list-item--now',
+
+ // Clear button
+ buttonClear: 'picker__button--clear'
+ }
+});
+
+var timePickerApi = timePickerInput.pickatime('picker');
+
+timePickerInput.pickatime('open');
+timePickerInput.pickatime('get', 'value');
+
+testApiMethods(timePickerApi);
+
diff --git a/pickadate/pickadate.d.ts b/pickadate/pickadate.d.ts
new file mode 100644
index 0000000000..d21550d000
--- /dev/null
+++ b/pickadate/pickadate.d.ts
@@ -0,0 +1,317 @@
+// Type definitions for pickadate.js 3.5.4
+// Project: https://github.com/amsul/pickadate.js
+// Definitions by: Adi Dahiya
+// Definitions: https://github.com/borisyankov/DefinitelyTyped
+
+declare module Pickadate {
+
+ export interface Api {
+ /**
+ * Clear the value in the picker's input element.
+ */
+ clear(): Pickadate.Api;
+
+ /**
+ * Close the picker.
+ *
+ * @param keepFocus whether to retain focus on the input element (default: false)
+ */
+ close(keepFocus?: boolean): Pickadate.Api;
+
+ /**
+ * Get the properties, objects, and states of the picker.
+ *
+ * @param field one of [ "value", "select", "highlight", "view", "min", "max", "open", "start", "id", "disable", "enable" ]
+ * @param format string formatter (available for certain fields)
+ */
+ get(field: string, format?: string): any;
+
+ /**
+ * Unbind callbacks that are bound using the `on` method.
+ * @param methodName one of [ "open, "close", "render", "start", "stop", "set" ]
+ */
+ off(methodName: string, ...moreMethodNames: string[]): Pickadate.Api;
+
+ /**
+ * Attach an event handler for the picker. Only "set" events callbacks receive a "context" object.
+ *
+ * @param methodName event to attach handler to, one of [ "open", "close", "render", "start", "stop", or "set" ]
+ * @param callback event handler
+ */
+ on(methodName: string, callback: (context?: any) => void): Pickadate.Api;
+
+ /**
+ * Open the picker.
+ *
+ * @param keepFocus whether to focus the input element (default: true)
+ */
+ open(keepFocus?: boolean): Pickadate.Api;
+
+ /**
+ * Refresh the picker after adding something to the holder.
+ * By default, only the “face” of the picker (i.e. the box element), has its contents re-rendered.
+ *
+ * @param fromRoot whether to render the entire picker from the root up (default: false)
+ */
+ render(fromRoot?: boolean): Pickadate.Api;
+
+ /**
+ * Set the properties, objects, and states of the picker.
+ *
+ * @param field one of [ "clear", "select", "highlight", "view", "min", "max", "disable", "enable", "interval" ]
+ * @param value the thing you want to set
+ */
+ set(field: string, value: any, options?: {[key: string]: any}): Pickadate.Api;
+ /**
+ * Batch set picker options after initialization.
+ */
+ set(values: {[field: string]: any}, options?: {[key: string]: any}): Pickadate.Api;
+
+ /**
+ * Rebuild the picker.
+ */
+ start(): Pickadate.Api;
+
+ /**
+ * Destroy the picker.
+ */
+ stop(): Pickadate.Api;
+
+ /**
+ * Trigger a picker event.
+ * @param eventName the event to trigger
+ */
+ trigger(eventName: string): Pickadate.Api;
+
+ /**
+ * The picker's relative element.
+ */
+ $node: JQuery;
+
+ /**
+ * The picker's relative root holder element.
+ */
+ $root: JQuery;
+
+ /**
+ * The picker's relative hidden element, which is undefined if there's no formatSubmit option.
+ * This is meant to be mostly for internal use.
+ */
+ _hidden: JQuery;
+ }
+
+ export interface DateOptions {
+ // String and translations
+ monthsFull?: string[];
+ monthsShort?: string[];
+ weekdaysFull?: string[];
+ weekdaysShort?: string[]
+ showMonthsShort?: boolean;
+ showWeekdaysFull?: boolean;
+
+ // Button labels (if falsy, the corresponding button is disabled)
+ today?: string;
+ clear?: string;
+ close?: string;
+
+ // Accessibility labels
+ labelMonthNext?: string;
+ labelMonthPrev?: string;
+ labelMonthSelect?: string;
+ labelYearSelect?: string;
+
+ // Formats
+ format?: string;
+ formatSubmit?: string;
+ hiddenPrefix?: string;
+ hiddenSuffix?: string;
+ hiddenName?: string;
+
+ // Editable input
+ editable?: boolean;
+
+ // Number of months to show in the month selection dropdown OR a boolean
+ selectMonths?: any;
+ // Number of years to show in the month selection dropdown OR a boolean
+ selectYears?: any;
+
+ // First day of the week
+ firstDay?: number
+
+ // Disable dates (elements can be Dates, [YEAR, MONTH, DATE] arrays, or integers of the week)
+ disable?: any[];
+
+ // Root container selector
+ container?: string
+
+ // Events
+ onStart?: () => void;
+ onRender?: () => void;
+ onOpen?: () => void;
+ onClose?: () => void;
+ onSet?: (context: {[key: string]: any}) => void;
+ onStop?: () => void;
+
+ // Classes
+ klass?: DateKlassOptions;
+ }
+
+ export interface DateKlassOptions {
+ // The element states
+ input?: string;
+ active?: string;
+
+ // The root picker and states
+ picker?: string;
+ opened?: string;
+ focused?: string;
+
+ // The picker holder
+ holder?: string;
+
+ // The picker frame, wrapper, and box
+ frame?: string;
+ wrap?: string;
+ box?: string;
+
+ // The picker header
+ header?: string;
+
+ // Month navigation
+ navPrev?: string;
+ navNext?: string;
+ navDisabled?: string;
+
+ // Month & year labels
+ month?: string;
+ year?: string;
+
+ // Month & year dropdowns
+ selectMonth?: string;
+ selectYear?: string;
+
+ // Table of dates
+ table?: string;
+
+ // Weekday labels
+ weekdays?: string;
+
+ // Day states
+ day?: string;
+ disabled?: string;
+ selected?: string;
+ highlighted?: string;
+ now?: string;
+ infocus?: string;
+ outfocus?: string;
+
+ // The picker footer
+ footer?: string;
+
+ // Today, clear, & close buttons
+ buttonClear?: string;
+ buttonClose?: string;
+ buttonToday?: string
+ }
+
+ export interface TimeOptions {
+ // Translations and clear button
+ clear?: string;
+
+ // Formats
+ format?: string;
+ formatLabel?: string;
+ formatSubmit?: string;
+ hiddenPrefix?: string;
+ hiddenSuffix?: string;
+
+ // Editable input
+ editable?: boolean;
+
+ // Time intervals
+ interval?: number;
+
+ // Time limits (can be Dates, arrays formatted as [HOUR, MINUTE], integers, or booleans)
+ min?: any;
+ max?: any;
+
+ // Disable dates (elements can be Dates, [YEAR, MONTH, DATE] arrays, or integers of the week)
+ disable?: any[];
+
+ // Root container selector
+ container?: string
+
+ // Events
+ onStart?: () => void;
+ onRender?: () => void;
+ onOpen?: () => void;
+ onClose?: () => void;
+ onSet?: (context: {[key: string]: any}) => void;
+ onStop?: () => void;
+
+ // Classes
+ klass?: TimeKlassOptions;
+ }
+
+ export interface TimeKlassOptions {
+ // The element states
+ input?: string;
+ active?: string;
+
+ // The root picker and states
+ picker?: string;
+ opened?: string;
+ focused?: string;
+
+ // The picker holder
+ holder?: string;
+
+ // The picker frame, wrapper, and box
+ frame?: string;
+ wrap?: string;
+ box?: string;
+
+ // List of times
+ list?: string;
+ listItem?: string;
+
+ // Time states
+ disabled?: string;
+ selected?: string;
+ highlighted?: string;
+ viewset?: string;
+ now?: string;
+
+ // Clear button
+ buttonClear?: string;
+ }
+}
+
+interface JQuery {
+ /**
+ * Initialize a date picker.
+ */
+ pickadate(options?: Pickadate.DateOptions): any;
+
+ /**
+ * Access objects attached to the picker or invoke API methods after initialization.
+ * If keyword is "picker", this returns a PickadateApi.
+ * @param keyword "picker", an object name, or method name
+ * @param arguments any arguments to pass to the method
+ */
+ pickadate(keyword: string, ...arguments: any[]): any;
+
+ /**
+ * Initialize a time picker.
+ */
+ pickatime(options?: Pickadate.TimeOptions): any;
+
+ /**
+ * Access objects attached to the picker or invoke API methods after initialization.
+ * If keyword is "picker", this returns a PickadateApi.
+ * @param keyword "picker", an object name, or method name
+ * @param arguments any arguments to pass to the method
+ */
+ pickatime(keyword: string, ...arguments: any[]): any;
+}
+