@event-calendar/core 3.6.2 → 3.7.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
@@ -203,8 +203,8 @@ Or in your Svelte component, use the calendar like this:
203
203
  ### Pre-built browser ready bundle
204
204
  Include the following lines of code in the `<head>` section of your page:
205
205
  ```html
206
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@event-calendar/build@3.6.2/event-calendar.min.css">
207
- <script src="https://cdn.jsdelivr.net/npm/@event-calendar/build@3.6.2/event-calendar.min.js"></script>
206
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@event-calendar/build@3.7.0/event-calendar.min.css">
207
+ <script src="https://cdn.jsdelivr.net/npm/@event-calendar/build@3.7.0/event-calendar.min.js"></script>
208
208
  ```
209
209
 
210
210
  <details>
@@ -2095,7 +2095,7 @@ Defines the time slot width in pixels in `ResourceTimeline` views. When changing
2095
2095
 
2096
2096
  ### theme
2097
2097
  - Type `object` or `function`
2098
- - Default `{allDay: 'ec-all-day', active: 'ec-active', bgEvent: 'ec-bg-event', bgEvents: 'ec-bg-events', body: 'ec-body', button: 'ec-button', buttonGroup: 'ec-button-group', calendar: 'ec', compact: 'ec-compact', container: 'ec-container', content: 'ec-content', day: 'ec-day', dayHead: 'ec-day-head', dayFoot: 'ec-day-foot', days: 'ec-days', daySide: 'ec-day-side', draggable: 'ec-draggable', dragging: 'ec-dragging', event: 'ec-event', eventBody: 'ec-event-body', eventTag: 'ec-event-tag', eventTime: 'ec-event-time', eventTitle: 'ec-event-title', events: 'ec-events', extra: 'ec-extra', ghost: 'ec-ghost', handle: 'ec-handle', header: 'ec-header', hiddenScroll: 'ec-hidden-scroll', highlight: 'ec-highlight', icon: 'ec-icon', line: 'ec-line', lines: 'ec-lines', main: 'ec-main', noEvents: 'ec-no-events', nowIndicator: 'ec-now-indicator', otherMonth: 'ec-other-month', pointer: 'ec-pointer', popup: 'ec-popup', preview: 'ec-preview', resizer: 'ec-resizer', resizingX: 'ec-resizing-x', resizingY: 'ec-resizing-y', resource: 'ec-resource', selecting: 'ec-selecting', sidebar: 'ec-sidebar', sidebarTitle: 'ec-sidebar-title', today: 'ec-today', time: 'ec-time', times: 'ec-times', title: 'ec-title', toolbar: 'ec-toolbar', view: 'ec-timeline ec-resource-week-view', weekdays: ['ec-sun', 'ec-mon', 'ec-tue', 'ec-wed', 'ec-thu', 'ec-fri', 'ec-sat'], withScroll: 'ec-with-scroll', uniform: 'ec-uniform'}`
2098
+ - Default `{allDay: 'ec-all-day', active: 'ec-active', bgEvent: 'ec-bg-event', bgEvents: 'ec-bg-events', body: 'ec-body', button: 'ec-button', buttonGroup: 'ec-button-group', calendar: 'ec', compact: 'ec-compact', container: 'ec-container', content: 'ec-content', day: 'ec-day', dayHead: 'ec-day-head', dayFoot: 'ec-day-foot', days: 'ec-days', daySide: 'ec-day-side', draggable: 'ec-draggable', dragging: 'ec-dragging', event: 'ec-event', eventBody: 'ec-event-body', eventTag: 'ec-event-tag', eventTime: 'ec-event-time', eventTitle: 'ec-event-title', events: 'ec-events', expander: 'ec-expander', extra: 'ec-extra', ghost: 'ec-ghost', handle: 'ec-handle', header: 'ec-header', hiddenScroll: 'ec-hidden-scroll', highlight: 'ec-highlight', icon: 'ec-icon', line: 'ec-line', lines: 'ec-lines', main: 'ec-main', noEvents: 'ec-no-events', nowIndicator: 'ec-now-indicator', otherMonth: 'ec-other-month', pointer: 'ec-pointer', popup: 'ec-popup', preview: 'ec-preview', resizer: 'ec-resizer', resizingX: 'ec-resizing-x', resizingY: 'ec-resizing-y', resource: 'ec-resource', selecting: 'ec-selecting', sidebar: 'ec-sidebar', sidebarTitle: 'ec-sidebar-title', today: 'ec-today', time: 'ec-time', times: 'ec-times', title: 'ec-title', toolbar: 'ec-toolbar', view: 'ec-timeline ec-resource-week-view', weekdays: ['ec-sun', 'ec-mon', 'ec-tue', 'ec-wed', 'ec-thu', 'ec-fri', 'ec-sat'], withScroll: 'ec-with-scroll', uniform: 'ec-uniform'}`
2099
2099
  > Views override the default value as follows:
