@koine/react 2.0.0-beta.80 → 2.0.0-beta.83

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/FaviconTags.cjs.js +10 -3
  2. package/FaviconTags.esm.js +10 -3
  3. package/Meta.cjs.js +10 -3
  4. package/Meta.esm.js +10 -3
  5. package/NoJs.cjs.js +1 -5
  6. package/NoJs.esm.js +1 -5
  7. package/calendar.cjs.js +97 -534
  8. package/calendar.esm.js +97 -534
  9. package/classed.cjs.js +42 -39
  10. package/classed.esm.js +42 -39
  11. package/createUseMediaQueryWidth.cjs.js +15 -34
  12. package/createUseMediaQueryWidth.d.ts +1 -1
  13. package/createUseMediaQueryWidth.esm.js +15 -34
  14. package/extendComponent.cjs.js +5 -7
  15. package/extendComponent.d.ts +1 -1
  16. package/extendComponent.esm.js +5 -7
  17. package/forms/antispam.d.ts +1 -1
  18. package/forms.cjs.js +27 -27
  19. package/forms.esm.js +27 -27
  20. package/mergeRefs.cjs.js +1 -12
  21. package/mergeRefs.d.ts +1 -1
  22. package/mergeRefs.esm.js +1 -12
  23. package/package.json +3 -3
  24. package/useAsyncFn.cjs.js +4 -23
  25. package/useAsyncFn.esm.js +4 -23
  26. package/useFirstMountState.cjs.js +3 -8
  27. package/useFirstMountState.esm.js +3 -8
  28. package/useFixedOffset.cjs.js +12 -37
  29. package/useFixedOffset.esm.js +13 -38
  30. package/useFocus.cjs.js +3 -7
  31. package/useFocus.esm.js +3 -7
  32. package/useInterval.cjs.js +6 -17
  33. package/useInterval.esm.js +6 -17
  34. package/useIsomorphicLayoutEffect.cjs.js +3 -1
  35. package/useIsomorphicLayoutEffect.esm.js +3 -1
  36. package/useKeyUp.cjs.js +6 -13
  37. package/useKeyUp.esm.js +6 -13
  38. package/useMeasure.cjs.js +33 -115
  39. package/useMeasure.esm.js +33 -115
  40. package/useMountedState.cjs.js +3 -11
  41. package/useMountedState.esm.js +3 -11
  42. package/useNavigateAway.cjs.js +47 -22
  43. package/useNavigateAway.esm.js +47 -22
  44. package/usePrevious.cjs.js +1 -7
  45. package/usePrevious.esm.js +1 -7
  46. package/usePreviousRef.cjs.js +1 -7
  47. package/usePreviousRef.esm.js +1 -7
  48. package/useScrollPosition.cjs.js +7 -53
  49. package/useScrollPosition.esm.js +7 -53
  50. package/useScrollThreshold.cjs.js +4 -22
  51. package/useScrollThreshold.esm.js +4 -22
  52. package/useScrollTo.cjs.js +3 -16
  53. package/useScrollTo.esm.js +3 -16
  54. package/useSmoothScroll.cjs.js +6 -27
  55. package/useSmoothScroll.esm.js +6 -27
  56. package/useSpinDelay.cjs.js +12 -34
  57. package/useSpinDelay.esm.js +12 -34
  58. package/useTraceUpdate.cjs.js +4 -15
  59. package/useTraceUpdate.esm.js +4 -15
  60. package/useUpdateEffect.cjs.js +4 -8
  61. package/useUpdateEffect.esm.js +4 -8
  62. package/useWindowSize.cjs.js +9 -17
  63. package/useWindowSize.esm.js +9 -17
package/calendar.cjs.js CHANGED
@@ -38,547 +38,110 @@ function _interopNamespace(e) {
38
38
  return Object.freeze(n);
39
39
  }
40
40
 
