@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
@@ -0,0 +1,115 @@
1
+ import React, { useRef } from 'react';
2
+ import { getWebProps } from 'react-native-unistyles/web';
3
+ import { videoStyles } from './Video.styles';
4
+ import type { VideoProps, VideoSource } from './types';
5
+ import useMergeRefs from '../hooks/useMergeRefs';
6
+
7
+ const Video: React.FC<VideoProps> = ({
8
+ source,
9
+ poster,
10
+ width,
11
+ height,
12
+ aspectRatio,
13
+ controls = true,
14
+ autoPlay = false,
15
+ loop = false,
16
+ muted = false,
17
+ playsInline = true,
18
+ preload = 'metadata',
19
+ onLoad,
20
+ onError,
21
+ onPlay,
22
+ onPause,
23
+ onEnd,
24
+ onProgress,
25
+ borderRadius,
26
+ style,
27
+ testID,
28
+ }) => {
29
+ const videoRef = useRef<HTMLVideoElement>(null);
30
+
31
+ const containerProps = getWebProps([videoStyles.container, style as any]);
32
+ const videoProps = getWebProps([videoStyles.video]);
33
+
34
+ const videoSource = typeof source === 'string'
35
+ ? source
36
+ : (source as VideoSource).uri;
37
+
38
+ const videoType = typeof source === 'object'
39
+ ? (source as VideoSource).type
40
+ : undefined;
41
+
42
+ const handleLoadedMetadata = () => {
43
+ onLoad?.();
44
+ };
45
+
46
+ const handleError = (e: React.SyntheticEvent<HTMLVideoElement, Event>) => {
47
+ onError?.(e);
48
+ };
49
+
50
+ const handlePlay = () => {
51
+ onPlay?.();
52
+ };
53
+
54
+ const handlePause = () => {
55
+ onPause?.();
56
+ };
57
+
58
+ const handleEnded = () => {
59
+ onEnd?.();
60
+ };
61
+
62
+ const handleTimeUpdate = () => {
63
+ if (videoRef.current && onProgress) {
64
+ onProgress({
65
+ currentTime: videoRef.current.currentTime,
66
+ playableDuration: videoRef.current.duration || 0,
67
+ });
68
+ }
69
+ };
70
+
71
+ const containerStyle: React.CSSProperties = {
72
+ width: width || '100%',
73
+ height: height || 'auto',
74
+ aspectRatio: aspectRatio ? String(aspectRatio) : undefined,
75
+ borderRadius: borderRadius ? `${borderRadius}px` : undefined,
76
+ };
77
+
78
+ const vidStyle: React.CSSProperties = {
79
+ borderRadius: borderRadius ? `${borderRadius}px` : undefined,
80
+ };
81
+
82
+ const mergedVideoRef = useMergeRefs(videoRef, videoProps.ref);
83
+
84
+ return (
85
+ <div
86
+ {...containerProps}
87
+ style={containerStyle}
88
+ data-testid={testID}
89
+ >
90
+ <video
91
+ ref={mergedVideoRef}
92
+ className={videoProps.className}
93
+ style={vidStyle}
94
+ poster={poster}
95
+ controls={controls}
96
+ autoPlay={autoPlay}
97
+ loop={loop}
98
+ muted={muted}
99
+ playsInline={playsInline}
100
+ preload={preload}
101
+ onLoadedMetadata={handleLoadedMetadata}
102
+ onError={handleError}
103
+ onPlay={handlePlay}
104
+ onPause={handlePause}
105
+ onEnded={handleEnded}
106
+ onTimeUpdate={handleTimeUpdate}
107
+ >
108
+ <source src={videoSource} type={videoType || 'video/mp4'} />
109
+ Your browser does not support the video tag.
110
+ </video>
111
+ </div>
112
+ );
113
+ };
114
+
115
+ export default Video;
@@ -0,0 +1,5 @@
1
+ import VideoComponent from './Video.native';
2
+
3
+ export default VideoComponent;
4
+ export { VideoComponent as Video };
5
+ export * from './types';
@@ -0,0 +1,5 @@
1
+ import VideoComponent from './Video.web';
2
+
3
+ export default VideoComponent;
4
+ export { VideoComponent as Video };
5
+ export * from './types';
@@ -0,0 +1,29 @@
1
+ import type { StyleProp, ViewStyle } from 'react-native';
2
+
3
+ export interface VideoSource {
4
+ uri: string;
5
+ type?: string;
6
+ }
7
+
8
+ export interface VideoProps {
9
+ source: VideoSource | string;
10
+ poster?: string;
11
+ width?: number | string;
12
+ height?: number | string;
13
+ aspectRatio?: number;
14
+ controls?: boolean;
15
+ autoPlay?: boolean;
16
+ loop?: boolean;
17
+ muted?: boolean;
18
+ playsInline?: boolean;
19
+ preload?: 'auto' | 'metadata' | 'none';
20
+ onLoad?: () => void;
21
+ onError?: (error: any) => void;
22
+ onPlay?: () => void;
23
+ onPause?: () => void;
24
+ onEnd?: () => void;
25
+ onProgress?: (progress: { currentTime: number; playableDuration: number }) => void;
26
+ borderRadius?: number;
27
+ style?: StyleProp<ViewStyle>;
28
+ testID?: string;
29
+ }
@@ -1,9 +1,9 @@
1
- import React from 'react';
2
- import { View as RNView } from 'react-native';
1
+ import React, { forwardRef } from 'react';
2
+ import { View as RNView, ViewStyle } from 'react-native';
3
3
  import { ViewProps } from './types';
