Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Table] New Feature And Bug Fix #660

Merged
merged 9 commits into from
Mar 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 2 additions & 10 deletions examples/table/demos/loading.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<div class="tdesign-demo-block-column">
<t-table :data="data" :columns="columns" :rowKey="rowKey" :size="size" :loading="true" height="150"></t-table>
<t-table :data="data" :columns="columns" :rowKey="rowKey" :size="size" :loading="true"></t-table>

<!-- loading-props 用于透传全部加载组件特性,以便实现更多自定义内容-->
<!-- loadingProps.indicator=false 隐藏加载图标 -->
Expand All @@ -11,20 +11,12 @@
:size="size"
:loading="true"
:loading-props="{ indicator: false }"
height="150"
>
<div slot="loading" class="t-table--loading-message">😊 这里使用插槽自定义加载状态 😊</div>
</t-table>

<!-- loadingProps.indicator=false 隐藏加载图标 -->
<t-table
:data="[]"
:columns="columns"
:rowKey="rowKey"
:size="size"
:loading="renderLoading"
height="150"
></t-table>
<t-table :data="[]" :columns="columns" :rowKey="rowKey" :size="size" :loading="renderLoading"></t-table>
</div>
</template>
<script lang="jsx">
Expand Down
5 changes: 2 additions & 3 deletions examples/table/demos/multi-header.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
:sort.sync="sortInfo"
:columns="columns"
:bordered="bordered"
:max-height="fixedHeader ? 380 : 1000"
:max-height="fixedHeader ? 380 : undefined"
:columnController="{ displayType: 'auto-width' }"
:filterRow="() => null"
:headerAffixProps="{ offsetTop: 0 }"
Expand Down Expand Up @@ -141,11 +141,10 @@ function getColumns(fixedLeftCol, fixedRightCol) {
children: [
{
align: 'left',
ellipsis: true,
colKey: 'property',
title: '属性',
fixed: fixedRightCol && 'right',
width: 100,
width: 110,
filter: {
type: 'single',
list: [
Expand Down
4 changes: 2 additions & 2 deletions examples/table/demos/pagination-ajax.vue
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export default {
colKey: 'name',
title: '姓名',
render(h, { row: { name } }) {
return name ? `${name.first} ${name.last}` : 'UNKNOW_USER';
return name ? `${name.first} ${name.last}` : 'UNKNOWN_USER';
},
},
{
Expand All @@ -48,7 +48,7 @@ export default {
ellipsis: true,
},
],
rowKey: 'property',
rowKey: 'phone',
tableLayout: 'auto',
rowClassName: 'property-class',
pagination: {
Expand Down
2 changes: 1 addition & 1 deletion src/_common
6 changes: 3 additions & 3 deletions src/hooks/useVirtualScroll.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,14 +95,14 @@ const useVirtualScroll = ({
if (!anchorDom) {
return; // 快速调整高度时,新的元素可能来不及加载,暂时跳过更新
}
const anchorDomHeight = anchorDom.getBoundingClientRect().height; // 获取锚点元素的高
const anchorDomHeight = anchorDom?.getBoundingClientRect()?.height; // 获取锚点元素的高
state.cachedScrollY[index] = container.value.scrollTop - offset; // 锚点元素scrollY= 容器滚动高度 - 锚点元素的offset
state.cachedHeight[index] = anchorDomHeight;

for (let i = index + 1; i <= state.visibleData[state.visibleData.length - 1].$index; i++) {
// 计算锚点后面的元素scrollY
const tr = trs.get(i);
const { height } = tr.getBoundingClientRect();
const { height } = tr?.getBoundingClientRect() || {};
state.cachedHeight[i] = height;
const scrollY = state.cachedScrollY[i - 1] + state.cachedHeight[i - 1]; // 当前元素的y 是前一个元素的y+前一个元素高度
// state.cachedScrollY[i] = scrollY;
Expand All @@ -111,7 +111,7 @@ const useVirtualScroll = ({

for (let i = index - 1; i >= state.visibleData[0].$index; i--) {
const tr = trs.get(i);
const { height } = tr.getBoundingClientRect();
const { height } = tr?.getBoundingClientRect() || {};
state.cachedHeight[i] = height;
const scrollY = state.cachedScrollY[i + 1] - state.cachedHeight[i]; // 当前元素的y是下一个元素y - 当前元素高度
// state.cachedScrollY[i] = scrollY;
Expand Down
16 changes: 9 additions & 7 deletions src/table/base-table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,14 @@ export default defineComponent({

const dynamicBaseTableClasses = computed(() => [
tableClasses.value,
{ [tableBaseClass.headerFixed]: isFixedHeader.value },
{ [tableBaseClass.columnFixed]: isFixedColumn.value },
{ [tableBaseClass.widthOverflow]: isWidthOverflow.value },
{ [tableBaseClass.multipleHeader]: isMultipleHeader.value },
{ [tableColFixedClasses.leftShadow]: showColumnShadow.left },
{ [tableColFixedClasses.rightShadow]: showColumnShadow.right },
{
[tableBaseClass.headerFixed]: isFixedHeader.value,
[tableBaseClass.columnFixed]: isFixedColumn.value,
[tableBaseClass.widthOverflow]: isWidthOverflow.value,
[tableBaseClass.multipleHeader]: isMultipleHeader.value,
[tableColFixedClasses.leftShadow]: showColumnShadow.left,
[tableColFixedClasses.rightShadow]: showColumnShadow.right,
},
]);

const tableElmClasses = computed(() => [
Expand Down Expand Up @@ -305,8 +307,8 @@ export default defineComponent({
<Loading
loading={!!(this.loading || customLoadingText)}
text={customLoadingText ? () => customLoadingText : undefined}
props={this.loadingProps}
showOverlay
props={this.loadingProps}
>
{tableContent}
</Loading>
Expand Down
7 changes: 6 additions & 1 deletion src/table/filter-controller.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export interface TableFilterControllerProps {
};
isFocusClass: string;
column: PrimaryTableCol;
primaryTableElement: HTMLDivElement;
}

export default defineComponent({
Expand All @@ -42,10 +43,12 @@ export default defineComponent({
innerFilterValue: Object as PropType<TableFilterControllerProps['innerFilterValue']>,
tableFilterClasses: Object as PropType<TableFilterControllerProps['tableFilterClasses']>,
isFocusClass: String,
primaryTableElement: HTMLDivElement,
},

// eslint-disable-next-line
setup(props: TableFilterControllerProps) {
const triggerElementRef = ref<HTMLDivElement>(null);
const renderTNode = useTNodeDefault();
const { t, global } = useConfig('table');
const filterPopupVisible = ref(false);
Expand All @@ -58,6 +61,7 @@ export default defineComponent({
t,
global,
filterPopupVisible,
triggerElementRef,
renderTNode,
onFilterPopupVisibleChange,
};
Expand Down Expand Up @@ -150,6 +154,7 @@ export default defineComponent({
const defaultFilterIcon = this.t(this.global.filterIcon) || <FilterIcon />;
return (
<Popup
attach={this.primaryTableElement ? () => this.primaryTableElement : undefined}
visible={this.filterPopupVisible}
destroyOnClose
trigger="click"
Expand All @@ -167,7 +172,7 @@ export default defineComponent({
</div>
)}
>
<div>{this.renderTNode('filterIcon', defaultFilterIcon)}</div>
<div ref="triggerElementRef">{this.renderTNode('filterIcon', defaultFilterIcon)}</div>
</Popup>
);
},
Expand Down
5 changes: 4 additions & 1 deletion src/table/hooks/useFilter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,12 @@ function filterEmptyData(data: FilterValue) {
}

export default function useFilter(props: TdPrimaryTableProps, context: SetupContext) {
const primaryTableRef = ref(null);
const renderTNode = useTNodeDefault();
const { filterValue } = toRefs(props);
const { tableFilterClasses, isFocusClass } = useClassName();

// uncontroll and controll
// unControl and control
const [tFilterValue, setTFilterValue] = useDefaultValue(
filterValue,
props.defaultFilterValue,
Expand Down Expand Up @@ -144,6 +145,7 @@ export default function useFilter(props: TdPrimaryTableProps, context: SetupCont
innerFilterValue={innerFilterValue.value}
tableFilterClasses={tableFilterClasses}
isFocusClass={isFocusClass}
primaryTableElement={primaryTableRef.value?.$el}
on={{
reset: onReset,
confirm: onConfirm,
Expand All @@ -154,6 +156,7 @@ export default function useFilter(props: TdPrimaryTableProps, context: SetupCont
}

return {
primaryTableRef,
hasEmptyCondition,
renderFilterIcon,
renderFirstFilterRow,
Expand Down
21 changes: 12 additions & 9 deletions src/table/primary-table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ export default defineComponent({
// 行选中功能
const { formatToRowSelectColumn, tRowClassNames } = useRowSelect(props);
// 过滤功能
const { hasEmptyCondition, renderFilterIcon, renderFirstFilterRow } = useFilter(props, context);
const {
hasEmptyCondition, primaryTableRef, renderFilterIcon, renderFirstFilterRow,
} = useFilter(props, context);

const { renderTitleWidthIcon } = useTableHeader(props);
const { renderAsyncLoading } = useAsyncLoading(props, context);
Expand Down Expand Up @@ -100,6 +102,7 @@ export default defineComponent({
showExpandedRow,
tRowClassNames,
hasEmptyCondition,
primaryTableRef,
renderTNode,
renderColumnController,
renderExpandedRow,
Expand All @@ -112,14 +115,14 @@ export default defineComponent({

methods: {
// support @row-click @page-change @row-hover .etc. events, Vue3 do not need this function
getListenser() {
const listenser: TableListeners = {};
getListener() {
const listener: TableListeners = {};
BASE_TABLE_ALL_EVENTS.forEach((key) => {
listenser[key] = (...args: any) => {
listener[key] = (...args: any) => {
this.$emit(key, ...args);
};
});
return listenser;
return listener;
},

formatNode(api: string, renderInnerNode: Function, condition: boolean) {
Expand All @@ -131,8 +134,8 @@ export default defineComponent({
if (innerNode && propsNode) {
return () => (
<div>
{innerNode}
{propsNode}
{innerNode}
</div>
);
}
Expand All @@ -155,15 +158,15 @@ export default defineComponent({
lastFullRow,
};

// 事件,Vue3 do not need this.getListenser
// 事件,Vue3 do not need this.getListener
const on: TableListeners = {
...this.getListenser(),
...this.getListener(),
'page-change': this.onInnerPageChange,
};
if (this.expandOnRowClick) {
on['row-click'] = this.onInnerExpandRowClick;
}
// replace `scopedSlots={this.$scopedSlots}` of `v-slots={this.$slots}` in Vue3
return <BaseTable scopedSlots={this.$scopedSlots} props={props} on={on} {...this.$attrs} />;
return <BaseTable ref="primaryTableRef" scopedSlots={this.$scopedSlots} props={props} on={on} {...this.$attrs} />;
},
});
18 changes: 12 additions & 6 deletions src/table/thead.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {
defineComponent, computed, SetupContext, PropType,
defineComponent, computed, SetupContext, PropType, ref,
} from '@vue/composition-api';
import isFunction from 'lodash/isFunction';
import { CreateElement } from 'vue';
Expand Down Expand Up @@ -41,6 +41,7 @@ export default defineComponent({
},

setup(props: TheadProps, { slots }: SetupContext) {
const theadRef = ref<HTMLHeadElement>();
const classnames = useClassName();
const { tableHeaderClasses, tableBaseClass } = classnames;
const { classPrefix } = useConfig();
Expand All @@ -55,6 +56,7 @@ export default defineComponent({

return {
...classnames,
theadRef,
theadClasses,
classPrefix,
slots,
Expand All @@ -73,9 +75,9 @@ export default defineComponent({
const thRowspanAndColspan = this.spansAndLeafNodes.rowspanAndColspanMap;
return this.thList.map((row, rowIndex) => {
const thRow = row.map((col: TableColumns[0], index: number) => {
const rospanAndColspan = thRowspanAndColspan.get(col);
if (index === 0 && rospanAndColspan.rowspan > 1) {
for (let j = rowIndex + 1; j < rowIndex + rospanAndColspan.rowspan; j++) {
const rowspanAndColspan = thRowspanAndColspan.get(col);
if (index === 0 && rowspanAndColspan.rowspan > 1) {
for (let j = rowIndex + 1; j < rowIndex + rowspanAndColspan.rowspan; j++) {
thBorderMap.set(this.thList[j][0], true);
}
}
Expand Down Expand Up @@ -107,10 +109,14 @@ export default defineComponent({
data-colkey={col.colKey}
class={thClasses}
style={styles}
attrs={{ ...rospanAndColspan }}
attrs={{ ...rowspanAndColspan }}
>
<div class={this.tableBaseClass.thCellInner}>
{col.ellipsis ? <TEllipsis>{innerTh}</TEllipsis> : innerTh}
{col.ellipsis ? (
<TEllipsis attach={this.theadRef ? () => this.theadRef : undefined}>{innerTh}</TEllipsis>
) : (
innerTh
)}
</div>
</th>
);
Expand Down
32 changes: 15 additions & 17 deletions test/ssr/__snapshots__/ssr.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -13123,8 +13123,8 @@ exports[`ssr snapshot test renders ./examples/table/demos/loading.vue correctly
<div class="tdesign-demo-block-column">
<div class="t-table t-size-s" style="position:relative;">
<div class="t-loading__parent">
<div class="t-table__content" style="height:150px;">
<table class="t-table--layout-fixed t-table--full-height" style="width:;">
<div class="t-table__content">
<table class="t-table--layout-fixed" style="width:;">
<colgroup>
<col style="width:100px;">
<col style="width:100px;">
Expand Down Expand Up @@ -13180,8 +13180,8 @@ exports[`ssr snapshot test renders ./examples/table/demos/loading.vue correctly
</div>
<div class="t-table t-size-s" style="position:relative;">
<div class="t-loading__parent">
<div class="t-table__content" style="height:150px;">
<table class="t-table--layout-fixed t-table--full-height" style="width:;">
<div class="t-table__content">
<table class="t-table--layout-fixed" style="width:;">
<colgroup>
<col style="width:100px;">
<col style="width:100px;">
Expand Down Expand Up @@ -13237,8 +13237,8 @@ exports[`ssr snapshot test renders ./examples/table/demos/loading.vue correctly
</div>
<div class="t-table t-size-s" style="position:relative;">
<div class="t-loading__parent">
<div class="t-table__content" style="height:150px;">
<table class="t-table--layout-fixed t-table--full-height" style="width:;">
<div class="t-table__content">
<table class="t-table--layout-fixed" style="width:;">
<colgroup>
<col style="width:100px;">
<col style="width:100px;">
Expand Down Expand Up @@ -13395,7 +13395,7 @@ exports[`ssr snapshot test renders ./examples/table/demos/multi-header.vue corre
<col style="width:100px;">
<col style="width:100px;">
<col style="width:100px;">
<col style="width:100px;">
<col style="width:110px;">
<col style="width:100px;">
<col style="width:100px;">
<col style="width:100px;">
Expand Down Expand Up @@ -13437,15 +13437,13 @@ exports[`ssr snapshot test renders ./examples/table/demos/multi-header.vue corre
</th>
<th data-colkey="property" rowspan="2" class="t-table__th-property">
<div class="t-table__th-cell-inner">
<div class="t-table__ellipsis t-text-ellipsis">
<div class="t-table__cell--filterable">
<div class="t-table__cell--title">
<div>属性</div>
<div class="t-table__filter-icon-wrap">
<div class="t-table__filter-icon"><svg fill="none" viewBox="0 0 16 16" width="1em" height="1em" class="t-icon t-icon-filter">
<path fill="currentColor" d="M2 3a1 1 0 011-1h10a1 1 0 011 1v1.79l-4.25 2.5V14h-3.5V7.29L2 4.79V3zm11 0H3v1.21l4.25 2.5V13h1.5V6.71L13 4.21V3z" fill-opacity="0.9"></path>
</svg></div>
</div>
<div class="t-table__cell--filterable">
<div class="t-table__cell--title">
<div>属性</div>
<div class="t-table__filter-icon-wrap">
<div class="t-table__filter-icon"><svg fill="none" viewBox="0 0 16 16" width="1em" height="1em" class="t-icon t-icon-filter">
<path fill="currentColor" d="M2 3a1 1 0 011-1h10a1 1 0 011 1v1.79l-4.25 2.5V14h-3.5V7.29L2 4.79V3zm11 0H3v1.21l4.25 2.5V13h1.5V6.71L13 4.21V3z" fill-opacity="0.9"></path>
</svg></div>
</div>
</div>
</div>
Expand Down Expand Up @@ -13750,7 +13748,7 @@ exports[`ssr snapshot test renders ./examples/table/demos/pagination-ajax.vue co
<thead class="t-table__header">
<tr>
<th data-colkey="name" class="t-table__th-name">
<div class="t-table__th-cell-inner">UNKNOW_USER</div>
<div class="t-table__th-cell-inner">UNKNOWN_USER</div>
</th>
<th data-colkey="gender" class="t-table__th-gender">
<div class="t-table__th-cell-inner">性别</div>
Expand Down
Loading