41
- let getEventTimestamp = (dateLike) => {
42
- const date = new Date(dateLike);
43
- date.setHours(0, 0, 0, 0);
44
- return date.valueOf() / 1000;
45
- };
46
- let getDisplayTime = (date) => date.getHours() +
47
- ":" +
48
- "0".repeat(2 - date.getMinutes().toString().length) +
49
- date.getMinutes();
50
- let getStartDate = (date, view) => {
51
- date.setHours(0, 0, 0);
52
- if (view === "month") {
53
- date.setDate(1);
54
- }
55
- else if (view === "week") {
56
- date = startOfWeek.startOfWeek(date, { weekStartsOn: 1 });
57
- }
58
- return date;
59
- };
60
- let getEndDate = (start, view) => {
61
- let end = start;
62
- if (view === "month") {
63
- end = endOfMonth.endOfMonth(start);
64
- }
65
- else if (view === "week") {
66
- end = endOfWeek.endOfWeek(start, { weekStartsOn: 1 });
67
- }
68
- end.setHours(23, 59, 59);
69
- return end;
70
- };
71
- let getPrevDate = (date, view) => view === "month" ? subMonths.subMonths(date, 1) : subWeeks.subWeeks(date, 1);
72
- let getNextDate = (date, view) => view === "month" ? addMonths.addMonths(date, 1) : addWeeks.addWeeks(date, 1);
73
- let isTodayInView = (start, end) => isWithinInterval.isWithinInterval(new Date(), { start, end });
74
- let addCalendarEvents = (toAdd, toExtend) => {
75
- for (const id in toAdd) {
76
- const event = toAdd[id];
77
- toExtend[id] = event;
78
- }
79
- return toExtend;
80
- };
81
- let getEventsByTimestamp = (events) => {
82
- const output = {};
83
- for (const uid in events) {
84
- const event = events[uid];
85
- event.days.forEach((timestamp) => {
86
- output[timestamp] = (output[timestamp] || {});
87
- output[timestamp][uid] = event;
88
- });
89
- }
90
- return output;
91
- };
92
- let getSortedEvents = (events) => {
93
- const output = [];
94
- for (const uid in events) {
95
- output.push(events[uid]);
96
- }
97
- output.sort((a, b) => {
98
- const multi = Number(b.multi) - Number(a.multi);
99
- const allDay = Number(b.allDay) - Number(a.allDay);
100
- const start = a.start.getTime() - b.start.getTime();
101
- const created = a.created.getTime() - b.created.getTime();
102
- return multi || allDay || start || created;
103
- });
104
- return output;
105
- };
106
- const FREE_SLOT = 0;
107
- const BUSY_SLOT = 1;
108
- let processEventsInView = (eventsMap, calendarView, month, weeks) => {
109
- const eventsByTimestamp = getEventsByTimestamp(eventsMap);
110
- const eventsList = getSortedEvents(eventsMap);
111
- const todayDate = new Date();
112
- const todayTimestamp = getEventTimestamp(todayDate);
113
- const startedAtTopMap = {};
114
- const viewWeeks = [];
115
- for (let weekIdx = 0; weekIdx < weeks.length; weekIdx++) {
116
- const viewWeek = {
117
- props: { key: `week.${weekIdx}` },
118
- days: [],
119
- };
120
- const weekStartDate = weeks[weekIdx];
121
- const weekStartDay = weekStartDate.getDate();
122
- const weekStartTimestamp = getEventTimestamp(new Date(weekStartDate));
123
- const weekEndTimestamp = getEventTimestamp(addDays.addDays(new Date(weekStartDate), 6));
124
- for (let dayNumber = 0; dayNumber < 7; dayNumber++) {
125
- const dayDate = new Date(new Date(weekStartDate).setDate(weekStartDay + dayNumber));
126
- const dayTimestamp = getEventTimestamp(dayDate);
127
- const $isToday = todayTimestamp === dayTimestamp;
128
- const $isOutOfRange = calendarView === "month" && dayDate.getMonth() !== month;
129
- const contextualProps = {
130
- $isToday,
131
- $isOutOfRange,
132
- };
133
- const viewDay = {
134
- props: { key: `day.${dayTimestamp}`, ...contextualProps },
135
- timestamp: dayTimestamp + "",
136
- label: dayDate.getDate() + "",
137
- events: [],
138
- };
139
- if (eventsByTimestamp?.[dayTimestamp]) {
140
- const verticalSlots = Object.keys(eventsByTimestamp[dayTimestamp]).map(() => FREE_SLOT);
141
- for (let eventIdx = 0; eventIdx < eventsList.length; eventIdx++) {
142
- const event = eventsList[eventIdx];
143
- let width = 1;
144
- let top = 0;
145
- let firstOfMulti;
146
- if (!event.daysMap[dayTimestamp]) {
147
- continue;
148
- }
149
- if (event.multi) {
150
- width = event.days.filter((t) => t >= weekStartTimestamp && t <= weekEndTimestamp).length;
151
- if (event.days.indexOf(dayTimestamp) === 0 || dayNumber === 0) {
152
- firstOfMulti = true;
153
- }
154
- }
155
- if (startedAtTopMap[event.uid]) {
156
- top = startedAtTopMap[event.uid];
157
- }
158
- else {
159
- for (let verticalIdx = 0; verticalIdx < verticalSlots.length; verticalIdx++) {
160
- const freeOrBusy = verticalSlots[verticalIdx];
161
- if (freeOrBusy !== BUSY_SLOT) {
162
- top = verticalIdx;
163
- break;
164
- }
165
- }
166
- }
167
- verticalSlots[top] = BUSY_SLOT;
168
- if (firstOfMulti) {
169
- startedAtTopMap[event.uid] = top;
170
- }
171
- viewDay.events.push({
172
- key: `event.${dayTimestamp}-${top}`,
173
- ...contextualProps,
174
- ...event,
175
- isPast: todayDate > event.end,
176
- firstOfMulti,
177
- top,
178
- width,
179
- });
180
- }
181
- for (let i = 0; i < verticalSlots.length; i++) {
182
- if (verticalSlots[i] !== BUSY_SLOT) {
183
- viewDay.events.push({
184
- key: `event.${dayTimestamp}-${i}}`,
185
- placeholder: true,
186
- top: i,
187
- });
188
- }
189
- }
190
- viewDay.events.sort((a, b) => a.top - b.top);
191
- }
192
- viewWeek.days.push(viewDay);
193
- }
194
- viewWeeks.push(viewWeek);
195
- }
196
- return viewWeeks;
197
- };
41
+ let getEventTimestamp=e=>{let t=new Date(e);return t.setHours(0,0,0,0),t.valueOf()/1e3};let getDisplayTime=e=>e.getHours()+":"+"0".repeat(2-e.getMinutes().toString().length)+e.getMinutes();let getStartDate=(e,t)=>(e.setHours(0,0,0),"month"===t?e.setDate(1):"week"===t&&(e=startOfWeek.startOfWeek(e,{weekStartsOn:1})),e);let getEndDate=(e,t)=>{let r=e;return "month"===t?r=endOfMonth.endOfMonth(e):"week"===t&&(r=endOfWeek.endOfWeek(e,{weekStartsOn:1})),r.setHours(23,59,59),r};let getPrevDate=(e,t)=>"month"===t?subMonths.subMonths(e,1):subWeeks.subWeeks(e,1);let getNextDate=(e,a)=>"month"===a?addMonths.addMonths(e,1):addWeeks.addWeeks(e,1);let isTodayInView=(e,t)=>isWithinInterval.isWithinInterval(new Date,{start:e,end:t});let addCalendarEvents=(e,t)=>{for(let r in e){let a=e[r];t[r]=a;}return t};let i=e=>{let t={};for(let r in e){let a=e[r];a.days.forEach(e=>{t[e]=t[e]||{},t[e][r]=a;});}return t},d$1=e=>{let t=[];for(let r in e)t.push(e[r]);return(// sort events first multi, then all day then by start then by created date
42
+ t.sort((e,t)=>{let r=Number(t.multi)-Number(e.multi),a=Number(t.allDay)-Number(e.allDay),n=e.start.getTime()-t.start.getTime(),s=e.created.getTime()-t.created.getTime();return r||a||n||s}),t)};let processEventsInView=(t,r,a,n)=>{let s=i(t),o=d$1(t),l=new Date,m=getEventTimestamp(l),p={},f=[];for(let t=0;t<n.length;t++){let i={props:{key:`week.${t}`},days:[]},d=n[t],u=d.getDate(),g=getEventTimestamp(new Date(d)),h=getEventTimestamp(addDays.addDays(new Date(d),6));for(let e=0;e<7;e++){let t=new Date(new Date(d).setDate(u+e)),n=getEventTimestamp(t),f={$isToday:m===n,$isOutOfRange:"month"===r&&t.getMonth()!==a},v={props:{key:`day.${n}`,...f},timestamp:n+"",label:t.getDate()+"",events:[]};// check that we have events in this day
43
+ if(s?.[n]){let t=Object.keys(s[n]).map(()=>0);for(let r=0;r<o.length;r++){let a;let s=o[r],m=1,i=0;if(s.daysMap[n]){// if we already have the information on when the event has been
44
+ // vertically positioned use that index
45
+ if(// only for multi days events:
46
+ s.multi&&(// filter out the days outside of the current week view to avoid
47
+ // making a multi-days event chip wider than the week row or shorter
48
+ // than it should be (when event spans across weeks)
49
+ m=s.days.filter(e=>e>=g&&e<=h).length,// flag the first day of multi-days events, consider that an event
50
+ // might start in a day earlier (hence outside) of the current
51
+ // week/month view, so we always check for Mondays (dayNumber === 0)
52
+ (0===s.days.indexOf(n)||0===e)&&(a=!0)),p[s.uid])i=p[s.uid];else // now look for a free slot and use its index as `top`
53
+ for(let e=0;e<t.length;e++)if(1!==t[e]){i=e;break}// now mark the slot as busy
54
+ t[i]=1,// store the slot vertical position consistently for multi-days events
55
+ a&&(p[s.uid]=i),// push the event, they will be sorted later
56
+ v.events.push({key:`event.${n}-${i}`,...f,...s,isPast:l>s.end,firstOfMulti:a,top:i,width:m});}}// fill the empty slots with events' placeholders
57
+ for(let e=0;e<t.length;e++)1!==t[e]&&v.events.push({key:`event.${n}-${e}}`,placeholder:!0,top:e});// sort events and events placeholders by top position
58
+ v.events.sort((e,t)=>e.top-t.top);}i.days.push(v);}f.push(i);}return f};
198
59
 
