add table resize
This commit is contained in:
parent
9fd1eccd74
commit
2c80d20fb8
@ -13,18 +13,20 @@ module.exports = {
|
||||
project: './tsconfig.json'
|
||||
},
|
||||
rules: {
|
||||
"@typescript-eslint/ban-ts-comment": "off",
|
||||
"@typescript-eslint/lines-between-class-members": "off",
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
"@typescript-eslint/no-unnecessary-type-assertion": "off",
|
||||
"@typescript-eslint/no-unsafe-argument": "off",
|
||||
"@typescript-eslint/no-unsafe-assignment": "off",
|
||||
"@typescript-eslint/no-unsafe-call": "off",
|
||||
"@typescript-eslint/no-unsafe-member-access": "off",
|
||||
"@typescript-eslint/restrict-template-expressions": "off",
|
||||
"@typescript-eslint/lines-between-class-members": "off",
|
||||
"@typescript-eslint/no-unsafe-return": "off",
|
||||
"@typescript-eslint/no-use-before-define": "off",
|
||||
"@typescript-eslint/ban-ts-comment": "off",
|
||||
"@typescript-eslint/restrict-template-expressions": "off",
|
||||
"arrow-parens": "off",
|
||||
"class-methods-use-this": "off",
|
||||
"func-names": "off",
|
||||
"import/prefer-default-export": "off",
|
||||
"no-console": "off",
|
||||
"no-plusplus": "off",
|
||||
|
||||
@ -1,10 +1,22 @@
|
||||
import { ExcelComponent } from '../../core/ExcelComponent';
|
||||
import { createTable } from './table.template';
|
||||
import { resizeHandler } from './table.resize';
|
||||
|
||||
export class Table extends ExcelComponent {
|
||||
static className = 'excel__table';
|
||||
|
||||
constructor($root: any) {
|
||||
super($root, {
|
||||
name: 'Table',
|
||||
listeners: ['mousedown'],
|
||||
});
|
||||
}
|
||||
|
||||
toHTML(): string {
|
||||
return createTable(50, 24);
|
||||
}
|
||||
|
||||
onMousedown(event: MouseEvent) {
|
||||
resizeHandler(this.$root, event);
|
||||
}
|
||||
}
|
||||
|
||||
0
src/components/table/table.functions.ts
Normal file
0
src/components/table/table.functions.ts
Normal file
77
src/components/table/table.resize.ts
Normal file
77
src/components/table/table.resize.ts
Normal file
@ -0,0 +1,77 @@
|
||||
import { $, Dom } from '../../core/dom';
|
||||
|
||||
type CustomElementType = Element & { css: any };
|
||||
|
||||
export function resizeHandler($root: Dom, event: MouseEvent) {
|
||||
const { target } = event;
|
||||
if (!(target as HTMLElement).dataset.resize) return;
|
||||
|
||||
const $resizer = $(target as HTMLElement);
|
||||
const $parent = $resizer.closest('[data-type="resizable"]');
|
||||
const coords = $parent.getCoords();
|
||||
const type = $resizer.data.resize;
|
||||
|
||||
const allCols = $root.findAll(`[data-col="${$parent.data.col}"]`);
|
||||
|
||||
let delta: number;
|
||||
|
||||
(Element.prototype as CustomElementType).css = function (styles: any) {
|
||||
Object.keys(styles).forEach((key: any) => {
|
||||
this.style[key] = styles[key];
|
||||
});
|
||||
};
|
||||
|
||||
$resizer.css({ opacity: 1 });
|
||||
|
||||
document.onmousemove = e => {
|
||||
document.body.style.userSelect = 'none';
|
||||
|
||||
switch (type) {
|
||||
case 'col': {
|
||||
delta = e.pageX - coords.right;
|
||||
$resizer.css({
|
||||
right: `${-delta}px`,
|
||||
bottom: '-100vh',
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'row': {
|
||||
delta = e.pageY - coords.bottom;
|
||||
|
||||
$resizer.css({
|
||||
bottom: `${-delta}px`,
|
||||
right: '-100vw',
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default: break;
|
||||
}
|
||||
};
|
||||
|
||||
document.onmouseup = () => {
|
||||
document.onmousemove = null;
|
||||
document.onmouseup = null;
|
||||
document.body.style.userSelect = null;
|
||||
|
||||
switch (type) {
|
||||
case 'col': {
|
||||
$parent.css({ width: `${coords.width + delta}px` });
|
||||
allCols.forEach((el: CustomElementType) => el.css({ width: `${coords.width + delta}px` }));
|
||||
break;
|
||||
}
|
||||
|
||||
case 'row': {
|
||||
$parent.css({ height: `${coords.height + (delta)}px` });
|
||||
break;
|
||||
}
|
||||
|
||||
default: break;
|
||||
}
|
||||
|
||||
$resizer.css({ opacity: 0, bottom: 0, right: 0 });
|
||||
};
|
||||
}
|
||||
@ -3,22 +3,28 @@ const CODES = {
|
||||
Z: 90,
|
||||
};
|
||||
|
||||
function createCell(cellContent = '') {
|
||||
function createCell(cellContent = '', index = 1) {
|
||||
return `
|
||||
<div class="cell" contenteditable>${cellContent}</div>
|
||||
<div class="cell" contenteditable data-col="${index}">${cellContent}</div>
|
||||
`;
|
||||
}
|
||||
|
||||
function createCol(columnContent = '') {
|
||||
function createCol(columnContent = '', index = 1) {
|
||||
return `
|
||||
<div class="column">${columnContent}</div>
|
||||
<div class="column" data-type="resizable" data-col="${index}">
|
||||
${columnContent}
|
||||
<div class="col-resize" data-resize="col"></div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
function createRow(dataContent = '', infoContent = '') {
|
||||
function createRow(dataContent = '', infoContent = '', needResize = true) {
|
||||
return `
|
||||
<div class="row">
|
||||
<div class="row-info">${infoContent}</div>
|
||||
<div class="row" data-type="resizable">
|
||||
<div class="row-info">
|
||||
${infoContent}
|
||||
${needResize ? '<div class="row-resize" data-resize="row"></div>' : ''}
|
||||
</div>
|
||||
<div class="row-data">${dataContent}</div>
|
||||
</div>
|
||||
`;
|
||||
@ -31,13 +37,16 @@ export function createTable(rowsCount = 10, columnCount = 10) {
|
||||
const cols = new Array(colsCount)
|
||||
.fill('')
|
||||
.map((el, index) => String.fromCharCode(CODES.A + index))
|
||||
.map((el) => createCol(el))
|
||||
.map((el, index) => createCol(el, index))
|
||||
.join('');
|
||||
|
||||
rows.push(createRow(cols));
|
||||
rows.push(createRow(cols, '', false));
|
||||
|
||||
for (let i = 0; i < rowsCount; i++) {
|
||||
const cells = new Array(colsCount).fill(createCell()).join('');
|
||||
const cells = new Array(colsCount)
|
||||
.fill('')
|
||||
.map((el, index) => createCell('', index))
|
||||
.join('');
|
||||
rows.push(createRow(cells, `${i + 1}`));
|
||||
}
|
||||
|
||||
|
||||
@ -52,6 +52,28 @@ export class Dom implements DomClass {
|
||||
off(eventType: string, callback: any) {
|
||||
this.$el.removeEventListener(eventType, callback);
|
||||
}
|
||||
|
||||
get data() {
|
||||
return this.$el.dataset;
|
||||
}
|
||||
|
||||
closest(selector: string) {
|
||||
return $(this.$el.closest(selector) as HTMLElement);
|
||||
}
|
||||
|
||||
getCoords() {
|
||||
return this.$el.getBoundingClientRect();
|
||||
}
|
||||
|
||||
findAll(selector: string) {
|
||||
return this.$el.querySelectorAll(selector);
|
||||
}
|
||||
|
||||
css(styles: any) {
|
||||
Object.keys(styles).forEach((key: any) => {
|
||||
this.$el.style[key] = styles[key];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function $(selector: SelectorType) {
|
||||
|
||||
@ -5,4 +5,5 @@ $formula-height: 24px;
|
||||
$header-height: 34px;
|
||||
$info-cell-width: 40px;
|
||||
$row-height: 25px;
|
||||
$toolbar-height: 40px;
|
||||
$toolbar-height: 40px;
|
||||
$primary-color: #3c74ff;
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
"compilerOptions": {
|
||||
"outDir": "./dist/",
|
||||
"noImplicitAny": true,
|
||||
"target": "es3",
|
||||
"target": "es5",
|
||||
"allowJs": true,
|
||||
"moduleResolution": "node",
|
||||
"esModuleInterop": true,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user