import Icons from '@ali/ve-icons'; import classNames from 'classnames'; import { Component } from 'react'; import { testType } from '@ali/ve-utils'; import VEField, { IVEFieldProps } from './field'; import { SettingField } from './settingField'; import VariableSwitcher from './variableSwitcher'; import popups from '@ali/ve-popups'; import './fields.less'; interface IHelpTip { url?: string; content?: string | JSX.Element; } function renderTip(tip: IHelpTip, prop?: { propName?: string }) { const propName = prop && prop.propName; if (!tip) { return (
{propName}
); } if (testType(tip) === 'object') { return (
属性:{propName}
说明:{tip.content}
); } return (
属性:{propName}
说明:{tip}
); } export class PlainField extends VEField { public static defaultProps = { headDIY: true, }; public static displayName = 'PlainField'; public renderHead(): null { return null; } } export class InlineField extends VEField { public static displayName = 'InlineField'; constructor(props: any) { super(props); this.classNames = ['engine-setting-field', 'engine-inline-field']; } public renderFoot() { return (
); } } export class BlockField extends VEField { public static displayName = 'BlockField'; constructor(props: IVEFieldProps) { super(props); this.classNames = ['engine-setting-field', 'engine-block-field', props.isGroup ? 'engine-group-field' : '']; } public renderHead() { const { title, tip, propName } = this.props; return [ {title} , renderTip(tip, { propName }), , ]; } } export class AccordionField extends VEField { public readonly props: IVEFieldProps; private willDetach?: () => any; constructor(props: IVEFieldProps) { super(props); this._generateClassNames(props); if (this.props.onExpandChange) { this.willDetach = this.props.onExpandChange(() => this.forceUpdate()); } } public componentWillReceiveProps(nextProps: IVEFieldProps) { this.classNames = this._generateClassNames(nextProps); } public componentWillUnmount() { if (this.willDetach) { this.willDetach(); } } public renderHead() { const { title, tip, toggleExpand, propName } = this.props; return (
toggleExpand && toggleExpand()}> {title} {renderTip(tip, { propName })} {}
); } private _generateClassNames(props: IVEFieldProps) { this.classNames = [ 'engine-setting-field', 'engine-accordion-field', props.isGroup ? 'engine-group-field' : '', !props.isExpand ? 'engine-collapsed' : '', ]; return this.classNames; } } export class EntryField extends VEField { constructor(props: any) { super(props); this.classNames = ['engine-setting-field', 'engine-entry-field']; } public render() { const { propName, stageName, tip, title } = this.props; const classNameList = classNames(...this.classNames, this.props.className); const fieldProps: any = {}; if (stageName) { // 为 stage 切换奠定基础 fieldProps['data-stage-target'] = this.props.stageName; } const innerElements = [ {title} , renderTip(tip, { propName }), , ]; return (
{innerElements}
); } } export class PopupField extends VEField { constructor(props: any) { super(props); this.classNames = ['engine-setting-field', 'engine-popup-field']; } public renderBody() { return ''; } public render() { const { propName, stageName, tip, title } = this.props; const classNameList = classNames(...this.classNames, this.props.className); const fieldProps: any = {}; if (stageName) { // 为 stage 切换奠定基础 fieldProps['data-stage-target'] = this.props.stageName; } return (
popups.popup({ cancelOnBlur: true, content: this.props.children, position: 'left bottom', showClose: true, sizeFixed: true, target: e.currentTarget, }) } > {title} {renderTip(tip, { propName })}
); } } export class CaptionField extends VEField { constructor(props: IVEFieldProps) { super(props); this.classNames = ['engine-setting-field', 'engine-caption-field']; } public renderHead() { const { title, tip, propName } = this.props; return (
{title} {renderTip(tip, { propName })}
); } } export class Stage extends Component { public readonly props: { key: any; stage: any; current?: boolean; direction?: any; }; public stage: any; public additionClassName: string; public shell: Element | null = null; private willDetach: () => any; public componentWillMount() { this.stage = this.props.stage; if (this.stage.onCurrentTabChange) { this.willDetach = this.stage.onCurrentTabChange(() => this.forceUpdate()); } } public componentDidMount() { this.doSkate(); } public componentWillReceiveProps(props: any) { if (props.stage !== this.stage) { this.stage = props.stage; if (this.willDetach) { this.willDetach(); } if (this.stage.onCurrentTabChange) { this.willDetach = this.stage.onCurrentTabChange(() => this.forceUpdate()); } } } public componentDidUpdate() { this.doSkate(); } public componentWillUnmount() { if (this.willDetach) { this.willDetach(); } } public doSkate() { if (this.additionClassName) { setTimeout(() => { const elem = this.shell; if (elem && elem.classList) { if (this.props.current) { elem.classList.remove(this.additionClassName); } else { elem.classList.add(this.additionClassName); } this.additionClassName = ''; } }, 10); } } public render() { const { stage } = this; let content = null; let tabs = null; let className = 'engine-settings-stage'; if (stage.getTabs) { const selected = stage.getNode(); // stat for cache stage.stat(); const currentTab = stage.getCurrentTab(); if (stage.hasTabs()) { className += ' engine-has-tabs'; tabs = (
{stage.getTabs().map((tab: any) => (
stage.setCurrentTab(tab)} > {tab.getTitle()} {renderTip(tab.getTip())}
))}
); } if (currentTab) { if (currentTab.getVisibleItems) { content = currentTab .getVisibleItems() .map((item: any) => ); } else if (currentTab.getSetter) { content = ( ); } } } else { content = stage.getContent(); } if (this.props.current) { if (this.props.direction) { this.additionClassName = `engine-stagein-${this.props.direction}`; className += ` ${this.additionClassName}`; } } else if (this.props.direction) { this.additionClassName = `engine-stageout-${this.props.direction}`; } let stageBacker = null; if (stage.hasBack()) { className += ' engine-has-backer'; stageBacker = (
{stage.getTitle()} {renderTip(stage.getTip())}
); } return (
{ this.shell = ref; }} className={className} > {stageBacker} {tabs}
{content}
); } }