199
- const IconExpand = (props) => {
200
- return (jsxRuntime.jsxs("svg", { viewBox: "0 0 24 24", fill: "currentColor", stroke: "none", ...props, children: [jsxRuntime.jsx("path", { d: "M0 0h24v24H0z" }), jsxRuntime.jsx("path", { d: "M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z" })] }));
201
- };
202
- const styleBtn = {
203
- overflow: "hidden",
204
- whiteSpace: "nowrap",
205
- textOverflow: "ellipsis",
206
- };
207
- let CalendarDaygridCell = ({ eventClicked, setEventClicked, setEventHovered, view, maxEvents, events, calendarsMap, Cell = "div", CellOverflow = "div", CellEvent = "div", CellEventBtn = "div", CellEventTitle = "span", CellEventStart = "span", }) => {
208
- const [isExpanded, expand] = react.useState(false);
209
- const eventsWithoutPlaceholders = events.filter((event) => !event.placeholder);
210
- return (jsxRuntime.jsx(Cell, { children: events.map((event, i) => {
211
- if (i === maxEvents && !isExpanded) {
212
- return (jsxRuntime.jsxs(CellOverflow, { onClick: () => expand(true), children: [jsxRuntime.jsx(IconExpand, {}), eventsWithoutPlaceholders.length - maxEvents] }, "overflowMessage" + i));
213
- }
214
- if (i > maxEvents && !isExpanded)
215
- return null;
216
- if (event.placeholder) {
217
- return (jsxRuntime.jsx(react.Fragment, { children: jsxRuntime.jsx(CellEvent, { "$placeholder": true, children: jsxRuntime.jsx(CellEventBtn, { "aria-hidden": "true", style: { visibility: "hidden" }, "$placeholder": true, children: jsxRuntime.jsx(CellEventTitle, { children: "\u00A0" }) }) }) }, event.key));
218
- }
219
- const styleEvent = {
220
- zIndex: event.firstOfMulti ? 1 : 0,
221
- position: "relative",
222
- width: event.firstOfMulti ? `${100 * event.width}%` : "100%",
223
- };
224
- if (!calendarsMap[event.calendar.id].on) {
225
- styleBtn.display = "none";
226
- }
227
- const styledProps = {
228
- $view: view,
229
- $selected: eventClicked?.uid === event.uid,
230
- $past: event.isPast,
231
- $color: event.color,
232
- $isOutOfRange: event.$isOutOfRange,
233
- $isToday: event.$isToday,
234
- };
235
- return (jsxRuntime.jsx(react.Fragment, { children: jsxRuntime.jsx(CellEvent, { style: styleEvent, ...styledProps, children: jsxRuntime.jsx(CellEventBtn, { role: "button", style: styleBtn, ...styledProps, onClick: () => setEventClicked((prev) => prev?.uid === event.uid ? null : event), onMouseEnter: () => setEventHovered(event), onMouseLeave: () => setEventHovered(null), children: event.allDay ? (jsxRuntime.jsx(CellEventTitle, { children: event.title })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(CellEventStart, { children: getDisplayTime(event.start) }), jsxRuntime.jsx(CellEventTitle, { children: event.title })] })) }) }) }, event.key));
236
- }) }));
237
- };
60
+ /**
61
+ * TODO: include in this lib utilities like in https://github.com/react-icons/react-icons/blob/master/packages/react-icons/src/iconBase.tsx
62
+ *
63
+ * this is the `MdAdd` icon from `react-icons`
64
+ */let d=l=>/*#__PURE__*/jsxRuntime.jsxs("svg",{viewBox:"0 0 24 24",fill:"currentColor",stroke:"none",...l,children:[/*#__PURE__*/jsxRuntime.jsx("path",{d:"M0 0h24v24H0z"}),/*#__PURE__*/jsxRuntime.jsx("path",{d:"M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"})]}),/**
65
+ * Style for button within a event cell
66
+ *
67
+ * Here we might differentiate week/month view where the first does not get
68
+ * ellipsed btn texts, with `Start` as block element and underneath the `Title`
69
+ * on multiple lines, but that would mean that we loose the ability to interweave
70
+ * single-day events among the spaces left by wider multi-days events.
71
+ */o$1={overflow:"hidden",whiteSpace:"nowrap",textOverflow:"ellipsis"};let CalendarDaygridCell=({eventClicked:a,setEventClicked:s,// eventHovered,
72
+ setEventHovered:h,view:c,maxEvents:u,events:p,calendarsMap:v,Cell:f="div",CellOverflow:y="div",CellEvent:$="div",CellEventBtn:m="div",CellEventTitle:w="span",CellEventStart:g="span"})=>{let[x,M]=react.useState(!1),O=p.filter(e=>!e.placeholder);return /*#__PURE__*/jsxRuntime.jsx(f,{children:p.map((t,p)=>{if(p===u&&!x)return /*#__PURE__*/jsxRuntime.jsxs(y,{onClick:()=>M(!0),children:[/*#__PURE__*/jsxRuntime.jsx(d,{}),O.length-u]},"overflowMessage"+p);if(p>u&&!x)return null;if(t.placeholder)return /*#__PURE__*/jsxRuntime.jsx(react.Fragment,{children:/*#__PURE__*/jsxRuntime.jsx($,{$placeholder:!0,children:/*#__PURE__*/jsxRuntime.jsx(m,{"aria-hidden":"true",style:{visibility:"hidden"},$placeholder:!0,children:/*#__PURE__*/jsxRuntime.jsx(w,{children:" "})})})},t.key);let f={zIndex:t.firstOfMulti?1:0,// to cover the following event days
73
+ position:"relative",width:t.firstOfMulti?`${100*t.width}%`:"100%"};v[t.calendar.id].on||// @ts-expect-error nevermind
74
+ (o$1.display="none");let k={$view:c,$selected:a?.uid===t.uid,$past:t.isPast,$color:t.color,$isOutOfRange:t.$isOutOfRange,$isToday:t.$isToday};return /*#__PURE__*/jsxRuntime.jsx(react.Fragment,{children:/*#__PURE__*/jsxRuntime.jsx($,{style:f,...k,children:/*#__PURE__*/jsxRuntime.jsx(m,{role:"button",style:o$1,...k,onClick:()=>s(e=>e?.uid===t.uid?null:t),onMouseEnter:()=>h(t),onMouseLeave:()=>h(null),children:t.allDay?/*#__PURE__*/jsxRuntime.jsx(w,{children:t.title}):/*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[/*#__PURE__*/jsxRuntime.jsx(g,{children:getDisplayTime(t.start)}),/*#__PURE__*/jsxRuntime.jsx(w,{children:t.title})]})})})},t.key)})})};/* {i === events.length - 1 && isExpanded ? (
75
+ <CellOverflow onClick={() => expand(false)}>
76
+ <IconCollapse />
77
+ Show less
78
+ </CellOverflow>
79
+ ) : null} */
238
80
 
