Browse Source

fix: [Transfer] fix the issue that the item in the right panel can still be deleted and cannot be dragged after the item is disabled in the draggable transfer (#970)

YyumeiZhang 3 years ago
parent
commit
2c59f07a82

+ 29 - 0
packages/semi-ui/transfer/_story/transfer.stories.js

@@ -166,6 +166,35 @@ TransferDraggable.story = {
   name: 'Transfer draggable',
 };
 
+export const TransferDraggableAndDisabled = () => {
+  const data = Array.from({ length: 30 }, (v, i) => {
+      return {
+          label: `选项名称 ${i}`,
+          value: i,
+          key: i,
+          disabled: true,
+      };
+  });
+  return (
+    <>
+      <div>Transfer设置draggable, 并且左侧面板中的选项disabled </div>
+      <div>符合预期的行为: 右侧面板hover不会出现删除按钮,因此不可以点击删除,但是可以拖拽 </div>
+      <Transfer
+          style={{ width: 568, height: 416 }}
+          dataSource={data}
+          defaultValue={[2, 4]}
+          draggable
+          onChange={(values, items) => console.log(values, items)}
+      />
+    </>
+  );
+};
+
+TransferDraggableAndDisabled.story = {
+  name: 'transfer draggable and disabled',
+}
+
+
 const ControledTransfer = () => {
   const [value, setValue] = useState([2, 3]);
 

+ 10 - 10
packages/semi-ui/transfer/index.tsx

@@ -102,6 +102,12 @@ export interface ResolvedDataItem extends DataItem {
     _optionKey?: string | number;
 }
 
+export interface DraggableResolvedDataItem {
+    key?: string | number;
+    index?: number;
+    item?: ResolvedDataItem;
+}
+
 export type DataSource = Array<DataItem> | Array<GroupItem> | Array<TreeItem>;
 
 interface HeaderConfig {
@@ -511,12 +517,7 @@ class Transfer extends BaseComponent<TransferProps, TransferState> {
 
     renderRightItem(item: ResolvedDataItem): React.ReactNode {
         const { renderSelectedItem, draggable, type, showPath } = this.props;
-        let newItem = item;
-        if (draggable) {
-            newItem = { ...item, key: item._optionKey };
-            delete newItem._optionKey;
-        }
-        const onRemove = () => this.foundation.handleSelectOrRemove(newItem);
+        const onRemove = () => this.foundation.handleSelectOrRemove(item);
         const rightItemCls = cls({
             [`${prefixcls}-item`]: true,
             [`${prefixcls}-right-item`]: true,
@@ -536,7 +537,7 @@ class Transfer extends BaseComponent<TransferProps, TransferState> {
 
         return (
             // https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex
-            <div role="listitem" className={rightItemCls} key={newItem.key}>
+            <div role="listitem" className={rightItemCls} key={item.key}>
                 {draggable ? <DragHandle /> : null}
                 <div className={`${prefixcls}-right-item-text`}>{label}</div>
                 <IconClose
@@ -562,14 +563,13 @@ class Transfer extends BaseComponent<TransferProps, TransferState> {
     renderRightSortableList(selectedData: Array<ResolvedDataItem>) {
         // when choose some items && draggable is true
         const SortableItem = SortableElement((
-            (item: ResolvedDataItem) => this.renderRightItem(item)) as React.FC<ResolvedDataItem>
+            (props: DraggableResolvedDataItem) => this.renderRightItem(props.item)) as React.FC<DraggableResolvedDataItem>
         );
         const SortableList = SortableContainer(({ items }: { items: Array<ResolvedDataItem> }) => (
             <div className={`${prefixcls}-right-list`} role="list" aria-label="Selected list">
                 {items.map((item, index: number) => (
-                    // sortableElement will take over the property 'key', so use another '_optionKey' to pass
                     // @ts-ignore skip SortableItem type check
-                    <SortableItem key={item.label} index={index} {...item} _optionKey={item.key} />
+                    <SortableItem key={item.label} index={index} item={item} />
                 ))}
             </div>
         // eslint-disable-next-line @typescript-eslint/ban-ts-comment