This commit is contained in:
Eugene 2023-11-10 17:12:20 +03:00
parent 184b5960be
commit 48b5f8a2b2
32 changed files with 14609 additions and 20 deletions

File diff suppressed because one or more lines are too long

View File

@ -1 +0,0 @@
body{padding:0;margin:0}.content{position:absolute;top:0;left:0}.spreadsheet_container{position:relative;isolation:isolate;border:2px solid black}.sheet{display:block;contain:strict}.scroller{overflow:scroll;box-sizing:border-box;transform:translateZ(0)}.scroller:focus{outline:none}.editor{position:absolute;box-sizing:border-box;font-size:16px;font-family:Arial,Helvetica,sans-serif}.hide{visibility:hidden}

16
components/columnsBar.d.ts vendored Normal file
View File

@ -0,0 +1,16 @@
import Spreadsheet from "../main";
export declare class ColumnsBar {
element: HTMLCanvasElement;
private root;
height: number;
width: number;
ctx: CanvasRenderingContext2D;
constructor(root: Spreadsheet);
private createElement;
setElementPosition(top: number, left: number): void;
private isColumnSelected;
private renderText;
private renderRect;
private renderSingleColumn;
renderBar(): void;
}

11
components/editor.d.ts vendored Normal file
View File

@ -0,0 +1,11 @@
import Spreadsheet from "../main";
import { Position } from "../modules/cell";
export declare class Editor {
element: HTMLInputElement;
root: Spreadsheet;
constructor(root: Spreadsheet);
hide(): void;
show(position: Position, initialString?: string): void;
handleKeydown: (event: KeyboardEvent) => void;
handleClickOutside: (event: MouseEvent) => void;
}

17
components/rowsBar.d.ts vendored Normal file
View File

@ -0,0 +1,17 @@
import Spreadsheet from "../main";
export declare class RowsBar {
element: HTMLCanvasElement;
ctx: CanvasRenderingContext2D;
root: Spreadsheet;
width: number;
height: number;
resizerHeight: number;
constructor(root: Spreadsheet);
private createElement;
setElementPosition(top: number, left: number): void;
private isRowSelected;
private renderText;
private renderRect;
private renderSingleRow;
renderBar(): void;
}

29
components/scroller.d.ts vendored Normal file
View File

@ -0,0 +1,29 @@
import Spreadsheet from "../main";
export interface ViewportRect {
top: number;
left: number;
right: number;
bottom: number;
}
export declare class Scroller {
element: HTMLDivElement;
private verticalScroller;
private horizontalScroller;
private root;
private isSelecting;
constructor(root: Spreadsheet);
setSelectingMode(mode: boolean): void;
private handleMouseMove;
private handleMouseUp;
private handleDoubleClick;
private handleKeydown;
private handleClick;
private handleScroll;
getViewportBoundlingRect(): ViewportRect;
private buildComponent;
private getActualHeight;
private getActualWidth;
updateScrollerSize(): void;
private setScrollerHeight;
private setScrollerWidth;
}

17
components/sheet.d.ts vendored Normal file
View File

@ -0,0 +1,17 @@
import Spreadsheet from "../main";
import { Position } from "../modules/cell";
/**
* Display (CANVAS) element where cells render
*/
export declare class Sheet {
element: HTMLCanvasElement;
ctx: CanvasRenderingContext2D;
root: Spreadsheet;
constructor(root: Spreadsheet);
getCellByCoords(x: number, y: number): Position;
renderCell(position: Position): void;
private getSelectionRange;
private renderSelectionRange;
renderSelection(): void;
renderSheet(): void;
}

9
components/table.d.ts vendored Normal file
View File

@ -0,0 +1,9 @@
import Spreadsheet from "../main";
import { ViewProperties } from "../modules/config";
/** Base (root) component */
export declare class Table {
element: HTMLDivElement;
root: Spreadsheet;
constructor(root: Spreadsheet);
changeElementSizes(sizes: ViewProperties): void;
}

7
components/toolbar.d.ts vendored Normal file
View File

@ -0,0 +1,7 @@
import Spreadsheet from "../main";
export declare class Toolbar {
element: HTMLDivElement;
root: Spreadsheet;
height: number;
constructor(root: Spreadsheet);
}

1
index.d.ts vendored Normal file
View File

@ -0,0 +1 @@
export {};

View File

@ -1,15 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/spreadsheet_2/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Spreadsheet example</title>
<script type="module" crossorigin src="/spreadsheet_2/assets/index-a70da1df.js"></script>
<link rel="stylesheet" href="/spreadsheet_2/assets/index-e5b881ce.css">
</head>
<body>
<div id="spreadsheet"></div>
</body>
</html>