239
- let useDateLocale = (locale, defaultLocale = "en") => {
240
- const [data, setData] = react.useState();
241
- const [current, setCurrent] = react.useState(defaultLocale);
242
- react.useEffect(() => {
243
- const importLocaleFile = async () => {
244
- const localeToSet = await Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespace(require('date-fns/locale/en-US')); });
245
- setCurrent(locale || current);
246
- setData(localeToSet.enUS);
247
- };
248
- if (locale !== current) {
249
- importLocaleFile();
250
- }
251
- }, [locale, current]);
252
- return data;
253
- };
81
+ /**
82
+ * Dynamically import the date-fns correct locale
83
+ *
84
+ * Inspired by:
85
+ * @see https://robertmarshall.dev/blog/dynamically-import-datefns-locale-mui-datepicker-localization/
86
+ */let useDateLocale=(a,l="en")=>{let[r,n]=react.useState(),[o,c]=react.useState(l);return(// const [ready, setReady] = useState(false);
87
+ // If the user changes the locale listen to the change and import the locale that is now required.
88
+ react.useEffect(()=>{let e=async()=>{// This webpack option stops all of the date-fns files being imported and chunked.
89
+ // NB: this makes unnecessary numerous webpack chunks in applications
90
+ // that do not even use this hook, so we comment out the webpack dynamic
91
+ // import and its magic comment
92
+ // const localeToSet = await import(
93
+ // /FIXME: * webpackMode: "lazy", webpackChunkName: "df-[index]", webpackExclude: /_lib/ */
94
+ // `date-fns/locale/${locale}/index.js`,
95
+ // );
96
+ let e=await Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespace(require('date-fns/locale/en-US')); });c(a||o),n(e.enUS);};// setReady(true);
97
+ // If the locale has not yet been loaded.
98
+ a!==o&&e();},[a,o]),r)};
254
99
 
255
- let KoineCalendarDaygridNav = ({ range, view, todayInView, handlePrev, handleNext, handleToday, handleView, locale: localeCode, NavRoot = "nav", NavTitle = "div", NavBtns = "div", NavBtnPrev = "button", NavBtnNext = "button", NavBtnToday = "button", NavBtnViewMonth = "button", NavBtnViewWeek = "button", }) => {
256
- const [start, end] = range;
257
- const locale = useDateLocale(localeCode);
258
- const opts = { locale };
259
- let formatted = "";
260
- if (view === "month") {
261
- formatted = format.format(start, "MMMM yyyy", opts);
262
- }
263
- if (view === "week") {
264
- const inSameMonth = start.getMonth() === end.getMonth();
265
- if (inSameMonth) {
266
- formatted = format.format(start, "# MMMM yyyy", opts).replace("#", `${start.getDate()}-${end.getDate()}`);
267
- }
268
- else {
269
- formatted = `${format.format(start, "d MMMM", opts)} - ${format.format(end, "d MMMM yyyy", opts)}`;
270
- }
271
- }
272
- return (jsxRuntime.jsxs(NavRoot, { children: [jsxRuntime.jsxs(NavBtns, { children: [jsxRuntime.jsx(NavBtnPrev, { onClick: handlePrev }), jsxRuntime.jsx(NavBtnNext, { onClick: handleNext }), jsxRuntime.jsx(NavBtnToday, { onClick: handleToday, disabled: todayInView }), jsxRuntime.jsx(NavBtnViewMonth, { onClick: () => handleView("month"), disabled: view === "month" }), jsxRuntime.jsx(NavBtnViewWeek, { onClick: () => handleView("week"), disabled: view === "week" })] }), jsxRuntime.jsx(NavTitle, { range: range, formatted: formatted })] }));
273
- };
100
+ let KoineCalendarDaygridNav=({range:a,view:l,todayInView:r,handlePrev:i,handleNext:M,handleToday:d,handleView:y,locale:c,NavRoot:m="nav",NavTitle:s="div",NavBtns:b="div",NavBtnPrev:k="button",NavBtnNext:u="button",NavBtnToday:h="button",NavBtnViewMonth:f="button",NavBtnViewWeek:g="button"})=>{let[C,p]=a,v={locale:useDateLocale(c)},x="";return "month"===l&&(x=format.format(C,"MMMM yyyy",v)),"week"===l&&(x=C.getMonth()===p.getMonth()?format.format(C,"# MMMM yyyy",v).replace("#",`${C.getDate()}-${p.getDate()}`):`${format.format(C,"d MMMM",v)} - ${format.format(p,"d MMMM yyyy",v)}`),/*#__PURE__*/jsxRuntime.jsxs(m,{children:[/*#__PURE__*/jsxRuntime.jsxs(b,{children:[/*#__PURE__*/jsxRuntime.jsx(k,{onClick:i}),/*#__PURE__*/jsxRuntime.jsx(u,{onClick:M}),/*#__PURE__*/jsxRuntime.jsx(h,{onClick:d,disabled:r}),/*#__PURE__*/jsxRuntime.jsx(f,{onClick:()=>y("month"),disabled:"month"===l}),/*#__PURE__*/jsxRuntime.jsx(g,{onClick:()=>y("week"),disabled:"week"===l})]}),/*#__PURE__*/jsxRuntime.jsx(s,{range:a,formatted:x})]})};
274
101
 
