add table resize
This commit is contained in:
parent
9fd1eccd74
commit
2c80d20fb8
@ -13,18 +13,20 @@ module.exports = {
|
|||||||
project: './tsconfig.json'
|
project: './tsconfig.json'
|
||||||
},
|
},
|
||||||
rules: {
|
rules: {
|
||||||
|
"@typescript-eslint/ban-ts-comment": "off",
|
||||||
|
"@typescript-eslint/lines-between-class-members": "off",
|
||||||
"@typescript-eslint/no-explicit-any": "off",
|
"@typescript-eslint/no-explicit-any": "off",
|
||||||
|
"@typescript-eslint/no-unnecessary-type-assertion": "off",
|
||||||
"@typescript-eslint/no-unsafe-argument": "off",
|
"@typescript-eslint/no-unsafe-argument": "off",
|
||||||
"@typescript-eslint/no-unsafe-assignment": "off",
|
"@typescript-eslint/no-unsafe-assignment": "off",
|
||||||
"@typescript-eslint/no-unsafe-call": "off",
|
"@typescript-eslint/no-unsafe-call": "off",
|
||||||
"@typescript-eslint/no-unsafe-member-access": "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-unsafe-return": "off",
|
||||||
"@typescript-eslint/no-use-before-define": "off",
|
"@typescript-eslint/no-use-before-define": "off",
|
||||||
"@typescript-eslint/ban-ts-comment": "off",
|
"@typescript-eslint/restrict-template-expressions": "off",
|
||||||
"arrow-parens": "off",
|
"arrow-parens": "off",
|
||||||
"class-methods-use-this": "off",
|
"class-methods-use-this": "off",
|
||||||
|
"func-names": "off",
|
||||||
"import/prefer-default-export": "off",
|
"import/prefer-default-export": "off",
|
||||||
"no-console": "off",
|
"no-console": "off",
|
||||||
"no-plusplus": "off",
|
"no-plusplus": "off",
|
||||||
|
|||||||
@ -1,10 +1,22 @@
|
|||||||
import { ExcelComponent } from '../../core/ExcelComponent';
|
import { ExcelComponent } from '../../core/ExcelComponent';
|
||||||
import { createTable } from './table.template';
|
import { createTable } from './table.template';
|
||||||
|
import { resizeHandler } from './table.resize';
|
||||||
|
|
||||||
export class Table extends ExcelComponent {
|
export class Table extends ExcelComponent {
|
||||||
static className = 'excel__table';
|
static className = 'excel__table';
|
||||||
|
|
||||||
|
constructor($root: any) {
|
||||||
|
super($root, {
|
||||||
|
name: 'Table',
|
||||||
|
listeners: ['mousedown'],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
toHTML(): string {
|
toHTML(): string {
|
||||||
return createTable(50, 24);
|
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,
|
Z: 90,
|
||||||
};
|
};
|
||||||
|
|
||||||
function createCell(cellContent = '') {
|
function createCell(cellContent = '', index = 1) {
|
||||||
return `
|
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 `
|
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 `
|
return `
|
||||||
<div class="row">
|
<div class="row" data-type="resizable">
|
||||||
<div class="row-info">${infoContent}</div>
|
<div class="row-info">
|
||||||
|
${infoContent}
|
||||||
|
${needResize ? '<div class="row-resize" data-resize="row"></div>' : ''}
|
||||||
|
</div>
|
||||||
<div class="row-data">${dataContent}</div>
|
<div class="row-data">${dataContent}</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
@ -31,13 +37,16 @@ export function createTable(rowsCount = 10, columnCount = 10) {
|
|||||||
const cols = new Array(colsCount)
|
const cols = new Array(colsCount)
|
||||||
.fill('')
|
.fill('')
|
||||||
.map((el, index) => String.fromCharCode(CODES.A + index))
|
.map((el, index) => String.fromCharCode(CODES.A + index))
|
||||||
.map((el) => createCol(el))
|
.map((el, index) => createCol(el, index))
|
||||||
.join('');
|
.join('');
|
||||||
|
|
||||||
rows.push(createRow(cols));
|
rows.push(createRow(cols, '', false));
|
||||||
|
|
||||||
for (let i = 0; i < rowsCount; i++) {
|
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}`));
|
rows.push(createRow(cells, `${i + 1}`));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -52,6 +52,28 @@ export class Dom implements DomClass {
|
|||||||
off(eventType: string, callback: any) {
|
off(eventType: string, callback: any) {
|
||||||
this.$el.removeEventListener(eventType, callback);
|
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) {
|
export function $(selector: SelectorType) {
|
||||||
|
|||||||
@ -5,4 +5,5 @@ $formula-height: 24px;
|
|||||||
$header-height: 34px;
|
$header-height: 34px;
|
||||||
$info-cell-width: 40px;
|
$info-cell-width: 40px;
|
||||||
$row-height: 25px;
|
$row-height: 25px;
|
||||||
$toolbar-height: 40px;
|
$toolbar-height: 40px;
|
||||||
|
$primary-color: #3c74ff;
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"outDir": "./dist/",
|
"outDir": "./dist/",
|
||||||
"noImplicitAny": true,
|
"noImplicitAny": true,
|
||||||
"target": "es3",
|
"target": "es5",
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user