@yuafox/easepick2-core 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE.md ADDED
@@ -0,0 +1,5 @@
1
+ # Software License Agreement
2
+
3
+ Licensed under the terms of [GNU General Public License Version 2 or later](http://www.gnu.org/licenses/gpl.html).
4
+
5
+ Copyright © 2021-2022, [Rinat G.](https://github.com/wakirin)
package/README.md ADDED
@@ -0,0 +1,126 @@
1
+ # @easepick/core
2
+
3
+ [![npm version](https://badge.fury.io/js/@easepick%2Fcore.svg)](https://www.npmjs.com/package/@easepick/core)
4
+
5
+ > This package does not need to be installed if you are using [@easepick/bundle](https://easepick.com/packages/bundle).
6
+
7
+ Main package of easepick.
8
+
9
+ ## Documentation
10
+
11
+ [https://easepick.com/packages/core](https://easepick.com/packages/core)
12
+
13
+ ## Options
14
+
15
+ | Name | Type | Default | Description
16
+ | --- | :---: | :---: | ---
17
+ | element | HTMLElement <br/> string | null | Bind the datepicker to a element. Also is possible to bind to any element (not input) for example you need inline calendar.
18
+ | doc | Document <br/> ShadowRoot | document | May be required if you need to pass ShadowRoot.
19
+ | css | string <br/> array <br/> function | [] | Pass a CSS file for picker. Don't mix types, if you are using css link then array should only contain links.
20
+ | firstDay | number | 1 | Day of start week. (0 - Sunday, 1 - Monday, 2 - Tuesday, etc…)
21
+ | lang | string | en-US | Language. <br/>This option affect to day names, month names via [Date.prototype.toLocaleString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleString) and also affect to plural rules via [Intl.PluralRules](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/PluralRules).
22
+ | date | Date <br/> string <br/> number | null | Preselect date. <br/> Date Object or Unix Timestamp (with milliseconds) or String (must be equal to option format).
23
+ | format | string | YYYY-MM-DD | The default output format. <br/> See [tokens format](https://easepick.com/packages/datetime#tokens-format).
24
+ | grid | number | 1 | Number of calendar columns.
25
+ | calendars | number | 1 | Number of visible months.
26
+ | readonly | boolean | true | Add `readonly` attribute to `element`.
27
+ | autoApply | boolean | true | Hide the apply and cancel buttons, and automatically apply a new date range as soon as two dates are clicked.
28
+ | zIndex | number | null | zIndex of picker.
29
+ | inline | boolean | false | Show calendar inline.
30
+ | scrollToDate | boolean | true | Scroll to the selected date on open.
31
+ | header | boolean <br/> string <br/> HTMLElement | false | Add header to calendar.
32
+ | locale| object | { <br/>nextMonth: '<svg width="11" height="16" xmlns="http://www.w3.org/2000/svg"><path d="M2.748 16L0 13.333 5.333 8 0 2.667 2.748 0l7.919 8z" fill-rule="nonzero"/></svg>', <br/> previousMonth: '<svg width="11" height="16" xmlns="http://www.w3.org/2000/svg"><path d="M7.919 0l2.748 2.667L5.333 8l5.334 5.333L7.919 16 0 8z" fill-rule="nonzero"/></svg>', <br/> cancel: 'Cancel', <br/>apply: 'Apply'<br/>} | Icon and text for buttons.
33
+ | documentClick | boolean <br/> function | function | Hide picker on click outside picker element.
34
+ | setup | function | null |
35
+ | plugins | array | [] | List of plugins.
36
+
37
+ ## Methods
38
+
39
+ | Name | Description
40
+ | --- | ---
41
+ | version | return version of picker.
42
+ | isShown() | Determine if the picker is visible or not.
43
+ | show() | Show the picker.
44
+ | hide() | Hide the picker.
45
+ | clear() | Clear the picker selection.
46
+ | gotoDate(date) | Change visible month.
47
+ | setDate(date) | Set date programmatically.
48
+ | getDate() | Get selected date.
49
+ | on(type, listener, options) | Add listener to container element.
50
+ | off(type, listener, options) | Remove listener from container element.
51
+ | trigger(type, detail) | Dispatch an event.
52
+ | renderAll() | Redraw the calendar layout.
53
+ | destroy() | Destroy the picker.
54
+
55
+
56
+ #### Example
57
+ ```js
58
+ const picker = new easepick.create({
59
+ element: document.getElementById('datepicker'),
60
+ css: [
61
+ 'https://cdn.jsdelivr.net/npm/@easepick/core@[version.number]/dist/index.css',
62
+ ],
63
+ });
64
+ //
65
+ picker.setDate('2022-01-01');
66
+ ```
67
+
68
+ ## Events
69
+
70
+ Events based on [CustomEvent()](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent).
71
+
72
+ | Name | Description
73
+ | --- | ---
74
+ | render |
75
+ | view |
76
+ | preselect | Event is called on select days (before submit selection). When `autoApply` option is `false`.
77
+ | select | Event is called when selection is submitted.
78
+
79
+ It is also allowed to use default events such as `click`, `keydown`, etc.
80
+
81
+ #### Example
82
+ ```js
83
+ const picker = new easepick.create({
84
+ element: document.getElementById('datepicker'),
85
+ css: [
86
+ 'https://cdn.jsdelivr.net/npm/@easepick/core@[version.number]/dist/index.css',
87
+ ],
88
+ setup(picker) {
89
+ picker.on('view', (e) => {
90
+ const { view, date, target } = e.detail;
91
+ // do something
92
+ });
93
+ },
94
+ });
95
+ ```
96
+
97
+ ## PluginManager
98
+
99
+ `PluginManager` allows you to manage plugins of created picker.
100
+
101
+
102
+ #### Methods
103
+
104
+ | Name | Description
105
+ | --- | ---
106
+ | [getInstance(pluginName)](#pluginManager-getInstance) | Returns the plugin instance. `pluginName` is a string (eg.: `RangePlugin`).
107
+ | [addInstance(pluginName)](#pluginManager-addInstance) | Adds a plugin to the picker. Returns an instance of the added plugin.
108
+ | [removeInstance(pluginName)](#pluginManager-removeInstance) | Removes the plugin from the picker.Returns a boolean result.
109
+ | [reloadInstance(pluginName)](#pluginManager-reloadInstance) | Removes the plugin from the picker and adds it again. Returns an instance of the added plugin.
110
+
111
+ #### Example
112
+
113
+ ```js
114
+ // example use bundle version
115
+ const picker = new easepick.create({
116
+ element: document.getElementById('datepicker'),
117
+ css: [
118
+ 'https://cdn.jsdelivr.net/npm/@easepick/core@[version.number]/dist/index.css',
119
+ ],
120
+ });
121
+
122
+ // add AmpPlugin to the picker
123
+ const ampPlugin = picker.PluginManager.addInstance('AmpPlugin');
124
+ // change plugin option
125
+ ampPlugin.options.resetButton = true;
126
+ ```
@@ -0,0 +1,97 @@
1
+ import { Core } from './core';
2
+ import { DateTime } from '@yuafox/easepick2-datetime';
3
+ export default class Calendar {
4
+ picker: Core;
5
+ constructor(picker: Core);
6
+ /**
7
+ * Render transferred date and view
8
+ *
9
+ * @param date
10
+ * @param view
11
+ */
12
+ render(date: DateTime, view: string): void;
13
+ /**
14
+ * Function for `Container` view
15
+ *
16
+ * @param date
17
+ */
18
+ getContainerView(date: DateTime): void;
19
+ /**
20
+ * Function for `Header` view
21
+ *
22
+ * @param date
23
+ */
24
+ getHeaderView(date: DateTime): void;
25
+ /**
26
+ * Function for `Main` view
27
+ *
28
+ * @param date
29
+ */
30
+ getMainView(date: DateTime): void;
31
+ /**
32
+ * Function for `Footer` view
33
+ *
34
+ * @param date
35
+ */
36
+ getFooterView(date: DateTime): void;
37
+ /**
38
+ * Function for `CalendarHeader` view
39
+ *
40
+ * @param date
41
+ * @returns HTMLElement
42
+ */
43
+ getCalendarHeaderView(date: DateTime): HTMLElement;
44
+ /**
45
+ * Function for `CalendarMonths` view
46
+ * Renders a 4x3 grid of months for the given year
47
+ *
48
+ * @param date
49
+ * @returns HTMLElement
50
+ */
51
+ getCalendarMonthsView(date: DateTime): HTMLElement;
52
+ /**
53
+ * Function for `CalendarYears` view
54
+ * Renders a 4x3 grid of years for the current decade
55
+ *
56
+ * @param date
57
+ * @returns HTMLElement
58
+ */
59
+ getCalendarYearsView(date: DateTime): HTMLElement;
60
+ /**
61
+ * Function for `CalendarDayNames` view
62
+ *
63
+ * @param date
64
+ * @returns HTMLElement
65
+ */
66
+ getCalendarDayNamesView(): HTMLElement;
67
+ /**
68
+ * Function for `CalendarDays` view
69
+ *
70
+ * @param date
71
+ * @returns HTMLElement
72
+ */
73
+ getCalendarDaysView(date: DateTime): HTMLElement;
74
+ /**
75
+ * Function for `CalendarDay` view
76
+ *
77
+ * @param date
78
+ * @returns HTMLElement
79
+ */
80
+ getCalendarDayView(date: DateTime): HTMLElement;
81
+ /**
82
+ * Function for `CalendarFooter` view
83
+ *
84
+ * @param lang
85
+ * @param date
86
+ * @returns HTMLElement
87
+ */
88
+ getCalendarFooterView(lang: string, date: DateTime): HTMLElement;
89
+ /**
90
+ * Count the number of days of indentation
91
+ *
92
+ * @param date
93
+ * @param firstDay
94
+ * @returns Number
95
+ */
96
+ calcOffsetDays(date: DateTime, firstDay: number): number;
97
+ }
package/dist/core.d.ts ADDED
@@ -0,0 +1,209 @@
1
+ import Calendar from './calendar';
2
+ import { DateTime } from '@yuafox/easepick2-datetime';
3
+ import PluginManager from './pluginManager';
4
+ import { IPickerConfig, IPickerElements } from './types';
5
+ export declare class Core {
6
+ Calendar: Calendar;
7
+ PluginManager: PluginManager;
8
+ calendars: DateTime[];
9
+ datePicked: DateTime[];
10
+ cssLoaded: number;
11
+ binds: {
12
+ hidePicker: any;
13
+ show: any;
14
+ };
15
+ options: IPickerConfig;
16
+ ui: IPickerElements;
17
+ version: string;
18
+ constructor(options: IPickerConfig);
19
+ /**
20
+ * Add listener to container element
21
+ *
22
+ * @param type
23
+ * @param listener
24
+ * @param options
25
+ */
26
+ on(type: string, listener: (event: any) => void, options?: unknown): void;
27
+ /**
28
+ * Remove listener from container element
29
+ *
30
+ * @param type
31
+ * @param listener
32
+ * @param options
33
+ */
34
+ off(type: string, listener: (event: any) => void, options?: unknown): void;
35
+ /**
36
+ * Dispatch an event
37
+ *
38
+ * @param type
39
+ * @param detail
40
+ * @returns
41
+ */
42
+ trigger(type: string, detail?: unknown): boolean;
43
+ /**
44
+ * Destroy picker
45
+ */
46
+ destroy(): void;
47
+ /**
48
+ * Fired on render event
49
+ *
50
+ * @param event
51
+ */
52
+ onRender(event: CustomEvent): void;
53
+ onView(event: CustomEvent): void;
54
+ /**
55
+ *
56
+ * @param element
57
+ */
58
+ onClickHeaderButton(element: HTMLElement): void;
59
+ /**
60
+ *
61
+ * @param element
62
+ */
63
+ onClickCalendarDay(element: HTMLElement): void;
64
+ /**
65
+ * Handle click on a month element (viewMode: 'month')
66
+ *
67
+ * @param element
68
+ */
69
+ onClickCalendarMonth(element: HTMLElement): void;
70
+ /**
71
+ * Handle click on a year element (viewMode: 'year')
72
+ *
73
+ * @param element
74
+ */
75
+ onClickCalendarYear(element: HTMLElement): void;
76
+ /**
77
+ *
78
+ * @param element
79
+ */
80
+ onClickApplyButton(element: HTMLElement): void;
81
+ /**
82
+ *
83
+ * @param element
84
+ * @returns
85
+ */
86
+ onClickCancelButton(element: HTMLElement): void;
87
+ /**
88
+ * Fired on click event
89
+ *
90
+ * @param event
91
+ */
92
+ onClick(event: any): void;
93
+ /**
94
+ * Determine if the picker is visible or not
95
+ *
96
+ * @returns Boolean
97
+ */
98
+ isShown(): boolean;
99
+ /**
100
+ * Show the picker
101
+ *
102
+ * @param event
103
+ */
104
+ show(event?: any): void;
105
+ /**
106
+ * Hide the picker
107
+ */
108
+ hide(): void;
109
+ /**
110
+ * Set date programmatically
111
+ *
112
+ * @param date
113
+ */
114
+ setDate(date: Date | string | number): void;
115
+ /**
116
+ *
117
+ * @returns DateTime
118
+ */
119
+ getDate(): DateTime;
120
+ /**
121
+ * Parse `date` option or value of input element
122
+ */
123
+ parseValues(): void;
124
+ /**
125
+ * Update value of input element
126
+ */
127
+ updateValues(): void;
128
+ /**
129
+ * Function for documentClick option
130
+ * Allows the picker to close when the user clicks outside
131
+ *
132
+ * @param e
133
+ */
134
+ hidePicker(e: any): void;
135
+ /**
136
+ * Render entire picker layout
137
+ *
138
+ * @param date
139
+ */
140
+ renderAll(date?: DateTime): void;
141
+ /**
142
+ * Determines if the element is buttons of header (previous month, next month)
143
+ *
144
+ * @param element
145
+ * @returns Boolean
146
+ */
147
+ isCalendarHeaderButton(element: HTMLElement): boolean;
148
+ /**
149
+ * Determines if the element is day element
150
+ *
151
+ * @param element
152
+ * @returns Boolean
153
+ */
154
+ isCalendarDay(element: HTMLElement): boolean;
155
+ /**
156
+ * Determines if the element is a month element
157
+ *
158
+ * @param element
159
+ * @returns Boolean
160
+ */
161
+ isCalendarMonth(element: HTMLElement): boolean;
162
+ /**
163
+ * Determines if the element is a year element
164
+ *
165
+ * @param element
166
+ * @returns Boolean
167
+ */
168
+ isCalendarYear(element: HTMLElement): boolean;
169
+ /**
170
+ * Determines if the element is the apply button
171
+ *
172
+ * @param element
173
+ * @returns Boolean
174
+ */
175
+ isApplyButton(element: HTMLElement): boolean;
176
+ /**
177
+ * Determines if the element is the cancel button
178
+ *
179
+ * @param element
180
+ * @returns Boolean
181
+ */
182
+ isCancelButton(element: HTMLElement): boolean;
183
+ /**
184
+ * Change visible month
185
+ *
186
+ * @param date
187
+ */
188
+ gotoDate(date: Date | string | number): void;
189
+ /**
190
+ * Clear date selection
191
+ */
192
+ clear(): void;
193
+ /**
194
+ * Handling parameters passed by the user
195
+ */
196
+ private handleOptions;
197
+ /**
198
+ * Apply CSS passed by the user
199
+ */
200
+ private handleCSS;
201
+ /**
202
+ * Calculate the position of the picker
203
+ *
204
+ * @param element
205
+ * @returns { top, left }
206
+ */
207
+ private adjustPosition;
208
+ }
209
+ export { Core as create, };
package/dist/index.css ADDED
@@ -0,0 +1 @@
1
+ :host{--color-bg-default:#fff;--color-bg-secondary:#f9f9f9;--color-fg-default:#333;--color-fg-primary:#6b82ff;--color-fg-secondary:#748194;--color-fg-selected:#fff;--color-fg-muted:#9e9e9e;--color-fg-accent:#e63757;--color-btn-primary-bg:#fff;--color-btn-primary-fg:#6b82ff;--color-btn-primary-border:#6b82ff;--color-btn-primary-hover-bg:#6b82ff;--color-btn-primary-hover-fg:#fff;--color-btn-primary-hover-border:#6b82ff;--color-btn-primary-disabled-bg:#a2b0ff;--color-btn-primary-disabled-fg:#fff;--color-btn-primary-disabled-border:#a2b0ff;--color-btn-secondary-bg:#fff;--color-btn-secondary-fg:#748194;--color-btn-secondary-border:#748194;--color-btn-secondary-hover-bg:#748194;--color-btn-secondary-hover-fg:#fff;--color-btn-secondary-hover-border:#748194;--color-btn-secondary-disabled-bg:#b5bbc4;--color-btn-secondary-disabled-fg:#fff;--color-btn-secondary-disabled-border:#b5bbc4;--color-border-default:#ddd;--color-border-locked:#f9f9f9;--day-width:42px;--day-height:37px;--border-radius:2px;--primary-color:#6b82ff;--secondary-color:#748194;--white-color:#fff;--black-color:#333;--lightgray-color:#f9f9f9;--gray-color:#9e9e9e;--red-color:#e63757}*{box-sizing:border-box}.container{border-radius:4px;color:var(--color-fg-default);cursor:default;display:inline-block;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-size:.8em;height:0;overflow:hidden;pointer-events:all;position:absolute;transform:scale(0);transform-origin:top left;transition:transform .3s ease-out}.container.calc{height:auto;transform:none;transition:none;visibility:hidden}.container.show{box-shadow:0 0 25px rgba(0,0,0,.3);height:auto;transform:scale(1)}.container.inline{box-shadow:0 7px 14px 0 rgba(65,69,88,.1),0 3px 6px 0 rgba(0,0,0,.07);height:auto;left:0;position:relative;top:0;transform:scaleY(1)}.container>main{background-color:var(--color-bg-default)}.container>footer,.container>header{background-color:var(--color-bg-secondary);padding:10px}.container>footer .footer-buttons{-moz-column-gap:5px;column-gap:5px;display:flex;justify-content:flex-end}.container>footer .footer-buttons>button{background-color:transparent;border:1px solid transparent;border-radius:var(--border-radius);cursor:pointer;padding:5px 10px}.container>footer .footer-buttons>button.apply-button{background-color:var(--color-btn-primary-bg);border-color:var(--color-btn-primary-border);color:var(--color-btn-primary-fg)}.container>footer .footer-buttons>button.apply-button:hover{background-color:var(--color-btn-primary-hover-bg);border-color:var(--color-btn-primary-hover-border);color:var(--color-btn-primary-hover-fg)}.container>footer .footer-buttons>button.apply-button:disabled{background-color:var(--color-btn-primary-disabled-bg);border-color:var(--color-btn-primary-disabled-border);color:var(--color-btn-primary-disabled-fg);cursor:default}.container>footer .footer-buttons>button.cancel-button{background-color:var(--color-btn-secondary-bg);border-color:var(--color-btn-secondary-border);color:var(--color-btn-secondary-fg)}.container>footer .footer-buttons>button.cancel-button:hover{background-color:var(--color-btn-secondary-hover-bg);border-color:var(--color-btn-secondary-hover-border);color:var(--color-btn-secondary-hover-fg)}.container>footer .footer-buttons>button.cancel-button:disabled{background-color:var(--color-btn-secondary-disabled-bg);border-color:var(--color-btn-secondary-disabled-border);color:var(--color-btn-secondary-disabled-fg);cursor:default}.grid-1{grid-template-columns:repeat(1,1fr)}.grid-2{grid-template-columns:repeat(2,1fr)}.grid-3{grid-template-columns:repeat(3,1fr)}.grid-4{grid-template-columns:repeat(4,1fr)}.grid-5{grid-template-columns:repeat(5,1fr)}.grid-6{grid-template-columns:repeat(6,1fr)}.grid-7{grid-template-columns:repeat(7,1fr)}.grid-8{grid-template-columns:repeat(8,1fr)}.grid-9{grid-template-columns:repeat(9,1fr)}.grid-10{grid-template-columns:repeat(10,1fr)}.grid-11{grid-template-columns:repeat(11,1fr)}.grid-12{grid-template-columns:repeat(12,1fr)}.calendars{display:grid}.calendars:not(.grid-1) .calendar>.header .month-name{order:2;text-align:center}.calendars:not(.grid-1) .calendar>.header .previous-button{order:1;visibility:hidden}.calendars:not(.grid-1) .calendar>.header .next-button{order:3;visibility:hidden}.calendars:not(.grid-1) .calendar:first-child>.header .previous-button,.calendars:not(.grid-1) .calendar:last-child>.header .next-button{visibility:visible}.calendar{padding:10px}.calendar>.header{align-items:center;-moz-column-gap:5px;column-gap:5px;display:flex;justify-content:space-between;padding:10px}.calendar>.header .month-name{flex:1;font-size:15px;font-weight:500}.calendar>.header .month-name>span{font-weight:700}.calendar>.header button{align-items:center;background-color:transparent;border:1px solid transparent;border-radius:2px;color:var(--color-btn-secondary-fg);cursor:pointer;display:flex;justify-content:center;padding:4px 7px}.calendar>.header button:hover{background-color:var(--color-bg-secondary)}.calendar>.header button:hover>img,.calendar>.header button:hover>svg{fill:var(--color-fg-primary);color:var(--color-fg-primary)}.calendar>.header button>img,.calendar>.header button>svg{fill:var(--color-btn-secondary-fg);color:var(--color-btn-secondary-fg);pointer-events:none;transform:scale(.7)}.calendar>.daynames-row,.calendar>.days-grid{display:grid;grid-template-columns:repeat(7,1fr);row-gap:2px}.calendar>.daynames-row>.day,.calendar>.daynames-row>.dayname,.calendar>.days-grid>.day,.calendar>.days-grid>.dayname{align-items:center;cursor:default;display:flex;flex-direction:column;font-size:13px;justify-content:center}.calendar>.daynames-row>.dayname{color:var(--color-fg-muted);font-size:12px;padding:5px 0}.calendar>.days-grid>.day{border:1px solid transparent;border-radius:2px;height:var(--day-height);max-height:var(--day-height);max-width:var(--day-width);min-height:var(--day-height);min-width:var(--day-width);padding:10px 0;width:var(--day-width)}.calendar>.days-grid>.day:hover{border:1px solid var(--color-fg-primary);color:var(--color-fg-primary)}.calendar>.days-grid>.day.today{color:var(--color-fg-accent)}.calendar>.days-grid>.day.selected{background-color:var(--color-fg-primary);color:var(--color-fg-selected)}.calendar>.months-grid,.calendar>.years-grid{-moz-column-gap:2px;column-gap:2px;display:grid;grid-template-columns:repeat(4,1fr);row-gap:2px}.calendar>.months-grid>.month,.calendar>.months-grid>.year,.calendar>.years-grid>.month,.calendar>.years-grid>.year{align-items:center;border:1px solid transparent;border-radius:2px;cursor:default;display:flex;font-size:13px;justify-content:center;padding:12px 8px}.calendar>.months-grid>.month:hover,.calendar>.months-grid>.year:hover,.calendar>.years-grid>.month:hover,.calendar>.years-grid>.year:hover{border:1px solid var(--color-fg-primary);color:var(--color-fg-primary)}.calendar>.months-grid>.month.today,.calendar>.months-grid>.year.today,.calendar>.years-grid>.month.today,.calendar>.years-grid>.year.today{color:var(--color-fg-accent)}.calendar>.months-grid>.month.selected,.calendar>.months-grid>.year.selected,.calendar>.years-grid>.month.selected,.calendar>.years-grid>.year.selected{background-color:var(--color-fg-primary);color:var(--color-fg-selected)}.calendar>.months-grid>.month.outside,.calendar>.months-grid>.year.outside,.calendar>.years-grid>.month.outside,.calendar>.years-grid>.year.outside{color:var(--color-fg-muted)}.calendar>.years-grid{grid-template-columns:repeat(4,1fr)}@media (max-width:480px){.container:not(.inline){transform:scaleY(0)!important;transform-origin:bottom center!important}.container:not(.inline).show{bottom:0!important;left:0!important;position:fixed!important;right:0!important;top:auto!important;transform:scaleY(1)!important}.container{width:100%}.calendars{grid-template-columns:repeat(1,1fr)}.calendars .calendar{box-sizing:border-box;width:100%}.calendars .calendar:nth-child(n+2){display:none}.calendars .calendar>.days-grid>.day{height:auto;max-height:unset;max-width:unset;min-height:unset;min-width:unset;width:auto}.calendars .calendar>.header:not(.no-next-month) .next-button{visibility:visible}}
@@ -0,0 +1,3 @@
1
+ import './scss/index.scss';
2
+ export { Core, create } from './core';
3
+ export * as easepick from './core';
@@ -0,0 +1 @@
1
+ import{DateTime as e}from"@yuafox/easepick2-datetime";class t{picker;constructor(e){this.picker=e}render(t,i){t||(t=new e),t.setDate(1),t.setHours(0,0,0,0),"function"==typeof this[`get${i}View`]&&this[`get${i}View`](t)}getContainerView(e){this.picker.ui.container.innerHTML="",this.picker.options.header&&this.picker.trigger("render",{date:e.clone(),view:"Header"}),this.picker.trigger("render",{date:e.clone(),view:"Main"}),this.picker.options.autoApply||this.picker.trigger("render",{date:e.clone(),view:"Footer"})}getHeaderView(e){const t=document.createElement("header");this.picker.options.header instanceof HTMLElement&&t.appendChild(this.picker.options.header),"string"==typeof this.picker.options.header&&(t.innerHTML=this.picker.options.header),this.picker.ui.container.appendChild(t),this.picker.trigger("view",{target:t,date:e.clone(),view:"Header"})}getMainView(e){const t=document.createElement("main");this.picker.ui.container.appendChild(t);const i=this.picker.options.viewMode||"day",n=document.createElement("div");if(n.className=`calendars grid-${this.picker.options.grid}`,"month"===i){const t=document.createElement("div");t.className="calendar",n.appendChild(t);const i=this.getCalendarHeaderView(e.clone());t.appendChild(i),this.picker.trigger("view",{date:e.clone(),view:"CalendarHeader",index:0,target:i});const s=this.getCalendarMonthsView(e.clone());t.appendChild(s),this.picker.trigger("view",{date:e.clone(),view:"CalendarMonths",index:0,target:s}),this.picker.trigger("view",{date:e.clone(),view:"CalendarItem",index:0,target:t})}else if("year"===i){const t=document.createElement("div");t.className="calendar",n.appendChild(t);const i=this.getCalendarHeaderView(e.clone());t.appendChild(i),this.picker.trigger("view",{date:e.clone(),view:"CalendarHeader",index:0,target:i});const s=this.getCalendarYearsView(e.clone());t.appendChild(s),this.picker.trigger("view",{date:e.clone(),view:"CalendarYears",index:0,target:s}),this.picker.trigger("view",{date:e.clone(),view:"CalendarItem",index:0,target:t})}else for(let t=0;t<this.picker.options.calendars;t++){const i=document.createElement("div");i.className="calendar",n.appendChild(i);const s=this.getCalendarHeaderView(e.clone());i.appendChild(s),this.picker.trigger("view",{date:e.clone(),view:"CalendarHeader",index:t,target:s});const a=this.getCalendarDayNamesView();i.appendChild(a),this.picker.trigger("view",{date:e.clone(),view:"CalendarDayNames",index:t,target:a});const o=this.getCalendarDaysView(e.clone());i.appendChild(o),this.picker.trigger("view",{date:e.clone(),view:"CalendarDays",index:t,target:o});const r=this.getCalendarFooterView(this.picker.options.lang,e.clone());i.appendChild(r),this.picker.trigger("view",{date:e.clone(),view:"CalendarFooter",index:t,target:r}),this.picker.trigger("view",{date:e.clone(),view:"CalendarItem",index:t,target:i}),e.add(1,"month")}t.appendChild(n),this.picker.trigger("view",{date:e.clone(),view:"Calendars",target:n}),this.picker.trigger("view",{date:e.clone(),view:"Main",target:t})}getFooterView(e){const t=document.createElement("footer"),i=document.createElement("div");i.className="footer-buttons";const n=document.createElement("button");n.className="cancel-button unit",n.innerHTML=this.picker.options.locale.cancel,i.appendChild(n);const s=document.createElement("button");s.className="apply-button unit",s.innerHTML=this.picker.options.locale.apply,s.disabled=!0,i.appendChild(s),t.appendChild(i),this.picker.ui.container.appendChild(t),this.picker.trigger("view",{date:e,target:t,view:"Footer"})}getCalendarHeaderView(e){const t=this.picker.options.viewMode||"day",i=document.createElement("div");i.className="header";const n=document.createElement("div");if(n.className="month-name","month"===t)n.innerHTML=`<span>${e.format("YYYY")}</span>`;else if("year"===t){const t=10*Math.floor(e.getFullYear()/10);n.innerHTML=`<span>${t} - ${t+9}</span>`}else n.innerHTML=`<span>${e.toLocaleString(this.picker.options.lang,{month:"long"})}</span> ${e.format("YYYY")}`;i.appendChild(n);const s=document.createElement("button");s.className="previous-button unit",s.innerHTML=this.picker.options.locale.previousMonth,i.appendChild(s);const a=document.createElement("button");return a.className="next-button unit",a.innerHTML=this.picker.options.locale.nextMonth,i.appendChild(a),i}getCalendarMonthsView(t){const i=document.createElement("div");i.className="months-grid";const n=new e;for(let s=0;s<12;s++){const a=new e(new Date(t.getFullYear(),s,1)),o=document.createElement("div");if(o.className="month unit",o.innerHTML=a.toLocaleString(this.picker.options.lang,{month:"short"}),o.dataset.time=String(a.getTime()),a.getFullYear()===n.getFullYear()&&s===n.getMonth()&&o.classList.add("today"),this.picker.datePicked.length)this.picker.datePicked[0].isSame(a,"month")&&o.classList.add("selected");else if(this.picker.options.date){new e(this.picker.options.date).isSame(a,"month")&&o.classList.add("selected")}i.appendChild(o),this.picker.trigger("view",{date:a,view:"CalendarMonth",target:o})}return i}getCalendarYearsView(t){const i=document.createElement("div");i.className="years-grid";const n=new e,s=10*Math.floor(t.getFullYear()/10);for(let t=s;t<s+12;t++){const a=new e(new Date(t,0,1)),o=document.createElement("div");if(o.className="year unit",o.innerHTML=String(t),o.dataset.time=String(a.getTime()),t===n.getFullYear()&&o.classList.add("today"),(t<s||t>s+9)&&o.classList.add("outside"),this.picker.datePicked.length)this.picker.datePicked[0].getFullYear()===t&&o.classList.add("selected");else if(this.picker.options.date){new e(this.picker.options.date).getFullYear()===t&&o.classList.add("selected")}i.appendChild(o),this.picker.trigger("view",{date:a,view:"CalendarYear",target:o})}return i}getCalendarDayNamesView(){const e=document.createElement("div");e.className="daynames-row";for(let t=1;t<=7;t++){const i=3+this.picker.options.firstDay+t,n=document.createElement("div");n.className="dayname",n.innerHTML=new Date(1970,0,i,12,0,0,0).toLocaleString(this.picker.options.lang,{weekday:"short"}),n.title=new Date(1970,0,i,12,0,0,0).toLocaleString(this.picker.options.lang,{weekday:"long"}),e.appendChild(n),this.picker.trigger("view",{dayIdx:i,view:"CalendarDayName",target:n})}return e}getCalendarDaysView(e){const t=document.createElement("div");t.className="days-grid";const i=this.calcOffsetDays(e,this.picker.options.firstDay),n=32-new Date(e.getFullYear(),e.getMonth(),32).getDate();for(let e=0;e<i;e++){const e=document.createElement("div");e.className="offset",t.appendChild(e)}for(let i=1;i<=n;i++){e.setDate(i);const n=this.getCalendarDayView(e);t.appendChild(n),this.picker.trigger("view",{date:e,view:"CalendarDay",target:n})}return t}getCalendarDayView(t){const i=this.picker.options.date?new e(this.picker.options.date):null,n=new e,s=document.createElement("div");return s.className="day unit",s.innerHTML=t.format("D"),s.dataset.time=String(t.getTime()),t.isSame(n,"day")&&s.classList.add("today"),[0,6].includes(t.getDay())&&s.classList.add("weekend"),this.picker.datePicked.length?this.picker.datePicked[0].isSame(t,"day")&&s.classList.add("selected"):i&&t.isSame(i,"day")&&s.classList.add("selected"),this.picker.trigger("view",{date:t,view:"CalendarDay",target:s}),s}getCalendarFooterView(e,t){const i=document.createElement("div");return i.className="footer",i}calcOffsetDays(e,t){let i=e.getDay()-t;return i<0&&(i+=7),i}}class i{picker;instances={};constructor(e){this.picker=e}initialize(){const e=[];this.picker.options.plugins.forEach((t=>{"function"==typeof t?e.push(new t):"string"==typeof t&&"undefined"!=typeof easepick&&Object.prototype.hasOwnProperty.call(easepick,t)?e.push(new easepick[t]):console.warn(`easepick: ${t} not found.`)})),e.sort(((e,t)=>e.priority>t.priority?-1:e.priority<t.priority||e.dependencies.length>t.dependencies.length?1:e.dependencies.length<t.dependencies.length?-1:0)),e.forEach((e=>{e.attach(this.picker),this.instances[e.getName()]=e}))}getInstance(e){return this.instances[e]}addInstance(e){if(Object.prototype.hasOwnProperty.call(this.instances,e))console.warn(`easepick: ${e} already added.`);else{if("undefined"!=typeof easepick&&Object.prototype.hasOwnProperty.call(easepick,e)){const t=new easepick[e];return t.attach(this.picker),this.instances[t.getName()]=t,t}if("undefined"!==this.getPluginFn(e)){const t=new(this.getPluginFn(e));return t.attach(this.picker),this.instances[t.getName()]=t,t}console.warn(`easepick: ${e} not found.`)}return null}removeInstance(e){return e in this.instances&&this.instances[e].detach(),delete this.instances[e]}reloadInstance(e){return this.removeInstance(e),this.addInstance(e)}getPluginFn(e){return[...this.picker.options.plugins].filter((t=>"function"==typeof t&&(new t).getName()===e)).shift()}}class n{Calendar=new t(this);PluginManager=new i(this);calendars=[];datePicked=[];cssLoaded=0;binds={hidePicker:this.hidePicker.bind(this),show:this.show.bind(this)};options={doc:document,css:[],element:null,firstDay:1,grid:1,calendars:1,lang:"en-US",date:null,format:"YYYY-MM-DD",readonly:!0,autoApply:!0,header:!1,inline:!1,viewMode:"day",scrollToDate:!0,locale:{nextMonth:'<svg width="11" height="16" xmlns="http://www.w3.org/2000/svg"><path d="M2.748 16L0 13.333 5.333 8 0 2.667 2.748 0l7.919 8z" fill-rule="nonzero"/></svg>',previousMonth:'<svg width="11" height="16" xmlns="http://www.w3.org/2000/svg"><path d="M7.919 0l2.748 2.667L5.333 8l5.334 5.333L7.919 16 0 8z" fill-rule="nonzero"/></svg>',cancel:"Cancel",apply:"Apply"},documentClick:this.binds.hidePicker,plugins:[]};ui={container:null,shadowRoot:null,wrapper:null};version="2.0.0";constructor(e){const t={...this.options.locale,...e.locale};this.options={...this.options,...e},this.options.locale=t,this.handleOptions(),this.ui.wrapper=document.createElement("span"),this.ui.wrapper.style.display="none",this.ui.wrapper.style.position="absolute",this.ui.wrapper.style.pointerEvents="none",this.ui.wrapper.className="easepick-wrapper",this.ui.wrapper.attachShadow({mode:"open"}),this.ui.shadowRoot=this.ui.wrapper.shadowRoot,this.ui.container=document.createElement("div"),this.ui.container.className="container",this.options.zIndex&&(this.ui.container.style.zIndex=String(this.options.zIndex)),this.options.inline&&(this.ui.wrapper.style.position="relative",this.ui.container.classList.add("inline")),this.ui.shadowRoot.appendChild(this.ui.container),this.options.element.after(this.ui.wrapper),this.handleCSS(),this.options.element.addEventListener("click",this.binds.show),this.on("view",this.onView.bind(this)),this.on("render",this.onRender.bind(this)),this.PluginManager.initialize(),this.parseValues(),"function"==typeof this.options.setup&&this.options.setup(this),this.on("click",this.onClick.bind(this));const i=this.options.scrollToDate?this.getDate():null;this.renderAll(i)}on(e,t,i={}){this.ui.container.addEventListener(e,t,i)}off(e,t,i={}){this.ui.container.removeEventListener(e,t,i)}trigger(e,t={}){return this.ui.container.dispatchEvent(new CustomEvent(e,{detail:t}))}destroy(){this.options.element.removeEventListener("click",this.binds.show),"function"==typeof this.options.documentClick&&document.removeEventListener("click",this.options.documentClick,!0),Object.keys(this.PluginManager.instances).forEach((e=>{this.PluginManager.removeInstance(e)})),this.ui.wrapper.remove()}onRender(e){const{view:t,date:i}=e.detail;this.Calendar.render(i,t)}onView(e){const{view:t,target:i}=e.detail;if("Footer"===t&&this.datePicked.length){i.querySelector(".apply-button").disabled=!1}}onClickHeaderButton(e){if(this.isCalendarHeaderButton(e)){const t=this.options.viewMode||"day",i=e.classList.contains("next-button");"year"===t?i?this.calendars[0].setFullYear(this.calendars[0].getFullYear()+10):this.calendars[0].setFullYear(this.calendars[0].getFullYear()-10):"month"===t?i?this.calendars[0].setFullYear(this.calendars[0].getFullYear()+1):this.calendars[0].setFullYear(this.calendars[0].getFullYear()-1):i?this.calendars[0].add(1,"month"):this.calendars[0].subtract(1,"month"),this.renderAll(this.calendars[0])}}onClickCalendarDay(t){if(this.isCalendarDay(t)){const i=new e(t.dataset.time);this.options.autoApply?(this.setDate(i),this.trigger("select",{date:this.getDate()}),this.hide()):(this.datePicked[0]=i,this.trigger("preselect",{date:this.getDate()}),this.renderAll())}}onClickCalendarMonth(t){if(this.isCalendarMonth(t)){const i=new e(t.dataset.time);this.options.autoApply?(this.setDate(i),this.trigger("select",{date:this.getDate()}),this.hide()):(this.datePicked[0]=i,this.trigger("preselect",{date:this.getDate()}),this.renderAll())}}onClickCalendarYear(t){if(this.isCalendarYear(t)){const i=new e(t.dataset.time);this.options.autoApply?(this.setDate(i),this.trigger("select",{date:this.getDate()}),this.hide()):(this.datePicked[0]=i,this.trigger("preselect",{date:this.getDate()}),this.renderAll())}}onClickApplyButton(e){if(this.isApplyButton(e)){if(this.datePicked[0]instanceof Date){const e=this.datePicked[0].clone();this.setDate(e)}this.hide(),this.trigger("select",{date:this.getDate()})}}onClickCancelButton(e){this.isCancelButton(e)&&this.hide()}onClick(e){const t=e.target;if(t instanceof HTMLElement){const e=t.closest(".unit");if(!(e instanceof HTMLElement))return;this.onClickHeaderButton(e),this.onClickCalendarDay(e),this.onClickCalendarMonth(e),this.onClickCalendarYear(e),this.onClickApplyButton(e),this.onClickCancelButton(e)}}isShown(){return this.ui.container.classList.contains("inline")||this.ui.container.classList.contains("show")}show(e){if(this.isShown())return;const t=e&&"target"in e?e.target:this.options.element,{top:i,left:n}=this.adjustPosition(t);this.ui.container.style.top=`${i}px`,this.ui.container.style.left=`${n}px`,this.ui.container.classList.add("show"),this.trigger("show",{target:t})}hide(){this.ui.container.classList.remove("show"),this.datePicked.length=0,this.renderAll(),this.trigger("hide")}setDate(t){const i=new e(t,this.options.format);this.options.date=i.clone(),this.updateValues(),this.calendars.length&&this.renderAll()}getDate(){return this.options.date instanceof e?this.options.date.clone():null}parseValues(){this.options.date?this.setDate(this.options.date):this.options.element instanceof HTMLInputElement&&this.options.element.value.length&&this.setDate(this.options.element.value),this.options.date instanceof Date||(this.options.date=null)}updateValues(){const e=this.getDate(),t=e instanceof Date?e.format(this.options.format,this.options.lang):"",i=this.options.element;i instanceof HTMLInputElement?i.value=t:i instanceof HTMLElement&&(i.innerText=t)}hidePicker(e){let t=e.target,i=null;t.shadowRoot&&(t=e.composedPath()[0],i=t.getRootNode().host),this.isShown()&&!1===this.options.inline&&i!==this.ui.wrapper&&t!==this.options.element&&this.hide()}renderAll(e){this.trigger("render",{view:"Container",date:(e||this.calendars[0]).clone()})}isCalendarHeaderButton(e){return["previous-button","next-button"].some((t=>e.classList.contains(t)))}isCalendarDay(e){return e.classList.contains("day")}isCalendarMonth(e){return e.classList.contains("month")}isCalendarYear(e){return e.classList.contains("year")}isApplyButton(e){return e.classList.contains("apply-button")}isCancelButton(e){return e.classList.contains("cancel-button")}gotoDate(t){const i=new e(t,this.options.format);i.setDate(1),this.calendars[0]=i.clone(),this.renderAll()}clear(){this.options.date=null,this.datePicked.length=0,this.updateValues(),this.renderAll(),this.trigger("clear")}handleOptions(){this.options.element instanceof HTMLElement||(this.options.element=this.options.doc.querySelector(this.options.element)),"function"==typeof this.options.documentClick&&document.addEventListener("click",this.options.documentClick,!0),this.options.element instanceof HTMLInputElement&&(this.options.element.readOnly=this.options.readonly),this.options.date?this.calendars[0]=new e(this.options.date,this.options.format):this.calendars[0]=new e}handleCSS(){if(Array.isArray(this.options.css))this.options.css.forEach((e=>{const t=document.createElement("link");t.href=e,t.rel="stylesheet";const i=()=>{this.cssLoaded++,this.cssLoaded===this.options.css.length&&(this.ui.wrapper.style.display="")};t.addEventListener("load",i),t.addEventListener("error",i),this.ui.shadowRoot.append(t)}));else if("string"==typeof this.options.css){const e=document.createElement("style"),t=document.createTextNode(this.options.css);e.appendChild(t),this.ui.shadowRoot.append(e),this.ui.wrapper.style.display=""}else"function"==typeof this.options.css&&(this.options.css.call(this,this),this.ui.wrapper.style.display="")}adjustPosition(e){const t=e.getBoundingClientRect(),i=this.ui.wrapper.getBoundingClientRect();this.ui.container.classList.add("calc");const n=this.ui.container.getBoundingClientRect();this.ui.container.classList.remove("calc");let s=t.bottom-i.bottom,a=t.left-i.left;return"undefined"!=typeof window&&(window.innerHeight<s+n.height&&s-n.height>=0&&(s=t.top-i.top-n.height),window.innerWidth<a+n.width&&t.right-n.width>=0&&(a=t.right-i.right-n.width)),{left:a,top:s}}}var s=Object.freeze({__proto__:null,Core:n,create:n});export{n as Core,n as create,s as easepick};
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @license
3
+ * Package: @yuafox/easepick2-core
4
+ * Version: 2.0.0
5
+ * https://github.com/YuaFox/easepick2
6
+ * Copyright 2026 YuaFox
7
+ *
8
+ * Licensed under the terms of GNU General Public License Version 2 or later. (http://www.gnu.org/licenses/gpl.html)
9
+ */
10
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@yuafox/easepick2-datetime")):"function"==typeof define&&define.amd?define(["exports","@yuafox/easepick2-datetime"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).easepick=e.easepick||{},e.easepick)}(this,(function(e,t){"use strict";class i{picker;constructor(e){this.picker=e}render(e,i){e||(e=new t.DateTime),e.setDate(1),e.setHours(0,0,0,0),"function"==typeof this[`get${i}View`]&&this[`get${i}View`](e)}getContainerView(e){this.picker.ui.container.innerHTML="",this.picker.options.header&&this.picker.trigger("render",{date:e.clone(),view:"Header"}),this.picker.trigger("render",{date:e.clone(),view:"Main"}),this.picker.options.autoApply||this.picker.trigger("render",{date:e.clone(),view:"Footer"})}getHeaderView(e){const t=document.createElement("header");this.picker.options.header instanceof HTMLElement&&t.appendChild(this.picker.options.header),"string"==typeof this.picker.options.header&&(t.innerHTML=this.picker.options.header),this.picker.ui.container.appendChild(t),this.picker.trigger("view",{target:t,date:e.clone(),view:"Header"})}getMainView(e){const t=document.createElement("main");this.picker.ui.container.appendChild(t);const i=this.picker.options.viewMode||"day",n=document.createElement("div");if(n.className=`calendars grid-${this.picker.options.grid}`,"month"===i){const t=document.createElement("div");t.className="calendar",n.appendChild(t);const i=this.getCalendarHeaderView(e.clone());t.appendChild(i),this.picker.trigger("view",{date:e.clone(),view:"CalendarHeader",index:0,target:i});const s=this.getCalendarMonthsView(e.clone());t.appendChild(s),this.picker.trigger("view",{date:e.clone(),view:"CalendarMonths",index:0,target:s}),this.picker.trigger("view",{date:e.clone(),view:"CalendarItem",index:0,target:t})}else if("year"===i){const t=document.createElement("div");t.className="calendar",n.appendChild(t);const i=this.getCalendarHeaderView(e.clone());t.appendChild(i),this.picker.trigger("view",{date:e.clone(),view:"CalendarHeader",index:0,target:i});const s=this.getCalendarYearsView(e.clone());t.appendChild(s),this.picker.trigger("view",{date:e.clone(),view:"CalendarYears",index:0,target:s}),this.picker.trigger("view",{date:e.clone(),view:"CalendarItem",index:0,target:t})}else for(let t=0;t<this.picker.options.calendars;t++){const i=document.createElement("div");i.className="calendar",n.appendChild(i);const s=this.getCalendarHeaderView(e.clone());i.appendChild(s),this.picker.trigger("view",{date:e.clone(),view:"CalendarHeader",index:t,target:s});const a=this.getCalendarDayNamesView();i.appendChild(a),this.picker.trigger("view",{date:e.clone(),view:"CalendarDayNames",index:t,target:a});const o=this.getCalendarDaysView(e.clone());i.appendChild(o),this.picker.trigger("view",{date:e.clone(),view:"CalendarDays",index:t,target:o});const r=this.getCalendarFooterView(this.picker.options.lang,e.clone());i.appendChild(r),this.picker.trigger("view",{date:e.clone(),view:"CalendarFooter",index:t,target:r}),this.picker.trigger("view",{date:e.clone(),view:"CalendarItem",index:t,target:i}),e.add(1,"month")}t.appendChild(n),this.picker.trigger("view",{date:e.clone(),view:"Calendars",target:n}),this.picker.trigger("view",{date:e.clone(),view:"Main",target:t})}getFooterView(e){const t=document.createElement("footer"),i=document.createElement("div");i.className="footer-buttons";const n=document.createElement("button");n.className="cancel-button unit",n.innerHTML=this.picker.options.locale.cancel,i.appendChild(n);const s=document.createElement("button");s.className="apply-button unit",s.innerHTML=this.picker.options.locale.apply,s.disabled=!0,i.appendChild(s),t.appendChild(i),this.picker.ui.container.appendChild(t),this.picker.trigger("view",{date:e,target:t,view:"Footer"})}getCalendarHeaderView(e){const t=this.picker.options.viewMode||"day",i=document.createElement("div");i.className="header";const n=document.createElement("div");if(n.className="month-name","month"===t)n.innerHTML=`<span>${e.format("YYYY")}</span>`;else if("year"===t){const t=10*Math.floor(e.getFullYear()/10);n.innerHTML=`<span>${t} - ${t+9}</span>`}else n.innerHTML=`<span>${e.toLocaleString(this.picker.options.lang,{month:"long"})}</span> ${e.format("YYYY")}`;i.appendChild(n);const s=document.createElement("button");s.className="previous-button unit",s.innerHTML=this.picker.options.locale.previousMonth,i.appendChild(s);const a=document.createElement("button");return a.className="next-button unit",a.innerHTML=this.picker.options.locale.nextMonth,i.appendChild(a),i}getCalendarMonthsView(e){const i=document.createElement("div");i.className="months-grid";const n=new t.DateTime;for(let s=0;s<12;s++){const a=new t.DateTime(new Date(e.getFullYear(),s,1)),o=document.createElement("div");if(o.className="month unit",o.innerHTML=a.toLocaleString(this.picker.options.lang,{month:"short"}),o.dataset.time=String(a.getTime()),a.getFullYear()===n.getFullYear()&&s===n.getMonth()&&o.classList.add("today"),this.picker.datePicked.length)this.picker.datePicked[0].isSame(a,"month")&&o.classList.add("selected");else if(this.picker.options.date){new t.DateTime(this.picker.options.date).isSame(a,"month")&&o.classList.add("selected")}i.appendChild(o),this.picker.trigger("view",{date:a,view:"CalendarMonth",target:o})}return i}getCalendarYearsView(e){const i=document.createElement("div");i.className="years-grid";const n=new t.DateTime,s=10*Math.floor(e.getFullYear()/10);for(let e=s;e<s+12;e++){const a=new t.DateTime(new Date(e,0,1)),o=document.createElement("div");if(o.className="year unit",o.innerHTML=String(e),o.dataset.time=String(a.getTime()),e===n.getFullYear()&&o.classList.add("today"),(e<s||e>s+9)&&o.classList.add("outside"),this.picker.datePicked.length)this.picker.datePicked[0].getFullYear()===e&&o.classList.add("selected");else if(this.picker.options.date){new t.DateTime(this.picker.options.date).getFullYear()===e&&o.classList.add("selected")}i.appendChild(o),this.picker.trigger("view",{date:a,view:"CalendarYear",target:o})}return i}getCalendarDayNamesView(){const e=document.createElement("div");e.className="daynames-row";for(let t=1;t<=7;t++){const i=3+this.picker.options.firstDay+t,n=document.createElement("div");n.className="dayname",n.innerHTML=new Date(1970,0,i,12,0,0,0).toLocaleString(this.picker.options.lang,{weekday:"short"}),n.title=new Date(1970,0,i,12,0,0,0).toLocaleString(this.picker.options.lang,{weekday:"long"}),e.appendChild(n),this.picker.trigger("view",{dayIdx:i,view:"CalendarDayName",target:n})}return e}getCalendarDaysView(e){const t=document.createElement("div");t.className="days-grid";const i=this.calcOffsetDays(e,this.picker.options.firstDay),n=32-new Date(e.getFullYear(),e.getMonth(),32).getDate();for(let e=0;e<i;e++){const e=document.createElement("div");e.className="offset",t.appendChild(e)}for(let i=1;i<=n;i++){e.setDate(i);const n=this.getCalendarDayView(e);t.appendChild(n),this.picker.trigger("view",{date:e,view:"CalendarDay",target:n})}return t}getCalendarDayView(e){const i=this.picker.options.date?new t.DateTime(this.picker.options.date):null,n=new t.DateTime,s=document.createElement("div");return s.className="day unit",s.innerHTML=e.format("D"),s.dataset.time=String(e.getTime()),e.isSame(n,"day")&&s.classList.add("today"),[0,6].includes(e.getDay())&&s.classList.add("weekend"),this.picker.datePicked.length?this.picker.datePicked[0].isSame(e,"day")&&s.classList.add("selected"):i&&e.isSame(i,"day")&&s.classList.add("selected"),this.picker.trigger("view",{date:e,view:"CalendarDay",target:s}),s}getCalendarFooterView(e,t){const i=document.createElement("div");return i.className="footer",i}calcOffsetDays(e,t){let i=e.getDay()-t;return i<0&&(i+=7),i}}class n{picker;instances={};constructor(e){this.picker=e}initialize(){const e=[];this.picker.options.plugins.forEach((t=>{"function"==typeof t?e.push(new t):"string"==typeof t&&"undefined"!=typeof easepick&&Object.prototype.hasOwnProperty.call(easepick,t)?e.push(new easepick[t]):console.warn(`easepick: ${t} not found.`)})),e.sort(((e,t)=>e.priority>t.priority?-1:e.priority<t.priority||e.dependencies.length>t.dependencies.length?1:e.dependencies.length<t.dependencies.length?-1:0)),e.forEach((e=>{e.attach(this.picker),this.instances[e.getName()]=e}))}getInstance(e){return this.instances[e]}addInstance(e){if(Object.prototype.hasOwnProperty.call(this.instances,e))console.warn(`easepick: ${e} already added.`);else{if("undefined"!=typeof easepick&&Object.prototype.hasOwnProperty.call(easepick,e)){const t=new easepick[e];return t.attach(this.picker),this.instances[t.getName()]=t,t}if("undefined"!==this.getPluginFn(e)){const t=new(this.getPluginFn(e));return t.attach(this.picker),this.instances[t.getName()]=t,t}console.warn(`easepick: ${e} not found.`)}return null}removeInstance(e){return e in this.instances&&this.instances[e].detach(),delete this.instances[e]}reloadInstance(e){return this.removeInstance(e),this.addInstance(e)}getPluginFn(e){return[...this.picker.options.plugins].filter((t=>"function"==typeof t&&(new t).getName()===e)).shift()}}class s{Calendar=new i(this);PluginManager=new n(this);calendars=[];datePicked=[];cssLoaded=0;binds={hidePicker:this.hidePicker.bind(this),show:this.show.bind(this)};options={doc:document,css:[],element:null,firstDay:1,grid:1,calendars:1,lang:"en-US",date:null,format:"YYYY-MM-DD",readonly:!0,autoApply:!0,header:!1,inline:!1,viewMode:"day",scrollToDate:!0,locale:{nextMonth:'<svg width="11" height="16" xmlns="http://www.w3.org/2000/svg"><path d="M2.748 16L0 13.333 5.333 8 0 2.667 2.748 0l7.919 8z" fill-rule="nonzero"/></svg>',previousMonth:'<svg width="11" height="16" xmlns="http://www.w3.org/2000/svg"><path d="M7.919 0l2.748 2.667L5.333 8l5.334 5.333L7.919 16 0 8z" fill-rule="nonzero"/></svg>',cancel:"Cancel",apply:"Apply"},documentClick:this.binds.hidePicker,plugins:[]};ui={container:null,shadowRoot:null,wrapper:null};version="2.0.0";constructor(e){const t={...this.options.locale,...e.locale};this.options={...this.options,...e},this.options.locale=t,this.handleOptions(),this.ui.wrapper=document.createElement("span"),this.ui.wrapper.style.display="none",this.ui.wrapper.style.position="absolute",this.ui.wrapper.style.pointerEvents="none",this.ui.wrapper.className="easepick-wrapper",this.ui.wrapper.attachShadow({mode:"open"}),this.ui.shadowRoot=this.ui.wrapper.shadowRoot,this.ui.container=document.createElement("div"),this.ui.container.className="container",this.options.zIndex&&(this.ui.container.style.zIndex=String(this.options.zIndex)),this.options.inline&&(this.ui.wrapper.style.position="relative",this.ui.container.classList.add("inline")),this.ui.shadowRoot.appendChild(this.ui.container),this.options.element.after(this.ui.wrapper),this.handleCSS(),this.options.element.addEventListener("click",this.binds.show),this.on("view",this.onView.bind(this)),this.on("render",this.onRender.bind(this)),this.PluginManager.initialize(),this.parseValues(),"function"==typeof this.options.setup&&this.options.setup(this),this.on("click",this.onClick.bind(this));const i=this.options.scrollToDate?this.getDate():null;this.renderAll(i)}on(e,t,i={}){this.ui.container.addEventListener(e,t,i)}off(e,t,i={}){this.ui.container.removeEventListener(e,t,i)}trigger(e,t={}){return this.ui.container.dispatchEvent(new CustomEvent(e,{detail:t}))}destroy(){this.options.element.removeEventListener("click",this.binds.show),"function"==typeof this.options.documentClick&&document.removeEventListener("click",this.options.documentClick,!0),Object.keys(this.PluginManager.instances).forEach((e=>{this.PluginManager.removeInstance(e)})),this.ui.wrapper.remove()}onRender(e){const{view:t,date:i}=e.detail;this.Calendar.render(i,t)}onView(e){const{view:t,target:i}=e.detail;if("Footer"===t&&this.datePicked.length){i.querySelector(".apply-button").disabled=!1}}onClickHeaderButton(e){if(this.isCalendarHeaderButton(e)){const t=this.options.viewMode||"day",i=e.classList.contains("next-button");"year"===t?i?this.calendars[0].setFullYear(this.calendars[0].getFullYear()+10):this.calendars[0].setFullYear(this.calendars[0].getFullYear()-10):"month"===t?i?this.calendars[0].setFullYear(this.calendars[0].getFullYear()+1):this.calendars[0].setFullYear(this.calendars[0].getFullYear()-1):i?this.calendars[0].add(1,"month"):this.calendars[0].subtract(1,"month"),this.renderAll(this.calendars[0])}}onClickCalendarDay(e){if(this.isCalendarDay(e)){const i=new t.DateTime(e.dataset.time);this.options.autoApply?(this.setDate(i),this.trigger("select",{date:this.getDate()}),this.hide()):(this.datePicked[0]=i,this.trigger("preselect",{date:this.getDate()}),this.renderAll())}}onClickCalendarMonth(e){if(this.isCalendarMonth(e)){const i=new t.DateTime(e.dataset.time);this.options.autoApply?(this.setDate(i),this.trigger("select",{date:this.getDate()}),this.hide()):(this.datePicked[0]=i,this.trigger("preselect",{date:this.getDate()}),this.renderAll())}}onClickCalendarYear(e){if(this.isCalendarYear(e)){const i=new t.DateTime(e.dataset.time);this.options.autoApply?(this.setDate(i),this.trigger("select",{date:this.getDate()}),this.hide()):(this.datePicked[0]=i,this.trigger("preselect",{date:this.getDate()}),this.renderAll())}}onClickApplyButton(e){if(this.isApplyButton(e)){if(this.datePicked[0]instanceof Date){const e=this.datePicked[0].clone();this.setDate(e)}this.hide(),this.trigger("select",{date:this.getDate()})}}onClickCancelButton(e){this.isCancelButton(e)&&this.hide()}onClick(e){const t=e.target;if(t instanceof HTMLElement){const e=t.closest(".unit");if(!(e instanceof HTMLElement))return;this.onClickHeaderButton(e),this.onClickCalendarDay(e),this.onClickCalendarMonth(e),this.onClickCalendarYear(e),this.onClickApplyButton(e),this.onClickCancelButton(e)}}isShown(){return this.ui.container.classList.contains("inline")||this.ui.container.classList.contains("show")}show(e){if(this.isShown())return;const t=e&&"target"in e?e.target:this.options.element,{top:i,left:n}=this.adjustPosition(t);this.ui.container.style.top=`${i}px`,this.ui.container.style.left=`${n}px`,this.ui.container.classList.add("show"),this.trigger("show",{target:t})}hide(){this.ui.container.classList.remove("show"),this.datePicked.length=0,this.renderAll(),this.trigger("hide")}setDate(e){const i=new t.DateTime(e,this.options.format);this.options.date=i.clone(),this.updateValues(),this.calendars.length&&this.renderAll()}getDate(){return this.options.date instanceof t.DateTime?this.options.date.clone():null}parseValues(){this.options.date?this.setDate(this.options.date):this.options.element instanceof HTMLInputElement&&this.options.element.value.length&&this.setDate(this.options.element.value),this.options.date instanceof Date||(this.options.date=null)}updateValues(){const e=this.getDate(),t=e instanceof Date?e.format(this.options.format,this.options.lang):"",i=this.options.element;i instanceof HTMLInputElement?i.value=t:i instanceof HTMLElement&&(i.innerText=t)}hidePicker(e){let t=e.target,i=null;t.shadowRoot&&(t=e.composedPath()[0],i=t.getRootNode().host),this.isShown()&&!1===this.options.inline&&i!==this.ui.wrapper&&t!==this.options.element&&this.hide()}renderAll(e){this.trigger("render",{view:"Container",date:(e||this.calendars[0]).clone()})}isCalendarHeaderButton(e){return["previous-button","next-button"].some((t=>e.classList.contains(t)))}isCalendarDay(e){return e.classList.contains("day")}isCalendarMonth(e){return e.classList.contains("month")}isCalendarYear(e){return e.classList.contains("year")}isApplyButton(e){return e.classList.contains("apply-button")}isCancelButton(e){return e.classList.contains("cancel-button")}gotoDate(e){const i=new t.DateTime(e,this.options.format);i.setDate(1),this.calendars[0]=i.clone(),this.renderAll()}clear(){this.options.date=null,this.datePicked.length=0,this.updateValues(),this.renderAll(),this.trigger("clear")}handleOptions(){this.options.element instanceof HTMLElement||(this.options.element=this.options.doc.querySelector(this.options.element)),"function"==typeof this.options.documentClick&&document.addEventListener("click",this.options.documentClick,!0),this.options.element instanceof HTMLInputElement&&(this.options.element.readOnly=this.options.readonly),this.options.date?this.calendars[0]=new t.DateTime(this.options.date,this.options.format):this.calendars[0]=new t.DateTime}handleCSS(){if(Array.isArray(this.options.css))this.options.css.forEach((e=>{const t=document.createElement("link");t.href=e,t.rel="stylesheet";const i=()=>{this.cssLoaded++,this.cssLoaded===this.options.css.length&&(this.ui.wrapper.style.display="")};t.addEventListener("load",i),t.addEventListener("error",i),this.ui.shadowRoot.append(t)}));else if("string"==typeof this.options.css){const e=document.createElement("style"),t=document.createTextNode(this.options.css);e.appendChild(t),this.ui.shadowRoot.append(e),this.ui.wrapper.style.display=""}else"function"==typeof this.options.css&&(this.options.css.call(this,this),this.ui.wrapper.style.display="")}adjustPosition(e){const t=e.getBoundingClientRect(),i=this.ui.wrapper.getBoundingClientRect();this.ui.container.classList.add("calc");const n=this.ui.container.getBoundingClientRect();this.ui.container.classList.remove("calc");let s=t.bottom-i.bottom,a=t.left-i.left;return"undefined"!=typeof window&&(window.innerHeight<s+n.height&&s-n.height>=0&&(s=t.top-i.top-n.height),window.innerWidth<a+n.width&&t.right-n.width>=0&&(a=t.right-i.right-n.width)),{left:a,top:s}}}var a=Object.freeze({__proto__:null,Core:s,create:s});e.Core=s,e.create=s,e.easepick=a,Object.defineProperty(e,"__esModule",{value:!0})}));
@@ -0,0 +1,42 @@
1
+ import { Core } from './core';
2
+ export default class PluginManager {
3
+ picker: Core;
4
+ instances: {};
5
+ constructor(picker: Core);
6
+ /**
7
+ * Initialize user-supplied plugins (if any)
8
+ */
9
+ initialize(): void;
10
+ /**
11
+ * Return instance of plugin
12
+ *
13
+ * @param name
14
+ * @returns Plugin
15
+ */
16
+ getInstance<T>(name: string): T;
17
+ /**
18
+ * Add plugin «on the fly» to the picker
19
+ *
20
+ * @param name
21
+ */
22
+ addInstance<T>(name: string): T;
23
+ /**
24
+ * Remove plugin from the picker
25
+ *
26
+ * @param name
27
+ */
28
+ removeInstance(name: string): boolean;
29
+ /**
30
+ * Reload plugin
31
+ *
32
+ * @param name
33
+ */
34
+ reloadInstance<T>(name: string): T;
35
+ /**
36
+ * Find plugin function by the name
37
+ *
38
+ * @param name
39
+ * @returns Plugin
40
+ */
41
+ private getPluginFn;
42
+ }
@@ -0,0 +1,40 @@
1
+ import { DateTime } from '@yuafox/easepick2-datetime';
2
+ import { Core } from './core';
3
+ export interface IEventDetail {
4
+ view?: string;
5
+ date?: DateTime;
6
+ target?: HTMLElement;
7
+ index?: number;
8
+ }
9
+ export interface IPickerElements {
10
+ container: HTMLElement;
11
+ shadowRoot: ShadowRoot;
12
+ wrapper: HTMLElement;
13
+ }
14
+ export interface IPickerConfig {
15
+ element: HTMLElement | string;
16
+ doc?: Document | ShadowRoot;
17
+ css?: string | string[] | ((picker: Core) => void);
18
+ firstDay?: number;
19
+ lang?: string;
20
+ date?: Date | string | number;
21
+ format?: string;
22
+ grid?: number;
23
+ calendars?: number;
24
+ readonly?: boolean;
25
+ autoApply?: boolean;
26
+ header?: boolean | string | HTMLElement;
27
+ locale?: {
28
+ previousMonth?: string;
29
+ nextMonth?: string;
30
+ cancel?: string;
31
+ apply?: string;
32
+ };
33
+ viewMode?: 'day' | 'month' | 'year';
34
+ plugins?: any[];
35
+ documentClick?: boolean | (() => void);
36
+ zIndex?: number;
37
+ inline?: boolean;
38
+ scrollToDate?: boolean;
39
+ setup?(picker: Core): void;
40
+ }
package/package.json ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "@yuafox/easepick2-core",
3
+ "description": "The core of easepick2.",
4
+ "version": "2.0.0",
5
+ "main": "dist/index.umd.js",
6
+ "module": "dist/index.esm.js",
7
+ "types": "dist/index.d.ts",
8
+ "dependencies": {
9
+ "@yuafox/easepick2-datetime": "^2.0.0"
10
+ },
11
+ "author": {
12
+ "name": "YuaFox"
13
+ },
14
+ "license": "GPL-2.0-or-later",
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "https://github.com/YuaFox/easepick2.git",
18
+ "directory": "packages/core"
19
+ },
20
+ "homepage": "https://github.com/YuaFox/easepick2",
21
+ "bugs": {
22
+ "url": "https://github.com/YuaFox/easepick2/issues"
23
+ },
24
+ "files": [
25
+ "dist"
26
+ ]
27
+ }