2100
2100
  > - dayGridMonth `theme => ({...theme, view: 'ec-day-grid ec-month-view'})`
2101
2101
  > - listDay `theme => ({...theme, view: 'ec-list ec-day-view'})`
@@ -2890,8 +2890,36 @@ Here are all admissible fields for the resource’s input object:
2890
2890
  `object` A plain object with any miscellaneous properties. It will be directly transferred to the `extendedProps` property of the Resource object. Default `{}`
2891
2891
  </td>
2892
2892
  </tr>
2893
+ <tr>
2894
+ <td>
2895
+
2896
+ `children`
2897
+ </td>
2898
+ <td>Nested resources. See below</td>
2899
+ </tr>
2893
2900
  </table>
2894
2901
 
2902
+ The `timeline` views support displaying nested resources. Nested resources can be collapsed or expanded using an additional button that appears before the parent resource name. To pass nested resources, use the `children` field:
2903
+
2904
+ ```js
2905
+ resources: [
2906
+ {
2907
+ id: 1,
2908
+ title: 'Resource A',
2909
+ children: [
2910
+ {
2911
+ id: 11,
2912
+ title: 'Resource A1'
2913
+ },
2914
+ {
2915
+ id: 12,
2916
+ title: 'Resource A2'
2917
+ }
2918
+ ]
2919
+ }
2920
+ ]
2921
+ ```
2922
+
2895
2923
  ## View object
2896
2924
  A View object contains information about a calendar view, such as title and date range.
2897
2925
 
package/index.css CHANGED
@@ -359,6 +359,17 @@
359
359
  z-index: 1;
360
360
  }
361
361
 
362
+ .ec-expander {
363
+ margin-right: 0.25em;
364
+ width: 1.25em;
365
+ }
366
+ .ec-expander .ec-button {
367
+ line-height: normal;
368
+ padding: 0;
369
+ aspect-ratio: 1;
370
+ height: 1.25em;
371
+ }
372
+
362
373
  .ec-button-group {
363
374
  display: inline-flex;
364
375
  }
package/index.js CHANGED
@@ -294,6 +294,23 @@ function task(fn, handle, tasks) {
294
294
  }
295
295
  }
296
296
 
