Commit 91bcfa06 by Vladislav Lagunov

printItem в MultiSelect

parent 82b10bbc
...@@ -14,6 +14,7 @@ import * as ST from '~/fields/AutoComplete/state-machine'; ...@@ -14,6 +14,7 @@ import * as ST from '~/fields/AutoComplete/state-machine';
import * as Rx from 'rxjs'; import * as Rx from 'rxjs';
import { memoize } from '~/utils'; import { memoize } from '~/utils';
import { pick } from 'lodash'; import { pick } from 'lodash';
import classNames = require('classnames');
// Props // Props
...@@ -47,7 +48,7 @@ export type State<A> = AutoCompleteState<A> & { ...@@ -47,7 +48,7 @@ export type State<A> = AutoCompleteState<A> & {
// Component // Component
// @ts-ignore Хак для работы дженерик-параметров // @ts-ignore Хак для работы дженерик-параметров
@withStyles(styles) @withStyles(styles)
export default class AutoComplete<A=string> extends React.PureComponent<Props<A>, State<A>> { export default class AutoComplete<A=string> extends React.Component<Props<A>, State<A>> {
static defaultProps = { static defaultProps = {
openOnFocus: true, openOnFocus: true,
openOnClick: true, openOnClick: true,
...@@ -184,10 +185,13 @@ export default class AutoComplete<A=string> extends React.PureComponent<Props<A> ...@@ -184,10 +185,13 @@ export default class AutoComplete<A=string> extends React.PureComponent<Props<A>
}; };
render() { render() {
const { children, ctx, source, debounce, renderItem, printItem, openOnFocus, openOnClick, suggestionProps, keepOpenAfterSelect, textFieldProps, classes, anchorEl, observable, ...rest } = this.props; const { className, fullWidth, children, ctx, source, debounce, renderItem, printItem, openOnFocus, openOnClick, suggestionProps, keepOpenAfterSelect, textFieldProps, classes, anchorEl, observable, ...rest } = this.props;
const { suggestions, open } = this.state; const { suggestions, open } = this.state;
const rootClass = classNames(classes!.root, className, {
[classes!.fullWidth!]: fullWidth
});
return <div {...rest} className={classes!.wrapper}> return <div {...rest} className={rootClass}>
{!observable && (children ? React.cloneElement(children, this.childrenProps()) : <TextField {...this.childrenProps() as any} {...textFieldProps}/>)} {!observable && (children ? React.cloneElement(children, this.childrenProps()) : <TextField {...this.childrenProps() as any} {...textFieldProps}/>)}
<Suggestions <Suggestions
{...suggestionProps} {...suggestionProps}
...@@ -267,10 +271,14 @@ export function styles(theme: Theme): StyleRules { ...@@ -267,10 +271,14 @@ export function styles(theme: Theme): StyleRules {
// const { unit } = theme.spacing; // const { unit } = theme.spacing;
return { return {
wrapper: { root: {
'& > div': { '& > div': {
position: 'relative', position: 'relative',
} }
}, },
fullWidth: {
width: '100%',
},
}; };
} }
...@@ -14,8 +14,9 @@ import { FieldProps } from '~/fields'; ...@@ -14,8 +14,9 @@ import { FieldProps } from '~/fields';
// Props // Props
export type Props<A> = StandardProps<React.HTMLProps<HTMLDivElement>, string, 'value'> & FieldProps & { export type Props<A> = StandardProps<React.HTMLProps<HTMLDivElement>, string, 'value'> & FieldProps & {
source: Source<A>; source: Source<A>;
fullWidth?: boolean;
textFieldProps?: Partial<TextFieldProps>; textFieldProps?: Partial<TextFieldProps>;
renderSuggestion?(a: A): React.ReactNode; renderItem?(a: A, selected: boolean): React.ReactNode;
placeholder?: string; placeholder?: string;
printItem?(a: A): string; printItem?(a: A): string;
id?: string; // Используется для установки `key` пропсов id?: string; // Используется для установки `key` пропсов
...@@ -77,20 +78,23 @@ export default class MultiSelect<A> extends React.Component<Props<A>> { ...@@ -77,20 +78,23 @@ export default class MultiSelect<A> extends React.Component<Props<A>> {
}); });
renderSuggestion = (item: A) => { renderSuggestion = (item: A) => {
const { renderSuggestion, printItem, value } = this.props; const { renderItem, printItem, value } = this.props;
const selected = !!value!.find(x => this.isEqual(x, item)); const selected = !!value!.find(x => this.isEqual(x, item));
const id = this.props.id || 'id'; const id = this.props.id || 'id';
if (renderItem) return renderItem(item, selected);
return <MenuItem key={item[id]} disableRipple> return <MenuItem key={item[id]} disableRipple>
<Checkbox disableRipple checked={selected}/> <Checkbox disableRipple checked={selected}/>
<ListItemText primary={(renderSuggestion || printItem || String)(item)}/> <ListItemText primary={(printItem || String)(item)}/>
</MenuItem>; </MenuItem>;
}; };
render() { render() {
const { classes, className, source, renderSuggestion, printItem, id, textFieldProps, value, error, disabled, onValueChange, placeholder, ...rest } = this.props; const { classes, fullWidth, className, source, renderItem, printItem, id, textFieldProps, value, error, disabled, onValueChange, placeholder, ...rest } = this.props;
const rootClass = classNames(className, classes!.root, { const rootClass = classNames(className, classes!.root, {
[classes!.disabled!]: disabled, [classes!.disabled!]: disabled,
[classes!.fullWidth!]: fullWidth,
}); });
return <div {...rest} className={rootClass}> return <div {...rest} className={rootClass}>
...@@ -99,12 +103,14 @@ export default class MultiSelect<A> extends React.Component<Props<A>> { ...@@ -99,12 +103,14 @@ export default class MultiSelect<A> extends React.Component<Props<A>> {
value={null} value={null}
printItem={printItem} printItem={printItem}
source={source} source={source}
// @ts-ignore
renderItem={this.renderSuggestion} renderItem={this.renderSuggestion}
onValueChange={this.handleValueChange} onValueChange={this.handleValueChange}
textFieldProps={textFieldProps} textFieldProps={textFieldProps}
placeholder={placeholder} placeholder={placeholder}
error={error} error={error}
disabled={disabled} disabled={disabled}
fullWidth={fullWidth}
keepOpenAfterSelect keepOpenAfterSelect
openOnClick openOnClick
openOnFocus openOnFocus
...@@ -136,6 +142,10 @@ export function styles(theme: Theme): StyleRules { ...@@ -136,6 +142,10 @@ export function styles(theme: Theme): StyleRules {
disabled: { disabled: {
cursor: 'not-allowed', cursor: 'not-allowed',
},
fullWidth: {
width: '100%',
}, },
}; };
} }
import * as React from 'react';
import { FieldProps } from './';
import * as F from './';
// Props
export type Props<A> = Partial<FieldProps<A>> & {
Component: React.ReactType<FieldProps<A>>;
};
// Component
export default class WithContext<A> extends React.Component<Props<A>> {
renderConsumer = (context: FieldProps<A>) => {
const { Component, ...rest } = this.props;
// @ts-ignore
return React.createElement(Component, { ...context, ...rest });
};
render() {
return <F.Consumer>{this.renderConsumer}</F.Consumer>;
}
}
...@@ -7,6 +7,7 @@ export { default as Label } from './Label'; ...@@ -7,6 +7,7 @@ export { default as Label } from './Label';
export { default as ResourceID } from './ResourceID'; export { default as ResourceID } from './ResourceID';
export { default as ArrayIDS } from './ArrayIDS'; export { default as ArrayIDS } from './ArrayIDS';
export { default as Debounce } from './Debounce'; export { default as Debounce } from './Debounce';
export { default as WithContext } from './WithContext';
import BooleanField_ from './BooleanField'; import BooleanField_ from './BooleanField';
......
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