Commit ffaaa781 by Vladislav Lagunov

Хелпер для создания формы перенесен в ~/create-form

parent 7439d626
import * as React from 'react'; import * as React from 'react';
import { FieldProps } from './';
// import * as F from './';
// import { StandardProps } from '@material-ui/core';
import memoize from '~/functions/memoize'; import memoize from '~/functions/memoize';
import { ObjectKey, ObjectPath } from '~/functions/get-at'; import { ObjectKey, ObjectPath } from '~/functions/get-at';
import { isEqual } from 'lodash'; import { isEqual } from 'lodash';
import { AuthCtx as Ctx } from '~/context';
import { I18nString } from '~/gettext';
// Контекст поля
export interface FieldProps<T = any> {
ctx?: Ctx;
value: T;
disabled?: Disabled;
// Здесь должен передавться результат `validate` те `Validation<A>`
error?: Error;
onValueChange?(value: T): void;
onValueChange?(value: any, at?: ObjectPath): void;
}
// Флаги активности
export type Disabled = boolean|object;
// Ошибки в поле
export type Error = boolean|string|object|I18nString;
// Валидация формы
export type Validation<A> = Partial<Record<keyof A, Error>>;
// Props // Props
...@@ -17,11 +40,7 @@ export type CardProps<T> = { ...@@ -17,11 +40,7 @@ export type CardProps<T> = {
} }
// // Опции для `createForm`
export type Any<T=any> = React.ReactType<FieldProps<T>>;
export type GetProps<T extends Any> = T extends React.ReactType<infer Props> ? Props : never;
export type CreateFormOptions<T> = { export type CreateFormOptions<T> = {
validate?(value: T): any; validate?(value: T): any;
disabled?(value: T): any; disabled?(value: T): any;
...@@ -91,3 +110,8 @@ const zoomAny = memoize((path: ObjectKey[], input: any) => { ...@@ -91,3 +110,8 @@ const zoomAny = memoize((path: ObjectKey[], input: any) => {
} }
return iter; return iter;
}); });
// Хелперы
export type Any<T=any> = React.ReactType<FieldProps<T>>;
export type GetProps<T extends Any> = T extends React.ReactType<infer Props> ? Props : never;
...@@ -2,7 +2,7 @@ import * as React from 'react'; ...@@ -2,7 +2,7 @@ import * as React from 'react';
import * as ReactDOM from 'react-dom'; import * as ReactDOM from 'react-dom';
import Suggestions, { Props as SuggestionProps } from '~/fields/Suggestions'; import Suggestions, { Props as SuggestionProps } from '~/fields/Suggestions';
import { AuthCtx as Ctx } from '~/context'; import { AuthCtx as Ctx } from '~/context';
import { FieldProps } from '~/fields'; import { FieldProps } from '~/create-form';
import TextField from '~/fields/TextField'; import TextField from '~/fields/TextField';
import { Props as TextFieldProps } from '~/fields/TextField'; import { Props as TextFieldProps } from '~/fields/TextField';
import { StandardProps } from '@material-ui/core'; import { StandardProps } from '@material-ui/core';
...@@ -87,15 +87,15 @@ export default class AutoComplete<A=string> extends React.Component<Props<A>, St ...@@ -87,15 +87,15 @@ export default class AutoComplete<A=string> extends React.Component<Props<A>, St
this.handleValueChange(e.target.value); this.handleValueChange(e.target.value);
}; };
handleFocus = (e?: React.SyntheticEvent) => { handleFocus = (e?: React.FocusEvent<any>) => {
this.dispatch({ tag: 'Focus' }) this.dispatch({ tag: 'Focus' })
this.props.onFocus && this.props.onFocus(e); this.props.onFocus && e && this.props.onFocus(e);
}; };
handleBlur = (e?: React.SyntheticEvent) => { handleBlur = (e?: React.FocusEvent<any>) => {
this.dispatch({ tag: 'Blur' }); this.dispatch({ tag: 'Blur' });
this.setState({ value: null }); this.setState({ value: null });
this.props.onBlur && this.props.onBlur(e); this.props.onBlur && e && this.props.onBlur(e);
}; };
handleClick = (e?: React.SyntheticEvent) => { handleClick = (e?: React.SyntheticEvent) => {
......
...@@ -2,7 +2,7 @@ import * as React from 'react'; ...@@ -2,7 +2,7 @@ import * as React from 'react';
import Switch, { SwitchProps } from '@material-ui/core/Switch'; import Switch, { SwitchProps } from '@material-ui/core/Switch';
import { Theme } from '@material-ui/core/styles/createMuiTheme'; import { Theme } from '@material-ui/core/styles/createMuiTheme';
import withStyles, { WithStyles, StyleRules } from '@material-ui/core/styles/withStyles'; import withStyles, { WithStyles, StyleRules } from '@material-ui/core/styles/withStyles';
import { FieldProps } from './'; import { FieldProps } from '~/create-form';
import * as classNames from 'classnames'; import * as classNames from 'classnames';
import { StandardProps } from '@material-ui/core'; import { StandardProps } from '@material-ui/core';
......
...@@ -2,7 +2,7 @@ import * as React from 'react'; ...@@ -2,7 +2,7 @@ import * as React from 'react';
import * as ReactDOM from 'react-dom'; import * as ReactDOM from 'react-dom';
import { Theme } from '@material-ui/core/styles/createMuiTheme'; import { Theme } from '@material-ui/core/styles/createMuiTheme';
import withStyles, { WithStyles, StyleRules } from '@material-ui/core/styles/withStyles'; import withStyles, { WithStyles, StyleRules } from '@material-ui/core/styles/withStyles';
import { FieldProps } from './'; import { FieldProps } from '~/create-form';
import * as moment from 'moment'; import * as moment from 'moment';
import TextField, { Props as TextFieldProps } from './TextField'; import TextField, { Props as TextFieldProps } from './TextField';
import { StandardProps, Popover } from '@material-ui/core'; import { StandardProps, Popover } from '@material-ui/core';
......
...@@ -8,7 +8,7 @@ import { Theme } from '@material-ui/core/styles/createMuiTheme'; ...@@ -8,7 +8,7 @@ import { Theme } from '@material-ui/core/styles/createMuiTheme';
import AutoComplete from './AutoComplete'; import AutoComplete from './AutoComplete';
import { Props as TextFieldProps } from '~/fields/TextField'; import { Props as TextFieldProps } from '~/fields/TextField';
import { Source } from '~/fields/AutoComplete/state-machine'; import { Source } from '~/fields/AutoComplete/state-machine';
import { FieldProps } from '~/fields'; import { FieldProps } from '~/create-form';
// Props // Props
......
...@@ -3,7 +3,7 @@ import { isEqual } from 'lodash'; ...@@ -3,7 +3,7 @@ import { isEqual } from 'lodash';
import { Theme } from '@material-ui/core/styles/createMuiTheme'; import { Theme } from '@material-ui/core/styles/createMuiTheme';
import withStyles, { WithStyles, StyleRules } from '@material-ui/core/styles/withStyles'; import withStyles, { WithStyles, StyleRules } from '@material-ui/core/styles/withStyles';
import * as classNames from 'classnames'; import * as classNames from 'classnames';
import { FieldProps } from './'; import { FieldProps } from '~/create-form';
import { MenuItem, StandardProps } from '@material-ui/core'; import { MenuItem, StandardProps } from '@material-ui/core';
import Select, { SelectProps } from '@material-ui/core/Select'; import Select, { SelectProps } from '@material-ui/core/Select';
import { AuthCtx as Ctx } from '~/context'; import { AuthCtx as Ctx } from '~/context';
......
...@@ -2,7 +2,7 @@ import * as React from 'react'; ...@@ -2,7 +2,7 @@ import * as React from 'react';
import { Theme } from '@material-ui/core/styles/createMuiTheme'; import { Theme } from '@material-ui/core/styles/createMuiTheme';
import withStyles, { StyleRules, WithStyles } from '@material-ui/core/styles/withStyles'; import withStyles, { StyleRules, WithStyles } from '@material-ui/core/styles/withStyles';
import * as classNames from 'classnames'; import * as classNames from 'classnames';
import { FieldProps } from './'; import { FieldProps } from '~/create-form';
import { StandardProps } from '@material-ui/core'; import { StandardProps } from '@material-ui/core';
import { withGettext, Gettext, LocaleCtx } from '~/gettext'; import { withGettext, Gettext, LocaleCtx } from '~/gettext';
const eye = require('./eye.svg'); const eye = require('./eye.svg');
......
import { AuthCtx as Ctx } from '~/context';
import { I18nString } from '~/gettext';
import { ObjectPath } from '~/functions/get-at';
// Контекст поля
export interface FieldProps<T = any> {
ctx?: Ctx;
value: T;
disabled?: Disabled;
// Здесь должен передавться результат `validate` те `Validation<A>`
error?: Error;
onValueChange?(value: T): void;
onValueChange?(value: any, at?: ObjectPath): void;
}
// Флаги активности
export type Disabled = boolean|object;
// Ошибки в поле
export type Error = boolean|string|object|I18nString;
// Валидация формы
export type Validation<A> = Partial<Record<keyof A, Error>>;
export * from './context'; export * from '~/create-form';
export { default as Label } from './Label'; export { default as Label } from './Label';
export { default as Debounce } from './Debounce'; export { default as Debounce } from './Debounce';
......
...@@ -19,8 +19,9 @@ export default function getAt<R=any>(at_: ObjectPath): <A>(a: A) => R { ...@@ -19,8 +19,9 @@ export default function getAt<R=any>(at_: ObjectPath): <A>(a: A) => R {
let iter = a as any as R; let iter = a as any as R;
for (const k of at) { for (const k of at) {
if (!iter.hasOwnProperty(k)) return undefined as any as R; // Поле отсутствует if (!iter.hasOwnProperty(k)) return undefined as any as R; // Поле отсутствует
iter = iter[k]; iter = iter[k] as any;
} }
return iter; return iter;
} }
} }
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