297
+ let payloadProp = symbol();
298
+ function setPayload(obj, payload) {
299
+ obj[payloadProp] = payload;
300
+ }
301
+
302
+ function hasPayload(obj) {
303
+ return !!obj?.[payloadProp];
304
+ }
305
+
306
+ function getPayload(obj) {
307
+ return obj[payloadProp];
308
+ }
309
+
310
+ function removePayload(obj) {
311
+ delete obj?.[payloadProp];
312
+ }
313
+
297
314
  function createElement(tag, className, content, attrs = []) {
298
315
  let el = document.createElement(tag);
299
316
  el.className = className;
@@ -329,19 +346,6 @@ function height(el) {
329
346
  return rect(el).height;
330
347
  }
331
348
 
332
- let payloadProp = symbol();
333
- function setPayload(el, payload) {
334
- el[payloadProp] = payload;
335
- }
336
-
337
- function hasPayload(el) {
338
- return !!el?.[payloadProp];
339
- }
340
-
341
- function getPayload(el) {
342
- return el[payloadProp];
343
- }
344
-
345
349
  function getElementWithPayload(x, y, root = document) {
346
350
  for (let el of root.elementsFromPoint(x, y)) {
347
351
  if (hasPayload(el)) {
@@ -703,13 +707,39 @@ function themeView(view) {
703
707
  }
704
708
 
705
709
  function createResources(input) {
706
- return input.map(resource => ({
707
- id: String(resource.id),
708
- title: resource.title || '',
709
- eventBackgroundColor: resource.eventBackgroundColor,
710
- eventTextColor: resource.eventTextColor,
711
- extendedProps: resource.extendedProps ?? {}
712
- }));
710
+ let result = [];
711
+ _createResources(input, 0, result);
712
+ return result;
713
+ }
714
+
715
+ function _createResources(input, level, flat) {
716
+ let result = [];
717
+ for (let item of input) {
718
+ let resource = createResource(item);
719
+ result.push(resource);
720
+ flat.push(resource);
721
+ let payload = {
722
+ level,
723
+ children: [],
724
+ expanded: true,
725
+ hidden: false
726
+ };
727
+ setPayload(resource, payload);
728
+ if (item.children) {
729
+ payload.children = _createResources(item.children, level + 1, flat);
730
+ }
731
+ }
732
+ return result;
733
+ }
734
+
735
+ function createResource(input) {
736
+ return {
737
+ id: String(input.id),
738
+ title: input.title || '',
739
+ eventBackgroundColor: input.eventBackgroundColor,
740
+ eventTextColor: input.eventTextColor,
741
+ extendedProps: input.extendedProps ?? {}
742
+ };
713
743
  }
714
744
 
715
745
  function resourceBackgroundColor(event, resources) {
@@ -788,7 +818,7 @@ function viewResources(state) {
788
818
  return derived(
789
819
  [state.resources, state.filterResourcesWithEvents, state._events, state._activeRange],
790
820
  ([$resources, $filterResourcesWithEvents, $_events, $_activeRange]) => {
791
- let result = $resources;
821
+ let result = $resources.filter(resource => !getPayload(resource).hidden);
792
822
 
793
823
  if ($filterResourcesWithEvents) {
794
824
  result = $resources.filter(resource => {
@@ -2906,4 +2936,4 @@ class index extends Calendar {
2906
2936
  }
2907
2937
  }
2908
2938
 
2909
- export { DAY_IN_SECONDS, addDay, addDuration, ancestor, assign, bgEvent, btnTextDay, btnTextMonth, btnTextWeek, btnTextYear, ceil, cloneDate, cloneEvent, copyTime, createDate, createDuration, createElement, createEventChunk, createEventClasses, createEventContent, createEventSources, createEvents, createResources, createSlotTimeLimits, createTimes, createView, datesEqual, debounce, index as default, eventIntersects, floor, flushDebounce, getElementWithPayload, getPayload, ghostEvent, hasPayload, hasYScroll, height, helperEvent, identity, intl, intlRange, isArray, isFunction, keyEnter, keys, listView, listen, max, min, nextClosestDay, nextDate, noTimePart, noop, outsideEvent, pointerEvent, prepareEventChunks, prevClosestDay, prevDate, previewEvent, rect, repositionEvent, resourceBackgroundColor, resourceTextColor, run, runAll, runReposition, setContent, setMidnight, setPayload, sortEventChunks, subtractDay, subtractDuration, symbol, task, themeView, timelineView, toEventWithLocalDates, toISOString, toLocalDate, toSeconds, toViewWithLocalDates, viewResources };
2939
+ export { DAY_IN_SECONDS, addDay, addDuration, ancestor, assign, bgEvent, btnTextDay, btnTextMonth, btnTextWeek, btnTextYear, ceil, cloneDate, cloneEvent, copyTime, createDate, createDuration, createElement, createEventChunk, createEventClasses, createEventContent, createEventSources, createEvents, createResource, createResources, createSlotTimeLimits, createTimes, createView, datesEqual, debounce, index as default, eventIntersects, floor, flushDebounce, getElementWithPayload, getPayload, ghostEvent, hasPayload, hasYScroll, height, helperEvent, identity, intl, intlRange, isArray, isFunction, keyEnter, keys, listView, listen, max, min, nextClosestDay, nextDate, noTimePart, noop, outsideEvent, pointerEvent, prepareEventChunks, prevClosestDay, prevDate, previewEvent, rect, removePayload, repositionEvent, resourceBackgroundColor, resourceTextColor, run, runAll, runReposition, setContent, setMidnight, setPayload, sortEventChunks, subtractDay, subtractDuration, symbol, task, themeView, timelineView, toEventWithLocalDates, toISOString, toLocalDate, toSeconds, toViewWithLocalDates, viewResources };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@event-calendar/core",
3
- "version": "3.6.2",
3
+ "version": "3.7.0",
4
4
  "title": "Event Calendar Core package",
5
5
  "description": "Full-sized drag & drop event calendar with resource & timeline views",
6
6
  "keywords": [
@@ -17,7 +17,8 @@
17
17
  flushDebounce,
18
18
  hasYScroll,
19
19
  listView,
20
- task, prevDate, nextDate
20
+ task,
21
+ prevDate, nextDate
21
22
  } from './lib.js';
22
23
 
23
24
  export let plugins = [];
package/src/lib/dom.js CHANGED
@@ -1,4 +1,4 @@
1
- import {symbol} from './utils.js';
1
+ import {hasPayload} from './payload.js';
2
2
 
3
3
  export function createElement(tag, className, content, attrs = []) {
4
4
  let el = document.createElement(tag);
@@ -35,19 +35,6 @@ export function height(el) {
35
35
  return rect(el).height;
36
36
  }
37
37
 
38
- let payloadProp = symbol();
39
- export function setPayload(el, payload) {
40
- el[payloadProp] = payload;
41
- }
42
-
43
- export function hasPayload(el) {
44
- return !!el?.[payloadProp];
45
- }
46
-
47
- export function getPayload(el) {
48
- return el[payloadProp];
49
- }
50
-
51
38
  export function getElementWithPayload(x, y, root = document) {
52
39
  for (let el of root.elementsFromPoint(x, y)) {
53
40
  if (hasPayload(el)) {
@@ -0,0 +1,18 @@
1
+ import {symbol} from './utils.js';
2
+
3
+ let payloadProp = symbol();
4
+ export function setPayload(obj, payload) {
5
+ obj[payloadProp] = payload;
6
+ }
7
+
8
+ export function hasPayload(obj) {
9
+ return !!obj?.[payloadProp];
10
+ }
11
+
12
+ export function getPayload(obj) {
13
+ return obj[payloadProp];
14
+ }
15
+
16
+ export function removePayload(obj) {
17
+ delete obj?.[payloadProp];
18
+ }
@@ -1,11 +1,39 @@
1
+ import {setPayload} from './payload.js';
2
+
1
3
  export function createResources(input) {
2
- return input.map(resource => ({
3
- id: String(resource.id),
4
- title: resource.title || '',
5
- eventBackgroundColor: resource.eventBackgroundColor,
6
- eventTextColor: resource.eventTextColor,
7
- extendedProps: resource.extendedProps ?? {}
8
- }));
4
+ let result = [];
5
+ _createResources(input, 0, result);
6
+ return result;
7
+ }
8
+
9
+ function _createResources(input, level, flat) {
10
+ let result = [];
11
+ for (let item of input) {
12
+ let resource = createResource(item);
13
+ result.push(resource);
14
+ flat.push(resource);
15
+ let payload = {
16
+ level,
17
+ children: [],
18
+ expanded: true,
19
+ hidden: false
20
+ };
21
+ setPayload(resource, payload);
22
+ if (item.children) {
23
+ payload.children = _createResources(item.children, level + 1, flat);
24
+ }
25
+ }
26
+ return result;
27
+ }
28
+
29
+ export function createResource(input) {
30
+ return {
31
+ id: String(input.id),
32
+ title: input.title || '',
33
+ eventBackgroundColor: input.eventBackgroundColor,
34
+ eventTextColor: input.eventTextColor,
35
+ extendedProps: input.extendedProps ?? {}
36
+ };
9
37
  }
10
38
 
11
39
  export function resourceBackgroundColor(event, resources) {
package/src/lib/stores.js CHANGED
@@ -2,6 +2,7 @@ import {derived} from 'svelte/store';
2
2
  import {isFunction} from './utils.js';
3
3
  import {toLocalDate} from './date';
4
4
  import {createResources} from './resources.js';
5
+ import {getPayload} from './payload.js';
5
6
 
6
7
  export function intl(locale, format) {
7
8
  return derived([locale, format], ([$locale, $format]) => {
@@ -67,7 +68,7 @@ export function viewResources(state) {
67
68
  return derived(
68
69
  [state.resources, state.filterResourcesWithEvents, state._events, state._activeRange],
69
70
  ([$resources, $filterResourcesWithEvents, $_events, $_activeRange]) => {
70
- let result = $resources;
71
+ let result = $resources.filter(resource => !getPayload(resource).hidden);
71
72
 
72
73
  if ($filterResourcesWithEvents) {
73
74
  result = $resources.filter(resource => {
package/src/lib.js CHANGED
@@ -5,6 +5,7 @@ export * from './lib/debounce.js';
5
5
  export * from './lib/dom.js';
6
6
  export * from './lib/events.js';
7
7
  export * from './lib/options.js';
8
+ export * from './lib/payload.js';
8
9
  export * from './lib/resources.js';
9
10
  export * from './lib/stores.js';
10
11
  export * from './lib/times.js';
@@ -96,6 +96,18 @@
96
96
  }
97
97
  }
98
98
 
99
+ .ec-expander {
100
+ margin-right: .25em;
101
+ width: 1.25em;
102
+
103
+ .ec-button {
104
+ line-height: normal;
105
+ padding: 0;
106
+ aspect-ratio: 1;
107
+ height: 1.25em;
108
+ }
109
+ }
110
+
99
111
  .ec-button-group {
100
112
  display: inline-flex;
101
113