chore(components): [virtual-table] code reorg (#7356)

- Reorganize code for components under vtable/components
This commit is contained in:
JeremyWuuuuu
2022-04-24 15:42:25 +08:00
committed by GitHub
parent 77c7225a9d
commit 79d45df09c
16 changed files with 62 additions and 258 deletions

View File

@@ -1,30 +0,0 @@
import { buildProps, definePropType } from '@element-plus/utils'
import { column, styleType } from './common'
import type { ExtractPropTypes } from 'vue'
import type { AnyColumn } from './common'
type ResizeTimingFn = (column: AnyColumn) => void
type ResizeHandler = (column: AnyColumn, width: number) => void
export const tableV2ColumnResizerProps = buildProps({
column: { ...column, required: true },
onResize: {
type: definePropType<ResizeHandler>(Function),
},
onResizeStart: {
type: definePropType<ResizeTimingFn>(Function),
},
onResizeStop: {
type: definePropType<ResizeTimingFn>(Function),
},
minWidth: {
type: Number,
default: 30,
},
style: styleType,
} as const)
export type TableV2ColumnResizerProps = ExtractPropTypes<
typeof tableV2ColumnResizerProps
>

View File

@@ -1,6 +1,10 @@
import type { TableV2CellProps } from './cell'
import type { FunctionalComponent } from 'vue'
import type { TableV2CellProps } from '../cell'
const TableV2Cell = (props: TableV2CellProps, { slots }) => {
const TableV2Cell: FunctionalComponent<TableV2CellProps> = (
props: TableV2CellProps,
{ slots }
) => {
const { cellData, style } = props
const displayText = cellData?.toString?.() || ''
return (
@@ -10,7 +14,7 @@ const TableV2Cell = (props: TableV2CellProps, { slots }) => {
)
}
TableV2Cell.componentName = 'ElTableV2Cell'
TableV2Cell.displayName = 'ElTableV2Cell'
TableV2Cell.inheritAttrs = false
export default TableV2Cell

View File

@@ -2,7 +2,7 @@ import ElIcon from '@element-plus/components/icon'
import { ArrowRight } from '@element-plus/icons-vue'
import type { StyleValue } from 'vue'
import type { TableV2RowCellRenderParam } from './table-row'
import type { TableV2RowCellRenderParam } from './row'
const ExpandIcon = (
props: TableV2RowCellRenderParam['expandIconProps'] & {

View File

@@ -1,5 +1,5 @@
import type { FunctionalComponent } from 'vue'
import type { TableV2HeaderCell } from './header-cell'
import type { TableV2HeaderCell } from '../header-cell'
const HeaderCell: FunctionalComponent<TableV2HeaderCell> = (props, { slots }) =>
slots.default ? (

View File

@@ -1,8 +1,8 @@
import { defineComponent } from 'vue'
import { tableV2HeaderRowProps } from './header-row'
import { tableV2HeaderRowProps } from '../header-row'
import type { ColumnCellsType } from './types'
import type { TableV2HeaderRowProps } from './header-row'
import type { ColumnCellsType } from '../types'
import type { TableV2HeaderRowProps } from '../header-row'
const TableV2HeaderRow = defineComponent({
name: 'ElTableV2HeaderRow',

View File

@@ -1,11 +1,11 @@
import { computed, defineComponent, nextTick, ref, unref } from 'vue'
import { useNamespace } from '@element-plus/hooks'
import { ensureArray } from '@element-plus/utils'
import { tableV2HeaderProps } from './header'
import { enforceUnit } from './utils'
import { tableV2HeaderProps } from '../header'
import { enforceUnit } from '../utils'
import type { CSSProperties } from 'vue'
import type { TableV2HeaderProps } from './header'
import type { TableV2HeaderProps } from '../header'
const COMPONENT_NAME = 'ElTableV2Header'
const TableV2Header = defineComponent({

View File

@@ -0,0 +1,18 @@
export { default as TableCell } from './cell'
export { default as HeaderCell } from './header-cell'
export { default as HeaderRow } from './header-row'
export { default as Header } from './header'
export { default as Row } from './row'
export { default as SortIcon } from './sort-icon'
export { default as ExpandIcon } from './expand-icon'
export type {
TableV2HeaderRowCellRendererParams,
TableV2HeaderRowRendererParams,
} from './header-row'
export type { TableV2RowCellRenderParam } from './row'
export type {
TableV2HeaderRendererParams,
TableV2HeaderInstance,
} from './header'

View File

@@ -8,12 +8,12 @@ import {
unref,
} from 'vue'
import { isArray, isFunction, isNumber } from '@element-plus/utils'
import { tableV2RowProps } from './row'
import { TableV2InjectionKey } from './tokens'
import { placeholderSign } from './private'
import { tableV2RowProps } from '../row'
import { TableV2InjectionKey } from '../tokens'
import { placeholderSign } from '../private'
import type { RendererElement, RendererNode, VNode } from 'vue'
import type { RowEventHandlers, TableV2RowProps } from './row'
import type { RowEventHandlers, TableV2RowProps } from '../row'
type CustomizedCellsType = VNode<
RendererNode,
@@ -64,11 +64,15 @@ const useTableRow = (props: TableV2RowProps) => {
const eventHandlers = computed(() => {
const { rowData, rowIndex, rowKey, onRowHover } = props
const handlers = props.rowEventHandlers || ({} as RowEventHandlers<any>)
const eventHandlers = {}
const eventHandlers = {} as {
[key in keyof RowEventHandlers<any>]: (e: Event) => void
}
Object.entries(handlers).forEach(([eventName, handler]) => {
if (isFunction(handler)) {
eventHandlers[eventName] = (event: Event) => {
eventHandlers[eventName as keyof RowEventHandlers<any>] = (
event: Event
) => {
handler({
event,
rowData,
@@ -87,7 +91,7 @@ const useTableRow = (props: TableV2RowProps) => {
] as const
).forEach(({ name, hovered }) => {
const existedHandler = eventHandlers[name]
eventHandlers[name] = (event: MouseEvent) => {
eventHandlers[name] = ((event: MouseEvent) => {
onRowHover({
event,
hovered,
@@ -97,7 +101,7 @@ const useTableRow = (props: TableV2RowProps) => {
})
existedHandler?.(event)
}
}) as any
})
}
return eventHandlers

View File

@@ -1,6 +1,6 @@
import ElIcon from '@element-plus/components/icon'
import { SortDown, SortUp } from '@element-plus/icons-vue'
import { SortOrder } from './constants'
import { SortOrder } from '../constants'
import type { FunctionalComponent } from 'vue'

View File

@@ -1,14 +1,13 @@
import { get } from 'lodash-unified'
import { isFunction, isObject } from '@element-plus/utils'
import TableCell from '../table-cell'
import ExpandIcon from '../expand-icon'
import { ExpandIcon, TableCell } from '../components'
import { Alignment } from '../constants'
import { placeholderSign } from '../private'
import { componentToSlot, enforceUnit } from '../utils'
import type { FunctionalComponent, UnwrapNestedRefs, VNode } from 'vue'
import type { CellRendererParams } from '../types'
import type { TableV2RowCellRenderParam } from '../table-row'
import type { TableV2RowCellRenderParam } from '../components'
import type { UseNamespaceReturn } from '@element-plus/hooks'
import type { UseTableReturn } from '../use-table'
import type { TableV2Props } from '../table'

View File

@@ -1,28 +1,18 @@
import HeaderCell from '../table-header-cell'
import { HeaderCell, SortIcon } from '../components'
// import ColumnResizer from '../table-column-resizer'
import SortIcon from '../sort-icon'
import { Alignment, SortOrder, oppositeOrderMap } from '../constants'
import { placeholderSign } from '../private'
import { componentToSlot, enforceUnit, tryCall } from '../utils'
import type { FunctionalComponent, UnwrapNestedRefs } from 'vue'
import type { UseNamespaceReturn } from '@element-plus/hooks'
import type { TableV2HeaderRowCellRendererParams } from '../table-header-row'
import type { TableV2HeaderRowCellRendererParams } from '../components'
import type { UseTableReturn } from '../use-table'
import type { TableV2Props } from '../table'
import type { TableV2HeaderCell } from '../header-cell'
type HeaderCellRendererProps = TableV2HeaderRowCellRendererParams &
UnwrapNestedRefs<
Pick<
UseTableReturn,
'columnsStyles' | 'onColumnSorted'
// | 'resizingKey'
// | 'onColumnResized'
// | 'onColumnResizeEnd'
// | 'onColumnResizeStart'
>
> &
UnwrapNestedRefs<Pick<UseTableReturn, 'columnsStyles' | 'onColumnSorted'>> &
Pick<TableV2Props, 'sortBy' | 'sortState' | 'headerCellProps'> & {
ns: UseNamespaceReturn
}
@@ -31,16 +21,7 @@ const HeaderCellRenderer: FunctionalComponent<HeaderCellRendererProps> = (
props,
{ slots }
) => {
const {
column,
ns,
columnsStyles,
// resizingKey,
// onColumnResizeEnd,
// onColumnResizeStart,
// onColumnResized,
onColumnSorted,
} = props
const { column, ns, columnsStyles, onColumnSorted } = props
const style = enforceUnit(columnsStyles[column.key])
@@ -87,7 +68,6 @@ const HeaderCellRenderer: FunctionalComponent<HeaderCellRendererProps> = (
column.align === Alignment.CENTER && ns.is('align-center'),
column.align === Alignment.RIGHT && ns.is('align-right'),
sortable && ns.is('sortable'),
// column.key === resizingKey && ns.is('resizing'),
]
const cellWrapperProps = {
@@ -109,16 +89,6 @@ const HeaderCellRenderer: FunctionalComponent<HeaderCellRendererProps> = (
sortOrder={sortOrder}
/>
)}
{/* {resizable && (
<ColumnResizer
class={ns.e('column-resizer')}
column={column}
onResize={onColumnResized}
onResizeStart={onColumnResizeStart}
onResizeStop={onColumnResizeEnd}
/>
)} */}
</div>
)
}

View File

@@ -1,16 +1,15 @@
import HeaderRow from '../table-header-row'
import { HeaderRow } from '../components'
import { tryCall } from '../utils'
import type { FunctionalComponent } from 'vue'
import type { UseNamespaceReturn } from '@element-plus/hooks'
import type { TableV2HeaderRendererParams } from '../table-header'
import type { TableV2HeaderRendererParams } from '../components'
import type { TableV2Props } from '../table'
type HeaderRendererProps = TableV2HeaderRendererParams &
Pick<TableV2Props, 'headerClass' | 'headerProps'> & {
ns: UseNamespaceReturn
}
// & UnwrapNestedRefs<Pick<UseTableReturn, 'resizingKey'>>
const HeaderRenderer: FunctionalComponent<HeaderRendererProps> = (
{
@@ -22,8 +21,6 @@ const HeaderRenderer: FunctionalComponent<HeaderRendererProps> = (
headerProps,
ns,
// returned by use-table
// resizingKey,
},
{ slots }
) => {

View File

@@ -1,4 +1,4 @@
import Row from '../table-row'
import { Row } from '../components'
import { tryCall } from '../utils'
import type { FunctionalComponent, UnwrapNestedRefs } from 'vue'

View File

@@ -1,160 +0,0 @@
import {
computed,
defineComponent,
onBeforeUnmount,
ref,
shallowRef,
unref,
watch,
withModifiers,
} from 'vue'
import { NOOP } from '@vue/shared'
import { useNamespace } from '@element-plus/hooks'
import { tableV2ColumnResizerProps } from './column-resizer'
import type { TableV2ColumnResizerProps } from './column-resizer'
const COMPONENT_NAME = 'ColumnResizer'
const ColumnResizer = defineComponent({
name: COMPONENT_NAME,
props: tableV2ColumnResizerProps,
setup(props) {
const { resizerRef, onClick, onMousedown, onTouchStart, onDragEnd } =
useColumnResizer(props)
return () => (
<div
ref={resizerRef}
onClick={onClick}
onMousedown={onMousedown}
onMouseup={onDragEnd}
onTouchstart={onTouchStart}
onTouchend={onDragEnd}
style={props.style}
/>
)
},
})
function useColumnResizer(props: TableV2ColumnResizerProps) {
const ns = useNamespace('')
const isDragging = shallowRef(false)
const resizerRef = ref<HTMLElement>()
const width = shallowRef(0)
const lastX = shallowRef<null | number>(null)
const ownerDocument = computed(() => unref(resizerRef)?.ownerDocument)
const onDragStart = withModifiers(() => {
isDragging.value = true
const column = props.column!
width.value = column.width
props.onResizeStart?.(column)
}, ['left'])
const addEvents = (
drag: 'mousemove' | 'touchmove',
end: 'mouseup' | 'touchend'
) => {
const _ownerDocument = unref(ownerDocument)!
if (!_ownerDocument) return
_ownerDocument.addEventListener(drag, onDrag)
_ownerDocument.addEventListener(end, onDragEnd)
}
const detachEvents = () => {
const _ownerDocument = unref(ownerDocument)!
if (!_ownerDocument) return
_ownerDocument.removeEventListener('mousemove', onDrag)
_ownerDocument.removeEventListener('touchmove', onDrag)
_ownerDocument.removeEventListener('mouseup', onDragEnd)
_ownerDocument.removeEventListener('touchend', onDragEnd)
}
const onDragEnd = () => {
if (!unref(isDragging)) return
const { column, onResizeStop } = props
isDragging.value = false
onResizeStop?.(column)
detachEvents()
}
const onClick = withModifiers(NOOP, ['stop'])
const onMousedown = (e: MouseEvent) => {
onDragStart(e)
addEvents('mousemove', 'mouseup')
}
const onTouchStart = (e: TouchEvent) => {
onDragStart(e)
addEvents('touchmove', 'touchend')
}
function onDrag(e: MouseEvent | TouchEvent) {
const { type, preventDefault } = e
let { clientX } = e as MouseEvent
const { targetTouches } = e as TouchEvent
if (type === 'touchmove') {
preventDefault()
if (targetTouches?.[0]) clientX = targetTouches[0].clientX
}
const { offsetParent } = unref(resizerRef)!
const offsetParentRect = offsetParent!.getBoundingClientRect()
const x = clientX + offsetParent!.scrollLeft - offsetParentRect.left
const _lastX = unref(lastX)
if (_lastX === null) {
lastX.value = x
return
}
const { column, minWidth: propMinWidth } = props
const { width: columnWidth, maxWidth, minWidth = propMinWidth } = column!
const movedX = x - _lastX
if (!movedX) return
width.value = columnWidth + movedX
lastX.value = x
let newWidth = unref(width)
if (maxWidth && newWidth > maxWidth) {
newWidth = maxWidth
} else if (newWidth < minWidth) {
newWidth = minWidth
}
if (newWidth === unref(width)) return
props.onResize?.(column, newWidth)
}
watch(isDragging, (val) => {
const _ownerDocument = unref(ownerDocument)
if (!_ownerDocument) return
if (val) {
_ownerDocument.body.classList.add(`${unref(ns.namespace)}-dragging`)
} else {
_ownerDocument.body.classList.remove(`${unref(ns.namespace)}-dragging`)
}
})
onBeforeUnmount(() => {
detachEvents()
})
return {
resizerRef,
onClick,
onMousedown,
onTouchStart,
onDragEnd,
}
}
export default ColumnResizer
export { useColumnResizer }

View File

@@ -4,7 +4,7 @@ import {
FixedSizeGrid,
} from '@element-plus/components/virtual-list'
import { isNumber, isObject } from '@element-plus/utils'
import Header from './table-header'
import { Header } from './components'
import { TableV2InjectionKey } from './tokens'
import { tableV2GridProps } from './grid'
import { sum } from './utils'
@@ -18,7 +18,7 @@ import type {
GridScrollOptions,
ResetAfterIndex,
} from '@element-plus/components/virtual-list'
import type { TableV2HeaderInstance } from './table-header'
import type { TableV2HeaderInstance } from './components'
import type { TableV2GridProps } from './grid'
const COMPONENT_NAME = 'ElTableV2Grid'

View File

@@ -16,10 +16,12 @@ import Empty from './renderers/empty'
import Overlay from './renderers/overlay'
import type { TableGridRowSlotParams } from './table-grid'
import type { TableV2RowCellRenderParam } from './table-row'
import type { TableV2HeaderRendererParams } from './table-header'
import type { TableV2HeaderRowCellRendererParams } from './table-header-row'
import type {
TableV2HeaderRendererParams,
TableV2HeaderRowCellRendererParams,
TableV2RowCellRenderParam,
} from './components'
const COMPONENT_NAME = 'ElTableV2'