@itrocks/table 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/edit.js ADDED
@@ -0,0 +1,208 @@
1
+ import ContentEditable from '../contenteditable/contenteditable.js';
2
+ import Plugin from '../plugin/plugin.js';
3
+ let editable;
4
+ let selected;
5
+ let selectedStyle;
6
+ let selectedText;
7
+ export class RangeCopy {
8
+ commonAncestorContainer;
9
+ endContainer;
10
+ endOffset;
11
+ startContainer;
12
+ startOffset;
13
+ constructor(range) {
14
+ this.commonAncestorContainer = range.commonAncestorContainer;
15
+ this.endContainer = range.endContainer;
16
+ this.endOffset = range.endOffset;
17
+ this.startContainer = range.startContainer;
18
+ this.startOffset = range.startOffset;
19
+ }
20
+ toRange() {
21
+ const range = new Range;
22
+ range.setStart(this.startContainer, this.startOffset);
23
+ range.setEnd(this.endContainer, this.endOffset);
24
+ return range;
25
+ }
26
+ }
27
+ export default class TableEdit extends Plugin {
28
+ zIndex = '2';
29
+ init() {
30
+ const table = this.of;
31
+ table.styleSheet.push(`
32
+ ${table.selector} > * > tr > * > div[contenteditable] {
33
+ position: relative;
34
+ z-index: ${this.zIndex};
35
+ }
36
+ `);
37
+ table.addEventListener(table.element, 'mousedown', event => {
38
+ const cell = this.closestEditableCell(event.target);
39
+ if (!cell)
40
+ return;
41
+ this.selectCell(cell);
42
+ });
43
+ }
44
+ closestEditable(node) {
45
+ if ((node instanceof Range) || (node instanceof RangeCopy)) {
46
+ node = node.commonAncestorContainer;
47
+ }
48
+ let parent = (node instanceof Element) ? node : (node.parentElement ?? undefined);
49
+ while (parent && !parent.hasAttribute('contenteditable')) {
50
+ parent = parent.parentElement ?? undefined;
51
+ }
52
+ if (!parent) {
53
+ throw 'Called from a node outside of contenteditable';
54
+ }
55
+ return parent;
56
+ }
57
+ closestEditableCell(target) {
58
+ return (target instanceof Element)
59
+ ? target.closest('table.itrocks > * > tr > *, table.itrocks > * > tr > *') ?? undefined
60
+ : undefined;
61
+ }
62
+ createEditable(selected, selectedStyle) {
63
+ const contentEditable = new ContentEditable(document.createElement('div'));
64
+ const editable = contentEditable.element;
65
+ editable.innerHTML = selected.innerHTML;
66
+ selected.innerHTML = '';
67
+ const height = getComputedStyle(selected).height;
68
+ if (!contentEditable.value().includes(contentEditable.br()))
69
+ editable.style.lineHeight = height;
70
+ editable.style.minHeight = height;
71
+ editable.style.paddingBottom = selectedStyle.paddingBottom;
72
+ editable.style.paddingLeft = selectedStyle.paddingLeft;
73
+ editable.style.paddingRight = selectedStyle.paddingRight;
74
+ editable.style.paddingTop = selectedStyle.paddingTop;
75
+ editable.addEventListener('input', event => {
76
+ const editable = event.target;
77
+ const contentEditable = editable.editable;
78
+ const text = contentEditable.value();
79
+ if (text.includes(contentEditable.br())) {
80
+ if (editable.style.lineHeight) {
81
+ editable.style.removeProperty('line-height');
82
+ }
83
+ }
84
+ else if (!editable.style.lineHeight) {
85
+ editable.style.lineHeight = editable.style.minHeight;
86
+ }
87
+ this.setSelectedText(text);
88
+ });
89
+ selected.replaceChildren(editable);
90
+ selected.style.padding = '0';
91
+ if (selectedStyle.position === 'sticky') {
92
+ selected.style.zIndex = this.zIndex;
93
+ }
94
+ return editable;
95
+ }
96
+ editable() {
97
+ return editable;
98
+ }
99
+ editableEndRange(node) {
100
+ node = this.closestEditable(node);
101
+ while (node.lastChild && !(node.nodeType === Node.TEXT_NODE)) {
102
+ node = node.lastChild;
103
+ }
104
+ const newRange = new Range;
105
+ newRange.setStartAfter(node);
106
+ newRange.setEndAfter(node);
107
+ return newRange;
108
+ }
109
+ editableFullRange(node) {
110
+ const newRange = new Range;
111
+ newRange.selectNodeContents(this.closestEditable(node));
112
+ return newRange;
113
+ }
114
+ getSelectionRange() {
115
+ const selection = getSelection();
116
+ if (!selection)
117
+ throw 'Should be called only when there is a selection';
118
+ const range = selection?.getRangeAt(0);
119
+ if (!range)
120
+ throw 'Should be called only when there is a selection range';
121
+ return range;
122
+ }
123
+ inEditable(node) {
124
+ if ((node instanceof Range) || (node instanceof RangeCopy)) {
125
+ node = node.commonAncestorContainer;
126
+ }
127
+ return !!((node instanceof Element)
128
+ ? node.closest('div[contenteditable]')
129
+ : node.parentElement?.closest('div[contenteditable]'));
130
+ }
131
+ rangeTextContent(range) {
132
+ const element = document.createElement('div');
133
+ element.appendChild(range.cloneContents());
134
+ return element.innerHTML;
135
+ }
136
+ /** If cell is not already selected : unselects old cell, then selects this new one */
137
+ selectCell(cell) {
138
+ if (cell === selected)
139
+ return;
140
+ this.unselectCell();
141
+ this.setSelectedCell(cell);
142
+ }
143
+ /** Returns the currently selected cell, or undefined if no cell is selected */
144
+ selected() {
145
+ return selected;
146
+ }
147
+ /** Sets selected cell to this cell, and set its content to div[contenteditable] */
148
+ setSelectedCell(cell) {
149
+ selected = cell;
150
+ selectedText = selected.innerHTML;
151
+ const originSelectedStyle = getComputedStyle(selected);
152
+ selectedStyle = selected.getAttribute('style') ?? '';
153
+ selected.setAttribute('contenteditable', '');
154
+ setTimeout(() => {
155
+ if (!selected) {
156
+ console.error('cell:', cell);
157
+ throw 'Unexpected failure: cell was unselected before contenteditable was effective';
158
+ }
159
+ const range = new RangeCopy(this.getSelectionRange());
160
+ selected.removeAttribute('contenteditable');
161
+ editable = this.createEditable(selected, originSelectedStyle);
162
+ this.setSelectionRange(this.inEditable(range) ? range.toRange() : this.editableFullRange(editable));
163
+ });
164
+ }
165
+ setSelectedText(newText) {
166
+ if (newText === selectedText)
167
+ return;
168
+ selectedText = newText;
169
+ //this.of.reset()
170
+ }
171
+ setSelectionRange(range) {
172
+ const selection = getSelection();
173
+ if (!selection)
174
+ throw 'Should be called only when there is a selection';
175
+ selection.removeAllRanges();
176
+ selection.addRange(range);
177
+ }
178
+ textContentAfterRange() {
179
+ const range = this.getSelectionRange();
180
+ const editable = this.closestEditable(range.commonAncestorContainer);
181
+ const next = new Range;
182
+ next.setStart(range.endContainer, range.endOffset);
183
+ editable.lastChild
184
+ ? next.setEndAfter(editable.lastChild)
185
+ : next.setEnd(editable, editable.textContent?.length ?? 0);
186
+ return this.rangeTextContent(next);
187
+ }
188
+ textContentBeforeRange() {
189
+ const range = this.getSelectionRange();
190
+ const editable = this.closestEditable(range.commonAncestorContainer);
191
+ const previous = new Range;
192
+ previous.setStart(editable, 0);
193
+ previous.setEnd(range.startContainer, range.startOffset);
194
+ return this.rangeTextContent(previous);
195
+ }
196
+ unselectCell() {
197
+ if (!editable || !selected)
198
+ return;
199
+ editable.editable.deactivate();
200
+ selected.innerHTML = editable.innerHTML;
201
+ selectedStyle.length
202
+ ? selected.setAttribute('style', selectedStyle)
203
+ : selected.removeAttribute('style');
204
+ this.setSelectedText(selected.innerHTML);
205
+ editable = undefined;
206
+ selected = undefined;
207
+ }
208
+ }
package/fix.d.ts ADDED
@@ -0,0 +1,27 @@
1
+ import Plugin from '../node_modules/@itrocks/plugin/plugin.js';
2
+ import { HTMLTableFixElement, Table } from './table.js';
3
+ interface FullIndex {
4
+ column: string;
5
+ corner: string;
6
+ row: string;
7
+ }
8
+ export declare class FixTable extends Plugin<Table> {
9
+ columns: NodeListOf<HTMLTableFixElement>;
10
+ full?: FullIndex;
11
+ leftColumnCount: number;
12
+ rightColumnCount: number;
13
+ zIndex: string;
14
+ constructor(table: Table);
15
+ init(): void;
16
+ closestScrollable(element: Element): HTMLElement | (Window & typeof globalThis) | undefined;
17
+ protected countLeftColumns(): number;
18
+ protected countRightColumns(): number;
19
+ protected fixFootRows(): void;
20
+ protected fixHeadRows(): void;
21
+ protected fixLeftColumns(): void;
22
+ protected fixRightColumns(): void;
23
+ protected getColumns(): NodeListOf<HTMLTableFixElement>;
24
+ position(position: number, _counter: number, _colCell: HTMLTableFixElement, _side: 'bottom' | 'left' | 'right' | 'top'): string;
25
+ visibleInnerRect(): DOMRect;
26
+ }
27
+ export default FixTable;
package/fix.js ADDED
@@ -0,0 +1,191 @@
1
+ import Plugin from '../plugin/plugin.js';
2
+ export class FixTable extends Plugin {
3
+ columns;
4
+ full;
5
+ leftColumnCount;
6
+ rightColumnCount;
7
+ zIndex = '1';
8
+ constructor(table) {
9
+ super(table);
10
+ this.columns = this.getColumns();
11
+ this.leftColumnCount = this.countLeftColumns();
12
+ this.rightColumnCount = this.countRightColumns();
13
+ }
14
+ init() {
15
+ this.fixFootRows();
16
+ this.fixHeadRows();
17
+ this.fixLeftColumns();
18
+ this.fixRightColumns();
19
+ }
20
+ closestScrollable(element) {
21
+ let parent = element.closest('table')?.parentElement;
22
+ while (parent && (parent.scrollHeight <= parent.clientHeight)) {
23
+ parent = parent.parentElement;
24
+ }
25
+ return parent ? ((parent instanceof HTMLHtmlElement) ? window : parent) : undefined;
26
+ }
27
+ countLeftColumns() {
28
+ let count = 0;
29
+ while ((count < this.columns.length - 1) && (this.columns[count].dataset.fix !== undefined)) {
30
+ count++;
31
+ }
32
+ return count;
33
+ }
34
+ countRightColumns() {
35
+ let count = this.columns.length - 1;
36
+ while ((count > 0) && (this.columns[count].dataset.fix !== undefined)) {
37
+ count--;
38
+ }
39
+ return this.columns.length - 1 - count;
40
+ }
41
+ fixFootRows() {
42
+ const table = this.of;
43
+ if (!table.element.tFoot?.rows.length)
44
+ return;
45
+ let counter = 1, bottom = .0, previousBottom = table.element.getBoundingClientRect().bottom;
46
+ for (const row of Array.from(table.element.tFoot.querySelectorAll(':scope > tr')).reverse()) {
47
+ const actualBottom = row.getBoundingClientRect().bottom;
48
+ bottom += previousBottom - actualBottom;
49
+ previousBottom = actualBottom;
50
+ table.styleSheet.push(`
51
+ ${table.selector} > tfoot > tr:nth-last-child(${counter}) > * {
52
+ bottom: ${this.position(bottom, counter, row.firstElementChild, 'bottom')};
53
+ }
54
+ `);
55
+ counter++;
56
+ }
57
+ const zIndex = this.full ? `z-index: ${this.full.row};` : '';
58
+ table.styleSheet.push(`
59
+ ${table.selector} > tfoot > tr > * {
60
+ position: sticky;
61
+ ${zIndex}
62
+ }
63
+ `);
64
+ }
65
+ fixHeadRows() {
66
+ const table = this.of;
67
+ if (!table.element.tHead?.rows.length)
68
+ return;
69
+ let counter = 1, top = .0, previousTop = table.element.getBoundingClientRect().top;
70
+ table.element.tHead.querySelectorAll(':scope > tr').forEach(row => {
71
+ const actualTop = row.getBoundingClientRect().top;
72
+ top += actualTop - previousTop;
73
+ previousTop = actualTop;
74
+ table.styleSheet.push(`
75
+ ${table.selector} > thead > tr:nth-child(${counter}) > * {
76
+ top: ${this.position(top, counter, row.firstElementChild, 'top')};
77
+ }
78
+ `);
79
+ counter++;
80
+ });
81
+ const zIndex = this.full ? `z-index: ${this.full.row};` : '';
82
+ table.styleSheet.push(`
83
+ ${table.selector} > thead > tr > * {
84
+ position: sticky;
85
+ ${zIndex}
86
+ }
87
+ `);
88
+ }
89
+ fixLeftColumns() {
90
+ if (!this.leftColumnCount)
91
+ return;
92
+ const table = this.of;
93
+ const bodySel = [];
94
+ const cornerSel = [];
95
+ let counter = 1, left = .0, previousLeft = table.element.getBoundingClientRect().left;
96
+ for (const colCell of Array.from(this.columns).toSpliced(this.leftColumnCount)) {
97
+ const actualLeft = colCell.getBoundingClientRect().left;
98
+ left += actualLeft - previousLeft;
99
+ previousLeft = actualLeft;
100
+ table.styleSheet.push(`
101
+ ${table.selector} > * > tr > :nth-child(${counter}) {
102
+ left: ${this.position(left, counter, colCell, 'left')};
103
+ }
104
+ `);
105
+ bodySel.push(`${table.selector} > tbody > tr > :nth-child(${counter})`);
106
+ cornerSel.push(`${table.selector} > tfoot > tr > :nth-child(${counter})`);
107
+ cornerSel.push(`${table.selector} > thead > tr > :nth-child(${counter})`);
108
+ counter++;
109
+ }
110
+ const zIndex = this.full ? `z-index: ${this.full.column};` : '';
111
+ const zIndexValue = this.full ? this.full.corner : this.zIndex;
112
+ table.styleSheet.push(`
113
+ ${bodySel.join(', ')} {
114
+ position: sticky;
115
+ ${zIndex}
116
+ }
117
+ ${cornerSel.join(', ')} {
118
+ z-index: ${zIndexValue};
119
+ }
120
+ `);
121
+ }
122
+ fixRightColumns() {
123
+ if (!this.rightColumnCount)
124
+ return;
125
+ const table = this.of;
126
+ const bodySel = [];
127
+ const cornerSel = [];
128
+ let counter = 1, right = .0, previousRight = table.element.getBoundingClientRect().right;
129
+ for (const colCell of Array.from(this.columns).reverse().toSpliced(this.rightColumnCount)) {
130
+ const actualRight = colCell.getBoundingClientRect().right;
131
+ right += previousRight - actualRight;
132
+ previousRight = actualRight;
133
+ table.styleSheet.push(`
134
+ ${table.selector} > * > tr > :nth-last-child(${counter}) {
135
+ right: ${this.position(right, counter, colCell, 'right')};
136
+ }
137
+ `);
138
+ bodySel.push(`${table.selector} > tbody > tr > :nth-last-child(${counter})`);
139
+ if (this.full) {
140
+ cornerSel.push(`${table.selector} > tfoot > tr > :nth-last-child(${counter})`);
141
+ }
142
+ cornerSel.push(`${table.selector} > thead > tr > :nth-last-child(${counter})`);
143
+ counter++;
144
+ }
145
+ const zIndex = this.full ? `z-index: ${this.full.column};` : '';
146
+ const zIndexValue = this.full ? this.full.corner : this.zIndex;
147
+ table.styleSheet.push(`
148
+ ${bodySel.join(', ')} {
149
+ position: sticky;
150
+ ${zIndex}
151
+ }
152
+ ${cornerSel.join(', ')} {
153
+ z-index: ${zIndexValue};
154
+ }
155
+ `);
156
+ }
157
+ getColumns() {
158
+ if (this.columns)
159
+ return this.columns;
160
+ const table = this.of;
161
+ let columns = table.element.querySelectorAll(':scope > colgroup > col');
162
+ if (!columns.length) {
163
+ columns = table.element.querySelectorAll(':scope > thead > tr:first-child > *');
164
+ if (!columns.length) {
165
+ columns = table.element.querySelectorAll(':scope > tbody > tr:first-child > *');
166
+ }
167
+ }
168
+ return columns;
169
+ }
170
+ position(position, _counter, _colCell, _side) {
171
+ return `${position}px`;
172
+ }
173
+ visibleInnerRect() {
174
+ const tableElement = this.of.element;
175
+ const rect = tableElement.getBoundingClientRect();
176
+ if (this.leftColumnCount) {
177
+ rect.x = this.columns[this.leftColumnCount - 1].getBoundingClientRect().right;
178
+ }
179
+ if (tableElement.tHead?.lastElementChild?.firstElementChild) {
180
+ rect.y = tableElement.tHead.lastElementChild.firstElementChild.getBoundingClientRect().bottom;
181
+ }
182
+ if (this.rightColumnCount) {
183
+ rect.width = this.columns[this.columns.length - this.rightColumnCount].getBoundingClientRect().left - rect.x + 1;
184
+ }
185
+ if (tableElement.tFoot?.firstElementChild?.firstElementChild) {
186
+ rect.height = tableElement.tFoot.firstElementChild.firstElementChild.getBoundingClientRect().top - rect.y + 1;
187
+ }
188
+ return rect;
189
+ }
190
+ }
191
+ export default FixTable;
@@ -0,0 +1,10 @@
1
+ import TableFreeze from '../freeze.js';
2
+ import Table from '../table';
3
+ /**
4
+ * This plugin has no use and no effect if your table has border-collapse: collapse
5
+ */
6
+ export default class TableFreezeInheritBackground extends TableFreeze {
7
+ tableStyle: CSSStyleDeclaration;
8
+ constructor(table: Table);
9
+ init(): void;
10
+ }
@@ -0,0 +1,41 @@
1
+ import TableFreeze from '../freeze.js';
2
+ /**
3
+ * This plugin has no use and no effect if your table has border-collapse: collapse
4
+ */
5
+ export default class TableFreezeInheritBackground extends TableFreeze {
6
+ tableStyle;
7
+ constructor(table) {
8
+ super(table);
9
+ this.tableStyle = getComputedStyle(table.element);
10
+ }
11
+ init() {
12
+ if (this.tableStyle.borderCollapse !== 'separate')
13
+ return;
14
+ const table = this.of;
15
+ if (this.tableStyle.backgroundColor.replaceAll(' ', '').endsWith(',0)'))
16
+ return;
17
+ const borderSpacing = parseFloat(this.tableStyle.borderSpacing);
18
+ if (!borderSpacing)
19
+ return;
20
+ let selectors = [];
21
+ for (let child = 1; child <= this.leftColumnCount; child++) {
22
+ selectors.push(`${table.selector} > tbody > tr > :nth-child(${child})`);
23
+ }
24
+ for (let child = 1; child <= this.rightColumnCount; child++) {
25
+ selectors.push(`${table.selector} > tbody > tr > :nth-last-child(${child})`);
26
+ }
27
+ if (table.element.tFoot?.rows.length) {
28
+ selectors.push(`${table.selector} > tfoot > tr > *`);
29
+ }
30
+ if (table.element.tHead?.rows.length) {
31
+ selectors.push(`${table.selector} > thead > tr > *`);
32
+ }
33
+ if (!selectors.length)
34
+ return;
35
+ table.styleSheet.push(`
36
+ ${selectors.join(', ')} {
37
+ box-shadow: 0 0 0 ${borderSpacing}px ${this.tableStyle.backgroundColor};
38
+ }
39
+ `);
40
+ }
41
+ }
@@ -0,0 +1,14 @@
1
+ import Plugin from '../../node_modules/@itrocks/plugin/plugin.js';
2
+ import TableFreeze from '../freeze.js';
3
+ import { HTMLTableFreezeElement } from '../freeze.js';
4
+ import Table from '../table.js';
5
+ /**
6
+ * This plugin has no use and no effect if your table has border-collapse: separate (default)
7
+ */
8
+ export default class TableFreezeInheritBorder extends Plugin<Table> {
9
+ tableStyle: CSSStyleDeclaration;
10
+ tableFreeze: TableFreeze;
11
+ constructor(table: Table);
12
+ init(): void;
13
+ position(position: number, counter: number, colCell: HTMLTableFreezeElement, side: 'bottom' | 'left' | 'right' | 'top'): number;
14
+ }
@@ -0,0 +1,77 @@
1
+ import Plugin from '../../plugin/plugin.js';
2
+ /**
3
+ * This plugin has no use and no effect if your table has border-collapse: separate (default)
4
+ */
5
+ export default class TableFreezeInheritBorder extends Plugin {
6
+ tableStyle;
7
+ tableFreeze;
8
+ constructor(table) {
9
+ super(table);
10
+ this.tableFreeze = table.plugins.TableFreeze;
11
+ this.tableStyle = getComputedStyle(table.element);
12
+ if (this.tableStyle.borderCollapse !== 'collapse')
13
+ return;
14
+ const superPosition = this.tableFreeze.position;
15
+ this.tableFreeze.position = (position, counter, colCell, side) => superPosition.call(this.of.plugins.TableFreeze, this.position(position, counter, colCell, side), counter, colCell, side);
16
+ }
17
+ init() {
18
+ if (this.tableStyle.borderCollapse !== 'collapse')
19
+ return;
20
+ const tableFreeze = this.tableFreeze;
21
+ const table = this.of;
22
+ // table
23
+ table.styleSheet.push(`
24
+ ${table.selector} {
25
+ border-collapse: separate;
26
+ border-spacing: 0;
27
+ }
28
+ `);
29
+ // columns
30
+ let rightSelector = '';
31
+ if (tableFreeze.rightColumnCount) {
32
+ rightSelector = `:not(:nth-last-child(${tableFreeze.rightColumnCount}))`;
33
+ table.styleSheet.push(`
34
+ ${table.selector} > * > tr > :nth-last-child(${tableFreeze.rightColumnCount + 1}) {
35
+ border-right-width: 0;
36
+ }
37
+ `);
38
+ }
39
+ table.styleSheet.push(`
40
+ ${table.selector} > * > tr > :not(:first-child)${rightSelector} {
41
+ border-left-width: 0;
42
+ }
43
+ `);
44
+ // rows
45
+ if (table.element.tHead?.rows.length) {
46
+ table.styleSheet.push(`
47
+ ${table.selector} > tbody > tr > *,
48
+ ${table.selector} > thead > tr:not(:first-child) > * {
49
+ border-top-width: 0;
50
+ }
51
+ `);
52
+ }
53
+ else {
54
+ table.styleSheet.push(`
55
+ ${table.selector} > tbody > tr:not(:first-child) > * {
56
+ border-top-width: 0;
57
+ }
58
+ `);
59
+ }
60
+ if (table.element.tFoot?.rows.length) {
61
+ table.styleSheet.push(`
62
+ ${table.selector} > tbody > tr:last-child > *,
63
+ ${table.selector} > tfoot > tr:not(:last-child) > * {
64
+ border-bottom-width: 0;
65
+ }
66
+ `);
67
+ }
68
+ }
69
+ position(position, counter, colCell, side) {
70
+ const width = parseFloat(getComputedStyle(colCell).borderWidth) / 2;
71
+ const shift = (counter > 1) ? width : -width;
72
+ position += (side === 'bottom') || (side === 'right')
73
+ ? Math.ceil(shift)
74
+ : Math.floor(shift);
75
+ return position;
76
+ }
77
+ }
package/freeze.d.ts ADDED
@@ -0,0 +1,28 @@
1
+ import Plugin from '../node_modules/@itrocks/plugin/plugin.js';
2
+ import Table from './table.js';
3
+ export type HTMLTableFreezeElement = HTMLTableCellElement | HTMLTableColElement;
4
+ interface FullIndex {
5
+ column: string;
6
+ corner: string;
7
+ row: string;
8
+ }
9
+ export default class TableFreeze extends Plugin<Table> {
10
+ columns: NodeListOf<HTMLTableFreezeElement>;
11
+ full?: FullIndex;
12
+ leftColumnCount: number;
13
+ rightColumnCount: number;
14
+ zIndex: string;
15
+ constructor(table: Table);
16
+ init(): void;
17
+ closestScrollable(element: Element): HTMLElement | (Window & typeof globalThis) | undefined;
18
+ protected countLeftColumns(): number;
19
+ protected countRightColumns(): number;
20
+ protected freezeFootRows(): void;
21
+ protected freezeHeadRows(): void;
22
+ protected freezeLeftColumns(): void;
23
+ protected freezeRightColumns(): void;
24
+ protected getColumns(): NodeListOf<HTMLTableFreezeElement>;
25
+ position(position: number, _counter: number, _colCell: HTMLTableFreezeElement, _side: 'bottom' | 'left' | 'right' | 'top'): string;
26
+ visibleInnerRect(): DOMRect;
27
+ }
28
+ export {};