@idealyst/components 1.1.1 → 1.1.3

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 (102) hide show
  1. package/package.json +8 -3
  2. package/src/Accordion/Accordion.native.tsx +2 -1
  3. package/src/Accordion/Accordion.web.tsx +2 -1
  4. package/src/ActivityIndicator/ActivityIndicator.native.tsx +2 -0
  5. package/src/ActivityIndicator/ActivityIndicator.web.tsx +2 -1
  6. package/src/ActivityIndicator/types.ts +2 -1
  7. package/src/Alert/Alert.native.tsx +2 -0
  8. package/src/Alert/Alert.web.tsx +2 -0
  9. package/src/Alert/types.ts +2 -1
  10. package/src/Avatar/Avatar.native.tsx +2 -1
  11. package/src/Avatar/Avatar.web.tsx +2 -1
  12. package/src/Avatar/types.ts +2 -1
  13. package/src/Badge/Badge.native.tsx +3 -0
  14. package/src/Badge/Badge.web.tsx +3 -0
  15. package/src/Badge/types.ts +2 -1
  16. package/src/Breadcrumb/Breadcrumb.native.tsx +2 -0
  17. package/src/Breadcrumb/Breadcrumb.web.tsx +2 -1
  18. package/src/Breadcrumb/types.ts +2 -1
  19. package/src/Button/Button.native.tsx +17 -12
  20. package/src/Button/Button.styles.tsx +3 -2
  21. package/src/Button/Button.web.tsx +2 -0
  22. package/src/Button/types.ts +2 -1
  23. package/src/Card/Card.native.tsx +2 -0
  24. package/src/Card/Card.web.tsx +2 -0
  25. package/src/Checkbox/Checkbox.native.tsx +2 -1
  26. package/src/Checkbox/Checkbox.web.tsx +2 -1
  27. package/src/Chip/Chip.native.tsx +3 -1
  28. package/src/Chip/Chip.web.tsx +2 -0
  29. package/src/Chip/types.ts +2 -1
  30. package/src/Dialog/Dialog.native.tsx +2 -0
  31. package/src/Dialog/Dialog.web.tsx +2 -0
  32. package/src/Dialog/types.ts +2 -1
  33. package/src/Divider/Divider.native.tsx +4 -0
  34. package/src/Divider/Divider.web.tsx +3 -0
  35. package/src/Divider/types.ts +2 -1
  36. package/src/Icon/Icon.native.tsx +2 -0
  37. package/src/Icon/Icon.web.tsx +3 -1
  38. package/src/Icon/types.ts +2 -1
  39. package/src/Image/Image.native.tsx +2 -1
  40. package/src/Image/Image.web.tsx +2 -0
  41. package/src/Image/types.ts +2 -1
  42. package/src/Input/Input.native.tsx +2 -1
  43. package/src/Input/Input.styles.tsx +1 -0
  44. package/src/Input/Input.web.tsx +2 -1
  45. package/src/Link/Link.native.tsx +2 -0
  46. package/src/Link/Link.web.tsx +2 -0
  47. package/src/Link/types.ts +2 -1
  48. package/src/List/List.native.tsx +3 -1
  49. package/src/List/List.web.tsx +2 -0
  50. package/src/Menu/Menu.native.tsx +2 -1
  51. package/src/Menu/Menu.web.tsx +2 -0
  52. package/src/Menu/types.ts +2 -1
  53. package/src/Popover/Popover.native.tsx +2 -0
  54. package/src/Popover/Popover.web.tsx +2 -1
  55. package/src/Popover/types.ts +2 -1
  56. package/src/Pressable/Pressable.native.tsx +2 -1
  57. package/src/Pressable/Pressable.web.tsx +2 -0
  58. package/src/Progress/Progress.native.tsx +3 -2
  59. package/src/Progress/Progress.web.tsx +3 -2
  60. package/src/Progress/types.ts +2 -1
  61. package/src/RadioButton/RadioButton.native.tsx +2 -0
  62. package/src/RadioButton/RadioButton.web.tsx +2 -0
  63. package/src/RadioButton/RadioGroup.native.tsx +2 -0
  64. package/src/RadioButton/RadioGroup.web.tsx +2 -0
  65. package/src/RadioButton/types.ts +2 -2
  66. package/src/SVGImage/SVGImage.native.tsx +3 -2
  67. package/src/SVGImage/SVGImage.web.tsx +3 -2
  68. package/src/SVGImage/types.ts +2 -1
  69. package/src/Screen/Screen.native.tsx +3 -1
  70. package/src/Screen/Screen.web.tsx +2 -0
  71. package/src/Select/Select.native.tsx +2 -1
  72. package/src/Select/Select.web.tsx +2 -1
  73. package/src/Skeleton/Skeleton.native.tsx +4 -0
  74. package/src/Skeleton/Skeleton.web.tsx +4 -0
  75. package/src/Skeleton/types.ts +3 -2
  76. package/src/Slider/Slider.native.tsx +5 -4
  77. package/src/Slider/Slider.web.tsx +2 -1
  78. package/src/Switch/Switch.native.tsx +3 -0
  79. package/src/Switch/Switch.web.tsx +2 -0
  80. package/src/TabBar/TabBar.native.tsx +48 -6
  81. package/src/TabBar/TabBar.styles.tsx +88 -1
  82. package/src/TabBar/TabBar.web.tsx +50 -2
  83. package/src/TabBar/types.ts +10 -0
  84. package/src/Table/Table.native.tsx +2 -0
  85. package/src/Table/Table.web.tsx +2 -1
  86. package/src/Text/Text.native.tsx +7 -7
  87. package/src/Text/Text.styles.tsx +23 -30
  88. package/src/Text/Text.web.tsx +8 -8
  89. package/src/Text/types.ts +1 -9
  90. package/src/TextArea/TextArea.native.tsx +2 -1
  91. package/src/TextArea/TextArea.web.tsx +2 -1
  92. package/src/Tooltip/Tooltip.native.tsx +2 -1
  93. package/src/Tooltip/Tooltip.web.tsx +2 -0
  94. package/src/Tooltip/types.ts +2 -1
  95. package/src/Video/Video.native.tsx +3 -2
  96. package/src/Video/Video.web.tsx +2 -0
  97. package/src/Video/types.ts +2 -1
  98. package/src/View/View.native.tsx +3 -1
  99. package/src/View/View.web.tsx +2 -0
  100. package/src/examples/TabBarExamples.tsx +122 -1
  101. package/src/utils/index.ts +20 -0
  102. package/src/utils/viewStyleProps.ts +12 -4
