panelui-native 0.25.0 → 0.30.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 (242) hide show
  1. package/README.md +18 -1
  2. package/lib/module/components/accordion/index.js +8 -8
  3. package/lib/module/components/accordion/index.js.map +1 -1
  4. package/lib/module/components/alert/index.js +2 -2
  5. package/lib/module/components/alert/index.js.map +1 -1
  6. package/lib/module/components/area-chart/index.js +182 -50
  7. package/lib/module/components/area-chart/index.js.map +1 -1
  8. package/lib/module/components/attachment/index.js +2 -1
  9. package/lib/module/components/attachment/index.js.map +1 -1
  10. package/lib/module/components/avatar/index.js +3 -3
  11. package/lib/module/components/avatar/index.js.map +1 -1
  12. package/lib/module/components/badge/index.js +4 -4
  13. package/lib/module/components/badge/index.js.map +1 -1
  14. package/lib/module/components/bar-chart/index.js +197 -56
  15. package/lib/module/components/bar-chart/index.js.map +1 -1
  16. package/lib/module/components/bottom-sheet/index.js +15 -10
  17. package/lib/module/components/bottom-sheet/index.js.map +1 -1
  18. package/lib/module/components/breadcrumb/index.js +6 -6
  19. package/lib/module/components/breadcrumb/index.js.map +1 -1
  20. package/lib/module/components/button/index.js +11 -6
  21. package/lib/module/components/button/index.js.map +1 -1
  22. package/lib/module/components/calendar/index.js +792 -0
  23. package/lib/module/components/calendar/index.js.map +1 -0
  24. package/lib/module/components/carousel/index.js +680 -0
  25. package/lib/module/components/carousel/index.js.map +1 -0
  26. package/lib/module/components/chip/index.js +4 -4
  27. package/lib/module/components/chip/index.js.map +1 -1
  28. package/lib/module/components/code-block/highlight.js +363 -0
  29. package/lib/module/components/code-block/highlight.js.map +1 -0
  30. package/lib/module/components/code-block/index.js +313 -0
  31. package/lib/module/components/code-block/index.js.map +1 -0
  32. package/lib/module/components/date-picker/index.js +165 -0
  33. package/lib/module/components/date-picker/index.js.map +1 -0
  34. package/lib/module/components/dialog/index.js +7 -2
  35. package/lib/module/components/dialog/index.js.map +1 -1
  36. package/lib/module/components/direction/index.js +2 -1
  37. package/lib/module/components/direction/index.js.map +1 -1
  38. package/lib/module/components/empty-state/index.js +2 -2
  39. package/lib/module/components/empty-state/index.js.map +1 -1
  40. package/lib/module/components/field/index.js +5 -5
  41. package/lib/module/components/field/index.js.map +1 -1
  42. package/lib/module/components/flow/index.js +3 -3
  43. package/lib/module/components/flow/index.js.map +1 -1
  44. package/lib/module/components/frame/index.js +5 -5
  45. package/lib/module/components/frame/index.js.map +1 -1
  46. package/lib/module/components/input-group/index.js +3 -2
  47. package/lib/module/components/input-group/index.js.map +1 -1
  48. package/lib/module/components/item/index.js +9 -9
  49. package/lib/module/components/item/index.js.map +1 -1
  50. package/lib/module/components/label/index.js +4 -4
  51. package/lib/module/components/label/index.js.map +1 -1
  52. package/lib/module/components/line-chart/index.js +167 -44
  53. package/lib/module/components/line-chart/index.js.map +1 -1
  54. package/lib/module/components/map/index.js +7 -7
  55. package/lib/module/components/map/index.js.map +1 -1
  56. package/lib/module/components/marker/index.js +3 -3
  57. package/lib/module/components/marker/index.js.map +1 -1
  58. package/lib/module/components/menu/index.js +714 -0
  59. package/lib/module/components/menu/index.js.map +1 -0
  60. package/lib/module/components/message/index.js +7 -7
  61. package/lib/module/components/message/index.js.map +1 -1
  62. package/lib/module/components/message-scroller/index.js +5 -4
  63. package/lib/module/components/message-scroller/index.js.map +1 -1
  64. package/lib/module/components/plan/index.js +296 -0
  65. package/lib/module/components/plan/index.js.map +1 -0
  66. package/lib/module/components/popover/index.js +73 -10
  67. package/lib/module/components/popover/index.js.map +1 -1
  68. package/lib/module/components/radio-group/index.js +15 -10
  69. package/lib/module/components/radio-group/index.js.map +1 -1
  70. package/lib/module/components/reasoning/index.js +244 -0
  71. package/lib/module/components/reasoning/index.js.map +1 -0
  72. package/lib/module/components/section-rail/index.js +4 -4
  73. package/lib/module/components/section-rail/index.js.map +1 -1
  74. package/lib/module/components/select/index.js +10 -4
  75. package/lib/module/components/select/index.js.map +1 -1
  76. package/lib/module/components/sources/index.js +221 -0
  77. package/lib/module/components/sources/index.js.map +1 -0
  78. package/lib/module/components/steps/index.js +4 -4
  79. package/lib/module/components/steps/index.js.map +1 -1
  80. package/lib/module/components/tabs/index.js +7 -7
  81. package/lib/module/components/tabs/index.js.map +1 -1
  82. package/lib/module/components/task/index.js +300 -0
  83. package/lib/module/components/task/index.js.map +1 -0
  84. package/lib/module/components/textarea/index.js +295 -0
  85. package/lib/module/components/textarea/index.js.map +1 -0
  86. package/lib/module/components/timeline/index.js +4 -4
  87. package/lib/module/components/timeline/index.js.map +1 -1
  88. package/lib/module/components/toast/index.js +2 -2
  89. package/lib/module/components/toast/index.js.map +1 -1
  90. package/lib/module/components/toggle-button/index.js +5 -5
  91. package/lib/module/components/toggle-button/index.js.map +1 -1
  92. package/lib/module/components/tooltip/index.js +648 -0
  93. package/lib/module/components/tooltip/index.js.map +1 -0
  94. package/lib/module/components/typography/index.js +2 -2
  95. package/lib/module/components/typography/index.js.map +1 -1
  96. package/lib/module/hooks/index.js +1 -0
  97. package/lib/module/hooks/index.js.map +1 -1
  98. package/lib/module/hooks/use-back-handler.js +37 -0
  99. package/lib/module/hooks/use-back-handler.js.map +1 -0
  100. package/lib/module/icons/index.js +202 -0
  101. package/lib/module/icons/index.js.map +1 -1
  102. package/lib/module/index.js +13 -1
  103. package/lib/module/index.js.map +1 -1
  104. package/lib/module/primitives/collapse.js +112 -0
  105. package/lib/module/primitives/collapse.js.map +1 -0
  106. package/lib/module/primitives/keyboard-avoider.js +2 -1
  107. package/lib/module/primitives/keyboard-avoider.js.map +1 -1
  108. package/lib/module/primitives/text.js +25 -1
  109. package/lib/module/primitives/text.js.map +1 -1
  110. package/lib/module/utils/date.js +386 -0
  111. package/lib/module/utils/date.js.map +1 -0
  112. package/lib/typescript/src/components/accordion/index.d.ts.map +1 -1
  113. package/lib/typescript/src/components/alert/index.d.ts.map +1 -1
  114. package/lib/typescript/src/components/area-chart/index.d.ts +41 -1
  115. package/lib/typescript/src/components/area-chart/index.d.ts.map +1 -1
  116. package/lib/typescript/src/components/attachment/index.d.ts.map +1 -1
  117. package/lib/typescript/src/components/bar-chart/index.d.ts +44 -2
  118. package/lib/typescript/src/components/bar-chart/index.d.ts.map +1 -1
  119. package/lib/typescript/src/components/bottom-sheet/index.d.ts.map +1 -1
  120. package/lib/typescript/src/components/breadcrumb/index.d.ts.map +1 -1
  121. package/lib/typescript/src/components/button/index.d.ts.map +1 -1
  122. package/lib/typescript/src/components/calendar/index.d.ts +173 -0
  123. package/lib/typescript/src/components/calendar/index.d.ts.map +1 -0
  124. package/lib/typescript/src/components/carousel/index.d.ts +179 -0
  125. package/lib/typescript/src/components/carousel/index.d.ts.map +1 -0
  126. package/lib/typescript/src/components/chip/index.d.ts.map +1 -1
  127. package/lib/typescript/src/components/code-block/highlight.d.ts +39 -0
  128. package/lib/typescript/src/components/code-block/highlight.d.ts.map +1 -0
  129. package/lib/typescript/src/components/code-block/index.d.ts +113 -0
  130. package/lib/typescript/src/components/code-block/index.d.ts.map +1 -0
  131. package/lib/typescript/src/components/date-picker/index.d.ts +97 -0
  132. package/lib/typescript/src/components/date-picker/index.d.ts.map +1 -0
  133. package/lib/typescript/src/components/dialog/index.d.ts.map +1 -1
  134. package/lib/typescript/src/components/direction/index.d.ts.map +1 -1
  135. package/lib/typescript/src/components/empty-state/index.d.ts.map +1 -1
  136. package/lib/typescript/src/components/field/index.d.ts.map +1 -1
  137. package/lib/typescript/src/components/frame/index.d.ts.map +1 -1
  138. package/lib/typescript/src/components/input-group/index.d.ts.map +1 -1
  139. package/lib/typescript/src/components/item/index.d.ts.map +1 -1
  140. package/lib/typescript/src/components/label/index.d.ts.map +1 -1
  141. package/lib/typescript/src/components/line-chart/index.d.ts +41 -2
  142. package/lib/typescript/src/components/line-chart/index.d.ts.map +1 -1
  143. package/lib/typescript/src/components/map/index.d.ts.map +1 -1
  144. package/lib/typescript/src/components/marker/index.d.ts.map +1 -1
  145. package/lib/typescript/src/components/menu/index.d.ts +261 -0
  146. package/lib/typescript/src/components/menu/index.d.ts.map +1 -0
  147. package/lib/typescript/src/components/message/index.d.ts.map +1 -1
  148. package/lib/typescript/src/components/message-scroller/index.d.ts.map +1 -1
  149. package/lib/typescript/src/components/plan/index.d.ts +127 -0
  150. package/lib/typescript/src/components/plan/index.d.ts.map +1 -0
  151. package/lib/typescript/src/components/popover/index.d.ts +35 -1
  152. package/lib/typescript/src/components/popover/index.d.ts.map +1 -1
  153. package/lib/typescript/src/components/radio-group/index.d.ts.map +1 -1
  154. package/lib/typescript/src/components/reasoning/index.d.ts +97 -0
  155. package/lib/typescript/src/components/reasoning/index.d.ts.map +1 -0
  156. package/lib/typescript/src/components/select/index.d.ts.map +1 -1
  157. package/lib/typescript/src/components/sources/index.d.ts +85 -0
  158. package/lib/typescript/src/components/sources/index.d.ts.map +1 -0
  159. package/lib/typescript/src/components/steps/index.d.ts.map +1 -1
  160. package/lib/typescript/src/components/tabs/index.d.ts.map +1 -1
  161. package/lib/typescript/src/components/task/index.d.ts +103 -0
  162. package/lib/typescript/src/components/task/index.d.ts.map +1 -0
  163. package/lib/typescript/src/components/textarea/index.d.ts +175 -0
  164. package/lib/typescript/src/components/textarea/index.d.ts.map +1 -0
  165. package/lib/typescript/src/components/timeline/index.d.ts.map +1 -1
  166. package/lib/typescript/src/components/toast/index.d.ts.map +1 -1
  167. package/lib/typescript/src/components/toggle-button/index.d.ts.map +1 -1
  168. package/lib/typescript/src/components/tooltip/index.d.ts +180 -0
  169. package/lib/typescript/src/components/tooltip/index.d.ts.map +1 -0
  170. package/lib/typescript/src/components/typography/index.d.ts.map +1 -1
  171. package/lib/typescript/src/hooks/index.d.ts +1 -0
  172. package/lib/typescript/src/hooks/index.d.ts.map +1 -1
  173. package/lib/typescript/src/hooks/use-back-handler.d.ts +19 -0
  174. package/lib/typescript/src/hooks/use-back-handler.d.ts.map +1 -0
  175. package/lib/typescript/src/icons/index.d.ts +17 -0
  176. package/lib/typescript/src/icons/index.d.ts.map +1 -1
  177. package/lib/typescript/src/index.d.ts +16 -4
  178. package/lib/typescript/src/index.d.ts.map +1 -1
  179. package/lib/typescript/src/primitives/collapse.d.ts +42 -0
  180. package/lib/typescript/src/primitives/collapse.d.ts.map +1 -0
  181. package/lib/typescript/src/primitives/keyboard-avoider.d.ts.map +1 -1
  182. package/lib/typescript/src/primitives/text.d.ts +20 -0
  183. package/lib/typescript/src/primitives/text.d.ts.map +1 -1
  184. package/lib/typescript/src/utils/date.d.ts +116 -0
  185. package/lib/typescript/src/utils/date.d.ts.map +1 -0
  186. package/package.json +1 -1
  187. package/src/components/accordion/index.tsx +8 -12
  188. package/src/components/alert/index.tsx +2 -2
  189. package/src/components/area-chart/index.tsx +208 -55
  190. package/src/components/attachment/index.tsx +2 -2
  191. package/src/components/avatar/index.tsx +3 -3
  192. package/src/components/badge/index.tsx +6 -6
  193. package/src/components/bar-chart/index.tsx +214 -54
  194. package/src/components/bottom-sheet/index.tsx +17 -16
  195. package/src/components/breadcrumb/index.tsx +6 -8
  196. package/src/components/button/index.tsx +12 -8
  197. package/src/components/calendar/index.tsx +970 -0
  198. package/src/components/carousel/index.tsx +788 -0
  199. package/src/components/chip/index.tsx +4 -6
  200. package/src/components/code-block/highlight.ts +278 -0
  201. package/src/components/code-block/index.tsx +341 -0
  202. package/src/components/date-picker/index.tsx +255 -0
  203. package/src/components/dialog/index.tsx +7 -2
  204. package/src/components/direction/index.tsx +2 -1
  205. package/src/components/empty-state/index.tsx +2 -2
  206. package/src/components/field/index.tsx +3 -5
  207. package/src/components/flow/index.tsx +3 -3
  208. package/src/components/frame/index.tsx +5 -7
  209. package/src/components/input-group/index.tsx +3 -2
  210. package/src/components/item/index.tsx +9 -9
  211. package/src/components/label/index.tsx +2 -2
  212. package/src/components/line-chart/index.tsx +189 -50
  213. package/src/components/map/index.tsx +7 -9
  214. package/src/components/marker/index.tsx +3 -3
  215. package/src/components/menu/index.tsx +812 -0
  216. package/src/components/message/index.tsx +7 -7
  217. package/src/components/message-scroller/index.tsx +5 -4
  218. package/src/components/plan/index.tsx +325 -0
  219. package/src/components/popover/index.tsx +111 -8
  220. package/src/components/radio-group/index.tsx +13 -4
  221. package/src/components/reasoning/index.tsx +297 -0
  222. package/src/components/section-rail/index.tsx +4 -4
  223. package/src/components/select/index.tsx +10 -4
  224. package/src/components/sources/index.tsx +278 -0
  225. package/src/components/steps/index.tsx +4 -4
  226. package/src/components/tabs/index.tsx +7 -9
  227. package/src/components/task/index.tsx +329 -0
  228. package/src/components/textarea/index.tsx +381 -0
  229. package/src/components/timeline/index.tsx +4 -4
  230. package/src/components/toast/index.tsx +2 -2
  231. package/src/components/toggle-button/index.tsx +5 -7
  232. package/src/components/tooltip/index.tsx +793 -0
  233. package/src/components/typography/index.tsx +2 -2
  234. package/src/hooks/index.ts +1 -0
  235. package/src/hooks/use-back-handler.ts +37 -0
  236. package/src/icons/index.tsx +147 -0
  237. package/src/index.ts +116 -0
  238. package/src/primitives/collapse.tsx +128 -0
  239. package/src/primitives/keyboard-avoider.tsx +2 -1
  240. package/src/primitives/text.tsx +28 -1
  241. package/src/utils/date.ts +446 -0
  242. package/theme.css +112 -0
