@fullcalendar/core 6.1.15 → 6.1.17

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 (170) hide show
  1. package/index.cjs +91 -21
  2. package/index.global.js +147 -74
  3. package/index.global.min.js +2 -2
  4. package/index.js +92 -22
  5. package/internal-common.cjs +105 -105
  6. package/internal-common.d.ts +19 -4
  7. package/internal-common.js +106 -103
  8. package/internal.js +1 -1
  9. package/locales/af.global.js +1 -1
  10. package/locales/af.global.min.js +1 -1
  11. package/locales/ar-dz.global.js +1 -1
  12. package/locales/ar-dz.global.min.js +1 -1
  13. package/locales/ar-kw.global.js +1 -1
  14. package/locales/ar-kw.global.min.js +1 -1
  15. package/locales/ar-ly.global.js +1 -1
  16. package/locales/ar-ly.global.min.js +1 -1
  17. package/locales/ar-ma.global.js +1 -1
  18. package/locales/ar-ma.global.min.js +1 -1
  19. package/locales/ar-sa.global.js +1 -1
  20. package/locales/ar-sa.global.min.js +1 -1
  21. package/locales/ar-tn.global.js +1 -1
  22. package/locales/ar-tn.global.min.js +1 -1
  23. package/locales/ar.global.js +1 -1
  24. package/locales/ar.global.min.js +1 -1
  25. package/locales/az.global.js +1 -1
  26. package/locales/az.global.min.js +1 -1
  27. package/locales/bg.global.js +1 -1
  28. package/locales/bg.global.min.js +1 -1
  29. package/locales/bn.global.js +1 -1
  30. package/locales/bn.global.min.js +1 -1
  31. package/locales/bs.global.js +1 -1
  32. package/locales/bs.global.min.js +1 -1
  33. package/locales/ca.global.js +1 -1
  34. package/locales/ca.global.min.js +1 -1
  35. package/locales/cs.global.js +1 -1
  36. package/locales/cs.global.min.js +1 -1
  37. package/locales/cy.global.js +1 -1
  38. package/locales/cy.global.min.js +1 -1
  39. package/locales/da.global.js +1 -1
  40. package/locales/da.global.min.js +1 -1
  41. package/locales/de-at.global.js +1 -1
  42. package/locales/de-at.global.min.js +1 -1
  43. package/locales/de.global.js +1 -1
  44. package/locales/de.global.min.js +1 -1
  45. package/locales/el.global.js +1 -1
  46. package/locales/el.global.min.js +1 -1
  47. package/locales/en-au.global.js +1 -1
  48. package/locales/en-au.global.min.js +1 -1
  49. package/locales/en-gb.global.js +1 -1
  50. package/locales/en-gb.global.min.js +1 -1
  51. package/locales/en-nz.global.js +1 -1
  52. package/locales/en-nz.global.min.js +1 -1
  53. package/locales/eo.global.js +1 -1
  54. package/locales/eo.global.min.js +1 -1
  55. package/locales/es-us.global.js +1 -1
  56. package/locales/es-us.global.min.js +1 -1
  57. package/locales/es.global.js +1 -1
  58. package/locales/es.global.min.js +1 -1
  59. package/locales/et.global.js +1 -1
  60. package/locales/et.global.min.js +1 -1
  61. package/locales/eu.global.js +1 -1
  62. package/locales/eu.global.min.js +1 -1
  63. package/locales/fa.global.js +1 -1
  64. package/locales/fa.global.min.js +1 -1
  65. package/locales/fi.global.js +1 -1
  66. package/locales/fi.global.min.js +1 -1
  67. package/locales/fr-ca.global.js +1 -1
  68. package/locales/fr-ca.global.min.js +1 -1
  69. package/locales/fr-ch.global.js +1 -1
  70. package/locales/fr-ch.global.min.js +1 -1
  71. package/locales/fr.global.js +1 -1
  72. package/locales/fr.global.min.js +1 -1
  73. package/locales/gl.global.js +1 -1
  74. package/locales/gl.global.min.js +1 -1
  75. package/locales/he.global.js +1 -1
  76. package/locales/he.global.min.js +1 -1
  77. package/locales/hi.global.js +1 -1
  78. package/locales/hi.global.min.js +1 -1
  79. package/locales/hr.global.js +1 -1
  80. package/locales/hr.global.min.js +1 -1
  81. package/locales/hu.global.js +1 -1
  82. package/locales/hu.global.min.js +1 -1
  83. package/locales/hy-am.global.js +1 -1
  84. package/locales/hy-am.global.min.js +1 -1
  85. package/locales/id.global.js +1 -1
  86. package/locales/id.global.min.js +1 -1
  87. package/locales/is.global.js +1 -1
  88. package/locales/is.global.min.js +1 -1
  89. package/locales/it.global.js +1 -1
  90. package/locales/it.global.min.js +1 -1
  91. package/locales/ja.global.js +1 -1
  92. package/locales/ja.global.min.js +1 -1
  93. package/locales/ka.global.js +1 -1
  94. package/locales/ka.global.min.js +1 -1
  95. package/locales/kk.global.js +1 -1
  96. package/locales/kk.global.min.js +1 -1
  97. package/locales/km.global.js +1 -1
  98. package/locales/km.global.min.js +1 -1
  99. package/locales/ko.global.js +1 -1
  100. package/locales/ko.global.min.js +1 -1
  101. package/locales/ku.global.js +1 -1
  102. package/locales/ku.global.min.js +1 -1
  103. package/locales/lb.global.js +1 -1
  104. package/locales/lb.global.min.js +1 -1
  105. package/locales/lt.global.js +1 -1
  106. package/locales/lt.global.min.js +1 -1
  107. package/locales/lv.global.js +1 -1
  108. package/locales/lv.global.min.js +1 -1
  109. package/locales/mk.global.js +1 -1
  110. package/locales/mk.global.min.js +1 -1
  111. package/locales/ms.global.js +1 -1
  112. package/locales/ms.global.min.js +1 -1
  113. package/locales/nb.global.js +1 -1
  114. package/locales/nb.global.min.js +1 -1
  115. package/locales/ne.global.js +1 -1
  116. package/locales/ne.global.min.js +1 -1
  117. package/locales/nl.global.js +1 -1
  118. package/locales/nl.global.min.js +1 -1
  119. package/locales/nn.global.js +1 -1
  120. package/locales/nn.global.min.js +1 -1
  121. package/locales/pl.global.js +1 -1
  122. package/locales/pl.global.min.js +1 -1
  123. package/locales/pt-br.global.js +1 -1
  124. package/locales/pt-br.global.min.js +1 -1
  125. package/locales/pt.global.js +1 -1
  126. package/locales/pt.global.min.js +1 -1
  127. package/locales/ro.global.js +1 -1
  128. package/locales/ro.global.min.js +1 -1
  129. package/locales/ru.global.js +1 -1
  130. package/locales/ru.global.min.js +1 -1
  131. package/locales/si-lk.global.js +1 -1
  132. package/locales/si-lk.global.min.js +1 -1
  133. package/locales/sk.global.js +1 -1
  134. package/locales/sk.global.min.js +1 -1
  135. package/locales/sl.global.js +1 -1
  136. package/locales/sl.global.min.js +1 -1
  137. package/locales/sm.global.js +1 -1
  138. package/locales/sm.global.min.js +1 -1
  139. package/locales/sq.global.js +1 -1
  140. package/locales/sq.global.min.js +1 -1
  141. package/locales/sr-cyrl.global.js +1 -1
  142. package/locales/sr-cyrl.global.min.js +1 -1
  143. package/locales/sr.global.js +1 -1
  144. package/locales/sr.global.min.js +1 -1
  145. package/locales/sv.global.js +1 -1
  146. package/locales/sv.global.min.js +1 -1
  147. package/locales/ta-in.global.js +1 -1
  148. package/locales/ta-in.global.min.js +1 -1
  149. package/locales/th.global.js +1 -1
  150. package/locales/th.global.min.js +1 -1
  151. package/locales/tr.global.js +1 -1
  152. package/locales/tr.global.min.js +1 -1
  153. package/locales/ug.global.js +1 -1
  154. package/locales/ug.global.min.js +1 -1
  155. package/locales/uk.global.js +1 -1
  156. package/locales/uk.global.min.js +1 -1
  157. package/locales/uz-cy.global.js +1 -1
  158. package/locales/uz-cy.global.min.js +1 -1
  159. package/locales/uz.global.js +1 -1
  160. package/locales/uz.global.min.js +1 -1
  161. package/locales/vi.global.js +1 -1
  162. package/locales/vi.global.min.js +1 -1
  163. package/locales/zh-cn.global.js +1 -1
  164. package/locales/zh-cn.global.min.js +1 -1
  165. package/locales/zh-tw.global.js +1 -1
  166. package/locales/zh-tw.global.min.js +1 -1
  167. package/locales-all.global.js +1 -1
  168. package/locales-all.global.min.js +1 -1
  169. package/package.json +1 -1
  170. package/preact.js +1 -1
