@idealyst/components 1.0.82 → 1.0.84

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 (316) hide show
  1. package/CLAUDE.md +199 -232
  2. package/README.md +5 -5
  3. package/package.json +25 -7
  4. package/plugin/README.md +272 -0
  5. package/plugin/test-cases.jsx +112 -0
  6. package/plugin/web-legacy.js +320 -0
  7. package/plugin/web.js +422 -124
  8. package/src/Accordion/Accordion.native.tsx +182 -0
  9. package/src/Accordion/Accordion.styles.tsx +260 -0
  10. package/src/Accordion/Accordion.web.tsx +147 -0
  11. package/src/Accordion/index.native.tsx +3 -0
  12. package/src/Accordion/index.ts +3 -0
  13. package/src/Accordion/index.web.tsx +3 -0
  14. package/src/Accordion/types.ts +23 -0
  15. package/src/ActivityIndicator/ActivityIndicator.native.tsx +17 -12
  16. package/src/ActivityIndicator/ActivityIndicator.styles.tsx +83 -109
  17. package/src/ActivityIndicator/ActivityIndicator.web.tsx +23 -17
  18. package/src/ActivityIndicator/index.ts +5 -2
  19. package/src/ActivityIndicator/index.web.ts +5 -2
  20. package/src/ActivityIndicator/types.ts +15 -10
  21. package/src/Alert/Alert.native.tsx +113 -0
  22. package/src/Alert/Alert.styles.tsx +304 -0
  23. package/src/Alert/Alert.web.tsx +123 -0
  24. package/src/Alert/index.native.ts +5 -0
  25. package/src/Alert/index.ts +5 -0
  26. package/src/Alert/index.web.ts +5 -0
  27. package/src/Alert/types.ts +21 -0
  28. package/src/Avatar/Avatar.native.tsx +8 -6
  29. package/src/Avatar/Avatar.styles.tsx +64 -58
  30. package/src/Avatar/Avatar.web.tsx +13 -8
  31. package/src/Avatar/index.ts +5 -2
  32. package/src/Avatar/index.web.ts +5 -2
  33. package/src/Avatar/types.ts +19 -13
  34. package/src/Badge/Badge.native.tsx +59 -14
  35. package/src/Badge/Badge.styles.tsx +125 -139
  36. package/src/Badge/Badge.web.tsx +72 -16
  37. package/src/Badge/index.ts +5 -2
  38. package/src/Badge/index.web.ts +5 -2
  39. package/src/Badge/types.ts +23 -11
  40. package/src/Breadcrumb/Breadcrumb.native.tsx +225 -0
  41. package/src/Breadcrumb/Breadcrumb.styles.tsx +234 -0
  42. package/src/Breadcrumb/Breadcrumb.web.tsx +268 -0
  43. package/src/Breadcrumb/index.native.ts +5 -0
  44. package/src/Breadcrumb/index.ts +5 -0
  45. package/src/Breadcrumb/index.web.ts +5 -0
  46. package/src/Breadcrumb/types.ts +56 -0
  47. package/src/Button/Button.native.tsx +75 -24
  48. package/src/Button/Button.styles.tsx +248 -205
  49. package/src/Button/Button.web.tsx +82 -25
  50. package/src/Button/index.ts +5 -5
  51. package/src/Button/index.web.ts +5 -3
  52. package/src/Button/types.ts +32 -15
  53. package/src/Card/Card.native.tsx +14 -11
  54. package/src/Card/Card.styles.tsx +146 -220
  55. package/src/Card/Card.web.tsx +20 -21
  56. package/src/Card/index.ts +5 -5
  57. package/src/Card/index.web.ts +5 -3
  58. package/src/Card/types.ts +24 -17
  59. package/src/Checkbox/Checkbox.native.tsx +24 -34
  60. package/src/Checkbox/Checkbox.styles.tsx +223 -275
  61. package/src/Checkbox/Checkbox.web.tsx +30 -37
  62. package/src/Checkbox/index.ts +5 -5
  63. package/src/Checkbox/index.web.ts +5 -3
  64. package/src/Checkbox/types.ts +26 -20
  65. package/src/Chip/Chip.native.tsx +126 -0
  66. package/src/Chip/Chip.styles.tsx +138 -0
  67. package/src/Chip/Chip.web.tsx +154 -0
  68. package/src/Chip/index.native.ts +5 -0
  69. package/src/Chip/index.ts +5 -0
  70. package/src/Chip/index.web.ts +5 -0
  71. package/src/Chip/types.ts +51 -0
  72. package/src/Dialog/Dialog.native.tsx +65 -12
  73. package/src/Dialog/Dialog.styles.tsx +154 -136
  74. package/src/Dialog/Dialog.web.tsx +16 -11
  75. package/src/Dialog/index.ts +5 -2
  76. package/src/Dialog/index.web.ts +5 -2
  77. package/src/Dialog/types.ts +22 -16
  78. package/src/Divider/Divider.native.tsx +19 -14
  79. package/src/Divider/Divider.styles.tsx +273 -595
  80. package/src/Divider/Divider.web.tsx +19 -12
  81. package/src/Divider/index.ts +5 -5
  82. package/src/Divider/index.web.ts +5 -3
  83. package/src/Divider/types.ts +28 -19
  84. package/src/Icon/Icon.native.tsx +17 -24
  85. package/src/Icon/Icon.styles.tsx +64 -48
  86. package/src/Icon/Icon.web.tsx +14 -11
  87. package/src/Icon/IconSvg/IconSvg.native.tsx +42 -0
  88. package/src/Icon/IconSvg/IconSvg.web.tsx +40 -0
  89. package/src/Icon/IconSvg/index.native.ts +1 -0
  90. package/src/Icon/IconSvg/index.ts +1 -0
  91. package/src/Icon/icon-resolver.native.ts +27 -0
  92. package/src/Icon/icon-resolver.ts +70 -0
  93. package/src/Icon/index.ts +5 -5
  94. package/src/Icon/index.web.ts +5 -3
  95. package/src/Icon/types.ts +17 -11
  96. package/src/Image/Image.native.tsx +86 -0
  97. package/src/Image/Image.styles.tsx +57 -0
  98. package/src/Image/Image.web.tsx +92 -0
  99. package/src/Image/index.native.ts +5 -0
  100. package/src/Image/index.ts +5 -0
  101. package/src/Image/types.ts +21 -0
  102. package/src/Input/Input.native.tsx +103 -26
  103. package/src/Input/Input.styles.tsx +240 -177
  104. package/src/Input/Input.web.tsx +141 -38
  105. package/src/Input/index.ts +5 -5
  106. package/src/Input/index.web.ts +5 -3
  107. package/src/Input/types.ts +43 -20
  108. package/src/List/List.native.tsx +56 -0
  109. package/src/List/List.styles.tsx +257 -0
  110. package/src/List/List.web.tsx +43 -0
  111. package/src/List/ListContext.tsx +16 -0
  112. package/src/List/ListItem.native.tsx +111 -0
  113. package/src/List/ListItem.web.tsx +110 -0
  114. package/src/List/ListSection.native.tsx +31 -0
  115. package/src/List/ListSection.web.tsx +33 -0
  116. package/src/List/index.native.tsx +5 -0
  117. package/src/List/index.ts +5 -0
  118. package/src/List/index.web.tsx +5 -0
  119. package/src/List/types.ts +42 -0
  120. package/src/Menu/Menu.native.tsx +150 -0
  121. package/src/Menu/Menu.styles.tsx +185 -0
  122. package/src/Menu/Menu.web.tsx +99 -0
  123. package/src/Menu/MenuItem.native.tsx +66 -0
  124. package/src/Menu/MenuItem.styles.tsx +119 -0
  125. package/src/Menu/MenuItem.web.tsx +67 -0
  126. package/src/Menu/index.native.ts +3 -0
  127. package/src/Menu/index.ts +3 -0
  128. package/src/Menu/index.web.ts +3 -0
  129. package/src/Menu/types.ts +30 -0
  130. package/src/Popover/Popover.native.tsx +102 -32
  131. package/src/Popover/Popover.styles.tsx +100 -67
  132. package/src/Popover/Popover.web.tsx +36 -260
  133. package/src/Popover/index.ts +5 -2
  134. package/src/Popover/index.web.ts +5 -2
  135. package/src/Popover/types.ts +14 -13
  136. package/src/Pressable/Pressable.native.tsx +7 -6
  137. package/src/Pressable/Pressable.web.tsx +8 -6
  138. package/src/Pressable/index.ts +5 -2
  139. package/src/Pressable/index.web.ts +5 -2
  140. package/src/Pressable/types.ts +11 -10
  141. package/src/Progress/Progress.native.tsx +179 -0
  142. package/src/Progress/Progress.styles.tsx +164 -0
  143. package/src/Progress/Progress.web.tsx +144 -0
  144. package/src/Progress/index.native.ts +1 -0
  145. package/src/Progress/index.ts +5 -0
  146. package/src/Progress/index.web.ts +5 -0
  147. package/src/Progress/types.ts +21 -0
  148. package/src/RadioButton/RadioButton.native.tsx +88 -0
  149. package/src/RadioButton/RadioButton.styles.tsx +163 -0
  150. package/src/RadioButton/RadioButton.web.tsx +85 -0
  151. package/src/RadioButton/RadioGroup.native.tsx +43 -0
  152. package/src/RadioButton/RadioGroup.web.tsx +49 -0
  153. package/src/RadioButton/index.native.ts +2 -0
  154. package/src/RadioButton/index.ts +2 -0
  155. package/src/RadioButton/index.web.ts +2 -0
  156. package/src/RadioButton/types.ts +29 -0
  157. package/src/SVGImage/SVGImage.native.tsx +9 -7
  158. package/src/SVGImage/SVGImage.styles.tsx +63 -55
  159. package/src/SVGImage/SVGImage.web.tsx +16 -13
  160. package/src/SVGImage/index.ts +5 -5
  161. package/src/SVGImage/index.web.ts +5 -2
  162. package/src/SVGImage/types.ts +7 -3
  163. package/src/Screen/Screen.native.tsx +43 -17
  164. package/src/Screen/Screen.styles.tsx +58 -54
  165. package/src/Screen/Screen.web.tsx +11 -5
  166. package/src/Screen/index.ts +5 -2
  167. package/src/Screen/index.web.ts +5 -2
  168. package/src/Screen/types.ts +23 -9
  169. package/src/Select/Select.native.tsx +347 -0
  170. package/src/Select/Select.styles.tsx +335 -0
  171. package/src/Select/Select.web.tsx +276 -0
  172. package/src/Select/index.native.ts +2 -0
  173. package/src/Select/index.ts +5 -0
  174. package/src/Select/index.web.ts +5 -0
  175. package/src/Select/types.ts +124 -0
  176. package/src/Skeleton/Skeleton.native.tsx +139 -0
  177. package/src/Skeleton/Skeleton.styles.tsx +59 -0
  178. package/src/Skeleton/Skeleton.web.tsx +112 -0
  179. package/src/Skeleton/index.native.ts +4 -0
  180. package/src/Skeleton/index.ts +5 -0
  181. package/src/Skeleton/index.web.ts +5 -0
  182. package/src/Skeleton/types.ts +75 -0
  183. package/src/Slider/Slider.native.tsx +248 -0
  184. package/src/Slider/Slider.styles.tsx +241 -0
  185. package/src/Slider/Slider.web.tsx +226 -0
  186. package/src/Slider/index.native.ts +3 -0
  187. package/src/Slider/index.ts +5 -0
  188. package/src/Slider/index.web.ts +5 -0
  189. package/src/Slider/types.ts +31 -0
  190. package/src/Switch/Switch.native.tsx +131 -0
  191. package/src/Switch/Switch.styles.tsx +169 -0
  192. package/src/Switch/Switch.web.tsx +121 -0
  193. package/src/Switch/index.native.ts +3 -0
  194. package/src/Switch/index.ts +5 -0
  195. package/src/Switch/index.web.ts +5 -0
  196. package/src/Switch/types.ts +21 -0
  197. package/src/TabBar/TabBar.native.tsx +142 -0
  198. package/src/TabBar/TabBar.styles.tsx +399 -0
  199. package/src/TabBar/TabBar.web.tsx +205 -0
  200. package/src/TabBar/index.native.tsx +3 -0
  201. package/src/TabBar/index.ts +3 -0
  202. package/src/TabBar/index.web.tsx +3 -0
  203. package/src/TabBar/types.ts +26 -0
  204. package/src/Table/Table.native.tsx +122 -0
  205. package/src/Table/Table.styles.tsx +283 -0
  206. package/src/Table/Table.web.tsx +112 -0
  207. package/src/Table/index.native.tsx +3 -0
  208. package/src/Table/index.ts +3 -0
  209. package/src/Table/index.web.tsx +3 -0
  210. package/src/Table/types.ts +28 -0
  211. package/src/Text/Text.native.tsx +12 -11
  212. package/src/Text/Text.styles.tsx +76 -64
  213. package/src/Text/Text.web.tsx +14 -9
  214. package/src/Text/index.ts +5 -5
  215. package/src/Text/index.web.ts +5 -3
  216. package/src/Text/types.ts +20 -13
  217. package/src/TextArea/TextArea.native.tsx +134 -0
  218. package/src/TextArea/TextArea.styles.tsx +175 -0
  219. package/src/TextArea/TextArea.web.tsx +156 -0
  220. package/src/TextArea/index.native.ts +3 -0
  221. package/src/TextArea/index.ts +3 -0
  222. package/src/TextArea/index.web.ts +3 -0
  223. package/src/TextArea/types.ts +30 -0
  224. package/src/Tooltip/Tooltip.native.tsx +165 -0
  225. package/src/Tooltip/Tooltip.styles.tsx +73 -0
  226. package/src/Tooltip/Tooltip.web.tsx +87 -0
  227. package/src/Tooltip/index.native.ts +3 -0
  228. package/src/Tooltip/index.ts +3 -0
  229. package/src/Tooltip/types.ts +18 -0
  230. package/src/Video/Video.native.tsx +105 -0
  231. package/src/Video/Video.styles.tsx +39 -0
  232. package/src/Video/Video.web.tsx +115 -0
  233. package/src/Video/index.native.ts +5 -0
  234. package/src/Video/index.ts +5 -0
  235. package/src/Video/types.ts +29 -0
  236. package/src/View/View.native.tsx +9 -14
  237. package/src/View/View.styles.tsx +101 -93
  238. package/src/View/View.web.tsx +16 -17
  239. package/src/View/index.ts +5 -5
  240. package/src/View/index.web.ts +5 -3
  241. package/src/View/types.ts +29 -21
  242. package/src/examples/AccordionExamples.tsx +126 -0
  243. package/src/examples/AlertExamples.tsx +280 -0
  244. package/src/examples/AvatarExamples.tsx +23 -23
  245. package/src/examples/BadgeExamples.tsx +109 -41
  246. package/src/examples/BreadcrumbExamples.tsx +312 -0
  247. package/src/examples/ButtonExamples.tsx +160 -33
  248. package/src/examples/CardExamples.tsx +40 -40
  249. package/src/examples/CheckboxExamples.tsx +12 -12
  250. package/src/examples/ChipExamples.tsx +197 -0
  251. package/src/examples/DialogExamples.tsx +22 -22
  252. package/src/examples/DividerExamples.tsx +49 -49
  253. package/src/examples/IconExamples.tsx +270 -54
  254. package/src/examples/ImageExamples.tsx +174 -0
  255. package/src/examples/InputExamples.tsx +75 -17
  256. package/src/examples/ListExamples.tsx +288 -0
  257. package/src/examples/MenuExamples.tsx +144 -0
  258. package/src/examples/PopoverExamples.tsx +69 -73
  259. package/src/examples/ProgressExamples.tsx +137 -0
  260. package/src/examples/RadioButtonExamples.tsx +161 -0
  261. package/src/examples/SVGImageExamples.tsx +19 -17
  262. package/src/examples/ScreenExamples.tsx +31 -31
  263. package/src/examples/SelectExamples.tsx +423 -0
  264. package/src/examples/SkeletonExamples.tsx +206 -0
  265. package/src/examples/SliderExamples.tsx +200 -0
  266. package/src/examples/SwitchExamples.tsx +182 -0
  267. package/src/examples/TabBarExamples.tsx +143 -0
  268. package/src/examples/TableExamples.tsx +280 -0
  269. package/src/examples/TextAreaExamples.tsx +173 -0
  270. package/src/examples/TextExamples.tsx +28 -32
  271. package/src/examples/ThemeExtensionExamples.tsx +10 -10
  272. package/src/examples/TooltipExamples.tsx +126 -0
  273. package/src/examples/VideoExamples.tsx +144 -0
  274. package/src/examples/ViewExamples.tsx +64 -56
  275. package/src/examples/index.ts +18 -3
  276. package/src/hooks/useMergeRefs.ts +16 -0
  277. package/src/hooks/useSmartPosition.native.ts +169 -0
  278. package/src/index.native.ts +80 -9
  279. package/src/index.ts +75 -1
  280. package/src/internal/BoundedModalContent.native.tsx +58 -0
  281. package/src/internal/PositionedPortal.tsx +254 -0
  282. package/src/internal/SafeAreaDebugOverlay.native.tsx +173 -0
  283. package/src/unistyles.d.ts +6 -0
  284. package/src/utils/buildSizeVariants.ts +16 -0
  285. package/src/utils/deepMerge.ts +43 -0
  286. package/src/utils/positionUtils.native.ts +280 -0
  287. package/src/utils/styleHelpers.ts +48 -0
  288. package/LLM-ACCESS-GUIDE.md +0 -143
  289. package/src/ActivityIndicator/README.md +0 -132
  290. package/src/Avatar/README.md +0 -139
  291. package/src/Badge/README.md +0 -170
  292. package/src/Button/Button.types.ts +0 -12
  293. package/src/Button/README.md +0 -262
  294. package/src/Card/README.md +0 -258
  295. package/src/Checkbox/README.md +0 -102
  296. package/src/Dialog/README.md +0 -210
  297. package/src/Divider/README.md +0 -108
  298. package/src/Icon/README.md +0 -81
  299. package/src/Input/README.md +0 -100
  300. package/src/SVGImage/README.md +0 -209
  301. package/src/Screen/README.md +0 -86
  302. package/src/Text/README.md +0 -94
  303. package/src/View/README.md +0 -107
  304. package/src/examples/AllExamples.tsx +0 -84
  305. package/src/examples/README.md +0 -136
  306. package/src/examples/ValidationExamples.tsx +0 -95
  307. package/src/examples/extendedTheme.ts +0 -329
  308. package/src/theme/breakpoints.ts +0 -8
  309. package/src/theme/colorResolver.ts +0 -218
  310. package/src/theme/colors.ts +0 -315
  311. package/src/theme/defaultThemes.ts +0 -326
  312. package/src/theme/index.ts +0 -188
  313. package/src/theme/themeBuilder.ts +0 -602
  314. package/src/theme/unistyles.d.ts +0 -6
  315. package/src/theme/variantHelpers.ts +0 -584
  316. package/src/theme/variants.ts +0 -56
