Skip to content

Commit 983ca14

Browse files
committed
feat: enhance SwiftUIPicker with onChange event and tint support
1 parent 35835ac commit 983ca14

File tree

6 files changed

+56
-19
lines changed

6 files changed

+56
-19
lines changed

example/src/views/StandalonePickerExample.tsx

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,8 @@ export const StandalonePickerExample: FunctionComponent = () => {
4242
selection={pickerStyle}
4343
options={['default', 'inline', 'menu', 'segmented', 'wheel']}
4444
pickerStyle="segmented"
45-
onNativeChange={event =>
46-
setPickerStyle(event.nativeEvent.value as typeof pickerStyle)
47-
}
48-
style={styles.picker}
45+
onChange={value => setPickerStyle(value as typeof pickerStyle)}
46+
style={[styles.picker, { tint: '#fb7185' }]}
4947
/>
5048
</View>
5149

@@ -57,8 +55,8 @@ export const StandalonePickerExample: FunctionComponent = () => {
5755
selection={selectedFruit}
5856
options={['Apple', 'Banana', 'Orange', 'Grape', 'Mango']}
5957
pickerStyle={pickerStyle}
60-
onNativeChange={event => setSelectedFruit(event.nativeEvent.value)}
61-
style={styles.picker}
58+
onChange={value => setSelectedFruit(value)}
59+
style={[styles.picker, { tint: '#22d3ee' }]}
6260
/>
6361
</View>
6462

@@ -70,8 +68,8 @@ export const StandalonePickerExample: FunctionComponent = () => {
7068
selection={selectedColor}
7169
options={['Red', 'Blue', 'Green', 'Yellow', 'Purple']}
7270
pickerStyle={pickerStyle}
73-
onNativeChange={event => setSelectedColor(event.nativeEvent.value)}
74-
style={styles.picker}
71+
onChange={value => setSelectedColor(value)}
72+
style={[styles.picker, { tint: '#a855f7' }]}
7573
/>
7674
</View>
7775

@@ -83,7 +81,7 @@ export const StandalonePickerExample: FunctionComponent = () => {
8381
selection={selectedSize}
8482
options={['Small', 'Medium', 'Large', 'Extra Large']}
8583
pickerStyle={pickerStyle}
86-
onNativeChange={event => setSelectedSize(event.nativeEvent.value)}
84+
onChange={value => setSelectedSize(value)}
8785
style={styles.picker}
8886
/>
8987
</View>

ios/components/Picker/PickerProps.swift

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -104,13 +104,25 @@ public final class PickerProps: ObservableObject, Decodable {
104104
public init() {}
105105

106106
public func merge(from other: PickerProps) {
107-
options = other.options
108-
selection = other.selection
109-
config = other.config
110-
label = other.label
107+
if options != other.options {
108+
options = other.options
109+
}
110+
if selection != other.selection {
111+
selection = other.selection
112+
}
113+
if config != other.config {
114+
config = other.config
115+
}
116+
if label != other.label {
117+
label = other.label
118+
}
111119
labelColor = other.labelColor
112-
pickerStyle = other.pickerStyle
113-
disabled = other.disabled
120+
if pickerStyle != other.pickerStyle {
121+
pickerStyle = other.pickerStyle
122+
}
123+
if disabled != other.disabled {
124+
disabled = other.disabled
125+
}
114126
style = other.style
115127
}
116128
}

ios/components/StyleProps.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ public struct StyleProps: Decodable {
44
// ViewStyle
55
public var color: ColorValue? // alias for foregroundColor
66
public var accentColor: ColorValue?
7+
public var tint: ColorValue?
78
public var tintColor: ColorValue?
89
public var foregroundColor: ColorValue?
910
public var backgroundColor: ColorValue?
@@ -42,7 +43,7 @@ public struct StyleProps: Decodable {
4243
public var textAlign: TextAlignment?
4344

4445
enum CodingKeys: String, CodingKey {
45-
case color, accentColor, tintColor, backgroundColor, preferredColorScheme, foregroundColor, width, minWidth, maxWidth, height, minHeight, maxHeight, position, top, left, bottom, right, padding, paddingHorizontal, paddingVertical, paddingLeft, paddingRight, paddingTop, paddingBottom, borderColor, borderWidth, borderRadius, cornerRadius, fontWeight, fontSize, font, fontFamily, textAlign
46+
case color, accentColor, tint, tintColor, backgroundColor, preferredColorScheme, foregroundColor, width, minWidth, maxWidth, height, minHeight, maxHeight, position, top, left, bottom, right, padding, paddingHorizontal, paddingVertical, paddingLeft, paddingRight, paddingTop, paddingBottom, borderColor, borderWidth, borderRadius, cornerRadius, fontWeight, fontSize, font, fontFamily, textAlign
4647
}
4748

4849
public init(from decoder: Decoder) throws {
@@ -51,6 +52,7 @@ public struct StyleProps: Decodable {
5152
// ViewStyle
5253
color = try container.decodeIfPresent(ColorValue.self, forKey: .color) // alias for foregroundColor
5354
accentColor = try container.decodeIfPresent(ColorValue.self, forKey: .accentColor)
55+
tint = try container.decodeIfPresent(ColorValue.self, forKey: .tint)
5456
tintColor = try container.decodeIfPresent(ColorValue.self, forKey: .tintColor)
5557
foregroundColor = try container.decodeIfPresent(ColorValue.self, forKey: .foregroundColor)
5658
backgroundColor = try container.decodeIfPresent(ColorValue.self, forKey: .backgroundColor)

ios/extensions/View+Styling.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,9 @@ extension View {
8181
.applyIf(style.backgroundColor != nil) { $0.background(Color(value: style.backgroundColor!)) }
8282
.applyIf(style.color != nil || style.foregroundColor != nil) { $0.foregroundStyle(Color(value: style.color ?? style.foregroundColor!)) }
8383
.applyIf(style.accentColor != nil) { $0.accentColor(Color(value: style.accentColor!)) }
84-
.applyIf(style.tintColor != nil) { $0.tint(Color(value: style.tintColor!)) }
84+
.applyIf(style.tint != nil || style.tintColor != nil) {
85+
$0.tint(Color(value: style.tint ?? style.tintColor!))
86+
}
8587
.applyIf(style.preferredColorScheme != nil) { $0.preferredColorScheme(style.preferredColorScheme!) }
8688
.applyIf(style.borderWidth != nil) { view in
8789
view.overlay(

src/SwiftUIPicker.tsx

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import NativePickerViewNativeComponent, {
55
type NativePickerProps,
66
type NativePickerStyle,
77
} from "./native/PickerViewNativeComponent";
8+
import { NativeTextStyle } from "./types";
89

910
type NativePickerComponentRef = React.ComponentRef<typeof NativePickerViewNativeComponent>;
1011

@@ -16,14 +17,35 @@ const DEFAULT_HEIGHTS: Record<NativePickerStyle, number> = {
1617
wheel: 216,
1718
};
1819

19-
export const SwiftUIPicker = forwardRef<NativePickerComponentRef, NativePickerProps>(
20-
({ pickerStyle, style, ...restProps }, ref) => {
20+
type NativeOnChangeEvent = Parameters<NonNullable<NativePickerProps["onNativeChange"]>>[0];
21+
22+
export type SwiftUIPickerProps = Omit<
23+
NativePickerProps,
24+
"onNativeChange" | "onNativeFocus" | "onNativeBlur" | "style"
25+
> & {
26+
onChange?: (value: string, event: NativeOnChangeEvent) => void;
27+
onFocus?: () => void;
28+
onBlur?: () => void;
29+
style?: StyleProp<ViewStyle & Pick<NativeTextStyle, "tint">>;
30+
};
31+
32+
export const SwiftUIPicker = forwardRef<NativePickerComponentRef, SwiftUIPickerProps>(
33+
({ pickerStyle, style, onChange, onFocus, onBlur, ...restProps }, ref) => {
2134
const defaultHeight = DEFAULT_HEIGHTS[pickerStyle ?? "default"];
2235
const composedStyle: StyleProp<ViewStyle> = [{ minHeight: defaultHeight }, style];
2336

2437
return (
2538
<NativePickerViewNativeComponent
2639
{...restProps}
40+
onNativeChange={
41+
onChange
42+
? (event) => {
43+
onChange(event.nativeEvent.value, event);
44+
}
45+
: undefined
46+
}
47+
onNativeFocus={onFocus ?? undefined}
48+
onNativeBlur={onBlur ?? undefined}
2749
pickerStyle={pickerStyle}
2850
style={composedStyle}
2951
ref={ref}

src/types/style.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export type NativeViewStyle = Pick<
2525
| "right"
2626
| "bottom"
2727
> & {
28+
tint?: ColorValue;
2829
tintColor?: ColorValue;
2930
accentColor?: ColorValue;
3031
foregroundColor?: ColorValue;

0 commit comments

Comments
 (0)