Added "Cell change" event

This commit is contained in:
Eugene 2023-07-26 15:08:47 +03:00
parent 8596220e85
commit 322378904c
7 changed files with 92 additions and 22 deletions

View File

@ -30,10 +30,34 @@ function loadData() {
} }
``` ```
## Supported events
- onCellClick
- onSelectionChange
- onCellChange
### Using events examples
```ts
import Spreadsheet, { SpreadsheetConstructorProperties } from "./main";
const options: SpreadsheetConstructorProperties = {
onCellClick: (event, cell) => {
console.log('Cell click', event, cell)
},
onSelectionChange: (selection) => {
console.log("Changed selection: ", selection)
},
onCellChange(cell) {
console.log("Cell changed: ", cell)
},
}
const sheet = new Spreadsheet("#spreadsheet", options);
```
## Roadmap ## Roadmap
- ~~Rows number and columns heading render~~ - ~~Rows number and columns heading render~~
- Custom event functions (ex.: onSelectionChange, onCellEdit...). Full list of supported events will available on this page - ~~Custom event functions (ex.: onSelectionChange, onCellEdit...). Full list of supported events will available on this page~~
- Rows and columns resizing - Rows and columns resizing
- Toolbar - Toolbar
- Context menu - Context menu

View File

@ -1,5 +1,6 @@
import Spreadsheet, { CSS_PREFIX } from "../main"; import Spreadsheet, { CSS_PREFIX } from "../main";
import { Position } from "../modules/cell"; import { Position } from "../modules/cell";
import { EventTypes } from "../modules/events";
import { RenderBox } from "../modules/renderBox"; import { RenderBox } from "../modules/renderBox";
export class Editor { export class Editor {
@ -52,10 +53,17 @@ export class Editor {
break; break;
} }
case "Enter": { case "Enter": {
this.root.changeCellValues(this.root.selection.selectedCell!, { if (!this.root.selection.selectedCell) return;
value: this.element.value,
displayValue: this.element.value, this.root.events.dispatch({
}); type: EventTypes.CELL_CHANGE,
cell: this.root.getCell(this.root.selection.selectedCell),
values: {
value: this.element.value,
displayValue: this.element.value,
}
})
this.hide(); this.hide();
} }
} }

View File

