Commit ebb4b956 by Vladislav Lagunov

Доавлен модуль create-zoom

parent 58a8a77a
import memoize from '../functions/memoize';
import { ObjectKey, ObjectPath } from '../functions/get-at';
import { FieldProps } from '../create-form';
// Опции для `createForm`
export type CreateZoomOptions<T> = {
validate?(value: T): any;
disabled?(value: T): any;
getValue: () => T;
onValueChange(value: T): void;
onValueChange(value: unknown, at: ObjectPath): void;
};
// Функция-хелпер для подключения полей ввода
export type Zoom<T> = {
(): FieldProps<T>;
<K1 extends keyof T>(...keys: [K1]): FieldProps<T[K1]>;
<K1 extends keyof T, K2 extends keyof T[K1]>(...keys: [K1, K2]): FieldProps<T[K1][K2]>;
<K1 extends keyof T, K2 extends keyof T[K1], K3 extends keyof T[K1][K2]>(...keys: [K1, K2, K3]): FieldProps<T[K1][K2][K3]>;
<K1 extends keyof T, K2 extends keyof T[K1], K3 extends keyof T[K1][K2], K4 extends keyof T[K1][K2][K3]>(...keys: [K1, K2, K3, K4]): FieldProps<T[K1][K2][K3][K4]>;
};
// Функция-хелпер для подключения полей ввода
export default function createZoom<T>(options: CreateZoomOptions<T>): Zoom<T> {
const { onValueChange, getValue } = options;
return (...keys) => {
const value = getValue();
const error = options.validate ? options.validate(value) : {};
const disabled = options.disabled ? options.disabled(value) : {};
const zoomedError = zoomAny(keys, error);
return {
value: zoomAny(keys, value),
error: zoomedError,
disabled: zoomAny(keys, disabled),
onValueChange: zoomOnChange(keys, onValueChange),
};
};
}
const zoomOnChange = memoize((path: ObjectKey[], onChange: ((x: any, at: ObjectPath) => void)|undefined) => {
return (next, at=[]) => {
onChange && onChange(next, [...path, ...at]);
};
});
const zoomAny = memoize((path: ObjectKey[], input: any) => {
let iter = input as any;
for (const key of path) {
if (typeof(iter) !== 'object' || iter === null) return iter;
iter = iter[key];
}
return iter;
});
......@@ -13,7 +13,7 @@ import DayPickerSingleDateController from 'react-dates/lib/components/DayPickerS
// Props
export type Props = StandardProps<React.HTMLProps<HTMLDivElement>, ClassKey, 'value'|'disabled'> & FieldProps<moment.Moment> & {
export type Props = StandardProps<React.HTMLProps<HTMLDivElement>, ClassKey, 'value'|'disabled'> & FieldProps<moment.Moment|null> & {
InputProps?: Partial<TextFieldProps>;
format?: string;
nonNull?: boolean;
......
......@@ -25,8 +25,7 @@ export type AsyncSource<A> = {
// Props
export type Props<A = any> = StandardProps<React.HTMLProps<HTMLDivElement>, ClassKey, 'disabled'> & FieldProps<A> & {
selectProps?: Partial<SelectProps>;
export type Props<A = any> = StandardProps<SelectProps, ClassKey, 'disabled'> & FieldProps<A> & {
source: Source<A>;
renderItem?(item: A): string;
prepareItem?(item: A): any;
......@@ -115,7 +114,7 @@ export default class SelectField<A = any> extends React.Component<Props<A>, Stat
}
render() {
const { classes, error, nullCase, /*dirty, selectProps, options: optionsProps, */ disabled, renderItem, /*onFocus, */value, className, isEqual: isEqualProp /*...rest*/ } = this.props as Props<A> & WithStyles<ClassKey>;
const { ctx, source, classes, error, nullCase, disabled, renderItem, value, className, isEqual: isEqualProp, ...rest } = this.props as Props<A> & WithStyles<ClassKey>;
const { open } = this.state;
const rootClass = classNames(className, classes.root, {
[classes.error]: error,
......@@ -125,7 +124,7 @@ export default class SelectField<A = any> extends React.Component<Props<A>, Stat
const valueIdx = options.findIndex(x => predicate(x, value!));
return (
<Select value={valueIdx} onChange={this.handleChange} className={rootClass} disabled={Boolean(disabled)} open={open} onOpen={this.handleOpen} onClose={this.handleClose}>
<Select {...rest} value={valueIdx} onChange={this.handleChange} className={rootClass} disabled={Boolean(disabled)} open={open} onOpen={this.handleOpen} onClose={this.handleClose}>
{nullCase && <MenuItem key="@null" value={-1}>{nullCase}</MenuItem>}
{options.map((item, idx) => <MenuItem key={idx} value={idx}>{(renderItem || String)(item)}</MenuItem>)}
</Select>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment