react-native-platform-components 0.8.10 → 0.9.0
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/README.md +126 -30
- package/android/src/main/java/com/platformcomponents/PCImageLoader.kt +88 -0
- package/android/src/main/java/com/platformcomponents/PCSegmentedControlView.kt +288 -29
- package/android/src/main/java/com/platformcomponents/PCSegmentedControlViewManager.kt +74 -8
- package/ios/PCImageLoader.swift +58 -0
- package/ios/PCSegmentedControl.mm +85 -25
- package/ios/PCSegmentedControl.swift +231 -308
- package/lib/commonjs/DatePickerNativeComponent.ts +4 -2
- package/lib/commonjs/SegmentedControl.js +138 -6
- package/lib/commonjs/SegmentedControl.js.map +1 -1
- package/lib/commonjs/SegmentedControlNativeComponent.ts +62 -8
- package/lib/commonjs/SelectionMenuNativeComponent.ts +4 -2
- package/lib/commonjs/index.web.js.map +1 -1
- package/lib/module/DatePickerNativeComponent.ts +4 -2
- package/lib/module/SegmentedControl.js +138 -7
- package/lib/module/SegmentedControl.js.map +1 -1
- package/lib/module/SegmentedControlNativeComponent.ts +62 -8
- package/lib/module/SelectionMenuNativeComponent.ts +4 -2
- package/lib/module/index.web.js.map +1 -1
- package/lib/typescript/commonjs/src/DatePickerNativeComponent.d.ts +2 -2
- package/lib/typescript/commonjs/src/DatePickerNativeComponent.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/SegmentedControl.d.ts +111 -6
- package/lib/typescript/commonjs/src/SegmentedControl.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/SegmentedControlNativeComponent.d.ts +46 -7
- package/lib/typescript/commonjs/src/SegmentedControlNativeComponent.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/SelectionMenuNativeComponent.d.ts +2 -2
- package/lib/typescript/commonjs/src/SelectionMenuNativeComponent.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/index.web.d.ts +36 -1
- package/lib/typescript/commonjs/src/index.web.d.ts.map +1 -1
- package/lib/typescript/module/src/DatePicker.d.ts +1 -1
- package/lib/typescript/module/src/DatePicker.d.ts.map +1 -1
- package/lib/typescript/module/src/DatePickerNativeComponent.d.ts +2 -2
- package/lib/typescript/module/src/DatePickerNativeComponent.d.ts.map +1 -1
- package/lib/typescript/module/src/SegmentedControl.d.ts +111 -6
- package/lib/typescript/module/src/SegmentedControl.d.ts.map +1 -1
- package/lib/typescript/module/src/SegmentedControlNativeComponent.d.ts +46 -7
- package/lib/typescript/module/src/SegmentedControlNativeComponent.d.ts.map +1 -1
- package/lib/typescript/module/src/SelectionMenu.d.ts +1 -1
- package/lib/typescript/module/src/SelectionMenu.d.ts.map +1 -1
- package/lib/typescript/module/src/SelectionMenuNativeComponent.d.ts +2 -2
- package/lib/typescript/module/src/SelectionMenuNativeComponent.d.ts.map +1 -1
- package/lib/typescript/module/src/index.d.ts +6 -6
- package/lib/typescript/module/src/index.d.ts.map +1 -1
- package/lib/typescript/module/src/index.web.d.ts +36 -1
- package/lib/typescript/module/src/index.web.d.ts.map +1 -1
- package/package.json +29 -25
- package/plugin/tsconfig.json +2 -2
- package/src/DatePickerNativeComponent.ts +4 -2
- package/src/SegmentedControl.tsx +238 -11
- package/src/SegmentedControlNativeComponent.ts +62 -8
- package/src/SelectionMenuNativeComponent.ts +4 -2
- package/src/index.web.tsx +34 -1
package/src/SegmentedControl.tsx
CHANGED
|
@@ -1,14 +1,20 @@
|
|
|
1
1
|
// SegmentedControl.tsx
|
|
2
2
|
import React, { useCallback, useMemo } from 'react';
|
|
3
3
|
import {
|
|
4
|
+
Image,
|
|
4
5
|
Platform,
|
|
5
6
|
StyleSheet,
|
|
7
|
+
type ColorValue,
|
|
8
|
+
type ImageRequireSource,
|
|
9
|
+
type ImageURISource,
|
|
6
10
|
type StyleProp,
|
|
11
|
+
type TextStyle,
|
|
7
12
|
type ViewProps,
|
|
8
13
|
type ViewStyle,
|
|
9
14
|
} from 'react-native';
|
|
10
15
|
|
|
11
16
|
import NativeSegmentedControl, {
|
|
17
|
+
type SegmentedControlSegment as NativeSegment,
|
|
12
18
|
type SegmentedControlSelectEvent,
|
|
13
19
|
} from './SegmentedControlNativeComponent';
|
|
14
20
|
|
|
@@ -17,6 +23,68 @@ import NativeSegmentedControl, {
|
|
|
17
23
|
// so we apply a minHeight that matches Material design touch target guidelines.
|
|
18
24
|
const ANDROID_MIN_HEIGHT = 48;
|
|
19
25
|
|
|
26
|
+
/**
|
|
27
|
+
* A single icon source.
|
|
28
|
+
*
|
|
29
|
+
* - `string`: shorthand for an SF Symbol name on iOS and a drawable resource
|
|
30
|
+
* name on Android (the original API).
|
|
31
|
+
* - `{ type: 'sfSymbol' }`: an SF Symbol. iOS only; ignored on Android.
|
|
32
|
+
* - `{ type: 'drawable' }`: a drawable from the app's `res/drawable`.
|
|
33
|
+
* Android only; ignored on iOS.
|
|
34
|
+
* - `{ type: 'image' }`: an image asset (`require('./icon.png')`) or a
|
|
35
|
+
* `{ uri }` source. Works on both platforms. Images are drawn as tinted
|
|
36
|
+
* templates unless `tinted` is `false`.
|
|
37
|
+
*/
|
|
38
|
+
export type SegmentedControlIconSource =
|
|
39
|
+
| string
|
|
40
|
+
| { type: 'sfSymbol'; name: string }
|
|
41
|
+
| { type: 'drawable'; name: string }
|
|
42
|
+
| {
|
|
43
|
+
type: 'image';
|
|
44
|
+
source: ImageRequireSource | ImageURISource;
|
|
45
|
+
tinted?: boolean;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* An icon for a segment: a single source used on both platforms, or a
|
|
50
|
+
* per-platform pair so callers don't need to branch on `Platform.OS`.
|
|
51
|
+
*/
|
|
52
|
+
export type SegmentedControlIcon =
|
|
53
|
+
| SegmentedControlIconSource
|
|
54
|
+
| {
|
|
55
|
+
ios?: SegmentedControlIconSource;
|
|
56
|
+
android?: SegmentedControlIconSource;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* How labels and icons combine for segments that have an icon.
|
|
61
|
+
*
|
|
62
|
+
* - `auto` (default): platform behavior. iOS shows the icon in place of the
|
|
63
|
+
* label (UISegmentedControl cannot show both); Android shows icon and label.
|
|
64
|
+
* - `labeled`: always show the label. iOS drops the icon; Android shows both.
|
|
65
|
+
* - `unlabeled`: show only the icon. Segments without an icon still show
|
|
66
|
+
* their label. Screen readers still announce the label on both platforms.
|
|
67
|
+
*/
|
|
68
|
+
export type SegmentedControlLabelVisibility = 'auto' | 'labeled' | 'unlabeled';
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Font for segment labels. Each field falls back to the platform default.
|
|
72
|
+
*/
|
|
73
|
+
export interface SegmentedControlLabelStyle {
|
|
74
|
+
fontFamily?: string;
|
|
75
|
+
fontSize?: number;
|
|
76
|
+
fontWeight?: TextStyle['fontWeight'];
|
|
77
|
+
fontStyle?: 'normal' | 'italic';
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Badge colors. Both default to the platform look (red with white text).
|
|
82
|
+
*/
|
|
83
|
+
export interface SegmentedControlBadgeStyle {
|
|
84
|
+
backgroundColor?: ColorValue;
|
|
85
|
+
color?: ColorValue;
|
|
86
|
+
}
|
|
87
|
+
|
|
20
88
|
export interface SegmentedControlSegmentProps {
|
|
21
89
|
/** Display label for the segment */
|
|
22
90
|
label: string;
|
|
@@ -27,8 +95,21 @@ export interface SegmentedControlSegmentProps {
|
|
|
27
95
|
/** Whether this specific segment is disabled */
|
|
28
96
|
disabled?: boolean;
|
|
29
97
|
|
|
30
|
-
/** Optional
|
|
31
|
-
icon?:
|
|
98
|
+
/** Optional icon. See {@link SegmentedControlIcon}. */
|
|
99
|
+
icon?: SegmentedControlIcon;
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Badge shown at the segment's top-right corner, e.g. an unread count.
|
|
103
|
+
* Numbers are shown as-is; use `undefined` to hide the badge.
|
|
104
|
+
*/
|
|
105
|
+
badge?: string | number;
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Screen-reader label. Defaults to `label`.
|
|
109
|
+
* On iOS this applies to segments rendered as icons; text segments are
|
|
110
|
+
* announced by their title.
|
|
111
|
+
*/
|
|
112
|
+
accessibilityLabel?: string;
|
|
32
113
|
}
|
|
33
114
|
|
|
34
115
|
export interface SegmentedControlProps extends ViewProps {
|
|
@@ -48,9 +129,40 @@ export interface SegmentedControlProps extends ViewProps {
|
|
|
48
129
|
*/
|
|
49
130
|
onSelect?: (value: string, index: number) => void;
|
|
50
131
|
|
|
132
|
+
/**
|
|
133
|
+
* Called when the user clears the selection by tapping the selected segment.
|
|
134
|
+
* Only possible on Android with `android.selectionRequired` set to `false`;
|
|
135
|
+
* iOS never clears a selection from a tap.
|
|
136
|
+
*/
|
|
137
|
+
onDeselect?: () => void;
|
|
138
|
+
|
|
51
139
|
/** Whether the entire control is disabled */
|
|
52
140
|
disabled?: boolean;
|
|
53
141
|
|
|
142
|
+
/**
|
|
143
|
+
* How labels and icons combine. Default: `'auto'`.
|
|
144
|
+
* See {@link SegmentedControlLabelVisibility}.
|
|
145
|
+
*/
|
|
146
|
+
labelVisibility?: SegmentedControlLabelVisibility;
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Background color of the selected segment.
|
|
150
|
+
* iOS: `selectedSegmentTintColor`. Android: checked button background.
|
|
151
|
+
*/
|
|
152
|
+
selectedSegmentColor?: ColorValue;
|
|
153
|
+
|
|
154
|
+
/** Text and icon color of the selected segment. */
|
|
155
|
+
activeTintColor?: ColorValue;
|
|
156
|
+
|
|
157
|
+
/** Text and icon color of unselected segments. */
|
|
158
|
+
inactiveTintColor?: ColorValue;
|
|
159
|
+
|
|
160
|
+
/** Font for segment labels. See {@link SegmentedControlLabelStyle}. */
|
|
161
|
+
labelStyle?: SegmentedControlLabelStyle;
|
|
162
|
+
|
|
163
|
+
/** Colors for segment badges. See {@link SegmentedControlBadgeStyle}. */
|
|
164
|
+
badgeStyle?: SegmentedControlBadgeStyle;
|
|
165
|
+
|
|
54
166
|
/**
|
|
55
167
|
* iOS-specific configuration
|
|
56
168
|
*/
|
|
@@ -68,7 +180,7 @@ export interface SegmentedControlProps extends ViewProps {
|
|
|
68
180
|
apportionsSegmentWidthsByContent?: boolean;
|
|
69
181
|
|
|
70
182
|
/**
|
|
71
|
-
*
|
|
183
|
+
* @deprecated Use `selectedSegmentColor`, which works on both platforms.
|
|
72
184
|
*/
|
|
73
185
|
selectedSegmentTintColor?: string;
|
|
74
186
|
};
|
|
@@ -78,16 +190,89 @@ export interface SegmentedControlProps extends ViewProps {
|
|
|
78
190
|
*/
|
|
79
191
|
android?: {
|
|
80
192
|
/**
|
|
81
|
-
* Whether one segment must always be selected.
|
|
82
|
-
*
|
|
193
|
+
* Whether one segment must always be selected. When `false`, tapping the
|
|
194
|
+
* selected segment clears the selection and calls `onDeselect`.
|
|
195
|
+
* Default: true (matches iOS, which cannot clear a selection by tapping)
|
|
83
196
|
*/
|
|
84
197
|
selectionRequired?: boolean;
|
|
198
|
+
|
|
199
|
+
/** Ripple color shown while pressing a segment. */
|
|
200
|
+
rippleColor?: ColorValue;
|
|
201
|
+
|
|
202
|
+
/** Outline color of the segments. */
|
|
203
|
+
strokeColor?: ColorValue;
|
|
85
204
|
};
|
|
86
205
|
|
|
87
206
|
/** Test identifier */
|
|
88
207
|
testID?: string;
|
|
89
208
|
}
|
|
90
209
|
|
|
210
|
+
type NativeIconFields = Pick<
|
|
211
|
+
NativeSegment,
|
|
212
|
+
'iconType' | 'iconName' | 'iconUri' | 'iconScale' | 'iconTinted'
|
|
213
|
+
>;
|
|
214
|
+
|
|
215
|
+
const NO_ICON: NativeIconFields = {
|
|
216
|
+
iconType: '',
|
|
217
|
+
iconName: '',
|
|
218
|
+
iconUri: '',
|
|
219
|
+
iconScale: 1,
|
|
220
|
+
iconTinted: 'true',
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
function pickIconSource(
|
|
224
|
+
icon: SegmentedControlIcon | undefined
|
|
225
|
+
): SegmentedControlIconSource | undefined {
|
|
226
|
+
if (icon === undefined || typeof icon === 'string' || 'type' in icon) {
|
|
227
|
+
return icon;
|
|
228
|
+
}
|
|
229
|
+
return Platform.OS === 'ios' ? icon.ios : icon.android;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Flattens the public icon shape into the strings native expects, dropping
|
|
234
|
+
* sources that don't apply to the current platform.
|
|
235
|
+
*/
|
|
236
|
+
export function resolveSegmentIcon(
|
|
237
|
+
icon: SegmentedControlIcon | undefined
|
|
238
|
+
): NativeIconFields {
|
|
239
|
+
const source = pickIconSource(icon);
|
|
240
|
+
if (source === undefined) return NO_ICON;
|
|
241
|
+
|
|
242
|
+
if (typeof source === 'string') {
|
|
243
|
+
if (source.length === 0) return NO_ICON;
|
|
244
|
+
return {
|
|
245
|
+
...NO_ICON,
|
|
246
|
+
iconType: Platform.OS === 'ios' ? 'sfSymbol' : 'drawable',
|
|
247
|
+
iconName: source,
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
switch (source.type) {
|
|
252
|
+
case 'sfSymbol':
|
|
253
|
+
return Platform.OS === 'ios'
|
|
254
|
+
? { ...NO_ICON, iconType: 'sfSymbol', iconName: source.name }
|
|
255
|
+
: NO_ICON;
|
|
256
|
+
case 'drawable':
|
|
257
|
+
return Platform.OS === 'android'
|
|
258
|
+
? { ...NO_ICON, iconType: 'drawable', iconName: source.name }
|
|
259
|
+
: NO_ICON;
|
|
260
|
+
case 'image': {
|
|
261
|
+
const resolved = Image.resolveAssetSource(source.source);
|
|
262
|
+
if (!resolved?.uri) return NO_ICON;
|
|
263
|
+
return {
|
|
264
|
+
iconType: 'image',
|
|
265
|
+
iconName: '',
|
|
266
|
+
iconUri: resolved.uri,
|
|
267
|
+
iconScale: resolved.scale > 0 ? resolved.scale : 1,
|
|
268
|
+
iconTinted: source.tinted === false ? 'false' : 'true',
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
default:
|
|
272
|
+
return NO_ICON;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
91
276
|
function normalizeSelectedValue(selected: string | null): string {
|
|
92
277
|
return selected ?? '';
|
|
93
278
|
}
|
|
@@ -100,19 +285,29 @@ export function SegmentedControl(
|
|
|
100
285
|
segments,
|
|
101
286
|
selectedValue,
|
|
102
287
|
disabled,
|
|
288
|
+
labelVisibility,
|
|
289
|
+
selectedSegmentColor,
|
|
290
|
+
activeTintColor,
|
|
291
|
+
inactiveTintColor,
|
|
292
|
+
labelStyle,
|
|
293
|
+
badgeStyle,
|
|
103
294
|
onSelect,
|
|
295
|
+
onDeselect,
|
|
104
296
|
ios,
|
|
105
297
|
android,
|
|
106
298
|
...viewProps
|
|
107
299
|
} = props;
|
|
108
300
|
|
|
109
301
|
// Normalize segments for native
|
|
110
|
-
const nativeSegments = useMemo(() => {
|
|
302
|
+
const nativeSegments = useMemo((): NativeSegment[] => {
|
|
111
303
|
return segments.map((seg) => ({
|
|
112
304
|
label: seg.label,
|
|
113
305
|
value: seg.value,
|
|
114
306
|
disabled: seg.disabled ? 'disabled' : 'enabled',
|
|
115
|
-
|
|
307
|
+
badge:
|
|
308
|
+
seg.badge === undefined || seg.badge === null ? '' : String(seg.badge),
|
|
309
|
+
accessibilityLabel: seg.accessibilityLabel ?? '',
|
|
310
|
+
...resolveSegmentIcon(seg.icon),
|
|
116
311
|
}));
|
|
117
312
|
}, [segments]);
|
|
118
313
|
|
|
@@ -124,9 +319,14 @@ export function SegmentedControl(
|
|
|
124
319
|
const handleSelect = useCallback(
|
|
125
320
|
(e: { nativeEvent: SegmentedControlSelectEvent }) => {
|
|
126
321
|
const { index, value } = e.nativeEvent;
|
|
322
|
+
// Native reports a cleared selection as index -1 with an empty value.
|
|
323
|
+
if (index < 0) {
|
|
324
|
+
onDeselect?.();
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
127
327
|
onSelect?.(value, index);
|
|
128
328
|
},
|
|
129
|
-
[onSelect]
|
|
329
|
+
[onSelect, onDeselect]
|
|
130
330
|
);
|
|
131
331
|
|
|
132
332
|
// Normalize iOS props to native string format
|
|
@@ -137,15 +337,33 @@ export function SegmentedControl(
|
|
|
137
337
|
apportionsSegmentWidthsByContent: ios.apportionsSegmentWidthsByContent
|
|
138
338
|
? 'true'
|
|
139
339
|
: 'false',
|
|
140
|
-
selectedSegmentTintColor: ios.selectedSegmentTintColor ?? '',
|
|
141
340
|
};
|
|
142
341
|
}, [ios]);
|
|
143
342
|
|
|
343
|
+
// Deprecated iOS-only tint falls back to the cross-platform prop
|
|
344
|
+
const nativeSelectedSegmentColor =
|
|
345
|
+
selectedSegmentColor ??
|
|
346
|
+
(Platform.OS === 'ios' ? ios?.selectedSegmentTintColor : undefined);
|
|
347
|
+
|
|
348
|
+
// Normalize the label font; empty / 0 means platform default
|
|
349
|
+
const nativeLabelStyle = useMemo(() => {
|
|
350
|
+
if (!labelStyle) return undefined;
|
|
351
|
+
return {
|
|
352
|
+
fontFamily: labelStyle.fontFamily ?? '',
|
|
353
|
+
fontSize: labelStyle.fontSize ?? 0,
|
|
354
|
+
fontWeight:
|
|
355
|
+
labelStyle.fontWeight === undefined
|
|
356
|
+
? ''
|
|
357
|
+
: String(labelStyle.fontWeight),
|
|
358
|
+
fontStyle: labelStyle.fontStyle ?? '',
|
|
359
|
+
};
|
|
360
|
+
}, [labelStyle]);
|
|
361
|
+
|
|
144
362
|
// Normalize Android props
|
|
145
363
|
const nativeAndroid = useMemo(() => {
|
|
146
364
|
if (!android) return undefined;
|
|
147
365
|
return {
|
|
148
|
-
selectionRequired: android.selectionRequired ? '
|
|
366
|
+
selectionRequired: android.selectionRequired === false ? 'false' : 'true',
|
|
149
367
|
};
|
|
150
368
|
}, [android]);
|
|
151
369
|
|
|
@@ -163,7 +381,16 @@ export function SegmentedControl(
|
|
|
163
381
|
segments={nativeSegments}
|
|
164
382
|
selectedValue={selectedData}
|
|
165
383
|
interactivity={disabled ? 'disabled' : 'enabled'}
|
|
166
|
-
|
|
384
|
+
labelVisibility={labelVisibility ?? 'auto'}
|
|
385
|
+
selectedSegmentColor={nativeSelectedSegmentColor}
|
|
386
|
+
activeTintColor={activeTintColor}
|
|
387
|
+
inactiveTintColor={inactiveTintColor}
|
|
388
|
+
androidRippleColor={android?.rippleColor}
|
|
389
|
+
androidStrokeColor={android?.strokeColor}
|
|
390
|
+
labelStyle={nativeLabelStyle}
|
|
391
|
+
badgeBackgroundColor={badgeStyle?.backgroundColor}
|
|
392
|
+
badgeTextColor={badgeStyle?.color}
|
|
393
|
+
onSelect={onSelect || onDeselect ? handleSelect : undefined}
|
|
167
394
|
ios={nativeIos}
|
|
168
395
|
android={nativeAndroid}
|
|
169
396
|
{...viewProps}
|
|
@@ -1,31 +1,59 @@
|
|
|
1
1
|
// SegmentedControlNativeComponent.ts
|
|
2
|
-
import type {
|
|
2
|
+
import type {
|
|
3
|
+
CodegenTypes,
|
|
4
|
+
ColorValue,
|
|
5
|
+
HostComponent,
|
|
6
|
+
ViewProps,
|
|
7
|
+
} from 'react-native';
|
|
3
8
|
import { codegenNativeComponent } from 'react-native';
|
|
4
9
|
|
|
5
10
|
/**
|
|
6
11
|
* A single segment in the control.
|
|
12
|
+
*
|
|
13
|
+
* Icons are pre-resolved on the JS side so native only deals with flat
|
|
14
|
+
* strings: `iconType` selects the source, `iconName` carries an SF Symbol or
|
|
15
|
+
* drawable name, and `iconUri` / `iconScale` carry a resolved image asset.
|
|
7
16
|
*/
|
|
8
17
|
export type SegmentedControlSegment = Readonly<{
|
|
9
18
|
label: string;
|
|
10
19
|
value: string;
|
|
11
20
|
disabled: string; // 'enabled' | 'disabled'
|
|
12
|
-
|
|
21
|
+
iconType: string; // '' | 'sfSymbol' | 'drawable' | 'image'
|
|
22
|
+
iconName: string; // SF Symbol (iOS) or drawable resource name (Android)
|
|
23
|
+
iconUri: string; // Resolved image URI when iconType === 'image'
|
|
24
|
+
iconScale: CodegenTypes.Double; // Resolved image scale when iconType === 'image'
|
|
25
|
+
iconTinted: string; // 'true' | 'false' — draw the image as a tinted template
|
|
26
|
+
badge: string; // Badge text, empty = no badge
|
|
27
|
+
accessibilityLabel: string; // Screen-reader label, empty = use label
|
|
13
28
|
}>;
|
|
14
29
|
|
|
15
30
|
/**
|
|
16
31
|
* Event emitted when the user selects a segment.
|
|
17
32
|
*/
|
|
18
33
|
export type SegmentedControlSelectEvent = Readonly<{
|
|
19
|
-
/** Selected segment index */
|
|
34
|
+
/** Selected segment index. -1 means the selection was cleared. */
|
|
20
35
|
index: CodegenTypes.Int32;
|
|
21
36
|
|
|
22
|
-
/** Selected segment value */
|
|
37
|
+
/** Selected segment value. Empty when the selection was cleared. */
|
|
23
38
|
value: string;
|
|
24
39
|
}>;
|
|
25
40
|
|
|
26
41
|
/** Interactivity state (no booleans). */
|
|
27
42
|
export type SegmentedControlInteractivity = 'enabled' | 'disabled';
|
|
28
43
|
|
|
44
|
+
/** How labels and icons combine (no booleans). */
|
|
45
|
+
export type SegmentedControlLabelVisibility = 'auto' | 'labeled' | 'unlabeled';
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Label font. Empty strings / 0 mean "platform default".
|
|
49
|
+
*/
|
|
50
|
+
export type LabelStyleProps = Readonly<{
|
|
51
|
+
fontFamily?: string;
|
|
52
|
+
fontSize?: CodegenTypes.Double;
|
|
53
|
+
fontWeight?: string; // 'normal' | 'bold' | '100'..'900'
|
|
54
|
+
fontStyle?: string; // 'normal' | 'italic'
|
|
55
|
+
}>;
|
|
56
|
+
|
|
29
57
|
/**
|
|
30
58
|
* iOS-specific configuration.
|
|
31
59
|
*/
|
|
@@ -35,9 +63,6 @@ export type IOSProps = Readonly<{
|
|
|
35
63
|
|
|
36
64
|
/** Whether segment widths are proportional to content */
|
|
37
65
|
apportionsSegmentWidthsByContent?: string; // 'true' | 'false'
|
|
38
|
-
|
|
39
|
-
/** Selected segment tint color (hex string) */
|
|
40
|
-
selectedSegmentTintColor?: string;
|
|
41
66
|
}>;
|
|
42
67
|
|
|
43
68
|
/**
|
|
@@ -65,6 +90,35 @@ export interface SegmentedControlProps extends ViewProps {
|
|
|
65
90
|
*/
|
|
66
91
|
interactivity?: string; // SegmentedControlInteractivity
|
|
67
92
|
|
|
93
|
+
/**
|
|
94
|
+
* How segment labels and icons combine.
|
|
95
|
+
*/
|
|
96
|
+
labelVisibility?: string; // SegmentedControlLabelVisibility
|
|
97
|
+
|
|
98
|
+
/** Background of the selected segment. */
|
|
99
|
+
selectedSegmentColor?: ColorValue;
|
|
100
|
+
|
|
101
|
+
/** Text / icon color of the selected segment. */
|
|
102
|
+
activeTintColor?: ColorValue;
|
|
103
|
+
|
|
104
|
+
/** Text / icon color of unselected segments. */
|
|
105
|
+
inactiveTintColor?: ColorValue;
|
|
106
|
+
|
|
107
|
+
/** Android: ripple color when pressing a segment. */
|
|
108
|
+
androidRippleColor?: ColorValue;
|
|
109
|
+
|
|
110
|
+
/** Android: outline color of the segments. */
|
|
111
|
+
androidStrokeColor?: ColorValue;
|
|
112
|
+
|
|
113
|
+
/** Label font. */
|
|
114
|
+
labelStyle?: LabelStyleProps;
|
|
115
|
+
|
|
116
|
+
/** Badge background (default: system red). */
|
|
117
|
+
badgeBackgroundColor?: ColorValue;
|
|
118
|
+
|
|
119
|
+
/** Badge text color (default: white). */
|
|
120
|
+
badgeTextColor?: ColorValue;
|
|
121
|
+
|
|
68
122
|
/**
|
|
69
123
|
* Fired when the user selects a segment.
|
|
70
124
|
*/
|
|
@@ -76,4 +130,4 @@ export interface SegmentedControlProps extends ViewProps {
|
|
|
76
130
|
|
|
77
131
|
export default codegenNativeComponent<SegmentedControlProps>(
|
|
78
132
|
'PCSegmentedControl'
|
|
79
|
-
)
|
|
133
|
+
) as HostComponent<SegmentedControlProps>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// SelectionMenuNativeComponent.ts
|
|
2
|
-
import type { CodegenTypes, ViewProps } from 'react-native';
|
|
2
|
+
import type { CodegenTypes, HostComponent, ViewProps } from 'react-native';
|
|
3
3
|
import { codegenNativeComponent } from 'react-native';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -94,4 +94,6 @@ export interface SelectionMenuProps extends ViewProps {
|
|
|
94
94
|
android?: AndroidProps;
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
export default codegenNativeComponent<SelectionMenuProps>(
|
|
97
|
+
export default codegenNativeComponent<SelectionMenuProps>(
|
|
98
|
+
'PCSelectionMenu'
|
|
99
|
+
) as HostComponent<SelectionMenuProps>;
|
package/src/index.web.tsx
CHANGED
|
@@ -111,18 +111,51 @@ export const ContextMenu = ({
|
|
|
111
111
|
// SegmentedControl
|
|
112
112
|
// ============================================================================
|
|
113
113
|
|
|
114
|
+
export type SegmentedControlIconSource =
|
|
115
|
+
| string
|
|
116
|
+
| { type: 'sfSymbol'; name: string }
|
|
117
|
+
| { type: 'drawable'; name: string }
|
|
118
|
+
| { type: 'image'; source: unknown; tinted?: boolean };
|
|
119
|
+
|
|
120
|
+
export type SegmentedControlIcon =
|
|
121
|
+
| SegmentedControlIconSource
|
|
122
|
+
| { ios?: SegmentedControlIconSource; android?: SegmentedControlIconSource };
|
|
123
|
+
|
|
124
|
+
export type SegmentedControlLabelVisibility = 'auto' | 'labeled' | 'unlabeled';
|
|
125
|
+
|
|
114
126
|
export interface SegmentedControlSegmentProps {
|
|
115
127
|
label: string;
|
|
116
128
|
value: string;
|
|
117
129
|
disabled?: boolean;
|
|
118
|
-
icon?:
|
|
130
|
+
icon?: SegmentedControlIcon;
|
|
131
|
+
badge?: string | number;
|
|
132
|
+
accessibilityLabel?: string;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export interface SegmentedControlBadgeStyle {
|
|
136
|
+
backgroundColor?: string;
|
|
137
|
+
color?: string;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export interface SegmentedControlLabelStyle {
|
|
141
|
+
fontFamily?: string;
|
|
142
|
+
fontSize?: number;
|
|
143
|
+
fontWeight?: string | number;
|
|
144
|
+
fontStyle?: 'normal' | 'italic';
|
|
119
145
|
}
|
|
120
146
|
|
|
121
147
|
export interface SegmentedControlProps extends ViewProps {
|
|
122
148
|
segments: readonly SegmentedControlSegmentProps[];
|
|
123
149
|
selectedValue: string | null;
|
|
124
150
|
disabled?: boolean;
|
|
151
|
+
labelVisibility?: SegmentedControlLabelVisibility;
|
|
152
|
+
selectedSegmentColor?: string;
|
|
153
|
+
activeTintColor?: string;
|
|
154
|
+
inactiveTintColor?: string;
|
|
155
|
+
labelStyle?: SegmentedControlLabelStyle;
|
|
156
|
+
badgeStyle?: SegmentedControlBadgeStyle;
|
|
125
157
|
onSelect?: (value: string, index: number) => void;
|
|
158
|
+
onDeselect?: () => void;
|
|
126
159
|
ios?: Record<string, unknown>;
|
|
127
160
|
android?: Record<string, unknown>;
|
|
128
161
|
}
|