@fullcalendar/list 7.0.0-beta.4 → 7.0.0-beta.5

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.
@@ -0,0 +1,220 @@
1
+ import { joinClassNames } from '@fullcalendar/core';
2
+ import { BaseComponent, findDayNumberText, buildNavLinkAttrs, ContentContainer, renderText, formatDayString, WEEKDAY_ONLY_FORMAT, FULL_DATE_FORMAT, createFormatter, StandardEvent, memoize, getDateMeta, sortEventSegs, buildDateStr, generateClassName, getEventKey, getEventRangeMeta, DateComponent, getIsHeightAuto, ViewContainer, Scroller, joinArrayishClassNames, NowTimer, sliceEventStore, intersectRanges, startOfDay, addDays } from '@fullcalendar/core/internal';
3
+ import classNames from '@fullcalendar/core/internal-classnames';
4
+ import { createElement, Fragment } from '@fullcalendar/core/preact';
5
+
6
+ class ListDayHeaderInner extends BaseComponent {
7
+ render() {
8
+ const { props, context } = this;
9
+ const { options } = context;
10
+ const [text, textParts] = context.dateEnv.format(props.dayDate, props.dayFormat);
11
+ const hasNavLink = options.navLinks;
12
+ const renderProps = Object.assign(Object.assign({}, props.dateMeta), { view: context.viewApi, text,
13
+ textParts,
14
+ get dayNumberText() { return findDayNumberText(textParts); },
15
+ hasNavLink, level: props.level });
16
+ const navLinkAttrs = hasNavLink
17
+ ? buildNavLinkAttrs(this.context, props.dayDate, undefined, text, this.props.isTabbable)
18
+ : {};
19
+ return (createElement(ContentContainer, { tag: "div", attrs: navLinkAttrs, renderProps: renderProps, generatorName: "listDayHeaderContent", customGenerator: options.listDayHeaderContent, defaultGenerator: renderText, classNameGenerator: options.listDayHeaderInnerClass }));
20
+ }
21
+ }
22
+
23
+ class ListDayHeader extends BaseComponent {
24
+ render() {
25
+ var _a, _b;
26
+ let { options, viewApi, viewSpec } = this.context;
27
+ let { dayDate, dateMeta } = this.props;
28
+ let stickyHeaderDates = !this.props.forPrint;
29
+ const listDayFormat = (_a = options.listDayFormat) !== null && _a !== void 0 ? _a : createDefaultListDayFormat(viewSpec);
30
+ const listDaySideFormat = (_b = options.listDaySideFormat) !== null && _b !== void 0 ? _b : createDefaultListDaySideFormat(viewSpec);
31
+ let renderProps = Object.assign(Object.assign({}, dateMeta), { view: viewApi });
32
+ return (createElement(ContentContainer, { tag: "div", attrs: Object.assign({ 'data-date': formatDayString(dayDate) }, (dateMeta.isToday ? { 'aria-current': 'date' } : {})), className: stickyHeaderDates ? classNames.stickyT : '', renderProps: renderProps, generatorName: undefined, classNameGenerator: options.listDayHeaderClass, didMount: options.listDayHeaderDidMount, willUnmount: options.listDayHeaderWillUnmount }, () => (createElement(Fragment, null,
33
+ Boolean(listDayFormat) && (createElement(ListDayHeaderInner, { dayDate: dayDate, dayFormat: listDayFormat, isTabbable: true, dateMeta: dateMeta, level: 0 })),
34
+ Boolean(listDaySideFormat) && (createElement(ListDayHeaderInner, { dayDate: dayDate, dayFormat: listDaySideFormat, isTabbable: false, dateMeta: dateMeta, level: 1 }))))));
35
+ }
36
+ }
37
+ function createDefaultListDayFormat({ durationUnit, singleUnit }) {
38
+ if (singleUnit === 'day') {
39
+ return WEEKDAY_ONLY_FORMAT;
40
+ }
41
+ else if (durationUnit === 'day' || singleUnit === 'week') {
42
+ return WEEKDAY_ONLY_FORMAT;
43
+ }
44
+ else {
45
+ return FULL_DATE_FORMAT;
46
+ }
47
+ }
48
+ function createDefaultListDaySideFormat({ durationUnit, singleUnit }) {
49
+ if (singleUnit === 'day') ;
50
+ else if (durationUnit === 'day' || singleUnit === 'week') {
51
+ return FULL_DATE_FORMAT;
52
+ }
53
+ else {
54
+ return WEEKDAY_ONLY_FORMAT;
55
+ }
56
+ }
57
+
58
+ const DEFAULT_TIME_FORMAT = createFormatter({
59
+ hour: 'numeric',
60
+ minute: '2-digit',
61
+ meridiem: 'short',
62
+ });
63
+ class ListEvent extends BaseComponent {
64
+ render() {
65
+ let { props, context } = this;
66
+ let { eventRange } = props;
67
+ let forcedTimeText = (eventRange.def.allDay || (!props.isStart && !props.isEnd))
68
+ ? context.options.allDayText
69
+ : undefined;
70
+ return (createElement(StandardEvent, Object.assign({}, props, { attrs: {
71
+ role: 'listitem',
72
+ }, forcedTimeText: forcedTimeText, defaultTimeFormat: DEFAULT_TIME_FORMAT, disableDragging: true, disableResizing: true, disableZindexes // because conflicts with sticky list headers
73
+ : true, display: 'list-item' })));
74
+ }
75
+ }
76
+
77
+ class ListDay extends BaseComponent {
78
+ constructor() {
79
+ super(...arguments);
80
+ // memo
81
+ this.getDateMeta = memoize(getDateMeta);
82
+ this.sortEventSegs = memoize(sortEventSegs);
83
+ }
84
+ render() {
85
+ const { props, context } = this;
86
+ const { nowDate, todayRange } = props;
87
+ const { options } = context;
88
+ const dateMeta = this.getDateMeta(props.dayDate, context.dateEnv, undefined, todayRange);
89
+ const segs = this.sortEventSegs(props.segs, options.eventOrder);
90
+ const fullDateStr = buildDateStr(this.context, props.dayDate);
91
+ return (createElement("div", { role: 'listitem', "aria-label": fullDateStr, className: generateClassName(options.listDayClass, Object.assign(Object.assign({}, dateMeta), { view: context.viewApi })) },
92
+ createElement(ListDayHeader, { dayDate: props.dayDate, dateMeta: dateMeta, forPrint: props.forPrint }),
93
+ createElement("div", { role: 'list', "aria-label": options.eventsHint, className: joinClassNames(generateClassName(options.listDayEventsClass, dateMeta), classNames.flexCol) }, segs.map((seg) => {
94
+ const key = getEventKey(seg);
95
+ return (createElement(ListEvent, Object.assign({ key: key, eventRange: seg.eventRange, slicedStart: seg.slicedStart, slicedEnd: seg.slicedEnd, isStart: seg.isStart, isEnd: seg.isEnd, isDragging: false, isResizing: false, isMirror: false, isSelected: false }, getEventRangeMeta(seg.eventRange, todayRange, nowDate))));
96
+ }))));
97
+ }
98
+ }
99
+
100
+ /*
101
+ Responsible for the scroller, and forwarding event-related actions into the "grid".
102
+ */
103
+ class ListView extends DateComponent {
104
+ constructor() {
105
+ super(...arguments);
106
+ // memo
107
+ this.computeDateVars = memoize(computeDateVars);
108
+ this.eventStoreToSegs = memoize(this._eventStoreToSegs);
109
+ this.setRootEl = (rootEl) => {
110
+ if (rootEl) {
111
+ this.context.registerInteractiveComponent(this, {
112
+ el: rootEl,
113
+ disableHits: true, // HACK to not do date-clicking/selecting
114
+ });
115
+ }
116
+ else {
117
+ this.context.unregisterInteractiveComponent(this);
118
+ }
119
+ };
120
+ }
121
+ render() {
122
+ let { props, context } = this;
123
+ let { options } = context;
124
+ let { dayDates, dayRanges } = this.computeDateVars(props.dateProfile);
125
+ let eventSegs = this.eventStoreToSegs(props.eventStore, props.eventUiBases, dayRanges);
126
+ let verticalScrolling = !props.forPrint && !getIsHeightAuto(options);
127
+ return (createElement(ViewContainer, { viewSpec: context.viewSpec, className: joinClassNames(props.className, classNames.flexCol), elRef: this.setRootEl, borderlessX: props.borderlessX, borderlessTop: props.borderlessTop, borderlessBottom: props.borderlessBottom, noEdgeEffects: props.noEdgeEffects }, eventSegs.length ? (createElement(Scroller // TODO: don't need heavyweight component
128
+ , { vertical: verticalScrolling, className: joinClassNames(classNames.flexCol, verticalScrolling ? classNames.liquid : '') }, this.renderSegList(eventSegs, dayDates))) : this.renderEmptyMessage()));
129
+ }
130
+ renderEmptyMessage() {
131
+ let { options, viewApi } = this.context;
132
+ let renderProps = {
133
+ text: options.noEventsText,
134
+ view: viewApi,
135
+ };
136
+ return (createElement(ContentContainer, { tag: "div", attrs: {
137
+ role: 'status', // does a polite announcement
138
+ }, renderProps: renderProps, generatorName: "noEventsContent", customGenerator: options.noEventsContent, defaultGenerator: renderNoEventsInner, classNameGenerator: options.noEventsClass, className: classNames.grow, didMount: options.noEventsDidMount, willUnmount: options.noEventsWillUnmount }, (InnerContent) => (createElement(InnerContent, { tag: "div", className: generateClassName(options.noEventsInnerClass, renderProps) }))));
139
+ }
140
+ renderSegList(allSegs, dayDates) {
141
+ let { options } = this.context;
142
+ let segsByDay = groupSegsByDay(allSegs); // sparse array
143
+ return (createElement("div", { role: "list", "aria-labelledby": this.props.labelId, "aria-label": this.props.labelStr, className: joinClassNames(classNames.flexCol, joinArrayishClassNames(options.listDaysClass)) },
144
+ createElement(NowTimer, { unit: "day" }, (nowDate, todayRange) => {
145
+ const dayNodes = [];
146
+ for (let dayIndex = 0; dayIndex < segsByDay.length; dayIndex += 1) {
147
+ let daySegs = segsByDay[dayIndex];
148
+ if (daySegs) { // sparse array, so might be undefined
149
+ const dayDate = dayDates[dayIndex];
150
+ const key = formatDayString(dayDate);
151
+ dayNodes.push(createElement(ListDay, { key: key, dayDate: dayDate, nowDate: nowDate, todayRange: todayRange, segs: daySegs, forPrint: this.props.forPrint }));
152
+ }
153
+ }
154
+ return (createElement(Fragment, null, dayNodes));
155
+ })));
156
+ }
157
+ _eventStoreToSegs(eventStore, eventUiBases, dayRanges) {
158
+ return this.eventRangesToSegs(sliceEventStore(eventStore, eventUiBases,
159
+ // HACKY to reference internal state...
160
+ this.props.dateProfile.activeRange, this.context.options.nextDayThreshold).fg, dayRanges);
161
+ }
162
+ eventRangesToSegs(fullDayEventRanges, dayRanges) {
163
+ let segs = [];
164
+ for (let fullDayEventRange of fullDayEventRanges) {
165
+ segs.push(...this.eventRangeToSegs(fullDayEventRange, dayRanges));
166
+ }
167
+ return segs;
168
+ }
169
+ eventRangeToSegs(fullDayEventRange, dayRanges) {
170
+ let fullDayRange = fullDayEventRange.range;
171
+ let dayIndex;
172
+ let segs = [];
173
+ for (dayIndex = 0; dayIndex < dayRanges.length; dayIndex += 1) {
174
+ const slicedFullDayRange = intersectRanges(fullDayRange, dayRanges[dayIndex]);
175
+ if (slicedFullDayRange) {
176
+ segs.push({
177
+ eventRange: fullDayEventRange,
178
+ slicedStart: slicedFullDayRange.start,
179
+ slicedEnd: slicedFullDayRange.end,
180
+ isStart: fullDayEventRange.isStart && fullDayRange.start.valueOf() === slicedFullDayRange.start.valueOf(),
181
+ isEnd: fullDayEventRange.isEnd && fullDayRange.end.valueOf() === slicedFullDayRange.end.valueOf(),
182
+ dayIndex,
183
+ });
184
+ }
185
+ }
186
+ return segs;
187
+ }
188
+ }
189
+ function renderNoEventsInner(renderProps) {
190
+ return renderProps.text;
191
+ }
192
+ function computeDateVars(dateProfile) {
193
+ let dayStart = startOfDay(dateProfile.renderRange.start);
194
+ let viewEnd = dateProfile.renderRange.end;
195
+ let dayDates = [];
196
+ let dayRanges = [];
197
+ while (dayStart < viewEnd) {
198
+ dayDates.push(dayStart);
199
+ dayRanges.push({
200
+ start: dayStart,
201
+ end: addDays(dayStart, 1),
202
+ });
203
+ dayStart = addDays(dayStart, 1);
204
+ }
205
+ return { dayDates, dayRanges };
206
+ }
207
+ // Returns a sparse array of arrays, segs grouped by their dayIndex
208
+ function groupSegsByDay(segs) {
209
+ let segsByDay = []; // sparse array
210
+ let i;
211
+ let seg;
212
+ for (i = 0; i < segs.length; i += 1) {
213
+ seg = segs[i];
214
+ (segsByDay[seg.dayIndex] || (segsByDay[seg.dayIndex] = []))
215
+ .push(seg);
216
+ }
217
+ return segsByDay;
218
+ }
219
+
220
+ export { ListView };
package/global.js ADDED
@@ -0,0 +1,290 @@
1
+ /*!
2
+ FullCalendar List View Plugin v7.0.0-beta.5
3
+ Docs & License: https://fullcalendar.io/docs/list-view
4
+ (c) 2025 Adam Shaw
5
+ */
6
+ FullCalendar.List = (function (exports, core, internal$1, classNames, preact) {
7
+ 'use strict';
8
+
9
+ function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
10
+
11
+ var classNames__default = /*#__PURE__*/_interopDefault(classNames);
12
+
13
+ class ListDayHeaderInner extends internal$1.BaseComponent {
14
+ render() {
15
+ const { props, context } = this;
16
+ const { options } = context;
17
+ const [text, textParts] = context.dateEnv.format(props.dayDate, props.dayFormat);
18
+ const hasNavLink = options.navLinks;
19
+ const renderProps = Object.assign(Object.assign({}, props.dateMeta), { view: context.viewApi, text,
20
+ textParts,
21
+ get dayNumberText() { return internal$1.findDayNumberText(textParts); },
22
+ hasNavLink, level: props.level });
23
+ const navLinkAttrs = hasNavLink
24
+ ? internal$1.buildNavLinkAttrs(this.context, props.dayDate, undefined, text, this.props.isTabbable)
25
+ : {};
26
+ return (preact.createElement(internal$1.ContentContainer, { tag: "div", attrs: navLinkAttrs, renderProps: renderProps, generatorName: "listDayHeaderContent", customGenerator: options.listDayHeaderContent, defaultGenerator: internal$1.renderText, classNameGenerator: options.listDayHeaderInnerClass }));
27
+ }
28
+ }
29
+
30
+ class ListDayHeader extends internal$1.BaseComponent {
31
+ render() {
32
+ var _a, _b;
33
+ let { options, viewApi, viewSpec } = this.context;
34
+ let { dayDate, dateMeta } = this.props;
35
+ let stickyHeaderDates = !this.props.forPrint;
36
+ const listDayFormat = (_a = options.listDayFormat) !== null && _a !== void 0 ? _a : createDefaultListDayFormat(viewSpec);
37
+ const listDaySideFormat = (_b = options.listDaySideFormat) !== null && _b !== void 0 ? _b : createDefaultListDaySideFormat(viewSpec);
38
+ let renderProps = Object.assign(Object.assign({}, dateMeta), { view: viewApi });
39
+ return (preact.createElement(internal$1.ContentContainer, { tag: "div", attrs: Object.assign({ 'data-date': internal$1.formatDayString(dayDate) }, (dateMeta.isToday ? { 'aria-current': 'date' } : {})), className: stickyHeaderDates ? classNames__default["default"].stickyT : '', renderProps: renderProps, generatorName: undefined, classNameGenerator: options.listDayHeaderClass, didMount: options.listDayHeaderDidMount, willUnmount: options.listDayHeaderWillUnmount }, () => (preact.createElement(preact.Fragment, null,
40
+ Boolean(listDayFormat) && (preact.createElement(ListDayHeaderInner, { dayDate: dayDate, dayFormat: listDayFormat, isTabbable: true, dateMeta: dateMeta, level: 0 })),
41
+ Boolean(listDaySideFormat) && (preact.createElement(ListDayHeaderInner, { dayDate: dayDate, dayFormat: listDaySideFormat, isTabbable: false, dateMeta: dateMeta, level: 1 }))))));
42
+ }
43
+ }
44
+ function createDefaultListDayFormat({ durationUnit, singleUnit }) {
45
+ if (singleUnit === 'day') {
46
+ return internal$1.WEEKDAY_ONLY_FORMAT;
47
+ }
48
+ else if (durationUnit === 'day' || singleUnit === 'week') {
49
+ return internal$1.WEEKDAY_ONLY_FORMAT;
50
+ }
51
+ else {
52
+ return internal$1.FULL_DATE_FORMAT;
53
+ }
54
+ }
55
+ function createDefaultListDaySideFormat({ durationUnit, singleUnit }) {
56
+ if (singleUnit === 'day') ;
57
+ else if (durationUnit === 'day' || singleUnit === 'week') {
58
+ return internal$1.FULL_DATE_FORMAT;
59
+ }
60
+ else {
61
+ return internal$1.WEEKDAY_ONLY_FORMAT;
62
+ }
63
+ }
64
+
65
+ const DEFAULT_TIME_FORMAT = internal$1.createFormatter({
66
+ hour: 'numeric',
67
+ minute: '2-digit',
68
+ meridiem: 'short',
69
+ });
70
+ class ListEvent extends internal$1.BaseComponent {
71
+ render() {
72
+ let { props, context } = this;
73
+ let { eventRange } = props;
74
+ let forcedTimeText = (eventRange.def.allDay || (!props.isStart && !props.isEnd))
75
+ ? context.options.allDayText
76
+ : undefined;
77
+ return (preact.createElement(internal$1.StandardEvent, Object.assign({}, props, { attrs: {
78
+ role: 'listitem',
79
+ }, forcedTimeText: forcedTimeText, defaultTimeFormat: DEFAULT_TIME_FORMAT, disableDragging: true, disableResizing: true, disableZindexes // because conflicts with sticky list headers
80
+ : true, display: 'list-item' })));
81
+ }
82
+ }
83
+
84
+ class ListDay extends internal$1.BaseComponent {
85
+ constructor() {
86
+ super(...arguments);
87
+ // memo
88
+ this.getDateMeta = internal$1.memoize(internal$1.getDateMeta);
89
+ this.sortEventSegs = internal$1.memoize(internal$1.sortEventSegs);
90
+ }
91
+ render() {
92
+ const { props, context } = this;
93
+ const { nowDate, todayRange } = props;
94
+ const { options } = context;
95
+ const dateMeta = this.getDateMeta(props.dayDate, context.dateEnv, undefined, todayRange);
96
+ const segs = this.sortEventSegs(props.segs, options.eventOrder);
97
+ const fullDateStr = internal$1.buildDateStr(this.context, props.dayDate);
98
+ return (preact.createElement("div", { role: 'listitem', "aria-label": fullDateStr, className: internal$1.generateClassName(options.listDayClass, Object.assign(Object.assign({}, dateMeta), { view: context.viewApi })) },
99
+ preact.createElement(ListDayHeader, { dayDate: props.dayDate, dateMeta: dateMeta, forPrint: props.forPrint }),
100
+ preact.createElement("div", { role: 'list', "aria-label": options.eventsHint, className: core.joinClassNames(internal$1.generateClassName(options.listDayEventsClass, dateMeta), classNames__default["default"].flexCol) }, segs.map((seg) => {
101
+ const key = internal$1.getEventKey(seg);
102
+ return (preact.createElement(ListEvent, Object.assign({ key: key, eventRange: seg.eventRange, slicedStart: seg.slicedStart, slicedEnd: seg.slicedEnd, isStart: seg.isStart, isEnd: seg.isEnd, isDragging: false, isResizing: false, isMirror: false, isSelected: false }, internal$1.getEventRangeMeta(seg.eventRange, todayRange, nowDate))));
103
+ }))));
104
+ }
105
+ }
106
+
107
+ /*
108
+ Responsible for the scroller, and forwarding event-related actions into the "grid".
109
+ */
110
+ class ListView extends internal$1.DateComponent {
111
+ constructor() {
112
+ super(...arguments);
113
+ // memo
114
+ this.computeDateVars = internal$1.memoize(computeDateVars);
115
+ this.eventStoreToSegs = internal$1.memoize(this._eventStoreToSegs);
116
+ this.setRootEl = (rootEl) => {
117
+ if (rootEl) {
118
+ this.context.registerInteractiveComponent(this, {
119
+ el: rootEl,
120
+ disableHits: true, // HACK to not do date-clicking/selecting
121
+ });
122
+ }
123
+ else {
124
+ this.context.unregisterInteractiveComponent(this);
125
+ }
126
+ };
127
+ }
128
+ render() {
129
+ let { props, context } = this;
130
+ let { options } = context;
131
+ let { dayDates, dayRanges } = this.computeDateVars(props.dateProfile);
132
+ let eventSegs = this.eventStoreToSegs(props.eventStore, props.eventUiBases, dayRanges);
133
+ let verticalScrolling = !props.forPrint && !internal$1.getIsHeightAuto(options);
134
+ return (preact.createElement(internal$1.ViewContainer, { viewSpec: context.viewSpec, className: core.joinClassNames(props.className, classNames__default["default"].flexCol), elRef: this.setRootEl, borderlessX: props.borderlessX, borderlessTop: props.borderlessTop, borderlessBottom: props.borderlessBottom, noEdgeEffects: props.noEdgeEffects }, eventSegs.length ? (preact.createElement(internal$1.Scroller // TODO: don't need heavyweight component
135
+ , { vertical: verticalScrolling, className: core.joinClassNames(classNames__default["default"].flexCol, verticalScrolling ? classNames__default["default"].liquid : '') }, this.renderSegList(eventSegs, dayDates))) : this.renderEmptyMessage()));
136
+ }
137
+ renderEmptyMessage() {
138
+ let { options, viewApi } = this.context;
139
+ let renderProps = {
140
+ text: options.noEventsText,
141
+ view: viewApi,
142
+ };
143
+ return (preact.createElement(internal$1.ContentContainer, { tag: "div", attrs: {
144
+ role: 'status', // does a polite announcement
145
+ }, renderProps: renderProps, generatorName: "noEventsContent", customGenerator: options.noEventsContent, defaultGenerator: renderNoEventsInner, classNameGenerator: options.noEventsClass, className: classNames__default["default"].grow, didMount: options.noEventsDidMount, willUnmount: options.noEventsWillUnmount }, (InnerContent) => (preact.createElement(InnerContent, { tag: "div", className: internal$1.generateClassName(options.noEventsInnerClass, renderProps) }))));
146
+ }
147
+ renderSegList(allSegs, dayDates) {
148
+ let { options } = this.context;
149
+ let segsByDay = groupSegsByDay(allSegs); // sparse array
150
+ return (preact.createElement("div", { role: "list", "aria-labelledby": this.props.labelId, "aria-label": this.props.labelStr, className: core.joinClassNames(classNames__default["default"].flexCol, internal$1.joinArrayishClassNames(options.listDaysClass)) },
151
+ preact.createElement(internal$1.NowTimer, { unit: "day" }, (nowDate, todayRange) => {
152
+ const dayNodes = [];
153
+ for (let dayIndex = 0; dayIndex < segsByDay.length; dayIndex += 1) {
154
+ let daySegs = segsByDay[dayIndex];
155
+ if (daySegs) { // sparse array, so might be undefined
156
+ const dayDate = dayDates[dayIndex];
157
+ const key = internal$1.formatDayString(dayDate);
158
+ dayNodes.push(preact.createElement(ListDay, { key: key, dayDate: dayDate, nowDate: nowDate, todayRange: todayRange, segs: daySegs, forPrint: this.props.forPrint }));
159
+ }
160
+ }
161
+ return (preact.createElement(preact.Fragment, null, dayNodes));
162
+ })));
163
+ }
164
+ _eventStoreToSegs(eventStore, eventUiBases, dayRanges) {
165
+ return this.eventRangesToSegs(internal$1.sliceEventStore(eventStore, eventUiBases,
166
+ // HACKY to reference internal state...
167
+ this.props.dateProfile.activeRange, this.context.options.nextDayThreshold).fg, dayRanges);
168
+ }
169
+ eventRangesToSegs(fullDayEventRanges, dayRanges) {
170
+ let segs = [];
171
+ for (let fullDayEventRange of fullDayEventRanges) {
172
+ segs.push(...this.eventRangeToSegs(fullDayEventRange, dayRanges));
173
+ }
174
+ return segs;
175
+ }
176
+ eventRangeToSegs(fullDayEventRange, dayRanges) {
177
+ let fullDayRange = fullDayEventRange.range;
178
+ let dayIndex;
179
+ let segs = [];
180
+ for (dayIndex = 0; dayIndex < dayRanges.length; dayIndex += 1) {
181
+ const slicedFullDayRange = internal$1.intersectRanges(fullDayRange, dayRanges[dayIndex]);
182
+ if (slicedFullDayRange) {
183
+ segs.push({
184
+ eventRange: fullDayEventRange,
185
+ slicedStart: slicedFullDayRange.start,
186
+ slicedEnd: slicedFullDayRange.end,
187
+ isStart: fullDayEventRange.isStart && fullDayRange.start.valueOf() === slicedFullDayRange.start.valueOf(),
188
+ isEnd: fullDayEventRange.isEnd && fullDayRange.end.valueOf() === slicedFullDayRange.end.valueOf(),
189
+ dayIndex,
190
+ });
191
+ }
192
+ }
193
+ return segs;
194
+ }
195
+ }
196
+ function renderNoEventsInner(renderProps) {
197
+ return renderProps.text;
198
+ }
199
+ function computeDateVars(dateProfile) {
200
+ let dayStart = internal$1.startOfDay(dateProfile.renderRange.start);
201
+ let viewEnd = dateProfile.renderRange.end;
202
+ let dayDates = [];
203
+ let dayRanges = [];
204
+ while (dayStart < viewEnd) {
205
+ dayDates.push(dayStart);
206
+ dayRanges.push({
207
+ start: dayStart,
208
+ end: internal$1.addDays(dayStart, 1),
209
+ });
210
+ dayStart = internal$1.addDays(dayStart, 1);
211
+ }
212
+ return { dayDates, dayRanges };
213
+ }
214
+ // Returns a sparse array of arrays, segs grouped by their dayIndex
215
+ function groupSegsByDay(segs) {
216
+ let segsByDay = []; // sparse array
217
+ let i;
218
+ let seg;
219
+ for (i = 0; i < segs.length; i += 1) {
220
+ seg = segs[i];
221
+ (segsByDay[seg.dayIndex] || (segsByDay[seg.dayIndex] = []))
222
+ .push(seg);
223
+ }
224
+ return segsByDay;
225
+ }
226
+
227
+ const OPTION_REFINERS = {
228
+ listDaysClass: internal$1.identity,
229
+ listDayClass: internal$1.identity,
230
+ listDayFormat: createFalsableFormatter,
231
+ listDaySideFormat: createFalsableFormatter,
232
+ listDayHeaderDidMount: internal$1.identity,
233
+ listDayHeaderWillUnmount: internal$1.identity,
234
+ listDayHeaderClass: internal$1.identity,
235
+ listDayHeaderInnerClass: internal$1.identity,
236
+ listDayHeaderContent: internal$1.identity,
237
+ listDayEventsClass: internal$1.identity,
238
+ noEventsClass: internal$1.identity,
239
+ noEventsInnerClass: internal$1.identity,
240
+ noEventsContent: internal$1.identity,
241
+ noEventsDidMount: internal$1.identity,
242
+ noEventsWillUnmount: internal$1.identity,
243
+ // noEventsText is defined in base options
244
+ };
245
+ function createFalsableFormatter(input) {
246
+ return input === false ? null : internal$1.createFormatter(input);
247
+ }
248
+
249
+ var plugin = core.createPlugin({
250
+ name: '@fullcalendar/list',
251
+ optionRefiners: OPTION_REFINERS,
252
+ views: {
253
+ list: {
254
+ component: ListView,
255
+ buttonTextKey: 'listText', // what to lookup in locale files
256
+ },
257
+ listDay: {
258
+ type: 'list',
259
+ duration: { days: 1 },
260
+ },
261
+ listWeek: {
262
+ type: 'list',
263
+ duration: { weeks: 1 },
264
+ },
265
+ listMonth: {
266
+ type: 'list',
267
+ duration: { month: 1 },
268
+ },
269
+ listYear: {
270
+ type: 'list',
271
+ duration: { year: 1 },
272
+ },
273
+ },
274
+ });
275
+
276
+ var internal = {
277
+ __proto__: null,
278
+ ListView: ListView
279
+ };
280
+
281
+ core.globalPlugins.push(plugin);
282
+
283
+ exports.Internal = internal;
284
+ exports["default"] = plugin;
285
+
286
+ Object.defineProperty(exports, '__esModule', { value: true });
287
+
288
+ return exports;
289
+
290
+ })({}, FullCalendar, FullCalendar.Internal, FullCalendar.InternalClassNames, FullCalendar.Preact);
package/global.min.js ADDED
@@ -0,0 +1,6 @@
1
+ /*!
2
+ FullCalendar List View Plugin v7.0.0-beta.5
3
+ Docs & License: https://fullcalendar.io/docs/list-view
4
+ (c) 2025 Adam Shaw
5
+ */
6
+ FullCalendar.List=function(e,t,a,n,s){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}var i=r(n);class l extends a.BaseComponent{render(){const{props:e,context:t}=this,{options:n}=t,[r,i]=t.dateEnv.format(e.dayDate,e.dayFormat),l=n.navLinks,o=Object.assign(Object.assign({},e.dateMeta),{view:t.viewApi,text:r,textParts:i,get dayNumberText(){return a.findDayNumberText(i)},hasNavLink:l,level:e.level}),d=l?a.buildNavLinkAttrs(this.context,e.dayDate,void 0,r,this.props.isTabbable):{};return s.createElement(a.ContentContainer,{tag:"div",attrs:d,renderProps:o,generatorName:"listDayHeaderContent",customGenerator:n.listDayHeaderContent,defaultGenerator:a.renderText,classNameGenerator:n.listDayHeaderInnerClass})}}class o extends a.BaseComponent{render(){var e,t;let{options:n,viewApi:r,viewSpec:o}=this.context,{dayDate:d,dateMeta:c}=this.props,u=!this.props.forPrint;const m=null!==(e=n.listDayFormat)&&void 0!==e?e:function({durationUnit:e,singleUnit:t}){return"day"===t||"day"===e||"week"===t?a.WEEKDAY_ONLY_FORMAT:a.FULL_DATE_FORMAT}(o),g=null!==(t=n.listDaySideFormat)&&void 0!==t?t:function({durationUnit:e,singleUnit:t}){if("day"!==t)return"day"===e||"week"===t?a.FULL_DATE_FORMAT:a.WEEKDAY_ONLY_FORMAT}(o);let y=Object.assign(Object.assign({},c),{view:r});return s.createElement(a.ContentContainer,{tag:"div",attrs:Object.assign({"data-date":a.formatDayString(d)},c.isToday?{"aria-current":"date"}:{}),className:u?i.default.stickyT:"",renderProps:y,generatorName:void 0,classNameGenerator:n.listDayHeaderClass,didMount:n.listDayHeaderDidMount,willUnmount:n.listDayHeaderWillUnmount},()=>s.createElement(s.Fragment,null,Boolean(m)&&s.createElement(l,{dayDate:d,dayFormat:m,isTabbable:!0,dateMeta:c,level:0}),Boolean(g)&&s.createElement(l,{dayDate:d,dayFormat:g,isTabbable:!1,dateMeta:c,level:1})))}}const d=a.createFormatter({hour:"numeric",minute:"2-digit",meridiem:"short"});class c extends a.BaseComponent{render(){let{props:e,context:t}=this,{eventRange:n}=e,r=n.def.allDay||!e.isStart&&!e.isEnd?t.options.allDayText:void 0;return s.createElement(a.StandardEvent,Object.assign({},e,{attrs:{role:"listitem"},forcedTimeText:r,defaultTimeFormat:d,disableDragging:!0,disableResizing:!0,disableZindexes:!0,display:"list-item"}))}}class u extends a.BaseComponent{constructor(){super(...arguments),this.getDateMeta=a.memoize(a.getDateMeta),this.sortEventSegs=a.memoize(a.sortEventSegs)}render(){const{props:e,context:n}=this,{nowDate:r,todayRange:l}=e,{options:d}=n,u=this.getDateMeta(e.dayDate,n.dateEnv,void 0,l),m=this.sortEventSegs(e.segs,d.eventOrder),g=a.buildDateStr(this.context,e.dayDate);return s.createElement("div",{role:"listitem","aria-label":g,className:a.generateClassName(d.listDayClass,Object.assign(Object.assign({},u),{view:n.viewApi}))},s.createElement(o,{dayDate:e.dayDate,dateMeta:u,forPrint:e.forPrint}),s.createElement("div",{role:"list","aria-label":d.eventsHint,className:t.joinClassNames(a.generateClassName(d.listDayEventsClass,u),i.default.flexCol)},m.map(e=>{const t=a.getEventKey(e);return s.createElement(c,Object.assign({key:t,eventRange:e.eventRange,slicedStart:e.slicedStart,slicedEnd:e.slicedEnd,isStart:e.isStart,isEnd:e.isEnd,isDragging:!1,isResizing:!1,isMirror:!1,isSelected:!1},a.getEventRangeMeta(e.eventRange,l,r)))})))}}class m extends a.DateComponent{constructor(){super(...arguments),this.computeDateVars=a.memoize(y),this.eventStoreToSegs=a.memoize(this._eventStoreToSegs),this.setRootEl=e=>{e?this.context.registerInteractiveComponent(this,{el:e,disableHits:!0}):this.context.unregisterInteractiveComponent(this)}}render(){let{props:e,context:n}=this,{options:r}=n,{dayDates:l,dayRanges:o}=this.computeDateVars(e.dateProfile),d=this.eventStoreToSegs(e.eventStore,e.eventUiBases,o),c=!e.forPrint&&!a.getIsHeightAuto(r);return s.createElement(a.ViewContainer,{viewSpec:n.viewSpec,className:t.joinClassNames(e.className,i.default.flexCol),elRef:this.setRootEl,borderlessX:e.borderlessX,borderlessTop:e.borderlessTop,borderlessBottom:e.borderlessBottom,noEdgeEffects:e.noEdgeEffects},d.length?s.createElement(a.Scroller,{vertical:c,className:t.joinClassNames(i.default.flexCol,c?i.default.liquid:"")},this.renderSegList(d,l)):this.renderEmptyMessage())}renderEmptyMessage(){let{options:e,viewApi:t}=this.context,n={text:e.noEventsText,view:t};return s.createElement(a.ContentContainer,{tag:"div",attrs:{role:"status"},renderProps:n,generatorName:"noEventsContent",customGenerator:e.noEventsContent,defaultGenerator:g,classNameGenerator:e.noEventsClass,className:i.default.grow,didMount:e.noEventsDidMount,willUnmount:e.noEventsWillUnmount},t=>s.createElement(t,{tag:"div",className:a.generateClassName(e.noEventsInnerClass,n)}))}renderSegList(e,n){let{options:r}=this.context,l=function(e){let t,a,n=[];for(t=0;t<e.length;t+=1)a=e[t],(n[a.dayIndex]||(n[a.dayIndex]=[])).push(a);return n}(e);return s.createElement("div",{role:"list","aria-labelledby":this.props.labelId,"aria-label":this.props.labelStr,className:t.joinClassNames(i.default.flexCol,a.joinArrayishClassNames(r.listDaysClass))},s.createElement(a.NowTimer,{unit:"day"},(e,t)=>{const r=[];for(let i=0;i<l.length;i+=1){let o=l[i];if(o){const l=n[i],d=a.formatDayString(l);r.push(s.createElement(u,{key:d,dayDate:l,nowDate:e,todayRange:t,segs:o,forPrint:this.props.forPrint}))}}return s.createElement(s.Fragment,null,r)}))}_eventStoreToSegs(e,t,n){return this.eventRangesToSegs(a.sliceEventStore(e,t,this.props.dateProfile.activeRange,this.context.options.nextDayThreshold).fg,n)}eventRangesToSegs(e,t){let a=[];for(let n of e)a.push(...this.eventRangeToSegs(n,t));return a}eventRangeToSegs(e,t){let n,s=e.range,r=[];for(n=0;n<t.length;n+=1){const i=a.intersectRanges(s,t[n]);i&&r.push({eventRange:e,slicedStart:i.start,slicedEnd:i.end,isStart:e.isStart&&s.start.valueOf()===i.start.valueOf(),isEnd:e.isEnd&&s.end.valueOf()===i.end.valueOf(),dayIndex:n})}return r}}function g(e){return e.text}function y(e){let t=a.startOfDay(e.renderRange.start),n=e.renderRange.end,s=[],r=[];for(;t<n;)s.push(t),r.push({start:t,end:a.addDays(t,1)}),t=a.addDays(t,1);return{dayDates:s,dayRanges:r}}const v={listDaysClass:a.identity,listDayClass:a.identity,listDayFormat:p,listDaySideFormat:p,listDayHeaderDidMount:a.identity,listDayHeaderWillUnmount:a.identity,listDayHeaderClass:a.identity,listDayHeaderInnerClass:a.identity,listDayHeaderContent:a.identity,listDayEventsClass:a.identity,noEventsClass:a.identity,noEventsInnerClass:a.identity,noEventsContent:a.identity,noEventsDidMount:a.identity,noEventsWillUnmount:a.identity};function p(e){return!1===e?null:a.createFormatter(e)}var E=t.createPlugin({name:"@fullcalendar/list",optionRefiners:v,views:{list:{component:m,buttonTextKey:"listText"},listDay:{type:"list",duration:{days:1}},listWeek:{type:"list",duration:{weeks:1}},listMonth:{type:"list",duration:{month:1}},listYear:{type:"list",duration:{year:1}}}}),D={__proto__:null,ListView:m};return t.globalPlugins.push(E),e.Internal=D,e.default=E,Object.defineProperty(e,"__esModule",{value:!0}),e}({},FullCalendar,FullCalendar.Internal,FullCalendar.InternalClassNames,FullCalendar.Preact);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fullcalendar/list",
3
- "version": "7.0.0-beta.4",
3
+ "version": "7.0.0-beta.5",
4
4
  "title": "FullCalendar List View Plugin",
