diff --git a/packages/vtable/examples/menu.ts b/packages/vtable/examples/menu.ts index 43acadaad6..f7b7f04e23 100644 --- a/packages/vtable/examples/menu.ts +++ b/packages/vtable/examples/menu.ts @@ -806,6 +806,10 @@ export const menus = [ { path: 'theme', name: 'custom-list' + }, + { + path: 'theme', + name: 'scrollbar-always-visible-space-correction' } ] }, diff --git a/packages/vtable/examples/theme/scrollbar-always-visible-space-correction.ts b/packages/vtable/examples/theme/scrollbar-always-visible-space-correction.ts new file mode 100644 index 0000000000..911437dad3 --- /dev/null +++ b/packages/vtable/examples/theme/scrollbar-always-visible-space-correction.ts @@ -0,0 +1,153 @@ +import * as VTable from '../../src'; +import { bindDebugTool } from '../../src/scenegraph/debug-tool'; +const CONTAINER_ID = 'vTable'; + +const generatePersons = count => { + return Array.from(new Array(count)).map((_, i) => ({ + id: i + 1, + email1: `${i + 1}@xxx.com`, + name: `小明${i + 1}`, + lastName: '王', + date1: '2022年9月1日', + tel: '000-0000-0000', + sex: i % 2 === 0 ? 'boy' : 'girl', + work: i % 2 === 0 ? 'back-end engineer' + (i + 1) : 'front-end engineer' + (i + 1), + city: 'beijing', + profit: 'test-the-edge-side' + })); +}; +export function createTable() { + const columns = [ + { + field: 'id', + title: 'Order ID', + width: 'auto' + }, + { + field: 'lastName', + title: 'Last Name', + width: 'auto' + }, + { + field: 'name', + title: 'Name', + width: 'auto' + }, + { + field: 'email1', + title: 'Email Address', + width: 'auto' + }, + { + field: 'date1', + title: 'date1', + width: 'auto' + }, + { + field: 'tel', + title: 'tel', + width: 'auto' + }, + { + field: 'sex', + title: 'sex', + width: 'auto' + }, + { + field: 'work', + title: 'work', + width: 'auto' + }, + { + field: 'city', + title: 'city', + width: 'auto' + }, + { + field: 'Quantity', + title: 'Quantity', + width: 'auto' + }, + { + field: 'Sales', + title: 'Sales', + width: 'auto' + }, + { + field: 'profit', + title: 'Profit', + width: 'auto' + } + ]; + + const records = generatePersons(10); + const container = document.getElementById(CONTAINER_ID); + const button1 = document.createElement('button'); + button1.innerText = 'set 10 rows'; + + const button2 = document.createElement('button'); + button2.innerText = 'set 40 rows'; + + container?.parentElement?.appendChild(button1); + container?.parentElement?.appendChild(button2); + + container?.style.setProperty('margin', '10px'); + container?.style.setProperty('width', '500px'); + container?.style.setProperty('height', '500px'); + container?.style.setProperty('box-sizing', 'border-box'); + container?.style.setProperty('border', '1px solid #d7d9dc'); + const option: VTable.ListTableConstructorOptions = { + container: container, + emptyTip: true, + records: records, + columns: [...columns, ...columns, ...columns], + theme: VTable.themes.ARCO.extends({ + defaultStyle: { + padding: 0 + }, + headerStyle: { + fontSize: 14, + padding: 0, + fontWeight: 600 + }, + bodyStyle: { + fontSize: 14, + padding: 0, + bgColor: args => { + const { row, table } = args; + return 1 & (row - table.frozenRowCount) ? '#f8f8f8' : '#FFF'; + } + }, + cellInnerBorder: false, + frameStyle: { + borderLineWidth: [0, 1, 1, 0], + shadowBlur: 0, + cornerRadius: 0, + shadowColor: 'transparent' + }, + scrollStyle: { + scrollRailColor: 'RGBA(216,216,216,.5)', + visible: 'always', + width: 16, + hoverOn: false, + barToSide: true, + scrollSliderCornerRadius: 0, + scrollSliderColor: 'RGBA(170,170,170,1)' + } + }) + }; + const tableInstance = new VTable.ListTable(option); + (window as any).tableInstance = tableInstance; + + bindDebugTool(tableInstance.scenegraph.stage, { + customGrapicKeys: ['col', 'row'] + }); + + button1.onclick = () => { + tableInstance.setRecords(generatePersons(10)); + }; + + button2.onclick = () => { + tableInstance.setRecords(generatePersons(40)); + }; +} diff --git a/packages/vtable/src/core/BaseTable.ts b/packages/vtable/src/core/BaseTable.ts index cde6f93a35..61008e3de4 100644 --- a/packages/vtable/src/core/BaseTable.ts +++ b/packages/vtable/src/core/BaseTable.ts @@ -1163,8 +1163,25 @@ export abstract class BaseTable extends EventTarget implements BaseTableAPI { heightP = this.canvasHeight - 1; } - const width = Math.floor(widthP - style.getVerticalScrollBarSize(this.getTheme().scrollStyle)); - const height = Math.floor(heightP - style.getHorizontalScrollBarSize(this.getTheme().scrollStyle)); + const scrollStyle = this.getTheme().scrollStyle; + let vScrollBarWidth = style.getVerticalScrollBarSize(scrollStyle); + let hScrollBarHeight = style.getHorizontalScrollBarSize(scrollStyle); + + // always的情况下没触发scrollbar应当取消掉这部分区域的留白 + if (scrollStyle.visible === 'always') { + const vScrollBarVisible = this.scenegraph ? this.scenegraph.component.vScrollBar.attribute.visible : false; + if (vScrollBarWidth > 0 && vScrollBarVisible !== true) { + vScrollBarWidth = 0; + } + + const hScrollBarVisible = this.scenegraph ? this.scenegraph.component.hScrollBar.attribute.visible : false; + if (hScrollBarHeight > 0 && hScrollBarVisible !== true) { + hScrollBarHeight = 0; + } + } + + const width = Math.floor(widthP - vScrollBarWidth); + const height = Math.floor(heightP - hScrollBarHeight); if (this.internalProps.theme?.frameStyle) { //考虑表格整体边框的问题 diff --git a/packages/vtable/src/scenegraph/component/table-component.ts b/packages/vtable/src/scenegraph/component/table-component.ts index 1324346142..da5a97ed7d 100644 --- a/packages/vtable/src/scenegraph/component/table-component.ts +++ b/packages/vtable/src/scenegraph/component/table-component.ts @@ -376,6 +376,11 @@ export class TableComponent { attrY = y - (hoverOn ? width : -this.table.scenegraph.tableGroup.attribute.y); } + // always的情况下没触发scrollbar应当取消掉这部分区域的留白 + if (hoverOn && horizontalVisible === 'always' && this.table.scenegraph.component.hScrollBar.attribute.visible) { + attrY += width; + } + this.hScrollBar.setAttributes({ x: frozenColsWidth + (!hoverOn ? this.table.scenegraph.tableGroup.attribute.x : 0), y: attrY, @@ -416,6 +421,11 @@ export class TableComponent { attrX = x - (hoverOn ? width : -this.table.scenegraph.tableGroup.attribute.x); } + // always的情况下没触发scrollbar应当取消掉这部分区域的留白 + if (hoverOn && verticalVisible === 'always' && this.table.scenegraph.component.vScrollBar.attribute.visible) { + attrX += width; + } + this.vScrollBar.setAttributes({ x: attrX, y: frozenRowsHeight + (!hoverOn ? this.table.scenegraph.tableGroup.attribute.y : 0), @@ -443,6 +453,10 @@ export class TableComponent { this.table.stateManager.setScrollLeft(oldHorizontalBarPos); this.table.stateManager.setScrollTop(oldVerticalBarPos); + + if (horizontalVisible === 'always') { + this.table._updateSize(); + } } /** diff --git a/packages/vtable/src/tools/style.ts b/packages/vtable/src/tools/style.ts index ac42717876..4c6720d459 100644 --- a/packages/vtable/src/tools/style.ts +++ b/packages/vtable/src/tools/style.ts @@ -3,7 +3,7 @@ import type { ScrollStyle } from '../ts-types'; export function getHorizontalScrollBarSize(scrollStyle?: ScrollStyle): number { if ( - scrollStyle?.hoverOn || + (scrollStyle.visible !== 'always' && scrollStyle?.hoverOn) || (scrollStyle?.horizontalVisible && scrollStyle?.horizontalVisible === 'none') || (!scrollStyle?.horizontalVisible && scrollStyle?.visible === 'none') ) { @@ -14,7 +14,7 @@ export function getHorizontalScrollBarSize(scrollStyle?: ScrollStyle): number { export function getVerticalScrollBarSize(scrollStyle?: ScrollStyle): number { if ( - scrollStyle?.hoverOn || + (scrollStyle.visible !== 'always' && scrollStyle?.hoverOn) || (scrollStyle?.verticalVisible && scrollStyle?.verticalVisible === 'none') || (!scrollStyle?.verticalVisible && scrollStyle?.visible === 'none') ) {