ember-power-calendar 0.18.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 +61 -58
  4. package/addon/components/power-calendar/nav.js +9 -6
  5. package/addon/components/power-calendar-multiple/days.js +11 -6
  6. package/addon/components/power-calendar-multiple.js +24 -17
  7. package/addon/components/power-calendar-range/days.js +5 -5
  8. package/addon/components/power-calendar-range.js +73 -39
  9. package/addon/{templates/components → components}/power-calendar.hbs +5 -3
  10. package/addon/components/power-calendar.js +51 -45
  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 +85 -51
  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,10 +1,9 @@
1
- import { layout, tagName } from "@ember-decorators/component";
2
- import Component from '@ember/component';
3
- import { computed, action } from '@ember/object';
1
+ import Component from '@glimmer/component';
2
+ import { tracked } from '@glimmer/tracking';
3
+ import { action } from '@ember/object';
4
4
  import { scheduleOnce } from '@ember/runloop';
5
5
  import { inject as service } from '@ember/service';
6
6
  import { assert } from '@ember/debug';
7
- import templateLayout from '../../templates/components/power-calendar/days';
8
7
  import {
9
8
  add,
10
9
  endOf,
@@ -22,71 +21,68 @@ import {
22
21
  startOf,
23
22
  startOfWeek,
24
23
  withLocale,
25
- } from 'ember-power-calendar-utils';
24
+ } from 'ember-power-calendar/utils';
26
25
 
27
- const WEEK_DAYS = [
28
- 'Mon',
29
- 'Tue',
30
- 'Wed',
31
- 'Thu',
32
- 'Fri',
33
- 'Sat',
34
- 'Sun'
35
- ];
26
+ const WEEK_DAYS = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
36
27
 
37
- export default @layout(templateLayout) @tagName('') class extends Component {
38
- focusedId = undefined
39
- showDaysAround = true
40
- weekdayFormat = 'short' // "min" | "short" | "long"
41
- @service('power-calendar') powerCalendarService
28
+ export default class extends Component {
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
+ }
42
42
 
43
- // CPs
44
- @computed('calendar.locale')
45
43
  get weekdaysMin() {
46
- return withLocale(this.calendar.locale, getWeekdaysMin);
44
+ return withLocale(this.args.calendar.locale, getWeekdaysMin);
47
45
  }
48
46
 
49
- @computed('calendar.locale')
50
47
  get weekdaysShort() {
51
- return withLocale(this.calendar.locale, getWeekdaysShort);
48
+ return withLocale(this.args.calendar.locale, getWeekdaysShort);
52
49
  }
53
50
 
54
- @computed('calendar.locale')
55
51
  get weekdays() {
56
- return withLocale(this.calendar.locale, getWeekdays);
52
+ return withLocale(this.args.calendar.locale, getWeekdays);
57
53
  }
58
54
 
59
- @computed('weekdaysShort', 'startOfWeek')
60
55
  get localeStartOfWeek() {
61
- let forcedStartOfWeek = this.startOfWeek;
56
+ let forcedStartOfWeek = this.args.startOfWeek;
62
57
  if (forcedStartOfWeek) {
63
58
  return parseInt(forcedStartOfWeek, 10);
64
59
  }
65
- return localeStartOfWeek(this.calendar.locale);
60
+ return localeStartOfWeek(this.args.calendar.locale);
66
61
  }
67
62
 
68
- @computed('localeStartOfWeek', 'weekdayFormat', 'calendar.locale')
69
63
  get weekdaysNames() {
70
64
  let { localeStartOfWeek, weekdayFormat } = this;
71
- let format = `weekdays${weekdayFormat === 'long' ? '' : (weekdayFormat === 'min' ? 'Min' : 'Short')}`;
65
+ let format = `weekdays${
66
+ weekdayFormat === 'long' ? '' : weekdayFormat === 'min' ? 'Min' : 'Short'
67
+ }`;
72
68
  let weekdaysNames = this[format];
73
- return weekdaysNames.slice(localeStartOfWeek).concat(weekdaysNames.slice(0, localeStartOfWeek));
69
+ return weekdaysNames
70
+ .slice(localeStartOfWeek)
71
+ .concat(weekdaysNames.slice(0, localeStartOfWeek));
74
72
  }
75
73
 
76
- @computed('calendar', 'focusedId', 'localeStartOfWeek', 'minDate', 'maxDate', 'disabledDates.[]', 'maxLength', 'currentCenter')
77
74
  get days() {
78
75
  let today = this.powerCalendarService.getDate();
79
76
  let lastDay = this.lastDay();
80
77
  let day = this.firstDay();
81
78
  let days = [];
82
79
  while (isBefore(day, lastDay)) {
83
- days.push(this.buildDay(day, today, this.calendar));
84
- day = add(day, 1, "day");
80
+ days.push(this.buildDay(day, today, this.args.calendar));
81
+ day = add(day, 1, 'day');
85
82
  }
86
83
  return days;
87
84
  }
88
85
 
89
- @computed('showDaysAround', 'days')
90
86
  get weeks() {
91
87
  let { showDaysAround, days } = this;
92
88
  let weeks = [];
@@ -99,18 +95,17 @@ export default @layout(templateLayout) @tagName('') class extends Component {
99
95
  weeks.push({
100
96
  id: `week-of-${daysOfWeek[0].id}`,
101
97
  days: daysOfWeek,
102
- missingDays: 7 - daysOfWeek.length
98
+ missingDays: 7 - daysOfWeek.length,
103
99
  });
104
100
  i += 7;
105
101
  }
106
102
  return weeks;
107
103
  }
108
104
 
109
- @computed('center', 'calendar.center')
110
105
  get currentCenter() {
111
- let center = this.center;
106
+ let center = this.args.center;
112
107
  if (!center) {
113
- center = this.selected || this.calendar.center;
108
+ center = this.args.selected || this.args.calendar.center;
114
109
  }
115
110
  return normalizeDate(center);
116
111
  }
@@ -175,14 +170,14 @@ export default @layout(templateLayout) @tagName('') class extends Component {
175
170
  } else {
176
171
  return;
177
172
  }
178
- this.set('focusedId', day.id);
173
+ this.focusedId = day.id;
179
174
  scheduleOnce('afterRender', this, '_focusDate', day.id);
180
175
  }
