@sudobility/components-rn 1.0.42 → 1.0.44

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 (115) hide show
  1. package/dist/index.cjs.js +895 -299
  2. package/dist/index.cjs.js.map +1 -1
  3. package/dist/index.esm.js +896 -300
  4. package/dist/index.esm.js.map +1 -1
  5. package/dist/ui/Avatar/Avatar.d.ts.map +1 -1
  6. package/dist/ui/Breadcrumb/Breadcrumb.d.ts.map +1 -1
  7. package/dist/ui/BreadcrumbNav/BreadcrumbNav.d.ts.map +1 -1
  8. package/dist/ui/CTASection/CTASection.d.ts.map +1 -1
  9. package/dist/ui/Calendar/Calendar.d.ts.map +1 -1
  10. package/dist/ui/ChainBadge/ChainBadge.d.ts.map +1 -1
  11. package/dist/ui/Checkbox/Checkbox.d.ts +0 -22
  12. package/dist/ui/Checkbox/Checkbox.d.ts.map +1 -1
  13. package/dist/ui/Code/Code.d.ts +0 -17
  14. package/dist/ui/Code/Code.d.ts.map +1 -1
  15. package/dist/ui/CodeDisplay/CodeDisplay.d.ts +0 -21
  16. package/dist/ui/CodeDisplay/CodeDisplay.d.ts.map +1 -1
  17. package/dist/ui/CollapsibleSection/CollapsibleSection.d.ts.map +1 -1
  18. package/dist/ui/Combobox/Combobox.d.ts.map +1 -1
  19. package/dist/ui/Command/Command.d.ts.map +1 -1
  20. package/dist/ui/DashboardStatCard/DashboardStatCard.d.ts +0 -17
  21. package/dist/ui/DashboardStatCard/DashboardStatCard.d.ts.map +1 -1
  22. package/dist/ui/DataList/DataList.d.ts.map +1 -1
  23. package/dist/ui/Dropdown/Dropdown.d.ts.map +1 -1
  24. package/dist/ui/ExternalLink/ExternalLink.d.ts.map +1 -1
  25. package/dist/ui/FeatureCard/FeatureCard.d.ts.map +1 -1
  26. package/dist/ui/FeatureGrid/FeatureGrid.d.ts.map +1 -1
  27. package/dist/ui/GradientIconContainer/GradientIconContainer.d.ts +0 -13
  28. package/dist/ui/GradientIconContainer/GradientIconContainer.d.ts.map +1 -1
  29. package/dist/ui/HelperText/HelperText.d.ts.map +1 -1
  30. package/dist/ui/IconContainer/IconContainer.d.ts +0 -13
  31. package/dist/ui/IconContainer/IconContainer.d.ts.map +1 -1
  32. package/dist/ui/IconText/IconText.d.ts.map +1 -1
  33. package/dist/ui/InfiniteScroll/InfiniteScroll.d.ts.map +1 -1
  34. package/dist/ui/KeyValuePair/KeyValuePair.d.ts.map +1 -1
  35. package/dist/ui/Link/Link.d.ts.map +1 -1
  36. package/dist/ui/ListItemWithAction/ListItemWithAction.d.ts.map +1 -1
  37. package/dist/ui/Modal/Modal.d.ts.map +1 -1
  38. package/dist/ui/MultiSelect/MultiSelect.d.ts.map +1 -1
  39. package/dist/ui/NavigationList/NavigationList.d.ts.map +1 -1
  40. package/dist/ui/PageSectionHeader/PageSectionHeader.d.ts.map +1 -1
  41. package/dist/ui/Pagination/Pagination.d.ts.map +1 -1
  42. package/dist/ui/PhoneInput/PhoneInput.d.ts.map +1 -1
  43. package/dist/ui/PopupSelect/PopupSelect.d.ts.map +1 -1
  44. package/dist/ui/Progress/Progress.d.ts +0 -15
  45. package/dist/ui/Progress/Progress.d.ts.map +1 -1
  46. package/dist/ui/PromotionalBanner/PromotionalBanner.d.ts.map +1 -1
  47. package/dist/ui/SearchInput/SearchInput.d.ts.map +1 -1
  48. package/dist/ui/SectionHeader/SectionHeader.d.ts.map +1 -1
  49. package/dist/ui/Select/Select.d.ts.map +1 -1
  50. package/dist/ui/SettingsList/SettingsList.d.ts.map +1 -1
  51. package/dist/ui/Sheet/Sheet.d.ts.map +1 -1
  52. package/dist/ui/SideNav/SideNav.d.ts.map +1 -1
  53. package/dist/ui/SmartLink/SmartLink.d.ts.map +1 -1
  54. package/dist/ui/StatDisplay/StatDisplay.d.ts +0 -12
  55. package/dist/ui/StatDisplay/StatDisplay.d.ts.map +1 -1
  56. package/dist/ui/StepList/StepList.d.ts.map +1 -1
  57. package/dist/ui/Table/Table.d.ts.map +1 -1
  58. package/dist/ui/Tabs/Tabs.d.ts.map +1 -1
  59. package/dist/ui/TextArea/TextArea.d.ts.map +1 -1
  60. package/dist/ui/TextInputModal/TextInputModal.d.ts.map +1 -1
  61. package/dist/ui/Tooltip/Tooltip.d.ts +0 -20
  62. package/dist/ui/Tooltip/Tooltip.d.ts.map +1 -1
  63. package/dist/ui/TransferList/TransferList.d.ts.map +1 -1
  64. package/package.json +3 -3
  65. package/src/ui/Avatar/Avatar.tsx +6 -5
  66. package/src/ui/Breadcrumb/Breadcrumb.tsx +8 -5
  67. package/src/ui/BreadcrumbNav/BreadcrumbNav.tsx +22 -3
  68. package/src/ui/CTASection/CTASection.tsx +8 -6
  69. package/src/ui/Calendar/Calendar.tsx +35 -6
  70. package/src/ui/ChainBadge/ChainBadge.tsx +67 -42
  71. package/src/ui/Checkbox/Checkbox.tsx +47 -20
  72. package/src/ui/Code/Code.tsx +51 -21
  73. package/src/ui/CodeDisplay/CodeDisplay.tsx +46 -20
  74. package/src/ui/CollapsibleSection/CollapsibleSection.tsx +7 -3
  75. package/src/ui/Combobox/Combobox.tsx +2 -1
  76. package/src/ui/Command/Command.tsx +2 -1
  77. package/src/ui/DashboardStatCard/DashboardStatCard.tsx +29 -11
  78. package/src/ui/DataList/DataList.tsx +23 -5
  79. package/src/ui/Dropdown/Dropdown.tsx +4 -1
  80. package/src/ui/ExternalLink/ExternalLink.tsx +5 -4
  81. package/src/ui/FeatureCard/FeatureCard.tsx +60 -29
  82. package/src/ui/FeatureGrid/FeatureGrid.tsx +7 -7
  83. package/src/ui/GradientIconContainer/GradientIconContainer.tsx +33 -8
  84. package/src/ui/HelperText/HelperText.tsx +9 -8
  85. package/src/ui/IconContainer/IconContainer.tsx +26 -9
  86. package/src/ui/IconText/IconText.tsx +6 -5
  87. package/src/ui/InfiniteScroll/InfiniteScroll.tsx +2 -1
  88. package/src/ui/KeyValuePair/KeyValuePair.tsx +12 -5
  89. package/src/ui/Link/Link.tsx +6 -5
  90. package/src/ui/ListItemWithAction/ListItemWithAction.tsx +2 -1
  91. package/src/ui/Modal/Modal.tsx +16 -2
  92. package/src/ui/MultiSelect/MultiSelect.tsx +2 -1
  93. package/src/ui/NavigationList/NavigationList.tsx +17 -3
  94. package/src/ui/PageSectionHeader/PageSectionHeader.tsx +2 -1
  95. package/src/ui/Pagination/Pagination.tsx +9 -6
  96. package/src/ui/PhoneInput/PhoneInput.tsx +3 -2
  97. package/src/ui/PopupSelect/PopupSelect.tsx +15 -14
  98. package/src/ui/Progress/Progress.tsx +63 -14
  99. package/src/ui/PromotionalBanner/PromotionalBanner.tsx +7 -4
  100. package/src/ui/SearchInput/SearchInput.tsx +3 -2
  101. package/src/ui/SectionHeader/SectionHeader.tsx +4 -1
  102. package/src/ui/Select/Select.tsx +20 -5
  103. package/src/ui/SettingsList/SettingsList.tsx +4 -1
  104. package/src/ui/Sheet/Sheet.tsx +20 -3
  105. package/src/ui/SideNav/SideNav.tsx +11 -2
  106. package/src/ui/SmartLink/SmartLink.tsx +6 -3
  107. package/src/ui/Spinner/Spinner.tsx +1 -1
  108. package/src/ui/StatDisplay/StatDisplay.tsx +59 -23
  109. package/src/ui/StepList/StepList.tsx +25 -3
  110. package/src/ui/Table/Table.tsx +22 -9
  111. package/src/ui/Tabs/Tabs.tsx +7 -2
  112. package/src/ui/TextArea/TextArea.tsx +2 -1
  113. package/src/ui/TextInputModal/TextInputModal.tsx +2 -1
  114. package/src/ui/Tooltip/Tooltip.tsx +47 -9
  115. package/src/ui/TransferList/TransferList.tsx +2 -1