204
main.cjs Normal file

File diff suppressed because one or more lines are too long

1
main.cjs.map Normal file

File diff suppressed because one or more lines are too long

84
main.d.ts vendored Normal file
View File

@ -0,0 +1,84 @@
import { Cell, CellConstructorProps, CellStyles, Position, SerializableCell } from "./modules/cell";
import { CellChangeEvent, CellClickEvent, Config, CopyEvent, SelectionChangeEvent, ViewProperties } from "./modules/config";
import { RangeSelectionType, Selection } from "./modules/selection";
import { Styles } from "./modules/styles";
import { Viewport } from "./modules/viewport";
import "./scss/main.scss";
import { Cache } from "./modules/cache";
import { Events } from "./modules/events";
import { Clipboard } from "./modules/clipboard";
import { FormulaParser } from "./modules/formulaParser";
export interface SpreadsheetConstructorProperties {
view?: ViewProperties;
onCellClick?: CellClickEvent | null;
onSelectionChange?: SelectionChangeEvent | null;
onCellChange?: CellChangeEvent | null;
onCopy?: CopyEvent | null;
}
export declare const CSS_PREFIX = "modern_sc_";
export default class Spreadsheet {
private table;
private scroller;
private toolbar;
private rowsBar;
private columnsBar;
private sheet;
private editor;
styles: Styles;
config: Config;
data: Cell[][];
viewport: Viewport;
selection: Selection;
cache: Cache;
events: Events;
clipboard: Clipboard;
formulaParser: FormulaParser;
constructor(target: string | HTMLElement, props?: SpreadsheetConstructorProperties);
private setRowsBarPosition;
private setColumnsBarPosition;
private setElementsPositions;
private getInitialCache;
private buildComponent;
/**Destroy spreadsheet DOM element.
*
* May be usefull when need to rerender component.
*/
destroy(): void;
private appendTableToTarget;
/** Canvas rendering context 2D.
*
* Abble to draw on canvas with default CanvasAPI methods
*/
get ctx(): CanvasRenderingContext2D;
get viewProps(): ViewProperties;
get columnsBarHeight(): number;
get rowsBarWidth(): number;
get toolbarHeight(): number;
/** Focusing on interactive part of spreadsheet */
focusTable(): void;
getCellByCoords(x: number, y: number): Position;
getCell(position: Position): Cell;
changeCellValues(position: Position, values: Partial<Omit<CellConstructorProps, "position">>, enableCallback?: boolean): void;
changeCellStyles(position: Position, styles: CellStyles): void;
applyActionToRange(range: RangeSelectionType, callback: (cell: Cell) => void): void;
deleteSelectedCellsValues(): void;
showEditor(position: Position, initialString?: string): void;
renderSheet(): void;
renderSelection(): void;
renderColumnsBar(): void;
renderRowsBar(): void;
renderCell(row: number, col: number): void;
loadData(data: Cell[][] | SerializableCell[][]): Spreadsheet;
private makeConfigFromData;
serializeData(): SerializableCell[][];
}
export * from "./modules/cache";
export * from "./modules/cell";
export * from "./modules/column";
export * from "./modules/config";
export * from "./modules/renderBox";
export * from "./modules/row";
export * from "./modules/selection";
export * from "./modules/styles";
export * from "./modules/viewport";
export * from "./utils/createData";

13933
main.js Normal file

File diff suppressed because it is too large Load Diff

1
main.js.map Normal file

File diff suppressed because one or more lines are too long

11
manifest.json Normal file
View File

@ -0,0 +1,11 @@
{
"src/main.ts": {
"file": "main.cjs",
"isEntry": true,
"src": "src/main.ts"
},
"style.css": {
"file": "style.css",
"src": "style.css"
}
}

29
modules/cache.d.ts vendored Normal file
View File

@ -0,0 +1,29 @@
export interface CachedColumnProperties {
xPos: number;
colIdx: number;
}
export declare class CachedColumn {
xPos: number;
colIdx: number;
constructor(props: CachedColumnProperties);
}
export interface CachedRowProperties {
yPos: number;
rowIdx: number;
}
export declare class CachedRow {
yPos: number;
rowIdx: number;
constructor(props: CachedRowProperties);
}
export interface CacheConstructorProps {
columns: CachedColumn[];
rows: CachedRow[];
}
export declare class Cache {
columns: CachedColumn[];
rows: CachedRow[];
constructor(initial: CacheConstructorProps);
getRowByYCoord(y: number): number;
getColumnByXCoord(x: number): number;
}

