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,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Drag the calendar open and closed. `progress` moves (0 closed, 1 open); every
|
|
3
|
+
* layer reads it as a transform or opacity. Follows `ChartSheet.tsx`: remember
|
|
4
|
+
* where this drag began, clamp while dragging, land on an end. `activeOffsetY(±8)`
|
|
5
|
+
* and `failOffsetX(±12)` settle the axis against the horizontal pagers inside the
|
|
6
|
+
* same detector within the first few pixels.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { ANIMATION } from '../theme/tokens';
|
|
10
|
+
import { useCallback, useMemo } from 'react';
|
|
11
|
+
import { Gesture } from 'react-native-gesture-handler';
|
|
12
|
+
import {
|
|
13
|
+
cancelAnimation,
|
|
14
|
+
useSharedValue,
|
|
15
|
+
withTiming,
|
|
16
|
+
type SharedValue,
|
|
17
|
+
} from 'react-native-reanimated';
|
|
18
|
+
import { runOnJS, runOnUI } from 'react-native-worklets';
|
|
19
|
+
import { KIT_EASING } from '../core/motion';
|
|
20
|
+
import { clampNum } from '../core/worklets';
|
|
21
|
+
import { PAN_THRESHOLD, SNAP_VELOCITY } from './geometry';
|
|
22
|
+
|
|
23
|
+
type OnToggled = (isOpen: boolean) => void;
|
|
24
|
+
|
|
25
|
+
const finish = (lastReported: SharedValue<number>, target: 0 | 1, onToggled: OnToggled) => {
|
|
26
|
+
'worklet';
|
|
27
|
+
if (lastReported.value === target) return;
|
|
28
|
+
lastReported.value = target;
|
|
29
|
+
runOnJS(onToggled)(target === 1);
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Snap to an end and report a CHANGE of end once it lands. Module scope, so the
|
|
34
|
+
* plugin workletizes it unconditionally. The duration scales with the distance
|
|
35
|
+
* left, so a release two pixels from open does not take the full animation.
|
|
36
|
+
*/
|
|
37
|
+
export const snap = (
|
|
38
|
+
progress: SharedValue<number>,
|
|
39
|
+
lastReported: SharedValue<number>,
|
|
40
|
+
target: 0 | 1,
|
|
41
|
+
reduceMotion: boolean,
|
|
42
|
+
onToggled: OnToggled,
|
|
43
|
+
) => {
|
|
44
|
+
'worklet';
|
|
45
|
+
if (progress.value === target) {
|
|
46
|
+
finish(lastReported, target, onToggled);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
const duration = reduceMotion
|
|
50
|
+
? 0
|
|
51
|
+
: clampNum(Math.abs(target - progress.value) * ANIMATION.slow, ANIMATION.base, ANIMATION.slow);
|
|
52
|
+
progress.value = withTiming(target, { duration, easing: KIT_EASING }, (done) => {
|
|
53
|
+
'worklet';
|
|
54
|
+
if (done) finish(lastReported, target, onToggled);
|
|
55
|
+
});
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
type Params = {
|
|
59
|
+
progress: SharedValue<number>;
|
|
60
|
+
/** Open − closed height of the visible month, px. */
|
|
61
|
+
travel: SharedValue<number>;
|
|
62
|
+
enabled: boolean;
|
|
63
|
+
openThreshold?: number;
|
|
64
|
+
closeThreshold?: number;
|
|
65
|
+
reduceMotion: boolean;
|
|
66
|
+
/** The starting end — passed in rather than read from `progress.value` during render. */
|
|
67
|
+
initialOpen: boolean;
|
|
68
|
+
/** Identity-stable: the gesture's worklets capture it. */
|
|
69
|
+
onToggled: OnToggled;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
export const useExpandGesture = ({
|
|
73
|
+
progress,
|
|
74
|
+
travel,
|
|
75
|
+
enabled,
|
|
76
|
+
openThreshold = PAN_THRESHOLD,
|
|
77
|
+
closeThreshold = PAN_THRESHOLD,
|
|
78
|
+
reduceMotion,
|
|
79
|
+
initialOpen,
|
|
80
|
+
onToggled,
|
|
81
|
+
}: Params) => {
|
|
82
|
+
const start = useSharedValue(0);
|
|
83
|
+
/** 1 once `onEnd` ran for this gesture, so `onFinalize` does not snap twice. */
|
|
84
|
+
const ended = useSharedValue(0);
|
|
85
|
+
/** The end last reported: `onToggled` fires on a change only. */
|
|
86
|
+
const lastReported = useSharedValue(initialOpen ? 1 : 0);
|
|
87
|
+
|
|
88
|
+
const pan = useMemo(
|
|
89
|
+
() =>
|
|
90
|
+
Gesture.Pan()
|
|
91
|
+
.enabled(enabled)
|
|
92
|
+
.activeOffsetY([-8, 8])
|
|
93
|
+
.failOffsetX([-12, 12])
|
|
94
|
+
.onBegin(() => {
|
|
95
|
+
'worklet';
|
|
96
|
+
// Catch the calendar mid-snap rather than letting it finish under the finger.
|
|
97
|
+
cancelAnimation(progress);
|
|
98
|
+
start.value = progress.value;
|
|
99
|
+
ended.value = 0;
|
|
100
|
+
})
|
|
101
|
+
.onUpdate((e) => {
|
|
102
|
+
'worklet';
|
|
103
|
+
// Closed and dragging up: hold at 0, which reads as the end of the travel.
|
|
104
|
+
if (start.value === 0 && e.translationY < 0) {
|
|
105
|
+
progress.value = 0;
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
progress.value = clampNum(start.value + e.translationY / travel.value, 0, 1);
|
|
109
|
+
})
|
|
110
|
+
.onEnd((e) => {
|
|
111
|
+
'worklet';
|
|
112
|
+
ended.value = 1;
|
|
113
|
+
const deltaPx = (progress.value - start.value) * travel.value;
|
|
114
|
+
let target: 0 | 1;
|
|
115
|
+
if (Math.abs(e.velocityY) > SNAP_VELOCITY) {
|
|
116
|
+
target = e.velocityY > 0 ? 1 : 0;
|
|
117
|
+
} else if (start.value < 0.5) {
|
|
118
|
+
target = deltaPx > openThreshold ? 1 : 0;
|
|
119
|
+
} else {
|
|
120
|
+
target = -deltaPx > closeThreshold ? 0 : 1;
|
|
121
|
+
}
|
|
122
|
+
snap(progress, lastReported, target, reduceMotion, onToggled);
|
|
123
|
+
})
|
|
124
|
+
.onFinalize(() => {
|
|
125
|
+
'worklet';
|
|
126
|
+
if (ended.value === 1) return;
|
|
127
|
+
// Cancelled before activating (a day tap, a pager claiming the touch):
|
|
128
|
+
// land on the nearer end rather than freezing where `onBegin` caught it.
|
|
129
|
+
snap(progress, lastReported, progress.value >= 0.5 ? 1 : 0, reduceMotion, onToggled);
|
|
130
|
+
}),
|
|
131
|
+
// Shared values are stable for the hook's life; only these rebuild the gesture.
|
|
132
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
133
|
+
[closeThreshold, enabled, onToggled, openThreshold, reduceMotion],
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
/** `undefined` toggles. Returns the end moved TO — the library's `toggleCalendarPosition` contract. */
|
|
137
|
+
const snapTo = useCallback(
|
|
138
|
+
(target?: 0 | 1): boolean => {
|
|
139
|
+
const to: 0 | 1 = target ?? (progress.value >= 0.5 ? 0 : 1);
|
|
140
|
+
runOnUI(snap)(progress, lastReported, to, reduceMotion, onToggled);
|
|
141
|
+
return to === 1;
|
|
142
|
+
},
|
|
143
|
+
[lastReported, onToggled, progress, reduceMotion],
|
|
144
|
+
);
|
|
145
|
+
|
|
146
|
+
return { pan, snapTo, lastReported };
|
|
147
|
+
};
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The month pager's horizontal paging over the kit's index space. The week strip
|
|
3
|
+
* shared it until it became a vertical tape (2026-09-11).
|
|
4
|
+
*
|
|
5
|
+
* A programmatic move pages to its day instantly; moves stamped with the pager's
|
|
6
|
+
* own `origin` are ignored. A doctor's swipe commits at momentum end, and only
|
|
7
|
+
* when it left its start page.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
11
|
+
import type Animated from 'react-native-reanimated';
|
|
12
|
+
import {
|
|
13
|
+
scrollTo,
|
|
14
|
+
useAnimatedReaction,
|
|
15
|
+
useAnimatedRef,
|
|
16
|
+
useAnimatedScrollHandler,
|
|
17
|
+
useSharedValue,
|
|
18
|
+
type AnimatedRef,
|
|
19
|
+
type SharedValue,
|
|
20
|
+
} from 'react-native-reanimated';
|
|
21
|
+
import { runOnJS, runOnUI } from 'react-native-worklets';
|
|
22
|
+
import { useCalendarContext } from '../core/CalendarContext';
|
|
23
|
+
import type { MoveOrigin } from '../types';
|
|
24
|
+
|
|
25
|
+
/** The pager reads only drag begin and momentum end; the scroll events between are waste. */
|
|
26
|
+
export const PAGER_SCROLL_THROTTLE = 100;
|
|
27
|
+
|
|
28
|
+
export type HorizontalPagerParams = {
|
|
29
|
+
width: number;
|
|
30
|
+
initialPage: number;
|
|
31
|
+
origin: MoveOrigin;
|
|
32
|
+
/** Worklet, identity-stable: the page that shows day index `idx`. */
|
|
33
|
+
pageOf: (idx: number) => number;
|
|
34
|
+
/** The page shown or headed to, when the caller needs to read it; the hook owns one otherwise. */
|
|
35
|
+
page?: SharedValue<number>;
|
|
36
|
+
/** JS, identity-stable: the doctor's own swipe settled on a different page. */
|
|
37
|
+
onSettled: (page: number) => void;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
/** A new width moved every page: land back on the one that was showing. */
|
|
41
|
+
const reland = (
|
|
42
|
+
ref: AnimatedRef<Animated.ScrollView>,
|
|
43
|
+
widthSV: SharedValue<number>,
|
|
44
|
+
page: SharedValue<number>,
|
|
45
|
+
ready: SharedValue<number>,
|
|
46
|
+
width: number,
|
|
47
|
+
) => {
|
|
48
|
+
'worklet';
|
|
49
|
+
widthSV.value = width;
|
|
50
|
+
if (ready.value === 1) scrollTo(ref, page.value * width, 0, false);
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export const useHorizontalPager = ({
|
|
54
|
+
width,
|
|
55
|
+
initialPage,
|
|
56
|
+
origin,
|
|
57
|
+
pageOf,
|
|
58
|
+
page: callerPage,
|
|
59
|
+
onSettled,
|
|
60
|
+
}: HorizontalPagerParams) => {
|
|
61
|
+
const { store } = useCalendarContext();
|
|
62
|
+
const ref = useAnimatedRef<Animated.ScrollView>();
|
|
63
|
+
const widthSV = useSharedValue(width);
|
|
64
|
+
const ownPage = useSharedValue(initialPage);
|
|
65
|
+
const page = callerPage ?? ownPage;
|
|
66
|
+
const dragStartPage = useSharedValue(0);
|
|
67
|
+
const userDriven = useSharedValue(0);
|
|
68
|
+
const ready = useSharedValue(0);
|
|
69
|
+
|
|
70
|
+
// Read once: the native ScrollView re-applies `contentOffset` whenever its value
|
|
71
|
+
// changes, which would throw the pager back to its mount page on a width change.
|
|
72
|
+
const [contentOffset] = useState(() => ({ x: initialPage * width, y: 0 }));
|
|
73
|
+
const laidOutWidth = useRef(width);
|
|
74
|
+
useEffect(() => {
|
|
75
|
+
if (laidOutWidth.current === width) return;
|
|
76
|
+
laidOutWidth.current = width;
|
|
77
|
+
runOnUI(reland)(ref, widthSV, page, ready, width);
|
|
78
|
+
}, [page, ready, ref, width, widthSV]);
|
|
79
|
+
|
|
80
|
+
const onLayout = useCallback(() => {
|
|
81
|
+
ready.value = 1;
|
|
82
|
+
}, [ready]);
|
|
83
|
+
|
|
84
|
+
const move = store.move;
|
|
85
|
+
|
|
86
|
+
useAnimatedReaction(
|
|
87
|
+
() => move.value.seq,
|
|
88
|
+
(seq, prev) => {
|
|
89
|
+
if (prev === null || seq === prev) return;
|
|
90
|
+
const m = move.value;
|
|
91
|
+
if (m.origin === origin) return;
|
|
92
|
+
const target = pageOf(m.idx);
|
|
93
|
+
if (page.value !== target) page.value = target;
|
|
94
|
+
if (ready.value === 1) {
|
|
95
|
+
userDriven.value = 0;
|
|
96
|
+
scrollTo(ref, target * widthSV.value, 0, false);
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
const onScroll = useAnimatedScrollHandler({
|
|
102
|
+
onBeginDrag: () => {
|
|
103
|
+
userDriven.value = 1;
|
|
104
|
+
dragStartPage.value = page.value;
|
|
105
|
+
},
|
|
106
|
+
onMomentumEnd: (e) => {
|
|
107
|
+
const landed = Math.round(e.contentOffset.x / widthSV.value);
|
|
108
|
+
const wasUser = userDriven.value === 1;
|
|
109
|
+
userDriven.value = 0;
|
|
110
|
+
if (page.value !== landed) page.value = landed;
|
|
111
|
+
if (wasUser && landed !== dragStartPage.value) runOnJS(onSettled)(landed);
|
|
112
|
+
},
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
return { ref, onScroll, onLayout, contentOffset, widthSV };
|
|
116
|
+
};
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* react-native-agenda-kit — the one barrel.
|
|
3
|
+
*
|
|
4
|
+
* Three surfaces (`ExpandableCalendar`, `AgendaList`, `TimelineList`) sharing
|
|
5
|
+
* one date owner (`CalendarProvider`) and one integer index space. The kit
|
|
6
|
+
* fetches nothing, knows no domain type, and reads only its own theme:
|
|
7
|
+
* everything domain-shaped arrives as a render prop or a primitive.
|
|
8
|
+
*
|
|
9
|
+
* Every scroll handler depends on the worklets babel plugin (shipped inside
|
|
10
|
+
* `babel-preset-expo`, or added manually via `react-native-worklets/plugin`);
|
|
11
|
+
* `core/worklets.ts` asserts it in DEV.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/* ── Components ────────────────────────────────────────────────────────── */
|
|
15
|
+
export { AgendaList } from './agenda/AgendaList';
|
|
16
|
+
export { CalendarProvider, type CalendarProviderProps } from './core/CalendarProvider';
|
|
17
|
+
export { ExpandableCalendar } from './expandable/ExpandableCalendar';
|
|
18
|
+
export { TimelineList } from './timeline/TimelineDay';
|
|
19
|
+
export { KitText } from './core/KitText';
|
|
20
|
+
|
|
21
|
+
/* ── Building a range, and reading the current date ────────────────────── */
|
|
22
|
+
export { buildRange, clampIndex, dayIndexOf, todayIndexOf, ymdAt } from './core/dateKey';
|
|
23
|
+
export { useCalendarDate } from './core/CalendarContext';
|
|
24
|
+
export { epochDayOfYmd, todayEpochDay, ymdOfEpochDay } from './core/civil';
|
|
25
|
+
|
|
26
|
+
/* ── Theme ─────────────────────────────────────────────────────────────── */
|
|
27
|
+
export {
|
|
28
|
+
AgendaKitThemeProvider,
|
|
29
|
+
darkTheme,
|
|
30
|
+
lightTheme,
|
|
31
|
+
resolveTheme,
|
|
32
|
+
useKitTheme,
|
|
33
|
+
type AgendaKitColors,
|
|
34
|
+
type AgendaKitFonts,
|
|
35
|
+
type AgendaKitTheme,
|
|
36
|
+
type AgendaKitThemeProviderProps,
|
|
37
|
+
type PartialAgendaKitTheme,
|
|
38
|
+
} from './theme';
|
|
39
|
+
/** Static metrics the kit lays out with. Read them; they are not themeable. */
|
|
40
|
+
export { ANIMATION, EASING, FONT_SIZE, RADIUS, SPACING } from './theme/tokens';
|
|
41
|
+
|
|
42
|
+
/* ── Types ─────────────────────────────────────────────────────────────── */
|
|
43
|
+
export { UpdateSources } from './types';
|
|
44
|
+
export type {
|
|
45
|
+
AgendaListProps,
|
|
46
|
+
AgendaListRef,
|
|
47
|
+
AgendaSection,
|
|
48
|
+
AvailableHours,
|
|
49
|
+
CalendarMove,
|
|
50
|
+
CalendarPosition,
|
|
51
|
+
CalendarRange,
|
|
52
|
+
DateString,
|
|
53
|
+
ExpandableCalendarProps,
|
|
54
|
+
ExpandableCalendarRef,
|
|
55
|
+
MarkedDates,
|
|
56
|
+
MoveOrigin,
|
|
57
|
+
PackedTimelineEvent,
|
|
58
|
+
TimelineEvent,
|
|
59
|
+
TimelineInnerProps,
|
|
60
|
+
TimelineListProps,
|
|
61
|
+
UpdateSource,
|
|
62
|
+
} from './types';
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Theme plumbing. Two exports matter to a consumer: `AgendaKitThemeProvider`
|
|
3
|
+
* and `useKitTheme`. Everything else is how the kit builds stylesheets.
|
|
4
|
+
*
|
|
5
|
+
* A theme is optional — with no provider above it the kit renders `lightTheme`,
|
|
6
|
+
* so a consumer can drop `<ExpandableCalendar />` in and see something correct
|
|
7
|
+
* before deciding on colours.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { createContext, useContext, useMemo, type ReactNode } from 'react';
|
|
11
|
+
import {
|
|
12
|
+
lightTheme,
|
|
13
|
+
resolveTheme,
|
|
14
|
+
type AgendaKitTheme,
|
|
15
|
+
type PartialAgendaKitTheme,
|
|
16
|
+
} from './theme';
|
|
17
|
+
|
|
18
|
+
const ThemeContext = createContext<AgendaKitTheme>(lightTheme);
|
|
19
|
+
|
|
20
|
+
export type AgendaKitThemeProviderProps = {
|
|
21
|
+
/** A full theme, or a partial one layered over `lightTheme` / `darkTheme`. */
|
|
22
|
+
theme?: AgendaKitTheme | PartialAgendaKitTheme;
|
|
23
|
+
/** Which built-in to layer a partial theme over. Ignored for a full theme. */
|
|
24
|
+
base?: AgendaKitTheme;
|
|
25
|
+
children: ReactNode;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export const AgendaKitThemeProvider = ({
|
|
29
|
+
theme,
|
|
30
|
+
base = lightTheme,
|
|
31
|
+
children,
|
|
32
|
+
}: AgendaKitThemeProviderProps) => {
|
|
33
|
+
// The resolved object's IDENTITY is the stylesheet cache key, so it must be
|
|
34
|
+
// stable across renders — a consumer passing an inline literal would
|
|
35
|
+
// otherwise rebuild every sheet in the tree on every render.
|
|
36
|
+
const value = useMemo(
|
|
37
|
+
() => resolveTheme(base, theme as PartialAgendaKitTheme | undefined),
|
|
38
|
+
[base, theme],
|
|
39
|
+
);
|
|
40
|
+
return <ThemeContext.Provider value={value}>{children}</ThemeContext.Provider>;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export const useKitTheme = (): AgendaKitTheme => useContext(ThemeContext);
|
|
44
|
+
|
|
45
|
+
export type KitStyleArgs = {
|
|
46
|
+
colors: AgendaKitTheme['colors'];
|
|
47
|
+
fonts: AgendaKitTheme['fonts'];
|
|
48
|
+
dark: boolean;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export type KitStyleFactory<T> = (args: KitStyleArgs) => T;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* The ONE way a kit component builds a StyleSheet.
|
|
55
|
+
*
|
|
56
|
+
* const makeStyles = ({ colors }: KitStyleArgs) => StyleSheet.create({ ... });
|
|
57
|
+
* const styles = useKitStyles(makeStyles);
|
|
58
|
+
*
|
|
59
|
+
* A module-scope `StyleSheet.create` is built once and can never follow the
|
|
60
|
+
* theme. This builds it through a factory instead, and caches one sheet per
|
|
61
|
+
* (factory, theme) for the life of the process — so a list with three hundred
|
|
62
|
+
* rows calling this from its row component shares one object, and memoised
|
|
63
|
+
* rows still compare equal.
|
|
64
|
+
*
|
|
65
|
+
* The factory MUST be a module-scope constant depending only on its arguments:
|
|
66
|
+
* it is half the cache key.
|
|
67
|
+
*/
|
|
68
|
+
const cache = new WeakMap<KitStyleFactory<any>, WeakMap<AgendaKitTheme, unknown>>();
|
|
69
|
+
|
|
70
|
+
export function useKitStyles<T>(factory: KitStyleFactory<T>): T {
|
|
71
|
+
const theme = useKitTheme();
|
|
72
|
+
|
|
73
|
+
let byTheme = cache.get(factory);
|
|
74
|
+
if (!byTheme) {
|
|
75
|
+
byTheme = new WeakMap();
|
|
76
|
+
cache.set(factory, byTheme);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
let built = byTheme.get(theme) as T | undefined;
|
|
80
|
+
if (!built) {
|
|
81
|
+
built = factory({ colors: theme.colors, fonts: theme.fonts, dark: theme.dark });
|
|
82
|
+
byTheme.set(theme, built);
|
|
83
|
+
}
|
|
84
|
+
return built;
|
|
85
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export {
|
|
2
|
+
AgendaKitThemeProvider,
|
|
3
|
+
useKitStyles,
|
|
4
|
+
useKitTheme,
|
|
5
|
+
type AgendaKitThemeProviderProps,
|
|
6
|
+
type KitStyleArgs,
|
|
7
|
+
type KitStyleFactory,
|
|
8
|
+
} from './ThemeProvider';
|
|
9
|
+
export {
|
|
10
|
+
darkTheme,
|
|
11
|
+
lightTheme,
|
|
12
|
+
resolveTheme,
|
|
13
|
+
type AgendaKitColors,
|
|
14
|
+
type AgendaKitFonts,
|
|
15
|
+
type AgendaKitTheme,
|
|
16
|
+
type PartialAgendaKitTheme,
|
|
17
|
+
} from './theme';
|
|
18
|
+
export { ANIMATION, EASING, FONT_SIZE, RADIUS, SPACING } from './tokens';
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The kit's entire visual surface: eleven colours and three font families.
|
|
3
|
+
*
|
|
4
|
+
* It is deliberately flat and deliberately small. Every name says what the
|
|
5
|
+
* value PAINTS, not where it came from in some design system — so a consumer
|
|
6
|
+
* can map their own tokens onto it in one object literal and know nothing was
|
|
7
|
+
* missed. If a colour is not in this list, the kit does not draw it.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export type AgendaKitColors = {
|
|
11
|
+
/** Ground under the calendar, the agenda rows and the timeline. */
|
|
12
|
+
surface: string;
|
|
13
|
+
/** Recessed band behind the week strip, one step darker than `surface`. */
|
|
14
|
+
canvas: string;
|
|
15
|
+
/** Hairlines: hour lines, the grid, row and block borders. */
|
|
16
|
+
border: string;
|
|
17
|
+
/** Accent INK — today's number, dots, the Today pill's label, the refresh spinner. */
|
|
18
|
+
accent: string;
|
|
19
|
+
/** Accent FILL — the selected-day pill. The one place accent is a background. */
|
|
20
|
+
accentFill: string;
|
|
21
|
+
/** Text and icons that sit ON `accentFill`. */
|
|
22
|
+
onAccentFill: string;
|
|
23
|
+
/** Default event-block fill (a tint of the accent). */
|
|
24
|
+
accentSoft: string;
|
|
25
|
+
/** Available-hours wash behind the timeline (the faintest accent tint). */
|
|
26
|
+
accentSubtle: string;
|
|
27
|
+
/** Primary text: day numbers, event titles. */
|
|
28
|
+
text: string;
|
|
29
|
+
/** Metadata: hour labels, disabled days, weekday initials. */
|
|
30
|
+
textMuted: string;
|
|
31
|
+
/** The now line and its cap. The only non-accent hue the kit draws. */
|
|
32
|
+
nowIndicator: string;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Font families by weight. `undefined` means the platform default — the kit
|
|
37
|
+
* ships no fonts and never assumes one is loaded.
|
|
38
|
+
*/
|
|
39
|
+
export type AgendaKitFonts = {
|
|
40
|
+
regular?: string;
|
|
41
|
+
medium?: string;
|
|
42
|
+
semiBold?: string;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export type AgendaKitTheme = {
|
|
46
|
+
colors: AgendaKitColors;
|
|
47
|
+
fonts: AgendaKitFonts;
|
|
48
|
+
dark: boolean;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export type PartialAgendaKitTheme = {
|
|
52
|
+
colors?: Partial<AgendaKitColors>;
|
|
53
|
+
fonts?: Partial<AgendaKitFonts>;
|
|
54
|
+
dark?: boolean;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
/** True-neutral greys (R=G=B) so the accent carries all the colour. */
|
|
58
|
+
export const lightTheme: AgendaKitTheme = {
|
|
59
|
+
colors: {
|
|
60
|
+
surface: '#FFFFFF',
|
|
61
|
+
canvas: '#F4F4F4',
|
|
62
|
+
border: '#DDDDDD',
|
|
63
|
+
accent: '#5B6FAE',
|
|
64
|
+
accentFill: '#5B6FAE',
|
|
65
|
+
onAccentFill: '#FFFFFF',
|
|
66
|
+
accentSoft: '#E8EBF4',
|
|
67
|
+
accentSubtle: '#F7F8FB',
|
|
68
|
+
text: '#1F1F1F',
|
|
69
|
+
textMuted: '#6F6F6F',
|
|
70
|
+
nowIndicator: '#EF4444',
|
|
71
|
+
},
|
|
72
|
+
fonts: {},
|
|
73
|
+
dark: false,
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* `text` is #CCCCCC, not white: a bold stroke at 14:1 on a dark surface blooms
|
|
78
|
+
* optically and reads as glowing. The accent FILL does not lift (white on the
|
|
79
|
+
* lighter #818CF8 is only 2.99:1) — only the INK does.
|
|
80
|
+
*/
|
|
81
|
+
export const darkTheme: AgendaKitTheme = {
|
|
82
|
+
colors: {
|
|
83
|
+
surface: '#181818',
|
|
84
|
+
canvas: '#121212',
|
|
85
|
+
border: '#3A3A3A',
|
|
86
|
+
accent: '#818CF8',
|
|
87
|
+
accentFill: '#5B6FAE',
|
|
88
|
+
onAccentFill: '#FFFFFF',
|
|
89
|
+
accentSoft: '#212123',
|
|
90
|
+
accentSubtle: '#1C1C1E',
|
|
91
|
+
text: '#CCCCCC',
|
|
92
|
+
textMuted: '#8C8C8C',
|
|
93
|
+
nowIndicator: '#F87171',
|
|
94
|
+
},
|
|
95
|
+
fonts: {},
|
|
96
|
+
dark: true,
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
/** Shallow-merges each group. Called once per distinct input, in the provider. */
|
|
100
|
+
export const resolveTheme = (
|
|
101
|
+
base: AgendaKitTheme,
|
|
102
|
+
overrides?: PartialAgendaKitTheme,
|
|
103
|
+
): AgendaKitTheme => {
|
|
104
|
+
if (!overrides) return base;
|
|
105
|
+
return {
|
|
106
|
+
colors: { ...base.colors, ...overrides.colors },
|
|
107
|
+
fonts: { ...base.fonts, ...overrides.fonts },
|
|
108
|
+
dark: overrides.dark ?? base.dark,
|
|
109
|
+
};
|
|
110
|
+
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Static metrics. NOT themeable, on purpose.
|
|
3
|
+
*
|
|
4
|
+
* Row heights, week-strip geometry and the packer all read these at module
|
|
5
|
+
* scope — `expandable/geometry.ts` computes line heights from `FONT_SIZE`
|
|
6
|
+
* before any React tree exists. A themeable font size would mean measuring at
|
|
7
|
+
* runtime, which is exactly what this kit refuses to do (declared heights are
|
|
8
|
+
* why a fling never shifts the list).
|
|
9
|
+
*
|
|
10
|
+
* Motion is here for the same reason: `KIT_EASING` is captured by worklets at
|
|
11
|
+
* module scope, so it cannot depend on a React context.
|
|
12
|
+
*
|
|
13
|
+
* Colours and font FAMILIES are themeable — see `theme.ts`.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
export const SPACING = {
|
|
17
|
+
0: 0,
|
|
18
|
+
1: 4,
|
|
19
|
+
2: 8,
|
|
20
|
+
3: 12,
|
|
21
|
+
4: 16,
|
|
22
|
+
5: 20,
|
|
23
|
+
6: 24,
|
|
24
|
+
8: 32,
|
|
25
|
+
} as const;
|
|
26
|
+
|
|
27
|
+
export const FONT_SIZE = {
|
|
28
|
+
xxs: 11,
|
|
29
|
+
xs: 12,
|
|
30
|
+
sm: 14,
|
|
31
|
+
base: 16,
|
|
32
|
+
} as const;
|
|
33
|
+
|
|
34
|
+
export const RADIUS = {
|
|
35
|
+
none: 0,
|
|
36
|
+
card: 8,
|
|
37
|
+
inner: 6,
|
|
38
|
+
full: 9999,
|
|
39
|
+
} as const;
|
|
40
|
+
|
|
41
|
+
/** Milliseconds. Short on purpose: a calendar that animates slowly feels broken. */
|
|
42
|
+
export const ANIMATION = {
|
|
43
|
+
fast: 80,
|
|
44
|
+
base: 120,
|
|
45
|
+
slow: 180,
|
|
46
|
+
} as const;
|
|
47
|
+
|
|
48
|
+
export const EASING = {
|
|
49
|
+
bezier: [0.2, 0, 0, 1] as [number, number, number, number],
|
|
50
|
+
} as const;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One day as two absolute layers, so the pager can slot the shared hour lines between them:
|
|
3
|
+
* `DayBands` (availability) under the lines, `DayEvents` (packed blocks, then the now-line) above.
|
|
4
|
+
* Packing is memoised on the day's own event array: mounting a neighbour packs one day.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { memo, useMemo, type ReactElement } from 'react';
|
|
8
|
+
import { StyleSheet, View } from 'react-native';
|
|
9
|
+
import type { SharedValue } from 'react-native-reanimated';
|
|
10
|
+
import type { AvailableHours, PackedTimelineEvent, TimelineEvent } from '../types';
|
|
11
|
+
import { EventBlock } from './EventBlock';
|
|
12
|
+
import { NowIndicator } from './NowIndicator';
|
|
13
|
+
import { packEvents } from './packEvents';
|
|
14
|
+
import { buildBands } from './timelineMath';
|
|
15
|
+
|
|
16
|
+
type BandsProps = {
|
|
17
|
+
left: number;
|
|
18
|
+
width: number;
|
|
19
|
+
availableHours: AvailableHours | undefined;
|
|
20
|
+
color: string;
|
|
21
|
+
hourHeight: number;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const DayBandsInner = ({ left, width, availableHours, color, hourHeight }: BandsProps) => {
|
|
25
|
+
const bands = useMemo(() => buildBands(availableHours, hourHeight), [availableHours, hourHeight]);
|
|
26
|
+
const fill = useMemo(() => ({ backgroundColor: color }), [color]);
|
|
27
|
+
if (!bands.length) return null;
|
|
28
|
+
return (
|
|
29
|
+
<View pointerEvents="none" style={[styles.column, { left, width }]}>
|
|
30
|
+
{bands.map((band, i) => (
|
|
31
|
+
<View key={i} style={[styles.band, fill, { top: band.top, height: band.height }]} />
|
|
32
|
+
))}
|
|
33
|
+
</View>
|
|
34
|
+
);
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export const DayBands = memo(DayBandsInner);
|
|
38
|
+
DayBands.displayName = 'DayBands';
|
|
39
|
+
|
|
40
|
+
type EventsProps<E extends TimelineEvent> = {
|
|
41
|
+
left: number;
|
|
42
|
+
width: number;
|
|
43
|
+
events: E[] | undefined;
|
|
44
|
+
hourHeight: number;
|
|
45
|
+
overlapEventsSpacing: number;
|
|
46
|
+
rightEdgeSpacing: number;
|
|
47
|
+
renderEvent?: (event: PackedTimelineEvent<E>) => ReactElement | null;
|
|
48
|
+
onEventPress?: (event: PackedTimelineEvent<E>) => void;
|
|
49
|
+
/** Only on today's column while the indicator is on; stable, so a minute tick renders nothing. */
|
|
50
|
+
nowMinutes?: SharedValue<number>;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const DayEventsInner = <E extends TimelineEvent>({
|
|
54
|
+
left,
|
|
55
|
+
width,
|
|
56
|
+
events,
|
|
57
|
+
hourHeight,
|
|
58
|
+
overlapEventsSpacing,
|
|
59
|
+
rightEdgeSpacing,
|
|
60
|
+
renderEvent,
|
|
61
|
+
onEventPress,
|
|
62
|
+
nowMinutes,
|
|
63
|
+
}: EventsProps<E>) => {
|
|
64
|
+
const packed = useMemo(
|
|
65
|
+
() => packEvents(events, { colW: width, hourHeight, overlapEventsSpacing, rightEdgeSpacing }),
|
|
66
|
+
[events, hourHeight, overlapEventsSpacing, rightEdgeSpacing, width],
|
|
67
|
+
);
|
|
68
|
+
if (!packed.length && !nowMinutes) return null;
|
|
69
|
+
return (
|
|
70
|
+
<View pointerEvents="box-none" style={[styles.column, { left, width }]}>
|
|
71
|
+
{packed.map((event) => (
|
|
72
|
+
<EventBlock key={event.id} event={event} renderEvent={renderEvent} onPress={onEventPress} />
|
|
73
|
+
))}
|
|
74
|
+
{nowMinutes ? <NowIndicator hourHeight={hourHeight} minutes={nowMinutes} /> : null}
|
|
75
|
+
</View>
|
|
76
|
+
);
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
export const DayEvents = memo(DayEventsInner) as typeof DayEventsInner;
|
|
80
|
+
|
|
81
|
+
const styles = StyleSheet.create({
|
|
82
|
+
column: { position: 'absolute', top: 0, bottom: 0 },
|
|
83
|
+
band: { position: 'absolute', left: 0, right: 0 },
|
|
84
|
+
});
|