Skip to content

Commit 28c3c65

Browse files
committed
feat(multi-picker): add configuration support for dynamic option generation
1 parent a38b10b commit 28c3c65

File tree

3 files changed

+61
-11
lines changed

3 files changed

+61
-11
lines changed

ios/components/MultiPicker/MultiPickerProps.swift

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,14 @@ public final class MultiPickerProps: ObservableObject, Decodable {
1717
let label: String
1818
let options: [MultiPickerOption]
1919
let width: CGFloat?
20+
let config: MultiPickerComponentConfig?
21+
22+
var computedOptions: [MultiPickerOption] {
23+
if config != nil {
24+
return config!.generateOptions()
25+
}
26+
return options
27+
}
2028
}
2129

2230
struct MultiPickerOption: Identifiable, Decodable, Hashable {
@@ -25,6 +33,29 @@ public final class MultiPickerProps: ObservableObject, Decodable {
2533
var id: String { value } // Use value as the unique identifier
2634
}
2735

36+
struct MultiPickerComponentConfig: Decodable, Hashable {
37+
let min: Int
38+
let max: Int
39+
let step: Int
40+
let prefix: String
41+
let suffix: String
42+
43+
// Generate options based on numeric configuration
44+
func generateOptions() -> [MultiPickerOption] {
45+
var options: [MultiPickerOption] = []
46+
var current = min
47+
48+
while current <= max {
49+
let valueString = "\(current)"
50+
let labelString = "\(prefix)\(current)\(suffix)"
51+
options.append(MultiPickerOption(label: labelString, value: valueString))
52+
current += step
53+
}
54+
55+
return options
56+
}
57+
}
58+
2859
// Coding keys for decoding
2960
enum CodingKeys: String, CodingKey, CaseIterable {
3061
case components, selections, label, disabled, style

ios/components/MultiPicker/MultiPickerView.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,13 @@ public struct MultiPickerView: View {
3939
ForEach(0 ..< props.components.count, id: \.self) { index in
4040
let component = props.components[index]
4141
ZStack(alignment: Alignment(horizontal: .trailing, vertical: .center)) {
42-
if !component.label.isEmpty && !component.options.isEmpty {
43-
Text(component.label)
44-
.padding(.trailing, 16)
45-
.font(.caption)
42+
if !component.label.isEmpty && !component.computedOptions.isEmpty {
43+
Text(component.label)
44+
.padding(.trailing, 16)
45+
.font(.caption)
4646
}
4747
Picker(component.label, selection: $props.selections[index]) {
48-
ForEach(component.options, id: \.value) { option in
48+
ForEach(component.computedOptions, id: \.value) { option in
4949
Text(option.label).tag(option.value)
5050
}
5151
}

src/components/MultiPicker.tsx

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,26 @@ import { fillArray } from "../utils";
88

99
export type NativeMultiPickerOption<T extends string> = { value: T; label: string } | T;
1010

11+
export type NativeMultiPickerComponentConfig = {
12+
min: number;
13+
max: number;
14+
step?: number;
15+
prefix?: string;
16+
suffix?: string;
17+
};
18+
19+
const DEFAULT_COMPONENT_CONFIG = {
20+
min: 0,
21+
max: 100,
22+
step: 1,
23+
prefix: "",
24+
suffix: "",
25+
} satisfies NativeMultiPickerComponentConfig;
26+
1127
export type NativeMultiPickerComponent<T extends string> = {
1228
label?: string;
13-
options: readonly NativeMultiPickerOption<T>[];
29+
options?: readonly NativeMultiPickerOption<T>[];
30+
config?: NativeMultiPickerComponentConfig;
1431
// width?: number; // @TODO
1532
};
1633

@@ -51,12 +68,14 @@ export const MultiPicker = <T extends string>({
5168
const normalizedComponents = useMemo(
5269
() =>
5370
components.map((component) => {
54-
const { options, ...rest } = component;
55-
const normalizedOptions =
56-
options.length > 0 && typeof options[0] === "string"
71+
const { options, config, ...rest } = component;
72+
const normalizedConfig = config ? { ...DEFAULT_COMPONENT_CONFIG, ...config } : undefined;
73+
const normalizedOptions = options
74+
? options.length > 0 && typeof options[0] === "string"
5775
? options.map((value) => ({ value, label: value }))
58-
: options;
59-
return { ...rest, options: normalizedOptions };
76+
: options
77+
: [];
78+
return { ...rest, config: normalizedConfig, options: normalizedOptions };
6079
}),
6180
[components],
6281
);

0 commit comments

Comments
 (0)