@@ -7,9 +7,13 @@ export * from './Text/types';
7
7
  export { default as View } from './View';
8
8
  export * from './View/types';
9
9
 
10
+ export { default as Pressable } from './Pressable';
11
+ export * from './Pressable/types';
12
+
10
13
  export { default as Input } from './Input';
11
14
  export * from './Input/types';
12
15
 
16
+ // New primitive components
13
17
  export { default as Checkbox } from './Checkbox';
14
18
  export * from './Checkbox/types';
15
19
 
@@ -40,8 +44,62 @@ export * from './Dialog/types';
40
44
  export { default as Popover } from './Popover';
41
45
  export * from './Popover/types';
42
46
 
43
- export { default as Pressable } from './Pressable';
44
- export * from './Pressable/types';
47
+ export { default as ActivityIndicator } from './ActivityIndicator';
48
+ export * from './ActivityIndicator/types';
49
+
50
+ export { default as Select } from './Select';
51
+ export * from './Select/types';
52
+
53
+ export { default as Slider } from './Slider';
54
+ export * from './Slider/types';
55
+
56
+ export { default as Switch } from './Switch';
57
+ export * from './Switch/types';
58
+
59
+ export { RadioButton, RadioGroup } from './RadioButton';
60
+ export * from './RadioButton/types';
61
+
62
+ export { default as Progress } from './Progress';
63
+ export * from './Progress/types';
64
+
65
+ export { default as TextArea } from './TextArea';
66
+ export * from './TextArea/types';
67
+
68
+ export { default as TabBar } from './TabBar';
69
+ export * from './TabBar/types';
70
+
71
+ export { default as Tooltip } from './Tooltip';
72
+ export * from './Tooltip/types';
73
+
74
+ export { default as Accordion } from './Accordion';
75
+ export * from './Accordion/types';
76
+
77
+ export { List, ListItem, ListSection } from './List';
78
+ export * from './List/types';
79
+
80
+ export { default as Table } from './Table';
81
+ export * from './Table/types';
82
+
83
+ export { default as Menu } from './Menu';
84
+ export * from './Menu/types';
85
+
86
+ export { default as Image } from './Image';
87
+ export * from './Image/types';
88
+
89
+ export { default as Video } from './Video';
90
+ export * from './Video/types';
91
+
92
+ export { default as Alert } from './Alert';
93
+ export * from './Alert/types';
94
+
95
+ export { default as Skeleton, SkeletonGroup } from './Skeleton';
96
+ export * from './Skeleton/types';
97
+
98
+ export { default as Chip } from './Chip';
99
+ export * from './Chip/types';
100
+
101
+ export { default as Breadcrumb } from './Breadcrumb';
102
+ export * from './Breadcrumb/types';
45
103
 
