@idealyst/components 1.0.83 → 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 +20 -2
  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 +140 -63
  170. package/src/Select/Select.styles.tsx +312 -302
  171. package/src/Select/Select.web.tsx +156 -316
  172. package/src/Select/index.ts +5 -2
  173. package/src/Select/index.web.ts +5 -2
  174. package/src/Select/types.ts +13 -7
  175. package/src/Skeleton/Skeleton.native.tsx +139 -0
  176. package/src/Skeleton/Skeleton.styles.tsx +59 -0
  177. package/src/Skeleton/Skeleton.web.tsx +112 -0
  178. package/src/Skeleton/index.native.ts +4 -0
  179. package/src/Skeleton/index.ts +5 -0
  180. package/src/Skeleton/index.web.ts +5 -0
  181. package/src/Skeleton/types.ts +75 -0
  182. package/src/Slider/Slider.native.tsx +248 -0
  183. package/src/Slider/Slider.styles.tsx +241 -0
  184. package/src/Slider/Slider.web.tsx +226 -0
  185. package/src/Slider/index.native.ts +3 -0
  186. package/src/Slider/index.ts +5 -0
  187. package/src/Slider/index.web.ts +5 -0
  188. package/src/Slider/types.ts +31 -0
  189. package/src/Switch/Switch.native.tsx +131 -0
  190. package/src/Switch/Switch.styles.tsx +169 -0
  191. package/src/Switch/Switch.web.tsx +121 -0
  192. package/src/Switch/index.native.ts +3 -0
  193. package/src/Switch/index.ts +5 -0
  194. package/src/Switch/index.web.ts +5 -0
  195. package/src/Switch/types.ts +21 -0
  196. package/src/TabBar/TabBar.native.tsx +142 -0
  197. package/src/TabBar/TabBar.styles.tsx +399 -0
  198. package/src/TabBar/TabBar.web.tsx +205 -0
  199. package/src/TabBar/index.native.tsx +3 -0
  200. package/src/TabBar/index.ts +3 -0
  201. package/src/TabBar/index.web.tsx +3 -0
  202. package/src/TabBar/types.ts +26 -0
  203. package/src/Table/Table.native.tsx +122 -0
  204. package/src/Table/Table.styles.tsx +283 -0
  205. package/src/Table/Table.web.tsx +112 -0
  206. package/src/Table/index.native.tsx +3 -0
  207. package/src/Table/index.ts +3 -0
  208. package/src/Table/index.web.tsx +3 -0
  209. package/src/Table/types.ts +28 -0
  210. package/src/Text/Text.native.tsx +12 -11
  211. package/src/Text/Text.styles.tsx +76 -64
  212. package/src/Text/Text.web.tsx +14 -9
  213. package/src/Text/index.ts +5 -5
  214. package/src/Text/index.web.ts +5 -3
  215. package/src/Text/types.ts +20 -13
  216. package/src/TextArea/TextArea.native.tsx +134 -0
  217. package/src/TextArea/TextArea.styles.tsx +175 -0
  218. package/src/TextArea/TextArea.web.tsx +156 -0
  219. package/src/TextArea/index.native.ts +3 -0
  220. package/src/TextArea/index.ts +3 -0
  221. package/src/TextArea/index.web.ts +3 -0
  222. package/src/TextArea/types.ts +30 -0
  223. package/src/Tooltip/Tooltip.native.tsx +165 -0
  224. package/src/Tooltip/Tooltip.styles.tsx +73 -0
  225. package/src/Tooltip/Tooltip.web.tsx +87 -0
  226. package/src/Tooltip/index.native.ts +3 -0
  227. package/src/Tooltip/index.ts +3 -0
  228. package/src/Tooltip/types.ts +18 -0
  229. package/src/Video/Video.native.tsx +105 -0
  230. package/src/Video/Video.styles.tsx +39 -0
  231. package/src/Video/Video.web.tsx +115 -0
  232. package/src/Video/index.native.ts +5 -0
  233. package/src/Video/index.ts +5 -0
  234. package/src/Video/types.ts +29 -0
  235. package/src/View/View.native.tsx +9 -14
  236. package/src/View/View.styles.tsx +101 -93
  237. package/src/View/View.web.tsx +16 -17
  238. package/src/View/index.ts +5 -5
  239. package/src/View/index.web.ts +5 -3
  240. package/src/View/types.ts +29 -21
  241. package/src/examples/AccordionExamples.tsx +126 -0
  242. package/src/examples/AlertExamples.tsx +280 -0
  243. package/src/examples/AvatarExamples.tsx +23 -23
  244. package/src/examples/BadgeExamples.tsx +109 -41
  245. package/src/examples/BreadcrumbExamples.tsx +312 -0
  246. package/src/examples/ButtonExamples.tsx +160 -33
  247. package/src/examples/CardExamples.tsx +40 -40
  248. package/src/examples/CheckboxExamples.tsx +12 -12
  249. package/src/examples/ChipExamples.tsx +197 -0
  250. package/src/examples/DialogExamples.tsx +22 -22
  251. package/src/examples/DividerExamples.tsx +49 -49
  252. package/src/examples/IconExamples.tsx +270 -54
  253. package/src/examples/ImageExamples.tsx +174 -0
  254. package/src/examples/InputExamples.tsx +75 -17
  255. package/src/examples/ListExamples.tsx +288 -0
  256. package/src/examples/MenuExamples.tsx +144 -0
  257. package/src/examples/PopoverExamples.tsx +69 -73
  258. package/src/examples/ProgressExamples.tsx +137 -0
  259. package/src/examples/RadioButtonExamples.tsx +161 -0
  260. package/src/examples/SVGImageExamples.tsx +19 -17
  261. package/src/examples/ScreenExamples.tsx +31 -31
  262. package/src/examples/SelectExamples.tsx +67 -67
  263. package/src/examples/SkeletonExamples.tsx +206 -0
  264. package/src/examples/SliderExamples.tsx +200 -0
  265. package/src/examples/SwitchExamples.tsx +182 -0
  266. package/src/examples/TabBarExamples.tsx +143 -0
  267. package/src/examples/TableExamples.tsx +280 -0
  268. package/src/examples/TextAreaExamples.tsx +173 -0
  269. package/src/examples/TextExamples.tsx +28 -32
  270. package/src/examples/ThemeExtensionExamples.tsx +10 -10
  271. package/src/examples/TooltipExamples.tsx +126 -0
  272. package/src/examples/VideoExamples.tsx +144 -0
  273. package/src/examples/ViewExamples.tsx +64 -56
  274. package/src/examples/index.ts +17 -3
  275. package/src/hooks/useMergeRefs.ts +16 -0
  276. package/src/hooks/useSmartPosition.native.ts +169 -0
  277. package/src/index.native.ts +80 -9
  278. package/src/index.ts +71 -1
  279. package/src/internal/BoundedModalContent.native.tsx +58 -0
  280. package/src/internal/PositionedPortal.tsx +254 -0
  281. package/src/internal/SafeAreaDebugOverlay.native.tsx +173 -0
  282. package/src/unistyles.d.ts +6 -0
  283. package/src/utils/buildSizeVariants.ts +16 -0
  284. package/src/utils/deepMerge.ts +43 -0
  285. package/src/utils/positionUtils.native.ts +280 -0
  286. package/src/utils/styleHelpers.ts +48 -0
  287. package/LLM-ACCESS-GUIDE.md +0 -143
  288. package/src/ActivityIndicator/README.md +0 -132
  289. package/src/Avatar/README.md +0 -139
  290. package/src/Badge/README.md +0 -170
  291. package/src/Button/Button.types.ts +0 -12
  292. package/src/Button/README.md +0 -262
  293. package/src/Card/README.md +0 -258
  294. package/src/Checkbox/README.md +0 -102
  295. package/src/Dialog/README.md +0 -210
  296. package/src/Divider/README.md +0 -108
  297. package/src/Icon/README.md +0 -81
  298. package/src/Input/README.md +0 -100
  299. package/src/SVGImage/README.md +0 -209
  300. package/src/Screen/README.md +0 -86
  301. package/src/Select/README.md +0 -166
  302. package/src/Text/README.md +0 -94
  303. package/src/View/README.md +0 -107
  304. package/src/examples/AllExamples.tsx +0 -88
  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
