@oxyhq/bloom 0.1.32 → 0.1.33

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 (275) hide show
  1. package/lib/commonjs/admonition/index.js +7 -0
  2. package/lib/commonjs/admonition/index.js.map +1 -1
  3. package/lib/commonjs/avatar/Avatar.js +2 -18
  4. package/lib/commonjs/avatar/Avatar.js.map +1 -1
  5. package/lib/commonjs/bottom-sheet/index.js +16 -6
  6. package/lib/commonjs/bottom-sheet/index.js.map +1 -1
  7. package/lib/commonjs/button/Button.js +6 -18
  8. package/lib/commonjs/button/Button.js.map +1 -1
  9. package/lib/commonjs/chip/Chip.js +6 -16
  10. package/lib/commonjs/chip/Chip.js.map +1 -1
  11. package/lib/commonjs/collapsible/Collapsible.js +28 -20
  12. package/lib/commonjs/collapsible/Collapsible.js.map +1 -1
  13. package/lib/commonjs/fill/index.js +7 -5
  14. package/lib/commonjs/fill/index.js.map +1 -1
  15. package/lib/commonjs/grid/index.js +9 -6
  16. package/lib/commonjs/grid/index.js.map +1 -1
  17. package/lib/commonjs/grouped-buttons/GroupedButtons.js +76 -48
  18. package/lib/commonjs/grouped-buttons/GroupedButtons.js.map +1 -1
  19. package/lib/commonjs/hooks/index.js +13 -0
  20. package/lib/commonjs/hooks/index.js.map +1 -1
  21. package/lib/commonjs/hooks/useInteractionState.js +42 -0
  22. package/lib/commonjs/hooks/useInteractionState.js.map +1 -1
  23. package/lib/commonjs/hooks/usePressAnimation.js +44 -0
  24. package/lib/commonjs/hooks/usePressAnimation.js.map +1 -0
  25. package/lib/commonjs/icon-circle/index.js +7 -5
  26. package/lib/commonjs/icon-circle/index.js.map +1 -1
  27. package/lib/commonjs/icons/{EnveopeOpen.js → EnvelopeOpen.js} +1 -1
  28. package/lib/commonjs/icons/EnvelopeOpen.js.map +1 -0
  29. package/lib/commonjs/icons/TEMPLATE.js +3 -2
  30. package/lib/commonjs/icons/TEMPLATE.js.map +1 -1
  31. package/lib/commonjs/icons/VerifiedCheck.js +3 -2
  32. package/lib/commonjs/icons/VerifiedCheck.js.map +1 -1
  33. package/lib/commonjs/icons/VerifierCheck.js +3 -2
  34. package/lib/commonjs/icons/VerifierCheck.js.map +1 -1
  35. package/lib/commonjs/icons/index.js +4 -4
  36. package/lib/commonjs/icons/index.js.map +1 -1
  37. package/lib/commonjs/loading/Loading.js +2 -17
  38. package/lib/commonjs/loading/Loading.js.map +1 -1
  39. package/lib/commonjs/loading/SpinnerIcon.js +3 -34
  40. package/lib/commonjs/loading/SpinnerIcon.js.map +1 -1
  41. package/lib/commonjs/prompt-input/Actions.js +1 -0
  42. package/lib/commonjs/prompt-input/Actions.js.map +1 -1
  43. package/lib/commonjs/prompt-input/Attachments.js +1 -0
  44. package/lib/commonjs/prompt-input/Attachments.js.map +1 -1
  45. package/lib/commonjs/prompt-input/PromptInput.js +1 -0
  46. package/lib/commonjs/prompt-input/PromptInput.js.map +1 -1
  47. package/lib/commonjs/prompt-input/SubmitButton.js +1 -0
  48. package/lib/commonjs/prompt-input/SubmitButton.js.map +1 -1
  49. package/lib/commonjs/prompt-input/Textarea.js +1 -0
  50. package/lib/commonjs/prompt-input/Textarea.js.map +1 -1
  51. package/lib/commonjs/prompt-input/Textarea.web.js +1 -0
  52. package/lib/commonjs/prompt-input/Textarea.web.js.map +1 -1
  53. package/lib/commonjs/search-input/index.js +1 -0
  54. package/lib/commonjs/search-input/index.js.map +1 -1
  55. package/lib/commonjs/settings-list/SettingsList.js +10 -11
  56. package/lib/commonjs/settings-list/SettingsList.js.map +1 -1
  57. package/lib/commonjs/skeleton/index.js +5 -0
  58. package/lib/commonjs/skeleton/index.js.map +1 -1
  59. package/lib/commonjs/switch/Switch.js +43 -28
  60. package/lib/commonjs/switch/Switch.js.map +1 -1
  61. package/lib/commonjs/tabs/Tabs.js +6 -15
  62. package/lib/commonjs/tabs/Tabs.js.map +1 -1
  63. package/lib/commonjs/typography/index.js +14 -5
  64. package/lib/commonjs/typography/index.js.map +1 -1
  65. package/lib/commonjs/utils/lazy-require.js +37 -0
  66. package/lib/commonjs/utils/lazy-require.js.map +1 -0
  67. package/lib/module/admonition/index.js +7 -0
  68. package/lib/module/admonition/index.js.map +1 -1
  69. package/lib/module/avatar/Avatar.js +2 -18
  70. package/lib/module/avatar/Avatar.js.map +1 -1
  71. package/lib/module/bottom-sheet/index.js +16 -6
  72. package/lib/module/bottom-sheet/index.js.map +1 -1
  73. package/lib/module/button/Button.js +7 -19
  74. package/lib/module/button/Button.js.map +1 -1
  75. package/lib/module/chip/Chip.js +7 -17
  76. package/lib/module/chip/Chip.js.map +1 -1
  77. package/lib/module/collapsible/Collapsible.js +30 -22
  78. package/lib/module/collapsible/Collapsible.js.map +1 -1
  79. package/lib/module/fill/index.js +5 -3
  80. package/lib/module/fill/index.js.map +1 -1
  81. package/lib/module/grid/index.js +9 -5
  82. package/lib/module/grid/index.js.map +1 -1
  83. package/lib/module/grouped-buttons/GroupedButtons.js +77 -48
  84. package/lib/module/grouped-buttons/GroupedButtons.js.map +1 -1
  85. package/lib/module/hooks/index.js +2 -1
  86. package/lib/module/hooks/index.js.map +1 -1
  87. package/lib/module/hooks/useInteractionState.js +41 -0
  88. package/lib/module/hooks/useInteractionState.js.map +1 -1
  89. package/lib/module/hooks/usePressAnimation.js +41 -0
  90. package/lib/module/hooks/usePressAnimation.js.map +1 -0
  91. package/lib/module/icon-circle/index.js +5 -3
  92. package/lib/module/icon-circle/index.js.map +1 -1
  93. package/lib/module/icons/{EnveopeOpen.js → EnvelopeOpen.js} +1 -1
  94. package/lib/module/icons/EnvelopeOpen.js.map +1 -0
  95. package/lib/module/icons/TEMPLATE.js +3 -2
  96. package/lib/module/icons/TEMPLATE.js.map +1 -1
  97. package/lib/module/icons/VerifiedCheck.js +3 -2
  98. package/lib/module/icons/VerifiedCheck.js.map +1 -1
  99. package/lib/module/icons/VerifierCheck.js +3 -2
  100. package/lib/module/icons/VerifierCheck.js.map +1 -1
  101. package/lib/module/icons/index.js +1 -1
  102. package/lib/module/icons/index.js.map +1 -1
  103. package/lib/module/loading/Loading.js +2 -17
  104. package/lib/module/loading/Loading.js.map +1 -1
  105. package/lib/module/loading/SpinnerIcon.js +3 -34
  106. package/lib/module/loading/SpinnerIcon.js.map +1 -1
  107. package/lib/module/prompt-input/Actions.js +1 -0
  108. package/lib/module/prompt-input/Actions.js.map +1 -1
  109. package/lib/module/prompt-input/Attachments.js +1 -0
  110. package/lib/module/prompt-input/Attachments.js.map +1 -1
  111. package/lib/module/prompt-input/PromptInput.js +1 -0
  112. package/lib/module/prompt-input/PromptInput.js.map +1 -1
  113. package/lib/module/prompt-input/SubmitButton.js +1 -0
  114. package/lib/module/prompt-input/SubmitButton.js.map +1 -1
  115. package/lib/module/prompt-input/Textarea.js +1 -0
  116. package/lib/module/prompt-input/Textarea.js.map +1 -1
  117. package/lib/module/prompt-input/Textarea.web.js +1 -0
  118. package/lib/module/prompt-input/Textarea.web.js.map +1 -1
  119. package/lib/module/search-input/index.js +1 -0
  120. package/lib/module/search-input/index.js.map +1 -1
  121. package/lib/module/settings-list/SettingsList.js +10 -11
  122. package/lib/module/settings-list/SettingsList.js.map +1 -1
  123. package/lib/module/skeleton/index.js +5 -0
  124. package/lib/module/skeleton/index.js.map +1 -1
  125. package/lib/module/switch/Switch.js +45 -30
  126. package/lib/module/switch/Switch.js.map +1 -1
  127. package/lib/module/tabs/Tabs.js +8 -17
  128. package/lib/module/tabs/Tabs.js.map +1 -1
  129. package/lib/module/typography/index.js +12 -3
  130. package/lib/module/typography/index.js.map +1 -1
  131. package/lib/module/utils/lazy-require.js +33 -0
  132. package/lib/module/utils/lazy-require.js.map +1 -0
  133. package/lib/typescript/commonjs/admonition/index.d.ts +21 -0
  134. package/lib/typescript/commonjs/admonition/index.d.ts.map +1 -1
  135. package/lib/typescript/commonjs/avatar/Avatar.d.ts.map +1 -1
  136. package/lib/typescript/commonjs/bottom-sheet/index.d.ts.map +1 -1
  137. package/lib/typescript/commonjs/button/Button.d.ts.map +1 -1
  138. package/lib/typescript/commonjs/chip/Chip.d.ts.map +1 -1
  139. package/lib/typescript/commonjs/collapsible/Collapsible.d.ts.map +1 -1
  140. package/lib/typescript/commonjs/fill/index.d.ts +2 -2
  141. package/lib/typescript/commonjs/fill/index.d.ts.map +1 -1
  142. package/lib/typescript/commonjs/grid/index.d.ts +4 -4
  143. package/lib/typescript/commonjs/grid/index.d.ts.map +1 -1
  144. package/lib/typescript/commonjs/grouped-buttons/GroupedButtons.d.ts +9 -5
  145. package/lib/typescript/commonjs/grouped-buttons/GroupedButtons.d.ts.map +1 -1
  146. package/lib/typescript/commonjs/hooks/index.d.ts +2 -1
  147. package/lib/typescript/commonjs/hooks/index.d.ts.map +1 -1
  148. package/lib/typescript/commonjs/hooks/useInteractionState.d.ts +23 -0
  149. package/lib/typescript/commonjs/hooks/useInteractionState.d.ts.map +1 -1
  150. package/lib/typescript/commonjs/hooks/usePressAnimation.d.ts +16 -0
  151. package/lib/typescript/commonjs/hooks/usePressAnimation.d.ts.map +1 -0
  152. package/lib/typescript/commonjs/icon-circle/index.d.ts +4 -4
  153. package/lib/typescript/commonjs/icon-circle/index.d.ts.map +1 -1
  154. package/lib/typescript/commonjs/icons/{EnveopeOpen.d.ts → EnvelopeOpen.d.ts} +1 -1
  155. package/lib/typescript/commonjs/icons/EnvelopeOpen.d.ts.map +1 -0
  156. package/lib/typescript/commonjs/icons/TEMPLATE.d.ts +2 -1
  157. package/lib/typescript/commonjs/icons/TEMPLATE.d.ts.map +1 -1
  158. package/lib/typescript/commonjs/icons/VerifiedCheck.d.ts.map +1 -1
  159. package/lib/typescript/commonjs/icons/VerifierCheck.d.ts.map +1 -1
  160. package/lib/typescript/commonjs/icons/index.d.ts +1 -1
  161. package/lib/typescript/commonjs/icons/index.d.ts.map +1 -1
  162. package/lib/typescript/commonjs/loading/Loading.d.ts.map +1 -1
  163. package/lib/typescript/commonjs/loading/SpinnerIcon.d.ts.map +1 -1
  164. package/lib/typescript/commonjs/prompt-input/Actions.d.ts +3 -0
  165. package/lib/typescript/commonjs/prompt-input/Actions.d.ts.map +1 -1
  166. package/lib/typescript/commonjs/prompt-input/Attachments.d.ts +3 -0
  167. package/lib/typescript/commonjs/prompt-input/Attachments.d.ts.map +1 -1
  168. package/lib/typescript/commonjs/prompt-input/PromptInput.d.ts +3 -0
  169. package/lib/typescript/commonjs/prompt-input/PromptInput.d.ts.map +1 -1
  170. package/lib/typescript/commonjs/prompt-input/SubmitButton.d.ts +3 -0
  171. package/lib/typescript/commonjs/prompt-input/SubmitButton.d.ts.map +1 -1
  172. package/lib/typescript/commonjs/prompt-input/Textarea.d.ts +3 -0
  173. package/lib/typescript/commonjs/prompt-input/Textarea.d.ts.map +1 -1
  174. package/lib/typescript/commonjs/prompt-input/Textarea.web.d.ts +3 -0
  175. package/lib/typescript/commonjs/prompt-input/Textarea.web.d.ts.map +1 -1
  176. package/lib/typescript/commonjs/settings-list/SettingsList.d.ts.map +1 -1
  177. package/lib/typescript/commonjs/skeleton/index.d.ts +15 -0
  178. package/lib/typescript/commonjs/skeleton/index.d.ts.map +1 -1
  179. package/lib/typescript/commonjs/switch/Switch.d.ts.map +1 -1
  180. package/lib/typescript/commonjs/tabs/Tabs.d.ts.map +1 -1
  181. package/lib/typescript/commonjs/typography/index.d.ts +11 -10
  182. package/lib/typescript/commonjs/typography/index.d.ts.map +1 -1
  183. package/lib/typescript/commonjs/utils/lazy-require.d.ts +15 -0
  184. package/lib/typescript/commonjs/utils/lazy-require.d.ts.map +1 -0
  185. package/lib/typescript/module/admonition/index.d.ts +21 -0
  186. package/lib/typescript/module/admonition/index.d.ts.map +1 -1
  187. package/lib/typescript/module/avatar/Avatar.d.ts.map +1 -1
  188. package/lib/typescript/module/bottom-sheet/index.d.ts.map +1 -1
  189. package/lib/typescript/module/button/Button.d.ts.map +1 -1
  190. package/lib/typescript/module/chip/Chip.d.ts.map +1 -1
  191. package/lib/typescript/module/collapsible/Collapsible.d.ts.map +1 -1
  192. package/lib/typescript/module/fill/index.d.ts +2 -2
  193. package/lib/typescript/module/fill/index.d.ts.map +1 -1
  194. package/lib/typescript/module/grid/index.d.ts +4 -4
  195. package/lib/typescript/module/grid/index.d.ts.map +1 -1
  196. package/lib/typescript/module/grouped-buttons/GroupedButtons.d.ts +9 -5
  197. package/lib/typescript/module/grouped-buttons/GroupedButtons.d.ts.map +1 -1
  198. package/lib/typescript/module/hooks/index.d.ts +2 -1
  199. package/lib/typescript/module/hooks/index.d.ts.map +1 -1
  200. package/lib/typescript/module/hooks/useInteractionState.d.ts +23 -0
  201. package/lib/typescript/module/hooks/useInteractionState.d.ts.map +1 -1
  202. package/lib/typescript/module/hooks/usePressAnimation.d.ts +16 -0
  203. package/lib/typescript/module/hooks/usePressAnimation.d.ts.map +1 -0
  204. package/lib/typescript/module/icon-circle/index.d.ts +4 -4
  205. package/lib/typescript/module/icon-circle/index.d.ts.map +1 -1
  206. package/lib/typescript/module/icons/{EnveopeOpen.d.ts → EnvelopeOpen.d.ts} +1 -1
  207. package/lib/typescript/module/icons/EnvelopeOpen.d.ts.map +1 -0
  208. package/lib/typescript/module/icons/TEMPLATE.d.ts +2 -1
  209. package/lib/typescript/module/icons/TEMPLATE.d.ts.map +1 -1
  210. package/lib/typescript/module/icons/VerifiedCheck.d.ts.map +1 -1
  211. package/lib/typescript/module/icons/VerifierCheck.d.ts.map +1 -1
  212. package/lib/typescript/module/icons/index.d.ts +1 -1
  213. package/lib/typescript/module/icons/index.d.ts.map +1 -1
  214. package/lib/typescript/module/loading/Loading.d.ts.map +1 -1
  215. package/lib/typescript/module/loading/SpinnerIcon.d.ts.map +1 -1
  216. package/lib/typescript/module/prompt-input/Actions.d.ts +3 -0
  217. package/lib/typescript/module/prompt-input/Actions.d.ts.map +1 -1
  218. package/lib/typescript/module/prompt-input/Attachments.d.ts +3 -0
  219. package/lib/typescript/module/prompt-input/Attachments.d.ts.map +1 -1
  220. package/lib/typescript/module/prompt-input/PromptInput.d.ts +3 -0
  221. package/lib/typescript/module/prompt-input/PromptInput.d.ts.map +1 -1
  222. package/lib/typescript/module/prompt-input/SubmitButton.d.ts +3 -0
  223. package/lib/typescript/module/prompt-input/SubmitButton.d.ts.map +1 -1
  224. package/lib/typescript/module/prompt-input/Textarea.d.ts +3 -0
  225. package/lib/typescript/module/prompt-input/Textarea.d.ts.map +1 -1
  226. package/lib/typescript/module/prompt-input/Textarea.web.d.ts +3 -0
  227. package/lib/typescript/module/prompt-input/Textarea.web.d.ts.map +1 -1
  228. package/lib/typescript/module/settings-list/SettingsList.d.ts.map +1 -1
  229. package/lib/typescript/module/skeleton/index.d.ts +15 -0
  230. package/lib/typescript/module/skeleton/index.d.ts.map +1 -1
  231. package/lib/typescript/module/switch/Switch.d.ts.map +1 -1
  232. package/lib/typescript/module/tabs/Tabs.d.ts.map +1 -1
  233. package/lib/typescript/module/typography/index.d.ts +11 -10
  234. package/lib/typescript/module/typography/index.d.ts.map +1 -1
  235. package/lib/typescript/module/utils/lazy-require.d.ts +15 -0
  236. package/lib/typescript/module/utils/lazy-require.d.ts.map +1 -0
  237. package/package.json +1 -1
  238. package/src/__tests__/BloomThemeProvider.test.tsx +3 -3
  239. package/src/admonition/index.tsx +7 -0
  240. package/src/avatar/Avatar.tsx +2 -19
  241. package/src/bottom-sheet/index.tsx +18 -6
  242. package/src/button/Button.tsx +6 -22
  243. package/src/chip/Chip.tsx +3 -19
  244. package/src/collapsible/Collapsible.tsx +34 -25
  245. package/src/fill/index.tsx +6 -3
  246. package/src/grid/index.tsx +11 -5
  247. package/src/grouped-buttons/GroupedButtons.tsx +79 -60
  248. package/src/hooks/index.ts +2 -1
  249. package/src/hooks/useInteractionState.ts +21 -0
  250. package/src/hooks/usePressAnimation.ts +37 -0
  251. package/src/icon-circle/index.tsx +6 -3
  252. package/src/icons/TEMPLATE.tsx +2 -2
  253. package/src/icons/VerifiedCheck.tsx +3 -2
  254. package/src/icons/VerifierCheck.tsx +3 -2
  255. package/src/icons/index.ts +1 -1
  256. package/src/loading/Loading.tsx +2 -18
  257. package/src/loading/SpinnerIcon.tsx +4 -36
  258. package/src/prompt-input/Actions.tsx +1 -0
  259. package/src/prompt-input/Attachments.tsx +1 -0
  260. package/src/prompt-input/PromptInput.tsx +1 -0
  261. package/src/prompt-input/SubmitButton.tsx +1 -0
  262. package/src/prompt-input/Textarea.tsx +1 -0
  263. package/src/prompt-input/Textarea.web.tsx +1 -0
  264. package/src/search-input/index.tsx +1 -0
  265. package/src/settings-list/SettingsList.tsx +12 -8
  266. package/src/skeleton/index.tsx +5 -0
  267. package/src/switch/Switch.tsx +45 -23
  268. package/src/tabs/Tabs.tsx +3 -21
  269. package/src/typography/index.tsx +14 -4
  270. package/src/utils/lazy-require.ts +31 -0
  271. package/lib/commonjs/icons/EnveopeOpen.js.map +0 -1
  272. package/lib/module/icons/EnveopeOpen.js.map +0 -1
  273. package/lib/typescript/commonjs/icons/EnveopeOpen.d.ts.map +0 -1
  274. package/lib/typescript/module/icons/EnveopeOpen.d.ts.map +0 -1
  275. /package/src/icons/{EnveopeOpen.tsx → EnvelopeOpen.tsx} +0 -0