46
104
  export type { ButtonProps } from './Button/types';
47
105
  export type { TextProps } from './Text/types';
@@ -57,10 +115,23 @@ export type { IconProps } from './Icon/types';
57
115
  export type { SVGImageProps } from './SVGImage/types';
58
116
  export type { DialogProps } from './Dialog/types';
59
117
  export type { PopoverProps } from './Popover/types';
60
- export type { PressableProps } from './Pressable/types';
61
-
62
- export { appThemes, breakpoints } from './theme';
63
- export type { AppThemes, AppBreakpoints } from './theme';
64
-
65
- // Theme provider for managing theme state (removed - using Unistyles Runtime directly)
66
- // export { ThemeProvider, useTheme } from './theme/ThemeProvider';
118
+ export type { ActivityIndicatorProps } from './ActivityIndicator/types';
119
+ export type { SelectProps } from './Select/types';
120
+ export type { SwitchProps } from './Switch/types';
121
+ export type { RadioButtonProps, RadioGroupProps } from './RadioButton/types';
122
+ export type { ProgressProps } from './Progress/types';
123
+ export type { TextAreaProps } from './TextArea/types';
124
+ export type { TabBarProps, TabBarItem } from './TabBar/types';
125
+ export type { TooltipProps } from './Tooltip/types';
126
+ export type { AccordionProps, AccordionItem } from './Accordion/types';
127
+ export type { ListProps, ListItemProps, ListSectionProps } from './List/types';
128
+ export type { TableProps, TableColumn } from './Table/types';
129
+ export type { MenuProps, MenuItem } from './Menu/types';
130
+ export type { ImageProps } from './Image/types';
131
+ export type { VideoProps, VideoSource } from './Video/types';
132
+ export type { AlertProps } from './Alert/types';
133
+ export type { SkeletonProps, SkeletonGroupProps, SkeletonShape, SkeletonAnimation } from './Skeleton/types';
134
+ export type { ChipProps, ChipSize, ChipIntent } from './Chip/types';
135
+ export type { BreadcrumbProps, BreadcrumbItem } from './Breadcrumb/types';
136
+
137
+ export type { AppTheme } from '@idealyst/theme';
package/src/index.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import useMergeRefs from './hooks/useMergeRefs';
2
+
1
3
  export { default as Button } from './Button';
