panelui-native 0.71.0 → 0.75.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 (306) hide show
  1. package/README.md +5 -2
  2. package/lib/module/components/accordion/index.js +10 -4
  3. package/lib/module/components/accordion/index.js.map +1 -1
  4. package/lib/module/components/area-chart/index.js +1 -0
  5. package/lib/module/components/area-chart/index.js.map +1 -1
  6. package/lib/module/components/avatar/avatar-group.js +64 -0
  7. package/lib/module/components/avatar/avatar-group.js.map +1 -0
  8. package/lib/module/components/avatar/index.js +84 -2
  9. package/lib/module/components/avatar/index.js.map +1 -1
  10. package/lib/module/components/breadcrumb/index.js +2 -1
  11. package/lib/module/components/breadcrumb/index.js.map +1 -1
  12. package/lib/module/components/button/index.js +7 -5
  13. package/lib/module/components/button/index.js.map +1 -1
  14. package/lib/module/components/carousel/index.js +1 -1
  15. package/lib/module/components/carousel/index.js.map +1 -1
  16. package/lib/module/components/chip/index.js +2 -2
  17. package/lib/module/components/chip/index.js.map +1 -1
  18. package/lib/module/components/code-block/index.js.map +1 -1
  19. package/lib/module/components/collapsible/index.js +5 -1
  20. package/lib/module/components/collapsible/index.js.map +1 -1
  21. package/lib/module/components/color-picker/color-picker-accessibility.js +12 -0
  22. package/lib/module/components/color-picker/color-picker-accessibility.js.map +1 -0
  23. package/lib/module/components/color-picker/index.js +9 -5
  24. package/lib/module/components/color-picker/index.js.map +1 -1
  25. package/lib/module/components/date-time-picker/index.js +11 -3
  26. package/lib/module/components/date-time-picker/index.js.map +1 -1
  27. package/lib/module/components/drawer/index.js +58 -13
  28. package/lib/module/components/drawer/index.js.map +1 -1
  29. package/lib/module/components/fab/index.js +7 -6
  30. package/lib/module/components/fab/index.js.map +1 -1
  31. package/lib/module/components/flow/index.js +1 -1
  32. package/lib/module/components/flow/index.js.map +1 -1
  33. package/lib/module/components/frame/index.js +2 -2
  34. package/lib/module/components/frame/index.js.map +1 -1
  35. package/lib/module/components/grid-item/index.js +2 -2
  36. package/lib/module/components/grid-item/index.js.map +1 -1
  37. package/lib/module/components/heatmap-chart/index.js +1 -0
  38. package/lib/module/components/heatmap-chart/index.js.map +1 -1
  39. package/lib/module/components/hex-chart/index.js +1 -0
  40. package/lib/module/components/hex-chart/index.js.map +1 -1
  41. package/lib/module/components/input/index.js +7 -4
  42. package/lib/module/components/input/index.js.map +1 -1
  43. package/lib/module/components/input/input-content-padding.js +6 -0
  44. package/lib/module/components/input/input-content-padding.js.map +1 -0
  45. package/lib/module/components/input-group/index.js +21 -11
  46. package/lib/module/components/input-group/index.js.map +1 -1
  47. package/lib/module/components/input-group/input-group-measurements.js +60 -0
  48. package/lib/module/components/input-group/input-group-measurements.js.map +1 -0
  49. package/lib/module/components/item/index.js +2 -2
  50. package/lib/module/components/item/index.js.map +1 -1
  51. package/lib/module/components/line-chart/index.js +1 -0
  52. package/lib/module/components/line-chart/index.js.map +1 -1
  53. package/lib/module/components/marker/index.js +2 -2
  54. package/lib/module/components/marker/index.js.map +1 -1
  55. package/lib/module/components/marquee/index.js +9 -12
  56. package/lib/module/components/marquee/index.js.map +1 -1
  57. package/lib/module/components/marquee/marquee-math.js +39 -0
  58. package/lib/module/components/marquee/marquee-math.js.map +1 -0
  59. package/lib/module/components/menu/index.js +11 -3
  60. package/lib/module/components/menu/index.js.map +1 -1
  61. package/lib/module/components/otp-input/index.js +3 -1
  62. package/lib/module/components/otp-input/index.js.map +1 -1
  63. package/lib/module/components/otp-input/otp-input-state.js +7 -0
  64. package/lib/module/components/otp-input/otp-input-state.js.map +1 -0
  65. package/lib/module/components/pagination/index.js +27 -11
  66. package/lib/module/components/pagination/index.js.map +1 -1
  67. package/lib/module/components/panelside/index.js +7 -2
  68. package/lib/module/components/panelside/index.js.map +1 -1
  69. package/lib/module/components/planner/index.js +46 -11
  70. package/lib/module/components/planner/index.js.map +1 -1
  71. package/lib/module/components/planner/planner-today.js +8 -0
  72. package/lib/module/components/planner/planner-today.js.map +1 -0
  73. package/lib/module/components/plot/index.js +113 -53
  74. package/lib/module/components/plot/index.js.map +1 -1
  75. package/lib/module/components/plot/plot-series-registry.js +32 -0
  76. package/lib/module/components/plot/plot-series-registry.js.map +1 -0
  77. package/lib/module/components/post/index.js +4 -4
  78. package/lib/module/components/post/index.js.map +1 -1
  79. package/lib/module/components/radio-group/index.js +2 -1
  80. package/lib/module/components/radio-group/index.js.map +1 -1
  81. package/lib/module/components/radio-group/radio-group-value.js +8 -0
  82. package/lib/module/components/radio-group/radio-group-value.js.map +1 -0
  83. package/lib/module/components/rating/index.js +7 -4
  84. package/lib/module/components/rating/index.js.map +1 -1
  85. package/lib/module/components/rating/rating-inputs.js +15 -0
  86. package/lib/module/components/rating/rating-inputs.js.map +1 -0
  87. package/lib/module/components/search-bar/index.js +331 -0
  88. package/lib/module/components/search-bar/index.js.map +1 -0
  89. package/lib/module/components/search-bar/search-bar-debounce.js +23 -0
  90. package/lib/module/components/search-bar/search-bar-debounce.js.map +1 -0
  91. package/lib/module/components/select/index.js +9 -1
  92. package/lib/module/components/select/index.js.map +1 -1
  93. package/lib/module/components/select/native-select-contract.js +11 -0
  94. package/lib/module/components/select/native-select-contract.js.map +1 -0
  95. package/lib/module/components/split-view/index.js +439 -0
  96. package/lib/module/components/split-view/index.js.map +1 -0
  97. package/lib/module/components/split-view/split-view-math.js +132 -0
  98. package/lib/module/components/split-view/split-view-math.js.map +1 -0
  99. package/lib/module/components/splitter/index.js +433 -0
  100. package/lib/module/components/splitter/index.js.map +1 -0
  101. package/lib/module/components/splitter/splitter-math.js +206 -0
  102. package/lib/module/components/splitter/splitter-math.js.map +1 -0
  103. package/lib/module/components/steps/index.js +16 -5
  104. package/lib/module/components/steps/index.js.map +1 -1
  105. package/lib/module/components/steps/steps-trigger.js +6 -0
  106. package/lib/module/components/steps/steps-trigger.js.map +1 -0
  107. package/lib/module/components/table/index.js +3 -4
  108. package/lib/module/components/table/index.js.map +1 -1
  109. package/lib/module/components/tag-input/index.js +15 -10
  110. package/lib/module/components/tag-input/index.js.map +1 -1
  111. package/lib/module/components/tag-input/tag-input-state.js +14 -0
  112. package/lib/module/components/tag-input/tag-input-state.js.map +1 -0
  113. package/lib/module/components/textarea/index.js +9 -4
  114. package/lib/module/components/textarea/index.js.map +1 -1
  115. package/lib/module/components/textarea/textarea-disabled.js +6 -0
  116. package/lib/module/components/textarea/textarea-disabled.js.map +1 -0
  117. package/lib/module/components/timeline/index.js +352 -47
  118. package/lib/module/components/timeline/index.js.map +1 -1
  119. package/lib/module/components/timeline/timeline-geometry.js +11 -0
  120. package/lib/module/components/timeline/timeline-geometry.js.map +1 -0
  121. package/lib/module/components/toast/index.js +18 -1
  122. package/lib/module/components/toast/index.js.map +1 -1
  123. package/lib/module/components/toast/toast-store.js +36 -4
  124. package/lib/module/components/toast/toast-store.js.map +1 -1
  125. package/lib/module/components/toggle-button/index.js +1 -1
  126. package/lib/module/components/toggle-button/index.js.map +1 -1
  127. package/lib/module/components/tour/index.js +4 -2
  128. package/lib/module/components/tour/index.js.map +1 -1
  129. package/lib/module/components/tour/tour-card-measurement.js +24 -0
  130. package/lib/module/components/tour/tour-card-measurement.js.map +1 -0
  131. package/lib/module/components/tree/index.js +13 -8
  132. package/lib/module/components/tree/index.js.map +1 -1
  133. package/lib/module/hooks/use-keyboard-avoidance.js.map +1 -1
  134. package/lib/module/index.js +3 -0
  135. package/lib/module/index.js.map +1 -1
  136. package/lib/module/utils/chart.js +50 -7
  137. package/lib/module/utils/chart.js.map +1 -1
  138. package/lib/typescript/src/components/accordion/index.d.ts +2 -2
  139. package/lib/typescript/src/components/accordion/index.d.ts.map +1 -1
  140. package/lib/typescript/src/components/area-chart/index.d.ts.map +1 -1
  141. package/lib/typescript/src/components/avatar/avatar-group.d.ts +46 -0
  142. package/lib/typescript/src/components/avatar/avatar-group.d.ts.map +1 -0
  143. package/lib/typescript/src/components/avatar/index.d.ts +23 -1
  144. package/lib/typescript/src/components/avatar/index.d.ts.map +1 -1
  145. package/lib/typescript/src/components/breadcrumb/index.d.ts.map +1 -1
  146. package/lib/typescript/src/components/button/index.d.ts.map +1 -1
  147. package/lib/typescript/src/components/code-block/index.d.ts +3 -3
  148. package/lib/typescript/src/components/code-block/index.d.ts.map +1 -1
  149. package/lib/typescript/src/components/collapsible/index.d.ts +2 -2
  150. package/lib/typescript/src/components/collapsible/index.d.ts.map +1 -1
  151. package/lib/typescript/src/components/color-picker/color-picker-accessibility.d.ts +8 -0
  152. package/lib/typescript/src/components/color-picker/color-picker-accessibility.d.ts.map +1 -0
  153. package/lib/typescript/src/components/color-picker/index.d.ts.map +1 -1
  154. package/lib/typescript/src/components/date-time-picker/index.d.ts.map +1 -1
  155. package/lib/typescript/src/components/drawer/index.d.ts.map +1 -1
  156. package/lib/typescript/src/components/fab/index.d.ts +4 -2
  157. package/lib/typescript/src/components/fab/index.d.ts.map +1 -1
  158. package/lib/typescript/src/components/heatmap-chart/index.d.ts.map +1 -1
  159. package/lib/typescript/src/components/hex-chart/index.d.ts.map +1 -1
  160. package/lib/typescript/src/components/input/index.d.ts.map +1 -1
  161. package/lib/typescript/src/components/input/input-content-padding.d.ts +2 -0
  162. package/lib/typescript/src/components/input/input-content-padding.d.ts.map +1 -0
  163. package/lib/typescript/src/components/input-group/index.d.ts.map +1 -1
  164. package/lib/typescript/src/components/input-group/input-group-measurements.d.ts +16 -0
  165. package/lib/typescript/src/components/input-group/input-group-measurements.d.ts.map +1 -0
  166. package/lib/typescript/src/components/line-chart/index.d.ts.map +1 -1
  167. package/lib/typescript/src/components/marquee/index.d.ts +1 -1
  168. package/lib/typescript/src/components/marquee/index.d.ts.map +1 -1
  169. package/lib/typescript/src/components/marquee/marquee-math.d.ts +21 -0
  170. package/lib/typescript/src/components/marquee/marquee-math.d.ts.map +1 -0
  171. package/lib/typescript/src/components/menu/index.d.ts +1 -1
  172. package/lib/typescript/src/components/menu/index.d.ts.map +1 -1
  173. package/lib/typescript/src/components/otp-input/index.d.ts.map +1 -1
  174. package/lib/typescript/src/components/otp-input/otp-input-state.d.ts +3 -0
  175. package/lib/typescript/src/components/otp-input/otp-input-state.d.ts.map +1 -0
  176. package/lib/typescript/src/components/pagination/index.d.ts.map +1 -1
  177. package/lib/typescript/src/components/panelside/index.d.ts +1 -1
  178. package/lib/typescript/src/components/panelside/index.d.ts.map +1 -1
  179. package/lib/typescript/src/components/plan/index.d.ts +2 -2
  180. package/lib/typescript/src/components/planner/index.d.ts.map +1 -1
  181. package/lib/typescript/src/components/planner/planner-today.d.ts +2 -0
  182. package/lib/typescript/src/components/planner/planner-today.d.ts.map +1 -0
  183. package/lib/typescript/src/components/plot/index.d.ts +60 -6
  184. package/lib/typescript/src/components/plot/index.d.ts.map +1 -1
  185. package/lib/typescript/src/components/plot/plot-series-registry.d.ts +8 -0
  186. package/lib/typescript/src/components/plot/plot-series-registry.d.ts.map +1 -0
  187. package/lib/typescript/src/components/radio-group/index.d.ts.map +1 -1
  188. package/lib/typescript/src/components/radio-group/radio-group-value.d.ts +2 -0
  189. package/lib/typescript/src/components/radio-group/radio-group-value.d.ts.map +1 -0
  190. package/lib/typescript/src/components/rating/index.d.ts.map +1 -1
  191. package/lib/typescript/src/components/rating/rating-inputs.d.ts +4 -0
  192. package/lib/typescript/src/components/rating/rating-inputs.d.ts.map +1 -0
  193. package/lib/typescript/src/components/search-bar/index.d.ts +216 -0
  194. package/lib/typescript/src/components/search-bar/index.d.ts.map +1 -0
  195. package/lib/typescript/src/components/search-bar/search-bar-debounce.d.ts +7 -0
  196. package/lib/typescript/src/components/search-bar/search-bar-debounce.d.ts.map +1 -0
  197. package/lib/typescript/src/components/select/index.d.ts.map +1 -1
  198. package/lib/typescript/src/components/select/native-select-contract.d.ts +11 -0
  199. package/lib/typescript/src/components/select/native-select-contract.d.ts.map +1 -0
  200. package/lib/typescript/src/components/split-view/index.d.ts +159 -0
  201. package/lib/typescript/src/components/split-view/index.d.ts.map +1 -0
  202. package/lib/typescript/src/components/split-view/split-view-math.d.ts +54 -0
  203. package/lib/typescript/src/components/split-view/split-view-math.d.ts.map +1 -0
  204. package/lib/typescript/src/components/splitter/index.d.ts +78 -0
  205. package/lib/typescript/src/components/splitter/index.d.ts.map +1 -0
  206. package/lib/typescript/src/components/splitter/splitter-math.d.ts +67 -0
  207. package/lib/typescript/src/components/splitter/splitter-math.d.ts.map +1 -0
  208. package/lib/typescript/src/components/steps/index.d.ts +2 -2
  209. package/lib/typescript/src/components/steps/index.d.ts.map +1 -1
  210. package/lib/typescript/src/components/steps/steps-trigger.d.ts +2 -0
  211. package/lib/typescript/src/components/steps/steps-trigger.d.ts.map +1 -0
  212. package/lib/typescript/src/components/tag-input/index.d.ts.map +1 -1
  213. package/lib/typescript/src/components/tag-input/tag-input-state.d.ts +12 -0
  214. package/lib/typescript/src/components/tag-input/tag-input-state.d.ts.map +1 -0
  215. package/lib/typescript/src/components/textarea/index.d.ts.map +1 -1
  216. package/lib/typescript/src/components/textarea/textarea-disabled.d.ts +2 -0
  217. package/lib/typescript/src/components/textarea/textarea-disabled.d.ts.map +1 -0
  218. package/lib/typescript/src/components/timeline/index.d.ts +36 -2
  219. package/lib/typescript/src/components/timeline/index.d.ts.map +1 -1
  220. package/lib/typescript/src/components/timeline/timeline-geometry.d.ts +4 -0
  221. package/lib/typescript/src/components/timeline/timeline-geometry.d.ts.map +1 -0
  222. package/lib/typescript/src/components/toast/index.d.ts.map +1 -1
  223. package/lib/typescript/src/components/toast/toast-store.d.ts +7 -2
  224. package/lib/typescript/src/components/toast/toast-store.d.ts.map +1 -1
  225. package/lib/typescript/src/components/tour/index.d.ts.map +1 -1
  226. package/lib/typescript/src/components/tour/tour-card-measurement.d.ts +14 -0
  227. package/lib/typescript/src/components/tour/tour-card-measurement.d.ts.map +1 -0
  228. package/lib/typescript/src/components/tree/index.d.ts +3 -4
  229. package/lib/typescript/src/components/tree/index.d.ts.map +1 -1
  230. package/lib/typescript/src/hooks/use-keyboard-avoidance.d.ts +2 -2
  231. package/lib/typescript/src/hooks/use-keyboard-avoidance.d.ts.map +1 -1
  232. package/lib/typescript/src/index.d.ts +5 -2
  233. package/lib/typescript/src/index.d.ts.map +1 -1
  234. package/lib/typescript/src/utils/chart.d.ts +28 -3
  235. package/lib/typescript/src/utils/chart.d.ts.map +1 -1
  236. package/package.json +1 -1
  237. package/src/components/accordion/index.tsx +17 -7
  238. package/src/components/area-chart/index.tsx +8 -0
  239. package/src/components/avatar/avatar-group.ts +78 -0
  240. package/src/components/avatar/index.tsx +121 -1
  241. package/src/components/breadcrumb/index.tsx +2 -1
  242. package/src/components/button/index.tsx +3 -2
  243. package/src/components/carousel/index.tsx +1 -1
  244. package/src/components/chip/index.tsx +2 -2
  245. package/src/components/code-block/index.tsx +3 -3
  246. package/src/components/collapsible/index.tsx +13 -4
  247. package/src/components/color-picker/color-picker-accessibility.ts +12 -0
  248. package/src/components/color-picker/index.tsx +30 -10
  249. package/src/components/date-time-picker/index.tsx +11 -3
  250. package/src/components/drawer/index.tsx +42 -14
  251. package/src/components/fab/index.tsx +21 -11
  252. package/src/components/flow/index.tsx +1 -1
  253. package/src/components/frame/index.tsx +2 -2
  254. package/src/components/grid-item/index.tsx +2 -2
  255. package/src/components/heatmap-chart/index.tsx +7 -1
  256. package/src/components/hex-chart/index.tsx +7 -1
  257. package/src/components/input/index.tsx +6 -2
  258. package/src/components/input/input-content-padding.ts +3 -0
  259. package/src/components/input-group/index.tsx +45 -12
  260. package/src/components/input-group/input-group-measurements.ts +98 -0
  261. package/src/components/item/index.tsx +2 -2
  262. package/src/components/line-chart/index.tsx +9 -0
  263. package/src/components/marker/index.tsx +2 -2
  264. package/src/components/marquee/index.tsx +14 -12
  265. package/src/components/marquee/marquee-math.ts +37 -0
  266. package/src/components/menu/index.tsx +11 -3
  267. package/src/components/otp-input/index.tsx +3 -1
  268. package/src/components/otp-input/otp-input-state.ts +7 -0
  269. package/src/components/pagination/index.tsx +26 -13
  270. package/src/components/panelside/index.tsx +7 -2
  271. package/src/components/plan/index.tsx +2 -2
  272. package/src/components/planner/index.tsx +44 -11
  273. package/src/components/planner/planner-today.ts +5 -0
  274. package/src/components/plot/index.tsx +199 -51
  275. package/src/components/plot/plot-series-registry.ts +41 -0
  276. package/src/components/post/index.tsx +4 -4
  277. package/src/components/radio-group/index.tsx +4 -1
  278. package/src/components/radio-group/radio-group-value.ts +9 -0
  279. package/src/components/rating/index.tsx +11 -4
  280. package/src/components/rating/rating-inputs.ts +19 -0
  281. package/src/components/search-bar/index.tsx +441 -0
  282. package/src/components/search-bar/search-bar-debounce.ts +35 -0
  283. package/src/components/select/index.tsx +10 -1
  284. package/src/components/select/native-select-contract.ts +12 -0
  285. package/src/components/split-view/index.tsx +565 -0
  286. package/src/components/split-view/split-view-math.ts +146 -0
  287. package/src/components/splitter/index.tsx +589 -0
  288. package/src/components/splitter/splitter-math.ts +244 -0
  289. package/src/components/steps/index.tsx +35 -9
  290. package/src/components/steps/steps-trigger.ts +6 -0
  291. package/src/components/table/index.tsx +2 -2
  292. package/src/components/tag-input/index.tsx +13 -11
  293. package/src/components/tag-input/tag-input-state.ts +18 -0
  294. package/src/components/textarea/index.tsx +8 -4
  295. package/src/components/textarea/textarea-disabled.ts +6 -0
  296. package/src/components/timeline/index.tsx +405 -46
  297. package/src/components/timeline/timeline-geometry.ts +9 -0
  298. package/src/components/toast/index.tsx +26 -1
  299. package/src/components/toast/toast-store.ts +43 -8
  300. package/src/components/toggle-button/index.tsx +1 -1
  301. package/src/components/tour/index.tsx +11 -3
  302. package/src/components/tour/tour-card-measurement.ts +29 -0
  303. package/src/components/tree/index.tsx +17 -12
  304. package/src/hooks/use-keyboard-avoidance.ts +7 -2
  305. package/src/index.ts +19 -0
  306. package/src/utils/chart.ts +66 -7