package/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { m as mergeProps, g as guid, i as isArraysEqual, T as Theme, a as mapHash, B as BaseComponent, V as ViewContextType, C as ContentContainer, b as buildViewClassNames, c as greatestDurationDenominator, d as createDuration, e as BASE_OPTION_DEFAULTS, f as arrayToHash, h as filterHash, j as buildEventSourceRefiners, p as parseEventSource, k as formatWithOrdinals, u as unpromisify, l as buildRangeApiWithTimeZone, n as identity, r as requestJson, s as subtractDurations, o as intersectRanges, q as startOfDay, t as addDays, v as hashValuesToArray, w as buildEventApis, D as DelayedRunner, x as createFormatter, y as diffWholeDays, z as memoize, A as memoizeObjArg, E as isPropsEqual, F as Emitter, G as getInitialDate, H as rangeContainsMarker, I as createEmptyEventStore, J as reduceCurrentDate, K as reduceEventStore, L as rezoneEventStoreDates, M as mergeRawOptions, N as BASE_OPTION_REFINERS, O as CALENDAR_LISTENER_REFINERS, P as CALENDAR_OPTION_REFINERS, Q as COMPLEX_OPTION_COMPARATORS, R as VIEW_OPTION_REFINERS, S as DateEnv, U as DateProfileGenerator, W as createEventUi, X as parseBusinessHours, Y as setRef, Z as Interaction, _ as getElSeg, $ as elementClosest, a0 as EventImpl, a1 as listenBySelector, a2 as listenToHoverBySelector, a3 as PureComponent, a4 as buildViewContext, a5 as getUniqueDomId, a6 as parseInteractionSettings, a7 as interactionSettingsStore, a8 as getNow, a9 as CalendarImpl, aa as flushSync, ab as CalendarRoot, ac as RenderId, ad as ensureElHasStyles, ae as applyStyleProp, af as sliceEventStore } from './internal-common.js';
2
- export { ag as JsonRequestError } from './internal-common.js';
1
+ import { m as mergeProps, g as guid, i as isArraysEqual, T as Theme, a as mapHash, B as BaseComponent, V as ViewContextType, C as ContentContainer, b as buildViewClassNames, c as greatestDurationDenominator, d as createDuration, e as BASE_OPTION_DEFAULTS, f as arrayToHash, h as filterHash, j as buildEventSourceRefiners, p as parseEventSource, k as formatWithOrdinals, u as unpromisify, l as buildRangeApiWithTimeZone, n as identity, r as requestJson, s as subtractDurations, o as intersectRanges, q as startOfDay, t as addDays, v as hashValuesToArray, w as buildEventApis, D as DelayedRunner, x as createFormatter, y as diffWholeDays, z as memoize, A as memoizeObjArg, E as isPropsEqual, F as Emitter, G as rangeContainsMarker, H as createEmptyEventStore, I as reduceEventStore, J as rezoneEventStoreDates, K as mergeRawOptions, L as BASE_OPTION_REFINERS, M as CALENDAR_LISTENER_REFINERS, N as CALENDAR_OPTION_REFINERS, O as COMPLEX_OPTION_COMPARATORS, P as VIEW_OPTION_REFINERS, Q as DateEnv, R as DateProfileGenerator, S as createEventUi, U as parseBusinessHours, W as setRef, X as Interaction, Y as getElSeg, Z as elementClosest, _ as EventImpl, $ as listenBySelector, a0 as listenToHoverBySelector, a1 as PureComponent, a2 as buildViewContext, a3 as getUniqueDomId, a4 as parseInteractionSettings, a5 as interactionSettingsStore, a6 as NowTimer, a7 as CalendarImpl, a8 as flushSync, a9 as CalendarRoot, aa as RenderId, ab as ensureElHasStyles, ac as applyStyleProp, ad as sliceEventStore } from './internal-common.js';
2
+ export { ae as JsonRequestError } from './internal-common.js';
3
3
  import { createElement, createRef, Fragment, render } from 'preact';
4
4
  import 'preact/compat';
5
5
 
@@ -459,6 +459,25 @@ function reduceViewType(viewType, action) {
459
459
  return viewType;
460
460
  }
461
461
 