@@ -25,7 +25,7 @@
25
25
  import { Children, forwardRef, type ReactNode } from 'react';
26
26
  import { View, type Text as RNText, type ViewProps } from 'react-native';
27
27
  import { tv, type VariantProps } from 'tailwind-variants';
28
- import { Text, type TextProps } from '../../primitives/text';
28
+ import { Text, type TextProps, textChildren } from '../../primitives/text';
29
29
  import { cn } from '../../utils/cn';
30
30
 
31
31
  const typographyVariants = tv({
@@ -300,7 +300,7 @@ const TypographyList = forwardRef<View, TypographyListProps>(
300
300
  // platform font, and a view does not.
301
301
  <View className="mt-2.5 size-1.5 shrink-0 rounded-full bg-muted-foreground" />
302
302
  )}
303
- <View className="flex-1">{child}</View>
303
+ <View className="flex-1">{textChildren(child)}</View>
304
304
  </View>
305
305
  ))}
306
306
  </View>
@@ -31,5 +31,6 @@ export {
31
31
  type UseScrollSectionsOptions,
32
32
  type UseScrollSectionsResult,
33
33
  } from './use-scroll-sections';
34
+ export { useBackHandler } from './use-back-handler';
34
35
  export { useDebouncedValue } from './use-debounced-value';