2
4
  export * from './Button/types';
3
5
 
@@ -47,6 +49,60 @@ export * from './Popover/types';
47
49
  export { default as ActivityIndicator } from './ActivityIndicator';
48
50
  export * from './ActivityIndicator/types';
49
51
 
52
+ export { default as Select } from './Select';
53
+ export * from './Select/types';
54
+
55
+ export { default as Slider } from './Slider';
56
+ export * from './Slider/types';
57
+
58
+ export { default as Switch } from './Switch';
59
+ export * from './Switch/types';
60
+
61
+ export { RadioButton, RadioGroup } from './RadioButton';
62
+ export * from './RadioButton/types';
63
+
64
+ export { default as Progress } from './Progress';
65
+ export * from './Progress/types';
66
+
67
+ export { default as TextArea } from './TextArea';
68
+ export * from './TextArea/types';
69
+
70
+ export { default as TabBar } from './TabBar';
71
+ export * from './TabBar/types';
72
+
73
+ export { default as Tooltip } from './Tooltip';
74
+ export * from './Tooltip/types';
75
+
76
+ export { default as Accordion } from './Accordion';
77
+ export * from './Accordion/types';
78
+
79
+ export { List, ListItem, ListSection } from './List';
80
+ export * from './List/types';
81
+
82
+ export { default as Table } from './Table';
83
+ export * from './Table/types';
84
+
85
+ export { default as Menu } from './Menu';
86
+ export * from './Menu/types';
87
+
88
+ export { default as Image } from './Image';
89
+ export * from './Image/types';
90
+
91
+ export { default as Video } from './Video';
92
+ export * from './Video/types';
93
+
94
+ export { default as Alert } from './Alert';
95
+ export * from './Alert/types';
96
+
97
+ export { default as Skeleton, SkeletonGroup } from './Skeleton';
98
+ export * from './Skeleton/types';
99
+
100
+ export { default as Chip } from './Chip';
101
+ export * from './Chip/types';
102
+
103
+ export { default as Breadcrumb } from './Breadcrumb';
104
+ export * from './Breadcrumb/types';
105
+
50
106
  export type { ButtonProps } from './Button/types';
