@sudobility/components-rn 1.0.41 → 1.0.43

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 (142) hide show
  1. package/dist/index.cjs.js +1092 -473
  2. package/dist/index.cjs.js.map +1 -1
  3. package/dist/index.esm.js +1095 -476
  4. package/dist/index.esm.js.map +1 -1
  5. package/dist/ui/Alert/Alert.d.ts.map +1 -1
  6. package/dist/ui/Avatar/Avatar.d.ts.map +1 -1
  7. package/dist/ui/Badge/Badge.d.ts.map +1 -1
  8. package/dist/ui/Banner/Banner.d.ts.map +1 -1
  9. package/dist/ui/Breadcrumb/Breadcrumb.d.ts.map +1 -1
  10. package/dist/ui/BreadcrumbNav/BreadcrumbNav.d.ts.map +1 -1
  11. package/dist/ui/CTASection/CTASection.d.ts.map +1 -1
  12. package/dist/ui/Calendar/Calendar.d.ts.map +1 -1
  13. package/dist/ui/ChainBadge/ChainBadge.d.ts.map +1 -1
  14. package/dist/ui/Checkbox/Checkbox.d.ts +0 -22
  15. package/dist/ui/Checkbox/Checkbox.d.ts.map +1 -1
  16. package/dist/ui/Code/Code.d.ts +0 -17
  17. package/dist/ui/Code/Code.d.ts.map +1 -1
  18. package/dist/ui/CodeDisplay/CodeDisplay.d.ts +0 -21
  19. package/dist/ui/CodeDisplay/CodeDisplay.d.ts.map +1 -1
  20. package/dist/ui/CollapsibleSection/CollapsibleSection.d.ts.map +1 -1
  21. package/dist/ui/Combobox/Combobox.d.ts.map +1 -1
  22. package/dist/ui/Command/Command.d.ts.map +1 -1
  23. package/dist/ui/DashboardStatCard/DashboardStatCard.d.ts +0 -17
  24. package/dist/ui/DashboardStatCard/DashboardStatCard.d.ts.map +1 -1
  25. package/dist/ui/DataList/DataList.d.ts.map +1 -1
  26. package/dist/ui/Divider/Divider.d.ts.map +1 -1
  27. package/dist/ui/Dropdown/Dropdown.d.ts.map +1 -1
  28. package/dist/ui/ExternalLink/ExternalLink.d.ts.map +1 -1
  29. package/dist/ui/FeatureCard/FeatureCard.d.ts.map +1 -1
  30. package/dist/ui/FeatureGrid/FeatureGrid.d.ts.map +1 -1
  31. package/dist/ui/GradientIconContainer/GradientIconContainer.d.ts +0 -13
  32. package/dist/ui/GradientIconContainer/GradientIconContainer.d.ts.map +1 -1
  33. package/dist/ui/Heading/Heading.d.ts.map +1 -1
  34. package/dist/ui/HelperText/HelperText.d.ts.map +1 -1
  35. package/dist/ui/IconContainer/IconContainer.d.ts +0 -13
  36. package/dist/ui/IconContainer/IconContainer.d.ts.map +1 -1
  37. package/dist/ui/IconText/IconText.d.ts.map +1 -1
  38. package/dist/ui/InfiniteScroll/InfiniteScroll.d.ts.map +1 -1
  39. package/dist/ui/InfoBox/InfoBox.d.ts.map +1 -1
  40. package/dist/ui/Input/Input.d.ts.map +1 -1
  41. package/dist/ui/KeyValuePair/KeyValuePair.d.ts.map +1 -1
  42. package/dist/ui/Label/Label.d.ts.map +1 -1
  43. package/dist/ui/Link/Link.d.ts.map +1 -1
  44. package/dist/ui/ListItemWithAction/ListItemWithAction.d.ts.map +1 -1
  45. package/dist/ui/Modal/Modal.d.ts.map +1 -1
  46. package/dist/ui/MultiSelect/MultiSelect.d.ts.map +1 -1
  47. package/dist/ui/NavigationList/NavigationList.d.ts.map +1 -1
  48. package/dist/ui/PageSectionHeader/PageSectionHeader.d.ts.map +1 -1
  49. package/dist/ui/Pagination/Pagination.d.ts.map +1 -1
  50. package/dist/ui/PhoneInput/PhoneInput.d.ts.map +1 -1
  51. package/dist/ui/PopupSelect/PopupSelect.d.ts.map +1 -1
  52. package/dist/ui/Progress/Progress.d.ts +0 -15
  53. package/dist/ui/Progress/Progress.d.ts.map +1 -1
  54. package/dist/ui/ProgressCircle/ProgressCircle.d.ts.map +1 -1
  55. package/dist/ui/PromotionalBanner/PromotionalBanner.d.ts.map +1 -1
  56. package/dist/ui/QuickActions/QuickActions.d.ts.map +1 -1
  57. package/dist/ui/SearchInput/SearchInput.d.ts.map +1 -1
  58. package/dist/ui/SectionHeader/SectionHeader.d.ts.map +1 -1
  59. package/dist/ui/Select/Select.d.ts.map +1 -1
  60. package/dist/ui/SettingsList/SettingsList.d.ts.map +1 -1
  61. package/dist/ui/Sheet/Sheet.d.ts.map +1 -1
  62. package/dist/ui/SideNav/SideNav.d.ts.map +1 -1
  63. package/dist/ui/SmartLink/SmartLink.d.ts.map +1 -1
  64. package/dist/ui/Spinner/Spinner.d.ts.map +1 -1
  65. package/dist/ui/StatDisplay/StatDisplay.d.ts +0 -12
  66. package/dist/ui/StatDisplay/StatDisplay.d.ts.map +1 -1
  67. package/dist/ui/StepList/StepList.d.ts.map +1 -1
  68. package/dist/ui/Table/Table.d.ts.map +1 -1
  69. package/dist/ui/Tabs/Tabs.d.ts.map +1 -1
  70. package/dist/ui/Text/Text.d.ts.map +1 -1
  71. package/dist/ui/TextArea/TextArea.d.ts.map +1 -1
  72. package/dist/ui/TextInputModal/TextInputModal.d.ts.map +1 -1
  73. package/dist/ui/Toast/Toast.d.ts.map +1 -1
  74. package/dist/ui/Tooltip/Tooltip.d.ts +0 -20
  75. package/dist/ui/Tooltip/Tooltip.d.ts.map +1 -1
  76. package/dist/ui/TransferList/TransferList.d.ts.map +1 -1
  77. package/package.json +5 -4
  78. package/src/__tests__/alert.test.tsx +20 -10
  79. package/src/ui/Alert/Alert.tsx +13 -5
  80. package/src/ui/Avatar/Avatar.tsx +6 -5
  81. package/src/ui/Badge/Badge.tsx +61 -26
  82. package/src/ui/Banner/Banner.tsx +36 -25
  83. package/src/ui/Breadcrumb/Breadcrumb.tsx +8 -5
  84. package/src/ui/BreadcrumbNav/BreadcrumbNav.tsx +22 -3
  85. package/src/ui/CTASection/CTASection.tsx +8 -6
  86. package/src/ui/Calendar/Calendar.tsx +35 -6
  87. package/src/ui/Card/Card.tsx +2 -2
  88. package/src/ui/ChainBadge/ChainBadge.tsx +67 -42
  89. package/src/ui/Checkbox/Checkbox.tsx +47 -20
  90. package/src/ui/Code/Code.tsx +51 -21
  91. package/src/ui/CodeDisplay/CodeDisplay.tsx +46 -20
  92. package/src/ui/CollapsibleSection/CollapsibleSection.tsx +7 -3
  93. package/src/ui/Combobox/Combobox.tsx +2 -1
  94. package/src/ui/Command/Command.tsx +2 -1
  95. package/src/ui/DashboardStatCard/DashboardStatCard.tsx +29 -11
  96. package/src/ui/DataList/DataList.tsx +23 -5
  97. package/src/ui/Divider/Divider.tsx +12 -17
  98. package/src/ui/Dropdown/Dropdown.tsx +4 -1
  99. package/src/ui/ExternalLink/ExternalLink.tsx +5 -4
  100. package/src/ui/FeatureCard/FeatureCard.tsx +60 -29
  101. package/src/ui/FeatureGrid/FeatureGrid.tsx +7 -7
  102. package/src/ui/GradientIconContainer/GradientIconContainer.tsx +33 -8
  103. package/src/ui/Heading/Heading.tsx +15 -38
  104. package/src/ui/HelperText/HelperText.tsx +9 -8
  105. package/src/ui/IconContainer/IconContainer.tsx +26 -9
  106. package/src/ui/IconText/IconText.tsx +6 -5
  107. package/src/ui/InfiniteScroll/InfiniteScroll.tsx +2 -1
  108. package/src/ui/InfoBox/InfoBox.tsx +35 -17
  109. package/src/ui/Input/Input.tsx +10 -3
  110. package/src/ui/KeyValuePair/KeyValuePair.tsx +12 -5
  111. package/src/ui/Label/Label.tsx +3 -1
  112. package/src/ui/Link/Link.tsx +6 -5
  113. package/src/ui/ListItemWithAction/ListItemWithAction.tsx +2 -1
  114. package/src/ui/Modal/Modal.tsx +16 -2
  115. package/src/ui/MultiSelect/MultiSelect.tsx +2 -1
  116. package/src/ui/NavigationList/NavigationList.tsx +17 -3
  117. package/src/ui/PageSectionHeader/PageSectionHeader.tsx +2 -1
  118. package/src/ui/Pagination/Pagination.tsx +9 -6
  119. package/src/ui/PhoneInput/PhoneInput.tsx +3 -2
  120. package/src/ui/PopupSelect/PopupSelect.tsx +15 -14
  121. package/src/ui/Progress/Progress.tsx +63 -14
  122. package/src/ui/ProgressCircle/ProgressCircle.tsx +7 -6
  123. package/src/ui/PromotionalBanner/PromotionalBanner.tsx +7 -4
  124. package/src/ui/QuickActions/QuickActions.tsx +13 -9
  125. package/src/ui/SearchInput/SearchInput.tsx +3 -2
  126. package/src/ui/SectionHeader/SectionHeader.tsx +4 -1
  127. package/src/ui/Select/Select.tsx +20 -5
  128. package/src/ui/SettingsList/SettingsList.tsx +4 -1
  129. package/src/ui/Sheet/Sheet.tsx +20 -3
  130. package/src/ui/SideNav/SideNav.tsx +11 -2
  131. package/src/ui/SmartLink/SmartLink.tsx +6 -3
  132. package/src/ui/Spinner/Spinner.tsx +8 -6
  133. package/src/ui/StatDisplay/StatDisplay.tsx +59 -23
  134. package/src/ui/StepList/StepList.tsx +25 -3
  135. package/src/ui/Table/Table.tsx +22 -9
  136. package/src/ui/Tabs/Tabs.tsx +7 -2
  137. package/src/ui/Text/Text.tsx +19 -52
  138. package/src/ui/TextArea/TextArea.tsx +2 -1
  139. package/src/ui/TextInputModal/TextInputModal.tsx +2 -1
  140. package/src/ui/Toast/Toast.tsx +49 -14
  141. package/src/ui/Tooltip/Tooltip.tsx +47 -9
  142. package/src/ui/TransferList/TransferList.tsx +2 -1
