修复 tsc 错误

This commit is contained in:
2betop 2020-05-27 19:31:50 +08:00
parent e15b98aced
commit 4f7a0bfa62
36 changed files with 483 additions and 394 deletions

View File

@ -11,15 +11,14 @@ rm -rf lib/node_modules
rm -rf sdk && fis3 release publish-sdk -c rm -rf sdk && fis3 release publish-sdk -c
# 生成 .d.ts 文件 # 生成 .d.ts 文件
tsc --allowJs --declaration || true tsc --allowJs --declaration
cd output; cd output
for f in `find . -name "*.d.ts"`; for f in $(find . -name "*.d.ts"); do
do mkdir -p ../lib/`dirname $f` && mv $f ../lib/`dirname $f`; mkdir -p ../lib/$(dirname $f) && mv $f ../lib/$(dirname $f)
done done
cd ..; cd ..
rm -rf output rm -rf output

View File

@ -7,7 +7,7 @@
import React from 'react'; import React from 'react';
import cx from 'classnames'; import cx from 'classnames';
import {findDOMNode} from 'react-dom'; import {findDOMNode} from 'react-dom';
import {SketchPicker, GithubPicker, ColorResult} from 'react-color'; import {SketchPicker, GithubPicker, ColorState} from 'react-color';
import {Icon} from './icons'; import {Icon} from './icons';
import Overlay from './Overlay'; import Overlay from './Overlay';
import uncontrollable from 'uncontrollable'; import uncontrollable from 'uncontrollable';
@ -177,7 +177,7 @@ export class ColorControl extends React.PureComponent<
return image.style.color !== 'rgb(255, 255, 255)'; return image.style.color !== 'rgb(255, 255, 255)';
} }
handleChange(color: ColorResult) { handleChange(color: ColorState) {
const { const {
onChange, onChange,
format format

View File

@ -66,4 +66,6 @@ class InputInner extends React.Component<InputProps, InputState> {
export default React.forwardRef<HTMLInputElement>((props, ref) => { export default React.forwardRef<HTMLInputElement>((props, ref) => {
return <InputInner {...props} forwardedRef={ref} />; return <InputInner {...props} forwardedRef={ref} />;
}) as React.ReactType<React.InputHTMLAttributes<HTMLInputElement>>; }) as React.ComponentType<
React.InputHTMLAttributes<HTMLInputElement> & {ref?: any}
>;

View File

@ -5,6 +5,7 @@
*/ */
import React from 'react'; import React from 'react';
// @ts-ignore
import VisibilitySensor from 'react-visibility-sensor'; import VisibilitySensor from 'react-visibility-sensor';
import Spinner from './Spinner'; import Spinner from './Spinner';

View File

@ -21,7 +21,7 @@ BasePosition.propTypes.placement = () => null;
class Position extends BasePosition { class Position extends BasePosition {
props: any; props: any;
_lastTarget: any; _lastTarget: any;
setState: Function; setState: (state: any) => void;
updatePosition(target: any) { updatePosition(target: any) {
this._lastTarget = target; this._lastTarget = target;

View File

@ -146,9 +146,7 @@ export class Radios extends React.Component<RadioProps, any> {
multiple: false, multiple: false,
delimiter, delimiter,
valueField, valueField,
options, options
joinValues,
extractValue
}); });
let body: Array<React.ReactNode> = []; let body: Array<React.ReactNode> = [];

View File

@ -24,6 +24,7 @@ interface RangeProps extends RendererProps {
| number; | number;
classPrefix: string; classPrefix: string;
classnames: ClassNamesFn; classnames: ClassNamesFn;
onChange: (value: any) => void;
} }
export class Range extends React.Component<RangeProps, any> { export class Range extends React.Component<RangeProps, any> {
@ -53,12 +54,10 @@ export class Range extends React.Component<RangeProps, any> {
return ( return (
<InputRange <InputRange
{...this.props} {...this.props}
className={className}
classNames={classNames} classNames={classNames}
minValue={min} minValue={min}
maxValue={max} maxValue={max}
value={value} value={value}
multiple={multiple}
/> />
); );
} }

View File

@ -88,16 +88,9 @@ export default class FroalaEditor extends React.Component<any, any> {
this.$element = $(ref); this.$element = $(ref);
this.setContent(true); this.setContent(true);
this.registerEvents(); this.registerEvents();
resizeSensor( resizeSensor(ref.parentElement, () => {
ref.parentElement, $(ref).prev('.fr-box').find('.fr-toolbar').css('width', '');
() => { });
$(ref)
.prev('.fr-box')
.find('.fr-toolbar')
.css('width', '');
},
true
);
this.$editor = this.$element this.$editor = this.$element
.froalaEditor(this.config) .froalaEditor(this.config)
.data('froala.editor').$el; .data('froala.editor').$el;
@ -164,12 +157,12 @@ export default class FroalaEditor extends React.Component<any, any> {
this.registerEvent( this.registerEvent(
this.$element, this.$element,
'froalaEditor.contentChanged', 'froalaEditor.contentChanged',
function() { function () {
self.updateModel(); self.updateModel();
} }
); );
if (this.config.immediateReactModelUpdate) { if (this.config.immediateReactModelUpdate) {
this.registerEvent(this.$editor, 'keyup', function() { this.registerEvent(this.$editor, 'keyup', function () {
self.updateModel(); self.updateModel();
}); });
} }

View File

@ -1,2 +1,3 @@
// @ts-ignore
import Textarea from 'react-textarea-autosize'; import Textarea from 'react-textarea-autosize';
export default Textarea; export default Textarea;

View File

@ -132,8 +132,6 @@ export class TreeSelector extends React.Component<
this.setState({ this.setState({
value: value2array(props.value, { value: value2array(props.value, {
joinValues: props.joinValues,
extractValue: props.extractValue,
multiple: props.multiple, multiple: props.multiple,
delimiter: props.delimiter, delimiter: props.delimiter,
valueField: props.valueField, valueField: props.valueField,
@ -157,8 +155,6 @@ export class TreeSelector extends React.Component<
this.props.options !== nextProps.options this.props.options !== nextProps.options
) { ) {
toUpdate.value = value2array(nextProps.value, { toUpdate.value = value2array(nextProps.value, {
joinValues: nextProps.joinValues,
extractValue: nextProps.extractValue,
multiple: nextProps.multiple, multiple: nextProps.multiple,
delimiter: nextProps.delimiter, delimiter: nextProps.delimiter,
valueField: nextProps.valueField, valueField: nextProps.valueField,
@ -597,8 +593,10 @@ export class TreeSelector extends React.Component<
{showIcon ? ( {showIcon ? (
<i <i
className={cx( className={cx(
`Tree-itemIcon ${item[iconField] || `Tree-itemIcon ${
(childrenItems ? 'Tree-folderIcon' : 'Tree-leafIcon')}` item[iconField] ||
(childrenItems ? 'Tree-folderIcon' : 'Tree-leafIcon')
}`
)} )}
/> />
) : null} ) : null}

View File

@ -33,8 +33,8 @@ export interface AudioState {
export class Audio extends React.Component<AudioProps, AudioState> { export class Audio extends React.Component<AudioProps, AudioState> {
audio: any; audio: any;
progressTimeout: number; progressTimeout: NodeJS.Timeout;
durationTimeout: number; durationTimeout: NodeJS.Timeout;
static defaultProps: Pick< static defaultProps: Pick<
AudioProps, AudioProps,

View File

@ -74,8 +74,8 @@ const defaultSchema = {
export class Carousel extends React.Component<CarouselProps, CarouselState> { export class Carousel extends React.Component<CarouselProps, CarouselState> {
wrapperRef: React.RefObject<HTMLDivElement> = React.createRef(); wrapperRef: React.RefObject<HTMLDivElement> = React.createRef();
intervalTimeout: number; intervalTimeout: NodeJS.Timer;
durationTimeout: number; durationTimeout: NodeJS.Timer;
static defaultProps: Pick< static defaultProps: Pick<
CarouselProps, CarouselProps,

View File

@ -24,10 +24,10 @@ export default class Container<T> extends React.Component<
<div className={cx('Container-body', bodyClassName)}> <div className={cx('Container-body', bodyClassName)}>
{children {children
? typeof children === 'function' ? typeof children === 'function'
? (children(this.props) as JSX.Element) ? ((children as any)(this.props) as JSX.Element)
: (children as JSX.Element) : (children as JSX.Element)
: body : body
? (render('body', body) as JSX.Element) ? (render('body', body as any) as JSX.Element)
: null} : null}
</div> </div>
); );

View File

@ -37,7 +37,7 @@ export default class ArrayControl extends React.Component<ArrayProps> {
return ( return (
<Combo <Combo
{...rest} {...(rest as any)}
controls={[items]} controls={[items]}
flat flat
multiple multiple

View File

@ -3,7 +3,7 @@ import {FormItem, FormControlProps} from './Item';
import cx from 'classnames'; import cx from 'classnames';
import {Button} from '../../types'; import {Button} from '../../types';
export interface ButtonProps extends FormControlProps, Button {} export interface ButtonProps extends FormControlProps, Omit<Button, 'size'> {}
export class ButtonControl extends React.Component<ButtonProps, any> { export class ButtonControl extends React.Component<ButtonProps, any> {
static defaultProps: Partial<ButtonProps> = {}; static defaultProps: Partial<ButtonProps> = {};

View File

@ -22,7 +22,7 @@ import {dataMapping, resolveVariable} from '../../utils/tpl-builtin';
import {isEffectiveApi} from '../../utils/api'; import {isEffectiveApi} from '../../utils/api';
import {Alert2} from '../../components'; import {Alert2} from '../../components';
import memoize from 'lodash/memoize'; import memoize from 'lodash/memoize';
import {Icon}from '../../components/icons' import {Icon} from '../../components/icons';
export interface Condition { export interface Condition {
test: string; test: string;
controls: Array<Schema>; controls: Array<Schema>;
@ -31,11 +31,11 @@ export interface Condition {
mode?: string; mode?: string;
} }
function pickVars(vars:any, fields: Array<string>) { function pickVars(vars: any, fields: Array<string>) {
return fields.reduce((data:any, key: string) => { return fields.reduce((data: any, key: string) => {
data[key] = resolveVariable(key, vars); data[key] = resolveVariable(key, vars);
return data; return data;
}, {}) }, {});
} }
export interface ComboProps extends FormControlProps { export interface ComboProps extends FormControlProps {
@ -80,7 +80,25 @@ export interface ComboProps extends FormControlProps {
} }
export default class ComboControl extends React.Component<ComboProps> { export default class ComboControl extends React.Component<ComboProps> {
static defaultProps = { static defaultProps: Pick<
ComboProps,
| 'minLength'
| 'maxLength'
| 'multiple'
| 'multiLine'
| 'addButtonClassName'
| 'formClassName'
| 'subFormMode'
| 'draggableTip'
| 'addButtonText'
| 'canAccessSuperData'
| 'addIcon'
| 'dragIcon'
| 'deleteIcon'
| 'tabsMode'
| 'tabsStyle'
| 'placeholder'
> = {
minLength: 0, minLength: 0,
maxLength: 0, maxLength: 0,
multiple: false, multiple: false,
@ -188,13 +206,19 @@ export default class ComboControl extends React.Component<ComboProps> {
// combo 进来了新的值,且这次 form 初始化时带来的新值变化,但是之前的值已经 onInit 过了 // combo 进来了新的值,且这次 form 初始化时带来的新值变化,但是之前的值已经 onInit 过了
// 所以,之前 onInit 设置进去的初始值是过时了的。这个时候修复一下。 // 所以,之前 onInit 设置进去的初始值是过时了的。这个时候修复一下。
if (nextProps.value !== props.value && !props.formInited && this.subFormDefaultValues.length) { if (
this.subFormDefaultValues = this.subFormDefaultValues.map((item, index) => { nextProps.value !== props.value &&
return { !props.formInited &&
...item, this.subFormDefaultValues.length
values: values[index] ) {
this.subFormDefaultValues = this.subFormDefaultValues.map(
(item, index) => {
return {
...item,
values: values[index]
};
} }
}) );
} }
} }
} }
@ -390,7 +414,10 @@ export default class ComboControl extends React.Component<ComboProps> {
setted: false setted: false
}); });
if (syncDefaultValue === false || this.subFormDefaultValues.length !== this.subForms.length) { if (
syncDefaultValue === false ||
this.subFormDefaultValues.length !== this.subForms.length
) {
return; return;
} }
@ -429,11 +456,15 @@ export default class ComboControl extends React.Component<ComboProps> {
handleSingleFormInit(values: any) { handleSingleFormInit(values: any) {
const {syncDefaultValue, setPrinstineValue, value, nullable} = this.props; const {syncDefaultValue, setPrinstineValue, value, nullable} = this.props;
if (
if (syncDefaultValue !== false && !nullable && isObjectShallowModified(value, values) && setPrinstineValue) { syncDefaultValue !== false &&
!nullable &&
isObjectShallowModified(value, values) &&
setPrinstineValue
) {
setPrinstineValue({ setPrinstineValue({
...values ...values
}) });
} }
} }
@ -559,17 +590,33 @@ export default class ComboControl extends React.Component<ComboProps> {
} }
memoizedFormatValue = memoize( memoizedFormatValue = memoize(
(strictMode: boolean, syncFields: Array<string> | void, value: any, index: number, data: any) => { (
strictMode: boolean,
syncFields: Array<string> | void,
value: any,
index: number,
data: any
) => {
return createObject( return createObject(
extendObject(data, {index, __index: index, ...data}), extendObject(data, {index, __index: index, ...data}),
{ {
...value, ...value,
...Array.isArray(syncFields) ? pickVars(data, syncFields!) : null ...(Array.isArray(syncFields) ? pickVars(data, syncFields!) : null)
} }
); );
}, },
(strictMode: boolean, syncFields: Array<string> | void, value: any, index: number, data: any) => (
Array.isArray(syncFields) ? JSON.stringify([value, index, data, pickVars(data, syncFields)]): strictMode ? JSON.stringify([value, index]) : JSON.stringify([value, index, data]) strictMode: boolean,
syncFields: Array<string> | void,
value: any,
index: number,
data: any
) =>
Array.isArray(syncFields)
? JSON.stringify([value, index, data, pickVars(data, syncFields)])
: strictMode
? JSON.stringify([value, index])
: JSON.stringify([value, index, data])
); );
formatValue(value: any, index: number = -1) { formatValue(value: any, index: number = -1) {
@ -583,7 +630,13 @@ export default class ComboControl extends React.Component<ComboProps> {
value = value || this.defaultValue; value = value || this.defaultValue;
return this.memoizedFormatValue(strictMode !== false, syncFields, value, index, data); return this.memoizedFormatValue(
strictMode !== false,
syncFields,
value,
index,
data
);
} }
pickCondition(value: any): Condition | null { pickCondition(value: any): Condition | null {
@ -633,14 +686,15 @@ export default class ComboControl extends React.Component<ComboProps> {
} }
@autobind @autobind
setNull(e:React.MouseEvent) { setNull(e: React.MouseEvent) {
e.preventDefault(); e.preventDefault();
const {onChange} = this.props; const {onChange} = this.props;
onChange(null); onChange(null);
Array.isArray(this.subForms) && this.subForms.forEach(subForm => { Array.isArray(this.subForms) &&
subForm.clearErrors(); this.subForms.forEach(subForm => {
}); subForm.clearErrors();
});
} }
renderPlaceholder() { renderPlaceholder() {
@ -694,7 +748,7 @@ export default class ComboControl extends React.Component<ComboProps> {
return ( return (
<CTabs <CTabs
className={"ComboTabs"} className={'ComboTabs'}
mode={tabsStyle} mode={tabsStyle}
activeKey={store.activeKey} activeKey={store.activeKey}
onSelect={this.handleTabSelect} onSelect={this.handleTabSelect}
@ -724,7 +778,11 @@ export default class ComboControl extends React.Component<ComboProps> {
} }
) )
) : ( ) : (
<a onClick={this.addItem} data-position="left" data-tooltip="新增一条数据"> <a
onClick={this.addItem}
data-position="left"
data-tooltip="新增一条数据"
>
{addIcon ? <i className={cx('m-r-xs', addIcon)} /> : null} {addIcon ? <i className={cx('m-r-xs', addIcon)} /> : null}
<span>{addButtonText || '新增'}</span> <span>{addButtonText || '新增'}</span>
</a> </a>
@ -753,7 +811,11 @@ export default class ComboControl extends React.Component<ComboProps> {
data-tooltip="删除" data-tooltip="删除"
data-position="bottom" data-position="bottom"
> >
{deleteIcon ? <i className={deleteIcon} /> : <Icon icon="close" /> } {deleteIcon ? (
<i className={deleteIcon} />
) : (
<Icon icon="close" />
)}
</a> </a>
); );
} }
@ -891,145 +953,150 @@ export default class ComboControl extends React.Component<ComboProps> {
multiLine ? `Combo--ver` : `Combo--hor`, multiLine ? `Combo--ver` : `Combo--hor`,
noBorder ? `Combo--noBorder` : '', noBorder ? `Combo--noBorder` : '',
disabled ? 'is-disabled' : '', disabled ? 'is-disabled' : '',
(!disabled && draggable && Array.isArray(value) && value.length > 1) ? 'is-draggable' : '', !disabled && draggable && Array.isArray(value) && value.length > 1
? 'is-draggable'
: ''
)} )}
> >
<div className={cx(`Combo-items`)}> <div className={cx(`Combo-items`)}>
{Array.isArray(value) && value.length {Array.isArray(value) && value.length ? (
? value.map((value, index, thelist) => { value.map((value, index, thelist) => {
const toolbar: Array<any> = []; const toolbar: Array<any> = [];
// if (!disabled && draggable && thelist.length > 1) { // if (!disabled && draggable && thelist.length > 1) {
// toolbar.push( // toolbar.push(
// <a // <a
// key="drag" // key="drag"
// className={cx(`Combo-toolbarBtn Combo-itemDrager`)} // className={cx(`Combo-toolbarBtn Combo-itemDrager`)}
// data-tooltip="拖拽排序" // data-tooltip="拖拽排序"
// data-position="bottom" // data-position="bottom"
// > // >
// <i className={dragIcon} /> // <i className={dragIcon} />
// </a> // </a>
// ); // );
// } // }
if ( if (
finnalRemovable && // 表达式判断单条是否可删除 finnalRemovable && // 表达式判断单条是否可删除
(!itemRemovableOn || (!itemRemovableOn ||
evalExpression(itemRemovableOn, value) !== false) evalExpression(itemRemovableOn, value) !== false)
) { ) {
toolbar.push( toolbar.push(
<a <a
onClick={this.removeItem.bind(this, index)} onClick={this.removeItem.bind(this, index)}
key="remove" key="remove"
className={cx( className={cx(
`Combo-toolbarBtn ${ `Combo-toolbarBtn ${
!store.removable ? 'is-disabled' : '' !store.removable ? 'is-disabled' : ''
}` }`
)} )}
data-tooltip="删除" data-tooltip="删除"
data-position="bottom" data-position="bottom"
>
{deleteIcon ? <i className={deleteIcon} /> : <Icon icon="close" /> }
</a>
);
}
const data = this.formatValue(value, index);
let condition: Condition | null = null;
if (Array.isArray(conditions) && conditions.length) {
condition = this.pickCondition(data);
controls = condition ? condition.controls : undefined;
}
let finnalControls =
flat && controls
? [
{
...(controls && controls[0]),
name: 'flat'
}
]
: controls;
return (
<div
className={cx(`Combo-item`)}
key={this.keys[index] || (this.keys[index] = guid())}
> >
{!disabled && draggable && thelist.length > 1 ? ( {deleteIcon ? (
<div className={cx('Combo-itemDrager')}> <i className={deleteIcon} />
<a ) : (
key="drag" <Icon icon="close" />
data-tooltip="拖拽排序" )}
data-position="bottom" </a>
>
{dragIcon ? ( <i className={dragIcon} /> ): <Icon icon="combo-dragger"/> }
</a>
</div>
): null}
{condition && typeSwitchable !== false ? (
<div className={cx('Combo-itemTag')}>
<label></label>
<Select
onChange={this.handleComboTypeChange.bind(
this,
index
)}
options={(conditions as Array<Condition>).map(
item => ({
label: item.label,
value: item.label
})
)}
value={condition.label}
clearable={false}
/>
</div>
) : null}
<div className={cx(`Combo-itemInner`)}>
{finnalControls ? (
render(
`multiple/${index}`,
{
type: 'form',
controls: finnalControls,
wrapperComponent: 'div',
wrapWithPanel: false,
mode: multiLine ? subFormMode : 'row',
className: cx(`Combo-form`, formClassName)
},
{
index,
disabled,
data,
onChange: this.handleChange,
onInit: this.handleFormInit,
onAction: this.handleAction,
ref: this.makeFormRef(index),
lazyChange: changeImmediately ? false : true,
lazyFormChange: changeImmediately ? false : true,
lazyLoad,
canAccessSuperData,
value: undefined,
formItemValue: undefined
}
)
) : (
<Alert2 level="warning" className="m-b-none">
</Alert2>
)}
</div>
{toolbar.length ? (
<div className={cx(`Combo-itemToolbar`)}>{toolbar}</div>
) : null}
</div>
); );
}) }
: placeholder ? (
const data = this.formatValue(value, index);
let condition: Condition | null = null;
if (Array.isArray(conditions) && conditions.length) {
condition = this.pickCondition(data);
controls = condition ? condition.controls : undefined;
}
let finnalControls =
flat && controls
? [
{
...(controls && controls[0]),
name: 'flat'
}
]
: controls;
return (
<div
className={cx(`Combo-item`)}
key={this.keys[index] || (this.keys[index] = guid())}
>
{!disabled && draggable && thelist.length > 1 ? (
<div className={cx('Combo-itemDrager')}>
<a
key="drag"
data-tooltip="拖拽排序"
data-position="bottom"
>
{dragIcon ? (
<i className={dragIcon} />
) : (
<Icon icon="combo-dragger" />
)}
</a>
</div>
) : null}
{condition && typeSwitchable !== false ? (
<div className={cx('Combo-itemTag')}>
<label></label>
<Select
onChange={this.handleComboTypeChange.bind(this, index)}
options={(conditions as Array<Condition>).map(item => ({
label: item.label,
value: item.label
}))}
value={condition.label}
clearable={false}
/>
</div>
) : null}
<div className={cx(`Combo-itemInner`)}>
{finnalControls ? (
render(
`multiple/${index}`,
{
type: 'form',
controls: finnalControls,
wrapperComponent: 'div',
wrapWithPanel: false,
mode: multiLine ? subFormMode : 'row',
className: cx(`Combo-form`, formClassName)
},
{
index,
disabled,
data,
onChange: this.handleChange,
onInit: this.handleFormInit,
onAction: this.handleAction,
ref: this.makeFormRef(index),
lazyChange: changeImmediately ? false : true,
lazyFormChange: changeImmediately ? false : true,
lazyLoad,
canAccessSuperData,
value: undefined,
formItemValue: undefined
}
)
) : (
<Alert2 level="warning" className="m-b-none">
</Alert2>
)}
</div>
{toolbar.length ? (
<div className={cx(`Combo-itemToolbar`)}>{toolbar}</div>
) : null}
</div>
);
})
) : placeholder ? (
<div className={cx(`Combo-placeholder`)}>{placeholder}</div> <div className={cx(`Combo-placeholder`)}>{placeholder}</div>
) : null} ) : null}
</div> </div>
{!disabled ? ( {!disabled ? (
<div className={cx(`Combo-toolbar`)}> <div className={cx(`Combo-toolbar`)}>
@ -1092,7 +1159,7 @@ export default class ComboControl extends React.Component<ComboProps> {
noBorder, noBorder,
disabled, disabled,
typeSwitchable, typeSwitchable,
nullable, nullable
} = this.props; } = this.props;
let controls = this.props.controls; let controls = this.props.controls;
@ -1157,13 +1224,24 @@ export default class ComboControl extends React.Component<ComboProps> {
)} )}
</div> </div>
</div> </div>
{value && nullable ? (<a className={cx('Combo-setNullBtn')} href="#" onClick={this.setNull}></a>) : null} {value && nullable ? (
<a className={cx('Combo-setNullBtn')} href="#" onClick={this.setNull}>
</a>
) : null}
</div> </div>
); );
} }
render() { render() {
const {formInited, multiple, className, classPrefix: ns, classnames: cx, disabled} = this.props; const {
formInited,
multiple,
className,
classPrefix: ns,
classnames: cx,
disabled
} = this.props;
return formInited ? ( return formInited ? (
<div className={cx(`ComboControl`, className)}> <div className={cx(`ComboControl`, className)}>

View File

@ -3,8 +3,11 @@ import {Renderer} from '../../factory';
import cx from 'classnames'; import cx from 'classnames';
import Container from '../Container'; import Container from '../Container';
import FormItem, {FormControlProps} from './Item'; import FormItem, {FormControlProps} from './Item';
import {IIRendererStore} from '../../store/iRenderer';
export interface ContainerProps extends FormControlProps {} export interface ContainerProps extends FormControlProps {
store: IIRendererStore;
}
@FormItem({ @FormItem({
type: 'container', type: 'container',

View File

@ -6,8 +6,11 @@ import {FormItem, FormControlProps} from './Item';
import pick from 'lodash/pick'; import pick from 'lodash/pick';
import React from 'react'; import React from 'react';
import cx from 'classnames'; import cx from 'classnames';
import {IIRendererStore} from '../../store/iRenderer';
export interface GridProps extends FormControlProps {} export interface GridProps extends FormControlProps {
store: IIRendererStore;
}
const defaultHorizontal = { const defaultHorizontal = {
left: 'col-sm-4', left: 'col-sm-4',
right: 'col-sm-8', right: 'col-sm-8',
@ -36,13 +39,17 @@ export class GridRenderer extends Grid<GridProps> {
if (node && !node.type && (node.controls || node.tabs || node.feildSet)) { if (node && !node.type && (node.controls || node.tabs || node.feildSet)) {
return ( return (
<div className={cx(`Grid-form Form--${node.mode || 'normal'}`)}> <div className={cx(`Grid-form Form--${node.mode || 'normal'}`)}>
{renderFormItems(node, ($path as string).replace(/^.*form\//, ''), { {renderFormItems(
mode: node.mode || 'normal', node as any,
horizontal: node.horizontal || defaultHorizontal, ($path as string).replace(/^.*form\//, ''),
store, {
data: store.data, mode: node.mode || 'normal',
render horizontal: node.horizontal || defaultHorizontal,
})} store,
data: store.data,
render
}
)}
</div> </div>
); );
} }

View File

@ -5,9 +5,10 @@ import HBox from '../HBox';
import {Schema} from '../../types'; import {Schema} from '../../types';
import cx from 'classnames'; import cx from 'classnames';
import {isVisible} from '../../utils/helper'; import {isVisible} from '../../utils/helper';
import {IIRendererStore} from '../../store/iRenderer';
interface HBoxProps extends FormControlProps { interface HBoxProps extends FormControlProps {
size?: string; store: IIRendererStore;
} }
@FormItem({ @FormItem({
@ -53,17 +54,21 @@ export class HBoxRenderer extends React.Component<HBoxProps, any> {
const {render, renderFormItems, formMode, store, $path} = this.props; const {render, renderFormItems, formMode, store, $path} = this.props;
if (node && !node.type && (node.controls || node.tabs || node.feildSet)) { if (node && !node.type && (node.controls || node.tabs || node.feildSet)) {
return renderFormItems(node, ($path as string).replace(/^.*form\//, ''), { return renderFormItems(
mode: node.mode || 'normal', node as any,
horizontal: node.horizontal || { ($path as string).replace(/^.*form\//, ''),
left: 4, {
right: 8, mode: node.mode || 'normal',
offset: 4 horizontal: node.horizontal || {
}, left: 4,
store, right: 8,
data: store.data, offset: 4
render },
}); store,
data: store.data,
render
}
);
} }
return render(region, node.body || node); return render(region, node.body || node);

View File

@ -1,5 +1,6 @@
import React from 'react'; import React from 'react';
import cx from 'classnames'; import cx from 'classnames';
// @ts-ignore
import matchSorter from 'match-sorter'; import matchSorter from 'match-sorter';
import keycode from 'keycode'; import keycode from 'keycode';
import Downshift, {StateChangeOptions} from 'downshift'; import Downshift, {StateChangeOptions} from 'downshift';

View File

@ -11,10 +11,11 @@ import {
import cx from 'classnames'; import cx from 'classnames';
import getExprProperties from '../../utils/filter-schema'; import getExprProperties from '../../utils/filter-schema';
import {FormItem, FormControlProps} from './Item'; import {FormItem, FormControlProps} from './Item';
import {IFormStore} from '../../store/form';
export interface InputGroupProps extends FormControlProps { export interface InputGroupProps extends FormControlProps {
controls: Array<any>; controls: Array<any>;
size?: 'xs' | 'sm' | 'normal'; formStore: IFormStore;
} }
interface InputGroupState { interface InputGroupState {
@ -115,7 +116,8 @@ export class InputGroup extends React.Component<
}); });
let horizontalDeeper = let horizontalDeeper =
horizontal || makeHorizontalDeeper(formHorizontal, controls.length); horizontal ||
makeHorizontalDeeper(formHorizontal as any, controls.length);
return ( return (
<div <div
className={cx(`InputGroup`, className, { className={cx(`InputGroup`, className, {

View File

@ -770,117 +770,116 @@ export function asFormItem(config: Omit<FormItemConfig, 'component'>) {
delete config.storeType; delete config.storeType;
} }
// @observer return hoistNonReactStatic(
class FormItemRenderer extends FormItemWrap { class extends FormItemWrap {
static defaultProps = { static defaultProps = {
className: '', className: '',
renderLabel: config.renderLabel, renderLabel: config.renderLabel,
renderDescription: config.renderDescription, renderDescription: config.renderDescription,
sizeMutable: config.sizeMutable, sizeMutable: config.sizeMutable,
wrap: config.wrap, wrap: config.wrap,
...Control.defaultProps ...Control.defaultProps
}; };
static propsList: any = [ static propsList: any = [
'value', 'value',
'defaultValue', 'defaultValue',
'onChange', 'onChange',
'setPrinstineValue', 'setPrinstineValue',
'readOnly', 'readOnly',
'strictMode', 'strictMode',
...((Control as any).propsList || []) ...((Control as any).propsList || [])
]; ];
static displayName = `FormItem${config.type ? `(${config.type})` : ''}`; static displayName = `FormItem${config.type ? `(${config.type})` : ''}`;
static ComposedComponent = Control; static ComposedComponent = Control;
ref: any; ref: any;
constructor(props: FormItemProps) { constructor(props: FormItemProps) {
super(props); super(props);
this.refFn = this.refFn.bind(this); this.refFn = this.refFn.bind(this);
}
componentWillMount() {
const {validations, formItem: model} = this.props;
// 组件注册的时候可能默认指定验证器类型
if (model && !validations && config.validations) {
model.config({
rules: config.validations
});
} }
super.componentWillMount(); componentWillMount() {
} const {validations, formItem: model} = this.props;
shouldComponentUpdate(nextProps: FormControlProps) { // 组件注册的时候可能默认指定验证器类型
if (nextProps.strictMode === false || config.strictMode === false) { if (model && !validations && config.validations) {
return true; model.config({
rules: config.validations
});
}
super.componentWillMount();
} }
// 把可能会影响视图的白名单弄出来,减少重新渲染次数。 shouldComponentUpdate(nextProps: FormControlProps) {
if (anyChanged(detectProps, this.props, nextProps)) { if (nextProps.strictMode === false || config.strictMode === false) {
return true; return true;
}
// 把可能会影响视图的白名单弄出来,减少重新渲染次数。
if (anyChanged(detectProps, this.props, nextProps)) {
return true;
}
return false;
} }
return false; getWrappedInstance() {
} return this.ref;
}
getWrappedInstance() { refFn(ref: any) {
return this.ref; this.ref = ref;
} }
refFn(ref: any) { renderControl() {
this.ref = ref; const {
} inputClassName,
formItem: model,
classnames: cx,
children,
type,
size,
defaultSize,
...rest
} = this.props;
renderControl() { const controlSize = size || defaultSize;
const {
inputClassName,
formItem: model,
classnames: cx,
children,
type,
size,
defaultSize,
...rest
} = this.props;
const controlSize = size || defaultSize; return (
<Control
return ( {...rest}
<Control onOpenDialog={this.handleOpenDialog}
{...rest} size={config.sizeMutable !== false ? undefined : size}
onOpenDialog={this.handleOpenDialog} onFocus={this.handleFocus}
size={config.sizeMutable !== false ? undefined : size} onBlur={this.handleBlur}
onFocus={this.handleFocus} type={type}
onBlur={this.handleBlur} classnames={cx}
type={type} ref={isSFC ? undefined : this.refFn}
classnames={cx} formItem={model}
ref={isSFC ? undefined : this.refFn} className={cx(
formItem={model} `Form-control`,
className={cx( {
`Form-control`, 'is-inline': !!rest.inline,
{ 'is-error': model && !model.valid,
'is-inline': !!rest.inline, [`Form-control--withSize Form-control--size${ucFirst(
'is-error': model && !model.valid, controlSize
[`Form-control--withSize Form-control--size${ucFirst( )}`]:
controlSize config.sizeMutable !== false &&
)}`]: typeof controlSize === 'string' &&
config.sizeMutable !== false && !!controlSize &&
typeof controlSize === 'string' && controlSize !== 'full'
!!controlSize && },
controlSize !== 'full' inputClassName
}, )}
inputClassName />
)} );
/> }
); },
} Control
} );
hoistNonReactStatic(FormItemRenderer, Control);
return FormItemRenderer;
}; };
} }

View File

@ -253,7 +253,7 @@ export default class NestedSelectControl extends React.Component<
) )
? xorBy ? xorBy
: unionBy; : unionBy;
newValue = fn(items, option, valueField || 'value'); newValue = fn(items, option as any, valueField || 'value');
} else { } else {
newValue = items.filter( newValue = items.filter(
item => item =>
@ -406,10 +406,10 @@ export default class NestedSelectControl extends React.Component<
> >
<Icon icon="search" className="icon" /> <Icon icon="search" className="icon" />
<Input <Input
value={this.state.inputValue} value={this.state.inputValue || ''}
onFocus={this.onFocus} onFocus={this.onFocus}
onBlur={this.onBlur} onBlur={this.onBlur}
disabled={disabled} disabled={disabled!!}
placeholder={searchPromptText} placeholder={searchPromptText}
onChange={this.handleInputChange} onChange={this.handleInputChange}
ref={this.inputRef} ref={this.inputRef}

View File

@ -1,6 +1,7 @@
import React from 'react'; import React from 'react';
import {FormItem, FormControlProps} from './Item'; import {FormItem, FormControlProps} from './Item';
import cx from 'classnames'; import cx from 'classnames';
// @ts-ignore
import InputNumber from 'rc-input-number'; import InputNumber from 'rc-input-number';
import {filter} from '../../utils/tpl'; import {filter} from '../../utils/tpl';

View File

@ -37,7 +37,6 @@ export default class RatingControl extends React.Component<RatingProps, any> {
count={count} count={count}
half={half} half={half}
readOnly={readOnly} readOnly={readOnly}
size={size}
onChange={(value: any) => onChange(value)} onChange={(value: any) => onChange(value)}
/> />
</div> </div>

View File

@ -84,7 +84,7 @@ const eighties = {
} }
}; };
const themes = { const themes: any = {
twilight, twilight,
eighties eighties
}; };

View File

@ -31,7 +31,7 @@ export class OperationField extends React.Component<OperationProps, object> {
level: level:
button.level || button.level ||
(button.icon && !button.label ? 'link' : ''), (button.icon && !button.label ? 'link' : ''),
...button ...(button as any)
}, },
{ {
key: index key: index

View File

@ -3,6 +3,7 @@ import cx from 'classnames';
import {Renderer, RendererProps} from '../factory'; import {Renderer, RendererProps} from '../factory';
import {FormItem, FormControlProps} from './Form/Item'; import {FormItem, FormControlProps} from './Form/Item';
import {filter} from '../utils/tpl'; import {filter} from '../utils/tpl';
// @ts-ignore
import QrCode from 'qrcode.react'; import QrCode from 'qrcode.react';
export interface QRCodeProps extends FormControlProps { export interface QRCodeProps extends FormControlProps {

View File

@ -28,7 +28,7 @@ export interface ServiceProps extends RendererProps {
}; };
} }
export default class Service extends React.Component<ServiceProps> { export default class Service extends React.Component<ServiceProps> {
timer: number; timer: NodeJS.Timeout;
mounted: boolean; mounted: boolean;
static defaultProps: Partial<ServiceProps> = { static defaultProps: Partial<ServiceProps> = {

View File

@ -5,12 +5,14 @@
/* eslint fecs-indent: [0, "space", 2, 2] */ /* eslint fecs-indent: [0, "space", 2, 2] */
import React from 'react'; import React from 'react';
import { import {
Player, Player,
Shortcut, Shortcut,
BigPlayButton, BigPlayButton,
ControlBar, ControlBar,
PlaybackRateMenuButton PlaybackRateMenuButton
// @ts-ignore
} from 'video-react'; } from 'video-react';
import {padArr} from '../utils/helper'; import {padArr} from '../utils/helper';
import cx from 'classnames'; import cx from 'classnames';
@ -315,10 +317,9 @@ export default class Video extends React.Component<VideoProps, VideoState> {
const rect = item.getBoundingClientRect(); const rect = item.getBoundingClientRect();
this.cursorDom.setAttribute( this.cursorDom.setAttribute(
'style', 'style',
`width: ${rect.width - 4}px; height: ${rect.height - `width: ${rect.width - 4}px; height: ${rect.height - 4}px; left: ${
4}px; left: ${rect.left + 2 - frameRect.left}px; top: ${rect.top + rect.left + 2 - frameRect.left
2 - }px; top: ${rect.top + 2 - frameRect.top}px;`
frameRect.top}px;`
); );
} }
} }
@ -405,14 +406,16 @@ export default class Video extends React.Component<VideoProps, VideoState> {
</div> </div>
))} ))}
{/* 补充空白 */ restCount {
? blankArray.map((_, index) => ( /* 补充空白 */ restCount
<div ? blankArray.map((_, index) => (
className={`${ns}Hbox-col Wrapper--xxs`} <div
key={`blank_${index}`} className={`${ns}Hbox-col Wrapper--xxs`}
/> key={`blank_${index}`}
)) />
: null} ))
: null
}
</div> </div>
</div> </div>
); );

View File

@ -333,6 +333,7 @@ export const CRUDStore = ServiceStore.named('CRUDStore')
console.error(e.stack); console.error(e.stack);
root.notify('error', e.message); root.notify('error', e.message);
return;
} }
}); });
@ -432,7 +433,7 @@ export const CRUDStore = ServiceStore.named('CRUDStore')
self.hasInnerModalOpen = value; self.hasInnerModalOpen = value;
}; };
const initFromScope = function(scope: any, source: string) { const initFromScope = function (scope: any, source: string) {
let rowsData: Array<any> = resolveVariableAndFilter( let rowsData: Array<any> = resolveVariableAndFilter(
source, source,
scope, scope,

View File

@ -144,6 +144,7 @@ export const ServiceStore = iRendererStore
markFetching(false); markFetching(false);
e.stack && console.error(e.stack); e.stack && console.error(e.stack);
root.notify('error', e.message || e); root.notify('error', e.message || e);
return;
} }
}); });
@ -234,6 +235,7 @@ export const ServiceStore = iRendererStore
markFetching(false); markFetching(false);
e.stack && console.error(e.stack); e.stack && console.error(e.stack);
root.notify('error', e.message || e); root.notify('error', e.message || e);
return;
} }
}); });

View File

@ -126,38 +126,41 @@ export function themeable<
classnames?: ClassNamesFn; classnames?: ClassNamesFn;
}; };
class EnhancedComponent extends React.Component<Props> { const result = hoistNonReactStatic(
static displayName = `Themeable(${ class extends React.Component<Props> {
ComposedComponent.displayName || ComposedComponent.name static displayName = `Themeable(${
})`; ComposedComponent.displayName || ComposedComponent.name
static contextType = ThemeContext; })`;
static ComposedComponent = ComposedComponent; static contextType = ThemeContext;
static ComposedComponent = ComposedComponent;
render() { render() {
const theme: string = this.props.theme || this.context || defaultTheme; const theme: string = this.props.theme || this.context || defaultTheme;
const config = hasTheme(theme) ? getTheme(theme) : getTheme(defaultTheme); const config = hasTheme(theme)
const injectedProps: { ? getTheme(theme)
classPrefix: string; : getTheme(defaultTheme);
classnames: ClassNamesFn; const injectedProps: {
} = { classPrefix: string;
classPrefix: config.classPrefix as string, classnames: ClassNamesFn;
classnames: config.classnames } = {
}; classPrefix: config.classPrefix as string,
classnames: config.classnames
};
return ( return (
<ThemeContext.Provider value={theme}> <ThemeContext.Provider value={theme}>
<ComposedComponent <ComposedComponent
{ {
...(this.props as any) /* todo, 解决这个类型问题 */ ...(this.props as any) /* todo, 解决这个类型问题 */
} }
{...injectedProps} {...injectedProps}
/> />
</ThemeContext.Provider> </ThemeContext.Provider>
); );
} }
} },
ComposedComponent
const result = hoistNonReactStatic(EnhancedComponent, ComposedComponent); );
return result as typeof result & { return result as typeof result & {
ComposedComponent: T; ComposedComponent: T;

View File

@ -70,7 +70,7 @@ function getContainerDimensions(containerNode: any) {
getScrollTop(ownerDocument(containerNode).documentElement) || getScrollTop(ownerDocument(containerNode).documentElement) ||
getScrollTop(containerNode); getScrollTop(containerNode);
} else { } else {
({width, height} = getOffset(containerNode)); ({width, height} = getOffset(containerNode) as any);
scroll = getScrollTop(containerNode); scroll = getScrollTop(containerNode);
} }
@ -144,11 +144,13 @@ export function calculatePosition(
container: any, container: any,
padding: any = 0 padding: any = 0
) { ) {
const childOffset = const childOffset: any =
container.tagName === 'BODY' container.tagName === 'BODY'
? getOffset(target) ? getOffset(target)
: getPosition(target, container); : getPosition(target, container);
const {height: overlayHeight, width: overlayWidth} = getOffset(overlayNode); const {height: overlayHeight, width: overlayWidth} = getOffset(
overlayNode
) as any;
const clip = container.getBoundingClientRect(); const clip = container.getBoundingClientRect();
const clip2 = overlayNode.getBoundingClientRect(); const clip2 = overlayNode.getBoundingClientRect();

View File

@ -1,7 +1,7 @@
function property2control(property: any, key: any, schema: any) { function property2control(property: any, key: any, schema: any) {
const requiredList = schema.required || []; const requiredList = schema.required || [];
const rest = {}; const rest: any = {};
const validations = {}; const validations: any = {};
let type = 'text'; let type = 'text';
if (property.type === 'integer') { if (property.type === 'integer') {

View File

@ -3,10 +3,7 @@
"outDir": "output/", "outDir": "output/",
"module": "commonjs", "module": "commonjs",
"target": "es5", "target": "es5",
"lib": [ "lib": ["es6", "dom"],
"es6",
"dom"
],
"sourceMap": true, "sourceMap": true,
"jsx": "react", "jsx": "react",
"moduleResolution": "node", "moduleResolution": "node",
@ -21,14 +18,10 @@
"strictNullChecks": true, "strictNullChecks": true,
"experimentalDecorators": true, "experimentalDecorators": true,
"emitDecoratorMetadata": true, "emitDecoratorMetadata": true,
"typeRoots": [ "typeRoots": ["./node_modules/@types", "./types"],
"./node_modules/@types", "skipLibCheck": true
"./types"
]
}, },
"include": [ "include": ["src/**/*"],
"src/**/*"
],
"exclude": [ "exclude": [
"node_modules", "node_modules",
"build", "build",
@ -37,7 +30,5 @@
"webpack", "webpack",
"jest" "jest"
], ],
"types": [ "types": ["typePatches"]
"typePatches"
]
} }