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,439 @@
1
+ /**
2
+ * The closed calendar: a vertical TAPE of weeks seen through a one-row window.
3
+ *
4
+ * Every week is a row stacked in one `Animated.View`; the window clips it and
5
+ * `weekPos` translates it, so crossing into the next week slides the tape up and
6
+ * crossing back slides it down — the owner's Teams reference (2026-09-11). A move
7
+ * of more than a week jumps: the agenda jumps too, and a slide through months
8
+ * would read as a blur.
9
+ *
10
+ * Selection is TWO pills riding the tape: the new day's fades in while the old
11
+ * day's fades out, on the UI thread, with no React commit. Each pill shows its
12
+ * day through one non-editable TextInput (`text` is an animated prop —
13
+ * Reanimated's own `PerformanceMonitor` idiom) and one dot for a marked day.
14
+ *
15
+ * Alternate months sit on a canvas band and a 1st carries its month's short name,
16
+ * so a month edge shows inside a week. A horizontal swipe moves one week.
17
+ */
18
+
19
+ import { useKitStyles, type KitStyleArgs } from '../theme';
20
+ import { ANIMATION, FONT_SIZE, RADIUS } from '../theme/tokens';
21
+ import { memo, useCallback, useEffect, useMemo, useState, type ReactElement } from 'react';
22
+ import { Pressable, StyleSheet, TextInput, View, type StyleProp, type ViewStyle } from 'react-native';
23
+ import { Gesture, GestureDetector } from 'react-native-gesture-handler';
24
+ import Animated, {
25
+ useAnimatedProps,
26
+ useAnimatedReaction,
27
+ useAnimatedStyle,
28
+ useSharedValue,
29
+ withSequence,
30
+ withTiming,
31
+ type AnimatedStyle,
32
+ type SharedValue,
33
+ } from 'react-native-reanimated';
34
+ import { runOnJS } from 'react-native-worklets';
35
+ import { useCalendarContext } from '../core/CalendarContext';
36
+ import { clampIndex, dayIndexOf, ymdAt } from '../core/dateKey';
37
+ import { KitText } from '../core/KitText';
38
+ import { KIT_EASING, kitDuration } from '../core/motion';
39
+ import { cellLeft, columnAt, columnEdge } from './calendarCells';
40
+ import {
41
+ DAY_CELL,
42
+ DAY_LINE_HEIGHT,
43
+ DAY_TEXT_MARGIN_TOP,
44
+ DOT_MARGIN_TOP,
45
+ DOT_SIZE,
46
+ FIRST_OF_MONTH_TEXT_TOP,
47
+ MONTH_LABEL_LINE_HEIGHT,
48
+ MONTH_LABEL_TOP,
49
+ PAN_THRESHOLD,
50
+ SNAP_VELOCITY,
51
+ WEEK_ROW_HEIGHT,
52
+ WEEK_ROW_V_MARGIN,
53
+ } from './geometry';
54
+
55
+ const AnimatedTextInput = Animated.createAnimatedComponent(TextInput);
56
+ const DOT_INSET = (DAY_CELL - DOT_SIZE) / 2;
57
+ /** Where DayCell's flow puts the dot, from the cell top: text margin, the declared line box, the dot's own margin. */
58
+ const DOT_TOP = DAY_TEXT_MARGIN_TOP + DAY_LINE_HEIGHT + DOT_MARGIN_TOP;
59
+ /** How far a 1st's number and dot sit below every other day's. */
60
+ const FIRST_SHIFT = FIRST_OF_MONTH_TEXT_TOP - DAY_TEXT_MARGIN_TOP;
61
+
62
+ type RowProps = {
63
+ week: number;
64
+ width: number;
65
+ lefts: number[];
66
+ labels: string[];
67
+ ordinals: number[];
68
+ monthShortLabels?: readonly string[];
69
+ dots: (string | null)[];
70
+ todayIndex: number;
71
+ minIndex: number;
72
+ maxIndex: number;
73
+ onDayPress: (dayIndex: number) => void;
74
+ };
75
+
76
+ const WeekRow = memo(
77
+ ({ week, width, lefts, labels, ordinals, monthShortLabels, dots, todayIndex, minIndex, maxIndex, onDayPress }: RowProps) => {
78
+ const styles = useKitStyles(makeStyles);
79
+ const start = week * 7;
80
+ const cells: ReactElement[] = [];
81
+
82
+ // Months with an even ordinal (Jan, Mar … Nov) take the band. A week holds at
83
+ // most two months, so its banded days are one run.
84
+ let bandFrom = -1;
85
+ let bandTo = -1;
86
+ for (let col = 0; col < 7 && start + col < labels.length; col += 1) {
87
+ if ((ordinals[start + col] & 1) === 0) {
88
+ if (bandFrom < 0) bandFrom = col;
89
+ bandTo = col;
90
+ }
91
+ }
92
+ if (bandFrom >= 0) {
93
+ const left = bandFrom === 0 ? 0 : columnEdge(width, bandFrom);
94
+ const right = bandTo === 6 ? width : columnEdge(width, bandTo + 1);
95
+ cells.push(<View key="band" style={[styles.band, { left, width: right - left }]} />);
96
+ }
97
+
98
+ for (let col = 0; col < 7; col += 1) {
99
+ const i = start + col;
100
+ if (i >= labels.length) break;
101
+ const left = lefts[col];
102
+ const first = monthShortLabels !== undefined && labels[i] === '1';
103
+ const tone = i < minIndex || i > maxIndex ? styles.labelDisabled : i === todayIndex ? styles.labelToday : null;
104
+ if (first) {
105
+ cells.push(
106
+ <KitText key={`m${i}`} style={[styles.monthLabel, { left }]}>
107
+ {monthShortLabels?.[ordinals[i] % 12]}
108
+ </KitText>,
109
+ );
110
+ }
111
+ cells.push(
112
+ <KitText key={`t${i}`} style={[first ? styles.labelFirst : styles.label, { left }, tone]}>
113
+ {labels[i]}
114
+ </KitText>,
115
+ );
116
+ const dot = dots[i];
117
+ if (dot !== null) {
118
+ cells.push(
119
+ <View
120
+ key={`d${i}`}
121
+ style={[
122
+ first ? styles.dotFirst : styles.dot,
123
+ { left: left + DOT_INSET },
124
+ dot ? { backgroundColor: dot } : styles.dotDefault,
125
+ ]}
126
+ />,
127
+ );
128
+ }
129
+ }
130
+
131
+ // One Pressable per row; the column comes from the touch's x. `locationX` is
132
+ // relative to the view the finger lands on, so labels must not be hit-testable
133
+ // (they were, and every tap resolved to column 0).
134
+ return (
135
+ <Pressable
136
+ style={[styles.row, { top: week * WEEK_ROW_HEIGHT, width }]}
137
+ onPress={(e) => onDayPress(start + columnAt(width, e.nativeEvent.locationX))}
138
+ >
139
+ <View pointerEvents="none" style={StyleSheet.absoluteFill}>
140
+ {cells}
141
+ </View>
142
+ </Pressable>
143
+ );
144
+ },
145
+ );
146
+ WeekRow.displayName = 'WeekRow';
147
+
148
+ type PillProps = {
149
+ index: SharedValue<number>;
150
+ fade: SharedValue<number>;
151
+ /** The leaving pill's starting opacity; `null` for the arriving pill. */
152
+ leavingFrom: SharedValue<number> | null;
153
+ widthSV: SharedValue<number>;
154
+ labels: string[];
155
+ hasDot: boolean[];
156
+ firstOfMonth: boolean[];
157
+ };
158
+
159
+ const SelectionPill = memo(({ index, fade, leavingFrom, widthSV, labels, hasDot, firstOfMonth }: PillProps) => {
160
+ const styles = useKitStyles(makeStyles);
161
+ const frame = useAnimatedStyle(() => {
162
+ const i = index.value;
163
+ return {
164
+ opacity: leavingFrom === null ? fade.value : leavingFrom.value * (1 - fade.value),
165
+ transform: [{ translateX: cellLeft(widthSV.value, i % 7) }, { translateY: Math.floor(i / 7) * WEEK_ROW_HEIGHT }],
166
+ };
167
+ });
168
+ const content = useAnimatedStyle(() => ({
169
+ transform: [{ translateY: firstOfMonth[index.value] ? FIRST_SHIFT : 0 }],
170
+ }));
171
+ const labelProps = useAnimatedProps(() => {
172
+ const text = labels[index.value] ?? '';
173
+ return { text, defaultValue: text };
174
+ });
175
+ const dotStyle = useAnimatedStyle(() => ({ opacity: hasDot[index.value] ? 1 : 0 }));
176
+
177
+ return (
178
+ <Animated.View pointerEvents="none" style={[styles.pill, frame]}>
179
+ <Animated.View style={[styles.pillContent, content]}>
180
+ <AnimatedTextInput
181
+ animatedProps={labelProps}
182
+ editable={false}
183
+ pointerEvents="none"
184
+ caretHidden
185
+ contextMenuHidden
186
+ allowFontScaling={false}
187
+ maxFontSizeMultiplier={1}
188
+ underlineColorAndroid="transparent"
189
+ accessible={false}
190
+ importantForAccessibility="no"
191
+ style={styles.pillLabel}
192
+ />
193
+ <Animated.View style={[styles.pillDot, dotStyle]} />
194
+ </Animated.View>
195
+ </Animated.View>
196
+ );
197
+ });
198
+ SelectionPill.displayName = 'SelectionPill';
199
+
200
+ type Props = {
201
+ width: number;
202
+ /** `cellLefts(width)`: one array per width, shared by every row. */
203
+ lefts: number[];
204
+ labels: string[];
205
+ ordinals: number[];
206
+ monthShortLabels?: readonly string[];
207
+ dots: (string | null)[];
208
+ onDayPress: (dayIndex: number) => void;
209
+ animatedStyle: StyleProp<AnimatedStyle<StyleProp<ViewStyle>>>;
210
+ interactive: boolean;
211
+ };
212
+
213
+ const WeekStripInner = ({
214
+ width,
215
+ lefts,
216
+ labels,
217
+ ordinals,
218
+ monthShortLabels,
219
+ dots,
220
+ onDayPress,
221
+ animatedStyle,
222
+ interactive,
223
+ }: Props) => {
224
+ const styles = useKitStyles(makeStyles);
225
+ const { range, store, dateRef, setDate, reduceMotion } = useCalendarContext();
226
+ const { dayIndex } = store;
227
+ const weekCount = range.days / 7;
228
+
229
+ const [initialIndex] = useState(() => clampIndex(range, dayIndexOf(range, dateRef.current)));
230
+ const weekPos = useSharedValue(Math.floor(initialIndex / 7));
231
+ /** The week the tape is headed to: a day crossing inside it must not restart the slide. */
232
+ const weekTarget = useSharedValue(Math.floor(initialIndex / 7));
233
+ const current = useSharedValue(initialIndex);
234
+ const previous = useSharedValue(initialIndex);
235
+ const fade = useSharedValue(1);
236
+ /** The leaving pill's opacity when it began to leave, so a change mid-fade does not pop it to full. */
237
+ const leavingFrom = useSharedValue(0);
238
+ const widthSV = useSharedValue(width);
239
+ useEffect(() => {
240
+ widthSV.value = width;
241
+ }, [width, widthSV]);
242
+
243
+ const slide = kitDuration(ANIMATION.slow, reduceMotion);
244
+ const crossfade = kitDuration(ANIMATION.base, reduceMotion);
245
+
246
+ useAnimatedReaction(
247
+ () => dayIndex.value,
248
+ (idx, last) => {
249
+ if (idx === last) return;
250
+ const week = Math.floor(idx / 7);
251
+ if (last === null) {
252
+ weekPos.value = week;
253
+ weekTarget.value = week;
254
+ current.value = idx;
255
+ previous.value = idx;
256
+ return;
257
+ }
258
+ if (week !== weekTarget.value) {
259
+ const far = Math.abs(week - weekPos.value) > 1.5;
260
+ weekTarget.value = week;
261
+ weekPos.value = far || slide === 0 ? week : withTiming(week, { duration: slide, easing: KIT_EASING });
262
+ }
263
+ leavingFrom.value = fade.value;
264
+ previous.value = current.value;
265
+ current.value = idx;
266
+ fade.value =
267
+ crossfade === 0
268
+ ? 1
269
+ : withSequence(withTiming(0, { duration: 0 }), withTiming(1, { duration: crossfade, easing: KIT_EASING }));
270
+ },
271
+ [crossfade, slide],
272
+ );
273
+
274
+ /** A swipe asked for `week`: select its first selectable day, unless the range ends before it. */
275
+ const onSwipe = useCallback(
276
+ (week: number) => {
277
+ const target = clampIndex(range, week * 7);
278
+ if (Math.floor(target / 7) !== week) return;
279
+ setDate(ymdAt(range, target), 'weekScroll', 'week');
280
+ },
281
+ [range, setDate],
282
+ );
283
+
284
+ // `failOffsetY` hands a vertical drag to the calendar's expand pan, whose own
285
+ // `failOffsetX(±12)` hands a horizontal one to this.
286
+ const swipe = useMemo(
287
+ () =>
288
+ Gesture.Pan()
289
+ .enabled(interactive)
290
+ .activeOffsetX([-16, 16])
291
+ .failOffsetY([-10, 10])
292
+ .onEnd((e) => {
293
+ 'worklet';
294
+ const dx =
295
+ Math.abs(e.translationX) >= PAN_THRESHOLD
296
+ ? e.translationX
297
+ : Math.abs(e.velocityX) >= SNAP_VELOCITY
298
+ ? e.velocityX
299
+ : 0;
300
+ if (dx === 0) return;
301
+ runOnJS(onSwipe)(Math.floor(dayIndex.value / 7) + (dx < 0 ? 1 : -1));
302
+ }),
303
+ [dayIndex, interactive, onSwipe],
304
+ );
305
+
306
+ // Plain arrays captured by the worklets: one table read per day crossing.
307
+ const hasDot = useMemo(() => dots.map((d) => d !== null), [dots]);
308
+ const firstOfMonth = useMemo(
309
+ () => labels.map((label) => monthShortLabels !== undefined && label === '1'),
310
+ [labels, monthShortLabels],
311
+ );
312
+
313
+ const rows = useMemo(() => {
314
+ const out: ReactElement[] = [];
315
+ for (let w = 0; w < weekCount; w += 1) {
316
+ out.push(
317
+ <WeekRow
318
+ key={w}
319
+ week={w}
320
+ width={width}
321
+ lefts={lefts}
322
+ labels={labels}
323
+ ordinals={ordinals}
324
+ monthShortLabels={monthShortLabels}
325
+ dots={dots}
326
+ todayIndex={range.todayIndex}
327
+ minIndex={range.minIndex}
328
+ maxIndex={range.maxIndex}
329
+ onDayPress={onDayPress}
330
+ />,
331
+ );
332
+ }
333
+ return out;
334
+ }, [dots, labels, lefts, monthShortLabels, onDayPress, ordinals, range, weekCount, width]);
335
+
336
+ const tapeStyle = useAnimatedStyle(() => ({
337
+ transform: [{ translateY: -weekPos.value * WEEK_ROW_HEIGHT }],
338
+ }));
339
+
340
+ return (
341
+ <GestureDetector gesture={swipe}>
342
+ <Animated.View
343
+ pointerEvents={interactive ? 'auto' : 'none'}
344
+ style={[styles.root, { width }, animatedStyle]}
345
+ >
346
+ <Animated.View style={[styles.tape, { width, height: weekCount * WEEK_ROW_HEIGHT }, tapeStyle]}>
347
+ {rows}
348
+ <SelectionPill
349
+ index={previous}
350
+ fade={fade}
351
+ leavingFrom={leavingFrom}
352
+ widthSV={widthSV}
353
+ labels={labels}
354
+ hasDot={hasDot}
355
+ firstOfMonth={firstOfMonth}
356
+ />
357
+ <SelectionPill
358
+ index={current}
359
+ fade={fade}
360
+ leavingFrom={null}
361
+ widthSV={widthSV}
362
+ labels={labels}
363
+ hasDot={hasDot}
364
+ firstOfMonth={firstOfMonth}
365
+ />
366
+ </Animated.View>
367
+ </Animated.View>
368
+ </GestureDetector>
369
+ );
370
+ };
371
+
372
+ export const WeekStrip = memo(WeekStripInner);
373
+ WeekStrip.displayName = 'WeekStrip';
374
+
375
+ const makeStyles = ({ colors, fonts }: KitStyleArgs) => {
376
+ const text = {
377
+ position: 'absolute',
378
+ width: DAY_CELL,
379
+ textAlign: 'center',
380
+ fontFamily: fonts.regular,
381
+ fontSize: FONT_SIZE.sm,
382
+ lineHeight: DAY_LINE_HEIGHT,
383
+ } as const;
384
+ const dot = { position: 'absolute', width: DOT_SIZE, height: DOT_SIZE, borderRadius: RADIUS.full } as const;
385
+ return StyleSheet.create({
386
+ root: {
387
+ position: 'absolute',
388
+ top: 0,
389
+ left: 0,
390
+ height: WEEK_ROW_HEIGHT,
391
+ overflow: 'hidden',
392
+ backgroundColor: colors.surface,
393
+ },
394
+ tape: { position: 'absolute', top: 0, left: 0 },
395
+ row: { position: 'absolute', left: 0, height: WEEK_ROW_HEIGHT },
396
+ // A month's ground, alternating with the strip's own: it carries the month edge: it carries the month edge.
397
+ band: { position: 'absolute', top: 0, height: WEEK_ROW_HEIGHT, backgroundColor: colors.canvas },
398
+ label: { ...text, top: WEEK_ROW_V_MARGIN + DAY_TEXT_MARGIN_TOP, color: colors.text },
399
+ labelFirst: { ...text, top: WEEK_ROW_V_MARGIN + FIRST_OF_MONTH_TEXT_TOP, color: colors.text },
400
+ labelToday: { color: colors.accent },
401
+ labelDisabled: { color: colors.textMuted },
402
+ // Metadata: the muted tier, at the 11 px legibility floor.
403
+ monthLabel: {
404
+ position: 'absolute',
405
+ width: DAY_CELL,
406
+ textAlign: 'center',
407
+ top: WEEK_ROW_V_MARGIN + MONTH_LABEL_TOP,
408
+ fontFamily: fonts.regular,
409
+ fontSize: FONT_SIZE.xxs,
410
+ lineHeight: MONTH_LABEL_LINE_HEIGHT,
411
+ color: colors.textMuted,
412
+ },
413
+ dot: { ...dot, top: WEEK_ROW_V_MARGIN + DOT_TOP },
414
+ dotFirst: { ...dot, top: WEEK_ROW_V_MARGIN + DOT_TOP + FIRST_SHIFT },
415
+ dotDefault: { backgroundColor: colors.accent },
416
+ pill: {
417
+ position: 'absolute',
418
+ top: WEEK_ROW_V_MARGIN,
419
+ left: 0,
420
+ width: DAY_CELL,
421
+ height: DAY_CELL,
422
+ borderRadius: RADIUS.full,
423
+ // Active selection — the calendar's one accent fill: one accent, nowhere else.
424
+ backgroundColor: colors.accentFill,
425
+ },
426
+ pillContent: { ...StyleSheet.absoluteFillObject },
427
+ // A TextInput sits where a Text does only with Android's padding and font padding zeroed.
428
+ pillLabel: {
429
+ ...text,
430
+ top: DAY_TEXT_MARGIN_TOP,
431
+ left: 0,
432
+ height: DAY_LINE_HEIGHT,
433
+ padding: 0,
434
+ includeFontPadding: false,
435
+ color: colors.onAccentFill,
436
+ },
437
+ pillDot: { ...dot, top: DOT_TOP, left: DOT_INSET, backgroundColor: colors.onAccentFill },
438
+ });
439
+ };
@@ -0,0 +1,155 @@
1
+ /**
2
+ * Per-range tables the week strip and month grid render from, built in ONE
3
+ * integer pass over the range (no `Date`, no string parsing) and read by index.
4
+ */
5
+
6
+ import { civilOf, daysInMonth, epochDayOf } from '../core/civil';
7
+ import { dayIndexOf } from '../core/dateKey';
8
+ import type { CalendarRange, MarkedDates } from '../types';
9
+ import { DAY_CELL, WEEK_ROW_H_PADDING } from './geometry';
10
+
11
+ /** '1'…'31', so labels are shared strings rather than one allocation per day. */
12
+ const DAY_OF_MONTH_LABEL: readonly string[] = Array.from({ length: 32 }, (_, i) => String(i));
13
+
14
+ export type MonthPages = {
15
+ count: number;
16
+ /** Weeks per page (4, 5 or 6). */
17
+ weeksByPage: number[];
18
+ /** Day index of the 1st of each page's month (may be negative for page 0). */
19
+ monthStartByPage: number[];
20
+ /** First grid index (a week start) per page. */
21
+ gridStartByPage: number[];
22
+ /**
23
+ * Month page per day index, UNCLAMPED: −1 before the first page, `count` after
24
+ * the last. The grid's "is this day in this month" test needs it unclamped;
25
+ * paging clamps at the read site.
26
+ */
27
+ rawPageByIndex: number[];
28
+ };
29
+
30
+ export type CalendarCells = {
31
+ /** Day-of-month label per index. */
32
+ labels: string[];
33
+ /** y·12 + (m − 1) per index: the strip's month shading reads its parity, the month label its month. */
34
+ ordinalByIndex: number[];
35
+ pages: MonthPages;
36
+ };
37
+
38
+ /**
39
+ * Month pages span the SELECTABLE window only: the range is padded to whole
40
+ * weeks, and paging to a month with no selectable day would be a dead page.
41
+ */
42
+ export const buildCalendarCells = (range: CalendarRange): CalendarCells => {
43
+ const { days, startEpochDay, minIndex, maxIndex } = range;
44
+ const labels = new Array<string>(days);
45
+ const ordinalByIndex = new Array<number>(days);
46
+
47
+ const c0 = civilOf(startEpochDay);
48
+ let y = Math.floor(c0 / 10000);
49
+ let m = Math.floor(c0 / 100) % 100;
50
+ let d = c0 % 100;
51
+ let dim = daysInMonth(y, m);
52
+ for (let i = 0; i < days; i += 1) {
53
+ labels[i] = DAY_OF_MONTH_LABEL[d];
54
+ ordinalByIndex[i] = y * 12 + m - 1;
55
+ if (d === dim) {
56
+ d = 1;
57
+ if (m === 12) {
58
+ m = 1;
59
+ y += 1;
60
+ } else {
61
+ m += 1;
62
+ }
63
+ dim = daysInMonth(y, m);
64
+ } else {
65
+ d += 1;
66
+ }
67
+ }
68
+
69
+ const firstOrdinal = ordinalByIndex[minIndex];
70
+ const count = ordinalByIndex[maxIndex] - firstOrdinal + 1;
71
+
72
+ const rawPageByIndex = new Array<number>(days);
73
+ for (let i = 0; i < days; i += 1) {
74
+ const p = ordinalByIndex[i] - firstOrdinal;
75
+ rawPageByIndex[i] = p < 0 ? -1 : p >= count ? count : p;
76
+ }
77
+
78
+ const weeksByPage = new Array<number>(count);
79
+ const monthStartByPage = new Array<number>(count);
80
+ const gridStartByPage = new Array<number>(count);
81
+ for (let p = 0; p < count; p += 1) {
82
+ const ordinal = firstOrdinal + p;
83
+ const py = Math.floor(ordinal / 12);
84
+ const pm = (ordinal % 12) + 1;
85
+ const start = epochDayOf(py, pm, 1) - startEpochDay;
86
+ // Index 0 is a `firstDay`, so the week containing any index starts at the
87
+ // previous multiple of 7.
88
+ const gridStart = start - (((start % 7) + 7) % 7);
89
+ monthStartByPage[p] = start;
90
+ gridStartByPage[p] = gridStart;
91
+ weeksByPage[p] = Math.ceil((start - gridStart + daysInMonth(py, pm)) / 7);
92
+ }
93
+
94
+ return {
95
+ labels,
96
+ ordinalByIndex,
97
+ pages: { count, weeksByPage, monthStartByPage, gridStartByPage, rawPageByIndex },
98
+ };
99
+ };
100
+
101
+ /** Page of a day index, clamped to `[0, count)` — for paging, never for the grid test. */
102
+ export const pageOfIndex = (pages: MonthPages, idx: number): number => {
103
+ 'worklet';
104
+ const p = pages.rawPageByIndex[idx];
105
+ if (p === undefined) return 0;
106
+ return p < 0 ? 0 : p >= pages.count ? pages.count - 1 : p;
107
+ };
108
+
109
+ /**
110
+ * Dot colour per index: `null` = no dot, `''` = marked with no colour given
111
+ * (render the default token), otherwise the caller's colour.
112
+ */
113
+ export const buildDots = (range: CalendarRange, marked?: MarkedDates): (string | null)[] => {
114
+ const out = new Array<string | null>(range.days).fill(null);
115
+ if (!marked) return out;
116
+ for (const ymd in marked) {
117
+ const entry = marked[ymd];
118
+ if (!entry?.marked) continue;
119
+ const i = dayIndexOf(range, ymd);
120
+ if (i >= 0 && i < range.days) out[i] = entry.dotColor ?? '';
121
+ }
122
+ return out;
123
+ };
124
+
125
+ const columnWidth = (width: number): number => {
126
+ 'worklet';
127
+ return (width - WEEK_ROW_H_PADDING * 2) / 7;
128
+ };
129
+
130
+ /** Left edge of weekday COLUMN `col` (0…7) — where the strip's month band starts and stops. */
131
+ export const columnEdge = (width: number, col: number): number => WEEK_ROW_H_PADDING + col * columnWidth(width);
132
+
133
+ /**
134
+ * Left edge of weekday column `col`'s CELL: seven `flex: 1` columns inside 15 px side
135
+ * padding, each centring a 32 px cell — the library's layout, so strip, grid and
136
+ * pill share one formula and cannot sit a pixel apart.
137
+ */
138
+ export const cellLeft = (width: number, col: number): number => {
139
+ 'worklet';
140
+ const column = columnWidth(width);
141
+ return WEEK_ROW_H_PADDING + col * column + (column - DAY_CELL) / 2;
142
+ };
143
+
144
+ /** The seven column lefts for one width — build once per width, not per cell. */
145
+ export const cellLefts = (width: number): number[] => {
146
+ const out = new Array<number>(7);
147
+ for (let col = 0; col < 7; col += 1) out[col] = cellLeft(width, col);
148
+ return out;
149
+ };
150
+
151
+ /** Column under an x coordinate within a row — the inverse, for page-level taps. */
152
+ export const columnAt = (width: number, x: number): number => {
153
+ const col = Math.floor((x - WEEK_ROW_H_PADDING) / columnWidth(width));
154
+ return col < 0 ? 0 : col > 6 ? 6 : col;
155
+ };
@@ -0,0 +1,51 @@
1
+ /**
2
+ * The expandable calendar's geometry — numbers only, never a colour. Transcribed
3
+ * from `react-native-calendars`' style files (`calendar/day/basic/style.js`,
4
+ * `expandableCalendar/style.js`, `calendar/style.js`), then resized on
5
+ * 2026-09-11 toward the owner's Teams reference: a 40 px circle (was 32) with a
6
+ * month's short name above its 1st, in a row 2 px taller.
7
+ */
8
+
9
+ import { FONT_SIZE } from '../theme/tokens';
10
+
11
+ /** The selection circle and the tap target of a day. */
12
+ export const DAY_CELL = 40;
13
+ export const WEEK_ROW_V_MARGIN = 4;
14
+ /** The cell plus its two margins — the library's `WEEK_HEIGHT` shape. */
15
+ export const WEEK_ROW_HEIGHT = DAY_CELL + WEEK_ROW_V_MARGIN * 2;
16
+ export const WEEK_ROW_H_PADDING = 15;
17
+ /**
18
+ * Declared, never measured: the strip positions its dots absolutely and the grid
19
+ * flows them under the text, and an undeclared line box put them ~1.6 px apart.
20
+ * Inter's line box is fontSize × 1.21.
21
+ */
22
+ export const DAY_LINE_HEIGHT = Math.round(FONT_SIZE.sm * 1.21);
23
+ export const DOT_SIZE = 4;
24
+ export const DOT_MARGIN_TOP = 1;
25
+ /** Number and dot centred in the cell. */
26
+ export const DAY_TEXT_MARGIN_TOP = Math.round((DAY_CELL - DAY_LINE_HEIGHT - DOT_MARGIN_TOP - DOT_SIZE) / 2);
27
+
28
+ /** The strip's month name over a 1st, from the cell top; that cell's number and dot move under it. */
29
+ export const MONTH_LABEL_TOP = 1;
30
+ export const MONTH_LABEL_LINE_HEIGHT = Math.round(FONT_SIZE.xxs * 1.21);
31
+ export const FIRST_OF_MONTH_TEXT_TOP = MONTH_LABEL_TOP + MONTH_LABEL_LINE_HEIGHT;
32
+
33
+ export const KNOB_CONTAINER_HEIGHT = 24;
34
+ export const KNOB_WIDTH = 40;
35
+ export const KNOB_HEIGHT = 4;
36
+
37
+ /** The month layer is laid out once at the largest month's height. */
38
+ export const MAX_WEEKS = 6;
39
+
40
+ /** px a drag must travel before release commits to the other end. */
41
+ export const PAN_THRESHOLD = 30;
42
+ /** px/s: a faster flick decides the direction regardless of distance. */
43
+ export const SNAP_VELOCITY = 300;
44
+
45
+ /** Closed (one week), open on a `weeks`-row month, and the distance between; knob band included. */
46
+ export const calendarHeights = (weeks: number) => {
47
+ 'worklet';
48
+ const closed = WEEK_ROW_HEIGHT + KNOB_CONTAINER_HEIGHT;
49
+ const travel = WEEK_ROW_HEIGHT * (weeks - 1);
50
+ return { closed, full: closed + travel, travel };
51
+ };