kingdee / kdesign

An enterprise-class React UI components library
https://react.kingdee.design/
Apache License 2.0
107 stars 45 forks source link

table表格带有复选框的时候,鼠标hover上去会有hover类,鼠标在此点击当前行,hover类消失 #350

Closed NGyc closed 1 year ago

NGyc commented 1 year ago

重现链接或代码

重现问题步骤

table表格带有复选框的时候,鼠标hover上去会有hover类,鼠标在此点击当前行,hover类消失 image

期望的结果是什么

实际的结果是什么

希望hover类消失不要消失

组件库版本号、浏览器信息

murisans commented 1 year ago

Bug 机理分析: a41_cellSpanWithSelect 鼠标事件选用onMouseEnter,点击是触发点击事件后不会再触发鼠标进入事件; Bug解决方案: 改用onMouseOver, 点击触发后 鼠标仍在原地,会继续触发mouseOver事件

NGyc commented 1 year ago

点击复选框的时候还是会出现hover类消失的情况

murisans commented 1 year ago

点击复选框的时候还是会出现hover类消失的情况

react 有啥好的调试技巧吗, 找半天也不知道row-hover是怎么被移除的

还有些断点跟踪的代码 源码里面都搜不到,也是用了onMouseEnter,也不知道有没有关系

image
NGyc commented 1 year ago

应该看看他的highlight这个类是怎么加进去的,是这个类把row-hover给替换了

murisans commented 1 year ago

@kdcloudjs/table/es/table/pipeline/features/mergeCellHover.js image mergeCellHover.js 也使用了onMouseEnter监听鼠标事件 但是该文件实现这本仓库不存在

murisans commented 1 year ago

应该看看他的highlight这个类是怎么加进去的,是这个类把row-hover给替换了

mergeCellHover 是不是修改一下鼠标的监听事件 改成onMouseOver ,也能满足需求了 , 本来hover 用 mouseEnter也不太合理嘛, 单击鼠标后又不会再触发mouseEnter

murisans commented 1 year ago

应该看看他的highlight这个类是怎么加进去的,是这个类把row-hover给替换了 通过multiSelect.js 添加highlight类 image 但是只是pipeline中的其中一个环节 ,具体为什么会把row-hover替换掉,会不会和pipeline有关 image

murisans commented 1 year ago

@NGyc mergeCellProps.js 取不到行原本的class值,导致class丢失了 row-hover createRowPropsGetter返回的对象里面默认带上className,'className': 'row-hover' image PR #357 有更新,你测试一下能不能满足需求

wqhui commented 1 year ago

这个初步分析是row-hover没有状态存储,行节点更新之后又不会重新触发enter事件,导致样式丢了,我们这边会看下怎么完善

murisans commented 1 year ago

这个初步分析是row-hover没有状态存储,行节点更新之后又不会重新触发enter事件,导致样式丢了,我们这边会看下怎么完善

最好能在Table组件内部解决掉, 调用方去处理确实很奇怪

murisans commented 1 year ago

@kdcloudjs/table/es/table/pipeline/features/mergeCellHover.js image mergeCellHover.js 也使用了onMouseEnter监听鼠标事件 但是该文件实现这本仓库不存在

@wqhui mergeCellHover 使用onMouseEnter去监听是不是不太合理

murisans commented 1 year ago

@wqhui a41_cellSpanWithSelect.md 合并行鼠标悬浮效果联动 这个feature不做到组件内部吗? 在markdown里面改感觉 又改不全

wqhui commented 1 year ago

@murisans mergeCellHover只是为了处理合并单元格则所有融合行的增加row-hover,未考虑到这个功能是提供的row-hover的使用问题,这里功能扩大了,导致其他未融合的单元格也会走这一逻辑。

a41_cellSpanWithSelect这个不做到组件内部,是参考其他主流的开源库也都不会处理融合行的悬浮同步,而且这个融合数据也比较复杂,基础控件只知道哪些单元格融合了(rowSpan > 1),属于融合行的非融合的单元格(rowSpan=1的单元格)需要做融合单元格同步的话就比较麻烦,比如例子里的来户单元格,对于基础控件来说这就是非融合单元格,无法实现悬浮多行。

