@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.
- package/dist/index.cjs.js +895 -299
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +896 -300
- package/dist/index.esm.js.map +1 -1
- package/dist/ui/Avatar/Avatar.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/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/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/KeyValuePair/KeyValuePair.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/PromotionalBanner/PromotionalBanner.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/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/TextArea/TextArea.d.ts.map +1 -1
- package/dist/ui/TextInputModal/TextInputModal.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 +3 -3
- package/src/ui/Avatar/Avatar.tsx +6 -5
- 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/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/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/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/KeyValuePair/KeyValuePair.tsx +12 -5
- 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/PromotionalBanner/PromotionalBanner.tsx +7 -4
- 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 +1 -1
- 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/TextArea/TextArea.tsx +2 -1
- package/src/ui/TextInputModal/TextInputModal.tsx +2 -1
- 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, 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
|
};
|
|
@@ -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:
|
|
85
|
-
success:
|
|
86
|
-
warning:
|
|
87
|
-
danger:
|
|
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=
|
|
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:
|
|
59
|
-
md: {
|
|
60
|
-
|
|
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:
|
|
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:
|
|
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
|
|
package/src/ui/Link/Link.tsx
CHANGED
|
@@ -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:
|
|
59
|
-
primary:
|
|
60
|
-
secondary:
|
|
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:
|
|
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 ?
|
|
95
|
+
color={destructive ? colors.raw.red[600] : colors.raw.neutral[500]}
|
|
95
96
|
/>
|
|
96
97
|
) : (
|
|
97
98
|
<>
|
package/src/ui/Modal/Modal.tsx
CHANGED
|
@@ -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
|
|
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
|
|
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=
|
|
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
|
-
|
|
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
|
|
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
|
|
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=
|
|
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:
|
|
69
|
-
icon:
|
|
71
|
+
text: typography.size.xs,
|
|
72
|
+
icon: typography.size.xs,
|
|
70
73
|
},
|
|
71
74
|
md: {
|
|
72
75
|
button: 'h-10 w-10',
|
|
73
|
-
text:
|
|
74
|
-
icon:
|
|
76
|
+
text: typography.size.sm,
|
|
77
|
+
icon: typography.size.sm,
|
|
75
78
|
},
|
|
76
79
|
lg: {
|
|
77
80
|
button: 'h-12 w-12',
|
|
78
|
-
text:
|
|
79
|
-
icon:
|
|
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=
|
|
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=
|
|
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:
|
|
167
|
+
borderColor: colors.raw.neutral[300],
|
|
167
168
|
borderRadius: 8,
|
|
168
169
|
paddingHorizontal: 12,
|
|
169
170
|
paddingVertical: 12,
|
|
170
|
-
backgroundColor:
|
|
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:
|
|
179
|
+
color: colors.raw.neutral[900],
|
|
179
180
|
},
|
|
180
181
|
triggerPlaceholder: {
|
|
181
|
-
color:
|
|
182
|
+
color: colors.raw.neutral[400],
|
|
182
183
|
},
|
|
183
184
|
triggerArrow: {
|
|
184
185
|
fontSize: 10,
|
|
185
|
-
color:
|
|
186
|
+
color: colors.raw.neutral[400],
|
|
186
187
|
marginLeft: 8,
|
|
187
188
|
},
|
|
188
189
|
modalContainer: {
|
|
189
190
|
flex: 1,
|
|
190
|
-
backgroundColor:
|
|
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:
|
|
200
|
+
borderBottomColor: colors.raw.neutral[200],
|
|
200
201
|
},
|
|
201
202
|
modalTitle: {
|
|
202
203
|
fontSize: 18,
|
|
203
204
|
fontWeight: '600',
|
|
204
|
-
color:
|
|
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:
|
|
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:
|
|
222
|
+
backgroundColor: colors.raw.neutral[50],
|
|
222
223
|
borderRadius: 12,
|
|
223
224
|
},
|
|
224
225
|
optionItemSelected: {
|
|
225
|
-
backgroundColor:
|
|
226
|
+
backgroundColor: colors.raw.blue[100],
|
|
226
227
|
},
|
|
227
228
|
optionLabel: {
|
|
228
229
|
flex: 1,
|
|
229
230
|
fontSize: 16,
|
|
230
|
-
color:
|
|
231
|
+
color: colors.raw.neutral[900],
|
|
231
232
|
},
|
|
232
233
|
optionLabelSelected: {
|
|
233
234
|
fontWeight: '600',
|
|
234
|
-
color:
|
|
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:
|
|
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:
|
|
77
|
-
success:
|
|
78
|
-
warning:
|
|
79
|
-
danger:
|
|
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
|
|
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:
|
|
179
|
-
success:
|
|
180
|
-
warning:
|
|
181
|
-
danger:
|
|
182
|
-
purple:
|
|
183
|
-
gray:
|
|
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
|
|
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
|
)}
|