51
107
  export type { TextProps } from './Text/types';
52
108
  export type { ViewProps } from './View/types';
@@ -62,6 +118,24 @@ export type { SVGImageProps } from './SVGImage/types';
62
118
  export type { DialogProps } from './Dialog/types';
63
119
  export type { PopoverProps } from './Popover/types';
64
120
  export type { ActivityIndicatorProps } from './ActivityIndicator/types';
121
+ export type { SelectProps } from './Select/types';
122
+ export type { SwitchProps } from './Switch/types';
123
+ export type { RadioButtonProps, RadioGroupProps } from './RadioButton/types';
124
+ export type { ProgressProps } from './Progress/types';
125
+ export type { TextAreaProps } from './TextArea/types';
126
+ export type { TabBarProps, TabBarItem } from './TabBar/types';
127
+ export type { TooltipProps } from './Tooltip/types';
128
+ export type { AccordionProps, AccordionItem } from './Accordion/types';
129
+ export type { ListProps, ListItemProps, ListSectionProps } from './List/types';
130
+ export type { TableProps, TableColumn } from './Table/types';
131
+ export type { MenuProps, MenuItem } from './Menu/types';
132
+ export type { ImageProps } from './Image/types';
133
+ export type { VideoProps, VideoSource } from './Video/types';
134
+ export type { AlertProps } from './Alert/types';
135
+ export type { SkeletonProps, SkeletonGroupProps, SkeletonShape, SkeletonAnimation } from './Skeleton/types';
136
+ export type { ChipProps, ChipSize, ChipIntent } from './Chip/types';
137
+ export type { BreadcrumbProps, BreadcrumbItem } from './Breadcrumb/types';
138
+
139
+ export { useMergeRefs };
65
140
 
66
- export { breakpoints } from '@idealyst/theme';
67
141
  export type { AppTheme } from '@idealyst/theme';