4
- import viewStyles from './View.styles';
4
+ import { viewStyles } from './View.styles';
5
5
 
6
- const View: React.FC<ViewProps> = ({
6
+ const View = forwardRef<RNView, ViewProps>(({
7
7
  children,
8
8
  spacing = 'none',
9
9
  marginVariant = 'none',
@@ -18,10 +18,9 @@ const View: React.FC<ViewProps> = ({
18
18
  borderColor,
19
19
  style,
20
20
  testID,
21
- }) => {
21
+ }, ref) => {
22
22
  viewStyles.useVariants({
23
23
  spacing,
24
- margin: marginVariant,
25
24
  background,
26
25
  radius,
27
26
  border,
@@ -40,17 +39,13 @@ const View: React.FC<ViewProps> = ({
40
39
  return baseStyles;
41
40
  };
42
41
 
43
- const viewStyleArray = [
44
- viewStyles.view,
45
- getStyles(),
46
- style,
47
- ];
48
-
49
42
  return (
50
- <RNView style={viewStyleArray} testID={testID}>
43
+ <RNView ref={ref} style={[viewStyles.view, getStyles(), style]} testID={testID}>
51
44
  {children}
52
45
  </RNView>
53
46
  );
54
- };
47
+ });
48
+
49
+ View.displayName = 'View';
55
50
 
56
51
  export default View;
@@ -1,103 +1,111 @@
1
- import { StyleSheet } from "react-native-unistyles";
2
1
 
3
- const viewStyles = StyleSheet.create((theme) => ({
4
- view: {
5
- variants: {
6
- spacing: {
7
- none: {
8
- padding: 0,
9
- },
10
- xs: {
11
- padding: theme.spacing.xs,
12
- },
13
- sm: {
14
- padding: theme.spacing.sm,
15
- },
16
- md: {
17
- padding: theme.spacing.md,
18
- },
19
- lg: {
20
- padding: theme.spacing.lg,
21
- },
22
- xl: {
23
- padding: theme.spacing.xl,
24
- },
25
- },
26
- margin: {
27
- none: {
28
- margin: 0,
29
- },
30
- xs: {
31
- margin: theme.spacing.xs,
32
- },
33
- sm: {
34
- margin: theme.spacing.sm,
35
- },
36
- md: {
37
- margin: theme.spacing.md,
38
- },
39
- lg: {
40
- margin: theme.spacing.lg,
41
- },
42
- xl: {
43
- margin: theme.spacing.xl,
44
- },
45
- },
46
- background: {
2
+ import { StyleSheet } from 'react-native-unistyles';
3
+ import { Theme, StylesheetStyles, Surface} from '@idealyst/theme';
4
+ import { buildSizeVariants } from '../utils/buildSizeVariants';
5
+ import { ViewBackgroundVariant, ViewBorderVariant, ViewRadiusVariant, ViewSpacingVariant } from './types';
6
+
7
+ type ViewVariants = {
8
+ spacing: ViewSpacingVariant;
9
+ background: ViewBackgroundVariant;
10
+ radius: ViewRadiusVariant;
11
+ border: ViewBorderVariant;
12
+ }
13
+
14
+ export type ExpandedViewStyles = StylesheetStyles<keyof ViewVariants>;
15
+
16
+ export type ViewStylesheet = {
17
+ view: ExpandedViewStyles;
18
+ }
19
+
20
+ /**
21
+ * Create spacing variants for view
22
+ */
23
+ function createSpacingVariants(theme: Theme) {
24
+ const spacingVariants = buildSizeVariants(theme, 'view', (size) => ({
25
+ padding: size.padding,
26
+ gap: size.spacing,
27
+ }));
28
+
29
+ spacingVariants['none'] = {
30
+ padding: 0,
31
+ gap: 0,
32
+ };
33
+
34
+ return spacingVariants as Record<ViewSpacingVariant, Partial<ExpandedViewStyles>>;
35
+ }
36
+
37
+ /**
38
+ * Create background variants for view
39
+ */
40
+ function createBackgroundVariants(theme: Theme) {
41
+ const variants: any = {
47
42
  transparent: {
48
- backgroundColor: 'transparent',
49
- },
50
- surface: {
51
- backgroundColor: theme.colors.surface,
52
- },
53
- primary: {
54
- backgroundColor: theme.colors.primary,
55
- },
56
- secondary: {
57
- backgroundColor: theme.colors.secondary,
58
- },
59
- },
60
- radius: {
61
- none: {
62
- borderRadius: 0,
63
- },
64
- xs: {
65
- borderRadius: theme.borderRadius.xs,
66
- },
67
- sm: {
68
- borderRadius: theme.borderRadius.sm,
69
- },
70
- md: {
71
- borderRadius: theme.borderRadius.md,
72
- },
73
- lg: {
74
- borderRadius: theme.borderRadius.lg,
43
+ backgroundColor: 'transparent',
75
44
  },
76
- xl: {
77
- borderRadius: theme.borderRadius.xl,
78
- },
79
- },
80
- border: {
45
+ };
46
+
47
+ // Add all surface colors programmatically
48
+ for (const surface in theme.colors.surface) {
49
+ variants[surface] = {
50
+ backgroundColor: theme.colors.surface[surface as Surface],
51
+ };
52
+ }
53
+
54
+ return variants;
55
+ }
56
+
57
+ /**
58
+ * Create radius variants for view
59
+ */
60
+ function createRadiusVariants() {
61
+ return {
62
+ none: { borderRadius: 0 },
63
+ xs: { borderRadius: 2 },
64
+ sm: { borderRadius: 4 },
65
+ md: { borderRadius: 8 },
66
+ lg: { borderRadius: 12 },
67
+ xl: { borderRadius: 16 },
68
+ } as const;
69
+ }
70
+
71
+ /**
72
+ * Create border variants for view
73
+ */
74
+ function createBorderVariants(theme: Theme) {
75
+ return {
81
76
  none: {
82
- borderWidth: 0,
77
+ borderWidth: 0,
83
78
  },
84
79
  thin: {
85
- borderWidth: 1,
86
- borderColor: theme.colors.border,
80
+ borderWidth: 1,
81
+ borderStyle: 'solid',
82
+ borderColor: theme.colors['gray.300'],
87
83
  },
88
84
  thick: {
89
- borderWidth: 2,
90
- borderColor: theme.colors.border,
85
+ borderWidth: 2,
86
+ borderStyle: 'solid',
87
+ borderColor: theme.colors['gray.300'],
91
88
  },
92
- },
93
- },
94
- // Web-specific styles
95
- _web: {
96
- display: 'flex',
97
- flexDirection: 'column',
98
- boxSizing: 'border-box',
99
- },
100
- },
101
- }));
89
+ } as const;
90
+ }
102
91
 
103
- export default viewStyles;
92
+ // Styles are inlined here instead of in @idealyst/theme because Unistyles' Babel
93
+ // transform on native cannot resolve function calls to extract variant structures.
94
+ export const viewStyles = StyleSheet.create((theme: Theme) => {
95
+ return {
96
+ view: {
97
+ display: 'flex',
98
+ variants: {
99
+ spacing: createSpacingVariants(theme),
100
+ background: createBackgroundVariants(theme),
101
+ radius: createRadiusVariants(),
102
+ border: createBorderVariants(theme),
103
+ },
104
+ _web: {
105
+ display: 'flex',
106
+ flexDirection: 'column',
107
+ boxSizing: 'border-box',
108
+ },
109
+ },
110
+ };
111
+ });
@@ -1,14 +1,15 @@
1
- import React from 'react';
1
+ import React, { forwardRef } from 'react';
2
2
  import { getWebProps } from 'react-native-unistyles/web';
3
3
  import { ViewProps } from './types';
4
- import viewStyles from './View.styles';
4
+ import { viewStyles } from './View.styles';
5
+ import useMergeRefs from '../hooks/useMergeRefs';
5
6
 
6
- const View: React.FC<ViewProps> = ({
7
+ const View = forwardRef<HTMLDivElement, ViewProps>(({
7
8
  children,
8
9
  spacing = 'none',
9
10
  marginVariant = 'none',
10
11
  background = 'transparent',
11
- radius = 'none',
12
+ radius = 'none',
12
13
  border = 'none',
13
14
  backgroundColor,
14
15
  padding,
@@ -18,18 +19,17 @@ const View: React.FC<ViewProps> = ({
18
19
  borderColor,
19
20
  style,
20
21
  testID,
21
- }) => {
22
+ }, ref) => {
22
23
  viewStyles.useVariants({
23
- spacing,
24
- margin: marginVariant,
25
24
  background,
26
25
  radius,
27
26
  border,
27
+ spacing,
28
28
  });
29
29
 
30
30
  // Create dynamic styles based on custom props (overrides variants)
31
31
  const dynamicStyles: any = {};
32
-
32
+
33
33
  if (backgroundColor) dynamicStyles.backgroundColor = backgroundColor;
34
34
  if (padding !== undefined) dynamicStyles.padding = padding;
35
35
  if (margin !== undefined) dynamicStyles.margin = margin;
@@ -37,24 +37,23 @@ const View: React.FC<ViewProps> = ({
37
37
  if (borderWidth !== undefined) dynamicStyles.borderWidth = borderWidth;
38
38
  if (borderColor) dynamicStyles.borderColor = borderColor;
39
39
 
40
- // Create the style array following the official documentation pattern
41
- const viewStyleArray = [
42
- viewStyles.view,
43
- dynamicStyles,
44
- style,
45
- ];
40
+ /** @ts-ignore */
41
+ const webProps = getWebProps(viewStyles.view);
46
42
 
47
- // Use getWebProps to generate className and ref for web
48
- const webProps = getWebProps(viewStyleArray);
43
+ const mergedRef = useMergeRefs(ref, webProps.ref);
49
44
 
50
45
  return (
51
46
  <div
52
47
  {...webProps}
48
+ style={style as any}
49
+ ref={mergedRef}
53
50
  data-testid={testID}
54
51
  >
55
52
  {children}
56
53
  </div>
57
54
  );
58
- };
55
+ });
56
+
57
+ View.displayName = 'View';
59
58
 
60
59
  export default View;
package/src/View/index.ts CHANGED
@@ -1,5 +1,5 @@
1
- // Platform-agnostic View export
2
- // Bundlers will resolve to index.web.ts (web) or index.native.ts (React Native)
3
- // This file serves as fallback for web environments
4
- export { default } from './View.web';
5
- export * from './types';
1
+ import ViewComponent from './View.web';
2
+
3
+ export default ViewComponent;
4
+ export { ViewComponent as View };
5
+ export * from './types';
@@ -1,3 +1,5 @@
1
- // Web-specific View export
2
- export { default } from './View.web';
3
- export * from './types';
1
+ import ViewComponent from './View.web';
2
+
3
+ export default ViewComponent;
4
+ export { ViewComponent as View };
5
+ export * from './types';
package/src/View/types.ts CHANGED
@@ -1,71 +1,79 @@
1
- import { ReactNode } from 'react';
1
+ import { Size, Surface } from '@idealyst/theme';
2
+ import type { ReactNode } from 'react';
3
+ import type { StyleProp, ViewStyle } from 'react-native';
4
+
5
+ // Component-specific type aliases for future extensibility
6
+ export type ViewBackgroundVariant = Surface | 'transparent';
7
+ export type ViewSpacingVariant = Size | 'none';
8
+ export type ViewRadiusVariant = Size | 'none';
9
+ export type ViewBorderVariant = 'none' | 'thin' | 'thick';
2
10
 
3
11
  export interface ViewProps {
4
12
  /**
5
13
  * The content to display inside the view
6
14
  */
7
15
  children?: ReactNode;
8
-
16
+
9
17
  /**
10
- * Padding variant
18
+ * Padding/spacing variant
11
19
  */
12
- spacing?: 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl';
13
-
20
+ spacing?: ViewSpacingVariant;
21
+
14
22
  /**
15
23
  * Margin variant
16
24
  */
17
- marginVariant?: 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl';
18
-
25
+ marginVariant?: ViewSpacingVariant;
26
+
19
27
  /**
20
28
  * Background variant
21
29
  */
22
- background?: 'transparent' | 'surface' | 'primary' | 'secondary';
23
-
30
+ background?: ViewBackgroundVariant;
31
+
24
32
  /**
25
33
  * Border radius variant
26
34
  */
27
- radius?: 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl';
28
-
35
+ radius?: ViewRadiusVariant;
36
+
29
37
  /**
30
38
  * Border variant
31
39
  */
32
- border?: 'none' | 'thin' | 'thick';
33
-
40
+ border?: ViewBorderVariant;
41
+
34
42
  /**
35
43
  * Custom background color (overrides background variant)
36
44
  */
37
45
  backgroundColor?: string;
38
-
46
+
39
47
  /**
40
48
  * Custom padding (overrides spacing variant)
41
49
  */
42
50
  padding?: number;
43
-
51
+
44
52
  /**
45
53
  * Custom margin (overrides marginVariant)
46
54
  */
47
55
  margin?: number;
48
-
56
+
49
57
  /**
50
58
  * Custom border radius (overrides radius variant)
51
59
  */
52
60
  borderRadius?: number;
53
-
61
+
54
62
  /**
55
63
  * Custom border width (overrides border variant)
56
64
  */
57
65
  borderWidth?: number;
58
-
66
+
59
67
  /**
60
68
  * Custom border color
61
69
  */
62
70
  borderColor?: string;
63
-
71
+
64
72
  /**
65
73
  * Additional styles (platform-specific)
66
74
  */
67
- style?: any;
68
-
75
+ style?: React.CSSProperties | StyleProp<ViewStyle>;
76
+
69
77
  /**
70
78
  * Test ID for testing
71
79
  */