@delacour/react-native-ui 0.1.0-alpha.3 → 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 (482) hide show
  1. package/README.md +11 -7
  2. package/package.json +49 -5
  3. package/src/components/accordion/AGENTS.md +21 -9
  4. package/src/components/accordion/accordion-content.tsx +7 -4
  5. package/src/components/accordion/accordion-item.tsx +15 -13
  6. package/src/components/accordion/accordion.context.tsx +11 -5
  7. package/src/components/accordion/accordion.variants.test.ts +64 -3
  8. package/src/components/accordion/accordion.variants.ts +33 -9
  9. package/src/components/alert/AGENTS.md +102 -0
  10. package/src/components/alert/alert-action.tsx +17 -0
  11. package/src/components/alert/alert-close-button.tsx +50 -0
  12. package/src/components/alert/alert-content.tsx +15 -0
  13. package/src/components/alert/alert-description.tsx +16 -0
  14. package/src/components/alert/alert-glyphs.ts +25 -0
  15. package/src/components/alert/alert-indicator.tsx +40 -0
  16. package/src/components/alert/alert-title.tsx +18 -0
  17. package/src/components/alert/alert.context.tsx +69 -0
  18. package/src/components/alert/alert.tsx +160 -0
  19. package/src/components/alert/alert.types.ts +10 -0
  20. package/src/components/alert/alert.variants.test.ts +218 -0
  21. package/src/components/alert/alert.variants.ts +180 -0
  22. package/src/components/alert/index.ts +23 -0
  23. package/src/components/avatar/AGENTS.md +106 -0
  24. package/src/components/avatar/avatar-badge.tsx +51 -0
  25. package/src/components/avatar/avatar-group.tsx +139 -0
  26. package/src/components/avatar/avatar.context.tsx +93 -0
  27. package/src/components/avatar/avatar.tsx +201 -0
  28. package/src/components/avatar/avatar.utils.test.ts +174 -0
  29. package/src/components/avatar/avatar.utils.ts +141 -0
  30. package/src/components/avatar/avatar.variants.test.ts +251 -0
  31. package/src/components/avatar/avatar.variants.ts +270 -0
  32. package/src/components/avatar/index.ts +39 -0
  33. package/src/components/badge/AGENTS.md +5 -0
  34. package/src/components/badge/badge.tsx +6 -1
  35. package/src/components/bottom-sheet/AGENTS.md +186 -221
  36. package/src/components/bottom-sheet/bottom-sheet-background.tsx +31 -22
  37. package/src/components/bottom-sheet/bottom-sheet-close.tsx +23 -30
  38. package/src/components/bottom-sheet/bottom-sheet-container.tsx +54 -207
  39. package/src/components/bottom-sheet/bottom-sheet-content.tsx +25 -48
  40. package/src/components/bottom-sheet/bottom-sheet-description.tsx +8 -2
  41. package/src/components/bottom-sheet/bottom-sheet-flat-list.tsx +65 -0
  42. package/src/components/bottom-sheet/bottom-sheet-footer.tsx +53 -120
  43. package/src/components/bottom-sheet/bottom-sheet-handle.tsx +31 -26
  44. package/src/components/bottom-sheet/bottom-sheet-legend-list.tsx +69 -0
  45. package/src/components/bottom-sheet/bottom-sheet-overlay.tsx +25 -147
  46. package/src/components/bottom-sheet/bottom-sheet-provider.tsx +42 -0
  47. package/src/components/bottom-sheet/bottom-sheet-scroll-view.tsx +38 -52
  48. package/src/components/bottom-sheet/bottom-sheet-section-list.tsx +58 -0
  49. package/src/components/bottom-sheet/bottom-sheet-steps.tsx +88 -0
  50. package/src/components/bottom-sheet/bottom-sheet-text-input.tsx +44 -0
  51. package/src/components/bottom-sheet/bottom-sheet-title.tsx +12 -8
  52. package/src/components/bottom-sheet/bottom-sheet-trigger.tsx +19 -37
  53. package/src/components/bottom-sheet/bottom-sheet.tsx +113 -60
  54. package/src/components/bottom-sheet/bottom-sheet.variants.test.ts +47 -70
  55. package/src/components/bottom-sheet/bottom-sheet.variants.ts +50 -105
  56. package/src/components/bottom-sheet/index.ts +39 -17
  57. package/src/components/bottom-sheet/use-bottom-sheet-input.ts +16 -115
  58. package/src/components/button/AGENTS.md +45 -11
  59. package/src/components/button/button-group.tsx +44 -8
  60. package/src/components/button/button.context.tsx +10 -0
  61. package/src/components/button/button.tsx +2 -1
  62. package/src/components/button/button.variants.test.ts +154 -0
  63. package/src/components/button/button.variants.ts +71 -6
  64. package/src/components/button/index.ts +2 -0
  65. package/src/components/calendar/AGENTS.md +142 -0
  66. package/src/components/calendar/calendar-caption.tsx +116 -0
  67. package/src/components/calendar/calendar-day.tsx +103 -0
  68. package/src/components/calendar/calendar-grid.tsx +183 -0
  69. package/src/components/calendar/calendar-header.tsx +34 -0
  70. package/src/components/calendar/calendar-nav.tsx +51 -0
  71. package/src/components/calendar/calendar-picker.tsx +128 -0
  72. package/src/components/calendar/calendar-weekdays.tsx +48 -0
  73. package/src/components/calendar/calendar.context.tsx +108 -0
  74. package/src/components/calendar/calendar.date.test.ts +456 -0
  75. package/src/components/calendar/calendar.date.ts +584 -0
  76. package/src/components/calendar/calendar.tsx +389 -0
  77. package/src/components/calendar/calendar.types.ts +87 -0
  78. package/src/components/calendar/calendar.variants.test.ts +363 -0
  79. package/src/components/calendar/calendar.variants.ts +426 -0
  80. package/src/components/calendar/index.ts +96 -0
  81. package/src/components/card/AGENTS.md +88 -0
  82. package/src/components/card/card-action.tsx +16 -0
  83. package/src/components/card/card-content.tsx +12 -0
  84. package/src/components/card/card-description.tsx +12 -0
  85. package/src/components/card/card-footer.tsx +30 -0
  86. package/src/components/card/card-header.tsx +45 -0
  87. package/src/components/card/card-title.tsx +25 -0
  88. package/src/components/card/card.context.tsx +64 -0
  89. package/src/components/card/card.tsx +94 -0
  90. package/src/components/card/card.types.ts +13 -0
  91. package/src/components/card/card.variants.test.ts +240 -0
  92. package/src/components/card/card.variants.ts +177 -0
  93. package/src/components/card/index.ts +15 -0
  94. package/src/components/chart/AGENTS.md +9 -1
  95. package/src/components/chart/chart.tsx +8 -1
  96. package/src/components/chip/AGENTS.md +113 -0
  97. package/src/components/chip/chip-close-button.tsx +48 -0
  98. package/src/components/chip/chip-end-content.tsx +15 -0
  99. package/src/components/chip/chip-label.tsx +21 -0
  100. package/src/components/chip/chip-start-content.tsx +16 -0
  101. package/src/components/chip/chip.context.tsx +66 -0
  102. package/src/components/chip/chip.tsx +268 -0
  103. package/src/components/chip/chip.types.ts +10 -0
  104. package/src/components/chip/chip.variants.test.ts +335 -0
  105. package/src/components/chip/chip.variants.ts +321 -0
  106. package/src/components/chip/index.ts +24 -0
  107. package/src/components/collapsible/AGENTS.md +97 -0
  108. package/src/components/collapsible/collapsible-content.tsx +97 -0
  109. package/src/components/collapsible/collapsible-description.tsx +17 -0
  110. package/src/components/collapsible/collapsible-indicator.tsx +92 -0
  111. package/src/components/collapsible/collapsible-title.tsx +17 -0
  112. package/src/components/collapsible/collapsible-trigger.tsx +133 -0
  113. package/src/components/collapsible/collapsible.context.tsx +91 -0
  114. package/src/components/collapsible/collapsible.tsx +167 -0
  115. package/src/components/collapsible/collapsible.types.ts +9 -0
  116. package/src/components/collapsible/collapsible.variants.test.ts +338 -0
  117. package/src/components/collapsible/collapsible.variants.ts +228 -0
  118. package/src/components/collapsible/index.ts +32 -0
  119. package/src/components/context-menu/AGENTS.md +103 -0
  120. package/src/components/context-menu/context-menu-content.tsx +64 -0
  121. package/src/components/context-menu/context-menu-item.tsx +22 -0
  122. package/src/components/context-menu/context-menu-preview.tsx +60 -0
  123. package/src/components/context-menu/context-menu-trigger.tsx +160 -0
  124. package/src/components/context-menu/context-menu.context.tsx +91 -0
  125. package/src/components/context-menu/context-menu.tsx +90 -0
  126. package/src/components/context-menu/context-menu.variants.test.ts +266 -0
  127. package/src/components/context-menu/context-menu.variants.ts +147 -0
  128. package/src/components/context-menu/index.ts +18 -0
  129. package/src/components/dialog/AGENTS.md +97 -0
  130. package/src/components/dialog/dialog-body.tsx +21 -0
  131. package/src/components/dialog/dialog-close.tsx +82 -0
  132. package/src/components/dialog/dialog-content.tsx +153 -0
  133. package/src/components/dialog/dialog-description.tsx +23 -0
  134. package/src/components/dialog/dialog-footer.tsx +32 -0
  135. package/src/components/dialog/dialog-header.tsx +20 -0
  136. package/src/components/dialog/dialog-title.tsx +42 -0
  137. package/src/components/dialog/dialog-trigger.tsx +54 -0
  138. package/src/components/dialog/dialog.context.tsx +90 -0
  139. package/src/components/dialog/dialog.tsx +119 -0
  140. package/src/components/dialog/dialog.variants.test.ts +224 -0
  141. package/src/components/dialog/dialog.variants.ts +173 -0
  142. package/src/components/dialog/index.ts +30 -0
  143. package/src/components/drawer/AGENTS.md +123 -0
  144. package/src/components/drawer/drawer-body.tsx +46 -0
  145. package/src/components/drawer/drawer-close.tsx +76 -0
  146. package/src/components/drawer/drawer-content.tsx +186 -0
  147. package/src/components/drawer/drawer-description.tsx +23 -0
  148. package/src/components/drawer/drawer-footer.tsx +21 -0
  149. package/src/components/drawer/drawer-header.tsx +42 -0
  150. package/src/components/drawer/drawer-title.tsx +35 -0
  151. package/src/components/drawer/drawer-trigger.tsx +54 -0
  152. package/src/components/drawer/drawer.context.tsx +114 -0
  153. package/src/components/drawer/drawer.tsx +119 -0
  154. package/src/components/drawer/drawer.variants.test.ts +392 -0
  155. package/src/components/drawer/drawer.variants.ts +244 -0
  156. package/src/components/drawer/index.ts +41 -0
  157. package/src/components/drawer/use-drawer-pan.ts +108 -0
  158. package/src/components/empty-state/AGENTS.md +90 -0
  159. package/src/components/empty-state/empty-state-content.tsx +17 -0
  160. package/src/components/empty-state/empty-state-description.tsx +12 -0
  161. package/src/components/empty-state/empty-state-header.tsx +17 -0
  162. package/src/components/empty-state/empty-state-media.tsx +56 -0
  163. package/src/components/empty-state/empty-state-title.tsx +18 -0
  164. package/src/components/empty-state/empty-state.context.tsx +65 -0
  165. package/src/components/empty-state/empty-state.tsx +84 -0
  166. package/src/components/empty-state/empty-state.types.ts +14 -0
  167. package/src/components/empty-state/empty-state.variants.test.ts +245 -0
  168. package/src/components/empty-state/empty-state.variants.ts +132 -0
  169. package/src/components/empty-state/index.ts +20 -0
  170. package/src/components/fab/AGENTS.md +119 -0
  171. package/src/components/fab/fab-action.tsx +118 -0
  172. package/src/components/fab/fab-group.tsx +214 -0
  173. package/src/components/fab/fab-label.tsx +18 -0
  174. package/src/components/fab/fab.context.tsx +125 -0
  175. package/src/components/fab/fab.tsx +156 -0
  176. package/src/components/fab/fab.types.ts +17 -0
  177. package/src/components/fab/fab.variants.test.ts +274 -0
  178. package/src/components/fab/fab.variants.ts +234 -0
  179. package/src/components/fab/index.ts +37 -0
  180. package/src/components/feedback/AGENTS.md +95 -0
  181. package/src/components/feedback/feedback-action.tsx +16 -0
  182. package/src/components/feedback/feedback-cancel.tsx +34 -0
  183. package/src/components/feedback/feedback-close.tsx +21 -0
  184. package/src/components/feedback/feedback-content.tsx +24 -0
  185. package/src/components/feedback/feedback-field.tsx +70 -0
  186. package/src/components/feedback/feedback-footer.tsx +21 -0
  187. package/src/components/feedback/feedback-panel.tsx +54 -0
  188. package/src/components/feedback/feedback-submit.tsx +74 -0
  189. package/src/components/feedback/feedback-title.tsx +34 -0
  190. package/src/components/feedback/feedback-trigger.tsx +20 -0
  191. package/src/components/feedback/feedback.context.tsx +73 -0
  192. package/src/components/feedback/feedback.tsx +135 -0
  193. package/src/components/feedback/feedback.variants.test.ts +185 -0
  194. package/src/components/feedback/feedback.variants.ts +128 -0
  195. package/src/components/feedback/index.ts +24 -0
  196. package/src/components/field/AGENTS.md +19 -0
  197. package/src/components/field/field-label.tsx +19 -5
  198. package/src/components/field/field.context.tsx +17 -0
  199. package/src/components/field/field.tsx +15 -2
  200. package/src/components/field/field.variants.test.ts +24 -0
  201. package/src/components/field/field.variants.ts +20 -0
  202. package/src/components/field/index.ts +1 -0
  203. package/src/components/item/AGENTS.md +92 -0
  204. package/src/components/item/index.ts +25 -0
  205. package/src/components/item/item-actions.tsx +28 -0
  206. package/src/components/item/item-content.tsx +15 -0
  207. package/src/components/item/item-description.tsx +12 -0
  208. package/src/components/item/item-footer.tsx +13 -0
  209. package/src/components/item/item-group.tsx +32 -0
  210. package/src/components/item/item-header.tsx +13 -0
  211. package/src/components/item/item-media.tsx +37 -0
  212. package/src/components/item/item-separator.tsx +13 -0
  213. package/src/components/item/item-title.tsx +17 -0
  214. package/src/components/item/item.context.tsx +66 -0
  215. package/src/components/item/item.tsx +218 -0
  216. package/src/components/item/item.types.ts +12 -0
  217. package/src/components/item/item.variants.test.ts +263 -0
  218. package/src/components/item/item.variants.ts +200 -0
  219. package/src/components/kpi/AGENTS.md +125 -0
  220. package/src/components/kpi/index.ts +45 -0
  221. package/src/components/kpi/kpi-action.tsx +12 -0
  222. package/src/components/kpi/kpi-content.tsx +35 -0
  223. package/src/components/kpi/kpi-footer.tsx +52 -0
  224. package/src/components/kpi/kpi-group.tsx +70 -0
  225. package/src/components/kpi/kpi-header.tsx +25 -0
  226. package/src/components/kpi/kpi-icon.tsx +28 -0
  227. package/src/components/kpi/kpi-sparkline.tsx +145 -0
  228. package/src/components/kpi/kpi-stat.tsx +20 -0
  229. package/src/components/kpi/kpi-title.tsx +19 -0
  230. package/src/components/kpi/kpi-trend.tsx +105 -0
  231. package/src/components/kpi/kpi-value.tsx +32 -0
  232. package/src/components/kpi/kpi.context.tsx +111 -0
  233. package/src/components/kpi/kpi.tsx +154 -0
  234. package/src/components/kpi/kpi.types.ts +9 -0
  235. package/src/components/kpi/kpi.variants.test.ts +428 -0
  236. package/src/components/kpi/kpi.variants.ts +347 -0
  237. package/src/components/label/AGENTS.md +89 -0
  238. package/src/components/label/index.ts +10 -0
  239. package/src/components/label/label.tsx +97 -0
  240. package/src/components/label/label.variants.test.ts +176 -0
  241. package/src/components/label/label.variants.ts +123 -0
  242. package/src/components/menu/AGENTS.md +176 -0
  243. package/src/components/menu/index.ts +44 -0
  244. package/src/components/menu/menu-background.tsx +17 -0
  245. package/src/components/menu/menu-checkbox-item.tsx +57 -0
  246. package/src/components/menu/menu-content.tsx +303 -0
  247. package/src/components/menu/menu-item.tsx +162 -0
  248. package/src/components/menu/menu-label.tsx +14 -0
  249. package/src/components/menu/menu-radio-group.tsx +50 -0
  250. package/src/components/menu/menu-radio-item.tsx +57 -0
  251. package/src/components/menu/menu-separator.tsx +11 -0
  252. package/src/components/menu/menu-sub-content.tsx +72 -0
  253. package/src/components/menu/menu-sub-trigger.tsx +50 -0
  254. package/src/components/menu/menu-sub.tsx +75 -0
  255. package/src/components/menu/menu-trigger.tsx +57 -0
  256. package/src/components/menu/menu.context.tsx +214 -0
  257. package/src/components/menu/menu.tsx +88 -0
  258. package/src/components/menu/menu.types.ts +33 -0
  259. package/src/components/menu/menu.variants.test.ts +400 -0
  260. package/src/components/menu/menu.variants.ts +353 -0
  261. package/src/components/meter/AGENTS.md +135 -0
  262. package/src/components/meter/index.ts +43 -0
  263. package/src/components/meter/meter-fill.tsx +19 -0
  264. package/src/components/meter/meter-header.tsx +17 -0
  265. package/src/components/meter/meter-label.tsx +18 -0
  266. package/src/components/meter/meter-output.tsx +42 -0
  267. package/src/components/meter/meter-segments.tsx +83 -0
  268. package/src/components/meter/meter-track.tsx +16 -0
  269. package/src/components/meter/meter.context.tsx +62 -0
  270. package/src/components/meter/meter.tsx +286 -0
  271. package/src/components/meter/meter.types.ts +30 -0
  272. package/src/components/meter/meter.variants.test.ts +430 -0
  273. package/src/components/meter/meter.variants.ts +347 -0
  274. package/src/components/overlay/AGENTS.md +89 -0
  275. package/src/components/overlay/index.ts +27 -0
  276. package/src/components/overlay/overlay-portal.tsx +84 -0
  277. package/src/components/overlay/overlay-presence.test.ts +46 -0
  278. package/src/components/overlay/overlay-presence.ts +49 -0
  279. package/src/components/overlay/overlay-registry.test.ts +96 -0
  280. package/src/components/overlay/overlay-registry.ts +99 -0
  281. package/src/components/overlay/overlay-scrim.tsx +49 -0
  282. package/src/components/overlay/overlay.context.tsx +48 -0
  283. package/src/components/overlay/overlay.tsx +118 -0
  284. package/src/components/overlay/overlay.variants.test.ts +37 -0
  285. package/src/components/overlay/overlay.variants.ts +33 -0
  286. package/src/components/overlay/use-overlay-back-handler.ts +34 -0
  287. package/src/components/overlay/use-overlay-presence.ts +87 -0
  288. package/src/components/popover/AGENTS.md +138 -0
  289. package/src/components/popover/index.ts +48 -0
  290. package/src/components/popover/popover-anchor.tsx +49 -0
  291. package/src/components/popover/popover-arrow.tsx +89 -0
  292. package/src/components/popover/popover-close.tsx +73 -0
  293. package/src/components/popover/popover-content.tsx +235 -0
  294. package/src/components/popover/popover-description.tsx +18 -0
  295. package/src/components/popover/popover-title.tsx +33 -0
  296. package/src/components/popover/popover-trigger.tsx +56 -0
  297. package/src/components/popover/popover.context.tsx +71 -0
  298. package/src/components/popover/popover.position.test.ts +354 -0
  299. package/src/components/popover/popover.position.ts +286 -0
  300. package/src/components/popover/popover.tsx +123 -0
  301. package/src/components/popover/popover.variants.test.ts +135 -0
  302. package/src/components/popover/popover.variants.ts +85 -0
  303. package/src/components/popover/use-anchor-measure.ts +76 -0
  304. package/src/components/popover/use-anchored-content.ts +219 -0
  305. package/src/components/pressable/AGENTS.md +11 -1
  306. package/src/components/pressable/pressable.tsx +7 -2
  307. package/src/components/pressable/pressable.variants.test.ts +29 -0
  308. package/src/components/pressable/pressable.variants.ts +17 -0
  309. package/src/components/progress/AGENTS.md +120 -0
  310. package/src/components/progress/index.ts +40 -0
  311. package/src/components/progress/progress-fill.tsx +152 -0
  312. package/src/components/progress/progress-header.tsx +19 -0
  313. package/src/components/progress/progress-label.tsx +27 -0
  314. package/src/components/progress/progress-output.tsx +47 -0
  315. package/src/components/progress/progress-track.tsx +38 -0
  316. package/src/components/progress/progress.context.tsx +79 -0
  317. package/src/components/progress/progress.tsx +171 -0
  318. package/src/components/progress/progress.types.ts +23 -0
  319. package/src/components/progress/progress.variants.test.ts +335 -0
  320. package/src/components/progress/progress.variants.ts +284 -0
  321. package/src/components/progress-button/AGENTS.md +116 -0
  322. package/src/components/progress-button/index.ts +36 -0
  323. package/src/components/progress-button/progress-button-done.tsx +33 -0
  324. package/src/components/progress-button/progress-button-label.tsx +27 -0
  325. package/src/components/progress-button/progress-button.context.tsx +93 -0
  326. package/src/components/progress-button/progress-button.tsx +414 -0
  327. package/src/components/progress-button/progress-button.variants.test.ts +314 -0
  328. package/src/components/progress-button/progress-button.variants.ts +236 -0
  329. package/src/components/provider/AGENTS.md +38 -25
  330. package/src/components/provider/provider.tsx +38 -11
  331. package/src/components/radio/AGENTS.md +8 -10
  332. package/src/components/radio/radio.variants.test.ts +5 -6
  333. package/src/components/radio/radio.variants.ts +6 -7
  334. package/src/components/rating/AGENTS.md +143 -0
  335. package/src/components/rating/index.ts +43 -0
  336. package/src/components/rating/rating-output.tsx +39 -0
  337. package/src/components/rating/rating-star.tsx +70 -0
  338. package/src/components/rating/rating-stars.tsx +219 -0
  339. package/src/components/rating/rating.context.tsx +79 -0
  340. package/src/components/rating/rating.tsx +163 -0
  341. package/src/components/rating/rating.variants.test.ts +347 -0
  342. package/src/components/rating/rating.variants.ts +354 -0
  343. package/src/components/screen/screen-navbar-back-button.tsx +1 -1
  344. package/src/components/selection-mode/AGENTS.md +155 -0
  345. package/src/components/selection-mode/index.ts +43 -0
  346. package/src/components/selection-mode/selection-mode-action.tsx +65 -0
  347. package/src/components/selection-mode/selection-mode-bar.tsx +79 -0
  348. package/src/components/selection-mode/selection-mode-group.tsx +123 -0
  349. package/src/components/selection-mode/selection-mode-header.tsx +85 -0
  350. package/src/components/selection-mode/selection-mode-indicator.tsx +118 -0
  351. package/src/components/selection-mode/selection-mode-item.tsx +182 -0
  352. package/src/components/selection-mode/selection-mode.context.tsx +89 -0
  353. package/src/components/selection-mode/selection-mode.tsx +207 -0
  354. package/src/components/selection-mode/selection-mode.types.ts +36 -0
  355. package/src/components/selection-mode/selection-mode.variants.test.ts +292 -0
  356. package/src/components/selection-mode/selection-mode.variants.ts +329 -0
  357. package/src/components/skeleton/AGENTS.md +120 -0
  358. package/src/components/skeleton/index.ts +15 -0
  359. package/src/components/skeleton/skeleton-clock.ts +48 -0
  360. package/src/components/skeleton/skeleton-group.tsx +64 -0
  361. package/src/components/skeleton/skeleton-shimmer.tsx +80 -0
  362. package/src/components/skeleton/skeleton.context.tsx +45 -0
  363. package/src/components/skeleton/skeleton.tsx +227 -0
  364. package/src/components/skeleton/skeleton.variants.test.ts +245 -0
  365. package/src/components/skeleton/skeleton.variants.ts +222 -0
  366. package/src/components/slide-button/AGENTS.md +122 -0
  367. package/src/components/slide-button/index.ts +43 -0
  368. package/src/components/slide-button/slide-button-label.tsx +70 -0
  369. package/src/components/slide-button/slide-button-thumb.tsx +93 -0
  370. package/src/components/slide-button/slide-button.context.tsx +76 -0
  371. package/src/components/slide-button/slide-button.tsx +457 -0
  372. package/src/components/slide-button/slide-button.variants.test.ts +288 -0
  373. package/src/components/slide-button/slide-button.variants.ts +324 -0
  374. package/src/components/slider/index.ts +2 -0
  375. package/src/components/slider/slider-thumb.tsx +33 -1
  376. package/src/components/slider/slider.variants.test.ts +52 -0
  377. package/src/components/slider/slider.variants.ts +56 -2
  378. package/src/components/stack-card/AGENTS.md +169 -0
  379. package/src/components/stack-card/index.ts +37 -0
  380. package/src/components/stack-card/stack-card-action.tsx +66 -0
  381. package/src/components/stack-card/stack-card-actions.tsx +18 -0
  382. package/src/components/stack-card/stack-card-card.tsx +71 -0
  383. package/src/components/stack-card/stack-card-empty.tsx +30 -0
  384. package/src/components/stack-card/stack-card-slot.tsx +90 -0
  385. package/src/components/stack-card/stack-card-stamp.tsx +76 -0
  386. package/src/components/stack-card/stack-card.context.tsx +117 -0
  387. package/src/components/stack-card/stack-card.tsx +557 -0
  388. package/src/components/stack-card/stack-card.types.ts +26 -0
  389. package/src/components/stack-card/stack-card.variants.test.ts +355 -0
  390. package/src/components/stack-card/stack-card.variants.ts +360 -0
  391. package/src/components/steps/AGENTS.md +153 -0
  392. package/src/components/steps/index.ts +45 -0
  393. package/src/components/steps/steps-connector.tsx +31 -0
  394. package/src/components/steps/steps-description.tsx +26 -0
  395. package/src/components/steps/steps-indicator.tsx +106 -0
  396. package/src/components/steps/steps-item.tsx +225 -0
  397. package/src/components/steps/steps-panel.tsx +41 -0
  398. package/src/components/steps/steps-title.tsx +32 -0
  399. package/src/components/steps/steps-track.tsx +59 -0
  400. package/src/components/steps/steps.context.tsx +123 -0
  401. package/src/components/steps/steps.tsx +166 -0
  402. package/src/components/steps/steps.variants.test.ts +388 -0
  403. package/src/components/steps/steps.variants.ts +468 -0
  404. package/src/components/surface/AGENTS.md +72 -0
  405. package/src/components/surface/index.ts +15 -0
  406. package/src/components/surface/surface.context.tsx +54 -0
  407. package/src/components/surface/surface.tsx +70 -0
  408. package/src/components/surface/surface.variants.test.ts +180 -0
  409. package/src/components/surface/surface.variants.ts +133 -0
  410. package/src/components/swipe/AGENTS.md +140 -0
  411. package/src/components/swipe/index.ts +31 -0
  412. package/src/components/swipe/swipe-action.tsx +99 -0
  413. package/src/components/swipe/swipe-end.tsx +14 -0
  414. package/src/components/swipe/swipe-group.tsx +55 -0
  415. package/src/components/swipe/swipe-panel.tsx +55 -0
  416. package/src/components/swipe/swipe-start.tsx +15 -0
  417. package/src/components/swipe/swipe.context.tsx +135 -0
  418. package/src/components/swipe/swipe.tsx +393 -0
  419. package/src/components/swipe/swipe.types.ts +7 -0
  420. package/src/components/swipe/swipe.variants.test.ts +337 -0
  421. package/src/components/swipe/swipe.variants.ts +290 -0
  422. package/src/components/switch/switch.variants.ts +2 -2
  423. package/src/components/tabs/AGENTS.md +4 -3
  424. package/src/components/tabs/tabs.variants.test.ts +1 -1
  425. package/src/components/tabs/tabs.variants.ts +4 -6
  426. package/src/components/textarea/AGENTS.md +86 -0
  427. package/src/components/textarea/index.ts +16 -0
  428. package/src/components/textarea/textarea.tsx +157 -0
  429. package/src/components/textarea/textarea.variants.test.ts +219 -0
  430. package/src/components/textarea/textarea.variants.ts +171 -0
  431. package/src/components/toast/AGENTS.md +140 -0
  432. package/src/components/toast/index.ts +74 -0
  433. package/src/components/toast/toast-action.tsx +59 -0
  434. package/src/components/toast/toast-api.ts +32 -0
  435. package/src/components/toast/toast-close.tsx +44 -0
  436. package/src/components/toast/toast-content.tsx +11 -0
  437. package/src/components/toast/toast-description.tsx +11 -0
  438. package/src/components/toast/toast-indicator.tsx +34 -0
  439. package/src/components/toast/toast-item.tsx +308 -0
  440. package/src/components/toast/toast-title.tsx +13 -0
  441. package/src/components/toast/toast-viewport.tsx +135 -0
  442. package/src/components/toast/toast.context.tsx +69 -0
  443. package/src/components/toast/toast.store.test.ts +259 -0
  444. package/src/components/toast/toast.store.ts +338 -0
  445. package/src/components/toast/toast.timer.test.ts +64 -0
  446. package/src/components/toast/toast.timer.ts +51 -0
  447. package/src/components/toast/toast.tsx +132 -0
  448. package/src/components/toast/toast.variants.test.ts +393 -0
  449. package/src/components/toast/toast.variants.ts +304 -0
  450. package/src/components/toggle-button/AGENTS.md +106 -0
  451. package/src/components/toggle-button/index.ts +30 -0
  452. package/src/components/toggle-button/toggle-button-group.tsx +156 -0
  453. package/src/components/toggle-button/toggle-button-label.tsx +19 -0
  454. package/src/components/toggle-button/toggle-button.context.tsx +130 -0
  455. package/src/components/toggle-button/toggle-button.tsx +172 -0
  456. package/src/components/toggle-button/toggle-button.variants.test.ts +189 -0
  457. package/src/components/toggle-button/toggle-button.variants.ts +160 -0
  458. package/src/components/tooltip/AGENTS.md +133 -0
  459. package/src/components/tooltip/index.ts +28 -0
  460. package/src/components/tooltip/tooltip-arrow.tsx +40 -0
  461. package/src/components/tooltip/tooltip-content.tsx +179 -0
  462. package/src/components/tooltip/tooltip-description.tsx +19 -0
  463. package/src/components/tooltip/tooltip-text.tsx +21 -0
  464. package/src/components/tooltip/tooltip-title.tsx +20 -0
  465. package/src/components/tooltip/tooltip-trigger.tsx +103 -0
  466. package/src/components/tooltip/tooltip.context.tsx +68 -0
  467. package/src/components/tooltip/tooltip.tsx +213 -0
  468. package/src/components/tooltip/tooltip.variants.test.ts +231 -0
  469. package/src/components/tooltip/tooltip.variants.ts +177 -0
  470. package/src/hooks/use-calm-motion.tsx +31 -0
  471. package/src/lib/calm-motion.test.ts +17 -0
  472. package/src/lib/calm-motion.ts +23 -0
  473. package/src/lib/cn.test.ts +14 -0
  474. package/src/lib/cn.ts +2 -2
  475. package/src/no-gorhom.test.ts +54 -0
  476. package/src/styles/geometry.test.ts +1 -0
  477. package/src/styles/theme.css +4 -0
  478. package/src/styles/tokens.css +11 -0
  479. package/src/styles/tokens.test.ts +22 -0
  480. package/src/styles/tokens.ts +20 -0
  481. package/src/components/bottom-sheet/bottom-sheet-portal.tsx +0 -72
  482. package/src/components/bottom-sheet/bottom-sheet.context.tsx +0 -135
