ember-power-calendar 0.19.0 → 0.20.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.
Files changed (30) hide show
  1. package/README.md +43 -38
  2. package/addon/{templates/components → components}/power-calendar/days.hbs +2 -2
  3. package/addon/components/power-calendar/days.js +60 -58
  4. package/addon/components/power-calendar/nav.js +8 -6
  5. package/addon/components/power-calendar-multiple/days.js +11 -6
  6. package/addon/components/power-calendar-multiple.js +24 -18
  7. package/addon/components/power-calendar-range/days.js +5 -5
  8. package/addon/components/power-calendar-range.js +73 -40
  9. package/addon/{templates/components → components}/power-calendar.hbs +5 -3
  10. package/addon/components/power-calendar.js +50 -47
  11. package/addon/helpers/ember-power-calendar-day-classes.js +8 -4
  12. package/addon/helpers/power-calendar-format-date.js +1 -1
  13. package/addon/services/power-calendar.js +11 -6
  14. package/addon/utils.js +119 -0
  15. package/addon-test-support/index.js +23 -8
  16. package/app/components/power-calendar/days.js +1 -1
  17. package/app/components/power-calendar/nav.js +1 -1
  18. package/app/components/power-calendar-multiple/days.js +1 -1
  19. package/app/components/power-calendar-multiple.js +1 -1
  20. package/app/components/power-calendar-range/days.js +1 -1
  21. package/app/components/power-calendar-range.js +1 -1
  22. package/app/components/power-calendar.js +1 -1
  23. package/app/helpers/ember-power-calendar-day-classes.js +4 -1
  24. package/app/helpers/power-calendar-format-date.js +4 -1
  25. package/app/styles/ember-power-calendar.scss +53 -25
  26. package/index.js +0 -27
  27. package/package.json +83 -47
  28. package/test-support/helpers/ember-power-calendar.js +17 -8
  29. package/addon/utils/computed-fallback-if-undefined.js +0 -13
  30. /package/addon/{templates/components → components}/power-calendar/nav.hbs +0 -0