275
- function getView(range) {
276
- const [start, end] = range;
277
- const weeks = eachWeekOfInterval.eachWeekOfInterval({ start, end }, { weekStartsOn: 1 });
278
- return {
279
- month: start.getMonth(),
280
- weeks,
281
- };
282
- }
283
- let KoineCalendarDaygridTable = ({ locale: localeCode, handlePrev, handleNext, events, dayLabels, view, range, eventClicked, setEventClicked, eventHovered, setEventHovered, calendarsMap = {}, maxEvents = 5, Table = "table", TableHead = "thead", TableHeadCell = "th", TableBody = "tbody", TableBodyRow = "tr", TableBodyCell = "td", TableBodyCellDate = "div", Cell, CellOverflow, CellEvent, CellEventBtn, CellEventTitle, CellEventStart, }) => {
284
- const restKoine = {
285
- Cell,
286
- CellOverflow,
287
- CellEvent,
288
- CellEventBtn,
289
- CellEventTitle,
290
- CellEventStart,
291
- };
292
- const [days, setDays] = react.useState(dayLabels || [0, 1, 2, 3, 4, 5, 6]);
293
- const [weeksEvents, setWeeksEvents] = react.useState([]);
294
- const locale = useDateLocale(localeCode);
295
- const { month, weeks } = react.useMemo(() => getView(range), [range]);
296
- const swipeableHandlers = reactSwipeable.useSwipeable({
297
- onSwipedLeft: handleNext,
298
- onSwipedRight: handlePrev,
299
- });
300
- react.useEffect(() => {
301
- setWeeksEvents(processEventsInView(events, view, month, weeks));
302
- }, [events, view, month, weeks]);
303
- react.useEffect(() => {
304
- if (locale && locale.localize && !dayLabels) {
305
- setDays([1, 2, 3, 4, 5, 6, 0].map((i) => locale.localize.day(i, { width: "abbreviated" })));
306
- }
307
- }, [locale, dayLabels]);
308
- return (jsxRuntime.jsxs(Table, { ...swipeableHandlers, children: [jsxRuntime.jsx(TableHead, { children: jsxRuntime.jsx("tr", { children: days.map((day) => (jsxRuntime.jsx(TableHeadCell, { scope: "column", children: day }, day))) }) }), jsxRuntime.jsx(TableBody, { children: weeksEvents.map((week, i) => (jsxRuntime.jsx(TableBodyRow, { ...week.props, children: week.days.map((day) => (jsxRuntime.jsxs(TableBodyCell, { ...day.props, children: [jsxRuntime.jsx(TableBodyCellDate, { ...day.props, children: day.label }), day.events.length > 0 && (jsxRuntime.jsx(CalendarDaygridCell, { eventClicked,
309
- setEventClicked,
310
- eventHovered,
311
- setEventHovered,
312
- view,
313
- maxEvents,
314
- events: day.events,
315
- timestamp: day.timestamp,
316
- calendarsMap, ...restKoine }))] }))) }))) })] }));
317
- };
102
+ let KoineCalendarDaygridTable=({locale:d,handlePrev:s,handleNext:c,events:h,dayLabels:f,view:b,range:u,eventClicked:v,setEventClicked:g,eventHovered:w,setEventHovered:y,calendarsMap:x={},maxEvents:j=5,Table:C="table",TableHead:D="thead",TableHeadCell:S="th",TableBody:k="tbody",TableBodyRow:z="tr",TableBodyCell:L="td",TableBodyCellDate:O="div",Cell:I,CellOverflow:K,CellEvent:M,CellEventBtn:R,CellEventTitle:T,CellEventStart:W})=>// ...props
103
+ {let q={Cell:I,CellOverflow:K,CellEvent:M,CellEventBtn:R,CellEventTitle:T,CellEventStart:W},[A,B]=react.useState(f||[0,1,2,3,4,5,6]),[E,F]=react.useState([]),// const [days, setDays] = useState(dayLabels || [...Array(7).keys()]);
104
+ G=useDateLocale(d),{month:H,weeks:J}=react.useMemo(()=>(function(e){let[t,a]=e,i=eachWeekOfInterval.eachWeekOfInterval({start:t,end:a},{weekStartsOn:1});return {month:t.getMonth(),weeks:i}})(u),[u]),N=reactSwipeable.useSwipeable({onSwipedLeft:c,onSwipedRight:s});return react.useEffect(()=>{F(processEventsInView(h,b,H,J));},[h,b,H,J]),react.useEffect(()=>{G&&G.localize&&!f&&B([1,2,3,4,5,6,0].map(// @ts-expect-error nevermind
105
+ e=>G.localize.day(e,{width:"abbreviated"})));},[G,f]),/*#__PURE__*/jsxRuntime.jsxs(C,{...N,children:[/*#__PURE__*/jsxRuntime.jsx(D,{children:/*#__PURE__*/jsxRuntime.jsx("tr",{children:A.map(t=>/*#__PURE__*/jsxRuntime.jsx(S,{scope:"column",children:t},t))})}),/*#__PURE__*/jsxRuntime.jsx(k,{children:E.map((r,a)=>/*#__PURE__*/jsxRuntime.jsx(z,{...r.props,children:r.days.map(r=>/*#__PURE__*/jsxRuntime.jsxs(L,{...r.props,children:[/*#__PURE__*/jsxRuntime.jsx(O,{...r.props,children:r.label}),r.events.length>0&&/*#__PURE__*/jsxRuntime.jsx(CalendarDaygridCell,{eventClicked:v,setEventClicked:g,eventHovered:w,setEventHovered:y,view:b,maxEvents:j,events:r.events,timestamp:r.timestamp,calendarsMap:x,...q})]}))}))})]})};
318
106
 