@@ -0,0 +1,389 @@
1
+ import { type ReactElement, useCallback, useEffect, useMemo, useRef, useState } from "react";
2
+ import { AccessibilityInfo, AppState, View } from "react-native";
3
+ import { useControllableState } from "../../hooks/use-controllable-state";
4
+ import { useFieldContext } from "../field/field.context";
5
+ import { Surface } from "../surface";
6
+ import { type CalendarContextValue, CalendarProvider } from "./calendar.context";
7
+ import {
8
+ addMonths,
9
+ addYears,
10
+ type CalendarDate,
11
+ type CalendarSelectionState,
12
+ clampDate,
13
+ compareMonths,
14
+ formatMonthYear,
15
+ isDateDisabled as isDateDisabledBy,
16
+ isSameMonth,
17
+ nextSelection,
18
+ today as readToday,
19
+ resolveWeekStart,
20
+ resolveYearSpan,
21
+ startOfMonth,
22
+ } from "./calendar.date";
23
+ import type { CalendarProps, CalendarSelection } from "./calendar.types";
24
+ import {
25
+ type CalendarView,
26
+ calendarVariants,
27
+ isDateSelected,
28
+ isMonthInBounds,
29
+ resolveCalendarAxes,
30
+ resolveMonthBounds,
31
+ resolveRangeRole,
32
+ } from "./calendar.variants";
33
+ import { CalendarCaption } from "./calendar-caption";
34
+ import { CalendarDay } from "./calendar-day";
35
+ import { CalendarGrid } from "./calendar-grid";
36
+ import { CalendarHeader } from "./calendar-header";
37
+ import { CalendarNav } from "./calendar-nav";
38
+ import { CalendarPicker } from "./calendar-picker";
39
+ import { CalendarWeekdays } from "./calendar-weekdays";
40
+
41
+ /** The controlled selection, as state — `undefined` while the caller leaves it uncontrolled. */
42
+ function controlledSelection(props: CalendarSelection): CalendarSelectionState | undefined {
43
+ switch (props.mode) {
44
+ case "multiple":
45
+ return props.selected === undefined ? undefined : { mode: "multiple", value: props.selected };
46
+ case "range":
47
+ return props.selected === undefined ? undefined : { mode: "range", value: props.selected };
48
+ default:
49
+ return props.selected === undefined ? undefined : { mode: "single", value: props.selected };
50
+ }
51
+ }
52
+
53
+ /** The starting selection while uncontrolled — empty in the mode's own shape. */
54
+ function defaultSelection(props: CalendarSelection): CalendarSelectionState {
55
+ switch (props.mode) {
56
+ case "multiple":
57
+ return { mode: "multiple", value: props.defaultSelected ?? [] };
58
+ case "range":
59
+ return { mode: "range", value: props.defaultSelected ?? { start: null, end: null } };
60
+ default:
61
+ return { mode: "single", value: props.defaultSelected ?? null };
62
+ }
63
+ }
64
+
65
+ /** Reports a new selection to the caller's `onSelect`, typed for its mode. */
66
+ function emitSelection(props: CalendarSelection, next: CalendarSelectionState): void {
67
+ switch (props.mode) {
68
+ case "multiple":
69
+ if (next.mode === "multiple") props.onSelect?.(next.value);
70
+ return;
71
+ case "range":
72
+ if (next.mode === "range") props.onSelect?.(next.value);
73
+ return;
74
+ default:
75
+ if (next.mode === "single") props.onSelect?.(next.value);
76
+ }
77
+ }
78
+
79
+ /** The day a selection opens on — the month a calendar starts in when nothing else names one. */
80
+ function anchorOf(selection: CalendarSelectionState): CalendarDate | null {
81
+ switch (selection.mode) {
82
+ case "single":
83
+ return selection.value;
84
+ case "multiple":
85
+ return selection.value[0] ?? null;
86
+ case "range":
87
+ return selection.value.start;
88
+ }
89
+ }
90
+
91
+ /**
92
+ * Today, kept current: re-read whenever the app returns to the foreground, so a calendar left open
93
+ * overnight marks the right day in the morning. An override wins and is never re-read.
94
+ */
95
+ function useToday(override: CalendarDate | undefined): CalendarDate {
96
+ const [current, setCurrent] = useState(readToday);
97
+ useEffect(() => {
98
+ if (override) return;
99
+ const subscription = AppState.addEventListener("change", (status) => {
100
+ if (status === "active") setCurrent(readToday());
101
+ });
102
+ return () => subscription.remove();
103
+ }, [override]);
104
+ return override ?? current;
105
+ }
106
+
107
+ function CalendarRoot(props: CalendarProps): ReactElement {
108
+ const {
109
+ variant,
110
+ size,
111
+ minDate,
112
+ maxDate,
113
+ disabled,
114
+ isDisabled,
115
+ isInvalid,
116
+ isReadOnly,
117
+ month,
118
+ defaultMonth,
119
+ onMonthChange,
120
+ startMonth,
121
+ endMonth,
122
+ locale,
123
+ weekStartsOn = "auto",
124
+ captionLayout = "picker",
125
+ showOutsideDays = true,
126
+ selectOutsideDays = false,
127
+ isBordered = false,
128
+ swipeToPage = true,
129
+ today: todayOverride,
130
+ className,
131
+ children,
132
+ testID,
133
+ mode: _mode,
134
+ selected: _selected,
135
+ defaultSelected: _defaultSelected,
136
+ onSelect: _onSelect,
137
+ ...viewProps
138
+ } = props;
139
+
140
+ const field = useFieldContext();
141
+ const axes = resolveCalendarAxes({ field, own: { isDisabled, isInvalid, isReadOnly, size, variant } });
142
+ const today = useToday(todayOverride);
143
+
144
+ const handleSelectionChange = useCallback((next: CalendarSelectionState) => emitSelection(props, next), [props]);
145
+ const [selection, setSelection] = useControllableState<CalendarSelectionState>({
146
+ defaultValue: defaultSelection(props),
147
+ onChange: handleSelectionChange,
148
+ value: controlledSelection(props),
149
+ });
150
+
151
+ const monthBounds = useMemo(
152
+ () => resolveMonthBounds({ endMonth, maxDate, minDate, startMonth }),
153
+ [endMonth, maxDate, minDate, startMonth]
154
+ );
155
+
156
+ const handleMonthChange = useCallback((next: CalendarDate) => onMonthChange?.(next), [onMonthChange]);
157
+ const [visibleMonthRaw, setVisibleMonth] = useControllableState<CalendarDate>({
158
+ defaultValue: startOfMonth(
159
+ clampDate(defaultMonth ?? anchorOf(selection) ?? today, monthBounds.first, monthBounds.last)
160
+ ),
161
+ onChange: handleMonthChange,
162
+ value: month ? startOfMonth(month) : undefined,
163
+ });
164
+ const visibleMonth = useMemo(() => startOfMonth(visibleMonthRaw), [visibleMonthRaw]);
165
+
166
+ const [view, setView] = useState<CalendarView>("days");
167
+ const [pageDirection, setPageDirection] = useState<-1 | 0 | 1>(0);
168
+
169
+ const goToMonth = useCallback(
170
+ (date: CalendarDate) => {
171
+ const target = startOfMonth(clampDate(startOfMonth(date), monthBounds.first, monthBounds.last));
172
+ if (isSameMonth(target, visibleMonth)) return;
173
+ setPageDirection(0);
174
+ setVisibleMonth(target);
175
+ },
176
+ [monthBounds.first, monthBounds.last, setVisibleMonth, visibleMonth]
177
+ );
178
+
179
+ const step = view === "months" ? 12 : 1;
180
+ const prevMonth = view === "months" ? addYears(visibleMonth, -1) : addMonths(visibleMonth, -1);
181
+ const nextMonth = view === "months" ? addYears(visibleMonth, 1) : addMonths(visibleMonth, 1);
182
+ const canGoPrev =
183
+ view === "months"
184
+ ? !monthBounds.first || prevMonth.year >= monthBounds.first.year
185
+ : isMonthInBounds(prevMonth, monthBounds);
186
+ const canGoNext =
187
+ view === "months"
188
+ ? !monthBounds.last || nextMonth.year <= monthBounds.last.year
189
+ : isMonthInBounds(nextMonth, monthBounds);
190
+
191
+ const page = useCallback(
192
+ (direction: -1 | 1) => {
193
+ const target = addMonths(visibleMonth, direction * step);
194
+ const held = startOfMonth(clampDate(target, monthBounds.first, monthBounds.last));
195
+ if (compareMonths(held, visibleMonth) === 0) return;
196
+ setPageDirection(view === "days" ? direction : 0);
197
+ setVisibleMonth(held);
198
+ },
199
+ [monthBounds.first, monthBounds.last, setVisibleMonth, step, view, visibleMonth]
200
+ );
201
+ const goPrev = useCallback(() => page(-1), [page]);
202
+ const goNext = useCallback(() => page(1), [page]);
203
+
204
+ const isDateDisabled = useCallback(
205
+ (date: CalendarDate) => isDateDisabledBy(date, { disabled, maxDate, minDate }),
206
+ [disabled, maxDate, minDate]
207
+ );
208
+
209
+ const select = useCallback(
210
+ (date: CalendarDate) => {
211
+ if (axes.isDisabled || axes.isReadOnly || isDateDisabled(date)) return;
212
+ setSelection(nextSelection(selection, date, isDateDisabled));
213
+ if (!isSameMonth(date, visibleMonth)) {
214
+ setPageDirection(compareMonths(date, visibleMonth) > 0 ? 1 : -1);
215
+ setVisibleMonth(startOfMonth(date));
216
+ }
217
+ },
218
+ [axes.isDisabled, axes.isReadOnly, isDateDisabled, selection, setSelection, setVisibleMonth, visibleMonth]
219
+ );
220
+
221
+ // The month is announced when it changes, never on mount — the caption already says it.
222
+ const announced = useRef(visibleMonth);
223
+ useEffect(() => {
224
+ if (isSameMonth(announced.current, visibleMonth)) return;
225
+ announced.current = visibleMonth;
226
+ AccessibilityInfo.announceForAccessibility(formatMonthYear(visibleMonth, locale));
227
+ }, [locale, visibleMonth]);
228
+
229
+ const resolvedWeekStart = useMemo(
230
+ () => (weekStartsOn === "auto" ? resolveWeekStart(locale) : weekStartsOn),
231
+ [locale, weekStartsOn]
232
+ );
233
+ const yearSpan = useMemo(
234
+ () => resolveYearSpan({ endMonth: monthBounds.last, startMonth: monthBounds.first, visible: today }),
235
+ [monthBounds.first, monthBounds.last, today]
236
+ );
237
+
238
+ const context = useMemo<CalendarContextValue>(
239
+ () => ({
240
+ canGoNext,
241
+ canGoPrev,
242
+ captionLayout,
243
+ goNext,
244
+ goPrev,
245
+ goToMonth,
246
+ isDateDisabled,
247
+ isDateSelected: (date) => isDateSelected(selection, date),
248
+ isDisabled: axes.isDisabled,
249
+ isInvalid: axes.isInvalid,
250
+ isReadOnly: axes.isReadOnly,
251
+ label: field?.label ?? null,
252
+ testID,
253
+ locale,
254
+ mode: selection.mode,
255
+ monthBounds,
256
+ pageDirection,
257
+ rangeRole: (date) => (selection.mode === "range" ? resolveRangeRole(selection.value, date) : null),
258
+ select,
259
+ selectOutsideDays,
260
+ selection,
261
+ setView,
262
+ showOutsideDays,
263
+ size: axes.size,
264
+ swipeToPage,
265
+ today,
266
+ variant: axes.variant,
267
+ view,
268
+ visibleMonth,
269
+ weekStartsOn: resolvedWeekStart,
270
+ yearSpan,
271
+ }),
272
+ [
273
+ axes.isDisabled,
274
+ axes.isInvalid,
275
+ axes.isReadOnly,
276
+ axes.size,
277
+ axes.variant,
278
+ canGoNext,
279
+ canGoPrev,
280
+ captionLayout,
281
+ field?.label,
282
+ testID,
283
+ goNext,
284
+ goPrev,
285
+ goToMonth,
286
+ isDateDisabled,
287
+ locale,
288
+ monthBounds,
289
+ pageDirection,
290
+ resolvedWeekStart,
291
+ select,
292
+ selectOutsideDays,
293
+ selection,
294
+ showOutsideDays,
295
+ swipeToPage,
296
+ today,
297
+ view,
298
+ visibleMonth,
299
+ yearSpan,
300
+ ]
301
+ );
302
+
303
+ const rootClassName = calendarVariants({ isDisabled: axes.isDisabled, size: axes.size }).root({ className });
304
+ const body = children ?? (
305
+ <>
306
+ <CalendarHeader />
307
+ <CalendarWeekdays />
308
+ <CalendarGrid />
309
+ </>
310
+ );
311
+
312
+ // A bordered calendar is a card on `Surface`; a bare one is a plain column, the way a sheet or a
313
+ // `Card` embeds it without a second frame inside its own.
314
+ return (
315
+ <CalendarProvider value={context}>
316
+ {isBordered ? (
317
+ <Surface className={rootClassName} padding="sm" testID={testID} {...viewProps}>
318
+ {body}
319
+ </Surface>
320
+ ) : (
321
+ <View className={rootClassName} testID={testID} {...viewProps}>
322
+ {body}
323
+ </View>
324
+ )}
325
+ </CalendarProvider>
326
+ );
327
+ }
328
+
329
+ /**
330
+ * An always-visible month grid for picking a day, several days or a range.
331
+ *
332
+ * **Three modes, one discriminant.** `mode="single"` (the default) holds one `CalendarDate` and a
333
+ * tap on it clears it; `mode="multiple"` toggles days in and out of a sorted list; `mode="range"`
334
+ * takes two taps in either order, the earlier day becoming the start, and a range that would
335
+ * swallow a disabled day restarts instead. `selected`/`onSelect` are typed for the mode named, and work
336
+ * controlled or uncontrolled.
337
+ *
338
+ * **Dates are `CalendarDate`s** — `{ year, month, day }`, with no time zone to shift them.
339
+ * `@delacour/react-native-ui/calendar` exports the helpers to make, compare, format and
340
+ * serialise them; no date library is needed.
341
+ *
342
+ * **Always six weeks**, so the height and every column hold still while paging, including through
343
+ * a February that fits in four. Swipe the grid or tap the arrows to page; with
344
+ * `captionLayout="picker"` (the default) the caption opens a months view, then a years view.
345
+ *
346
+ * `minDate`/`maxDate` bound what can be picked and, unless `startMonth`/`endMonth` say otherwise,
347
+ * how far paging goes. `disabled` takes further matchers: a date, a span, weekdays or a predicate.
348
+ *
349
+ * `isDisabled` and `isInvalid` cascade in from an enclosing `Field`, whose label names the grid.
350
+ * The week starts where the locale says, and names come from `Intl`.
351
+ *
352
+ * @example
353
+ * const [day, setDay] = useState<CalendarDate | null>(null);
354
+ * <Calendar onSelect={setDay} selected={day} />
355
+ *
356
+ * @example
357
+ * <Calendar mode="range" minDate={today()} onSelect={setStay} selected={stay} isBordered />
358
+ *
359
+ * @example
360
+ * <Calendar disabled={[{ type: "weekday", days: [0, 6] }]} mode="multiple" />
361
+ *
362
+ * @example
363
+ * <Calendar>
364
+ * <Calendar.Header>
365
+ * <Calendar.Caption />
366
+ * <Calendar.Nav direction="prev" />
367
+ * <Calendar.Nav direction="next" />
368
+ * </Calendar.Header>
369
+ * <Calendar.Weekdays format="narrow" />
370
+ * <Calendar.Grid />
371
+ * </Calendar>
372
+ */
373
+ export const Calendar = Object.assign(CalendarRoot, {
374
+ /** The row above the grid — the arrows and the caption, or whatever it is given. */
375
+ Header: CalendarHeader,
376
+ /** A paging arrow that disables itself at the bound it points at. */
377
+ Nav: CalendarNav,
378
+ /** The month and year — a label, or the button that opens the jump views. */
379
+ Caption: CalendarCaption,
380
+ /** The weekday names, in column order. */
381
+ Weekdays: CalendarWeekdays,
382
+ /** The six weeks, the swipe that pages them, and the jump view over them. */
383
+ Grid: CalendarGrid,
384
+ /** One day. Give it children for custom content under the number. */
385
+ Day: CalendarDay,
386
+ /** The months and years jump views. The grid hosts it; exported for a custom grid. */
387
+ Picker: CalendarPicker,
388
+ displayName: "DelacourUI.Calendar",
389
+ });
@@ -0,0 +1,87 @@
1
+ import type { ReactNode } from "react";
2
+ import type { ViewProps } from "react-native";
3
+ import type { CalendarDate, CalendarDateRange, DateMatcher, Weekday } from "./calendar.date";
4
+ import type { CalendarSize, CalendarVariant } from "./calendar.variants";
5
+
6
+ /**
7
+ * What a calendar selects, and the value it reports — one shape per mode.
8
+ *
9
+ * `mode` is the discriminant, so `selected` and `onSelect` are typed for the mode named: a range
10
+ * calendar cannot be handed a single date. Omitted, it is `single`.
11
+ */
12
+ export type CalendarSelection =
13
+ | {
14
+ mode?: "single";
15
+ /** Controlled selection. `null` is no day. */
16
+ selected?: CalendarDate | null;
17
+ /** Starting selection while uncontrolled. */
18
+ defaultSelected?: CalendarDate | null;
19
+ /** Fires on every change. A tap on the selected day clears it to `null`. */
20
+ onSelect?: (value: CalendarDate | null) => void;
21
+ }
22
+ | {
23
+ mode: "multiple";
24
+ selected?: readonly CalendarDate[];
25
+ defaultSelected?: readonly CalendarDate[];
26
+ /** Fires on every change, sorted earliest first. */
27
+ onSelect?: (value: readonly CalendarDate[]) => void;
28
+ }
29
+ | {
30
+ mode: "range";
31
+ selected?: CalendarDateRange;
32
+ defaultSelected?: CalendarDateRange;
33
+ /** Fires on both taps — once with only a start, once complete. */
34
+ onSelect?: (value: CalendarDateRange) => void;
35
+ };
36
+
37
+ /** What a month's caption is: a plain label, or a button that opens the month and year views. */
38
+ export type CalendarCaptionLayout = "label" | "picker";
39
+
40
+ export type CalendarProps = Omit<ViewProps, "children"> &
41
+ CalendarSelection & {
42
+ /** `primary` fills the selected day; `secondary` softens it. */
43
+ variant?: CalendarVariant;
44
+ /** The cell height and the number's size, on the input scale. */
45
+ size?: CalendarSize;
46
+ /** The earliest day that can be picked, inclusive. */
47
+ minDate?: CalendarDate;
48
+ /** The latest day that can be picked, inclusive. */
49
+ maxDate?: CalendarDate;
50
+ /** Further days that cannot be picked. A day any matcher matches is disabled. */
51
+ disabled?: readonly DateMatcher[];
52
+ /** Inert and faded. Inherited from an enclosing `Field`. */
53
+ isDisabled?: boolean;
54
+ /** Tints the selection destructive. Inherited from an enclosing `Field`. */
55
+ isInvalid?: boolean;
56
+ /** The selection is shown and cannot be changed. Paging still works. */
57
+ isReadOnly?: boolean;
58
+ /** Controlled visible month. The day is ignored. */
59
+ month?: CalendarDate;
60
+ /** Starting month while uncontrolled. Omitted, the selection's month, else today's. */
61
+ defaultMonth?: CalendarDate;
62
+ /** Fires with the first of the month whenever the visible month changes. */
63
+ onMonthChange?: (month: CalendarDate) => void;
64
+ /** The earliest month paging and the jump views reach. Omitted, `minDate`'s month. */
65
+ startMonth?: CalendarDate;
66
+ /** The latest month paging and the jump views reach. Omitted, `maxDate`'s month. */
67
+ endMonth?: CalendarDate;
68
+ /** A BCP 47 tag for the names and the week start. Omitted, the device's. */
69
+ locale?: string;
70
+ /** The first column's weekday. `auto` reads it from the locale. */
71
+ weekStartsOn?: Weekday | "auto";
72
+ /** `picker` makes the caption open the month and year views. */
73
+ captionLayout?: CalendarCaptionLayout;
74
+ /** Draws the neighbouring months' days in the leading and trailing cells. */
75
+ showOutsideDays?: boolean;
76
+ /** Lets an outside day be picked, paging to its month. */
77
+ selectOutsideDays?: boolean;
78
+ /** Draws the calendar on a `Surface` card. Off, it sits bare — the way a sheet embeds it. */
79
+ isBordered?: boolean;
80
+ /** A horizontal swipe on the grid pages the month. */
81
+ swipeToPage?: boolean;
82
+ /** Overrides today — for a demo, a screenshot or a test. */
83
+ today?: CalendarDate;
84
+ className?: string;
85
+ /** A custom anatomy. Omitted, the header, the weekday row and the grid. */
86
+ children?: ReactNode;
87
+ };