58
modules/cell.d.ts vendored Normal file
View File

@ -0,0 +1,58 @@
import Spreadsheet from "../main";
import { FormulaParser } from "./formulaParser";
export type CellConstructorProps = {
value: string;
displayValue: string;
resultValue: string;
position: Position;
style: CellStyles | null;
};
interface CellStylesConstructorProps {
fontSize: number;
fontColor: string;
background: string;
borderColor: string;
selectedBackground: string;
selectedFontColor: string;
}
export declare class CellStyles {
fontSize: number;
fontColor: string;
background: string;
borderColor: string;
selectedBackground: string;
selectedFontColor: string;
constructor(props?: CellStylesConstructorProps);
}
export declare class Position {
row: number;
column: number;
constructor(row: number, column: number);
}
export declare class SerializableCell {
value: string;
displayValue: string;
resultValue: string;
position: Position;
style: CellStyles | null;
constructor(props: SerializableCell | SerializableCell);
}
export declare class Cell {
/** True value (data) */
value: string;
/** Value to render */
displayValue: string;
/** This refers to the values that were obtained by calculations, for example, after calculating the formula */
resultValue: string;
position: Position;
style: CellStyles | null;
cellsDependsOnThisCell: Position[];
dependedFromCells: Position[];
constructor(props: CellConstructorProps);
getSerializableCell(): SerializableCell;
changeStyles(styles: CellStyles): void;
changeValues(values: Partial<Omit<CellConstructorProps, "position">>): void;
evalFormula(parser: FormulaParser): void;
render(root: Spreadsheet): void;
}
export {};

9
modules/clipboard.d.ts vendored Normal file
View File

@ -0,0 +1,9 @@
import Spreadsheet, { RangeSelectionType } from "../main";
import { Cell, Position } from "./cell";
export declare class Clipboard {
saved: Cell[][] | null;
root: Spreadsheet;
constructor(root: Spreadsheet);
copy(data: Cell[][], range: RangeSelectionType): void;
paste(root: Spreadsheet, { column, row }: Position, event: ClipboardEvent): void;
}

9
modules/column.d.ts vendored Normal file
View File

@ -0,0 +1,9 @@
export type ColumnConstructorProperties = {
width: number;
title: string;
};
export declare class Column {
width: number;
title: string;
constructor(props: ColumnConstructorProperties);
}

41
modules/config.d.ts vendored Normal file
View File

@ -0,0 +1,41 @@
import { Cell } from "./cell";
import { Column } from "./column";
import { Row } from "./row";
import { RangeSelectionType, Selection } from "./selection";
export interface ViewProperties {
width: number;
height: number;
}
export type CellClickEvent = (event: MouseEvent, cell: Cell) => void;
export type SelectionChangeEvent = (selection: Selection) => void;
export type CellChangeEvent = (cell: Cell) => void;
export type CopyEvent = (range: RangeSelectionType, data: Cell[][], dataAsString: string) => void;
export type ConfigProperties = {
/** Please, end it with '_' symbol.
*
* *Example:*
*
* 'test_'
* 'google_' */
rows: Row[];
columns: Column[];
view: ViewProperties;
onCellClick?: CellClickEvent | null;
onSelectionChange?: SelectionChangeEvent | null;
onCellChange?: CellChangeEvent | null;
onCopy?: CopyEvent | null;
};
export type SheetConfigConstructorProps = {
rows: Row[];
columns: Column[];
};
export declare class Config {
rows: Row[];
columns: Column[];
view: ViewProperties;
onCellClick: CellClickEvent | null;
onSelectonChange: SelectionChangeEvent | null;
onCellChange: CellChangeEvent | null;
onCopy: CopyEvent | null;
constructor(props: ConfigProperties);
}

39
modules/events.d.ts vendored Normal file
View File