319
- let KoineCalendarLegend = ({ calendarsMap = {}, toggleCalendarVisibility, LegendItem = "div", LegendItemStatus = "span", LegendItemLabel = "span", LegendItemEvents = "span", }) => {
320
- return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: Object.entries(calendarsMap).map(([id, calendar]) => (jsxRuntime.jsxs(LegendItem, { onClick: () => toggleCalendarVisibility(id), "$color": calendar.color, "$empty": calendar.events === 0, disabled: calendar.events === 0, children: [jsxRuntime.jsx(LegendItemStatus, { children: calendar.on ? "\u2b24" : "\u2b58" }), jsxRuntime.jsx(LegendItemLabel, { children: calendar.name }), jsxRuntime.jsx(LegendItemEvents, { children: calendar.events })] }, "CalendarLegend." + id))) }));
321
- };
107
+ let KoineCalendarLegend=({calendarsMap:a={},toggleCalendarVisibility:s,LegendItem:d="div",LegendItemStatus:i="span",LegendItemLabel:l="span",LegendItemEvents:t="span"})=>// const sorted = Object.entries(calendarsMap).sort((a, b) => {
108
+ // const { name: nameA } = a[1];
109
+ // const { name: nameB } = b[1];
110
+ // if (nameA < nameB) return -1;
111
+ // else if (nameA > nameB) return 1;
112
+ // else return 0;
113
+ // });
114
+ /*#__PURE__*/jsxRuntime.jsx(jsxRuntime.Fragment,{children:Object.entries(a).map(([r,a])=>/*#__PURE__*/jsxRuntime.jsxs(d,{onClick:()=>s(r),$color:a.color,$empty:0===a.events,disabled:0===a.events,children:[/*#__PURE__*/jsxRuntime.jsx(i,{children:a.on?"⬤":"⭘"}),/*#__PURE__*/jsxRuntime.jsx(l,{children:a.name}),/*#__PURE__*/jsxRuntime.jsx(t,{children:a.events})]},"CalendarLegend."+r))});
322
115
 
323
- const baseURL = "https://www.googleapis.com/calendar/v3/calendars/";
324
- let getCalendarsEventsFromGoogle = async ({ calendars, ...options }) => {
325
- const allEvents = {};
326
- await Promise.all(calendars.map(async (calendar) => {
327
- const events = await getCalendarEventsFromGoogle({
328
- calendar,
329
- ...options,
330
- });
331
- addCalendarEvents(events, allEvents);
332
- }));
333
- return allEvents;
334
- };
335
- async function getCalendarEventsFromGoogle({ apiKey, calendar, timeZone = "", start, end, }) {
336
- const events = {};
337
- const params = new URLSearchParams({
338
- calendarId: calendar.id,
339
- timeZone,
340
- singleEvents: "true",
341
- maxAttendees: "1",
342
- maxResults: "9999",
343
- sanitizeHtml: "true",
344
- timeMin: start.toISOString(),
345
- timeMax: end.toISOString(),
346
- key: apiKey || process.env["GOOGLE_CALENDAR_API_KEY"] || "",
347
- }).toString();
348
- const url = baseURL + calendar.id + "/events?" + params;
349
- try {
350
- const response = await fetch(url, { method: "GET" });
351
- const data = (await response.json());
352
- calendar.name = calendar.name || data.summary;
353
- data.items.forEach((googleEvent) => {
354
- const event = transformCalendarEventFromGoogle(googleEvent, calendar);
355
- events[event.uid] = event;
356
- });
357
- }
358
- catch (e) {
359
- }
360
- return events;
361
- }
362
- function transformCalendarEventFromGoogle(event, calendar) {
363
- const created = new Date(event.created);
364
- const link = event.htmlLink;
365
- const title = event.summary;
366
- const status = event.status;
367
- const start = new Date(event.start.date || event.start.dateTime);
368
- let end = new Date(event.end.date || event.end.dateTime);
369
- const color = calendar.color;
370
- const allDay = utils.isUndefined(event.end.dateTime) && utils.isString(event.end.date);
371
- const location = event.location || "";
372
- const description = event.description || "";
373
- const uid = created.getTime() + "" + start.getTime();
374
- if (allDay && end > start) {
375
- end = subDays.subDays(end, 1);
376
- end.setHours(23, 59, 59);
377
- }
378
- const days = getDays();
379
- const daysMap = utils.arrayToLookup(days);
380
- const multi = days.length > 1;
381
- function getDays() {
382
- const from = new Date(start);
383
- const to = new Date(end);
384
- const days = [getEventTimestamp(from)];
385
- while (differenceInDays.differenceInDays(to, from)) {
386
- from.setDate(from.getDate() + 1);
387
- days.push(getEventTimestamp(from));
388
- }
389
- return days;
390
- }
391
- return {
392
- calendar,
393
- created,
394
- link,
395
- title,
396
- status,
397
- start,
398
- end,
399
- days,
400
- daysMap,
401
- multi,
402
- color,
403
- allDay,
404
- location,
405
- description,
406
- uid,
407
- };
408
- }
116
+ /** Fall back to `process.env.GOOGLE_CALENDAR_API_KEY *//** Start gethering events from date *//** End gethering events at date *//**
117
+ * The default is the time zone of the calendar
118
+ * @see https://developers.google.com/calendar/api/v3/reference/events/list
119
+ *//** The calendars settings */let getCalendarsEventsFromGoogle=async({calendars:e,...t})=>{let a={};return await Promise.all(e.map(async e=>{addCalendarEvents(await o({calendar:e,...t}),a);})),a};/** The calendar settings */async function o({apiKey:i,calendar:o,timeZone:m="",start:d,end:l}){let c={},u=new URLSearchParams({calendarId:o.id,timeZone:m,singleEvents:"true",maxAttendees:"1",maxResults:"9999",sanitizeHtml:"true",timeMin:d.toISOString(),timeMax:l.toISOString(),key:i||process.env.GOOGLE_CALENDAR_API_KEY||""}).toString(),f=/**
120
+ * Google event as it comes from Google's API
121
+ *//**
122
+ * Google calendar as it comes from Google's API
123
+ *//**
124
+ * Google event's date as it comes from Google's API
125
+ *//** When the event is "all day" we have `date` instead of `dateTime` */"https://www.googleapis.com/calendar/v3/calendars/"+o.id+"/events?"+u;try{let i=await fetch(f,{method:"GET"}),m=await i.json();o.name=o.name||m.summary,m.items.forEach(i=>{let m=function(i,o){let m=new Date(i.created),d=i.htmlLink,l=i.summary,c=i.status,u=new Date(i.start.date||i.start.dateTime),f=new Date(i.end.date||i.end.dateTime),w=o.color,g=utils.isUndefined(i.end.dateTime)&&utils.isString(i.end.date),p=i.location||"",D=i.description||"",// FIXME: he.decode(event.description || '');
126
+ h=m.getTime()+""+u.getTime();// multi-days all day events has as end date the date after to what we actually
127
+ // mean, hence we subtract one day. @see https://support.google.com/calendar/thread/10074544/google-calendar-all-day-events-are-showing-up-as-a-24-hr-event-across-time-zones?hl=en
128
+ g&&f>u&&(f=subDays.subDays(f,1)).setHours(23,59,59);let y=function(){let t=new Date(u),a=new Date(f),n=[getEventTimestamp(t)];for(;differenceInDays.differenceInDays(a,t);)// console.log(title, differenceInDays(to, from))
129
+ t.setDate(t.getDate()+1),n.push(getEventTimestamp(t));return n}(),E=utils.arrayToLookup(y),S=y.length>1;return {calendar:o,created:m,link:d,title:l,status:c,start:u,end:f,days:y,daysMap:E,multi:S,color:w,allDay:g,location:p,description:D,uid:h}}(i,o);c[m.uid]=m;});}catch(e){}// if (onError) onError(e);
130
+ return c}
409
131
 
