@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
@@ -5,9 +5,8 @@ import { textStyles } from './Text.styles';
5
5
 
6
6
  const Text = forwardRef<RNText, TextProps>(({
7
7
  children,
8
- typography,
9
- size = 'md',
10
- weight = 'normal',
8
+ typography = 'body1',
9
+ weight,
11
10
  color,
12
11
  align = 'left',
13
12
  // Spacing variants from TextSpacingStyleProps
@@ -17,11 +16,11 @@ const Text = forwardRef<RNText, TextProps>(({
17
16
  paddingHorizontal,
18
17
  style,
19
18
  testID,
19
+ id,
20
20
  }, ref) => {
21
- // When typography is set, it overrides size and weight (handled in styles)
22
21
  textStyles.useVariants({
23
- size: typography ? 'md' : size, // Use default when typography is set (will be overridden)
24
- weight: typography ? 'normal' : weight, // Use default when typography is set (will be overridden)
22
+ typography,
23
+ weight,
25
24
  align,
26
25
  gap,
27
26
  padding,
@@ -32,8 +31,9 @@ const Text = forwardRef<RNText, TextProps>(({
32
31
  return (
33
32
  <RNText
34
33
  ref={ref}
34
+ nativeID={id}
35
35
  style={[
36
- textStyles.text({ color, typography }),
36
+ textStyles.text({ color }),
37
37
  style,
38
38
  ]}
39
39
  testID={testID}
@@ -1,47 +1,51 @@
1
1
  import { StyleSheet } from "react-native-unistyles";
2
- import { Theme } from '@idealyst/theme';
3
- import { buildSizeVariants } from '../utils/buildSizeVariants';
2
+ import { Theme, Typography } from '@idealyst/theme';
4
3
  import {
5
4
  buildGapVariants,
6
5
  buildPaddingVariants,
7
6
  buildPaddingVerticalVariants,
8
7
  buildPaddingHorizontalVariants,
9
8
  } from '../utils/buildViewStyleVariants';
10
- import { TextAlignVariant, TextColorVariant, TextSizeVariant, TextWeightVariant, TextTypographyVariant } from "./types";
9
+ import { TextAlignVariant, TextColorVariant, TextWeightVariant, TextTypographyVariant } from "./types";
11
10
 
12
- type TextVariants = {
13
- size: TextSizeVariant;
11
+ export type TextVariants = {
12
+ typography: TextTypographyVariant;
14
13
  weight: TextWeightVariant;
15
14
  align: TextAlignVariant;
16
15
  }
17
16
 
18
17
  /**
19
- * Create size variants for text (legacy)
20
- * @deprecated Use typography prop instead
18
+ * Create typography variants from theme
21
19
  */
22
- function createSizeVariants(theme: Theme): any {
23
- return buildSizeVariants(theme, 'text', (size) => ({
24
- fontSize: size.fontSize,
25
- lineHeight: size.lineHeight,
26
- }));
20
+ function createTypographyVariants(theme: Theme) {
21
+ const variants: Record<string, object> = {};
22
+
23
+ for (const key in theme.sizes.typography) {
24
+ const typo = theme.sizes.typography[key as Typography];
25
+ variants[key] = {
26
+ fontSize: typo.fontSize,
27
+ lineHeight: typo.lineHeight,
28
+ fontWeight: typo.fontWeight,
29
+ };
30
+ }
31
+
32
+ return variants;
27
33
  }
28
34
 
29
35
  type TextStyleParams = {
30
36
  color?: TextColorVariant;
31
- typography?: TextTypographyVariant;
32
37
  }
33
38
 
34
39
  function createTextStyles(theme: Theme) {
35
- return ({ color, typography }: TextStyleParams) => {
36
- const colorValue = theme.colors.text[color] || theme.colors.text.primary;
40
+ return ({ color }: TextStyleParams) => {
41
+ const colorValue = theme.colors.text[color ?? 'primary'] || theme.colors.text.primary;
37
42
 
38
- // Base styles
39
- const baseStyles: any = {
43
+ return {
40
44
  margin: 0,
41
45
  padding: 0,
42
46
  color: colorValue,
43
47
  variants: {
44
- size: createSizeVariants(theme) as any,
48
+ typography: createTypographyVariants(theme),
45
49
  weight: {
46
50
  light: {
47
51
  fontWeight: '300',
@@ -78,19 +82,8 @@ function createTextStyles(theme: Theme) {
78
82
  } as const,
79
83
  _web: {
80
84
  fontFamily: 'inherit',
81
- lineHeight: 'inherit',
82
85
  },
83
86
  };
84
-
85
- // If typography is set, apply typography styles (overrides size/weight variants)
86
- if (typography && theme.sizes.typography[typography]) {
87
- const typo = theme.sizes.typography[typography];
88
- baseStyles.fontSize = typo.fontSize;
89
- baseStyles.lineHeight = typo.lineHeight;
90
- baseStyles.fontWeight = typo.fontWeight;
91
- }
92
-
93
- return baseStyles;
94
87
  }
95
88
  }
96
89
 
@@ -100,4 +93,4 @@ export const textStyles = StyleSheet.create((theme: Theme) => {
100
93
  return {
101
94
  text: createTextStyles(theme),
102
95
  };
103
- });
96
+ });
@@ -6,9 +6,8 @@ import useMergeRefs from '../hooks/useMergeRefs';
6
6
 
7
7
  const Text = forwardRef<HTMLSpanElement, TextProps>(({
8
8
  children,
9
- typography,
10
- size = 'md',
11
- weight = 'normal',
9
+ typography = 'body1',
10
+ weight,
12
11
  color = 'primary',
13
12
  align = 'left',
14
13
  // Spacing variants from TextSpacingStyleProps
@@ -18,11 +17,11 @@ const Text = forwardRef<HTMLSpanElement, TextProps>(({
18
17
  paddingHorizontal,
19
18
  style,
20
19
  testID,
20
+ id,
21
21
  }, ref) => {
22
- // When typography is set, it overrides size and weight (handled in styles)
23
22
  textStyles.useVariants({
24
- size: typography ? 'md' : size, // Use default when typography is set (will be overridden)
25
- weight: typography ? 'normal' : weight, // Use default when typography is set (will be overridden)
23
+ typography,
24
+ weight,
26
25
  align,
27
26
  gap,
28
27
  padding,
@@ -30,9 +29,9 @@ const Text = forwardRef<HTMLSpanElement, TextProps>(({
30
29
  paddingHorizontal,
31
30
  });
32
31
 
33
- // Create the style array - pass typography to dynamic style function
32
+ // Create the style array
34
33
  const textStyleArray = [
35
- textStyles.text({ color, typography }),
34
+ textStyles.text({ color }),
36
35
  style,
37
36
  ];
38
37
 
@@ -45,6 +44,7 @@ const Text = forwardRef<HTMLSpanElement, TextProps>(({
45
44
  <span
46
45
  {...webProps}
47
46
  ref={mergedRef}
47
+ id={id}
48
48
  data-testid={testID}
49
49
  >
50
50
  {children}
package/src/Text/types.ts CHANGED
@@ -5,7 +5,6 @@ import { TextSpacingStyleProps } from '../utils/viewStyleProps';
5
5
 
6
6
  // Component-specific type aliases for future extensibility
7
7
  export type TextColorVariant = Text;
8
- export type TextSizeVariant = 'sm' | 'md' | 'lg' | 'xl'; // Using sm/md/lg/xl for consistency
9
8
  export type TextWeightVariant = 'light' | 'normal' | 'medium' | 'semibold' | 'bold';
10
9
  export type TextAlignVariant = 'left' | 'center' | 'right';
11
10
  export type TextTypographyVariant = Typography;
@@ -19,19 +18,12 @@ export interface TextProps extends TextSpacingStyleProps {
19
18
  /**
20
19
  * Typography variant for semantic text styling.
21
20
  * Automatically sets fontSize, lineHeight, and fontWeight.
22
- * When set, overrides size and weight props.
23
21
  */
24
22
  typography?: TextTypographyVariant;
25
23
 
26
- /**
27
- * The size variant of the text
28
- * @deprecated Use `typography` prop instead for semantic text styling (e.g., 'h1', 'body1', 'caption')
29
- */
30
- size?: TextSizeVariant;
31
-
32
24
  /**
33
25
  * The weight of the text.
34
- * Note: When `typography` is set, this is ignored as typography includes fontWeight.
26
+ * Overrides the weight from typography if both are set.
35
27
  */
36
28
  weight?: TextWeightVariant;
37
29
 
@@ -28,6 +28,7 @@ const TextArea = forwardRef<TextInput, TextAreaProps>(({
28
28
  style,
29
29
  textareaStyle,
30
30
  testID,
31
+ id,
31
32
  }, ref) => {
32
33
  const [internalValue, setInternalValue] = useState(defaultValue);
33
34
  const [contentHeight, setContentHeight] = useState<number | undefined>(undefined);
@@ -81,7 +82,7 @@ const TextArea = forwardRef<TextInput, TextAreaProps>(({
81
82
  const showFooter = (error || helperText) || (showCharacterCount && maxLength);
82
83
 
83
84
  return (
84
- <View style={[textAreaStyles.container, style]} testID={testID}>
85
+ <View nativeID={id} style={[textAreaStyles.container, style]} testID={testID}>
85
86
  {label && (
86
87
  <Text style={textAreaStyles.label}>{label}</Text>
87
88
  )}
@@ -29,6 +29,7 @@ const TextArea = forwardRef<HTMLDivElement, TextAreaProps>(({
29
29
  style,
30
30
  textareaStyle,
31
31
  testID,
32
+ id,
32
33
  }, ref) => {
33
34
  const [internalValue, setInternalValue] = useState(defaultValue);
34
35
  const textareaRef = useRef<HTMLTextAreaElement>(null);
@@ -112,7 +113,7 @@ const TextArea = forwardRef<HTMLDivElement, TextAreaProps>(({
112
113
  const mergedTextareaRef = useMergeRefs(textareaRef, computedTextareaProps.ref);
113
114
 
114
115
  return (
115
- <div {...containerProps} ref={mergedRef} data-testid={testID}>
116
+ <div {...containerProps} ref={mergedRef} id={id} data-testid={testID}>
116
117
  {label && (
117
118
  <label {...labelProps}>{label}</label>
118
119
  )}
@@ -12,6 +12,7 @@ const Tooltip = forwardRef<View, TooltipProps>(({
12
12
  size = 'md',
13
13
  style,
14
14
  testID,
15
+ id,
15
16
  }, ref) => {
16
17
  const [visible, setVisible] = useState(false);
17
18
  const [tooltipPosition, setTooltipPosition] = useState({ top: 0, left: 0, width: 0 });
@@ -126,7 +127,7 @@ const Tooltip = forwardRef<View, TooltipProps>(({
126
127
 
127
128
  return (
128
129
  <>
129
- <View ref={ref} collapsable={false} style={style}>
130
+ <View ref={ref} nativeID={id} collapsable={false} style={style}>
130
131
  {trigger}
131
132
  </View>
132
133
 
@@ -13,6 +13,7 @@ const Tooltip: React.FC<TooltipProps> = ({
13
13
  size = 'md',
14
14
  style,
15
15
  testID,
16
+ id,
16
17
  }) => {
17
18
  const [visible, setVisible] = useState(false);
18
19
  const timeoutRef = useRef<NodeJS.Timeout | null>(null);
@@ -60,6 +61,7 @@ const Tooltip: React.FC<TooltipProps> = ({
60
61
  {...containerProps}
61
62
  onMouseEnter={handleMouseEnter}
62
63
  onMouseLeave={handleMouseLeave}
64
+ id={id}
63
65
  data-testid={testID}
64
66
  >
65
67
  {children}
@@ -1,12 +1,13 @@
1
1
  import { Intent, Size } from '@idealyst/theme';
2
2
  import type { StyleProp, ViewStyle } from 'react-native';
3
+ import { BaseProps } from '../utils/viewStyleProps';
3
4
 
4
5
  // Component-specific type aliases for future extensibility
5
6
  export type TooltipIntentVariant = Intent;
6
7
  export type TooltipSizeVariant = Size;
7
8
  export type TooltipPlacement = 'top' | 'bottom' | 'left' | 'right';
8
9
 
9
- export interface TooltipProps {
10
+ export interface TooltipProps extends BaseProps {
10
11
  content: string | React.ReactNode;
11
12
  children: React.ReactNode;
12
13
  placement?: TooltipPlacement;
@@ -32,11 +32,12 @@ const Video = React.forwardRef<View, VideoProps>(({
32
32
  borderRadius,
33
33
  style,
34
34
  testID,
35
+ id,
35
36
  }, ref) => {
36
37
 
37
38
  if (!RNVideo) {
38
39
  return (
39
- <View ref={ref} style={[videoStyles.container, { aspectRatio, borderRadius }, style]} testID={testID}>
40
+ <View ref={ref} nativeID={id} style={[videoStyles.container, { aspectRatio, borderRadius }, style]} testID={testID}>
40
41
  <View style={videoStyles.fallback}>
41
42
  {/* Fallback when react-native-video is not installed */}
42
43
  </View>
@@ -79,7 +80,7 @@ const Video = React.forwardRef<View, VideoProps>(({
79
80
  };
80
81
 
81
82
  return (
82
- <View ref={ref} style={containerStyle} testID={testID}>
83
+ <View ref={ref} nativeID={id} style={containerStyle} testID={testID}>
83
84
  <RNVideo
84
85
  source={videoSource}
85
86
  poster={poster}
@@ -25,6 +25,7 @@ const Video: React.FC<VideoProps> = ({
25
25
  borderRadius,
26
26
  style,
27
27
  testID,
28
+ id,
28
29
  }) => {
29
30
  const videoRef = useRef<HTMLVideoElement>(null);
30
31
 
@@ -85,6 +86,7 @@ const Video: React.FC<VideoProps> = ({
85
86
  <div
86
87
  {...containerProps}
87
88
  style={containerStyle}
89
+ id={id}
88
90
  data-testid={testID}
89
91
  >
90
92
  <video
@@ -1,11 +1,12 @@
1
1
  import type { StyleProp, ViewStyle } from 'react-native';
2
+ import { BaseProps } from '../utils/viewStyleProps';
2
3
 
3
4
  export interface VideoSource {
4
5
  uri: string;
5
6
  type?: string;
6
7
  }
7
8
 
8
- export interface VideoProps {
9
+ export interface VideoProps extends BaseProps {
9
10
  source: VideoSource | string;
10
11
  poster?: string;
11
12
  width?: number | string;
@@ -24,6 +24,7 @@ const View = forwardRef<RNView | RNScrollView, ViewProps>(({
24
24
  scrollable = false,
25
25
  style,
26
26
  testID,
27
+ id,
27
28
  }, ref) => {
28
29
  viewStyles.useVariants({
29
30
  background,
@@ -56,6 +57,7 @@ const View = forwardRef<RNView | RNScrollView, ViewProps>(({
56
57
  style={[{ flex: 1 }, style]}
57
58
  contentContainerStyle={[viewStyles.view, getStyles()]}
58
59
  testID={testID}
60
+ nativeID={id}
59
61
  >
60
62
  {children}
61
63
  </RNScrollView>
@@ -63,7 +65,7 @@ const View = forwardRef<RNView | RNScrollView, ViewProps>(({
63
65
  }
64
66
 
65
67
  return (
66
- <RNView ref={ref as any} style={[viewStyles.view, getStyles(), style]} testID={testID}>
68
+ <RNView ref={ref as any} style={[viewStyles.view, getStyles(), style]} testID={testID} nativeID={id}>
67
69
  {children}
68
70
  </RNView>
69
71
  );
@@ -25,6 +25,7 @@ const View = forwardRef<HTMLDivElement, ViewProps>(({
25
25
  scrollable, // accepted but no-op on web - layout handles scrolling
26
26
  style,
27
27
  testID,
28
+ id,
28
29
  }, ref) => {
29
30
  viewStyles.useVariants({
30
31
  background,
@@ -56,6 +57,7 @@ const View = forwardRef<HTMLDivElement, ViewProps>(({
56
57
  <div
57
58
  {...webProps}
58
59
  ref={mergedRef}
60
+ id={id}
59
61
  data-testid={testID}
60
62
  >
61
63
  {children}
@@ -1,5 +1,5 @@
1
1
  import React, { useState } from 'react';
2
- import { Screen, View, Text } from '@idealyst/components';
2
+ import { Screen, View, Text, Icon } from '@idealyst/components';
3
3
  import TabBar from '../TabBar';
4
4
  import type { TabBarItem } from '../TabBar/types';
5
5
 
@@ -7,6 +7,8 @@ export const TabBarExamples: React.FC = () => {
7
7
  const [activeTab, setActiveTab] = useState('tab1');
8
8
  const [variantTab, setVariantTab] = useState('home');
9
9
  const [pillTab, setPillTab] = useState('tab1');
10
+ const [iconTab, setIconTab] = useState('home');
11
+ const [justifyTab, setJustifyTab] = useState('tab1');
10
12
 
11
13
  const basicTabs: TabBarItem[] = [
12
14
  { value: 'tab1', label: 'Tab 1' },
@@ -26,6 +28,38 @@ export const TabBarExamples: React.FC = () => {
26
28
  { value: 'tab3', label: 'Enabled' },
27
29
  ];
28
30
 
31
+ // Tabs with icons using render function
32
+ const iconTabs: TabBarItem[] = [
33
+ {
34
+ value: 'home',
35
+ label: 'Home',
36
+ icon: ({ active, size }) => (
37
+ <Icon name="home" size={size} color={active ? 'primary' : 'secondary'} />
38
+ ),
39
+ },
40
+ {
41
+ value: 'search',
42
+ label: 'Search',
43
+ icon: ({ active, size }) => (
44
+ <Icon name="magnify" size={size} color={active ? 'primary' : 'secondary'} />
45
+ ),
46
+ },
47
+ {
48
+ value: 'profile',
49
+ label: 'Profile',
50
+ icon: ({ active, size }) => (
51
+ <Icon name="account" size={size} color={active ? 'primary' : 'secondary'} />
52
+ ),
53
+ },
54
+ {
55
+ value: 'settings',
56
+ label: 'Settings',
57
+ icon: ({ active, size }) => (
58
+ <Icon name="cog" size={size} color={active ? 'primary' : 'secondary'} />
59
+ ),
60
+ },
61
+ ];
62
+
29
63
  return (
30
64
  <Screen background="primary" padding="lg">
31
65
  <View gap="lg">
@@ -135,6 +169,93 @@ export const TabBarExamples: React.FC = () => {
135
169
  onChange={setActiveTab}
136
170
  />
137
171
  </View>
172
+
173
+ <View gap="md">
174
+ <Text typography="h5">With Icons</Text>
175
+ <View gap="sm">
176
+ <View gap="xs">
177
+ <Text typography="body2">Icons Left (default)</Text>
178
+ <TabBar
179
+ items={iconTabs}
180
+ value={iconTab}
181
+ onChange={setIconTab}
182
+ iconPosition="left"
183
+ />
184
+ </View>
185
+ <View gap="xs">
186
+ <Text typography="body2">Icons Top (stacked)</Text>
187
+ <TabBar
188
+ items={iconTabs}
189
+ value={iconTab}
190
+ onChange={setIconTab}
191
+ iconPosition="top"
192
+ />
193
+ </View>
194
+ <View gap="xs">
195
+ <Text typography="body2">Pills with Icons</Text>
196
+ <TabBar
197
+ items={iconTabs}
198
+ value={iconTab}
199
+ onChange={setIconTab}
200
+ type="pills"
201
+ iconPosition="left"
202
+ />
203
+ </View>
204
+ </View>
205
+ </View>
206
+
207
+ <View gap="md">
208
+ <Text typography="h5">Layout Justification</Text>
209
+ <View gap="sm">
210
+ <View gap="xs">
211
+ <Text typography="body2">Start (default)</Text>
212
+ <TabBar
213
+ items={basicTabs}
214
+ value={justifyTab}
215
+ onChange={setJustifyTab}
216
+ justify="start"
217
+ />
218
+ </View>
219
+ <View gap="xs">
220
+ <Text typography="body2">Center</Text>
221
+ <TabBar
222
+ items={basicTabs}
223
+ value={justifyTab}
224
+ onChange={setJustifyTab}
225
+ justify="center"
226
+ />
227
+ </View>
228
+ <View gap="xs">
229
+ <Text typography="body2">Equal (full width, equal tabs)</Text>
230
+ <TabBar
231
+ items={basicTabs}
232
+ value={justifyTab}
233
+ onChange={setJustifyTab}
234
+ justify="equal"
235
+ />
236
+ </View>
237
+ <View gap="xs">
238
+ <Text typography="body2">Space Between</Text>
239
+ <TabBar
240
+ items={basicTabs}
241
+ value={justifyTab}
242
+ onChange={setJustifyTab}
243
+ justify="space-between"
244
+ />
245
+ </View>
246
+ </View>
247
+ </View>
248
+
249
+ <View gap="md">
250
+ <Text typography="h5">Full Width with Icons</Text>
251
+ <TabBar
252
+ items={iconTabs}
253
+ value={iconTab}
254
+ onChange={setIconTab}
255
+ justify="equal"
256
+ iconPosition="top"
257
+ />
258
+ </View>
138
259
  </View>
139
260
  </Screen>
140
261
  );
@@ -0,0 +1,20 @@
1
+ // Size variant builder
2
+ export { buildSizeVariants } from './buildSizeVariants';
3
+
4
+ // View/container style variant builders
5
+ export {
6
+ buildGapVariants,
7
+ buildPaddingVariants,
8
+ buildPaddingVerticalVariants,
9
+ buildPaddingHorizontalVariants,
10
+ buildMarginVariants,
11
+ buildMarginVerticalVariants,
12
+ buildMarginHorizontalVariants,
13
+ buildContainerStyleVariants,
14
+ buildPaddingStyleVariants,
15
+ buildMarginStyleVariants,
16
+ buildTextSpacingVariants,
17
+ } from './buildViewStyleVariants';
18
+
19
+ // General style helpers
20
+ export { deepMerge, isPlainObject } from './styleHelpers';
@@ -6,6 +6,14 @@ import { Size } from '@idealyst/theme';
6
6
  */
7
7
  export type ViewStyleSize = Size;
8
8
 
9
+ /**
10
+ * Base props shared by all components
11
+ */
12
+ export interface BaseProps {
13
+ /** Unique identifier for the element (maps to id on web, nativeID on native) */
14
+ id?: string;
15
+ }
16
+
9
17
  /**
10
18
  * Gap style props - for controlling gap/spacing between children
11
19
  */
@@ -42,22 +50,22 @@ export interface MarginStyleProps {
42
50
  * Full container style props - includes all spacing options
43
51
  * For: View, Card, Screen, List, Accordion, Table, TabBar
44
52
  */
45
- export interface ContainerStyleProps extends GapStyleProps, PaddingStyleProps, MarginStyleProps {}
53
+ export interface ContainerStyleProps extends BaseProps, GapStyleProps, PaddingStyleProps, MarginStyleProps {}
46
54
 
47
55
  /**
48
56
  * Text spacing style props - gap + padding only
49
57
  * For: Text (gap for inline elements, padding for block-level)
50
58
  */
51
- export interface TextSpacingStyleProps extends GapStyleProps, PaddingStyleProps {}
59
+ export interface TextSpacingStyleProps extends BaseProps, GapStyleProps, PaddingStyleProps {}
52
60
 
53
61
  /**
54
62
  * Pressable style props - padding only
55
63
  * For: Pressable
56
64
  */
57
- export interface PressableSpacingStyleProps extends PaddingStyleProps {}
65
+ export interface PressableSpacingStyleProps extends BaseProps, PaddingStyleProps {}
58
66
 
59
67
  /**
60
68
  * Form input style props - margin only
61
69
  * For: Input, Select, TextArea, Checkbox, RadioButton, Switch, Slider
62
70
  */
63
- export interface FormInputStyleProps extends MarginStyleProps {}
71
+ export interface FormInputStyleProps extends BaseProps, MarginStyleProps {}