@event-calendar/core 4.1.0 → 4.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -227,8 +227,8 @@ This bundle contains a version of the calendar that includes all plugins and is
227
227
 
228
228
  The first step is to include the following lines of code in the `<head>` section of your page:
229
229
  ```html
230
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@event-calendar/build@4.1.0/dist/event-calendar.min.css">
231
- <script src="https://cdn.jsdelivr.net/npm/@event-calendar/build@4.1.0/dist/event-calendar.min.js"></script>
230
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@event-calendar/build@4.3.0/dist/event-calendar.min.css">
231
+ <script src="https://cdn.jsdelivr.net/npm/@event-calendar/build@4.3.0/dist/event-calendar.min.js"></script>
232
232
  ```
233
233
 
234
234
  <details>
@@ -1552,7 +1552,7 @@ function (start, end) {
1552
1552
  - Type `string`
1553
1553
  - Default `undefined`
1554
1554
 
1555
- Sets the default text color for events on the calendar.
1555
+ Sets the default text color for calendar events (except for `list` view).
1556
1556
 
1557
1557
  You can use any of the CSS color formats such `'#f00'`, `'#ff0000'`, `'rgb(255,0,0)'`, or `'red'`.
1558
1558
 
package/dist/index.css CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * EventCalendar v4.1.0
2
+ * EventCalendar v4.3.0
3
3
  * https://github.com/vkurko/calendar
4
4
  */
5
5
  .ec {
@@ -74,6 +74,7 @@
74
74
  display: flex;
75
75
  flex-direction: column;
76
76
  min-width: 0;
77
+ position: relative;
77
78
  }
78
79
  .ec-timeline .ec-content {
79
80
  flex-direction: column;
@@ -541,6 +542,13 @@
541
542
  top: 0;
542
543
  z-index: 2;
543
544
  }
545
+ .ec-list .ec-day.ec-today .ec-day-head:before {
546
+ content: "";
547
+ position: absolute;
548
+ inset: 0;
549
+ z-index: -1;
550
+ background-color: var(--ec-today-bg-color);
551
+ }
544
552
  .ec-list .ec-day:first-child .ec-day-head {
545
553
  border-top: none;
546
554
  }
@@ -718,19 +726,28 @@
718
726
  .ec-now-indicator {
719
727
  position: absolute;
720
728
  z-index: 1005;
729
+ pointer-events: none;
730
+ }
731
+ .ec-time-grid .ec-now-indicator {
721
732
  width: 100%;
722
733
  border-top: var(--ec-now-indicator-color) solid 2px;
723
- pointer-events: none;
734
+ }
735
+ .ec-timeline .ec-now-indicator {
736
+ height: 100%;
737
+ border-left: var(--ec-now-indicator-color) solid 2px;
738
+ will-change: transform;
724
739
  }
725
740
  .ec-now-indicator:before {
726
741
  background: var(--ec-now-indicator-color);
727
742
  border-radius: 50%;
728
743
  content: "";
729
- position: absolute;
744
+ display: block;
730
745
  height: 12px;
731
746
  margin-top: -7px;
732
747
  width: 12px;
733
- pointer-events: none;
748
+ }
749
+ .ec-timeline .ec-now-indicator:before {
750
+ margin-left: -7px;
734
751
  }
735
752
 
736
753
  .ec-resizer {
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * EventCalendar v4.1.0
2
+ * EventCalendar v4.3.0
3
3
  * https://github.com/vkurko/calendar
4
4
  */
5
5
  import { tick, getContext, untrack, setContext, onMount, mount, unmount } from "svelte";
@@ -1465,7 +1465,7 @@ function Buttons($$anchor, $$props) {
1465
1465
  $$cleanup();
1466
1466
  }
1467
1467
  var root_3$5 = $.template(`<div><!></div>`);
1468
- var root_1$c = $.template(`<div></div>`);
1468
+ var root_1$d = $.template(`<div></div>`);
1469
1469
  var root$r = $.template(`<nav></nav>`);
1470
1470
  function Toolbar($$anchor, $$props) {
1471
1471
  $.push($$props, true);
@@ -1483,7 +1483,7 @@ function Toolbar($$anchor, $$props) {
1483
1483
  });
1484
1484
  var nav = root$r();
1485
1485
  $.each(nav, 21, () => keys($.get(sections)), $.index, ($$anchor2, key) => {
1486
- var div = root_1$c();
1486
+ var div = root_1$d();
1487
1487
  $.each(div, 21, () => $.get(sections)[$.get(key)], $.index, ($$anchor3, buttons) => {
1488
1488
  var fragment = $.comment();
1489
1489
  var node = $.first_child(fragment);
@@ -1670,18 +1670,17 @@ function Calendar($$anchor, $$props) {
1670
1670
  return toEventWithLocalDates(event);
1671
1671
  }
1672
1672
  function updateEvent(event) {
1673
- for (let e of $_events()) {
1674
- if (e.id == event.id) {
1675
- event = createEvents([event])[0];
1676
- assign(e, event);
1677
- $.store_set(_events, $_events());
1678
- return toEventWithLocalDates(event);
1679
- }
1673
+ let id = String(event.id);
1674
+ let idx = $_events().findIndex((event2) => event2.id === id);
1675
+ if (idx >= 0) {
1676
+ $.store_mutate(_events, $.untrack($_events)[idx] = createEvents([event])[0], $.untrack($_events));
1677
+ return toEventWithLocalDates(event);
1680
1678
  }
1681
1679
  return null;
1682
1680
  }
1683
1681
  function removeEventById(id) {
1684
- let idx = $_events().findIndex((event) => event.id == id);
1682
+ id = String(id);
1683
+ let idx = $_events().findIndex((event) => event.id === id);
1685
1684
  if (idx >= 0) {
1686
1685
  $_events().splice(idx, 1);
1687
1686
  $.store_set(_events, $_events());
@@ -1773,7 +1772,7 @@ function days(state) {
1773
1772
  return days2;
1774
1773
  });
1775
1774
  }
1776
- var root_1$b = $.template(`<div role="columnheader"><span></span></div>`);
1775
+ var root_1$c = $.template(`<div role="columnheader"><span></span></div>`);
1777
1776
  var root$p = $.template(`<div><div role="row"></div> <div></div></div>`);
1778
1777
  function Header$1($$anchor, $$props) {
1779
1778
  $.push($$props, false);
@@ -1792,7 +1791,7 @@ function Header$1($$anchor, $$props) {
1792
1791
  var div = root$p();
1793
1792
  var div_1 = $.child(div);
1794
1793
  $.each(div_1, 5, $_days, $.index, ($$anchor2, day) => {
1795
- var div_2 = root_1$b();
1794
+ var div_2 = root_1$c();
1796
1795
  var span = $.child(div_2);
1797
1796
  $.action(span, ($$node, $$action_arg) => setContent == null ? void 0 : setContent($$node, $$action_arg), () => $_intlDayHeader().format($.get(day)));
1798
1797
  $.reset(div_2);
@@ -1824,7 +1823,7 @@ function Header$1($$anchor, $$props) {
1824
1823
  $.pop();
1825
1824
  $$cleanup();
1826
1825
  }
1827
- var root_1$a = $.template(`<div></div>`);
1826
+ var root_1$b = $.template(`<div></div>`);
1828
1827
  var root$o = $.template(`<article><!></article>`);
1829
1828
  function BaseEvent($$anchor, $$props) {
1830
1829
  $.push($$props, true);
@@ -1909,13 +1908,10 @@ function BaseEvent($$anchor, $$props) {
1909
1908
  (_a = $$props.onpointerdown) == null ? void 0 : _a.apply(this, $$args);
1910
1909
  };
1911
1910
  {
1912
- const defaultBody = ($$anchor2, style2 = $.noop) => {
1913
- var div = root_1$a();
1911
+ const defaultBody = ($$anchor2) => {
1912
+ var div = root_1$b();
1914
1913
  $.action(div, ($$node, $$action_arg) => setContent == null ? void 0 : setContent($$node, $$action_arg), () => $.get(content));
1915
- $.template_effect(() => {
1916
- $.set_class(div, 1, $.clsx($theme().eventBody));
1917
- $.set_style(div, style2());
1918
- });
1914
+ $.template_effect(() => $.set_class(div, 1, $.clsx($theme().eventBody)));
1919
1915
  $.append($$anchor2, div);
1920
1916
  };
1921
1917
  var node = $.child(article);
@@ -2272,7 +2268,7 @@ function Popup($$anchor, $$props) {
2272
2268
  $$cleanup();
2273
2269
  }
2274
2270
  $.delegate(["pointerdown", "click", "keydown"]);
2275
- var root_1$9 = $.template(`<span></span>`);
2271
+ var root_1$a = $.template(`<span></span>`);
2276
2272
  var root_5$1 = $.template(`<div><!></div>`);
2277
2273
  var root_6 = $.template(`<div><!></div>`);
2278
2274
  var root_4$2 = $.template(`<!> <!>`, 1);
@@ -2405,7 +2401,7 @@ function Day$4($$anchor, $$props) {
2405
2401
  var node = $.sibling(time, 2);
2406
2402
  {
2407
2403
  var consequent = ($$anchor2) => {
2408
- var span = root_1$9();
2404
+ var span = root_1$a();
2409
2405
  $.action(span, ($$node, $$action_arg) => setContent == null ? void 0 : setContent($$node, $$action_arg), () => $.get(weekNumber));
2410
2406
  $.template_effect(() => $.set_class(span, 1, $theme().weekNumber));
2411
2407
  $.append($$anchor2, span);
@@ -3491,7 +3487,7 @@ function Pointer($$anchor, $$props) {
3491
3487
  $$cleanup();
3492
3488
  return $$pop;
3493
3489
  }
3494
- var root_1$8 = $.template(`<div></div>`);
3490
+ var root_1$9 = $.template(`<div></div>`);
3495
3491
  var root_2$6 = $.template(`<div></div>`);
3496
3492
  var root$i = $.template(`<!> <!> <!>`, 1);
3497
3493
  function Resizer($$anchor, $$props) {
@@ -3523,7 +3519,7 @@ function Resizer($$anchor, $$props) {
3523
3519
  var node = $.first_child(fragment);
3524
3520
  {
3525
3521
  var consequent = ($$anchor2) => {
3526
- var div = root_1$8();
3522
+ var div = root_1$9();
3527
3523
  var event_handler = $.derived(() => createResizeHandler(true));
3528
3524
  div.__pointerdown = function(...$$args) {
3529
3525
  var _a;
@@ -3667,7 +3663,7 @@ const index$3 = {
3667
3663
  state._auxiliary.update(($_auxiliary) => [...$_auxiliary, Auxiliary]);
3668
3664
  }
3669
3665
  };
3670
- var root_1$7 = $.template(`<div></div> <!>`, 1);
3666
+ var root_1$8 = $.template(`<div></div> <!>`, 1);
3671
3667
  function Event$3($$anchor, $$props) {
3672
3668
  $.push($$props, true);
3673
3669
  const [$$stores, $$cleanup] = $.setup_stores();
@@ -3685,11 +3681,11 @@ function Event$3($$anchor, $$props) {
3685
3681
  });
3686
3682
  {
3687
3683
  const body = ($$anchor2, defaultBody = $.noop, bgColor = $.noop, txtColor = $.noop) => {
3688
- var fragment_1 = root_1$7();
3684
+ var fragment_1 = root_1$8();
3689
3685
  var div = $.first_child(fragment_1);
3690
3686
  let styles_1;
3691
3687
  var node = $.sibling(div, 2);
3692
- $.snippet(node, defaultBody, () => `color:${txtColor()}`);
3688
+ $.snippet(node, defaultBody);
3693
3689
  $.template_effect(() => {
3694
3690
  $.set_class(div, 1, $theme().eventTag);
3695
3691
  styles_1 = $.set_style(div, "", styles_1, { "background-color": bgColor() });
@@ -3713,7 +3709,7 @@ function Event$3($$anchor, $$props) {
3713
3709
  $.pop();
3714
3710
  $$cleanup();
3715
3711
  }
3716
- var root_1$6 = $.template(`<div role="listitem"><h4><time></time> <time></time></h4> <!></div>`);
3712
+ var root_1$7 = $.template(`<div role="listitem"><h4><time></time> <time></time></h4> <!></div>`);
3717
3713
  function Day$3($$anchor, $$props) {
3718
3714
  $.push($$props, true);
3719
3715
  const [$$stores, $$cleanup] = $.setup_stores();
@@ -3774,7 +3770,7 @@ function Day$3($$anchor, $$props) {
3774
3770
  var node = $.first_child(fragment);
3775
3771
  {
3776
3772
  var consequent = ($$anchor2) => {
3777
- var div = root_1$6();
3773
+ var div = root_1$7();
3778
3774
  div.__pointerdown = function(...$$args) {
3779
3775
  var _a, _b;
3780
3776
  (_b = (_a = $_interaction().action) == null ? void 0 : _a.select) == null ? void 0 : _b.apply(this, $$args);
@@ -3829,7 +3825,7 @@ function onclick$1(jsEvent, $noEventsClick, noEventsClick, $_view, _view) {
3829
3825
  });
3830
3826
  }
3831
3827
  }
3832
- var root_1$5 = $.template(`<div></div>`);
3828
+ var root_1$6 = $.template(`<div></div>`);
3833
3829
  var root$g = $.template(`<div><div><!></div></div>`);
3834
3830
  function Body$2($$anchor, $$props) {
3835
3831
  $.push($$props, true);
@@ -3870,7 +3866,7 @@ function Body$2($$anchor, $$props) {
3870
3866
  var node = $.child(div_1);
3871
3867
  {
3872
3868
  var consequent = ($$anchor2) => {
3873
- var div_2 = root_1$5();
3869
+ var div_2 = root_1$6();
3874
3870
  div_2.__click = [
3875
3871
  onclick$1,
3876
3872
  $noEventsClick,
@@ -4019,7 +4015,7 @@ function createAllDayContent(allDayContent) {
4019
4015
  }
4020
4016
  return content;
4021
4017
  }
4022
- var root_1$4 = $.template(`<time></time>`);
4018
+ var root_1$5 = $.template(`<time></time>`);
4023
4019
  var root$f = $.template(`<div><div></div> <!></div> <div role="row"><div><!></div> <!></div>`, 1);
4024
4020
  function Section($$anchor, $$props) {
4025
4021
  $.push($$props, true);
@@ -4042,7 +4038,7 @@ function Section($$anchor, $$props) {
4042
4038
  $.action(div_1, ($$node, $$action_arg) => setContent == null ? void 0 : setContent($$node, $$action_arg), () => $.get(allDayText));
4043
4039
  var node = $.sibling(div_1, 2);
4044
4040
  $.each(node, 1, $_times, $.index, ($$anchor2, time, i) => {
4045
- var time_1 = root_1$4();
4041
+ var time_1 = root_1$5();
4046
4042
  $.action(time_1, ($$node, $$action_arg) => setContent == null ? void 0 : setContent($$node, $$action_arg), () => $.get(time)[1]);
4047
4043
  $.template_effect(() => {
4048
4044
  $.set_class(time_1, 1, `${$theme().time ?? ""}${(i || $.get(showAllTimes)) && $.get(time)[2] ? "" : " " + $theme().minor}`);
@@ -4204,7 +4200,7 @@ function Event$2($$anchor, $$props) {
4204
4200
  $$cleanup();
4205
4201
  }
4206
4202
  var root$d = $.template(`<div></div>`);
4207
- function NowIndicator($$anchor, $$props) {
4203
+ function NowIndicator$1($$anchor, $$props) {
4208
4204
  $.push($$props, true);
4209
4205
  const [$$stores, $$cleanup] = $.setup_stores();
4210
4206
  const $_now = () => $.store_get(_now, "$_now", $$stores);
@@ -4221,10 +4217,10 @@ function NowIndicator($$anchor, $$props) {
4221
4217
  _today,
4222
4218
  _slotTimeLimits
4223
4219
  } = getContext("state");
4224
- let start = $.derived(() => ($_now() - $_today()) / 1e3 / 60);
4220
+ let start = $.derived(() => ($_now() - $_today()) / 1e3);
4225
4221
  let top = $.derived(() => {
4226
- let step = $slotDuration().seconds / 60;
4227
- let offset = $_slotTimeLimits().min.seconds / 60;
4222
+ let step = $slotDuration().seconds;
4223
+ let offset = $_slotTimeLimits().min.seconds;
4228
4224
  return ($.get(start) - offset) / step * $slotHeight();
4229
4225
  });
4230
4226
  var div = root$d();
@@ -4404,7 +4400,7 @@ function Day$2($$anchor, $$props) {
4404
4400
  var node_6 = $.child(div_3);
4405
4401
  {
4406
4402
  var consequent_4 = ($$anchor2) => {
4407
- NowIndicator($$anchor2, {});
4403
+ NowIndicator$1($$anchor2, {});
4408
4404
  };
4409
4405
  $.if(node_6, ($$render) => {
4410
4406
  if ($nowIndicator() && $.get(isToday) && !$.get(disabled)) $$render(consequent_4);
@@ -4701,6 +4697,7 @@ function View$2($$anchor, $$props) {
4701
4697
  const [$$stores, $$cleanup] = $.setup_stores();
4702
4698
  const $theme = () => $.store_get(theme, "$theme", $$stores);
4703
4699
  const $_viewDates = () => $.store_get(_viewDates, "$_viewDates", $$stores);
4700
+ const $_today = () => $.store_get(_today, "$_today", $$stores);
4704
4701
  const $_intlDayHeaderAL = () => $.store_get(_intlDayHeaderAL, "$_intlDayHeaderAL", $$stores);
4705
4702
  const $_intlDayHeader = () => $.store_get(_intlDayHeader, "$_intlDayHeader", $$stores);
4706
4703
  const $allDaySlot = () => $.store_get(allDaySlot, "$allDaySlot", $$stores);
@@ -4708,6 +4705,7 @@ function View$2($$anchor, $$props) {
4708
4705
  _viewDates,
4709
4706
  _intlDayHeader,
4710
4707
  _intlDayHeaderAL,
4708
+ _today,
4711
4709
  allDaySlot,
4712
4710
  theme
4713
4711
  } = getContext("state");
@@ -4725,16 +4723,17 @@ function View$2($$anchor, $$props) {
4725
4723
  $.action(time, ($$node, $$action_arg) => setContent == null ? void 0 : setContent($$node, $$action_arg), () => $_intlDayHeader().format($.get(date)));
4726
4724
  $.reset(div_1);
4727
4725
  $.template_effect(
4728
- ($0, $1, $2) => {
4729
- $.set_class(div_1, 1, `${$theme().day ?? ""} ${$0 ?? ""}`);
4730
- $.set_attribute(time, "datetime", $1);
4731
- $.set_attribute(time, "aria-label", $2);
4726
+ ($0, $1, $2, $3) => {
4727
+ $.set_class(div_1, 1, `${$theme().day ?? ""} ${$0 ?? ""}${$1 ?? ""}`);
4728
+ $.set_attribute(time, "datetime", $2);
4729
+ $.set_attribute(time, "aria-label", $3);
4732
4730
  },
4733
4731
  [
4734
4732
  () => {
4735
4733
  var _a;
4736
4734
  return (_a = $theme().weekdays) == null ? void 0 : _a[$.get(date).getUTCDay()];
4737
4735
  },
4736
+ () => datesEqual($.get(date), $_today()) ? " " + $theme().today : "",
4738
4737
  () => toISOString($.get(date), 10),
4739
4738
  () => $_intlDayHeaderAL().format($.get(date))
4740
4739
  ],
@@ -4898,11 +4897,13 @@ function View$1($$anchor, $$props) {
4898
4897
  const $_viewDates = () => $.store_get(_viewDates, "$_viewDates", $$stores);
4899
4898
  const $_viewResources = () => $.store_get(_viewResources, "$_viewResources", $$stores);
4900
4899
  const $theme = () => $.store_get(theme, "$theme", $$stores);
4900
+ const $_today = () => $.store_get(_today, "$_today", $$stores);
4901
4901
  const $_intlDayHeaderAL = () => $.store_get(_intlDayHeaderAL, "$_intlDayHeaderAL", $$stores);
4902
4902
  const $_intlDayHeader = () => $.store_get(_intlDayHeader, "$_intlDayHeader", $$stores);
4903
4903
  const $allDaySlot = () => $.store_get(allDaySlot, "$allDaySlot", $$stores);
4904
4904
  let {
4905
4905
  datesAboveResources,
4906
+ _today,
4906
4907
  _viewDates,
4907
4908
  _viewResources,
4908
4909
  _intlDayHeader,
@@ -4929,16 +4930,17 @@ function View$1($$anchor, $$props) {
4929
4930
  $.action(time, ($$node, $$action_arg) => setContent == null ? void 0 : setContent($$node, $$action_arg), () => $_intlDayHeader().format($.get(item0)));
4930
4931
  $.reset(div_2);
4931
4932
  $.template_effect(
4932
- ($0, $1, $2) => {
4933
- $.set_class(div_2, 1, `${$theme().day ?? ""} ${$0 ?? ""}`);
4934
- $.set_attribute(time, "datetime", $1);
4935
- $.set_attribute(time, "aria-label", $2);
4933
+ ($0, $1, $2, $3) => {
4934
+ $.set_class(div_2, 1, `${$theme().day ?? ""} ${$0 ?? ""}${$1 ?? ""}`);
4935
+ $.set_attribute(time, "datetime", $2);
4936
+ $.set_attribute(time, "aria-label", $3);
4936
4937
  },
4937
4938
  [
4938
4939
  () => {
4939
4940
  var _a;
4940
4941
  return (_a = $theme().weekdays) == null ? void 0 : _a[$.get(item0).getUTCDay()];
4941
4942
  },
4943
+ () => datesEqual($.get(item0), $_today()) ? " " + $theme().today : "",
4942
4944
  () => toISOString($.get(item0), 10),
4943
4945
  () => $_intlDayHeaderAL().format($.get(item0))
4944
4946
  ]
@@ -4992,16 +4994,17 @@ function View$1($$anchor, $$props) {
4992
4994
  $.action(time_1, ($$node, $$action_arg) => setContent == null ? void 0 : setContent($$node, $$action_arg), () => $_intlDayHeader().format($.get(item1)));
4993
4995
  $.reset(div_6);
4994
4996
  $.template_effect(
4995
- ($0, $1, $2) => {
4996
- $.set_class(div_6, 1, `${$theme().day ?? ""} ${$0 ?? ""}`);
4997
- $.set_attribute(time_1, "datetime", $1);
4998
- $.set_attribute(time_1, "aria-label", `${resourceLabels[i] ?? ""}${$2 ?? ""}`);
4997
+ ($0, $1, $2, $3) => {
4998
+ $.set_class(div_6, 1, `${$theme().day ?? ""} ${$0 ?? ""}${$1 ?? ""}`);
4999
+ $.set_attribute(time_1, "datetime", $2);
5000
+ $.set_attribute(time_1, "aria-label", `${resourceLabels[i] ?? ""}${$3 ?? ""}`);
4999
5001
  },
5000
5002
  [
5001
5003
  () => {
5002
5004
  var _a;
5003
5005
  return (_a = $theme().weekdays) == null ? void 0 : _a[$.get(item1).getUTCDay()];
5004
5006
  },
5007
+ () => datesEqual($.get(item1), $_today()) ? " " + $theme().today : "",
5005
5008
  () => toISOString($.get(item1), 10),
5006
5009
  () => $_intlDayHeaderAL().format($.get(item1))
5007
5010
  ]
@@ -5247,7 +5250,7 @@ function onclick(_, expanded, payload, toggle, resources) {
5247
5250
  toggle($.get(payload).children, $.get(expanded));
5248
5251
  resources.update(identity);
5249
5252
  }
5250
- var root_1$3 = $.template(`<span></span>`);
5253
+ var root_1$4 = $.template(`<span></span>`);
5251
5254
  var root_2$2 = $.template(`<button><!></button>`);
5252
5255
  var root$6 = $.template(`<!> <span><!></span>`, 1);
5253
5256
  function Expander($$anchor, $$props) {
@@ -5273,7 +5276,7 @@ function Expander($$anchor, $$props) {
5273
5276
  var fragment = root$6();
5274
5277
  var node = $.first_child(fragment);
5275
5278
  $.each(node, 17, () => Array($.get(payload).level), $.index, ($$anchor2, level) => {
5276
- var span = root_1$3();
5279
+ var span = root_1$4();
5277
5280
  $.template_effect(() => $.set_class(span, 1, $theme().expander));
5278
5281
  $.append($$anchor2, span);
5279
5282
  });
@@ -5320,7 +5323,7 @@ function Expander($$anchor, $$props) {
5320
5323
  $$cleanup();
5321
5324
  }
5322
5325
  $.delegate(["click"]);
5323
- var root_1$2 = $.template(`<div role="rowheader"><!> <!></div>`);
5326
+ var root_1$3 = $.template(`<div role="rowheader"><!> <!></div>`);
5324
5327
  var root$5 = $.template(`<div><div></div> <div></div></div>`);
5325
5328
  function Sidebar($$anchor, $$props) {
5326
5329
  $.push($$props, false);
@@ -5349,7 +5352,7 @@ function Sidebar($$anchor, $$props) {
5349
5352
  var div_1 = $.child(div);
5350
5353
  var div_2 = $.sibling(div_1, 2);
5351
5354
  $.each(div_2, 5, $_viewResources, $.index, ($$anchor2, resource) => {
5352
- var div_3 = root_1$2();
5355
+ var div_3 = root_1$3();
5353
5356
  var node = $.child(div_3);
5354
5357
  {
5355
5358
  var consequent = ($$anchor3) => {
@@ -5399,7 +5402,7 @@ function Sidebar($$anchor, $$props) {
5399
5402
  var root_3 = $.template(`<div role="columnheader"><time></time></div>`);
5400
5403
  var root_2$1 = $.template(`<div><time></time></div> <div></div>`, 1);
5401
5404
  var root_4 = $.template(`<div role="columnheader"><time></time></div>`);
5402
- var root_1$1 = $.template(`<div><!></div>`);
5405
+ var root_1$2 = $.template(`<div><!></div>`);
5403
5406
  var root$4 = $.template(`<div><div role="row"></div> <div></div></div>`);
5404
5407
  function Header($$anchor, $$props) {
5405
5408
  $.push($$props, false);
@@ -5407,6 +5410,7 @@ function Header($$anchor, $$props) {
5407
5410
  const $theme = () => $.store_get(theme, "$theme", $$stores);
5408
5411
  const $_headerEl = () => $.store_get(_headerEl, "$_headerEl", $$stores);
5409
5412
  const $_viewDates = () => $.store_get(_viewDates, "$_viewDates", $$stores);
5413
+ const $_today = () => $.store_get(_today, "$_today", $$stores);
5410
5414
  const $slotDuration = () => $.store_get(slotDuration, "$slotDuration", $$stores);
5411
5415
  const $_intlDayHeaderAL = () => $.store_get(_intlDayHeaderAL, "$_intlDayHeaderAL", $$stores);
5412
5416
  const $_intlDayHeader = () => $.store_get(_intlDayHeader, "$_intlDayHeader", $$stores);
@@ -5417,6 +5421,7 @@ function Header($$anchor, $$props) {
5417
5421
  _intlDayHeader,
5418
5422
  _intlDayHeaderAL,
5419
5423
  _dayTimes,
5424
+ _today,
5420
5425
  _viewDates,
5421
5426
  slotDuration,
5422
5427
  theme
@@ -5425,7 +5430,7 @@ function Header($$anchor, $$props) {
5425
5430
  var div = root$4();
5426
5431
  var div_1 = $.child(div);
5427
5432
  $.each(div_1, 5, $_viewDates, $.index, ($$anchor2, date) => {
5428
- var div_2 = root_1$1();
5433
+ var div_2 = root_1$2();
5429
5434
  var node = $.child(div_2);
5430
5435
  {
5431
5436
  var consequent = ($$anchor3) => {
@@ -5488,12 +5493,13 @@ function Header($$anchor, $$props) {
5488
5493
  }
5489
5494
  $.reset(div_2);
5490
5495
  $.template_effect(
5491
- ($0) => $.set_class(div_2, 1, `${$theme().day ?? ""} ${$0 ?? ""}`),
5496
+ ($0, $1) => $.set_class(div_2, 1, `${$theme().day ?? ""} ${$0 ?? ""}${$1 ?? ""}`),
5492
5497
  [
5493
5498
  () => {
5494
5499
  var _a;
5495
5500
  return (_a = $theme().weekdays) == null ? void 0 : _a[$.get(date).getUTCDay()];
5496
- }
5501
+ },
5502
+ () => datesEqual($.get(date), $_today()) ? " " + $theme().today : ""
5497
5503
  ],
5498
5504
  $.derived_safe_equal
5499
5505
  );
@@ -5696,7 +5702,7 @@ function Event($$anchor, $$props) {
5696
5702
  $$cleanup();
5697
5703
  return $$pop;
5698
5704
  }
5699
- var root_1 = $.template(`<!> <!> <!> <!>`, 1);
5705
+ var root_1$1 = $.template(`<!> <!> <!> <!>`, 1);
5700
5706
  var root$3 = $.template(`<div role="cell"><div><!></div></div>`);
5701
5707
  function Day($$anchor, $$props) {
5702
5708
  $.push($$props, true);
@@ -5758,7 +5764,7 @@ function Day($$anchor, $$props) {
5758
5764
  var node = $.child(div_1);
5759
5765
  {
5760
5766
  var consequent_2 = ($$anchor2) => {
5761
- var fragment = root_1();
5767
+ var fragment = root_1$1();
5762
5768
  var node_1 = $.first_child(fragment);
5763
5769
  $.each(node_1, 17, () => $.get(dayBgChunks), (chunk) => chunk.event, ($$anchor3, chunk) => {
5764
5770
  Event($$anchor3, {
@@ -5963,9 +5969,9 @@ var root$1 = $.template(`<div><div><div></div> <!></div></div>`);
5963
5969
  function Body($$anchor, $$props) {
5964
5970
  $.push($$props, true);
5965
5971
  const [$$stores, $$cleanup] = $.setup_stores();
5966
- const $_bodyEl = () => $.store_get(_bodyEl, "$_bodyEl", $$stores);
5967
5972
  const $_dayTimeLimits = () => $.store_get(_dayTimeLimits, "$_dayTimeLimits", $$stores);
5968
5973
  const $_viewDates = () => $.store_get(_viewDates, "$_viewDates", $$stores);
5974
+ const $_bodyEl = () => $.store_get(_bodyEl, "$_bodyEl", $$stores);
5969
5975
  const $scrollTime = () => $.store_get(scrollTime, "$scrollTime", $$stores);
5970
5976
  const $slotDuration = () => $.store_get(slotDuration, "$slotDuration", $$stores);
5971
5977
  const $slotWidth = () => $.store_get(slotWidth, "$slotWidth", $$stores);
@@ -5978,28 +5984,28 @@ function Body($$anchor, $$props) {
5978
5984
  const $_dayTimes = () => $.store_get(_dayTimes, "$_dayTimes", $$stores);
5979
5985
  let {
5980
5986
  _bodyEl,
5987
+ _bodyHeight,
5988
+ _bodyWidth,
5989
+ _bodyScrollLeft,
5981
5990
  _headerEl,
5982
5991
  _events,
5983
5992
  _sidebarEl,
5984
5993
  _dayTimes,
5985
5994
  _dayTimeLimits,
5995
+ _recheckScrollable,
5986
5996
  _resHs,
5987
5997
  _viewResources,
5988
5998
  _viewDates,
5989
- _recheckScrollable,
5990
5999
  scrollTime,
5991
6000
  slotDuration,
5992
6001
  slotWidth,
5993
6002
  theme
5994
6003
  } = getContext("state");
5995
- let el = $.state(void 0);
5996
6004
  let refs = [];
5997
- $.user_effect(() => {
5998
- $.store_set(_bodyEl, $.get(el));
5999
- });
6000
6005
  function scrollToTime() {
6001
6006
  let slotTimeLimits2 = getSlotTimeLimits($_dayTimeLimits(), $_viewDates()[0]);
6002
- $.get(el).scrollLeft = (toSeconds($scrollTime()) - toSeconds(slotTimeLimits2.min)) / toSeconds($slotDuration()) * $slotWidth();
6007
+ $.store_mutate(_bodyEl, $.untrack($_bodyEl).scrollLeft = (toSeconds($scrollTime()) - toSeconds(slotTimeLimits2.min)) / toSeconds($slotDuration()) * $slotWidth(), $.untrack($_bodyEl));
6008
+ $.store_set(_bodyScrollLeft, $_bodyEl().scrollLeft);
6003
6009
  }
6004
6010
  $.user_effect(() => {
6005
6011
  $_viewDates();
@@ -6018,6 +6024,12 @@ function Body($$anchor, $$props) {
6018
6024
  function onscroll() {
6019
6025
  $.store_mutate(_headerEl, $.untrack($_headerEl).scrollLeft = $_bodyEl().scrollLeft, $.untrack($_headerEl));
6020
6026
  $.store_mutate(_sidebarEl, $.untrack($_sidebarEl).scrollTop = $_bodyEl().scrollTop, $.untrack($_sidebarEl));
6027
+ $.store_set(_bodyScrollLeft, $_bodyEl().scrollLeft);
6028
+ }
6029
+ function onresize() {
6030
+ $.store_set(_bodyHeight, $_bodyEl().clientHeight);
6031
+ $.store_set(_bodyWidth, $_bodyEl().clientWidth);
6032
+ $.store_set(_recheckScrollable, true);
6021
6033
  }
6022
6034
  var div = root$1();
6023
6035
  $.event("resize", $.window, reposition);
@@ -6049,8 +6061,8 @@ function Body($$anchor, $$props) {
6049
6061
  });
6050
6062
  $.reset(div_1);
6051
6063
  $.reset(div);
6052
- $.bind_this(div, ($$value) => $.set(el, $$value), () => $.get(el));
6053
- $.action(div, ($$node, $$action_arg) => observeResize == null ? void 0 : observeResize($$node, $$action_arg), () => () => $.store_set(_recheckScrollable, true));
6064
+ $.bind_this(div, ($$value) => $.store_set(_bodyEl, $$value), () => $_bodyEl());
6065
+ $.action(div, ($$node, $$action_arg) => observeResize == null ? void 0 : observeResize($$node, $$action_arg), () => onresize);
6054
6066
  $.template_effect(() => {
6055
6067
  $.set_class(div, 1, $theme().body);
6056
6068
  $.set_class(div_1, 1, $theme().content);
@@ -6061,12 +6073,85 @@ function Body($$anchor, $$props) {
6061
6073
  $.pop();
6062
6074
  $$cleanup();
6063
6075
  }
6064
- var root = $.template(`<div><!> <div><!> <!></div></div>`);
6076
+ var root_1 = $.template(`<div></div>`);
6077
+ function NowIndicator($$anchor, $$props) {
6078
+ $.push($$props, true);
6079
+ const [$$stores, $$cleanup] = $.setup_stores();
6080
+ const $_viewDates = () => $.store_get(_viewDates, "$_viewDates", $$stores);
6081
+ const $_dayTimeLimits = () => $.store_get(_dayTimeLimits, "$_dayTimeLimits", $$stores);
6082
+ const $_today = () => $.store_get(_today, "$_today", $$stores);
6083
+ const $_now = () => $.store_get(_now, "$_now", $$stores);
6084
+ const $slotDuration = () => $.store_get(slotDuration, "$slotDuration", $$stores);
6085
+ const $slotWidth = () => $.store_get(slotWidth, "$slotWidth", $$stores);
6086
+ const $_bodyScrollLeft = () => $.store_get(_bodyScrollLeft, "$_bodyScrollLeft", $$stores);
6087
+ const $_bodyWidth = () => $.store_get(_bodyWidth, "$_bodyWidth", $$stores);
6088
+ const $theme = () => $.store_get(theme, "$theme", $$stores);
6089
+ const $_headerHeight = () => $.store_get(_headerHeight, "$_headerHeight", $$stores);
6090
+ const $_bodyHeight = () => $.store_get(_bodyHeight, "$_bodyHeight", $$stores);
6091
+ let {
6092
+ slotDuration,
6093
+ slotWidth,
6094
+ theme,
6095
+ _bodyHeight,
6096
+ _bodyWidth,
6097
+ _bodyScrollLeft,
6098
+ _headerHeight,
6099
+ _dayTimeLimits,
6100
+ _now,
6101
+ _today,
6102
+ _viewDates
6103
+ } = getContext("state");
6104
+ let left = $.derived(() => {
6105
+ let offset = 0;
6106
+ for (let i = 0; i < $_viewDates().length; ++i) {
6107
+ let slotTimeLimits2 = getSlotTimeLimits($_dayTimeLimits(), $_viewDates()[i]);
6108
+ if (datesEqual($_viewDates()[i], $_today())) {
6109
+ let dayStart = addDuration(cloneDate($_viewDates()[i]), slotTimeLimits2.min);
6110
+ let dayEnd = addDuration(cloneDate($_viewDates()[i]), slotTimeLimits2.max);
6111
+ if ($_now() >= dayStart && $_now() <= dayEnd) {
6112
+ offset += ($_now() - dayStart) / 1e3;
6113
+ break;
6114
+ } else {
6115
+ return null;
6116
+ }
6117
+ } else {
6118
+ offset += slotTimeLimits2.max.seconds - slotTimeLimits2.min.seconds;
6119
+ }
6120
+ }
6121
+ let step = $slotDuration().seconds;
6122
+ return offset / step * $slotWidth() - $_bodyScrollLeft();
6123
+ });
6124
+ var fragment = $.comment();
6125
+ var node = $.first_child(fragment);
6126
+ {
6127
+ var consequent = ($$anchor2) => {
6128
+ var div = root_1();
6129
+ let styles;
6130
+ $.template_effect(() => {
6131
+ $.set_class(div, 1, $theme().nowIndicator);
6132
+ styles = $.set_style(div, "", styles, {
6133
+ top: `${$_headerHeight() + 2}px`,
6134
+ left: `${$.get(left) ?? ""}px`,
6135
+ height: `${$_bodyHeight() - 1}px`
6136
+ });
6137
+ });
6138
+ $.append($$anchor2, div);
6139
+ };
6140
+ $.if(node, ($$render) => {
6141
+ if ($.get(left) !== null && $.get(left) >= 3 && $.get(left) <= $_bodyWidth() - 3) $$render(consequent);
6142
+ });
6143
+ }
6144
+ $.append($$anchor, fragment);
6145
+ $.pop();
6146
+ $$cleanup();
6147
+ }
6148
+ var root = $.template(`<div><!> <div><!> <!> <!></div></div>`);
6065
6149
  function View($$anchor, $$props) {
6066
6150
  $.push($$props, false);
6067
6151
  const [$$stores, $$cleanup] = $.setup_stores();
6068
6152
  const $theme = () => $.store_get(theme, "$theme", $$stores);
6069
- let { theme } = getContext("state");
6153
+ const $nowIndicator = () => $.store_get(nowIndicator, "$nowIndicator", $$stores);
6154
+ let { nowIndicator, theme } = getContext("state");
6070
6155
  $.init();
6071
6156
  var div = root();
6072
6157
  var node = $.child(div);
@@ -6076,6 +6161,15 @@ function View($$anchor, $$props) {
6076
6161
  Header(node_1, {});
6077
6162
  var node_2 = $.sibling(node_1, 2);
6078
6163
  Body(node_2, {});
6164
+ var node_3 = $.sibling(node_2, 2);
6165
+ {
6166
+ var consequent = ($$anchor2) => {
6167
+ NowIndicator($$anchor2, {});
6168
+ };
6169
+ $.if(node_3, ($$render) => {
6170
+ if ($nowIndicator()) $$render(consequent);
6171
+ });
6172
+ }
6079
6173
  $.reset(div_1);
6080
6174
  $.reset(div);
6081
6175
  $.template_effect(() => {
@@ -6132,6 +6226,9 @@ const index = {
6132
6226
  if (!("_viewResources" in state)) {
6133
6227
  state._viewResources = viewResources(state);
6134
6228
  }
6229
+ state._bodyHeight = writable(0);
6230
+ state._bodyWidth = writable(0);
6231
+ state._bodyScrollLeft = writable(0);
6135
6232
  state._headerEl = writable(void 0);
6136
6233
  state._headerHeight = writable(0);
6137
6234
  state._dayTimeLimits = dayTimeLimits(state);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@event-calendar/core",
3
- "version": "4.1.0",
3
+ "version": "4.3.0",
4
4
  "title": "Event Calendar Core package",
5
5
  "description": "Full-sized drag & drop event calendar with resource & timeline views",
6
6
  "keywords": [
@@ -32,6 +32,6 @@
32
32
  "#components": "./src/lib/components/index.js"
33
33
  },
34
34
  "dependencies": {
35
- "svelte": "^5.28.2"
35
+ "svelte": "^5.28.6"
36
36
  }
37
37
  }
@@ -68,19 +68,18 @@
68
68
  }
69
69
 
70
70
  export function updateEvent(event) {
71
- for (let e of $_events) {
72
- if (e.id == event.id) {
73
- event = createEvents([event])[0];
74
- assign(e, event);
75
- $_events = $_events;
76
- return toEventWithLocalDates(event);
77
- }
71
+ let id = String(event.id);
72
+ let idx = $_events.findIndex(event => event.id === id);
73
+ if (idx >= 0) {
74
+ $_events[idx] = createEvents([event])[0];
75
+ return toEventWithLocalDates(event);
78
76
  }
79
77
  return null;
80
78
  }
81
79
 
82
80
  export function removeEventById(id) {
83
- let idx = $_events.findIndex(event => event.id == id);
81
+ id = String(id);
82
+ let idx = $_events.findIndex(event => event.id === id);
84
83
  if (idx >= 0) {
85
84
  $_events.splice(idx, 1);
86
85
  $_events = $_events;
@@ -77,8 +77,8 @@
77
77
  {onmouseleave}
78
78
  {onpointerdown}
79
79
  >
80
- {#snippet defaultBody(style)}
81
- <div class={$theme.eventBody} {style} use:setContent={content}></div>
80
+ {#snippet defaultBody()}
81
+ <div class={$theme.eventBody} use:setContent={content}></div>
82
82
  {/snippet}
83
83
  {#if body}
84
84
  {@render body(defaultBody, bgColor, txtColor)}
@@ -17,6 +17,6 @@
17
17
  <BaseEvent {chunk} {styles} onpointerdown={$_interaction.action?.noAction}>
18
18
  {#snippet body(defaultBody, bgColor, txtColor)}
19
19
  <div class="{$theme.eventTag}" style:background-color={bgColor}></div>
20
- {@render defaultBody(`color:${txtColor}`)}
20
+ {@render defaultBody()}
21
21
  {/snippet}
22
22
  </BaseEvent>
@@ -1,11 +1,11 @@
1
1
  <script>
2
2
  import {getContext} from 'svelte';
3
- import {setContent, toISOString} from '#lib';
3
+ import {datesEqual, setContent, toISOString} from '#lib';
4
4
  import {Section, Body, Day, Week} from '../time-grid/index.js';
5
5
  import Label from './Label.svelte';
6
6
 
7
7
  let {
8
- datesAboveResources, _viewDates, _viewResources, _intlDayHeader, _intlDayHeaderAL, allDaySlot, theme
8
+ datesAboveResources, _today, _viewDates, _viewResources, _intlDayHeader, _intlDayHeaderAL, allDaySlot, theme
9
9
  } = getContext('state');
10
10
 
11
11
  let loops = $derived($datesAboveResources ? [$_viewDates, $_viewResources] : [$_viewResources, $_viewDates]);
@@ -18,7 +18,7 @@
18
18
  {#each loops[0] as item0, i}
19
19
  <div class="{$theme.resource}">
20
20
  {#if $datesAboveResources}
21
- <div class="{$theme.day} {$theme.weekdays?.[item0.getUTCDay()]}">
21
+ <div class="{$theme.day} {$theme.weekdays?.[item0.getUTCDay()]}{datesEqual(item0, $_today) ? ' ' + $theme.today : ''}">
22
22
  <time
23
23
  datetime="{toISOString(item0, 10)}"
24
24
  aria-label="{$_intlDayHeaderAL.format(item0)}"
@@ -38,7 +38,10 @@
38
38
  <Label resource={item1} date={item0} />
39
39
  </div>
40
40
  {:else}
41
- <div class="{$theme.day} {$theme.weekdays?.[item1.getUTCDay()]}" role="columnheader">
41
+ <div
42
+ class="{$theme.day} {$theme.weekdays?.[item1.getUTCDay()]}{datesEqual(item1, $_today) ? ' ' + $theme.today : ''}"
43
+ role="columnheader"
44
+ >
42
45
  <time
43
46
  datetime="{toISOString(item1, 10)}"
44
47
  aria-label="{resourceLabels[i]}{$_intlDayHeaderAL.format(item1)}"
@@ -4,19 +4,15 @@
4
4
  import {getSlotTimeLimits} from './lib.js';
5
5
  import Days from './Days.svelte';
6
6
 
7
- let {_bodyEl, _headerEl, _events, _sidebarEl, _dayTimes, _dayTimeLimits, _resHs, _viewResources, _viewDates,
8
- _recheckScrollable, scrollTime, slotDuration, slotWidth, theme} = getContext('state');
7
+ let {_bodyEl, _bodyHeight, _bodyWidth, _bodyScrollLeft, _headerEl, _events, _sidebarEl, _dayTimes, _dayTimeLimits,
8
+ _recheckScrollable, _resHs, _viewResources, _viewDates, scrollTime, slotDuration, slotWidth, theme} = getContext('state');
9
9
 
10
- let el = $state();
11
10
  let refs = [];
12
11
 
13
- $effect(() => {
14
- $_bodyEl = el;
15
- });
16
-
17
12
  function scrollToTime() {
18
13
  let slotTimeLimits = getSlotTimeLimits($_dayTimeLimits, $_viewDates[0]);
19
- el.scrollLeft = (toSeconds($scrollTime) - toSeconds(slotTimeLimits.min)) / toSeconds($slotDuration) * $slotWidth;
14
+ $_bodyEl.scrollLeft = (toSeconds($scrollTime) - toSeconds(slotTimeLimits.min)) / toSeconds($slotDuration) * $slotWidth;
15
+ $_bodyScrollLeft = $_bodyEl.scrollLeft;
20
16
  }
21
17
  $effect(() => {
22
18
  $_viewDates;
@@ -37,14 +33,21 @@
37
33
  function onscroll() {
38
34
  $_headerEl.scrollLeft = $_bodyEl.scrollLeft;
39
35
  $_sidebarEl.scrollTop = $_bodyEl.scrollTop;
36
+ $_bodyScrollLeft = $_bodyEl.scrollLeft;
37
+ }
38
+
39
+ function onresize() {
40
+ $_bodyHeight = $_bodyEl.clientHeight;
41
+ $_bodyWidth = $_bodyEl.clientWidth;
42
+ $_recheckScrollable = true;
40
43
  }
41
44
  </script>
42
45
 
43
46
  <div
44
- bind:this={el}
47
+ bind:this={$_bodyEl}
45
48
  class="{$theme.body}"
46
49
  {onscroll}
47
- use:observeResize={() => $_recheckScrollable = true}
50
+ use:observeResize={onresize}
48
51
  >
49
52
  <div class="{$theme.content}">
50
53
  <div class="{$theme.lines}">
@@ -1,14 +1,15 @@
1
1
  <script>
2
2
  import {getContext} from 'svelte';
3
- import {setContent, toISOString, toSeconds, observeResize} from '#lib';
3
+ import {datesEqual, setContent, toISOString, toSeconds, observeResize} from '#lib';
4
4
 
5
- let {_headerEl, _headerHeight,_intlDayHeader, _intlDayHeaderAL, _dayTimes, _viewDates, slotDuration, theme} = getContext('state');
5
+ let {_headerEl, _headerHeight, _intlDayHeader, _intlDayHeaderAL, _dayTimes, _today, _viewDates,
6
+ slotDuration, theme} = getContext('state');
6
7
  </script>
7
8
 
8
9
  <div class="{$theme.header}" bind:this={$_headerEl} use:observeResize={() => $_headerHeight = $_headerEl.clientHeight}>
9
10
  <div class="{$theme.days}" role="row">
10
11
  {#each $_viewDates as date}
11
- <div class="{$theme.day} {$theme.weekdays?.[date.getUTCDay()]}">
12
+ <div class="{$theme.day} {$theme.weekdays?.[date.getUTCDay()]}{datesEqual(date, $_today) ? ' ' + $theme.today : ''}">
12
13
  {#if toSeconds($slotDuration)}
13
14
  <div class="{$theme.dayHead}">
14
15
  <time
@@ -0,0 +1,39 @@
1
+ <script>
2
+ import {getContext} from 'svelte';
3
+ import {addDuration, cloneDate, datesEqual} from '#lib';
4
+ import {getSlotTimeLimits} from './lib.js';
5
+
6
+ let {slotDuration, slotWidth, theme, _bodyHeight, _bodyWidth, _bodyScrollLeft,
7
+ _headerHeight, _dayTimeLimits, _now, _today, _viewDates} = getContext('state');
8
+
9
+ // Style
10
+ let left = $derived.by(() => {
11
+ let offset = 0;
12
+ for (let i = 0; i < $_viewDates.length; ++i) {
13
+ let slotTimeLimits = getSlotTimeLimits($_dayTimeLimits, $_viewDates[i]);
14
+ if (datesEqual($_viewDates[i], $_today)) {
15
+ let dayStart = addDuration(cloneDate($_viewDates[i]), slotTimeLimits.min);
16
+ let dayEnd = addDuration(cloneDate($_viewDates[i]), slotTimeLimits.max);
17
+ if ($_now >= dayStart && $_now <= dayEnd) {
18
+ offset += ($_now - dayStart) / 1000;
19
+ break;
20
+ } else {
21
+ return null;
22
+ }
23
+ } else {
24
+ offset += slotTimeLimits.max.seconds - slotTimeLimits.min.seconds;
25
+ }
26
+ }
27
+ let step = $slotDuration.seconds;
28
+ return offset / step * $slotWidth - $_bodyScrollLeft;
29
+ });
30
+ </script>
31
+
32
+ {#if left !== null && left >= 3 && left <= $_bodyWidth - 3}
33
+ <div
34
+ class="{$theme.nowIndicator}"
35
+ style:top="{$_headerHeight+2}px"
36
+ style:left="{left}px"
37
+ style:height="{$_bodyHeight-1}px"
38
+ ></div>
39
+ {/if}
@@ -3,8 +3,9 @@
3
3
  import Sidebar from './Sidebar.svelte';
4
4
  import Header from './Header.svelte';
5
5
  import Body from './Body.svelte';
6
+ import NowIndicator from './NowIndicator.svelte';
6
7
 
7
- let {theme} = getContext('state');
8
+ let {nowIndicator, theme} = getContext('state');
8
9
  </script>
9
10
 
10
11
  <div class="{$theme.container}">
@@ -12,5 +13,8 @@
12
13
  <div class="{$theme.main}">
13
14
  <Header/>
14
15
  <Body/>
16
+ {#if $nowIndicator}
17
+ <NowIndicator/>
18
+ {/if}
15
19
  </div>
16
20
  </div>
@@ -51,6 +51,9 @@ export default {
51
51
  if (!('_viewResources' in state)) {
52
52
  state._viewResources = viewResources(state);
53
53
  }
54
+ state._bodyHeight = writable(0);
55
+ state._bodyWidth = writable(0);
56
+ state._bodyScrollLeft = writable(0);
54
57
  state._headerEl = writable(undefined);
55
58
  state._headerHeight = writable(0);
56
59
  state._dayTimeLimits = dayTimeLimits(state); // flexible time limits per day
@@ -3,11 +3,11 @@
3
3
 
4
4
  let {slotDuration, slotHeight, theme, _now, _today, _slotTimeLimits} = getContext('state');
5
5
 
6
- let start = $derived(($_now - $_today) / 1000 / 60);
6
+ let start = $derived(($_now - $_today) / 1000);
7
7
  // Style
8
8
  let top = $derived.by(() => {
9
- let step = $slotDuration.seconds / 60;
10
- let offset = $_slotTimeLimits.min.seconds / 60;
9
+ let step = $slotDuration.seconds;
10
+ let offset = $_slotTimeLimits.min.seconds;
11
11
  return (start - offset) / step * $slotHeight;
12
12
  });
13
13
  </script>
@@ -1,18 +1,21 @@
1
1
  <script>
2
2
  import {getContext} from 'svelte';
3
- import {setContent, toISOString} from '#lib';
3
+ import {datesEqual, setContent, toISOString} from '#lib';
4
4
  import Section from './Section.svelte';
5
5
  import Body from './Body.svelte';
6
6
  import Day from './Day.svelte';
7
7
  import Week from './all-day/Week.svelte';
8
8
 
9
- let {_viewDates, _intlDayHeader, _intlDayHeaderAL, allDaySlot, theme} = getContext('state');
9
+ let {_viewDates, _intlDayHeader, _intlDayHeaderAL, _today, allDaySlot, theme} = getContext('state');
10
10
  </script>
11
11
 
12
12
  <div class="{$theme.header}">
13
13
  <Section>
14
14
  {#each $_viewDates as date}
15
- <div class="{$theme.day} {$theme.weekdays?.[date.getUTCDay()]}" role="columnheader">
15
+ <div
16
+ class="{$theme.day} {$theme.weekdays?.[date.getUTCDay()]}{datesEqual(date, $_today) ? ' ' + $theme.today : ''}"
17
+ role="columnheader"
18
+ >
16
19
  <time
17
20
  datetime="{toISOString(date, 10)}"
18
21
  aria-label="{$_intlDayHeaderAL.format(date)}"
@@ -284,6 +284,13 @@
284
284
  top: 0;
285
285
  z-index: 2;
286
286
  }
287
+ .ec-day.ec-today .ec-day-head:before {
288
+ content: '';
289
+ position: absolute;
290
+ inset: 0;
291
+ z-index: -1;
292
+ background-color: var(--ec-today-bg-color);
293
+ }
287
294
 
288
295
  .ec-day:first-child .ec-day-head {
289
296
  border-top: none;
@@ -490,19 +497,28 @@
490
497
  .ec-now-indicator {
491
498
  position: absolute;
492
499
  z-index: 1005;
493
- width: 100%;
494
- border-top: var(--ec-now-indicator-color) solid 2px;
495
500
  pointer-events: none;
501
+ .ec-time-grid & {
502
+ width: 100%;
503
+ border-top: var(--ec-now-indicator-color) solid 2px;
504
+ }
505
+ .ec-timeline & {
506
+ height: 100%;
507
+ border-left: var(--ec-now-indicator-color) solid 2px;
508
+ will-change: transform;
509
+ }
496
510
 
497
511
  &:before {
498
512
  background: var(--ec-now-indicator-color);
499
513
  border-radius: 50%;
500
514
  content: "";
501
- position: absolute;
515
+ display: block;
502
516
  height: 12px;
503
517
  margin-top: -7px;
504
518
  width: 12px;
505
- pointer-events: none;
519
+ .ec-timeline & {
520
+ margin-left: -7px;
521
+ }
506
522
  }
507
523
  }
508
524
 
@@ -9,6 +9,7 @@
9
9
  display: flex;
10
10
  flex-direction: column;
11
11
  min-width: 0;
12
+ position: relative;
12
13
  }
13
14
 
14
15
  .ec-content {