@ -0,0 +1,39 @@
import { Scroller } from "../components/scroller";
import Spreadsheet, { Cell, RangeSelectionType, Selection } from "../main";
export declare enum EventTypes {
CELL_CLICK = "CELL_CLICK",
SELECTION_CHANGE = "CHANGE_SELECTION",
CELL_CHANGE = "CELL_CHANGE",
COPY_CELLS = "COPY_CELLS"
}
export type CellClickEvent = {
type: EventTypes.CELL_CLICK;
event: MouseEvent;
scroller: Scroller;
};
export type ChangeSelectionEvent = {
type: EventTypes.SELECTION_CHANGE;
selection: Selection;
enableCallback?: boolean;
};
export type ChangeCellEvent = {
type: EventTypes.CELL_CHANGE;
cell: Cell;
enableCallback?: boolean;
};
export type CopyAction = {
type: EventTypes.COPY_CELLS;
range: RangeSelectionType;
data: Cell[][];
dataAsString: string;
};
export type ActionTypes = CellClickEvent | ChangeSelectionEvent | ChangeCellEvent | CopyAction;
export declare class Events {
root: Spreadsheet;
constructor(root: Spreadsheet);
dispatch(action: ActionTypes): Promise<void>;
private cellClick;
private changeSelection;
private changeCellValues;
private copy;
}

8
modules/formulaParser.d.ts vendored Normal file
View File

@ -0,0 +1,8 @@
import Parser, { DepParser } from 'fast-formula-parser';
import Spreadsheet from '../main';
export declare class FormulaParser {
parser: Parser;
depParser: DepParser;
root: Spreadsheet;
constructor(root: Spreadsheet);
}

11
modules/renderBox.d.ts vendored Normal file
View File

@ -0,0 +1,11 @@
import { Position } from "./cell";
import { Config } from "./config";
export declare class RenderBox {
x: number;
y: number;
width: number;
height: number;
constructor(config: Config, cellPosition: Position);
private getXCoord;
private getYCoord;
}

9
modules/row.d.ts vendored Normal file
View File

@ -0,0 +1,9 @@
export type RowConstructorProps = {
height: number;
title: string;
};
export declare class Row {
height: number;
title: string;
constructor(props: RowConstructorProps);
}

12
modules/selection.d.ts vendored Normal file
View File

@ -0,0 +1,12 @@
export type BaseSelectionType = {
row: number;
column: number;
};
export type RangeSelectionType = {
from: BaseSelectionType;
to: BaseSelectionType;
};
export declare class Selection {
selectedCell: BaseSelectionType | null;
selectedRange: RangeSelectionType | null;
}

5
modules/styles.d.ts vendored Normal file
View File

@ -0,0 +1,5 @@
import { CellStyles } from "./cell";
export declare class Styles {
cells: CellStyles;
constructor();
}

25
modules/viewport.d.ts vendored Normal file
View File

@ -0,0 +1,25 @@
import Spreadsheet from "../main";
export type ViewportConstructorProps = {
top: number;
left: number;
right: number;
bottom: number;
};
export declare class Viewport {
root: Spreadsheet;
top: number;
left: number;
right: number;
bottom: number;
firstRow: number;
lastRow: number;
firstCol: number;
lastCol: number;
constructor(root: Spreadsheet, props: ViewportConstructorProps);
updateValues(props: ViewportConstructorProps): void;
/** Get index of first row in viewport */
private getFirstRow;
private getLastRow;
private getFirstCol;
private getLastCol;
}

1
style.css Normal file
View File

@ -0,0 +1 @@
body{padding:0;margin:0}.modern_sc_spreadsheet_container{position:relative;isolation:isolate;border:2px solid black}.modern_sc_content{position:absolute}.modern_sc_sheet{display:block;contain:strict}.modern_sc_scroller{position:absolute;overflow:scroll;box-sizing:border-box;transform:translateZ(0)}.modern_sc_scroller:focus{outline:none}.modern_sc_editor{position:absolute;box-sizing:border-box;font-size:16px;font-family:Arial,Helvetica,sans-serif}.modern_sc_hide{visibility:hidden}

9
utils/createData.d.ts vendored Normal file
View File

@ -0,0 +1,9 @@
import { Cell } from "../modules/cell";
import { Config } from "../modules/config";
export declare function createSampleData(rows: number, columns: number, fillCellsByCoords?: boolean): Cell[][];
export declare function createSampleConfig(rows: number, columns: number): Config;
export type SpreadsheetConfigAndDataReturnType = {
config: Config;
data: Cell[][];
};
export declare function makeSpreadsheetConfigAndData(rows: number, columns: number): SpreadsheetConfigAndDataReturnType;

3
utils/position.d.ts vendored Normal file
View File

@ -0,0 +1,3 @@
import { BaseSelectionType, RangeSelectionType } from "../main";
export declare function checkEqualRanges(range1: RangeSelectionType, range2: RangeSelectionType): boolean;
export declare function checkEqualCellSelections(selection1: BaseSelectionType, selection2: BaseSelectionType): boolean;