@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.
- package/dist/index.cjs.js +1092 -473
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +1095 -476
- package/dist/index.esm.js.map +1 -1
- package/dist/ui/Alert/Alert.d.ts.map +1 -1
- package/dist/ui/Avatar/Avatar.d.ts.map +1 -1
- package/dist/ui/Badge/Badge.d.ts.map +1 -1
- package/dist/ui/Banner/Banner.d.ts.map +1 -1
- package/dist/ui/Breadcrumb/Breadcrumb.d.ts.map +1 -1
- package/dist/ui/BreadcrumbNav/BreadcrumbNav.d.ts.map +1 -1
- package/dist/ui/CTASection/CTASection.d.ts.map +1 -1
- package/dist/ui/Calendar/Calendar.d.ts.map +1 -1
- package/dist/ui/ChainBadge/ChainBadge.d.ts.map +1 -1
- package/dist/ui/Checkbox/Checkbox.d.ts +0 -22
- package/dist/ui/Checkbox/Checkbox.d.ts.map +1 -1
- package/dist/ui/Code/Code.d.ts +0 -17
- package/dist/ui/Code/Code.d.ts.map +1 -1
- package/dist/ui/CodeDisplay/CodeDisplay.d.ts +0 -21
- package/dist/ui/CodeDisplay/CodeDisplay.d.ts.map +1 -1
- package/dist/ui/CollapsibleSection/CollapsibleSection.d.ts.map +1 -1
- package/dist/ui/Combobox/Combobox.d.ts.map +1 -1
- package/dist/ui/Command/Command.d.ts.map +1 -1
- package/dist/ui/DashboardStatCard/DashboardStatCard.d.ts +0 -17
- package/dist/ui/DashboardStatCard/DashboardStatCard.d.ts.map +1 -1
- package/dist/ui/DataList/DataList.d.ts.map +1 -1
- package/dist/ui/Divider/Divider.d.ts.map +1 -1
- package/dist/ui/Dropdown/Dropdown.d.ts.map +1 -1
- package/dist/ui/ExternalLink/ExternalLink.d.ts.map +1 -1
- package/dist/ui/FeatureCard/FeatureCard.d.ts.map +1 -1
- package/dist/ui/FeatureGrid/FeatureGrid.d.ts.map +1 -1
- package/dist/ui/GradientIconContainer/GradientIconContainer.d.ts +0 -13
- package/dist/ui/GradientIconContainer/GradientIconContainer.d.ts.map +1 -1
- package/dist/ui/Heading/Heading.d.ts.map +1 -1
- package/dist/ui/HelperText/HelperText.d.ts.map +1 -1
- package/dist/ui/IconContainer/IconContainer.d.ts +0 -13
- package/dist/ui/IconContainer/IconContainer.d.ts.map +1 -1
- package/dist/ui/IconText/IconText.d.ts.map +1 -1
- package/dist/ui/InfiniteScroll/InfiniteScroll.d.ts.map +1 -1
- package/dist/ui/InfoBox/InfoBox.d.ts.map +1 -1
- package/dist/ui/Input/Input.d.ts.map +1 -1
- package/dist/ui/KeyValuePair/KeyValuePair.d.ts.map +1 -1
- package/dist/ui/Label/Label.d.ts.map +1 -1
- package/dist/ui/Link/Link.d.ts.map +1 -1
- package/dist/ui/ListItemWithAction/ListItemWithAction.d.ts.map +1 -1
- package/dist/ui/Modal/Modal.d.ts.map +1 -1
- package/dist/ui/MultiSelect/MultiSelect.d.ts.map +1 -1
- package/dist/ui/NavigationList/NavigationList.d.ts.map +1 -1
- package/dist/ui/PageSectionHeader/PageSectionHeader.d.ts.map +1 -1
- package/dist/ui/Pagination/Pagination.d.ts.map +1 -1
- package/dist/ui/PhoneInput/PhoneInput.d.ts.map +1 -1
- package/dist/ui/PopupSelect/PopupSelect.d.ts.map +1 -1
- package/dist/ui/Progress/Progress.d.ts +0 -15
- package/dist/ui/Progress/Progress.d.ts.map +1 -1
- package/dist/ui/ProgressCircle/ProgressCircle.d.ts.map +1 -1
- package/dist/ui/PromotionalBanner/PromotionalBanner.d.ts.map +1 -1
- package/dist/ui/QuickActions/QuickActions.d.ts.map +1 -1
- package/dist/ui/SearchInput/SearchInput.d.ts.map +1 -1
- package/dist/ui/SectionHeader/SectionHeader.d.ts.map +1 -1
- package/dist/ui/Select/Select.d.ts.map +1 -1
- package/dist/ui/SettingsList/SettingsList.d.ts.map +1 -1
- package/dist/ui/Sheet/Sheet.d.ts.map +1 -1
- package/dist/ui/SideNav/SideNav.d.ts.map +1 -1
- package/dist/ui/SmartLink/SmartLink.d.ts.map +1 -1
- package/dist/ui/Spinner/Spinner.d.ts.map +1 -1
- package/dist/ui/StatDisplay/StatDisplay.d.ts +0 -12
- package/dist/ui/StatDisplay/StatDisplay.d.ts.map +1 -1
- package/dist/ui/StepList/StepList.d.ts.map +1 -1
- package/dist/ui/Table/Table.d.ts.map +1 -1
- package/dist/ui/Tabs/Tabs.d.ts.map +1 -1
- package/dist/ui/Text/Text.d.ts.map +1 -1
- package/dist/ui/TextArea/TextArea.d.ts.map +1 -1
- package/dist/ui/TextInputModal/TextInputModal.d.ts.map +1 -1
- package/dist/ui/Toast/Toast.d.ts.map +1 -1
- package/dist/ui/Tooltip/Tooltip.d.ts +0 -20
- package/dist/ui/Tooltip/Tooltip.d.ts.map +1 -1
- package/dist/ui/TransferList/TransferList.d.ts.map +1 -1
- package/package.json +5 -4
- package/src/__tests__/alert.test.tsx +20 -10
- package/src/ui/Alert/Alert.tsx +13 -5
- package/src/ui/Avatar/Avatar.tsx +6 -5
- package/src/ui/Badge/Badge.tsx +61 -26
- package/src/ui/Banner/Banner.tsx +36 -25
- package/src/ui/Breadcrumb/Breadcrumb.tsx +8 -5
- package/src/ui/BreadcrumbNav/BreadcrumbNav.tsx +22 -3
- package/src/ui/CTASection/CTASection.tsx +8 -6
- package/src/ui/Calendar/Calendar.tsx +35 -6
- package/src/ui/Card/Card.tsx +2 -2
- package/src/ui/ChainBadge/ChainBadge.tsx +67 -42
- package/src/ui/Checkbox/Checkbox.tsx +47 -20
- package/src/ui/Code/Code.tsx +51 -21
- package/src/ui/CodeDisplay/CodeDisplay.tsx +46 -20
- package/src/ui/CollapsibleSection/CollapsibleSection.tsx +7 -3
- package/src/ui/Combobox/Combobox.tsx +2 -1
- package/src/ui/Command/Command.tsx +2 -1
- package/src/ui/DashboardStatCard/DashboardStatCard.tsx +29 -11
- package/src/ui/DataList/DataList.tsx +23 -5
- package/src/ui/Divider/Divider.tsx +12 -17
- package/src/ui/Dropdown/Dropdown.tsx +4 -1
- package/src/ui/ExternalLink/ExternalLink.tsx +5 -4
- package/src/ui/FeatureCard/FeatureCard.tsx +60 -29
- package/src/ui/FeatureGrid/FeatureGrid.tsx +7 -7
- package/src/ui/GradientIconContainer/GradientIconContainer.tsx +33 -8
- package/src/ui/Heading/Heading.tsx +15 -38
- package/src/ui/HelperText/HelperText.tsx +9 -8
- package/src/ui/IconContainer/IconContainer.tsx +26 -9
- package/src/ui/IconText/IconText.tsx +6 -5
- package/src/ui/InfiniteScroll/InfiniteScroll.tsx +2 -1
- package/src/ui/InfoBox/InfoBox.tsx +35 -17
- package/src/ui/Input/Input.tsx +10 -3
- package/src/ui/KeyValuePair/KeyValuePair.tsx +12 -5
- package/src/ui/Label/Label.tsx +3 -1
- package/src/ui/Link/Link.tsx +6 -5
- package/src/ui/ListItemWithAction/ListItemWithAction.tsx +2 -1
- package/src/ui/Modal/Modal.tsx +16 -2
- package/src/ui/MultiSelect/MultiSelect.tsx +2 -1
- package/src/ui/NavigationList/NavigationList.tsx +17 -3
- package/src/ui/PageSectionHeader/PageSectionHeader.tsx +2 -1
- package/src/ui/Pagination/Pagination.tsx +9 -6
- package/src/ui/PhoneInput/PhoneInput.tsx +3 -2
- package/src/ui/PopupSelect/PopupSelect.tsx +15 -14
- package/src/ui/Progress/Progress.tsx +63 -14
- package/src/ui/ProgressCircle/ProgressCircle.tsx +7 -6
- package/src/ui/PromotionalBanner/PromotionalBanner.tsx +7 -4
- package/src/ui/QuickActions/QuickActions.tsx +13 -9
- package/src/ui/SearchInput/SearchInput.tsx +3 -2
- package/src/ui/SectionHeader/SectionHeader.tsx +4 -1
- package/src/ui/Select/Select.tsx +20 -5
- package/src/ui/SettingsList/SettingsList.tsx +4 -1
- package/src/ui/Sheet/Sheet.tsx +20 -3
- package/src/ui/SideNav/SideNav.tsx +11 -2
- package/src/ui/SmartLink/SmartLink.tsx +6 -3
- package/src/ui/Spinner/Spinner.tsx +8 -6
- package/src/ui/StatDisplay/StatDisplay.tsx +59 -23
- package/src/ui/StepList/StepList.tsx +25 -3
- package/src/ui/Table/Table.tsx +22 -9
- package/src/ui/Tabs/Tabs.tsx +7 -2
- package/src/ui/Text/Text.tsx +19 -52
- package/src/ui/TextArea/TextArea.tsx +2 -1
- package/src/ui/TextInputModal/TextInputModal.tsx +2 -1
- package/src/ui/Toast/Toast.tsx +49 -14
- package/src/ui/Tooltip/Tooltip.tsx +47 -9
- 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
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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 &&
|
|
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=
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
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',
|
|
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',
|
|
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
|
-
|
|
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:
|
|
69
|
-
primary:
|
|
70
|
-
muted:
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
78
|
-
|
|
79
|
-
|
|
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
|
-
'
|
|
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
|
-
|
|
102
|
-
|
|
76
|
+
typography.size[actualSize],
|
|
77
|
+
typography.weight[weight],
|
|
78
|
+
typography.leading.heading,
|
|
79
|
+
typography.tracking.heading,
|
|
103
80
|
colorClasses[color],
|
|
104
|
-
|
|
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:
|
|
49
|
-
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:
|
|
61
|
+
text: colors.component.alert.info.icon,
|
|
61
62
|
icon: 'ℹ',
|
|
62
63
|
},
|
|
63
64
|
error: {
|
|
64
|
-
text:
|
|
65
|
+
text: colors.component.alert.error.icon,
|
|
65
66
|
icon: '⚠',
|
|
66
67
|
},
|
|
67
68
|
success: {
|
|
68
|
-
text:
|
|
69
|
+
text: colors.component.alert.success.icon,
|
|
69
70
|
icon: '✓',
|
|
70
71
|
},
|
|
71
72
|
warning: {
|
|
72
|
-
text:
|
|
73
|
+
text: colors.component.alert.warning.icon,
|
|
73
74
|
icon: '⚠',
|
|
74
75
|
},
|
|
75
76
|
};
|