mirror of
https://github.com/element-plus/element-plus.git
synced 2026-03-13 07:51:17 +08:00
chore(components): [virtual-table] code reorg (#7356)
- Reorganize code for components under vtable/components
This commit is contained in:
@@ -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
|
||||
>
|
||||
@@ -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
|
||||
@@ -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'] & {
|
||||
@@ -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 ? (
|
||||
@@ -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',
|
||||
@@ -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({
|
||||
18
packages/components/table-v2/src/components/index.ts
Normal file
18
packages/components/table-v2/src/components/index.ts
Normal 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'
|
||||
@@ -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
|
||||
@@ -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'
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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 }
|
||||
) => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import Row from '../table-row'
|
||||
import { Row } from '../components'
|
||||
import { tryCall } from '../utils'
|
||||
|
||||
import type { FunctionalComponent, UnwrapNestedRefs } from 'vue'
|
||||
|
||||
@@ -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 }
|
||||
@@ -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'
|
||||
|
||||
@@ -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'
|
||||
|
||||
|
||||
Reference in New Issue
Block a user