mirror of
https://github.com/element-plus/element-plus.git
synced 2026-03-13 07:51:17 +08:00
feat(components): [table] overflow tooltip supports enterable and customization (#10984)
* feat(components): [table] overflow tooltip supports `enterable` * fix(components): [table] fix modifiers merge * fix(components): [table] refine logic & fix popperClass isn't respected * docs(components): [table] add docs for `tooltip-options` & `show-overflow-tooltip` * docs(components): [table] * docs(components): [table] update version tag Co-authored-by: Xc <124118265@qq.com>
This commit is contained in:
@@ -231,44 +231,45 @@ table/table-layout
|
||||
|
||||
## Table Attributes
|
||||
|
||||
| Name | Description | Type | Accepted Values | Default |
|
||||
| -------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------- | ------------------------------------ | ------------------------------------------------------------------------------ |
|
||||
| data | Table data | array | — | — |
|
||||
| height | Table's height. By default it has an `auto` height. If its value is a number, the height is measured in pixels; if its value is a string, the value will be assigned to element's style.height, the height is affected by external styles | string / number | — | — |
|
||||
| max-height | Table's max-height. The legal value is a number or the height in px. | string / number | — | — |
|
||||
| stripe | whether Table is striped | boolean | — | false |
|
||||
| border | whether Table has vertical border | boolean | — | false |
|
||||
| size | size of Table | string | large / default /small | — |
|
||||
| fit | whether width of column automatically fits its container | boolean | — | true |
|
||||
| show-header | whether Table header is visible | boolean | — | true |
|
||||
| highlight-current-row | whether current row is highlighted | boolean | — | false |
|
||||
| current-row-key | key of current row, a set only prop | string / number | — | — |
|
||||
| row-class-name | function that returns custom class names for a row, or a string assigning class names for every row | function(\{ row, rowIndex \}) / string | — | — |
|
||||
| row-style | function that returns custom style for a row, or an object assigning custom style for every row | function(\{ row, rowIndex \}) / object | — | — |
|
||||
| cell-class-name | function that returns custom class names for a cell, or a string assigning class names for every cell | function(\{ row, column, rowIndex, columnIndex \}) / string | — | — |
|
||||
| cell-style | function that returns custom style for a cell, or an object assigning custom style for every cell | function(\{ row, column, rowIndex, columnIndex \}) / object | — | — |
|
||||
| header-row-class-name | function that returns custom class names for a row in table header, or a string assigning class names for every row in table header | function(\{ row, rowIndex }\) / string | — | — |
|
||||
| header-row-style | function that returns custom style for a row in table header, or an object assigning custom style for every row in table header | function(\{ row, rowIndex \}) / object | — | — |
|
||||
| header-cell-class-name | function that returns custom class names for a cell in table header, or a string assigning class names for every cell in table header | function(\{ row, column, rowIndex, columnIndex \}) / string | — | — |
|
||||
| header-cell-style | function that returns custom style for a cell in table header, or an object assigning custom style for every cell in table header | function(\{ row, column, rowIndex, columnIndex \}) / object | — | — |
|
||||
| row-key | key of row data, used for optimizing rendering. Required if `reserve-selection` is on or display tree data. When its type is String, multi-level access is supported, e.g. `user.info.id`, but `user.info[0].id` is not supported, in which case `Function` should be used. | function(row) / string | — | — |
|
||||
| empty-text | Displayed text when data is empty. You can customize this area with `#empty` | string | — | No Data |
|
||||
| default-expand-all | whether expand all rows by default, works when the table has a column type="expand" or contains tree structure data | boolean | — | false |
|
||||
| expand-row-keys | set expanded rows by this prop, prop's value is the keys of expand rows, you should set row-key before using this prop | array | — | — |
|
||||
| default-sort | set the default sort column and order. property `prop` is used to set default sort column, property `order` is used to set default sort order | object | (order: 'ascending' \| 'descending') | if `prop` is set, and `order` is not set, then `order` is default to ascending |
|
||||
| tooltip-effect | tooltip `effect` property | string | dark / light | dark |
|
||||
| show-summary | whether to display a summary row | boolean | — | false |
|
||||
| sum-text | displayed text for the first column of summary row | string | — | Sum |
|
||||
| summary-method | custom summary method | function(\{ columns, data \}) | — | — |
|
||||
| span-method | method that returns rowspan and colspan | function(\{ row, column, rowIndex, columnIndex \}) | — | — |
|
||||
| select-on-indeterminate | controls the behavior of master checkbox in multi-select tables when only some rows are selected (but not all). If true, all rows will be selected, else deselected. | boolean | — | true |
|
||||
| indent | horizontal indentation of tree data | number | — | 16 |
|
||||
| lazy | whether to lazy loading data | boolean | — | — |
|
||||
| load | method for loading child row data, only works when `lazy` is true | function(row, treeNode, resolve) | — | — |
|
||||
| tree-props | configuration for rendering nested data | object | — | `{ hasChildren: 'hasChildren', children: 'children' }` |
|
||||
| table-layout | Sets the algorithm used to lay out table cells, rows, and columns | string | fixed / auto | fixed |
|
||||
| scrollbar-always-on | always show scrollbar | boolean | — | false |
|
||||
| flexible<VersionTag version="2.2.1" /> | ensure main axis minimum-size doesn't follow the content | boolean | — | false |
|
||||
| Name | Description | Type | Accepted Values | Default |
|
||||
| ---------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
|
||||
| data | Table data | array | — | — |
|
||||
| height | Table's height. By default it has an `auto` height. If its value is a number, the height is measured in pixels; if its value is a string, the value will be assigned to element's style.height, the height is affected by external styles | string / number | — | — |
|
||||
| max-height | Table's max-height. The legal value is a number or the height in px. | string / number | — | — |
|
||||
| stripe | whether Table is striped | boolean | — | false |
|
||||
| border | whether Table has vertical border | boolean | — | false |
|
||||
| size | size of Table | string | large / default /small | — |
|
||||
| fit | whether width of column automatically fits its container | boolean | — | true |
|
||||
| show-header | whether Table header is visible | boolean | — | true |
|
||||
| highlight-current-row | whether current row is highlighted | boolean | — | false |
|
||||
| current-row-key | key of current row, a set only prop | string / number | — | — |
|
||||
| row-class-name | function that returns custom class names for a row, or a string assigning class names for every row | function(\{ row, rowIndex \}) / string | — | — |
|
||||
| row-style | function that returns custom style for a row, or an object assigning custom style for every row | function(\{ row, rowIndex \}) / object | — | — |
|
||||
| cell-class-name | function that returns custom class names for a cell, or a string assigning class names for every cell | function(\{ row, column, rowIndex, columnIndex \}) / string | — | — |
|
||||
| cell-style | function that returns custom style for a cell, or an object assigning custom style for every cell | function(\{ row, column, rowIndex, columnIndex \}) / object | — | — |
|
||||
| header-row-class-name | function that returns custom class names for a row in table header, or a string assigning class names for every row in table header | function(\{ row, rowIndex }\) / string | — | — |
|
||||
| header-row-style | function that returns custom style for a row in table header, or an object assigning custom style for every row in table header | function(\{ row, rowIndex \}) / object | — | — |
|
||||
| header-cell-class-name | function that returns custom class names for a cell in table header, or a string assigning class names for every cell in table header | function(\{ row, column, rowIndex, columnIndex \}) / string | — | — |
|
||||
| header-cell-style | function that returns custom style for a cell in table header, or an object assigning custom style for every cell in table header | function(\{ row, column, rowIndex, columnIndex \}) / object | — | — |
|
||||
| row-key | key of row data, used for optimizing rendering. Required if `reserve-selection` is on or display tree data. When its type is String, multi-level access is supported, e.g. `user.info.id`, but `user.info[0].id` is not supported, in which case `Function` should be used. | function(row) / string | — | — |
|
||||
| empty-text | Displayed text when data is empty. You can customize this area with `#empty` | string | — | No Data |
|
||||
| default-expand-all | whether expand all rows by default, works when the table has a column type="expand" or contains tree structure data | boolean | — | false |
|
||||
| expand-row-keys | set expanded rows by this prop, prop's value is the keys of expand rows, you should set row-key before using this prop | array | — | — |
|
||||
| default-sort | set the default sort column and order. property `prop` is used to set default sort column, property `order` is used to set default sort order | object | (order: 'ascending' \| 'descending') | if `prop` is set, and `order` is not set, then `order` is default to ascending |
|
||||
| tooltip-effect | the `effect` of the overflow tooltip | string | dark / light | dark |
|
||||
| tooltip-options<VersionTag version="2.2.28" /> | the options for the overflow tooltip, [see the following tooltip component](tooltip.html#attributes) | ^[object]`Pick<ElTooltipProps, 'effect' \| 'enterable' \| 'hideAfter' \| 'offset' \| 'placement' \| 'popperClass' \| 'popperOptions' \| 'showAfter' \| 'showArrow'>` | [refer to tooltip](tooltip.html#attributes) | ^[object]`{ enterable: true, placement: 'top', showArrow: true, hideAfter: 200, popperOptions: { strategy: 'fixed' } }` |
|
||||
| show-summary | whether to display a summary row | boolean | — | false |
|
||||
| sum-text | displayed text for the first column of summary row | string | — | Sum |
|
||||
| summary-method | custom summary method | function(\{ columns, data \}) | — | — |
|
||||
| span-method | method that returns rowspan and colspan | function(\{ row, column, rowIndex, columnIndex \}) | — | — |
|
||||
| select-on-indeterminate | controls the behavior of master checkbox in multi-select tables when only some rows are selected (but not all). If true, all rows will be selected, else deselected. | boolean | — | true |
|
||||
| indent | horizontal indentation of tree data | number | — | 16 |
|
||||
| lazy | whether to lazy loading data | boolean | — | — |
|
||||
| load | method for loading child row data, only works when `lazy` is true | function(row, treeNode, resolve) | — | — |
|
||||
| tree-props | configuration for rendering nested data | object | — | `{ hasChildren: 'hasChildren', children: 'children' }` |
|
||||
| table-layout | Sets the algorithm used to lay out table cells, rows, and columns | string | fixed / auto | fixed |
|
||||
| scrollbar-always-on | always show scrollbar | boolean | — | false |
|
||||
| flexible<VersionTag version="2.2.1" /> | ensure main axis minimum-size doesn't follow the content | boolean | — | false |
|
||||
|
||||
## Table Events
|
||||
|
||||
@@ -321,35 +322,35 @@ table/table-layout
|
||||
|
||||
## Table-column Attributes
|
||||
|
||||
| Name | Description | Type | Accepted Values | Default |
|
||||
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | --------------------------------- |
|
||||
| type | type of the column. If set to `selection`, the column will display checkbox. If set to `index`, the column will display index of the row (staring from 1). If set to `expand`, the column will display expand icon. | string | selection / index / expand | — |
|
||||
| index | customize indices for each row, works on columns with `type=index` | number / function(index) | — | — |
|
||||
| label | column label | string | — | — |
|
||||
| column-key | column's key. If you need to use the filter-change event, you need this attribute to identify which column is being filtered | string | — | — |
|
||||
| prop | field name. You can also use its alias: `property` | string | — | — |
|
||||
| width | column width | string / number | — | — |
|
||||
| min-width | column minimum width. Columns with `width` has a fixed width, while columns with `min-width` has a width that is distributed in proportion | string / number | — | — |
|
||||
| fixed | whether column is fixed at left / right. Will be fixed at left if `true` | string / boolean | true / 'left' / 'right' | — |
|
||||
| render-header | render function for table header of this column | function(\{ column, $index \}) | — | — |
|
||||
| sortable | whether column can be sorted. Remote sorting can be done by setting this attribute to 'custom' and listening to the `sort-change` event of Table | boolean / string | custom | false |
|
||||
| sort-method | sorting method, works when `sortable` is `true`. Should return a number, just like Array.sort | function(a, b) | — | — |
|
||||
| sort-by | specify which property to sort by, works when `sortable` is `true` and `sort-method` is `undefined`. If set to an Array, the column will sequentially sort by the next property if the previous one is equal | function(row, index) / string / array | — | — |
|
||||
| sort-orders | the order of the sorting strategies used when sorting the data, works when `sortable` is `true`. Accepts an array, as the user clicks on the header, the column is sorted in order of the elements in the array | array | (the elements in the array need to be one of the following: `ascending`, `descending` and `null` restores to the original order) | ['ascending', 'descending', null] |
|
||||
| resizable | whether column width can be resized, works when `border` of `el-table` is `true` | boolean | — | true |
|
||||
| formatter | function that formats cell content | function(row, column, cellValue, index) | — | — |
|
||||
| show-overflow-tooltip | whether to hide extra content and show them in a tooltip when hovering on the cell | boolean | — | false |
|
||||
| align | alignment | string | left / center / right | left |
|
||||
| header-align | alignment of the table header. If omitted, the value of the above `align` attribute will be applied | string | left / center / right | — |
|
||||
| class-name | class name of cells in the column | string | — | — |
|
||||
| label-class-name | class name of the label of this column | string | — | — |
|
||||
| selectable | function that determines if a certain row can be selected, works when `type` is 'selection' | function(row, index) | — | — |
|
||||
| reserve-selection | whether to reserve selection after data refreshing, works when `type` is 'selection'. Note that `row-key` is required for this to work | boolean | — | false |
|
||||
| filters | an array of data filtering options. For each element in this array, `text` and `value` are required | `Array<{text: string, value: string}>` | — | — |
|
||||
| filter-placement | placement for the filter dropdown | string | top / top-start / top-end / bottom / bottom-start / bottom-end / left / left-start / left-end / right / right-start / right-end | — |
|
||||
| filter-multiple | whether data filtering supports multiple options | boolean | — | true |
|
||||
| filter-method | data filtering method. If `filter-multiple` is on, this method will be called multiple times for each row, and a row will display if one of the calls returns `true` | function(value, row, column) | — | — |
|
||||
| filtered-value | filter value for selected data, might be useful when table header is rendered with `render-header` | array | — | — |
|
||||
| Name | Description | Type | Accepted Values | Default |
|
||||
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | --------------------------------- |
|
||||
| type | type of the column. If set to `selection`, the column will display checkbox. If set to `index`, the column will display index of the row (staring from 1). If set to `expand`, the column will display expand icon. | string | selection / index / expand | — |
|
||||
| index | customize indices for each row, works on columns with `type=index` | number / function(index) | — | — |
|
||||
| label | column label | string | — | — |
|
||||
| column-key | column's key. If you need to use the filter-change event, you need this attribute to identify which column is being filtered | string | — | — |
|
||||
| prop | field name. You can also use its alias: `property` | string | — | — |
|
||||
| width | column width | string / number | — | — |
|
||||
| min-width | column minimum width. Columns with `width` has a fixed width, while columns with `min-width` has a width that is distributed in proportion | string / number | — | — |
|
||||
| fixed | whether column is fixed at left / right. Will be fixed at left if `true` | string / boolean | true / 'left' / 'right' | — |
|
||||
| render-header | render function for table header of this column | function(\{ column, $index \}) | — | — |
|
||||
| sortable | whether column can be sorted. Remote sorting can be done by setting this attribute to 'custom' and listening to the `sort-change` event of Table | boolean / string | custom | false |
|
||||
| sort-method | sorting method, works when `sortable` is `true`. Should return a number, just like Array.sort | function(a, b) | — | — |
|
||||
| sort-by | specify which property to sort by, works when `sortable` is `true` and `sort-method` is `undefined`. If set to an Array, the column will sequentially sort by the next property if the previous one is equal | function(row, index) / string / array | — | — |
|
||||
| sort-orders | the order of the sorting strategies used when sorting the data, works when `sortable` is `true`. Accepts an array, as the user clicks on the header, the column is sorted in order of the elements in the array | array | (the elements in the array need to be one of the following: `ascending`, `descending` and `null` restores to the original order) | ['ascending', 'descending', null] |
|
||||
| resizable | whether column width can be resized, works when `border` of `el-table` is `true` | boolean | — | true |
|
||||
| formatter | function that formats cell content | function(row, column, cellValue, index) | — | — |
|
||||
| show-overflow-tooltip | whether to hide extra content and show them in a tooltip when hovering on the cell | boolean \| [`object`](#table-attributes)<VersionTag version="2.2.28" /> | Refer to table [tooltip-options](#table-attributes) | — |
|
||||
| align | alignment | string | left / center / right | left |
|
||||
| header-align | alignment of the table header. If omitted, the value of the above `align` attribute will be applied | string | left / center / right | — |
|
||||
| class-name | class name of cells in the column | string | — | — |
|
||||
| label-class-name | class name of the label of this column | string | — | — |
|
||||
| selectable | function that determines if a certain row can be selected, works when `type` is 'selection' | function(row, index) | — | — |
|
||||
| reserve-selection | whether to reserve selection after data refreshing, works when `type` is 'selection'. Note that `row-key` is required for this to work | boolean | — | false |
|
||||
| filters | an array of data filtering options. For each element in this array, `text` and `value` are required | `Array<{text: string, value: string}>` | — | — |
|
||||
| filter-placement | placement for the filter dropdown | string | top / top-start / top-end / bottom / bottom-start / bottom-end / left / left-start / left-end / right / right-start / right-end | — |
|
||||
| filter-multiple | whether data filtering supports multiple options | boolean | — | true |
|
||||
| filter-method | data filtering method. If `filter-multiple` is on, this method will be called multiple times for each row, and a row will display if one of the calls returns `true` | function(value, row, column) | — | — |
|
||||
| filtered-value | filter value for selected data, might be useful when table header is rendered with `render-header` | array | — | — |
|
||||
|
||||
## Table-column Slots
|
||||
|
||||
|
||||
@@ -160,14 +160,6 @@ describe('table column', () => {
|
||||
wrapper.unmount()
|
||||
})
|
||||
|
||||
it('show-tooltip-when-overflow', async () => {
|
||||
// old version prop name
|
||||
const wrapper = createTable('show-tooltip-when-overflow')
|
||||
await doubleWait()
|
||||
expect(wrapper.findAll('.el-tooltip').length).toEqual(5)
|
||||
wrapper.unmount()
|
||||
})
|
||||
|
||||
it('align', async () => {
|
||||
const wrapper = createTable(
|
||||
'align="left"',
|
||||
|
||||
@@ -7,6 +7,7 @@ import type {
|
||||
DefaultRow,
|
||||
Table,
|
||||
} from '../table/defaults'
|
||||
import type { TableOverflowTooltipOptions } from '../util'
|
||||
|
||||
interface TableBodyProps<T> {
|
||||
store: Store<T>
|
||||
@@ -16,7 +17,8 @@ interface TableBodyProps<T> {
|
||||
rowStyle: ColumnStyle<T>
|
||||
fixed: string
|
||||
highlight: boolean
|
||||
tooltipEffect: string
|
||||
tooltipEffect?: string
|
||||
tooltipOptions?: TableOverflowTooltipOptions
|
||||
}
|
||||
|
||||
const defaultProps = {
|
||||
@@ -26,6 +28,9 @@ const defaultProps = {
|
||||
},
|
||||
stripe: Boolean,
|
||||
tooltipEffect: String,
|
||||
tooltipOptions: {
|
||||
type: Object as PropType<TableBodyProps<DefaultRow>['tooltipOptions']>,
|
||||
},
|
||||
context: {
|
||||
default: () => ({}),
|
||||
type: Object as PropType<TableBodyProps<DefaultRow>['context']>,
|
||||
|
||||
@@ -6,6 +6,7 @@ import { createTablePopper, getCell, getColumnByCell } from '../util'
|
||||
import { TABLE_INJECTION_KEY } from '../tokens'
|
||||
import type { TableColumnCtx } from '../table-column/defaults'
|
||||
import type { TableBodyProps } from './defaults'
|
||||
import type { TableOverflowTooltipOptions } from '../util'
|
||||
|
||||
function useEvents<T>(props: Partial<TableBodyProps<T>>) {
|
||||
const parent = inject(TABLE_INJECTION_KEY)
|
||||
@@ -49,7 +50,7 @@ function useEvents<T>(props: Partial<TableBodyProps<T>>) {
|
||||
const handleCellMouseEnter = (
|
||||
event: MouseEvent,
|
||||
row: T,
|
||||
tooltipEffect: string
|
||||
tooltipOptions: TableOverflowTooltipOptions
|
||||
) => {
|
||||
const table = parent
|
||||
const cell = getCell(event)
|
||||
@@ -72,6 +73,10 @@ function useEvents<T>(props: Partial<TableBodyProps<T>>) {
|
||||
)
|
||||
}
|
||||
|
||||
if (!tooltipOptions) {
|
||||
return
|
||||
}
|
||||
|
||||
// 判断是否text-overflow, 如果是就显示tooltip
|
||||
const cellChild = (event.target as HTMLElement).querySelector(
|
||||
'.cell'
|
||||
@@ -107,11 +112,7 @@ function useEvents<T>(props: Partial<TableBodyProps<T>>) {
|
||||
parent?.refs.tableWrapper,
|
||||
cell,
|
||||
cell.innerText || cell.textContent,
|
||||
{
|
||||
placement: 'top',
|
||||
strategy: 'fixed',
|
||||
},
|
||||
tooltipEffect
|
||||
tooltipOptions
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// @ts-nocheck
|
||||
import { computed, h, inject } from 'vue'
|
||||
import { merge } from 'lodash-unified'
|
||||
import { useNamespace } from '@element-plus/hooks'
|
||||
import { getRowIdentity } from '../util'
|
||||
import { TABLE_INJECTION_KEY } from '../tokens'
|
||||
@@ -48,7 +49,7 @@ function useRender<T>(props: Partial<TableBodyProps<T>>) {
|
||||
treeRowData?: TreeNode,
|
||||
expanded = false
|
||||
) => {
|
||||
const { tooltipEffect, store } = props
|
||||
const { tooltipEffect, tooltipOptions, store } = props
|
||||
const { indent, columns } = store.states
|
||||
const rowClasses = getRowClass(row, $index)
|
||||
let display = true
|
||||
@@ -112,6 +113,15 @@ function useRender<T>(props: Partial<TableBodyProps<T>>) {
|
||||
const baseKey = `${$index},${cellIndex}`
|
||||
const patchKey = columnData.columnKey || columnData.rawColumnKey || ''
|
||||
const tdChildren = cellChildren(cellIndex, column, data)
|
||||
const mergedTooltipOptions =
|
||||
column.showOverflowTooltip &&
|
||||
merge(
|
||||
{
|
||||
effect: tooltipEffect,
|
||||
},
|
||||
tooltipOptions,
|
||||
column.showOverflowTooltip
|
||||
)
|
||||
return h(
|
||||
'td',
|
||||
{
|
||||
@@ -121,7 +131,7 @@ function useRender<T>(props: Partial<TableBodyProps<T>>) {
|
||||
rowspan,
|
||||
colspan,
|
||||
onMouseenter: ($event) =>
|
||||
handleCellMouseEnter($event, row, tooltipEffect),
|
||||
handleCellMouseEnter($event, row, mergedTooltipOptions),
|
||||
onMouseleave: handleCellMouseLeave,
|
||||
},
|
||||
[tdChildren]
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// @ts-nocheck
|
||||
import type { ComponentInternalInstance, PropType, Ref, VNode } from 'vue'
|
||||
import type { DefaultRow, Table } from '../table/defaults'
|
||||
import type { TableOverflowTooltipOptions } from '../util'
|
||||
|
||||
type CI<T> = { column: TableColumnCtx<T>; $index: number }
|
||||
|
||||
@@ -33,8 +34,7 @@ interface TableColumnCtx<T> {
|
||||
rawColumnKey: string
|
||||
align: string
|
||||
headerAlign: string
|
||||
showTooltipWhenOverflow: boolean
|
||||
showOverflowTooltip: boolean
|
||||
showOverflowTooltip?: boolean | TableOverflowTooltipOptions
|
||||
fixed: boolean | string
|
||||
formatter: (
|
||||
row: T,
|
||||
@@ -113,8 +113,9 @@ export default {
|
||||
columnKey: String,
|
||||
align: String,
|
||||
headerAlign: String,
|
||||
showTooltipWhenOverflow: Boolean,
|
||||
showOverflowTooltip: Boolean,
|
||||
showOverflowTooltip: [Boolean, Object] as PropType<
|
||||
TableColumnCtx<DefaultRow>['showOverflowTooltip']
|
||||
>,
|
||||
fixed: [Boolean, String],
|
||||
formatter: Function as PropType<TableColumnCtx<DefaultRow>['formatter']>,
|
||||
selectable: Function as PropType<TableColumnCtx<DefaultRow>['selectable']>,
|
||||
|
||||
@@ -73,8 +73,7 @@ export default defineComponent({
|
||||
property: props.prop || props.property,
|
||||
align: realAlign,
|
||||
headerAlign: realHeaderAlign,
|
||||
showOverflowTooltip:
|
||||
props.showOverflowTooltip || props.showTooltipWhenOverflow,
|
||||
showOverflowTooltip: props.showOverflowTooltip,
|
||||
// filter 相关属性
|
||||
filterable: props.filters || props.filterMethod,
|
||||
filteredValue: [],
|
||||
|
||||
@@ -92,6 +92,7 @@
|
||||
:highlight="highlightCurrentRow"
|
||||
:row-class-name="rowClassName"
|
||||
:tooltip-effect="tooltipEffect"
|
||||
:tooltip-options="tooltipOptions"
|
||||
:row-style="rowStyle"
|
||||
:store="store"
|
||||
:stripe="stripe"
|
||||
|
||||
@@ -10,6 +10,7 @@ import type { Nullable } from '@element-plus/utils'
|
||||
import type { Store } from '../store'
|
||||
import type { TableColumnCtx } from '../table-column/defaults'
|
||||
import type TableLayout from '../table-layout'
|
||||
import type { TableOverflowTooltipOptions } from '../util'
|
||||
|
||||
export type DefaultRow = any
|
||||
|
||||
@@ -115,6 +116,7 @@ interface TableProps<T> {
|
||||
defaultExpandAll?: boolean
|
||||
defaultSort?: Sort
|
||||
tooltipEffect?: string
|
||||
tooltipOptions?: TableOverflowTooltipOptions
|
||||
spanMethod?: (data: {
|
||||
row: T
|
||||
rowIndex: number
|
||||
@@ -226,6 +228,7 @@ export default {
|
||||
defaultExpandAll: Boolean,
|
||||
defaultSort: Object as PropType<TableProps<DefaultRow>['defaultSort']>,
|
||||
tooltipEffect: String,
|
||||
tooltipOptions: Object as PropType<TableProps<DefaultRow>['tooltipOptions']>,
|
||||
spanMethod: Function as PropType<TableProps<DefaultRow>['spanMethod']>,
|
||||
selectOnIndeterminate: {
|
||||
type: Boolean,
|
||||
|
||||
@@ -1,24 +1,40 @@
|
||||
// @ts-nocheck
|
||||
import { createPopper } from '@popperjs/core'
|
||||
import { flatMap, get } from 'lodash-unified'
|
||||
import { flatMap, get, merge } from 'lodash-unified'
|
||||
import escapeHtml from 'escape-html'
|
||||
import { hasOwn, isArray, isBoolean, throwError } from '@element-plus/utils'
|
||||
import { useZIndex } from '@element-plus/hooks'
|
||||
import type {
|
||||
IPopperOptions,
|
||||
PopperInstance,
|
||||
} from '@element-plus/components/popper'
|
||||
import {
|
||||
hasOwn,
|
||||
isArray,
|
||||
isBoolean,
|
||||
isObject,
|
||||
throwError,
|
||||
} from '@element-plus/utils'
|
||||
import { useDelayedToggle, useZIndex } from '@element-plus/hooks'
|
||||
import type { PopperInstance } from '@element-plus/components/popper'
|
||||
import type { Nullable } from '@element-plus/utils'
|
||||
import type { TableColumnCtx } from './table-column/defaults'
|
||||
import type { ElTooltipProps } from '@element-plus/components/tooltip'
|
||||
|
||||
export type TableOverflowTooltipOptions = Partial<
|
||||
Pick<
|
||||
ElTooltipProps,
|
||||
| 'effect'
|
||||
| 'enterable'
|
||||
| 'hideAfter'
|
||||
| 'offset'
|
||||
| 'placement'
|
||||
| 'popperClass'
|
||||
| 'popperOptions'
|
||||
| 'showAfter'
|
||||
| 'showArrow'
|
||||
// | 'transition'
|
||||
>
|
||||
>
|
||||
|
||||
export const getCell = function (event: Event) {
|
||||
return (event.target as HTMLElement)?.closest('td')
|
||||
}
|
||||
|
||||
const isObject = function (obj: unknown): boolean {
|
||||
return obj !== null && typeof obj === 'object'
|
||||
}
|
||||
|
||||
export const orderBy = function <T>(
|
||||
array: T[],
|
||||
sortKey: string,
|
||||
@@ -315,16 +331,27 @@ export function createTablePopper(
|
||||
parentNode: HTMLElement | undefined,
|
||||
trigger: HTMLElement,
|
||||
popperContent: string,
|
||||
popperOptions: Partial<IPopperOptions>,
|
||||
tooltipEffect: string
|
||||
tooltipOptions?: TableOverflowTooltipOptions
|
||||
) {
|
||||
// TODO transition
|
||||
tooltipOptions = merge(
|
||||
{
|
||||
enterable: true,
|
||||
showArrow: true,
|
||||
} as TableOverflowTooltipOptions,
|
||||
tooltipOptions
|
||||
)
|
||||
const { nextZIndex } = useZIndex()
|
||||
const ns = parentNode?.dataset.prefix
|
||||
const scrollContainer = parentNode?.querySelector(`.${ns}-scrollbar__wrap`)
|
||||
function renderContent(): HTMLDivElement {
|
||||
const isLight = tooltipEffect === 'light'
|
||||
const isLight = tooltipOptions.effect === 'light'
|
||||
const content = document.createElement('div')
|
||||
content.className = `${ns}-popper ${isLight ? 'is-light' : 'is-dark'}`
|
||||
content.className = [
|
||||
`${ns}-popper`,
|
||||
isLight ? 'is-light' : 'is-dark',
|
||||
tooltipOptions.popperClass || '',
|
||||
].join(' ')
|
||||
popperContent = escapeHtml(popperContent)
|
||||
content.innerHTML = popperContent
|
||||
content.style.zIndex = String(nextZIndex())
|
||||
@@ -345,37 +372,56 @@ export function createTablePopper(
|
||||
try {
|
||||
popperInstance && popperInstance.destroy()
|
||||
content && parentNode?.removeChild(content)
|
||||
trigger.removeEventListener('mouseenter', showPopper)
|
||||
trigger.removeEventListener('mouseleave', removePopper)
|
||||
trigger.removeEventListener('mouseenter', onOpen)
|
||||
trigger.removeEventListener('mouseleave', onClose)
|
||||
scrollContainer?.removeEventListener('scroll', removePopper)
|
||||
removePopper = undefined
|
||||
} catch {}
|
||||
}
|
||||
let popperInstance: Nullable<PopperInstance> = null
|
||||
let onOpen = showPopper
|
||||
let onClose = removePopper
|
||||
if (tooltipOptions.enterable) {
|
||||
;({ onOpen, onClose } = useDelayedToggle({
|
||||
showAfter: tooltipOptions.showAfter,
|
||||
hideAfter: tooltipOptions.hideAfter,
|
||||
open: showPopper,
|
||||
close: removePopper,
|
||||
}))
|
||||
}
|
||||
const content = renderContent()
|
||||
const arrow = renderArrow()
|
||||
content.appendChild(arrow)
|
||||
content.onmouseenter = onOpen
|
||||
content.onmouseleave = onClose
|
||||
const modifiers = []
|
||||
if (tooltipOptions.offset) {
|
||||
modifiers.push({
|
||||
name: 'offset',
|
||||
options: {
|
||||
offset: [0, tooltipOptions.offset],
|
||||
},
|
||||
})
|
||||
}
|
||||
if (tooltipOptions.showArrow) {
|
||||
const arrow = content.appendChild(renderArrow())
|
||||
modifiers.push({
|
||||
name: 'arrow',
|
||||
options: {
|
||||
element: arrow,
|
||||
padding: 10,
|
||||
},
|
||||
})
|
||||
}
|
||||
const popperOptions = tooltipOptions.popperOptions || {}
|
||||
popperInstance = createPopper(trigger, content, {
|
||||
strategy: 'absolute',
|
||||
modifiers: [
|
||||
{
|
||||
name: 'offset',
|
||||
options: {
|
||||
offset: [0, 8],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'arrow',
|
||||
options: {
|
||||
element: arrow,
|
||||
padding: 10,
|
||||
},
|
||||
},
|
||||
],
|
||||
placement: tooltipOptions.placement || 'top',
|
||||
strategy: 'fixed',
|
||||
...popperOptions,
|
||||
modifiers: popperOptions.modifiers
|
||||
? modifiers.concat(popperOptions.modifiers)
|
||||
: modifiers,
|
||||
})
|
||||
trigger.addEventListener('mouseenter', showPopper)
|
||||
trigger.addEventListener('mouseleave', removePopper)
|
||||
trigger.addEventListener('mouseenter', onOpen)
|
||||
trigger.addEventListener('mouseleave', onClose)
|
||||
scrollContainer?.addEventListener('scroll', removePopper)
|
||||
return popperInstance
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user