@@ -44,11 +44,18 @@ const DEFAULT_DURATION = 4000;
44
44
 
45
45
  let counter = 0;
46
46
 
47
- class ToastStore {
47
+ interface ToastTimer {
48
+ remaining: number;
49
+ startedAt?: number;
50
+ timeout?: ReturnType<typeof setTimeout>;
51
+ }
52
+
53
+ export class ToastStore {
48
54
  private items: ToastItem[] = [];
49
55
  private snapshot: readonly ToastItem[] = this.items;
50
56
  private listeners = new Set<() => void>();
51
- private timers = new Map<string, ReturnType<typeof setTimeout>>();
57
+ private timers = new Map<string, ToastTimer>();
58
+ private timersPaused = false;
52
59
 
53
60
  subscribe = (listener: () => void) => {
54
61
  this.listeners.add(listener);
@@ -69,10 +76,9 @@ class ToastStore {
69
76
 
70
77
  const duration = resolved.duration ?? DEFAULT_DURATION;
71
78
  if (duration > 0) {
72
- this.timers.set(
73
- id,
74
- setTimeout(() => this.hide(id), duration)
75
- );
79
+ const timer = { remaining: duration };
80
+ this.timers.set(id, timer);
81
+ if (!this.timersPaused) this.startTimer(id, timer);
76
82
  }
77
83
 
78
84
  return id;
@@ -81,7 +87,7 @@ class ToastStore {
81
87
  hide = (id: string) => {
82
88
  const timer = this.timers.get(id);
83
89
  if (timer) {
84
- clearTimeout(timer);
90
+ if (timer.timeout !== undefined) clearTimeout(timer.timeout);
85
91
  this.timers.delete(id);
86
92
  }
87
93
  if (!this.items.some((item) => item.id === id)) return;
@@ -90,13 +96,42 @@ class ToastStore {
90
96
  };
91
97
 
92
98
  hideAll = () => {
93
- this.timers.forEach(clearTimeout);
99
+ this.timers.forEach((timer) => {
100
+ if (timer.timeout !== undefined) clearTimeout(timer.timeout);
101
+ });
94
102
  this.timers.clear();
95
103
  if (this.items.length === 0) return;
96
104
  this.items = [];
97
105
  this.emit();
98
106
  };
99
107
 
108
+ /** Pause auto-dismiss countdowns while their viewport is not visible. */
109
+ pauseTimers = () => {
110
+ if (this.timersPaused) return;
111
+ this.timersPaused = true;
112
+ const now = Date.now();
113
+
114
+ this.timers.forEach((timer) => {
115
+ if (timer.timeout === undefined || timer.startedAt === undefined) return;
116
+ clearTimeout(timer.timeout);
117
+ timer.remaining = Math.max(0, timer.remaining - (now - timer.startedAt));
118
+ delete timer.timeout;
119
+ delete timer.startedAt;
120
+ });
121
+ };
122
+
123
+ /** Resume each auto-dismiss countdown from its remaining visible time. */
124
+ resumeTimers = () => {
125
+ if (!this.timersPaused) return;
126
+ this.timersPaused = false;
127
+ this.timers.forEach((timer, id) => this.startTimer(id, timer));
128
+ };
129
+
130
+ private startTimer(id: string, timer: ToastTimer) {
131
+ timer.startedAt = Date.now();
132
+ timer.timeout = setTimeout(() => this.hide(id), timer.remaining);
133
+ }
134
+
100
135
  private emit() {
101
136
  this.snapshot = this.items;
102
137
  this.listeners.forEach((listener) => listener());
@@ -333,6 +333,7 @@ const ToggleButtonRoot = forwardRef<View, ToggleButtonProps>(
333
333
  <IconColorProvider color={typeof tint === 'string' ? tint : undefined}>
334
334
  <AnimatedPressable
335
335
  ref={ref}
336
+ {...props}
336
337
  accessibilityRole="button"
337
338
  // `checked` is what a screen reader reads out as "on"/"off"; the
338
339
  // selected state is the entire point of this control, so it is
@@ -345,7 +346,6 @@ const ToggleButtonRoot = forwardRef<View, ToggleButtonProps>(
345
346
  slots.root({ className }),
346
347
  selected ? selectedClassName : unselectedClassName
347
348
  )}
348
- {...props}
349
349
  >
350
350
  {textChildren(children, (text) => (
351
351
  <Text className={slots.label({ className: labelClassName })}>
@@ -74,6 +74,11 @@ import { Portal } from '../../primitives/portal';
74
74
  import { Text } from '../../primitives/text';
75
75
  import { cn } from '../../utils/cn';
76
76
  import { Button } from '../button';
77
+ import {
78
+ currentTourCardHeight,
79
+ nextTourCardMeasurement,
80
+ type TourCardMeasurement,
81
+ } from './tour-card-measurement';
77
82
 
78
83
  const AnimatedPath = Animated.createAnimatedComponent(Path);
79
84
 
@@ -466,7 +471,10 @@ function TourOverlay({
466
471
  const insets = useSafeAreaInsets();
467
472
  const reducedMotion = useReducedMotion();
468
473
  const [spot, setSpot] = useState<(Rect & { radius: number }) | null>(null);
469
- const [cardHeight, setCardHeight] = useState<number | null>(null);
474
+ const [cardMeasurement, setCardMeasurement] = useState<TourCardMeasurement | null>(
475
+ null
476
+ );
477
+ const cardHeight = currentTourCardHeight(active, cardMeasurement);
470
478
 
471
479
  const stepPadding = active?.padding ?? padding;
472
480
  const stepRadius = active?.radius ?? radius;
@@ -570,8 +578,8 @@ function TourOverlay({
570
578
 
571
579
  const onCardLayout = (event: LayoutChangeEvent) => {
572
580
  const measured = event.nativeEvent.layout.height;
573
- setCardHeight((current) =>
574
- current !== null && Math.abs(current - measured) < 1 ? current : measured
581
+ setCardMeasurement((current) =>
582
+ nextTourCardMeasurement(active, measured, current)
575
583
  );
576
584
  };
577
585
 
@@ -0,0 +1,29 @@
1
+ /** A measured Tour card height tied to the step that produced it. */
2
+ export interface TourCardMeasurement {
3
+ owner: object | undefined;
4
+ height: number;
5
+ }
6
+
7
+ /**
8
+ * Returns a height only when it belongs to the step currently being rendered.
9
+ * A previous step can be much taller or shorter, so reusing its height would
10
+ * place the next card incorrectly before that card's first layout pass.
11
+ */
12
+ export function currentTourCardHeight(
13
+ owner: object | undefined,
14
+ measurement: TourCardMeasurement | null
15
+ ): number | null {
16
+ return measurement && measurement.owner === owner ? measurement.height : null;
17
+ }
18
+
19
+ /** Stores a card height without churning state for sub-pixel layout noise. */
20
+ export function nextTourCardMeasurement(
21
+ owner: object | undefined,
22
+ height: number,
23
+ current: TourCardMeasurement | null
24
+ ): TourCardMeasurement {
25
+ if (current && current.owner === owner && Math.abs(current.height - height) < 1) {
26
+ return current;
27
+ }
28
+ return { owner, height };
29
+ }
@@ -54,7 +54,13 @@ import {
54
54
  useState,
55
55
  type ReactNode,
56
56
  } from 'react';
57
- import { Pressable, View, type Text as RNText, type ViewProps } from 'react-native';
57
+ import {
58
+ Pressable,
59
+ View,
60
+ type PressableProps,
61
+ type Text as RNText,
62
+ type ViewProps,
63
+ } from 'react-native';
58
64
  import Animated, {
59
65
  LinearTransition,
60
66
  useAnimatedStyle,
@@ -353,10 +359,9 @@ const TreeItem = forwardRef<View, TreeItemProps>(
353
359
  );
354
360
  TreeItem.displayName = 'Tree.Item';
355
361
 
356
- export interface TreeTriggerProps extends ViewProps {
362
+ /** Pressable props are forwarded; `onPress` runs after the tree updates its state. */
363
+ export interface TreeTriggerProps extends Omit<PressableProps, 'children'> {
357
364
  className?: string;
358
- /** Runs after the press has been handled, with the tree's own state already updated. */
359
- onPress?: () => void;
360
365
  children?: ReactNode;
361
366
  }
362
367
 
@@ -370,20 +375,20 @@ export interface TreeTriggerProps extends ViewProps {
370
375
  * actually survives to the user.
371
376
  */
372
377
  const TreeTrigger = forwardRef<View, TreeTriggerProps>(
373
- ({ className, onPress, children, ...props }, ref) => {
378
+ ({ className, onPress, disabled = false, children, ...props }, ref) => {
374
379
  const { toggleExpanded, select, selectionMode, expandOnPress, size } =
375
380
  useTree('Tree.Trigger');
376
381
  const { value, level, isExpanded, isSelected, isDisabled, isBranch } =
377
382
  useTreeItem('Tree.Trigger');
378
- const { trigger } = treeVariants({ size, isSelected, isDisabled });
379
-
380
383
  const accentForeground = useCSSVariable('--color-accent-foreground');
381
384
  const selectedColor = typeof accentForeground === 'string' ? accentForeground : undefined;
382
385
 
383
- const handlePress = () => {
386
+ const triggerDisabled = Boolean(isDisabled || disabled);
387
+ const { trigger } = treeVariants({ size, isSelected, isDisabled: triggerDisabled });
388
+ const handlePress: NonNullable<PressableProps['onPress']> = (event) => {
384
389
  if (isBranch && expandOnPress) toggleExpanded(value);
385
390
  select(value);
386
- onPress?.();
391
+ onPress?.(event);
387
392
  };
388
393
 
389
394
  return (
@@ -393,13 +398,13 @@ const TreeTrigger = forwardRef<View, TreeTriggerProps>(
393
398
  accessibilityState={{
394
399
  expanded: isBranch ? isExpanded : undefined,
395
400
  selected: selectionMode === 'none' ? undefined : isSelected,
396
- disabled: isDisabled,
401
+ disabled: triggerDisabled,
397
402
  }}
398
403
  aria-level={level + 1}
399
- disabled={isDisabled}
400
- onPress={handlePress}
404
+ disabled={triggerDisabled}
401
405
  className={trigger({ className })}
402
406
  {...props}
407
+ onPress={handlePress}
403
408
  >
404
409
  <IconColorProvider color={isSelected ? selectedColor : undefined}>
405
410
  {children}
@@ -45,7 +45,12 @@
45
45
  * ```
46
46
  */
47
47
  import { useCallback, useEffect, useState } from 'react';
48
- import { useWindowDimensions, type LayoutChangeEvent, type View } from 'react-native';
48
+ import {
49
+ useWindowDimensions,
50
+ type LayoutChangeEvent,
51
+ type View,
52
+ type ViewStyle,
53
+ } from 'react-native';
49
54
  import {
50
55
  measure,
51
56
  runOnJS,
@@ -106,7 +111,7 @@ export interface UseKeyboardAvoidanceResult {
106
111
  /** Attach to the same element, so a re-layout at rest cannot leave it offset. */
107
112
  onLayout: (event: LayoutChangeEvent) => void;
108
113
  /** Apply to the same element. */
109
- animatedStyle: ReturnType<typeof useAnimatedStyle>;
114
+ animatedStyle: ReturnType<typeof useAnimatedStyle<ViewStyle>>;
110
115
  }
111
116
 
112
117
  type KeyboardHeightHook = () => SharedValue<number>;
package/src/index.ts CHANGED
@@ -61,6 +61,7 @@ export {
61
61
  Avatar,
62
62
  type AvatarProps,
63
63
  type AvatarBadgeProps,
64
+ type AvatarGroupProps,
64
65
  } from './components/avatar';
65
66
  export {
66
67
  Attachment,
@@ -522,6 +523,7 @@ export {
522
523
  type NumberInputProps,
523
524
  } from './components/number-input';
524
525
  export { OtpInput, type OtpInputProps } from './components/otp-input';
526
+ export { SearchBar, type SearchBarProps } from './components/search-bar';
525
527
  export {
526
528
  Panelside,
527
529
  usePanelside,
@@ -1031,6 +1033,22 @@ export {
1031
1033
  type SortableReorderDetails,
1032
1034
  } from './components/sortable';
1033
1035
  export { Spinner, type SpinnerProps } from './components/spinner';
1036
+ export {
1037
+ Splitter,
1038
+ type SplitterProps,
1039
+ type SplitterPanelProps,
1040
+ type SplitterHandleProps,
1041
+ type SplitterOrientation,
1042
+ type SplitterConstraint,
1043
+ } from './components/splitter';
1044
+ export {
1045
+ SplitView,
1046
+ useSplitView,
1047
+ type SplitViewProps,
1048
+ type SplitViewPaneProps,
1049
+ type SplitViewDragAreaProps,
1050
+ type SplitViewHandleProps,
1051
+ } from './components/split-view';
1034
1052
  export {
1035
1053
  Steps,
1036
1054
  type StepsProps,
@@ -1068,6 +1086,7 @@ export {
1068
1086
  type TimelineStatProps,
1069
1087
  type TimelineVariant,
1070
1088
  type TimelineTone,
1089
+ type TimelineOrientation,
1071
1090
  } from './components/timeline';
1072
1091
  export {
1073
1092
  Toast,
@@ -264,6 +264,50 @@ export function yOf(value: number, plot: Plot, min: number, max: number): number
264
264
  return plot.top + plot.height - ((value - min) / span) * plot.height;
265
265
  }
266
266
 
267
+ /**
268
+ * Widens a domain out to round numbers.
269
+ *
270
+ * An axis derived from the data ends wherever the data happened to end, so it
271
+ * gets labelled 34,650 — a number that is true and that nobody was looking for.
272
+ * Rounding the ends out to a step of 1, 2 or 5 times a power of ten gives the
273
+ * axis labels somebody can actually read a value off, and it can only ever add
274
+ * room, never crop.
275
+ *
276
+ * Zero survives: any step divides it, so a baseline pinned there stays there.
277
+ */
278
+ export function niceDomain(
279
+ min: number,
280
+ max: number,
281
+ ticks = 5
282
+ ): [number, number] {
283
+ if (!Number.isFinite(min) || !Number.isFinite(max) || max <= min) {
284
+ return [min, max];
285
+ }
286
+
287
+ const rough = (max - min) / Math.max(1, ticks);
288
+ const magnitude = 10 ** Math.floor(Math.log10(rough));
289
+ const error = rough / magnitude;
290
+
291
+ /*
292
+ * 1, 2, 5 or 10 times the magnitude — the steps a reader can divide in their
293
+ * head. The thresholds are geometric means rather than the steps themselves,
294
+ * so each candidate wins over the span it is genuinely closest to. Rounding at
295
+ * the steps instead pushes anything above 5 up to a full decade, which turns a
296
+ * top of 31,500 into an axis ending at 40,000 and hands a quarter of the plot
297
+ * to empty space.
298
+ */
299
+ const step =
300
+ (error >= Math.sqrt(50)
301
+ ? 10
302
+ : error >= Math.sqrt(10)
303
+ ? 5
304
+ : error >= Math.sqrt(2)
305
+ ? 2
306
+ : 1) * magnitude;
307
+
308
+ return [Math.floor(min / step) * step, Math.ceil(max / step) * step];
309
+ }
310
+
267
311
  /**
268
312
  * A value's x on a *measured* axis, with `min` at the left edge and `max` at
269
313
  * the right.
@@ -356,7 +400,16 @@ export function runsOf(
356
400
  min: number,
357
401
  max: number,
358
402
  /** Baselines to stack each point on top of, for a stacked area. */
359
- baselines?: number[]
403
+ baselines?: number[],
404
+ /**
405
+ * Place points at band centres rather than spreading them edge to edge.
406
+ *
407
+ * A line drawn over columns has to agree with them about where a row sits,
408
+ * and a column owns a slice of the axis rather than a position on it. Spread
409
+ * evenly, the first point lands half a slice left of the bar it describes and
410
+ * every point after it is wrong by the same amount.
411
+ */
412
+ banded?: boolean
360
413
  ): ChartPoint[][] {
361
414
  'worklet';
362
415
  const runs: ChartPoint[][] = [];
@@ -370,7 +423,8 @@ export function runsOf(
370
423
  continue;
371
424
  }
372
425
  const stacked = value + (baselines?.[i] ?? 0);
373
- run.push({ x: xOf(i, values.length, plot), y: yOf(stacked, plot, min, max) });
426
+ const x = banded ? bandOf(i, values.length, plot) : xOf(i, values.length, plot);
427
+ run.push({ x, y: yOf(stacked, plot, min, max) });
374
428
  }
375
429
  if (run.length) runs.push(run);
376
430
  return runs;
@@ -404,7 +458,9 @@ export function linePath(
404
458
  max: number,
405
459
  curve: ChartCurve,
406
460
  loading: boolean,
407
- baselines?: number[]
461
+ baselines?: number[],
462
+ /** Place points at band centres, for a line drawn over columns. */
463
+ banded?: boolean
408
464
  ): string {
409
465
  'worklet';
410
466
  if (loading || plot.width <= 0) {
@@ -413,7 +469,7 @@ export function linePath(
413
469
  const y = plot.top + plot.height / 2;
414
470
  return `M${plot.left},${y} L${plot.left + plot.width},${y}`;
415
471
  }
416
- return runsOf(values, plot, min, max, baselines)
472
+ return runsOf(values, plot, min, max, baselines, banded)
417
473
  .map((run) => segment(run, curve))
418
474
  .join(' ');
419
475
  }
@@ -433,13 +489,15 @@ export function areaPath(
433
489
  max: number,
434
490
  curve: ChartCurve,
435
491
  loading: boolean,
436
- baselines?: number[]
492
+ baselines?: number[],
493
+ /** Place points at band centres, for an area drawn against columns. */
494
+ banded?: boolean
437
495
  ): string {
438
496
  'worklet';
439
497
  if (loading || plot.width <= 0) return '';
440
498
 
441
499
  const bottom = plot.top + plot.height;
442
- const runs = runsOf(values, plot, min, max, baselines);
500
+ const runs = runsOf(values, plot, min, max, baselines, banded);
443
501
 
444
502
  if (!baselines) {
445
503
  return runs
@@ -460,7 +518,8 @@ export function areaPath(
460
518
  plot,
461
519
  min,
462
520
  max,
463
- baselines
521
+ baselines,
522
+ banded
464
523
  );
465
524
 
466
525
  return runs