@@ -13,7 +13,21 @@ export { SVGImageExamples } from './SVGImageExamples';
13
13
  export { DialogExamples } from './DialogExamples';
14
14
  export { PopoverExamples } from './PopoverExamples';
15
15
  export { SelectExamples } from './SelectExamples';
16
+ export { SliderExamples } from './SliderExamples';
17
+ export { SwitchExamples } from './SwitchExamples';
18
+ export { RadioButtonExamples } from './RadioButtonExamples';
19
+ export { ProgressExamples } from './ProgressExamples';
20
+ export { TextAreaExamples } from './TextAreaExamples';
21
+ export { TabBarExamples } from './TabBarExamples';
22
+ export { TooltipExamples } from './TooltipExamples';
23
+ export { AccordionExamples } from './AccordionExamples';
24
+ export { ListExamples } from './ListExamples';
25
+ export { TableExamples } from './TableExamples';
26
+ export { MenuExamples } from './MenuExamples';
27
+ export { ImageExamples } from './ImageExamples';
28
+ export { VideoExamples } from './VideoExamples';
29
+ export { AlertExamples } from './AlertExamples';
30
+ export { SkeletonExamples } from './SkeletonExamples';
31
+ export { ChipExamples } from './ChipExamples';
32
+ export { BreadcrumbExamples } from './BreadcrumbExamples';
16
33
  export { ThemeExtensionExamples } from './ThemeExtensionExamples';
