@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 } 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,24 @@
|
|
|
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';
|
|
5
|
+
|
|
6
|
+
const alert = colors.component.alert;
|
|
7
|
+
|
|
8
|
+
// Split DS alert color strings into separate parts for RN
|
|
9
|
+
function splitAlertClasses(base: string, dark: string) {
|
|
10
|
+
const all = `${base} ${dark}`.split(' ');
|
|
11
|
+
return {
|
|
12
|
+
bg: all.filter(c => c.includes('bg-')).join(' '),
|
|
13
|
+
border: all.filter(c => c.includes('border-')).join(' '),
|
|
14
|
+
text: all.filter(c => c.includes('text-')).join(' '),
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const dsInfo = splitAlertClasses(alert.info.base, alert.info.dark);
|
|
19
|
+
const dsSuccess = splitAlertClasses(alert.success.base, alert.success.dark);
|
|
20
|
+
const dsWarning = splitAlertClasses(alert.warning.base, alert.warning.dark);
|
|
21
|
+
const dsError = splitAlertClasses(alert.error.base, alert.error.dark);
|
|
4
22
|
|
|
5
23
|
export interface InfoBoxProps {
|
|
6
24
|
/** Content to display in the info box */
|
|
@@ -49,31 +67,31 @@ export const InfoBox: React.FC<InfoBoxProps> = ({
|
|
|
49
67
|
bordered = true,
|
|
50
68
|
className,
|
|
51
69
|
}) => {
|
|
52
|
-
// Color
|
|
70
|
+
// Color variants derived from design system (colors.component.alert)
|
|
53
71
|
const variantClasses = {
|
|
54
72
|
info: {
|
|
55
|
-
bg:
|
|
56
|
-
border:
|
|
57
|
-
title:
|
|
58
|
-
text:
|
|
73
|
+
bg: dsInfo.bg,
|
|
74
|
+
border: dsInfo.border,
|
|
75
|
+
title: dsInfo.text,
|
|
76
|
+
text: dsInfo.text,
|
|
59
77
|
},
|
|
60
78
|
success: {
|
|
61
|
-
bg:
|
|
62
|
-
border:
|
|
63
|
-
title:
|
|
64
|
-
text:
|
|
79
|
+
bg: dsSuccess.bg,
|
|
80
|
+
border: dsSuccess.border,
|
|
81
|
+
title: dsSuccess.text,
|
|
82
|
+
text: dsSuccess.text,
|
|
65
83
|
},
|
|
66
84
|
warning: {
|
|
67
|
-
bg:
|
|
68
|
-
border:
|
|
69
|
-
title:
|
|
70
|
-
text:
|
|
85
|
+
bg: dsWarning.bg,
|
|
86
|
+
border: dsWarning.border,
|
|
87
|
+
title: dsWarning.text,
|
|
88
|
+
text: dsWarning.text,
|
|
71
89
|
},
|
|
72
90
|
danger: {
|
|
73
|
-
bg:
|
|
74
|
-
border:
|
|
75
|
-
title:
|
|
76
|
-
text:
|
|
91
|
+
bg: dsError.bg,
|
|
92
|
+
border: dsError.border,
|
|
93
|
+
title: dsError.text,
|
|
94
|
+
text: dsError.text,
|
|
77
95
|
},
|
|
78
96
|
neutral: {
|
|
79
97
|
bg: 'bg-gray-50 dark:bg-gray-800',
|
package/src/ui/Input/Input.tsx
CHANGED
|
@@ -8,6 +8,13 @@ import {
|
|
|
8
8
|
import { cn } from '../../lib/utils';
|
|
9
9
|
import { variants as v } from '@sudobility/design';
|
|
10
10
|
|
|
11
|
+
// RN input state classes aligned with design system (colors.component.input.default).
|
|
12
|
+
// CSS pseudo-class selectors (focus:, disabled:) don't apply in RN, so we
|
|
13
|
+
// apply these conditionally via component state instead.
|
|
14
|
+
const inputFocusClass = 'border-blue-500 dark:border-blue-400';
|
|
15
|
+
const inputErrorClass = 'border-red-500 dark:border-red-400';
|
|
16
|
+
const inputDisabledClass = 'opacity-50 bg-gray-100 dark:bg-gray-800';
|
|
17
|
+
|
|
11
18
|
export interface InputProps extends Omit<TextInputProps, 'style'> {
|
|
12
19
|
/** Additional class names for styling */
|
|
13
20
|
className?: string;
|
|
@@ -54,9 +61,9 @@ export const Input = React.forwardRef<TextInput, InputProps>(
|
|
|
54
61
|
ref={ref}
|
|
55
62
|
className={cn(
|
|
56
63
|
v.input.default(),
|
|
57
|
-
isFocused &&
|
|
58
|
-
error &&
|
|
59
|
-
disabled &&
|
|
64
|
+
isFocused && inputFocusClass,
|
|
65
|
+
error && inputErrorClass,
|
|
66
|
+
disabled && inputDisabledClass,
|
|
60
67
|
className
|
|
61
68
|
)}
|
|
62
69
|
editable={isEditable}
|
|
@@ -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/Label/Label.tsx
CHANGED
|
@@ -45,7 +45,9 @@ export const Label = React.forwardRef<Text, LabelProps>(
|
|
|
45
45
|
{...props}
|
|
46
46
|
>
|
|
47
47
|
{children}
|
|
48
|
-
{required &&
|
|
48
|
+
{required && (
|
|
49
|
+
<Text className='text-red-600 dark:text-red-400 ml-1'>*</Text>
|
|
50
|
+
)}
|
|
49
51
|
</Text>
|
|
50
52
|
);
|
|
51
53
|
}
|
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: {
|