@ledgerhq/lumen-ui-rnative 0.1.37 → 0.1.38
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/module/lib/Components/AmountInput/AmountInput.js +109 -72
- package/dist/module/lib/Components/AmountInput/AmountInput.js.map +1 -1
- package/dist/module/lib/Components/AmountInput/AmountInput.mdx +12 -0
- package/dist/module/lib/Components/AmountInput/AmountInput.stories.js +53 -0
- package/dist/module/lib/Components/AmountInput/AmountInput.stories.js.map +1 -1
- package/dist/module/lib/Components/Avatar/Avatar.js +6 -5
- package/dist/module/lib/Components/Avatar/Avatar.js.map +1 -1
- package/dist/module/lib/Components/Avatar/Avatar.mdx +2 -0
- package/dist/module/lib/Components/Avatar/Avatar.test.js +10 -13
- package/dist/module/lib/Components/Avatar/Avatar.test.js.map +1 -1
- package/dist/module/lib/Components/DotIcon/DotIcon.js +7 -4
- package/dist/module/lib/Components/DotIcon/DotIcon.js.map +1 -1
- package/dist/module/lib/Components/DotIcon/DotIcon.stories.js +10 -0
- package/dist/module/lib/Components/DotIcon/DotIcon.stories.js.map +1 -1
- package/dist/module/lib/Components/DotIndicator/DotIndicator.js +5 -5
- package/dist/module/lib/Components/DotIndicator/DotIndicator.js.map +1 -1
- package/dist/module/lib/Components/DotIndicator/DotIndicator.mdx +4 -4
- package/dist/module/lib/Components/DotIndicator/DotIndicator.stories.js +3 -3
- package/dist/module/lib/Components/DotIndicator/DotIndicator.test.js +12 -2
- package/dist/module/lib/Components/DotIndicator/DotIndicator.test.js.map +1 -1
- package/dist/module/lib/Components/DotSymbol/DotSymbol.js +7 -4
- package/dist/module/lib/Components/DotSymbol/DotSymbol.js.map +1 -1
- package/dist/module/lib/Components/DotSymbol/DotSymbol.stories.js +19 -0
- package/dist/module/lib/Components/DotSymbol/DotSymbol.stories.js.map +1 -1
- package/dist/module/lib/Components/Label/Label.js +1 -1
- package/dist/module/lib/Components/MediaButton/MediaButton.js +2 -2
- package/dist/module/lib/Components/MediaButton/MediaButton.mdx +2 -2
- package/dist/module/lib/Components/MediaImage/MediaImage.js +4 -2
- package/dist/module/lib/Components/MediaImage/MediaImage.js.map +1 -1
- package/dist/module/lib/Components/MediaImage/MediaImage.mdx +1 -1
- package/dist/module/lib/Components/MediaImage/MediaImage.stories.js +12 -0
- package/dist/module/lib/Components/MediaImage/MediaImage.stories.js.map +1 -1
- package/dist/module/lib/Components/OptionList/OptionList.mdx +1 -1
- package/dist/module/lib/Components/ThemeProvider/ThemeProvider.js +2 -5
- package/dist/module/lib/Components/ThemeProvider/ThemeProvider.js.map +1 -1
- package/dist/module/lib/Components/index.js +0 -1
- package/dist/module/lib/Components/index.js.map +1 -1
- package/dist/module/lib/Symbols/Icons/Lightbulb.js +3 -3
- package/dist/module/lib/Symbols/Icons/Lightbulb.js.map +1 -1
- package/dist/typescript/src/lib/Components/AmountInput/AmountInput.d.ts +1 -1
- package/dist/typescript/src/lib/Components/AmountInput/AmountInput.d.ts.map +1 -1
- package/dist/typescript/src/lib/Components/AmountInput/types.d.ts +12 -0
- package/dist/typescript/src/lib/Components/AmountInput/types.d.ts.map +1 -1
- package/dist/typescript/src/lib/Components/Avatar/Avatar.d.ts +1 -1
- package/dist/typescript/src/lib/Components/Avatar/Avatar.d.ts.map +1 -1
- package/dist/typescript/src/lib/Components/DotIcon/DotIcon.d.ts +2 -1
- package/dist/typescript/src/lib/Components/DotIcon/DotIcon.d.ts.map +1 -1
- package/dist/typescript/src/lib/Components/DotIcon/types.d.ts +1 -1
- package/dist/typescript/src/lib/Components/DotIcon/types.d.ts.map +1 -1
- package/dist/typescript/src/lib/Components/DotIndicator/types.d.ts +2 -2
- package/dist/typescript/src/lib/Components/DotSymbol/DotSymbol.d.ts.map +1 -1
- package/dist/typescript/src/lib/Components/DotSymbol/types.d.ts +1 -1
- package/dist/typescript/src/lib/Components/DotSymbol/types.d.ts.map +1 -1
- package/dist/typescript/src/lib/Components/Label/Label.d.ts +1 -1
- package/dist/typescript/src/lib/Components/MediaButton/MediaButton.d.ts +2 -2
- package/dist/typescript/src/lib/Components/MediaImage/MediaImage.d.ts.map +1 -1
- package/dist/typescript/src/lib/Components/MediaImage/types.d.ts +1 -1
- package/dist/typescript/src/lib/Components/MediaImage/types.d.ts.map +1 -1
- package/dist/typescript/src/lib/Components/ThemeProvider/ThemeProvider.d.ts.map +1 -1
- package/dist/typescript/src/lib/Components/index.d.ts +0 -1
- package/dist/typescript/src/lib/Components/index.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/lib/Components/AmountInput/AmountInput.mdx +12 -0
- package/src/lib/Components/AmountInput/AmountInput.stories.tsx +68 -1
- package/src/lib/Components/AmountInput/AmountInput.tsx +118 -75
- package/src/lib/Components/AmountInput/types.ts +14 -0
- package/src/lib/Components/Avatar/Avatar.mdx +2 -0
- package/src/lib/Components/Avatar/Avatar.test.tsx +16 -18
- package/src/lib/Components/Avatar/Avatar.tsx +9 -8
- package/src/lib/Components/DotIcon/DotIcon.stories.tsx +8 -0
- package/src/lib/Components/DotIcon/DotIcon.tsx +4 -1
- package/src/lib/Components/DotIcon/types.ts +1 -1
- package/src/lib/Components/DotIndicator/DotIndicator.mdx +4 -4
- package/src/lib/Components/DotIndicator/DotIndicator.stories.tsx +2 -2
- package/src/lib/Components/DotIndicator/DotIndicator.test.tsx +12 -2
- package/src/lib/Components/DotIndicator/DotIndicator.tsx +5 -5
- package/src/lib/Components/DotIndicator/types.ts +2 -2
- package/src/lib/Components/DotSymbol/DotSymbol.stories.tsx +15 -0
- package/src/lib/Components/DotSymbol/DotSymbol.tsx +4 -1
- package/src/lib/Components/DotSymbol/types.ts +1 -1
- package/src/lib/Components/Label/Label.tsx +1 -1
- package/src/lib/Components/MediaButton/MediaButton.mdx +2 -2
- package/src/lib/Components/MediaButton/MediaButton.tsx +2 -2
- package/src/lib/Components/MediaImage/MediaImage.mdx +1 -1
- package/src/lib/Components/MediaImage/MediaImage.stories.tsx +3 -0
- package/src/lib/Components/MediaImage/MediaImage.tsx +2 -0
- package/src/lib/Components/MediaImage/types.ts +1 -1
- package/src/lib/Components/OptionList/OptionList.mdx +1 -1
- package/src/lib/Components/ThemeProvider/ThemeProvider.tsx +1 -4
- package/src/lib/Components/index.ts +0 -1
- package/src/lib/Symbols/Icons/Lightbulb.tsx +3 -3
- package/dist/module/lib/Components/Select/GlobalSelectBottomSheet.js +0 -155
- package/dist/module/lib/Components/Select/GlobalSelectBottomSheet.js.map +0 -1
- package/dist/module/lib/Components/Select/GlobalSelectContext.js +0 -78
- package/dist/module/lib/Components/Select/GlobalSelectContext.js.map +0 -1
- package/dist/module/lib/Components/Select/Select.js +0 -366
- package/dist/module/lib/Components/Select/Select.js.map +0 -1
- package/dist/module/lib/Components/Select/Select.mdx +0 -596
- package/dist/module/lib/Components/Select/Select.stories.js +0 -304
- package/dist/module/lib/Components/Select/Select.stories.js.map +0 -1
- package/dist/module/lib/Components/Select/Select.test.js +0 -123
- package/dist/module/lib/Components/Select/Select.test.js.map +0 -1
- package/dist/module/lib/Components/Select/SelectContext.js +0 -38
- package/dist/module/lib/Components/Select/SelectContext.js.map +0 -1
- package/dist/module/lib/Components/Select/index.js +0 -6
- package/dist/module/lib/Components/Select/index.js.map +0 -1
- package/dist/module/lib/Components/Select/types.js +0 -4
- package/dist/module/lib/Components/Select/types.js.map +0 -1
- package/dist/typescript/src/lib/Components/Select/GlobalSelectBottomSheet.d.ts +0 -20
- package/dist/typescript/src/lib/Components/Select/GlobalSelectBottomSheet.d.ts.map +0 -1
- package/dist/typescript/src/lib/Components/Select/GlobalSelectContext.d.ts +0 -44
- package/dist/typescript/src/lib/Components/Select/GlobalSelectContext.d.ts.map +0 -1
- package/dist/typescript/src/lib/Components/Select/Select.d.ts +0 -52
- package/dist/typescript/src/lib/Components/Select/Select.d.ts.map +0 -1
- package/dist/typescript/src/lib/Components/Select/SelectContext.d.ts +0 -36
- package/dist/typescript/src/lib/Components/Select/SelectContext.d.ts.map +0 -1
- package/dist/typescript/src/lib/Components/Select/index.d.ts +0 -4
- package/dist/typescript/src/lib/Components/Select/index.d.ts.map +0 -1
- package/dist/typescript/src/lib/Components/Select/types.d.ts +0 -130
- package/dist/typescript/src/lib/Components/Select/types.d.ts.map +0 -1
- package/src/lib/Components/Select/GlobalSelectBottomSheet.tsx +0 -180
- package/src/lib/Components/Select/GlobalSelectContext.tsx +0 -103
- package/src/lib/Components/Select/Select.mdx +0 -596
- package/src/lib/Components/Select/Select.stories.tsx +0 -266
- package/src/lib/Components/Select/Select.test.tsx +0 -117
- package/src/lib/Components/Select/Select.tsx +0 -469
- package/src/lib/Components/Select/SelectContext.tsx +0 -68
- package/src/lib/Components/Select/index.ts +0 -3
- package/src/lib/Components/Select/types.ts +0 -149
|
@@ -1,469 +0,0 @@
|
|
|
1
|
-
import { useDisabledContext } from '@ledgerhq/lumen-utils-shared';
|
|
2
|
-
import type { ReactNode } from 'react';
|
|
3
|
-
import {
|
|
4
|
-
useState,
|
|
5
|
-
useEffect,
|
|
6
|
-
useCallback,
|
|
7
|
-
useId,
|
|
8
|
-
Children,
|
|
9
|
-
isValidElement,
|
|
10
|
-
} from 'react';
|
|
11
|
-
import { StyleSheet, View } from 'react-native';
|
|
12
|
-
import { useStyleSheet } from '../../../styles';
|
|
13
|
-
import { ChevronDown } from '../../Symbols';
|
|
14
|
-
import { useControllableState, extractTextFromChildren } from '../../utils';
|
|
15
|
-
import { SlotPressable } from '../Slot';
|
|
16
|
-
import { Box, Pressable, Text } from '../Utility';
|
|
17
|
-
import { useSelectActions } from './GlobalSelectContext';
|
|
18
|
-
import { SelectContextProvider, useSelectSafeContext } from './SelectContext';
|
|
19
|
-
import type {
|
|
20
|
-
SelectProps,
|
|
21
|
-
SelectTriggerProps,
|
|
22
|
-
SelectContentProps,
|
|
23
|
-
SelectGroupProps,
|
|
24
|
-
SelectLabelProps,
|
|
25
|
-
SelectItemProps,
|
|
26
|
-
SelectItemTextProps,
|
|
27
|
-
SelectSeparatorProps,
|
|
28
|
-
SelectContentItem,
|
|
29
|
-
} from './types';
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* The root component that manages a select's state.
|
|
33
|
-
*
|
|
34
|
-
* This component coordinates between the trigger, content, and items.
|
|
35
|
-
* It works with GlobalSelectProvider to display options in a bottom sheet.
|
|
36
|
-
*
|
|
37
|
-
* @see {@link https://ldls.vercel.app/?path=/docs/components-select-overview--docs Storybook}
|
|
38
|
-
*
|
|
39
|
-
* @example
|
|
40
|
-
* import { Select, SelectTrigger, SelectContent, SelectItem, SelectItemText } from '@ledgerhq/lumen-ui-rnative';
|
|
41
|
-
*
|
|
42
|
-
* function App() {
|
|
43
|
-
* const [value, setValue] = useState('option1');
|
|
44
|
-
* return (
|
|
45
|
-
* <Select value={value} onValueChange={setValue}>
|
|
46
|
-
* <SelectTrigger label="Choose option">
|
|
47
|
-
* <SelectValue />
|
|
48
|
-
* </SelectTrigger>
|
|
49
|
-
* <SelectContent>
|
|
50
|
-
* <SelectItem value="option1">
|
|
51
|
-
* <SelectItemText>Option 1</SelectItemText>
|
|
52
|
-
* </SelectItem>
|
|
53
|
-
* <SelectItem value="option2">
|
|
54
|
-
* <SelectItemText>Option 2</SelectItemText>
|
|
55
|
-
* </SelectItem>
|
|
56
|
-
* </SelectContent>
|
|
57
|
-
* </Select>
|
|
58
|
-
* );
|
|
59
|
-
* }
|
|
60
|
-
*/
|
|
61
|
-
export const Select = ({
|
|
62
|
-
children,
|
|
63
|
-
open: controlledOpen,
|
|
64
|
-
defaultOpen = false,
|
|
65
|
-
onOpenChange,
|
|
66
|
-
value: controlledValue,
|
|
67
|
-
defaultValue,
|
|
68
|
-
onValueChange,
|
|
69
|
-
disabled: disabledProp = false,
|
|
70
|
-
}: SelectProps) => {
|
|
71
|
-
const disabled = useDisabledContext({
|
|
72
|
-
consumerName: 'Select',
|
|
73
|
-
mergeWith: { disabled: disabledProp },
|
|
74
|
-
});
|
|
75
|
-
const selectId = useId();
|
|
76
|
-
|
|
77
|
-
const [internalOpen, setInternalOpen] = useControllableState({
|
|
78
|
-
prop: controlledOpen,
|
|
79
|
-
defaultProp: defaultOpen,
|
|
80
|
-
onChange: onOpenChange,
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
const [internalValue, setInternalValue] = useControllableState<
|
|
84
|
-
SelectProps['value']
|
|
85
|
-
>({
|
|
86
|
-
prop: controlledValue,
|
|
87
|
-
defaultProp: defaultValue ?? undefined,
|
|
88
|
-
onChange: (value: SelectProps['value']) => {
|
|
89
|
-
if (value !== undefined) {
|
|
90
|
-
onValueChange?.(value);
|
|
91
|
-
}
|
|
92
|
-
},
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
const [items, setItems] = useState<SelectContentItem[]>([]);
|
|
96
|
-
|
|
97
|
-
const setOpen = useCallback(
|
|
98
|
-
(newOpen: boolean) => {
|
|
99
|
-
if (!disabled) {
|
|
100
|
-
setInternalOpen?.(newOpen);
|
|
101
|
-
}
|
|
102
|
-
},
|
|
103
|
-
[setInternalOpen, disabled],
|
|
104
|
-
);
|
|
105
|
-
|
|
106
|
-
const handleValueChange = useCallback(
|
|
107
|
-
(newValue: string) => {
|
|
108
|
-
setInternalValue?.(newValue);
|
|
109
|
-
},
|
|
110
|
-
[setInternalValue],
|
|
111
|
-
);
|
|
112
|
-
|
|
113
|
-
return (
|
|
114
|
-
<SelectContextProvider
|
|
115
|
-
selectId={selectId}
|
|
116
|
-
open={internalOpen ?? false}
|
|
117
|
-
setOpen={setOpen}
|
|
118
|
-
value={internalValue}
|
|
119
|
-
onValueChange={handleValueChange}
|
|
120
|
-
disabled={disabled}
|
|
121
|
-
items={items}
|
|
122
|
-
setItems={setItems}
|
|
123
|
-
>
|
|
124
|
-
{children}
|
|
125
|
-
</SelectContextProvider>
|
|
126
|
-
);
|
|
127
|
-
};
|
|
128
|
-
|
|
129
|
-
export const SelectTrigger = ({
|
|
130
|
-
children,
|
|
131
|
-
lx,
|
|
132
|
-
style,
|
|
133
|
-
label,
|
|
134
|
-
asChild = false,
|
|
135
|
-
disabled: triggerDisabled,
|
|
136
|
-
...props
|
|
137
|
-
}: SelectTriggerProps) => {
|
|
138
|
-
const {
|
|
139
|
-
selectId,
|
|
140
|
-
setOpen,
|
|
141
|
-
items,
|
|
142
|
-
value,
|
|
143
|
-
disabled: contextDisabled,
|
|
144
|
-
label: contextLabel,
|
|
145
|
-
onValueChange,
|
|
146
|
-
} = useSelectSafeContext({
|
|
147
|
-
consumerName: 'SelectTrigger',
|
|
148
|
-
contextRequired: true,
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
const { showSelect } = useSelectActions();
|
|
152
|
-
const disabled = triggerDisabled ?? contextDisabled;
|
|
153
|
-
const finalLabel = label ?? contextLabel;
|
|
154
|
-
|
|
155
|
-
const handlePress = useCallback((): void => {
|
|
156
|
-
if (!disabled && items.length > 0) {
|
|
157
|
-
setOpen(true);
|
|
158
|
-
showSelect({
|
|
159
|
-
id: selectId,
|
|
160
|
-
items,
|
|
161
|
-
selectedValue: value,
|
|
162
|
-
onSelectValue: onValueChange,
|
|
163
|
-
setOpen,
|
|
164
|
-
label: finalLabel,
|
|
165
|
-
});
|
|
166
|
-
}
|
|
167
|
-
}, [
|
|
168
|
-
disabled,
|
|
169
|
-
items,
|
|
170
|
-
selectId,
|
|
171
|
-
value,
|
|
172
|
-
setOpen,
|
|
173
|
-
showSelect,
|
|
174
|
-
finalLabel,
|
|
175
|
-
onValueChange,
|
|
176
|
-
]);
|
|
177
|
-
|
|
178
|
-
const hasValue = value !== undefined && value !== '';
|
|
179
|
-
const styles = useTriggerStyles({
|
|
180
|
-
disabled: !!disabled,
|
|
181
|
-
hasValue,
|
|
182
|
-
hasLabel: !!finalLabel,
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
const Comp = asChild ? SlotPressable : Pressable;
|
|
186
|
-
|
|
187
|
-
return (
|
|
188
|
-
<Comp
|
|
189
|
-
lx={lx}
|
|
190
|
-
style={[styles.trigger, style]}
|
|
191
|
-
disabled={disabled}
|
|
192
|
-
onPress={handlePress}
|
|
193
|
-
{...props}
|
|
194
|
-
>
|
|
195
|
-
{finalLabel && (
|
|
196
|
-
<Text style={styles.label} numberOfLines={1}>
|
|
197
|
-
{finalLabel}
|
|
198
|
-
</Text>
|
|
199
|
-
)}
|
|
200
|
-
<View style={styles.contentWrapper}>{children}</View>
|
|
201
|
-
<ChevronDown size={20} style={styles.chevron} />
|
|
202
|
-
</Comp>
|
|
203
|
-
);
|
|
204
|
-
};
|
|
205
|
-
|
|
206
|
-
const useTriggerStyles = ({
|
|
207
|
-
disabled,
|
|
208
|
-
hasValue,
|
|
209
|
-
hasLabel,
|
|
210
|
-
}: {
|
|
211
|
-
disabled: boolean;
|
|
212
|
-
hasValue: boolean;
|
|
213
|
-
hasLabel: boolean;
|
|
214
|
-
}) => {
|
|
215
|
-
return useStyleSheet(
|
|
216
|
-
(t) => {
|
|
217
|
-
return {
|
|
218
|
-
trigger: StyleSheet.flatten([
|
|
219
|
-
{
|
|
220
|
-
position: 'relative',
|
|
221
|
-
width: t.sizes.full,
|
|
222
|
-
height: t.sizes.s48,
|
|
223
|
-
backgroundColor: t.colors.bg.muted,
|
|
224
|
-
borderRadius: t.borderRadius.sm,
|
|
225
|
-
paddingHorizontal: t.spacings.s16,
|
|
226
|
-
flexDirection: 'row',
|
|
227
|
-
alignItems: 'center',
|
|
228
|
-
justifyContent: 'space-between',
|
|
229
|
-
},
|
|
230
|
-
disabled && {
|
|
231
|
-
opacity: 0.5,
|
|
232
|
-
},
|
|
233
|
-
]),
|
|
234
|
-
label: StyleSheet.flatten([
|
|
235
|
-
t.typographies.body2,
|
|
236
|
-
{
|
|
237
|
-
position: 'absolute',
|
|
238
|
-
left: t.spacings.s16,
|
|
239
|
-
color: t.colors.text.muted,
|
|
240
|
-
width: '100%',
|
|
241
|
-
},
|
|
242
|
-
hasValue
|
|
243
|
-
? {
|
|
244
|
-
top: t.spacings.s6,
|
|
245
|
-
...t.typographies.body4,
|
|
246
|
-
}
|
|
247
|
-
: {
|
|
248
|
-
top: t.spacings.s14,
|
|
249
|
-
...t.typographies.body2,
|
|
250
|
-
},
|
|
251
|
-
disabled && {
|
|
252
|
-
color: t.colors.text.disabled,
|
|
253
|
-
},
|
|
254
|
-
]),
|
|
255
|
-
contentWrapper: StyleSheet.flatten([
|
|
256
|
-
{
|
|
257
|
-
flex: 1,
|
|
258
|
-
},
|
|
259
|
-
hasLabel &&
|
|
260
|
-
hasValue && {
|
|
261
|
-
paddingTop: t.spacings.s16,
|
|
262
|
-
paddingBottom: t.spacings.s2,
|
|
263
|
-
},
|
|
264
|
-
hasLabel &&
|
|
265
|
-
!hasValue && {
|
|
266
|
-
paddingVertical: 0,
|
|
267
|
-
},
|
|
268
|
-
]),
|
|
269
|
-
chevron: StyleSheet.flatten([
|
|
270
|
-
{
|
|
271
|
-
flexShrink: 0,
|
|
272
|
-
color: t.colors.text.muted,
|
|
273
|
-
marginLeft: t.spacings.s8,
|
|
274
|
-
},
|
|
275
|
-
disabled && {
|
|
276
|
-
color: t.colors.text.disabled,
|
|
277
|
-
},
|
|
278
|
-
]),
|
|
279
|
-
};
|
|
280
|
-
},
|
|
281
|
-
[disabled, hasValue, hasLabel],
|
|
282
|
-
);
|
|
283
|
-
};
|
|
284
|
-
|
|
285
|
-
/**
|
|
286
|
-
* Displays the current selected value
|
|
287
|
-
*/
|
|
288
|
-
export const SelectValue = () => {
|
|
289
|
-
const { value, items } = useSelectSafeContext({
|
|
290
|
-
consumerName: 'SelectValue',
|
|
291
|
-
contextRequired: true,
|
|
292
|
-
});
|
|
293
|
-
|
|
294
|
-
const styles = useStyleSheet(
|
|
295
|
-
(t) => ({
|
|
296
|
-
text: StyleSheet.flatten([
|
|
297
|
-
t.typographies.body2,
|
|
298
|
-
{
|
|
299
|
-
color: t.colors.text.base,
|
|
300
|
-
textAlign: 'left',
|
|
301
|
-
},
|
|
302
|
-
]),
|
|
303
|
-
}),
|
|
304
|
-
[],
|
|
305
|
-
);
|
|
306
|
-
|
|
307
|
-
const selectedItem = items.find(
|
|
308
|
-
(item) => item.type === 'item' && item.value === value,
|
|
309
|
-
);
|
|
310
|
-
|
|
311
|
-
if (!selectedItem || selectedItem.type !== 'item') {
|
|
312
|
-
return null;
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
return (
|
|
316
|
-
<Text style={styles.text} numberOfLines={1} ellipsizeMode='tail'>
|
|
317
|
-
{selectedItem.label}
|
|
318
|
-
</Text>
|
|
319
|
-
);
|
|
320
|
-
};
|
|
321
|
-
|
|
322
|
-
/**
|
|
323
|
-
* Container for select items. This component collects all items
|
|
324
|
-
* and makes them available to the bottom sheet.
|
|
325
|
-
*/
|
|
326
|
-
export const SelectContent = ({ children }: SelectContentProps) => {
|
|
327
|
-
const { setItems } = useSelectSafeContext({
|
|
328
|
-
consumerName: 'SelectContent',
|
|
329
|
-
contextRequired: true,
|
|
330
|
-
});
|
|
331
|
-
|
|
332
|
-
useEffect(() => {
|
|
333
|
-
const items: SelectContentItem[] = [];
|
|
334
|
-
|
|
335
|
-
const extractItems = (child: ReactNode): void => {
|
|
336
|
-
Children.forEach(child, (element) => {
|
|
337
|
-
if (!isValidElement(element)) return;
|
|
338
|
-
|
|
339
|
-
if (element.type === SelectItem) {
|
|
340
|
-
const props = element.props as SelectItemProps;
|
|
341
|
-
const textValue =
|
|
342
|
-
props.textValue ??
|
|
343
|
-
extractTextFromChildren(props.children, SelectItemText);
|
|
344
|
-
items.push({
|
|
345
|
-
type: 'item',
|
|
346
|
-
value: props.value,
|
|
347
|
-
label: textValue,
|
|
348
|
-
disabled: props.disabled,
|
|
349
|
-
});
|
|
350
|
-
} else if (element.type === SelectGroup) {
|
|
351
|
-
extractItems((element.props as { children?: ReactNode }).children);
|
|
352
|
-
} else if (element.type === SelectLabel) {
|
|
353
|
-
const labelText = extractTextFromChildren(
|
|
354
|
-
(element.props as { children?: ReactNode }).children,
|
|
355
|
-
SelectItemText,
|
|
356
|
-
);
|
|
357
|
-
items.push({
|
|
358
|
-
type: 'group-label',
|
|
359
|
-
label: labelText,
|
|
360
|
-
});
|
|
361
|
-
} else if (element.type === SelectSeparator) {
|
|
362
|
-
items.push({
|
|
363
|
-
type: 'separator',
|
|
364
|
-
});
|
|
365
|
-
} else if ((element.props as { children?: ReactNode })?.children) {
|
|
366
|
-
extractItems((element.props as { children?: ReactNode }).children);
|
|
367
|
-
}
|
|
368
|
-
});
|
|
369
|
-
};
|
|
370
|
-
|
|
371
|
-
extractItems(children);
|
|
372
|
-
setItems(items);
|
|
373
|
-
}, [children, setItems]);
|
|
374
|
-
|
|
375
|
-
return null;
|
|
376
|
-
};
|
|
377
|
-
|
|
378
|
-
export const SelectGroup = ({
|
|
379
|
-
children,
|
|
380
|
-
lx,
|
|
381
|
-
style,
|
|
382
|
-
...props
|
|
383
|
-
}: SelectGroupProps) => {
|
|
384
|
-
const styles = useStyleSheet(
|
|
385
|
-
(t) => ({
|
|
386
|
-
group: {
|
|
387
|
-
width: t.sizes.full,
|
|
388
|
-
gap: t.spacings.s4,
|
|
389
|
-
},
|
|
390
|
-
}),
|
|
391
|
-
[],
|
|
392
|
-
);
|
|
393
|
-
|
|
394
|
-
return (
|
|
395
|
-
<Box lx={lx} style={[styles.group, style]} {...props}>
|
|
396
|
-
{children}
|
|
397
|
-
</Box>
|
|
398
|
-
);
|
|
399
|
-
};
|
|
400
|
-
|
|
401
|
-
export const SelectLabel = ({
|
|
402
|
-
children,
|
|
403
|
-
lx,
|
|
404
|
-
style,
|
|
405
|
-
...props
|
|
406
|
-
}: SelectLabelProps) => {
|
|
407
|
-
const styles = useStyleSheet(
|
|
408
|
-
(t) => ({
|
|
409
|
-
label: StyleSheet.flatten([
|
|
410
|
-
t.typographies.body3SemiBold,
|
|
411
|
-
{
|
|
412
|
-
paddingHorizontal: t.spacings.s8,
|
|
413
|
-
paddingBottom: 0,
|
|
414
|
-
paddingTop: t.spacings.s8,
|
|
415
|
-
color: t.colors.text.muted,
|
|
416
|
-
marginBottom: t.spacings.s4,
|
|
417
|
-
},
|
|
418
|
-
]),
|
|
419
|
-
}),
|
|
420
|
-
[],
|
|
421
|
-
);
|
|
422
|
-
|
|
423
|
-
return (
|
|
424
|
-
<Text lx={lx} style={[styles.label, style]} {...props}>
|
|
425
|
-
{children}
|
|
426
|
-
</Text>
|
|
427
|
-
);
|
|
428
|
-
};
|
|
429
|
-
|
|
430
|
-
/**
|
|
431
|
-
* Individual select item. Note: The actual rendering happens in GlobalSelectBottomSheet.
|
|
432
|
-
* This component is used to declare the structure and collect item data.
|
|
433
|
-
*/
|
|
434
|
-
export const SelectItem = (_props: SelectItemProps) => {
|
|
435
|
-
// This component doesn't render anything - it's used for structure
|
|
436
|
-
// The actual items are rendered in GlobalSelectBottomSheet
|
|
437
|
-
return null;
|
|
438
|
-
};
|
|
439
|
-
|
|
440
|
-
export const SelectItemText = ({
|
|
441
|
-
children,
|
|
442
|
-
lx,
|
|
443
|
-
style,
|
|
444
|
-
...props
|
|
445
|
-
}: SelectItemTextProps) => {
|
|
446
|
-
const styles = useStyleSheet(
|
|
447
|
-
(t) => ({
|
|
448
|
-
text: StyleSheet.flatten([
|
|
449
|
-
t.typographies.body2,
|
|
450
|
-
{
|
|
451
|
-
color: t.colors.text.base,
|
|
452
|
-
},
|
|
453
|
-
]),
|
|
454
|
-
}),
|
|
455
|
-
[],
|
|
456
|
-
);
|
|
457
|
-
|
|
458
|
-
return (
|
|
459
|
-
<Text lx={lx} style={[styles.text, style]} {...props}>
|
|
460
|
-
{children}
|
|
461
|
-
</Text>
|
|
462
|
-
);
|
|
463
|
-
};
|
|
464
|
-
|
|
465
|
-
export const SelectSeparator = (_props: SelectSeparatorProps) => {
|
|
466
|
-
// This component doesn't render anything - it's used for structure
|
|
467
|
-
// The actual separators are rendered in GlobalSelectBottomSheet
|
|
468
|
-
return null;
|
|
469
|
-
};
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import { createSafeContext } from '@ledgerhq/lumen-utils-shared';
|
|
2
|
-
import type { ReactNode } from 'react';
|
|
3
|
-
import type { SelectContentItem } from './types';
|
|
4
|
-
|
|
5
|
-
export type SelectContextValue = {
|
|
6
|
-
selectId: string;
|
|
7
|
-
open: boolean;
|
|
8
|
-
setOpen: (open: boolean) => void;
|
|
9
|
-
value: string | undefined;
|
|
10
|
-
onValueChange: (value: string) => void;
|
|
11
|
-
disabled: boolean;
|
|
12
|
-
items: SelectContentItem[];
|
|
13
|
-
setItems: (items: SelectContentItem[]) => void;
|
|
14
|
-
label?: string;
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
const [SelectProvider, _useSelectSafeContext] =
|
|
18
|
-
createSafeContext<SelectContextValue>('Select');
|
|
19
|
-
|
|
20
|
-
export const useSelectSafeContext = _useSelectSafeContext;
|
|
21
|
-
|
|
22
|
-
type SelectContextProviderProps = {
|
|
23
|
-
selectId: string;
|
|
24
|
-
open: boolean;
|
|
25
|
-
setOpen: (open: boolean) => void;
|
|
26
|
-
value: string | undefined;
|
|
27
|
-
onValueChange: (value: string) => void;
|
|
28
|
-
disabled: boolean;
|
|
29
|
-
items: SelectContentItem[];
|
|
30
|
-
setItems: (items: SelectContentItem[]) => void;
|
|
31
|
-
label?: string;
|
|
32
|
-
children: ReactNode;
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Internal context provider for an individual Select component.
|
|
37
|
-
* This is used automatically by the Select component.
|
|
38
|
-
*/
|
|
39
|
-
export const SelectContextProvider = ({
|
|
40
|
-
selectId,
|
|
41
|
-
open,
|
|
42
|
-
setOpen,
|
|
43
|
-
value,
|
|
44
|
-
onValueChange,
|
|
45
|
-
disabled,
|
|
46
|
-
items,
|
|
47
|
-
setItems,
|
|
48
|
-
label,
|
|
49
|
-
children,
|
|
50
|
-
}: SelectContextProviderProps) => {
|
|
51
|
-
return (
|
|
52
|
-
<SelectProvider
|
|
53
|
-
value={{
|
|
54
|
-
selectId,
|
|
55
|
-
open,
|
|
56
|
-
setOpen,
|
|
57
|
-
value,
|
|
58
|
-
onValueChange,
|
|
59
|
-
disabled,
|
|
60
|
-
items,
|
|
61
|
-
setItems,
|
|
62
|
-
label,
|
|
63
|
-
}}
|
|
64
|
-
>
|
|
65
|
-
{children}
|
|
66
|
-
</SelectProvider>
|
|
67
|
-
);
|
|
68
|
-
};
|
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
import type { ReactNode } from 'react';
|
|
2
|
-
import type { PressableProps } from 'react-native';
|
|
3
|
-
import type {
|
|
4
|
-
StyledViewProps,
|
|
5
|
-
StyledPressableProps,
|
|
6
|
-
StyledTextProps,
|
|
7
|
-
} from '../../../styles';
|
|
8
|
-
import type { BoxProps } from '../Utility';
|
|
9
|
-
|
|
10
|
-
export type SelectProps = {
|
|
11
|
-
/**
|
|
12
|
-
* The children of the select (SelectTrigger, SelectContent)
|
|
13
|
-
*/
|
|
14
|
-
children: ReactNode;
|
|
15
|
-
/**
|
|
16
|
-
* The controlled open state of the select.
|
|
17
|
-
* Must be used in conjunction with onOpenChange.
|
|
18
|
-
*/
|
|
19
|
-
open?: boolean;
|
|
20
|
-
/**
|
|
21
|
-
* The value of the select when initially rendered.
|
|
22
|
-
* Use when you do not need to control the state of the select.
|
|
23
|
-
*/
|
|
24
|
-
defaultValue?: string;
|
|
25
|
-
/**
|
|
26
|
-
* Event handler called when the open state of the select changes.
|
|
27
|
-
*/
|
|
28
|
-
onOpenChange?: (open: boolean) => void;
|
|
29
|
-
/**
|
|
30
|
-
* The open state of the select when it is initially rendered.
|
|
31
|
-
* Use when you do not need to control its open state.
|
|
32
|
-
* @default false
|
|
33
|
-
*/
|
|
34
|
-
defaultOpen?: boolean;
|
|
35
|
-
/**
|
|
36
|
-
* When true, prevents the user from interacting with select.
|
|
37
|
-
*/
|
|
38
|
-
disabled?: boolean;
|
|
39
|
-
/**
|
|
40
|
-
* The controlled value of the select.
|
|
41
|
-
* Should be used in conjunction with onValueChange.
|
|
42
|
-
*/
|
|
43
|
-
value?: string;
|
|
44
|
-
/**
|
|
45
|
-
* Event handler called when the value changes.
|
|
46
|
-
*/
|
|
47
|
-
onValueChange?: (value: string) => void;
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
export type SelectTriggerProps = {
|
|
51
|
-
/**
|
|
52
|
-
* The children to render inside the trigger
|
|
53
|
-
*/
|
|
54
|
-
children?: ReactNode;
|
|
55
|
-
/**
|
|
56
|
-
* The label text that floats above the input when focused or filled
|
|
57
|
-
* @example label='Select an option'
|
|
58
|
-
*/
|
|
59
|
-
label?: string;
|
|
60
|
-
/**
|
|
61
|
-
* Change the default rendered element for the one passed as a child,
|
|
62
|
-
* merging their props and behavior.
|
|
63
|
-
* @default false
|
|
64
|
-
*/
|
|
65
|
-
asChild?: boolean;
|
|
66
|
-
} & Omit<StyledPressableProps, 'children'>;
|
|
67
|
-
|
|
68
|
-
export type SelectContentProps = {
|
|
69
|
-
/**
|
|
70
|
-
* The children of the select content (SelectItem, SelectGroup, etc.)
|
|
71
|
-
*/
|
|
72
|
-
children: ReactNode;
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
export type SelectGroupProps = {
|
|
76
|
-
/**
|
|
77
|
-
* The children of the select group (SelectLabel, SelectItem)
|
|
78
|
-
*/
|
|
79
|
-
children: ReactNode;
|
|
80
|
-
} & StyledViewProps;
|
|
81
|
-
|
|
82
|
-
export type SelectLabelProps = {
|
|
83
|
-
/**
|
|
84
|
-
* The children of the select label
|
|
85
|
-
* @required
|
|
86
|
-
*/
|
|
87
|
-
children: ReactNode;
|
|
88
|
-
} & StyledTextProps;
|
|
89
|
-
|
|
90
|
-
export type SelectItemProps = {
|
|
91
|
-
/**
|
|
92
|
-
* The value of the select item
|
|
93
|
-
* @required
|
|
94
|
-
*/
|
|
95
|
-
value: string;
|
|
96
|
-
/**
|
|
97
|
-
* The children of the select item
|
|
98
|
-
* @required
|
|
99
|
-
*/
|
|
100
|
-
children: ReactNode;
|
|
101
|
-
/**
|
|
102
|
-
* Optional text used for display. Use this when the content is complex.
|
|
103
|
-
*/
|
|
104
|
-
textValue?: string;
|
|
105
|
-
/**
|
|
106
|
-
* The disabled state of the select item
|
|
107
|
-
*/
|
|
108
|
-
disabled?: boolean;
|
|
109
|
-
} & Omit<PressableProps, 'children' | 'onPress' | 'disabled'>;
|
|
110
|
-
|
|
111
|
-
export type SelectItemTextProps = {
|
|
112
|
-
/**
|
|
113
|
-
* The children of the select item text
|
|
114
|
-
* @required
|
|
115
|
-
*/
|
|
116
|
-
children: ReactNode;
|
|
117
|
-
} & StyledTextProps;
|
|
118
|
-
|
|
119
|
-
export type SelectSeparatorProps = {} & BoxProps;
|
|
120
|
-
|
|
121
|
-
export type SelectItemData = {
|
|
122
|
-
type: 'item';
|
|
123
|
-
value: string;
|
|
124
|
-
label: string;
|
|
125
|
-
disabled?: boolean;
|
|
126
|
-
};
|
|
127
|
-
|
|
128
|
-
export type SelectGroupData = {
|
|
129
|
-
type: 'group-label';
|
|
130
|
-
label: string;
|
|
131
|
-
};
|
|
132
|
-
|
|
133
|
-
export type SelectSeparatorData = {
|
|
134
|
-
type: 'separator';
|
|
135
|
-
};
|
|
136
|
-
|
|
137
|
-
export type SelectContentItem =
|
|
138
|
-
| SelectItemData
|
|
139
|
-
| SelectGroupData
|
|
140
|
-
| SelectSeparatorData;
|
|
141
|
-
|
|
142
|
-
export type SelectData = {
|
|
143
|
-
id: string;
|
|
144
|
-
items: SelectContentItem[];
|
|
145
|
-
selectedValue: string | undefined;
|
|
146
|
-
onSelectValue: (value: string) => void;
|
|
147
|
-
setOpen?: (open: boolean) => void;
|
|
148
|
-
label?: string;
|
|
149
|
-
};
|