17
- export { extendedThemes, } from './extendedTheme';
18
- export type { ExtendedColorVariant, ExtendedIntentVariant } from './extendedTheme';
19
- export { AllExamples } from './AllExamples';
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Userful when workign with getWebProps and forwarding refs
3
+ * @param refs
4
+ * @returns
5
+ */
6
+ export default function useMergeRefs<T>(...refs: React.Ref<T>[]): React.RefCallback<T> {
7
+ return (value: T) => {
8
+ refs.forEach((ref) => {
9
+ if (typeof ref === 'function') {
10
+ ref(value);
11
+ } else if (ref && 'current' in ref) {
12
+ ref.current = value;
13
+ }
14
+ });
15
+ };
16
+ }
@@ -0,0 +1,169 @@
1
+ import { useState, useRef, useEffect } from 'react';
2
+ import { useSafeAreaInsets } from 'react-native-safe-area-context';
3
+ import { calculateSmartPosition, type Placement } from '../utils/positionUtils.native';
4
+
5
+ export interface UseSmartPositionOptions {
6
+ placement?: Placement;
7
+ offset?: number;
8
+ maxHeight?: number;
9
+ matchWidth?: boolean;
10
+ }
11
+
12
+ export interface SmartPosition {
13
+ top: number;
14
+ left: number;
15
+ width: number;
16
+ }
17
+
18
+ export interface SmartSize {
19
+ width: number;
20
+ height: number;
21
+ }
22
+
23
+ export interface UseSmartPositionReturn {
24
+ position: SmartPosition;
25
+ size: SmartSize;
26
+ isPositioned: boolean;
27
+ anchorRef: React.MutableRefObject<any>;
28
+ measureAndPosition: () => void;
29
+ handleLayout: (event: any) => void;
30
+ reset: () => void;
31
+ }
32
+
33
+ /**
34
+ * Hook for smart positioning of modals/dropdowns with automatic flip detection
35
+ * and stable measurement-based positioning.
36
+ *
37
+ * This hook handles the complex two-phase rendering pattern:
38
+ * 1. Render invisible at initial position
39
+ * 2. Measure actual content size
40
+ * 3. Calculate final position based on measured size
41
+ * 4. Show once positioned and measurements are stable
42
+ */
43
+ export const useSmartPosition = ({
44
+ placement = 'bottom-start',
45
+ offset = 8,
46
+ maxHeight = 300,
47
+ matchWidth = false,
48
+ }: UseSmartPositionOptions = {}): UseSmartPositionReturn => {
49
+ const [position, setPosition] = useState<SmartPosition>({ top: 0, left: 0, width: 0 });
50
+ const [size, setSize] = useState<SmartSize>({ width: 0, height: 0 });
51
+ const [isPositioned, setIsPositioned] = useState(false);
52
+
53
+ const anchorRef = useRef<any>(null);
54
+ const anchorMeasurements = useRef<{ x: number; y: number; width: number; height: number } | null>(null);
55
+ const previousHeightRef = useRef<number>(0);
56
+ const rafRef = useRef<any | null>(null);
57
+ const insets = useSafeAreaInsets();
58
+
59
+ // Calculate position based on anchor and content measurements
60
+ const calculatePosition = (x: number, y: number, width: number, height: number) => {
61
+ // For flip detection, use maxHeight to properly detect insufficient space
62
+ // But once we have a measured height, use that for tighter positioning
63
+ let heightForPositioning = maxHeight;
64
+
65
+ if (size.height > 0) {
66
+ // We have a measured height - use it if it's less than maxHeight
67
+ heightForPositioning = Math.min(size.height, maxHeight);
68
+ }
69
+
70
+ const desiredSize = {
71
+ width: size.width,
72
+ height: heightForPositioning
73
+ };
74
+
75
+ // Calculate position with flip detection
76
+ const calculatedPosition = calculateSmartPosition(
77
+ { x, y, width, height },
78
+ desiredSize,
79
+ placement,
80
+ offset,
81
+ matchWidth,
82
+ insets
83
+ );
84
+
85
+ setPosition({
86
+ top: calculatedPosition.top,
87
+ left: calculatedPosition.left,
88
+ width: calculatedPosition.width || width,
89
+ });
90
+ };
91
+
92
+ // Recalculate position when size changes
93
+ useEffect(() => {
94
+ if (anchorMeasurements.current && size.width > 0 && size.height > 0) {
95
+ const { x, y, width, height } = anchorMeasurements.current;
96
+ calculatePosition(x, y, width, height);
97
+
98
+ // Cancel any pending RAF
99
+ if (rafRef.current !== null) {
100
+ cancelAnimationFrame(rafRef.current);
101
+ }
102
+
103
+ // Wait for next frame to allow layout to settle before showing
104
+ rafRef.current = setTimeout(() => {
105
+ setIsPositioned(true);
106
+ rafRef.current = null;
107
+ }, 20)
108
+ }
109
+
110
+ return () => {
111
+ if (rafRef.current !== null) {
112
+ clearTimeout(rafRef.current);
113
+ rafRef.current = null;
114
+ }
115
+ };
116
+ }, [size]);
117
+
118
+ // Measure anchor and set initial position
119
+ const measureAndPosition = () => {
120
+ anchorRef.current?.measureInWindow((x: number, y: number, width: number, height: number) => {
121
+ // Store anchor measurements for potential recalculation
122
+ anchorMeasurements.current = { x, y, width, height };
123
+
124
+ // Set initial position (will be adjusted after measurement)
125
+ setPosition({ top: y + height + offset, left: x, width });
126
+ setIsPositioned(false);
127
+ previousHeightRef.current = 0;
128
+ });
129
+ };
130
+
131
+ // Handle layout measurement from content
132
+ const handleLayout = (event: any) => {
133
+ const { width, height } = event.nativeEvent.layout;
134
+
135
+ if (__DEV__) {
136
+ console.log('[useSmartPosition] onLayout:', { width, height, currentSize: size, isPositioned });
137
+ }
138
+
139
+ // Only update if size has changed significantly
140
+ if (Math.abs(width - size.width) > 1 || Math.abs(height - size.height) > 1) {
141
+ if (__DEV__) {
142
+ console.log('[useSmartPosition] Size changed, updating');
143
+ }
144
+ previousHeightRef.current = size.height;
145
+ setSize({ width, height });
146
+ }
147
+ };
148
+
149
+ // Reset state (call when closing modal)
150
+ const reset = () => {
151
+ if (rafRef.current !== null) {
152
+ clearTimeout(rafRef.current);
153
+ rafRef.current = null;
154
+ }
155
+ setIsPositioned(false);
156
+ setSize({ width: 0, height: 0 });
157
+ previousHeightRef.current = 0;
158
+ };
159
+
160
+ return {
161
+ position,
162
+ size,
163
+ isPositioned,
164
+ anchorRef,
165
+ measureAndPosition,
166
+ handleLayout,
167
+ reset,
168
+ };
169
+ };
@@ -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
 
@@ -50,6 +52,57 @@ export * from './ActivityIndicator/types';
50
52
  export { default as Select } from './Select';
51
53
  export * from './Select/types';
52
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
+
53
106
  export type { ButtonProps } from './Button/types';
54
107
  export type { TextProps } from './Text/types';
55
108
  export type { ViewProps } from './View/types';
@@ -66,6 +119,23 @@ export type { DialogProps } from './Dialog/types';
66
119
  export type { PopoverProps } from './Popover/types';
67
120
  export type { ActivityIndicatorProps } from './ActivityIndicator/types';
68
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 };
69
140
 
70
- export { breakpoints } from '@idealyst/theme';
71
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
+ };