@ -59,7 +59,7 @@ export class Scroller {
if (isRangeChanged) { if (isRangeChanged) {
this.root.selection.selectedRange.to = lastSelectedCell; this.root.selection.selectedRange.to = lastSelectedCell;
this.root.events.dispatch({ this.root.events.dispatch({
type: EventTypes.CHANGE_SELECTION, type: EventTypes.SELECTION_CHANGE,
selection: this.root.selection, selection: this.root.selection,
enableCallback: true enableCallback: true
}) })
@ -78,7 +78,7 @@ export class Scroller {
) { ) {
newSelection.selectedRange = null; newSelection.selectedRange = null;
this.root.events.dispatch({ this.root.events.dispatch({
type: EventTypes.CHANGE_SELECTION, type: EventTypes.SELECTION_CHANGE,
selection: newSelection, selection: newSelection,
enableCallback: false enableCallback: false
}) })
@ -148,7 +148,7 @@ export class Scroller {
} }
} }
this.root.events.dispatch({ this.root.events.dispatch({
type: EventTypes.CHANGE_SELECTION, type: EventTypes.SELECTION_CHANGE,
selection: this.root.selection, selection: this.root.selection,
enableCallback: true enableCallback: true
}) })

View File

@ -2,11 +2,14 @@ import Spreadsheet, { SpreadsheetConstructorProperties } from "./main";
const options: SpreadsheetConstructorProperties = { const options: SpreadsheetConstructorProperties = {
onCellClick: (event, cell) => { onCellClick: (event, cell) => {
console.log('Callback from instance', event, cell) console.log('Cell click', event, cell)
}, },
onSelectionChange: (selection) => { onSelectionChange: (selection) => {
console.log("Changed selection: ", selection) console.log("Changed selection: ", selection)
} },
onCellChange(cell) {
console.log("Cell changed: ", cell)
},
} }
const sheet = new Spreadsheet("#spreadsheet", options); const sheet = new Spreadsheet("#spreadsheet", options);

View File

@ -10,7 +10,7 @@ import {
Position, Position,
SerializableCell, SerializableCell,
} from "./modules/cell"; } from "./modules/cell";
import { Config, ViewProperties } from "./modules/config"; import { CellChangeEvent, CellClickEvent, Config, SelectionChangeEvent, ViewProperties } from "./modules/config";
import { RangeSelectionType, Selection } from "./modules/selection"; import { RangeSelectionType, Selection } from "./modules/selection";
import { Styles } from "./modules/styles"; import { Styles } from "./modules/styles";
import { Viewport } from "./modules/viewport"; import { Viewport } from "./modules/viewport";
@ -37,8 +37,9 @@ import { Events } from "./modules/events";
export interface SpreadsheetConstructorProperties { export interface SpreadsheetConstructorProperties {
view?: ViewProperties; view?: ViewProperties;
onCellClick?: ((event: MouseEvent, cell: Cell) => void) | null onCellClick?: CellClickEvent | null
onSelectionChange?: ((selection: Selection) => void) | null onSelectionChange?: SelectionChangeEvent | null
onCellChange?: CellChangeEvent | null
} }
export const CSS_PREFIX = "modern_sc_"; export const CSS_PREFIX = "modern_sc_";
@ -76,6 +77,7 @@ export default class Spreadsheet {
this.config.onCellClick = props?.onCellClick ?? null this.config.onCellClick = props?.onCellClick ?? null
this.config.onSelectonChange = props?.onSelectionChange ?? null this.config.onSelectonChange = props?.onSelectionChange ?? null
this.config.onCellChange = props?.onCellChange ?? null
this.rowsBar = new RowsBar(this); this.rowsBar = new RowsBar(this);
this.columnsBar = new ColumnsBar(this); this.columnsBar = new ColumnsBar(this);

View File

@ -7,6 +7,9 @@ export interface ViewProperties {
width: number; width: number;
height: 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 ConfigProperties = { export type ConfigProperties = {
/** Please, end it with '_' symbol. /** Please, end it with '_' symbol.
@ -18,8 +21,9 @@ export type ConfigProperties = {
rows: Row[]; rows: Row[];
columns: Column[]; columns: Column[];
view: ViewProperties; view: ViewProperties;
onCellClick?: ((event: MouseEvent, cell: Cell) => void) | null onCellClick?: CellClickEvent | null
onSelectionChange?: ((selection: Selection) => void) | null onSelectionChange?: SelectionChangeEvent | null
onCellChange?: CellChangeEvent | null
}; };
export type SheetConfigConstructorProps = { export type SheetConfigConstructorProps = {
@ -35,8 +39,9 @@ export class Config {
height: 600, height: 600,
}; };
onCellClick: ( (event: MouseEvent, cell: Cell) => void ) | null = null onCellClick: ((event: MouseEvent, cell: Cell) => void) | null = null
onSelectonChange: ((selection: Selection) => void) | null = null onSelectonChange: SelectionChangeEvent | null = null
onCellChange: CellChangeEvent | null = null
constructor(props: ConfigProperties) { constructor(props: ConfigProperties) {
this.columns = props.columns; this.columns = props.columns;
@ -45,5 +50,6 @@ export class Config {
this.onCellClick = props.onCellClick ?? null this.onCellClick = props.onCellClick ?? null
this.onSelectonChange = props.onSelectionChange ?? null this.onSelectonChange = props.onSelectionChange ?? null
this.onCellChange = props.onCellChange ?? null
} }
} }

View File

@ -1,9 +1,10 @@
import { Scroller } from "../components/scroller"; import { Scroller } from "../components/scroller";
import Spreadsheet, { Selection } from "../main"; import Spreadsheet, { Cell, CellConstructorProps, Selection } from "../main";
export enum EventTypes { export enum EventTypes {
CELL_CLICK = "CELL_CLICK", CELL_CLICK = "CELL_CLICK",
CHANGE_SELECTION = "CHANGE_SELECTION" SELECTION_CHANGE = "CHANGE_SELECTION",
CELL_CHANGE = "CELL_CHANGE"
} }
export type CellClickEvent = { export type CellClickEvent = {
@ -13,12 +14,18 @@ export type CellClickEvent = {
} }
export type ChangeSelectionEvent = { export type ChangeSelectionEvent = {
type: EventTypes.CHANGE_SELECTION, type: EventTypes.SELECTION_CHANGE,
selection: Selection selection: Selection
enableCallback?: boolean enableCallback?: boolean
} }
export type ActionTypes = CellClickEvent | ChangeSelectionEvent export type ChangeCellEvent = {
type: EventTypes.CELL_CHANGE,
cell: Cell,
values: Partial<Omit<CellConstructorProps, "position">>
}
export type ActionTypes = CellClickEvent | ChangeSelectionEvent | ChangeCellEvent
export class Events { export class Events {
@ -32,16 +39,31 @@ export class Events {
switch (action.type) { switch (action.type) {
case EventTypes.CELL_CLICK: { case EventTypes.CELL_CLICK: {
const { event, scroller } = action const { event, scroller } = action
//
//* Here may be side effects
//
this.cellClick(event, scroller) this.cellClick(event, scroller)
break; break;
} }
case EventTypes.CHANGE_SELECTION: { case EventTypes.SELECTION_CHANGE: {
const { selection, enableCallback } = action const { selection, enableCallback } = action
//
//* Here may be side effects
//
this.changeSelection(selection, enableCallback) this.changeSelection(selection, enableCallback)
break; break;
} }
case EventTypes.CELL_CHANGE: {
const { cell, values } = action
//
//* Here may be side effects
//
this.changeCellValues(cell, values)
break;
}
default: { default: {
break; break;
} }
@ -77,4 +99,9 @@ export class Events {
this.root.renderRowsBar(); this.root.renderRowsBar();
} }
private changeCellValues(cell: Cell, values: Partial<Omit<CellConstructorProps, "position">>) {
this.root.changeCellValues(cell.position, values)
this.root.config.onCellChange?.(cell)
}
} }