diff --git a/examples/components/EventAction/TransferEvent.jsx b/examples/components/EventAction/TransferEvent.jsx new file mode 100644 index 000000000..dc2c452c9 --- /dev/null +++ b/examples/components/EventAction/TransferEvent.jsx @@ -0,0 +1,57 @@ +export default { + type: 'page', + title: '穿梭框类事件', + regions: ['body', 'toolbar', 'header'], + body: [ + { + name: 'trigger1', + id: 'trigger1', + type: 'action', + label: '穿梭框1', + level: 'primary', + className: 'mr-3 mb-3', + onEvent: { + click: { + actions: [ + { + actionType: 'selectAll', + componentId: 'transfer-change-receiver' + } + ] + } + } + }, + { + "label": "穿梭器", + "id": 'transfer-change-receiver', + "type": "transfer", + "name": "transfer-change-receiver", + "options": [ + { + "label": "诸葛亮", + "value": "zhugeliang" + }, + { + "label": "曹操", + "value": "caocao" + }, + { + "label": "钟无艳", + "value": "zhongwuyan" + }, + { + "label": "李白", + "value": "libai" + }, + { + "label": "韩信", + "value": "hanxin" + }, + { + "label": "云中君", + "value": "yunzhongjun" + } + ] + } + ] +}; diff --git a/examples/components/Example.jsx b/examples/components/Example.jsx index e3a3633df..7b4716569 100644 --- a/examples/components/Example.jsx +++ b/examples/components/Example.jsx @@ -86,6 +86,7 @@ import WizardEventSchema from './EventAction/WizardEvent'; import InputTreeEventSchema from './EventAction/InputTreeEvent'; import treeSelectEventSchema from './EventAction/treeSelectEvent'; import FormEventActionSchema from './EventAction/FormEvent'; +import TransferEventSchema from './EventAction/TransferEvent'; import WizardSchema from './Wizard'; import ChartSchema from './Chart'; import EChartsEditorSchema from './ECharts'; @@ -604,6 +605,11 @@ export const examples = [ label: 'form表单', path: 'examples/event/form', component: makeSchemaRenderer(FormEventActionSchema) + }, + { + label: '穿梭框类组件', + path: 'examples/event/transfer', + component: makeSchemaRenderer(TransferEventSchema) } ] }, diff --git a/src/components/PickerContainer.tsx b/src/components/PickerContainer.tsx index 3eb63c072..b8ffac4b2 100644 --- a/src/components/PickerContainer.tsx +++ b/src/components/PickerContainer.tsx @@ -29,6 +29,8 @@ export interface PickerContainerProps extends ThemeProps, LocaleProps { popOverContainer?: any; popOverClassName?: string; size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'full'; + onOpen?: () => void; + onClose?: () => void; } export interface PickerContainerState { @@ -57,9 +59,12 @@ export class PickerContainer extends React.Component< @autobind handleClick() { - this.setState({ - isOpened: true - }); + this.setState( + { + isOpened: true + }, + (() => this.props.onOpen?.()) + ); } @autobind @@ -68,8 +73,14 @@ export class PickerContainer extends React.Component< { isOpened: false }, - callback || (() => this.props.onCancel?.()) - ); + () => { + this.props?.onClose?.(); + if (callback) { + callback(); + return + } + this.props?.onCancel?.(); + }) } @autobind diff --git a/src/components/TabsTransfer.tsx b/src/components/TabsTransfer.tsx index 5f980ac42..1bdf2fcbf 100644 --- a/src/components/TabsTransfer.tsx +++ b/src/components/TabsTransfer.tsx @@ -45,6 +45,8 @@ export interface TabsTransferProps colIndex: number, rowIndex: number ) => JSX.Element; + onTabChange?: (key: number) => void; + activeKey: number } export interface TabsTransferState { @@ -134,7 +136,9 @@ export class TabsTransfer extends React.Component< } @autobind - handleTabChange() { + handleTabChange(key: number) { + this.props?.onTabChange?.(key); + this.handleSeachCancel(); } @@ -225,7 +229,7 @@ export class TabsTransfer extends React.Component< @autobind renderSelect() { - const {options, placeholder, classnames: cx, translate: __} = this.props; + const {options, placeholder, activeKey, classnames: cx, translate: __} = this.props; const showOptions = options.filter(item => item.visible !== false); if (!Array.isArray(options) || !options.length) { @@ -241,6 +245,7 @@ export class TabsTransfer extends React.Component< mode="line" className={cx('TabsTransfer-tabs')} onSelect={this.handleTabChange} + activeKey={activeKey} > {showOptions.map((option, index) => ( JSX.Element; sortable?: boolean; + onRef?: (ref: Transfer) => void; + onSelectAll?: (options: Options) => void; } export interface TransferState { @@ -102,6 +104,10 @@ export class Transfer< unmounted = false; cancelSearch?: () => void; + componentDidMount() { + this.props?.onRef?.(this); + } + componentWillUnmount() { this.lazySearch.cancel(); this.unmounted = true; @@ -109,7 +115,7 @@ export class Transfer< @autobind toggleAll() { - const {options, option2value, onChange, value} = this.props; + const {options, option2value, onChange, value, onSelectAll} = this.props; let valueArray = BaseSelection.value2array(value, options, option2value); const availableOptions = flattenTree(options).filter( (option, index, list) => @@ -128,6 +134,9 @@ export class Transfer< ? valueArray.map(item => option2value(item)) : valueArray; + // > 0 全选 + newValue.length > 0 && onSelectAll && onSelectAll(newValue); + onChange && onChange(newValue); } diff --git a/src/components/TransferPicker.tsx b/src/components/TransferPicker.tsx index 5053ec221..c15aa1bbc 100644 --- a/src/components/TransferPicker.tsx +++ b/src/components/TransferPicker.tsx @@ -16,6 +16,10 @@ export interface TransferPickerProps extends Omit { * 边框模式,全边框,还是半边框,或者没边框。 */ borderMode?: 'full' | 'half' | 'none'; + + onFocus?: Function; + + onBlur?: Function; } export class TransferPicker extends React.Component { @@ -26,6 +30,16 @@ export class TransferPicker extends React.Component { this.optionModified = false; } + @autobind + onFoucs() { + this.props?.onFocus?.(); + } + + @autobind + onBlur() { + this.props?.onBlur?.(); + } + render() { const { classnames: cx, @@ -42,6 +56,8 @@ export class TransferPicker extends React.Component { return ( { return ( {} + +interface BaseTransferState { + activeKey: number +} export class BaseTabsTransferRenderer< T extends OptionsControlProps = TabsTransferProps > extends BaseTransferRenderer { + + state: BaseTransferState = { + activeKey: 0 + } + + + @autobind + async onTabChange(key: number) { + const {dispatchEvent} = this.props; + const rendererEvent = await dispatchEvent('tab-change', {value: key}); + if (rendererEvent?.prevented) { + return; + } + this.setState({ + activeKey: key + }); + } + @autobind async handleTabSearch( term: string, @@ -220,6 +243,25 @@ export class TabsTransferRenderer extends BaseTabsTransferRenderer diff --git a/src/renderers/Form/TabsTransferPicker.tsx b/src/renderers/Form/TabsTransferPicker.tsx index 0eee137a7..21b3b3842 100644 --- a/src/renderers/Form/TabsTransferPicker.tsx +++ b/src/renderers/Form/TabsTransferPicker.tsx @@ -7,6 +7,7 @@ import {TabsTransferControlSchema} from './TabsTransfer'; import {autobind, createObject} from '../../utils/helper'; import {Option, optionValueCompare} from '../../components/Select'; import {BaseSelection, ItemRenderStates} from '../../components/Selection'; +import {Action} from '../../types'; /** * TabsTransferPicker 穿梭器的弹框形态 @@ -28,10 +29,19 @@ export interface TabsTransferProps | 'descriptionClassName' > {} +interface BaseTransferState { + activeKey: number +} + @OptionsControl({ type: 'tabs-transfer-picker' }) export class TabsTransferPickerRenderer extends BaseTabsTransferRenderer { + + state: BaseTransferState = { + activeKey: 0 + } + @autobind optionItemRender(option: any, states: ItemRenderStates) { const {menuTpl, render, data} = this.props; @@ -52,6 +62,20 @@ export class TabsTransferPickerRenderer extends BaseTabsTransferRenderer extends React.Component { + + tranferRef?: BaseTransfer; + @autobind async handleChange(value: Array