@@ -0,0 +1,58 @@
1
+ import React, { ReactNode } from 'react';
2
+ import { View, Dimensions, StyleProp, ViewStyle } from 'react-native';
3
+ import { useSafeAreaInsets } from 'react-native-safe-area-context';
4
+
5
+ interface BoundedModalContentProps {
6
+ children: ReactNode;
7
+ top: number;
8
+ left: number;
9
+ width?: number;
10
+ maxHeight?: number;
11
+ style?: StyleProp<ViewStyle>;
12
+ onLayout?: (event: any) => void;
13
+ }
14
+
15
+ /**
16
+ * A wrapper component for modal content that automatically constrains its height
17
+ * to fit within screen boundaries, accounting for safe areas.
18
+ */
19
+ export const BoundedModalContent: React.FC<BoundedModalContentProps> = ({
20
+ children,
21
+ top,
22
+ left,
23
+ width,
24
+ maxHeight = 500,
25
+ style,
26
+ onLayout,
27
+ }) => {
28
+ const insets = useSafeAreaInsets();
29
+ const { height: windowHeight } = Dimensions.get('window');
30
+ const padding = 12;
31
+
32
+ // Calculate dynamic maxHeight to ensure content stays within bounds
33
+ // The safe area goes from the top of the window to windowHeight - insets.bottom
34
+ // We then subtract padding from available space for visual breathing room
35
+ const bottomSafeEdge = windowHeight - insets.bottom;
36
+ const bottomBound = bottomSafeEdge - padding;
37
+
38
+ // Calculate available height: from current top position to bottom boundary
39
+ const availableHeight = Math.max(100, bottomBound - top);
40
+
41
+ return (
42
+ <View
43
+ style={[
44
+ {
45
+ position: 'absolute',
46
+ top,
47
+ left,
48
+ ...(width && { width }),
49
+ maxHeight: availableHeight,
50
+ },
51
+ style,
52
+ ]}
53
+ onLayout={onLayout}
54
+ >
55
+ {children}
56
+ </View>
57
+ );
58
+ };
@@ -0,0 +1,254 @@
1
+ import React, { useRef, useState, useEffect, useLayoutEffect, useCallback, ReactNode } from 'react';
2
+ import { createPortal } from 'react-dom';
3
+
4
+ export type Placement =
5
+ | 'top' | 'top-start' | 'top-end'
6
+ | 'bottom' | 'bottom-start' | 'bottom-end'
7
+ | 'left' | 'left-start' | 'left-end'
8
+ | 'right' | 'right-start' | 'right-end';
9
+
10
+ interface PositionedPortalProps {
11
+ open: boolean;
12
+ anchor: React.RefObject<HTMLElement>;
13
+ children: ReactNode;
14
+ placement?: Placement;
15
+ offset?: number;
16
+ onClickOutside?: () => void;
17
+ onEscapeKey?: () => void;
18
+ matchWidth?: boolean;
19
+ zIndex?: number;
20
+ }
21
+
22
+ interface Position {
23
+ top: number;
24
+ left: number;
25
+ width?: number;
26
+ }
27
+
28
+ const calculatePosition = (
29
+ anchorRect: DOMRect,
30
+ contentSize: { width: number; height: number },
31
+ placement: Placement,
32
+ offset: number,
33
+ matchWidth: boolean
34
+ ): Position => {
35
+ const viewport = {
36
+ width: window.innerWidth,
37
+ height: window.innerHeight,
38
+ scrollX: window.scrollX,
39
+ scrollY: window.scrollY,
40
+ };
41
+
42
+ let position: Position = { top: 0, left: 0 };
43
+
44
+ // Calculate initial position based on placement
45
+ switch (placement) {
46
+ case 'top':
47
+ position = {
48
+ top: anchorRect.top + viewport.scrollY - contentSize.height - offset,
49
+ left: anchorRect.left + viewport.scrollX + anchorRect.width / 2 - contentSize.width / 2,
50
+ };
51
+ break;
52
+ case 'top-start':
53
+ position = {
54
+ top: anchorRect.top + viewport.scrollY - contentSize.height - offset,
55
+ left: anchorRect.left + viewport.scrollX,
56
+ };
57
+ break;
58
+ case 'top-end':
59
+ position = {
60
+ top: anchorRect.top + viewport.scrollY - contentSize.height - offset,
61
+ left: anchorRect.right + viewport.scrollX - contentSize.width,
62
+ };
63
+ break;
64
+ case 'bottom':
65
+ position = {
66
+ top: anchorRect.bottom + viewport.scrollY + offset,
67
+ left: anchorRect.left + viewport.scrollX + anchorRect.width / 2 - contentSize.width / 2,
68
+ };
69
+ break;
70
+ case 'bottom-start':
71
+ position = {
72
+ top: anchorRect.bottom + viewport.scrollY + offset,
73
+ left: anchorRect.left + viewport.scrollX,
74
+ };
75
+ break;
76
+ case 'bottom-end':
77
+ position = {
78
+ top: anchorRect.bottom + viewport.scrollY + offset,
79
+ left: anchorRect.right + viewport.scrollX - contentSize.width,
80
+ };
81
+ break;
82
+ case 'left':
83
+ position = {
84
+ top: anchorRect.top + viewport.scrollY + anchorRect.height / 2 - contentSize.height / 2,
85
+ left: anchorRect.left + viewport.scrollX - contentSize.width - offset,
86
+ };
87
+ break;
88
+ case 'left-start':
89
+ position = {
90
+ top: anchorRect.top + viewport.scrollY,
91
+ left: anchorRect.left + viewport.scrollX - contentSize.width - offset,
92
+ };
93
+ break;
94
+ case 'left-end':
95
+ position = {
96
+ top: anchorRect.bottom + viewport.scrollY - contentSize.height,
97
+ left: anchorRect.left + viewport.scrollX - contentSize.width - offset,
98
+ };
99
+ break;
100
+ case 'right':
101
+ position = {
102
+ top: anchorRect.top + viewport.scrollY + anchorRect.height / 2 - contentSize.height / 2,
103
+ left: anchorRect.right + viewport.scrollX + offset,
104
+ };
105
+ break;
106
+ case 'right-start':
107
+ position = {
108
+ top: anchorRect.top + viewport.scrollY,
109
+ left: anchorRect.right + viewport.scrollX + offset,
110
+ };
111
+ break;
112
+ case 'right-end':
113
+ position = {
114
+ top: anchorRect.bottom + viewport.scrollY - contentSize.height,
115
+ left: anchorRect.right + viewport.scrollX + offset,
116
+ };
117
+ break;
118
+ }
119
+
120
+ // Match anchor width if requested
121
+ if (matchWidth) {
122
+ position.width = anchorRect.width;
123
+ }
124
+
125
+ // Constrain to viewport
126
+ const padding = 8;
127
+ position.left = Math.max(padding, Math.min(position.left, viewport.width - contentSize.width - padding));
128
+ position.top = Math.max(padding, Math.min(position.top, viewport.height + viewport.scrollY - contentSize.height - padding));
129
+
130
+ return position;
131
+ };
132
+
133
+ export const PositionedPortal: React.FC<PositionedPortalProps> = ({
134
+ open,
135
+ anchor,
136
+ children,
137
+ placement = 'bottom-start',
138
+ offset = 4,
139
+ onClickOutside,
140
+ onEscapeKey,
141
+ matchWidth = false,
142
+ zIndex = 1000,
143
+ }) => {
144
+ const contentRef = useRef<HTMLDivElement>(null);
145
+ const [position, setPosition] = useState<Position>({ top: 0, left: 0 });
146
+ const [isPositioned, setIsPositioned] = useState(false);
147
+
148
+ // Calculate position
149
+ const updatePosition = useCallback(() => {
150
+ if (!contentRef.current || !anchor.current) {
151
+ return;
152
+ }
153
+
154
+ const anchorRect = anchor.current.getBoundingClientRect();
155
+ const contentRect = contentRef.current.getBoundingClientRect();
156
+
157
+ // Use actual measured size from the DOM
158
+ const newPosition = calculatePosition(
159
+ anchorRect,
160
+ { width: contentRect.width, height: contentRect.height },
161
+ placement,
162
+ offset,
163
+ matchWidth
164
+ );
165
+
166
+ setPosition(newPosition);
167
+ setIsPositioned(true);
168
+ }, [anchor, placement, offset, matchWidth]);
169
+
170
+ // Position after DOM is ready
171
+ useLayoutEffect(() => {
172
+ if (open) {
173
+ // Use requestAnimationFrame to ensure ref is attached and layout is complete
174
+ const rafId = requestAnimationFrame(() => {
175
+ if (contentRef.current && anchor.current) {
176
+ updatePosition();
177
+ }
178
+ });
179
+ return () => cancelAnimationFrame(rafId);
180
+ } else {
181
+ setIsPositioned(false);
182
+ }
183
+ }, [open, updatePosition]);
184
+
185
+ // Update position on scroll/resize
186
+ useEffect(() => {
187
+ if (!open) return;
188
+
189
+ updatePosition();
190
+
191
+ const handleUpdate = () => updatePosition();
192
+ window.addEventListener('resize', handleUpdate);
193
+ window.addEventListener('scroll', handleUpdate, true);
194
+
195
+ return () => {
196
+ window.removeEventListener('resize', handleUpdate);
197
+ window.removeEventListener('scroll', handleUpdate, true);
198
+ };
199
+ }, [open, updatePosition]);
200
+
201
+ // Handle escape key
202
+ useEffect(() => {
203
+ if (!open || !onEscapeKey) return;
204
+
205
+ const handleEscape = (event: KeyboardEvent) => {
206
+ if (event.key === 'Escape') {
207
+ onEscapeKey();
208
+ }
209
+ };
210
+
211
+ document.addEventListener('keydown', handleEscape);
212
+ return () => document.removeEventListener('keydown', handleEscape);
213
+ }, [open, onEscapeKey]);
214
+
215
+ // Handle click outside
216
+ useEffect(() => {
217
+ if (!open || !onClickOutside) return;
218
+
219
+ const handleClickOutside = (event: MouseEvent) => {
220
+ const target = event.target as Node;
221
+
222
+ if (
223
+ contentRef.current && !contentRef.current.contains(target) &&
224
+ anchor.current && !anchor.current.contains(target)
225
+ ) {
226
+ onClickOutside();
227
+ }
228
+ };
229
+
230
+ document.addEventListener('mousedown', handleClickOutside, true);
231
+ return () => document.removeEventListener('mousedown', handleClickOutside, true);
232
+ }, [open, onClickOutside, anchor]);
233
+
234
+ if (!open) return null;
235
+
236
+ const content = (
237
+ <div
238
+ ref={contentRef}
239
+ style={{
240
+ position: 'fixed',
241
+ top: position.top,
242
+ left: position.left,
243
+ width: position.width,
244
+ zIndex,
245
+ opacity: isPositioned ? 1 : 0,
246
+ pointerEvents: isPositioned ? 'auto' : 'none',
247
+ }}
248
+ >
249
+ {children}
250
+ </div>
251
+ );
252
+
253
+ return createPortal(content, document.body);
254
+ };
@@ -0,0 +1,173 @@
1
+ import React from 'react';
2
+ import { View, Text, Dimensions, StyleSheet } from 'react-native';
3
+ import { useSafeAreaInsets } from 'react-native-safe-area-context';
4
+
5
+ interface SafeAreaDebugOverlayProps {
6
+ visible?: boolean;
7
+ }
8
+
9
+ export const SafeAreaDebugOverlay: React.FC<SafeAreaDebugOverlayProps> = ({ visible = true }) => {
10
+ const insets = useSafeAreaInsets();
11
+ const { width: windowWidth, height: windowHeight } = Dimensions.get('window');
12
+ const padding = 12;
13
+
14
+ if (!visible) return null;
15
+
16
+ // Calculate safe area bounds (system-defined safe zones)
17
+ // Allow overlap with header at top (lenient), but respect system UI at bottom
18
+ const topSafeEdge = 0; // Allow header overlap
19
+ const leftSafeEdge = insets.left;
20
+ const rightSafeEdge = windowWidth - insets.right;
21
+ const bottomSafeEdge = windowHeight - insets.bottom;
22
+
23
+ // Calculate content bounds (safe area with padding for visual comfort)
24
+ const topBound = padding; // Start from top with just padding
25
+ const leftBound = leftSafeEdge + padding;
26
+ const rightBound = rightSafeEdge - padding;
27
+ const bottomBound = bottomSafeEdge - padding;
28
+
29
+ const safeWidth = rightBound - leftBound;
30
+ const safeHeight = windowHeight - insets.bottom - insets.top - padding * 2;
31
+
32
+ return (
33
+ <View style={styles.container} pointerEvents="none">
34
+ {/* Top unsafe area (status bar, notch) */}
35
+ <View
36
+ style={[
37
+ styles.safeAreaIndicator,
38
+ {
39
+ top: 0,
40
+ left: 0,
41
+ width: windowWidth,
42
+ height: topSafeEdge,
43
+ backgroundColor: 'rgba(255, 0, 0, 0.2)',
44
+ },
45
+ ]}
46
+ >
47
+ <Text style={styles.label}>System UI: {topSafeEdge.toFixed(0)}px</Text>
48
+ </View>
49
+
50
+ {/* Bottom unsafe area (gesture bar, home indicator) */}
51
+ <View
52
+ style={[
53
+ styles.safeAreaIndicator,
54
+ {
55
+ top: bottomSafeEdge,
56
+ left: 0,
57
+ width: windowWidth,
58
+ height: windowHeight - bottomSafeEdge,
59
+ backgroundColor: 'rgba(255, 0, 0, 0.2)',
60
+ },
61
+ ]}
62
+ >
63
+ <Text style={styles.label}>Gesture Bar: {(windowHeight - bottomSafeEdge).toFixed(0)}px</Text>
64
+ </View>
65
+
66
+ {/* Left unsafe area */}
67
+ <View
68
+ style={[
69
+ styles.safeAreaIndicator,
70
+ {
71
+ top: topSafeEdge,
72
+ left: 0,
73
+ width: leftSafeEdge,
74
+ height: bottomSafeEdge - topSafeEdge,
75
+ backgroundColor: 'rgba(255, 0, 0, 0.2)',
76
+ },
77
+ ]}
78
+ >
79
+ <Text style={[styles.label, styles.rotatedLabel]}>L: {leftSafeEdge.toFixed(0)}px</Text>
80
+ </View>
81
+
82
+ {/* Right unsafe area */}
83
+ <View
84
+ style={[
85
+ styles.safeAreaIndicator,
86
+ {
87
+ top: topSafeEdge,
88
+ left: rightSafeEdge,
89
+ width: windowWidth - rightSafeEdge,
90
+ height: bottomSafeEdge - topSafeEdge,
91
+ backgroundColor: 'rgba(255, 0, 0, 0.2)',
92
+ },
93
+ ]}
94
+ >
95
+ <Text style={[styles.label, styles.rotatedLabel]}>R: {(windowWidth - rightSafeEdge).toFixed(0)}px</Text>
96
+ </View>
97
+
98
+ {/* Safe area border outline */}
99
+ <View
100
+ style={[
101
+ styles.safeAreaBorder,
102
+ {
103
+ top: topBound,
104
+ left: leftBound,
105
+ width: safeWidth,
106
+ height: safeHeight,
107
+ },
108
+ ]}
109
+ />
110
+
111
+ {/* Info panel */}
112
+ <View style={styles.infoPanel}>
113
+ <Text style={styles.infoText}>Window: {windowWidth.toFixed(0)}x{windowHeight.toFixed(0)}</Text>
114
+ <Text style={styles.infoText}>Safe Area: {(rightSafeEdge - leftSafeEdge).toFixed(0)}x{(bottomSafeEdge - topSafeEdge).toFixed(0)}</Text>
115
+ <Text style={styles.infoText}>Content: {safeWidth.toFixed(0)}x{safeHeight.toFixed(0)}</Text>
116
+ <Text style={styles.infoText}>Insets: T:{insets.top} R:{insets.right} B:{insets.bottom} L:{insets.left}</Text>
117
+ <Text style={styles.infoText}>Safe: T:{topSafeEdge} B:{bottomSafeEdge.toFixed(0)}</Text>
118
+ <Text style={styles.infoText}>Bounds: T:{topBound.toFixed(0)} B:{bottomBound.toFixed(0)}</Text>
119
+ <Text style={styles.infoText}>Padding: {padding}px</Text>
120
+ </View>
121
+ </View>
122
+ );
123
+ };
124
+
125
+ const styles = StyleSheet.create({
126
+ container: {
127
+ position: 'absolute',
128
+ top: 0,
129
+ left: 0,
130
+ right: 0,
131
+ bottom: 0,
132
+ zIndex: 9999,
133
+ },
134
+ safeAreaIndicator: {
135
+ position: 'absolute',
136
+ justifyContent: 'center',
137
+ alignItems: 'center',
138
+ },
139
+ safeAreaBorder: {
140
+ position: 'absolute',
141
+ borderWidth: 2,
142
+ borderColor: 'rgba(0, 255, 0, 0.8)',
143
+ borderStyle: 'dashed',
144
+ },
145
+ label: {
146
+ color: '#fff',
147
+ fontSize: 10,
148
+ fontWeight: 'bold',
149
+ backgroundColor: 'rgba(0, 0, 0, 0.5)',
150
+ paddingHorizontal: 4,
151
+ paddingVertical: 2,
152
+ borderRadius: 4,
153
+ },
154
+ rotatedLabel: {
155
+ transform: [{ rotate: '90deg' }],
156
+ },
157
+ infoPanel: {
158
+ position: 'absolute',
159
+ top: 50,
160
+ right: 10,
161
+ backgroundColor: 'rgba(0, 0, 0, 0.8)',
162
+ padding: 8,
163
+ borderRadius: 8,
164
+ borderWidth: 1,
165
+ borderColor: 'rgba(0, 255, 0, 0.8)',
166
+ },
167
+ infoText: {
168
+ color: '#fff',
169
+ fontSize: 11,
170
+ fontFamily: 'monospace',
171
+ marginBottom: 2,
172
+ },
173
+ });
@@ -0,0 +1,6 @@
1
+ /**
2
+ * This file ensures that the Unistyles module augmentation from @idealyst/theme
3
+ * is properly loaded for all component files.
4
+ */
5
+
6
+ import '@idealyst/theme/unistyles';