From f1c204f79020948616847728c1ee85006aabd93f Mon Sep 17 00:00:00 2001 From: Juergen Kunz Date: Tue, 7 Apr 2026 13:55:43 +0000 Subject: [PATCH] feat(dees-table): add floating header support with fixed-height table mode --- changelog.md | 7 + ts_web/00_commitinfo_data.ts | 2 +- .../00group-dataview/dees-table/dees-table.ts | 380 ++++++++++++++---- .../00group-dataview/dees-table/styles.ts | 66 ++- 4 files changed, 364 insertions(+), 91 deletions(-) diff --git a/changelog.md b/changelog.md index c4588e3..1109567 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,12 @@ # Changelog +## 2026-04-07 - 3.63.0 - feat(dees-table) +add floating header support with fixed-height table mode + +- replace the sticky-header option with a fixed-height mode for internal scrolling +- add a JS-managed floating header so column headers remain visible when tables scroll inside ancestor containers +- sync floating header column widths and filter rows with the rendered table + ## 2026-04-07 - 3.62.0 - feat(dees-table) add multi-column sorting with header menu controls and priority indicators diff --git a/ts_web/00_commitinfo_data.ts b/ts_web/00_commitinfo_data.ts index 6561f51..26641e1 100644 --- a/ts_web/00_commitinfo_data.ts +++ b/ts_web/00_commitinfo_data.ts @@ -3,6 +3,6 @@ */ export const commitinfo = { name: '@design.estate/dees-catalog', - version: '3.62.0', + version: '3.63.0', description: 'A comprehensive library that provides dynamic web components for building sophisticated and modern web applications using JavaScript and TypeScript.' } diff --git a/ts_web/elements/00group-dataview/dees-table/dees-table.ts b/ts_web/elements/00group-dataview/dees-table/dees-table.ts index 55e9817..bff991a 100644 --- a/ts_web/elements/00group-dataview/dees-table/dees-table.ts +++ b/ts_web/elements/00group-dataview/dees-table/dees-table.ts @@ -184,8 +184,17 @@ export class DeesTable extends DeesElement { accessor columnFilters: Record = {}; @property({ type: Boolean, attribute: 'show-column-filters' }) accessor showColumnFilters: boolean = false; - @property({ type: Boolean, reflect: true, attribute: 'sticky-header' }) - accessor stickyHeader: boolean = false; + /** + * When set, the table renders inside a fixed-height scroll container + * (`max-height: var(--table-max-height, 360px)`) and the header sticks + * within that box via plain CSS sticky. + * + * When unset (the default), the table flows naturally and a JS-managed + * floating header keeps the column headers visible while the table is + * scrolled past in any ancestor scroll container (page or otherwise). + */ + @property({ type: Boolean, reflect: true, attribute: 'fixed-height' }) + accessor fixedHeight: boolean = false; // search row state @property({ type: String }) @@ -297,74 +306,7 @@ export class DeesTable extends DeesElement {
- - ${this.selectionMode !== 'none' - ? html` - - ` - : html``} - ${effectiveColumns - .filter((c) => !c.hidden) - .map((col) => { - const isSortable = !!col.sortable; - const ariaSort = this.getAriaSort(col); - return html` - `; - })} - ${(() => { - if (this.dataActions && this.dataActions.length > 0) { - return html` `; - } - })()} - - ${this.showColumnFilters - ? html` - ${this.selectionMode !== 'none' - ? html`` - : html``} - ${effectiveColumns - .filter((c) => !c.hidden) - .map((col) => { - const key = String(col.key); - if (col.filterable === false) return html``; - return html``; - })} - ${(() => { - if (this.dataActions && this.dataActions.length > 0) { - return html` `; - } - })()} - ` - : html``} + ${this.renderHeaderRows(effectiveColumns)} ${viewData.map((itemArg, rowIndex) => { @@ -507,6 +449,13 @@ export class DeesTable extends DeesElement {
- ${this.selectionMode === 'multi' - ? html` - ) => { - e.stopPropagation(); - this.setSelectVisible(e.detail === true); - }} - > - ` - : html``} - - isSortable ? this.handleHeaderClick(eventArg, col, effectiveColumns) : null} - @contextmenu=${(eventArg: MouseEvent) => - isSortable - ? this.openHeaderContextMenu(eventArg, col, effectiveColumns) - : null} - > - ${col.header ?? (col.key as any)} - ${this.renderSortIndicator(col)} - Actions
- this.setColumnFilter(key, (e.target as HTMLInputElement).value)} /> -
+ ` : html`
No data set!
`}