react-native-form-model
Version:
An easily testable and opinionated React Native form model builder written in pure JavaScript.
76 lines (64 loc) • 2.16 kB
text/typescript
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import InputFieldModel, {
ParsedInputFieldModelOptions,
} from './InputFieldModel';
export type OptionInputFieldMode = 'segmented' | 'dropdown' | 'dialog';
export type OptionInputClearButtonMode = 'auto' | 'always' | 'never';
export interface OptionInputFieldModelOptions<T>
extends ParsedInputFieldModelOptions<T, number> {
mode: OptionInputFieldMode;
possibleValues: T[];
/**
* Set this when values are not
* supported by `Array#indexOf` method.
*/
serializer?: (value: T | undefined) => any;
optional?: boolean;
prompt?: string;
/**
* When to show the clear button.
*
* Supported with `segmented` mode only.
*/
clearButtonMode?: OptionInputClearButtonMode;
}
export default class OptionInputFieldModel<T = string>
extends InputFieldModel<T, number>
implements OptionInputFieldModelOptions<T>
{
mode: OptionInputFieldMode;
possibleValues: T[];
serializer?: OptionInputFieldModelOptions<T>['serializer'];
optional: boolean;
prompt?: string;
clearButtonMode: OptionInputClearButtonMode;
constructor(options: OptionInputFieldModelOptions<T>) {
const { parseInput = i => this.possibleValues[i] } = options;
super({
...options,
parseInput,
});
const { optional = false, clearButtonMode = 'auto' } = options;
this.mode = options.mode;
this.possibleValues = [...options.possibleValues];
this.serializer = options.serializer;
this.optional = optional;
this.prompt = options.prompt;
this.clearButtonMode = clearButtonMode;
}
indexOf(value: T): number {
if (this.serializer) {
return this.possibleValues
.map(this.serializer)
.indexOf(this.serializer(value));
}
return this.possibleValues.indexOf(value);
}
selectedIndex(): Observable<number> {
return this.value.pipe(map(value => this.indexOf(value)));
}
selectIndex(index: number) {
this.setInput(index);
}
}