@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.
@@ -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.value));
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.value === v);
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.label.toLowerCase().includes(q) || (o.description ?? '').toLowerCase().includes(q));
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.disabled) return;
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(option.value) ? current.filter(v => v !== option.value) : [...current, option.value];
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(option.value);
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.label).join(', ');
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.label).join(', ')}`;
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 selected = isSelected(item.value);
159
- const optDisabled = item.disabled === true;
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: item.label,
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: [item.icon ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
201
+ children: [itemIcon ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
182
202
  style: styles.optionIcon,
183
- children: item.icon
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: item.label
194
- }), item.description ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
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: item.description
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.value),
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.value));
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.value === v);
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.label.toLowerCase().includes(q) || (o.description ?? '').toLowerCase().includes(q));
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.disabled) return;
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(option.value) ? current.filter(v => v !== option.value) : [...current, option.value];
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(option.value);
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.label).join(', ');
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.label).join(', ')}`;
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 selected = isSelected(item.value);
154
- const optDisabled = item.disabled === true;
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: item.label,
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: [item.icon ? /*#__PURE__*/_jsx(View, {
196
+ children: [itemIcon ? /*#__PURE__*/_jsx(View, {
177
197
  style: styles.optionIcon,
178
- children: item.icon
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: item.label
189
- }), item.description ? /*#__PURE__*/_jsx(Text, {
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: item.description
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.value),
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: string;
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
- options: SelectOption[];
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: string;
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
- options: SelectOption[];
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.10",
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",