@webority-technologies/mobile 0.0.10 → 0.0.12
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/lib/commonjs/components/SearchBar/SearchBar.js +6 -1
- package/lib/commonjs/components/Select/Select.js +41 -21
- package/lib/module/components/SearchBar/SearchBar.js +6 -1
- package/lib/module/components/Select/Select.js +41 -21
- package/lib/typescript/commonjs/components/SearchBar/SearchBar.d.ts +2 -1
- package/lib/typescript/commonjs/components/Select/Select.d.ts +23 -6
- package/lib/typescript/module/components/SearchBar/SearchBar.d.ts +2 -1
- package/lib/typescript/module/components/Select/Select.d.ts +23 -6
- package/package.json +1 -1
|
@@ -38,7 +38,7 @@ const sizeMap = {
|
|
|
38
38
|
const CANCEL_WIDTH = 72;
|
|
39
39
|
const SearchBar = exports.SearchBar = /*#__PURE__*/(0, _react.forwardRef)((props, ref) => {
|
|
40
40
|
const {
|
|
41
|
-
value,
|
|
41
|
+
value: rawValue,
|
|
42
42
|
onChangeText,
|
|
43
43
|
onSubmit,
|
|
44
44
|
placeholder = 'Search…',
|
|
@@ -64,6 +64,11 @@ const SearchBar = exports.SearchBar = /*#__PURE__*/(0, _react.forwardRef)((props
|
|
|
64
64
|
};
|
|
65
65
|
const cancelWidth = theme.components.searchBar?.cancelButtonWidth ?? CANCEL_WIDTH;
|
|
66
66
|
const styles = (0, _react.useMemo)(() => buildStyles(theme), [theme]);
|
|
67
|
+
|
|
68
|
+
// Coerce nullable inputs to '' once at the top so every downstream read is
|
|
69
|
+
// a guaranteed string. Required when consumers pass `value={state}` where
|
|
70
|
+
// `state` may be `undefined` / `null` before being initialised.
|
|
71
|
+
const value = typeof rawValue === 'string' ? rawValue : '';
|
|
67
72
|
const [isFocused, setIsFocused] = (0, _react.useState)(false);
|
|
68
73
|
const [internalValue, setInternalValue] = (0, _react.useState)(value);
|
|
69
74
|
const debouncedValue = (0, _useDebounce.useDebounce)(internalValue, debounceMs ?? 0);
|
|
@@ -44,9 +44,17 @@ const sizeMap = {
|
|
|
44
44
|
iconSize: 20
|
|
45
45
|
}
|
|
46
46
|
};
|
|
47
|
+
|
|
48
|
+
// `unknown` here keeps the forwardRef signature non-generic — consumers who
|
|
49
|
+
// pass non-`SelectOption` shapes use the accessor props; type inference is
|
|
50
|
+
// preserved at the call site via the `SelectProps<T>` union.
|
|
47
51
|
const Select = exports.Select = /*#__PURE__*/(0, _react.forwardRef)((props, ref) => {
|
|
48
52
|
const {
|
|
49
53
|
options,
|
|
54
|
+
getOptionLabel,
|
|
55
|
+
getOptionValue,
|
|
56
|
+
getOptionDisabled,
|
|
57
|
+
getOptionDescription,
|
|
50
58
|
placeholder,
|
|
51
59
|
searchable = false,
|
|
52
60
|
label,
|
|
@@ -60,6 +68,13 @@ const Select = exports.Select = /*#__PURE__*/(0, _react.forwardRef)((props, ref)
|
|
|
60
68
|
testID
|
|
61
69
|
} = props;
|
|
62
70
|
const multi = props.multi === true;
|
|
71
|
+
|
|
72
|
+
// Accessors — fall back to SelectOption-shaped reads when unset so the
|
|
73
|
+
// default/typed call site keeps zero boilerplate.
|
|
74
|
+
const labelOf = (0, _react.useCallback)(o => getOptionLabel ? getOptionLabel(o) : o.label ?? '', [getOptionLabel]);
|
|
75
|
+
const valueOf = (0, _react.useCallback)(o => getOptionValue ? getOptionValue(o) : o.value, [getOptionValue]);
|
|
76
|
+
const disabledOf = (0, _react.useCallback)(o => getOptionDisabled ? getOptionDisabled(o) : o.disabled === true, [getOptionDisabled]);
|
|
77
|
+
const descriptionOf = (0, _react.useCallback)(o => getOptionDescription ? getOptionDescription(o) : o.description, [getOptionDescription]);
|
|
63
78
|
const theme = (0, _index.useTheme)();
|
|
64
79
|
const styles = (0, _react.useMemo)(() => buildStyles(theme), [theme]);
|
|
65
80
|
const sizeStyles = sizeMap[size];
|
|
@@ -111,18 +126,18 @@ const Select = exports.Select = /*#__PURE__*/(0, _react.forwardRef)((props, ref)
|
|
|
111
126
|
const selectedOptions = (0, _react.useMemo)(() => {
|
|
112
127
|
if (multi) {
|
|
113
128
|
const arr = props.value ?? [];
|
|
114
|
-
return options.filter(o => arr.includes(o
|
|
129
|
+
return options.filter(o => arr.includes(valueOf(o)));
|
|
115
130
|
}
|
|
116
131
|
const v = props.value;
|
|
117
132
|
if (v === undefined || v === null) return [];
|
|
118
|
-
const found = options.find(o => o
|
|
133
|
+
const found = options.find(o => valueOf(o) === v);
|
|
119
134
|
return found ? [found] : [];
|
|
120
|
-
}, [multi, options, props.value]);
|
|
135
|
+
}, [multi, options, props.value, valueOf]);
|
|
121
136
|
const filteredOptions = (0, _react.useMemo)(() => {
|
|
122
|
-
if (!searchable || query.trim().length === 0) return options;
|
|
137
|
+
if (!searchable || query.trim().length === 0) return [...options];
|
|
123
138
|
const q = query.trim().toLowerCase();
|
|
124
|
-
return options.filter(o => o.
|
|
125
|
-
}, [searchable, query, options]);
|
|
139
|
+
return options.filter(o => labelOf(o).toLowerCase().includes(q) || (descriptionOf(o) ?? '').toLowerCase().includes(q));
|
|
140
|
+
}, [searchable, query, options, labelOf, descriptionOf]);
|
|
126
141
|
const handleOpen = (0, _react.useCallback)(() => {
|
|
127
142
|
if (disabled) return;
|
|
128
143
|
(0, _index2.triggerHaptic)('selection');
|
|
@@ -133,30 +148,35 @@ const Select = exports.Select = /*#__PURE__*/(0, _react.forwardRef)((props, ref)
|
|
|
133
148
|
setQuery('');
|
|
134
149
|
}, []);
|
|
135
150
|
const handleSelect = (0, _react.useCallback)(option => {
|
|
136
|
-
if (option
|
|
151
|
+
if (disabledOf(option)) return;
|
|
152
|
+
const optValue = valueOf(option);
|
|
137
153
|
(0, _index2.triggerHaptic)('selection');
|
|
138
154
|
if (multi) {
|
|
139
155
|
const current = props.value ?? [];
|
|
140
|
-
const next = current.includes(
|
|
156
|
+
const next = current.includes(optValue) ? current.filter(v => v !== optValue) : [...current, optValue];
|
|
141
157
|
props.onChange(next);
|
|
142
158
|
return;
|
|
143
159
|
}
|
|
144
|
-
props.onChange(
|
|
160
|
+
props.onChange(optValue);
|
|
145
161
|
handleClose();
|
|
146
|
-
}, [multi, props, handleClose]);
|
|
162
|
+
}, [multi, props, handleClose, disabledOf, valueOf]);
|
|
147
163
|
|
|
148
164
|
// Trigger label / placeholder text.
|
|
149
|
-
const triggerText = selectedOptions.length === 0 ? placeholder ?? 'Select…' : selectedOptions.map(o => o
|
|
165
|
+
const triggerText = selectedOptions.length === 0 ? placeholder ?? 'Select…' : selectedOptions.map(o => labelOf(o)).join(', ');
|
|
150
166
|
const showingPlaceholder = selectedOptions.length === 0;
|
|
151
167
|
const hasError = typeof error === 'string' && error.length > 0;
|
|
152
168
|
const borderColor = hasError ? theme.colors.border.error : theme.colors.border.primary;
|
|
153
|
-
const a11ySummary = selectedOptions.length === 0 ? placeholder ?? 'No selection' : `Selected: ${selectedOptions.map(o => o
|
|
169
|
+
const a11ySummary = selectedOptions.length === 0 ? placeholder ?? 'No selection' : `Selected: ${selectedOptions.map(o => labelOf(o)).join(', ')}`;
|
|
154
170
|
const a11yLabel = accessibilityLabel ?? `${label ?? 'Select'}. ${a11ySummary}`;
|
|
155
171
|
const renderOption = ({
|
|
156
172
|
item
|
|
157
173
|
}) => {
|
|
158
|
-
const
|
|
159
|
-
const
|
|
174
|
+
const itemLabel = labelOf(item);
|
|
175
|
+
const itemValue = valueOf(item);
|
|
176
|
+
const itemDescription = descriptionOf(item);
|
|
177
|
+
const itemIcon = props.getOptionIcon ? props.getOptionIcon(item) : item.icon;
|
|
178
|
+
const selected = isSelected(itemValue);
|
|
179
|
+
const optDisabled = disabledOf(item);
|
|
160
180
|
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Pressable, {
|
|
161
181
|
onPress: () => handleSelect(item),
|
|
162
182
|
disabled: optDisabled,
|
|
@@ -165,7 +185,7 @@ const Select = exports.Select = /*#__PURE__*/(0, _react.forwardRef)((props, ref)
|
|
|
165
185
|
borderless: false
|
|
166
186
|
},
|
|
167
187
|
accessibilityRole: "button",
|
|
168
|
-
accessibilityLabel:
|
|
188
|
+
accessibilityLabel: itemLabel,
|
|
169
189
|
accessibilityState: {
|
|
170
190
|
selected,
|
|
171
191
|
disabled: optDisabled
|
|
@@ -178,9 +198,9 @@ const Select = exports.Select = /*#__PURE__*/(0, _react.forwardRef)((props, ref)
|
|
|
178
198
|
paddingHorizontal: theme.spacing.lg,
|
|
179
199
|
paddingVertical: theme.spacing.md
|
|
180
200
|
}],
|
|
181
|
-
children: [
|
|
201
|
+
children: [itemIcon ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
182
202
|
style: styles.optionIcon,
|
|
183
|
-
children:
|
|
203
|
+
children: itemIcon
|
|
184
204
|
}) : null, /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
185
205
|
style: styles.optionTextWrap,
|
|
186
206
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
@@ -190,14 +210,14 @@ const Select = exports.Select = /*#__PURE__*/(0, _react.forwardRef)((props, ref)
|
|
|
190
210
|
fontWeight: selected ? theme.typography.fontWeight.semibold : theme.typography.fontWeight.medium
|
|
191
211
|
}],
|
|
192
212
|
numberOfLines: 1,
|
|
193
|
-
children:
|
|
194
|
-
}),
|
|
213
|
+
children: itemLabel
|
|
214
|
+
}), itemDescription ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
195
215
|
style: [styles.optionDescription, {
|
|
196
216
|
color: theme.colors.text.tertiary,
|
|
197
217
|
fontSize: theme.typography.fontSize.sm
|
|
198
218
|
}],
|
|
199
219
|
numberOfLines: 2,
|
|
200
|
-
children:
|
|
220
|
+
children: itemDescription
|
|
201
221
|
}) : null]
|
|
202
222
|
}), multi ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
203
223
|
style: [styles.checkbox, {
|
|
@@ -344,7 +364,7 @@ const Select = exports.Select = /*#__PURE__*/(0, _react.forwardRef)((props, ref)
|
|
|
344
364
|
})
|
|
345
365
|
}) : null, /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.FlatList, {
|
|
346
366
|
data: filteredOptions,
|
|
347
|
-
keyExtractor: item => String(item
|
|
367
|
+
keyExtractor: item => String(valueOf(item)),
|
|
348
368
|
renderItem: renderOption,
|
|
349
369
|
keyboardShouldPersistTaps: "handled",
|
|
350
370
|
showsVerticalScrollIndicator: true,
|
|
@@ -33,7 +33,7 @@ const sizeMap = {
|
|
|
33
33
|
const CANCEL_WIDTH = 72;
|
|
34
34
|
const SearchBar = /*#__PURE__*/forwardRef((props, ref) => {
|
|
35
35
|
const {
|
|
36
|
-
value,
|
|
36
|
+
value: rawValue,
|
|
37
37
|
onChangeText,
|
|
38
38
|
onSubmit,
|
|
39
39
|
placeholder = 'Search…',
|
|
@@ -59,6 +59,11 @@ const SearchBar = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
59
59
|
};
|
|
60
60
|
const cancelWidth = theme.components.searchBar?.cancelButtonWidth ?? CANCEL_WIDTH;
|
|
61
61
|
const styles = useMemo(() => buildStyles(theme), [theme]);
|
|
62
|
+
|
|
63
|
+
// Coerce nullable inputs to '' once at the top so every downstream read is
|
|
64
|
+
// a guaranteed string. Required when consumers pass `value={state}` where
|
|
65
|
+
// `state` may be `undefined` / `null` before being initialised.
|
|
66
|
+
const value = typeof rawValue === 'string' ? rawValue : '';
|
|
62
67
|
const [isFocused, setIsFocused] = useState(false);
|
|
63
68
|
const [internalValue, setInternalValue] = useState(value);
|
|
64
69
|
const debouncedValue = useDebounce(internalValue, debounceMs ?? 0);
|
|
@@ -39,9 +39,17 @@ const sizeMap = {
|
|
|
39
39
|
iconSize: 20
|
|
40
40
|
}
|
|
41
41
|
};
|
|
42
|
+
|
|
43
|
+
// `unknown` here keeps the forwardRef signature non-generic — consumers who
|
|
44
|
+
// pass non-`SelectOption` shapes use the accessor props; type inference is
|
|
45
|
+
// preserved at the call site via the `SelectProps<T>` union.
|
|
42
46
|
const Select = /*#__PURE__*/forwardRef((props, ref) => {
|
|
43
47
|
const {
|
|
44
48
|
options,
|
|
49
|
+
getOptionLabel,
|
|
50
|
+
getOptionValue,
|
|
51
|
+
getOptionDisabled,
|
|
52
|
+
getOptionDescription,
|
|
45
53
|
placeholder,
|
|
46
54
|
searchable = false,
|
|
47
55
|
label,
|
|
@@ -55,6 +63,13 @@ const Select = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
55
63
|
testID
|
|
56
64
|
} = props;
|
|
57
65
|
const multi = props.multi === true;
|
|
66
|
+
|
|
67
|
+
// Accessors — fall back to SelectOption-shaped reads when unset so the
|
|
68
|
+
// default/typed call site keeps zero boilerplate.
|
|
69
|
+
const labelOf = useCallback(o => getOptionLabel ? getOptionLabel(o) : o.label ?? '', [getOptionLabel]);
|
|
70
|
+
const valueOf = useCallback(o => getOptionValue ? getOptionValue(o) : o.value, [getOptionValue]);
|
|
71
|
+
const disabledOf = useCallback(o => getOptionDisabled ? getOptionDisabled(o) : o.disabled === true, [getOptionDisabled]);
|
|
72
|
+
const descriptionOf = useCallback(o => getOptionDescription ? getOptionDescription(o) : o.description, [getOptionDescription]);
|
|
58
73
|
const theme = useTheme();
|
|
59
74
|
const styles = useMemo(() => buildStyles(theme), [theme]);
|
|
60
75
|
const sizeStyles = sizeMap[size];
|
|
@@ -106,18 +121,18 @@ const Select = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
106
121
|
const selectedOptions = useMemo(() => {
|
|
107
122
|
if (multi) {
|
|
108
123
|
const arr = props.value ?? [];
|
|
109
|
-
return options.filter(o => arr.includes(o
|
|
124
|
+
return options.filter(o => arr.includes(valueOf(o)));
|
|
110
125
|
}
|
|
111
126
|
const v = props.value;
|
|
112
127
|
if (v === undefined || v === null) return [];
|
|
113
|
-
const found = options.find(o => o
|
|
128
|
+
const found = options.find(o => valueOf(o) === v);
|
|
114
129
|
return found ? [found] : [];
|
|
115
|
-
}, [multi, options, props.value]);
|
|
130
|
+
}, [multi, options, props.value, valueOf]);
|
|
116
131
|
const filteredOptions = useMemo(() => {
|
|
117
|
-
if (!searchable || query.trim().length === 0) return options;
|
|
132
|
+
if (!searchable || query.trim().length === 0) return [...options];
|
|
118
133
|
const q = query.trim().toLowerCase();
|
|
119
|
-
return options.filter(o => o.
|
|
120
|
-
}, [searchable, query, options]);
|
|
134
|
+
return options.filter(o => labelOf(o).toLowerCase().includes(q) || (descriptionOf(o) ?? '').toLowerCase().includes(q));
|
|
135
|
+
}, [searchable, query, options, labelOf, descriptionOf]);
|
|
121
136
|
const handleOpen = useCallback(() => {
|
|
122
137
|
if (disabled) return;
|
|
123
138
|
triggerHaptic('selection');
|
|
@@ -128,30 +143,35 @@ const Select = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
128
143
|
setQuery('');
|
|
129
144
|
}, []);
|
|
130
145
|
const handleSelect = useCallback(option => {
|
|
131
|
-
if (option
|
|
146
|
+
if (disabledOf(option)) return;
|
|
147
|
+
const optValue = valueOf(option);
|
|
132
148
|
triggerHaptic('selection');
|
|
133
149
|
if (multi) {
|
|
134
150
|
const current = props.value ?? [];
|
|
135
|
-
const next = current.includes(
|
|
151
|
+
const next = current.includes(optValue) ? current.filter(v => v !== optValue) : [...current, optValue];
|
|
136
152
|
props.onChange(next);
|
|
137
153
|
return;
|
|
138
154
|
}
|
|
139
|
-
props.onChange(
|
|
155
|
+
props.onChange(optValue);
|
|
140
156
|
handleClose();
|
|
141
|
-
}, [multi, props, handleClose]);
|
|
157
|
+
}, [multi, props, handleClose, disabledOf, valueOf]);
|
|
142
158
|
|
|
143
159
|
// Trigger label / placeholder text.
|
|
144
|
-
const triggerText = selectedOptions.length === 0 ? placeholder ?? 'Select…' : selectedOptions.map(o => o
|
|
160
|
+
const triggerText = selectedOptions.length === 0 ? placeholder ?? 'Select…' : selectedOptions.map(o => labelOf(o)).join(', ');
|
|
145
161
|
const showingPlaceholder = selectedOptions.length === 0;
|
|
146
162
|
const hasError = typeof error === 'string' && error.length > 0;
|
|
147
163
|
const borderColor = hasError ? theme.colors.border.error : theme.colors.border.primary;
|
|
148
|
-
const a11ySummary = selectedOptions.length === 0 ? placeholder ?? 'No selection' : `Selected: ${selectedOptions.map(o => o
|
|
164
|
+
const a11ySummary = selectedOptions.length === 0 ? placeholder ?? 'No selection' : `Selected: ${selectedOptions.map(o => labelOf(o)).join(', ')}`;
|
|
149
165
|
const a11yLabel = accessibilityLabel ?? `${label ?? 'Select'}. ${a11ySummary}`;
|
|
150
166
|
const renderOption = ({
|
|
151
167
|
item
|
|
152
168
|
}) => {
|
|
153
|
-
const
|
|
154
|
-
const
|
|
169
|
+
const itemLabel = labelOf(item);
|
|
170
|
+
const itemValue = valueOf(item);
|
|
171
|
+
const itemDescription = descriptionOf(item);
|
|
172
|
+
const itemIcon = props.getOptionIcon ? props.getOptionIcon(item) : item.icon;
|
|
173
|
+
const selected = isSelected(itemValue);
|
|
174
|
+
const optDisabled = disabledOf(item);
|
|
155
175
|
return /*#__PURE__*/_jsxs(Pressable, {
|
|
156
176
|
onPress: () => handleSelect(item),
|
|
157
177
|
disabled: optDisabled,
|
|
@@ -160,7 +180,7 @@ const Select = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
160
180
|
borderless: false
|
|
161
181
|
},
|
|
162
182
|
accessibilityRole: "button",
|
|
163
|
-
accessibilityLabel:
|
|
183
|
+
accessibilityLabel: itemLabel,
|
|
164
184
|
accessibilityState: {
|
|
165
185
|
selected,
|
|
166
186
|
disabled: optDisabled
|
|
@@ -173,9 +193,9 @@ const Select = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
173
193
|
paddingHorizontal: theme.spacing.lg,
|
|
174
194
|
paddingVertical: theme.spacing.md
|
|
175
195
|
}],
|
|
176
|
-
children: [
|
|
196
|
+
children: [itemIcon ? /*#__PURE__*/_jsx(View, {
|
|
177
197
|
style: styles.optionIcon,
|
|
178
|
-
children:
|
|
198
|
+
children: itemIcon
|
|
179
199
|
}) : null, /*#__PURE__*/_jsxs(View, {
|
|
180
200
|
style: styles.optionTextWrap,
|
|
181
201
|
children: [/*#__PURE__*/_jsx(Text, {
|
|
@@ -185,14 +205,14 @@ const Select = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
185
205
|
fontWeight: selected ? theme.typography.fontWeight.semibold : theme.typography.fontWeight.medium
|
|
186
206
|
}],
|
|
187
207
|
numberOfLines: 1,
|
|
188
|
-
children:
|
|
189
|
-
}),
|
|
208
|
+
children: itemLabel
|
|
209
|
+
}), itemDescription ? /*#__PURE__*/_jsx(Text, {
|
|
190
210
|
style: [styles.optionDescription, {
|
|
191
211
|
color: theme.colors.text.tertiary,
|
|
192
212
|
fontSize: theme.typography.fontSize.sm
|
|
193
213
|
}],
|
|
194
214
|
numberOfLines: 2,
|
|
195
|
-
children:
|
|
215
|
+
children: itemDescription
|
|
196
216
|
}) : null]
|
|
197
217
|
}), multi ? /*#__PURE__*/_jsx(View, {
|
|
198
218
|
style: [styles.checkbox, {
|
|
@@ -339,7 +359,7 @@ const Select = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
339
359
|
})
|
|
340
360
|
}) : null, /*#__PURE__*/_jsx(FlatList, {
|
|
341
361
|
data: filteredOptions,
|
|
342
|
-
keyExtractor: item => String(item
|
|
362
|
+
keyExtractor: item => String(valueOf(item)),
|
|
343
363
|
renderItem: renderOption,
|
|
344
364
|
keyboardShouldPersistTaps: "handled",
|
|
345
365
|
showsVerticalScrollIndicator: true,
|
|
@@ -4,7 +4,8 @@ import type { StyleProp, TextInputProps, ViewStyle } from 'react-native';
|
|
|
4
4
|
export type SearchBarSize = 'sm' | 'md' | 'lg';
|
|
5
5
|
export type SearchBarVariant = 'filled' | 'outlined';
|
|
6
6
|
export interface SearchBarProps extends Omit<TextInputProps, 'style' | 'value' | 'onChangeText'> {
|
|
7
|
-
value
|
|
7
|
+
/** Current value. Optional / nullable — treated as empty string when undefined or null. */
|
|
8
|
+
value?: string | null;
|
|
8
9
|
onChangeText: (text: string) => void;
|
|
9
10
|
onSubmit?: (text: string) => void;
|
|
10
11
|
placeholder?: string;
|
|
@@ -17,8 +17,25 @@ export interface SelectOption {
|
|
|
17
17
|
disabled?: boolean;
|
|
18
18
|
icon?: React.ReactNode;
|
|
19
19
|
}
|
|
20
|
-
interface BaseSelectProps {
|
|
21
|
-
|
|
20
|
+
interface BaseSelectProps<T = SelectOption> {
|
|
21
|
+
/**
|
|
22
|
+
* Options to render. Default shape is `SelectOption` (`{ label, value, ... }`)
|
|
23
|
+
* — for that shape no accessors are needed. To use a different option shape
|
|
24
|
+
* (e.g. `{ id, name }` from a domain model), pass `getOptionLabel` /
|
|
25
|
+
* `getOptionValue` (and optionally `getOptionDisabled`/`getOptionDescription`/
|
|
26
|
+
* `getOptionIcon`) so Select can read it without per-call-site mapping.
|
|
27
|
+
*/
|
|
28
|
+
options: ReadonlyArray<T>;
|
|
29
|
+
/** Defaults to `(o) => (o as SelectOption).label`. */
|
|
30
|
+
getOptionLabel?: (option: T) => string;
|
|
31
|
+
/** Defaults to `(o) => (o as SelectOption).value`. */
|
|
32
|
+
getOptionValue?: (option: T) => SelectValue;
|
|
33
|
+
/** Defaults to `(o) => (o as SelectOption).disabled === true`. */
|
|
34
|
+
getOptionDisabled?: (option: T) => boolean;
|
|
35
|
+
/** Defaults to `(o) => (o as SelectOption).description`. */
|
|
36
|
+
getOptionDescription?: (option: T) => string | undefined;
|
|
37
|
+
/** Defaults to `(o) => (o as SelectOption).icon`. */
|
|
38
|
+
getOptionIcon?: (option: T) => React.ReactNode;
|
|
22
39
|
placeholder?: string;
|
|
23
40
|
searchable?: boolean;
|
|
24
41
|
label?: string;
|
|
@@ -31,18 +48,18 @@ interface BaseSelectProps {
|
|
|
31
48
|
textStyle?: StyleProp<TextStyle>;
|
|
32
49
|
testID?: string;
|
|
33
50
|
}
|
|
34
|
-
interface SingleSelectProps extends BaseSelectProps {
|
|
51
|
+
interface SingleSelectProps<T = SelectOption> extends BaseSelectProps<T> {
|
|
35
52
|
multi?: false;
|
|
36
53
|
value?: SelectValue;
|
|
37
54
|
onChange: (value: SelectValue) => void;
|
|
38
55
|
}
|
|
39
|
-
interface MultiSelectProps extends BaseSelectProps {
|
|
56
|
+
interface MultiSelectProps<T = SelectOption> extends BaseSelectProps<T> {
|
|
40
57
|
multi: true;
|
|
41
58
|
value?: SelectValue[];
|
|
42
59
|
onChange: (value: SelectValue[]) => void;
|
|
43
60
|
}
|
|
44
|
-
export type SelectProps = SingleSelectProps | MultiSelectProps
|
|
45
|
-
declare const Select: React.ForwardRefExoticComponent<SelectProps & React.RefAttributes<View>>;
|
|
61
|
+
export type SelectProps<T = SelectOption> = SingleSelectProps<T> | MultiSelectProps<T>;
|
|
62
|
+
declare const Select: React.ForwardRefExoticComponent<SelectProps<unknown> & React.RefAttributes<View>>;
|
|
46
63
|
export { Select };
|
|
47
64
|
export default Select;
|
|
48
65
|
//# sourceMappingURL=Select.d.ts.map
|
|
@@ -4,7 +4,8 @@ import type { StyleProp, TextInputProps, ViewStyle } from 'react-native';
|
|
|
4
4
|
export type SearchBarSize = 'sm' | 'md' | 'lg';
|
|
5
5
|
export type SearchBarVariant = 'filled' | 'outlined';
|
|
6
6
|
export interface SearchBarProps extends Omit<TextInputProps, 'style' | 'value' | 'onChangeText'> {
|
|
7
|
-
value
|
|
7
|
+
/** Current value. Optional / nullable — treated as empty string when undefined or null. */
|
|
8
|
+
value?: string | null;
|
|
8
9
|
onChangeText: (text: string) => void;
|
|
9
10
|
onSubmit?: (text: string) => void;
|
|
10
11
|
placeholder?: string;
|
|
@@ -17,8 +17,25 @@ export interface SelectOption {
|
|
|
17
17
|
disabled?: boolean;
|
|
18
18
|
icon?: React.ReactNode;
|
|
19
19
|
}
|
|
20
|
-
interface BaseSelectProps {
|
|
21
|
-
|
|
20
|
+
interface BaseSelectProps<T = SelectOption> {
|
|
21
|
+
/**
|
|
22
|
+
* Options to render. Default shape is `SelectOption` (`{ label, value, ... }`)
|
|
23
|
+
* — for that shape no accessors are needed. To use a different option shape
|
|
24
|
+
* (e.g. `{ id, name }` from a domain model), pass `getOptionLabel` /
|
|
25
|
+
* `getOptionValue` (and optionally `getOptionDisabled`/`getOptionDescription`/
|
|
26
|
+
* `getOptionIcon`) so Select can read it without per-call-site mapping.
|
|
27
|
+
*/
|
|
28
|
+
options: ReadonlyArray<T>;
|
|
29
|
+
/** Defaults to `(o) => (o as SelectOption).label`. */
|
|
30
|
+
getOptionLabel?: (option: T) => string;
|
|
31
|
+
/** Defaults to `(o) => (o as SelectOption).value`. */
|
|
32
|
+
getOptionValue?: (option: T) => SelectValue;
|
|
33
|
+
/** Defaults to `(o) => (o as SelectOption).disabled === true`. */
|
|
34
|
+
getOptionDisabled?: (option: T) => boolean;
|
|
35
|
+
/** Defaults to `(o) => (o as SelectOption).description`. */
|
|
36
|
+
getOptionDescription?: (option: T) => string | undefined;
|
|
37
|
+
/** Defaults to `(o) => (o as SelectOption).icon`. */
|
|
38
|
+
getOptionIcon?: (option: T) => React.ReactNode;
|
|
22
39
|
placeholder?: string;
|
|
23
40
|
searchable?: boolean;
|
|
24
41
|
label?: string;
|
|
@@ -31,18 +48,18 @@ interface BaseSelectProps {
|
|
|
31
48
|
textStyle?: StyleProp<TextStyle>;
|
|
32
49
|
testID?: string;
|
|
33
50
|
}
|
|
34
|
-
interface SingleSelectProps extends BaseSelectProps {
|
|
51
|
+
interface SingleSelectProps<T = SelectOption> extends BaseSelectProps<T> {
|
|
35
52
|
multi?: false;
|
|
36
53
|
value?: SelectValue;
|
|
37
54
|
onChange: (value: SelectValue) => void;
|
|
38
55
|
}
|
|
39
|
-
interface MultiSelectProps extends BaseSelectProps {
|
|
56
|
+
interface MultiSelectProps<T = SelectOption> extends BaseSelectProps<T> {
|
|
40
57
|
multi: true;
|
|
41
58
|
value?: SelectValue[];
|
|
42
59
|
onChange: (value: SelectValue[]) => void;
|
|
43
60
|
}
|
|
44
|
-
export type SelectProps = SingleSelectProps | MultiSelectProps
|
|
45
|
-
declare const Select: React.ForwardRefExoticComponent<SelectProps & React.RefAttributes<View>>;
|
|
61
|
+
export type SelectProps<T = SelectOption> = SingleSelectProps<T> | MultiSelectProps<T>;
|
|
62
|
+
declare const Select: React.ForwardRefExoticComponent<SelectProps<unknown> & React.RefAttributes<View>>;
|
|
46
63
|
export { Select };
|
|
47
64
|
export default Select;
|
|
48
65
|
//# sourceMappingURL=Select.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webority-technologies/mobile",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.12",
|
|
4
4
|
"description": "Beautiful, animated, accessible React Native components plus API/auth/logging/network/storage utilities for Webority projects.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react-native",
|