我这里提供个例子,不过会被 mergeCellHover 影响:

import React from 'react'
import ReactDOM from 'react-dom'
import { Table } from '@kdcloudjs/kdesign'

function Demo() {
  const [ selected, setSelected ] = React.useState([])
  const [ hoverRow, setHoverRow ] = React.useState()

  const dataSource = [
    { id: "1", "No":1,"order":"AP-202009-00001","from":"陕西环宇科技","to":"深圳环球科技","amount":"26,800.00","balance":"5,200.00" },
    { id: "2", "No":2,"order":"AP-202009-00001","from":"陕西环宇科技","to":"深圳环球科技","amount":"236,800.00","balance":"1,500.00" },
    { id: "3", "No":3,"order":"AP-202009-00002","from":"陕西环宇科技","to":"深圳环球科技","amount":"246,800.00","balance":"5,300.00" },
    { id: "4", "No":4,"order":"AP-202009-00003","from":"陕西环宇科技","to":"深圳环球科技","amount":"216,800.00","balance":"5,400.00" },
    { id: "5", "No":5,"order":"AP-202009-00004","from":"陕西环宇科技","to":"深圳环球科技","amount":"236,800.00","balance":"1,500.00" }
  ]

  const rowSpanData = {
     '2': 2,
     '3': 1
  }
  const rowSpanKeys = ['2','3']
  const rowSpanGroupMap = {
    '2': rowSpanKeys,
    '3': rowSpanKeys
  }

  const createRowPropsGetter = (rowSpanData) => (record) => {
    // 合并行鼠标悬浮效果联动
    if (rowSpanData[record.id]) {
      const rowSpanGroup = rowSpanGroupMap[record.id]
      console.log(111, record.id, rowSpanGroup.includes(hoverRow))
      return {
        'className':  rowSpanGroup.includes(hoverRow) ? 'row-hover' : '',
        'data-row-id': record.id,
        onMouseEnter: (key, tbody) => {
          setHoverRow(record.id)
        },
        onMouseLeave: () => {
          setHoverRow()
        }
      }
    }
  }

  const createCellPropsGetter = (rowSpanData) => (value, record) => {
    if (rowSpanData[record.id]) {
      return {
        rowSpan: rowSpanData[record.id]
      }
    }
  }

  const columns = [
    { code: 'No', name: '序号', width: 60, align: 'center'},
    { code: 'order', name: '单据号', width: 200, getCellProps: createCellPropsGetter(rowSpanData) },
    { code: 'from', name: '来户', width: 200 },
    { code: 'to', name: '往户', width: 200 },
    { code: 'amount', name: '应付金额', width: 100, align: 'right' },
    { code: 'balance', name: '应收余额', width: 100, align: 'right' }
  ]

  const handleSelected = (keys, actionRowkey, actionRowskeys, action ) => {
    // 合并行选择状态联动
    if (Array.isArray(rowSpanGroupMap[actionRowkey])) {
      if (action === 'check') {
        setSelected(Array.from(new Set(keys.concat(rowSpanGroupMap[actionRowkey]))))
      } else {
        const rowSpanKeysSet = new Set(rowSpanGroupMap[actionRowkey])
        setSelected(keys.reduce((result, key) => {
          if (!rowSpanKeysSet.has(key)) {
            result.push(key)
          }
          return result
        },[]))
      }
    } else {
      setSelected(keys)
    }
  }

  const rowSelection = {
     type: 'checkbox',
     value: selected,
     onChange: handleSelected,
     column: { 
      lock: true,
      getCellProps: createCellPropsGetter(rowSpanData)
     },
     clickArea: 'row',
     highlightRowWhenSelected: true
  }

  return <Table 
    primaryKey={'id'} 
    dataSource={dataSource} 
    columns={columns} 
    rowSelection={rowSelection}
    getRowProps={createRowPropsGetter(rowSpanData)}
  />
}

ReactDOM.render(<Demo />, mountNode)