@koine/react 2.0.0-beta.124 → 2.0.0-beta.126
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/calendar/CalendarDaygridCell.cjs.js +28 -0
- package/calendar/CalendarDaygridCell.esm.js +26 -0
- package/calendar/CalendarDaygridNav.cjs.js +9 -0
- package/calendar/CalendarDaygridNav.esm.js +7 -0
- package/calendar/CalendarDaygridTable.cjs.js +16 -0
- package/calendar/CalendarDaygridTable.esm.js +14 -0
- package/calendar/CalendarLegend.cjs.js +14 -0
- package/calendar/CalendarLegend.esm.js +12 -0
- package/calendar/calendar-api-google.cjs.js +24 -0
- package/calendar/calendar-api-google.esm.js +22 -0
- package/calendar/useCalendar.cjs.js +21 -0
- package/calendar/useCalendar.esm.js +19 -0
- package/calendar/useDateLocale.cjs.js +24 -0
- package/calendar/useDateLocale.esm.js +22 -0
- package/calendar/utils.cjs.js +40 -0
- package/calendar/utils.esm.js +30 -0
- package/calendar.cjs.js +12 -126
- package/calendar.esm.js +6 -124
- package/classed.d.ts +1 -1
- package/extendComponent.d.ts +1 -1
- package/forms/antispam.cjs.js +35 -0
- package/forms/antispam.d.ts +4 -4
- package/forms/antispam.esm.js +32 -0
- package/forms.cjs.js +4 -31
- package/forms.esm.js +1 -32
- package/index.cjs.js +0 -4
- package/index.esm.js +0 -4
- package/package.json +36 -3
- package/useScrollPosition.d.ts +1 -1
- package/useSmoothScroll.cjs.js +0 -1
- package/useSmoothScroll.esm.js +0 -1
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
var react = require('react');
|
|
5
|
+
var utils = require('./utils.cjs.js');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* TODO: include in this lib utilities like in https://github.com/react-icons/react-icons/blob/master/packages/react-icons/src/iconBase.tsx
|
|
9
|
+
*
|
|
10
|
+
* this is the `MdAdd` icon from `react-icons`
|
|
11
|
+
*/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"})]}),/**
|
|
12
|
+
* Style for button within a event cell
|
|
13
|
+
*
|
|
14
|
+
* Here we might differentiate week/month view where the first does not get
|
|
15
|
+
* ellipsed btn texts, with `Start` as block element and underneath the `Title`
|
|
16
|
+
* on multiple lines, but that would mean that we loose the ability to interweave
|
|
17
|
+
* single-day events among the spaces left by wider multi-days events.
|
|
18
|
+
*/o={overflow:"hidden",whiteSpace:"nowrap",textOverflow:"ellipsis"};let CalendarDaygridCell=({eventClicked:a,setEventClicked:s,// eventHovered,
|
|
19
|
+
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
|
|
20
|
+
position:"relative",width:t.firstOfMulti?`${100*t.width}%`:"100%"};v[t.calendar.id].on||// @ts-expect-error nevermind
|
|
21
|
+
(o.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,...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:utils.getDisplayTime(t.start)}),/*#__PURE__*/jsxRuntime.jsx(w,{children:t.title})]})})})},t.key)})})};/* {i === events.length - 1 && isExpanded ? (
|
|
22
|
+
<CellOverflow onClick={() => expand(false)}>
|
|
23
|
+
<IconCollapse />
|
|
24
|
+
Show less
|
|
25
|
+
</CellOverflow>
|
|
26
|
+
) : null} */
|
|
27
|
+
|
|
28
|
+
exports.CalendarDaygridCell = CalendarDaygridCell;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { jsx, jsxs, Fragment as Fragment$1 } from 'react/jsx-runtime';
|
|
2
|
+
import { useState, Fragment } from 'react';
|
|
3
|
+
import { getDisplayTime } from './utils.esm.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* TODO: include in this lib utilities like in https://github.com/react-icons/react-icons/blob/master/packages/react-icons/src/iconBase.tsx
|
|
7
|
+
*
|
|
8
|
+
* this is the `MdAdd` icon from `react-icons`
|
|
9
|
+
*/let d=l=>/*#__PURE__*/jsxs("svg",{viewBox:"0 0 24 24",fill:"currentColor",stroke:"none",...l,children:[/*#__PURE__*/jsx("path",{d:"M0 0h24v24H0z"}),/*#__PURE__*/jsx("path",{d:"M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"})]}),/**
|
|
10
|
+
* Style for button within a event cell
|
|
11
|
+
*
|
|
12
|
+
* Here we might differentiate week/month view where the first does not get
|
|
13
|
+
* ellipsed btn texts, with `Start` as block element and underneath the `Title`
|
|
14
|
+
* on multiple lines, but that would mean that we loose the ability to interweave
|
|
15
|
+
* single-day events among the spaces left by wider multi-days events.
|
|
16
|
+
*/o={overflow:"hidden",whiteSpace:"nowrap",textOverflow:"ellipsis"};let CalendarDaygridCell=({eventClicked:a,setEventClicked:s,// eventHovered,
|
|
17
|
+
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]=useState(!1),O=p.filter(e=>!e.placeholder);return /*#__PURE__*/jsx(f,{children:p.map((t,p)=>{if(p===u&&!x)return /*#__PURE__*/jsxs(y,{onClick:()=>M(!0),children:[/*#__PURE__*/jsx(d,{}),O.length-u]},"overflowMessage"+p);if(p>u&&!x)return null;if(t.placeholder)return /*#__PURE__*/jsx(Fragment,{children:/*#__PURE__*/jsx($,{$placeholder:!0,children:/*#__PURE__*/jsx(m,{"aria-hidden":"true",style:{visibility:"hidden"},$placeholder:!0,children:/*#__PURE__*/jsx(w,{children:" "})})})},t.key);let f={zIndex:t.firstOfMulti?1:0,// to cover the following event days
|
|
18
|
+
position:"relative",width:t.firstOfMulti?`${100*t.width}%`:"100%"};v[t.calendar.id].on||// @ts-expect-error nevermind
|
|
19
|
+
(o.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__*/jsx(Fragment,{children:/*#__PURE__*/jsx($,{style:f,...k,children:/*#__PURE__*/jsx(m,{role:"button",style:o,...k,onClick:()=>s(e=>e?.uid===t.uid?null:t),onMouseEnter:()=>h(t),onMouseLeave:()=>h(null),children:t.allDay?/*#__PURE__*/jsx(w,{children:t.title}):/*#__PURE__*/jsxs(Fragment$1,{children:[/*#__PURE__*/jsx(g,{children:getDisplayTime(t.start)}),/*#__PURE__*/jsx(w,{children:t.title})]})})})},t.key)})})};/* {i === events.length - 1 && isExpanded ? (
|
|
20
|
+
<CellOverflow onClick={() => expand(false)}>
|
|
21
|
+
<IconCollapse />
|
|
22
|
+
Show less
|
|
23
|
+
</CellOverflow>
|
|
24
|
+
) : null} */
|
|
25
|
+
|
|
26
|
+
export { CalendarDaygridCell };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
var format = require('date-fns/format');
|
|
5
|
+
var useDateLocale = require('./useDateLocale.cjs.js');
|
|
6
|
+
|
|
7
|
+
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.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})]})};
|
|
8
|
+
|
|
9
|
+
exports.KoineCalendarDaygridNav = KoineCalendarDaygridNav;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { format } from 'date-fns/format';
|
|
3
|
+
import { useDateLocale } from './useDateLocale.esm.js';
|
|
4
|
+
|
|
5
|
+
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(C,"MMMM yyyy",v)),"week"===l&&(x=C.getMonth()===p.getMonth()?format(C,"# MMMM yyyy",v).replace("#",`${C.getDate()}-${p.getDate()}`):`${format(C,"d MMMM",v)} - ${format(p,"d MMMM yyyy",v)}`),/*#__PURE__*/jsxs(m,{children:[/*#__PURE__*/jsxs(b,{children:[/*#__PURE__*/jsx(k,{onClick:i}),/*#__PURE__*/jsx(u,{onClick:M}),/*#__PURE__*/jsx(h,{onClick:d,disabled:r}),/*#__PURE__*/jsx(f,{onClick:()=>y("month"),disabled:"month"===l}),/*#__PURE__*/jsx(g,{onClick:()=>y("week"),disabled:"week"===l})]}),/*#__PURE__*/jsx(s,{range:a,formatted:x})]})};
|
|
6
|
+
|
|
7
|
+
export { KoineCalendarDaygridNav };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
var eachWeekOfInterval = require('date-fns/eachWeekOfInterval');
|
|
5
|
+
var react = require('react');
|
|
6
|
+
var reactSwipeable = require('react-swipeable');
|
|
7
|
+
var CalendarDaygridCell = require('./CalendarDaygridCell.cjs.js');
|
|
8
|
+
var useDateLocale = require('./useDateLocale.cjs.js');
|
|
9
|
+
var utils = require('./utils.cjs.js');
|
|
10
|
+
|
|
11
|
+
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
|
|
12
|
+
{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()]);
|
|
13
|
+
G=useDateLocale.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(utils.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
|
|
14
|
+
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.CalendarDaygridCell,{eventClicked:v,setEventClicked:g,eventHovered:w,setEventHovered:y,view:b,maxEvents:j,events:r.events,timestamp:r.timestamp,calendarsMap:x,...q})]}))}))})]})};
|
|
15
|
+
|
|
16
|
+
exports.KoineCalendarDaygridTable = KoineCalendarDaygridTable;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { eachWeekOfInterval } from 'date-fns/eachWeekOfInterval';
|
|
3
|
+
import { useState, useMemo, useEffect } from 'react';
|
|
4
|
+
import { useSwipeable } from 'react-swipeable';
|
|
5
|
+
import { CalendarDaygridCell } from './CalendarDaygridCell.esm.js';
|
|
6
|
+
import { useDateLocale } from './useDateLocale.esm.js';
|
|
7
|
+
import { processEventsInView } from './utils.esm.js';
|
|
8
|
+
|
|
9
|
+
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
|
|
10
|
+
{let q={Cell:I,CellOverflow:K,CellEvent:M,CellEventBtn:R,CellEventTitle:T,CellEventStart:W},[A,B]=useState(f||[0,1,2,3,4,5,6]),[E,F]=useState([]),// const [days, setDays] = useState(dayLabels || [...Array(7).keys()]);
|
|
11
|
+
G=useDateLocale(d),{month:H,weeks:J}=useMemo(()=>(function(e){let[t,a]=e,i=eachWeekOfInterval({start:t,end:a},{weekStartsOn:1});return {month:t.getMonth(),weeks:i}})(u),[u]),N=useSwipeable({onSwipedLeft:c,onSwipedRight:s});return useEffect(()=>{F(processEventsInView(h,b,H,J));},[h,b,H,J]),useEffect(()=>{G&&G.localize&&!f&&B([1,2,3,4,5,6,0].map(// @ts-expect-error nevermind
|
|
12
|
+
e=>G.localize.day(e,{width:"abbreviated"})));},[G,f]),/*#__PURE__*/jsxs(C,{...N,children:[/*#__PURE__*/jsx(D,{children:/*#__PURE__*/jsx("tr",{children:A.map(t=>/*#__PURE__*/jsx(S,{scope:"column",children:t},t))})}),/*#__PURE__*/jsx(k,{children:E.map((r,a)=>/*#__PURE__*/jsx(z,{...r.props,children:r.days.map(r=>/*#__PURE__*/jsxs(L,{...r.props,children:[/*#__PURE__*/jsx(O,{...r.props,children:r.label}),r.events.length>0&&/*#__PURE__*/jsx(CalendarDaygridCell,{eventClicked:v,setEventClicked:g,eventHovered:w,setEventHovered:y,view:b,maxEvents:j,events:r.events,timestamp:r.timestamp,calendarsMap:x,...q})]}))}))})]})};
|
|
13
|
+
|
|
14
|
+
export { KoineCalendarDaygridTable };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
|
|
5
|
+
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) => {
|
|
6
|
+
// const { name: nameA } = a[1];
|
|
7
|
+
// const { name: nameB } = b[1];
|
|
8
|
+
// if (nameA < nameB) return -1;
|
|
9
|
+
// else if (nameA > nameB) return 1;
|
|
10
|
+
// else return 0;
|
|
11
|
+
// });
|
|
12
|
+
/*#__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))});
|
|
13
|
+
|
|
14
|
+
exports.KoineCalendarLegend = KoineCalendarLegend;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
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) => {
|
|
4
|
+
// const { name: nameA } = a[1];
|
|
5
|
+
// const { name: nameB } = b[1];
|
|
6
|
+
// if (nameA < nameB) return -1;
|
|
7
|
+
// else if (nameA > nameB) return 1;
|
|
8
|
+
// else return 0;
|
|
9
|
+
// });
|
|
10
|
+
/*#__PURE__*/jsx(Fragment,{children:Object.entries(a).map(([r,a])=>/*#__PURE__*/jsxs(d,{onClick:()=>s(r),$color:a.color,$empty:0===a.events,disabled:0===a.events,children:[/*#__PURE__*/jsx(i,{children:a.on?"⬤":"⭘"}),/*#__PURE__*/jsx(l,{children:a.name}),/*#__PURE__*/jsx(t,{children:a.events})]},"CalendarLegend."+r))});
|
|
11
|
+
|
|
12
|
+
export { KoineCalendarLegend };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var differenceInDays = require('date-fns/differenceInDays');
|
|
4
|
+
var subDays = require('date-fns/subDays');
|
|
5
|
+
var utils$1 = require('@koine/utils');
|
|
6
|
+
var utils = require('./utils.cjs.js');
|
|
7
|
+
|
|
8
|
+
/** Fall back to `process.env.GOOGLE_CALENDAR_API_KEY *//** Start gethering events from date *//** End gethering events at date *//**
|
|
9
|
+
* The default is the time zone of the calendar
|
|
10
|
+
* @see https://developers.google.com/calendar/api/v3/reference/events/list
|
|
11
|
+
*//** The calendars settings */let getCalendarsEventsFromGoogle=async({calendars:e,...t})=>{let a={};return await Promise.all(e.map(async e=>{utils.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=/**
|
|
12
|
+
* Google event as it comes from Google's API
|
|
13
|
+
*//**
|
|
14
|
+
* Google calendar as it comes from Google's API
|
|
15
|
+
*//**
|
|
16
|
+
* Google event's date as it comes from Google's API
|
|
17
|
+
*//** 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$1.isUndefined(i.end.dateTime)&&utils$1.isString(i.end.date),p=i.location||"",D=i.description||"",// FIXME: he.decode(event.description || '');
|
|
18
|
+
h=m.getTime()+""+u.getTime();// multi-days all day events has as end date the date after to what we actually
|
|
19
|
+
// 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
|
|
20
|
+
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=[utils.getEventTimestamp(t)];for(;differenceInDays.differenceInDays(a,t);)// console.log(title, differenceInDays(to, from))
|
|
21
|
+
t.setDate(t.getDate()+1),n.push(utils.getEventTimestamp(t));return n}(),E=utils$1.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);
|
|
22
|
+
return c}
|
|
23
|
+
|
|
24
|
+
exports.getCalendarsEventsFromGoogle = getCalendarsEventsFromGoogle;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { differenceInDays } from 'date-fns/differenceInDays';
|
|
2
|
+
import { subDays } from 'date-fns/subDays';
|
|
3
|
+
import { isUndefined, isString, arrayToLookup } from '@koine/utils';
|
|
4
|
+
import { addCalendarEvents, getEventTimestamp } from './utils.esm.js';
|
|
5
|
+
|
|
6
|
+
/** Fall back to `process.env.GOOGLE_CALENDAR_API_KEY *//** Start gethering events from date *//** End gethering events at date *//**
|
|
7
|
+
* The default is the time zone of the calendar
|
|
8
|
+
* @see https://developers.google.com/calendar/api/v3/reference/events/list
|
|
9
|
+
*//** 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=/**
|
|
10
|
+
* Google event as it comes from Google's API
|
|
11
|
+
*//**
|
|
12
|
+
* Google calendar as it comes from Google's API
|
|
13
|
+
*//**
|
|
14
|
+
* Google event's date as it comes from Google's API
|
|
15
|
+
*//** 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=isUndefined(i.end.dateTime)&&isString(i.end.date),p=i.location||"",D=i.description||"",// FIXME: he.decode(event.description || '');
|
|
16
|
+
h=m.getTime()+""+u.getTime();// multi-days all day events has as end date the date after to what we actually
|
|
17
|
+
// 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
|
|
18
|
+
g&&f>u&&(f=subDays(f,1)).setHours(23,59,59);let y=function(){let t=new Date(u),a=new Date(f),n=[getEventTimestamp(t)];for(;differenceInDays(a,t);)// console.log(title, differenceInDays(to, from))
|
|
19
|
+
t.setDate(t.getDate()+1),n.push(getEventTimestamp(t));return n}(),E=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);
|
|
20
|
+
return c}
|
|
21
|
+
|
|
22
|
+
export { getCalendarsEventsFromGoogle };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var react = require('react');
|
|
4
|
+
var calendarApiGoogle = require('./calendar-api-google.cjs.js');
|
|
5
|
+
var utils = require('./utils.cjs.js');
|
|
6
|
+
|
|
7
|
+
/** 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 *//**
|
|
8
|
+
* The calendar view
|
|
9
|
+
* @default "month"
|
|
10
|
+
*//**
|
|
11
|
+
* The default is the time zone of the calendar
|
|
12
|
+
* @see https://developers.google.com/calendar/api/v3/reference/events/list
|
|
13
|
+
*/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||utils.getStartDate(new Date,w),h=y||utils.getEndDate(D,w),[O,P]=react.useState([D,h]),[j,x]=react.useState(utils.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
|
|
14
|
+
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 calendarApiGoogle.getCalendarsEventsFromGoogle({apiKey:c,calendars:e,timeZone:f,start:t,end:l});// setEvents(mergeCalendarEvents(events, newEvents));
|
|
15
|
+
L(n);}catch(e){b&&b(e);}},[L,c,f,b]),H=react.useCallback(()=>{let[e,t]=O,l=utils.getStartDate(new Date,w),n=utils.getEndDate(l,w);P([l,n]),// reset event only if we are not on the current view already
|
|
16
|
+
(e.getTime()!==l.getTime()||t.getTime()!==n.getTime())&&(z(null),k(null));},[w,O]),I=react.useCallback(()=>{P(([e])=>{let t=utils.getPrevDate(e,w),l=utils.getEndDate(t,w);return [t,l]}),z(null),k(null);},[w]),J=react.useCallback(()=>{P(([e])=>{let t=utils.getNextDate(e,w),l=utils.getEndDate(t,w);return [t,l]}),z(null),k(null);},[w]),K=react.useCallback(e=>{let t=utils.getStartDate(D,e),l=utils.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(utils.isTodayInView(e,t));},// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
17
|
+
[O]),react.useEffect(()=>{C&&F(C);},[C,F]),// when toggling a calendar we also remove the clicked event if that belongs
|
|
18
|
+
// to a now hidden calendar
|
|
19
|
+
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})}};
|
|
20
|
+
|
|
21
|
+
exports.useCalendar = useCalendar;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { useState, useReducer, useCallback, useEffect } from 'react';
|
|
2
|
+
import { getCalendarsEventsFromGoogle } from './calendar-api-google.esm.js';
|
|
3
|
+
import { getStartDate, getEndDate, isTodayInView, getPrevDate, getNextDate } from './utils.esm.js';
|
|
4
|
+
|
|
5
|
+
/** 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 *//**
|
|
6
|
+
* The calendar view
|
|
7
|
+
* @default "month"
|
|
8
|
+
*//**
|
|
9
|
+
* The default is the time zone of the calendar
|
|
10
|
+
* @see https://developers.google.com/calendar/api/v3/reference/events/list
|
|
11
|
+
*/let useCalendar=({locale:d,apiKey:c,calendars:p,events:g,start:m,end:y,view:v="month",timeZone:f="",onError:b})=>{let[w,T]=useState(v),D=m||getStartDate(new Date,w),h=y||getEndDate(D,w),[O,P]=useState([D,h]),[j,x]=useState(isTodayInView(D,h)),[C,L]=useState(g||{}),[N,k]=useState(null),[q,z]=useState(null),[A,B]=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
|
|
12
|
+
p.reduce((e,t)=>(e[t.id]={...t,name:t.name||"",on:!0,events:0},e),{})),E=useCallback(e=>{B({type:"visibility",payload:e});},[B]),F=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=useCallback(async(e,t,l)=>{try{let n=await getCalendarsEventsFromGoogle({apiKey:c,calendars:e,timeZone:f,start:t,end:l});// setEvents(mergeCalendarEvents(events, newEvents));
|
|
13
|
+
L(n);}catch(e){b&&b(e);}},[L,c,f,b]),H=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
|
|
14
|
+
(e.getTime()!==l.getTime()||t.getTime()!==n.getTime())&&(z(null),k(null));},[w,O]),I=useCallback(()=>{P(([e])=>{let t=getPrevDate(e,w),l=getEndDate(t,w);return [t,l]}),z(null),k(null);},[w]),J=useCallback(()=>{P(([e])=>{let t=getNextDate(e,w),l=getEndDate(t,w);return [t,l]}),z(null),k(null);},[w]),K=useCallback(e=>{let t=getStartDate(D,e),l=getEndDate(t,e);P([t,l]),T(e),z(null),k(null);},[D]);return useEffect(()=>{let[e,t]=O;G(p,e,t),x(isTodayInView(e,t));},// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
15
|
+
[O]),useEffect(()=>{C&&F(C);},[C,F]),// when toggling a calendar we also remove the clicked event if that belongs
|
|
16
|
+
// to a now hidden calendar
|
|
17
|
+
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})}};
|
|
18
|
+
|
|
19
|
+
export { useCalendar };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var react = require('react');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Dynamically import the date-fns correct locale
|
|
7
|
+
*
|
|
8
|
+
* Inspired by:
|
|
9
|
+
* @see https://robertmarshall.dev/blog/dynamically-import-datefns-locale-mui-datepicker-localization/
|
|
10
|
+
*/let useDateLocale=(a,l="en")=>{let[r,n]=react.useState(),[o,c]=react.useState(l);return(// const [ready, setReady] = useState(false);
|
|
11
|
+
// If the user changes the locale listen to the change and import the locale that is now required.
|
|
12
|
+
react.useEffect(()=>{let e=async()=>{// This webpack option stops all of the date-fns files being imported and chunked.
|
|
13
|
+
// NB: this makes unnecessary numerous webpack chunks in applications
|
|
14
|
+
// that do not even use this hook, so we comment out the webpack dynamic
|
|
15
|
+
// import and its magic comment
|
|
16
|
+
// const localeToSet = await import(
|
|
17
|
+
// /FIXME: * webpackMode: "lazy", webpackChunkName: "df-[index]", webpackExclude: /_lib/ */
|
|
18
|
+
// `date-fns/locale/${locale}/index.js`,
|
|
19
|
+
// );
|
|
20
|
+
let e=await import('date-fns/locale/en-US');c(a||o),n(e.enUS);};// setReady(true);
|
|
21
|
+
// If the locale has not yet been loaded.
|
|
22
|
+
a!==o&&e();},[a,o]),r)};
|
|
23
|
+
|
|
24
|
+
exports.useDateLocale = useDateLocale;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { useState, useEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Dynamically import the date-fns correct locale
|
|
5
|
+
*
|
|
6
|
+
* Inspired by:
|
|
7
|
+
* @see https://robertmarshall.dev/blog/dynamically-import-datefns-locale-mui-datepicker-localization/
|
|
8
|
+
*/let useDateLocale=(a,l="en")=>{let[r,n]=useState(),[o,c]=useState(l);return(// const [ready, setReady] = useState(false);
|
|
9
|
+
// If the user changes the locale listen to the change and import the locale that is now required.
|
|
10
|
+
useEffect(()=>{let e=async()=>{// This webpack option stops all of the date-fns files being imported and chunked.
|
|
11
|
+
// NB: this makes unnecessary numerous webpack chunks in applications
|
|
12
|
+
// that do not even use this hook, so we comment out the webpack dynamic
|
|
13
|
+
// import and its magic comment
|
|
14
|
+
// const localeToSet = await import(
|
|
15
|
+
// /FIXME: * webpackMode: "lazy", webpackChunkName: "df-[index]", webpackExclude: /_lib/ */
|
|
16
|
+
// `date-fns/locale/${locale}/index.js`,
|
|
17
|
+
// );
|
|
18
|
+
let e=await import('date-fns/locale/en-US');c(a||o),n(e.enUS);};// setReady(true);
|
|
19
|
+
// If the locale has not yet been loaded.
|
|
20
|
+
a!==o&&e();},[a,o]),r)};
|
|
21
|
+
|
|
22
|
+
export { useDateLocale };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var addDays = require('date-fns/addDays');
|
|
4
|
+
var addMonths = require('date-fns/addMonths');
|
|
5
|
+
var addWeeks = require('date-fns/addWeeks');
|
|
6
|
+
var endOfMonth = require('date-fns/endOfMonth');
|
|
7
|
+
var endOfWeek = require('date-fns/endOfWeek');
|
|
8
|
+
var isWithinInterval = require('date-fns/isWithinInterval');
|
|
9
|
+
var startOfWeek = require('date-fns/startOfWeek');
|
|
10
|
+
var subMonths = require('date-fns/subMonths');
|
|
11
|
+
var subWeeks = require('date-fns/subWeeks');
|
|
12
|
+
|
|
13
|
+
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=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
|
|
14
|
+
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(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
|
|
15
|
+
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
|
|
16
|
+
// vertically positioned use that index
|
|
17
|
+
if(// only for multi days events:
|
|
18
|
+
s.multi&&(// filter out the days outside of the current week view to avoid
|
|
19
|
+
// making a multi-days event chip wider than the week row or shorter
|
|
20
|
+
// than it should be (when event spans across weeks)
|
|
21
|
+
m=s.days.filter(e=>e>=g&&e<=h).length,// flag the first day of multi-days events, consider that an event
|
|
22
|
+
// might start in a day earlier (hence outside) of the current
|
|
23
|
+
// week/month view, so we always check for Mondays (dayNumber === 0)
|
|
24
|
+
(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`
|
|
25
|
+
for(let e=0;e<t.length;e++)if(1!==t[e]){i=e;break}// now mark the slot as busy
|
|
26
|
+
t[i]=1,// store the slot vertical position consistently for multi-days events
|
|
27
|
+
a&&(p[s.uid]=i),// push the event, they will be sorted later
|
|
28
|
+
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
|
|
29
|
+
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
|
|
30
|
+
v.events.sort((e,t)=>e.top-t.top);}i.days.push(v);}f.push(i);}return f};
|
|
31
|
+
|
|
32
|
+
exports.addCalendarEvents = addCalendarEvents;
|
|
33
|
+
exports.getDisplayTime = getDisplayTime;
|
|
34
|
+
exports.getEndDate = getEndDate;
|
|
35
|
+
exports.getEventTimestamp = getEventTimestamp;
|
|
36
|
+
exports.getNextDate = getNextDate;
|
|
37
|
+
exports.getPrevDate = getPrevDate;
|
|
38
|
+
exports.getStartDate = getStartDate;
|
|
39
|
+
exports.isTodayInView = isTodayInView;
|
|
40
|
+
exports.processEventsInView = processEventsInView;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { addDays } from 'date-fns/addDays';
|
|
2
|
+
import { addMonths } from 'date-fns/addMonths';
|
|
3
|
+
import { addWeeks } from 'date-fns/addWeeks';
|
|
4
|
+
import { endOfMonth } from 'date-fns/endOfMonth';
|
|
5
|
+
import { endOfWeek } from 'date-fns/endOfWeek';
|
|
6
|
+
import { isWithinInterval } from 'date-fns/isWithinInterval';
|
|
7
|
+
import { startOfWeek } from 'date-fns/startOfWeek';
|
|
8
|
+
import { subMonths } from 'date-fns/subMonths';
|
|
9
|
+
import { subWeeks } from 'date-fns/subWeeks';
|
|
10
|
+
|
|
11
|
+
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(e,{weekStartsOn:1})),e);let getEndDate=(e,t)=>{let r=e;return "month"===t?r=endOfMonth(e):"week"===t&&(r=endOfWeek(e,{weekStartsOn:1})),r.setHours(23,59,59),r};let getPrevDate=(e,t)=>"month"===t?subMonths(e,1):subWeeks(e,1);let getNextDate=(e,a)=>"month"===a?addMonths(e,1):addWeeks(e,1);let isTodayInView=(e,t)=>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=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
|
|
12
|
+
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(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(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
|
|
13
|
+
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
|
|
14
|
+
// vertically positioned use that index
|
|
15
|
+
if(// only for multi days events:
|
|
16
|
+
s.multi&&(// filter out the days outside of the current week view to avoid
|
|
17
|
+
// making a multi-days event chip wider than the week row or shorter
|
|
18
|
+
// than it should be (when event spans across weeks)
|
|
19
|
+
m=s.days.filter(e=>e>=g&&e<=h).length,// flag the first day of multi-days events, consider that an event
|
|
20
|
+
// might start in a day earlier (hence outside) of the current
|
|
21
|
+
// week/month view, so we always check for Mondays (dayNumber === 0)
|
|
22
|
+
(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`
|
|
23
|
+
for(let e=0;e<t.length;e++)if(1!==t[e]){i=e;break}// now mark the slot as busy
|
|
24
|
+
t[i]=1,// store the slot vertical position consistently for multi-days events
|
|
25
|
+
a&&(p[s.uid]=i),// push the event, they will be sorted later
|
|
26
|
+
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
|
|
27
|
+
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
|
|
28
|
+
v.events.sort((e,t)=>e.top-t.top);}i.days.push(v);}f.push(i);}return f};
|
|
29
|
+
|
|
30
|
+
export { addCalendarEvents, getDisplayTime, getEndDate, getEventTimestamp, getNextDate, getPrevDate, getStartDate, isTodayInView, processEventsInView };
|
package/calendar.cjs.js
CHANGED
|
@@ -1,131 +1,17 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var
|
|
5
|
-
var
|
|
6
|
-
var
|
|
7
|
-
var
|
|
8
|
-
var
|
|
9
|
-
var endOfWeek = require('date-fns/endOfWeek');
|
|
10
|
-
var isWithinInterval = require('date-fns/isWithinInterval');
|
|
11
|
-
var startOfWeek = require('date-fns/startOfWeek');
|
|
12
|
-
var subMonths = require('date-fns/subMonths');
|
|
13
|
-
var subWeeks = require('date-fns/subWeeks');
|
|
14
|
-
var format = require('date-fns/format');
|
|
15
|
-
var eachWeekOfInterval = require('date-fns/eachWeekOfInterval');
|
|
16
|
-
var reactSwipeable = require('react-swipeable');
|
|
17
|
-
var differenceInDays = require('date-fns/differenceInDays');
|
|
18
|
-
var subDays = require('date-fns/subDays');
|
|
19
|
-
var utils = require('@koine/utils');
|
|
3
|
+
var CalendarDaygridCell = require('./calendar/CalendarDaygridCell.cjs.js');
|
|
4
|
+
var CalendarDaygridNav = require('./calendar/CalendarDaygridNav.cjs.js');
|
|
5
|
+
var CalendarDaygridTable = require('./calendar/CalendarDaygridTable.cjs.js');
|
|
6
|
+
var CalendarLegend = require('./calendar/CalendarLegend.cjs.js');
|
|
7
|
+
var useCalendar = require('./calendar/useCalendar.cjs.js');
|
|
8
|
+
var useDateLocale = require('./calendar/useDateLocale.cjs.js');
|
|
20
9
|
|
|
21
|
-
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
|
|
22
|
-
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
|
|
23
|
-
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
|
|
24
|
-
// vertically positioned use that index
|
|
25
|
-
if(// only for multi days events:
|
|
26
|
-
s.multi&&(// filter out the days outside of the current week view to avoid
|
|
27
|
-
// making a multi-days event chip wider than the week row or shorter
|
|
28
|
-
// than it should be (when event spans across weeks)
|
|
29
|
-
m=s.days.filter(e=>e>=g&&e<=h).length,// flag the first day of multi-days events, consider that an event
|
|
30
|
-
// might start in a day earlier (hence outside) of the current
|
|
31
|
-
// week/month view, so we always check for Mondays (dayNumber === 0)
|
|
32
|
-
(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`
|
|
33
|
-
for(let e=0;e<t.length;e++)if(1!==t[e]){i=e;break}// now mark the slot as busy
|
|
34
|
-
t[i]=1,// store the slot vertical position consistently for multi-days events
|
|
35
|
-
a&&(p[s.uid]=i),// push the event, they will be sorted later
|
|
36
|
-
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
|
|
37
|
-
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
|
|
38
|
-
v.events.sort((e,t)=>e.top-t.top);}i.days.push(v);}f.push(i);}return f};
|
|
39
10
|
|
|
40
|
-
/**
|
|
41
|
-
* TODO: include in this lib utilities like in https://github.com/react-icons/react-icons/blob/master/packages/react-icons/src/iconBase.tsx
|
|
42
|
-
*
|
|
43
|
-
* this is the `MdAdd` icon from `react-icons`
|
|
44
|
-
*/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"})]}),/**
|
|
45
|
-
* Style for button within a event cell
|
|
46
|
-
*
|
|
47
|
-
* Here we might differentiate week/month view where the first does not get
|
|
48
|
-
* ellipsed btn texts, with `Start` as block element and underneath the `Title`
|
|
49
|
-
* on multiple lines, but that would mean that we loose the ability to interweave
|
|
50
|
-
* single-day events among the spaces left by wider multi-days events.
|
|
51
|
-
*/o$1={overflow:"hidden",whiteSpace:"nowrap",textOverflow:"ellipsis"};let CalendarDaygridCell=({eventClicked:a,setEventClicked:s,// eventHovered,
|
|
52
|
-
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
|
|
53
|
-
position:"relative",width:t.firstOfMulti?`${100*t.width}%`:"100%"};v[t.calendar.id].on||// @ts-expect-error nevermind
|
|
54
|
-
(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 ? (
|
|
55
|
-
<CellOverflow onClick={() => expand(false)}>
|
|
56
|
-
<IconCollapse />
|
|
57
|
-
Show less
|
|
58
|
-
</CellOverflow>
|
|
59
|
-
) : null} */
|
|
60
11
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
// If the user changes the locale listen to the change and import the locale that is now required.
|
|
68
|
-
react.useEffect(()=>{let e=async()=>{// This webpack option stops all of the date-fns files being imported and chunked.
|
|
69
|
-
// NB: this makes unnecessary numerous webpack chunks in applications
|
|
70
|
-
// that do not even use this hook, so we comment out the webpack dynamic
|
|
71
|
-
// import and its magic comment
|
|
72
|
-
// const localeToSet = await import(
|
|
73
|
-
// /FIXME: * webpackMode: "lazy", webpackChunkName: "df-[index]", webpackExclude: /_lib/ */
|
|
74
|
-
// `date-fns/locale/${locale}/index.js`,
|
|
75
|
-
// );
|
|
76
|
-
let e=await import('date-fns/locale/en-US');c(a||o),n(e.enUS);};// setReady(true);
|
|
77
|
-
// If the locale has not yet been loaded.
|
|
78
|
-
a!==o&&e();},[a,o]),r)};
|
|
79
|
-
|
|
80
|
-
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})]})};
|
|
81
|
-
|
|
82
|
-
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
|
|
83
|
-
{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()]);
|
|
84
|
-
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
|
|
85
|
-
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})]}))}))})]})};
|
|
86
|
-
|
|
87
|
-
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) => {
|
|
88
|
-
// const { name: nameA } = a[1];
|
|
89
|
-
// const { name: nameB } = b[1];
|
|
90
|
-
// if (nameA < nameB) return -1;
|
|
91
|
-
// else if (nameA > nameB) return 1;
|
|
92
|
-
// else return 0;
|
|
93
|
-
// });
|
|
94
|
-
/*#__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))});
|
|
95
|
-
|
|
96
|
-
/** Fall back to `process.env.GOOGLE_CALENDAR_API_KEY *//** Start gethering events from date *//** End gethering events at date *//**
|
|
97
|
-
* The default is the time zone of the calendar
|
|
98
|
-
* @see https://developers.google.com/calendar/api/v3/reference/events/list
|
|
99
|
-
*//** 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=/**
|
|
100
|
-
* Google event as it comes from Google's API
|
|
101
|
-
*//**
|
|
102
|
-
* Google calendar as it comes from Google's API
|
|
103
|
-
*//**
|
|
104
|
-
* Google event's date as it comes from Google's API
|
|
105
|
-
*//** 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 || '');
|
|
106
|
-
h=m.getTime()+""+u.getTime();// multi-days all day events has as end date the date after to what we actually
|
|
107
|
-
// 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
|
|
108
|
-
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))
|
|
109
|
-
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);
|
|
110
|
-
return c}
|
|
111
|
-
|
|
112
|
-
/** 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 *//**
|
|
113
|
-
* The calendar view
|
|
114
|
-
* @default "month"
|
|
115
|
-
*//**
|
|
116
|
-
* The default is the time zone of the calendar
|
|
117
|
-
* @see https://developers.google.com/calendar/api/v3/reference/events/list
|
|
118
|
-
*/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
|
|
119
|
-
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));
|
|
120
|
-
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
|
|
121
|
-
(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
|
|
122
|
-
[O]),react.useEffect(()=>{C&&F(C);},[C,F]),// when toggling a calendar we also remove the clicked event if that belongs
|
|
123
|
-
// to a now hidden calendar
|
|
124
|
-
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})}};
|
|
125
|
-
|
|
126
|
-
exports.CalendarDaygridCell = CalendarDaygridCell;
|
|
127
|
-
exports.KoineCalendarDaygridNav = KoineCalendarDaygridNav;
|
|
128
|
-
exports.KoineCalendarDaygridTable = KoineCalendarDaygridTable;
|
|
129
|
-
exports.KoineCalendarLegend = KoineCalendarLegend;
|
|
130
|
-
exports.useCalendar = useCalendar;
|
|
131
|
-
exports.useDateLocale = useDateLocale;
|
|
12
|
+
exports.CalendarDaygridCell = CalendarDaygridCell.CalendarDaygridCell;
|
|
13
|
+
exports.KoineCalendarDaygridNav = CalendarDaygridNav.KoineCalendarDaygridNav;
|
|
14
|
+
exports.KoineCalendarDaygridTable = CalendarDaygridTable.KoineCalendarDaygridTable;
|
|
15
|
+
exports.KoineCalendarLegend = CalendarLegend.KoineCalendarLegend;
|
|
16
|
+
exports.useCalendar = useCalendar.useCalendar;
|
|
17
|
+
exports.useDateLocale = useDateLocale.useDateLocale;
|
package/calendar.esm.js
CHANGED
|
@@ -1,124 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
import { endOfWeek } from 'date-fns/endOfWeek';
|
|
8
|
-
import { isWithinInterval } from 'date-fns/isWithinInterval';
|
|
9
|
-
import { startOfWeek } from 'date-fns/startOfWeek';
|
|
10
|
-
import { subMonths } from 'date-fns/subMonths';
|
|
11
|
-
import { subWeeks } from 'date-fns/subWeeks';
|
|
12
|
-
import { format } from 'date-fns/format';
|
|
13
|
-
import { eachWeekOfInterval } from 'date-fns/eachWeekOfInterval';
|
|
14
|
-
import { useSwipeable } from 'react-swipeable';
|
|
15
|
-
import { differenceInDays } from 'date-fns/differenceInDays';
|
|
16
|
-
import { subDays } from 'date-fns/subDays';
|
|
17
|
-
import { isUndefined, isString, arrayToLookup } from '@koine/utils';
|
|
18
|
-
|
|
19
|
-
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(e,{weekStartsOn:1})),e);let getEndDate=(e,t)=>{let r=e;return "month"===t?r=endOfMonth(e):"week"===t&&(r=endOfWeek(e,{weekStartsOn:1})),r.setHours(23,59,59),r};let getPrevDate=(e,t)=>"month"===t?subMonths(e,1):subWeeks(e,1);let getNextDate=(e,a)=>"month"===a?addMonths(e,1):addWeeks(e,1);let isTodayInView=(e,t)=>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
|
|
20
|
-
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(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
|
|
21
|
-
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
|
|
22
|
-
// vertically positioned use that index
|
|
23
|
-
if(// only for multi days events:
|
|
24
|
-
s.multi&&(// filter out the days outside of the current week view to avoid
|
|
25
|
-
// making a multi-days event chip wider than the week row or shorter
|
|
26
|
-
// than it should be (when event spans across weeks)
|
|
27
|
-
m=s.days.filter(e=>e>=g&&e<=h).length,// flag the first day of multi-days events, consider that an event
|
|
28
|
-
// might start in a day earlier (hence outside) of the current
|
|
29
|
-
// week/month view, so we always check for Mondays (dayNumber === 0)
|
|
30
|
-
(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`
|
|
31
|
-
for(let e=0;e<t.length;e++)if(1!==t[e]){i=e;break}// now mark the slot as busy
|
|
32
|
-
t[i]=1,// store the slot vertical position consistently for multi-days events
|
|
33
|
-
a&&(p[s.uid]=i),// push the event, they will be sorted later
|
|
34
|
-
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
|
|
35
|
-
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
|
|
36
|
-
v.events.sort((e,t)=>e.top-t.top);}i.days.push(v);}f.push(i);}return f};
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* TODO: include in this lib utilities like in https://github.com/react-icons/react-icons/blob/master/packages/react-icons/src/iconBase.tsx
|
|
40
|
-
*
|
|
41
|
-
* this is the `MdAdd` icon from `react-icons`
|
|
42
|
-
*/let d=l=>/*#__PURE__*/jsxs("svg",{viewBox:"0 0 24 24",fill:"currentColor",stroke:"none",...l,children:[/*#__PURE__*/jsx("path",{d:"M0 0h24v24H0z"}),/*#__PURE__*/jsx("path",{d:"M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"})]}),/**
|
|
43
|
-
* Style for button within a event cell
|
|
44
|
-
*
|
|
45
|
-
* Here we might differentiate week/month view where the first does not get
|
|
46
|
-
* ellipsed btn texts, with `Start` as block element and underneath the `Title`
|
|
47
|
-
* on multiple lines, but that would mean that we loose the ability to interweave
|
|
48
|
-
* single-day events among the spaces left by wider multi-days events.
|
|
49
|
-
*/o$1={overflow:"hidden",whiteSpace:"nowrap",textOverflow:"ellipsis"};let CalendarDaygridCell=({eventClicked:a,setEventClicked:s,// eventHovered,
|
|
50
|
-
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]=useState(!1),O=p.filter(e=>!e.placeholder);return /*#__PURE__*/jsx(f,{children:p.map((t,p)=>{if(p===u&&!x)return /*#__PURE__*/jsxs(y,{onClick:()=>M(!0),children:[/*#__PURE__*/jsx(d,{}),O.length-u]},"overflowMessage"+p);if(p>u&&!x)return null;if(t.placeholder)return /*#__PURE__*/jsx(Fragment,{children:/*#__PURE__*/jsx($,{$placeholder:!0,children:/*#__PURE__*/jsx(m,{"aria-hidden":"true",style:{visibility:"hidden"},$placeholder:!0,children:/*#__PURE__*/jsx(w,{children:" "})})})},t.key);let f={zIndex:t.firstOfMulti?1:0,// to cover the following event days
|
|
51
|
-
position:"relative",width:t.firstOfMulti?`${100*t.width}%`:"100%"};v[t.calendar.id].on||// @ts-expect-error nevermind
|
|
52
|
-
(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__*/jsx(Fragment,{children:/*#__PURE__*/jsx($,{style:f,...k,children:/*#__PURE__*/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__*/jsx(w,{children:t.title}):/*#__PURE__*/jsxs(Fragment$1,{children:[/*#__PURE__*/jsx(g,{children:getDisplayTime(t.start)}),/*#__PURE__*/jsx(w,{children:t.title})]})})})},t.key)})})};/* {i === events.length - 1 && isExpanded ? (
|
|
53
|
-
<CellOverflow onClick={() => expand(false)}>
|
|
54
|
-
<IconCollapse />
|
|
55
|
-
Show less
|
|
56
|
-
</CellOverflow>
|
|
57
|
-
) : null} */
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Dynamically import the date-fns correct locale
|
|
61
|
-
*
|
|
62
|
-
* Inspired by:
|
|
63
|
-
* @see https://robertmarshall.dev/blog/dynamically-import-datefns-locale-mui-datepicker-localization/
|
|
64
|
-
*/let useDateLocale=(a,l="en")=>{let[r,n]=useState(),[o,c]=useState(l);return(// const [ready, setReady] = useState(false);
|
|
65
|
-
// If the user changes the locale listen to the change and import the locale that is now required.
|
|
66
|
-
useEffect(()=>{let e=async()=>{// This webpack option stops all of the date-fns files being imported and chunked.
|
|
67
|
-
// NB: this makes unnecessary numerous webpack chunks in applications
|
|
68
|
-
// that do not even use this hook, so we comment out the webpack dynamic
|
|
69
|
-
// import and its magic comment
|
|
70
|
-
// const localeToSet = await import(
|
|
71
|
-
// /FIXME: * webpackMode: "lazy", webpackChunkName: "df-[index]", webpackExclude: /_lib/ */
|
|
72
|
-
// `date-fns/locale/${locale}/index.js`,
|
|
73
|
-
// );
|
|
74
|
-
let e=await import('date-fns/locale/en-US');c(a||o),n(e.enUS);};// setReady(true);
|
|
75
|
-
// If the locale has not yet been loaded.
|
|
76
|
-
a!==o&&e();},[a,o]),r)};
|
|
77
|
-
|
|
78
|
-
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(C,"MMMM yyyy",v)),"week"===l&&(x=C.getMonth()===p.getMonth()?format(C,"# MMMM yyyy",v).replace("#",`${C.getDate()}-${p.getDate()}`):`${format(C,"d MMMM",v)} - ${format(p,"d MMMM yyyy",v)}`),/*#__PURE__*/jsxs(m,{children:[/*#__PURE__*/jsxs(b,{children:[/*#__PURE__*/jsx(k,{onClick:i}),/*#__PURE__*/jsx(u,{onClick:M}),/*#__PURE__*/jsx(h,{onClick:d,disabled:r}),/*#__PURE__*/jsx(f,{onClick:()=>y("month"),disabled:"month"===l}),/*#__PURE__*/jsx(g,{onClick:()=>y("week"),disabled:"week"===l})]}),/*#__PURE__*/jsx(s,{range:a,formatted:x})]})};
|
|
79
|
-
|
|
80
|
-
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
|
|
81
|
-
{let q={Cell:I,CellOverflow:K,CellEvent:M,CellEventBtn:R,CellEventTitle:T,CellEventStart:W},[A,B]=useState(f||[0,1,2,3,4,5,6]),[E,F]=useState([]),// const [days, setDays] = useState(dayLabels || [...Array(7).keys()]);
|
|
82
|
-
G=useDateLocale(d),{month:H,weeks:J}=useMemo(()=>(function(e){let[t,a]=e,i=eachWeekOfInterval({start:t,end:a},{weekStartsOn:1});return {month:t.getMonth(),weeks:i}})(u),[u]),N=useSwipeable({onSwipedLeft:c,onSwipedRight:s});return useEffect(()=>{F(processEventsInView(h,b,H,J));},[h,b,H,J]),useEffect(()=>{G&&G.localize&&!f&&B([1,2,3,4,5,6,0].map(// @ts-expect-error nevermind
|
|
83
|
-
e=>G.localize.day(e,{width:"abbreviated"})));},[G,f]),/*#__PURE__*/jsxs(C,{...N,children:[/*#__PURE__*/jsx(D,{children:/*#__PURE__*/jsx("tr",{children:A.map(t=>/*#__PURE__*/jsx(S,{scope:"column",children:t},t))})}),/*#__PURE__*/jsx(k,{children:E.map((r,a)=>/*#__PURE__*/jsx(z,{...r.props,children:r.days.map(r=>/*#__PURE__*/jsxs(L,{...r.props,children:[/*#__PURE__*/jsx(O,{...r.props,children:r.label}),r.events.length>0&&/*#__PURE__*/jsx(CalendarDaygridCell,{eventClicked:v,setEventClicked:g,eventHovered:w,setEventHovered:y,view:b,maxEvents:j,events:r.events,timestamp:r.timestamp,calendarsMap:x,...q})]}))}))})]})};
|
|
84
|
-
|
|
85
|
-
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) => {
|
|
86
|
-
// const { name: nameA } = a[1];
|
|
87
|
-
// const { name: nameB } = b[1];
|
|
88
|
-
// if (nameA < nameB) return -1;
|
|
89
|
-
// else if (nameA > nameB) return 1;
|
|
90
|
-
// else return 0;
|
|
91
|
-
// });
|
|
92
|
-
/*#__PURE__*/jsx(Fragment$1,{children:Object.entries(a).map(([r,a])=>/*#__PURE__*/jsxs(d,{onClick:()=>s(r),$color:a.color,$empty:0===a.events,disabled:0===a.events,children:[/*#__PURE__*/jsx(i,{children:a.on?"⬤":"⭘"}),/*#__PURE__*/jsx(l,{children:a.name}),/*#__PURE__*/jsx(t,{children:a.events})]},"CalendarLegend."+r))});
|
|
93
|
-
|
|
94
|
-
/** Fall back to `process.env.GOOGLE_CALENDAR_API_KEY *//** Start gethering events from date *//** End gethering events at date *//**
|
|
95
|
-
* The default is the time zone of the calendar
|
|
96
|
-
* @see https://developers.google.com/calendar/api/v3/reference/events/list
|
|
97
|
-
*//** 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=/**
|
|
98
|
-
* Google event as it comes from Google's API
|
|
99
|
-
*//**
|
|
100
|
-
* Google calendar as it comes from Google's API
|
|
101
|
-
*//**
|
|
102
|
-
* Google event's date as it comes from Google's API
|
|
103
|
-
*//** 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=isUndefined(i.end.dateTime)&&isString(i.end.date),p=i.location||"",D=i.description||"",// FIXME: he.decode(event.description || '');
|
|
104
|
-
h=m.getTime()+""+u.getTime();// multi-days all day events has as end date the date after to what we actually
|
|
105
|
-
// 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
|
|
106
|
-
g&&f>u&&(f=subDays(f,1)).setHours(23,59,59);let y=function(){let t=new Date(u),a=new Date(f),n=[getEventTimestamp(t)];for(;differenceInDays(a,t);)// console.log(title, differenceInDays(to, from))
|
|
107
|
-
t.setDate(t.getDate()+1),n.push(getEventTimestamp(t));return n}(),E=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);
|
|
108
|
-
return c}
|
|
109
|
-
|
|
110
|
-
/** 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 *//**
|
|
111
|
-
* The calendar view
|
|
112
|
-
* @default "month"
|
|
113
|
-
*//**
|
|
114
|
-
* The default is the time zone of the calendar
|
|
115
|
-
* @see https://developers.google.com/calendar/api/v3/reference/events/list
|
|
116
|
-
*/let useCalendar=({locale:d,apiKey:c,calendars:p,events:g,start:m,end:y,view:v="month",timeZone:f="",onError:b})=>{let[w,T]=useState(v),D=m||getStartDate(new Date,w),h=y||getEndDate(D,w),[O,P]=useState([D,h]),[j,x]=useState(isTodayInView(D,h)),[C,L]=useState(g||{}),[N,k]=useState(null),[q,z]=useState(null),[A,B]=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
|
|
117
|
-
p.reduce((e,t)=>(e[t.id]={...t,name:t.name||"",on:!0,events:0},e),{})),E=useCallback(e=>{B({type:"visibility",payload:e});},[B]),F=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=useCallback(async(e,t,l)=>{try{let n=await getCalendarsEventsFromGoogle({apiKey:c,calendars:e,timeZone:f,start:t,end:l});// setEvents(mergeCalendarEvents(events, newEvents));
|
|
118
|
-
L(n);}catch(e){b&&b(e);}},[L,c,f,b]),H=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
|
|
119
|
-
(e.getTime()!==l.getTime()||t.getTime()!==n.getTime())&&(z(null),k(null));},[w,O]),I=useCallback(()=>{P(([e])=>{let t=getPrevDate(e,w),l=getEndDate(t,w);return [t,l]}),z(null),k(null);},[w]),J=useCallback(()=>{P(([e])=>{let t=getNextDate(e,w),l=getEndDate(t,w);return [t,l]}),z(null),k(null);},[w]),K=useCallback(e=>{let t=getStartDate(D,e),l=getEndDate(t,e);P([t,l]),T(e),z(null),k(null);},[D]);return useEffect(()=>{let[e,t]=O;G(p,e,t),x(isTodayInView(e,t));},// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
120
|
-
[O]),useEffect(()=>{C&&F(C);},[C,F]),// when toggling a calendar we also remove the clicked event if that belongs
|
|
121
|
-
// to a now hidden calendar
|
|
122
|
-
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})}};
|
|
123
|
-
|
|
124
|
-
export { CalendarDaygridCell, KoineCalendarDaygridNav, KoineCalendarDaygridTable, KoineCalendarLegend, useCalendar, useDateLocale };
|
|
1
|
+
export { CalendarDaygridCell } from './calendar/CalendarDaygridCell.esm.js';
|
|
2
|
+
export { KoineCalendarDaygridNav } from './calendar/CalendarDaygridNav.esm.js';
|
|
3
|
+
export { KoineCalendarDaygridTable } from './calendar/CalendarDaygridTable.esm.js';
|
|
4
|
+
export { KoineCalendarLegend } from './calendar/CalendarLegend.esm.js';
|
|
5
|
+
export { useCalendar } from './calendar/useCalendar.esm.js';
|
|
6
|
+
export { useDateLocale } from './calendar/useDateLocale.esm.js';
|
package/classed.d.ts
CHANGED
|
@@ -4,5 +4,5 @@ type ClassedAugmentedProps<Props> = Props & {
|
|
|
4
4
|
ref?: React.Ref<any>;
|
|
5
5
|
};
|
|
6
6
|
type ClassedFinalProps<Props, Component> = Component extends React.ReactHTML ? React.HTMLProps<Component> & ClassedAugmentedProps<Props> : ClassedAugmentedProps<Props>;
|
|
7
|
-
export declare let classed: <Props, Component extends React.ElementType
|
|
7
|
+
export declare let classed: <Props, Component extends React.ElementType = any>(component: Component) => (strings: TemplateStringsArray, ...args: ((props: Props) => string)[] | string[]) => React.ForwardRefExoticComponent<React.PropsWithoutRef<ClassedFinalProps<Props, Component>> & React.RefAttributes<Component>>;
|
|
8
8
|
export default classed;
|
package/extendComponent.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export type ExtendableComponent<Props = any> = React.ForwardRefExoticComponent<Props> | React.ExoticComponent<Props> | React.FC<Props> | ((props: Props) => JSX.Element);
|
|
2
|
-
export declare let extendComponent: <Component extends ExtendableComponent
|
|
2
|
+
export declare let extendComponent: <Component extends ExtendableComponent, DefaultProps extends {}>(component: Component, defaultProps: DefaultProps) => ((props: React.ComponentProps<Component>) => import("react").FunctionComponentElement<any>) & DefaultProps & {
|
|
3
3
|
defaultProps: DefaultProps;
|
|
4
4
|
};
|
|
5
5
|
export interface OverridableComponents {
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var yup = require('@kuus/yup');
|
|
4
|
+
var utils = require('@koine/utils');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Encode form
|
|
8
|
+
*
|
|
9
|
+
* Takes a record of yup validations and outputs a `yup` schema with encoded
|
|
10
|
+
* names (antispam technique) and a record of the encoded/decoded input `name`s.
|
|
11
|
+
*
|
|
12
|
+
* We skip the names prefixed wth an underscore which are considered programmatic
|
|
13
|
+
* form data not created by user input.
|
|
14
|
+
*
|
|
15
|
+
* FIXME: types https://github.com/jquense/yup/issues/1700
|
|
16
|
+
*/let encodeForm=t=>{let o={},i={};for(let e in t)if(!e.startsWith("_")){let l=utils.encode(e);o[l]=t[e],i[e]=l;}return {encodedSchema:// we need `.required()` to correctly infer the type @see
|
|
17
|
+
// https://github.com/jquense/yup/issues/946
|
|
18
|
+
yup.object(o).required(),encodedNames:i}};/**
|
|
19
|
+
* Decode form data
|
|
20
|
+
*
|
|
21
|
+
* This function is meant to be used inside an api endpoint to gather an encoded
|
|
22
|
+
* form submit data and transform it to the decoded desired json data.
|
|
23
|
+
*
|
|
24
|
+
* Here too we skip encoding/decoding process for names prefixed wth an underscore
|
|
25
|
+
* which are considered programmatic form data not created by user input.
|
|
26
|
+
*/let decodeForm=e=>{let r={};for(let i in e){let l=utils.decode(i);// always add underscore prefixed names as they are treated as internal
|
|
27
|
+
// private inputs outside of the honeypot system, normalise them here removing
|
|
28
|
+
// the underscore prefix
|
|
29
|
+
i.startsWith("_")?// @ts-expect-error nevermind
|
|
30
|
+
r[i.substring(1)]=e[i]:utils.isUndefined(e[i])||""!==e[l]||// @ts-expect-error nevermind
|
|
31
|
+
(r[l]=e[i]);}// console.log(formData, decoded, json);
|
|
32
|
+
return r};
|
|
33
|
+
|
|
34
|
+
exports.decodeForm = decodeForm;
|
|
35
|
+
exports.encodeForm = encodeForm;
|
package/forms/antispam.d.ts
CHANGED
|
@@ -10,11 +10,11 @@ export declare let encodeForm: <T extends ObjectShape = {}>(validationRules: T)
|
|
|
10
10
|
readonly getter: (data: unknown) => unknown;
|
|
11
11
|
readonly map?: ((value: unknown) => infer T_1) | undefined;
|
|
12
12
|
readonly __isYupRef: boolean;
|
|
13
|
-
getValue(value: any, parent?: {}
|
|
13
|
+
getValue(value: any, parent?: {}, context?: {}): infer T_1;
|
|
14
14
|
cast(value: any, options?: {
|
|
15
|
-
parent?: {}
|
|
16
|
-
context?: {}
|
|
17
|
-
}
|
|
15
|
+
parent?: {};
|
|
16
|
+
context?: {};
|
|
17
|
+
}): infer T_1;
|
|
18
18
|
resolve(): any;
|
|
19
19
|
describe(): import("@kuus/yup").SchemaRefDescription;
|
|
20
20
|
toString(): string;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { object } from '@kuus/yup';
|
|
2
|
+
import { encode, decode, isUndefined } from '@koine/utils';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Encode form
|
|
6
|
+
*
|
|
7
|
+
* Takes a record of yup validations and outputs a `yup` schema with encoded
|
|
8
|
+
* names (antispam technique) and a record of the encoded/decoded input `name`s.
|
|
9
|
+
*
|
|
10
|
+
* We skip the names prefixed wth an underscore which are considered programmatic
|
|
11
|
+
* form data not created by user input.
|
|
12
|
+
*
|
|
13
|
+
* FIXME: types https://github.com/jquense/yup/issues/1700
|
|
14
|
+
*/let encodeForm=t=>{let o={},i={};for(let e in t)if(!e.startsWith("_")){let l=encode(e);o[l]=t[e],i[e]=l;}return {encodedSchema:// we need `.required()` to correctly infer the type @see
|
|
15
|
+
// https://github.com/jquense/yup/issues/946
|
|
16
|
+
object(o).required(),encodedNames:i}};/**
|
|
17
|
+
* Decode form data
|
|
18
|
+
*
|
|
19
|
+
* This function is meant to be used inside an api endpoint to gather an encoded
|
|
20
|
+
* form submit data and transform it to the decoded desired json data.
|
|
21
|
+
*
|
|
22
|
+
* Here too we skip encoding/decoding process for names prefixed wth an underscore
|
|
23
|
+
* which are considered programmatic form data not created by user input.
|
|
24
|
+
*/let decodeForm=e=>{let r={};for(let i in e){let l=decode(i);// always add underscore prefixed names as they are treated as internal
|
|
25
|
+
// private inputs outside of the honeypot system, normalise them here removing
|
|
26
|
+
// the underscore prefix
|
|
27
|
+
i.startsWith("_")?// @ts-expect-error nevermind
|
|
28
|
+
r[i.substring(1)]=e[i]:isUndefined(e[i])||""!==e[l]||// @ts-expect-error nevermind
|
|
29
|
+
(r[l]=e[i]);}// console.log(formData, decoded, json);
|
|
30
|
+
return r};
|
|
31
|
+
|
|
32
|
+
export { decodeForm, encodeForm };
|
package/forms.cjs.js
CHANGED
|
@@ -1,35 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var utils = require('@koine/utils');
|
|
3
|
+
var antispam = require('./forms/antispam.cjs.js');
|
|
5
4
|
|
|
6
|
-
/**
|
|
7
|
-
* Encode form
|
|
8
|
-
*
|
|
9
|
-
* Takes a record of yup validations and outputs a `yup` schema with encoded
|
|
10
|
-
* names (antispam technique) and a record of the encoded/decoded input `name`s.
|
|
11
|
-
*
|
|
12
|
-
* We skip the names prefixed wth an underscore which are considered programmatic
|
|
13
|
-
* form data not created by user input.
|
|
14
|
-
*
|
|
15
|
-
* FIXME: types https://github.com/jquense/yup/issues/1700
|
|
16
|
-
*/let encodeForm=t=>{let o={},i={};for(let e in t)if(!e.startsWith("_")){let l=utils.encode(e);o[l]=t[e],i[e]=l;}return {encodedSchema:// we need `.required()` to correctly infer the type @see
|
|
17
|
-
// https://github.com/jquense/yup/issues/946
|
|
18
|
-
yup.object(o).required(),encodedNames:i}};/**
|
|
19
|
-
* Decode form data
|
|
20
|
-
*
|
|
21
|
-
* This function is meant to be used inside an api endpoint to gather an encoded
|
|
22
|
-
* form submit data and transform it to the decoded desired json data.
|
|
23
|
-
*
|
|
24
|
-
* Here too we skip encoding/decoding process for names prefixed wth an underscore
|
|
25
|
-
* which are considered programmatic form data not created by user input.
|
|
26
|
-
*/let decodeForm=e=>{let r={};for(let i in e){let l=utils.decode(i);// always add underscore prefixed names as they are treated as internal
|
|
27
|
-
// private inputs outside of the honeypot system, normalise them here removing
|
|
28
|
-
// the underscore prefix
|
|
29
|
-
i.startsWith("_")?// @ts-expect-error nevermind
|
|
30
|
-
r[i.substring(1)]=e[i]:utils.isUndefined(e[i])||""!==e[l]||// @ts-expect-error nevermind
|
|
31
|
-
(r[l]=e[i]);}// console.log(formData, decoded, json);
|
|
32
|
-
return r};
|
|
33
5
|
|
|
34
|
-
|
|
35
|
-
exports.
|
|
6
|
+
|
|
7
|
+
exports.decodeForm = antispam.decodeForm;
|
|
8
|
+
exports.encodeForm = antispam.encodeForm;
|
package/forms.esm.js
CHANGED
|
@@ -1,32 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { encode, decode, isUndefined } from '@koine/utils';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Encode form
|
|
6
|
-
*
|
|
7
|
-
* Takes a record of yup validations and outputs a `yup` schema with encoded
|
|
8
|
-
* names (antispam technique) and a record of the encoded/decoded input `name`s.
|
|
9
|
-
*
|
|
10
|
-
* We skip the names prefixed wth an underscore which are considered programmatic
|
|
11
|
-
* form data not created by user input.
|
|
12
|
-
*
|
|
13
|
-
* FIXME: types https://github.com/jquense/yup/issues/1700
|
|
14
|
-
*/let encodeForm=t=>{let o={},i={};for(let e in t)if(!e.startsWith("_")){let l=encode(e);o[l]=t[e],i[e]=l;}return {encodedSchema:// we need `.required()` to correctly infer the type @see
|
|
15
|
-
// https://github.com/jquense/yup/issues/946
|
|
16
|
-
object(o).required(),encodedNames:i}};/**
|
|
17
|
-
* Decode form data
|
|
18
|
-
*
|
|
19
|
-
* This function is meant to be used inside an api endpoint to gather an encoded
|
|
20
|
-
* form submit data and transform it to the decoded desired json data.
|
|
21
|
-
*
|
|
22
|
-
* Here too we skip encoding/decoding process for names prefixed wth an underscore
|
|
23
|
-
* which are considered programmatic form data not created by user input.
|
|
24
|
-
*/let decodeForm=e=>{let r={};for(let i in e){let l=decode(i);// always add underscore prefixed names as they are treated as internal
|
|
25
|
-
// private inputs outside of the honeypot system, normalise them here removing
|
|
26
|
-
// the underscore prefix
|
|
27
|
-
i.startsWith("_")?// @ts-expect-error nevermind
|
|
28
|
-
r[i.substring(1)]=e[i]:isUndefined(e[i])||""!==e[l]||// @ts-expect-error nevermind
|
|
29
|
-
(r[l]=e[i]);}// console.log(formData, decoded, json);
|
|
30
|
-
return r};
|
|
31
|
-
|
|
32
|
-
export { decodeForm, encodeForm };
|
|
1
|
+
export { decodeForm, encodeForm } from './forms/antispam.esm.js';
|
package/index.cjs.js
CHANGED
|
@@ -26,10 +26,6 @@ var useSpinDelay = require('./useSpinDelay.cjs.js');
|
|
|
26
26
|
var useTraceUpdate = require('./useTraceUpdate.cjs.js');
|
|
27
27
|
var useUpdateEffect = require('./useUpdateEffect.cjs.js');
|
|
28
28
|
var useWindowSize = require('./useWindowSize.cjs.js');
|
|
29
|
-
require('react');
|
|
30
|
-
require('@koine/utils');
|
|
31
|
-
require('react/jsx-runtime');
|
|
32
|
-
require('@koine/dom');
|
|
33
29
|
|
|
34
30
|
|
|
35
31
|
|
package/index.esm.js
CHANGED
|
@@ -24,7 +24,3 @@ export { useSpinDelay } from './useSpinDelay.esm.js';
|
|
|
24
24
|
export { useTraceUpdate } from './useTraceUpdate.esm.js';
|
|
25
25
|
export { useUpdateEffect } from './useUpdateEffect.esm.js';
|
|
26
26
|
export { useWindowSize } from './useWindowSize.esm.js';
|
|
27
|
-
import 'react';
|
|
28
|
-
import '@koine/utils';
|
|
29
|
-
import 'react/jsx-runtime';
|
|
30
|
-
import '@koine/dom';
|
package/package.json
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
"name": "@koine/react",
|
|
3
3
|
"sideEffects": false,
|
|
4
4
|
"dependencies": {
|
|
5
|
-
"@koine/dom": "2.0.0-beta.
|
|
6
|
-
"@koine/utils": "2.0.0-beta.
|
|
5
|
+
"@koine/dom": "2.0.0-beta.126",
|
|
6
|
+
"@koine/utils": "2.0.0-beta.126"
|
|
7
7
|
},
|
|
8
8
|
"peerDependencies": {
|
|
9
9
|
"@kuus/yup": "1.0.0-beta.7",
|
|
@@ -29,166 +29,199 @@
|
|
|
29
29
|
"./package.json": "./package.json",
|
|
30
30
|
".": {
|
|
31
31
|
"module": "./index.esm.js",
|
|
32
|
+
"types": "./index.esm.d.ts",
|
|
32
33
|
"import": "./index.cjs.mjs",
|
|
33
34
|
"default": "./index.cjs.js"
|
|
34
35
|
},
|
|
35
36
|
"./calendar": {
|
|
36
37
|
"module": "./calendar.esm.js",
|
|
38
|
+
"types": "./calendar.esm.d.ts",
|
|
37
39
|
"import": "./calendar.cjs.mjs",
|
|
38
40
|
"default": "./calendar.cjs.js"
|
|
39
41
|
},
|
|
40
42
|
"./classed": {
|
|
41
43
|
"module": "./classed.esm.js",
|
|
44
|
+
"types": "./classed.esm.d.ts",
|
|
42
45
|
"import": "./classed.cjs.mjs",
|
|
43
46
|
"default": "./classed.cjs.js"
|
|
44
47
|
},
|
|
45
48
|
"./createUseMediaQueryWidth": {
|
|
46
49
|
"module": "./createUseMediaQueryWidth.esm.js",
|
|
50
|
+
"types": "./createUseMediaQueryWidth.esm.d.ts",
|
|
47
51
|
"import": "./createUseMediaQueryWidth.cjs.mjs",
|
|
48
52
|
"default": "./createUseMediaQueryWidth.cjs.js"
|
|
49
53
|
},
|
|
50
54
|
"./extendComponent": {
|
|
51
55
|
"module": "./extendComponent.esm.js",
|
|
56
|
+
"types": "./extendComponent.esm.d.ts",
|
|
52
57
|
"import": "./extendComponent.cjs.mjs",
|
|
53
58
|
"default": "./extendComponent.cjs.js"
|
|
54
59
|
},
|
|
55
60
|
"./FaviconTags": {
|
|
56
61
|
"module": "./FaviconTags.esm.js",
|
|
62
|
+
"types": "./FaviconTags.esm.d.ts",
|
|
57
63
|
"import": "./FaviconTags.cjs.mjs",
|
|
58
64
|
"default": "./FaviconTags.cjs.js"
|
|
59
65
|
},
|
|
60
66
|
"./forms": {
|
|
61
67
|
"module": "./forms.esm.js",
|
|
68
|
+
"types": "./forms.esm.d.ts",
|
|
62
69
|
"import": "./forms.cjs.mjs",
|
|
63
70
|
"default": "./forms.cjs.js"
|
|
64
71
|
},
|
|
65
72
|
"./mergeRefs": {
|
|
66
73
|
"module": "./mergeRefs.esm.js",
|
|
74
|
+
"types": "./mergeRefs.esm.d.ts",
|
|
67
75
|
"import": "./mergeRefs.cjs.mjs",
|
|
68
76
|
"default": "./mergeRefs.cjs.js"
|
|
69
77
|
},
|
|
70
78
|
"./Meta": {
|
|
71
79
|
"module": "./Meta.esm.js",
|
|
80
|
+
"types": "./Meta.esm.d.ts",
|
|
72
81
|
"import": "./Meta.cjs.mjs",
|
|
73
82
|
"default": "./Meta.cjs.js"
|
|
74
83
|
},
|
|
75
84
|
"./NoJs": {
|
|
76
85
|
"module": "./NoJs.esm.js",
|
|
86
|
+
"types": "./NoJs.esm.d.ts",
|
|
77
87
|
"import": "./NoJs.cjs.mjs",
|
|
78
88
|
"default": "./NoJs.cjs.js"
|
|
79
89
|
},
|
|
80
90
|
"./Polymorphic": {
|
|
81
91
|
"module": "./Polymorphic.esm.js",
|
|
92
|
+
"types": "./Polymorphic.esm.d.ts",
|
|
82
93
|
"import": "./Polymorphic.cjs.mjs",
|
|
83
94
|
"default": "./Polymorphic.cjs.js"
|
|
84
95
|
},
|
|
85
96
|
"./types": {
|
|
86
97
|
"module": "./types.esm.js",
|
|
98
|
+
"types": "./types.esm.d.ts",
|
|
87
99
|
"import": "./types.cjs.mjs",
|
|
88
100
|
"default": "./types.cjs.js"
|
|
89
101
|
},
|
|
90
102
|
"./useAsyncFn": {
|
|
91
103
|
"module": "./useAsyncFn.esm.js",
|
|
104
|
+
"types": "./useAsyncFn.esm.d.ts",
|
|
92
105
|
"import": "./useAsyncFn.cjs.mjs",
|
|
93
106
|
"default": "./useAsyncFn.cjs.js"
|
|
94
107
|
},
|
|
95
108
|
"./useFirstMountState": {
|
|
96
109
|
"module": "./useFirstMountState.esm.js",
|
|
110
|
+
"types": "./useFirstMountState.esm.d.ts",
|
|
97
111
|
"import": "./useFirstMountState.cjs.mjs",
|
|
98
112
|
"default": "./useFirstMountState.cjs.js"
|
|
99
113
|
},
|
|
100
114
|
"./useFixedOffset": {
|
|
101
115
|
"module": "./useFixedOffset.esm.js",
|
|
116
|
+
"types": "./useFixedOffset.esm.d.ts",
|
|
102
117
|
"import": "./useFixedOffset.cjs.mjs",
|
|
103
118
|
"default": "./useFixedOffset.cjs.js"
|
|
104
119
|
},
|
|
105
120
|
"./useFocus": {
|
|
106
121
|
"module": "./useFocus.esm.js",
|
|
122
|
+
"types": "./useFocus.esm.d.ts",
|
|
107
123
|
"import": "./useFocus.cjs.mjs",
|
|
108
124
|
"default": "./useFocus.cjs.js"
|
|
109
125
|
},
|
|
110
126
|
"./useInterval": {
|
|
111
127
|
"module": "./useInterval.esm.js",
|
|
128
|
+
"types": "./useInterval.esm.d.ts",
|
|
112
129
|
"import": "./useInterval.cjs.mjs",
|
|
113
130
|
"default": "./useInterval.cjs.js"
|
|
114
131
|
},
|
|
115
132
|
"./useIsomorphicLayoutEffect": {
|
|
116
133
|
"module": "./useIsomorphicLayoutEffect.esm.js",
|
|
134
|
+
"types": "./useIsomorphicLayoutEffect.esm.d.ts",
|
|
117
135
|
"import": "./useIsomorphicLayoutEffect.cjs.mjs",
|
|
118
136
|
"default": "./useIsomorphicLayoutEffect.cjs.js"
|
|
119
137
|
},
|
|
120
138
|
"./useKeyUp": {
|
|
121
139
|
"module": "./useKeyUp.esm.js",
|
|
140
|
+
"types": "./useKeyUp.esm.d.ts",
|
|
122
141
|
"import": "./useKeyUp.cjs.mjs",
|
|
123
142
|
"default": "./useKeyUp.cjs.js"
|
|
124
143
|
},
|
|
125
144
|
"./useMeasure": {
|
|
126
145
|
"module": "./useMeasure.esm.js",
|
|
146
|
+
"types": "./useMeasure.esm.d.ts",
|
|
127
147
|
"import": "./useMeasure.cjs.mjs",
|
|
128
148
|
"default": "./useMeasure.cjs.js"
|
|
129
149
|
},
|
|
130
150
|
"./useMountedState": {
|
|
131
151
|
"module": "./useMountedState.esm.js",
|
|
152
|
+
"types": "./useMountedState.esm.d.ts",
|
|
132
153
|
"import": "./useMountedState.cjs.mjs",
|
|
133
154
|
"default": "./useMountedState.cjs.js"
|
|
134
155
|
},
|
|
135
156
|
"./useNavigateAway": {
|
|
136
157
|
"module": "./useNavigateAway.esm.js",
|
|
158
|
+
"types": "./useNavigateAway.esm.d.ts",
|
|
137
159
|
"import": "./useNavigateAway.cjs.mjs",
|
|
138
160
|
"default": "./useNavigateAway.cjs.js"
|
|
139
161
|
},
|
|
140
162
|
"./usePrevious": {
|
|
141
163
|
"module": "./usePrevious.esm.js",
|
|
164
|
+
"types": "./usePrevious.esm.d.ts",
|
|
142
165
|
"import": "./usePrevious.cjs.mjs",
|
|
143
166
|
"default": "./usePrevious.cjs.js"
|
|
144
167
|
},
|
|
145
168
|
"./usePreviousRef": {
|
|
146
169
|
"module": "./usePreviousRef.esm.js",
|
|
170
|
+
"types": "./usePreviousRef.esm.d.ts",
|
|
147
171
|
"import": "./usePreviousRef.cjs.mjs",
|
|
148
172
|
"default": "./usePreviousRef.cjs.js"
|
|
149
173
|
},
|
|
150
174
|
"./useScrollPosition": {
|
|
151
175
|
"module": "./useScrollPosition.esm.js",
|
|
176
|
+
"types": "./useScrollPosition.esm.d.ts",
|
|
152
177
|
"import": "./useScrollPosition.cjs.mjs",
|
|
153
178
|
"default": "./useScrollPosition.cjs.js"
|
|
154
179
|
},
|
|
155
180
|
"./useScrollThreshold": {
|
|
156
181
|
"module": "./useScrollThreshold.esm.js",
|
|
182
|
+
"types": "./useScrollThreshold.esm.d.ts",
|
|
157
183
|
"import": "./useScrollThreshold.cjs.mjs",
|
|
158
184
|
"default": "./useScrollThreshold.cjs.js"
|
|
159
185
|
},
|
|
160
186
|
"./useScrollTo": {
|
|
161
187
|
"module": "./useScrollTo.esm.js",
|
|
188
|
+
"types": "./useScrollTo.esm.d.ts",
|
|
162
189
|
"import": "./useScrollTo.cjs.mjs",
|
|
163
190
|
"default": "./useScrollTo.cjs.js"
|
|
164
191
|
},
|
|
165
192
|
"./useSmoothScroll": {
|
|
166
193
|
"module": "./useSmoothScroll.esm.js",
|
|
194
|
+
"types": "./useSmoothScroll.esm.d.ts",
|
|
167
195
|
"import": "./useSmoothScroll.cjs.mjs",
|
|
168
196
|
"default": "./useSmoothScroll.cjs.js"
|
|
169
197
|
},
|
|
170
198
|
"./useSpinDelay": {
|
|
171
199
|
"module": "./useSpinDelay.esm.js",
|
|
200
|
+
"types": "./useSpinDelay.esm.d.ts",
|
|
172
201
|
"import": "./useSpinDelay.cjs.mjs",
|
|
173
202
|
"default": "./useSpinDelay.cjs.js"
|
|
174
203
|
},
|
|
175
204
|
"./useTraceUpdate": {
|
|
176
205
|
"module": "./useTraceUpdate.esm.js",
|
|
206
|
+
"types": "./useTraceUpdate.esm.d.ts",
|
|
177
207
|
"import": "./useTraceUpdate.cjs.mjs",
|
|
178
208
|
"default": "./useTraceUpdate.cjs.js"
|
|
179
209
|
},
|
|
180
210
|
"./useUpdateEffect": {
|
|
181
211
|
"module": "./useUpdateEffect.esm.js",
|
|
212
|
+
"types": "./useUpdateEffect.esm.d.ts",
|
|
182
213
|
"import": "./useUpdateEffect.cjs.mjs",
|
|
183
214
|
"default": "./useUpdateEffect.cjs.js"
|
|
184
215
|
},
|
|
185
216
|
"./useWindowSize": {
|
|
186
217
|
"module": "./useWindowSize.esm.js",
|
|
218
|
+
"types": "./useWindowSize.esm.d.ts",
|
|
187
219
|
"import": "./useWindowSize.cjs.mjs",
|
|
188
220
|
"default": "./useWindowSize.cjs.js"
|
|
189
221
|
}
|
|
190
222
|
},
|
|
191
223
|
"module": "./index.esm.js",
|
|
192
224
|
"main": "./index.cjs.js",
|
|
193
|
-
"
|
|
225
|
+
"types": "./index.esm.d.ts",
|
|
226
|
+
"version": "2.0.0-beta.126"
|
|
194
227
|
}
|
package/useScrollPosition.d.ts
CHANGED
|
@@ -3,5 +3,5 @@ type Position = {
|
|
|
3
3
|
y: number;
|
|
4
4
|
};
|
|
5
5
|
type ElementRef = React.MutableRefObject<HTMLElement | undefined>;
|
|
6
|
-
export declare let useScrollPosition: (effect: (currentPosition: Position, prevPosition: Position) => void, deps?:
|
|
6
|
+
export declare let useScrollPosition: (effect: (currentPosition: Position, prevPosition: Position) => void, deps?: React.DependencyList, element?: ElementRef, boundingElement?: ElementRef, wait?: number) => void;
|
|
7
7
|
export default useScrollPosition;
|
package/useSmoothScroll.cjs.js
CHANGED
package/useSmoothScroll.esm.js
CHANGED