5
5
  "description": "Display events on a calendar view that looks like a bulleted list",
6
6
  "keywords": [
@@ -12,7 +12,7 @@
12
12
  ],
13
13
  "homepage": "https://fullcalendar.io/docs/list-view",
14
14
  "peerDependencies": {
15
- "@fullcalendar/core": "7.0.0-beta.4"
15
+ "@fullcalendar/core": "7.0.0-beta.5"
16
16
  },
17
17
  "type": "module",
18
18
  "bugs": "https://fullcalendar.io/reporting-bugs",
@@ -27,28 +27,31 @@
27
27
  "email": "arshaw@arshaw.com",
28
28
  "url": "http://arshaw.com/"
29
29
  },
30
- "copyright": "2024 Adam Shaw",
31
- "types": "./index.d.ts",
32
- "main": "./index.cjs",
33
- "module": "./index.js",
34
- "unpkg": "./index.global.min.js",
35
- "jsdelivr": "./index.global.min.js",
30
+ "copyright": "2025 Adam Shaw",
31
+ "types": "./esm/index.d.ts",
32
+ "module": "./esm/index.js",
33
+ "main": "./cjs/index.cjs",
34
+ "unpkg": "./global.min.js",
35
+ "jsdelivr": "./global.min.js",
36
36
  "exports": {
37
37
  "./package.json": "./package.json",
38
- "./index.cjs": "./index.cjs",
39
- "./index.js": "./index.js",
40
38
  ".": {
41
- "types": "./index.d.ts",
42
- "require": "./index.cjs",
43
- "import": "./index.js"
39
+ "import": {
40
+ "types": "./esm/index.d.ts",
41
+ "default": "./esm/index.js"
42
+ },
43
+ "require": "./cjs/index.cjs"
44
44
  },
45
- "./internal.cjs": "./internal.cjs",
46
- "./internal.js": "./internal.js",
47
45
  "./internal": {
48
- "types": "./internal.d.ts",
49
- "require": "./internal.cjs",
50
- "import": "./internal.js"
46
+ "import": {
47
+ "types": "./esm/internal.d.ts",
48
+ "default": "./esm/internal.js"
49
+ },
50
+ "require": "./cjs/internal.cjs"
51
51
  }
52
52
  },
