react-native-agenda-kit 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +364 -0
- package/lib/commonjs/agenda/AgendaBackdrop.js +68 -0
- package/lib/commonjs/agenda/AgendaBackdrop.js.map +1 -0
- package/lib/commonjs/agenda/AgendaList.js +354 -0
- package/lib/commonjs/agenda/AgendaList.js.map +1 -0
- package/lib/commonjs/agenda/AgendaSlot.js +88 -0
- package/lib/commonjs/agenda/AgendaSlot.js.map +1 -0
- package/lib/commonjs/agenda/AgendaWindow.js +171 -0
- package/lib/commonjs/agenda/AgendaWindow.js.map +1 -0
- package/lib/commonjs/agenda/StickyHeaderOverlay.js +125 -0
- package/lib/commonjs/agenda/StickyHeaderOverlay.js.map +1 -0
- package/lib/commonjs/agenda/buildAgendaLayout.js +100 -0
- package/lib/commonjs/agenda/buildAgendaLayout.js.map +1 -0
- package/lib/commonjs/agenda/constants.js +29 -0
- package/lib/commonjs/agenda/constants.js.map +1 -0
- package/lib/commonjs/agenda/heights.js +49 -0
- package/lib/commonjs/agenda/heights.js.map +1 -0
- package/lib/commonjs/agenda/useAgendaScrollSync.js +204 -0
- package/lib/commonjs/agenda/useAgendaScrollSync.js.map +1 -0
- package/lib/commonjs/core/ArrowGlyph.js +65 -0
- package/lib/commonjs/core/ArrowGlyph.js.map +1 -0
- package/lib/commonjs/core/CalendarContext.js +32 -0
- package/lib/commonjs/core/CalendarContext.js.map +1 -0
- package/lib/commonjs/core/CalendarProvider.js +141 -0
- package/lib/commonjs/core/CalendarProvider.js.map +1 -0
- package/lib/commonjs/core/CalendarStore.js +70 -0
- package/lib/commonjs/core/CalendarStore.js.map +1 -0
- package/lib/commonjs/core/KitText.js +23 -0
- package/lib/commonjs/core/KitText.js.map +1 -0
- package/lib/commonjs/core/TodayButton.js +136 -0
- package/lib/commonjs/core/TodayButton.js.map +1 -0
- package/lib/commonjs/core/civil.js +101 -0
- package/lib/commonjs/core/civil.js.map +1 -0
- package/lib/commonjs/core/dateKey.js +56 -0
- package/lib/commonjs/core/dateKey.js.map +1 -0
- package/lib/commonjs/core/motion.js +56 -0
- package/lib/commonjs/core/motion.js.map +1 -0
- package/lib/commonjs/core/worklets.js +44 -0
- package/lib/commonjs/core/worklets.js.map +1 -0
- package/lib/commonjs/expandable/DayCell.js +120 -0
- package/lib/commonjs/expandable/DayCell.js.map +1 -0
- package/lib/commonjs/expandable/ExpandableCalendar.js +280 -0
- package/lib/commonjs/expandable/ExpandableCalendar.js.map +1 -0
- package/lib/commonjs/expandable/Knob.js +72 -0
- package/lib/commonjs/expandable/Knob.js.map +1 -0
- package/lib/commonjs/expandable/MonthPager.js +180 -0
- package/lib/commonjs/expandable/MonthPager.js.map +1 -0
- package/lib/commonjs/expandable/WeekStrip.js +451 -0
- package/lib/commonjs/expandable/WeekStrip.js.map +1 -0
- package/lib/commonjs/expandable/calendarCells.js +152 -0
- package/lib/commonjs/expandable/calendarCells.js.map +1 -0
- package/lib/commonjs/expandable/geometry.js +62 -0
- package/lib/commonjs/expandable/geometry.js.map +1 -0
- package/lib/commonjs/expandable/useExpandGesture.js +124 -0
- package/lib/commonjs/expandable/useExpandGesture.js.map +1 -0
- package/lib/commonjs/expandable/useHorizontalPager.js +97 -0
- package/lib/commonjs/expandable/useHorizontalPager.js.map +1 -0
- package/lib/commonjs/index.js +167 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/theme/ThemeProvider.js +73 -0
- package/lib/commonjs/theme/ThemeProvider.js.map +1 -0
- package/lib/commonjs/theme/index.js +75 -0
- package/lib/commonjs/theme/index.js.map +1 -0
- package/lib/commonjs/theme/theme.js +79 -0
- package/lib/commonjs/theme/theme.js.map +1 -0
- package/lib/commonjs/theme/tokens.js +54 -0
- package/lib/commonjs/theme/tokens.js.map +1 -0
- package/lib/commonjs/timeline/DayColumn.js +95 -0
- package/lib/commonjs/timeline/DayColumn.js.map +1 -0
- package/lib/commonjs/timeline/DayPager.js +250 -0
- package/lib/commonjs/timeline/DayPager.js.map +1 -0
- package/lib/commonjs/timeline/EventBlock.js +91 -0
- package/lib/commonjs/timeline/EventBlock.js.map +1 -0
- package/lib/commonjs/timeline/GridLines.js +47 -0
- package/lib/commonjs/timeline/GridLines.js.map +1 -0
- package/lib/commonjs/timeline/HourGrid.js +96 -0
- package/lib/commonjs/timeline/HourGrid.js.map +1 -0
- package/lib/commonjs/timeline/NowIndicator.js +132 -0
- package/lib/commonjs/timeline/NowIndicator.js.map +1 -0
- package/lib/commonjs/timeline/TimelineDay.js +126 -0
- package/lib/commonjs/timeline/TimelineDay.js.map +1 -0
- package/lib/commonjs/timeline/packEvents.js +102 -0
- package/lib/commonjs/timeline/packEvents.js.map +1 -0
- package/lib/commonjs/timeline/timelineGeometry.js +27 -0
- package/lib/commonjs/timeline/timelineGeometry.js.map +1 -0
- package/lib/commonjs/timeline/timelineMath.js +82 -0
- package/lib/commonjs/timeline/timelineMath.js.map +1 -0
- package/lib/commonjs/types.js +71 -0
- package/lib/commonjs/types.js.map +1 -0
- package/lib/module/agenda/AgendaBackdrop.js +63 -0
- package/lib/module/agenda/AgendaBackdrop.js.map +1 -0
- package/lib/module/agenda/AgendaList.js +349 -0
- package/lib/module/agenda/AgendaList.js.map +1 -0
- package/lib/module/agenda/AgendaSlot.js +84 -0
- package/lib/module/agenda/AgendaSlot.js.map +1 -0
- package/lib/module/agenda/AgendaWindow.js +167 -0
- package/lib/module/agenda/AgendaWindow.js.map +1 -0
- package/lib/module/agenda/StickyHeaderOverlay.js +120 -0
- package/lib/module/agenda/StickyHeaderOverlay.js.map +1 -0
- package/lib/module/agenda/buildAgendaLayout.js +95 -0
- package/lib/module/agenda/buildAgendaLayout.js.map +1 -0
- package/lib/module/agenda/constants.js +25 -0
- package/lib/module/agenda/constants.js.map +1 -0
- package/lib/module/agenda/heights.js +42 -0
- package/lib/module/agenda/heights.js.map +1 -0
- package/lib/module/agenda/useAgendaScrollSync.js +200 -0
- package/lib/module/agenda/useAgendaScrollSync.js.map +1 -0
- package/lib/module/core/ArrowGlyph.js +60 -0
- package/lib/module/core/ArrowGlyph.js.map +1 -0
- package/lib/module/core/CalendarContext.js +26 -0
- package/lib/module/core/CalendarContext.js.map +1 -0
- package/lib/module/core/CalendarProvider.js +136 -0
- package/lib/module/core/CalendarProvider.js.map +1 -0
- package/lib/module/core/CalendarStore.js +66 -0
- package/lib/module/core/CalendarStore.js.map +1 -0
- package/lib/module/core/KitText.js +19 -0
- package/lib/module/core/KitText.js.map +1 -0
- package/lib/module/core/TodayButton.js +133 -0
- package/lib/module/core/TodayButton.js.map +1 -0
- package/lib/module/core/civil.js +88 -0
- package/lib/module/core/civil.js.map +1 -0
- package/lib/module/core/dateKey.js +47 -0
- package/lib/module/core/dateKey.js.map +1 -0
- package/lib/module/core/motion.js +49 -0
- package/lib/module/core/motion.js.map +1 -0
- package/lib/module/core/worklets.js +38 -0
- package/lib/module/core/worklets.js.map +1 -0
- package/lib/module/expandable/DayCell.js +116 -0
- package/lib/module/expandable/DayCell.js.map +1 -0
- package/lib/module/expandable/ExpandableCalendar.js +275 -0
- package/lib/module/expandable/ExpandableCalendar.js.map +1 -0
- package/lib/module/expandable/Knob.js +67 -0
- package/lib/module/expandable/Knob.js.map +1 -0
- package/lib/module/expandable/MonthPager.js +175 -0
- package/lib/module/expandable/MonthPager.js.map +1 -0
- package/lib/module/expandable/WeekStrip.js +446 -0
- package/lib/module/expandable/WeekStrip.js.map +1 -0
- package/lib/module/expandable/calendarCells.js +142 -0
- package/lib/module/expandable/calendarCells.js.map +1 -0
- package/lib/module/expandable/geometry.js +58 -0
- package/lib/module/expandable/geometry.js.map +1 -0
- package/lib/module/expandable/useExpandGesture.js +118 -0
- package/lib/module/expandable/useExpandGesture.js.map +1 -0
- package/lib/module/expandable/useHorizontalPager.js +92 -0
- package/lib/module/expandable/useHorizontalPager.js.map +1 -0
- package/lib/module/index.js +35 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/theme/ThemeProvider.js +65 -0
- package/lib/module/theme/ThemeProvider.js.map +1 -0
- package/lib/module/theme/index.js +6 -0
- package/lib/module/theme/index.js.map +1 -0
- package/lib/module/theme/theme.js +74 -0
- package/lib/module/theme/theme.js.map +1 -0
- package/lib/module/theme/tokens.js +50 -0
- package/lib/module/theme/tokens.js.map +1 -0
- package/lib/module/timeline/DayColumn.js +91 -0
- package/lib/module/timeline/DayColumn.js.map +1 -0
- package/lib/module/timeline/DayPager.js +245 -0
- package/lib/module/timeline/DayPager.js.map +1 -0
- package/lib/module/timeline/EventBlock.js +87 -0
- package/lib/module/timeline/EventBlock.js.map +1 -0
- package/lib/module/timeline/GridLines.js +43 -0
- package/lib/module/timeline/GridLines.js.map +1 -0
- package/lib/module/timeline/HourGrid.js +94 -0
- package/lib/module/timeline/HourGrid.js.map +1 -0
- package/lib/module/timeline/NowIndicator.js +126 -0
- package/lib/module/timeline/NowIndicator.js.map +1 -0
- package/lib/module/timeline/TimelineDay.js +122 -0
- package/lib/module/timeline/TimelineDay.js.map +1 -0
- package/lib/module/timeline/packEvents.js +97 -0
- package/lib/module/timeline/packEvents.js.map +1 -0
- package/lib/module/timeline/timelineGeometry.js +22 -0
- package/lib/module/timeline/timelineGeometry.js.map +1 -0
- package/lib/module/timeline/timelineMath.js +75 -0
- package/lib/module/timeline/timelineMath.js.map +1 -0
- package/lib/module/types.js +67 -0
- package/lib/module/types.js.map +1 -0
- package/lib/typescript/commonjs/agenda/AgendaBackdrop.d.ts +20 -0
- package/lib/typescript/commonjs/agenda/AgendaBackdrop.d.ts.map +1 -0
- package/lib/typescript/commonjs/agenda/AgendaList.d.ts +12 -0
- package/lib/typescript/commonjs/agenda/AgendaList.d.ts.map +1 -0
- package/lib/typescript/commonjs/agenda/AgendaSlot.d.ts +45 -0
- package/lib/typescript/commonjs/agenda/AgendaSlot.d.ts.map +1 -0
- package/lib/typescript/commonjs/agenda/AgendaWindow.d.ts +49 -0
- package/lib/typescript/commonjs/agenda/AgendaWindow.d.ts.map +1 -0
- package/lib/typescript/commonjs/agenda/StickyHeaderOverlay.d.ts +39 -0
- package/lib/typescript/commonjs/agenda/StickyHeaderOverlay.d.ts.map +1 -0
- package/lib/typescript/commonjs/agenda/buildAgendaLayout.d.ts +57 -0
- package/lib/typescript/commonjs/agenda/buildAgendaLayout.d.ts.map +1 -0
- package/lib/typescript/commonjs/agenda/constants.d.ts +19 -0
- package/lib/typescript/commonjs/agenda/constants.d.ts.map +1 -0
- package/lib/typescript/commonjs/agenda/heights.d.ts +20 -0
- package/lib/typescript/commonjs/agenda/heights.d.ts.map +1 -0
- package/lib/typescript/commonjs/agenda/useAgendaScrollSync.d.ts +44 -0
- package/lib/typescript/commonjs/agenda/useAgendaScrollSync.d.ts.map +1 -0
- package/lib/typescript/commonjs/core/ArrowGlyph.d.ts +14 -0
- package/lib/typescript/commonjs/core/ArrowGlyph.d.ts.map +1 -0
- package/lib/typescript/commonjs/core/CalendarContext.d.ts +35 -0
- package/lib/typescript/commonjs/core/CalendarContext.d.ts.map +1 -0
- package/lib/typescript/commonjs/core/CalendarProvider.d.ts +41 -0
- package/lib/typescript/commonjs/core/CalendarProvider.d.ts.map +1 -0
- package/lib/typescript/commonjs/core/CalendarStore.d.ts +28 -0
- package/lib/typescript/commonjs/core/CalendarStore.d.ts.map +1 -0
- package/lib/typescript/commonjs/core/KitText.d.ts +10 -0
- package/lib/typescript/commonjs/core/KitText.d.ts.map +1 -0
- package/lib/typescript/commonjs/core/TodayButton.d.ts +18 -0
- package/lib/typescript/commonjs/core/TodayButton.d.ts.map +1 -0
- package/lib/typescript/commonjs/core/civil.d.ts +26 -0
- package/lib/typescript/commonjs/core/civil.d.ts.map +1 -0
- package/lib/typescript/commonjs/core/dateKey.d.ts +21 -0
- package/lib/typescript/commonjs/core/dateKey.d.ts.map +1 -0
- package/lib/typescript/commonjs/core/motion.d.ts +18 -0
- package/lib/typescript/commonjs/core/motion.d.ts.map +1 -0
- package/lib/typescript/commonjs/core/worklets.d.ts +12 -0
- package/lib/typescript/commonjs/core/worklets.d.ts.map +1 -0
- package/lib/typescript/commonjs/expandable/DayCell.d.ts +22 -0
- package/lib/typescript/commonjs/expandable/DayCell.d.ts.map +1 -0
- package/lib/typescript/commonjs/expandable/ExpandableCalendar.d.ts +40 -0
- package/lib/typescript/commonjs/expandable/ExpandableCalendar.d.ts.map +1 -0
- package/lib/typescript/commonjs/expandable/Knob.d.ts +19 -0
- package/lib/typescript/commonjs/expandable/Knob.d.ts.map +1 -0
- package/lib/typescript/commonjs/expandable/MonthPager.d.ts +35 -0
- package/lib/typescript/commonjs/expandable/MonthPager.d.ts.map +1 -0
- package/lib/typescript/commonjs/expandable/WeekStrip.d.ts +34 -0
- package/lib/typescript/commonjs/expandable/WeekStrip.d.ts.map +1 -0
- package/lib/typescript/commonjs/expandable/calendarCells.d.ts +52 -0
- package/lib/typescript/commonjs/expandable/calendarCells.d.ts.map +1 -0
- package/lib/typescript/commonjs/expandable/geometry.d.ts +43 -0
- package/lib/typescript/commonjs/expandable/geometry.d.ts.map +1 -0
- package/lib/typescript/commonjs/expandable/useExpandGesture.d.ts +35 -0
- package/lib/typescript/commonjs/expandable/useExpandGesture.d.ts.map +1 -0
- package/lib/typescript/commonjs/expandable/useHorizontalPager.d.ts +35 -0
- package/lib/typescript/commonjs/expandable/useHorizontalPager.d.ts.map +1 -0
- package/lib/typescript/commonjs/index.d.ts +26 -0
- package/lib/typescript/commonjs/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/package.json +1 -0
- package/lib/typescript/commonjs/theme/ThemeProvider.d.ts +27 -0
- package/lib/typescript/commonjs/theme/ThemeProvider.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/index.d.ts +4 -0
- package/lib/typescript/commonjs/theme/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/theme.d.ts +62 -0
- package/lib/typescript/commonjs/theme/theme.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/tokens.d.ts +46 -0
- package/lib/typescript/commonjs/theme/tokens.d.ts.map +1 -0
- package/lib/typescript/commonjs/timeline/DayColumn.d.ts +32 -0
- package/lib/typescript/commonjs/timeline/DayColumn.d.ts.map +1 -0
- package/lib/typescript/commonjs/timeline/DayPager.d.ts +32 -0
- package/lib/typescript/commonjs/timeline/DayPager.d.ts.map +1 -0
- package/lib/typescript/commonjs/timeline/EventBlock.d.ts +17 -0
- package/lib/typescript/commonjs/timeline/EventBlock.d.ts.map +1 -0
- package/lib/typescript/commonjs/timeline/GridLines.d.ts +5 -0
- package/lib/typescript/commonjs/timeline/GridLines.d.ts.map +1 -0
- package/lib/typescript/commonjs/timeline/HourGrid.d.ts +12 -0
- package/lib/typescript/commonjs/timeline/HourGrid.d.ts.map +1 -0
- package/lib/typescript/commonjs/timeline/NowIndicator.d.ts +28 -0
- package/lib/typescript/commonjs/timeline/NowIndicator.d.ts.map +1 -0
- package/lib/typescript/commonjs/timeline/TimelineDay.d.ts +14 -0
- package/lib/typescript/commonjs/timeline/TimelineDay.d.ts.map +1 -0
- package/lib/typescript/commonjs/timeline/packEvents.d.ts +25 -0
- package/lib/typescript/commonjs/timeline/packEvents.d.ts.map +1 -0
- package/lib/typescript/commonjs/timeline/timelineGeometry.d.ts +14 -0
- package/lib/typescript/commonjs/timeline/timelineGeometry.d.ts.map +1 -0
- package/lib/typescript/commonjs/timeline/timelineMath.d.ts +32 -0
- package/lib/typescript/commonjs/timeline/timelineMath.d.ts.map +1 -0
- package/lib/typescript/commonjs/types.d.ts +237 -0
- package/lib/typescript/commonjs/types.d.ts.map +1 -0
- package/lib/typescript/module/agenda/AgendaBackdrop.d.ts +20 -0
- package/lib/typescript/module/agenda/AgendaBackdrop.d.ts.map +1 -0
- package/lib/typescript/module/agenda/AgendaList.d.ts +12 -0
- package/lib/typescript/module/agenda/AgendaList.d.ts.map +1 -0
- package/lib/typescript/module/agenda/AgendaSlot.d.ts +45 -0
- package/lib/typescript/module/agenda/AgendaSlot.d.ts.map +1 -0
- package/lib/typescript/module/agenda/AgendaWindow.d.ts +49 -0
- package/lib/typescript/module/agenda/AgendaWindow.d.ts.map +1 -0
- package/lib/typescript/module/agenda/StickyHeaderOverlay.d.ts +39 -0
- package/lib/typescript/module/agenda/StickyHeaderOverlay.d.ts.map +1 -0
- package/lib/typescript/module/agenda/buildAgendaLayout.d.ts +57 -0
- package/lib/typescript/module/agenda/buildAgendaLayout.d.ts.map +1 -0
- package/lib/typescript/module/agenda/constants.d.ts +19 -0
- package/lib/typescript/module/agenda/constants.d.ts.map +1 -0
- package/lib/typescript/module/agenda/heights.d.ts +20 -0
- package/lib/typescript/module/agenda/heights.d.ts.map +1 -0
- package/lib/typescript/module/agenda/useAgendaScrollSync.d.ts +44 -0
- package/lib/typescript/module/agenda/useAgendaScrollSync.d.ts.map +1 -0
- package/lib/typescript/module/core/ArrowGlyph.d.ts +14 -0
- package/lib/typescript/module/core/ArrowGlyph.d.ts.map +1 -0
- package/lib/typescript/module/core/CalendarContext.d.ts +35 -0
- package/lib/typescript/module/core/CalendarContext.d.ts.map +1 -0
- package/lib/typescript/module/core/CalendarProvider.d.ts +41 -0
- package/lib/typescript/module/core/CalendarProvider.d.ts.map +1 -0
- package/lib/typescript/module/core/CalendarStore.d.ts +28 -0
- package/lib/typescript/module/core/CalendarStore.d.ts.map +1 -0
- package/lib/typescript/module/core/KitText.d.ts +10 -0
- package/lib/typescript/module/core/KitText.d.ts.map +1 -0
- package/lib/typescript/module/core/TodayButton.d.ts +18 -0
- package/lib/typescript/module/core/TodayButton.d.ts.map +1 -0
- package/lib/typescript/module/core/civil.d.ts +26 -0
- package/lib/typescript/module/core/civil.d.ts.map +1 -0
- package/lib/typescript/module/core/dateKey.d.ts +21 -0
- package/lib/typescript/module/core/dateKey.d.ts.map +1 -0
- package/lib/typescript/module/core/motion.d.ts +18 -0
- package/lib/typescript/module/core/motion.d.ts.map +1 -0
- package/lib/typescript/module/core/worklets.d.ts +12 -0
- package/lib/typescript/module/core/worklets.d.ts.map +1 -0
- package/lib/typescript/module/expandable/DayCell.d.ts +22 -0
- package/lib/typescript/module/expandable/DayCell.d.ts.map +1 -0
- package/lib/typescript/module/expandable/ExpandableCalendar.d.ts +40 -0
- package/lib/typescript/module/expandable/ExpandableCalendar.d.ts.map +1 -0
- package/lib/typescript/module/expandable/Knob.d.ts +19 -0
- package/lib/typescript/module/expandable/Knob.d.ts.map +1 -0
- package/lib/typescript/module/expandable/MonthPager.d.ts +35 -0
- package/lib/typescript/module/expandable/MonthPager.d.ts.map +1 -0
- package/lib/typescript/module/expandable/WeekStrip.d.ts +34 -0
- package/lib/typescript/module/expandable/WeekStrip.d.ts.map +1 -0
- package/lib/typescript/module/expandable/calendarCells.d.ts +52 -0
- package/lib/typescript/module/expandable/calendarCells.d.ts.map +1 -0
- package/lib/typescript/module/expandable/geometry.d.ts +43 -0
- package/lib/typescript/module/expandable/geometry.d.ts.map +1 -0
- package/lib/typescript/module/expandable/useExpandGesture.d.ts +35 -0
- package/lib/typescript/module/expandable/useExpandGesture.d.ts.map +1 -0
- package/lib/typescript/module/expandable/useHorizontalPager.d.ts +35 -0
- package/lib/typescript/module/expandable/useHorizontalPager.d.ts.map +1 -0
- package/lib/typescript/module/index.d.ts +26 -0
- package/lib/typescript/module/index.d.ts.map +1 -0
- package/lib/typescript/module/package.json +1 -0
- package/lib/typescript/module/theme/ThemeProvider.d.ts +27 -0
- package/lib/typescript/module/theme/ThemeProvider.d.ts.map +1 -0
- package/lib/typescript/module/theme/index.d.ts +4 -0
- package/lib/typescript/module/theme/index.d.ts.map +1 -0
- package/lib/typescript/module/theme/theme.d.ts +62 -0
- package/lib/typescript/module/theme/theme.d.ts.map +1 -0
- package/lib/typescript/module/theme/tokens.d.ts +46 -0
- package/lib/typescript/module/theme/tokens.d.ts.map +1 -0
- package/lib/typescript/module/timeline/DayColumn.d.ts +32 -0
- package/lib/typescript/module/timeline/DayColumn.d.ts.map +1 -0
- package/lib/typescript/module/timeline/DayPager.d.ts +32 -0
- package/lib/typescript/module/timeline/DayPager.d.ts.map +1 -0
- package/lib/typescript/module/timeline/EventBlock.d.ts +17 -0
- package/lib/typescript/module/timeline/EventBlock.d.ts.map +1 -0
- package/lib/typescript/module/timeline/GridLines.d.ts +5 -0
- package/lib/typescript/module/timeline/GridLines.d.ts.map +1 -0
- package/lib/typescript/module/timeline/HourGrid.d.ts +12 -0
- package/lib/typescript/module/timeline/HourGrid.d.ts.map +1 -0
- package/lib/typescript/module/timeline/NowIndicator.d.ts +28 -0
- package/lib/typescript/module/timeline/NowIndicator.d.ts.map +1 -0
- package/lib/typescript/module/timeline/TimelineDay.d.ts +14 -0
- package/lib/typescript/module/timeline/TimelineDay.d.ts.map +1 -0
- package/lib/typescript/module/timeline/packEvents.d.ts +25 -0
- package/lib/typescript/module/timeline/packEvents.d.ts.map +1 -0
- package/lib/typescript/module/timeline/timelineGeometry.d.ts +14 -0
- package/lib/typescript/module/timeline/timelineGeometry.d.ts.map +1 -0
- package/lib/typescript/module/timeline/timelineMath.d.ts +32 -0
- package/lib/typescript/module/timeline/timelineMath.d.ts.map +1 -0
- package/lib/typescript/module/types.d.ts +237 -0
- package/lib/typescript/module/types.d.ts.map +1 -0
- package/package.json +105 -0
- package/src/agenda/AgendaBackdrop.tsx +55 -0
- package/src/agenda/AgendaList.tsx +370 -0
- package/src/agenda/AgendaSlot.tsx +88 -0
- package/src/agenda/AgendaWindow.tsx +183 -0
- package/src/agenda/StickyHeaderOverlay.tsx +126 -0
- package/src/agenda/buildAgendaLayout.ts +110 -0
- package/src/agenda/constants.ts +22 -0
- package/src/agenda/heights.ts +44 -0
- package/src/agenda/useAgendaScrollSync.ts +251 -0
- package/src/core/ArrowGlyph.tsx +53 -0
- package/src/core/CalendarContext.ts +47 -0
- package/src/core/CalendarProvider.tsx +165 -0
- package/src/core/CalendarStore.ts +64 -0
- package/src/core/KitText.tsx +10 -0
- package/src/core/TodayButton.tsx +121 -0
- package/src/core/civil.ts +92 -0
- package/src/core/dateKey.ts +52 -0
- package/src/core/motion.ts +51 -0
- package/src/core/worklets.ts +37 -0
- package/src/expandable/DayCell.tsx +97 -0
- package/src/expandable/ExpandableCalendar.tsx +278 -0
- package/src/expandable/Knob.tsx +67 -0
- package/src/expandable/MonthPager.tsx +208 -0
- package/src/expandable/WeekStrip.tsx +439 -0
- package/src/expandable/calendarCells.ts +155 -0
- package/src/expandable/geometry.ts +51 -0
- package/src/expandable/useExpandGesture.ts +147 -0
- package/src/expandable/useHorizontalPager.ts +116 -0
- package/src/index.ts +62 -0
- package/src/theme/ThemeProvider.tsx +85 -0
- package/src/theme/index.ts +18 -0
- package/src/theme/theme.ts +110 -0
- package/src/theme/tokens.ts +50 -0
- package/src/timeline/DayColumn.tsx +84 -0
- package/src/timeline/DayPager.tsx +295 -0
- package/src/timeline/EventBlock.tsx +76 -0
- package/src/timeline/GridLines.tsx +36 -0
- package/src/timeline/HourGrid.tsx +90 -0
- package/src/timeline/NowIndicator.tsx +123 -0
- package/src/timeline/TimelineDay.tsx +112 -0
- package/src/timeline/packEvents.ts +118 -0
- package/src/timeline/timelineGeometry.ts +23 -0
- package/src/timeline/timelineMath.ts +86 -0
- package/src/types.ts +252 -0
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The date owner. Compat with `react-native-calendars`' `CalendarProvider`.
|
|
3
|
+
*
|
|
4
|
+
* Two cadences: `setDate` is synchronous (day tap, Today, page settle, the `date`
|
|
5
|
+
* prop) and writes `dayIndex`; `commitDate` is the scroll path, called from a
|
|
6
|
+
* worklet at settle and per month crossing, and leaves `dayIndex` to the
|
|
7
|
+
* scroller that already owns it. Both bump `move` so the OTHER surfaces follow.
|
|
8
|
+
*
|
|
9
|
+
* The prop echo: a controlled caller mirrors every `onDateChanged` back into
|
|
10
|
+
* `date`, and a `runOnJS` commit can land between a render's commit and its
|
|
11
|
+
* effects, so "prop equals current date" is not enough (M5: a fast fling was
|
|
12
|
+
* thrown back a month as `propUpdate`). The provider queues what it emitted; a
|
|
13
|
+
* prop matching a pending emission is an echo and consumes the queue up to it.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState, type ReactNode } from 'react';
|
|
17
|
+
import { StyleSheet, View } from 'react-native';
|
|
18
|
+
import { monthOrdinalOfYmd } from './civil';
|
|
19
|
+
import { CalendarContext, CalendarDateContext, type CalendarContextValue } from './CalendarContext';
|
|
20
|
+
import { useCreateCalendarStore } from './CalendarStore';
|
|
21
|
+
import { clampIndex, dayIndexOf, ymdAt } from './dateKey';
|
|
22
|
+
import { useReduceMotion } from './motion';
|
|
23
|
+
import { TodayButton } from './TodayButton';
|
|
24
|
+
import { AgendaKitThemeProvider } from '../theme';
|
|
25
|
+
import type { AgendaKitTheme, PartialAgendaKitTheme } from '../theme';
|
|
26
|
+
import type { CalendarRange, DateString, MoveOrigin, UpdateSource } from '../types';
|
|
27
|
+
|
|
28
|
+
export type CalendarProviderProps = {
|
|
29
|
+
range: CalendarRange;
|
|
30
|
+
date: DateString;
|
|
31
|
+
onDateChanged?: (date: DateString, source: UpdateSource) => void;
|
|
32
|
+
onMonthChange?: (date: DateString, source: UpdateSource) => void;
|
|
33
|
+
showTodayButton?: boolean;
|
|
34
|
+
todayBottomMargin?: number;
|
|
35
|
+
/** Required for the Today button to render: the kit ships no strings. */
|
|
36
|
+
todayLabel?: string;
|
|
37
|
+
/**
|
|
38
|
+
* Colours and font families. A partial theme layers over `base`
|
|
39
|
+
* (`lightTheme` unless given), so `{ colors: { accent: '#0F766E' } }` is a
|
|
40
|
+
* complete override. Omit it entirely for the built-in light theme.
|
|
41
|
+
*
|
|
42
|
+
* Pass a STABLE object — a fresh literal every render rebuilds every
|
|
43
|
+
* stylesheet in the tree. Hoist it to module scope or memoise it.
|
|
44
|
+
*/
|
|
45
|
+
theme?: AgendaKitTheme | PartialAgendaKitTheme;
|
|
46
|
+
/** Which built-in a partial `theme` layers over. Pass `darkTheme` for dark mode. */
|
|
47
|
+
themeBase?: AgendaKitTheme;
|
|
48
|
+
children: ReactNode;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/** Emissions a caller may leave unechoed before the oldest is forgotten. */
|
|
52
|
+
const MAX_PENDING_ECHOES = 8;
|
|
53
|
+
|
|
54
|
+
export const CalendarProvider = ({
|
|
55
|
+
range,
|
|
56
|
+
date,
|
|
57
|
+
onDateChanged,
|
|
58
|
+
onMonthChange,
|
|
59
|
+
showTodayButton = false,
|
|
60
|
+
todayBottomMargin = 0,
|
|
61
|
+
todayLabel,
|
|
62
|
+
theme,
|
|
63
|
+
themeBase,
|
|
64
|
+
children,
|
|
65
|
+
}: CalendarProviderProps) => {
|
|
66
|
+
const [initialIndex] = useState(() => dayIndexOf(range, date));
|
|
67
|
+
const store = useCreateCalendarStore(range, initialIndex);
|
|
68
|
+
const dateRef = useRef(date);
|
|
69
|
+
const pendingEchoesRef = useRef<DateString[]>([]);
|
|
70
|
+
const reduceMotion = useReduceMotion();
|
|
71
|
+
const [committed, setCommitted] = useState(date);
|
|
72
|
+
|
|
73
|
+
// Read through a ref so a caller passing inline arrows, or the setting
|
|
74
|
+
// changing, cannot churn `setDate`'s identity — every scroller holds it.
|
|
75
|
+
const live = useRef({ onDateChanged, onMonthChange, reduceMotion });
|
|
76
|
+
live.current.onDateChanged = onDateChanged;
|
|
77
|
+
live.current.onMonthChange = onMonthChange;
|
|
78
|
+
live.current.reduceMotion = reduceMotion;
|
|
79
|
+
|
|
80
|
+
useEffect(() => {
|
|
81
|
+
if (__DEV__ && showTodayButton && !todayLabel) {
|
|
82
|
+
console.warn('[agenda-kit] showTodayButton needs todayLabel; the button is not rendered.');
|
|
83
|
+
}
|
|
84
|
+
}, [showTodayButton, todayLabel]);
|
|
85
|
+
|
|
86
|
+
const commitCore = useCallback(
|
|
87
|
+
(idx: number, source: UpdateSource, writeDayIndex: boolean, origin: MoveOrigin, animated: boolean) => {
|
|
88
|
+
const ymd = ymdAt(range, idx);
|
|
89
|
+
const prev = dateRef.current;
|
|
90
|
+
dateRef.current = ymd;
|
|
91
|
+
|
|
92
|
+
const pending = pendingEchoesRef.current;
|
|
93
|
+
pending.push(ymd);
|
|
94
|
+
if (pending.length > MAX_PENDING_ECHOES) pending.shift();
|
|
95
|
+
|
|
96
|
+
setCommitted(ymd);
|
|
97
|
+
live.current.onDateChanged?.(ymd, source);
|
|
98
|
+
if (monthOrdinalOfYmd(prev) !== monthOrdinalOfYmd(ymd)) live.current.onMonthChange?.(ymd, source);
|
|
99
|
+
|
|
100
|
+
if (writeDayIndex) store.dayIndex.value = idx;
|
|
101
|
+
store.move.value = {
|
|
102
|
+
seq: store.move.value.seq + 1,
|
|
103
|
+
idx,
|
|
104
|
+
origin,
|
|
105
|
+
animated: animated && !live.current.reduceMotion,
|
|
106
|
+
};
|
|
107
|
+
},
|
|
108
|
+
[range, store],
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
const setDate = useCallback(
|
|
112
|
+
(ymd: DateString, source: UpdateSource, origin: MoveOrigin = 'external', animated = true) => {
|
|
113
|
+
if (ymd === dateRef.current) return;
|
|
114
|
+
const idx = dayIndexOf(range, ymd);
|
|
115
|
+
if (Number.isNaN(idx)) return;
|
|
116
|
+
commitCore(clampIndex(range, idx), source, true, origin, animated);
|
|
117
|
+
},
|
|
118
|
+
[commitCore, range],
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
const commitDate = useCallback(
|
|
122
|
+
(idx: number, source: UpdateSource, origin: MoveOrigin) => {
|
|
123
|
+
const clamped = clampIndex(range, idx);
|
|
124
|
+
if (ymdAt(range, clamped) === dateRef.current) return;
|
|
125
|
+
commitCore(clamped, source, false, origin, false);
|
|
126
|
+
},
|
|
127
|
+
[commitCore, range],
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
// A layout effect runs inside the commit, which narrows the race; the queue is
|
|
131
|
+
// what makes it correct. `indexOf` consumes the EARLIEST matching emission.
|
|
132
|
+
useLayoutEffect(() => {
|
|
133
|
+
const pending = pendingEchoesRef.current;
|
|
134
|
+
const at = pending.indexOf(date);
|
|
135
|
+
if (at >= 0) {
|
|
136
|
+
pending.splice(0, at + 1);
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
setDate(date, 'propUpdate');
|
|
140
|
+
}, [date, setDate]);
|
|
141
|
+
|
|
142
|
+
const value = useMemo<CalendarContextValue>(
|
|
143
|
+
() => ({ range, store, dateRef, setDate, commitDate, reduceMotion }),
|
|
144
|
+
[range, store, setDate, commitDate, reduceMotion],
|
|
145
|
+
);
|
|
146
|
+
|
|
147
|
+
return (
|
|
148
|
+
<AgendaKitThemeProvider theme={theme} base={themeBase}>
|
|
149
|
+
<CalendarContext.Provider value={value}>
|
|
150
|
+
<CalendarDateContext.Provider value={committed}>
|
|
151
|
+
<View style={styles.wrapper}>
|
|
152
|
+
{children}
|
|
153
|
+
{showTodayButton && todayLabel ? (
|
|
154
|
+
<TodayButton label={todayLabel} bottomMargin={todayBottomMargin} />
|
|
155
|
+
) : null}
|
|
156
|
+
</View>
|
|
157
|
+
</CalendarDateContext.Provider>
|
|
158
|
+
</CalendarContext.Provider>
|
|
159
|
+
</AgendaKitThemeProvider>
|
|
160
|
+
);
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
const styles = StyleSheet.create({
|
|
164
|
+
wrapper: { flex: 1 },
|
|
165
|
+
});
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The UI-thread half of the calendar: four shared values, created once.
|
|
3
|
+
*
|
|
4
|
+
* The scroll offset owns position and `dayIndex` is derived from it on the UI
|
|
5
|
+
* thread, so the week strip, the Today button and the sticky header track a
|
|
6
|
+
* fling frame-locked. `move` carries a programmatic move with its `origin`;
|
|
7
|
+
* each scroller ignores its own origin, so a `scrollTo` never echoes back.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { useEffect, useState } from 'react';
|
|
11
|
+
import { AppState } from 'react-native';
|
|
12
|
+
import { useSharedValue, type SharedValue } from 'react-native-reanimated';
|
|
13
|
+
import { todayIndexOf } from './dateKey';
|
|
14
|
+
import type { CalendarMove, CalendarRange } from '../types';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* SHARED VALUES ONLY. Worklets that read `store.x.value` capture `store`, and
|
|
18
|
+
* react-native-worklets freezes captured objects in `__DEV__`: a plain ref in
|
|
19
|
+
* here silently ignores every write (M2: the echo guard compared against a date
|
|
20
|
+
* frozen at mount). Anything else lives on the provider and the context.
|
|
21
|
+
*/
|
|
22
|
+
export type CalendarStore = {
|
|
23
|
+
/** UI-thread truth. Written by whichever scroller owns the position. */
|
|
24
|
+
dayIndex: SharedValue<number>;
|
|
25
|
+
/** The last programmatic move. `seq` makes repeats distinct. */
|
|
26
|
+
move: SharedValue<CalendarMove>;
|
|
27
|
+
/** Index of today, refreshed across midnight and on app foreground. */
|
|
28
|
+
todayIndex: SharedValue<number>;
|
|
29
|
+
/** Bumped when a list starts a drag; only the CHANGE means anything. */
|
|
30
|
+
listDragSeq: SharedValue<number>;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const NO_MOVE: CalendarMove = { seq: 0, idx: 0, origin: 'external', animated: false };
|
|
34
|
+
|
|
35
|
+
export const useCreateCalendarStore = (range: CalendarRange, initialIndex: number): CalendarStore => {
|
|
36
|
+
const dayIndex = useSharedValue(initialIndex);
|
|
37
|
+
const move = useSharedValue<CalendarMove>(NO_MOVE);
|
|
38
|
+
const todayIndex = useSharedValue(range.todayIndex);
|
|
39
|
+
const listDragSeq = useSharedValue(0);
|
|
40
|
+
|
|
41
|
+
const { startEpochDay, days } = range;
|
|
42
|
+
useEffect(() => {
|
|
43
|
+
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
44
|
+
// One timer for the next local midnight, re-armed on foreground: a 24 h
|
|
45
|
+
// interval drifts and fires at the wrong instant after a suspend.
|
|
46
|
+
const refreshAndArm = () => {
|
|
47
|
+
todayIndex.value = todayIndexOf(startEpochDay, days);
|
|
48
|
+
if (timer) clearTimeout(timer);
|
|
49
|
+
const now = new Date();
|
|
50
|
+
const next = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1, 0, 0, 5);
|
|
51
|
+
timer = setTimeout(refreshAndArm, Math.max(1000, next.getTime() - now.getTime()));
|
|
52
|
+
};
|
|
53
|
+
refreshAndArm();
|
|
54
|
+
const sub = AppState.addEventListener('change', (state) => {
|
|
55
|
+
if (state === 'active') refreshAndArm();
|
|
56
|
+
});
|
|
57
|
+
return () => {
|
|
58
|
+
if (timer) clearTimeout(timer);
|
|
59
|
+
sub.remove();
|
|
60
|
+
};
|
|
61
|
+
}, [days, startEpochDay, todayIndex]);
|
|
62
|
+
|
|
63
|
+
return useState(() => ({ dayIndex, move, todayIndex, listDragSeq }))[0];
|
|
64
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Ref } from 'react';
|
|
2
|
+
import { Text, type TextProps } from 'react-native';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Kit text with OS scaling pinned off: row heights are declared, so scaled text
|
|
6
|
+
* would clip in its slot. `Text.defaultProps` is a no-op under React 19.
|
|
7
|
+
*/
|
|
8
|
+
export const KitText = ({ ref, ...props }: TextProps & { ref?: Ref<Text> }) => (
|
|
9
|
+
<Text ref={ref} allowFontScaling={false} maxFontSizeMultiplier={1} {...props} />
|
|
10
|
+
);
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Today pill, visible whenever the calendar is not on today: centred, with an
|
|
3
|
+
* arrow pointing the way back to today (the owner's Teams reference, 2026-09-11).
|
|
4
|
+
*
|
|
5
|
+
* Visibility and the arrow's direction are derived on the UI thread from
|
|
6
|
+
* `dayIndex` and `todayIndex`, so the pill appears the frame a fling leaves today
|
|
7
|
+
* and the arrow flips with no React commit. The show/hide animation starts from a
|
|
8
|
+
* reaction that fires only when the boolean flips — `withTiming` returned from
|
|
9
|
+
* `useAnimatedStyle` would restart on every frame of a fling. Hidden means
|
|
10
|
+
* translated off the bottom edge: a transparent pill would still swallow taps.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { useKitStyles, useKitTheme, type KitStyleArgs } from '../theme';
|
|
14
|
+
import { ANIMATION, FONT_SIZE, RADIUS, SPACING } from '../theme/tokens';
|
|
15
|
+
import { memo, useCallback, useMemo } from 'react';
|
|
16
|
+
import { Pressable, StyleSheet } from 'react-native';
|
|
17
|
+
import Animated, {
|
|
18
|
+
useAnimatedReaction,
|
|
19
|
+
useAnimatedStyle,
|
|
20
|
+
useSharedValue,
|
|
21
|
+
withTiming,
|
|
22
|
+
} from 'react-native-reanimated';
|
|
23
|
+
import { ArrowGlyph } from './ArrowGlyph';
|
|
24
|
+
import { useCalendarContext } from './CalendarContext';
|
|
25
|
+
import { dayIndexOf, ymdAt } from './dateKey';
|
|
26
|
+
import { KitText } from './KitText';
|
|
27
|
+
import { KIT_EASING, kitDuration } from './motion';
|
|
28
|
+
|
|
29
|
+
/** The library's non-tablet `todayButton.height`. */
|
|
30
|
+
const BUTTON_HEIGHT = 28;
|
|
31
|
+
const ARROW_SIZE = 14;
|
|
32
|
+
|
|
33
|
+
type Props = {
|
|
34
|
+
label: string;
|
|
35
|
+
bottomMargin?: number;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const TodayButtonInner = ({ label, bottomMargin = 0 }: Props) => {
|
|
39
|
+
const styles = useKitStyles(makeStyles);
|
|
40
|
+
const { colors } = useKitTheme();
|
|
41
|
+
const { range, store, dateRef, setDate, reduceMotion } = useCalendarContext();
|
|
42
|
+
const duration = kitDuration(ANIMATION.base, reduceMotion);
|
|
43
|
+
const hiddenOffset = bottomMargin + BUTTON_HEIGHT + SPACING[5];
|
|
44
|
+
|
|
45
|
+
// Mount-time seed from plain values (reading a shared value in render is
|
|
46
|
+
// unsupported); the reaction owns every change after that.
|
|
47
|
+
const shown = useSharedValue(
|
|
48
|
+
range.todayIndex >= 0 && dayIndexOf(range, dateRef.current) !== range.todayIndex ? 1 : 0,
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
useAnimatedReaction(
|
|
52
|
+
() => {
|
|
53
|
+
const today = store.todayIndex.value;
|
|
54
|
+
return today >= 0 && store.dayIndex.value !== today ? 1 : 0;
|
|
55
|
+
},
|
|
56
|
+
(next, prev) => {
|
|
57
|
+
if (next === prev) return;
|
|
58
|
+
shown.value = withTiming(next, { duration, easing: KIT_EASING });
|
|
59
|
+
},
|
|
60
|
+
[duration],
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
const animatedStyle = useAnimatedStyle(() => ({
|
|
64
|
+
opacity: shown.value,
|
|
65
|
+
transform: [{ translateY: (1 - shown.value) * hiddenOffset }],
|
|
66
|
+
}));
|
|
67
|
+
// Up when today lies above the list's day, down when below.
|
|
68
|
+
const arrowStyle = useAnimatedStyle(() => ({
|
|
69
|
+
transform: [{ rotate: store.todayIndex.value < store.dayIndex.value ? '0deg' : '180deg' }],
|
|
70
|
+
}));
|
|
71
|
+
|
|
72
|
+
const onPress = useCallback(() => {
|
|
73
|
+
const today = store.todayIndex.value;
|
|
74
|
+
if (today >= 0) setDate(ymdAt(range, today), 'todayPress');
|
|
75
|
+
}, [range, setDate, store]);
|
|
76
|
+
|
|
77
|
+
const containerStyle = useMemo(
|
|
78
|
+
() => [styles.container, { bottom: bottomMargin }, animatedStyle],
|
|
79
|
+
[animatedStyle, bottomMargin, styles.container],
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
return (
|
|
83
|
+
<Animated.View pointerEvents="box-none" style={containerStyle}>
|
|
84
|
+
<Pressable
|
|
85
|
+
style={styles.button}
|
|
86
|
+
onPress={onPress}
|
|
87
|
+
hitSlop={8}
|
|
88
|
+
accessibilityRole="button"
|
|
89
|
+
accessibilityLabel={label}
|
|
90
|
+
>
|
|
91
|
+
<Animated.View style={arrowStyle}>
|
|
92
|
+
<ArrowGlyph size={ARROW_SIZE} color={colors.accent} />
|
|
93
|
+
</Animated.View>
|
|
94
|
+
<KitText style={styles.label} numberOfLines={1}>
|
|
95
|
+
{label}
|
|
96
|
+
</KitText>
|
|
97
|
+
</Pressable>
|
|
98
|
+
</Animated.View>
|
|
99
|
+
);
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
export const TodayButton = memo(TodayButtonInner);
|
|
103
|
+
TodayButton.displayName = 'TodayButton';
|
|
104
|
+
|
|
105
|
+
const makeStyles = ({ colors, fonts }: KitStyleArgs) =>
|
|
106
|
+
StyleSheet.create({
|
|
107
|
+
container: { position: 'absolute', left: 0, right: 0, alignItems: 'center' },
|
|
108
|
+
button: {
|
|
109
|
+
height: BUTTON_HEIGHT,
|
|
110
|
+
flexDirection: 'row',
|
|
111
|
+
alignItems: 'center',
|
|
112
|
+
gap: SPACING[1],
|
|
113
|
+
paddingHorizontal: SPACING[3],
|
|
114
|
+
borderRadius: RADIUS.full,
|
|
115
|
+
borderWidth: 1,
|
|
116
|
+
borderColor: colors.border,
|
|
117
|
+
backgroundColor: colors.surface,
|
|
118
|
+
},
|
|
119
|
+
// An action's label: accent INK, never a fill.
|
|
120
|
+
label: { fontFamily: fonts.medium, fontSize: FONT_SIZE.sm, color: colors.accent },
|
|
121
|
+
});
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Integer civil-date arithmetic: no `Date`, no string splitting, no timezone.
|
|
3
|
+
*
|
|
4
|
+
* An epoch day is the count of days since 1970-01-01 in the proleptic Gregorian
|
|
5
|
+
* calendar. Calendar days are integers here, so a DST transition cannot make two
|
|
6
|
+
* days 23 or 25 hours apart — the bug a `(a - b) / 86400000` calendar has twice
|
|
7
|
+
* a year. Algorithms: H. Hinnant, "chrono-Compatible Low-Level Date Algorithms".
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/** Epoch day of a civil date. `m` is 1–12. */
|
|
11
|
+
export const epochDayOf = (y: number, m: number, d: number): number => {
|
|
12
|
+
const yy = m <= 2 ? y - 1 : y;
|
|
13
|
+
const era = Math.floor(yy / 400);
|
|
14
|
+
const yoe = yy - era * 400;
|
|
15
|
+
const doy = Math.floor((153 * ((m + 9) % 12) + 2) / 5) + d - 1;
|
|
16
|
+
const doe = yoe * 365 + Math.floor(yoe / 4) - Math.floor(yoe / 100) + doy;
|
|
17
|
+
return era * 146097 + doe - 719468;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/** Civil date of an epoch day, packed as YYYYMMDD so nothing is allocated. */
|
|
21
|
+
export const civilOf = (z: number): number => {
|
|
22
|
+
const zz = z + 719468;
|
|
23
|
+
const era = Math.floor(zz / 146097);
|
|
24
|
+
const doe = zz - era * 146097;
|
|
25
|
+
const yoe = Math.floor(
|
|
26
|
+
(doe - Math.floor(doe / 1460) + Math.floor(doe / 36524) - Math.floor(doe / 146096)) / 365,
|
|
27
|
+
);
|
|
28
|
+
const doy = doe - (365 * yoe + Math.floor(yoe / 4) - Math.floor(yoe / 100));
|
|
29
|
+
const mp = Math.floor((5 * doy + 2) / 153);
|
|
30
|
+
const d = doy - Math.floor((153 * mp + 2) / 5) + 1;
|
|
31
|
+
const m = mp < 10 ? mp + 3 : mp - 9;
|
|
32
|
+
return (yoe + era * 400 + (m <= 2 ? 1 : 0)) * 10000 + m * 100 + d;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
/** 0 = Sunday … 6 = Saturday, as `Date#getDay`. 1970-01-01 was a Thursday. */
|
|
36
|
+
export const weekdayOf = (z: number): number => (((z + 4) % 7) + 7) % 7;
|
|
37
|
+
|
|
38
|
+
const isLeap = (y: number): boolean => (y % 4 === 0 && y % 100 !== 0) || y % 400 === 0;
|
|
39
|
+
const MONTH_DAYS = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
|
40
|
+
|
|
41
|
+
export const daysInMonth = (y: number, m: number): number =>
|
|
42
|
+
m === 2 && isLeap(y) ? 29 : MONTH_DAYS[m - 1];
|
|
43
|
+
|
|
44
|
+
/** '00'…'31', so formatting never calls `padStart` or builds a template per part. */
|
|
45
|
+
const TWO_DIGIT: readonly string[] = Array.from({ length: 32 }, (_, i) => (i < 10 ? `0${i}` : `${i}`));
|
|
46
|
+
|
|
47
|
+
/** 'YYYY-MM-DD' of an epoch day. */
|
|
48
|
+
export const ymdOfEpochDay = (z: number): string => {
|
|
49
|
+
const c = civilOf(z);
|
|
50
|
+
const y = Math.floor(c / 10000);
|
|
51
|
+
return `${y}-${TWO_DIGIT[Math.floor(c / 100) % 100]}-${TWO_DIGIT[c % 100]}`;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const digit = (s: string, i: number): number => {
|
|
55
|
+
const c = s.charCodeAt(i) - 48;
|
|
56
|
+
return c >= 0 && c <= 9 ? c : NaN;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
/** Epoch day of 'YYYY-MM-DD' (anything after position 10 is ignored); NaN if malformed. */
|
|
60
|
+
export const epochDayOfYmd = (s: string): number => {
|
|
61
|
+
if (s.length < 10) return NaN;
|
|
62
|
+
const y = digit(s, 0) * 1000 + digit(s, 1) * 100 + digit(s, 2) * 10 + digit(s, 3);
|
|
63
|
+
const m = digit(s, 5) * 10 + digit(s, 6);
|
|
64
|
+
const d = digit(s, 8) * 10 + digit(s, 9);
|
|
65
|
+
return epochDayOf(y, m, d);
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
/** y·12 + (m − 1) of 'YYYY-MM-DD' — a month ordinal that orders and subtracts. */
|
|
69
|
+
export const monthOrdinalOfYmd = (s: string): number =>
|
|
70
|
+
(digit(s, 0) * 1000 + digit(s, 1) * 100 + digit(s, 2) * 10 + digit(s, 3)) * 12 +
|
|
71
|
+
digit(s, 5) * 10 +
|
|
72
|
+
digit(s, 6) -
|
|
73
|
+
1;
|
|
74
|
+
|
|
75
|
+
/** Epoch day of a `Date`'s LOCAL calendar day. The one bridge from `Date`. */
|
|
76
|
+
export const epochDayOfDate = (d: Date): number =>
|
|
77
|
+
epochDayOf(d.getFullYear(), d.getMonth() + 1, d.getDate());
|
|
78
|
+
|
|
79
|
+
let today = { epochDay: 0, validUntilMs: 0 };
|
|
80
|
+
|
|
81
|
+
/** Today's epoch day. Cached until local midnight: a hot call is one `Date.now()`, no allocation. */
|
|
82
|
+
export const todayEpochDay = (): number => {
|
|
83
|
+
const now = Date.now();
|
|
84
|
+
if (now >= today.validUntilMs) {
|
|
85
|
+
const d = new Date(now);
|
|
86
|
+
today = {
|
|
87
|
+
epochDay: epochDayOfDate(d),
|
|
88
|
+
validUntilMs: new Date(d.getFullYear(), d.getMonth(), d.getDate() + 1).getTime(),
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
return today.epochDay;
|
|
92
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one translation between the kit's integer index space and 'YYYY-MM-DD'.
|
|
3
|
+
*
|
|
4
|
+
* Every surface addresses a day as `dayIndex`, an offset from `range.start`.
|
|
5
|
+
* `buildRange` pays for the strings once; after that both directions are O(1)
|
|
6
|
+
* and allocation-free: `dayIndexOf` is a subtraction, `ymdAt` an array read.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { epochDayOfDate, epochDayOfYmd, todayEpochDay, weekdayOf, ymdOfEpochDay } from './civil';
|
|
10
|
+
import type { CalendarRange, DateString } from '../types';
|
|
11
|
+
|
|
12
|
+
/** Index of `ymd` within `range`. May fall outside `[0, days)`; NaN if malformed. */
|
|
13
|
+
export const dayIndexOf = (range: CalendarRange, ymd: DateString): number =>
|
|
14
|
+
epochDayOfYmd(ymd) - range.startEpochDay;
|
|
15
|
+
|
|
16
|
+
/** 'YYYY-MM-DD' at `idx`. Defined for any integer; callers clamp first. */
|
|
17
|
+
export const ymdAt = (range: CalendarRange, idx: number): DateString =>
|
|
18
|
+
range.ymdByIndex[idx] ?? ymdOfEpochDay(range.startEpochDay + idx);
|
|
19
|
+
|
|
20
|
+
/** The single gating predicate: an index is selectable iff clamping leaves it alone. */
|
|
21
|
+
export const clampIndex = (range: CalendarRange, idx: number): number =>
|
|
22
|
+
idx < range.minIndex ? range.minIndex : idx > range.maxIndex ? range.maxIndex : idx;
|
|
23
|
+
|
|
24
|
+
export const todayIndexOf = (startEpochDay: number, days: number): number => {
|
|
25
|
+
const i = todayEpochDay() - startEpochDay;
|
|
26
|
+
return i >= 0 && i < days ? i : -1;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* `start` is pushed back to the `firstDay` week boundary and `days` rounded up
|
|
31
|
+
* to whole weeks, so `floor(dayIndex / 7)` is always a week page.
|
|
32
|
+
*/
|
|
33
|
+
export const buildRange = (minDate: Date, maxDate: Date, firstDay: number = 1): CalendarRange => {
|
|
34
|
+
const min = epochDayOfDate(minDate);
|
|
35
|
+
const max = epochDayOfDate(maxDate);
|
|
36
|
+
const startEpochDay = min - ((weekdayOf(min) - firstDay + 7) % 7);
|
|
37
|
+
const days = Math.ceil((max - startEpochDay + 1) / 7) * 7;
|
|
38
|
+
|
|
39
|
+
const ymdByIndex = new Array<DateString>(days);
|
|
40
|
+
for (let i = 0; i < days; i += 1) ymdByIndex[i] = ymdOfEpochDay(startEpochDay + i);
|
|
41
|
+
|
|
42
|
+
return {
|
|
43
|
+
start: ymdByIndex[0],
|
|
44
|
+
startEpochDay,
|
|
45
|
+
ymdByIndex,
|
|
46
|
+
days,
|
|
47
|
+
minIndex: min - startEpochDay,
|
|
48
|
+
maxIndex: max - startEpochDay,
|
|
49
|
+
firstDay,
|
|
50
|
+
todayIndex: todayIndexOf(startEpochDay, days),
|
|
51
|
+
};
|
|
52
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The kit's motion inputs and the two accessibility flags it obeys.
|
|
3
|
+
*
|
|
4
|
+
* Durations come from `theme/tokens` (`ANIMATION.fast/base/slow`). They are
|
|
5
|
+
* module constants, not themeable: `KIT_EASING` is captured by worklets at
|
|
6
|
+
* module scope and so cannot read a React context.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { EASING } from '../theme/tokens';
|
|
10
|
+
import { useEffect, useState } from 'react';
|
|
11
|
+
import { AccessibilityInfo, type AccessibilityChangeEventName } from 'react-native';
|
|
12
|
+
import { Easing } from 'react-native-reanimated';
|
|
13
|
+
|
|
14
|
+
export const KIT_EASING = Easing.bezier(...EASING.bezier);
|
|
15
|
+
|
|
16
|
+
/** Reanimated treats `duration: 0` as an immediate set, so a snap stays a snap. */
|
|
17
|
+
export const kitDuration = (ms: number, reduced: boolean): number => (reduced ? 0 : ms);
|
|
18
|
+
|
|
19
|
+
/** A platform that cannot answer gets the default: full motion, visual calendar. */
|
|
20
|
+
const useA11yFlag = (read: () => Promise<boolean>, event: AccessibilityChangeEventName): boolean => {
|
|
21
|
+
const [on, setOn] = useState(false);
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
let alive = true;
|
|
24
|
+
read()
|
|
25
|
+
.then((value) => {
|
|
26
|
+
if (alive) setOn(value);
|
|
27
|
+
})
|
|
28
|
+
.catch(() => undefined);
|
|
29
|
+
const sub = AccessibilityInfo.addEventListener(event, (value) => {
|
|
30
|
+
if (alive) setOn(Boolean(value));
|
|
31
|
+
});
|
|
32
|
+
return () => {
|
|
33
|
+
alive = false;
|
|
34
|
+
sub.remove();
|
|
35
|
+
};
|
|
36
|
+
}, [read, event]);
|
|
37
|
+
return on;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const readReduceMotion = () => AccessibilityInfo.isReduceMotionEnabled();
|
|
41
|
+
const readScreenReader = () => AccessibilityInfo.isScreenReaderEnabled();
|
|
42
|
+
|
|
43
|
+
/** Subscribe ONCE per tree: the provider reads it and publishes it on the context. */
|
|
44
|
+
export const useReduceMotion = (): boolean => useA11yFlag(readReduceMotion, 'reduceMotionChanged');
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* TalkBack does not see opacity, so the stacked week strip and month grid would
|
|
48
|
+
* both be read. `ExpandableCalendar` renders a static grid while this is true.
|
|
49
|
+
*/
|
|
50
|
+
export const useScreenReaderEnabled = (): boolean =>
|
|
51
|
+
useA11yFlag(readScreenReader, 'screenReaderChanged');
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Module-scope `'worklet'` helpers. The babel plugin workletizes a top-level
|
|
3
|
+
* function with the directive unconditionally; inside a hook call it depends on
|
|
4
|
+
* configuration (`hooks/useChromeScrub.ts:24-39`).
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Largest `i` with `offsets[i] <= y`, or 0. `offsets` is a strictly increasing
|
|
9
|
+
* prefix-sum table, so the search is exact and allocation-free.
|
|
10
|
+
*/
|
|
11
|
+
export const bsearchLE = (offsets: readonly number[], y: number): number => {
|
|
12
|
+
'worklet';
|
|
13
|
+
let lo = 0;
|
|
14
|
+
let hi = offsets.length - 1;
|
|
15
|
+
if (hi < 0 || y <= offsets[0]) return 0;
|
|
16
|
+
if (y >= offsets[hi]) return hi;
|
|
17
|
+
while (lo < hi) {
|
|
18
|
+
// Upper mid, so the loop converges on the LAST index satisfying the predicate.
|
|
19
|
+
const mid = (lo + hi + 1) >> 1;
|
|
20
|
+
if (offsets[mid] <= y) lo = mid;
|
|
21
|
+
else hi = mid - 1;
|
|
22
|
+
}
|
|
23
|
+
return lo;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export const clampNum = (v: number, lo: number, hi: number): number => {
|
|
27
|
+
'worklet';
|
|
28
|
+
return v < lo ? lo : v > hi ? hi : v;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
// Without the worklets babel plugin every scroll handler silently runs on the JS
|
|
32
|
+
// thread; the only symptom would be the jank the kit exists to remove.
|
|
33
|
+
if (__DEV__ && (clampNum as unknown as { __workletHash?: unknown }).__workletHash === undefined) {
|
|
34
|
+
console.error(
|
|
35
|
+
'[agenda-kit] worklet helpers are not workletized — the worklets babel plugin did not run over this package. Metro must apply babel to node_modules.',
|
|
36
|
+
);
|
|
37
|
+
}
|