35
36
  export { usePrevious } from './use-previous';
@@ -0,0 +1,37 @@
1
+ import { useEffect, useRef } from 'react';
2
+ import { BackHandler, Platform } from 'react-native';
3
+
4
+ /**
5
+ * Runs a handler when the Android hardware back button is pressed.
6
+ *
7
+ * An open overlay owns the back button while it is up: pressing back should
8
+ * dismiss the overlay, not pop the screen behind it. Without this, the back
9
+ * gesture navigates away and the overlay is orphaned — the same mistake as a
10
+ * modal that stays put when you tap outside it.
11
+ *
12
+ * The listener is Android-only and gated on `enabled`, so an overlay wires it
13
+ * to `open && dismissible` and nothing runs while the overlay is closed or
14
+ * pinned. Returning `true` from the handler tells the platform the press was
15
+ * consumed, which is what stops the navigation.
16
+ *
17
+ * ```tsx
18
+ * useBackHandler(open && dismissible, () => setOpen(false));
19
+ * ```
20
+ */
21
+ export function useBackHandler(enabled: boolean, onBack: () => void): void {
22
+ // Held in a ref so a caller passing an inline `() => setOpen(false)` does not
23
+ // resubscribe the listener on every render — only a change in `enabled` does.
24
+ const onBackRef = useRef(onBack);
25
+ onBackRef.current = onBack;
26
+
27
+ useEffect(() => {
28
+ if (Platform.OS !== 'android' || !enabled) return;
29
+
30
+ const subscription = BackHandler.addEventListener('hardwareBackPress', () => {
31
+ onBackRef.current();
32
+ return true;
33
+ });
34
+
35
+ return () => subscription.remove();
36
+ }, [enabled]);
37
+ }
@@ -103,6 +103,51 @@ export function MinusIcon({ size = 14, color, strokeWidth = 3, ...props }: IconP
103
103
  );
