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.
Files changed (403) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +364 -0
  3. package/lib/commonjs/agenda/AgendaBackdrop.js +68 -0
  4. package/lib/commonjs/agenda/AgendaBackdrop.js.map +1 -0
  5. package/lib/commonjs/agenda/AgendaList.js +354 -0
  6. package/lib/commonjs/agenda/AgendaList.js.map +1 -0
  7. package/lib/commonjs/agenda/AgendaSlot.js +88 -0
  8. package/lib/commonjs/agenda/AgendaSlot.js.map +1 -0
  9. package/lib/commonjs/agenda/AgendaWindow.js +171 -0
  10. package/lib/commonjs/agenda/AgendaWindow.js.map +1 -0
  11. package/lib/commonjs/agenda/StickyHeaderOverlay.js +125 -0
  12. package/lib/commonjs/agenda/StickyHeaderOverlay.js.map +1 -0
  13. package/lib/commonjs/agenda/buildAgendaLayout.js +100 -0
  14. package/lib/commonjs/agenda/buildAgendaLayout.js.map +1 -0
  15. package/lib/commonjs/agenda/constants.js +29 -0
  16. package/lib/commonjs/agenda/constants.js.map +1 -0
  17. package/lib/commonjs/agenda/heights.js +49 -0
  18. package/lib/commonjs/agenda/heights.js.map +1 -0
  19. package/lib/commonjs/agenda/useAgendaScrollSync.js +204 -0
  20. package/lib/commonjs/agenda/useAgendaScrollSync.js.map +1 -0
  21. package/lib/commonjs/core/ArrowGlyph.js +65 -0
  22. package/lib/commonjs/core/ArrowGlyph.js.map +1 -0
  23. package/lib/commonjs/core/CalendarContext.js +32 -0
  24. package/lib/commonjs/core/CalendarContext.js.map +1 -0
  25. package/lib/commonjs/core/CalendarProvider.js +141 -0
  26. package/lib/commonjs/core/CalendarProvider.js.map +1 -0
  27. package/lib/commonjs/core/CalendarStore.js +70 -0
  28. package/lib/commonjs/core/CalendarStore.js.map +1 -0
  29. package/lib/commonjs/core/KitText.js +23 -0
  30. package/lib/commonjs/core/KitText.js.map +1 -0
  31. package/lib/commonjs/core/TodayButton.js +136 -0
  32. package/lib/commonjs/core/TodayButton.js.map +1 -0
  33. package/lib/commonjs/core/civil.js +101 -0
  34. package/lib/commonjs/core/civil.js.map +1 -0
  35. package/lib/commonjs/core/dateKey.js +56 -0
  36. package/lib/commonjs/core/dateKey.js.map +1 -0
  37. package/lib/commonjs/core/motion.js +56 -0
  38. package/lib/commonjs/core/motion.js.map +1 -0
  39. package/lib/commonjs/core/worklets.js +44 -0
  40. package/lib/commonjs/core/worklets.js.map +1 -0
  41. package/lib/commonjs/expandable/DayCell.js +120 -0
  42. package/lib/commonjs/expandable/DayCell.js.map +1 -0
  43. package/lib/commonjs/expandable/ExpandableCalendar.js +280 -0
  44. package/lib/commonjs/expandable/ExpandableCalendar.js.map +1 -0
  45. package/lib/commonjs/expandable/Knob.js +72 -0
  46. package/lib/commonjs/expandable/Knob.js.map +1 -0
  47. package/lib/commonjs/expandable/MonthPager.js +180 -0
  48. package/lib/commonjs/expandable/MonthPager.js.map +1 -0
  49. package/lib/commonjs/expandable/WeekStrip.js +451 -0
  50. package/lib/commonjs/expandable/WeekStrip.js.map +1 -0
  51. package/lib/commonjs/expandable/calendarCells.js +152 -0
  52. package/lib/commonjs/expandable/calendarCells.js.map +1 -0
  53. package/lib/commonjs/expandable/geometry.js +62 -0
  54. package/lib/commonjs/expandable/geometry.js.map +1 -0
  55. package/lib/commonjs/expandable/useExpandGesture.js +124 -0
  56. package/lib/commonjs/expandable/useExpandGesture.js.map +1 -0
  57. package/lib/commonjs/expandable/useHorizontalPager.js +97 -0
  58. package/lib/commonjs/expandable/useHorizontalPager.js.map +1 -0
  59. package/lib/commonjs/index.js +167 -0
  60. package/lib/commonjs/index.js.map +1 -0
  61. package/lib/commonjs/package.json +1 -0
  62. package/lib/commonjs/theme/ThemeProvider.js +73 -0
  63. package/lib/commonjs/theme/ThemeProvider.js.map +1 -0
  64. package/lib/commonjs/theme/index.js +75 -0
  65. package/lib/commonjs/theme/index.js.map +1 -0
  66. package/lib/commonjs/theme/theme.js +79 -0
  67. package/lib/commonjs/theme/theme.js.map +1 -0
  68. package/lib/commonjs/theme/tokens.js +54 -0
  69. package/lib/commonjs/theme/tokens.js.map +1 -0
  70. package/lib/commonjs/timeline/DayColumn.js +95 -0
  71. package/lib/commonjs/timeline/DayColumn.js.map +1 -0
  72. package/lib/commonjs/timeline/DayPager.js +250 -0
  73. package/lib/commonjs/timeline/DayPager.js.map +1 -0
  74. package/lib/commonjs/timeline/EventBlock.js +91 -0
  75. package/lib/commonjs/timeline/EventBlock.js.map +1 -0
  76. package/lib/commonjs/timeline/GridLines.js +47 -0
  77. package/lib/commonjs/timeline/GridLines.js.map +1 -0
  78. package/lib/commonjs/timeline/HourGrid.js +96 -0
  79. package/lib/commonjs/timeline/HourGrid.js.map +1 -0
  80. package/lib/commonjs/timeline/NowIndicator.js +132 -0
  81. package/lib/commonjs/timeline/NowIndicator.js.map +1 -0
  82. package/lib/commonjs/timeline/TimelineDay.js +126 -0
  83. package/lib/commonjs/timeline/TimelineDay.js.map +1 -0
  84. package/lib/commonjs/timeline/packEvents.js +102 -0
  85. package/lib/commonjs/timeline/packEvents.js.map +1 -0
  86. package/lib/commonjs/timeline/timelineGeometry.js +27 -0
  87. package/lib/commonjs/timeline/timelineGeometry.js.map +1 -0
  88. package/lib/commonjs/timeline/timelineMath.js +82 -0
  89. package/lib/commonjs/timeline/timelineMath.js.map +1 -0
  90. package/lib/commonjs/types.js +71 -0
  91. package/lib/commonjs/types.js.map +1 -0
  92. package/lib/module/agenda/AgendaBackdrop.js +63 -0
  93. package/lib/module/agenda/AgendaBackdrop.js.map +1 -0
  94. package/lib/module/agenda/AgendaList.js +349 -0
  95. package/lib/module/agenda/AgendaList.js.map +1 -0
  96. package/lib/module/agenda/AgendaSlot.js +84 -0
  97. package/lib/module/agenda/AgendaSlot.js.map +1 -0
  98. package/lib/module/agenda/AgendaWindow.js +167 -0
  99. package/lib/module/agenda/AgendaWindow.js.map +1 -0
  100. package/lib/module/agenda/StickyHeaderOverlay.js +120 -0
  101. package/lib/module/agenda/StickyHeaderOverlay.js.map +1 -0
  102. package/lib/module/agenda/buildAgendaLayout.js +95 -0
  103. package/lib/module/agenda/buildAgendaLayout.js.map +1 -0
  104. package/lib/module/agenda/constants.js +25 -0
  105. package/lib/module/agenda/constants.js.map +1 -0
  106. package/lib/module/agenda/heights.js +42 -0
  107. package/lib/module/agenda/heights.js.map +1 -0
  108. package/lib/module/agenda/useAgendaScrollSync.js +200 -0
  109. package/lib/module/agenda/useAgendaScrollSync.js.map +1 -0
  110. package/lib/module/core/ArrowGlyph.js +60 -0
  111. package/lib/module/core/ArrowGlyph.js.map +1 -0
  112. package/lib/module/core/CalendarContext.js +26 -0
  113. package/lib/module/core/CalendarContext.js.map +1 -0
  114. package/lib/module/core/CalendarProvider.js +136 -0
  115. package/lib/module/core/CalendarProvider.js.map +1 -0
  116. package/lib/module/core/CalendarStore.js +66 -0
  117. package/lib/module/core/CalendarStore.js.map +1 -0
  118. package/lib/module/core/KitText.js +19 -0
  119. package/lib/module/core/KitText.js.map +1 -0
  120. package/lib/module/core/TodayButton.js +133 -0
  121. package/lib/module/core/TodayButton.js.map +1 -0
  122. package/lib/module/core/civil.js +88 -0
  123. package/lib/module/core/civil.js.map +1 -0
  124. package/lib/module/core/dateKey.js +47 -0
  125. package/lib/module/core/dateKey.js.map +1 -0
  126. package/lib/module/core/motion.js +49 -0
  127. package/lib/module/core/motion.js.map +1 -0
  128. package/lib/module/core/worklets.js +38 -0
  129. package/lib/module/core/worklets.js.map +1 -0
  130. package/lib/module/expandable/DayCell.js +116 -0
  131. package/lib/module/expandable/DayCell.js.map +1 -0
  132. package/lib/module/expandable/ExpandableCalendar.js +275 -0
  133. package/lib/module/expandable/ExpandableCalendar.js.map +1 -0
  134. package/lib/module/expandable/Knob.js +67 -0
  135. package/lib/module/expandable/Knob.js.map +1 -0
  136. package/lib/module/expandable/MonthPager.js +175 -0
  137. package/lib/module/expandable/MonthPager.js.map +1 -0
  138. package/lib/module/expandable/WeekStrip.js +446 -0
  139. package/lib/module/expandable/WeekStrip.js.map +1 -0
  140. package/lib/module/expandable/calendarCells.js +142 -0
  141. package/lib/module/expandable/calendarCells.js.map +1 -0
  142. package/lib/module/expandable/geometry.js +58 -0
  143. package/lib/module/expandable/geometry.js.map +1 -0
  144. package/lib/module/expandable/useExpandGesture.js +118 -0
  145. package/lib/module/expandable/useExpandGesture.js.map +1 -0
  146. package/lib/module/expandable/useHorizontalPager.js +92 -0
  147. package/lib/module/expandable/useHorizontalPager.js.map +1 -0
  148. package/lib/module/index.js +35 -0
  149. package/lib/module/index.js.map +1 -0
  150. package/lib/module/package.json +1 -0
  151. package/lib/module/theme/ThemeProvider.js +65 -0
  152. package/lib/module/theme/ThemeProvider.js.map +1 -0
  153. package/lib/module/theme/index.js +6 -0
  154. package/lib/module/theme/index.js.map +1 -0
  155. package/lib/module/theme/theme.js +74 -0
  156. package/lib/module/theme/theme.js.map +1 -0
  157. package/lib/module/theme/tokens.js +50 -0
  158. package/lib/module/theme/tokens.js.map +1 -0
  159. package/lib/module/timeline/DayColumn.js +91 -0
  160. package/lib/module/timeline/DayColumn.js.map +1 -0
  161. package/lib/module/timeline/DayPager.js +245 -0
  162. package/lib/module/timeline/DayPager.js.map +1 -0
  163. package/lib/module/timeline/EventBlock.js +87 -0
  164. package/lib/module/timeline/EventBlock.js.map +1 -0
  165. package/lib/module/timeline/GridLines.js +43 -0
  166. package/lib/module/timeline/GridLines.js.map +1 -0
  167. package/lib/module/timeline/HourGrid.js +94 -0
  168. package/lib/module/timeline/HourGrid.js.map +1 -0
  169. package/lib/module/timeline/NowIndicator.js +126 -0
  170. package/lib/module/timeline/NowIndicator.js.map +1 -0
  171. package/lib/module/timeline/TimelineDay.js +122 -0
  172. package/lib/module/timeline/TimelineDay.js.map +1 -0
  173. package/lib/module/timeline/packEvents.js +97 -0
  174. package/lib/module/timeline/packEvents.js.map +1 -0
  175. package/lib/module/timeline/timelineGeometry.js +22 -0
  176. package/lib/module/timeline/timelineGeometry.js.map +1 -0
  177. package/lib/module/timeline/timelineMath.js +75 -0
  178. package/lib/module/timeline/timelineMath.js.map +1 -0
  179. package/lib/module/types.js +67 -0
  180. package/lib/module/types.js.map +1 -0
  181. package/lib/typescript/commonjs/agenda/AgendaBackdrop.d.ts +20 -0
  182. package/lib/typescript/commonjs/agenda/AgendaBackdrop.d.ts.map +1 -0
  183. package/lib/typescript/commonjs/agenda/AgendaList.d.ts +12 -0
  184. package/lib/typescript/commonjs/agenda/AgendaList.d.ts.map +1 -0
  185. package/lib/typescript/commonjs/agenda/AgendaSlot.d.ts +45 -0
  186. package/lib/typescript/commonjs/agenda/AgendaSlot.d.ts.map +1 -0
  187. package/lib/typescript/commonjs/agenda/AgendaWindow.d.ts +49 -0
  188. package/lib/typescript/commonjs/agenda/AgendaWindow.d.ts.map +1 -0
  189. package/lib/typescript/commonjs/agenda/StickyHeaderOverlay.d.ts +39 -0
  190. package/lib/typescript/commonjs/agenda/StickyHeaderOverlay.d.ts.map +1 -0
  191. package/lib/typescript/commonjs/agenda/buildAgendaLayout.d.ts +57 -0
  192. package/lib/typescript/commonjs/agenda/buildAgendaLayout.d.ts.map +1 -0
  193. package/lib/typescript/commonjs/agenda/constants.d.ts +19 -0
  194. package/lib/typescript/commonjs/agenda/constants.d.ts.map +1 -0
  195. package/lib/typescript/commonjs/agenda/heights.d.ts +20 -0
  196. package/lib/typescript/commonjs/agenda/heights.d.ts.map +1 -0
  197. package/lib/typescript/commonjs/agenda/useAgendaScrollSync.d.ts +44 -0
  198. package/lib/typescript/commonjs/agenda/useAgendaScrollSync.d.ts.map +1 -0
  199. package/lib/typescript/commonjs/core/ArrowGlyph.d.ts +14 -0
  200. package/lib/typescript/commonjs/core/ArrowGlyph.d.ts.map +1 -0
  201. package/lib/typescript/commonjs/core/CalendarContext.d.ts +35 -0
  202. package/lib/typescript/commonjs/core/CalendarContext.d.ts.map +1 -0
  203. package/lib/typescript/commonjs/core/CalendarProvider.d.ts +41 -0
  204. package/lib/typescript/commonjs/core/CalendarProvider.d.ts.map +1 -0
  205. package/lib/typescript/commonjs/core/CalendarStore.d.ts +28 -0
  206. package/lib/typescript/commonjs/core/CalendarStore.d.ts.map +1 -0
  207. package/lib/typescript/commonjs/core/KitText.d.ts +10 -0
  208. package/lib/typescript/commonjs/core/KitText.d.ts.map +1 -0
  209. package/lib/typescript/commonjs/core/TodayButton.d.ts +18 -0
  210. package/lib/typescript/commonjs/core/TodayButton.d.ts.map +1 -0
  211. package/lib/typescript/commonjs/core/civil.d.ts +26 -0
  212. package/lib/typescript/commonjs/core/civil.d.ts.map +1 -0
  213. package/lib/typescript/commonjs/core/dateKey.d.ts +21 -0
  214. package/lib/typescript/commonjs/core/dateKey.d.ts.map +1 -0
  215. package/lib/typescript/commonjs/core/motion.d.ts +18 -0
  216. package/lib/typescript/commonjs/core/motion.d.ts.map +1 -0
  217. package/lib/typescript/commonjs/core/worklets.d.ts +12 -0
  218. package/lib/typescript/commonjs/core/worklets.d.ts.map +1 -0
  219. package/lib/typescript/commonjs/expandable/DayCell.d.ts +22 -0
  220. package/lib/typescript/commonjs/expandable/DayCell.d.ts.map +1 -0
  221. package/lib/typescript/commonjs/expandable/ExpandableCalendar.d.ts +40 -0
  222. package/lib/typescript/commonjs/expandable/ExpandableCalendar.d.ts.map +1 -0
  223. package/lib/typescript/commonjs/expandable/Knob.d.ts +19 -0
  224. package/lib/typescript/commonjs/expandable/Knob.d.ts.map +1 -0
  225. package/lib/typescript/commonjs/expandable/MonthPager.d.ts +35 -0
  226. package/lib/typescript/commonjs/expandable/MonthPager.d.ts.map +1 -0
  227. package/lib/typescript/commonjs/expandable/WeekStrip.d.ts +34 -0
  228. package/lib/typescript/commonjs/expandable/WeekStrip.d.ts.map +1 -0
  229. package/lib/typescript/commonjs/expandable/calendarCells.d.ts +52 -0
  230. package/lib/typescript/commonjs/expandable/calendarCells.d.ts.map +1 -0
  231. package/lib/typescript/commonjs/expandable/geometry.d.ts +43 -0
  232. package/lib/typescript/commonjs/expandable/geometry.d.ts.map +1 -0
  233. package/lib/typescript/commonjs/expandable/useExpandGesture.d.ts +35 -0
  234. package/lib/typescript/commonjs/expandable/useExpandGesture.d.ts.map +1 -0
  235. package/lib/typescript/commonjs/expandable/useHorizontalPager.d.ts +35 -0
  236. package/lib/typescript/commonjs/expandable/useHorizontalPager.d.ts.map +1 -0
  237. package/lib/typescript/commonjs/index.d.ts +26 -0
  238. package/lib/typescript/commonjs/index.d.ts.map +1 -0
  239. package/lib/typescript/commonjs/package.json +1 -0
  240. package/lib/typescript/commonjs/theme/ThemeProvider.d.ts +27 -0
  241. package/lib/typescript/commonjs/theme/ThemeProvider.d.ts.map +1 -0
  242. package/lib/typescript/commonjs/theme/index.d.ts +4 -0
  243. package/lib/typescript/commonjs/theme/index.d.ts.map +1 -0
  244. package/lib/typescript/commonjs/theme/theme.d.ts +62 -0
  245. package/lib/typescript/commonjs/theme/theme.d.ts.map +1 -0
  246. package/lib/typescript/commonjs/theme/tokens.d.ts +46 -0
  247. package/lib/typescript/commonjs/theme/tokens.d.ts.map +1 -0
  248. package/lib/typescript/commonjs/timeline/DayColumn.d.ts +32 -0
  249. package/lib/typescript/commonjs/timeline/DayColumn.d.ts.map +1 -0
  250. package/lib/typescript/commonjs/timeline/DayPager.d.ts +32 -0
  251. package/lib/typescript/commonjs/timeline/DayPager.d.ts.map +1 -0
  252. package/lib/typescript/commonjs/timeline/EventBlock.d.ts +17 -0
  253. package/lib/typescript/commonjs/timeline/EventBlock.d.ts.map +1 -0
  254. package/lib/typescript/commonjs/timeline/GridLines.d.ts +5 -0
  255. package/lib/typescript/commonjs/timeline/GridLines.d.ts.map +1 -0
  256. package/lib/typescript/commonjs/timeline/HourGrid.d.ts +12 -0
  257. package/lib/typescript/commonjs/timeline/HourGrid.d.ts.map +1 -0
  258. package/lib/typescript/commonjs/timeline/NowIndicator.d.ts +28 -0
  259. package/lib/typescript/commonjs/timeline/NowIndicator.d.ts.map +1 -0
  260. package/lib/typescript/commonjs/timeline/TimelineDay.d.ts +14 -0
  261. package/lib/typescript/commonjs/timeline/TimelineDay.d.ts.map +1 -0
  262. package/lib/typescript/commonjs/timeline/packEvents.d.ts +25 -0
  263. package/lib/typescript/commonjs/timeline/packEvents.d.ts.map +1 -0
  264. package/lib/typescript/commonjs/timeline/timelineGeometry.d.ts +14 -0
  265. package/lib/typescript/commonjs/timeline/timelineGeometry.d.ts.map +1 -0
  266. package/lib/typescript/commonjs/timeline/timelineMath.d.ts +32 -0
  267. package/lib/typescript/commonjs/timeline/timelineMath.d.ts.map +1 -0
  268. package/lib/typescript/commonjs/types.d.ts +237 -0
  269. package/lib/typescript/commonjs/types.d.ts.map +1 -0
  270. package/lib/typescript/module/agenda/AgendaBackdrop.d.ts +20 -0
  271. package/lib/typescript/module/agenda/AgendaBackdrop.d.ts.map +1 -0
  272. package/lib/typescript/module/agenda/AgendaList.d.ts +12 -0
  273. package/lib/typescript/module/agenda/AgendaList.d.ts.map +1 -0
  274. package/lib/typescript/module/agenda/AgendaSlot.d.ts +45 -0
  275. package/lib/typescript/module/agenda/AgendaSlot.d.ts.map +1 -0
  276. package/lib/typescript/module/agenda/AgendaWindow.d.ts +49 -0
  277. package/lib/typescript/module/agenda/AgendaWindow.d.ts.map +1 -0
  278. package/lib/typescript/module/agenda/StickyHeaderOverlay.d.ts +39 -0
  279. package/lib/typescript/module/agenda/StickyHeaderOverlay.d.ts.map +1 -0
  280. package/lib/typescript/module/agenda/buildAgendaLayout.d.ts +57 -0
  281. package/lib/typescript/module/agenda/buildAgendaLayout.d.ts.map +1 -0
  282. package/lib/typescript/module/agenda/constants.d.ts +19 -0
  283. package/lib/typescript/module/agenda/constants.d.ts.map +1 -0
  284. package/lib/typescript/module/agenda/heights.d.ts +20 -0
  285. package/lib/typescript/module/agenda/heights.d.ts.map +1 -0
  286. package/lib/typescript/module/agenda/useAgendaScrollSync.d.ts +44 -0
  287. package/lib/typescript/module/agenda/useAgendaScrollSync.d.ts.map +1 -0
  288. package/lib/typescript/module/core/ArrowGlyph.d.ts +14 -0
  289. package/lib/typescript/module/core/ArrowGlyph.d.ts.map +1 -0
  290. package/lib/typescript/module/core/CalendarContext.d.ts +35 -0
  291. package/lib/typescript/module/core/CalendarContext.d.ts.map +1 -0
  292. package/lib/typescript/module/core/CalendarProvider.d.ts +41 -0
  293. package/lib/typescript/module/core/CalendarProvider.d.ts.map +1 -0
  294. package/lib/typescript/module/core/CalendarStore.d.ts +28 -0
  295. package/lib/typescript/module/core/CalendarStore.d.ts.map +1 -0
  296. package/lib/typescript/module/core/KitText.d.ts +10 -0
  297. package/lib/typescript/module/core/KitText.d.ts.map +1 -0
  298. package/lib/typescript/module/core/TodayButton.d.ts +18 -0
  299. package/lib/typescript/module/core/TodayButton.d.ts.map +1 -0
  300. package/lib/typescript/module/core/civil.d.ts +26 -0
  301. package/lib/typescript/module/core/civil.d.ts.map +1 -0
  302. package/lib/typescript/module/core/dateKey.d.ts +21 -0
  303. package/lib/typescript/module/core/dateKey.d.ts.map +1 -0
  304. package/lib/typescript/module/core/motion.d.ts +18 -0
  305. package/lib/typescript/module/core/motion.d.ts.map +1 -0
  306. package/lib/typescript/module/core/worklets.d.ts +12 -0
  307. package/lib/typescript/module/core/worklets.d.ts.map +1 -0
  308. package/lib/typescript/module/expandable/DayCell.d.ts +22 -0
  309. package/lib/typescript/module/expandable/DayCell.d.ts.map +1 -0
  310. package/lib/typescript/module/expandable/ExpandableCalendar.d.ts +40 -0
  311. package/lib/typescript/module/expandable/ExpandableCalendar.d.ts.map +1 -0
  312. package/lib/typescript/module/expandable/Knob.d.ts +19 -0
  313. package/lib/typescript/module/expandable/Knob.d.ts.map +1 -0
  314. package/lib/typescript/module/expandable/MonthPager.d.ts +35 -0
  315. package/lib/typescript/module/expandable/MonthPager.d.ts.map +1 -0
  316. package/lib/typescript/module/expandable/WeekStrip.d.ts +34 -0
  317. package/lib/typescript/module/expandable/WeekStrip.d.ts.map +1 -0
  318. package/lib/typescript/module/expandable/calendarCells.d.ts +52 -0
  319. package/lib/typescript/module/expandable/calendarCells.d.ts.map +1 -0
  320. package/lib/typescript/module/expandable/geometry.d.ts +43 -0
  321. package/lib/typescript/module/expandable/geometry.d.ts.map +1 -0
  322. package/lib/typescript/module/expandable/useExpandGesture.d.ts +35 -0
  323. package/lib/typescript/module/expandable/useExpandGesture.d.ts.map +1 -0
  324. package/lib/typescript/module/expandable/useHorizontalPager.d.ts +35 -0
  325. package/lib/typescript/module/expandable/useHorizontalPager.d.ts.map +1 -0
  326. package/lib/typescript/module/index.d.ts +26 -0
  327. package/lib/typescript/module/index.d.ts.map +1 -0
  328. package/lib/typescript/module/package.json +1 -0
  329. package/lib/typescript/module/theme/ThemeProvider.d.ts +27 -0
  330. package/lib/typescript/module/theme/ThemeProvider.d.ts.map +1 -0
  331. package/lib/typescript/module/theme/index.d.ts +4 -0
  332. package/lib/typescript/module/theme/index.d.ts.map +1 -0
  333. package/lib/typescript/module/theme/theme.d.ts +62 -0
  334. package/lib/typescript/module/theme/theme.d.ts.map +1 -0
  335. package/lib/typescript/module/theme/tokens.d.ts +46 -0
  336. package/lib/typescript/module/theme/tokens.d.ts.map +1 -0
  337. package/lib/typescript/module/timeline/DayColumn.d.ts +32 -0
  338. package/lib/typescript/module/timeline/DayColumn.d.ts.map +1 -0
  339. package/lib/typescript/module/timeline/DayPager.d.ts +32 -0
  340. package/lib/typescript/module/timeline/DayPager.d.ts.map +1 -0
  341. package/lib/typescript/module/timeline/EventBlock.d.ts +17 -0
  342. package/lib/typescript/module/timeline/EventBlock.d.ts.map +1 -0
  343. package/lib/typescript/module/timeline/GridLines.d.ts +5 -0
  344. package/lib/typescript/module/timeline/GridLines.d.ts.map +1 -0
  345. package/lib/typescript/module/timeline/HourGrid.d.ts +12 -0
  346. package/lib/typescript/module/timeline/HourGrid.d.ts.map +1 -0
  347. package/lib/typescript/module/timeline/NowIndicator.d.ts +28 -0
  348. package/lib/typescript/module/timeline/NowIndicator.d.ts.map +1 -0
  349. package/lib/typescript/module/timeline/TimelineDay.d.ts +14 -0
  350. package/lib/typescript/module/timeline/TimelineDay.d.ts.map +1 -0
  351. package/lib/typescript/module/timeline/packEvents.d.ts +25 -0
  352. package/lib/typescript/module/timeline/packEvents.d.ts.map +1 -0
  353. package/lib/typescript/module/timeline/timelineGeometry.d.ts +14 -0
  354. package/lib/typescript/module/timeline/timelineGeometry.d.ts.map +1 -0
  355. package/lib/typescript/module/timeline/timelineMath.d.ts +32 -0
  356. package/lib/typescript/module/timeline/timelineMath.d.ts.map +1 -0
  357. package/lib/typescript/module/types.d.ts +237 -0
  358. package/lib/typescript/module/types.d.ts.map +1 -0
  359. package/package.json +105 -0
  360. package/src/agenda/AgendaBackdrop.tsx +55 -0
  361. package/src/agenda/AgendaList.tsx +370 -0
  362. package/src/agenda/AgendaSlot.tsx +88 -0
  363. package/src/agenda/AgendaWindow.tsx +183 -0
  364. package/src/agenda/StickyHeaderOverlay.tsx +126 -0
  365. package/src/agenda/buildAgendaLayout.ts +110 -0
  366. package/src/agenda/constants.ts +22 -0
  367. package/src/agenda/heights.ts +44 -0
  368. package/src/agenda/useAgendaScrollSync.ts +251 -0
  369. package/src/core/ArrowGlyph.tsx +53 -0
  370. package/src/core/CalendarContext.ts +47 -0
  371. package/src/core/CalendarProvider.tsx +165 -0
  372. package/src/core/CalendarStore.ts +64 -0
  373. package/src/core/KitText.tsx +10 -0
  374. package/src/core/TodayButton.tsx +121 -0
  375. package/src/core/civil.ts +92 -0
  376. package/src/core/dateKey.ts +52 -0
  377. package/src/core/motion.ts +51 -0
  378. package/src/core/worklets.ts +37 -0
  379. package/src/expandable/DayCell.tsx +97 -0
  380. package/src/expandable/ExpandableCalendar.tsx +278 -0
  381. package/src/expandable/Knob.tsx +67 -0
  382. package/src/expandable/MonthPager.tsx +208 -0
  383. package/src/expandable/WeekStrip.tsx +439 -0
  384. package/src/expandable/calendarCells.ts +155 -0
  385. package/src/expandable/geometry.ts +51 -0
  386. package/src/expandable/useExpandGesture.ts +147 -0
  387. package/src/expandable/useHorizontalPager.ts +116 -0
  388. package/src/index.ts +62 -0
  389. package/src/theme/ThemeProvider.tsx +85 -0
  390. package/src/theme/index.ts +18 -0
  391. package/src/theme/theme.ts +110 -0
  392. package/src/theme/tokens.ts +50 -0
  393. package/src/timeline/DayColumn.tsx +84 -0
  394. package/src/timeline/DayPager.tsx +295 -0
  395. package/src/timeline/EventBlock.tsx +76 -0
  396. package/src/timeline/GridLines.tsx +36 -0
  397. package/src/timeline/HourGrid.tsx +90 -0
  398. package/src/timeline/NowIndicator.tsx +123 -0
  399. package/src/timeline/TimelineDay.tsx +112 -0
  400. package/src/timeline/packEvents.ts +118 -0
  401. package/src/timeline/timelineGeometry.ts +23 -0
  402. package/src/timeline/timelineMath.ts +86 -0
  403. package/src/types.ts +252 -0