@@ -1,6 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import { View, Text, TextProps } from 'react-native';
3
3
  import { cn } from '../../lib/utils';
4
+ import { colors, designTokens } from '@sudobility/design';
4
5
 
5
6
  export interface HelperTextProps extends TextProps {
6
7
  /** Helper text content */
@@ -43,10 +44,10 @@ export const HelperText: React.FC<HelperTextProps> = ({
43
44
  className,
44
45
  ...textProps
45
46
  }) => {
46
- // Size configurations
47
+ // Size configurations using design tokens
47
48
  const sizeClasses = {
48
- sm: 'text-sm',
49
- base: 'text-base',
49
+ sm: designTokens.typography.size.sm,
50
+ base: designTokens.typography.size.base,
50
51
  };
51
52
 
52
53
  const iconSize = {
@@ -54,22 +55,22 @@ export const HelperText: React.FC<HelperTextProps> = ({
54
55
  base: 'w-5 h-5',
55
56
  };
56
57
 
57
- // Variant configurations
58
+ // Variant configurations using DS alert icon colors and semantic text
58
59
  const variantConfig = {
59
60
  default: {
60
- text: 'text-gray-600 dark:text-gray-400',
61
+ text: colors.component.alert.info.icon,
61
62
  icon: 'ℹ',
62
63
  },
63
64
  error: {
64
- text: 'text-red-600 dark:text-red-400',
65
+ text: colors.component.alert.error.icon,
65
66
  icon: '⚠',
66
67
  },
67
68
  success: {
68
- text: 'text-green-600 dark:text-green-400',
69
+ text: colors.component.alert.success.icon,
69
70
  icon: '✓',
70
71
  },
71
72
  warning: {
72
- text: 'text-yellow-600 dark:text-yellow-400',
73
+ text: colors.component.alert.warning.icon,
73
74
  icon: '⚠',
74
75
  },
75
76
  };
@@ -1,6 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import { View } from 'react-native';
3
3
  import { cn } from '../../lib/utils';
4
+ import { colors } from '@sudobility/design';
4
5
 
5
6
  export interface IconContainerProps {
6
7
  /** Icon element */
@@ -34,6 +35,29 @@ export interface IconContainerProps {
34
35
  * </IconContainer>
35
36
  * ```
36
37
  */
38
+
39
+ // Lazily derive icon container colors from DS to avoid ESM issues in tests.
40
+ let _iconContainerColors: Record<string, string> | null = null;
41
+ function getIconContainerColors() {
42
+ if (!_iconContainerColors) {
43
+ const badge = colors.component.badge;
44
+ // DS badge classes include text-*, but IconContainer only needs bg-*
45
+ function extractBg(base: string, dark: string) {
46
+ const all = `${base} ${dark}`.split(' ');
47
+ return all.filter(c => c.includes('bg-')).join(' ');
48
+ }
49
+ _iconContainerColors = {
50
+ primary: extractBg(badge.primary.base, badge.primary.dark),
51
+ secondary: 'bg-purple-100 dark:bg-purple-900/30', // DS has no purple badge variant; local fallback
52
+ success: extractBg(badge.success.base, badge.success.dark),
53
+ warning: extractBg(badge.warning.base, badge.warning.dark),
54
+ error: extractBg(badge.error.base, badge.error.dark),
55
+ neutral: extractBg(badge.default.base, badge.default.dark),
56
+ };
57
+ }
58
+ return _iconContainerColors;
59
+ }
60
+
37
61
  export const IconContainer: React.FC<IconContainerProps> = ({
38
62
  children,
39
63
  size = 'md',
@@ -49,15 +73,8 @@ export const IconContainer: React.FC<IconContainerProps> = ({
49
73
  xl: 'w-20 h-20',
50
74
  };
51
75
 
52
- // Variant configurations
53
- const variantClasses = {
54
- primary: 'bg-blue-100 dark:bg-blue-900/30',
55
- secondary: 'bg-purple-100 dark:bg-purple-900/30',
56
- success: 'bg-green-100 dark:bg-green-900/30',
57
- warning: 'bg-yellow-100 dark:bg-yellow-900/30',
58
- error: 'bg-red-100 dark:bg-red-900/30',
59
- neutral: 'bg-gray-100 dark:bg-gray-800',
60
- };
76
+ // Variant configurations from DS
77
+ const variantClasses = getIconContainerColors();
61
78
 
62
79
  // Shape configurations
63
80
  const shapeClasses = {
@@ -1,6 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import { View, Text } from 'react-native';
3
3
  import { cn } from '../../lib/utils';
4
+ import { colors } from '@sudobility/design';
4
5
 
5
6
  export interface IconTextProps {
6
7
  /** Icon element to display */
@@ -78,13 +79,13 @@ export const IconText: React.FC<IconTextProps> = ({
78
79
  right: 'text-right',
79
80
  };
80
81
 
81
- // Color variant configurations
82
+ // Color variant configurations using DS semantic references
82
83
  const variantClasses = {
83
84
  default: 'text-gray-700 dark:text-gray-300',
84
- primary: 'text-blue-600 dark:text-blue-400',
85
- success: 'text-green-600 dark:text-green-400',
86
- warning: 'text-yellow-600 dark:text-yellow-400',
87
- danger: 'text-red-600 dark:text-red-400',
85
+ primary: colors.component.alert.info.icon,
86
+ success: colors.component.alert.success.icon,
87
+ warning: colors.component.alert.warning.icon,
88
+ danger: colors.component.alert.error.icon,
88
89
  muted: 'text-gray-500 dark:text-gray-400',
89
90
  };
90
91
 
@@ -9,6 +9,7 @@ import {
9
9
  RefreshControl,
10
10
  } from 'react-native';
11
11
  import { cn } from '../../lib/utils';
12
+ import { colors } from '@sudobility/design';
12
13
 
13
14
  export interface InfiniteScrollProps<T> {
14
15
  /** Data items to render */
@@ -117,7 +118,7 @@ export function InfiniteScroll<T>({
117
118
  const ListFooterComponent = useCallback(() => {
118
119
  const footerLoader = (
119
120
  <View className='flex-row justify-center items-center py-4'>
120
- <ActivityIndicator size='small' color='#3b82f6' />
121
+ <ActivityIndicator size='small' color={colors.raw.blue[500]} />
121
122
  <Text className='ml-2 text-sm text-gray-600 dark:text-gray-400'>
122
123
  Loading...
123
124
  </Text>
@@ -1,6 +1,9 @@
1
1
  import * as React from 'react';
2
2
  import { View, Text } from 'react-native';
3
3
  import { cn } from '../../lib/utils';
4
+ import { designTokens } from '@sudobility/design';
5
+
6
+ const { typography } = designTokens;
4
7
 
5
8
  export interface KeyValuePairProps {
6
9
  /** Label/key text */
@@ -55,9 +58,13 @@ export const KeyValuePair: React.FC<KeyValuePairProps> = ({
55
58
  className,
56
59
  }) => {
57
60
  const sizeClasses = {
58
- sm: { label: 'text-sm', value: 'text-sm', gap: 'gap-1' },
59
- md: { label: 'text-base', value: 'text-base', gap: 'gap-2' },
60
- lg: { label: 'text-lg', value: 'text-lg', gap: 'gap-3' },
61
+ sm: { label: typography.size.sm, value: typography.size.sm, gap: 'gap-1' },
62
+ md: {
63
+ label: typography.size.base,
64
+ value: typography.size.base,
65
+ gap: 'gap-2',
66
+ },
67
+ lg: { label: typography.size.lg, value: typography.size.lg, gap: 'gap-3' },
61
68
  };
62
69
 
63
70
  const labelWidthStyles = {
@@ -76,13 +83,13 @@ export const KeyValuePair: React.FC<KeyValuePairProps> = ({
76
83
  const labelVariantClasses = {
77
84
  default: 'text-gray-700 dark:text-gray-300',
78
85
  muted: 'text-gray-600 dark:text-gray-400',
79
- strong: 'text-gray-900 dark:text-gray-100 font-semibold',
86
+ strong: `text-gray-900 dark:text-gray-100 ${typography.weight.semibold}`,
80
87
  };
81
88
 
82
89
  const valueVariantClasses = {
83
90
  default: 'text-gray-900 dark:text-gray-100',
84
91
  muted: 'text-gray-600 dark:text-gray-400',
85
- strong: 'text-gray-900 dark:text-gray-100 font-semibold',
92
+ strong: `text-gray-900 dark:text-gray-100 ${typography.weight.semibold}`,
86
93
  primary: 'text-blue-600 dark:text-blue-400',
87
94
  };
88
95
 
@@ -1,6 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import { Text, Pressable, Linking } from 'react-native';
3
3
  import { cn } from '../../lib/utils';
4
+ import { textVariants } from '@sudobility/design';
4
5
 
5
6
  export interface LinkProps {
6
7
  /** Link URL */
@@ -53,13 +54,13 @@ export const Link: React.FC<LinkProps> = ({
53
54
  // Auto-detect external links
54
55
  const isExternal = href.startsWith('http://') || href.startsWith('https://');
55
56
 
56
- // Variant configurations
57
+ // Variant configurations using DS textVariants.link where applicable
57
58
  const variantClasses = {
58
- default: 'text-blue-600 dark:text-blue-400',
59
- primary: 'text-blue-600 dark:text-blue-400 font-medium',
60
- secondary: 'text-gray-600 dark:text-gray-400',
59
+ default: textVariants.link.subtle(),
60
+ primary: `${textVariants.link.default()} font-medium`,
61
+ secondary: textVariants.link.muted(),
61
62
  muted: 'text-gray-500 dark:text-gray-500',
62
- underline: 'text-blue-600 dark:text-blue-400 underline',
63
+ underline: textVariants.link.default(),
63
64
  };
64
65
 
65
66
  const handlePress = async () => {
@@ -1,6 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import { View, Text, Pressable, ActivityIndicator } from 'react-native';
3
3
  import { cn } from '../../lib/utils';
4
+ import { colors } from '@sudobility/design';
4
5
 
5
6
  export interface ListItemWithActionProps {
6
7
  /** Main content/text to display */
@@ -91,7 +92,7 @@ export const ListItemWithAction: React.FC<ListItemWithActionProps> = ({
91
92
  {isProcessing ? (
92
93
  <ActivityIndicator
93
94
  size='small'
94
- color={destructive ? '#dc2626' : '#6b7280'}
95
+ color={destructive ? colors.raw.red[600] : colors.raw.neutral[500]}
95
96
  />
96
97
  ) : (
97
98
  <>
@@ -9,6 +9,9 @@ import {
9
9
  Platform,
10
10
  } from 'react-native';
11
11
  import { cn } from '../../lib/utils';
12
+ import { designTokens } from '@sudobility/design';
13
+
14
+ const { typography } = designTokens;
12
15
 
13
16
  export interface ModalProps {
14
17
  /** Whether the modal is visible */
@@ -103,7 +106,13 @@ export const Modal: React.FC<ModalProps> = ({
103
106
  {(title || showCloseButton) && (
104
107
  <View className='flex flex-row items-center justify-between px-4 py-3 border-b border-gray-200 dark:border-gray-700'>
105
108
  {title && (
106
- <Text className='text-lg font-semibold text-gray-900 dark:text-white flex-1'>
109
+ <Text
110
+ className={cn(
111
+ typography.size.lg,
112
+ typography.weight.semibold,
113
+ 'text-gray-900 dark:text-white flex-1'
114
+ )}
115
+ >
107
116
  {title}
108
117
  </Text>
109
118
  )}
@@ -114,7 +123,12 @@ export const Modal: React.FC<ModalProps> = ({
114
123
  accessibilityRole='button'
115
124
  accessibilityLabel='Close modal'
116
125
  >
117
- <Text className='text-xl text-gray-500 dark:text-gray-400'>
126
+ <Text
127
+ className={cn(
128
+ typography.size.xl,
129
+ 'text-gray-500 dark:text-gray-400'
130
+ )}
131
+ >
118
132
 
119
133
  </Text>
120
134
  </Pressable>
@@ -10,6 +10,7 @@ import {
10
10
  TouchableWithoutFeedback,
11
11
  } from 'react-native';
12
12
  import { cn } from '../../lib/utils';
13
+ import { colors } from '@sudobility/design';
13
14
 
14
15
  export interface MultiSelectOption {
15
16
  /** Option value */
@@ -183,7 +184,7 @@ export const MultiSelect: React.FC<MultiSelectProps> = ({
183
184
  value={searchQuery}
184
185
  onChangeText={setSearchQuery}
185
186
  placeholder={searchPlaceholder}
186
- placeholderTextColor='#9ca3af'
187
+ placeholderTextColor={colors.raw.neutral[400]}
187
188
  className='px-3 py-2 text-sm bg-gray-50 dark:bg-gray-800 text-gray-900 dark:text-white rounded-md'
188
189
  />
189
190
  </View>
@@ -1,6 +1,9 @@
1
1
  import * as React from 'react';
2
2
  import { View, Text, Pressable } from 'react-native';
3
3
  import { cn } from '../../lib/utils';
4
+ import { designTokens } from '@sudobility/design';
5
+
6
+ const { typography } = designTokens;
4
7
 
5
8
  export interface NavigationItem {
6
9
  /** Unique identifier for the item */
@@ -108,7 +111,7 @@ export const NavigationList: React.FC<NavigationListProps> = ({
108
111
  <View className='flex-row items-center'>
109
112
  <Text
110
113
  className={cn(
111
- 'font-medium',
114
+ typography.weight.medium,
112
115
  isSelected
113
116
  ? 'text-blue-600 dark:text-blue-400'
114
117
  : 'text-gray-700 dark:text-gray-300'
@@ -118,14 +121,25 @@ export const NavigationList: React.FC<NavigationListProps> = ({
118
121
  </Text>
119
122
  {item.badge !== undefined && item.badge > 0 && (
120
123
  <View className='ml-2 px-2 py-0.5 bg-blue-100 dark:bg-blue-900 rounded-full'>
121
- <Text className='text-xs font-medium text-blue-800 dark:text-blue-200'>
124
+ <Text
125
+ className={cn(
126
+ typography.size.xs,
127
+ typography.weight.medium,
128
+ 'text-blue-800 dark:text-blue-200'
129
+ )}
130
+ >
122
131
  {item.badge}
123
132
  </Text>
124
133
  </View>
125
134
  )}
126
135
  </View>
127
136
  {item.description && (
128
- <Text className='text-xs text-gray-500 dark:text-gray-400 mt-0.5'>
137
+ <Text
138
+ className={cn(
139
+ typography.size.xs,
140
+ 'text-gray-500 dark:text-gray-400 mt-0.5'
141
+ )}
142
+ >
129
143
  {item.description}
130
144
  </Text>
131
145
  )}
@@ -1,6 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import { View, Text, ActivityIndicator } from 'react-native';
3
3
  import { cn } from '../../lib/utils';
4
+ import { colors } from '@sudobility/design';
4
5
 
5
6
  export interface PageSectionHeaderProps {
6
7
  /** Section title */
@@ -107,7 +108,7 @@ export const PageSectionHeader: React.FC<PageSectionHeaderProps> = ({
107
108
 
108
109
  {loading && (
109
110
  <View className='flex-row items-center gap-2'>
110
- <ActivityIndicator size='small' color='#3b82f6' />
111
+ <ActivityIndicator size='small' color={colors.raw.blue[500]} />
111
112
  <Text
112
113
  className={cn(
113
114
  sizeConfig.count,
@@ -1,6 +1,9 @@
1
1
  import * as React from 'react';
2
2
  import { View, Text, Pressable } from 'react-native';
3
3
  import { cn } from '../../lib/utils';
4
+ import { designTokens } from '@sudobility/design';
5
+
6
+ const { typography } = designTokens;
4
7
 
5
8
  export interface PaginationProps {
6
9
  /** Current page number (1-indexed) */
@@ -65,18 +68,18 @@ export const Pagination: React.FC<PaginationProps> = ({
65
68
  const sizeConfig = {
66
69
  sm: {
67
70
  button: 'h-8 w-8',
68
- text: 'text-xs',
69
- icon: 'text-xs',
71
+ text: typography.size.xs,
72
+ icon: typography.size.xs,
70
73
  },
71
74
  md: {
72
75
  button: 'h-10 w-10',
73
- text: 'text-sm',
74
- icon: 'text-sm',
76
+ text: typography.size.sm,
77
+ icon: typography.size.sm,
75
78
  },
76
79
  lg: {
77
80
  button: 'h-12 w-12',
78
- text: 'text-base',
79
- icon: 'text-base',
81
+ text: typography.size.base,
82
+ icon: typography.size.base,
80
83
  },
81
84
  };
82
85
 
@@ -10,6 +10,7 @@ import {
10
10
  TouchableWithoutFeedback,
11
11
  } from 'react-native';
12
12
  import { cn } from '../../lib/utils';
13
+ import { colors } from '@sudobility/design';
13
14
 
14
15
  export interface Country {
15
16
  /** Country code (ISO 3166-1 alpha-2) */
@@ -170,7 +171,7 @@ export const PhoneInput: React.FC<PhoneInputProps> = ({
170
171
  value={value}
171
172
  onChangeText={handleInputChange}
172
173
  placeholder={placeholder}
173
- placeholderTextColor='#9ca3af'
174
+ placeholderTextColor={colors.raw.neutral[400]}
174
175
  keyboardType='phone-pad'
175
176
  editable={!disabled}
176
177
  className={cn(
@@ -207,7 +208,7 @@ export const PhoneInput: React.FC<PhoneInputProps> = ({
207
208
  value={searchQuery}
208
209
  onChangeText={setSearchQuery}
209
210
  placeholder='Search countries...'
210
- placeholderTextColor='#9ca3af'
211
+ placeholderTextColor={colors.raw.neutral[400]}
211
212
  className='px-3 py-2 text-sm bg-gray-50 dark:bg-gray-800 text-gray-900 dark:text-white rounded-md'
212
213
  />
213
214
  </View>
@@ -9,6 +9,7 @@ import {
9
9
  Pressable,
10
10
  } from 'react-native';
11
11
  import { useSafeAreaInsets } from 'react-native-safe-area-context';
12
+ import { colors } from '@sudobility/design';
12
13
 
13
14
  export interface PopupSelectOption {
14
15
  label: string;
@@ -163,11 +164,11 @@ const styles = StyleSheet.create({
163
164
  alignItems: 'center',
164
165
  justifyContent: 'space-between',
165
166
  borderWidth: 1,
166
- borderColor: '#d1d5db',
167
+ borderColor: colors.raw.neutral[300],
167
168
  borderRadius: 8,
168
169
  paddingHorizontal: 12,
169
170
  paddingVertical: 12,
170
- backgroundColor: '#ffffff',
171
+ backgroundColor: colors.raw.neutral[0],
171
172
  },
172
173
  triggerDisabled: {
173
174
  opacity: 0.5,
@@ -175,19 +176,19 @@ const styles = StyleSheet.create({
175
176
  triggerText: {
176
177
  flex: 1,
177
178
  fontSize: 16,
178
- color: '#1a1a1a',
179
+ color: colors.raw.neutral[900],
179
180
  },
180
181
  triggerPlaceholder: {
181
- color: '#9ca3af',
182
+ color: colors.raw.neutral[400],
182
183
  },
183
184
  triggerArrow: {
184
185
  fontSize: 10,
185
- color: '#9ca3af',
186
+ color: colors.raw.neutral[400],
186
187
  marginLeft: 8,
187
188
  },
188
189
  modalContainer: {
189
190
  flex: 1,
190
- backgroundColor: '#ffffff',
191
+ backgroundColor: colors.raw.neutral[0],
191
192
  },
192
193
  modalHeader: {
193
194
  flexDirection: 'row',
@@ -196,12 +197,12 @@ const styles = StyleSheet.create({
196
197
  paddingHorizontal: 16,
197
198
  paddingVertical: 12,
198
199
  borderBottomWidth: 1,
199
- borderBottomColor: '#e9ecef',
200
+ borderBottomColor: colors.raw.neutral[200],
200
201
  },
201
202
  modalTitle: {
202
203
  fontSize: 18,
203
204
  fontWeight: '600',
204
- color: '#1a1a1a',
205
+ color: colors.raw.neutral[900],
205
206
  },
206
207
  closeButton: {
207
208
  padding: 8,
@@ -209,7 +210,7 @@ const styles = StyleSheet.create({
209
210
  closeButtonText: {
210
211
  fontSize: 16,
211
212
  fontWeight: '600',
212
- color: '#3b82f6',
213
+ color: colors.raw.blue[500],
213
214
  },
214
215
  listContent: {
215
216
  padding: 16,
@@ -218,27 +219,27 @@ const styles = StyleSheet.create({
218
219
  flexDirection: 'row',
219
220
  alignItems: 'center',
220
221
  padding: 16,
221
- backgroundColor: '#f8f9fa',
222
+ backgroundColor: colors.raw.neutral[50],
222
223
  borderRadius: 12,
223
224
  },
224
225
  optionItemSelected: {
225
- backgroundColor: '#e0f2fe',
226
+ backgroundColor: colors.raw.blue[100],
226
227
  },
227
228
  optionLabel: {
228
229
  flex: 1,
229
230
  fontSize: 16,
230
- color: '#1a1a1a',
231
+ color: colors.raw.neutral[900],
231
232
  },
232
233
  optionLabelSelected: {
233
234
  fontWeight: '600',
234
- color: '#3b82f6',
235
+ color: colors.raw.blue[500],
235
236
  },
236
237
  optionDisabled: {
237
238
  opacity: 0.5,
238
239
  },
239
240
  checkmark: {
240
241
  fontSize: 18,
241
- color: '#3b82f6',
242
+ color: colors.raw.blue[500],
242
243
  fontWeight: 'bold',
243
244
  },
244
245
  separator: {
@@ -1,6 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import { View, Text, Animated } from 'react-native';
3
3
  import { cn } from '../../lib/utils';
4
+ import { colors, designTokens } from '@sudobility/design';
4
5
 
5
6
  export interface ProgressProps {
6
7
  /** Progress value (0-100) */
@@ -36,6 +37,48 @@ export interface ProgressProps {
36
37
  * <Progress indeterminate />
37
38
  * ```
38
39
  */
40
+
41
+ // Lazily derive progress colors from DS to avoid ESM issues in tests.
42
+ let _progressColors: ReturnType<typeof buildProgressColors> | null = null;
43
+ function getProgressColors() {
44
+ if (!_progressColors) _progressColors = buildProgressColors();
45
+ return _progressColors;
46
+ }
47
+ function buildProgressColors() {
48
+ // Extract the leading bg-* class from DS button base strings
49
+ function extractBg(base: string, darkStr: string) {
50
+ const bg =
51
+ base
52
+ .split(' ')
53
+ .find(
54
+ c =>
55
+ c.startsWith('bg-') &&
56
+ !c.includes('hover:') &&
57
+ !c.includes('active:')
58
+ ) || '';
59
+ const darkBg =
60
+ darkStr
61
+ .split(' ')
62
+ .find(
63
+ c =>
64
+ c.startsWith('dark:bg-') &&
65
+ !c.includes('hover:') &&
66
+ !c.includes('active:')
67
+ ) || '';
68
+ return `${bg} ${darkBg}`;
69
+ }
70
+ const btn = colors.component.button;
71
+ return {
72
+ default: extractBg(btn.primary.base, btn.primary.dark),
73
+ primary: extractBg(btn.primary.base, btn.primary.dark),
74
+ success: extractBg(btn.success.base, btn.success.dark),
75
+ warning: 'bg-yellow-600 dark:bg-yellow-500', // DS has no yellow button; local fallback
76
+ danger: extractBg(btn.destructive.base, btn.destructive.dark),
77
+ purple: 'bg-purple-600 dark:bg-purple-500', // DS has no purple button; local fallback
78
+ gray: 'bg-gray-600 dark:bg-gray-500', // local fallback
79
+ } as Record<string, string>;
80
+ }
81
+
39
82
  export const Progress: React.FC<ProgressProps> = ({
40
83
  value = 0,
41
84
  max = 100,
@@ -71,12 +114,13 @@ export const Progress: React.FC<ProgressProps> = ({
71
114
  // Clamp value between 0 and 100
72
115
  const percentage = Math.min(Math.max((value / max) * 100, 0), 100);
73
116
 
74
- // Color configurations
117
+ // Color configurations from DS
118
+ const allColors = getProgressColors();
75
119
  const colorClasses = {
76
- default: 'bg-blue-600 dark:bg-blue-500',
77
- success: 'bg-green-600 dark:bg-green-500',
78
- warning: 'bg-yellow-600 dark:bg-yellow-500',
79
- danger: 'bg-red-600 dark:bg-red-500',
120
+ default: allColors.default,
121
+ success: allColors.success,
122
+ warning: allColors.warning,
123
+ danger: allColors.danger,
80
124
  };
81
125
 
82
126
  // Size configurations
@@ -119,7 +163,9 @@ export const Progress: React.FC<ProgressProps> = ({
119
163
  </View>
120
164
  {(showLabel || label) && (
121
165
  <View className='mt-1'>
122
- <Text className='text-xs text-gray-600 dark:text-gray-400 text-right'>
166
+ <Text
167
+ className={`${designTokens.typography.size.xs} text-gray-600 dark:text-gray-400 text-right`}
168
+ >
123
169
  {label || `${Math.round(percentage)}%`}
124
170
  </Text>
125
171
  </View>
@@ -173,14 +219,15 @@ export const ProgressBar: React.FC<ProgressBarProps> = ({
173
219
  const percentage = Math.min(Math.max((value / max) * 100, 0), 100);
174
220
  const displayLabel = label || `${Math.round(percentage)}%`;
175
221
 
176
- // Color variant configurations
222
+ // Color variant configurations from DS
223
+ const progressColors = getProgressColors();
177
224
  const variantClasses = {
178
- primary: 'bg-blue-600 dark:bg-blue-500',
179
- success: 'bg-green-600 dark:bg-green-500',
180
- warning: 'bg-yellow-600 dark:bg-yellow-500',
181
- danger: 'bg-red-600 dark:bg-red-500',
182
- purple: 'bg-purple-600 dark:bg-purple-500',
183
- gray: 'bg-gray-600 dark:bg-gray-500',
225
+ primary: progressColors.primary,
226
+ success: progressColors.success,
227
+ warning: progressColors.warning,
228
+ danger: progressColors.danger,
229
+ purple: progressColors.purple,
230
+ gray: progressColors.gray,
184
231
  };
185
232
 
186
233
  // Size configurations
@@ -211,7 +258,9 @@ export const ProgressBar: React.FC<ProgressBarProps> = ({
211
258
  />
212
259
  </View>
213
260
  {showLabel && labelPosition === 'outside' && (
214
- <Text className='text-sm font-medium text-gray-600 dark:text-gray-400'>
261
+ <Text
262
+ className={`${designTokens.typography.size.sm} ${designTokens.typography.weight.medium} text-gray-600 dark:text-gray-400`}
263
+ >
215
264
  {displayLabel}
216
265
  </Text>
217
266
  )}