104
104
  }
105
105
 
106
+ export function ChevronUpIcon({ size = 16, color, ...props }: IconProps) {
107
+ const resolved = useResolvedColor(color, '#737373');
108
+ return (
109
+ <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
110
+ <Path
111
+ d="m18 15-6-6-6 6"
112
+ stroke={resolved}
113
+ strokeWidth={2}
114
+ strokeLinecap="round"
115
+ strokeLinejoin="round"
116
+ />
117
+ </Svg>
118
+ );
119
+ }
120
+
121
+ export function CalendarIcon({ size = 16, color, ...props }: IconProps) {
122
+ const resolved = useResolvedColor(color, '#737373');
123
+ return (
124
+ <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
125
+ <Path
126
+ d="M8 2v4M16 2v4M3 10h18M5 4h14a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2Z"
127
+ stroke={resolved}
128
+ strokeWidth={2}
129
+ strokeLinecap="round"
130
+ strokeLinejoin="round"
131
+ />
132
+ </Svg>
133
+ );
134
+ }
135
+
136
+ export function BookmarkIcon({ size = 16, color, ...props }: IconProps) {
137
+ const resolved = useResolvedColor(color, '#737373');
138
+ return (
139
+ <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
140
+ <Path
141
+ d="m19 21-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2Z"
142
+ stroke={resolved}
143
+ strokeWidth={2}
144
+ strokeLinecap="round"
145
+ strokeLinejoin="round"
146
+ />
147
+ </Svg>
148
+ );
149
+ }
150
+
106
151
  export function ChevronDownIcon({ size = 16, color, ...props }: IconProps) {
107
152
  const resolved = useResolvedColor(color, '#737373');
108
153
  return (
@@ -827,3 +872,105 @@ export function UnlockIcon({ size = 16, color, ...props }: IconProps) {
827
872
  </Svg>
828
873
  );
829
874
  }
875
+
876
+ /**
877
+ * Four-pointed sparkles. The mark for a model doing something on your behalf —
878
+ * a reasoning step, a generated plan — where a gear or a brain reads as
879
+ * machinery rather than as assistance.
880
+ */
881
+ export function SparklesIcon({ size = 16, color, ...props }: IconProps) {
882
+ const resolved = useResolvedColor(color, '#737373');
883
+ return (
884
+ <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
885
+ <Path
886
+ d="M11 3 12.6 8.4 18 10l-5.4 1.6L11 17l-1.6-5.4L4 10l5.4-1.6z"
887
+ stroke={resolved}
888
+ strokeWidth={2}
889
+ strokeLinejoin="round"
890
+ />
891
+ <Path
892
+ d="M18 15.5 18.7 18l2.3.7-2.3.7-.7 2.3-.7-2.3-2.3-.7 2.3-.7z"
893
+ stroke={resolved}
894
+ strokeWidth={1.6}
895
+ strokeLinejoin="round"
896
+ />
897
+ </Svg>
898
+ );
899
+ }
900
+
901
+ /** Two stacked sheets — the copy action, paired with CheckIcon once it has run. */
902
+ export function CopyIcon({ size = 16, color, ...props }: IconProps) {
903
+ const resolved = useResolvedColor(color, '#737373');
904
+ return (
905
+ <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
906
+ <Path
907
+ d="M9 9h10v12H9z"
908
+ stroke={resolved}
909
+ strokeWidth={2}
910
+ strokeLinejoin="round"
911
+ />
912
+ <Path
913
+ d="M15 5H5v12h2"
914
+ stroke={resolved}
915
+ strokeWidth={2}
916
+ strokeLinecap="round"
917
+ strokeLinejoin="round"
918
+ />
919
+ </Svg>
920
+ );
921
+ }
922
+
923
+ /** Two links of a chain, for a row that opens somewhere outside the app. */
924
+ export function LinkIcon({ size = 16, color, ...props }: IconProps) {
925
+ const resolved = useResolvedColor(color, '#737373');
926
+ return (
927
+ <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
928
+ <Path
929
+ d="M10 13a5 5 0 0 0 7.5.5l3-3a5 5 0 0 0-7-7l-1.7 1.7"
930
+ stroke={resolved}
931
+ strokeWidth={2}
932
+ strokeLinecap="round"
933
+ strokeLinejoin="round"
934
+ />
935
+ <Path
936
+ d="M14 11a5 5 0 0 0-7.5-.5l-3 3a5 5 0 0 0 7 7l1.7-1.7"
937
+ stroke={resolved}
938
+ strokeWidth={2}
939
+ strokeLinecap="round"
940
+ strokeLinejoin="round"
941
+ />
942
+ </Svg>
943
+ );
944
+ }
945
+
946
+ /** A list with its items ticked off — a plan, or a run of steps. */
947
+ export function ListChecksIcon({ size = 16, color, ...props }: IconProps) {
948
+ const resolved = useResolvedColor(color, '#737373');
949
+ return (
950
+ <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
951
+ <Path
952
+ d="m3 6 1.8 1.8L8 4.5M3 16l1.8 1.8L8 14.5"
953
+ stroke={resolved}
954
+ strokeWidth={2}
955
+ strokeLinecap="round"
956
+ strokeLinejoin="round"
957
+ />
958
+ <Path
959
+ d="M12 6.5h9M12 17.5h9"
960
+ stroke={resolved}
961
+ strokeWidth={2}
962
+ strokeLinecap="round"
963
+ />
964
+ </Svg>
965
+ );
966
+ }
967
+
968
+ /** A hollow ring, for a step that has not started. */
969
+ export function CircleIcon({ size = 16, color, ...props }: IconProps) {
970
+ const resolved = useResolvedColor(color, '#737373');
971
+ return (
972
+ <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
973
+ <Circle cx={12} cy={12} r={8} stroke={resolved} strokeWidth={2} />
974
+ </Svg>
975
+ );
976
+ }
package/src/index.ts CHANGED
@@ -21,6 +21,7 @@ export { Portal, PortalHost, PortalProvider } from './primitives/portal';
21
21
  // graceful fall back from blur to dim — as the built-in ones.
22
22
  export { Scrim, hasBlur, type ScrimProps } from './primitives/scrim';
23
23
  export { Text, type TextProps } from './primitives/text';
24
+ export { Collapse, type CollapseProps } from './primitives/collapse';
24
25
  export {
25
26
  KeyboardAvoider,
26
27
  type KeyboardAvoiderProps,
@@ -79,6 +80,7 @@ export {
79
80
  type AreaChartProps,
80
81
  type AreaChartHandle,
81
82
  type AreaChartGridProps,
83
+ type AreaChartHeaderProps,
82
84
  type AreaChartAreaProps,
83
85
  type AreaChartXAxisProps,
84
86
  type AreaChartYAxisProps,
@@ -93,6 +95,7 @@ export {
93
95
  useBarChart,
94
96
  type BarChartProps,
95
97
  type BarChartHandle,
98
+ type BarChartHeaderProps,
96
99
  type BarChartGridProps,
97
100
  type BarChartBarProps,
98
101
  type BarChartXAxisProps,
@@ -133,6 +136,11 @@ export {
133
136
  type ToggleButtonVariant,
134
137
  type ToggleSelectionMode,
135
138
  } from './components/toggle-button';
139
+ export {
140
+ DatePicker,
141
+ type DatePickerProps,
142
+ type DatePickerMode,
143
+ } from './components/date-picker';
136
144
  export {
137
145
  Dialog,
138
146
  type DialogProps,
@@ -246,6 +254,32 @@ export {
246
254
  type TabsTriggerProps,
247
255
  type TabsContentProps,
248
256
  } from './components/tabs';
257
+ export {
258
+ Carousel,
259
+ useCarouselState,
260
+ type CarouselProps,
261
+ type CarouselHandle,
262
+ type CarouselContentProps,
263
+ type CarouselItemProps,
264
+ type CarouselCaptionProps,
265
+ type CarouselDotsProps,
266
+ type CarouselArrowProps,
267
+ type CarouselControlsProps,
268
+ type CarouselVariant,
269
+ type CarouselOrientation,
270
+ type CarouselAlign,
271
+ } from './components/carousel';
272
+ export {
273
+ Calendar,
274
+ type CalendarProps,
275
+ type CalendarHeaderProps,
276
+ type CalendarNavProps,
277
+ type CalendarMode,
278
+ type CalendarCaptionLayout,
279
+ type CalendarDisabled,
280
+ type CalendarSelection,
281
+ type DateRange,
282
+ } from './components/calendar';
249
283
  export { Card, type CardProps } from './components/card';
250
284
  export { Checkbox, type CheckboxProps } from './components/checkbox';
251
285
  export {
@@ -301,6 +335,7 @@ export {
301
335
  type NumberInputProps,
302
336
  } from './components/number-input';
303
337
  export { OtpInput, type OtpInputProps } from './components/otp-input';
338
+ export { Textarea, type TextareaProps } from './components/textarea';
304
339
  export {
305
340
  Item,
306
341
  type ItemProps,
@@ -320,6 +355,7 @@ export {
320
355
  useLineChart,
321
356
  type LineChartProps,
322
357
  type LineChartHandle,
358
+ type LineChartHeaderProps,
323
359
  type LineChartGridProps,
324
360
  type LineChartLineProps,
325
361
  type LineChartAreaProps,
@@ -343,6 +379,24 @@ export {
343
379
  type MarkerIconProps,
344
380
  type MarkerContentProps,
345
381
  } from './components/marker';
382
+ export {
383
+ Menu,
384
+ type MenuProps,
385
+ type MenuTriggerProps,
386
+ type MenuContentProps,
387
+ type MenuBackgroundProps,
388
+ type MenuLabelProps,
389
+ type MenuItemProps,
390
+ type MenuCheckboxItemProps,
391
+ type MenuRadioGroupProps,
392
+ type MenuRadioItemProps,
393
+ type MenuSeparatorProps,
394
+ type MenuSubProps,
395
+ type MenuSubTriggerProps,
396
+ type MenuSubContentProps,
397
+ type MenuItemVariant,
398
+ type MenuRadioIndicator,
399
+ } from './components/menu';
346
400
  export {
347
401
  MessageScroller,
348
402
  useMessageScroller,
@@ -416,6 +470,52 @@ export {
416
470
  type SignatureButtonProps,
417
471
  } from './components/signature';
418
472
  export { Shimmer, type ShimmerProps } from './components/shimmer';
473
+ export {
474
+ Reasoning,
475
+ type ReasoningProps,
476
+ type ReasoningTriggerProps,
477
+ type ReasoningContentProps,
478
+ } from './components/reasoning';
479
+ export {
480
+ Sources,
481
+ type SourcesProps,
482
+ type SourcesTriggerProps,
483
+ type SourcesContentProps,
484
+ type SourcesSourceProps,
485
+ } from './components/sources';
486
+ export {
487
+ Task,
488
+ type TaskProps,
489
+ type TaskTriggerProps,
490
+ type TaskContentProps,
491
+ type TaskItemProps,
492
+ type TaskFileProps,
493
+ type TaskStatus,
494
+ } from './components/task';
495
+ export {
496
+ CodeBlock,
497
+ resolveLanguage,
498
+ type CodeBlockProps,
499
+ type CodeBlockHeaderProps,
500
+ type CodeBlockFilenameProps,
501
+ type CodeBlockLanguageProps,
502
+ type CodeBlockActionsProps,
503
+ type CodeBlockCopyButtonProps,
504
+ type CodeLanguage,
505
+ type Token,
506
+ type TokenKind,
507
+ } from './components/code-block';
508
+ export {
509
+ Plan,
510
+ type PlanProps,
511
+ type PlanHeaderProps,
512
+ type PlanTitleProps,
513
+ type PlanDescriptionProps,
514
+ type PlanActionProps,
515
+ type PlanTriggerProps,
516
+ type PlanContentProps,
517
+ type PlanFooterProps,
518
+ } from './components/plan';
419
519
  export {
420
520
  ScrollText,
421
521
  type ScrollTextProps,
@@ -470,6 +570,19 @@ export {
470
570
  type ToastIndicatorProps,
471
571
  type ToastCloseProps,
472
572
  } from './components/toast';
573
+ export {
574
+ Tooltip,
575
+ type TooltipProps,
576
+ type TooltipTriggerProps,
577
+ type TooltipContentProps,
578
+ type TooltipArrowProps,
579
+ type TooltipTitleProps,
580
+ type TooltipDescriptionProps,
581
+ type TooltipPlacement,
582
+ type TooltipAlign,
583
+ type TooltipOpenOn,
584
+ type TooltipVariant,
585
+ } from './components/tooltip';
473
586
  export {
474
587
  Typography,
475
588
  type TypographyProps,
@@ -485,12 +598,15 @@ export {
485
598
  AppleIcon,
486
599
  ArrowUpRightIcon,
487
600
  BellIcon,
601
+ BookmarkIcon,
602
+ CalendarIcon,
488
603
  CardIcon,
489
604
  CheckCircleIcon,
490
605
  CheckIcon,
491
606
  ChevronDownIcon,
492
607
  ChevronLeftIcon,
493
608
  ChevronRightIcon,
609
+ ChevronUpIcon,
494
610
  DownloadIcon,
495
611
  EllipsisIcon,
496
612
  FacebookIcon,
@@ -0,0 +1,128 @@
1
+ /**
2
+ * Collapse — a body that opens and closes by animating its own height.
3
+ *
4
+ * Height cannot be animated from `auto`, so the content is measured first and
5
+ * the measurement is what gets animated to. While that is happening the content
6
+ * is taken out of the flow, because a child of a view whose height is
7
+ * mid-animation reports that animated height back and the panel then settles on
8
+ * whatever it happened to measure.
9
+ *
10
+ * The moment the animation finishes, both go away and the content lays out
11
+ * normally again. That is what lets a Collapse hold another Collapse — or hold
12
+ * content that is still streaming in — without either of them being clipped to
13
+ * a number that was true a frame ago.
14
+ *
15
+ * ```tsx
16
+ * <Collapse open={open}>
17
+ * <Text>Anything, of any height.</Text>
18
+ * </Collapse>
19
+ * ```
20
+ *
21
+ * The alternative — unmounting the body and letting a layout transition on the
22
+ * parent carry the change — is what `Accordion` does, and it is right when the
23
+ * closed state should cost nothing. This is for a body that opens and closes
24
+ * repeatedly and often while its content is still arriving, where remounting
25
+ * would throw away scroll position and restart every animation inside it.
26
+ */
27
+ import { useEffect, useRef, useState, type ReactNode } from 'react';
28
+ import { View, type LayoutChangeEvent, type ViewProps } from 'react-native';
29
+ import Animated, {
30
+ runOnJS,
31
+ useAnimatedStyle,
32
+ useReducedMotion,
33
+ useSharedValue,
34
+ withTiming,
35
+ } from 'react-native-reanimated';
36
+ import { cn } from '../utils/cn';
37
+
38
+ /** Long enough to read as the panel opening, short enough not to be waited on. */
39
+ export const COLLAPSE_DURATION = 200;
40
+
41
+ export interface CollapseProps extends Omit<ViewProps, 'children'> {
42
+ open: boolean;
43
+ /** Classes on the measured content, not on the clipping frame. */
44
+ className?: string;
45
+ duration?: number;
46
+ children?: ReactNode;
47
+ }
48
+
49
+ export function Collapse({
50
+ open,
51
+ className,
52
+ duration = COLLAPSE_DURATION,
53
+ children,
54
+ ...props
55
+ }: CollapseProps) {
56
+ const reducedMotion = useReducedMotion();
57
+ const [height, setHeight] = useState(0);
58
+ const [animating, setAnimating] = useState(false);
59
+ const progress = useSharedValue(open ? 1 : 0);
60
+ const mounted = useRef(false);
61
+
62
+ useEffect(() => {
63
+ // The first pass is not a transition — a body that starts open should be
64
+ // open, not play its own entrance at nobody.
65
+ if (!mounted.current) {
66
+ mounted.current = true;
67
+ progress.value = open ? 1 : 0;
68
+ return;
69
+ }
70
+ if (reducedMotion) {
71
+ progress.value = open ? 1 : 0;
72
+ setAnimating(false);
73
+ return;
74
+ }
75
+ setAnimating(true);
76
+ progress.value = withTiming(open ? 1 : 0, { duration }, (finished) => {
77
+ if (finished) runOnJS(setAnimating)(false);
78
+ });
79
+ }, [open, reducedMotion, duration, progress]);
80
+
81
+ const style = useAnimatedStyle(() => ({
82
+ height: progress.value * height,
83
+ opacity: progress.value,
84
+ }));
85
+
86
+ // Re-measured rather than measured once: a body whose content is still
87
+ // streaming in grows, and a height captured on the first frame would crop it.
88
+ const onLayout = (event: LayoutChangeEvent) => {
89
+ const next = event.nativeEvent.layout.height;
90
+ setHeight((current) => (Math.abs(current - next) < 1 ? current : next));
91
+ };
92
+
93
+ /*
94
+ * Once it has finished opening, the measured height and the absolute
95
+ * positioning are both dropped and the content lays out normally.
96
+ *
97
+ * They are only needed *while* the height is being animated to a number, and
98
+ * keeping them costs real bugs: a Collapse whose content is itself a Collapse
99
+ * measures a child that has not settled yet, and settles on that wrong
100
+ * number, so the inner body ends up clipped to nothing. Content that is still
101
+ * streaming in has the same problem against itself. In natural flow both are
102
+ * simply laid out, and the measurement carries on in the background against
103
+ * the next time it closes.
104
+ */
105
+ const natural = open && !animating;
106
+
107
+ return (
108
+ <Animated.View
109
+ style={natural ? undefined : style}
110
+ className={natural ? undefined : 'overflow-hidden'}
111
+ >
112
+ {/*
113
+ The same two elements in both modes, so switching between them is a
114
+ style change rather than a remount — a remount would throw away the
115
+ state of everything inside.
116
+ */}
117
+ <View
118
+ onLayout={onLayout}
119
+ style={natural ? undefined : { position: 'absolute', left: 0, right: 0, top: 0 }}
120
+ className={cn(className)}
121
+ {...props}
122
+ >
123
+ {children}
124
+ </View>
125
+ </Animated.View>
126
+ );
127
+ }
128
+ Collapse.displayName = 'Collapse';
@@ -27,6 +27,7 @@ import {
27
27
  useKeyboardAvoidance,
28
28
  type KeyboardAvoidanceMode,
29
29
  } from '../hooks/use-keyboard-avoidance';
30
+ import { textChildren } from './text';
30
31
 
31
32
  export interface KeyboardAvoiderProps extends ViewProps {
32
33
  className?: string;
@@ -86,7 +87,7 @@ export function KeyboardAvoider({
86
87
  className={className}
87
88
  style={[style, avoidance.animatedStyle]}
88
89
  >
89
- {children}
90
+ {textChildren(children)}
90
91
  </Animated.View>
91
92
  );
92
93
  }
@@ -1,4 +1,4 @@
1
- import { forwardRef } from 'react';
1
+ import { Children, forwardRef, type ReactElement, type ReactNode } from 'react';
2
2
  import { Text as RNText, type Text as RNTextType, type TextProps as RNTextProps } from 'react-native';
3
3
  import { tv, type VariantProps } from 'tailwind-variants';
4
4
  import { useDirection } from '../hooks/use-direction';
@@ -63,3 +63,30 @@ export const Text = forwardRef<RNTextType, TextProps>(
63
63
  );
64
64
 
65
65
  Text.displayName = 'Text';
66
+
67
+ /**
68
+ * Wraps the bare text among `children` so it can live in a plain view.
69
+ *
70
+ * React Native will not render a string outside a `<Text>`, and a component
71
+ * that takes `children` has no say in whether it is handed one — so anything
72
+ * putting `children` into a `View`, a `Pressable` or a scroller has to allow
73
+ * for it. Every part in the library that does runs its children through here.
74
+ *
75
+ * Per child, and not all-or-nothing. A part is nearly always given an element
76
+ * and some text together — an icon and a label, an arrow and a line of text —
77
+ * which makes `children` an *array*, so a `typeof children === 'string'` check
78
+ * never matches and the text underneath reaches the view bare. That is the
79
+ * shape this exists to make impossible.
80
+ *
81
+ * `render` is there because the wrapper is rarely the plain default: a button
82
+ * wants its own label variant, a sheet header wants a heading. Pass one, and
83
+ * the text arrives dressed the way the part would have dressed it anyway.
84
+ */
85
+ export function textChildren(
86
+ children: ReactNode,
87
+ render: (text: string | number) => ReactElement = (text) => <Text>{text}</Text>
88
+ ): ReactNode {
89
+ return Children.map(children, (child) =>
90
+ typeof child === 'string' || typeof child === 'number' ? render(child) : child
91
+ );
92
+ }