53
- "sideEffects": false
53
+ "sideEffects": [
54
+ "./global.js",
55
+ "./global.min.js"
56
+ ]
54
57
  }
package/index.cjs DELETED
@@ -1,56 +0,0 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
- var index_cjs = require('@fullcalendar/core/index.cjs');
6
- var internalCommon = require('./internal.cjs');
7
- var internal_cjs = require('@fullcalendar/core/internal.cjs');
8
- require('@fullcalendar/core/preact.cjs');
9
-
10
- const OPTION_REFINERS = {
11
- listDayFormat: createFalsableFormatter,
12
- listDaySideFormat: createFalsableFormatter,
13
- noEventsClassNames: internal_cjs.identity,
14
- noEventsContent: internal_cjs.identity,
15
- noEventsDidMount: internal_cjs.identity,
16
- noEventsWillUnmount: internal_cjs.identity,
17
- // noEventsText is defined in base options
18
- };
19
- function createFalsableFormatter(input) {
20
- return input === false ? null : internal_cjs.createFormatter(input);
21
- }
22
-
23
- var index = index_cjs.createPlugin({
24
- name: '@fullcalendar/list',
25
- optionRefiners: OPTION_REFINERS,
26
- views: {
27
- list: {
28
- component: internalCommon.ListView,
29
- buttonTextKey: 'list',
30
- listDayFormat: { month: 'long', day: 'numeric', year: 'numeric' }, // like "January 1, 2016"
31
- },
32
- listDay: {
33
- type: 'list',
34
- duration: { days: 1 },
35
- listDayFormat: { weekday: 'long' }, // day-of-week is all we need. full date is probably in headerToolbar
36
- },
37
- listWeek: {
38
- type: 'list',
39
- duration: { weeks: 1 },
40
- listDayFormat: { weekday: 'long' },
41
- listDaySideFormat: { month: 'long', day: 'numeric', year: 'numeric' },
42
- },
43
- listMonth: {
44
- type: 'list',
45
- duration: { month: 1 },
46
- listDaySideFormat: { weekday: 'long' }, // day-of-week is nice-to-have
47
- },
48
- listYear: {
49
- type: 'list',
50
- duration: { year: 1 },
51
- listDaySideFormat: { weekday: 'long' }, // day-of-week is nice-to-have
52
- },
53
- },
54
- });
55
-
56
- exports["default"] = index;