package/README.md CHANGED
@@ -1,38 +1,43 @@
1
- # Ember Power Calendar [![Build Status](https://travis-ci.org/cibernox/ember-power-calendar.svg?branch=master)](https://travis-ci.org/cibernox/ember-power-calendar)
2
-
3
- Customizable Calendar Component for Ember.
4
-
5
- ## Disclaimer
6
-
7
- Version 0.14 of this addon requires Ember 3.11 or greater.
8
- Versions below 0.14 would work with Ember 3.0+ (and perhaps 2.12+)
9
-
10
- ## Installation
11
-
12
- `ember install ember-power-calendar`
13
-
14
- Internet Explorer 11 support requires babel polyfill:
15
-
16
- ```js
17
- // ember-cli-build.js
18
-
19
- let app = new EmberAddon(defaults, {
20
- 'ember-cli-babel': {
21
- includePolyfill: true
22
- }
23
- });
24
- ```
25
-
26
- ## Usage
27
-
28
- There are many possible ways to use it, for giving you just a taste of the API:
29
-
30
- ```hbs
31
- <PowerCalendar @selected={{arrival}} @onSelect={{action (mut arrival) value="date"}} as |calendar|>
32
- <calendar.Nav/>
33
- <calendar.Days/>
34
- </PowerCalendar>
35
- ```
36
-
37
- Check the full documentation at www.ember-power-calendar.com
38
-
1
+ # Ember Power Calendar
2
+
3
+ [![CI](https://github.com/cibernox/ember-power-calendar/actions/workflows/ci.yml/badge.svg)](https://github.com/cibernox/ember-power-calendar/actions/workflows/ci.yml)
4
+ [![Ember Observer Score](http://emberobserver.com/badges/ember-power-calendar.svg)](http://emberobserver.com/addons/ember-power-calendar)
5
+ [![npm version](https://badge.fury.io/js/ember-power-calendar.svg)](https://badge.fury.io/js/ember-power-calendar)
6
+
7
+ Customizable Calendar Component for Ember.
8
+
9
+ ## Compatibility
10
+
11
+ * Ember.js v3.28 or above
12
+ * Ember CLI v3.28 or above
13
+ * Node.js v16 or above
14
+
15
+ ## Installation
16
+
17
+ `ember install ember-power-calendar`
18
+
19
+ Internet Explorer 11 support requires babel polyfill:
20
+
21
+ ```js
22
+ // ember-cli-build.js
23
+
24
+ let app = new EmberAddon(defaults, {
25
+ 'ember-cli-babel': {
26
+ includePolyfill: true
27
+ }
28
+ });
29
+ ```
30
+
31
+ ## Usage
32
+
33
+ There are many possible ways to use it, for giving you just a taste of the API:
34
+
35
+ ```hbs
36
+ <PowerCalendar @selected={{this.arrival}} @onSelect={{this.onChange}} as |calendar|>
37
+ <calendar.Nav/>
38
+ <calendar.Days/>
39
+ </PowerCalendar>
40
+ ```
41
+
42
+ Check the full documentation at www.ember-power-calendar.com
43
+
@@ -1,3 +1,4 @@
1
+ {{! template-lint-disable no-invalid-interactive }}
1
2
  <div
2
3
  class="ember-power-calendar-days"
3
4
  {{on "click" this.handleClick}}
@@ -8,14 +9,13 @@
8
9
  <div class="ember-power-calendar-weekday">{{wdn}}</div>
9
10
  {{/each}}
10
11
  </div>
11
- {{! template-lint-disable no-invalid-interactive }}
12
12
  <div class="ember-power-calendar-day-grid" {{on "keydown" this.handleKeyDown}}>
13
13
  {{#each this.weeks key='id' as |week|}}
14
14
  <div class="ember-power-calendar-row ember-power-calendar-week" data-missing-days={{week.missingDays}}>
15
15
  {{#each week.days key='id' as |day|}}
16
16
  <button type="button"
17
17
  data-date="{{day.id}}"
18
- class={{ember-power-calendar-day-classes day @calendar this.weeks this.dayClass}}
18
+ class={{ember-power-calendar-day-classes day @calendar this.weeks @dayClass}}
19
19
  {{on "focus" this.handleDayFocus}}
20
20
  {{on "blur" this.handleDayBlur}}
21
21
  disabled={{day.isDisabled}}>
@@ -1,9 +1,9 @@
1
- import Component from '@ember/component';
2
- import { computed, action } from '@ember/object';
1
+ import Component from '@glimmer/component';
2
+ import { tracked } from '@glimmer/tracking';
3
+ import { action } from '@ember/object';
3
4
  import { scheduleOnce } from '@ember/runloop';
4
5
  import { inject as service } from '@ember/service';
5
6
  import { assert } from '@ember/debug';
6
- import templateLayout from '../../templates/components/power-calendar/days';
7
7
  import {
8
8
  add,
9
9
  endOf,
@@ -21,73 +21,68 @@ import {
21
21
  startOf,
22
22
  startOfWeek,
23
23
  withLocale,
24
- } from 'ember-power-calendar-utils';
24
+ } from 'ember-power-calendar/utils';
25
25
 
26
- const WEEK_DAYS = [
27
- 'Mon',
28
- 'Tue',
29
- 'Wed',
30
- 'Thu',
31
- 'Fri',
32
- 'Sat',
33
- 'Sun'
34
- ];
26
+ const WEEK_DAYS = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
35
27
 
36
28
  export default class extends Component {
37
- layout = templateLayout
38
- tagName = ''
39
- focusedId = undefined
40
- showDaysAround = true
41
- weekdayFormat = 'short' // "min" | "short" | "long"
42
- @service('power-calendar') powerCalendarService
29
+ @service('power-calendar') powerCalendarService;
30
+
31
+ @tracked focusedId = undefined;
32
+
33
+ get weekdayFormat() {
34
+ return this.args.weekdayFormat || 'short'; // "min" | "short" | "long"
35
+ }
36
+
37
+ get showDaysAround() {
38
+ return this.args.showDaysAround !== undefined
39
+ ? this.args.showDaysAround
40
+ : true;
41
+ }
43
42
 
44
- // CPs
45
- @computed('calendar.locale')
46
43
  get weekdaysMin() {
47
- return withLocale(this.calendar.locale, getWeekdaysMin);
44
+ return withLocale(this.args.calendar.locale, getWeekdaysMin);
48
45
  }
49
46
 
50
- @computed('calendar.locale')
51
47
  get weekdaysShort() {
52
- return withLocale(this.calendar.locale, getWeekdaysShort);
48
+ return withLocale(this.args.calendar.locale, getWeekdaysShort);
53
49
  }
54
50
 
55
- @computed('calendar.locale')
56
51
  get weekdays() {
57
- return withLocale(this.calendar.locale, getWeekdays);
52
+ return withLocale(this.args.calendar.locale, getWeekdays);
58
53
  }
59
54
 
60
- @computed('weekdaysShort', 'startOfWeek')
61
55
  get localeStartOfWeek() {
62
- let forcedStartOfWeek = this.startOfWeek;
56
+ let forcedStartOfWeek = this.args.startOfWeek;
63
57
  if (forcedStartOfWeek) {
64
58
  return parseInt(forcedStartOfWeek, 10);
65
59
  }
66
- return localeStartOfWeek(this.calendar.locale);
60
+ return localeStartOfWeek(this.args.calendar.locale);
67
61
  }
68
62
 
69
- @computed('localeStartOfWeek', 'weekdayFormat', 'calendar.locale')
70
63
  get weekdaysNames() {
71
64
  let { localeStartOfWeek, weekdayFormat } = this;
72
- let format = `weekdays${weekdayFormat === 'long' ? '' : (weekdayFormat === 'min' ? 'Min' : 'Short')}`;
65
+ let format = `weekdays${
66
+ weekdayFormat === 'long' ? '' : weekdayFormat === 'min' ? 'Min' : 'Short'
67
+ }`;
73
68
  let weekdaysNames = this[format];
74
- return weekdaysNames.slice(localeStartOfWeek).concat(weekdaysNames.slice(0, localeStartOfWeek));
69
+ return weekdaysNames
70
+ .slice(localeStartOfWeek)
71
+ .concat(weekdaysNames.slice(0, localeStartOfWeek));
75
72
  }
76
73
 
77
- @computed('calendar', 'focusedId', 'localeStartOfWeek', 'minDate', 'maxDate', 'disabledDates.[]', 'maxLength', 'currentCenter')
78
74
  get days() {
79
75
  let today = this.powerCalendarService.getDate();
80
76
  let lastDay = this.lastDay();
81
77
  let day = this.firstDay();
82
78
  let days = [];
83
79
  while (isBefore(day, lastDay)) {
84
- days.push(this.buildDay(day, today, this.calendar));
85
- day = add(day, 1, "day");
80
+ days.push(this.buildDay(day, today, this.args.calendar));
81
+ day = add(day, 1, 'day');
86
82
  }
87
83
  return days;
88
84
  }
89
85
 
90
- @computed('showDaysAround', 'days')
91
86
  get weeks() {
92
87
  let { showDaysAround, days } = this;
93
88
  let weeks = [];
@@ -100,18 +95,17 @@ export default class extends Component {
100
95
  weeks.push({
101
96
  id: `week-of-${daysOfWeek[0].id}`,
102
97
  days: daysOfWeek,
103
- missingDays: 7 - daysOfWeek.length
98
+ missingDays: 7 - daysOfWeek.length,
104
99
  });
105
100
  i += 7;
106
101
  }
107
102
  return weeks;
108
103
  }
109
104
 
110
- @computed('center', 'calendar.center')
111
105
  get currentCenter() {
112
- let center = this.center;
106
+ let center = this.args.center;
113
107
  if (!center) {
114
- center = this.selected || this.calendar.center;
108
+ center = this.args.selected || this.args.calendar.center;
115
109
  }
116
110
  return normalizeDate(center);
117
111
  }
@@ -176,14 +170,14 @@ export default class extends Component {
176
170
  } else {
177
171
  return;
178
172
  }
179
- this.set('focusedId', day.id);
173
+ this.focusedId = day.id;
180
174
  scheduleOnce('afterRender', this, '_focusDate', day.id);
181
175
  }
182
176
  }
183
177
 
184
178
  // Methods
185
179
  buildDay(date, today, calendar) {
186
- let id = formatDate(date, 'YYYY-MM-DD')
180
+ let id = formatDate(date, 'YYYY-MM-DD');
187
181
 
188
182
  return normalizeCalendarDay({
189
183
  id,
@@ -193,7 +187,7 @@ export default class extends Component {
193
187
  isFocused: this.focusedId === id,
194
188
  isCurrentMonth: date.getMonth() === this.currentCenter.getMonth(),
195
189
  isToday: isSame(date, today, 'day'),
196
- isSelected: this.dayIsSelected(date, calendar)
190
+ isSelected: this.dayIsSelected(date, calendar),
197
191
  });
198
192
  }
199
193
 
@@ -201,29 +195,32 @@ export default class extends Component {
201
195
  return day;
202
196
  }
203
197
 
204
- dayIsSelected(date, calendar = this.calendar) {
198
+ dayIsSelected(date, calendar = this.args.calendar) {
205
199
  return calendar.selected ? isSame(date, calendar.selected, 'day') : false;
206
200
  }
207
201
 
208
202
  dayIsDisabled(date) {
209
- let isDisabled = !this.calendar.actions.select;
203
+ let isDisabled = !this.args.calendar.actions.select;
210
204
  if (isDisabled) {
211
205
  return true;
212
206
  }
213
207
 
214
- if (this.minDate && isBefore(date, startOf(this.minDate, 'day'))) {
208
+ if (
209
+ this.args.minDate &&
210
+ isBefore(date, startOf(this.args.minDate, 'day'))
211
+ ) {
215
212
  return true;
216
213
  }
217
214
 
218
- if (this.maxDate && isAfter(date, endOf(this.maxDate, 'day'))) {
215
+ if (this.args.maxDate && isAfter(date, endOf(this.args.maxDate, 'day'))) {
219
216
  return true;
220
217
  }
221
218
 
222
-
223
- if (this.disabledDates) {
224
- let disabledInRange = this.disabledDates.some((d) => {
219
+ if (this.args.disabledDates) {
220
+ let disabledInRange = this.args.disabledDates.some((d) => {
225
221
  let isSameDay = isSame(date, d, 'day');
226
- let isWeekDayIncludes = WEEK_DAYS.indexOf(d) !== -1 && formatDate(date, 'ddd') === d;
222
+ let isWeekDayIncludes =
223
+ WEEK_DAYS.indexOf(d) !== -1 && formatDate(date, 'ddd') === d;
227
224
  return isSameDay || isWeekDayIncludes;
228
225
  });
229
226
 
@@ -242,17 +239,22 @@ export default class extends Component {
242
239
 
243
240
  lastDay() {
244
241
  let localeStartOfWeek = this.localeStartOfWeek;
245
- assert("The center of the calendar is an invalid date.", !isNaN(this.currentCenter.getTime()));
246
- let lastDay = endOf(this.currentCenter, 'month')
242
+ assert(
243
+ 'The center of the calendar is an invalid date.',
244
+ !isNaN(this.currentCenter.getTime()),
245
+ );
246
+ let lastDay = endOf(this.currentCenter, 'month');
247
247
  return endOfWeek(lastDay, localeStartOfWeek);
248
248
  }
249
249
 
250
250
  _updateFocused(id) {
251
- this.set('focusedId', id);
251
+ this.focusedId = id;
252
252
  }
253
253
 
254
254
  _focusDate(id) {
255
- let dayElement = document.querySelector(`[data-power-calendar-id="${this.calendar.uniqueId}"] [data-date="${id}"]`);
255
+ let dayElement = document.querySelector(
256
+ `[data-power-calendar-id="${this.args.calendar.uniqueId}"] [data-date="${id}"]`,
257
+ );
256
258
  if (dayElement) {
257
259
  dayElement.focus();
258
260
  }
@@ -263,10 +265,10 @@ export default class extends Component {
263
265
  let dayEl = e.target.closest('[data-date]');
264
266
  if (dayEl) {
265
267
  let dateStr = dayEl.dataset.date;
266
- let day = this.days.find(d => d.id === dateStr);
268
+ let day = this.days.find((d) => d.id === dateStr);
267
269
  if (day) {
268
- if (this.calendar.actions.select) {
269
- this.calendar.actions.select(day, this.calendar, e);
270
+ if (this.args.calendar.actions.select) {
271
+ this.args.calendar.actions.select(day, this.args.calendar, e);
270
272
  }
271
273
  }
272
274
  }
@@ -1,9 +1,11 @@
1
- import Component from '@ember/component';
2
- import templateLayout from '../../templates/components/power-calendar/nav';
1
+ import Component from '@glimmer/component';
3
2
 
4
3
  export default class extends Component {
5
- layout = templateLayout
6
- tagName = ''
7
- unit = 'month'
8
- format = 'MMMM YYYY'
4
+ get unit() {
5
+ return this.args.unit || 'month';
6
+ }
7
+
8
+ get format() {
9
+ return this.args.format || 'MMMM YYYY';
10
+ }
9
11
  }
@@ -1,19 +1,24 @@
1
1
  import DaysComponent from '../power-calendar/days';
2
- import fallbackIfUndefined from '../../utils/computed-fallback-if-undefined';
3
- import { isSame } from 'ember-power-calendar-utils';
2
+ import { isSame } from 'ember-power-calendar/utils';
4
3
 
5
4
  export default class extends DaysComponent {
6
- @fallbackIfUndefined(Infinity) maxLength
5
+ get maxLength() {
6
+ return this.args.maxLength || Infinity;
7
+ }
7
8
 
8
9
  // Methods
9
- dayIsSelected(date, calendar = this.calendar) {
10
+ dayIsSelected(date, calendar = this.args.calendar) {
10
11
  let selected = calendar.selected || [];
11
12
  return selected.some((d) => isSame(date, d, 'day'));
12
13
  }
13
14
 
14
15
  dayIsDisabled(date) {
15
- let numSelected = (this.calendar.selected && this.calendar.selected.length) || 0;
16
+ let numSelected =
17
+ (this.args.calendar.selected && this.args.calendar.selected.length) || 0;
16
18
  let maxLength = this.maxLength || Infinity;
17
- return super.dayIsDisabled(...arguments) || (numSelected >= maxLength && !this.dayIsSelected(date));
19
+ return (
20
+ super.dayIsDisabled(...arguments) ||
21
+ (numSelected >= maxLength && !this.dayIsSelected(date))
22
+ );
18
23
  }
19
24
  }
@@ -1,30 +1,33 @@
1
1
  import CalendarComponent from './power-calendar';
2
- import { computed, action } from '@ember/object';
2
+ import { action } from '@ember/object';
3
+ import { tracked } from '@glimmer/tracking';
3
4
  import {
4
5
  normalizeDate,
5
6
  isSame,
6
- normalizeMultipleActionValue
7
- } from 'ember-power-calendar-utils';
7
+ normalizeMultipleActionValue,
8
+ } from 'ember-power-calendar/utils';
8
9
  import { assert } from '@ember/debug';
9
10
  import { isArray } from '@ember/array';
10
- import PowerCalendarMultipleDaysComponent from './power-calendar-multiple/days'
11
+ import PowerCalendarMultipleDaysComponent from './power-calendar-multiple/days';
11
12
 
12
13
  export default class extends CalendarComponent {
13
- daysComponent = PowerCalendarMultipleDaysComponent
14
- _calendarType = 'multiple'
14
+ daysComponent = PowerCalendarMultipleDaysComponent;
15
+ _calendarType = 'multiple';
16
+
17
+ @tracked _selected;
15
18
 
16
- // CPs
17
- @computed
18
19
  get selected() {
19
- return undefined;
20
- }
21
- set selected(v) {
22
- return isArray(v) ? v.map(normalizeDate) : v;
20
+ if (this._selected) {
21
+ return this._selected;
22
+ }
23
+
24
+ const value = this.args.selected;
25
+
26
+ return isArray(value) ? value.map(normalizeDate) : value;
23
27
  }
24
28
 
25
- @computed('center')
26
29
  get currentCenter() {
27
- let center = this.center;
30
+ let center = this.args.center;
28
31
  if (!center) {
29
32
  center = (this.selected || [])[0] || this.powerCalendarService.getDate();
30
33
  }
@@ -36,7 +39,8 @@ export default class extends CalendarComponent {
36
39
  select(dayOrDays, calendar, e) {
37
40
  assert(
38
41
  `The select action expects an array of date objects, or a date object. ${typeof dayOrDays} was recieved instead.`,
39
- isArray(dayOrDays) || dayOrDays instanceof Object && dayOrDays.date instanceof Date
42
+ isArray(dayOrDays) ||
43
+ (dayOrDays instanceof Object && dayOrDays.date instanceof Date),
40
44
  );
41
45
 
42
46
  let days;
@@ -47,8 +51,8 @@ export default class extends CalendarComponent {
47
51
  days = [dayOrDays];
48
52
  }
49
53
 
50
- if (this.onSelect) {
51
- this.onSelect(this._buildCollection(days), calendar, e);
54
+ if (this.args.onSelect) {
55
+ this.args.onSelect(this._buildCollection(days), calendar, e);
52
56
  }
53
57
  }
54
58
 
@@ -57,7 +61,9 @@ export default class extends CalendarComponent {
57
61
  let selected = this.publicAPI.selected || [];
58
62
 
59
63
  for (let day of days) {
60
- let index = selected.findIndex(selectedDate => isSame(day.date, selectedDate, "day"));
64
+ let index = selected.findIndex((selectedDate) =>
65
+ isSame(day.date, selectedDate, 'day'),
66
+ );
61
67
  if (index === -1) {
62
68
  selected = [...selected, day.date];
63
69
  } else {
@@ -1,12 +1,11 @@
1
- import { getProperties } from '@ember/object';
2
1
  import DaysComponent from '../power-calendar/days';
3
- import { isBetween, isSame, diff } from 'ember-power-calendar-utils';
2
+ import { isBetween, isSame, diff } from 'ember-power-calendar/utils';
4
3
 
5
4
  export default class extends DaysComponent {
6
5
  // Methods
7
6
  buildDay(date, today, calendar) {
8
7
  let day = super.buildDay(...arguments);
9
- let { start, end } = getProperties(calendar.selected || { start: null, end: null }, 'start', 'end');
8
+ let { start, end } = calendar.selected || { start: null, end: null };
10
9
  if (start && end) {
11
10
  day.isSelected = isBetween(date, start, end, 'day', '[]');
12
11
  day.isRangeStart = day.isSelected && isSame(date, start, 'day');
@@ -19,8 +18,9 @@ export default class extends DaysComponent {
19
18
  day.isRangeStart = day.isSelected = isSame(date, start, 'day');
20
19
  if (!day.isDisabled) {
21
20
  let diffInMs = Math.abs(diff(day.date, start));
22
- day.isDisabled = diffInMs < calendar.minRange
23
- || calendar.maxRange !== null && diffInMs > calendar.maxRange;
21
+ day.isDisabled =
22
+ diffInMs < calendar.minRange ||
23
+ (calendar.maxRange !== null && diffInMs > calendar.maxRange);
24
24
  }
25
25
  }
26
26
  }