react-native-roster 0.0.0 → 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 (373) hide show
  1. package/NOTICE.md +29 -0
  2. package/README.md +455 -2
  3. package/dist/src/adapters/rrule/cache.d.ts +15 -0
  4. package/dist/src/adapters/rrule/cache.d.ts.map +1 -0
  5. package/dist/src/adapters/rrule/cache.js +53 -0
  6. package/dist/src/adapters/rrule/cache.js.map +1 -0
  7. package/dist/src/adapters/rrule/envelope.d.ts +3 -0
  8. package/dist/src/adapters/rrule/envelope.d.ts.map +1 -0
  9. package/dist/src/adapters/rrule/envelope.js +9 -0
  10. package/dist/src/adapters/rrule/envelope.js.map +1 -0
  11. package/dist/src/adapters/rrule/expand.d.ts +4 -0
  12. package/dist/src/adapters/rrule/expand.d.ts.map +1 -0
  13. package/dist/src/adapters/rrule/expand.js +92 -0
  14. package/dist/src/adapters/rrule/expand.js.map +1 -0
  15. package/dist/src/adapters/rrule/hash.d.ts +3 -0
  16. package/dist/src/adapters/rrule/hash.d.ts.map +1 -0
  17. package/dist/src/adapters/rrule/hash.js +15 -0
  18. package/dist/src/adapters/rrule/hash.js.map +1 -0
  19. package/dist/src/adapters/rrule/index.d.ts +5 -0
  20. package/dist/src/adapters/rrule/index.d.ts.map +1 -0
  21. package/dist/src/adapters/rrule/index.js +12 -0
  22. package/dist/src/adapters/rrule/index.js.map +1 -0
  23. package/dist/src/adapters/rrule/net.d.ts +6 -0
  24. package/dist/src/adapters/rrule/net.d.ts.map +1 -0
  25. package/dist/src/adapters/rrule/net.js +31 -0
  26. package/dist/src/adapters/rrule/net.js.map +1 -0
  27. package/dist/src/adapters/rrule/occurrences.d.ts +6 -0
  28. package/dist/src/adapters/rrule/occurrences.d.ts.map +1 -0
  29. package/dist/src/adapters/rrule/occurrences.js +252 -0
  30. package/dist/src/adapters/rrule/occurrences.js.map +1 -0
  31. package/dist/src/adapters/rrule/types.d.ts +62 -0
  32. package/dist/src/adapters/rrule/types.d.ts.map +1 -0
  33. package/dist/src/adapters/rrule/types.js +3 -0
  34. package/dist/src/adapters/rrule/types.js.map +1 -0
  35. package/dist/src/adapters/rrule/validate.d.ts +6 -0
  36. package/dist/src/adapters/rrule/validate.d.ts.map +1 -0
  37. package/dist/src/adapters/rrule/validate.js +64 -0
  38. package/dist/src/adapters/rrule/validate.js.map +1 -0
  39. package/dist/src/components/layers/layers.types.d.ts +15 -0
  40. package/dist/src/components/layers/layers.types.d.ts.map +1 -0
  41. package/dist/src/components/layers/layers.types.js +3 -0
  42. package/dist/src/components/layers/layers.types.js.map +1 -0
  43. package/dist/src/components/layers/parts/gap.d.ts +3 -0
  44. package/dist/src/components/layers/parts/gap.d.ts.map +1 -0
  45. package/dist/src/components/layers/parts/gap.js +7 -0
  46. package/dist/src/components/layers/parts/gap.js.map +1 -0
  47. package/dist/src/components/layers/parts/interval.d.ts +3 -0
  48. package/dist/src/components/layers/parts/interval.d.ts.map +1 -0
  49. package/dist/src/components/layers/parts/interval.js +22 -0
  50. package/dist/src/components/layers/parts/interval.js.map +1 -0
  51. package/dist/src/components/layers/utils/styles.d.ts +7 -0
  52. package/dist/src/components/layers/utils/styles.d.ts.map +1 -0
  53. package/dist/src/components/layers/utils/styles.js +24 -0
  54. package/dist/src/components/layers/utils/styles.js.map +1 -0
  55. package/dist/src/components/primitives/press-point.d.ts +3 -0
  56. package/dist/src/components/primitives/press-point.d.ts.map +1 -0
  57. package/dist/src/components/primitives/press-point.js +7 -0
  58. package/dist/src/components/primitives/press-point.js.map +1 -0
  59. package/dist/src/components/primitives/press-point.types.d.ts +14 -0
  60. package/dist/src/components/primitives/press-point.types.d.ts.map +1 -0
  61. package/dist/src/components/primitives/press-point.types.js +3 -0
  62. package/dist/src/components/primitives/press-point.types.js.map +1 -0
  63. package/dist/src/components/primitives/press-point.web.d.ts +3 -0
  64. package/dist/src/components/primitives/press-point.web.d.ts.map +1 -0
  65. package/dist/src/components/primitives/press-point.web.js +17 -0
  66. package/dist/src/components/primitives/press-point.web.js.map +1 -0
  67. package/dist/src/components/primitives/region-style.d.ts +9 -0
  68. package/dist/src/components/primitives/region-style.d.ts.map +1 -0
  69. package/dist/src/components/primitives/region-style.js +20 -0
  70. package/dist/src/components/primitives/region-style.js.map +1 -0
  71. package/dist/src/components/roster/body-layout.d.ts +9 -0
  72. package/dist/src/components/roster/body-layout.d.ts.map +1 -0
  73. package/dist/src/components/roster/body-layout.js +9 -0
  74. package/dist/src/components/roster/body-layout.js.map +1 -0
  75. package/dist/src/components/roster/index.d.ts +3 -0
  76. package/dist/src/components/roster/index.d.ts.map +1 -0
  77. package/dist/src/components/roster/index.js +40 -0
  78. package/dist/src/components/roster/index.js.map +1 -0
  79. package/dist/src/components/roster/lanes/interval-hover.d.ts +3 -0
  80. package/dist/src/components/roster/lanes/interval-hover.d.ts.map +1 -0
  81. package/dist/src/components/roster/lanes/interval-hover.js +7 -0
  82. package/dist/src/components/roster/lanes/interval-hover.js.map +1 -0
  83. package/dist/src/components/roster/lanes/interval-hover.types.d.ts +15 -0
  84. package/dist/src/components/roster/lanes/interval-hover.types.d.ts.map +1 -0
  85. package/dist/src/components/roster/lanes/interval-hover.types.js +3 -0
  86. package/dist/src/components/roster/lanes/interval-hover.types.js.map +1 -0
  87. package/dist/src/components/roster/lanes/interval-hover.web.d.ts +3 -0
  88. package/dist/src/components/roster/lanes/interval-hover.web.d.ts.map +1 -0
  89. package/dist/src/components/roster/lanes/interval-hover.web.js +20 -0
  90. package/dist/src/components/roster/lanes/interval-hover.web.js.map +1 -0
  91. package/dist/src/components/roster/lanes/lane.d.ts +10 -0
  92. package/dist/src/components/roster/lanes/lane.d.ts.map +1 -0
  93. package/dist/src/components/roster/lanes/lane.js +32 -0
  94. package/dist/src/components/roster/lanes/lane.js.map +1 -0
  95. package/dist/src/components/roster/lanes/parts/incomplete.d.ts +8 -0
  96. package/dist/src/components/roster/lanes/parts/incomplete.d.ts.map +1 -0
  97. package/dist/src/components/roster/lanes/parts/incomplete.js +30 -0
  98. package/dist/src/components/roster/lanes/parts/incomplete.js.map +1 -0
  99. package/dist/src/components/roster/lanes/parts/lane-label.d.ts +3 -0
  100. package/dist/src/components/roster/lanes/parts/lane-label.d.ts.map +1 -0
  101. package/dist/src/components/roster/lanes/parts/lane-label.js +18 -0
  102. package/dist/src/components/roster/lanes/parts/lane-label.js.map +1 -0
  103. package/dist/src/components/roster/layout.d.ts +17 -0
  104. package/dist/src/components/roster/layout.d.ts.map +1 -0
  105. package/dist/src/components/roster/layout.js +24 -0
  106. package/dist/src/components/roster/layout.js.map +1 -0
  107. package/dist/src/components/roster/parts/body.d.ts +7 -0
  108. package/dist/src/components/roster/parts/body.d.ts.map +1 -0
  109. package/dist/src/components/roster/parts/body.js +14 -0
  110. package/dist/src/components/roster/parts/body.js.map +1 -0
  111. package/dist/src/components/roster/parts/corner.d.ts +2 -0
  112. package/dist/src/components/roster/parts/corner.d.ts.map +1 -0
  113. package/dist/src/components/roster/parts/corner.js +7 -0
  114. package/dist/src/components/roster/parts/corner.js.map +1 -0
  115. package/dist/src/components/roster/parts/empty.d.ts +2 -0
  116. package/dist/src/components/roster/parts/empty.d.ts.map +1 -0
  117. package/dist/src/components/roster/parts/empty.js +9 -0
  118. package/dist/src/components/roster/parts/empty.js.map +1 -0
  119. package/dist/src/components/roster/parts/grid.d.ts +3 -0
  120. package/dist/src/components/roster/parts/grid.d.ts.map +1 -0
  121. package/dist/src/components/roster/parts/grid.js +16 -0
  122. package/dist/src/components/roster/parts/grid.js.map +1 -0
  123. package/dist/src/components/roster/parts/header-cell.d.ts +3 -0
  124. package/dist/src/components/roster/parts/header-cell.d.ts.map +1 -0
  125. package/dist/src/components/roster/parts/header-cell.js +9 -0
  126. package/dist/src/components/roster/parts/header-cell.js.map +1 -0
  127. package/dist/src/components/roster/parts/header.d.ts +3 -0
  128. package/dist/src/components/roster/parts/header.d.ts.map +1 -0
  129. package/dist/src/components/roster/parts/header.js +13 -0
  130. package/dist/src/components/roster/parts/header.js.map +1 -0
  131. package/dist/src/components/roster/parts/lane-label-column.d.ts +3 -0
  132. package/dist/src/components/roster/parts/lane-label-column.d.ts.map +1 -0
  133. package/dist/src/components/roster/parts/lane-label-column.js +18 -0
  134. package/dist/src/components/roster/parts/lane-label-column.js.map +1 -0
  135. package/dist/src/components/roster/parts/lane-list.d.ts +7 -0
  136. package/dist/src/components/roster/parts/lane-list.d.ts.map +1 -0
  137. package/dist/src/components/roster/parts/lane-list.js +25 -0
  138. package/dist/src/components/roster/parts/lane-list.js.map +1 -0
  139. package/dist/src/components/roster/roster.types.d.ts +145 -0
  140. package/dist/src/components/roster/roster.types.d.ts.map +1 -0
  141. package/dist/src/components/roster/roster.types.js +3 -0
  142. package/dist/src/components/roster/roster.types.js.map +1 -0
  143. package/dist/src/components/roster/use-roster.d.ts +3 -0
  144. package/dist/src/components/roster/use-roster.d.ts.map +1 -0
  145. package/dist/src/components/roster/use-roster.js +106 -0
  146. package/dist/src/components/roster/use-roster.js.map +1 -0
  147. package/dist/src/components/roster/utils/body-content-key.d.ts +3 -0
  148. package/dist/src/components/roster/utils/body-content-key.d.ts.map +1 -0
  149. package/dist/src/components/roster/utils/body-content-key.js +29 -0
  150. package/dist/src/components/roster/utils/body-content-key.js.map +1 -0
  151. package/dist/src/components/roster/utils/ticks.d.ts +4 -0
  152. package/dist/src/components/roster/utils/ticks.d.ts.map +1 -0
  153. package/dist/src/components/roster/utils/ticks.js +60 -0
  154. package/dist/src/components/roster/utils/ticks.js.map +1 -0
  155. package/dist/src/components/schedule/days/day.d.ts +20 -0
  156. package/dist/src/components/schedule/days/day.d.ts.map +1 -0
  157. package/dist/src/components/schedule/days/day.js +17 -0
  158. package/dist/src/components/schedule/days/day.js.map +1 -0
  159. package/dist/src/components/schedule/days/header-layout.d.ts +9 -0
  160. package/dist/src/components/schedule/days/header-layout.d.ts.map +1 -0
  161. package/dist/src/components/schedule/days/header-layout.js +9 -0
  162. package/dist/src/components/schedule/days/header-layout.js.map +1 -0
  163. package/dist/src/components/schedule/days/layout.d.ts +18 -0
  164. package/dist/src/components/schedule/days/layout.d.ts.map +1 -0
  165. package/dist/src/components/schedule/days/layout.js +9 -0
  166. package/dist/src/components/schedule/days/layout.js.map +1 -0
  167. package/dist/src/components/schedule/days/parts/column.d.ts +3 -0
  168. package/dist/src/components/schedule/days/parts/column.d.ts.map +1 -0
  169. package/dist/src/components/schedule/days/parts/column.js +28 -0
  170. package/dist/src/components/schedule/days/parts/column.js.map +1 -0
  171. package/dist/src/components/schedule/days/parts/day-header.d.ts +5 -0
  172. package/dist/src/components/schedule/days/parts/day-header.d.ts.map +1 -0
  173. package/dist/src/components/schedule/days/parts/day-header.js +10 -0
  174. package/dist/src/components/schedule/days/parts/day-header.js.map +1 -0
  175. package/dist/src/components/schedule/days/parts/grid.d.ts +3 -0
  176. package/dist/src/components/schedule/days/parts/grid.d.ts.map +1 -0
  177. package/dist/src/components/schedule/days/parts/grid.js +14 -0
  178. package/dist/src/components/schedule/days/parts/grid.js.map +1 -0
  179. package/dist/src/components/schedule/days/parts/now-line.d.ts +5 -0
  180. package/dist/src/components/schedule/days/parts/now-line.d.ts.map +1 -0
  181. package/dist/src/components/schedule/days/parts/now-line.js +9 -0
  182. package/dist/src/components/schedule/days/parts/now-line.js.map +1 -0
  183. package/dist/src/components/schedule/days/parts/skipped-date.d.ts +4 -0
  184. package/dist/src/components/schedule/days/parts/skipped-date.d.ts.map +1 -0
  185. package/dist/src/components/schedule/days/parts/skipped-date.js +17 -0
  186. package/dist/src/components/schedule/days/parts/skipped-date.js.map +1 -0
  187. package/dist/src/components/schedule/days/parts/transition.d.ts +3 -0
  188. package/dist/src/components/schedule/days/parts/transition.d.ts.map +1 -0
  189. package/dist/src/components/schedule/days/parts/transition.js +42 -0
  190. package/dist/src/components/schedule/days/parts/transition.js.map +1 -0
  191. package/dist/src/components/schedule/index.d.ts +3 -0
  192. package/dist/src/components/schedule/index.d.ts.map +1 -0
  193. package/dist/src/components/schedule/index.js +44 -0
  194. package/dist/src/components/schedule/index.js.map +1 -0
  195. package/dist/src/components/schedule/layout.d.ts +15 -0
  196. package/dist/src/components/schedule/layout.d.ts.map +1 -0
  197. package/dist/src/components/schedule/layout.js +10 -0
  198. package/dist/src/components/schedule/layout.js.map +1 -0
  199. package/dist/src/components/schedule/parts/gutter.d.ts +3 -0
  200. package/dist/src/components/schedule/parts/gutter.d.ts.map +1 -0
  201. package/dist/src/components/schedule/parts/gutter.js +9 -0
  202. package/dist/src/components/schedule/parts/gutter.js.map +1 -0
  203. package/dist/src/components/schedule/parts/incomplete.d.ts +6 -0
  204. package/dist/src/components/schedule/parts/incomplete.d.ts.map +1 -0
  205. package/dist/src/components/schedule/parts/incomplete.js +9 -0
  206. package/dist/src/components/schedule/parts/incomplete.js.map +1 -0
  207. package/dist/src/components/schedule/schedule.types.d.ts +109 -0
  208. package/dist/src/components/schedule/schedule.types.d.ts.map +1 -0
  209. package/dist/src/components/schedule/schedule.types.js +3 -0
  210. package/dist/src/components/schedule/schedule.types.js.map +1 -0
  211. package/dist/src/components/schedule/use-schedule-viewport.d.ts +7 -0
  212. package/dist/src/components/schedule/use-schedule-viewport.d.ts.map +1 -0
  213. package/dist/src/components/schedule/use-schedule-viewport.js +15 -0
  214. package/dist/src/components/schedule/use-schedule-viewport.js.map +1 -0
  215. package/dist/src/components/schedule/use-schedule.d.ts +3 -0
  216. package/dist/src/components/schedule/use-schedule.d.ts.map +1 -0
  217. package/dist/src/components/schedule/use-schedule.js +71 -0
  218. package/dist/src/components/schedule/use-schedule.js.map +1 -0
  219. package/dist/src/components/schedule/utils/days.d.ts +17 -0
  220. package/dist/src/components/schedule/utils/days.d.ts.map +1 -0
  221. package/dist/src/components/schedule/utils/days.js +49 -0
  222. package/dist/src/components/schedule/utils/days.js.map +1 -0
  223. package/dist/src/core/axis.d.ts +18 -0
  224. package/dist/src/core/axis.d.ts.map +1 -0
  225. package/dist/src/core/axis.js +58 -0
  226. package/dist/src/core/axis.js.map +1 -0
  227. package/dist/src/core/cache.d.ts +29 -0
  228. package/dist/src/core/cache.d.ts.map +1 -0
  229. package/dist/src/core/cache.js +33 -0
  230. package/dist/src/core/cache.js.map +1 -0
  231. package/dist/src/core/columns.d.ts +3 -0
  232. package/dist/src/core/columns.d.ts.map +1 -0
  233. package/dist/src/core/columns.js +45 -0
  234. package/dist/src/core/columns.js.map +1 -0
  235. package/dist/src/core/coverage.d.ts +3 -0
  236. package/dist/src/core/coverage.d.ts.map +1 -0
  237. package/dist/src/core/coverage.js +60 -0
  238. package/dist/src/core/coverage.js.map +1 -0
  239. package/dist/src/core/flag.d.ts +3 -0
  240. package/dist/src/core/flag.d.ts.map +1 -0
  241. package/dist/src/core/flag.js +17 -0
  242. package/dist/src/core/flag.js.map +1 -0
  243. package/dist/src/core/hash.d.ts +5 -0
  244. package/dist/src/core/hash.d.ts.map +1 -0
  245. package/dist/src/core/hash.js +29 -0
  246. package/dist/src/core/hash.js.map +1 -0
  247. package/dist/src/core/hit-test.d.ts +6 -0
  248. package/dist/src/core/hit-test.d.ts.map +1 -0
  249. package/dist/src/core/hit-test.js +23 -0
  250. package/dist/src/core/hit-test.js.map +1 -0
  251. package/dist/src/core/index.d.ts +12 -0
  252. package/dist/src/core/index.d.ts.map +1 -0
  253. package/dist/src/core/index.js +30 -0
  254. package/dist/src/core/index.js.map +1 -0
  255. package/dist/src/core/layout.d.ts +3 -0
  256. package/dist/src/core/layout.d.ts.map +1 -0
  257. package/dist/src/core/layout.js +96 -0
  258. package/dist/src/core/layout.js.map +1 -0
  259. package/dist/src/core/order.d.ts +7 -0
  260. package/dist/src/core/order.d.ts.map +1 -0
  261. package/dist/src/core/order.js +12 -0
  262. package/dist/src/core/order.js.map +1 -0
  263. package/dist/src/core/scale.d.ts +9 -0
  264. package/dist/src/core/scale.d.ts.map +1 -0
  265. package/dist/src/core/scale.js +41 -0
  266. package/dist/src/core/scale.js.map +1 -0
  267. package/dist/src/core/snap.d.ts +10 -0
  268. package/dist/src/core/snap.d.ts.map +1 -0
  269. package/dist/src/core/snap.js +43 -0
  270. package/dist/src/core/snap.js.map +1 -0
  271. package/dist/src/core/spans.d.ts +3 -0
  272. package/dist/src/core/spans.d.ts.map +1 -0
  273. package/dist/src/core/spans.js +60 -0
  274. package/dist/src/core/spans.js.map +1 -0
  275. package/dist/src/core/types.d.ts +104 -0
  276. package/dist/src/core/types.d.ts.map +1 -0
  277. package/dist/src/core/types.js +3 -0
  278. package/dist/src/core/types.js.map +1 -0
  279. package/dist/src/core/zone.d.ts +10 -0
  280. package/dist/src/core/zone.d.ts.map +1 -0
  281. package/dist/src/core/zone.js +103 -0
  282. package/dist/src/core/zone.js.map +1 -0
  283. package/dist/src/index.d.ts +29 -0
  284. package/dist/src/index.d.ts.map +1 -0
  285. package/dist/src/index.js +67 -0
  286. package/dist/src/index.js.map +1 -0
  287. package/dist/src/nativewind/index.d.ts +59 -0
  288. package/dist/src/nativewind/index.d.ts.map +1 -0
  289. package/dist/src/nativewind/index.js +24 -0
  290. package/dist/src/nativewind/index.js.map +1 -0
  291. package/docs/migrations.md +61 -0
  292. package/llms.txt +498 -0
  293. package/package.json +155 -8
  294. package/src/adapters/rrule/README.md +41 -0
  295. package/src/adapters/rrule/cache.ts +50 -0
  296. package/src/adapters/rrule/envelope.ts +7 -0
  297. package/src/adapters/rrule/expand.ts +105 -0
  298. package/src/adapters/rrule/hash.ts +13 -0
  299. package/src/adapters/rrule/index.ts +11 -0
  300. package/src/adapters/rrule/net.ts +30 -0
  301. package/src/adapters/rrule/occurrences.ts +288 -0
  302. package/src/adapters/rrule/types.ts +52 -0
  303. package/src/adapters/rrule/validate.ts +78 -0
  304. package/src/components/layers/README.md +15 -0
  305. package/src/components/layers/layers.types.ts +6 -0
  306. package/src/components/layers/parts/gap.tsx +5 -0
  307. package/src/components/layers/parts/interval.tsx +24 -0
  308. package/src/components/layers/utils/styles.ts +24 -0
  309. package/src/components/primitives/README.md +12 -0
  310. package/src/components/primitives/press-point.tsx +5 -0
  311. package/src/components/primitives/press-point.types.ts +5 -0
  312. package/src/components/primitives/press-point.web.tsx +19 -0
  313. package/src/components/primitives/region-style.ts +21 -0
  314. package/src/components/roster/README.md +29 -0
  315. package/src/components/roster/body-layout.tsx +32 -0
  316. package/src/components/roster/index.tsx +108 -0
  317. package/src/components/roster/lanes/interval-hover.tsx +5 -0
  318. package/src/components/roster/lanes/interval-hover.types.ts +11 -0
  319. package/src/components/roster/lanes/interval-hover.web.tsx +19 -0
  320. package/src/components/roster/lanes/lane.tsx +93 -0
  321. package/src/components/roster/lanes/parts/incomplete.tsx +44 -0
  322. package/src/components/roster/lanes/parts/lane-label.tsx +41 -0
  323. package/src/components/roster/layout.tsx +68 -0
  324. package/src/components/roster/parts/body.tsx +24 -0
  325. package/src/components/roster/parts/corner.tsx +3 -0
  326. package/src/components/roster/parts/empty.tsx +5 -0
  327. package/src/components/roster/parts/grid.tsx +26 -0
  328. package/src/components/roster/parts/header-cell.tsx +10 -0
  329. package/src/components/roster/parts/header.tsx +23 -0
  330. package/src/components/roster/parts/lane-label-column.tsx +31 -0
  331. package/src/components/roster/parts/lane-list.tsx +74 -0
  332. package/src/components/roster/roster.types.ts +156 -0
  333. package/src/components/roster/use-roster.ts +133 -0
  334. package/src/components/roster/utils/body-content-key.ts +46 -0
  335. package/src/components/roster/utils/ticks.ts +62 -0
  336. package/src/components/schedule/README.md +23 -0
  337. package/src/components/schedule/days/day.tsx +89 -0
  338. package/src/components/schedule/days/header-layout.tsx +12 -0
  339. package/src/components/schedule/days/layout.tsx +38 -0
  340. package/src/components/schedule/days/parts/column.tsx +59 -0
  341. package/src/components/schedule/days/parts/day-header.tsx +18 -0
  342. package/src/components/schedule/days/parts/grid.tsx +21 -0
  343. package/src/components/schedule/days/parts/now-line.tsx +11 -0
  344. package/src/components/schedule/days/parts/skipped-date.tsx +22 -0
  345. package/src/components/schedule/days/parts/transition.tsx +70 -0
  346. package/src/components/schedule/index.tsx +108 -0
  347. package/src/components/schedule/layout.tsx +42 -0
  348. package/src/components/schedule/parts/gutter.tsx +16 -0
  349. package/src/components/schedule/parts/incomplete.tsx +13 -0
  350. package/src/components/schedule/schedule.types.ts +103 -0
  351. package/src/components/schedule/use-schedule-viewport.ts +13 -0
  352. package/src/components/schedule/use-schedule.ts +75 -0
  353. package/src/components/schedule/utils/days.ts +54 -0
  354. package/src/core/README.md +25 -0
  355. package/src/core/axis.ts +58 -0
  356. package/src/core/cache.ts +38 -0
  357. package/src/core/columns.ts +49 -0
  358. package/src/core/coverage.ts +56 -0
  359. package/src/core/flag.ts +14 -0
  360. package/src/core/hash.ts +28 -0
  361. package/src/core/hit-test.ts +27 -0
  362. package/src/core/index.ts +34 -0
  363. package/src/core/layout.ts +101 -0
  364. package/src/core/order.ts +18 -0
  365. package/src/core/scale.ts +45 -0
  366. package/src/core/snap.ts +52 -0
  367. package/src/core/spans.ts +58 -0
  368. package/src/core/types.ts +92 -0
  369. package/src/core/zone.ts +100 -0
  370. package/src/index.ts +52 -0
  371. package/src/nativewind/README.md +14 -0
  372. package/src/nativewind/index.ts +30 -0
  373. package/index.js +0 -4
