@thewhileloop/whileui 1.2.2 → 2.0.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 (688) hide show
  1. package/README.md +248 -85
  2. package/dist/blocks/chat/chat.d.ts +3 -4
  3. package/dist/blocks/chat/chat.js +29 -17
  4. package/dist/blocks/chat/index.d.ts +0 -1
  5. package/dist/blocks/chat/index.js +0 -1
  6. package/dist/blocks/commerce/checkout-summary.d.ts +1 -2
  7. package/dist/blocks/commerce/checkout-summary.js +16 -4
  8. package/dist/blocks/commerce/feature-gate.d.ts +1 -2
  9. package/dist/blocks/commerce/feature-gate.js +14 -4
  10. package/dist/blocks/commerce/index.d.ts +0 -1
  11. package/dist/blocks/commerce/index.js +0 -1
  12. package/dist/blocks/commerce/metric-card.d.ts +3 -4
  13. package/dist/blocks/commerce/metric-card.js +7 -3
  14. package/dist/blocks/commerce/plan-toggle.d.ts +1 -2
  15. package/dist/blocks/commerce/plan-toggle.js +11 -9
  16. package/dist/blocks/commerce/pricing-card.d.ts +1 -2
  17. package/dist/blocks/commerce/pricing-card.js +23 -6
  18. package/dist/blocks/commerce/product-card.d.ts +1 -2
  19. package/dist/blocks/commerce/product-card.js +23 -9
  20. package/dist/blocks/commerce/subscription-card.d.ts +1 -2
  21. package/dist/blocks/commerce/subscription-card.js +6 -3
  22. package/dist/blocks/commerce/upgrade-banner.d.ts +1 -2
  23. package/dist/blocks/commerce/upgrade-banner.js +13 -3
  24. package/dist/blocks/commerce/usage-bar.d.ts +1 -2
  25. package/dist/blocks/commerce/usage-bar.js +4 -2
  26. package/dist/blocks/datepicker/date-range-picker-modal.d.ts +2 -3
  27. package/dist/blocks/datepicker/date-range-picker-modal.js +33 -7
  28. package/dist/blocks/datepicker/datepicker-inline.d.ts +1 -2
  29. package/dist/blocks/datepicker/datepicker-inline.js +9 -3
  30. package/dist/blocks/datepicker/datepicker-modal.d.ts +2 -3
  31. package/dist/blocks/datepicker/datepicker-modal.js +49 -17
  32. package/dist/blocks/datepicker/index.d.ts +0 -1
  33. package/dist/blocks/datepicker/index.js +0 -1
  34. package/dist/blocks/datepicker/use-calendar-theme.d.ts +0 -1
  35. package/dist/blocks/datepicker/use-calendar-theme.js +0 -1
  36. package/dist/blocks/layout/action-bar.d.ts +1 -2
  37. package/dist/blocks/layout/action-bar.js +0 -1
  38. package/dist/blocks/layout/app-shell.d.ts +1 -2
  39. package/dist/blocks/layout/app-shell.js +11 -5
  40. package/dist/blocks/layout/confirm-action-sheet.d.ts +1 -2
  41. package/dist/blocks/layout/confirm-action-sheet.js +18 -6
  42. package/dist/blocks/layout/content-skeleton.d.ts +1 -2
  43. package/dist/blocks/layout/content-skeleton.js +22 -9
  44. package/dist/blocks/layout/docked-input.d.ts +11 -0
  45. package/dist/blocks/layout/docked-input.js +27 -0
  46. package/dist/blocks/layout/empty-state.d.ts +1 -2
  47. package/dist/blocks/layout/empty-state.js +10 -5
  48. package/dist/blocks/layout/error-boundary.d.ts +1 -2
  49. package/dist/blocks/layout/error-boundary.js +0 -2
  50. package/dist/blocks/layout/error-state.d.ts +1 -2
  51. package/dist/blocks/layout/error-state.js +0 -2
  52. package/dist/blocks/layout/form-modal-screen.d.ts +1 -2
  53. package/dist/blocks/layout/form-modal-screen.js +24 -21
  54. package/dist/blocks/layout/index.d.ts +2 -2
  55. package/dist/blocks/layout/index.js +2 -2
  56. package/dist/blocks/layout/keyboard-aware-screen.d.ts +14 -0
  57. package/dist/blocks/layout/keyboard-aware-screen.js +12 -0
  58. package/dist/blocks/layout/loading-screen.d.ts +1 -2
  59. package/dist/blocks/layout/loading-screen.js +6 -8
  60. package/dist/blocks/layout/page-skeleton.d.ts +1 -2
  61. package/dist/blocks/layout/page-skeleton.js +38 -20
  62. package/dist/blocks/layout/pull-to-refresh-scroll-view.d.ts +8 -4
  63. package/dist/blocks/layout/pull-to-refresh-scroll-view.js +17 -4
  64. package/dist/blocks/layout/screen-skeleton.d.ts +1 -2
  65. package/dist/blocks/layout/screen-skeleton.js +0 -1
  66. package/dist/blocks/layout/sheet.d.ts +9 -9
  67. package/dist/blocks/layout/sheet.js +51 -21
  68. package/dist/blocks/layout/smart-input.d.ts +6 -1
  69. package/dist/blocks/layout/smart-input.js +121 -9
  70. package/dist/blocks/lists/index.d.ts +0 -2
  71. package/dist/blocks/lists/index.js +0 -2
  72. package/dist/blocks/lists/list-item.d.ts +1 -2
  73. package/dist/blocks/lists/list-item.js +20 -6
  74. package/dist/blocks/lists/notification-item.d.ts +1 -2
  75. package/dist/blocks/lists/notification-item.js +19 -6
  76. package/dist/blocks/lists/timeline-feed.d.ts +1 -2
  77. package/dist/blocks/lists/timeline-feed.js +4 -2
  78. package/dist/blocks/media/index.d.ts +0 -1
  79. package/dist/blocks/media/index.js +0 -1
  80. package/dist/blocks/media/smart-image.d.ts +0 -1
  81. package/dist/blocks/media/smart-image.js +24 -8
  82. package/dist/blocks/navigation/bottom-nav.d.ts +1 -2
  83. package/dist/blocks/navigation/bottom-nav.js +7 -4
  84. package/dist/blocks/navigation/drawer-menu.d.ts +1 -2
  85. package/dist/blocks/navigation/drawer-menu.js +52 -15
  86. package/dist/blocks/navigation/floating-bottom-nav.d.ts +1 -2
  87. package/dist/blocks/navigation/floating-bottom-nav.js +14 -5
  88. package/dist/blocks/navigation/header.d.ts +2 -3
  89. package/dist/blocks/navigation/header.js +13 -5
  90. package/dist/blocks/navigation/index.d.ts +0 -2
  91. package/dist/blocks/navigation/index.js +0 -2
  92. package/dist/blocks/navigation/tab-bar.d.ts +1 -2
  93. package/dist/blocks/navigation/tab-bar.js +22 -10
  94. package/dist/blocks/splash/index.d.ts +0 -1
  95. package/dist/blocks/splash/index.js +0 -1
  96. package/dist/blocks/splash/splash-screen.d.ts +3 -4
  97. package/dist/blocks/splash/splash-screen.js +15 -11
  98. package/dist/components/accordion/accordion.d.ts +4 -5
  99. package/dist/components/accordion/accordion.js +6 -7
  100. package/dist/components/accordion/index.d.ts +0 -1
  101. package/dist/components/accordion/index.js +0 -1
  102. package/dist/components/alert/alert.d.ts +2 -3
  103. package/dist/components/alert/alert.js +19 -8
  104. package/dist/components/alert/index.d.ts +0 -1
  105. package/dist/components/alert/index.js +0 -1
  106. package/dist/components/alert-dialog/alert-dialog.d.ts +16 -12
  107. package/dist/components/alert-dialog/alert-dialog.js +184 -49
  108. package/dist/components/alert-dialog/index.d.ts +0 -1
  109. package/dist/components/alert-dialog/index.js +0 -1
  110. package/dist/components/aspect-ratio/aspect-ratio.d.ts +1 -2
  111. package/dist/components/aspect-ratio/aspect-ratio.js +0 -3
  112. package/dist/components/aspect-ratio/index.d.ts +0 -1
  113. package/dist/components/aspect-ratio/index.js +0 -1
  114. package/dist/components/avatar/avatar.d.ts +2 -3
  115. package/dist/components/avatar/avatar.js +7 -8
  116. package/dist/components/avatar/index.d.ts +0 -1
  117. package/dist/components/avatar/index.js +0 -1
  118. package/dist/components/badge/badge.d.ts +6 -7
  119. package/dist/components/badge/badge.js +21 -9
  120. package/dist/components/badge/index.d.ts +0 -1
  121. package/dist/components/badge/index.js +0 -1
  122. package/dist/components/button/button.d.ts +11 -10
  123. package/dist/components/button/button.js +62 -33
  124. package/dist/components/button/index.d.ts +0 -1
  125. package/dist/components/button/index.js +0 -1
  126. package/dist/components/card/card.d.ts +5 -3
  127. package/dist/components/card/card.js +28 -14
  128. package/dist/components/card/index.d.ts +0 -1
  129. package/dist/components/card/index.js +0 -1
  130. package/dist/components/checkbox/checkbox.d.ts +1 -2
  131. package/dist/components/checkbox/checkbox.js +15 -2
  132. package/dist/components/checkbox/index.d.ts +0 -1
  133. package/dist/components/checkbox/index.js +0 -1
  134. package/dist/components/collapsible/collapsible.d.ts +4 -4
  135. package/dist/components/collapsible/collapsible.js +8 -11
  136. package/dist/components/collapsible/index.d.ts +0 -1
  137. package/dist/components/collapsible/index.js +0 -1
  138. package/dist/components/container/container.d.ts +146 -0
  139. package/dist/components/container/container.js +43 -0
  140. package/dist/components/container/index.d.ts +1 -0
  141. package/dist/components/container/index.js +1 -0
  142. package/dist/components/context-menu/context-menu.d.ts +6 -7
  143. package/dist/components/context-menu/context-menu.js +42 -12
  144. package/dist/components/context-menu/index.d.ts +0 -1
  145. package/dist/components/context-menu/index.js +0 -1
  146. package/dist/components/data-row/data-row.d.ts +0 -1
  147. package/dist/components/data-row/data-row.js +35 -17
  148. package/dist/components/data-row/index.d.ts +0 -1
  149. package/dist/components/data-row/index.js +0 -1
  150. package/dist/components/dialog/dialog.d.ts +8 -9
  151. package/dist/components/dialog/dialog.js +48 -24
  152. package/dist/components/dialog/index.d.ts +0 -1
  153. package/dist/components/dialog/index.js +0 -1
  154. package/dist/components/dropdown-menu/dropdown-menu.d.ts +6 -7
  155. package/dist/components/dropdown-menu/dropdown-menu.js +45 -11
  156. package/dist/components/dropdown-menu/index.d.ts +0 -1
  157. package/dist/components/dropdown-menu/index.js +0 -1
  158. package/dist/components/form-field/form-field.d.ts +0 -1
  159. package/dist/components/form-field/form-field.js +26 -13
  160. package/dist/components/form-field/index.d.ts +0 -1
  161. package/dist/components/form-field/index.js +0 -1
  162. package/dist/components/hover-card/hover-card.d.ts +1 -2
  163. package/dist/components/hover-card/hover-card.js +12 -3
  164. package/dist/components/hover-card/index.d.ts +0 -1
  165. package/dist/components/hover-card/index.js +0 -1
  166. package/dist/components/input/index.d.ts +0 -1
  167. package/dist/components/input/index.js +0 -1
  168. package/dist/components/input/input.d.ts +2 -3
  169. package/dist/components/input/input.js +18 -3
  170. package/dist/components/label/index.d.ts +0 -1
  171. package/dist/components/label/index.js +0 -1
  172. package/dist/components/label/label.d.ts +0 -1
  173. package/dist/components/label/label.js +0 -1
  174. package/dist/components/labeled-field/index.d.ts +0 -1
  175. package/dist/components/labeled-field/index.js +0 -1
  176. package/dist/components/labeled-field/labeled-field.d.ts +1 -2
  177. package/dist/components/labeled-field/labeled-field.js +10 -2
  178. package/dist/components/menubar/index.d.ts +0 -1
  179. package/dist/components/menubar/index.js +0 -1
  180. package/dist/components/menubar/menubar.d.ts +7 -8
  181. package/dist/components/menubar/menubar.js +48 -15
  182. package/dist/components/numeric-input/index.d.ts +0 -1
  183. package/dist/components/numeric-input/index.js +0 -1
  184. package/dist/components/numeric-input/numeric-input.d.ts +6 -5
  185. package/dist/components/numeric-input/numeric-input.js +55 -26
  186. package/dist/components/otp-input/index.d.ts +0 -1
  187. package/dist/components/otp-input/index.js +0 -1
  188. package/dist/components/otp-input/otp-input.d.ts +3 -4
  189. package/dist/components/otp-input/otp-input.js +13 -9
  190. package/dist/components/popover/index.d.ts +0 -1
  191. package/dist/components/popover/index.js +0 -1
  192. package/dist/components/popover/popover.d.ts +4 -2
  193. package/dist/components/popover/popover.js +21 -4
  194. package/dist/components/pressable/index.d.ts +0 -1
  195. package/dist/components/pressable/index.js +0 -1
  196. package/dist/components/pressable/pressable.d.ts +7 -1
  197. package/dist/components/pressable/pressable.js +47 -4
  198. package/dist/components/progress/index.d.ts +0 -1
  199. package/dist/components/progress/index.js +0 -1
  200. package/dist/components/progress/progress.d.ts +0 -1
  201. package/dist/components/progress/progress.js +5 -2
  202. package/dist/components/radio-group/index.d.ts +0 -1
  203. package/dist/components/radio-group/index.js +0 -1
  204. package/dist/components/radio-group/radio-group.d.ts +2 -3
  205. package/dist/components/radio-group/radio-group.js +16 -7
  206. package/dist/components/row/index.d.ts +0 -1
  207. package/dist/components/row/index.js +0 -1
  208. package/dist/components/row/row.d.ts +0 -1
  209. package/dist/components/row/row.js +0 -1
  210. package/dist/components/segmented-control/index.d.ts +0 -1
  211. package/dist/components/segmented-control/index.js +0 -1
  212. package/dist/components/segmented-control/segmented-control.d.ts +7 -8
  213. package/dist/components/segmented-control/segmented-control.js +57 -24
  214. package/dist/components/select/index.d.ts +0 -1
  215. package/dist/components/select/index.js +0 -1
  216. package/dist/components/select/select.d.ts +15 -7
  217. package/dist/components/select/select.js +53 -11
  218. package/dist/components/separator/index.d.ts +0 -1
  219. package/dist/components/separator/index.js +0 -1
  220. package/dist/components/separator/separator.d.ts +0 -1
  221. package/dist/components/separator/separator.js +0 -1
  222. package/dist/components/skeleton/index.d.ts +0 -1
  223. package/dist/components/skeleton/index.js +0 -1
  224. package/dist/components/skeleton/skeleton.d.ts +3 -4
  225. package/dist/components/skeleton/skeleton.js +7 -8
  226. package/dist/components/spinner/index.d.ts +0 -1
  227. package/dist/components/spinner/index.js +0 -1
  228. package/dist/components/spinner/spinner.d.ts +1 -2
  229. package/dist/components/spinner/spinner.js +4 -2
  230. package/dist/components/stack/index.d.ts +0 -1
  231. package/dist/components/stack/index.js +0 -1
  232. package/dist/components/stack/stack.d.ts +0 -1
  233. package/dist/components/stack/stack.js +0 -1
  234. package/dist/components/switch/index.d.ts +0 -1
  235. package/dist/components/switch/index.js +0 -1
  236. package/dist/components/switch/switch.d.ts +1 -2
  237. package/dist/components/switch/switch.js +21 -2
  238. package/dist/components/tabs/index.d.ts +0 -1
  239. package/dist/components/tabs/index.js +0 -1
  240. package/dist/components/tabs/tabs.d.ts +6 -7
  241. package/dist/components/tabs/tabs.js +42 -12
  242. package/dist/components/text/index.d.ts +0 -1
  243. package/dist/components/text/index.js +0 -1
  244. package/dist/components/text/text.d.ts +0 -1
  245. package/dist/components/text/text.js +0 -1
  246. package/dist/components/textarea/index.d.ts +0 -1
  247. package/dist/components/textarea/index.js +0 -1
  248. package/dist/components/textarea/textarea.d.ts +2 -3
  249. package/dist/components/textarea/textarea.js +16 -8
  250. package/dist/components/toast/index.d.ts +0 -1
  251. package/dist/components/toast/index.js +0 -1
  252. package/dist/components/toast/toast.d.ts +5 -6
  253. package/dist/components/toast/toast.js +40 -24
  254. package/dist/components/toggle/index.d.ts +0 -1
  255. package/dist/components/toggle/index.js +0 -1
  256. package/dist/components/toggle/toggle.d.ts +6 -7
  257. package/dist/components/toggle/toggle.js +32 -16
  258. package/dist/components/toggle-group/index.d.ts +0 -1
  259. package/dist/components/toggle-group/index.js +0 -1
  260. package/dist/components/toggle-group/toggle-group.d.ts +7 -8
  261. package/dist/components/toggle-group/toggle-group.js +36 -19
  262. package/dist/components/tooltip/index.d.ts +0 -1
  263. package/dist/components/tooltip/index.js +0 -1
  264. package/dist/components/tooltip/tooltip.d.ts +1 -2
  265. package/dist/components/tooltip/tooltip.js +20 -3
  266. package/dist/components/view/index.d.ts +0 -1
  267. package/dist/components/view/index.js +0 -1
  268. package/dist/components/view/view.d.ts +0 -1
  269. package/dist/components/view/view.js +0 -1
  270. package/dist/index.d.ts +9 -3
  271. package/dist/index.js +9 -7
  272. package/dist/lib/cn.d.ts +0 -1
  273. package/dist/lib/cn.js +0 -1
  274. package/dist/lib/compose-event-handlers.d.ts +15 -0
  275. package/dist/lib/compose-event-handlers.js +20 -0
  276. package/dist/lib/focus-ring.d.ts +25 -0
  277. package/dist/lib/focus-ring.js +25 -0
  278. package/dist/lib/font-context.d.ts +1 -1
  279. package/dist/lib/font-context.js +6 -4
  280. package/dist/lib/frosted-surface.d.ts +0 -1
  281. package/dist/lib/frosted-surface.js +31 -6
  282. package/dist/lib/interaction-tokens.d.ts +12 -1
  283. package/dist/lib/interaction-tokens.js +27 -13
  284. package/dist/lib/motion-policy.d.ts +25 -0
  285. package/dist/lib/motion-policy.js +97 -0
  286. package/dist/lib/overlay-insets.d.ts +17 -0
  287. package/dist/lib/overlay-insets.js +23 -0
  288. package/dist/lib/portal.d.ts +0 -1
  289. package/dist/lib/portal.js +0 -1
  290. package/dist/lib/react-native-classname.d.ts +0 -1
  291. package/dist/lib/react-native-classname.js +0 -1
  292. package/dist/lib/recipes.d.ts +30 -0
  293. package/dist/lib/recipes.js +138 -0
  294. package/dist/lib/tap-only.d.ts +11 -0
  295. package/dist/lib/tap-only.js +24 -0
  296. package/dist/lib/theme-bridge.d.ts +0 -1
  297. package/dist/lib/theme-bridge.js +11 -3
  298. package/dist/lib/theme-colors.d.ts +2 -46
  299. package/dist/lib/theme-colors.js +25 -226
  300. package/dist/lib/theme-contract.d.ts +78 -0
  301. package/dist/lib/theme-contract.js +481 -0
  302. package/dist/lib/theme-derive.d.ts +4 -0
  303. package/dist/lib/theme-derive.js +80 -0
  304. package/dist/lib/theme-presets.d.ts +31 -0
  305. package/dist/lib/theme-presets.js +221 -0
  306. package/dist/lib/tv.d.ts +0 -1
  307. package/dist/lib/tv.js +0 -1
  308. package/dist/lib/visual-token-contract.d.ts +110 -0
  309. package/dist/lib/visual-token-contract.js +583 -0
  310. package/dist/lib/visual-tokens.d.ts +2 -38
  311. package/dist/lib/visual-tokens.js +22 -75
  312. package/dist/tokens.d.ts +4 -0
  313. package/dist/tokens.js +6 -0
  314. package/dist/vite.d.ts +0 -1
  315. package/dist/vite.js +0 -1
  316. package/package.json +30 -20
  317. package/dist/blocks/auth/forgot-password-form.d.ts +0 -10
  318. package/dist/blocks/auth/forgot-password-form.d.ts.map +0 -1
  319. package/dist/blocks/auth/forgot-password-form.js +0 -17
  320. package/dist/blocks/auth/forgot-password-form.js.map +0 -1
  321. package/dist/blocks/auth/index.d.ts +0 -8
  322. package/dist/blocks/auth/index.d.ts.map +0 -1
  323. package/dist/blocks/auth/index.js +0 -8
  324. package/dist/blocks/auth/index.js.map +0 -1
  325. package/dist/blocks/auth/reset-password-form.d.ts +0 -9
  326. package/dist/blocks/auth/reset-password-form.d.ts.map +0 -1
  327. package/dist/blocks/auth/reset-password-form.js +0 -16
  328. package/dist/blocks/auth/reset-password-form.js.map +0 -1
  329. package/dist/blocks/auth/sign-in-form.d.ts +0 -17
  330. package/dist/blocks/auth/sign-in-form.d.ts.map +0 -1
  331. package/dist/blocks/auth/sign-in-form.js +0 -19
  332. package/dist/blocks/auth/sign-in-form.js.map +0 -1
  333. package/dist/blocks/auth/sign-up-form.d.ts +0 -17
  334. package/dist/blocks/auth/sign-up-form.d.ts.map +0 -1
  335. package/dist/blocks/auth/sign-up-form.js +0 -21
  336. package/dist/blocks/auth/sign-up-form.js.map +0 -1
  337. package/dist/blocks/auth/social-connections.d.ts +0 -10
  338. package/dist/blocks/auth/social-connections.d.ts.map +0 -1
  339. package/dist/blocks/auth/social-connections.js +0 -8
  340. package/dist/blocks/auth/social-connections.js.map +0 -1
  341. package/dist/blocks/auth/user-menu.d.ts +0 -12
  342. package/dist/blocks/auth/user-menu.d.ts.map +0 -1
  343. package/dist/blocks/auth/user-menu.js +0 -10
  344. package/dist/blocks/auth/user-menu.js.map +0 -1
  345. package/dist/blocks/auth/verify-email-form.d.ts +0 -10
  346. package/dist/blocks/auth/verify-email-form.d.ts.map +0 -1
  347. package/dist/blocks/auth/verify-email-form.js +0 -17
  348. package/dist/blocks/auth/verify-email-form.js.map +0 -1
  349. package/dist/blocks/chat/chat.d.ts.map +0 -1
  350. package/dist/blocks/chat/chat.js.map +0 -1
  351. package/dist/blocks/chat/index.d.ts.map +0 -1
  352. package/dist/blocks/chat/index.js.map +0 -1
  353. package/dist/blocks/commerce/checkout-summary.d.ts.map +0 -1
  354. package/dist/blocks/commerce/checkout-summary.js.map +0 -1
  355. package/dist/blocks/commerce/feature-gate.d.ts.map +0 -1
  356. package/dist/blocks/commerce/feature-gate.js.map +0 -1
  357. package/dist/blocks/commerce/index.d.ts.map +0 -1
  358. package/dist/blocks/commerce/index.js.map +0 -1
  359. package/dist/blocks/commerce/metric-card.d.ts.map +0 -1
  360. package/dist/blocks/commerce/metric-card.js.map +0 -1
  361. package/dist/blocks/commerce/plan-toggle.d.ts.map +0 -1
  362. package/dist/blocks/commerce/plan-toggle.js.map +0 -1
  363. package/dist/blocks/commerce/pricing-card.d.ts.map +0 -1
  364. package/dist/blocks/commerce/pricing-card.js.map +0 -1
  365. package/dist/blocks/commerce/product-card.d.ts.map +0 -1
  366. package/dist/blocks/commerce/product-card.js.map +0 -1
  367. package/dist/blocks/commerce/subscription-card.d.ts.map +0 -1
  368. package/dist/blocks/commerce/subscription-card.js.map +0 -1
  369. package/dist/blocks/commerce/upgrade-banner.d.ts.map +0 -1
  370. package/dist/blocks/commerce/upgrade-banner.js.map +0 -1
  371. package/dist/blocks/commerce/usage-bar.d.ts.map +0 -1
  372. package/dist/blocks/commerce/usage-bar.js.map +0 -1
  373. package/dist/blocks/datepicker/date-range-picker-modal.d.ts.map +0 -1
  374. package/dist/blocks/datepicker/date-range-picker-modal.js.map +0 -1
  375. package/dist/blocks/datepicker/datepicker-inline.d.ts.map +0 -1
  376. package/dist/blocks/datepicker/datepicker-inline.js.map +0 -1
  377. package/dist/blocks/datepicker/datepicker-modal.d.ts.map +0 -1
  378. package/dist/blocks/datepicker/datepicker-modal.js.map +0 -1
  379. package/dist/blocks/datepicker/index.d.ts.map +0 -1
  380. package/dist/blocks/datepicker/index.js.map +0 -1
  381. package/dist/blocks/datepicker/use-calendar-theme.d.ts.map +0 -1
  382. package/dist/blocks/datepicker/use-calendar-theme.js.map +0 -1
  383. package/dist/blocks/layout/action-bar.d.ts.map +0 -1
  384. package/dist/blocks/layout/action-bar.js.map +0 -1
  385. package/dist/blocks/layout/app-shell.d.ts.map +0 -1
  386. package/dist/blocks/layout/app-shell.js.map +0 -1
  387. package/dist/blocks/layout/confirm-action-sheet.d.ts.map +0 -1
  388. package/dist/blocks/layout/confirm-action-sheet.js.map +0 -1
  389. package/dist/blocks/layout/content-skeleton.d.ts.map +0 -1
  390. package/dist/blocks/layout/content-skeleton.js.map +0 -1
  391. package/dist/blocks/layout/empty-state.d.ts.map +0 -1
  392. package/dist/blocks/layout/empty-state.js.map +0 -1
  393. package/dist/blocks/layout/error-boundary.d.ts.map +0 -1
  394. package/dist/blocks/layout/error-boundary.js.map +0 -1
  395. package/dist/blocks/layout/error-state.d.ts.map +0 -1
  396. package/dist/blocks/layout/error-state.js.map +0 -1
  397. package/dist/blocks/layout/form-modal-screen.d.ts.map +0 -1
  398. package/dist/blocks/layout/form-modal-screen.js.map +0 -1
  399. package/dist/blocks/layout/index.d.ts.map +0 -1
  400. package/dist/blocks/layout/index.js.map +0 -1
  401. package/dist/blocks/layout/loading-screen.d.ts.map +0 -1
  402. package/dist/blocks/layout/loading-screen.js.map +0 -1
  403. package/dist/blocks/layout/onboarding-screen.d.ts +0 -19
  404. package/dist/blocks/layout/onboarding-screen.d.ts.map +0 -1
  405. package/dist/blocks/layout/onboarding-screen.js +0 -35
  406. package/dist/blocks/layout/onboarding-screen.js.map +0 -1
  407. package/dist/blocks/layout/page-skeleton.d.ts.map +0 -1
  408. package/dist/blocks/layout/page-skeleton.js.map +0 -1
  409. package/dist/blocks/layout/pull-to-refresh-scroll-view.d.ts.map +0 -1
  410. package/dist/blocks/layout/pull-to-refresh-scroll-view.js.map +0 -1
  411. package/dist/blocks/layout/screen-skeleton.d.ts.map +0 -1
  412. package/dist/blocks/layout/screen-skeleton.js.map +0 -1
  413. package/dist/blocks/layout/sheet.d.ts.map +0 -1
  414. package/dist/blocks/layout/sheet.js.map +0 -1
  415. package/dist/blocks/layout/smart-image.d.ts +0 -9
  416. package/dist/blocks/layout/smart-image.d.ts.map +0 -1
  417. package/dist/blocks/layout/smart-image.js +0 -23
  418. package/dist/blocks/layout/smart-image.js.map +0 -1
  419. package/dist/blocks/layout/smart-input.d.ts.map +0 -1
  420. package/dist/blocks/layout/smart-input.js.map +0 -1
  421. package/dist/blocks/lists/index.d.ts.map +0 -1
  422. package/dist/blocks/lists/index.js.map +0 -1
  423. package/dist/blocks/lists/list-item.d.ts.map +0 -1
  424. package/dist/blocks/lists/list-item.js.map +0 -1
  425. package/dist/blocks/lists/notification-item.d.ts.map +0 -1
  426. package/dist/blocks/lists/notification-item.js.map +0 -1
  427. package/dist/blocks/lists/swipeable-item.d.ts +0 -17
  428. package/dist/blocks/lists/swipeable-item.d.ts.map +0 -1
  429. package/dist/blocks/lists/swipeable-item.js +0 -65
  430. package/dist/blocks/lists/swipeable-item.js.map +0 -1
  431. package/dist/blocks/lists/timeline-feed.d.ts.map +0 -1
  432. package/dist/blocks/lists/timeline-feed.js.map +0 -1
  433. package/dist/blocks/media/index.d.ts.map +0 -1
  434. package/dist/blocks/media/index.js.map +0 -1
  435. package/dist/blocks/media/smart-image.d.ts.map +0 -1
  436. package/dist/blocks/media/smart-image.js.map +0 -1
  437. package/dist/blocks/navigation/bottom-nav.d.ts.map +0 -1
  438. package/dist/blocks/navigation/bottom-nav.js.map +0 -1
  439. package/dist/blocks/navigation/drawer-menu.d.ts.map +0 -1
  440. package/dist/blocks/navigation/drawer-menu.js.map +0 -1
  441. package/dist/blocks/navigation/floating-bottom-nav.d.ts.map +0 -1
  442. package/dist/blocks/navigation/floating-bottom-nav.js.map +0 -1
  443. package/dist/blocks/navigation/header.d.ts.map +0 -1
  444. package/dist/blocks/navigation/header.js.map +0 -1
  445. package/dist/blocks/navigation/index.d.ts.map +0 -1
  446. package/dist/blocks/navigation/index.js.map +0 -1
  447. package/dist/blocks/navigation/navigation-sidebar.d.ts +0 -25
  448. package/dist/blocks/navigation/navigation-sidebar.d.ts.map +0 -1
  449. package/dist/blocks/navigation/navigation-sidebar.js +0 -18
  450. package/dist/blocks/navigation/navigation-sidebar.js.map +0 -1
  451. package/dist/blocks/navigation/tab-bar.d.ts.map +0 -1
  452. package/dist/blocks/navigation/tab-bar.js.map +0 -1
  453. package/dist/blocks/profile/account-card.d.ts +0 -11
  454. package/dist/blocks/profile/account-card.d.ts.map +0 -1
  455. package/dist/blocks/profile/account-card.js +0 -10
  456. package/dist/blocks/profile/account-card.js.map +0 -1
  457. package/dist/blocks/profile/index.d.ts +0 -5
  458. package/dist/blocks/profile/index.d.ts.map +0 -1
  459. package/dist/blocks/profile/index.js +0 -5
  460. package/dist/blocks/profile/index.js.map +0 -1
  461. package/dist/blocks/profile/profile-header.d.ts +0 -27
  462. package/dist/blocks/profile/profile-header.d.ts.map +0 -1
  463. package/dist/blocks/profile/profile-header.js +0 -11
  464. package/dist/blocks/profile/profile-header.js.map +0 -1
  465. package/dist/blocks/profile/settings-item.d.ts +0 -15
  466. package/dist/blocks/profile/settings-item.d.ts.map +0 -1
  467. package/dist/blocks/profile/settings-item.js +0 -11
  468. package/dist/blocks/profile/settings-item.js.map +0 -1
  469. package/dist/blocks/profile/settings-section.d.ts +0 -7
  470. package/dist/blocks/profile/settings-section.d.ts.map +0 -1
  471. package/dist/blocks/profile/settings-section.js +0 -9
  472. package/dist/blocks/profile/settings-section.js.map +0 -1
  473. package/dist/blocks/splash/index.d.ts.map +0 -1
  474. package/dist/blocks/splash/index.js.map +0 -1
  475. package/dist/blocks/splash/splash-screen.d.ts.map +0 -1
  476. package/dist/blocks/splash/splash-screen.js.map +0 -1
  477. package/dist/components/accordion/accordion.d.ts.map +0 -1
  478. package/dist/components/accordion/accordion.js.map +0 -1
  479. package/dist/components/accordion/index.d.ts.map +0 -1
  480. package/dist/components/accordion/index.js.map +0 -1
  481. package/dist/components/alert/alert.d.ts.map +0 -1
  482. package/dist/components/alert/alert.js.map +0 -1
  483. package/dist/components/alert/index.d.ts.map +0 -1
  484. package/dist/components/alert/index.js.map +0 -1
  485. package/dist/components/alert-dialog/alert-dialog.d.ts.map +0 -1
  486. package/dist/components/alert-dialog/alert-dialog.js.map +0 -1
  487. package/dist/components/alert-dialog/index.d.ts.map +0 -1
  488. package/dist/components/alert-dialog/index.js.map +0 -1
  489. package/dist/components/aspect-ratio/aspect-ratio.d.ts.map +0 -1
  490. package/dist/components/aspect-ratio/aspect-ratio.js.map +0 -1
  491. package/dist/components/aspect-ratio/index.d.ts.map +0 -1
  492. package/dist/components/aspect-ratio/index.js.map +0 -1
  493. package/dist/components/avatar/avatar.d.ts.map +0 -1
  494. package/dist/components/avatar/avatar.js.map +0 -1
  495. package/dist/components/avatar/index.d.ts.map +0 -1
  496. package/dist/components/avatar/index.js.map +0 -1
  497. package/dist/components/badge/badge.d.ts.map +0 -1
  498. package/dist/components/badge/badge.js.map +0 -1
  499. package/dist/components/badge/index.d.ts.map +0 -1
  500. package/dist/components/badge/index.js.map +0 -1
  501. package/dist/components/box/box.d.ts +0 -143
  502. package/dist/components/box/box.d.ts.map +0 -1
  503. package/dist/components/box/box.js +0 -38
  504. package/dist/components/box/box.js.map +0 -1
  505. package/dist/components/box/index.d.ts +0 -2
  506. package/dist/components/box/index.d.ts.map +0 -1
  507. package/dist/components/box/index.js +0 -2
  508. package/dist/components/box/index.js.map +0 -1
  509. package/dist/components/button/button.d.ts.map +0 -1
  510. package/dist/components/button/button.js.map +0 -1
  511. package/dist/components/button/index.d.ts.map +0 -1
  512. package/dist/components/button/index.js.map +0 -1
  513. package/dist/components/card/card.d.ts.map +0 -1
  514. package/dist/components/card/card.js.map +0 -1
  515. package/dist/components/card/index.d.ts.map +0 -1
  516. package/dist/components/card/index.js.map +0 -1
  517. package/dist/components/checkbox/checkbox.d.ts.map +0 -1
  518. package/dist/components/checkbox/checkbox.js.map +0 -1
  519. package/dist/components/checkbox/index.d.ts.map +0 -1
  520. package/dist/components/checkbox/index.js.map +0 -1
  521. package/dist/components/collapsible/collapsible.d.ts.map +0 -1
  522. package/dist/components/collapsible/collapsible.js.map +0 -1
  523. package/dist/components/collapsible/index.d.ts.map +0 -1
  524. package/dist/components/collapsible/index.js.map +0 -1
  525. package/dist/components/context-menu/context-menu.d.ts.map +0 -1
  526. package/dist/components/context-menu/context-menu.js.map +0 -1
  527. package/dist/components/context-menu/index.d.ts.map +0 -1
  528. package/dist/components/context-menu/index.js.map +0 -1
  529. package/dist/components/data-row/data-row.d.ts.map +0 -1
  530. package/dist/components/data-row/data-row.js.map +0 -1
  531. package/dist/components/data-row/index.d.ts.map +0 -1
  532. package/dist/components/data-row/index.js.map +0 -1
  533. package/dist/components/dialog/dialog.d.ts.map +0 -1
  534. package/dist/components/dialog/dialog.js.map +0 -1
  535. package/dist/components/dialog/index.d.ts.map +0 -1
  536. package/dist/components/dialog/index.js.map +0 -1
  537. package/dist/components/dropdown-menu/dropdown-menu.d.ts.map +0 -1
  538. package/dist/components/dropdown-menu/dropdown-menu.js.map +0 -1
  539. package/dist/components/dropdown-menu/index.d.ts.map +0 -1
  540. package/dist/components/dropdown-menu/index.js.map +0 -1
  541. package/dist/components/form-field/form-field.d.ts.map +0 -1
  542. package/dist/components/form-field/form-field.js.map +0 -1
  543. package/dist/components/form-field/index.d.ts.map +0 -1
  544. package/dist/components/form-field/index.js.map +0 -1
  545. package/dist/components/hover-card/hover-card.d.ts.map +0 -1
  546. package/dist/components/hover-card/hover-card.js.map +0 -1
  547. package/dist/components/hover-card/index.d.ts.map +0 -1
  548. package/dist/components/hover-card/index.js.map +0 -1
  549. package/dist/components/input/index.d.ts.map +0 -1
  550. package/dist/components/input/index.js.map +0 -1
  551. package/dist/components/input/input.d.ts.map +0 -1
  552. package/dist/components/input/input.js.map +0 -1
  553. package/dist/components/label/index.d.ts.map +0 -1
  554. package/dist/components/label/index.js.map +0 -1
  555. package/dist/components/label/label.d.ts.map +0 -1
  556. package/dist/components/label/label.js.map +0 -1
  557. package/dist/components/labeled-field/index.d.ts.map +0 -1
  558. package/dist/components/labeled-field/index.js.map +0 -1
  559. package/dist/components/labeled-field/labeled-field.d.ts.map +0 -1
  560. package/dist/components/labeled-field/labeled-field.js.map +0 -1
  561. package/dist/components/layout/index.d.ts +0 -2
  562. package/dist/components/layout/index.d.ts.map +0 -1
  563. package/dist/components/layout/index.js +0 -2
  564. package/dist/components/layout/index.js.map +0 -1
  565. package/dist/components/layout/layout.d.ts +0 -395
  566. package/dist/components/layout/layout.d.ts.map +0 -1
  567. package/dist/components/layout/layout.js +0 -93
  568. package/dist/components/layout/layout.js.map +0 -1
  569. package/dist/components/menubar/index.d.ts.map +0 -1
  570. package/dist/components/menubar/index.js.map +0 -1
  571. package/dist/components/menubar/menubar.d.ts.map +0 -1
  572. package/dist/components/menubar/menubar.js.map +0 -1
  573. package/dist/components/numeric-input/index.d.ts.map +0 -1
  574. package/dist/components/numeric-input/index.js.map +0 -1
  575. package/dist/components/numeric-input/numeric-input.d.ts.map +0 -1
  576. package/dist/components/numeric-input/numeric-input.js.map +0 -1
  577. package/dist/components/otp-input/index.d.ts.map +0 -1
  578. package/dist/components/otp-input/index.js.map +0 -1
  579. package/dist/components/otp-input/otp-input.d.ts.map +0 -1
  580. package/dist/components/otp-input/otp-input.js.map +0 -1
  581. package/dist/components/popover/index.d.ts.map +0 -1
  582. package/dist/components/popover/index.js.map +0 -1
  583. package/dist/components/popover/popover.d.ts.map +0 -1
  584. package/dist/components/popover/popover.js.map +0 -1
  585. package/dist/components/pressable/index.d.ts.map +0 -1
  586. package/dist/components/pressable/index.js.map +0 -1
  587. package/dist/components/pressable/pressable.d.ts.map +0 -1
  588. package/dist/components/pressable/pressable.js.map +0 -1
  589. package/dist/components/progress/index.d.ts.map +0 -1
  590. package/dist/components/progress/index.js.map +0 -1
  591. package/dist/components/progress/progress.d.ts.map +0 -1
  592. package/dist/components/progress/progress.js.map +0 -1
  593. package/dist/components/radio-group/index.d.ts.map +0 -1
  594. package/dist/components/radio-group/index.js.map +0 -1
  595. package/dist/components/radio-group/radio-group.d.ts.map +0 -1
  596. package/dist/components/radio-group/radio-group.js.map +0 -1
  597. package/dist/components/row/index.d.ts.map +0 -1
  598. package/dist/components/row/index.js.map +0 -1
  599. package/dist/components/row/row.d.ts.map +0 -1
  600. package/dist/components/row/row.js.map +0 -1
  601. package/dist/components/segmented-control/index.d.ts.map +0 -1
  602. package/dist/components/segmented-control/index.js.map +0 -1
  603. package/dist/components/segmented-control/segmented-control.d.ts.map +0 -1
  604. package/dist/components/segmented-control/segmented-control.js.map +0 -1
  605. package/dist/components/select/index.d.ts.map +0 -1
  606. package/dist/components/select/index.js.map +0 -1
  607. package/dist/components/select/select.d.ts.map +0 -1
  608. package/dist/components/select/select.js.map +0 -1
  609. package/dist/components/separator/index.d.ts.map +0 -1
  610. package/dist/components/separator/index.js.map +0 -1
  611. package/dist/components/separator/separator.d.ts.map +0 -1
  612. package/dist/components/separator/separator.js.map +0 -1
  613. package/dist/components/skeleton/index.d.ts.map +0 -1
  614. package/dist/components/skeleton/index.js.map +0 -1
  615. package/dist/components/skeleton/skeleton.d.ts.map +0 -1
  616. package/dist/components/skeleton/skeleton.js.map +0 -1
  617. package/dist/components/spinner/index.d.ts.map +0 -1
  618. package/dist/components/spinner/index.js.map +0 -1
  619. package/dist/components/spinner/spinner.d.ts.map +0 -1
  620. package/dist/components/spinner/spinner.js.map +0 -1
  621. package/dist/components/stack/index.d.ts.map +0 -1
  622. package/dist/components/stack/index.js.map +0 -1
  623. package/dist/components/stack/stack.d.ts.map +0 -1
  624. package/dist/components/stack/stack.js.map +0 -1
  625. package/dist/components/switch/index.d.ts.map +0 -1
  626. package/dist/components/switch/index.js.map +0 -1
  627. package/dist/components/switch/switch.d.ts.map +0 -1
  628. package/dist/components/switch/switch.js.map +0 -1
  629. package/dist/components/tabs/index.d.ts.map +0 -1
  630. package/dist/components/tabs/index.js.map +0 -1
  631. package/dist/components/tabs/tabs.d.ts.map +0 -1
  632. package/dist/components/tabs/tabs.js.map +0 -1
  633. package/dist/components/text/index.d.ts.map +0 -1
  634. package/dist/components/text/index.js.map +0 -1
  635. package/dist/components/text/text.d.ts.map +0 -1
  636. package/dist/components/text/text.js.map +0 -1
  637. package/dist/components/textarea/index.d.ts.map +0 -1
  638. package/dist/components/textarea/index.js.map +0 -1
  639. package/dist/components/textarea/textarea.d.ts.map +0 -1
  640. package/dist/components/textarea/textarea.js.map +0 -1
  641. package/dist/components/toast/index.d.ts.map +0 -1
  642. package/dist/components/toast/index.js.map +0 -1
  643. package/dist/components/toast/toast.d.ts.map +0 -1
  644. package/dist/components/toast/toast.js.map +0 -1
  645. package/dist/components/toggle/index.d.ts.map +0 -1
  646. package/dist/components/toggle/index.js.map +0 -1
  647. package/dist/components/toggle/toggle.d.ts.map +0 -1
  648. package/dist/components/toggle/toggle.js.map +0 -1
  649. package/dist/components/toggle-group/index.d.ts.map +0 -1
  650. package/dist/components/toggle-group/index.js.map +0 -1
  651. package/dist/components/toggle-group/toggle-group.d.ts.map +0 -1
  652. package/dist/components/toggle-group/toggle-group.js.map +0 -1
  653. package/dist/components/tooltip/index.d.ts.map +0 -1
  654. package/dist/components/tooltip/index.js.map +0 -1
  655. package/dist/components/tooltip/tooltip.d.ts.map +0 -1
  656. package/dist/components/tooltip/tooltip.js.map +0 -1
  657. package/dist/components/view/index.d.ts.map +0 -1
  658. package/dist/components/view/index.js.map +0 -1
  659. package/dist/components/view/view.d.ts.map +0 -1
  660. package/dist/components/view/view.js.map +0 -1
  661. package/dist/index.d.ts.map +0 -1
  662. package/dist/index.js.map +0 -1
  663. package/dist/lib/cn.d.ts.map +0 -1
  664. package/dist/lib/cn.js.map +0 -1
  665. package/dist/lib/font-context.d.ts.map +0 -1
  666. package/dist/lib/font-context.js.map +0 -1
  667. package/dist/lib/frosted-surface.d.ts.map +0 -1
  668. package/dist/lib/frosted-surface.js.map +0 -1
  669. package/dist/lib/index.d.ts +0 -6
  670. package/dist/lib/index.d.ts.map +0 -1
  671. package/dist/lib/index.js +0 -6
  672. package/dist/lib/index.js.map +0 -1
  673. package/dist/lib/interaction-tokens.d.ts.map +0 -1
  674. package/dist/lib/interaction-tokens.js.map +0 -1
  675. package/dist/lib/portal.d.ts.map +0 -1
  676. package/dist/lib/portal.js.map +0 -1
  677. package/dist/lib/react-native-classname.d.ts.map +0 -1
  678. package/dist/lib/react-native-classname.js.map +0 -1
  679. package/dist/lib/theme-bridge.d.ts.map +0 -1
  680. package/dist/lib/theme-bridge.js.map +0 -1
  681. package/dist/lib/theme-colors.d.ts.map +0 -1
  682. package/dist/lib/theme-colors.js.map +0 -1
  683. package/dist/lib/tv.d.ts.map +0 -1
  684. package/dist/lib/tv.js.map +0 -1
  685. package/dist/lib/visual-tokens.d.ts.map +0 -1
  686. package/dist/lib/visual-tokens.js.map +0 -1
  687. package/dist/vite.d.ts.map +0 -1
  688. package/dist/vite.js.map +0 -1