181
176
  }
182
177
 
183
178
  // Methods
184
179
  buildDay(date, today, calendar) {
185
- let id = formatDate(date, 'YYYY-MM-DD')
180
+ let id = formatDate(date, 'YYYY-MM-DD');
186
181
 
187
182
  return normalizeCalendarDay({
188
183
  id,
@@ -192,7 +187,7 @@ export default @layout(templateLayout) @tagName('') class extends Component {
192
187
  isFocused: this.focusedId === id,
193
188
  isCurrentMonth: date.getMonth() === this.currentCenter.getMonth(),
194
189
  isToday: isSame(date, today, 'day'),
195
- isSelected: this.dayIsSelected(date, calendar)
190
+ isSelected: this.dayIsSelected(date, calendar),
196
191
  });
197
192
  }
198
193
 
@@ -200,29 +195,32 @@ export default @layout(templateLayout) @tagName('') class extends Component {
200
195
  return day;
201
196
  }
202
197
 
203
- dayIsSelected(date, calendar = this.calendar) {
198
+ dayIsSelected(date, calendar = this.args.calendar) {
204
199
  return calendar.selected ? isSame(date, calendar.selected, 'day') : false;
205
200
  }
206
201
 
207
202
  dayIsDisabled(date) {
208
- let isDisabled = !this.calendar.actions.select;
203
+ let isDisabled = !this.args.calendar.actions.select;
209
204
  if (isDisabled) {
210
205
  return true;
211
206
  }
212
207
 
213
- if (this.minDate && isBefore(date, startOf(this.minDate, 'day'))) {
208
+ if (
209
+ this.args.minDate &&
210
+ isBefore(date, startOf(this.args.minDate, 'day'))
211
+ ) {
214
212
  return true;
215
213
  }
216
214
 
217
- if (this.maxDate && isAfter(date, endOf(this.maxDate, 'day'))) {
215
+ if (this.args.maxDate && isAfter(date, endOf(this.args.maxDate, 'day'))) {
218
216
  return true;
219
217
  }
220
218
 
221
-
222
- if (this.disabledDates) {
223
- let disabledInRange = this.disabledDates.some((d) => {
219
+ if (this.args.disabledDates) {
220
+ let disabledInRange = this.args.disabledDates.some((d) => {
224
221
  let isSameDay = isSame(date, d, 'day');
225
- let isWeekDayIncludes = WEEK_DAYS.indexOf(d) !== -1 && formatDate(date, 'ddd') === d;
222
+ let isWeekDayIncludes =
223
+ WEEK_DAYS.indexOf(d) !== -1 && formatDate(date, 'ddd') === d;
226
224
  return isSameDay || isWeekDayIncludes;
227
225
  });
228
226
 
@@ -241,17 +239,22 @@ export default @layout(templateLayout) @tagName('') class extends Component {
241
239
 
242
240
  lastDay() {
243
241
  let localeStartOfWeek = this.localeStartOfWeek;
244
- assert("The center of the calendar is an invalid date.", !isNaN(this.currentCenter.getTime()));
245
- 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');
246
247
  return endOfWeek(lastDay, localeStartOfWeek);
247
248
  }
248
249
 
249
250
  _updateFocused(id) {
250
- this.set('focusedId', id);
251
+ this.focusedId = id;
251
252
  }
252
253
 
253
254
  _focusDate(id) {
254
- 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
+ );
255
258
  if (dayElement) {
256
259
  dayElement.focus();
257
260
  }
@@ -262,10 +265,10 @@ export default @layout(templateLayout) @tagName('') class extends Component {
262
265
  let dayEl = e.target.closest('[data-date]');
263
266
  if (dayEl) {
264
267
  let dateStr = dayEl.dataset.date;
265
- let day = this.days.find(d => d.id === dateStr);
268
+ let day = this.days.find((d) => d.id === dateStr);
266
269
  if (day) {
267
- if (this.calendar.actions.select) {
268
- 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);
269
272
  }
270
273
  }
271
274
  }
@@ -1,8 +1,11 @@
1
- import Component from '@ember/component';
2
- import { layout, tagName } from "@ember-decorators/component";
3
- import templateLayout from '../../templates/components/power-calendar/nav';
1
+ import Component from '@glimmer/component';
4
2
 
5
- export default @layout(templateLayout) @tagName('') class extends Component {
6
- unit = 'month'
7
- format = 'MMMM YYYY'
3
+ export default class extends Component {
4
+ get unit() {
5
+ return this.args.unit || 'month';
6
+ }
7
+
8
+ get format() {
9
+ return this.args.format || 'MMMM YYYY';
10
+ }
8
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,29 +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';
11
+ import PowerCalendarMultipleDaysComponent from './power-calendar-multiple/days';
10
12
 
11
13
  export default class extends CalendarComponent {
12
- daysComponent = 'power-calendar-multiple/days'
13
- _calendarType = 'multiple'
14
+ daysComponent = PowerCalendarMultipleDaysComponent;
15
+ _calendarType = 'multiple';
16
+
17
+ @tracked _selected;
14
18
 
15
- // CPs
16
- @computed
17
19
  get selected() {
18
- return undefined;
19
- }
20
- set selected(v) {
21
- 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;
22
27
  }
23
28
 
24
- @computed('center')
25
29
  get currentCenter() {
26
- let center = this.center;
30
+ let center = this.args.center;
27
31
  if (!center) {
28
32
  center = (this.selected || [])[0] || this.powerCalendarService.getDate();
29
33
  }
@@ -35,7 +39,8 @@ export default class extends CalendarComponent {
35
39
  select(dayOrDays, calendar, e) {
36
40
  assert(
37
41
  `The select action expects an array of date objects, or a date object. ${typeof dayOrDays} was recieved instead.`,
38
- isArray(dayOrDays) || dayOrDays instanceof Object && dayOrDays.date instanceof Date
42
+ isArray(dayOrDays) ||
43
+ (dayOrDays instanceof Object && dayOrDays.date instanceof Date),
39
44
  );
40
45
 
41
46
  let days;
@@ -46,8 +51,8 @@ export default class extends CalendarComponent {
46
51
  days = [dayOrDays];
47
52
  }
48
53
 
49
- if (this.onSelect) {
50
- this.onSelect(this._buildCollection(days), calendar, e);
54
+ if (this.args.onSelect) {
55
+ this.args.onSelect(this._buildCollection(days), calendar, e);
51
56
  }
52
57
  }
53
58
 
@@ -56,7 +61,9 @@ export default class extends CalendarComponent {
56
61
  let selected = this.publicAPI.selected || [];
57
62
 
58
63
  for (let day of days) {
59
- let index = selected.findIndex(selectedDate => isSame(day.date, selectedDate, "day"));
64
+ let index = selected.findIndex((selectedDate) =>
65
+ isSame(day.date, selectedDate, 'day'),
66
+ );
60
67
  if (index === -1) {
61
68
  selected = [...selected, day.date];
62
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
  }