1- import React , { useMemo } from 'react' ;
2- import { Dropdown , Form , Input , Menu , Spin } from 'antd' ;
1+ import React from 'react' ;
2+ import { Dropdown , DropdownProps , Form , Input , Spin } from 'antd' ;
33import { DataNode } from 'antd/lib/tree' ;
4- import { EllipsisText , Empty } from 'dt-react-component' ;
5- import BlockHeader , { IBlockHeaderProps } from 'dt-react-component/blockHeader' ;
4+ import { BlockHeader , EllipsisText , Empty } from 'dt-react-component' ;
5+ import { IBlockHeaderProps } from 'dt-react-component/blockHeader' ;
66
77import { InputStatus , ITreeNode , useTreeData } from '../useTreeData' ;
8- import { CatalogIcon , DeleteIcon , DragIcon , EditIcon , EllipsisIcon , PlusCircleIcon } from './icon' ;
8+ import { CatalogIcon , DragIcon , EllipsisIcon } from './icon' ;
99import CatalogueTree , { ICatalogueTree } from './tree' ;
1010
11- interface ICatalogue
11+ export interface ICatalogue
1212 extends Pick < IBlockHeaderProps , 'tooltip' | 'addonAfter' | 'addonBefore' | 'title' > ,
13- Pick < ReturnType < typeof useTreeData > , 'onChange' > ,
1413 ICatalogueTree {
1514 showSearch ?: boolean ;
1615 edit ?: boolean ;
1716 placeholder ?: string ;
1817 loading ?: boolean ;
18+ onChange ?: ReturnType < typeof useTreeData > [ 'onChange' ] ;
19+ overlay ?: ( item : ITreeNode ) => DropdownProps [ 'overlay' ] ;
1920 onSearch ?: ( value : string ) => void ;
20- onSave ?: ( data : ITreeNode , value : string ) => void ;
21- onDelete ?: ( data : ITreeNode ) => void ;
21+ onSave ?: ( data : ITreeNode , value : string ) => Promise < string | void > ;
2222}
2323
2424const Catalogue = ( {
@@ -32,11 +32,11 @@ const Catalogue = ({
3232 loading = false ,
3333 treeData,
3434 draggable,
35+ overlay,
3536 onChange,
3637 onSearch,
3738 onExpand,
3839 onSave,
39- onDelete,
4040 ...rest
4141} : ICatalogue ) => {
4242 const [ form ] = Form . useForm ( ) ;
@@ -90,12 +90,13 @@ const Catalogue = ({
9090 } ;
9191
9292 const renderTree = ( ) => {
93+ const treeDataWithTitle = loopTree ( treeData ) ;
9394 if ( ! treeDataWithTitle . length ) return < Empty style = { { marginTop : 130 } } /> ;
9495 return (
9596 < div className = "dt-catalogue__tree" >
9697 < Spin spinning = { loading } >
9798 < CatalogueTree
98- treeData = { treeDataWithTitle }
99+ treeData = { loopTree ( treeData ) }
99100 draggable = { draggable ? { icon : false } : false }
100101 onExpand = { onExpand }
101102 { ...rest }
@@ -125,22 +126,30 @@ const Catalogue = ({
125126 return result ;
126127 } ;
127128 const parentItem = findAppendParents ( treeData , item ) ;
128- return parentItem && onSave ?.( { ...parentItem , type : InputStatus . Append } , value ) ;
129+ return (
130+ parentItem &&
131+ onSave ?.( { ...parentItem , type : InputStatus . Append } , value ) . then ( ( msg ) => {
132+ form . setFields ( [ { name : 'catalog_input' , errors : msg ? [ msg ] : [ ] } ] ) ;
133+ } )
134+ ) ;
129135 }
130- onSave ?.( item , value ) ;
136+ onSave ?.( item , value ) . then ( ( msg ) => {
137+ form . setFields ( [ { name : 'catalog_input' , errors : msg ? [ msg ] : [ ] } ] ) ;
138+ } ) ;
131139 } ;
132140
133141 const renderInput = ( item : DataNode ) => {
134142 return (
135143 < div className = "tree__title--input" >
136- < Form form = { form } >
137- < Form . Item >
144+ < Form form = { form } preserve = { false } >
145+ < Form . Item name = "catalog_input" >
138146 < Input
139147 defaultValue = { item ?. title as string }
140148 size = "small"
141149 placeholder = { `请输入${ title } 名称` }
142150 maxLength = { 100 }
143151 autoFocus
152+ onFocus = { ( ) => form . setFields ( [ { name : 'catalog_input' , errors : [ ] } ] ) }
144153 onClick = { ( e ) => e . stopPropagation ( ) }
145154 onBlur = { ( { target } ) => handleInputSubmit ( item , target . value ) }
146155 onPressEnter = { ( { target } ) =>
@@ -170,68 +179,31 @@ const Catalogue = ({
170179 } ;
171180
172181 const renderNodeHover = ( item : ITreeNode ) => {
173- const menu = (
174- < Menu
175- className = "tree__title--menu"
176- onClick = { ( { domEvent } ) => {
177- domEvent . stopPropagation ( ) ;
178- } }
179- >
180- < Menu . Item
181- key = "add"
182- className = "title__menu--item"
183- disabled = { ! item . addable }
184- onClick = { ( ) => item . addable && onChange ?.( item , InputStatus . Append ) }
185- >
186- < PlusCircleIcon />
187- < span > 新建目录</ span >
188- </ Menu . Item >
189- < Menu . Item
190- key = "edit"
191- className = "title__menu--item"
192- disabled = { ! item . editable }
193- onClick = { ( ) => item . editable && onChange ?.( item , InputStatus . Edit ) }
194- >
195- < EditIcon />
196- < span > 编辑</ span >
197- </ Menu . Item >
198- < Menu . Item
199- key = "delete"
200- className = "title__menu--item"
201- disabled = { ! item . deletable }
202- onClick = { ( ) => item . deletable && onDelete ?.( item ) }
203- >
204- < DeleteIcon />
205- < span > 删除</ span >
206- </ Menu . Item >
207- </ Menu >
208- ) ;
209182 return (
210183 < div
211184 className = "tree__title--operation"
212185 onMouseDown = { ( e ) => {
213186 e . stopPropagation ( ) ;
214187 } }
215188 >
216- < Dropdown
217- overlay = { menu }
218- trigger = { [ 'click' ] }
219- placement = "bottomRight"
220- arrow
221- destroyPopupOnHide
222- getPopupContainer = { ( triggerNode ) => triggerNode . parentElement as HTMLElement }
223- >
224- < EllipsisIcon onClick = { ( e ) => e . stopPropagation ( ) } />
225- </ Dropdown >
189+ { overlay && (
190+ < Dropdown
191+ overlay = { overlay ( item ) }
192+ placement = "bottomRight"
193+ arrow
194+ destroyPopupOnHide
195+ getPopupContainer = { ( triggerNode ) =>
196+ triggerNode . parentElement as HTMLElement
197+ }
198+ >
199+ < EllipsisIcon onClick = { ( e ) => e . stopPropagation ( ) } />
200+ </ Dropdown >
201+ ) }
226202 { draggable && < DragIcon /> }
227203 </ div >
228204 ) ;
229205 } ;
230206
231- const treeDataWithTitle = useMemo ( ( ) => {
232- return loopTree ( treeData ) ;
233- } , [ treeData ] ) ;
234-
235207 return (
236208 < div className = "dt-catalogue" >
237209 < div className = "dt-catalogue__header" >
0 commit comments