410
- let useCalendar = ({ locale, apiKey, calendars, events: initialEvents, start: initialStart, end: initialEnd, view: initialView = "month", timeZone = "", onError, }) => {
411
- const [view, setView] = react.useState(initialView);
412
- const start = initialStart || getStartDate(new Date(), view);
413
- const end = initialEnd || getEndDate(start, view);
414
- const [range, setRange] = react.useState([start, end]);
415
- const [todayInView, setTodayInView] = react.useState(isTodayInView(start, end));
416
- const [events, setEvents] = react.useState(initialEvents || {});
417
- const [eventHovered, setEventHovered] = react.useState(null);
418
- const [eventClicked, setEventClicked] = react.useState(null);
419
- const [calendarsMap, updateCalendars] = react.useReducer((state, action) => {
420
- const { type } = action;
421
- switch (type) {
422
- case "events": {
423
- const events = action.payload;
424
- return Object.entries(state).reduce((map, [id, calendar]) => {
425
- map[id] = {
426
- ...calendar,
427
- events: events[id] || 0,
428
- };
429
- return map;
430
- }, {});
431
- }
432
- case "visibility": {
433
- const visible = action.payload;
434
- if (typeof visible === "string") {
435
- return {
436
- ...state,
437
- [visible]: {
438
- ...state[visible],
439
- on: !state[visible].on,
440
- },
441
- };
442
- }
443
- else {
444
- return Object.entries(state).reduce((map, [id, calendar]) => {
445
- map[id] = {
446
- ...calendar,
447
- on: visible.indexOf(id) > -1,
448
- };
449
- return map;
450
- }, {});
451
- }
452
- }
453
- default:
454
- return state;
455
- }
456
- }, calendars.reduce((map, calendar) => {
457
- map[calendar.id] = {
458
- ...calendar,
459
- name: calendar.name || "",
460
- on: true,
461
- events: 0,
462
- };
463
- return map;
464
- }, {}));
465
- const toggleCalendarVisibility = react.useCallback((idOrIds) => {
466
- updateCalendars({ type: "visibility", payload: idOrIds });
467
- }, [updateCalendars]);
468
- const updateCalendarsBasedOnEvents = react.useCallback((events) => {
469
- const payload = {};
470
- for (const uid in events) {
471
- const { id } = events[uid].calendar;
472
- payload[id] = payload[id] || 0;
473
- payload[id]++;
474
- }
475
- updateCalendars({ type: "events", payload });
476
- }, []);
477
- const loadCalendars = react.useCallback(async (calendars, start, end) => {
478
- try {
479
- const newEvents = await getCalendarsEventsFromGoogle({
480
- apiKey,
481
- calendars,
482
- timeZone,
483
- start,
484
- end,
485
- });
486
- setEvents(newEvents);
487
- }
488
- catch (e) {
489
- if (onError)
490
- onError(e);
491
- }
492
- }, [setEvents, apiKey, timeZone, onError]);
493
- const handleToday = react.useCallback(() => {
494
- const [start, end] = range;
495
- const newStart = getStartDate(new Date(), view);
496
- const newEnd = getEndDate(newStart, view);
497
- setRange([newStart, newEnd]);
498
- if (start.getTime() !== newStart.getTime() ||
499
- end.getTime() !== newEnd.getTime()) {
500
- setEventClicked(null);
501
- setEventHovered(null);
502
- }
503
- }, [view, range]);
504
- const handlePrev = react.useCallback(() => {
505
- setRange(([start]) => {
506
- const newStart = getPrevDate(start, view);
507
- const newEnd = getEndDate(newStart, view);
508
- return [newStart, newEnd];
509
- });
510
- setEventClicked(null);
511
- setEventHovered(null);
512
- }, [view]);
513
- const handleNext = react.useCallback(() => {
514
- setRange(([start]) => {
515
- const newStart = getNextDate(start, view);
516
- const newEnd = getEndDate(newStart, view);
517
- return [newStart, newEnd];
518
- });
519
- setEventClicked(null);
520
- setEventHovered(null);
521
- }, [view]);
522
- const handleView = react.useCallback((newView) => {
523
- const newStart = getStartDate(start, newView);
524
- const newEnd = getEndDate(newStart, newView);
525
- setRange([newStart, newEnd]);
526
- setView(newView);
527
- setEventClicked(null);
528
- setEventHovered(null);
529
- }, [start]);
530
- react.useEffect(() => {
531
- const [start, end] = range;
532
- loadCalendars(calendars, start, end);
533
- setTodayInView(isTodayInView(start, end));
534
- }, [range]);
535
- react.useEffect(() => {
536
- if (events) {
537
- updateCalendarsBasedOnEvents(events);
538
- }
539
- }, [events, updateCalendarsBasedOnEvents]);
540
- react.useEffect(() => {
541
- if (eventClicked) {
542
- if (!calendarsMap[eventClicked.calendar.id].on) {
543
- setEventClicked(null);
544
- }
545
- }
546
- }, [calendarsMap, eventClicked, setEventClicked]);
547
- return {
548
- view,
549
- eventClicked,
550
- setEventClicked,
551
- eventHovered,
552
- setEventHovered,
553
- getDaygridNavProps: () => ({
554
- locale,
555
- handlePrev,
556
- handleNext,
557
- handleToday,
558
- handleView,
559
- todayInView,
560
- range,
561
- view,
562
- }),
563
- getDaygridTableProps: () => ({
564
- locale,
565
- events,
566
- eventClicked,
567
- setEventClicked,
568
- eventHovered,
569
- setEventHovered,
570
- handlePrev,
571
- handleNext,
572
- calendarsMap,
573
- range,
574
- view,
575
- }),
576
- getLegendProps: () => ({
577
- calendarsMap,
578
- toggleCalendarVisibility,
579
- }),
580
- };
581
- };
132
+ /** The locale to format with `date-fns` *//** Calendars infos to use *//** Fall back to `process.env.GOOGLE_CALENDAR_API_KEY *//** The key is the event `uid` *//** It defaults to the first of the current month *//** It defaults to the last day of the current month *//**
133
+ * The calendar view
134
+ * @default "month"
135
+ *//**
136
+ * The default is the time zone of the calendar
137
+ * @see https://developers.google.com/calendar/api/v3/reference/events/list
138
+ */let useCalendar=({locale:d,apiKey:c,calendars:p,events:g,start:m,end:y,view:v="month",timeZone:f="",onError:b})=>{let[w,T]=react.useState(v),D=m||getStartDate(new Date,w),h=y||getEndDate(D,w),[O,P]=react.useState([D,h]),[j,x]=react.useState(isTodayInView(D,h)),[C,L]=react.useState(g||{}),[N,k]=react.useState(null),[q,z]=react.useState(null),[A,B]=react.useReducer((e,t)=>{let{type:l}=t;switch(l){case"events":{let l=t.payload;return Object.entries(e).reduce((e,[t,n])=>(e[t]={...n,events:l[t]||0},e),{})}case"visibility":{let l=t.payload;if("string"==typeof l)return {...e,[l]:{...e[l],on:!e[l].on}};return Object.entries(e).reduce((e,[t,n])=>(e[t]={...n,on:l.indexOf(t)>-1},e),{})}default:return e}},// initial state
139
+ p.reduce((e,t)=>(e[t.id]={...t,name:t.name||"",on:!0,events:0},e),{})),E=react.useCallback(e=>{B({type:"visibility",payload:e});},[B]),F=react.useCallback(e=>{let t={};for(let l in e){let{id:n}=e[l].calendar;t[n]=t[n]||0,t[n]++;}B({type:"events",payload:t});},[]),G=react.useCallback(async(e,t,l)=>{try{let n=await getCalendarsEventsFromGoogle({apiKey:c,calendars:e,timeZone:f,start:t,end:l});// setEvents(mergeCalendarEvents(events, newEvents));
140
+ L(n);}catch(e){b&&b(e);}},[L,c,f,b]),H=react.useCallback(()=>{let[e,t]=O,l=getStartDate(new Date,w),n=getEndDate(l,w);P([l,n]),// reset event only if we are not on the current view already
141
+ (e.getTime()!==l.getTime()||t.getTime()!==n.getTime())&&(z(null),k(null));},[w,O]),I=react.useCallback(()=>{P(([e])=>{let t=getPrevDate(e,w),l=getEndDate(t,w);return [t,l]}),z(null),k(null);},[w]),J=react.useCallback(()=>{P(([e])=>{let t=getNextDate(e,w),l=getEndDate(t,w);return [t,l]}),z(null),k(null);},[w]),K=react.useCallback(e=>{let t=getStartDate(D,e),l=getEndDate(t,e);P([t,l]),T(e),z(null),k(null);},[D]);return react.useEffect(()=>{let[e,t]=O;G(p,e,t),x(isTodayInView(e,t));},// eslint-disable-next-line react-hooks/exhaustive-deps
142
+ [O]),react.useEffect(()=>{C&&F(C);},[C,F]),// when toggling a calendar we also remove the clicked event if that belongs
143
+ // to a now hidden calendar
144
+ react.useEffect(()=>{q&&!A[q.calendar.id].on&&z(null);},[A,q,z]),{view:w,eventClicked:q,setEventClicked:z,eventHovered:N,setEventHovered:k,getDaygridNavProps:()=>({locale:d,handlePrev:I,handleNext:J,handleToday:H,handleView:K,todayInView:j,range:O,view:w}),getDaygridTableProps:()=>({locale:d,events:C,eventClicked:q,setEventClicked:z,eventHovered:N,setEventHovered:k,handlePrev:I,handleNext:J,calendarsMap:A,range:O,view:w}),getLegendProps:()=>({calendarsMap:A,toggleCalendarVisibility:E})}};
582
145
 
583
146
  exports.CalendarDaygridCell = CalendarDaygridCell;
584
147
  exports.KoineCalendarDaygridNav = KoineCalendarDaygridNav;