@@ -1,10 +1,10 @@
1
- import React, { createContext, useContext, useMemo } from 'react';
1
+ import React, { createContext, memo, useContext, useMemo } from 'react';
2
2
  import { View, type ViewStyle } from 'react-native';
3
3
 
4
4
  const GridContext = createContext({ gap: 0 });
5
5
  GridContext.displayName = 'GridContext';
6
6
 
7
- export function Row({
7
+ const RowComponent = function Row({
8
8
  children,
9
9
  gap = 0,
10
10
  style,
@@ -29,9 +29,12 @@ export function Row({
29
29
  </View>
30
30
  </GridContext.Provider>
31
31
  );
32
- }
32
+ };
33
33
 
34
- export function Col({
34
+ export const Row = memo(RowComponent);
35
+ Row.displayName = 'Row';
36
+
37
+ const ColComponent = function Col({
35
38
  children,
36
39
  width = 1,
37
40
  style,
@@ -55,4 +58,7 @@ export function Col({
55
58
  {children}
56
59
  </View>
57
60
  );
58
- }
61
+ };
62
+
63
+ export const Col = memo(ColComponent);
64
+ Col.displayName = 'Col';
@@ -1,45 +1,14 @@
1
- import React, { Children } from 'react';
2
- import { View, Text, TouchableOpacity } from 'react-native';
1
+ import React, { Children, memo } from 'react';
2
+ import { View, Text, TouchableOpacity, StyleSheet } from 'react-native';
3
3
 
4
4
  import { useTheme } from '../theme/use-theme';
5
5
  import type { GroupedButtonsProps, GroupedButtonItemProps } from './types';
6
6
 
7
7
  export type { GroupedButtonsProps, GroupedButtonItemProps } from './types';
8
8
 
9
- export function GroupedButtons({ children, style }: GroupedButtonsProps) {
10
- const theme = useTheme();
11
- const childArray = Children.toArray(children);
9
+ // ── Item (defined first so it can be attached to GroupedButtons)
12
10
 
13
- return (
14
- <View
15
- style={[
16
- {
17
- borderRadius: 12,
18
- backgroundColor: theme.colors.card,
19
- overflow: 'hidden',
20
- },
21
- style,
22
- ]}
23
- >
24
- {childArray.map((child, index) => (
25
- <React.Fragment key={index}>
26
- {child}
27
- {index < childArray.length - 1 && (
28
- <View
29
- style={{
30
- height: 1,
31
- backgroundColor: theme.colors.borderLight,
32
- marginLeft: 16,
33
- }}
34
- />
35
- )}
36
- </React.Fragment>
37
- ))}
38
- </View>
39
- );
40
- }
41
-
42
- export function Item({
11
+ function ItemComponent({
43
12
  label,
44
13
  description,
45
14
  icon,
@@ -49,7 +18,6 @@ export function Item({
49
18
  testID,
50
19
  }: GroupedButtonItemProps) {
51
20
  const theme = useTheme();
52
-
53
21
  const labelColor = destructive ? theme.colors.negative : theme.colors.text;
54
22
 
55
23
  return (
@@ -58,31 +26,13 @@ export function Item({
58
26
  disabled={disabled}
59
27
  activeOpacity={0.6}
60
28
  testID={testID}
61
- style={{
62
- flexDirection: 'row',
63
- alignItems: 'center',
64
- paddingVertical: 12,
65
- paddingHorizontal: 16,
66
- opacity: disabled ? 0.5 : 1,
67
- }}
29
+ style={[styles.item, disabled && styles.disabled]}
68
30
  >
69
- {icon && (
70
- <View style={{ marginRight: 12 }}>
71
- {icon}
72
- </View>
73
- )}
74
- <View style={{ flex: 1 }}>
75
- <Text style={{ fontSize: 16, color: labelColor }}>
76
- {label}
77
- </Text>
31
+ {icon && <View style={styles.iconWrapper}>{icon}</View>}
32
+ <View style={styles.textWrapper}>
33
+ <Text style={[styles.label, { color: labelColor }]}>{label}</Text>
78
34
  {description && (
79
- <Text
80
- style={{
81
- fontSize: 13,
82
- color: theme.colors.textSecondary,
83
- marginTop: 2,
84
- }}
85
- >
35
+ <Text style={[styles.description, { color: theme.colors.textSecondary }]}>
86
36
  {description}
87
37
  </Text>
88
38
  )}
@@ -91,4 +41,73 @@ export function Item({
91
41
  );
92
42
  }
93
43
 
94
- GroupedButtons.Item = Item;
44
+ export const Item = memo(ItemComponent);
45
+ Item.displayName = 'GroupedButtons.Item';
46
+
47
+ // ── GroupedButtons ───────────────────────────────────────────────
48
+
49
+ function GroupedButtonsComponent({ children, style }: GroupedButtonsProps) {
50
+ const theme = useTheme();
51
+ const childArray = Children.toArray(children);
52
+
53
+ return (
54
+ <View
55
+ style={[
56
+ styles.container,
57
+ { backgroundColor: theme.colors.card },
58
+ style,
59
+ ]}
60
+ >
61
+ {childArray.map((child, index) => (
62
+ <React.Fragment key={index}>
63
+ {child}
64
+ {index < childArray.length - 1 && (
65
+ <View
66
+ style={[styles.divider, { backgroundColor: theme.colors.borderLight }]}
67
+ />
68
+ )}
69
+ </React.Fragment>
70
+ ))}
71
+ </View>
72
+ );
73
+ }
74
+
75
+ const GroupedButtonsMemo = memo(GroupedButtonsComponent);
76
+ GroupedButtonsMemo.displayName = 'GroupedButtons';
77
+
78
+ export const GroupedButtons = Object.assign(GroupedButtonsMemo, { Item });
79
+
80
+ // ── Styles ──────────────────────────────────────────────────────
81
+
82
+ const styles = StyleSheet.create({
83
+ container: {
84
+ borderRadius: 12,
85
+ overflow: 'hidden',
86
+ },
87
+ divider: {
88
+ height: 1,
89
+ marginLeft: 16,
90
+ },
91
+ item: {
92
+ flexDirection: 'row',
93
+ alignItems: 'center',
94
+ paddingVertical: 12,
95
+ paddingHorizontal: 16,
96
+ },
97
+ disabled: {
98
+ opacity: 0.5,
99
+ },
100
+ iconWrapper: {
101
+ marginRight: 12,
102
+ },
103
+ textWrapper: {
104
+ flex: 1,
105
+ },
106
+ label: {
107
+ fontSize: 16,
108
+ },
109
+ description: {
110
+ fontSize: 13,
111
+ marginTop: 2,
112
+ },
113
+ });
@@ -1,4 +1,5 @@
1
- export { useInteractionState } from './useInteractionState';
1
+ export { useInteractionState, useInteractionStates } from './useInteractionState';
2
2
  export { useDelayedLoading } from './useDelayedLoading';
3
3
  export { useThrottledValue } from './useThrottledValue';
4
+ export { usePressAnimation } from './usePressAnimation';
4
5
  export { mergeRefs } from './mergeRefs';
@@ -12,3 +12,24 @@ export function useInteractionState() {
12
12
 
13
13
  return { state, onIn, onOut };
14
14
  }
15
+
16
+ /**
17
+ * Tracks multiple interaction states (hovered, focused, pressed) in one hook.
18
+ *
19
+ * Returns stable handler objects suitable for spreading onto Pressable-like components.
20
+ * On web, `hoverHandlers` can be spread as `onMouseEnter`/`onMouseLeave`.
21
+ */
22
+ export function useInteractionStates() {
23
+ const { state: hovered, onIn: onHoverIn, onOut: onHoverOut } = useInteractionState();
24
+ const { state: focused, onIn: onFocus, onOut: onBlur } = useInteractionState();
25
+ const { state: pressed, onIn: onPressIn, onOut: onPressOut } = useInteractionState();
26
+
27
+ return {
28
+ hovered,
29
+ focused,
30
+ pressed,
31
+ hoverHandlers: { onHoverIn, onHoverOut } as const,
32
+ focusHandlers: { onFocus, onBlur } as const,
33
+ pressHandlers: { onPressIn, onPressOut } as const,
34
+ };
35
+ }
@@ -0,0 +1,37 @@
1
+ import { useCallback, useRef } from 'react';
2
+ import { Animated } from 'react-native';
3
+
4
+ import { animation } from '../styles/tokens';
5
+
6
+ /**
7
+ * Hook that provides press-scale animation feedback.
8
+ *
9
+ * Returns an `Animated.Value` for the scale transform and press-in/press-out
10
+ * handlers that spring the value between 1 and the target scale.
11
+ *
12
+ * @param pressScale - Scale value when pressed (e.g. 0.97). Pass `undefined` to disable.
13
+ */
14
+ export function usePressAnimation(pressScale: number | undefined = 0.97) {
15
+ const scaleAnim = useRef(new Animated.Value(1)).current;
16
+ const enabled = pressScale !== undefined;
17
+
18
+ const onPressIn = useCallback(() => {
19
+ if (!enabled) return;
20
+ Animated.spring(scaleAnim, {
21
+ toValue: pressScale!,
22
+ useNativeDriver: true,
23
+ ...animation.spring.snappy,
24
+ }).start();
25
+ }, [scaleAnim, enabled, pressScale]);
26
+
27
+ const onPressOut = useCallback(() => {
28
+ if (!enabled) return;
29
+ Animated.spring(scaleAnim, {
30
+ toValue: 1,
31
+ useNativeDriver: true,
32
+ ...animation.spring.gentle,
33
+ }).start();
34
+ }, [scaleAnim, enabled]);
35
+
36
+ return { scaleAnim, onPressIn, onPressOut, enabled } as const;
37
+ }
@@ -1,10 +1,10 @@
1
- import React from 'react';
1
+ import React, { memo } from 'react';
2
2
  import { View, type ViewStyle } from 'react-native';
3
3
 
4
4
  import { useTheme } from '../theme/use-theme';
5
5
  import { type Props as IconProps } from '../icons/common';
6
6
 
7
- export function IconCircle({
7
+ const IconCircleComponent = function IconCircle({
8
8
  icon: Icon,
9
9
  size = 'xl',
10
10
  style,
@@ -33,4 +33,7 @@ export function IconCircle({
33
33
  <Icon size={size} style={[{ color: colors.primary }, iconStyle]} />
34
34
  </View>
35
35
  );
36
- }
36
+ };
37
+
38
+ export const IconCircle = memo(IconCircleComponent);
39
+ IconCircle.displayName = 'IconCircle';
@@ -46,7 +46,7 @@ export function createSinglePathSVG({
46
46
  });
47
47
  }
48
48
 
49
- export function createMultiPathSVG({ paths }: { paths: string[] }) {
49
+ export function createMultiPathSVG({ paths, viewBox }: { paths: string[]; viewBox?: string }) {
50
50
  return forwardRef<Svg, Props>(function IconImpl(props, ref) {
51
51
  const { fill, size, style, gradient, ...rest } = useCommonSVGProps(props);
52
52
 
@@ -55,7 +55,7 @@ export function createMultiPathSVG({ paths }: { paths: string[] }) {
55
55
  fill="none"
56
56
  {...rest}
57
57
  ref={ref}
58
- viewBox="0 0 24 24"
58
+ viewBox={viewBox || '0 0 24 24'}
59
59
  width={size}
60
60
  height={size}
61
61
  style={[style]}>
@@ -4,8 +4,8 @@ import Svg, {Circle, Path} from 'react-native-svg'
4
4
  import {type Props, useCommonSVGProps} from './common'
5
5
 
6
6
  export const VerifiedCheck = forwardRef<Svg, Props>(
7
- function LogoImpl(props, ref) {
8
- const {fill, size, style, ...rest} = useCommonSVGProps(props)
7
+ function VerifiedCheckImpl(props, ref) {
8
+ const {fill, size, style, gradient, ...rest} = useCommonSVGProps(props)
9
9
 
10
10
  return (
11
11
  <Svg
@@ -16,6 +16,7 @@ export const VerifiedCheck = forwardRef<Svg, Props>(
16
16
  width={size}
17
17
  height={size}
18
18
  style={[style]}>
19
+ {gradient}
19
20
  <Circle cx="12" cy="12" r="11.5" fill={fill} />
20
21
  <Path
21
22
  fill="#fff"
@@ -4,8 +4,8 @@ import Svg, {Path} from 'react-native-svg'
4
4
  import {type Props, useCommonSVGProps} from './common'
5
5
 
6
6
  export const VerifierCheck = forwardRef<Svg, Props>(
7
- function LogoImpl(props, ref) {
8
- const {fill, size, style, ...rest} = useCommonSVGProps(props)
7
+ function VerifierCheckImpl(props, ref) {
8
+ const {fill, size, style, gradient, ...rest} = useCommonSVGProps(props)
9
9
 
10
10
  return (
11
11
  <Svg
@@ -16,6 +16,7 @@ export const VerifierCheck = forwardRef<Svg, Props>(
16
16
  width={size}
17
17
  height={size}
18
18
  style={[style]}>
19
+ {gradient}
19
20
  <Path
20
21
  fill={fill}
21
22
  fillRule="evenodd"
@@ -58,7 +58,7 @@ export * from './Download';
58
58
  export * from './EditBig';
59
59
  export * from './Emoji';
60
60
  export * from './Envelope';
61
- export * from './EnveopeOpen';
61
+ export * from './EnvelopeOpen';
62
62
  export * from './Explosion';
63
63
  export * from './Eye';
64
64
  export * from './EyeSlash';
@@ -3,6 +3,7 @@ import { View, Text, StyleSheet, type DimensionValue } from 'react-native';
3
3
 
4
4
  import { useTheme } from '../theme/use-theme';
5
5
  import { animation } from '../styles/tokens';
6
+ import { lazyRequire } from '../utils/lazy-require';
6
7
  import { SpinnerIcon } from './SpinnerIcon';
7
8
  import type {
8
9
  LoadingProps,
@@ -20,24 +21,7 @@ const SIZE_CONFIG = {
20
21
 
21
22
  // Lazy-loaded reanimated for the top variant
22
23
  type ReanimatedType = typeof import('react-native-reanimated');
23
- let reanimatedModule: ReanimatedType | null = null;
24
- let reanimatedResolved = false;
25
-
26
- function getReanimated(): ReanimatedType | null {
27
- if (!reanimatedResolved) {
28
- reanimatedResolved = true;
29
- try {
30
- // Guard for ESM environments (Vite/browser) where require is not defined.
31
- if (typeof require !== 'undefined') {
32
- const moduleName = 'react-native-reanimated';
33
- reanimatedModule = require(moduleName);
34
- }
35
- } catch {
36
- reanimatedModule = null;
37
- }
38
- }
39
- return reanimatedModule;
40
- }
24
+ const getReanimated = lazyRequire<ReanimatedType>('react-native-reanimated');
41
25
 
42
26
  const SpinnerLoading: React.FC<SpinnerLoadingProps> = ({
43
27
  size = 'medium',
@@ -1,47 +1,15 @@
1
1
  import React, { useEffect } from 'react';
2
2
  import { ActivityIndicator, type ViewStyle } from 'react-native';
3
3
 
4
+ import { lazyRequire } from '../utils/lazy-require';
5
+
4
6
  // Lazy-loaded dependencies for the SVG spinner.
5
7
  // Falls back to ActivityIndicator if react-native-svg or react-native-reanimated are not installed.
6
8
  type SvgModuleType = typeof import('react-native-svg');
7
9
  type ReanimatedType = typeof import('react-native-reanimated');
8
10
 
9
- let svgModule: SvgModuleType | null = null;
10
- let svgModuleResolved = false;
11
- let reanimatedModule: ReanimatedType | null = null;
12
- let reanimatedResolved = false;
13
-
14
- function getSvgModule(): SvgModuleType | null {
15
- if (!svgModuleResolved) {
16
- svgModuleResolved = true;
17
- try {
18
- // Guard for ESM environments (Vite/browser) where require is not defined.
19
- if (typeof require !== 'undefined') {
20
- const moduleName = 'react-native-svg';
21
- svgModule = require(moduleName);
22
- }
23
- } catch {
24
- svgModule = null;
25
- }
26
- }
27
- return svgModule;
28
- }
29
-
30
- function getReanimated(): ReanimatedType | null {
31
- if (!reanimatedResolved) {
32
- reanimatedResolved = true;
33
- try {
34
- // Guard for ESM environments (Vite/browser) where require is not defined.
35
- if (typeof require !== 'undefined') {
36
- const moduleName = 'react-native-reanimated';
37
- reanimatedModule = require(moduleName);
38
- }
39
- } catch {
40
- reanimatedModule = null;
41
- }
42
- }
43
- return reanimatedModule;
44
- }
11
+ const getSvgModule = lazyRequire<SvgModuleType>('react-native-svg');
12
+ const getReanimated = lazyRequire<ReanimatedType>('react-native-reanimated');
45
13
 
46
14
  interface SpinnerIconProps {
47
15
  size?: number;
@@ -43,3 +43,4 @@ export function PromptInputActions({
43
43
  </View>
44
44
  );
45
45
  }
46
+ PromptInputActions.displayName = 'PromptInputActions';
@@ -262,3 +262,4 @@ export function PromptInputAttachments({
262
262
  </ScrollView>
263
263
  );
264
264
  }
265
+ PromptInputAttachments.displayName = 'PromptInputAttachments';
@@ -261,3 +261,4 @@ export function PromptInput({
261
261
  </PromptInputContext.Provider>
262
262
  );
263
263
  }
264
+ PromptInput.displayName = 'PromptInput';
@@ -72,3 +72,4 @@ export function PromptInputSubmitButton({
72
72
  </TouchableOpacity>
73
73
  );
74
74
  }
75
+ PromptInputSubmitButton.displayName = 'PromptInputSubmitButton';
@@ -100,3 +100,4 @@ export function PromptInputTextarea({
100
100
 
101
101
  return <View style={style}>{textInput}</View>;
102
102
  }
103
+ PromptInputTextarea.displayName = 'PromptInputTextarea';
@@ -152,3 +152,4 @@ export function PromptInputTextarea({
152
152
 
153
153
  return <View style={style}>{textInput}</View>;
154
154
  }
155
+ PromptInputTextarea.displayName = 'PromptInputTextarea';
@@ -70,3 +70,4 @@ export const SearchInput = forwardRef<TextInput, SearchInputProps>(
70
70
  );
71
71
  },
72
72
  );
73
+ SearchInput.displayName = 'SearchInput';
@@ -1,6 +1,5 @@
1
1
  import React, { memo } from 'react';
2
2
  import { View, Text, Pressable, StyleSheet } from 'react-native';
3
- import Svg, { Path } from 'react-native-svg';
4
3
 
5
4
  import { useTheme } from '../theme/use-theme';
6
5
  import type {
@@ -9,14 +8,19 @@ import type {
9
8
  SettingsListDividerProps,
10
9
  } from './types';
11
10
 
12
- // ── Chevron icon (inline to avoid external dependency) ──────────
11
+ // ── Chevron icon (unicode-based, no SVG dependency) ─────────────
13
12
  const Chevron = memo(({ size = 16, color }: { size?: number; color: string }) => (
14
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
15
- <Path
16
- d="M9.29 6.71c-.39.39-.39 1.02 0 1.41L13.17 12l-3.88 3.88c-.39.39-.39 1.02 0 1.41.39.39 1.02.39 1.41 0l4.59-4.59c.39-.39.39-1.02 0-1.41L10.7 6.7c-.38-.38-1.02-.38-1.41.01z"
17
- fill={color}
18
- />
19
- </Svg>
13
+ <Text
14
+ style={{
15
+ fontSize: size,
16
+ color,
17
+ lineHeight: size,
18
+ textAlign: 'center',
19
+ width: size,
20
+ }}
21
+ >
22
+ {'\u203A'}
23
+ </Text>
20
24
  ));
21
25
  Chevron.displayName = 'Chevron';
22
26
 
@@ -65,6 +65,7 @@ export function Text({
65
65
  </View>
66
66
  );
67
67
  }
68
+ Text.displayName = 'Skeleton.Text';
68
69
 
69
70
  export function Circle({
70
71
  children,
@@ -96,6 +97,7 @@ export function Circle({
96
97
  </Animated.View>
97
98
  );
98
99
  }
100
+ Circle.displayName = 'Skeleton.Circle';
99
101
 
100
102
  export function Pill({
101
103
  size,
@@ -124,6 +126,7 @@ export function Pill({
124
126
  />
125
127
  );
126
128
  }
129
+ Pill.displayName = 'Skeleton.Pill';
127
130
 
128
131
  export function Col({
129
132
  children,
@@ -134,6 +137,7 @@ export function Col({
134
137
  }) {
135
138
  return <View style={[styles.col, style]}>{children}</View>;
136
139
  }
140
+ Col.displayName = 'Skeleton.Col';
137
141
 
138
142
  export function Row({
139
143
  children,
@@ -144,6 +148,7 @@ export function Row({
144
148
  }) {
145
149
  return <View style={[styles.row, style]}>{children}</View>;
146
150
  }
151
+ Row.displayName = 'Skeleton.Row';
147
152
 
148
153
  const styles = StyleSheet.create({
149
154
  textOuter: {