Added CSS prefixes

Added common styles for cells and single cells styles
This commit is contained in:
Eugene 2023-07-25 15:26:43 +03:00
parent e4c09a517d
commit a37401a28d
12 changed files with 77 additions and 41 deletions

View File

@ -1,7 +1,7 @@
{
"name": "modern_spreadsheet",
"private": false,
"version": "0.0.21",
"version": "0.0.23",
"exports": {
".": {
"import": "./dist/main.js",

View File

@ -1,4 +1,4 @@
import Spreadsheet from "../main";
import Spreadsheet, { CSS_PREFIX } from "../main";
import { Position } from "../modules/cell";
import { RenderBox } from "../modules/renderBox";
@ -8,7 +8,7 @@ export class Editor {
constructor(root: Spreadsheet) {
this.root = root
const element = document.createElement('input')
element.classList.add('editor')
element.classList.add(CSS_PREFIX + 'editor')
this.element = element
this.hide()
}
@ -23,7 +23,7 @@ export class Editor {
this.root.focusTable()
}
show(position: Position) {
show(position: Position, initialString?: string) {
const { height, width, x, y } = new RenderBox(this.root.config, position);
const cell = this.root.getCell(position)
this.element.classList.remove('hide')
@ -36,9 +36,11 @@ export class Editor {
window.addEventListener('click', this.handleClickOutside)
this.element.addEventListener('keydown', this.handleKeydown)
this.element.value = cell.value
this.element.value = initialString ? initialString : cell.value
this.element.focus()
this.element.select()
if (!initialString) this.element.select()
}
handleKeydown = (event: KeyboardEvent) => {

View File

@ -1,4 +1,4 @@
import Spreadsheet from "../main"
import Spreadsheet, { CSS_PREFIX } from "../main"
export interface ViewportRect {
top: number
@ -107,11 +107,15 @@ export class Scroller {
}
}
}
const keysRegex = /^([a-z]|[а-я])$/
if (!event.metaKey && !event.ctrlKey) { //* Prevent handle shortcutrs
if (event.key === 'F2' || /^([a-z]|[а-я])$/.test(event.key.toLowerCase())) { //* English and Russian keyboard. Or F2 button
const isPressedLetterKey = keysRegex.test(event.key.toLowerCase())
if (event.key === 'F2' || isPressedLetterKey) { //* English and Russian keyboard. Or F2 button
event.preventDefault()
if (!this.root.selection.selectedCell) return;
this.root.showEditor(this.root.selection.selectedCell)
this.root.showEditor(this.root.selection.selectedCell, isPressedLetterKey ? event.key : undefined)
}
}
@ -177,7 +181,7 @@ export class Scroller {
this.verticalScroller = verticalScroller
this.horizontalScroller = horizontalScroller
scroller.appendChild(groupScrollers)
scroller.classList.add('scroller')
scroller.classList.add(CSS_PREFIX + 'scroller')
return { scroller, verticalScroller, horizontalScroller }
}

View File

@ -1,4 +1,4 @@
import Spreadsheet from "../main"
import Spreadsheet, { CSS_PREFIX } from "../main"
import { Position } from "../modules/cell"
/**
@ -11,7 +11,7 @@ export class Sheet {
constructor(root: Spreadsheet) {
this.root = root
const canvas = document.createElement('canvas')
canvas.classList.add('sheet')
canvas.classList.add(CSS_PREFIX + 'sheet')
//* Set up canvas sizes based on provided root config
canvas.height = this.root.config.view.height

View File

@ -1,4 +1,4 @@
import Spreadsheet from "../main"
import Spreadsheet, { CSS_PREFIX } from "../main"
import { ViewProperties } from "../modules/config"
/** Base (root) component */
@ -8,7 +8,7 @@ export class Table {
constructor(root: Spreadsheet) {
this.root = root
const container = document.createElement('div')
container.classList.add('spreadsheet_container')
container.classList.add(CSS_PREFIX + 'spreadsheet_container')
this.element = container
this.changeElementSizes(this.root.viewProps)

View File

@ -1,4 +1,4 @@
import Spreadsheet from "../main"
import Spreadsheet, { CSS_PREFIX } from "../main"
export class Toolbar {
element: HTMLDivElement
@ -6,7 +6,7 @@ export class Toolbar {
constructor(root: Spreadsheet) {
this.root = root
const toolbarElement = document.createElement('div')
toolbarElement.classList.add('toolbar')
toolbarElement.classList.add(CSS_PREFIX + 'toolbar')
this.element = toolbarElement
}
}

View File

@ -24,3 +24,11 @@ function loadDataFromLS() {
saveButton.addEventListener('click', saveDataToLS)
loadButton.addEventListener('click', loadDataFromLS)
sheet.changeCellStyles({column: 1, row: 1}, {
background: 'black',
borderColor: 'white',
fontColor: 'white',
fontSize: 20,
selectedBackground: 'green',
selectedFontColor: 'black'
})

View File

@ -4,7 +4,7 @@ import { Scroller } from "./components/scroller";
import { Sheet } from "./components/sheet";
import { Table } from "./components/table";
import { Toolbar } from "./components/toolbar";
import { Cell, CellConstructorProps, Position, SerializableCell } from "./modules/cell";
import { Cell, CellConstructorProps, CellStyles, Position, SerializableCell } from "./modules/cell";
import { Config, ViewProperties } from "./modules/config";
import { RangeSelectionType, Selection } from "./modules/selection";
import { Styles } from "./modules/styles";
@ -32,6 +32,8 @@ interface SpreadsheetConstructorProperties {
view?: ViewProperties
}
export const CSS_PREFIX = "modern_sc_"
export default class Spreadsheet {
private table: Table
private scroller: Scroller
@ -115,7 +117,7 @@ export default class Spreadsheet {
content.appendChild(this.header.element)
content.appendChild(this.sheet.element)
content.classList.add('content')
content.classList.add(CSS_PREFIX + 'content')
this.table.element.appendChild(this.toolbar.element)
this.table.element.appendChild(content)
@ -175,6 +177,12 @@ export default class Spreadsheet {
this.renderCell(row, column)
}
changeCellStyles(position: Position, styles: CellStyles) {
const { column, row } = position
this.data[row][column].changeStyles(styles)
this.renderCell(row, column)
}
applyActionToRange(range: RangeSelectionType, callback: (cell: Cell) => any): void {
const fromRow = Math.min(range.from.row, range.to.row)
const toRow = Math.max(range.from.row, range.to.row)
@ -211,8 +219,8 @@ export default class Spreadsheet {
}
}
showEditor(position: Position) {
this.editor.show(position)
showEditor(position: Position, initialString?: string) {
this.editor.show(position, initialString)
}
renderSheet() {
@ -238,7 +246,8 @@ export default class Spreadsheet {
displayValue: cell.displayValue,
position: cell.position,
resultValue: cell.resultValue,
value: cell.value
value: cell.value,
style: cell.style
}))
}
formattedData.push(innerRow)

View File

@ -6,6 +6,7 @@ export type CellConstructorProps = {
displayValue: string
resultValue: string
position: Position
style: CellStyles | null
}
interface CellStylesConstructorProps {
@ -48,7 +49,7 @@ export class SerializableCell {
displayValue: string
resultValue: string
position: Position
style: CellStyles
style: CellStyles | null
constructor(props: SerializableCell | SerializableCell) {
this.value = props.value
this.displayValue = props.displayValue
@ -59,18 +60,21 @@ export class SerializableCell {
}
export 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 = new CellStyles()
style: CellStyles | null = null
constructor(props: CellConstructorProps) {
this.value = props.value
this.displayValue = props.displayValue
this.resultValue = props.resultValue
this.position = props.position
this.style = props.style
}
public getSerializableCell(): SerializableCell {
@ -84,6 +88,10 @@ export class Cell {
return cell
}
changeStyles(styles: CellStyles) {
this.style = styles
}
changeValues(values: Partial<Omit<CellConstructorProps, 'position'>>) {
Object.assign(this, values)
}
@ -109,15 +117,17 @@ export class Cell {
y -= root.viewport.top
x -= root.viewport.left
const styles = this.style ?? root.styles.cells
ctx.clearRect(x, y, width, height)
ctx.fillStyle = isCellSelected || isCellInRange ? this.style.selectedBackground : this.style.background
ctx.fillStyle = isCellSelected || isCellInRange ? styles.selectedBackground : styles.background
ctx.strokeStyle = 'black'
ctx.fillRect(x, y, width - 1, height - 1)
ctx.strokeRect(x, y, width, height)
ctx.fillStyle = isCellSelected || isCellInRange ? this.style.selectedFontColor : this.style.fontColor
ctx.fillStyle = isCellSelected || isCellInRange ? styles.selectedFontColor : styles.fontColor
ctx.textAlign = 'left'
ctx.font = `${this.style.fontSize}px Arial`
ctx.font = `${styles.fontSize}px Arial`
ctx.textBaseline = 'middle'
ctx.fillText(this.displayValue, x + 2, y + height / 2)
}

View File

@ -1,4 +1,9 @@
import { CellStyles } from "./cell";
export class Styles {
cells: CellStyles
constructor() {
this.cells = new CellStyles()
}
}

View File

@ -1,25 +1,23 @@
$css_prefix: "modern_sc_";
.content {
.#{$css_prefix}content {
position: absolute;
top: 0;
left: 0;
}
.spreadsheet_container {
.#{$css_prefix}spreadsheet_container {
position: relative;
isolation: isolate;
border: 2px solid black;
}
.sheet{
.#{$css_prefix}sheet{
display: block;
contain: strict;
}
.scroller {
.#{$css_prefix}scroller {
overflow: scroll;
box-sizing: border-box;
transform: translateZ(0);
@ -28,13 +26,13 @@
}
}
.editor {
.#{$css_prefix}editor {
position: absolute;
box-sizing: border-box;
font-size: 16px;
font-family: Arial, Helvetica, sans-serif;
}
.hide {
.#{$css_prefix}hide {
visibility: hidden;
}