@@ -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 { designTokens, getCardVariantColors } from '@sudobility/design';
4
5
 
5
6
  export interface DashboardStatCardProps {
6
7
  /** Stat title */
@@ -36,6 +37,22 @@ export interface DashboardStatCardProps {
36
37
  * />
37
38
  * ```
38
39
  */
40
+
41
+ // Lazily derive card variant colors from DS to avoid ESM issues in tests.
42
+ let _cardColors: Record<string, string> | null = null;
43
+ function getDashboardCardColors() {
44
+ if (!_cardColors) {
45
+ _cardColors = {
46
+ default: getCardVariantColors('default'),
47
+ primary: getCardVariantColors('info'),
48
+ success: getCardVariantColors('success'),
49
+ warning: getCardVariantColors('warning'),
50
+ danger: getCardVariantColors('error'),
51
+ };
52
+ }
53
+ return _cardColors;
54
+ }
55
+
39
56
  export const DashboardStatCard: React.FC<DashboardStatCardProps> = ({
40
57
  title,
41
58
  value,
@@ -45,13 +62,7 @@ export const DashboardStatCard: React.FC<DashboardStatCardProps> = ({
45
62
  variant = 'default',
46
63
  className,
47
64
  }) => {
48
- const variantClasses = {
49
- default: 'bg-white dark:bg-gray-900',
50
- primary: 'bg-blue-50 dark:bg-blue-900/20',
51
- success: 'bg-green-50 dark:bg-green-900/20',
52
- warning: 'bg-yellow-50 dark:bg-yellow-900/20',
53
- danger: 'bg-red-50 dark:bg-red-900/20',
54
- };
65
+ const variantClasses = getDashboardCardColors();
55
66
 
56
67
  const isPositive = change !== undefined && change >= 0;
57
68
 
@@ -65,7 +76,9 @@ export const DashboardStatCard: React.FC<DashboardStatCardProps> = ({
65
76
  >
66
77
  {/* Header */}
67
78
  <View className='flex-row items-start justify-between mb-2'>
68
- <Text className='text-sm font-medium text-gray-600 dark:text-gray-400'>
79
+ <Text
80
+ className={`${designTokens.typography.size.sm} ${designTokens.typography.weight.medium} text-gray-600 dark:text-gray-400`}
81
+ >
69
82
  {title}
70
83
  </Text>
71
84
  {icon && (
@@ -74,7 +87,9 @@ export const DashboardStatCard: React.FC<DashboardStatCardProps> = ({
74
87
  </View>
75
88
 
76
89
  {/* Value */}
77
- <Text className='text-3xl font-bold text-gray-900 dark:text-white'>
90
+ <Text
91
+ className={`${designTokens.typography.size['3xl']} ${designTokens.typography.weight.bold} text-gray-900 dark:text-white`}
92
+ >
78
93
  {value}
79
94
  </Text>
80
95
 
@@ -83,7 +98,8 @@ export const DashboardStatCard: React.FC<DashboardStatCardProps> = ({
83
98
  <View className='flex-row items-center gap-1 mt-2'>
84
99
  <Text
85
100
  className={cn(
86
- 'text-sm font-medium',
101
+ designTokens.typography.size.sm,
102
+ designTokens.typography.weight.medium,
87
103
  isPositive
88
104
  ? 'text-green-600 dark:text-green-400'
89
105
  : 'text-red-600 dark:text-red-400'
@@ -91,7 +107,9 @@ export const DashboardStatCard: React.FC<DashboardStatCardProps> = ({
91
107
  >
92
108
  {isPositive ? '↑' : '↓'} {Math.abs(change)}%
93
109
  </Text>
94
- <Text className='text-xs text-gray-500 dark:text-gray-400'>
110
+ <Text
111
+ className={`${designTokens.typography.size.xs} text-gray-500 dark:text-gray-400`}
112
+ >
95
113
  {changePeriod}
96
114
  </Text>
97
115
  </View>
@@ -1,6 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import { View, Text, Pressable, FlatList } from 'react-native';
3
3
  import { cn } from '../../lib/utils';
4
+ import { ui, designTokens } from '@sudobility/design';
4
5
 
5
6
  export interface DataListColumn<T> {
6
7
  /** Column key */
@@ -74,7 +75,13 @@ export function DataList<T extends Record<string, unknown>>({
74
75
  if (!showHeader) return null;
75
76
 
76
77
  return (
77
- <View className='flex-row bg-gray-50 dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700'>
78
+ <View
79
+ className={cn(
80
+ 'flex-row',
81
+ ui.table.thead,
82
+ 'border-b border-gray-200 dark:border-gray-700'
83
+ )}
84
+ >
78
85
  {columns.map(column => (
79
86
  <View
80
87
  key={column.key}
@@ -84,7 +91,15 @@ export function DataList<T extends Record<string, unknown>>({
84
91
  )}
85
92
  style={{ flex: column.flex || 1 }}
86
93
  >
87
- <Text className='text-xs font-medium text-gray-700 dark:text-gray-300 uppercase tracking-wider'>
94
+ <Text
95
+ className={cn(
96
+ designTokens.typography.size.xs,
97
+ designTokens.typography.weight.medium,
98
+ 'text-gray-700 dark:text-gray-300',
99
+ designTokens.typography.transform.uppercase,
100
+ designTokens.typography.tracking.wider
101
+ )}
102
+ >
88
103
  {column.label}
89
104
  </Text>
90
105
  </View>
@@ -101,7 +116,7 @@ export function DataList<T extends Record<string, unknown>>({
101
116
  onPress={() => onRowPress?.(item, index)}
102
117
  className={cn(
103
118
  'flex-row border-b border-gray-200 dark:border-gray-700',
104
- isOdd && 'bg-gray-50 dark:bg-gray-800/50',
119
+ isOdd && ui.table.trAlt,
105
120
  onRowPress && 'active:bg-gray-100 dark:active:bg-gray-800'
106
121
  )}
107
122
  disabled={!onRowPress}
@@ -121,7 +136,10 @@ export function DataList<T extends Record<string, unknown>>({
121
136
  column.render(item, index)
122
137
  ) : (
123
138
  <Text
124
- className='text-sm text-gray-900 dark:text-white'
139
+ className={cn(
140
+ designTokens.typography.size.sm,
141
+ 'text-gray-900 dark:text-white'
142
+ )}
125
143
  numberOfLines={1}
126
144
  >
127
145
  {String(item[column.key] ?? '')}
@@ -142,7 +160,7 @@ export function DataList<T extends Record<string, unknown>>({
142
160
  );
143
161
 
144
162
  return (
145
- <View className={cn('bg-white dark:bg-gray-900', className)}>
163
+ <View className={cn(ui.table.tr, className)}>
146
164
  {renderHeader()}
147
165
  <FlatList
148
166
  data={data}
@@ -3,6 +3,13 @@ import { View, Text, ViewProps } from 'react-native';
3
3
  import { cn } from '../../lib/utils';
4
4
  import { textVariants } from '@sudobility/design';
5
5
 
6
+ // Divider line colors aligned with DS border tokens (colors.semantic.border)
7
+ const lineVariantClasses = {
8
+ light: 'bg-gray-200 dark:bg-gray-700',
9
+ medium: 'bg-gray-300 dark:bg-gray-600',
10
+ dark: 'bg-gray-400 dark:bg-gray-500',
11
+ } as const;
12
+
6
13
  export interface DividerProps extends ViewProps {
7
14
  /** Optional text label */
8
15
  label?: string;
@@ -81,20 +88,13 @@ export const Divider: React.FC<DividerProps> = ({
81
88
  thick: 4,
82
89
  };
83
90
 
84
- // Color variant configurations
85
- const variantClasses = {
86
- light: 'bg-gray-200 dark:bg-gray-700',
87
- medium: 'bg-gray-300 dark:bg-gray-600',
88
- dark: 'bg-gray-400 dark:bg-gray-500',
89
- };
90
-
91
91
  // Vertical divider
92
92
  if (orientation === 'vertical') {
93
93
  return (
94
94
  <View
95
95
  className={cn(
96
96
  'self-stretch',
97
- variantClasses[variant],
97
+ lineVariantClasses[variant],
98
98
  spacingClasses.vertical[spacing],
99
99
  className
100
100
  )}
@@ -111,7 +111,7 @@ export const Divider: React.FC<DividerProps> = ({
111
111
  <View
112
112
  className={cn(
113
113
  'w-full',
114
- variantClasses[variant],
114
+ lineVariantClasses[variant],
115
115
  spacingClasses.horizontal[spacing],
116
116
  lineClassName,
117
117
  className
@@ -143,21 +143,16 @@ export const Divider: React.FC<DividerProps> = ({
143
143
  >
144
144
  {labelPosition !== 'left' && (
145
145
  <View
146
- className={cn('flex-1', variantClasses[variant], lineClassName)}
146
+ className={cn('flex-1', lineVariantClasses[variant], lineClassName)}
147
147
  style={{ height: thicknessValues[thickness] }}
148
148
  />
149
149
  )}
150
- <Text
151
- className={cn(
152
- textVariants.body.sm(),
153
- 'px-3 text-gray-500 dark:text-gray-400'
154
- )}
155
- >
150
+ <Text className={cn(textVariants.caption.default(), 'px-3')}>
156
151
  {label}
157
152
  </Text>
158
153
  {labelPosition !== 'right' && (
159
154
  <View
160
- className={cn('flex-1', variantClasses[variant], lineClassName)}
155
+ className={cn('flex-1', lineVariantClasses[variant], lineClassName)}
161
156
  style={{ height: thicknessValues[thickness] }}
162
157
  />
163
158
  )}
@@ -8,6 +8,9 @@ import {
8
8
  TouchableWithoutFeedback,
9
9
  } from 'react-native';
10
10
  import { cn } from '../../lib/utils';
11
+ import { designTokens } from '@sudobility/design';
12
+
13
+ const { typography } = designTokens;
11
14
 
12
15
  export interface DropdownItem {
13
16
  /** Unique identifier */
@@ -156,7 +159,7 @@ export const Dropdown: React.FC<DropdownProps> = ({
156
159
  {item.icon && <View className='w-5 h-5'>{item.icon}</View>}
157
160
  <Text
158
161
  className={cn(
159
- 'text-sm',
162
+ typography.size.sm,
160
163
  item.disabled
161
164
  ? 'text-gray-400 dark:text-gray-500'
162
165
  : 'text-gray-700 dark:text-gray-200'
@@ -2,6 +2,7 @@ import * as React from 'react';
2
2
  import { useCallback } from 'react';
3
3
  import { Text, Pressable, Linking } from 'react-native';
4
4
  import { cn } from '../../lib/utils';
5
+ import { textVariants } from '@sudobility/design';
5
6
 
6
7
  export interface ExternalLinkProps {
7
8
  /** Link URL */
@@ -63,11 +64,11 @@ export const ExternalLink: React.FC<ExternalLinkProps> = ({
63
64
  lg: 'text-base',
64
65
  };
65
66
 
66
- // Color variant configurations
67
+ // Color variant configurations using DS textVariants.link
67
68
  const variantClasses = {
68
- default: 'text-blue-600 dark:text-blue-400',
69
- primary: 'text-blue-700 dark:text-blue-300 font-semibold',
70
- muted: 'text-gray-600 dark:text-gray-400',
69
+ default: textVariants.link.external(),
70
+ primary: `${textVariants.link.default()} font-semibold`,
71
+ muted: textVariants.link.muted(),
71
72
  };
72
73
 
73
74
  const handlePress = useCallback(async () => {
@@ -1,6 +1,7 @@
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';
4
5
 
5
6
  export type FeatureCardColor =
6
7
  | 'green'
@@ -69,57 +70,58 @@ export const FeatureCard: React.FC<FeatureCardProps> = ({
69
70
  borderColor = false,
70
71
  className,
71
72
  }) => {
72
- // Color configurations
73
+ // Color configurations -- derived from colors.raw.* palette
74
+ // Each Tailwind class maps to a colors.raw hex value at the same shade
73
75
  const colorClasses: Record<FeatureCardColor, string> = {
74
- blue: 'text-blue-600 dark:text-blue-400',
75
- green: 'text-green-600 dark:text-green-400',
76
+ blue: 'text-blue-600 dark:text-blue-400', // colors.raw.blue[600] / [400]
77
+ green: 'text-green-600 dark:text-green-400', // colors.raw.green[600] / [400]
76
78
  purple: 'text-purple-600 dark:text-purple-400',
77
- orange: 'text-orange-600 dark:text-orange-400',
79
+ orange: 'text-orange-600 dark:text-orange-400', // colors.raw.orange[600] / [400]
78
80
  pink: 'text-pink-600 dark:text-pink-400',
79
- gray: 'text-gray-600 dark:text-gray-400',
80
- red: 'text-red-600 dark:text-red-400',
81
+ gray: 'text-gray-600 dark:text-gray-400', // colors.raw.neutral[600] / [400]
82
+ red: 'text-red-600 dark:text-red-400', // colors.raw.red[600] / [400]
81
83
  indigo: 'text-indigo-600 dark:text-indigo-400',
82
84
  cyan: 'text-cyan-600 dark:text-cyan-400',
83
85
  emerald: 'text-emerald-600 dark:text-emerald-400',
84
86
  };
85
87
 
86
88
  const borderColorClasses: Record<FeatureCardColor, string> = {
87
- green: 'border-l-4 border-l-green-500',
88
- blue: 'border-l-4 border-l-blue-500',
89
- purple: 'border-l-4 border-l-purple-500',
90
- orange: 'border-l-4 border-l-orange-500',
91
- red: 'border-l-4 border-l-red-500',
89
+ green: 'border-l-4 border-l-green-500', // colors.raw.green[500]
90
+ blue: 'border-l-4 border-l-blue-500', // colors.raw.blue[500]
91
+ purple: 'border-l-4 border-l-purple-500', // colors.raw.purple[500]
92
+ orange: 'border-l-4 border-l-orange-500', // colors.raw.orange[500]
93
+ red: 'border-l-4 border-l-red-500', // colors.raw.red[500]
92
94
  indigo: 'border-l-4 border-l-indigo-500',
93
95
  cyan: 'border-l-4 border-l-cyan-500',
94
96
  emerald: 'border-l-4 border-l-emerald-500',
95
97
  pink: 'border-l-4 border-l-pink-500',
96
- gray: 'border-l-4 border-l-gray-500',
98
+ gray: 'border-l-4 border-l-gray-500', // colors.raw.neutral[500]
97
99
  };
98
100
 
99
101
  const iconBackgroundClasses: Record<FeatureCardColor, string> = {
100
- green: 'bg-green-100 dark:bg-green-900/20',
101
- blue: 'bg-blue-100 dark:bg-blue-900/20',
102
- purple: 'bg-purple-100 dark:bg-purple-900/20',
103
- orange: 'bg-orange-100 dark:bg-orange-900/20',
104
- red: 'bg-red-100 dark:bg-red-900/20',
102
+ green: 'bg-green-100 dark:bg-green-900/20', // colors.raw.green[100] / [900]
103
+ blue: 'bg-blue-100 dark:bg-blue-900/20', // colors.raw.blue[100] / [900]
104
+ purple: 'bg-purple-100 dark:bg-purple-900/20', // colors.raw.purple[100] / [900]
105
+ orange: 'bg-orange-100 dark:bg-orange-900/20', // colors.raw.orange[100] / [900]
106
+ red: 'bg-red-100 dark:bg-red-900/20', // colors.raw.red[100] / [900]
105
107
  indigo: 'bg-indigo-100 dark:bg-indigo-900/20',
106
108
  cyan: 'bg-cyan-100 dark:bg-cyan-900/20',
107
109
  emerald: 'bg-emerald-100 dark:bg-emerald-900/20',
108
110
  pink: 'bg-pink-100 dark:bg-pink-900/20',
109
- gray: 'bg-gray-100 dark:bg-gray-900/20',
111
+ gray: 'bg-gray-100 dark:bg-gray-900/20', // colors.raw.neutral[100] / [900]
110
112
  };
111
113
 
112
114
  const bulletColorClasses: Record<FeatureCardColor, string> = {
113
- green: 'bg-green-500',
114
- blue: 'bg-blue-500',
115
- purple: 'bg-purple-500',
116
- orange: 'bg-orange-500',
117
- red: 'bg-red-500',
115
+ green: 'bg-green-500', // colors.raw.green[500]
116
+ blue: 'bg-blue-500', // colors.raw.blue[500]
117
+ purple: 'bg-purple-500', // colors.raw.purple[500]
118
+ orange: 'bg-orange-500', // colors.raw.orange[500]
119
+ red: 'bg-red-500', // colors.raw.red[500]
118
120
  indigo: 'bg-indigo-500',
119
121
  cyan: 'bg-cyan-500',
120
122
  emerald: 'bg-emerald-500',
121
123
  pink: 'bg-pink-500',
122
- gray: 'bg-gray-500',
124
+ gray: 'bg-gray-500', // colors.raw.neutral[500]
123
125
  };
124
126
 
125
127
  const CardContent = () => (
@@ -139,12 +141,24 @@ export const FeatureCard: React.FC<FeatureCardProps> = ({
139
141
  )}
140
142
 
141
143
  {/* Title */}
142
- <Text className='text-xl font-semibold text-gray-900 dark:text-white mb-3'>
144
+ <Text
145
+ className={cn(
146
+ designTokens.typography.size.xl,
147
+ designTokens.typography.weight.semibold,
148
+ 'text-gray-900 dark:text-white mb-3'
149
+ )}
150
+ >
143
151
  {title}
144
152
  </Text>
145
153
 
146
154
  {/* Description */}
147
- <Text className='text-gray-600 dark:text-gray-300 mb-4 leading-relaxed'>
155
+ <Text
156
+ className={cn(
157
+ designTokens.typography.size.base,
158
+ designTokens.typography.leading.relaxed,
159
+ 'text-gray-600 dark:text-gray-300 mb-4'
160
+ )}
161
+ >
148
162
  {description}
149
163
  </Text>
150
164
 
@@ -162,7 +176,13 @@ export const FeatureCard: React.FC<FeatureCardProps> = ({
162
176
  bulletColorClasses[color]
163
177
  )}
164
178
  />
165
- <Text className='flex-1 text-sm text-gray-600 dark:text-gray-400'>
179
+ <Text
180
+ className={cn(
181
+ 'flex-1',
182
+ designTokens.typography.size.sm,
183
+ 'text-gray-600 dark:text-gray-400'
184
+ )}
185
+ >
166
186
  {benefit}
167
187
  </Text>
168
188
  </View>
@@ -178,10 +198,21 @@ export const FeatureCard: React.FC<FeatureCardProps> = ({
178
198
  key={index}
179
199
  className='flex-1 min-w-[80px] items-center p-3 bg-gray-50 dark:bg-gray-700/50 rounded-lg'
180
200
  >
181
- <Text className={cn('text-lg font-bold', colorClasses[color])}>
201
+ <Text
202
+ className={cn(
203
+ designTokens.typography.size.lg,
204
+ designTokens.typography.weight.bold,
205
+ colorClasses[color]
206
+ )}
207
+ >
182
208
  {value}
183
209
  </Text>
184
- <Text className='text-xs text-gray-500 dark:text-gray-400 mt-1'>
210
+ <Text
211
+ className={cn(
212
+ designTokens.typography.size.xs,
213
+ 'text-gray-500 dark:text-gray-400 mt-1'
214
+ )}
215
+ >
185
216
  {key}
186
217
  </Text>
187
218
  </View>
@@ -1,6 +1,7 @@
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 { colors, getCardVariantColors } from '@sudobility/design';
4
5
 
5
6
  export interface Feature {
6
7
  /** Unique identifier */
@@ -72,13 +73,12 @@ export const FeatureGrid: React.FC<FeatureGridProps> = ({
72
73
  lg: 'w-20 h-20',
73
74
  };
74
75
 
76
+ // Badge variants using DS badge colors
75
77
  const badgeVariants = {
76
- success:
77
- 'bg-green-100 dark:bg-green-900/30 text-green-800 dark:text-green-300',
78
- info: 'bg-blue-100 dark:bg-blue-900/30 text-blue-800 dark:text-blue-300',
79
- warning:
80
- 'bg-amber-100 dark:bg-amber-900/30 text-amber-800 dark:text-amber-300',
81
- default: 'bg-gray-100 dark:bg-gray-800 text-gray-800 dark:text-gray-300',
78
+ success: `${colors.component.badge.success.base} ${colors.component.badge.success.dark}`,
79
+ info: `${colors.component.badge.primary.base} ${colors.component.badge.primary.dark}`,
80
+ warning: `${colors.component.badge.attention.base} ${colors.component.badge.attention.dark}`,
81
+ default: `${colors.component.badge.default.base} ${colors.component.badge.default.dark}`,
82
82
  };
83
83
 
84
84
  const renderFeature = (feature: Feature, index: number) => {
@@ -87,7 +87,7 @@ export const FeatureGrid: React.FC<FeatureGridProps> = ({
87
87
  className={cn(
88
88
  'items-center',
89
89
  cardVariant === 'card' &&
90
- 'bg-white dark:bg-gray-800 rounded-2xl p-6 shadow-lg',
90
+ `${getCardVariantColors('elevated')} rounded-2xl p-6`,
91
91
  cardVariant === 'minimal' && 'gap-4'
92
92
  )}
93
93
  >
@@ -1,6 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import { View, StyleSheet } from 'react-native';
3
3
  import { cn } from '../../lib/utils';
4
+ import { colors } from '@sudobility/design';
4
5
 
5
6
  export interface GradientIconContainerProps {
6
7
  /** Icon element */
@@ -28,6 +29,36 @@ export interface GradientIconContainerProps {
28
29
  * </GradientIconContainer>
29
30
  * ```
30
31
  */
32
+
33
+ // Lazily derive gradient icon colors from DS to avoid ESM issues in tests.
34
+ let _gradientIconColors: Record<string, string> | null = null;
35
+ function getGradientIconColors() {
36
+ if (!_gradientIconColors) {
37
+ const btn = colors.component.button;
38
+ // Extract the leading bg-* class from DS button base strings (solid colors)
39
+ function extractBg(base: string) {
40
+ return (
41
+ base
42
+ .split(' ')
43
+ .find(
44
+ c =>
45
+ c.startsWith('bg-') &&
46
+ !c.includes('hover:') &&
47
+ !c.includes('active:')
48
+ ) || ''
49
+ );
50
+ }
51
+ _gradientIconColors = {
52
+ blue: extractBg(btn.primary.base),
53
+ purple: 'bg-purple-600', // DS has no purple button; local fallback
54
+ green: extractBg(btn.success.base),
55
+ orange: 'bg-orange-600', // DS has no orange button; local fallback
56
+ gray: 'bg-gray-700 dark:bg-gray-600',
57
+ };
58
+ }
59
+ return _gradientIconColors;
60
+ }
61
+
31
62
  export const GradientIconContainer: React.FC<GradientIconContainerProps> = ({
32
63
  children,
33
64
  size = 'md',
@@ -50,14 +81,8 @@ export const GradientIconContainer: React.FC<GradientIconContainerProps> = ({
50
81
  circle: 'rounded-full',
51
82
  };
52
83
 
53
- // Color variants (solid colors approximating gradients)
54
- const variantClasses = {
55
- blue: 'bg-blue-600',
56
- purple: 'bg-purple-600',
57
- green: 'bg-green-600',
58
- orange: 'bg-orange-600',
59
- gray: 'bg-gray-700 dark:bg-gray-600',
60
- };
84
+ // Color variants from DS (solid colors approximating gradients)
85
+ const variantClasses = getGradientIconColors();
61
86
 
62
87
  const config = sizeConfig[size];
63
88
 
@@ -1,6 +1,16 @@
1
1
  import * as React from 'react';
2
2
  import { Text } from 'react-native';
3
3
  import { cn } from '../../lib/utils';
4
+ import { designTokens } from '@sudobility/design';
5
+
6
+ const { typography } = designTokens;
7
+
8
+ // Heading colors aligned with the design system color architecture
9
+ const colorClasses = {
10
+ default: 'text-gray-900 dark:text-gray-100',
11
+ muted: 'text-gray-700 dark:text-gray-300',
12
+ primary: 'text-blue-600 dark:text-blue-400',
13
+ } as const;
4
14
 
5
15
  export interface HeadingProps {
6
16
  /** Heading content */
@@ -60,48 +70,15 @@ export const Heading: React.FC<HeadingProps> = ({
60
70
 
61
71
  const actualSize = size || defaultSizes[level];
62
72
 
63
- // Size configurations
64
- const sizeClasses = {
65
- '4xl': 'text-4xl',
66
- '3xl': 'text-3xl',
67
- '2xl': 'text-2xl',
68
- xl: 'text-xl',
69
- lg: 'text-lg',
70
- base: 'text-base',
71
- };
72
-
73
- // Weight configurations
74
- const weightClasses = {
75
- normal: 'font-normal',
76
- medium: 'font-medium',
77
- semibold: 'font-semibold',
78
- bold: 'font-bold',
79
- extrabold: 'font-extrabold',
80
- };
81
-
82
- // Color configurations
83
- const colorClasses = {
84
- default: 'text-gray-900 dark:text-gray-100',
85
- muted: 'text-gray-700 dark:text-gray-300',
86
- primary: 'text-blue-600 dark:text-blue-400',
87
- };
88
-
89
- // Alignment configurations
90
- const alignClasses = align
91
- ? {
92
- left: 'text-left',
93
- center: 'text-center',
94
- right: 'text-right',
95
- }[align]
96
- : '';
97
-
98
73
  return (
99
74
  <Text
100
75
  className={cn(
101
- sizeClasses[actualSize],
102
- weightClasses[weight],
76
+ typography.size[actualSize],
77
+ typography.weight[weight],
78
+ typography.leading.heading,
79
+ typography.tracking.heading,
103
80
  colorClasses[color],
104
- alignClasses,
81
+ align ? typography.align[align] : '',
105
82
  className
106
83
  )}
107
84
  accessibilityRole='header'
@@ -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
  };