462
+ function reduceCurrentDate(currentDate, action) {
463
+ switch (action.type) {
464
+ case 'CHANGE_DATE':
465
+ return action.dateMarker;
466
+ default:
467
+ return currentDate;
468
+ }
469
+ }
470
+ // should be initialized once and stay constant
471
+ // this will change too
472
+ function getInitialDate(options, dateEnv, nowManager) {
473
+ let initialDateInput = options.initialDate;
474
+ // compute the initial ambig-timezone date
475
+ if (initialDateInput != null) {
476
+ return dateEnv.createMarker(initialDateInput);
477
+ }
478
+ return nowManager.getDateMarker();
479
+ }
480
+
462
481
  function reduceDynamicOptionOverrides(dynamicOptionOverrides, action) {
463
482
  switch (action.type) {
464
483
  case 'SET_OPTION':
@@ -968,6 +987,7 @@ let recurring = {
968
987
  endTime: refined.endTime || null,
969
988
  startRecur: refined.startRecur ? dateEnv.createMarker(refined.startRecur) : null,
970
989
  endRecur: refined.endRecur ? dateEnv.createMarker(refined.endRecur) : null,
990
+ dateEnv,
971
991
  };
972
992
  let duration;
973
993
  if (refined.duration) {
@@ -987,7 +1007,7 @@ let recurring = {
987
1007
  expand(typeData, framingRange, dateEnv) {
988
1008
  let clippedFramingRange = intersectRanges(framingRange, { start: typeData.startRecur, end: typeData.endRecur });
989
1009
  if (clippedFramingRange) {
990
- return expandRanges(typeData.daysOfWeek, typeData.startTime, clippedFramingRange, dateEnv);
1010
+ return expandRanges(typeData.daysOfWeek, typeData.startTime, typeData.dateEnv, dateEnv, clippedFramingRange);
991
1011
  }
992
1012
  return [];
993
1013
  },
@@ -997,7 +1017,7 @@ const simpleRecurringEventsPlugin = createPlugin({
997
1017
  recurringTypes: [recurring],
998
1018
  eventRefiners: SIMPLE_RECURRING_REFINERS,
999
1019
  });
1000
- function expandRanges(daysOfWeek, startTime, framingRange, dateEnv) {
1020
+ function expandRanges(daysOfWeek, startTime, eventDateEnv, calendarDateEnv, framingRange) {
1001
1021
  let dowHash = daysOfWeek ? arrayToHash(daysOfWeek) : null;
1002
1022
  let dayMarker = startOfDay(framingRange.start);
1003
1023
  let endMarker = framingRange.end;
@@ -1007,12 +1027,12 @@ function expandRanges(daysOfWeek, startTime, framingRange, dateEnv) {
1007
1027
  // if everyday, or this particular day-of-week
1008
1028
  if (!dowHash || dowHash[dayMarker.getUTCDay()]) {
1009
1029
  if (startTime) {
1010
- instanceStart = dateEnv.add(dayMarker, startTime);
1030
+ instanceStart = calendarDateEnv.add(dayMarker, startTime);
1011
1031
  }
1012
1032
  else {
1013
1033
  instanceStart = dayMarker;
1014
1034
  }
1015
- instanceStarts.push(instanceStart);
1035
+ instanceStarts.push(calendarDateEnv.createMarker(eventDateEnv.toDate(instanceStart)));
1016
1036
  }
1017
1037
  dayMarker = addDays(dayMarker, 1);
1018
1038
  }
@@ -1177,6 +1197,49 @@ function buildTitleFormat(dateProfile) {
1177
1197
  return { year: 'numeric', month: 'long', day: 'numeric' };
1178
1198
  }
1179
1199
 
1200
+ /*
1201
+ TODO: test switching timezones when NO timezone plugin
1202
+ */
1203
+ class CalendarNowManager {
1204
+ constructor() {
1205
+ this.resetListeners = new Set();
1206
+ }
1207
+ handleInput(dateEnv, // will change if timezone setup changed
1208
+ nowInput) {
1209
+ const oldDateEnv = this.dateEnv;
1210
+ if (dateEnv !== oldDateEnv) {
1211
+ if (typeof nowInput === 'function') {
1212
+ this.nowFn = nowInput;
1213
+ }
1214
+ else if (!oldDateEnv) { // first time?
1215
+ this.nowAnchorDate = dateEnv.toDate(nowInput
1216
+ ? dateEnv.createMarker(nowInput)
1217
+ : dateEnv.createNowMarker());
1218
+ this.nowAnchorQueried = Date.now();
1219
+ }
1220
+ this.dateEnv = dateEnv;
1221
+ // not first time? fire reset handlers
1222
+ if (oldDateEnv) {
1223
+ for (const resetListener of this.resetListeners.values()) {
1224
+ resetListener();
1225
+ }
1226
+ }
1227
+ }
1228
+ }
1229
+ getDateMarker() {
1230
+ return this.nowAnchorDate
1231
+ ? this.dateEnv.timestampToMarker(this.nowAnchorDate.valueOf() +
1232
+ (Date.now() - this.nowAnchorQueried))
1233
+ : this.dateEnv.createMarker(this.nowFn());
1234
+ }
1235
+ addResetListener(handler) {
1236
+ this.resetListeners.add(handler);
1237
+ }
1238
+ removeResetListener(handler) {
1239
+ this.resetListeners.delete(handler);
1240
+ }
1241
+ }
1242
+
1180
1243
  // in future refactor, do the redux-style function(state=initial) for initial-state
1181
1244
  // also, whatever is happening in constructor, have it happen in action queue too
1182
1245
  class CalendarDataManager {
@@ -1196,6 +1259,7 @@ class CalendarDataManager {
1196
1259
  this.buildEventUiBases = memoize(buildEventUiBases);
1197
1260
  this.parseContextBusinessHours = memoizeObjArg(parseContextBusinessHours);
1198
1261
  this.buildTitle = memoize(buildTitle);
1262
+ this.nowManager = new CalendarNowManager();
1199
1263
  this.emitter = new Emitter();
1200
1264
  this.actionRunner = new TaskRunner(this._handleAction.bind(this), this.updateData.bind(this));
1201
1265
  this.currentCalendarOptionsInput = {};
@@ -1211,6 +1275,7 @@ class CalendarDataManager {
1211
1275
  };
1212
1276
  this.props = props;
1213
1277
  this.actionRunner.pause();
1278
+ this.nowManager = new CalendarNowManager();
1214
1279
  let dynamicOptionOverrides = {};
1215
1280
  let optionsData = this.computeOptionsData(props.optionOverrides, dynamicOptionOverrides, props.calendarApi);
1216
1281
  let currentViewType = optionsData.calendarOptions.initialView || optionsData.pluginHooks.initialView;
@@ -1220,12 +1285,8 @@ class CalendarDataManager {
1220
1285
  props.calendarApi.currentDataManager = this;
1221
1286
  this.emitter.setThisContext(props.calendarApi);
1222
1287
  this.emitter.setOptions(currentViewData.options);
1223
- let currentDate = getInitialDate(optionsData.calendarOptions, optionsData.dateEnv);
1224
- let dateProfile = currentViewData.dateProfileGenerator.build(currentDate);
1225
- if (!rangeContainsMarker(dateProfile.activeRange, currentDate)) {
1226
- currentDate = dateProfile.currentRange.start;
1227
- }
1228
1288
  let calendarContext = {
1289
+ nowManager: this.nowManager,
1229
1290
  dateEnv: optionsData.dateEnv,
1230
1291
  options: optionsData.calendarOptions,
1231
1292
  pluginHooks: optionsData.pluginHooks,
@@ -1234,6 +1295,11 @@ class CalendarDataManager {
1234
1295
  emitter: this.emitter,
1235
1296
  getCurrentData: this.getCurrentData,
1236
1297
  };
1298
+ let currentDate = getInitialDate(optionsData.calendarOptions, optionsData.dateEnv, this.nowManager);
1299
+ let dateProfile = currentViewData.dateProfileGenerator.build(currentDate);
1300
+ if (!rangeContainsMarker(dateProfile.activeRange, currentDate)) {
1301
+ currentDate = dateProfile.currentRange.start;
1302
+ }
1237
1303
  // needs to be after setThisContext
1238
1304
  for (let callback of optionsData.pluginHooks.contextInit) {
1239
1305
  callback(calendarContext);
@@ -1294,6 +1360,7 @@ class CalendarDataManager {
1294
1360
  emitter.setThisContext(props.calendarApi);
1295
1361
  emitter.setOptions(currentViewData.options);
1296
1362
  let calendarContext = {
1363
+ nowManager: this.nowManager,
1297
1364
  dateEnv: optionsData.dateEnv,
1298
1365
  options: optionsData.calendarOptions,
1299
1366
  pluginHooks: optionsData.pluginHooks,
@@ -1361,7 +1428,7 @@ class CalendarDataManager {
1361
1428
  let oldData = this.data;
1362
1429
  let optionsData = this.computeOptionsData(props.optionOverrides, state.dynamicOptionOverrides, props.calendarApi);
1363
1430
  let currentViewData = this.computeCurrentViewData(state.currentViewType, optionsData, props.optionOverrides, state.dynamicOptionOverrides);
1364
- let data = this.data = Object.assign(Object.assign(Object.assign({ viewTitle: this.buildTitle(state.dateProfile, currentViewData.options, optionsData.dateEnv), calendarApi: props.calendarApi, dispatch: this.dispatch, emitter: this.emitter, getCurrentData: this.getCurrentData }, optionsData), currentViewData), state);
1431
+ let data = this.data = Object.assign(Object.assign(Object.assign({ nowManager: this.nowManager, viewTitle: this.buildTitle(state.dateProfile, currentViewData.options, optionsData.dateEnv), calendarApi: props.calendarApi, dispatch: this.dispatch, emitter: this.emitter, getCurrentData: this.getCurrentData }, optionsData), currentViewData), state);
1365
1432
  let changeHandlers = optionsData.pluginHooks.optionChangeHandlers;
1366
1433
  let oldCalendarOptions = oldData && oldData.calendarOptions;
1367
1434
  let newCalendarOptions = optionsData.calendarOptions;
@@ -1469,8 +1536,10 @@ class CalendarDataManager {
1469
1536
  }
1470
1537
  let { refinedOptions, extra } = this.processRawViewOptions(viewSpec, optionsData.pluginHooks, optionsData.localeDefaults, optionOverrides, dynamicOptionOverrides);
1471
1538
  warnUnknownOptions(extra);
1539
+ this.nowManager.handleInput(optionsData.dateEnv, refinedOptions.now);
1472
1540
  let dateProfileGenerator = this.buildDateProfileGenerator({
1473
1541
  dateProfileGeneratorClass: viewSpec.optionDefaults.dateProfileGeneratorClass,
1542
+ nowManager: this.nowManager,
1474
1543
  duration: viewSpec.duration,
1475
1544
  durationUnit: viewSpec.durationUnit,
1476
1545
  usesMinMaxTime: viewSpec.optionDefaults.usesMinMaxTime,
@@ -1484,7 +1553,6 @@ class CalendarDataManager {
1484
1553
  dateIncrement: refinedOptions.dateIncrement,
1485
1554
  hiddenDays: refinedOptions.hiddenDays,
1486
1555
  weekends: refinedOptions.weekends,
1487
- nowInput: refinedOptions.now,
1488
1556
  validRangeInput: refinedOptions.validRange,
1489
1557
  visibleRangeInput: refinedOptions.visibleRange,
1490
1558
  fixedWeekCount: refinedOptions.fixedWeekCount,
@@ -1888,8 +1956,6 @@ class CalendarContent extends PureComponent {
1888
1956
  render() {
1889
1957
  let { props } = this;
1890
1958
  let { toolbarConfig, options } = props;
1891
- let toolbarProps = this.buildToolbarProps(props.viewSpec, props.dateProfile, props.dateProfileGenerator, props.currentDate, getNow(props.options.now, props.dateEnv), // TODO: use NowTimer????
1892
- props.viewTitle);
1893
1959
  let viewVGrow = false;
1894
1960
  let viewHeight = '';
1895
1961
  let viewAspectRatio;
@@ -1905,16 +1971,20 @@ class CalendarContent extends PureComponent {
1905
1971
  else {
1906
1972
  viewAspectRatio = Math.max(options.aspectRatio, 0.5); // prevent from getting too tall
1907
1973
  }
1908
- let viewContext = this.buildViewContext(props.viewSpec, props.viewApi, props.options, props.dateProfileGenerator, props.dateEnv, props.theme, props.pluginHooks, props.dispatch, props.getCurrentData, props.emitter, props.calendarApi, this.registerInteractiveComponent, this.unregisterInteractiveComponent);
1974
+ let viewContext = this.buildViewContext(props.viewSpec, props.viewApi, props.options, props.dateProfileGenerator, props.dateEnv, props.nowManager, props.theme, props.pluginHooks, props.dispatch, props.getCurrentData, props.emitter, props.calendarApi, this.registerInteractiveComponent, this.unregisterInteractiveComponent);
1909
1975
  let viewLabelId = (toolbarConfig.header && toolbarConfig.header.hasTitle)
1910
1976
  ? this.state.viewLabelId
1911
1977
  : undefined;
1912
1978
  return (createElement(ViewContextType.Provider, { value: viewContext },
1913
- toolbarConfig.header && (createElement(Toolbar, Object.assign({ ref: this.headerRef, extraClassName: "fc-header-toolbar", model: toolbarConfig.header, titleId: viewLabelId }, toolbarProps))),
1914
- createElement(ViewHarness, { liquid: viewVGrow, height: viewHeight, aspectRatio: viewAspectRatio, labeledById: viewLabelId },
1915
- this.renderView(props),
1916
- this.buildAppendContent()),
1917
- toolbarConfig.footer && (createElement(Toolbar, Object.assign({ ref: this.footerRef, extraClassName: "fc-footer-toolbar", model: toolbarConfig.footer, titleId: "" }, toolbarProps)))));
1979
+ createElement(NowTimer, { unit: "day" }, (nowDate) => {
1980
+ let toolbarProps = this.buildToolbarProps(props.viewSpec, props.dateProfile, props.dateProfileGenerator, props.currentDate, nowDate, props.viewTitle);
1981
+ return (createElement(Fragment, null,
1982
+ toolbarConfig.header && (createElement(Toolbar, Object.assign({ ref: this.headerRef, extraClassName: "fc-header-toolbar", model: toolbarConfig.header, titleId: viewLabelId }, toolbarProps))),
1983
+ createElement(ViewHarness, { liquid: viewVGrow, height: viewHeight, aspectRatio: viewAspectRatio, labeledById: viewLabelId },
1984
+ this.renderView(props),
1985
+ this.buildAppendContent()),
1986
+ toolbarConfig.footer && (createElement(Toolbar, Object.assign({ ref: this.footerRef, extraClassName: "fc-footer-toolbar", model: toolbarConfig.footer, titleId: "" }, toolbarProps)))));
1987
+ })));
1918
1988
  }
1919
1989
  componentDidMount() {
1920
1990
  let { props } = this;
@@ -2136,6 +2206,6 @@ function sliceEvents(props, allDay) {
2136
2206
  return sliceEventStore(props.eventStore, props.eventUiBases, props.dateProfile.activeRange, allDay ? props.nextDayThreshold : null).fg;
2137
2207
  }
2138
2208
 
2139
- const version = '6.1.15';
2209
+ const version = '6.1.17';
2140
2210
 
2141
2211
  export { Calendar, createPlugin, formatDate, formatRange, globalLocales, globalPlugins, sliceEvents, version };
@@ -103,7 +103,7 @@ if (typeof document !== 'undefined') {
103
103
  registerStylesRoot(document);
104
104
  }
105
105
 
106
- var css_248z = ":root{--fc-small-font-size:.85em;--fc-page-bg-color:#fff;--fc-neutral-bg-color:hsla(0,0%,82%,.3);--fc-neutral-text-color:grey;--fc-border-color:#ddd;--fc-button-text-color:#fff;--fc-button-bg-color:#2c3e50;--fc-button-border-color:#2c3e50;--fc-button-hover-bg-color:#1e2b37;--fc-button-hover-border-color:#1a252f;--fc-button-active-bg-color:#1a252f;--fc-button-active-border-color:#151e27;--fc-event-bg-color:#3788d8;--fc-event-border-color:#3788d8;--fc-event-text-color:#fff;--fc-event-selected-overlay-color:rgba(0,0,0,.25);--fc-more-link-bg-color:#d0d0d0;--fc-more-link-text-color:inherit;--fc-event-resizer-thickness:8px;--fc-event-resizer-dot-total-width:8px;--fc-event-resizer-dot-border-width:1px;--fc-non-business-color:hsla(0,0%,84%,.3);--fc-bg-event-color:#8fdf82;--fc-bg-event-opacity:0.3;--fc-highlight-color:rgba(188,232,241,.3);--fc-today-bg-color:rgba(255,220,40,.15);--fc-now-indicator-color:red}.fc-not-allowed,.fc-not-allowed .fc-event{cursor:not-allowed}.fc{display:flex;flex-direction:column;font-size:1em}.fc,.fc *,.fc :after,.fc :before{box-sizing:border-box}.fc table{border-collapse:collapse;border-spacing:0;font-size:1em}.fc th{text-align:center}.fc td,.fc th{padding:0;vertical-align:top}.fc a[data-navlink]{cursor:pointer}.fc a[data-navlink]:hover{text-decoration:underline}.fc-direction-ltr{direction:ltr;text-align:left}.fc-direction-rtl{direction:rtl;text-align:right}.fc-theme-standard td,.fc-theme-standard th{border:1px solid var(--fc-border-color)}.fc-liquid-hack td,.fc-liquid-hack th{position:relative}@font-face{font-family:fcicons;font-style:normal;font-weight:400;src:url(\"data:application/x-font-ttf;charset=utf-8;base64,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\") format(\"truetype\")}.fc-icon{speak:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;display:inline-block;font-family:fcicons!important;font-style:normal;font-variant:normal;font-weight:400;height:1em;line-height:1;text-align:center;text-transform:none;-moz-user-select:none;user-select:none;width:1em}.fc-icon-chevron-left:before{content:\"\\e900\"}.fc-icon-chevron-right:before{content:\"\\e901\"}.fc-icon-chevrons-left:before{content:\"\\e902\"}.fc-icon-chevrons-right:before{content:\"\\e903\"}.fc-icon-minus-square:before{content:\"\\e904\"}.fc-icon-plus-square:before{content:\"\\e905\"}.fc-icon-x:before{content:\"\\e906\"}.fc .fc-button{border-radius:0;font-family:inherit;font-size:inherit;line-height:inherit;margin:0;overflow:visible;text-transform:none}.fc .fc-button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}.fc .fc-button{-webkit-appearance:button}.fc .fc-button:not(:disabled){cursor:pointer}.fc .fc-button{background-color:transparent;border:1px solid transparent;border-radius:.25em;display:inline-block;font-size:1em;font-weight:400;line-height:1.5;padding:.4em .65em;text-align:center;-moz-user-select:none;user-select:none;vertical-align:middle}.fc .fc-button:hover{text-decoration:none}.fc .fc-button:focus{box-shadow:0 0 0 .2rem rgba(44,62,80,.25);outline:0}.fc .fc-button:disabled{opacity:.65}.fc .fc-button-primary{background-color:var(--fc-button-bg-color);border-color:var(--fc-button-border-color);color:var(--fc-button-text-color)}.fc .fc-button-primary:hover{background-color:var(--fc-button-hover-bg-color);border-color:var(--fc-button-hover-border-color);color:var(--fc-button-text-color)}.fc .fc-button-primary:disabled{background-color:var(--fc-button-bg-color);border-color:var(--fc-button-border-color);color:var(--fc-button-text-color)}.fc .fc-button-primary:focus{box-shadow:0 0 0 .2rem rgba(76,91,106,.5)}.fc .fc-button-primary:not(:disabled).fc-button-active,.fc .fc-button-primary:not(:disabled):active{background-color:var(--fc-button-active-bg-color);border-color:var(--fc-button-active-border-color);color:var(--fc-button-text-color)}.fc .fc-button-primary:not(:disabled).fc-button-active:focus,.fc .fc-button-primary:not(:disabled):active:focus{box-shadow:0 0 0 .2rem rgba(76,91,106,.5)}.fc .fc-button .fc-icon{font-size:1.5em;vertical-align:middle}.fc .fc-button-group{display:inline-flex;position:relative;vertical-align:middle}.fc .fc-button-group>.fc-button{flex:1 1 auto;position:relative}.fc .fc-button-group>.fc-button.fc-button-active,.fc .fc-button-group>.fc-button:active,.fc .fc-button-group>.fc-button:focus,.fc .fc-button-group>.fc-button:hover{z-index:1}.fc-direction-ltr .fc-button-group>.fc-button:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0;margin-left:-1px}.fc-direction-ltr .fc-button-group>.fc-button:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}.fc-direction-rtl .fc-button-group>.fc-button:not(:first-child){border-bottom-right-radius:0;border-top-right-radius:0;margin-right:-1px}.fc-direction-rtl .fc-button-group>.fc-button:not(:last-child){border-bottom-left-radius:0;border-top-left-radius:0}.fc .fc-toolbar{align-items:center;display:flex;justify-content:space-between}.fc .fc-toolbar.fc-header-toolbar{margin-bottom:1.5em}.fc .fc-toolbar.fc-footer-toolbar{margin-top:1.5em}.fc .fc-toolbar-title{font-size:1.75em;margin:0}.fc-direction-ltr .fc-toolbar>*>:not(:first-child){margin-left:.75em}.fc-direction-rtl .fc-toolbar>*>:not(:first-child){margin-right:.75em}.fc-direction-rtl .fc-toolbar-ltr{flex-direction:row-reverse}.fc .fc-scroller{-webkit-overflow-scrolling:touch;position:relative}.fc .fc-scroller-liquid{height:100%}.fc .fc-scroller-liquid-absolute{bottom:0;left:0;position:absolute;right:0;top:0}.fc .fc-scroller-harness{direction:ltr;overflow:hidden;position:relative}.fc .fc-scroller-harness-liquid{height:100%}.fc-direction-rtl .fc-scroller-harness>.fc-scroller{direction:rtl}.fc-theme-standard .fc-scrollgrid{border:1px solid var(--fc-border-color)}.fc .fc-scrollgrid,.fc .fc-scrollgrid table{table-layout:fixed;width:100%}.fc .fc-scrollgrid table{border-left-style:hidden;border-right-style:hidden;border-top-style:hidden}.fc .fc-scrollgrid{border-bottom-width:0;border-collapse:separate;border-right-width:0}.fc .fc-scrollgrid-liquid{height:100%}.fc .fc-scrollgrid-section,.fc .fc-scrollgrid-section table,.fc .fc-scrollgrid-section>td{height:1px}.fc .fc-scrollgrid-section-liquid>td{height:100%}.fc .fc-scrollgrid-section>*{border-left-width:0;border-top-width:0}.fc .fc-scrollgrid-section-footer>*,.fc .fc-scrollgrid-section-header>*{border-bottom-width:0}.fc .fc-scrollgrid-section-body table,.fc .fc-scrollgrid-section-footer table{border-bottom-style:hidden}.fc .fc-scrollgrid-section-sticky>*{background:var(--fc-page-bg-color);position:sticky;z-index:3}.fc .fc-scrollgrid-section-header.fc-scrollgrid-section-sticky>*{top:0}.fc .fc-scrollgrid-section-footer.fc-scrollgrid-section-sticky>*{bottom:0}.fc .fc-scrollgrid-sticky-shim{height:1px;margin-bottom:-1px}.fc-sticky{position:sticky}.fc .fc-view-harness{flex-grow:1;position:relative}.fc .fc-view-harness-active>.fc-view{bottom:0;left:0;position:absolute;right:0;top:0}.fc .fc-col-header-cell-cushion{display:inline-block;padding:2px 4px}.fc .fc-bg-event,.fc .fc-highlight,.fc .fc-non-business{bottom:0;left:0;position:absolute;right:0;top:0}.fc .fc-non-business{background:var(--fc-non-business-color)}.fc .fc-bg-event{background:var(--fc-bg-event-color);opacity:var(--fc-bg-event-opacity)}.fc .fc-bg-event .fc-event-title{font-size:var(--fc-small-font-size);font-style:italic;margin:.5em}.fc .fc-highlight{background:var(--fc-highlight-color)}.fc .fc-cell-shaded,.fc .fc-day-disabled{background:var(--fc-neutral-bg-color)}a.fc-event,a.fc-event:hover{text-decoration:none}.fc-event.fc-event-draggable,.fc-event[href]{cursor:pointer}.fc-event .fc-event-main{position:relative;z-index:2}.fc-event-dragging:not(.fc-event-selected){opacity:.75}.fc-event-dragging.fc-event-selected{box-shadow:0 2px 7px rgba(0,0,0,.3)}.fc-event .fc-event-resizer{display:none;position:absolute;z-index:4}.fc-event-selected .fc-event-resizer,.fc-event:hover .fc-event-resizer{display:block}.fc-event-selected .fc-event-resizer{background:var(--fc-page-bg-color);border-color:inherit;border-radius:calc(var(--fc-event-resizer-dot-total-width)/2);border-style:solid;border-width:var(--fc-event-resizer-dot-border-width);height:var(--fc-event-resizer-dot-total-width);width:var(--fc-event-resizer-dot-total-width)}.fc-event-selected .fc-event-resizer:before{bottom:-20px;content:\"\";left:-20px;position:absolute;right:-20px;top:-20px}.fc-event-selected,.fc-event:focus{box-shadow:0 2px 5px rgba(0,0,0,.2)}.fc-event-selected:before,.fc-event:focus:before{bottom:0;content:\"\";left:0;position:absolute;right:0;top:0;z-index:3}.fc-event-selected:after,.fc-event:focus:after{background:var(--fc-event-selected-overlay-color);bottom:-1px;content:\"\";left:-1px;position:absolute;right:-1px;top:-1px;z-index:1}.fc-h-event{background-color:var(--fc-event-bg-color);border:1px solid var(--fc-event-border-color);display:block}.fc-h-event .fc-event-main{color:var(--fc-event-text-color)}.fc-h-event .fc-event-main-frame{display:flex}.fc-h-event .fc-event-time{max-width:100%;overflow:hidden}.fc-h-event .fc-event-title-container{flex-grow:1;flex-shrink:1;min-width:0}.fc-h-event .fc-event-title{display:inline-block;left:0;max-width:100%;overflow:hidden;right:0;vertical-align:top}.fc-h-event.fc-event-selected:before{bottom:-10px;top:-10px}.fc-direction-ltr .fc-daygrid-block-event:not(.fc-event-start),.fc-direction-rtl .fc-daygrid-block-event:not(.fc-event-end){border-bottom-left-radius:0;border-left-width:0;border-top-left-radius:0}.fc-direction-ltr .fc-daygrid-block-event:not(.fc-event-end),.fc-direction-rtl .fc-daygrid-block-event:not(.fc-event-start){border-bottom-right-radius:0;border-right-width:0;border-top-right-radius:0}.fc-h-event:not(.fc-event-selected) .fc-event-resizer{bottom:0;top:0;width:var(--fc-event-resizer-thickness)}.fc-direction-ltr .fc-h-event:not(.fc-event-selected) .fc-event-resizer-start,.fc-direction-rtl .fc-h-event:not(.fc-event-selected) .fc-event-resizer-end{cursor:w-resize;left:calc(var(--fc-event-resizer-thickness)*-.5)}.fc-direction-ltr .fc-h-event:not(.fc-event-selected) .fc-event-resizer-end,.fc-direction-rtl .fc-h-event:not(.fc-event-selected) .fc-event-resizer-start{cursor:e-resize;right:calc(var(--fc-event-resizer-thickness)*-.5)}.fc-h-event.fc-event-selected .fc-event-resizer{margin-top:calc(var(--fc-event-resizer-dot-total-width)*-.5);top:50%}.fc-direction-ltr .fc-h-event.fc-event-selected .fc-event-resizer-start,.fc-direction-rtl .fc-h-event.fc-event-selected .fc-event-resizer-end{left:calc(var(--fc-event-resizer-dot-total-width)*-.5)}.fc-direction-ltr .fc-h-event.fc-event-selected .fc-event-resizer-end,.fc-direction-rtl .fc-h-event.fc-event-selected .fc-event-resizer-start{right:calc(var(--fc-event-resizer-dot-total-width)*-.5)}.fc .fc-popover{box-shadow:0 2px 6px rgba(0,0,0,.15);position:absolute;z-index:9999}.fc .fc-popover-header{align-items:center;display:flex;flex-direction:row;justify-content:space-between;padding:3px 4px}.fc .fc-popover-title{margin:0 2px}.fc .fc-popover-close{cursor:pointer;font-size:1.1em;opacity:.65}.fc-theme-standard .fc-popover{background:var(--fc-page-bg-color);border:1px solid var(--fc-border-color)}.fc-theme-standard .fc-popover-header{background:var(--fc-neutral-bg-color)}";
106
+ var css_248z = ":root{--fc-small-font-size:.85em;--fc-page-bg-color:#fff;--fc-neutral-bg-color:hsla(0,0%,82%,.3);--fc-neutral-text-color:grey;--fc-border-color:#ddd;--fc-button-text-color:#fff;--fc-button-bg-color:#2c3e50;--fc-button-border-color:#2c3e50;--fc-button-hover-bg-color:#1e2b37;--fc-button-hover-border-color:#1a252f;--fc-button-active-bg-color:#1a252f;--fc-button-active-border-color:#151e27;--fc-event-bg-color:#3788d8;--fc-event-border-color:#3788d8;--fc-event-text-color:#fff;--fc-event-selected-overlay-color:rgba(0,0,0,.25);--fc-more-link-bg-color:#d0d0d0;--fc-more-link-text-color:inherit;--fc-event-resizer-thickness:8px;--fc-event-resizer-dot-total-width:8px;--fc-event-resizer-dot-border-width:1px;--fc-non-business-color:hsla(0,0%,84%,.3);--fc-bg-event-color:#8fdf82;--fc-bg-event-opacity:0.3;--fc-highlight-color:rgba(188,232,241,.3);--fc-today-bg-color:rgba(255,220,40,.15);--fc-now-indicator-color:red}.fc-not-allowed,.fc-not-allowed .fc-event{cursor:not-allowed}.fc{display:flex;flex-direction:column;font-size:1em}.fc,.fc *,.fc :after,.fc :before{box-sizing:border-box}.fc table{border-collapse:collapse;border-spacing:0;font-size:1em}.fc th{text-align:center}.fc td,.fc th{padding:0;vertical-align:top}.fc a[data-navlink]{cursor:pointer}.fc a[data-navlink]:hover{text-decoration:underline}.fc-direction-ltr{direction:ltr;text-align:left}.fc-direction-rtl{direction:rtl;text-align:right}.fc-theme-standard td,.fc-theme-standard th{border:1px solid var(--fc-border-color)}.fc-liquid-hack td,.fc-liquid-hack th{position:relative}@font-face{font-family:fcicons;font-style:normal;font-weight:400;src:url(\"data:application/x-font-ttf;charset=utf-8;base64,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\") format(\"truetype\")}.fc-icon{speak:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;display:inline-block;font-family:fcicons!important;font-style:normal;font-variant:normal;font-weight:400;height:1em;line-height:1;text-align:center;text-transform:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:1em}.fc-icon-chevron-left:before{content:\"\\e900\"}.fc-icon-chevron-right:before{content:\"\\e901\"}.fc-icon-chevrons-left:before{content:\"\\e902\"}.fc-icon-chevrons-right:before{content:\"\\e903\"}.fc-icon-minus-square:before{content:\"\\e904\"}.fc-icon-plus-square:before{content:\"\\e905\"}.fc-icon-x:before{content:\"\\e906\"}.fc .fc-button{border-radius:0;font-family:inherit;font-size:inherit;line-height:inherit;margin:0;overflow:visible;text-transform:none}.fc .fc-button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}.fc .fc-button{-webkit-appearance:button}.fc .fc-button:not(:disabled){cursor:pointer}.fc .fc-button{background-color:transparent;border:1px solid transparent;border-radius:.25em;display:inline-block;font-size:1em;font-weight:400;line-height:1.5;padding:.4em .65em;text-align:center;-webkit-user-select:none;-moz-user-select:none;user-select:none;vertical-align:middle}.fc .fc-button:hover{text-decoration:none}.fc .fc-button:focus{box-shadow:0 0 0 .2rem rgba(44,62,80,.25);outline:0}.fc .fc-button:disabled{opacity:.65}.fc .fc-button-primary{background-color:var(--fc-button-bg-color);border-color:var(--fc-button-border-color);color:var(--fc-button-text-color)}.fc .fc-button-primary:hover{background-color:var(--fc-button-hover-bg-color);border-color:var(--fc-button-hover-border-color);color:var(--fc-button-text-color)}.fc .fc-button-primary:disabled{background-color:var(--fc-button-bg-color);border-color:var(--fc-button-border-color);color:var(--fc-button-text-color)}.fc .fc-button-primary:focus{box-shadow:0 0 0 .2rem rgba(76,91,106,.5)}.fc .fc-button-primary:not(:disabled).fc-button-active,.fc .fc-button-primary:not(:disabled):active{background-color:var(--fc-button-active-bg-color);border-color:var(--fc-button-active-border-color);color:var(--fc-button-text-color)}.fc .fc-button-primary:not(:disabled).fc-button-active:focus,.fc .fc-button-primary:not(:disabled):active:focus{box-shadow:0 0 0 .2rem rgba(76,91,106,.5)}.fc .fc-button .fc-icon{font-size:1.5em;vertical-align:middle}.fc .fc-button-group{display:inline-flex;position:relative;vertical-align:middle}.fc .fc-button-group>.fc-button{flex:1 1 auto;position:relative}.fc .fc-button-group>.fc-button.fc-button-active,.fc .fc-button-group>.fc-button:active,.fc .fc-button-group>.fc-button:focus,.fc .fc-button-group>.fc-button:hover{z-index:1}.fc-direction-ltr .fc-button-group>.fc-button:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0;margin-left:-1px}.fc-direction-ltr .fc-button-group>.fc-button:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}.fc-direction-rtl .fc-button-group>.fc-button:not(:first-child){border-bottom-right-radius:0;border-top-right-radius:0;margin-right:-1px}.fc-direction-rtl .fc-button-group>.fc-button:not(:last-child){border-bottom-left-radius:0;border-top-left-radius:0}.fc .fc-toolbar{align-items:center;display:flex;justify-content:space-between}.fc .fc-toolbar.fc-header-toolbar{margin-bottom:1.5em}.fc .fc-toolbar.fc-footer-toolbar{margin-top:1.5em}.fc .fc-toolbar-title{font-size:1.75em;margin:0}.fc-direction-ltr .fc-toolbar>*>:not(:first-child){margin-left:.75em}.fc-direction-rtl .fc-toolbar>*>:not(:first-child){margin-right:.75em}.fc-direction-rtl .fc-toolbar-ltr{flex-direction:row-reverse}.fc .fc-scroller{-webkit-overflow-scrolling:touch;position:relative}.fc .fc-scroller-liquid{height:100%}.fc .fc-scroller-liquid-absolute{bottom:0;left:0;position:absolute;right:0;top:0}.fc .fc-scroller-harness{direction:ltr;overflow:hidden;position:relative}.fc .fc-scroller-harness-liquid{height:100%}.fc-direction-rtl .fc-scroller-harness>.fc-scroller{direction:rtl}.fc-theme-standard .fc-scrollgrid{border:1px solid var(--fc-border-color)}.fc .fc-scrollgrid,.fc .fc-scrollgrid table{table-layout:fixed;width:100%}.fc .fc-scrollgrid table{border-left-style:hidden;border-right-style:hidden;border-top-style:hidden}.fc .fc-scrollgrid{border-bottom-width:0;border-collapse:separate;border-right-width:0}.fc .fc-scrollgrid-liquid{height:100%}.fc .fc-scrollgrid-section,.fc .fc-scrollgrid-section table,.fc .fc-scrollgrid-section>td{height:1px}.fc .fc-scrollgrid-section-liquid>td{height:100%}.fc .fc-scrollgrid-section>*{border-left-width:0;border-top-width:0}.fc .fc-scrollgrid-section-footer>*,.fc .fc-scrollgrid-section-header>*{border-bottom-width:0}.fc .fc-scrollgrid-section-body table,.fc .fc-scrollgrid-section-footer table{border-bottom-style:hidden}.fc .fc-scrollgrid-section-sticky>*{background:var(--fc-page-bg-color);position:sticky;z-index:3}.fc .fc-scrollgrid-section-header.fc-scrollgrid-section-sticky>*{top:0}.fc .fc-scrollgrid-section-footer.fc-scrollgrid-section-sticky>*{bottom:0}.fc .fc-scrollgrid-sticky-shim{height:1px;margin-bottom:-1px}.fc-sticky{position:sticky}.fc .fc-view-harness{flex-grow:1;position:relative}.fc .fc-view-harness-active>.fc-view{bottom:0;left:0;position:absolute;right:0;top:0}.fc .fc-col-header-cell-cushion{display:inline-block;padding:2px 4px}.fc .fc-bg-event,.fc .fc-highlight,.fc .fc-non-business{bottom:0;left:0;position:absolute;right:0;top:0}.fc .fc-non-business{background:var(--fc-non-business-color)}.fc .fc-bg-event{background:var(--fc-bg-event-color);opacity:var(--fc-bg-event-opacity)}.fc .fc-bg-event .fc-event-title{font-size:var(--fc-small-font-size);font-style:italic;margin:.5em}.fc .fc-highlight{background:var(--fc-highlight-color)}.fc .fc-cell-shaded,.fc .fc-day-disabled{background:var(--fc-neutral-bg-color)}a.fc-event,a.fc-event:hover{text-decoration:none}.fc-event.fc-event-draggable,.fc-event[href]{cursor:pointer}.fc-event .fc-event-main{position:relative;z-index:2}.fc-event-dragging:not(.fc-event-selected){opacity:.75}.fc-event-dragging.fc-event-selected{box-shadow:0 2px 7px rgba(0,0,0,.3)}.fc-event .fc-event-resizer{display:none;position:absolute;z-index:4}.fc-event-selected .fc-event-resizer,.fc-event:hover .fc-event-resizer{display:block}.fc-event-selected .fc-event-resizer{background:var(--fc-page-bg-color);border-color:inherit;border-radius:calc(var(--fc-event-resizer-dot-total-width)/2);border-style:solid;border-width:var(--fc-event-resizer-dot-border-width);height:var(--fc-event-resizer-dot-total-width);width:var(--fc-event-resizer-dot-total-width)}.fc-event-selected .fc-event-resizer:before{bottom:-20px;content:\"\";left:-20px;position:absolute;right:-20px;top:-20px}.fc-event-selected,.fc-event:focus{box-shadow:0 2px 5px rgba(0,0,0,.2)}.fc-event-selected:before,.fc-event:focus:before{bottom:0;content:\"\";left:0;position:absolute;right:0;top:0;z-index:3}.fc-event-selected:after,.fc-event:focus:after{background:var(--fc-event-selected-overlay-color);bottom:-1px;content:\"\";left:-1px;position:absolute;right:-1px;top:-1px;z-index:1}.fc-h-event{background-color:var(--fc-event-bg-color);border:1px solid var(--fc-event-border-color);display:block}.fc-h-event .fc-event-main{color:var(--fc-event-text-color)}.fc-h-event .fc-event-main-frame{display:flex}.fc-h-event .fc-event-time{max-width:100%;overflow:hidden}.fc-h-event .fc-event-title-container{flex-grow:1;flex-shrink:1;min-width:0}.fc-h-event .fc-event-title{display:inline-block;left:0;max-width:100%;overflow:hidden;right:0;vertical-align:top}.fc-h-event.fc-event-selected:before{bottom:-10px;top:-10px}.fc-direction-ltr .fc-daygrid-block-event:not(.fc-event-start),.fc-direction-rtl .fc-daygrid-block-event:not(.fc-event-end){border-bottom-left-radius:0;border-left-width:0;border-top-left-radius:0}.fc-direction-ltr .fc-daygrid-block-event:not(.fc-event-end),.fc-direction-rtl .fc-daygrid-block-event:not(.fc-event-start){border-bottom-right-radius:0;border-right-width:0;border-top-right-radius:0}.fc-h-event:not(.fc-event-selected) .fc-event-resizer{bottom:0;top:0;width:var(--fc-event-resizer-thickness)}.fc-direction-ltr .fc-h-event:not(.fc-event-selected) .fc-event-resizer-start,.fc-direction-rtl .fc-h-event:not(.fc-event-selected) .fc-event-resizer-end{cursor:w-resize;left:calc(var(--fc-event-resizer-thickness)*-.5)}.fc-direction-ltr .fc-h-event:not(.fc-event-selected) .fc-event-resizer-end,.fc-direction-rtl .fc-h-event:not(.fc-event-selected) .fc-event-resizer-start{cursor:e-resize;right:calc(var(--fc-event-resizer-thickness)*-.5)}.fc-h-event.fc-event-selected .fc-event-resizer{margin-top:calc(var(--fc-event-resizer-dot-total-width)*-.5);top:50%}.fc-direction-ltr .fc-h-event.fc-event-selected .fc-event-resizer-start,.fc-direction-rtl .fc-h-event.fc-event-selected .fc-event-resizer-end{left:calc(var(--fc-event-resizer-dot-total-width)*-.5)}.fc-direction-ltr .fc-h-event.fc-event-selected .fc-event-resizer-end,.fc-direction-rtl .fc-h-event.fc-event-selected .fc-event-resizer-start{right:calc(var(--fc-event-resizer-dot-total-width)*-.5)}.fc .fc-popover{box-shadow:0 2px 6px rgba(0,0,0,.15);position:absolute;z-index:9999}.fc .fc-popover-header{align-items:center;display:flex;flex-direction:row;justify-content:space-between;padding:3px 4px}.fc .fc-popover-title{margin:0 2px}.fc .fc-popover-close{cursor:pointer;font-size:1.1em;opacity:.65}.fc-theme-standard .fc-popover{background:var(--fc-page-bg-color);border:1px solid var(--fc-border-color)}.fc-theme-standard .fc-popover-header{background:var(--fc-neutral-bg-color)}";
107
107
  injectStyles(css_248z);
108
108
 
109
109
  class DelayedRunner {
@@ -984,10 +984,10 @@ function memoizeHashlike(workerFunc, resEquality, teardownFunc) {
984
984
 
985
985
  const EXTENDED_SETTINGS_AND_SEVERITIES = {
986
986
  week: 3,
987
- separator: 0,
988
- omitZeroMinute: 0,
989
- meridiem: 0,
990
- omitCommas: 0,
987
+ separator: 9,
988
+ omitZeroMinute: 9,
989
+ meridiem: 9,
990
+ omitCommas: 9,
991
991
  };
992
992
  const STANDARD_DATE_PROP_SEVERITIES = {
993
993
  timeZoneName: 7,
@@ -1009,22 +1009,25 @@ class NativeFormatter {
1009
1009
  constructor(formatSettings) {
1010
1010
  let standardDateProps = {};
1011
1011
  let extendedSettings = {};
1012
- let severity = 0;
1012
+ let smallestUnitNum = 9; // the smallest unit in the formatter (9 is a sentinel, beyond max)
1013
1013
  for (let name in formatSettings) {
1014
1014
  if (name in EXTENDED_SETTINGS_AND_SEVERITIES) {
1015
1015
  extendedSettings[name] = formatSettings[name];
1016
- severity = Math.max(EXTENDED_SETTINGS_AND_SEVERITIES[name], severity);
1016
+ const severity = EXTENDED_SETTINGS_AND_SEVERITIES[name];
1017
+ if (severity < 9) {
1018
+ smallestUnitNum = Math.min(EXTENDED_SETTINGS_AND_SEVERITIES[name], smallestUnitNum);
1019
+ }
1017
1020
  }
1018
1021
  else {
1019
1022
  standardDateProps[name] = formatSettings[name];
1020
1023
  if (name in STANDARD_DATE_PROP_SEVERITIES) { // TODO: what about hour12? no severity
1021
- severity = Math.max(STANDARD_DATE_PROP_SEVERITIES[name], severity);
1024
+ smallestUnitNum = Math.min(STANDARD_DATE_PROP_SEVERITIES[name], smallestUnitNum);
1022
1025
  }
1023
1026
  }
1024
1027
  }
1025
1028
  this.standardDateProps = standardDateProps;
1026
1029
  this.extendedSettings = extendedSettings;
1027
- this.severity = severity;
1030
+ this.smallestUnitNum = smallestUnitNum;
1028
1031
  this.buildFormattingFunc = memoize(buildFormattingFunc);
1029
1032
  }
1030
1033
  format(date, context) {
@@ -1059,8 +1062,8 @@ class NativeFormatter {
1059
1062
  }
1060
1063
  return full0 + separator + full1;
1061
1064
  }
1062
- getLargestUnit() {
1063
- switch (this.severity) {
1065
+ getSmallestUnit() {
1066
+ switch (this.smallestUnitNum) {
1064
1067
  case 7:
1065
1068
  case 6:
1066
1069
  case 5:
@@ -2332,9 +2335,10 @@ class ScrollResponder {
2332
2335
  }
2333
2336
 
2334
2337
  const ViewContextType = createContext({}); // for Components
2335
- function buildViewContext(viewSpec, viewApi, viewOptions, dateProfileGenerator, dateEnv, theme, pluginHooks, dispatch, getCurrentData, emitter, calendarApi, registerInteractiveComponent, unregisterInteractiveComponent) {
2338
+ function buildViewContext(viewSpec, viewApi, viewOptions, dateProfileGenerator, dateEnv, nowManager, theme, pluginHooks, dispatch, getCurrentData, emitter, calendarApi, registerInteractiveComponent, unregisterInteractiveComponent) {
2336
2339
  return {
2337
2340
  dateEnv,
2341
+ nowManager,
2338
2342
  options: viewOptions,
2339
2343
  pluginHooks,
2340
2344
  emitter,
@@ -2767,36 +2771,9 @@ function diffDates(date0, date1, dateEnv, largeUnit) {
2767
2771
  return diffDayAndTime(date0, date1); // returns a duration
2768
2772
  }
2769
2773
 
2770
- function reduceCurrentDate(currentDate, action) {
2771
- switch (action.type) {
2772
- case 'CHANGE_DATE':
2773
- return action.dateMarker;
2774
- default:
2775
- return currentDate;
2776
- }
2777
- }
2778
- function getInitialDate(options, dateEnv) {
2779
- let initialDateInput = options.initialDate;
2780
- // compute the initial ambig-timezone date
2781
- if (initialDateInput != null) {
2782
- return dateEnv.createMarker(initialDateInput);
2783
- }
2784
- return getNow(options.now, dateEnv); // getNow already returns unzoned
2785
- }
2786
- function getNow(nowInput, dateEnv) {
2787
- if (typeof nowInput === 'function') {
2788
- nowInput = nowInput();
2789
- }
2790
- if (nowInput == null) {
2791
- return dateEnv.createNowMarker();
2792
- }
2793
- return dateEnv.createMarker(nowInput);
2794
- }
2795
-
2796
2774
  class DateProfileGenerator {
2797
2775
  constructor(props) {
2798
2776
  this.props = props;
2799
- this.nowDate = getNow(props.nowInput, props.dateEnv);
2800
2777
  this.initHiddenDays();
2801
2778
  }
2802
2779
  /* Date Range Computation
@@ -2881,7 +2858,7 @@ class DateProfileGenerator {
2881
2858
  buildValidRange() {
2882
2859
  let input = this.props.validRangeInput;
2883
2860
  let simpleInput = typeof input === 'function'
2884
- ? input.call(this.props.calendarApi, this.nowDate)
2861
+ ? input.call(this.props.calendarApi, this.props.dateEnv.toDate(this.props.nowManager.getDateMarker()))
2885
2862
  : input;
2886
2863
  return this.refineRange(simpleInput) ||
2887
2864
  { start: null, end: null }; // completely open-ended
@@ -4773,6 +4750,85 @@ function interactionSettingsToStore(settings) {
4773
4750
  // global state
4774
4751
  const interactionSettingsStore = {};
4775
4752
 
4753
+ class NowTimer extends preact.Component {
4754
+ constructor(props, context) {
4755
+ super(props, context);
4756
+ this.handleRefresh = () => {
4757
+ let timing = this.computeTiming();
4758
+ if (timing.state.nowDate.valueOf() !== this.state.nowDate.valueOf()) {
4759
+ this.setState(timing.state);
4760
+ }
4761
+ this.clearTimeout();
4762
+ this.setTimeout(timing.waitMs);
4763
+ };
4764
+ this.handleVisibilityChange = () => {
4765
+ if (!document.hidden) {
4766
+ this.handleRefresh();
4767
+ }
4768
+ };
4769
+ this.state = this.computeTiming().state;
4770
+ }
4771
+ render() {
4772
+ let { props, state } = this;
4773
+ return props.children(state.nowDate, state.todayRange);
4774
+ }
4775
+ componentDidMount() {
4776
+ this.setTimeout();
4777
+ this.context.nowManager.addResetListener(this.handleRefresh);
4778
+ // fired tab becomes visible after being hidden
4779
+ document.addEventListener('visibilitychange', this.handleVisibilityChange);
4780
+ }
4781
+ componentDidUpdate(prevProps) {
4782
+ if (prevProps.unit !== this.props.unit) {
4783
+ this.clearTimeout();
4784
+ this.setTimeout();
4785
+ }
4786
+ }
4787
+ componentWillUnmount() {
4788
+ this.clearTimeout();
4789
+ this.context.nowManager.removeResetListener(this.handleRefresh);
4790
+ document.removeEventListener('visibilitychange', this.handleVisibilityChange);
4791
+ }
4792
+ computeTiming() {
4793
+ let { props, context } = this;
4794
+ let unroundedNow = context.nowManager.getDateMarker();
4795
+ let currentUnitStart = context.dateEnv.startOf(unroundedNow, props.unit);
4796
+ let nextUnitStart = context.dateEnv.add(currentUnitStart, createDuration(1, props.unit));
4797
+ let waitMs = nextUnitStart.valueOf() - unroundedNow.valueOf();
4798
+ // there is a max setTimeout ms value (https://stackoverflow.com/a/3468650/96342)
4799
+ // ensure no longer than a day
4800
+ waitMs = Math.min(1000 * 60 * 60 * 24, waitMs);
4801
+ return {
4802
+ state: { nowDate: currentUnitStart, todayRange: buildDayRange(currentUnitStart) },
4803
+ waitMs,
4804
+ };
4805
+ }
4806
+ setTimeout(waitMs = this.computeTiming().waitMs) {
4807
+ // NOTE: timeout could take longer than expected if tab sleeps,
4808
+ // which is why we listen to 'visibilitychange'
4809
+ this.timeoutId = setTimeout(() => {
4810
+ // NOTE: timeout could also return *earlier* than expected, and we need to wait 2 ms more
4811
+ // This is why use use same waitMs from computeTiming, so we don't skip an interval while
4812
+ // .setState() is executing
4813
+ const timing = this.computeTiming();
4814
+ this.setState(timing.state, () => {
4815
+ this.setTimeout(timing.waitMs);
4816
+ });
4817
+ }, waitMs);
4818
+ }
4819
+ clearTimeout() {
4820
+ if (this.timeoutId) {
4821
+ clearTimeout(this.timeoutId);
4822
+ }
4823
+ }
4824
+ }
4825
+ NowTimer.contextType = ViewContextType;
4826
+ function buildDayRange(date) {
4827
+ let start = startOfDay(date);
4828
+ let end = addDays(start, 1);
4829
+ return { start, end };
4830
+ }
4831
+
4776
4832
  class CalendarImpl {
4777
4833
  getCurrentData() {
4778
4834
  return this.currentDataManager.getCurrentData();
@@ -4928,7 +4984,7 @@ class CalendarImpl {
4928
4984
  this.unselect();
4929
4985
  this.dispatch({
4930
4986
  type: 'CHANGE_DATE',
4931
- dateMarker: getNow(state.calendarOptions.now, state.dateEnv),
4987
+ dateMarker: state.nowManager.getDateMarker(),
4932
4988
  });
4933
4989
  }
4934
4990
  gotoDate(zonedDateInput) {
@@ -5329,7 +5385,7 @@ function buildEventUiForKey(allUi, eventUiForKey, individualUi) {
5329
5385
  function getDateMeta(date, todayRange, nowDate, dateProfile) {
5330
5386
  return {
5331
5387
  dow: date.getUTCDay(),
5332
- isDisabled: Boolean(dateProfile && !rangeContainsMarker(dateProfile.activeRange, date)),
5388
+ isDisabled: Boolean(dateProfile && (!dateProfile.activeRange || !rangeContainsMarker(dateProfile.activeRange, date))),
5333
5389
  isOther: Boolean(dateProfile && !rangeContainsMarker(dateProfile.currentRange, date)),
5334
5390
  isToday: Boolean(todayRange && rangeContainsMarker(todayRange, date)),
5335
5391
  isPast: Boolean(nowDate ? (date < nowDate) : todayRange ? (date < todayRange.start) : false),
@@ -6094,7 +6150,13 @@ class TableDateCell extends BaseComponent {
6094
6150
  let navLinkAttrs = (!dayMeta.isDisabled && props.colCnt > 1)
6095
6151
  ? buildNavLinkAttrs(this.context, date)
6096
6152
  : {};
6097
- let renderProps = Object.assign(Object.assign(Object.assign({ date: dateEnv.toDate(date), view: viewApi }, props.extraRenderProps), { text }), dayMeta);
6153
+ let publicDate = dateEnv.toDate(date);
6154
+ // workaround for Luxon (and maybe moment) returning prior-days when start-of-day
6155
+ // in DST gap: https://github.com/fullcalendar/fullcalendar/issues/7633
6156
+ if (dateEnv.namedTimeZoneImpl) {
6157
+ publicDate = addMs(publicDate, 3600000); // add an hour
6158
+ }
6159
+ let renderProps = Object.assign(Object.assign(Object.assign({ date: publicDate, view: viewApi }, props.extraRenderProps), { text }), dayMeta);
6098
6160
  return (preact.createElement(ContentContainer, { elTag: "th", elClasses: classNames, elAttrs: Object.assign({ role: 'columnheader', colSpan: props.colSpan, 'data-date': !dayMeta.isDisabled ? formatDayString(date) : undefined }, props.extraDataAttrs), renderProps: renderProps, generatorName: "dayHeaderContent", customGenerator: options.dayHeaderContent, defaultGenerator: renderInner$1, classNameGenerator: options.dayHeaderClassNames, didMount: options.dayHeaderDidMount, willUnmount: options.dayHeaderWillUnmount }, (InnerContainer) => (preact.createElement("div", { className: "fc-scrollgrid-sync-inner" }, !dayMeta.isDisabled && (preact.createElement(InnerContainer, { elTag: "a", elAttrs: navLinkAttrs, elClasses: [
6099
6161
  'fc-col-header-cell-cushion',
6100
6162
  props.isSticky && 'fc-sticky',
@@ -6133,65 +6195,6 @@ class TableDowCell extends BaseComponent {
6133
6195
  }
6134
6196
  }
6135
6197
 
6136
- class NowTimer extends preact.Component {
6137
- constructor(props, context) {
6138
- super(props, context);
6139
- this.initialNowDate = getNow(context.options.now, context.dateEnv);
6140
- this.initialNowQueriedMs = new Date().valueOf();
6141
- this.state = this.computeTiming().currentState;
6142
- }
6143
- render() {
6144
- let { props, state } = this;
6145
- return props.children(state.nowDate, state.todayRange);
6146
- }
6147
- componentDidMount() {
6148
- this.setTimeout();
6149
- }
6150
- componentDidUpdate(prevProps) {
6151
- if (prevProps.unit !== this.props.unit) {
6152
- this.clearTimeout();
6153
- this.setTimeout();
6154
- }
6155
- }
6156
- componentWillUnmount() {
6157
- this.clearTimeout();
6158
- }
6159
- computeTiming() {
6160
- let { props, context } = this;
6161
- let unroundedNow = addMs(this.initialNowDate, new Date().valueOf() - this.initialNowQueriedMs);
6162
- let currentUnitStart = context.dateEnv.startOf(unroundedNow, props.unit);
6163
- let nextUnitStart = context.dateEnv.add(currentUnitStart, createDuration(1, props.unit));
6164
- let waitMs = nextUnitStart.valueOf() - unroundedNow.valueOf();
6165
- // there is a max setTimeout ms value (https://stackoverflow.com/a/3468650/96342)
6166
- // ensure no longer than a day
6167
- waitMs = Math.min(1000 * 60 * 60 * 24, waitMs);
6168
- return {
6169
- currentState: { nowDate: currentUnitStart, todayRange: buildDayRange(currentUnitStart) },
6170
- nextState: { nowDate: nextUnitStart, todayRange: buildDayRange(nextUnitStart) },
6171
- waitMs,
6172
- };
6173
- }
6174
- setTimeout() {
6175
- let { nextState, waitMs } = this.computeTiming();
6176
- this.timeoutId = setTimeout(() => {
6177
- this.setState(nextState, () => {
6178
- this.setTimeout();
6179
- });
6180
- }, waitMs);
6181
- }
6182
- clearTimeout() {
6183
- if (this.timeoutId) {
6184
- clearTimeout(this.timeoutId);
6185
- }
6186
- }
6187
- }
6188
- NowTimer.contextType = ViewContextType;
6189
- function buildDayRange(date) {
6190
- let start = startOfDay(date);
6191
- let end = addDays(start, 1);
6192
- return { start, end };
6193
- }
6194
-
6195
6198
  class DayHeader extends BaseComponent {
6196
6199
  constructor() {
6197
6200
  super(...arguments);
@@ -7632,9 +7635,7 @@ exports.getDefaultEventEnd = getDefaultEventEnd;
7632
7635
  exports.getElSeg = getElSeg;
7633
7636
  exports.getEntrySpanEnd = getEntrySpanEnd;
7634
7637
  exports.getEventTargetViaRoot = getEventTargetViaRoot;
7635
- exports.getInitialDate = getInitialDate;
7636
7638
  exports.getIsRtlScrollbarOnLeft = getIsRtlScrollbarOnLeft;
7637
- exports.getNow = getNow;
7638
7639
  exports.getRectCenter = getRectCenter;
7639
7640
  exports.getRelevantEvents = getRelevantEvents;
7640
7641
  exports.getScrollGridClassNames = getScrollGridClassNames;
@@ -7699,7 +7700,6 @@ exports.rangeContainsMarker = rangeContainsMarker;
7699
7700
  exports.rangeContainsRange = rangeContainsRange;
7700
7701
  exports.rangesEqual = rangesEqual;
7701
7702
  exports.rangesIntersect = rangesIntersect;
7702
- exports.reduceCurrentDate = reduceCurrentDate;
7703
7703
  exports.reduceEventStore = reduceEventStore;
7704
7704
  exports.refineEventDef = refineEventDef;
7705
7705
  exports.refineProps = refineProps;