@@ -0,0 +1,108 @@
1
+ import { RosterGap } from '../layers/parts/gap';
2
+ import { RosterInterval } from '../layers/parts/interval';
3
+ import { RosterLaneLabel } from './lanes/parts/lane-label';
4
+ import { RosterLayout } from './layout';
5
+ import { RosterBody } from './parts/body';
6
+ import { RosterCorner } from './parts/corner';
7
+ import { RosterEmpty } from './parts/empty';
8
+ import { RosterGrid } from './parts/grid';
9
+ import { RosterHeader } from './parts/header';
10
+ import { RosterHeaderCell } from './parts/header-cell';
11
+ import { RosterLaneLabelColumn } from './parts/lane-label-column';
12
+ import type { RosterProps } from './roster.types';
13
+ import { useRoster } from './use-roster';
14
+
15
+ const defaultEmptyZone = <RosterEmpty />;
16
+ const defaultCornerZone = <RosterCorner />;
17
+
18
+ export function Roster(props: RosterProps) {
19
+ const {
20
+ status,
21
+ orderedLanes,
22
+ laneState,
23
+ window,
24
+ geometryFor,
25
+ projection,
26
+ scroll,
27
+ press,
28
+ ticks,
29
+ contentWidth,
30
+ viewport,
31
+ onLayout,
32
+ } = useRoster(props);
33
+ const {
34
+ emptyZone = defaultEmptyZone,
35
+ cornerZone = defaultCornerZone,
36
+ headerComponent: HeaderComponent = RosterHeader,
37
+ laneLabelColumnComponent: LaneLabelColumnComponent = RosterLaneLabelColumn,
38
+ bodyComponent: BodyComponent = RosterBody,
39
+ headerCellComponent = RosterHeaderCell,
40
+ laneLabelComponent = RosterLaneLabel,
41
+ intervalComponent = RosterInterval,
42
+ gapComponent = RosterGap,
43
+ gridComponent = RosterGrid,
44
+ incompleteLabel = 'Availability may be incomplete',
45
+ neverSetLabel = 'No availability set',
46
+ } = props;
47
+ if (status === 'empty') return emptyZone;
48
+ if (window.start === window.end) return null;
49
+ return (
50
+ <RosterLayout
51
+ style={props.style}
52
+ headerStyle={props.headerStyle}
53
+ laneLabelColumnStyle={props.laneLabelColumnStyle}
54
+ bodyStyle={props.bodyStyle}
55
+ laneLabelWidth={props.laneLabelWidth}
56
+ onLayout={onLayout}
57
+ cornerZone={cornerZone}
58
+ headerZone={
59
+ <HeaderComponent
60
+ ticks={ticks}
61
+ projection={projection}
62
+ scroll={scroll}
63
+ contentWidth={contentWidth}
64
+ headerCellComponent={headerCellComponent}
65
+ />
66
+ }
67
+ laneLabelColumnZone={
68
+ <LaneLabelColumnComponent
69
+ labels={orderedLanes.map((lane) => {
70
+ const state = laneState.get(lane.id) ?? {
71
+ flag: 'none',
72
+ complete: true,
73
+ };
74
+ return {
75
+ lane,
76
+ ...state,
77
+ viewTimezone: projection.viewTimezone,
78
+ incompleteLabel,
79
+ neverSetLabel,
80
+ };
81
+ })}
82
+ projection={projection}
83
+ scroll={scroll}
84
+ laneLabelComponent={laneLabelComponent}
85
+ />
86
+ }
87
+ bodyZone={
88
+ <BodyComponent
89
+ lanes={orderedLanes}
90
+ window={window}
91
+ geometryFor={geometryFor}
92
+ projection={projection}
93
+ scroll={scroll}
94
+ press={press}
95
+ ticks={ticks}
96
+ contentWidth={contentWidth}
97
+ viewport={viewport}
98
+ intervalComponent={intervalComponent}
99
+ gapComponent={gapComponent}
100
+ gridComponent={gridComponent}
101
+ highlightSource={props.highlightSource}
102
+ onIntervalHover={props.onIntervalHover}
103
+ incompleteLabel={incompleteLabel}
104
+ />
105
+ }
106
+ />
107
+ );
108
+ }
@@ -0,0 +1,5 @@
1
+ import type { IntervalHoverInput, IntervalHoverProps } from './interval-hover.types';
2
+
3
+ export function intervalHoverProps(_input: IntervalHoverInput): IntervalHoverProps {
4
+ return {};
5
+ }
@@ -0,0 +1,11 @@
1
+ import type { Lane, LaneGeometry, Rect } from '../../../core';
2
+ import type { PressPointInput } from '../../primitives/press-point.types';
3
+
4
+ export type IntervalHoverInput = {
5
+ lane: Lane;
6
+ geometry: LaneGeometry;
7
+ onIntervalHover?: (rect: Rect, lane: Lane) => void;
8
+ };
9
+ export type IntervalHoverProps = {
10
+ onPointerMove?: (input: PressPointInput & { nativeEvent: { pointerType?: string } }) => void;
11
+ };
@@ -0,0 +1,19 @@
1
+ import { hitTest } from '../../../core/hit-test';
2
+ import { pressPoint } from '../../primitives/press-point.web';
3
+ import type { IntervalHoverInput, IntervalHoverProps } from './interval-hover.types';
4
+
5
+ export function intervalHoverProps({
6
+ lane,
7
+ geometry,
8
+ onIntervalHover,
9
+ }: IntervalHoverInput): IntervalHoverProps {
10
+ if (!onIntervalHover) return {};
11
+ return {
12
+ onPointerMove(input) {
13
+ if (input.nativeEvent.pointerType === 'touch') return;
14
+ const { x, y } = pressPoint(input);
15
+ const hit = hitTest(lane, geometry, x, y);
16
+ if (hit?.kind === 'interval') onIntervalHover(hit.rect, lane);
17
+ },
18
+ };
19
+ }
@@ -0,0 +1,93 @@
1
+ import { Fragment } from 'react';
2
+ import { Pressable } from 'react-native';
3
+ import type { Lane, LaneGeometry } from '../../../core';
4
+ import { pressPoint } from '../../primitives/press-point';
5
+ import type { BodyInput } from '../roster.types';
6
+ import { intervalHoverProps } from './interval-hover';
7
+ import { RosterIncomplete } from './parts/incomplete';
8
+
9
+ export type LaneRowProps = Pick<
10
+ BodyInput,
11
+ | 'press'
12
+ | 'intervalComponent'
13
+ | 'gapComponent'
14
+ | 'highlightSource'
15
+ | 'onIntervalHover'
16
+ | 'incompleteLabel'
17
+ > & {
18
+ lane: Lane;
19
+ geometry: LaneGeometry;
20
+ width: number;
21
+ rowHeight: number;
22
+ };
23
+
24
+ export function LaneRow({
25
+ lane,
26
+ geometry,
27
+ width,
28
+ rowHeight,
29
+ press,
30
+ intervalComponent: IntervalComponent,
31
+ gapComponent: GapComponent,
32
+ highlightSource,
33
+ onIntervalHover,
34
+ incompleteLabel = 'Availability may be incomplete',
35
+ }: LaneRowProps) {
36
+ const layers = [...lane.layers].sort((a, b) => a.z - b.z);
37
+ return (
38
+ <Pressable
39
+ {...intervalHoverProps({ lane, geometry, onIntervalHover })}
40
+ testID={`roster-lane-${lane.id}`}
41
+ accessibilityLabel={lane.label}
42
+ onPress={(input) => {
43
+ const point = pressPoint(input);
44
+ press(lane, point.x, point.y);
45
+ }}
46
+ style={{ width, height: rowHeight }}
47
+ >
48
+ <RosterIncomplete lane={lane} geometry={geometry} width={width} label={incompleteLabel} />
49
+ {layers.map((layer) => (
50
+ <Fragment key={layer.id}>
51
+ {geometry.rects
52
+ .filter((rect) => rect.layerId === layer.id)
53
+ .map((rect) => (
54
+ <Fragment key={`interval-${rect.x}:${rect.width}`}>
55
+ <IntervalComponent
56
+ rect={rect}
57
+ layer={layer}
58
+ lane={lane}
59
+ highlighted={rect.sources.some(
60
+ (source) =>
61
+ source.kind === highlightSource?.kind && source.id === highlightSource.id,
62
+ )}
63
+ />
64
+ </Fragment>
65
+ ))}
66
+ {geometry.gapRects
67
+ .filter((rect) => rect.layerId === layer.id)
68
+ .map((rect) => (
69
+ <Pressable
70
+ key={`gap-${rect.x}:${rect.width}`}
71
+ accessibilityLabel={`${lane.label}: removed time`}
72
+ onPress={(input) => {
73
+ input.stopPropagation();
74
+ const point = pressPoint(input);
75
+ press(lane, rect.x + point.x, rect.y + point.y);
76
+ }}
77
+ style={{
78
+ position: 'absolute',
79
+ left: rect.x,
80
+ top: rect.y,
81
+ width: rect.width,
82
+ height: rect.height,
83
+ zIndex: rect.z,
84
+ }}
85
+ >
86
+ <GapComponent rect={rect} layer={layer} lane={lane} />
87
+ </Pressable>
88
+ ))}
89
+ </Fragment>
90
+ ))}
91
+ </Pressable>
92
+ );
93
+ }
@@ -0,0 +1,44 @@
1
+ import { Text } from 'react-native';
2
+ import type { Lane, LaneGeometry } from '../../../../core';
3
+
4
+ export function RosterIncomplete({
5
+ lane,
6
+ geometry,
7
+ width,
8
+ label,
9
+ }: {
10
+ lane: Lane;
11
+ geometry: LaneGeometry;
12
+ width: number;
13
+ label: string;
14
+ }) {
15
+ if (lane.complete !== false) return null;
16
+ // Choose the first empty span; the notice never covers an interval.
17
+ let left = 0;
18
+ let right = width;
19
+ for (const rect of [...geometry.rects].sort((a, b) => a.x - b.x)) {
20
+ if (rect.x > left) {
21
+ right = rect.x;
22
+ break;
23
+ }
24
+ left = Math.max(left, rect.x + rect.width);
25
+ }
26
+ if (left >= right) return null;
27
+ return (
28
+ <Text
29
+ testID={`roster-incomplete-${lane.id}`}
30
+ pointerEvents="none"
31
+ numberOfLines={1}
32
+ style={{
33
+ position: 'absolute',
34
+ left,
35
+ width: right - left,
36
+ top: 4,
37
+ color: '#64748b',
38
+ fontSize: 12,
39
+ }}
40
+ >
41
+ {label}
42
+ </Text>
43
+ );
44
+ }
@@ -0,0 +1,41 @@
1
+ import { Text, View } from 'react-native';
2
+ import type { LaneLabelInput } from '../../roster.types';
3
+
4
+ export function RosterLaneLabel({
5
+ lane,
6
+ flag,
7
+ complete,
8
+ viewTimezone,
9
+ incompleteLabel,
10
+ neverSetLabel,
11
+ }: LaneLabelInput) {
12
+ const zone =
13
+ lane.timezone && lane.timezone !== viewTimezone ? (
14
+ <Text style={{ fontSize: 10, color: '#64748b' }}>{lane.timezone}</Text>
15
+ ) : null;
16
+ const flagText =
17
+ flag === 'never-set' ? (
18
+ <Text style={{ fontSize: 10, color: '#9a3412' }}>{neverSetLabel}</Text>
19
+ ) : null;
20
+ const completeness = complete ? null : (
21
+ <Text style={{ fontSize: 10, color: '#9a3412' }}>{incompleteLabel}</Text>
22
+ );
23
+ return (
24
+ <View
25
+ style={{
26
+ flex: 1,
27
+ justifyContent: 'center',
28
+ paddingHorizontal: 8,
29
+ borderBottomWidth: 1,
30
+ borderBottomColor: '#e2e8f0',
31
+ }}
32
+ >
33
+ <Text numberOfLines={1} style={{ color: '#0f172a', fontSize: 12 }}>
34
+ {lane.label}
35
+ </Text>
36
+ {zone}
37
+ {flagText}
38
+ {completeness}
39
+ </View>
40
+ );
41
+ }
@@ -0,0 +1,68 @@
1
+ import type { ReactNode } from 'react';
2
+ import type { LayoutChangeEvent } from 'react-native';
3
+ import { View } from 'react-native';
4
+ import { regionStyle } from '../primitives/region-style';
5
+ import type { RosterStyleProps } from './roster.types';
6
+
7
+ type RosterLayoutProps = Omit<RosterStyleProps, `${string}ClassName` | 'className'> & {
8
+ /** Cell above the lane labels, beside the header. */
9
+ cornerZone: ReactNode;
10
+ /** Frozen tick row; the layout clips translated header content. */
11
+ headerZone: ReactNode;
12
+ /** Frozen lane labels; the layout supplies the label column and clips vertical translation. */
13
+ laneLabelColumnZone: ReactNode;
14
+ /** Virtualized body with its horizontal scroller; fills the measured viewport. */
15
+ bodyZone: ReactNode;
16
+ onLayout: (input: LayoutChangeEvent) => void;
17
+ };
18
+
19
+ export function RosterLayout({
20
+ cornerZone,
21
+ headerZone,
22
+ laneLabelColumnZone,
23
+ bodyZone,
24
+ onLayout,
25
+ style,
26
+ headerStyle,
27
+ laneLabelColumnStyle,
28
+ bodyStyle,
29
+ laneLabelWidth = 180,
30
+ }: RosterLayoutProps) {
31
+ return (
32
+ <View style={regionStyle(structure.root, paint.root, style)}>
33
+ <View style={regionStyle(structure.header, paint.header, headerStyle)}>
34
+ <View style={{ width: laneLabelWidth }}>{cornerZone}</View>
35
+ <View style={structure.headerStrip}>{headerZone}</View>
36
+ </View>
37
+ <View style={structure.content}>
38
+ <View
39
+ style={regionStyle(
40
+ { ...structure.labels, width: laneLabelWidth },
41
+ paint.labels,
42
+ laneLabelColumnStyle,
43
+ )}
44
+ >
45
+ {laneLabelColumnZone}
46
+ </View>
47
+ <View onLayout={onLayout} style={regionStyle(structure.body, {}, bodyStyle)}>
48
+ {bodyZone}
49
+ </View>
50
+ </View>
51
+ </View>
52
+ );
53
+ }
54
+
55
+ const structure = {
56
+ root: { flex: 1, minHeight: 0, overflow: 'hidden' },
57
+ header: { flexDirection: 'row', height: 40, overflow: 'hidden' },
58
+ headerStrip: { flex: 1, minWidth: 0, overflow: 'hidden' },
59
+ content: { flex: 1, minHeight: 0, flexDirection: 'row' },
60
+ labels: { overflow: 'hidden' },
61
+ body: { flex: 1, minWidth: 0, overflow: 'hidden' },
62
+ } as const;
63
+ // Paint is what a class replaces; see regionStyle.
64
+ const paint = {
65
+ root: { backgroundColor: '#fff' },
66
+ header: { borderBottomWidth: 1, borderBottomColor: '#cbd5e1' },
67
+ labels: { borderRightWidth: 1, borderRightColor: '#cbd5e1' },
68
+ } as const;
@@ -0,0 +1,24 @@
1
+ import type { ProfilerOnRenderCallback } from 'react';
2
+ import { RosterBodyLayout } from '../body-layout';
3
+ import type { BodyInput } from '../roster.types';
4
+ import { RosterLaneList } from './lane-list';
5
+
6
+ export function RosterBody(
7
+ props: BodyInput & {
8
+ /** Development-only Profiler hook used by the gallery; not a supported customization point. */
9
+ onRowRender?: ProfilerOnRenderCallback;
10
+ },
11
+ ) {
12
+ const { viewport, scroll, contentWidth, ticks, gridComponent: GridComponent } = props;
13
+ // LegendList requires a measured viewport and does not support static rendering.
14
+ if (viewport.width <= 0 || viewport.height <= 0) return null;
15
+ return (
16
+ <RosterBodyLayout
17
+ scroll={scroll}
18
+ contentWidth={contentWidth}
19
+ viewport={viewport}
20
+ gridZone={<GridComponent ticks={ticks} contentWidth={contentWidth} />}
21
+ listZone={<RosterLaneList {...props} />}
22
+ />
23
+ );
24
+ }
@@ -0,0 +1,3 @@
1
+ export function RosterCorner() {
2
+ return null;
3
+ }
@@ -0,0 +1,5 @@
1
+ import { Text } from 'react-native';
2
+
3
+ export function RosterEmpty() {
4
+ return <Text style={{ padding: 24, color: '#475569' }}>No lanes</Text>;
5
+ }
@@ -0,0 +1,26 @@
1
+ import { View } from 'react-native';
2
+ import type { GridInput } from '../roster.types';
3
+
4
+ export function RosterGrid({ ticks, contentWidth }: GridInput) {
5
+ return (
6
+ <View
7
+ testID="roster-grid"
8
+ pointerEvents="none"
9
+ style={{ position: 'absolute', width: contentWidth, height: '100%' }}
10
+ >
11
+ {ticks.map((tick) => (
12
+ <View
13
+ key={tick.time}
14
+ style={{
15
+ position: 'absolute',
16
+ left: tick.x,
17
+ top: 0,
18
+ bottom: 0,
19
+ width: 1,
20
+ backgroundColor: '#e2e8f0',
21
+ }}
22
+ />
23
+ ))}
24
+ </View>
25
+ );
26
+ }
@@ -0,0 +1,10 @@
1
+ import { Text } from 'react-native';
2
+ import type { HeaderCellInput } from '../roster.types';
3
+
4
+ export function RosterHeaderCell({ tick }: HeaderCellInput) {
5
+ return (
6
+ <Text numberOfLines={1} style={{ color: '#475569', fontSize: 11, padding: 4 }}>
7
+ {tick.label}
8
+ </Text>
9
+ );
10
+ }
@@ -0,0 +1,23 @@
1
+ import { View } from 'react-native';
2
+ import Animated from 'react-native-reanimated';
3
+ import type { HeaderInput } from '../roster.types';
4
+
5
+ export function RosterHeader({
6
+ ticks,
7
+ contentWidth,
8
+ scroll,
9
+ headerCellComponent: HeaderCellComponent,
10
+ }: HeaderInput) {
11
+ return (
12
+ <Animated.View
13
+ testID="roster-header"
14
+ style={[{ width: contentWidth, height: 40 }, scroll.headerStyle]}
15
+ >
16
+ {ticks.map((tick) => (
17
+ <View key={tick.time} style={{ position: 'absolute', left: tick.x, top: 0 }}>
18
+ <HeaderCellComponent tick={tick} />
19
+ </View>
20
+ ))}
21
+ </Animated.View>
22
+ );
23
+ }
@@ -0,0 +1,31 @@
1
+ import { View } from 'react-native';
2
+ import Animated from 'react-native-reanimated';
3
+ import type { LabelColumnInput } from '../roster.types';
4
+
5
+ export function RosterLaneLabelColumn({
6
+ labels,
7
+ projection,
8
+ scroll,
9
+ laneLabelComponent: LaneLabelComponent,
10
+ }: LabelColumnInput) {
11
+ return (
12
+ <Animated.View
13
+ testID="roster-labels"
14
+ style={[{ height: labels.length * projection.rowHeight }, scroll.labelStyle]}
15
+ >
16
+ {labels.map((label, index) => (
17
+ <View
18
+ key={label.lane.id}
19
+ style={{
20
+ position: 'absolute',
21
+ top: index * projection.rowHeight,
22
+ height: projection.rowHeight,
23
+ width: '100%',
24
+ }}
25
+ >
26
+ <LaneLabelComponent {...label} />
27
+ </View>
28
+ ))}
29
+ </Animated.View>
30
+ );
31
+ }
@@ -0,0 +1,74 @@
1
+ import { LegendList } from '@legendapp/list';
2
+ import { Profiler, type ProfilerOnRenderCallback } from 'react';
3
+ import { LaneRow } from '../lanes/lane';
4
+ import type { BodyInput } from '../roster.types';
5
+ import { bodyContentKey } from '../utils/body-content-key';
6
+
7
+ export function RosterLaneList({
8
+ lanes,
9
+ geometryFor,
10
+ projection,
11
+ scroll,
12
+ press,
13
+ contentWidth,
14
+ viewport,
15
+ window,
16
+ intervalComponent,
17
+ gapComponent,
18
+ highlightSource,
19
+ onIntervalHover,
20
+ incompleteLabel,
21
+ onRowRender,
22
+ }: Omit<BodyInput, 'ticks' | 'gridComponent'> & {
23
+ /** Development-only Profiler hook used by the gallery; not a supported customization point. */
24
+ onRowRender?: ProfilerOnRenderCallback;
25
+ }) {
26
+ return (
27
+ <LegendList
28
+ testID="roster-vertical-scroll"
29
+ data={lanes}
30
+ extraData={bodyContentKey({
31
+ window,
32
+ projection,
33
+ highlightSource,
34
+ intervalComponent,
35
+ gapComponent,
36
+ onIntervalHover,
37
+ incompleteLabel,
38
+ })}
39
+ keyExtractor={(lane) => lane.id}
40
+ estimatedListSize={{ width: contentWidth, height: viewport.height }}
41
+ estimatedItemSize={projection.rowHeight}
42
+ getFixedItemSize={() => projection.rowHeight}
43
+ drawDistance={0}
44
+ recycleItems={false}
45
+ maintainVisibleContentPosition={false}
46
+ onScroll={scroll.onVerticalScroll}
47
+ scrollEventThrottle={16}
48
+ style={{ flex: 1 }}
49
+ renderItem={({ item }) => {
50
+ const row = (
51
+ <LaneRow
52
+ lane={item}
53
+ geometry={geometryFor(item)}
54
+ width={contentWidth}
55
+ rowHeight={projection.rowHeight}
56
+ press={press}
57
+ intervalComponent={intervalComponent}
58
+ gapComponent={gapComponent}
59
+ highlightSource={highlightSource}
60
+ onIntervalHover={onIntervalHover}
61
+ incompleteLabel={incompleteLabel}
62
+ />
63
+ );
64
+ if (onRowRender)
65
+ return (
66
+ <Profiler id={item.id} onRender={onRowRender}>
67
+ {row}
68
+ </Profiler>
69
+ );
70
+ return row;
71
+ }}
72
+ />
73
+ );
74
+ }