@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
|
@@ -2,6 +2,9 @@ import * as React from 'react';
|
|
|
2
2
|
import { useState } from 'react';
|
|
3
3
|
import { View, Text, Pressable } from 'react-native';
|
|
4
4
|
import { cn } from '../../lib/utils';
|
|
5
|
+
import { designTokens } from '@sudobility/design';
|
|
6
|
+
|
|
7
|
+
const { typography } = designTokens;
|
|
5
8
|
|
|
6
9
|
export interface CalendarProps {
|
|
7
10
|
/** Selected date */
|
|
@@ -154,10 +157,23 @@ export const Calendar: React.FC<CalendarProps> = ({
|
|
|
154
157
|
accessibilityRole='button'
|
|
155
158
|
accessibilityLabel='Previous month'
|
|
156
159
|
>
|
|
157
|
-
<Text
|
|
160
|
+
<Text
|
|
161
|
+
className={cn(
|
|
162
|
+
typography.size.lg,
|
|
163
|
+
'text-gray-700 dark:text-gray-300'
|
|
164
|
+
)}
|
|
165
|
+
>
|
|
166
|
+
‹
|
|
167
|
+
</Text>
|
|
158
168
|
</Pressable>
|
|
159
169
|
|
|
160
|
-
<Text
|
|
170
|
+
<Text
|
|
171
|
+
className={cn(
|
|
172
|
+
typography.size.base,
|
|
173
|
+
typography.weight.semibold,
|
|
174
|
+
'text-gray-900 dark:text-white'
|
|
175
|
+
)}
|
|
176
|
+
>
|
|
161
177
|
{monthYear}
|
|
162
178
|
</Text>
|
|
163
179
|
|
|
@@ -167,7 +183,14 @@ export const Calendar: React.FC<CalendarProps> = ({
|
|
|
167
183
|
accessibilityRole='button'
|
|
168
184
|
accessibilityLabel='Next month'
|
|
169
185
|
>
|
|
170
|
-
<Text
|
|
186
|
+
<Text
|
|
187
|
+
className={cn(
|
|
188
|
+
typography.size.lg,
|
|
189
|
+
'text-gray-700 dark:text-gray-300'
|
|
190
|
+
)}
|
|
191
|
+
>
|
|
192
|
+
›
|
|
193
|
+
</Text>
|
|
171
194
|
</Pressable>
|
|
172
195
|
</View>
|
|
173
196
|
|
|
@@ -175,7 +198,13 @@ export const Calendar: React.FC<CalendarProps> = ({
|
|
|
175
198
|
<View className='flex-row mb-2'>
|
|
176
199
|
{weekDays.map(day => (
|
|
177
200
|
<View key={day} className='flex-1 items-center py-2'>
|
|
178
|
-
<Text
|
|
201
|
+
<Text
|
|
202
|
+
className={cn(
|
|
203
|
+
typography.size.xs,
|
|
204
|
+
typography.weight.medium,
|
|
205
|
+
'text-gray-600 dark:text-gray-400'
|
|
206
|
+
)}
|
|
207
|
+
>
|
|
179
208
|
{day}
|
|
180
209
|
</Text>
|
|
181
210
|
</View>
|
|
@@ -223,11 +252,11 @@ export const Calendar: React.FC<CalendarProps> = ({
|
|
|
223
252
|
>
|
|
224
253
|
<Text
|
|
225
254
|
className={cn(
|
|
226
|
-
|
|
255
|
+
typography.size.sm,
|
|
227
256
|
isCurrentMonth
|
|
228
257
|
? 'text-gray-900 dark:text-white'
|
|
229
258
|
: 'text-gray-400 dark:text-gray-600',
|
|
230
|
-
isSelected &&
|
|
259
|
+
isSelected && `text-white ${typography.weight.semibold}`
|
|
231
260
|
)}
|
|
232
261
|
>
|
|
233
262
|
{date.getDate()}
|
package/src/ui/Card/Card.tsx
CHANGED
|
@@ -29,8 +29,8 @@ export interface CardProps extends ViewProps {
|
|
|
29
29
|
onClose?: () => void;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
// Callout uses the DS info card variant colors
|
|
33
|
+
const calloutStyle = getCardVariantColors('info');
|
|
34
34
|
|
|
35
35
|
const paddingStyles = {
|
|
36
36
|
none: '',
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { View, Text, type ViewProps } from 'react-native';
|
|
3
3
|
import { cn } from '../../lib/utils';
|
|
4
|
+
import { colors, designTokens } from '@sudobility/design';
|
|
4
5
|
|
|
5
6
|
export type ChainType = 'evm' | 'solana' | 'bitcoin' | 'cosmos';
|
|
6
7
|
|
|
@@ -11,44 +12,61 @@ export interface ChainBadgeProps extends ViewProps {
|
|
|
11
12
|
showLabel?: boolean;
|
|
12
13
|
}
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Split combined DS badge color strings (which include both bg-* and text-*)
|
|
17
|
+
* into separate bg and text class strings.
|
|
18
|
+
*/
|
|
19
|
+
function splitBadgeClasses(base: string, dark: string) {
|
|
20
|
+
const all = `${base} ${dark}`.split(' ');
|
|
21
|
+
return {
|
|
22
|
+
bg: all.filter(c => c.includes('bg-')).join(' '),
|
|
23
|
+
text: all.filter(c => c.includes('text-')).join(' '),
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Lazily derive chain colors from DS to avoid ESM issues in tests.
|
|
28
|
+
let _chainColors: ReturnType<typeof buildChainColors> | null = null;
|
|
29
|
+
function getChainColors() {
|
|
30
|
+
if (!_chainColors) _chainColors = buildChainColors();
|
|
31
|
+
return _chainColors;
|
|
32
|
+
}
|
|
33
|
+
function buildChainColors() {
|
|
34
|
+
const badge = colors.component.badge;
|
|
35
|
+
return {
|
|
36
|
+
evm: splitBadgeClasses(badge.ethereum.base, badge.ethereum.dark),
|
|
37
|
+
solana: splitBadgeClasses(badge.solana.base, badge.solana.dark),
|
|
38
|
+
bitcoin: splitBadgeClasses(badge.bitcoin.base, badge.bitcoin.dark),
|
|
39
|
+
// DS has no cosmos badge — use local fallback (indigo)
|
|
40
|
+
cosmos: {
|
|
41
|
+
bg: 'bg-indigo-50 dark:bg-indigo-900/20',
|
|
42
|
+
text: 'text-indigo-700 dark:text-indigo-300',
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const chainMeta: Record<ChainType, { label: string; emoji: string }> = {
|
|
48
|
+
evm: { label: 'EVM', emoji: '⟠' },
|
|
49
|
+
solana: { label: 'SOL', emoji: '◎' },
|
|
50
|
+
bitcoin: { label: 'BTC', emoji: '₿' },
|
|
51
|
+
cosmos: { label: 'ATOM', emoji: '⚛' },
|
|
46
52
|
};
|
|
47
53
|
|
|
48
54
|
const sizeConfig = {
|
|
49
|
-
sm: {
|
|
50
|
-
|
|
51
|
-
|
|
55
|
+
sm: {
|
|
56
|
+
padding: 'px-1.5 py-0.5',
|
|
57
|
+
text: designTokens.typography.size.xs,
|
|
58
|
+
gap: 'gap-0.5',
|
|
59
|
+
},
|
|
60
|
+
md: {
|
|
61
|
+
padding: 'px-2 py-1',
|
|
62
|
+
text: designTokens.typography.size.sm,
|
|
63
|
+
gap: 'gap-1',
|
|
64
|
+
},
|
|
65
|
+
lg: {
|
|
66
|
+
padding: 'px-2.5 py-1.5',
|
|
67
|
+
text: designTokens.typography.size.base,
|
|
68
|
+
gap: 'gap-1.5',
|
|
69
|
+
},
|
|
52
70
|
};
|
|
53
71
|
|
|
54
72
|
export const ChainBadge: React.FC<ChainBadgeProps> = ({
|
|
@@ -58,27 +76,34 @@ export const ChainBadge: React.FC<ChainBadgeProps> = ({
|
|
|
58
76
|
className,
|
|
59
77
|
...props
|
|
60
78
|
}) => {
|
|
61
|
-
const
|
|
79
|
+
const chainColors = getChainColors()[chainType];
|
|
80
|
+
const meta = chainMeta[chainType];
|
|
62
81
|
const sizeStyles = sizeConfig[size];
|
|
63
82
|
|
|
64
83
|
return (
|
|
65
84
|
<View
|
|
66
85
|
className={cn(
|
|
67
86
|
'flex-row items-center rounded-md border',
|
|
68
|
-
|
|
87
|
+
chainColors.bg,
|
|
69
88
|
sizeStyles.padding,
|
|
70
89
|
sizeStyles.gap,
|
|
71
90
|
className
|
|
72
91
|
)}
|
|
73
|
-
accessibilityLabel={`${
|
|
92
|
+
accessibilityLabel={`${meta.label} chain`}
|
|
74
93
|
{...props}
|
|
75
94
|
>
|
|
76
|
-
<Text className={cn(sizeStyles.text,
|
|
77
|
-
{
|
|
95
|
+
<Text className={cn(sizeStyles.text, chainColors.text)}>
|
|
96
|
+
{meta.emoji}
|
|
78
97
|
</Text>
|
|
79
98
|
{showLabel && (
|
|
80
|
-
<Text
|
|
81
|
-
{
|
|
99
|
+
<Text
|
|
100
|
+
className={cn(
|
|
101
|
+
designTokens.typography.weight.medium,
|
|
102
|
+
sizeStyles.text,
|
|
103
|
+
chainColors.text
|
|
104
|
+
)}
|
|
105
|
+
>
|
|
106
|
+
{meta.label}
|
|
82
107
|
</Text>
|
|
83
108
|
)}
|
|
84
109
|
</View>
|
|
@@ -2,6 +2,7 @@ import * as React from 'react';
|
|
|
2
2
|
import { useState } from 'react';
|
|
3
3
|
import { View, Text, Pressable, PressableProps } from 'react-native';
|
|
4
4
|
import { cn } from '../../lib/utils';
|
|
5
|
+
import { colors, designTokens } from '@sudobility/design';
|
|
5
6
|
|
|
6
7
|
export interface CheckboxProps extends Omit<PressableProps, 'onPress'> {
|
|
7
8
|
/** Whether the checkbox is checked (controlled mode) */
|
|
@@ -54,6 +55,36 @@ export interface CheckboxProps extends Omit<PressableProps, 'onPress'> {
|
|
|
54
55
|
* />
|
|
55
56
|
* ```
|
|
56
57
|
*/
|
|
58
|
+
|
|
59
|
+
// Lazily derive checkbox colors from DS to avoid ESM issues in tests.
|
|
60
|
+
let _checkboxColors: ReturnType<typeof buildCheckboxColors> | null = null;
|
|
61
|
+
function getCheckboxColors() {
|
|
62
|
+
if (!_checkboxColors) _checkboxColors = buildCheckboxColors();
|
|
63
|
+
return _checkboxColors;
|
|
64
|
+
}
|
|
65
|
+
function buildCheckboxColors() {
|
|
66
|
+
// Extract solid bg colors from DS button variants for checked states
|
|
67
|
+
// DS button.primary.base contains "bg-blue-600 ... text-white"
|
|
68
|
+
// We only need the bg-* and border-* portions for checkbox checked state
|
|
69
|
+
function extractCheckedColor(base: string) {
|
|
70
|
+
const parts = base.split(' ');
|
|
71
|
+
const bg =
|
|
72
|
+
parts.find(
|
|
73
|
+
c =>
|
|
74
|
+
c.startsWith('bg-') && !c.includes('hover:') && !c.includes('active:')
|
|
75
|
+
) || '';
|
|
76
|
+
// For checkbox, border matches bg color
|
|
77
|
+
return `${bg} ${bg.replace('bg-', 'border-')}`;
|
|
78
|
+
}
|
|
79
|
+
const btn = colors.component.button;
|
|
80
|
+
return {
|
|
81
|
+
primary: extractCheckedColor(btn.primary.base),
|
|
82
|
+
success: extractCheckedColor(btn.success.base),
|
|
83
|
+
warning: 'bg-yellow-600 border-yellow-600', // DS has no yellow button; local fallback
|
|
84
|
+
error: extractCheckedColor(btn.destructive.base),
|
|
85
|
+
} as Record<string, string>;
|
|
86
|
+
}
|
|
87
|
+
|
|
57
88
|
export const Checkbox: React.FC<CheckboxProps> = ({
|
|
58
89
|
checked: controlledChecked,
|
|
59
90
|
defaultChecked = false,
|
|
@@ -80,43 +111,37 @@ export const Checkbox: React.FC<CheckboxProps> = ({
|
|
|
80
111
|
sm: {
|
|
81
112
|
box: 'w-4 h-4',
|
|
82
113
|
check: 'w-2 h-2',
|
|
83
|
-
text:
|
|
84
|
-
desc:
|
|
114
|
+
text: designTokens.typography.size.sm,
|
|
115
|
+
desc: designTokens.typography.size.xs,
|
|
85
116
|
},
|
|
86
117
|
md: {
|
|
87
118
|
box: 'w-5 h-5',
|
|
88
119
|
check: 'w-3 h-3',
|
|
89
|
-
text:
|
|
90
|
-
desc:
|
|
120
|
+
text: designTokens.typography.size.base,
|
|
121
|
+
desc: designTokens.typography.size.sm,
|
|
91
122
|
},
|
|
92
123
|
lg: {
|
|
93
124
|
box: 'w-6 h-6',
|
|
94
125
|
check: 'w-4 h-4',
|
|
95
|
-
text:
|
|
96
|
-
desc:
|
|
126
|
+
text: designTokens.typography.size.lg,
|
|
127
|
+
desc: designTokens.typography.size.base,
|
|
97
128
|
},
|
|
98
129
|
};
|
|
99
130
|
|
|
100
131
|
const getVariantClasses = () => {
|
|
132
|
+
const checkedColors = getCheckboxColors();
|
|
101
133
|
if (error) {
|
|
102
134
|
return checked
|
|
103
|
-
?
|
|
135
|
+
? checkedColors.error
|
|
104
136
|
: 'border-red-600 dark:border-red-500';
|
|
105
137
|
}
|
|
106
138
|
|
|
139
|
+
const unchecked = 'border-gray-300 dark:border-gray-600';
|
|
107
140
|
const variantClasses = {
|
|
108
|
-
primary: checked
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
? 'bg-green-600 border-green-600'
|
|
113
|
-
: 'border-gray-300 dark:border-gray-600',
|
|
114
|
-
warning: checked
|
|
115
|
-
? 'bg-yellow-600 border-yellow-600'
|
|
116
|
-
: 'border-gray-300 dark:border-gray-600',
|
|
117
|
-
error: checked
|
|
118
|
-
? 'bg-red-600 border-red-600'
|
|
119
|
-
: 'border-gray-300 dark:border-gray-600',
|
|
141
|
+
primary: checked ? checkedColors.primary : unchecked,
|
|
142
|
+
success: checked ? checkedColors.success : unchecked,
|
|
143
|
+
warning: checked ? checkedColors.warning : unchecked,
|
|
144
|
+
error: checked ? checkedColors.error : unchecked,
|
|
120
145
|
};
|
|
121
146
|
|
|
122
147
|
return variantClasses[variant];
|
|
@@ -191,7 +216,9 @@ export const Checkbox: React.FC<CheckboxProps> = ({
|
|
|
191
216
|
)}
|
|
192
217
|
</Pressable>
|
|
193
218
|
{errorMessage && (
|
|
194
|
-
<Text
|
|
219
|
+
<Text
|
|
220
|
+
className={`mt-1 ${designTokens.typography.size.sm} text-red-600 dark:text-red-400`}
|
|
221
|
+
>
|
|
195
222
|
{errorMessage}
|
|
196
223
|
</Text>
|
|
197
224
|
)}
|
package/src/ui/Code/Code.tsx
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { Text, View } from 'react-native';
|
|
3
3
|
import { cn } from '../../lib/utils';
|
|
4
|
+
import { colors, designTokens } from '@sudobility/design';
|
|
4
5
|
|
|
5
6
|
export interface CodeProps {
|
|
6
7
|
/** Code content */
|
|
@@ -30,6 +31,45 @@ export interface CodeProps {
|
|
|
30
31
|
* </Code>
|
|
31
32
|
* ```
|
|
32
33
|
*/
|
|
34
|
+
|
|
35
|
+
// Lazily derive code colors from DS to avoid ESM issues in tests.
|
|
36
|
+
let _codeColors: ReturnType<typeof buildCodeColors> | null = null;
|
|
37
|
+
function getCodeColors() {
|
|
38
|
+
if (!_codeColors) _codeColors = buildCodeColors();
|
|
39
|
+
return _codeColors;
|
|
40
|
+
}
|
|
41
|
+
function buildCodeColors() {
|
|
42
|
+
const alert = colors.component.alert;
|
|
43
|
+
// Split combined DS classes into separate bg/text for RN
|
|
44
|
+
function splitClasses(base: string, dark: string) {
|
|
45
|
+
const all = `${base} ${dark}`.split(' ');
|
|
46
|
+
return {
|
|
47
|
+
bg: all.filter(c => c.includes('bg-')).join(' '),
|
|
48
|
+
text: all.filter(c => c.includes('text-')).join(' '),
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
const info = splitClasses(alert.info.base, alert.info.dark);
|
|
52
|
+
const success = splitClasses(alert.success.base, alert.success.dark);
|
|
53
|
+
const warning = splitClasses(alert.warning.base, alert.warning.dark);
|
|
54
|
+
const error = splitClasses(alert.error.base, alert.error.dark);
|
|
55
|
+
return {
|
|
56
|
+
bg: {
|
|
57
|
+
default: 'bg-gray-100 dark:bg-gray-800',
|
|
58
|
+
primary: info.bg,
|
|
59
|
+
success: success.bg,
|
|
60
|
+
warning: warning.bg,
|
|
61
|
+
danger: error.bg,
|
|
62
|
+
} as Record<string, string>,
|
|
63
|
+
text: {
|
|
64
|
+
default: 'text-gray-900 dark:text-gray-100',
|
|
65
|
+
primary: info.text,
|
|
66
|
+
success: success.text,
|
|
67
|
+
warning: warning.text,
|
|
68
|
+
danger: error.text,
|
|
69
|
+
} as Record<string, string>,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
33
73
|
export const Code: React.FC<CodeProps> = ({
|
|
34
74
|
children,
|
|
35
75
|
size = 'md',
|
|
@@ -38,28 +78,14 @@ export const Code: React.FC<CodeProps> = ({
|
|
|
38
78
|
}) => {
|
|
39
79
|
// Size configurations
|
|
40
80
|
const sizeClasses = {
|
|
41
|
-
sm:
|
|
42
|
-
md:
|
|
43
|
-
lg:
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
// Variant configurations - background
|
|
47
|
-
const variantBgClasses = {
|
|
48
|
-
default: 'bg-gray-100 dark:bg-gray-800',
|
|
49
|
-
primary: 'bg-blue-50 dark:bg-blue-900/30',
|
|
50
|
-
success: 'bg-green-50 dark:bg-green-900/30',
|
|
51
|
-
warning: 'bg-yellow-50 dark:bg-yellow-900/30',
|
|
52
|
-
danger: 'bg-red-50 dark:bg-red-900/30',
|
|
81
|
+
sm: `${designTokens.typography.size.xs} px-1 py-0.5`,
|
|
82
|
+
md: `${designTokens.typography.size.sm} px-1.5 py-0.5`,
|
|
83
|
+
lg: `${designTokens.typography.size.base} px-2 py-1`,
|
|
53
84
|
};
|
|
54
85
|
|
|
55
|
-
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
primary: 'text-blue-700 dark:text-blue-300',
|
|
59
|
-
success: 'text-green-700 dark:text-green-300',
|
|
60
|
-
warning: 'text-yellow-700 dark:text-yellow-300',
|
|
61
|
-
danger: 'text-red-700 dark:text-red-300',
|
|
62
|
-
};
|
|
86
|
+
const codeColors = getCodeColors();
|
|
87
|
+
const variantBgClasses = codeColors.bg;
|
|
88
|
+
const variantTextClasses = codeColors.text;
|
|
63
89
|
|
|
64
90
|
return (
|
|
65
91
|
<View
|
|
@@ -71,7 +97,11 @@ export const Code: React.FC<CodeProps> = ({
|
|
|
71
97
|
)}
|
|
72
98
|
>
|
|
73
99
|
<Text
|
|
74
|
-
className={cn(
|
|
100
|
+
className={cn(
|
|
101
|
+
designTokens.typography.family.mono,
|
|
102
|
+
designTokens.typography.weight.medium,
|
|
103
|
+
variantTextClasses[variant]
|
|
104
|
+
)}
|
|
75
105
|
style={{ fontFamily: 'monospace' }}
|
|
76
106
|
>
|
|
77
107
|
{children}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { View, Text, ScrollView } from 'react-native';
|
|
3
3
|
import { cn } from '../../lib/utils';
|
|
4
|
+
import { colors, designTokens } from '@sudobility/design';
|
|
4
5
|
|
|
5
6
|
export interface CodeDisplayProps {
|
|
6
7
|
/** Code or text to display */
|
|
@@ -40,6 +41,36 @@ export interface CodeDisplayProps {
|
|
|
40
41
|
* </CodeDisplay>
|
|
41
42
|
* ```
|
|
42
43
|
*/
|
|
44
|
+
|
|
45
|
+
// Lazily derive display colors from DS to avoid ESM issues in tests.
|
|
46
|
+
let _displayColors: ReturnType<typeof buildDisplayColors> | null = null;
|
|
47
|
+
function getDisplayColors() {
|
|
48
|
+
if (!_displayColors) _displayColors = buildDisplayColors();
|
|
49
|
+
return _displayColors;
|
|
50
|
+
}
|
|
51
|
+
function buildDisplayColors() {
|
|
52
|
+
const alert = colors.component.alert;
|
|
53
|
+
function splitClasses(base: string, dark: string) {
|
|
54
|
+
const all = `${base} ${dark}`.split(' ');
|
|
55
|
+
return {
|
|
56
|
+
text: all.filter(c => c.includes('text-')).join(' '),
|
|
57
|
+
bg: all.filter(c => c.includes('bg-')).join(' '),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
const info = splitClasses(alert.info.base, alert.info.dark);
|
|
61
|
+
const success = splitClasses(alert.success.base, alert.success.dark);
|
|
62
|
+
const warning = splitClasses(alert.warning.base, alert.warning.dark);
|
|
63
|
+
return {
|
|
64
|
+
primary: `${info.text} ${info.bg}`,
|
|
65
|
+
// secondary uses purple — no DS mapping, keep local
|
|
66
|
+
secondary:
|
|
67
|
+
'text-purple-600 dark:text-purple-400 bg-purple-50 dark:bg-purple-900/30',
|
|
68
|
+
success: `${success.text} ${success.bg}`,
|
|
69
|
+
warning: `${warning.text} ${warning.bg}`,
|
|
70
|
+
neutral: 'text-gray-700 dark:text-gray-300 bg-gray-100 dark:bg-gray-800',
|
|
71
|
+
} as Record<string, string>;
|
|
72
|
+
}
|
|
73
|
+
|
|
43
74
|
export const CodeDisplay: React.FC<CodeDisplayProps> = ({
|
|
44
75
|
children,
|
|
45
76
|
variant = 'primary',
|
|
@@ -49,34 +80,25 @@ export const CodeDisplay: React.FC<CodeDisplayProps> = ({
|
|
|
49
80
|
wrap = false,
|
|
50
81
|
className,
|
|
51
82
|
}) => {
|
|
52
|
-
// Color variant configurations
|
|
53
|
-
const variantClasses =
|
|
54
|
-
primary: 'text-blue-600 dark:text-blue-400 bg-blue-50 dark:bg-blue-900/30',
|
|
55
|
-
secondary:
|
|
56
|
-
'text-purple-600 dark:text-purple-400 bg-purple-50 dark:bg-purple-900/30',
|
|
57
|
-
success:
|
|
58
|
-
'text-green-600 dark:text-green-400 bg-green-50 dark:bg-green-900/30',
|
|
59
|
-
warning:
|
|
60
|
-
'text-yellow-700 dark:text-yellow-400 bg-yellow-50 dark:bg-yellow-900/30',
|
|
61
|
-
neutral: 'text-gray-700 dark:text-gray-300 bg-gray-100 dark:bg-gray-800',
|
|
62
|
-
};
|
|
83
|
+
// Color variant configurations from DS
|
|
84
|
+
const variantClasses = getDisplayColors();
|
|
63
85
|
|
|
64
|
-
// Size configurations
|
|
86
|
+
// Size configurations using DS typography tokens
|
|
65
87
|
const sizeClasses = {
|
|
66
88
|
xs: {
|
|
67
|
-
text:
|
|
89
|
+
text: designTokens.typography.size.xs,
|
|
68
90
|
padding: inline ? 'px-1.5 py-0.5' : 'px-2 py-1',
|
|
69
91
|
},
|
|
70
92
|
sm: {
|
|
71
|
-
text:
|
|
93
|
+
text: designTokens.typography.size.sm,
|
|
72
94
|
padding: inline ? 'px-2 py-0.5' : 'px-3 py-1.5',
|
|
73
95
|
},
|
|
74
96
|
md: {
|
|
75
|
-
text:
|
|
97
|
+
text: designTokens.typography.size.base,
|
|
76
98
|
padding: inline ? 'px-2.5 py-1' : 'px-4 py-2',
|
|
77
99
|
},
|
|
78
100
|
lg: {
|
|
79
|
-
text:
|
|
101
|
+
text: designTokens.typography.size.lg,
|
|
80
102
|
padding: inline ? 'px-3 py-1' : 'px-4 py-2',
|
|
81
103
|
},
|
|
82
104
|
};
|
|
@@ -90,14 +112,18 @@ export const CodeDisplay: React.FC<CodeDisplayProps> = ({
|
|
|
90
112
|
|
|
91
113
|
const sizeConfig = sizeClasses[size];
|
|
92
114
|
|
|
93
|
-
// Extract background and text color classes
|
|
94
|
-
const
|
|
115
|
+
// Extract background and text color classes from combined variant string
|
|
116
|
+
const variantParts = variantClasses[variant].split(' ');
|
|
117
|
+
const textColorClass = variantParts
|
|
118
|
+
.filter(c => c.includes('text-'))
|
|
119
|
+
.join(' ');
|
|
120
|
+
const bgClass = variantParts.filter(c => c.includes('bg-')).join(' ');
|
|
95
121
|
|
|
96
122
|
if (inline) {
|
|
97
123
|
return (
|
|
98
124
|
<Text
|
|
99
125
|
className={cn(
|
|
100
|
-
|
|
126
|
+
`${designTokens.typography.family.mono} rounded-lg`,
|
|
101
127
|
textColorClass,
|
|
102
128
|
bgClass,
|
|
103
129
|
sizeConfig.text,
|
|
@@ -113,7 +139,7 @@ export const CodeDisplay: React.FC<CodeDisplayProps> = ({
|
|
|
113
139
|
const content = (
|
|
114
140
|
<Text
|
|
115
141
|
className={cn(
|
|
116
|
-
|
|
142
|
+
designTokens.typography.family.mono,
|
|
117
143
|
textColorClass,
|
|
118
144
|
sizeConfig.text,
|
|
119
145
|
!inline && alignClasses[align],
|
|
@@ -10,6 +10,9 @@ import {
|
|
|
10
10
|
UIManager,
|
|
11
11
|
} from 'react-native';
|
|
12
12
|
import { cn } from '../../lib/utils';
|
|
13
|
+
import { designTokens } from '@sudobility/design';
|
|
14
|
+
|
|
15
|
+
const { typography } = designTokens;
|
|
13
16
|
|
|
14
17
|
// Enable LayoutAnimation on Android
|
|
15
18
|
if (
|
|
@@ -126,7 +129,8 @@ export const CollapsibleSection: React.FC<CollapsibleSectionProps> = ({
|
|
|
126
129
|
>
|
|
127
130
|
<Text
|
|
128
131
|
className={cn(
|
|
129
|
-
|
|
132
|
+
typography.size.base,
|
|
133
|
+
typography.weight.medium,
|
|
130
134
|
isSelected && !selectedSubsection
|
|
131
135
|
? 'text-blue-700 dark:text-blue-300'
|
|
132
136
|
: 'text-gray-700 dark:text-gray-300'
|
|
@@ -145,7 +149,7 @@ export const CollapsibleSection: React.FC<CollapsibleSectionProps> = ({
|
|
|
145
149
|
accessibilityLabel={isExpanded ? 'Collapse' : 'Expand'}
|
|
146
150
|
>
|
|
147
151
|
<Animated.View style={{ transform: [{ rotate: rotation }] }}>
|
|
148
|
-
<Text className='text-gray-500
|
|
152
|
+
<Text className={cn('text-gray-500', typography.size.lg)}>›</Text>
|
|
149
153
|
</Animated.View>
|
|
150
154
|
</Pressable>
|
|
151
155
|
)}
|
|
@@ -172,7 +176,7 @@ export const CollapsibleSection: React.FC<CollapsibleSectionProps> = ({
|
|
|
172
176
|
>
|
|
173
177
|
<Text
|
|
174
178
|
className={cn(
|
|
175
|
-
|
|
179
|
+
typography.size.sm,
|
|
176
180
|
selectedSubsection === subsection.id
|
|
177
181
|
? 'text-blue-700 dark:text-blue-300'
|
|
178
182
|
: 'text-gray-600 dark:text-gray-400'
|
|
@@ -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 ComboboxOption {
|
|
15
16
|
/** Option value */
|
|
@@ -143,7 +144,7 @@ export const Combobox: React.FC<ComboboxProps> = ({
|
|
|
143
144
|
value={searchQuery}
|
|
144
145
|
onChangeText={setSearchQuery}
|
|
145
146
|
placeholder={searchPlaceholder}
|
|
146
|
-
placeholderTextColor=
|
|
147
|
+
placeholderTextColor={colors.raw.neutral[400]}
|
|
147
148
|
autoFocus
|
|
148
149
|
className='px-3 py-2 text-sm bg-gray-50 dark:bg-gray-800 text-gray-900 dark:text-white rounded-md'
|
|
149
150
|
/>
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
Platform,
|
|
12
12
|
} from 'react-native';
|
|
13
13
|
import { cn } from '../../lib/utils';
|
|
14
|
+
import { colors } from '@sudobility/design';
|
|
14
15
|
|
|
15
16
|
export interface CommandItem {
|
|
16
17
|
/** Item ID */
|
|
@@ -159,7 +160,7 @@ export const Command: React.FC<CommandProps> = ({
|
|
|
159
160
|
value={searchQuery}
|
|
160
161
|
onChangeText={setSearchQuery}
|
|
161
162
|
placeholder={placeholder}
|
|
162
|
-
placeholderTextColor=
|
|
163
|
+
placeholderTextColor={colors.raw.neutral[400]}
|
|
163
164
|
className='flex-1 text-gray-900 dark:text-white text-base'
|
|
164
165
|
autoCapitalize='none'
|
|
165
166
|
autoCorrect={false}
|