@@ -0,0 +1,97 @@
1
+ /**
2
+ * One day in the MONTH GRID. Selection arrives as a plain prop from the committed
3
+ * date, and `memo` on primitive props means a commit re-renders two cells, not the
4
+ * month. (The week strip tracks a fling frame by frame with one pill instead.)
5
+ */
6
+
7
+ import { useKitStyles, type KitStyleArgs } from '../theme';
8
+ import { FONT_SIZE, RADIUS } from '../theme/tokens';
9
+ import { memo } from 'react';
10
+ import { Pressable, StyleSheet, View } from 'react-native';
11
+ import { KitText } from '../core/KitText';
12
+ import { DAY_CELL, DAY_LINE_HEIGHT, DAY_TEXT_MARGIN_TOP, DOT_MARGIN_TOP, DOT_SIZE } from './geometry';
13
+
14
+ type Props = {
15
+ dayIndex: number;
16
+ label: string;
17
+ left: number;
18
+ top: number;
19
+ isToday: boolean;
20
+ isDisabled: boolean;
21
+ isSelected: boolean;
22
+ /** `null` = no dot, `''` = default colour. */
23
+ dot: string | null;
24
+ onPress: (dayIndex: number) => void;
25
+ /** The caller's spoken date; the bare number is read when absent. */
26
+ accessibilityLabel?: string;
27
+ };
28
+
29
+ const DayCellInner = ({
30
+ dayIndex,
31
+ label,
32
+ left,
33
+ top,
34
+ isToday,
35
+ isDisabled,
36
+ isSelected,
37
+ dot,
38
+ onPress,
39
+ accessibilityLabel,
40
+ }: Props) => {
41
+ const styles = useKitStyles(makeStyles);
42
+ const state = isSelected ? 3 : isDisabled ? 2 : isToday ? 1 : 0;
43
+
44
+ return (
45
+ <Pressable
46
+ style={[styles.cell, { left, top }, isSelected ? styles.cellSelected : null]}
47
+ onPress={() => onPress(dayIndex)}
48
+ disabled={isDisabled}
49
+ accessibilityRole="button"
50
+ accessibilityLabel={accessibilityLabel}
51
+ accessibilityState={{ selected: isSelected, disabled: isDisabled }}
52
+ >
53
+ <KitText style={styles.text[state]}>{label}</KitText>
54
+ {dot !== null ? (
55
+ <View style={[styles.dot, isSelected || !dot ? styles.dotFill[state] : { backgroundColor: dot }]} />
56
+ ) : null}
57
+ </Pressable>
58
+ );
59
+ };
60
+
61
+ export const DayCell = memo(DayCellInner);
62
+ DayCell.displayName = 'DayCell';
63
+
64
+ /** `text` and `dotFill` are indexed by state: 0 plain, 1 today, 2 disabled, 3 selected. */
65
+ const makeStyles = ({ colors, fonts }: KitStyleArgs) => {
66
+ const text = {
67
+ marginTop: DAY_TEXT_MARGIN_TOP,
68
+ fontFamily: fonts.regular,
69
+ fontSize: FONT_SIZE.sm,
70
+ lineHeight: DAY_LINE_HEIGHT,
71
+ } as const;
72
+ const s = StyleSheet.create({
73
+ cell: {
74
+ position: 'absolute',
75
+ width: DAY_CELL,
76
+ height: DAY_CELL,
77
+ borderRadius: RADIUS.full,
78
+ alignItems: 'center',
79
+ },
80
+ // The one accent use on the calendar — active selection: one accent, nowhere else.
81
+ cellSelected: { backgroundColor: colors.accentFill },
82
+ text: { ...text, color: colors.text },
83
+ textToday: { ...text, color: colors.accent },
84
+ textDisabled: { ...text, color: colors.textMuted },
85
+ textSelected: { ...text, color: colors.onAccentFill },
86
+ dot: { width: DOT_SIZE, height: DOT_SIZE, marginTop: DOT_MARGIN_TOP, borderRadius: RADIUS.full },
87
+ dotDefault: { backgroundColor: colors.accent },
88
+ dotSelected: { backgroundColor: colors.onAccentFill },
89
+ });
90
+ return {
91
+ cell: s.cell,
92
+ cellSelected: s.cellSelected,
93
+ dot: s.dot,
94
+ text: [s.text, s.textToday, s.textDisabled, s.textSelected],
95
+ dotFill: [s.dotDefault, s.dotDefault, s.dotDefault, s.dotSelected],
96
+ };
97
+ };
@@ -0,0 +1,278 @@
1
+ /**
2
+ * The expandable calendar — week strip closed, month grid open — and the body it
3
+ * pushes down.
4
+ *
5
+ * Nothing animates height. `progress` (0 closed, 1 open) moves and every layer
6
+ * reads it as a transform or opacity: the month layer fades in and slides from
7
+ * "selected week on top" to its natural place, the strip fades out, and the knob
8
+ * and fixed-height body translate by `progress · travel`, where `travel` belongs
9
+ * to the VISIBLE month and re-targets when that changes while open.
10
+ *
11
+ * The body renders `children` because it must read `progress`. A list drag closes
12
+ * an open calendar: the grid shows the committed date, the list the day under it.
13
+ * With a screen reader the calendar is a static open month grid — TalkBack ignores
14
+ * opacity, would read strip and grid both, and cannot perform the pan.
15
+ */
16
+
17
+ import { useKitStyles, type KitStyleArgs } from '../theme';
18
+ import { ANIMATION } from '../theme/tokens';
19
+ import {
20
+ memo,
21
+ useCallback,
22
+ useEffect,
23
+ useImperativeHandle,
24
+ useLayoutEffect,
25
+ useMemo,
26
+ useRef,
27
+ useState,
28
+ } from 'react';
29
+ import { Dimensions, StyleSheet, View, type LayoutChangeEvent } from 'react-native';
30
+ import { GestureDetector } from 'react-native-gesture-handler';
31
+ import Animated, {
32
+ useAnimatedReaction,
33
+ useAnimatedStyle,
34
+ useSharedValue,
35
+ withTiming,
36
+ } from 'react-native-reanimated';
37
+ import { useCalendarContext, useCalendarDate } from '../core/CalendarContext';
38
+ import { clampIndex, dayIndexOf, ymdAt } from '../core/dateKey';
39
+ import { KIT_EASING, kitDuration, useScreenReaderEnabled } from '../core/motion';
40
+ import { clampNum } from '../core/worklets';
41
+ import type { ExpandableCalendarProps } from '../types';
42
+ import { buildCalendarCells, buildDots, cellLefts, pageOfIndex } from './calendarCells';
43
+ import { calendarHeights, KNOB_CONTAINER_HEIGHT, MAX_WEEKS, WEEK_ROW_HEIGHT } from './geometry';
44
+ import { Knob } from './Knob';
45
+ import { MonthPager } from './MonthPager';
46
+ import { snap, useExpandGesture } from './useExpandGesture';
47
+ import { WeekStrip } from './WeekStrip';
48
+
49
+ const POSITIONS = { CLOSED: 'closed', OPEN: 'open' } as const;
50
+ const { closed: CLOSED_H, full: CALENDAR_H } = calendarHeights(MAX_WEEKS);
51
+ /**
52
+ * Invisible, so the stale translateY is unseen; one object makes Reanimated skip the
53
+ * update. Opacity only: `updateProps` reassigns `transform` on the object it is given.
54
+ */
55
+ const CLOSED_MONTH_STYLE = { opacity: 0 };
56
+
57
+ const ExpandableCalendarInner = ({
58
+ initialPosition = 'closed',
59
+ onCalendarToggled,
60
+ style,
61
+ closeOnDayPress = true,
62
+ closeOnListScroll = true,
63
+ markedDates,
64
+ disablePan = false,
65
+ openThreshold,
66
+ closeThreshold,
67
+ knobAccessibilityLabel,
68
+ dayAccessibilityLabel,
69
+ monthShortLabels,
70
+ children,
71
+ ref,
72
+ }: ExpandableCalendarProps) => {
73
+ const styles = useKitStyles(makeStyles);
74
+ const { range, store, dateRef, setDate, reduceMotion } = useCalendarContext();
75
+ const date = useCalendarDate();
76
+ const screenReader = useScreenReaderEnabled();
77
+ const { dayIndex, listDragSeq } = store;
78
+
79
+ const [layout, setLayout] = useState(() => ({ width: Dimensions.get('window').width, height: 0 }));
80
+ const [isOpen, setIsOpen] = useState(initialPosition === 'open');
81
+
82
+ const { labels, ordinalByIndex, pages } = useMemo(() => buildCalendarCells(range), [range]);
83
+ const dots = useMemo(() => buildDots(range, markedDates), [range, markedDates]);
84
+ const lefts = useMemo(() => cellLefts(layout.width), [layout.width]);
85
+ const a11yLabels = useMemo(
86
+ () =>
87
+ screenReader && dayAccessibilityLabel
88
+ ? range.ymdByIndex.map((ymd) => dayAccessibilityLabel(ymd))
89
+ : undefined,
90
+ [dayAccessibilityLabel, range, screenReader],
91
+ );
92
+
93
+ const [initialPage] = useState(() =>
94
+ pageOfIndex(pages, clampIndex(range, dayIndexOf(range, dateRef.current))),
95
+ );
96
+ const progress = useSharedValue(initialPosition === 'open' ? 1 : 0);
97
+ const visiblePage = useSharedValue(initialPage);
98
+ const travel = useSharedValue(calendarHeights(pages.weeksByPage[initialPage] ?? 5).travel);
99
+ const pagesSV = useSharedValue(pages);
100
+ const writtenPages = useRef(pages);
101
+ useLayoutEffect(() => {
102
+ if (writtenPages.current === pages) return;
103
+ writtenPages.current = pages;
104
+ pagesSV.value = pages;
105
+ }, [pages, pagesSV]);
106
+
107
+ const retarget = kitDuration(ANIMATION.base, reduceMotion);
108
+ useAnimatedReaction(
109
+ () => visiblePage.value,
110
+ (page, prev) => {
111
+ if (prev === null || page === prev) return;
112
+ const next = calendarHeights(pagesSV.value.weeksByPage[page] ?? 5).travel;
113
+ // Open: glide the body to the new month's bottom edge. Closed: record it for the next open.
114
+ travel.value =
115
+ progress.value > 0 ? withTiming(next, { duration: retarget, easing: KIT_EASING }) : next;
116
+ },
117
+ );
118
+
119
+ // Through a ref: the gesture's worklets capture `handleToggled`, so it never changes identity.
120
+ const onToggledRef = useRef(onCalendarToggled);
121
+ useLayoutEffect(() => {
122
+ onToggledRef.current = onCalendarToggled;
123
+ });
124
+ const handleToggled = useCallback((open: boolean) => {
125
+ setIsOpen(open);
126
+ onToggledRef.current?.(open);
127
+ }, []);
128
+
129
+ const { pan, snapTo, lastReported } = useExpandGesture({
130
+ progress,
131
+ travel,
132
+ enabled: !disablePan && !screenReader,
133
+ openThreshold,
134
+ closeThreshold,
135
+ reduceMotion,
136
+ initialOpen: initialPosition === 'open',
137
+ onToggled: handleToggled,
138
+ });
139
+ const toggle = useCallback(() => snapTo(), [snapTo]);
140
+
141
+ // Not foldable into the gesture's `initialOpen`/`enabled`: the flag resolves after
142
+ // mount, and `enabled` is also false for `disablePan`, which must not open.
143
+ useEffect(() => {
144
+ if (screenReader) snapTo(1);
145
+ }, [screenReader, snapTo]);
146
+
147
+ useAnimatedReaction(
148
+ () => listDragSeq.value,
149
+ (seq, prev) => {
150
+ // Only a CHANGE of the counter is a drag; its first reading is the mount.
151
+ if (prev === null || seq === prev || !closeOnListScroll || screenReader) return;
152
+ if (progress.value > 0) snap(progress, lastReported, 0, reduceMotion, handleToggled);
153
+ },
154
+ );
155
+
156
+ useImperativeHandle(
157
+ ref,
158
+ () => ({ toggleCalendarPosition: screenReader ? () => true : toggle }),
159
+ [screenReader, toggle],
160
+ );
161
+
162
+ const handleDayPress = useCallback(
163
+ (idx: number) => {
164
+ if (clampIndex(range, idx) !== idx) return;
165
+ setDate(ymdAt(range, idx), 'dayPress');
166
+ // Same tick as the date: no race between the agenda's scroll and the collapse.
167
+ if (closeOnDayPress && !screenReader && progress.value > 0) snapTo(0);
168
+ },
169
+ [closeOnDayPress, progress, range, screenReader, setDate, snapTo],
170
+ );
171
+
172
+ const monthStyle = useAnimatedStyle(() => {
173
+ const p = progress.value;
174
+ if (p === 0) return CLOSED_MONTH_STYLE;
175
+ const { gridStartByPage, weeksByPage } = pagesSV.value;
176
+ const page = visiblePage.value;
177
+ const row = clampNum(
178
+ Math.floor((dayIndex.value - (gridStartByPage[page] ?? 0)) / 7),
179
+ 0,
180
+ (weeksByPage[page] ?? MAX_WEEKS) - 1,
181
+ );
182
+ return { opacity: p, transform: [{ translateY: -(1 - p) * row * WEEK_ROW_HEIGHT }] };
183
+ });
184
+ const weekStyle = useAnimatedStyle(() => ({ opacity: 1 - progress.value }));
185
+ const knobStyle = useAnimatedStyle(() => ({
186
+ transform: [{ translateY: CLOSED_H - KNOB_CONTAINER_HEIGHT + progress.value * travel.value }],
187
+ }));
188
+ const bodyStyle = useAnimatedStyle(() => ({
189
+ transform: [{ translateY: progress.value * travel.value }],
190
+ }));
191
+
192
+ const onLayout = useCallback((e: LayoutChangeEvent) => {
193
+ const { width, height } = e.nativeEvent.layout;
194
+ setLayout((prev) =>
195
+ Math.abs(prev.width - width) < 0.5 && Math.abs(prev.height - height) < 0.5
196
+ ? prev
197
+ : { width, height },
198
+ );
199
+ }, []);
200
+
201
+ return (
202
+ <View style={[styles.region, style]} onLayout={onLayout}>
203
+ <GestureDetector gesture={pan}>
204
+ <View collapsable={false} style={styles.calendar}>
205
+ <MonthPager
206
+ width={layout.width}
207
+ lefts={lefts}
208
+ pages={pages}
209
+ pagesSV={pagesSV}
210
+ labels={labels}
211
+ a11yLabels={a11yLabels}
212
+ dots={dots}
213
+ selectedIndex={dayIndexOf(range, date)}
214
+ initialPage={initialPage}
215
+ visiblePage={visiblePage}
216
+ onDayPress={handleDayPress}
217
+ animatedStyle={monthStyle}
218
+ isOpen={isOpen}
219
+ screenReader={screenReader}
220
+ />
221
+ {screenReader ? null : (
222
+ <>
223
+ <WeekStrip
224
+ width={layout.width}
225
+ lefts={lefts}
226
+ labels={labels}
227
+ ordinals={ordinalByIndex}
228
+ monthShortLabels={monthShortLabels}
229
+ dots={dots}
230
+ onDayPress={handleDayPress}
231
+ animatedStyle={weekStyle}
232
+ interactive={!isOpen}
233
+ />
234
+ <Knob
235
+ animatedStyle={knobStyle}
236
+ onPress={toggle}
237
+ accessibilityLabel={knobAccessibilityLabel}
238
+ />
239
+ </>
240
+ )}
241
+ </View>
242
+ </GestureDetector>
243
+ <Animated.View
244
+ style={[styles.body, { height: Math.max(0, layout.height - CLOSED_H) }, bodyStyle]}
245
+ >
246
+ {children}
247
+ </Animated.View>
248
+ </View>
249
+ );
250
+ };
251
+
252
+ export const ExpandableCalendar = Object.assign(memo(ExpandableCalendarInner), {
253
+ positions: POSITIONS,
254
+ });
255
+
256
+ const makeStyles = ({ colors }: KitStyleArgs) =>
257
+ StyleSheet.create({
258
+ region: {
259
+ flex: 1,
260
+ overflow: 'hidden',
261
+ backgroundColor: colors.surface,
262
+ },
263
+ calendar: {
264
+ position: 'absolute',
265
+ top: 0,
266
+ left: 0,
267
+ right: 0,
268
+ height: CALENDAR_H,
269
+ backgroundColor: colors.surface,
270
+ },
271
+ body: {
272
+ position: 'absolute',
273
+ top: CLOSED_H,
274
+ left: 0,
275
+ right: 0,
276
+ backgroundColor: colors.surface,
277
+ },
278
+ });
@@ -0,0 +1,67 @@
1
+ /**
2
+ * The drag band under the calendar. A tap toggles; a drag anywhere on the
3
+ * calendar (not just here) opens and closes — the band is the affordance, not
4
+ * the only hit area.
5
+ *
6
+ * A `Pressable`, not a `Gesture.Tap` raced against the pan. The tap belongs to
7
+ * the knob alone; racing a tap on the whole detector would make every day-cell
8
+ * tap also toggle the calendar.
9
+ */
10
+
11
+ import { useKitStyles, type KitStyleArgs } from '../theme';
12
+ import { RADIUS } from '../theme/tokens';
13
+ import { memo } from 'react';
14
+ import { Pressable, StyleSheet, View, type StyleProp, type ViewStyle } from 'react-native';
15
+ import Animated, { type AnimatedStyle } from 'react-native-reanimated';
16
+ import { KNOB_CONTAINER_HEIGHT, KNOB_HEIGHT, KNOB_WIDTH } from './geometry';
17
+
18
+ type Props = {
19
+ animatedStyle: StyleProp<AnimatedStyle<StyleProp<ViewStyle>>>;
20
+ onPress: () => void;
21
+ accessibilityLabel?: string;
22
+ };
23
+
24
+ const KnobInner = ({ animatedStyle, onPress, accessibilityLabel }: Props) => {
25
+ const styles = useKitStyles(makeStyles);
26
+ return (
27
+ <Animated.View style={[styles.container, animatedStyle]}>
28
+ <Pressable
29
+ style={styles.hit}
30
+ onPress={onPress}
31
+ accessibilityRole="button"
32
+ accessibilityLabel={accessibilityLabel}
33
+ >
34
+ <View style={styles.knob} />
35
+ </Pressable>
36
+ </Animated.View>
37
+ );
38
+ };
39
+
40
+ export const Knob = memo(KnobInner);
41
+ Knob.displayName = 'Knob';
42
+
43
+ const makeStyles = ({ colors }: KitStyleArgs) =>
44
+ StyleSheet.create({
45
+ container: {
46
+ position: 'absolute',
47
+ top: 0,
48
+ left: 0,
49
+ right: 0,
50
+ height: KNOB_CONTAINER_HEIGHT,
51
+ backgroundColor: colors.surface,
52
+ },
53
+ hit: {
54
+ flex: 1,
55
+ alignItems: 'center',
56
+ justifyContent: 'center',
57
+ },
58
+ knob: {
59
+ width: KNOB_WIDTH,
60
+ height: KNOB_HEIGHT,
61
+ // A pill is the one shape `full` exists for — the one shape `full` exists for.
62
+ borderRadius: RADIUS.full,
63
+ // The library's default `expandableKnobColor` is #e8ecf0 — a slate grey,
64
+ // which reads as a tinted surface. `border` is the nearest true-neutral.
65
+ backgroundColor: colors.border,
66
+ },
67
+ });
@@ -0,0 +1,208 @@
1
+ /**
2
+ * The open calendar: one month per page across the selectable window.
3
+ *
4
+ * Selection is the COMMITTED date as a plain prop, handed only to the page that
5
+ * holds it, so a commit re-renders at most two pages and two memo'd cells.
6
+ *
7
+ * Mounted pages derive from that same committed date. Closed, only its month
8
+ * exists: the layer is invisible, and every month crossing commits a date. Open,
9
+ * its two neighbours join so a swipe shows one; a swipe that lands commits the
10
+ * new month, which re-centres the window. A screen reader pages by scroll
11
+ * actions, so it gets every month. Moves page the pager instantly even while
12
+ * closed, so opening shows the right month.
13
+ */
14
+
15
+ import { memo, useCallback, type ReactElement } from 'react';
16
+ import { StyleSheet, View, type StyleProp, type ViewStyle } from 'react-native';
17
+ import Animated, { type AnimatedStyle, type SharedValue } from 'react-native-reanimated';
18
+ import { useCalendarContext } from '../core/CalendarContext';
19
+ import { clampIndex, ymdAt } from '../core/dateKey';
20
+ import { pageOfIndex, type MonthPages } from './calendarCells';
21
+ import { DayCell } from './DayCell';
22
+ import { MAX_WEEKS, WEEK_ROW_HEIGHT, WEEK_ROW_V_MARGIN } from './geometry';
23
+ import { PAGER_SCROLL_THROTTLE, useHorizontalPager } from './useHorizontalPager';
24
+
25
+ const GRID_HEIGHT = MAX_WEEKS * WEEK_ROW_HEIGHT;
26
+
27
+ type GridProps = {
28
+ page: number;
29
+ width: number;
30
+ lefts: number[];
31
+ gridStart: number;
32
+ weeks: number;
33
+ rawPageByIndex: number[];
34
+ labels: string[];
35
+ /** Spoken names by day index; only present while a screen reader runs. */
36
+ a11yLabels?: string[];
37
+ dots: (string | null)[];
38
+ /** −1 unless the selected day is in this page — keeps other pages memo-equal. */
39
+ selectedIndex: number;
40
+ todayIndex: number;
41
+ minIndex: number;
42
+ maxIndex: number;
43
+ onDayPress: (dayIndex: number) => void;
44
+ };
45
+
46
+ const MonthGrid = memo(
47
+ ({
48
+ page,
49
+ width,
50
+ lefts,
51
+ gridStart,
52
+ weeks,
53
+ rawPageByIndex,
54
+ labels,
55
+ a11yLabels,
56
+ dots,
57
+ selectedIndex,
58
+ todayIndex,
59
+ minIndex,
60
+ maxIndex,
61
+ onDayPress,
62
+ }: GridProps) => {
63
+ const cells: ReactElement[] = [];
64
+ for (let r = 0; r < weeks; r += 1) {
65
+ for (let c = 0; c < 7; c += 1) {
66
+ const i = gridStart + r * 7 + c;
67
+ // Days of the neighbouring months are blank, as the library's `hideExtraDays` draws them.
68
+ if (i < 0 || i >= labels.length || rawPageByIndex[i] !== page) continue;
69
+ cells.push(
70
+ <DayCell
71
+ key={i}
72
+ dayIndex={i}
73
+ label={labels[i]}
74
+ accessibilityLabel={a11yLabels?.[i]}
75
+ left={lefts[c]}
76
+ top={r * WEEK_ROW_HEIGHT + WEEK_ROW_V_MARGIN}
77
+ isToday={i === todayIndex}
78
+ isDisabled={i < minIndex || i > maxIndex}
79
+ isSelected={i === selectedIndex}
80
+ dot={dots[i]}
81
+ onPress={onDayPress}
82
+ />,
83
+ );
84
+ }
85
+ }
86
+ return <View style={[styles.grid, { left: page * width, width }]}>{cells}</View>;
87
+ },
88
+ );
89
+ MonthGrid.displayName = 'MonthGrid';
90
+
91
+ type Props = {
92
+ width: number;
93
+ lefts: number[];
94
+ pages: MonthPages;
95
+ pagesSV: SharedValue<MonthPages>;
96
+ labels: string[];
97
+ a11yLabels?: string[];
98
+ dots: (string | null)[];
99
+ selectedIndex: number;
100
+ initialPage: number;
101
+ visiblePage: SharedValue<number>;
102
+ onDayPress: (dayIndex: number) => void;
103
+ animatedStyle: StyleProp<AnimatedStyle<StyleProp<ViewStyle>>>;
104
+ isOpen: boolean;
105
+ screenReader: boolean;
106
+ };
107
+
108
+ const MonthPagerInner = ({
109
+ width,
110
+ lefts,
111
+ pages,
112
+ pagesSV,
113
+ labels,
114
+ a11yLabels,
115
+ dots,
116
+ selectedIndex,
117
+ initialPage,
118
+ visiblePage,
119
+ onDayPress,
120
+ animatedStyle,
121
+ isOpen,
122
+ screenReader,
123
+ }: Props) => {
124
+ const { range, setDate } = useCalendarContext();
125
+
126
+ /** A swipe landed on another month: select its first selectable day. */
127
+ const onMonthSettled = useCallback(
128
+ (page: number) => {
129
+ setDate(ymdAt(range, clampIndex(range, pages.monthStartByPage[page])), 'pageScroll', 'month');
130
+ },
131
+ [pages, range, setDate],
132
+ );
133
+
134
+ const pageOf = useCallback(
135
+ (idx: number) => {
136
+ 'worklet';
137
+ return pageOfIndex(pagesSV.value, idx);
138
+ },
139
+ [pagesSV],
140
+ );
141
+
142
+ const pager = useHorizontalPager({
143
+ width,
144
+ initialPage,
145
+ origin: 'month',
146
+ pageOf,
147
+ page: visiblePage,
148
+ onSettled: onMonthSettled,
149
+ });
150
+
151
+ const interactive = isOpen || screenReader;
152
+ const committed = pageOfIndex(pages, clampIndex(range, selectedIndex));
153
+ const reach = isOpen ? 1 : 0;
154
+ const first = screenReader ? 0 : Math.max(0, committed - reach);
155
+ const last = screenReader ? pages.count - 1 : Math.min(pages.count - 1, committed + reach);
156
+
157
+ const grids: ReactElement[] = [];
158
+ for (let p = first; p <= last; p += 1) {
159
+ grids.push(
160
+ <MonthGrid
161
+ key={p}
162
+ page={p}
163
+ width={width}
164
+ lefts={lefts}
165
+ gridStart={pages.gridStartByPage[p]}
166
+ weeks={pages.weeksByPage[p]}
167
+ rawPageByIndex={pages.rawPageByIndex}
168
+ labels={labels}
169
+ a11yLabels={a11yLabels}
170
+ dots={dots}
171
+ selectedIndex={pages.rawPageByIndex[selectedIndex] === p ? selectedIndex : -1}
172
+ todayIndex={range.todayIndex}
173
+ minIndex={range.minIndex}
174
+ maxIndex={range.maxIndex}
175
+ onDayPress={onDayPress}
176
+ />,
177
+ );
178
+ }
179
+
180
+ return (
181
+ <Animated.View
182
+ pointerEvents={interactive ? 'auto' : 'none'}
183
+ style={[styles.root, { width }, animatedStyle]}
184
+ >
185
+ <Animated.ScrollView
186
+ ref={pager.ref}
187
+ horizontal
188
+ pagingEnabled
189
+ showsHorizontalScrollIndicator={false}
190
+ scrollEnabled={interactive}
191
+ onScroll={pager.onScroll}
192
+ scrollEventThrottle={PAGER_SCROLL_THROTTLE}
193
+ contentOffset={pager.contentOffset}
194
+ onLayout={pager.onLayout}
195
+ >
196
+ <View style={{ width: pages.count * width, height: GRID_HEIGHT }}>{grids}</View>
197
+ </Animated.ScrollView>
198
+ </Animated.View>
199
+ );
200
+ };
201
+
202
+ export const MonthPager = memo(MonthPagerInner);
203
+ MonthPager.displayName = 'MonthPager';
204
+
205
+ const styles = StyleSheet.create({
206
+ root: { position: 'absolute', top: 0, left: 0, height: GRID_HEIGHT },
207
+ grid: { position: 'absolute', top: 0, height: GRID_HEIGHT },
208
+ });