@one_deploy/sdk 1.0.6 → 1.0.7
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/react-native.d.mts +10 -6
- package/dist/react-native.d.ts +10 -6
- package/dist/react-native.js +695 -119
- package/dist/react-native.js.map +1 -1
- package/dist/react-native.mjs +696 -120
- package/dist/react-native.mjs.map +1 -1
- package/package.json +1 -1
- package/src/components/ai/OneChainSelector.tsx +336 -63
- package/src/components/ai/OnePairSelector.tsx +434 -77
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* OneChainSelector - Multi-chain selection component
|
|
3
|
-
* Part of ONE Ecosystem SDK -
|
|
2
|
+
* OneChainSelector - Multi-chain selection component with dropdown style
|
|
3
|
+
* Part of ONE Ecosystem SDK - Responsive design for desktop and mobile
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import React from 'react';
|
|
7
|
-
import { View, Text, StyleSheet, TouchableOpacity, ViewStyle, TextStyle } from 'react-native';
|
|
6
|
+
import React, { useState } from 'react';
|
|
7
|
+
import { View, Text, StyleSheet, TouchableOpacity, ViewStyle, TextStyle, Modal, ScrollView, Pressable, Dimensions, Platform } from 'react-native';
|
|
8
8
|
|
|
9
9
|
// Chain configuration with branding
|
|
10
10
|
export const CHAIN_CONFIG: Record<string, { name: string; icon: string; color: string }> = {
|
|
@@ -37,12 +37,19 @@ export interface OneChainSelectorProps {
|
|
|
37
37
|
subtitle?: string;
|
|
38
38
|
/** Minimum required selections (for multi-select) */
|
|
39
39
|
minSelections?: number;
|
|
40
|
+
/** Placeholder text */
|
|
41
|
+
placeholder?: string;
|
|
40
42
|
/** Custom styles */
|
|
41
43
|
style?: ViewStyle;
|
|
42
44
|
/** Custom title style */
|
|
43
45
|
titleStyle?: TextStyle;
|
|
44
46
|
}
|
|
45
47
|
|
|
48
|
+
const isDesktop = () => {
|
|
49
|
+
const { width } = Dimensions.get('window');
|
|
50
|
+
return Platform.OS === 'web' && width >= 768;
|
|
51
|
+
};
|
|
52
|
+
|
|
46
53
|
export const OneChainSelector: React.FC<OneChainSelectorProps> = ({
|
|
47
54
|
supportedChains,
|
|
48
55
|
selectedChains,
|
|
@@ -52,69 +59,179 @@ export const OneChainSelector: React.FC<OneChainSelectorProps> = ({
|
|
|
52
59
|
title,
|
|
53
60
|
subtitle,
|
|
54
61
|
minSelections = 1,
|
|
62
|
+
placeholder = 'Select chains...',
|
|
55
63
|
style,
|
|
56
64
|
titleStyle,
|
|
57
65
|
}) => {
|
|
66
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
67
|
+
const desktop = isDesktop();
|
|
68
|
+
|
|
58
69
|
const handleSelect = (chain: string) => {
|
|
59
70
|
if (multiSelect) {
|
|
60
|
-
// In multi-select, prevent deselecting if at minimum
|
|
61
71
|
if (selectedChains.includes(chain) && selectedChains.length <= minSelections) {
|
|
62
72
|
return;
|
|
63
73
|
}
|
|
64
74
|
onSelectChain(chain);
|
|
65
75
|
} else {
|
|
66
|
-
// Single select - always allow selection
|
|
67
76
|
if (!selectedChains.includes(chain)) {
|
|
68
77
|
onSelectChain(chain);
|
|
69
78
|
}
|
|
79
|
+
setIsOpen(false);
|
|
70
80
|
}
|
|
71
81
|
};
|
|
72
82
|
|
|
83
|
+
// Desktop: Inline grid display
|
|
84
|
+
if (desktop) {
|
|
85
|
+
return (
|
|
86
|
+
<View style={[styles.container, style]}>
|
|
87
|
+
{title && <Text style={[styles.title, titleStyle]}>{title}</Text>}
|
|
88
|
+
{subtitle && <Text style={styles.subtitle}>{subtitle}</Text>}
|
|
89
|
+
|
|
90
|
+
<View style={styles.desktopGrid}>
|
|
91
|
+
{supportedChains.map((chain) => {
|
|
92
|
+
const chainInfo = CHAIN_CONFIG[chain] || { name: chain, icon: '●', color: '#888' };
|
|
93
|
+
const isSelected = selectedChains.includes(chain);
|
|
94
|
+
|
|
95
|
+
return (
|
|
96
|
+
<TouchableOpacity
|
|
97
|
+
key={chain}
|
|
98
|
+
style={[
|
|
99
|
+
styles.desktopChip,
|
|
100
|
+
isSelected && styles.desktopChipSelected,
|
|
101
|
+
isSelected && { borderColor: accentColor, backgroundColor: accentColor + '12' }
|
|
102
|
+
]}
|
|
103
|
+
onPress={() => handleSelect(chain)}
|
|
104
|
+
activeOpacity={0.7}
|
|
105
|
+
>
|
|
106
|
+
<View style={[styles.desktopIconBg, { backgroundColor: chainInfo.color + '20' }]}>
|
|
107
|
+
<Text style={[styles.desktopIcon, { color: chainInfo.color }]}>{chainInfo.icon}</Text>
|
|
108
|
+
</View>
|
|
109
|
+
<Text style={[
|
|
110
|
+
styles.desktopChipText,
|
|
111
|
+
isSelected && { color: accentColor, fontWeight: '600' }
|
|
112
|
+
]}>
|
|
113
|
+
{chainInfo.name}
|
|
114
|
+
</Text>
|
|
115
|
+
{isSelected && (
|
|
116
|
+
<View style={[styles.desktopCheckbox, { backgroundColor: accentColor }]}>
|
|
117
|
+
<Text style={styles.desktopCheckIcon}>✓</Text>
|
|
118
|
+
</View>
|
|
119
|
+
)}
|
|
120
|
+
</TouchableOpacity>
|
|
121
|
+
);
|
|
122
|
+
})}
|
|
123
|
+
</View>
|
|
124
|
+
|
|
125
|
+
{multiSelect && selectedChains.length > 0 && (
|
|
126
|
+
<Text style={[styles.selectedCount, { color: accentColor }]}>
|
|
127
|
+
{selectedChains.length} chain{selectedChains.length > 1 ? 's' : ''} selected
|
|
128
|
+
</Text>
|
|
129
|
+
)}
|
|
130
|
+
</View>
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Mobile: Dropdown modal
|
|
73
135
|
return (
|
|
74
136
|
<View style={[styles.container, style]}>
|
|
75
137
|
{title && <Text style={[styles.title, titleStyle]}>{title}</Text>}
|
|
76
138
|
{subtitle && <Text style={styles.subtitle}>{subtitle}</Text>}
|
|
77
139
|
|
|
78
|
-
<
|
|
79
|
-
{
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
isSelected && { borderColor: accentColor, backgroundColor: accentColor + '15' }
|
|
90
|
-
]}
|
|
91
|
-
onPress={() => handleSelect(chain)}
|
|
92
|
-
activeOpacity={0.7}
|
|
93
|
-
>
|
|
94
|
-
<View style={[styles.chainIconBg, { backgroundColor: chainInfo.color + '20' }]}>
|
|
95
|
-
<Text style={[styles.chainIcon, { color: chainInfo.color }]}>{chainInfo.icon}</Text>
|
|
140
|
+
<TouchableOpacity
|
|
141
|
+
style={[styles.dropdownTrigger, { borderColor: isOpen ? accentColor : '#e5e5e5' }]}
|
|
142
|
+
onPress={() => setIsOpen(true)}
|
|
143
|
+
activeOpacity={0.7}
|
|
144
|
+
>
|
|
145
|
+
<View style={styles.selectedPreview}>
|
|
146
|
+
{selectedChains.slice(0, 3).map((chain) => {
|
|
147
|
+
const chainInfo = CHAIN_CONFIG[chain] || { name: chain, icon: '●', color: '#888' };
|
|
148
|
+
return (
|
|
149
|
+
<View key={chain} style={[styles.previewChip, { backgroundColor: chainInfo.color + '20' }]}>
|
|
150
|
+
<Text style={[styles.previewIcon, { color: chainInfo.color }]}>{chainInfo.icon}</Text>
|
|
96
151
|
</View>
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
}
|
|
109
|
-
</
|
|
152
|
+
);
|
|
153
|
+
})}
|
|
154
|
+
{selectedChains.length > 3 && (
|
|
155
|
+
<View style={styles.previewMore}>
|
|
156
|
+
<Text style={styles.previewMoreText}>+{selectedChains.length - 3}</Text>
|
|
157
|
+
</View>
|
|
158
|
+
)}
|
|
159
|
+
{selectedChains.length === 0 && (
|
|
160
|
+
<Text style={styles.placeholderText}>{placeholder}</Text>
|
|
161
|
+
)}
|
|
162
|
+
</View>
|
|
163
|
+
<Text style={styles.dropdownArrow}>{isOpen ? '▲' : '▼'}</Text>
|
|
164
|
+
</TouchableOpacity>
|
|
110
165
|
|
|
111
166
|
{multiSelect && selectedChains.length > 0 && (
|
|
112
|
-
<
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
</Text>
|
|
116
|
-
</View>
|
|
167
|
+
<Text style={[styles.selectedCount, { color: accentColor }]}>
|
|
168
|
+
{selectedChains.length} chain{selectedChains.length > 1 ? 's' : ''} selected
|
|
169
|
+
</Text>
|
|
117
170
|
)}
|
|
171
|
+
|
|
172
|
+
<Modal
|
|
173
|
+
visible={isOpen}
|
|
174
|
+
transparent
|
|
175
|
+
animationType="fade"
|
|
176
|
+
onRequestClose={() => setIsOpen(false)}
|
|
177
|
+
>
|
|
178
|
+
<Pressable style={styles.modalOverlay} onPress={() => setIsOpen(false)}>
|
|
179
|
+
<View style={styles.modalContent}>
|
|
180
|
+
<View style={styles.modalHeader}>
|
|
181
|
+
<Text style={styles.modalTitle}>{title || 'Select Chains'}</Text>
|
|
182
|
+
<TouchableOpacity onPress={() => setIsOpen(false)}>
|
|
183
|
+
<Text style={styles.modalClose}>✕</Text>
|
|
184
|
+
</TouchableOpacity>
|
|
185
|
+
</View>
|
|
186
|
+
|
|
187
|
+
<ScrollView style={styles.optionsList} showsVerticalScrollIndicator={false}>
|
|
188
|
+
{supportedChains.map((chain) => {
|
|
189
|
+
const chainInfo = CHAIN_CONFIG[chain] || { name: chain, icon: '●', color: '#888' };
|
|
190
|
+
const isSelected = selectedChains.includes(chain);
|
|
191
|
+
|
|
192
|
+
return (
|
|
193
|
+
<TouchableOpacity
|
|
194
|
+
key={chain}
|
|
195
|
+
style={[
|
|
196
|
+
styles.optionItem,
|
|
197
|
+
isSelected && styles.optionItemSelected,
|
|
198
|
+
isSelected && { backgroundColor: accentColor + '10', borderColor: accentColor }
|
|
199
|
+
]}
|
|
200
|
+
onPress={() => handleSelect(chain)}
|
|
201
|
+
activeOpacity={0.7}
|
|
202
|
+
>
|
|
203
|
+
<View style={[styles.optionIconBg, { backgroundColor: chainInfo.color + '20' }]}>
|
|
204
|
+
<Text style={[styles.optionIcon, { color: chainInfo.color }]}>{chainInfo.icon}</Text>
|
|
205
|
+
</View>
|
|
206
|
+
<Text style={[
|
|
207
|
+
styles.optionText,
|
|
208
|
+
isSelected && { color: accentColor, fontWeight: '600' }
|
|
209
|
+
]}>
|
|
210
|
+
{chainInfo.name}
|
|
211
|
+
</Text>
|
|
212
|
+
{isSelected ? (
|
|
213
|
+
<View style={[styles.checkbox, { backgroundColor: accentColor }]}>
|
|
214
|
+
<Text style={styles.checkboxIcon}>✓</Text>
|
|
215
|
+
</View>
|
|
216
|
+
) : (
|
|
217
|
+
<View style={styles.checkboxEmpty} />
|
|
218
|
+
)}
|
|
219
|
+
</TouchableOpacity>
|
|
220
|
+
);
|
|
221
|
+
})}
|
|
222
|
+
</ScrollView>
|
|
223
|
+
|
|
224
|
+
{multiSelect && (
|
|
225
|
+
<TouchableOpacity
|
|
226
|
+
style={[styles.doneButton, { backgroundColor: accentColor }]}
|
|
227
|
+
onPress={() => setIsOpen(false)}
|
|
228
|
+
>
|
|
229
|
+
<Text style={styles.doneButtonText}>Done ({selectedChains.length})</Text>
|
|
230
|
+
</TouchableOpacity>
|
|
231
|
+
)}
|
|
232
|
+
</View>
|
|
233
|
+
</Pressable>
|
|
234
|
+
</Modal>
|
|
118
235
|
</View>
|
|
119
236
|
);
|
|
120
237
|
};
|
|
@@ -134,50 +251,206 @@ const styles = StyleSheet.create({
|
|
|
134
251
|
color: '#666',
|
|
135
252
|
marginBottom: 12,
|
|
136
253
|
},
|
|
137
|
-
|
|
254
|
+
// Desktop styles
|
|
255
|
+
desktopGrid: {
|
|
138
256
|
flexDirection: 'row',
|
|
139
257
|
flexWrap: 'wrap',
|
|
140
|
-
gap:
|
|
258
|
+
gap: 10,
|
|
141
259
|
},
|
|
142
|
-
|
|
260
|
+
desktopChip: {
|
|
143
261
|
flexDirection: 'row',
|
|
144
262
|
alignItems: 'center',
|
|
145
|
-
paddingHorizontal:
|
|
146
|
-
paddingVertical:
|
|
263
|
+
paddingHorizontal: 14,
|
|
264
|
+
paddingVertical: 10,
|
|
147
265
|
backgroundColor: '#fff',
|
|
148
|
-
borderRadius:
|
|
266
|
+
borderRadius: 10,
|
|
149
267
|
borderWidth: 2,
|
|
150
|
-
borderColor: '#
|
|
151
|
-
gap:
|
|
268
|
+
borderColor: '#e8e8e8',
|
|
269
|
+
gap: 10,
|
|
270
|
+
cursor: 'pointer' as any,
|
|
152
271
|
},
|
|
153
|
-
|
|
272
|
+
desktopChipSelected: {
|
|
154
273
|
borderWidth: 2,
|
|
155
274
|
},
|
|
156
|
-
|
|
157
|
-
width:
|
|
158
|
-
height:
|
|
159
|
-
borderRadius:
|
|
275
|
+
desktopIconBg: {
|
|
276
|
+
width: 32,
|
|
277
|
+
height: 32,
|
|
278
|
+
borderRadius: 16,
|
|
160
279
|
alignItems: 'center',
|
|
161
280
|
justifyContent: 'center',
|
|
162
281
|
},
|
|
163
|
-
|
|
282
|
+
desktopIcon: {
|
|
164
283
|
fontSize: 14,
|
|
165
284
|
fontWeight: '700',
|
|
166
285
|
},
|
|
167
|
-
|
|
286
|
+
desktopChipText: {
|
|
168
287
|
fontSize: 14,
|
|
169
|
-
color: '#
|
|
288
|
+
color: '#444',
|
|
170
289
|
},
|
|
171
|
-
|
|
172
|
-
|
|
290
|
+
desktopCheckbox: {
|
|
291
|
+
width: 20,
|
|
292
|
+
height: 20,
|
|
293
|
+
borderRadius: 10,
|
|
294
|
+
alignItems: 'center',
|
|
295
|
+
justifyContent: 'center',
|
|
296
|
+
marginLeft: 4,
|
|
297
|
+
},
|
|
298
|
+
desktopCheckIcon: {
|
|
299
|
+
fontSize: 12,
|
|
300
|
+
color: '#fff',
|
|
173
301
|
fontWeight: '700',
|
|
174
302
|
},
|
|
175
|
-
|
|
176
|
-
|
|
303
|
+
// Mobile dropdown styles
|
|
304
|
+
dropdownTrigger: {
|
|
305
|
+
flexDirection: 'row',
|
|
306
|
+
alignItems: 'center',
|
|
307
|
+
justifyContent: 'space-between',
|
|
308
|
+
paddingHorizontal: 14,
|
|
309
|
+
paddingVertical: 12,
|
|
310
|
+
backgroundColor: '#fff',
|
|
311
|
+
borderRadius: 12,
|
|
312
|
+
borderWidth: 2,
|
|
313
|
+
borderColor: '#e5e5e5',
|
|
314
|
+
minHeight: 52,
|
|
315
|
+
},
|
|
316
|
+
selectedPreview: {
|
|
317
|
+
flex: 1,
|
|
318
|
+
flexDirection: 'row',
|
|
319
|
+
alignItems: 'center',
|
|
320
|
+
gap: 6,
|
|
321
|
+
},
|
|
322
|
+
previewChip: {
|
|
323
|
+
width: 32,
|
|
324
|
+
height: 32,
|
|
325
|
+
borderRadius: 16,
|
|
326
|
+
alignItems: 'center',
|
|
327
|
+
justifyContent: 'center',
|
|
328
|
+
},
|
|
329
|
+
previewIcon: {
|
|
330
|
+
fontSize: 14,
|
|
331
|
+
fontWeight: '700',
|
|
332
|
+
},
|
|
333
|
+
previewMore: {
|
|
334
|
+
paddingHorizontal: 8,
|
|
177
335
|
paddingVertical: 4,
|
|
336
|
+
backgroundColor: '#f0f0f0',
|
|
337
|
+
borderRadius: 8,
|
|
338
|
+
},
|
|
339
|
+
previewMoreText: {
|
|
340
|
+
fontSize: 12,
|
|
341
|
+
color: '#666',
|
|
342
|
+
fontWeight: '600',
|
|
343
|
+
},
|
|
344
|
+
placeholderText: {
|
|
345
|
+
fontSize: 14,
|
|
346
|
+
color: '#999',
|
|
347
|
+
},
|
|
348
|
+
dropdownArrow: {
|
|
349
|
+
fontSize: 12,
|
|
350
|
+
color: '#888',
|
|
351
|
+
marginLeft: 8,
|
|
178
352
|
},
|
|
179
|
-
|
|
353
|
+
selectedCount: {
|
|
180
354
|
fontSize: 12,
|
|
355
|
+
marginTop: 6,
|
|
356
|
+
fontWeight: '500',
|
|
357
|
+
},
|
|
358
|
+
// Modal styles
|
|
359
|
+
modalOverlay: {
|
|
360
|
+
flex: 1,
|
|
361
|
+
backgroundColor: 'rgba(0, 0, 0, 0.5)',
|
|
362
|
+
justifyContent: 'center',
|
|
363
|
+
alignItems: 'center',
|
|
364
|
+
},
|
|
365
|
+
modalContent: {
|
|
366
|
+
width: '85%',
|
|
367
|
+
maxWidth: 340,
|
|
368
|
+
maxHeight: '70%',
|
|
369
|
+
backgroundColor: '#fff',
|
|
370
|
+
borderRadius: 16,
|
|
371
|
+
overflow: 'hidden',
|
|
372
|
+
},
|
|
373
|
+
modalHeader: {
|
|
374
|
+
flexDirection: 'row',
|
|
375
|
+
justifyContent: 'space-between',
|
|
376
|
+
alignItems: 'center',
|
|
377
|
+
paddingHorizontal: 16,
|
|
378
|
+
paddingVertical: 14,
|
|
379
|
+
borderBottomWidth: 1,
|
|
380
|
+
borderBottomColor: '#f0f0f0',
|
|
381
|
+
},
|
|
382
|
+
modalTitle: {
|
|
383
|
+
fontSize: 18,
|
|
384
|
+
fontWeight: '700',
|
|
385
|
+
color: '#1a1a1a',
|
|
386
|
+
},
|
|
387
|
+
modalClose: {
|
|
388
|
+
fontSize: 20,
|
|
181
389
|
color: '#888',
|
|
390
|
+
padding: 4,
|
|
391
|
+
},
|
|
392
|
+
optionsList: {
|
|
393
|
+
padding: 8,
|
|
394
|
+
},
|
|
395
|
+
optionItem: {
|
|
396
|
+
flexDirection: 'row',
|
|
397
|
+
alignItems: 'center',
|
|
398
|
+
paddingHorizontal: 12,
|
|
399
|
+
paddingVertical: 12,
|
|
400
|
+
borderRadius: 10,
|
|
401
|
+
borderWidth: 1,
|
|
402
|
+
borderColor: 'transparent',
|
|
403
|
+
marginBottom: 6,
|
|
404
|
+
gap: 12,
|
|
405
|
+
},
|
|
406
|
+
optionItemSelected: {
|
|
407
|
+
borderWidth: 1,
|
|
408
|
+
},
|
|
409
|
+
optionIconBg: {
|
|
410
|
+
width: 36,
|
|
411
|
+
height: 36,
|
|
412
|
+
borderRadius: 18,
|
|
413
|
+
alignItems: 'center',
|
|
414
|
+
justifyContent: 'center',
|
|
415
|
+
},
|
|
416
|
+
optionIcon: {
|
|
417
|
+
fontSize: 16,
|
|
418
|
+
fontWeight: '700',
|
|
419
|
+
},
|
|
420
|
+
optionText: {
|
|
421
|
+
flex: 1,
|
|
422
|
+
fontSize: 15,
|
|
423
|
+
color: '#333',
|
|
424
|
+
},
|
|
425
|
+
checkbox: {
|
|
426
|
+
width: 24,
|
|
427
|
+
height: 24,
|
|
428
|
+
borderRadius: 12,
|
|
429
|
+
alignItems: 'center',
|
|
430
|
+
justifyContent: 'center',
|
|
431
|
+
},
|
|
432
|
+
checkboxIcon: {
|
|
433
|
+
fontSize: 14,
|
|
434
|
+
color: '#fff',
|
|
435
|
+
fontWeight: '700',
|
|
436
|
+
},
|
|
437
|
+
checkboxEmpty: {
|
|
438
|
+
width: 24,
|
|
439
|
+
height: 24,
|
|
440
|
+
borderRadius: 12,
|
|
441
|
+
borderWidth: 2,
|
|
442
|
+
borderColor: '#ddd',
|
|
443
|
+
},
|
|
444
|
+
doneButton: {
|
|
445
|
+
marginHorizontal: 16,
|
|
446
|
+
marginVertical: 12,
|
|
447
|
+
paddingVertical: 14,
|
|
448
|
+
borderRadius: 10,
|
|
449
|
+
alignItems: 'center',
|
|
450
|
+
},
|
|
451
|
+
doneButtonText: {
|
|
452
|
+
fontSize: 16,
|
|
453
|
+
fontWeight: '600',
|
|
454
|
+
color: '#fff',
|
|
182
455
|
},
|
|
183
456
|
});
|