@@ -1,6 +1,7 @@
1
1
  import { Intent, Size } from '@idealyst/theme';
2
2
  import type { ReactNode } from 'react';
3
3
  import type { StyleProp, ViewStyle } from 'react-native';
4
+ import { BaseProps } from '../utils/viewStyleProps';
4
5
 
5
6
  // Component-specific type aliases for future extensibility
6
7
  export type DividerIntentVariant = Intent;
@@ -10,7 +11,7 @@ export type DividerThicknessVariant = 'thin' | 'md' | 'thick';
10
11
  export type DividerLengthVariant = 'full' | 'auto' | number;
11
12
  export type DividerSpacingVariant = 'none' | Size;
12
13
 
13
- export interface DividerProps {
14
+ export interface DividerProps extends BaseProps {
14
15
  /**
15
16
  * The orientation of the divider
16
17
  */
@@ -11,6 +11,7 @@ const Icon = forwardRef<any, IconProps>(({
11
11
  style,
12
12
  testID,
13
13
  accessibilityLabel,
14
+ id,
14
15
  }: IconProps, ref) => {
15
16
 
16
17
 
@@ -22,6 +23,7 @@ const Icon = forwardRef<any, IconProps>(({
22
23
  return (
23
24
  <MaterialCommunityIcons
24
25
  ref={ref}
26
+ nativeID={id}
25
27
  name={name}
26
28
  style={[iconStyle, style]}
27
29
  testID={testID}
@@ -19,6 +19,7 @@ const Icon = forwardRef<HTMLDivElement, IconProps>((props: InternalIconProps, re
19
19
  style,
20
20
  testID,
21
21
  accessibilityLabel,
22
+ id,
22
23
  ...restProps
23
24
  } = props;
24
25
 
@@ -32,7 +33,8 @@ const Icon = forwardRef<HTMLDivElement, IconProps>((props: InternalIconProps, re
32
33
  return (
33
34
  <div
34
35
  {...iconProps}
35
- ref={mergedRef}>
36
+ ref={mergedRef}
37
+ id={id}>
36
38
  <MdiIcon
37
39
  path={path}
38
40
  size={'100%'}
package/src/Icon/types.ts CHANGED
@@ -2,10 +2,11 @@ import type { StyleProp, ViewStyle } from 'react-native';
2
2
  import type { IconName } from "./icon-types";
3
3
  import type { Size } from '@idealyst/theme';
4
4
  import { Color, Intent } from '@idealyst/theme';
5
+ import { BaseProps } from '../utils/viewStyleProps';
5
6
 
6
7
  export type IconSizeVariant = Size | number;
7
8
 
8
- export interface IconProps {
9
+ export interface IconProps extends BaseProps {
9
10
  /**
10
11
  * The name of the icon to display
11
12
  */
@@ -19,6 +19,7 @@ const Image = forwardRef<View, ImageProps>(({
19
19
  style,
20
20
  testID,
21
21
  accessibilityLabel,
22
+ id,
22
23
  }, ref) => {
23
24
 
24
25
  const [isLoading, setIsLoading] = useState(true);
@@ -56,7 +57,7 @@ const Image = forwardRef<View, ImageProps>(({
56
57
  ];
57
58
 
58
59
  return (
59
- <View ref={ref} style={containerStyle as any} testID={testID}>
60
+ <View ref={ref} nativeID={id} style={containerStyle as any} testID={testID}>
60
61
  <RNImage
61
62
  source={imageSource as any}
62
63
  style={[imageStyles.image, { borderRadius }]}
@@ -20,6 +20,7 @@ const Image: React.FC<ImageProps> = ({
20
20
  style,
21
21
  testID,
22
22
  accessibilityLabel,
23
+ id,
23
24
  }) => {
24
25
  const [isLoading, setIsLoading] = useState(true);
25
26
  const [hasError, setHasError] = useState(false);
@@ -62,6 +63,7 @@ const Image: React.FC<ImageProps> = ({
62
63
  return (
63
64
  <div
64
65
  {...containerProps}
66
+ id={id}
65
67
  data-testid={testID}
66
68
  >
67
69
  <img
@@ -1,8 +1,9 @@
1
1
  import type { StyleProp, ImageStyle, ImageSourcePropType } from 'react-native';
2
+ import { BaseProps } from '../utils/viewStyleProps';
2
3
 
3
4
  export type ImageObjectFit = 'contain' | 'cover' | 'fill' | 'none' | 'scale-down';
4
5
 
5
- export interface ImageProps {
6
+ export interface ImageProps extends BaseProps {
6
7
  source: ImageSourcePropType | string;
7
8
  alt?: string;
8
9
  width?: number | string;
@@ -27,6 +27,7 @@ const Input = React.forwardRef<TextInput, InputProps>(({
27
27
  marginHorizontal,
28
28
  style,
29
29
  testID,
30
+ id,
30
31
  }, ref) => {
31
32
  const [isFocused, setIsFocused] = useState(false);
32
33
  const [isPasswordVisible, setIsPasswordVisible] = useState(false);
@@ -125,7 +126,7 @@ const Input = React.forwardRef<TextInput, InputProps>(({
125
126
  };
126
127
 
127
128
  return (
128
- <View style={[inputStyles.container, style]} testID={testID}>
129
+ <View style={[inputStyles.container, style]} testID={testID} nativeID={id}>
129
130
  {/* Left Icon */}
130
131
  {leftIcon && (
131
132
  <View style={inputStyles.leftIconContainer}>
@@ -121,6 +121,7 @@ export const inputStyles = StyleSheet.create((theme: Theme) => {
121
121
  flexDirection: 'row',
122
122
  alignItems: 'center',
123
123
  width: '100%',
124
+ minWidth: 0,
124
125
  borderRadius: 8,
125
126
  variants: {
126
127
  size: buildSizeVariants(theme, 'input', (size) => ({
@@ -29,6 +29,7 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>(({
29
29
  marginHorizontal,
30
30
  style,
31
31
  testID,
32
+ id,
32
33
  }, ref) => {
33
34
  const [isPasswordVisible, setIsPasswordVisible] = useState(false);
34
35
 
@@ -179,7 +180,7 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>(({
179
180
  };
180
181
 
181
182
  return (
182
- <div onClick={handleContainerPress} {...containerProps} data-testid={testID}>
183
+ <div onClick={handleContainerPress} {...containerProps} id={id} data-testid={testID}>
183
184
  {/* Left Icon */}
184
185
  {leftIcon && (
185
186
  <span {...leftIconContainerProps}>
@@ -12,6 +12,7 @@ const Link: React.FC<LinkProps> = ({
12
12
  testID,
13
13
  accessibilityLabel,
14
14
  onPress,
15
+ id,
15
16
  }) => {
16
17
  const navigator = useNavigator();
17
18
 
@@ -28,6 +29,7 @@ const Link: React.FC<LinkProps> = ({
28
29
  disabled={disabled}
29
30
  style={style}
30
31
  testID={testID}
32
+ id={id}
31
33
  accessibilityLabel={accessibilityLabel}
32
34
  accessibilityRole="link"
33
35
  >
@@ -12,6 +12,7 @@ const Link: React.FC<LinkProps> = ({
12
12
  testID,
13
13
  accessibilityLabel,
14
14
  onPress,
15
+ id,
15
16
  }) => {
16
17
  const navigator = useNavigator();
17
18
 
@@ -30,6 +31,7 @@ const Link: React.FC<LinkProps> = ({
30
31
  testID={testID}
31
32
  accessibilityLabel={accessibilityLabel}
32
33
  accessibilityRole="link"
34
+ id={id}
33
35
  >
34
36
  {children}
35
37
  </Pressable>
package/src/Link/types.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  import type { ReactNode } from 'react';
2
2
  import type { StyleProp, ViewStyle } from 'react-native';
3
+ import { BaseProps } from '../utils/viewStyleProps';
3
4
 
4
- export interface LinkProps {
5
+ export interface LinkProps extends BaseProps {
5
6
  /** The destination path to navigate to */
6
7
  to: string;
7
8
  /** Variables to substitute in the path (e.g., { id: '123' } for '/user/:id') */
@@ -20,6 +20,7 @@ const List = forwardRef<View, ListProps>(({
20
20
  testID,
21
21
  scrollable = false,
22
22
  maxHeight,
23
+ id,
23
24
  }, ref) => {
24
25
  // Apply types
25
26
  listStyles.useVariants({
@@ -50,6 +51,7 @@ const List = forwardRef<View, ListProps>(({
50
51
  return (
51
52
  <ScrollView
52
53
  ref={ref as any}
54
+ nativeID={id}
53
55
  style={containerStyle as any}
54
56
  testID={testID}
55
57
  showsVerticalScrollIndicator={true}
@@ -60,7 +62,7 @@ const List = forwardRef<View, ListProps>(({
60
62
  }
61
63
 
62
64
  return (
63
- <View ref={ref} style={containerStyle as any} testID={testID}>
65
+ <View ref={ref} nativeID={id} style={containerStyle as any} testID={testID}>
64
66
  {content}
65
67
  </View>
66
68
  );
@@ -20,6 +20,7 @@ const List: React.FC<ListProps> = ({
20
20
  testID,
21
21
  scrollable = false,
22
22
  maxHeight,
23
+ id,
23
24
  }) => {
24
25
  // Apply types
25
26
  listStyles.useVariants({
@@ -47,6 +48,7 @@ const List: React.FC<ListProps> = ({
47
48
  <div
48
49
  {...containerProps}
49
50
  role="list"
51
+ id={id}
50
52
  data-testid={testID}
51
53
  >
52
54
  {children}
@@ -21,6 +21,7 @@ const Menu = forwardRef<View, MenuProps>(({
21
21
  style,
22
22
  size,
23
23
  testID,
24
+ id,
24
25
  }, ref) => {
25
26
  const {
26
27
  position: menuPosition,
@@ -136,7 +137,7 @@ const Menu = forwardRef<View, MenuProps>(({
136
137
 
137
138
  return (
138
139
  <>
139
- <View ref={mergedTriggerRef} collapsable={false}>
140
+ <View ref={mergedTriggerRef} nativeID={id} collapsable={false}>
140
141
  {trigger}
141
142
  </View>
142
143
 
@@ -16,6 +16,7 @@ const Menu = forwardRef<HTMLDivElement, MenuProps>(({
16
16
  size = 'md',
17
17
  style,
18
18
  testID,
19
+ id,
19
20
  }, ref) => {
20
21
  const triggerRef = useRef<HTMLDivElement>(null);
21
22
  const menuRef = useRef<HTMLDivElement>(null);
@@ -65,6 +66,7 @@ const Menu = forwardRef<HTMLDivElement, MenuProps>(({
65
66
  {...menuProps}
66
67
  ref={mergedMenuRef}
67
68
  role="menu"
69
+ id={id}
68
70
  data-testid={testID}
69
71
  >
70
72
  {items.map((item, index) => {
package/src/Menu/types.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import type { StyleProp, ViewStyle } from 'react-native';
2
2
  import type { IconName } from '../Icon/icon-types';
3
3
  import { Intent, Size } from '@idealyst/theme';
4
+ import { BaseProps } from '../utils/viewStyleProps';
4
5
 
5
6
  // Component-specific type aliases for future extensibility
6
7
  export type MenuIntentVariant = Intent;
@@ -17,7 +18,7 @@ export interface MenuItem {
17
18
  separator?: boolean;
18
19
  }
19
20
 
20
- export interface MenuProps {
21
+ export interface MenuProps extends BaseProps {
21
22
  children: React.ReactNode;
22
23
  items: MenuItem[];
23
24
  open?: boolean;
@@ -17,6 +17,7 @@ const Popover = forwardRef<View, PopoverProps>(({
17
17
  showArrow = false,
18
18
  style,
19
19
  testID,
20
+ id,
20
21
  }, ref) => {
21
22
  const popoverRef = useRef<View>(null);
22
23
  const [popoverPosition, setPopoverPosition] = useState({ top: 0, left: 0, width: 0 });
@@ -128,6 +129,7 @@ const Popover = forwardRef<View, PopoverProps>(({
128
129
  animationType="fade"
129
130
  onRequestClose={() => onOpenChange(false)}
130
131
  testID={testID}
132
+ nativeID={id}
131
133
  >
132
134
  <TouchableWithoutFeedback onPress={handleBackdropPress}>
133
135
  <View style={popoverStyles.backdrop}>
@@ -16,6 +16,7 @@ const Popover = forwardRef<HTMLDivElement, PopoverProps>(({
16
16
  closeOnEscapeKey = true,
17
17
  showArrow = false,
18
18
  testID,
19
+ id,
19
20
  }, ref) => {
20
21
  const popoverRef = useRef<HTMLDivElement>(null);
21
22
 
@@ -47,7 +48,7 @@ const Popover = forwardRef<HTMLDivElement, PopoverProps>(({
47
48
  onEscapeKey={closeOnEscapeKey ? () => onOpenChange(false) : undefined}
48
49
  zIndex={9999}
49
50
  >
50
- <div ref={mergedPopoverRef} data-testid={testID}>
51
+ <div ref={mergedPopoverRef} id={id} data-testid={testID}>
51
52
  <div {...containerProps}>
52
53
  <div {...contentProps}>
53
54
  {children}
@@ -1,5 +1,6 @@
1
1
  import type { ReactNode } from 'react';
2
2
  import type { StyleProp, ViewStyle } from 'react-native';
3
+ import { BaseProps } from '../utils/viewStyleProps';
3
4
 
4
5
  export type PopoverPlacement =
5
6
  | 'top' | 'top-start' | 'top-end'
@@ -7,7 +8,7 @@ export type PopoverPlacement =
7
8
  | 'left' | 'left-start' | 'left-end'
8
9
  | 'right' | 'right-start' | 'right-end';
9
10
 
10
- export interface PopoverProps {
11
+ export interface PopoverProps extends BaseProps {
11
12
  /**
12
13
  * Whether the popover is open/visible
13
14
  */
@@ -17,6 +17,7 @@ const Pressable = forwardRef<View, PressableProps>(({
17
17
  testID,
18
18
  accessibilityLabel,
19
19
  accessibilityRole,
20
+ id,
20
21
  }, ref) => {
21
22
  // Apply spacing variants
22
23
  pressableStyles.useVariants({
@@ -34,7 +35,7 @@ const Pressable = forwardRef<View, PressableProps>(({
34
35
  testID={testID}
35
36
  accessibilityLabel={accessibilityLabel}
36
37
  >
37
- <View ref={ref} style={[pressableStyles.pressable, style]}>
38
+ <View ref={ref} nativeID={id} style={[pressableStyles.pressable, style]}>
38
39
  {children}
39
40
  </View>
40
41
  </TouchableWithoutFeedback>
@@ -18,6 +18,7 @@ const Pressable = forwardRef<HTMLDivElement, PressableProps>(({
18
18
  testID,
19
19
  accessibilityLabel,
20
20
  accessibilityRole = 'button',
21
+ id,
21
22
  }, ref) => {
22
23
  const [isPressed, setIsPressed] = useState(false);
23
24
 
@@ -74,6 +75,7 @@ const Pressable = forwardRef<HTMLDivElement, PressableProps>(({
74
75
  <div
75
76
  {...webProps}
76
77
  ref={mergedRef}
78
+ id={id}
77
79
  role={accessibilityRole}
78
80
  tabIndex={disabled ? -1 : 0}
79
81
  style={{ ...baseStyle, ...webProps.style }}
@@ -29,6 +29,7 @@ const Progress = forwardRef<View, ProgressProps>(({
29
29
  rounded = true,
30
30
  style,
31
31
  testID,
32
+ id,
32
33
  }, ref) => {
33
34
  const percentage = Math.min(Math.max((value / max) * 100, 0), 100);
34
35
  const { theme }: { theme: Theme } = useUnistyles();
@@ -104,7 +105,7 @@ const Progress = forwardRef<View, ProgressProps>(({
104
105
  });
105
106
 
106
107
  return (
107
- <View style={[progressStyles.circularContainer, style]} testID={testID}>
108
+ <View nativeID={id} style={[progressStyles.circularContainer, style]} testID={testID}>
108
109
  <Animated.View style={indeterminate ? rotationStyle : {}}>
109
110
  <Svg width={circularSize} height={circularSize} style={{ transform: [{ rotate: '-90deg' }] }}>
110
111
  {/* Track circle (background) */}
@@ -157,7 +158,7 @@ const Progress = forwardRef<View, ProgressProps>(({
157
158
  });
158
159
 
159
160
  return (
160
- <View ref={ref} style={[progressStyles.container, style]} testID={testID} accessibilityRole="progressbar">
161
+ <View ref={ref} nativeID={id} style={[progressStyles.container, style]} testID={testID} accessibilityRole="progressbar">
161
162
  <View style={progressStyles.linearTrack}>
162
163
  {indeterminate ? (
163
164
  <Animated.View style={[progressStyles.indeterminateBar, indeterminateAnimatedStyle]} />
@@ -15,6 +15,7 @@ const Progress: React.FC<ProgressProps> = ({
15
15
  rounded = true,
16
16
  style,
17
17
  testID,
18
+ id,
18
19
  }) => {
19
20
  const percentage = Math.min(Math.max((value / max) * 100, 0), 100);
20
21
 
@@ -56,7 +57,7 @@ const Progress: React.FC<ProgressProps> = ({
56
57
  console.log(trackColorProps)
57
58
 
58
59
  return (
59
- <div {...computedContainerProps} data-testid={testID}>
60
+ <div {...computedContainerProps} id={id} data-testid={testID}>
60
61
  <svg
61
62
  width={circularSize}
62
63
  height={circularSize}
@@ -106,7 +107,7 @@ const Progress: React.FC<ProgressProps> = ({
106
107
 
107
108
  return (
108
109
  <>
109
- <div {...containerProps} data-testid={testID}>
110
+ <div {...containerProps} id={id} data-testid={testID}>
110
111
  <div
111
112
  {...trackProps}
112
113
  role="progressbar"
@@ -1,12 +1,13 @@
1
1
  import type { StyleProp, ViewStyle } from 'react-native';
2
2
  import type { Intent, Size } from '@idealyst/theme';
3
+ import { BaseProps } from '../utils/viewStyleProps';
3
4
 
4
5
  // Component-specific type aliases for future extensibility
5
6
  export type ProgressIntentVariant = Intent;
6
7
  export type ProgressSizeVariant = Size;
7
8
  export type ProgressVariant = 'linear' | 'circular';
8
9
 
9
- export interface ProgressProps {
10
+ export interface ProgressProps extends BaseProps {
10
11
  value?: number;
11
12
  max?: number;
12
13
  variant?: ProgressVariant;
@@ -19,6 +19,7 @@ const RadioButton = forwardRef<ComponentRef<typeof Pressable>, RadioButtonProps>
19
19
  marginHorizontal,
20
20
  style,
21
21
  testID,
22
+ id,
22
23
  }, ref) => {
23
24
  const group = useRadioGroup();
24
25
 
@@ -64,6 +65,7 @@ const RadioButton = forwardRef<ComponentRef<typeof Pressable>, RadioButtonProps>
64
65
  return (
65
66
  <Pressable
66
67
  ref={ref}
68
+ nativeID={id}
67
69
  onPress={handlePress}
68
70
  disabled={disabled}
69
71
  style={[radioButtonStyles.container, style]}
@@ -18,6 +18,7 @@ const RadioButton: React.FC<RadioButtonProps> = ({
18
18
  marginHorizontal,
19
19
  style,
20
20
  testID,
21
+ id,
21
22
  }) => {
22
23
  const group = useRadioGroup();
23
24
 
@@ -54,6 +55,7 @@ const RadioButton: React.FC<RadioButtonProps> = ({
54
55
  {...containerProps}
55
56
  onClick={handleClick}
56
57
  disabled={disabled}
58
+ id={id}
57
59
  data-testid={testID}
58
60
  role="radio"
59
61
  aria-checked={checked}
@@ -19,12 +19,14 @@ const RadioGroup = forwardRef<View, RadioGroupProps>(({
19
19
  children,
20
20
  style,
21
21
  testID,
22
+ id,
22
23
  }, ref) => {
23
24
 
24
25
  return (
25
26
  <RadioGroupContext.Provider value={{ value, onValueChange, disabled }}>
26
27
  <View
27
28
  ref={ref}
29
+ nativeID={id}
28
30
  style={[
29
31
  radioButtonStyles.groupContainer,
30
32
  style as any,
@@ -19,6 +19,7 @@ const RadioGroup: React.FC<RadioGroupProps> = ({
19
19
  children,
20
20
  style,
21
21
  testID,
22
+ id,
22
23
  }) => {
23
24
  // Apply variants
24
25
  radioButtonStyles.useVariants({
@@ -35,6 +36,7 @@ const RadioGroup: React.FC<RadioGroupProps> = ({
35
36
  <div
36
37
  {...groupProps}
37
38
  role="radiogroup"
39
+ id={id}
38
40
  data-testid={testID}
39
41
  style={{
40
42
  display: 'flex',
@@ -1,7 +1,7 @@
1
1
  import type { StyleProp, ViewStyle } from 'react-native';
2
2
  import type { ReactNode } from 'react';
3
3
  import { Intent, Size } from '@idealyst/theme';
4
- import { FormInputStyleProps } from '../utils/viewStyleProps';
4
+ import { FormInputStyleProps, BaseProps } from '../utils/viewStyleProps';
5
5
 
6
6
  // Component-specific type aliases for future extensibility
7
7
  export type RadioButtonIntentVariant = Intent;
@@ -19,7 +19,7 @@ export interface RadioButtonProps extends FormInputStyleProps {
19
19
  testID?: string;
20
20
  }
21
21
 
22
- export interface RadioGroupProps {
22
+ export interface RadioGroupProps extends BaseProps {
23
23
  value?: string;
24
24
  onValueChange?: (value: string) => void;
25
25
  disabled?: boolean;
@@ -13,6 +13,7 @@ const SVGImage = forwardRef<View, SVGImageProps>(({
13
13
  intent,
14
14
  style,
15
15
  testID,
16
+ id,
16
17
  ...props
17
18
  }, ref) => {
18
19
  // Apply variants using Unistyles 3.0 pattern
@@ -30,7 +31,7 @@ const SVGImage = forwardRef<View, SVGImageProps>(({
30
31
  if (typeof source === 'function') {
31
32
  const SvgComponent = source;
32
33
  return (
33
- <View ref={ref} style={[svgImageStyles.container, style]} testID={testID} {...props}>
34
+ <View ref={ref} nativeID={id} style={[svgImageStyles.container, style]} testID={testID} {...props}>
34
35
  <SvgComponent
35
36
  width={finalWidth}
36
37
  height={finalHeight}
@@ -45,7 +46,7 @@ const SVGImage = forwardRef<View, SVGImageProps>(({
45
46
  const sourceUri = typeof source === 'string' ? source : source.uri;
46
47
 
47
48
  return (
48
- <View ref={ref} style={[svgImageStyles.container, style]} testID={testID} {...props}>
49
+ <View ref={ref} nativeID={id} style={[svgImageStyles.container, style]} testID={testID} {...props}>
49
50
  <SvgUri
50
51
  uri={sourceUri}
51
52
  width={finalWidth}
@@ -14,6 +14,7 @@ const SVGImage = forwardRef<HTMLDivElement, SVGImageProps>(({
14
14
  resizeMode = 'contain',
15
15
  style,
16
16
  testID,
17
+ id,
17
18
  ...props
18
19
  }, ref) => {
19
20
  // Apply variants using Unistyles 3.0 pattern
@@ -33,7 +34,7 @@ const SVGImage = forwardRef<HTMLDivElement, SVGImageProps>(({
33
34
  const componentContainerProps = getWebProps([svgImageStyles.container, style as any]);
34
35
  const mergedRefForComponent = useMergeRefs(ref, componentContainerProps.ref);
35
36
  return (
36
- <div {...componentContainerProps} ref={mergedRefForComponent} {...(props as any)} data-testid={testID}>
37
+ <div {...componentContainerProps} ref={mergedRefForComponent} {...(props as any)} id={id} data-testid={testID}>
37
38
  <SvgComponent
38
39
  width={finalWidth || 24}
39
40
  height={finalHeight || 24}
@@ -80,7 +81,7 @@ const SVGImage = forwardRef<HTMLDivElement, SVGImageProps>(({
80
81
  const mergedRef = useMergeRefs(ref, containerWebProps.ref);
81
82
 
82
83
  return (
83
- <div {...containerWebProps} ref={mergedRef} {...(props as any)} data-testid={testID}>
84
+ <div {...containerWebProps} ref={mergedRef} {...(props as any)} id={id} data-testid={testID}>
84
85
  <img
85
86
  {...imageWebProps}
86
87
  src={sourceUrl}
@@ -2,12 +2,13 @@ import { Intent } from '@idealyst/theme';
2
2
  import React from 'react';
3
3
  import { ViewProps } from 'react-native';
4
4
  import { SvgProps } from 'react-native-svg';
5
+ import { BaseProps } from '../utils/viewStyleProps';
5
6
 
6
7
  // Component-specific type aliases for future extensibility
7
8
  export type SVGImageIntentVariant = Intent;
8
9
  export type SVGImageResizeMode = 'contain' | 'cover' | 'stretch';
9
10
 
10
- export interface SVGImageProps extends Omit<ViewProps, 'children'> {
11
+ export interface SVGImageProps extends Omit<ViewProps, 'children'>, BaseProps {
11
12
  source: string | { uri: string } | React.FC<SvgProps>;
12
13
  width?: number | string;
13
14
  height?: number | string;
@@ -19,6 +19,7 @@ const Screen = forwardRef<RNView | RNScrollView, ScreenProps>(({
19
19
  marginHorizontal,
20
20
  style,
21
21
  testID,
22
+ id,
22
23
  }, ref) => {
23
24
 
24
25
  screenStyles.useVariants({
@@ -51,6 +52,7 @@ const Screen = forwardRef<RNView | RNScrollView, ScreenProps>(({
51
52
  return (
52
53
  <RNScrollView
53
54
  ref={ref as any}
55
+ nativeID={id}
54
56
  style={scrollViewStyle}
55
57
  contentContainerStyle={contentContainerStyleArray}
56
58
  testID={testID}
@@ -63,7 +65,7 @@ const Screen = forwardRef<RNView | RNScrollView, ScreenProps>(({
63
65
  const containerStyle = [screenStyles.screen, style];
64
66
 
65
67
  const view = (
66
- <RNView ref={ref as any} style={containerStyle} testID={testID}>
68
+ <RNView ref={ref as any} nativeID={id} style={containerStyle} testID={testID}>
67
69
  {children}
68
70
  </RNView>
69
71
  );
@@ -18,6 +18,7 @@ const Screen = forwardRef<HTMLDivElement, ScreenProps>(({
18
18
  marginHorizontal,
19
19
  style,
20
20
  testID,
21
+ id,
21
22
  }, ref) => {
22
23
  screenStyles.useVariants({
23
24
  background,
@@ -40,6 +41,7 @@ const Screen = forwardRef<HTMLDivElement, ScreenProps>(({
40
41
  <div
41
42
  {...webProps}
42
43
  ref={mergedRef}
44
+ id={id}
43
45
  data-testid={testID}
44
46
  >
45
47
  {children}
@@ -40,6 +40,7 @@ const Select = forwardRef<View, SelectProps>(({
40
40
  style,
41
41
  testID,
42
42
  accessibilityLabel,
43
+ id,
43
44
  }, ref) => {
44
45
  const [isOpen, setIsOpen] = useState(false);
45
46
  const [searchTerm, setSearchTerm] = useState('');
@@ -298,7 +299,7 @@ const Select = forwardRef<View, SelectProps>(({
298
299
  };
299
300
 
300
301
  return (
301
- <View ref={ref} style={[selectStyles.container, style]} testID={testID}>
302
+ <View ref={ref} nativeID={id} style={[selectStyles.container, style]} testID={testID}>
302
303
  {label && (
303
304
  <Text style={selectStyles.label}>
304
305
  {label}