package/README.md CHANGED
@@ -6,6 +6,11 @@ Beautiful, accessible, themeable components built with [Uniwind](https://uniwind
6
6
 
7
7
  **Requirements:** React 19+, React Native 0.81+, Expo 52+ (if using Expo). Supports React Native Web.
8
8
 
9
+ WhileUI has one renderer: React Native. iOS, Android and React Native Web are all
10
+ production targets — iOS and Android set the interaction baseline. See
11
+ [ROADMAP.md](./ROADMAP.md) for the product boundary and extraction rules, and
12
+ [PLAN.md](./PLAN.md) for the supported stack and production contracts.
13
+
9
14
  ## Installation
10
15
 
11
16
  ```bash
@@ -101,15 +106,15 @@ module.exports = withUniwindConfig({
101
106
 
102
107
  ```tsx
103
108
  import './global.css';
104
- import { PortalHost } from '@thewhileloop/whileui';
109
+ import { MotionProvider, PortalHost } from '@thewhileloop/whileui';
105
110
  import { Button, ButtonText } from '@thewhileloop/whileui';
106
111
 
107
112
  export default function App() {
108
113
  return (
109
- <>
114
+ <MotionProvider>
110
115
  {/* Your app content */}
111
116
  <PortalHost />
112
- </>
117
+ </MotionProvider>
113
118
  );
114
119
  }
115
120
  ```
@@ -209,6 +214,8 @@ function MyScreen() {
209
214
  - **Layout:** `Stack` (vertical), `Row` (horizontal) — both support `gap`, `align`, `justify`
210
215
  - **Auth callbacks:** Auth templates use objects: `onSubmit({ email, password })`, `onSubmit({ firstName, lastName, email, password })`, etc. Copy templates from `apps/showcase/templates/auth/`.
211
216
  - **PortalHost:** Add `<PortalHost />` at app root for Select, Popover, Tooltip, HoverCard.
217
+ - **Motion:** Wrap the root in `<MotionProvider>`; use `useMotionPolicy()` for semantic
218
+ durations, the responsive spring, and reduced-motion behavior.
212
219
  - **Uniwind:** `withUniwindConfig` must wrap metro config. `global.css` at app root, imported in `App.tsx`.
213
220
  - **Reference:** Block props in `packages/ui/src/blocks` (core) and `apps/showcase/templates/` (auth, profile); flow patterns in README "Flow Patterns" section.
214
221
 
@@ -223,7 +230,12 @@ function MyScreen() {
223
230
  | **Pressable** | Themed pressable wrapper |
224
231
  | **Stack** | Vertical flex layout with gap |
225
232
  | **Row** | Horizontal flex layout with gap |
226
- | **Box** | Flexible container with variants |
233
+
234
+ ### Root Providers
235
+
236
+ | Provider | Notes |
237
+ | ------------------ | ------------------------------------------------------------------------ |
238
+ | **MotionProvider** | System reduced motion, explicit preview modes, and deterministic testing |
227
239
 
228
240
  ### Form Controls
229
241
 
@@ -267,6 +279,7 @@ function MyScreen() {
267
279
  | **Tabs** | TabsList, TabsTrigger, TabsContent |
268
280
  | **Accordion** | AccordionItem, AccordionTrigger, Content |
269
281
  | **Collapsible** | CollapsibleTrigger, CollapsibleContent |
282
+ | **Container** | Centred content column with a max width |
270
283
 
271
284
  ### Overlays & Menus
272
285
 
@@ -305,37 +318,37 @@ Copy from `apps/showcase/templates/auth/`:
305
318
 
306
319
  ### Navigation
307
320
 
308
- | Block | Description |
309
- | --------------------- | ------------------------------------------------- |
310
- | **AppShell** | Layout shell with header/footer/bottomNav slots |
311
- | **NavigationSidebar** | Sidebar nav with grouped sections and footer slot |
312
- | **Header** | Top app bar with back/actions |
313
- | **BottomNav** | Tab-style bottom navigation bar |
314
- | **FloatingBottomNav** | Elevated bottom nav with safe area support |
315
- | **TabBar** | Top tab bar with indicator |
316
- | **DrawerMenu** | Drawer with sections and items |
321
+ | Block | Description |
322
+ | --------------------- | ----------------------------------------------- |
323
+ | **AppShell** | Layout shell with header/footer/bottomNav slots |
324
+ | **Header** | Top app bar with back/actions |
325
+ | **BottomNav** | Tab-style bottom navigation bar |
326
+ | **FloatingBottomNav** | Elevated bottom nav with safe area support |
327
+ | **TabBar** | Top tab bar with indicator |
328
+ | **DrawerMenu** | Drawer with sections and items |
317
329
 
318
330
  ### Layout
319
331
 
320
- | Block | Description |
321
- | --------------------------- | ----------------------------------------------------------------------- |
322
- | **ActionBar** | Sticky bottom action row with safe-area padding |
323
- | **ConfirmActionSheet** | Reusable destructive confirmation sheet |
324
- | **Sheet** | Bottom sheet modal with header/content/footer slots |
325
- | **FormModalScreen** | Modal scaffold for forms with loading states |
326
- | **ContentSkeleton** | Page/content placeholder with variants (list, card, generic) |
327
- | **PageSkeleton** | Variant-based page layouts (dashboard, list, settings, card, generic) |
328
- | **ScreenSkeleton** | Header slot/placeholder + PageSkeleton content in one block |
329
- | **ErrorBoundary** | React ErrorBoundary that renders ErrorState by default |
330
- | **EmptyState** | Empty content placeholder |
331
- | **ErrorState** | Error display with retry |
332
- | **LoadingScreen** | Full-screen loading indicator |
333
- | **PullToRefreshScrollView** | Themed ScrollView with RefreshControl (useThemeTokens for colors) |
334
- | **SmartInput** | Keyboard-aware compose input: left/center/right slots, bar/card variant |
335
- | **OnboardingScreen** | Onboarding flow screen |
336
- | **SplashScreen** | Branded splash (fade/scale/slide variants) |
337
- | **MinimalSplash** | Minimal monochrome splash |
338
- | **BrandedSplash** | Splash with brand imagery |
332
+ | Block | Description |
333
+ | --------------------------- | --------------------------------------------------------------------- |
334
+ | **ActionBar** | Sticky bottom action row with safe-area padding |
335
+ | **ConfirmActionSheet** | Reusable destructive confirmation sheet |
336
+ | **Sheet** | Bottom sheet modal with header/content/footer slots |
337
+ | **FormModalScreen** | Modal scaffold for forms with loading states |
338
+ | **ContentSkeleton** | Page/content placeholder with variants (list, card, generic) |
339
+ | **PageSkeleton** | Variant-based page layouts (dashboard, list, settings, card, generic) |
340
+ | **ScreenSkeleton** | Header slot/placeholder + PageSkeleton content in one block |
341
+ | **ErrorBoundary** | React ErrorBoundary that renders ErrorState by default |
342
+ | **EmptyState** | Empty content placeholder |
343
+ | **ErrorState** | Error display with retry |
344
+ | **LoadingScreen** | Full-screen loading indicator |
345
+ | **PullToRefreshScrollView** | Themed ScrollView with RefreshControl (useThemeTokens for colors) |
346
+ | **KeyboardAwareScreen** | One screen-level keyboard policy for bottom-docked controls |
347
+ | **DockedInput** | Safe-area-aware bottom dock that reports its complete height |
348
+ | **SmartInput** | Compose input with slots, variants, and optional rotating examples |
349
+ | **SplashScreen** | Branded splash (fade/scale/slide variants) |
350
+ | **MinimalSplash** | Minimal monochrome splash |
351
+ | **BrandedSplash** | Splash with brand imagery |
339
352
 
340
353
  ### Chat
341
354
 
@@ -362,7 +375,6 @@ Copy from `apps/showcase/templates/profile/`:
362
375
  | -------------------- | ----------------------------------- |
363
376
  | **ListItem** | Title/subtitle row |
364
377
  | **NotificationItem** | Notification row with metadata |
365
- | **SwipeableItem** | Swipe actions list item |
366
378
  | **TimelineFeed** | Vertical feed with connecting lines |
367
379
 
368
380
  ### Commerce
@@ -393,12 +405,19 @@ Copy from `apps/showcase/templates/profile/`:
393
405
  | **DatePickerInline** | Inline calendar for forms or dashboards |
394
406
  | **DateRangePickerModal** | Range selection modal with period marking |
395
407
 
396
- ## Layout Primitives (Stack, Row, Box)
408
+ **Tokens without a renderer.** `@thewhileloop/whileui/tokens` exports the theme
409
+ and visual contracts, the presets, and `deriveThemeColors(base, scheme)` — give it
410
+ the 25 base colours an app defines and it returns all 52, using the same ratios
411
+ as the default presets. Safe in a build script (no React, RN or Uniwind
412
+ imports); `useThemeColors()` uses it too, so a missing `--color-primary-soft`
413
+ derives from the app's own primary instead of falling back to the default palette.
414
+
415
+ ## Layout Primitives (Stack, Row)
397
416
 
398
417
  Use `Stack` for vertical layouts, `Row` for horizontal layouts. Both support `gap`, `align`, and `justify` variants.
399
418
 
400
419
  ```tsx
401
- import { Stack, Row, Box } from '@thewhileloop/whileui';
420
+ import { Stack, Row } from '@thewhileloop/whileui';
402
421
 
403
422
  <Stack gap="lg">
404
423
  <Text>Title</Text>
@@ -419,7 +438,32 @@ import { Stack, Row, Box } from '@thewhileloop/whileui';
419
438
  | align | `'start' \| 'center' \| 'end' \| 'stretch' \| 'baseline'` | Cross-axis alignment |
420
439
  | justify | `'start' \| 'center' \| 'end' \| 'between' \| 'around' \| 'evenly'` | Main-axis alignment |
421
440
 
422
- `Box` provides optional padding and margin variants for consistent spacing.
441
+ ### Container
442
+
443
+ Caps content width and centres it. Phone-first layouts stretch to the viewport, which
444
+ is right at 390px and wrong at 1600px — line lengths become unreadable and related
445
+ controls drift apart.
446
+
447
+ ```tsx
448
+ <Container size="lg">{children}</Container>
449
+ ```
450
+
451
+ | Prop | Type | Default | Notes |
452
+ | ----------- | -------------------------------------- | ------- | --------------------------- |
453
+ | `size` | `sm` \| `md` \| `lg` \| `xl` \| `full` | `md` | `sm` forms, `lg` dashboards |
454
+ | `fill` | `boolean` | `false` | `flex-1`, for a screen root |
455
+ | `className` | `string` | — | Merged after the variant |
456
+
457
+ No platform branch, and none is needed: every size is wider than any phone, so on iOS
458
+ and Android the cap never engages and it renders as a plain full-width `View`. The same
459
+ component is a no-op on native and the whole fix on desktop.
460
+
461
+ For a scroll view, put the column on the content container so the scrollbar stays at
462
+ the window edge:
463
+
464
+ ```tsx
465
+ <ScrollView contentContainerClassName="w-full max-w-5xl self-center" />
466
+ ```
423
467
 
424
468
  ## Full-Screen Composition
425
469
 
@@ -548,7 +592,7 @@ The WhileUI token contract is strict for cross-app reuse. Define these in **ever
548
592
  - Required core tokens: `background`, `foreground`, `card`, `card-foreground`, `popover`, `popover-foreground`, `primary`, `primary-foreground`, `secondary`, `secondary-foreground`, `muted`, `muted-foreground`, `accent`, `accent-foreground`, `destructive`, `destructive-foreground`, `border`, `input`, `ring`
549
593
  - Optional status tokens: `success`, `success-foreground`, `warning`, `warning-foreground`, `info`, `info-foreground`
550
594
  - Optional effect tokens: `overlay`, `overlay-strong`, `surface-elevated`, `surface-border`, `surface-highlight`, `surface-translucent`, `surface-translucent-border`, `state-hover`, `state-pressed`, `state-disabled`
551
- - Optional interaction/motion tokens: `--ui-press-opacity`, `--ui-press-opacity-strong`, `--ui-disabled-opacity`, `--ui-disabled-opacity-soft`, `--ui-disabled-opacity-subtle`, `--ui-inactive-opacity`, `--ui-motion-fast`, `--ui-motion-normal`, `--ui-motion-slow`, `--ui-drawer-open-duration`, `--ui-drawer-close-duration`, `--ui-blur-intensity-subtle`, `--ui-blur-intensity-medium`, `--ui-blur-intensity-strong`, `--ui-blur-saturation-pct`, `--ui-frosted-highlight-height`, `--ui-frosted-backdrop-blur-intensity`, `--ui-frosted-backdrop-blur-scale`, `--ui-frosted-android-experimental-blur`, `--ui-drawer-frosted-inset`, `--ui-drawer-frosted-radius`, `--ui-drawer-content-top-padding`
595
+ - Optional interaction/motion tokens: `--ui-press-opacity`, `--ui-press-opacity-strong`, `--ui-disabled-opacity`, `--ui-disabled-opacity-soft`, `--ui-disabled-opacity-subtle`, `--ui-inactive-opacity`, `--ui-motion-fast`, `--ui-motion-normal`, `--ui-motion-slow`, `--ui-motion-spring-damping`, `--ui-motion-spring-stiffness`, `--ui-motion-spring-mass`, `--ui-drawer-open-duration`, `--ui-drawer-close-duration`, `--ui-blur-intensity-subtle`, `--ui-blur-intensity-medium`, `--ui-blur-intensity-strong`, `--ui-blur-saturation-pct`, `--ui-frosted-highlight-height`, `--ui-frosted-backdrop-blur-intensity`, `--ui-frosted-backdrop-blur-scale`, `--ui-frosted-android-tint-alpha-scale`, `--ui-frosted-android-experimental-blur`, `--ui-drawer-frosted-inset`, `--ui-drawer-frosted-radius`, `--ui-drawer-content-top-padding`
552
596
  - Optional scale tokens: spacing (`--spacing`, `--spacing-*`), typography (`--text-*`, `--leading-*`, `--tracking-*`), radius (`--radius-*`), elevation (`--shadow-*`)
553
597
 
554
598
  Minimal contract example:
@@ -608,6 +652,8 @@ Some apps want a frosted or translucent look for floating panels (modals, sheets
608
652
 
609
653
  **Optional:** Add `expo-blur` and register its `BlurView` once at app startup for full frosted blur. For tint-only (no blur), translucent surface tokens are sufficient.
610
654
 
655
+ **Android note:** frosted panels usually need denser tint than iOS/web. WhileUI now scales frosted tint alpha on Android with `--ui-frosted-android-tint-alpha-scale` (default `1.18`). Set it to `1` to match other platforms exactly, or raise it if your Android surfaces still feel washed out.
656
+
611
657
  ```tsx
612
658
  import { BlurView } from 'expo-blur';
613
659
  import { registerFrostedBlurView } from '@thewhileloop/whileui';
@@ -635,6 +681,7 @@ Additional frosted tuning tokens:
635
681
  - `--ui-frosted-highlight-height` (top highlight strip height in px, set `0` to disable hard top sheen)
636
682
  - `--ui-frosted-backdrop-blur-intensity` (default backdrop blur amount)
637
683
  - `--ui-frosted-backdrop-blur-scale` (ratio used when component blur is overridden)
684
+ - `--ui-frosted-android-tint-alpha-scale` (Android-only alpha multiplier applied to frosted tint and backdrop layers)
638
685
  - `--ui-frosted-android-experimental-blur` (`1` enables `expo-blur` Android experimental path)
639
686
  - `--ui-drawer-frosted-inset` (floating inset for frosted drawer shells)
640
687
  - `--ui-drawer-frosted-radius` (drawer corner radius in px)
@@ -678,6 +725,9 @@ WhileUI components also read optional `--ui-*` tokens for deeper control of pres
678
725
  --ui-motion-fast: 160;
679
726
  --ui-motion-normal: 220;
680
727
  --ui-motion-slow: 300;
728
+ --ui-motion-spring-damping: 20;
729
+ --ui-motion-spring-stiffness: 260;
730
+ --ui-motion-spring-mass: 0.8;
681
731
  --ui-drawer-open-duration: 300;
682
732
  --ui-drawer-close-duration: 220;
683
733
  --ui-blur-intensity-subtle: 18;
@@ -687,6 +737,7 @@ WhileUI components also read optional `--ui-*` tokens for deeper control of pres
687
737
  --ui-frosted-highlight-height: 0;
688
738
  --ui-frosted-backdrop-blur-intensity: 14;
689
739
  --ui-frosted-backdrop-blur-scale: 0.55;
740
+ --ui-frosted-android-tint-alpha-scale: 1.22;
690
741
  --ui-frosted-android-experimental-blur: 1;
691
742
  --ui-drawer-frosted-inset: 0;
692
743
  --ui-drawer-frosted-radius: 28;
@@ -700,6 +751,23 @@ For custom components, use:
700
751
  import { useInteractionTokens, withInteractivePressableStyle } from '@thewhileloop/whileui';
701
752
  ```
702
753
 
754
+ Wrap the application in `MotionProvider` to coordinate system reduced motion, explicit
755
+ preview overrides, and deterministic animation-free tests. The provider is optional:
756
+ without it `useMotionPolicy` returns the token defaults with Reanimated following the
757
+ system setting, and `--ui-motion-*` overrides are not read. `reduced` preserves
758
+ non-spatial feedback while asking Reanimated to skip motion; `disabled` also resolves
759
+ semantic durations to zero.
760
+
761
+ ```tsx
762
+ import { MotionProvider, useMotionPolicy } from '@thewhileloop/whileui';
763
+
764
+ <MotionProvider mode="system">{/* application */}</MotionProvider>;
765
+
766
+ const motion = useMotionPolicy();
767
+ motion.durations.normal;
768
+ motion.springs.responsive;
769
+ ```
770
+
703
771
  Optional RN fallback tokens (hex/rgb/hsl/named):
704
772
 
705
773
  ```css
@@ -798,6 +866,33 @@ const adapter: ThemeBridgeAdapter = {
798
866
  const { mode, resolvedTheme, setMode, cycleMode } = useThemeBridge({ adapter });
799
867
  ```
800
868
 
869
+ ## Focus rings
870
+
871
+ Every interactive component draws a themed focus ring on web. It uses `:focus-visible`,
872
+ so it appears for keyboard users and not after a mouse click, and it is driven by the
873
+ `--color-ring` token — restyle it with your theme, not with component overrides.
874
+
875
+ Use the same treatment on your own controls:
876
+
877
+ ```tsx
878
+ import { focusRing, focusRingInset, cn } from '@thewhileloop/whileui';
879
+
880
+ <Pressable className={cn('rounded-full px-4 py-2', focusRing)} onPress={onPress}>
881
+ <Text>Custom control</Text>
882
+ </Pressable>;
883
+ ```
884
+
885
+ | Export | Use for |
886
+ | ---------------- | ------------------------------------------------------------------------------- |
887
+ | `focusRing` | Standalone controls — buttons, inputs, cards, nav items |
888
+ | `focusRingInset` | Controls flush inside a track, where an offset ring would clip (segments, tabs) |
889
+
890
+ **Do not use a bare `outline-none`.** It removes the browser's indicator and leaves
891
+ keyboard users with nothing, which fails WCAG 2.4.7. `focusRing` removes the default and
892
+ supplies a themed replacement in the same class. The one exemption is a visually hidden
893
+ input, where a visible proxy shows the focus instead — `OTPInput` does this with its
894
+ blinking cursor.
895
+
801
896
  ## Tech Stack
802
897
 
803
898
  - **Styling**: [Uniwind](https://uniwind.dev) (free tier) + Tailwind CSS v4
@@ -808,28 +903,57 @@ const { mode, resolvedTheme, setMode, cycleMode } = useThemeBridge({ adapter });
808
903
 
809
904
  # API Reference
810
905
 
906
+ ## Pressable
907
+
908
+ ```tsx
909
+ import { Pressable, Text } from '@thewhileloop/whileui';
910
+
911
+ <Pressable
912
+ accessibilityRole="button"
913
+ feedback="strong"
914
+ disabledFeedback="default"
915
+ loading={false}
916
+ onPress={() => {}}
917
+ >
918
+ <Text>Open</Text>
919
+ </Pressable>;
920
+ ```
921
+
922
+ `Pressable` preserves React Native's event, ref, accessibility, and function-style
923
+ `style` contracts. Feedback changes opacity without changing layout. Native press state
924
+ comes directly from React Native; web adds a motion-policy-aware opacity transition.
925
+
926
+ | Prop | Type | Default | Description |
927
+ | ---------------- | ------------------------------------------- | ----------- | ------------------------------------------ |
928
+ | feedback | `'none' \| 'default' \| 'strong'` | `'none'` | Semantic pressed opacity |
929
+ | disabledFeedback | `'none' \| 'default' \| 'soft' \| 'subtle'` | `'default'` | Semantic unavailable opacity |
930
+ | loading | `boolean` | `false` | Expose busy/disabled state and block input |
931
+ | className | `string` | — | Additional Tailwind classes |
932
+
811
933
  ## Button
812
934
 
813
935
  ```tsx
814
936
  import { Button, ButtonText, ButtonIcon } from '@thewhileloop/whileui';
815
937
 
816
- <Button variant="default" size="default" disabled={false} onPress={() => {}}>
938
+ <Button variant="default" size="default" disabled={false} loading={false} onPress={() => {}}>
817
939
  <ButtonIcon>
818
940
  <Icon />
819
941
  </ButtonIcon>
820
942
  <ButtonText>Click me</ButtonText>
821
- <ButtonIcon position="right">
943
+ {/* Placement is child order — a trailing ButtonIcon renders after the label. */}
944
+ <ButtonIcon>
822
945
  <Icon />
823
946
  </ButtonIcon>
824
947
  </Button>;
825
948
  ```
826
949
 
827
- | Prop | Type | Default | Description |
828
- | --------- | ----------------------------------------------------------------------------- | ----------- | --------------------------- |
829
- | variant | `'default' \| 'destructive' \| 'outline' \| 'secondary' \| 'ghost' \| 'link'` | `'default'` | Button style variant |
830
- | size | `'default' \| 'sm' \| 'lg' \| 'icon'` | `'default'` | Button size |
831
- | disabled | `boolean` | `false` | Disable the button |
832
- | className | `string` | — | Additional Tailwind classes |
950
+ | Prop | Type | Default | Description |
951
+ | --------- | ----------------------------------------------------------------------------- | ----------- | -------------------------------------------------- |
952
+ | variant | `'default' \| 'destructive' \| 'outline' \| 'secondary' \| 'ghost' \| 'link'` | `'default'` | Button style variant |
953
+ | size | `'default' \| 'sm' \| 'lg' \| 'icon'` | `'default'` | Button size |
954
+ | disabled | `boolean` | `false` | Disable the button |
955
+ | loading | `boolean` | `false` | Show a spinner, expose busy state, and block input |
956
+ | className | `string` | — | Additional Tailwind classes |
833
957
 
834
958
  ## Input
835
959
 
@@ -1138,18 +1262,18 @@ import {
1138
1262
 
1139
1263
  `AlertDialogContent` supports the same frosted props as `DialogContent`.
1140
1264
 
1141
- | Prop | Type | Default | Description |
1142
- | ------------- | ------------------------ | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
1143
- | presentation | `'modal' \| 'native'` | `'modal'` | **Native (iOS/Android):** `'modal'` uses `Modal` (with iOS `overFullScreen` to improve stacking). `'native'` uses `Alert.alert` with copy from `AlertDialogTitle`, `AlertDialogDescription`, `AlertDialogCancel`, and `AlertDialogAction` — reliable when another fullscreen `Modal` is already open. **Web:** `'native'` is ignored; the custom `Modal` UI is always used. |
1144
- | frosted | `boolean` | `false` | Same as `DialogContent` |
1145
- | blurIntensity | `number` | — | Same as `DialogContent` |
1146
- | blurTintToken | `'surfaceElevated' \| …` | — | Same as `DialogContent` |
1265
+ | Prop | Type | Default | Description |
1266
+ | ------------- | ---------------------------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
1267
+ | presentation | `'modal' \| 'native' \| 'overlay'` | `'modal'` | **`modal`** — themed card in an RN `Modal` (iOS `overFullScreen`). **`native`** — `Alert.alert` on iOS/Android (system UI); use when a second `Modal` won’t stack; ignored on web. **`overlay`** — same themed card as `modal`, but absolutely positioned **inside the parent view** (no second `Modal`). Nest `<AlertDialog>` under your fullscreen sheet’s root so the confirm matches app styling. **Web:** `'native'` is ignored; `overlay` behaves like `modal`. |
1268
+ | frosted | `boolean` | `false` | Same as `DialogContent` |
1269
+ | blurIntensity | `number` | — | Same as `DialogContent` |
1270
+ | blurTintToken | `'surfaceElevated' \| …` | — | Same as `DialogContent` |
1147
1271
 
1148
1272
  ### React Native: stacked modals
1149
1273
 
1150
- If `AlertDialog` is a **sibling** of another fullscreen `Modal` (e.g. `<><Modal>…</Modal><AlertDialog>…</AlertDialog></>`), iOS often fails to show a second `Modal` on top, or taps feel dead, even though `open` is `true`. Prefer **`presentation="native"`** on `AlertDialogContent` in those flows so the system alert appears above the sheet. Alternatively, render the `AlertDialog` **inside** the visible `Modal` so both layers share one RN modal host.
1274
+ If `AlertDialog` is a **sibling** of another fullscreen `Modal`, iOS often fails to show a second `Modal` on top. Prefer **`presentation="overlay"`** and render `<AlertDialog>` **inside** that `Modal` (themed UI, one native modal host). Alternatively use **`presentation="native"`** for a system `Alert.alert` when themed UI is not required.
1151
1275
 
1152
- **Manual QA (iOS + Android):** Open a fullscreen `Modal`, trigger a delete/confirm that uses `presentation="native"`, confirm the system alert is visible, **Cancel** closes without side effects, **Delete** runs the action handler and dismisses.
1276
+ **Manual QA (iOS + Android):** Fullscreen sheet + `presentation="overlay"` nested in the sheet: themed confirm appears, **Cancel** / **Delete** behave correctly. Optionally repeat with `presentation="native"` for system alert stacking.
1153
1277
 
1154
1278
  ## Checkbox
1155
1279
 
@@ -1384,6 +1508,40 @@ import {
1384
1508
 
1385
1509
  ## Menubar
1386
1510
 
1511
+ ```tsx
1512
+ import {
1513
+ Menubar,
1514
+ MenubarMenu,
1515
+ MenubarTrigger,
1516
+ MenubarContent,
1517
+ MenubarLabel,
1518
+ MenubarItem,
1519
+ MenubarSeparator,
1520
+ } from '@thewhileloop/whileui';
1521
+
1522
+ <Menubar>
1523
+ <MenubarMenu>
1524
+ <MenubarTrigger>
1525
+ <Text className="text-foreground text-sm">File</Text>
1526
+ </MenubarTrigger>
1527
+ <MenubarContent>
1528
+ <MenubarLabel>Project</MenubarLabel>
1529
+ <MenubarItem>
1530
+ <Text className="text-foreground">New Project</Text>
1531
+ </MenubarItem>
1532
+ <MenubarSeparator />
1533
+ <MenubarItem>
1534
+ <Text className="text-foreground">Export</Text>
1535
+ </MenubarItem>
1536
+ </MenubarContent>
1537
+ </MenubarMenu>
1538
+ </Menubar>;
1539
+ ```
1540
+
1541
+ `MenubarLabel` is a non-interactive section heading. It takes a string or elements, and
1542
+ announces as a heading to assistive technology — as do `DropdownMenuLabel` and
1543
+ `ContextMenuLabel`.
1544
+
1387
1545
  `MenubarContent` supports the same frosted props as `PopoverContent` (default blur preset: medium).
1388
1546
 
1389
1547
  ---
@@ -1494,9 +1652,24 @@ import { ActionBar, Button, ButtonText } from '@thewhileloop/whileui';
1494
1652
  </ActionBar>;
1495
1653
  ```
1496
1654
 
1655
+ ## KeyboardAwareScreen and DockedInput
1656
+
1657
+ Use one keyboard-aware root for the screen, then place the composer in a bottom dock. Feed the dock height into the scroll content inset so the last item remains visible.
1658
+
1659
+ ```tsx
1660
+ import { DockedInput, KeyboardAwareScreen, SmartInput } from '@thewhileloop/whileui';
1661
+
1662
+ <KeyboardAwareScreen>
1663
+ <ScrollView contentContainerStyle={{ paddingBottom: inputHeight }} />
1664
+ <DockedInput onHeightChange={setInputHeight}>
1665
+ <SmartInput variant="card" safeArea={false} />
1666
+ </DockedInput>
1667
+ </KeyboardAwareScreen>;
1668
+ ```
1669
+
1497
1670
  ## SmartInput
1498
1671
 
1499
- Keyboard-aware compose input. `variant`: "bar" (sticky bottom) or "card" (floating). Slots: `leftSlot`, `centerSlot` (intent selector), `rightSlot`. `submitBehavior`: "newline" (default) or "submit"/"blurAndSubmit". Forwards ref to `TextInput`.
1672
+ Compose input for use inline or inside `DockedInput`. `variant`: "bar" or "card". Slots: `leftSlot`, `centerSlot` (intent selector), `rightSlot`. `submitBehavior`: "newline" (default) or "submit"/"blurAndSubmit". `placeholderExamples` animates rotating prompts and respects the platform reduced-motion setting. Forwards ref to `TextInput`.
1500
1673
 
1501
1674
  ```tsx
1502
1675
  import { SmartInput, Button, ButtonText } from '@thewhileloop/whileui';
@@ -1504,7 +1677,7 @@ import { SmartInput, Button, ButtonText } from '@thewhileloop/whileui';
1504
1677
  <SmartInput
1505
1678
  value={message}
1506
1679
  onChangeText={setMessage}
1507
- placeholder="Type a message..."
1680
+ placeholderExamples={['Log breakfast', 'Add a 30 minute walk', 'Set weight to 72 kg']}
1508
1681
  leftSlot={
1509
1682
  <Button variant="ghost" size="icon">
1510
1683
  <Icon name="add" />
@@ -1677,27 +1850,12 @@ import {
1677
1850
  | blurIntensity | `number` | medium preset |
1678
1851
  | blurTintToken | `'surfaceElevated' \| 'surfaceTranslucent' \| 'card' \| 'popover'` | `'surfaceTranslucent'` |
1679
1852
 
1680
- ## NavigationSidebar
1681
-
1682
- ```tsx
1683
- import { NavigationSidebar } from '@thewhileloop/whileui';
1684
-
1685
- <NavigationSidebar
1686
- sections={[
1687
- {
1688
- title: 'Workspace',
1689
- items: [
1690
- { key: 'overview', label: 'Overview', icon: <Icon /> },
1691
- { key: 'billing', label: 'Billing', icon: <Icon />, badge: 2 },
1692
- ],
1693
- },
1694
- ]}
1695
- activeKey="overview"
1696
- onSelect={(key) => {}}
1697
- header={<Text>Acme Inc.</Text>}
1698
- footer={<Text className="text-xs text-muted-foreground">v1.0.0</Text>}
1699
- />;
1700
- ```
1853
+ `SheetContent` is a `ScrollView` and accepts its props. It enables nested scrolling and
1854
+ keeps taps on inputs while the keyboard is open (`keyboardShouldPersistTaps="handled"`).
1855
+ Your `contentContainerStyle` is merged after the default padding. Tapping the backdrop
1856
+ closes the sheet; a drag across the backdrop does not, so a missed scroll never dismisses
1857
+ it. There is no drag-to-dismiss: close with the backdrop, Android back, Escape on web or
1858
+ `SheetClose`.
1701
1859
 
1702
1860
  ## Header
1703
1861
 
@@ -1825,11 +1983,17 @@ import { PullToRefreshScrollView } from '@thewhileloop/whileui';
1825
1983
  </PullToRefreshScrollView>;
1826
1984
  ```
1827
1985
 
1828
- | Prop | Type | Description |
1829
- | ------------ | ------------ | ------------------------------------------ |
1830
- | refreshing | `boolean` | Whether refresh is in progress |
1831
- | onRefresh | `() => void` | Called when user pulls to refresh |
1832
- | refreshColor | `string` | Optional hex override; defaults to primary |
1986
+ | Prop | Type | Description |
1987
+ | ------------ | ----------------------------- | --------------------------------------------------------------------------------------------------------------- |
1988
+ | refreshing | `boolean` | Whether refresh is in progress |
1989
+ | onRefresh | `() => void \| Promise<void>` | Called when user pulls to refresh. Not awaited — drive the spinner with `refreshing`, and catch your own errors |
1990
+ | refreshColor | `string` | Optional hex override; defaults to primary |
1991
+
1992
+ The scroll view owns the refresh gesture; don't pass `refreshControl`. It bounces even
1993
+ when content is shorter than the screen, so a short list can still be pulled. Screen
1994
+ reader users get the same refresh as a **Refresh** accessibility action, since they
1995
+ cannot pull. It is ignored while `refreshing` is true, and any `accessibilityActions` you
1996
+ pass are kept.
1833
1997
 
1834
1998
  ## EmptyState
1835
1999
 
@@ -2064,13 +2228,12 @@ Tracked work items for future releases.
2064
2228
 
2065
2229
  - [x] ProductCard, ListItem, NotificationItem, MetricCard, SubscriptionCard, PricingCard
2066
2230
  - [x] AppShell, Chat, FormModalScreen, CheckoutSummary (already had `loading`)
2067
- - [ ] Add `loading` to remaining blocks: Header, BottomNav, DrawerMenu, TimelineFeed, SwipeableItem
2231
+ - [ ] Add `loading` to remaining blocks: Header, BottomNav, DrawerMenu, TimelineFeed
2068
2232
 
2069
2233
  ### Documentation Gaps
2070
2234
 
2071
- - [ ] Add `## API` sections for: Textarea, Toggle, ToggleGroup, Label, Separator, Skeleton, AspectRatio, Collapsible, Text, View, Pressable
2072
- - [ ] Add `## API` sections for blocks: FloatingBottomNav, TabBar, FormModalScreen, ErrorState, LoadingScreen, OnboardingScreen, ListItem, NotificationItem, MetricCard, SmartImage, TimelineFeed
2073
- - [ ] Build `apps/site/` (docs website) with `registry.ts`, `demos.tsx`, `block-demos.tsx`, `props-data.ts`
2235
+ - [ ] Add `## API` sections for: Textarea, Toggle, ToggleGroup, Label, Separator, Skeleton, AspectRatio, Collapsible, Text, View
2236
+ - [ ] Add `## API` sections for blocks: FloatingBottomNav, TabBar, FormModalScreen, ErrorState, LoadingScreen, ListItem, NotificationItem, MetricCard, SmartImage, TimelineFeed
2074
2237
 
2075
2238
  ### Infrastructure
2076
2239
 
@@ -43,7 +43,6 @@ export interface ChatProps {
43
43
  export declare function ChatMessageBubble({ message, contentClassName, }: {
44
44
  message: ChatMessage;
45
45
  contentClassName?: string;
46
- }): import("react/jsx-runtime").JSX.Element;
47
- export declare function ChatSuggestions({ suggestions, onSelect, className }: ChatSuggestionsProps): import("react/jsx-runtime").JSX.Element;
48
- export declare function Chat({ messages, value, onChangeText, onSend, placeholder, suggestions, onSuggestionPress, leftSlot, rightSlot, loading, header, emptyTitle, emptyDescription, exampleMessage, renderMessage, loadingIndicator, inputSafeArea, keyboardVerticalOffset, className, messagesClassName, }: ChatProps): import("react/jsx-runtime").JSX.Element;
49
- //# sourceMappingURL=chat.d.ts.map
46
+ }): React.JSX.Element;
47
+ export declare function ChatSuggestions({ suggestions, onSelect, className }: ChatSuggestionsProps): React.JSX.Element;
48
+ export declare function Chat({ messages, value, onChangeText, onSend, placeholder, suggestions, onSuggestionPress, leftSlot, rightSlot, loading, header, emptyTitle, emptyDescription, exampleMessage, renderMessage, loadingIndicator, inputSafeArea, keyboardVerticalOffset, className, messagesClassName, }: ChatProps): React.JSX.Element;