parent
b4aa4a4b67
commit
9ef465b72d
|
|
@ -10,14 +10,13 @@
|
|||
"preview": "vite preview",
|
||||
"predeploy": "npm run dist",
|
||||
"deploy": "gh-pages -d dist"
|
||||
|
||||
},
|
||||
"devDependencies": {
|
||||
"gh-pages": "^5.0.0",
|
||||
"typescript": "^5.0.2",
|
||||
"vite": "^4.4.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"gh-pages": "^5.0.0",
|
||||
"sass": "^1.63.6"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,14 +5,14 @@ settings:
|
|||
excludeLinksFromLockfile: false
|
||||
|
||||
dependencies:
|
||||
gh-pages:
|
||||
specifier: ^5.0.0
|
||||
version: 5.0.0
|
||||
sass:
|
||||
specifier: ^1.63.6
|
||||
version: 1.63.6
|
||||
|
||||
devDependencies:
|
||||
gh-pages:
|
||||
specifier: ^5.0.0
|
||||
version: 5.0.0
|
||||
typescript:
|
||||
specifier: ^5.0.2
|
||||
version: 5.0.2
|
||||
|
|
@ -232,20 +232,20 @@ packages:
|
|||
engines: {node: '>=0.10.0'}
|
||||
dependencies:
|
||||
array-uniq: 1.0.3
|
||||
dev: false
|
||||
dev: true
|
||||
|
||||
/array-uniq@1.0.3:
|
||||
resolution: {integrity: sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
dev: false
|
||||
dev: true
|
||||
|
||||
/async@3.2.4:
|
||||
resolution: {integrity: sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==}
|
||||
dev: false
|
||||
dev: true
|
||||
|
||||
/balanced-match@1.0.2:
|
||||
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
|
||||
dev: false
|
||||
dev: true
|
||||
|
||||
/binary-extensions@2.2.0:
|
||||
resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==}
|
||||
|
|
@ -256,7 +256,7 @@ packages:
|
|||
dependencies:
|
||||
balanced-match: 1.0.2
|
||||
concat-map: 0.0.1
|
||||
dev: false
|
||||
dev: true
|
||||
|
||||
/braces@3.0.2:
|
||||
resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==}
|
||||
|
|
@ -280,19 +280,19 @@ packages:
|
|||
|
||||
/commander@2.20.3:
|
||||
resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==}
|
||||
dev: false
|
||||
dev: true
|
||||
|
||||
/commondir@1.0.1:
|
||||
resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==}
|
||||
dev: false
|
||||
dev: true
|
||||
|
||||
/concat-map@0.0.1:
|
||||
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
|
||||
dev: false
|
||||
dev: true
|
||||
|
||||
/email-addresses@5.0.0:
|
||||
resolution: {integrity: sha512-4OIPYlA6JXqtVn8zpHpGiI7vE6EQOAg16aGnDMIAlZVinnoZ8208tW1hAbjWydgN/4PLTT9q+O1K6AH/vALJGw==}
|
||||
dev: false
|
||||
dev: true
|
||||
|
||||
/esbuild@0.18.14:
|
||||
resolution: {integrity: sha512-uNPj5oHPYmj+ZhSQeYQVFZ+hAlJZbAGOmmILWIqrGvPVlNLbyOvU5Bu6Woi8G8nskcx0vwY0iFoMPrzT86Ko+w==}
|
||||
|
|
@ -327,12 +327,12 @@ packages:
|
|||
/escape-string-regexp@1.0.5:
|
||||
resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==}
|
||||
engines: {node: '>=0.8.0'}
|
||||
dev: false
|
||||
dev: true
|
||||
|
||||
/filename-reserved-regex@2.0.0:
|
||||
resolution: {integrity: sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==}
|
||||
engines: {node: '>=4'}
|
||||
dev: false
|
||||
dev: true
|
||||
|
||||
/filenamify@4.3.0:
|
||||
resolution: {integrity: sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==}
|
||||
|
|
@ -341,7 +341,7 @@ packages:
|
|||
filename-reserved-regex: 2.0.0
|
||||
strip-outer: 1.0.1
|
||||
trim-repeated: 1.0.0
|
||||
dev: false
|
||||
dev: true
|
||||
|
||||
/fill-range@7.0.1:
|
||||
resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==}
|
||||
|
|
@ -356,7 +356,7 @@ packages:
|
|||
commondir: 1.0.1
|
||||
make-dir: 3.1.0
|
||||
pkg-dir: 4.2.0
|
||||
dev: false
|
||||
dev: true
|
||||
|
||||
/find-up@4.1.0:
|
||||
resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==}
|
||||
|
|
@ -364,7 +364,7 @@ packages:
|
|||
dependencies:
|
||||
locate-path: 5.0.0
|
||||
path-exists: 4.0.0
|
||||
dev: false
|
||||
dev: true
|
||||
|
||||
/fs-extra@8.1.0:
|
||||
resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==}
|
||||
|
|
@ -373,11 +373,11 @@ packages:
|
|||
graceful-fs: 4.2.11
|
||||
jsonfile: 4.0.0
|
||||
universalify: 0.1.2
|
||||
dev: false
|
||||
dev: true
|
||||
|
||||
/fs.realpath@1.0.0:
|
||||
resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
|
||||
dev: false
|
||||
dev: true
|
||||
|
||||
/fsevents@2.3.2:
|
||||
resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
|
||||
|
|
@ -398,7 +398,7 @@ packages:
|
|||
find-cache-dir: 3.3.2
|
||||
fs-extra: 8.1.0
|
||||
globby: 6.1.0
|
||||
dev: false
|
||||
dev: true
|
||||
|
||||
/glob-parent@5.1.2:
|
||||
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
|
||||
|
|
@ -415,7 +415,7 @@ packages:
|
|||
minimatch: 3.1.2
|
||||
once: 1.4.0
|
||||
path-is-absolute: 1.0.1
|
||||
dev: false
|
||||
dev: true
|
||||
|
||||
/globby@6.1.0:
|
||||
resolution: {integrity: sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw==}
|
||||
|
|
@ -426,11 +426,11 @@ packages:
|
|||
object-assign: 4.1.1
|
||||
pify: 2.3.0
|
||||
pinkie-promise: 2.0.1
|
||||
dev: false
|
||||
dev: true
|
||||
|
||||
/graceful-fs@4.2.11:
|
||||
resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
|
||||
dev: false
|
||||
dev: true
|
||||
|
||||
/immutable@4.3.1:
|
||||
resolution: {integrity: sha512-lj9cnmB/kVS0QHsJnYKD1uo3o39nrbKxszjnqS9Fr6NB7bZzW45U6WSGBPKXDL/CvDKqDNPA4r3DoDQ8GTxo2A==}
|
||||
|
|
@ -440,11 +440,11 @@ packages:
|
|||
dependencies:
|
||||
once: 1.4.0
|
||||
wrappy: 1.0.2
|
||||
dev: false
|
||||
dev: true
|
||||
|
||||
/inherits@2.0.4:
|
||||
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
|
||||
dev: false
|
||||
dev: true
|
||||
|
||||
/is-binary-path@2.1.0:
|
||||
resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
|
||||
|
|
@ -470,27 +470,27 @@ packages:
|
|||
resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==}
|
||||
optionalDependencies:
|
||||
graceful-fs: 4.2.11
|
||||
dev: false
|
||||
dev: true
|
||||
|
||||
/locate-path@5.0.0:
|
||||
resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==}
|
||||
engines: {node: '>=8'}
|
||||
dependencies:
|
||||
p-locate: 4.1.0
|
||||
dev: false
|
||||
dev: true
|
||||
|
||||
/make-dir@3.1.0:
|
||||
resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==}
|
||||
engines: {node: '>=8'}
|
||||
dependencies:
|
||||
semver: 6.3.1
|
||||
dev: false
|
||||
dev: true
|
||||
|
||||
/minimatch@3.1.2:
|
||||
resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
|
||||
dependencies:
|
||||
brace-expansion: 1.1.11
|
||||
dev: false
|
||||
dev: true
|
||||
|
||||
/nanoid@3.3.6:
|
||||
resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==}
|
||||
|
|
@ -505,42 +505,42 @@ packages:
|
|||
/object-assign@4.1.1:
|
||||
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
dev: false
|
||||
dev: true
|
||||
|
||||
/once@1.4.0:
|
||||
resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
|
||||
dependencies:
|
||||
wrappy: 1.0.2
|
||||
dev: false
|
||||
dev: true
|
||||
|
||||
/p-limit@2.3.0:
|
||||
resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==}
|
||||
engines: {node: '>=6'}
|
||||
dependencies:
|
||||
p-try: 2.2.0
|
||||
dev: false
|
||||
dev: true
|
||||
|
||||
/p-locate@4.1.0:
|
||||
resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==}
|
||||
engines: {node: '>=8'}
|
||||
dependencies:
|
||||
p-limit: 2.3.0
|
||||
dev: false
|
||||
dev: true
|
||||
|
||||
/p-try@2.2.0:
|
||||
resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==}
|
||||
engines: {node: '>=6'}
|
||||
dev: false
|
||||
dev: true
|
||||
|
||||
/path-exists@4.0.0:
|
||||
resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
|
||||
engines: {node: '>=8'}
|
||||
dev: false
|
||||
dev: true
|
||||
|
||||
/path-is-absolute@1.0.1:
|
||||
resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
dev: false
|
||||
dev: true
|
||||
|
||||
/picocolors@1.0.0:
|
||||
resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==}
|
||||
|
|
@ -553,26 +553,26 @@ packages:
|
|||
/pify@2.3.0:
|
||||
resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
dev: false
|
||||
dev: true
|
||||
|
||||
/pinkie-promise@2.0.1:
|
||||
resolution: {integrity: sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
dependencies:
|
||||
pinkie: 2.0.4
|
||||
dev: false
|
||||
dev: true
|
||||
|
||||
/pinkie@2.0.4:
|
||||
resolution: {integrity: sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
dev: false
|
||||
dev: true
|
||||
|
||||
/pkg-dir@4.2.0:
|
||||
resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==}
|
||||
engines: {node: '>=8'}
|
||||
dependencies:
|
||||
find-up: 4.1.0
|
||||
dev: false
|
||||
dev: true
|
||||
|
||||
/postcss@8.4.26:
|
||||
resolution: {integrity: sha512-jrXHFF8iTloAenySjM/ob3gSj7pCu0Ji49hnjqzsgSRa50hkWCKD0HQ+gMNJkW38jBI68MpAAg7ZWwHwX8NMMw==}
|
||||
|
|
@ -609,7 +609,7 @@ packages:
|
|||
/semver@6.3.1:
|
||||
resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
|
||||
hasBin: true
|
||||
dev: false
|
||||
dev: true
|
||||
|
||||
/source-map-js@1.0.2:
|
||||
resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==}
|
||||
|
|
@ -620,7 +620,7 @@ packages:
|
|||
engines: {node: '>=0.10.0'}
|
||||
dependencies:
|
||||
escape-string-regexp: 1.0.5
|
||||
dev: false
|
||||
dev: true
|
||||
|
||||
/to-regex-range@5.0.1:
|
||||
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
|
||||
|
|
@ -633,7 +633,7 @@ packages:
|
|||
engines: {node: '>=0.10.0'}
|
||||
dependencies:
|
||||
escape-string-regexp: 1.0.5
|
||||
dev: false
|
||||
dev: true
|
||||
|
||||
/typescript@5.0.2:
|
||||
resolution: {integrity: sha512-wVORMBGO/FAs/++blGNeAVdbNKtIh1rbBL2EyQ1+J9lClJ93KiiKe8PmFIVdXhHcyv44SL9oglmfeSsndo0jRw==}
|
||||
|
|
@ -644,7 +644,7 @@ packages:
|
|||
/universalify@0.1.2:
|
||||
resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==}
|
||||
engines: {node: '>= 4.0.0'}
|
||||
dev: false
|
||||
dev: true
|
||||
|
||||
/vite@4.4.0(sass@1.63.6):
|
||||
resolution: {integrity: sha512-Wf+DCEjuM8aGavEYiF77hnbxEZ+0+/jC9nABR46sh5Xi+GYeSvkeEFRiVuI3x+tPjxgZeS91h1jTAQTPFgePpA==}
|
||||
|
|
@ -684,4 +684,4 @@ packages:
|
|||
|
||||
/wrappy@1.0.2:
|
||||
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
|
||||
dev: false
|
||||
dev: true
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
import { Spreadsheet } from "../main";
|
||||
import { Position } from "../modules/cell";
|
||||
import { RenderBox } from "../modules/renderBox";
|
||||
|
||||
export class Editor {
|
||||
element: HTMLInputElement
|
||||
|
|
@ -6,14 +8,57 @@ export class Editor {
|
|||
constructor(root: Spreadsheet) {
|
||||
this.root = root
|
||||
const element = document.createElement('input')
|
||||
element.classList.add('editor')
|
||||
this.element = element
|
||||
this.hide()
|
||||
}
|
||||
|
||||
|
||||
hide() {
|
||||
this.element.style.display = 'none'
|
||||
this.element.classList.add('hide')
|
||||
this.element.blur()
|
||||
window.removeEventListener('click', this.handleClickOutside)
|
||||
}
|
||||
show() {
|
||||
|
||||
show(position: Position) {
|
||||
const { height, width, x, y } = new RenderBox(this.root.config, position);
|
||||
const cell = this.root.getCell(position)
|
||||
this.element.classList.remove('hide')
|
||||
|
||||
this.element.style.top = (y - this.root.viewport.top) + 'px'
|
||||
this.element.style.left = (x - this.root.viewport.left) + 'px'
|
||||
this.element.style.width = width + 'px'
|
||||
this.element.style.height = height + 'px'
|
||||
this.element.style.display = 'block'
|
||||
|
||||
window.addEventListener('click', this.handleClickOutside)
|
||||
this.element.addEventListener('keydown', this.handleKeydown)
|
||||
this.element.value = cell.value
|
||||
this.element.focus()
|
||||
}
|
||||
|
||||
handleKeydown = (event: KeyboardEvent) => {
|
||||
const {key} = event
|
||||
|
||||
switch(key) {
|
||||
case 'Escape': {
|
||||
this.hide();
|
||||
break;
|
||||
}
|
||||
case 'Enter': {
|
||||
this.root.changeCellValues(this.root.selection.selectedCell!, {
|
||||
value: this.element.value,
|
||||
displayValue: this.element.value
|
||||
})
|
||||
this.hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
handleClickOutside = (event: MouseEvent) => {
|
||||
const target = event.target as HTMLElement
|
||||
if (!this.element.contains(target)) {
|
||||
this.hide()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -37,16 +37,22 @@ export class Scroller {
|
|||
if(this.root.selection.selectedRange) {
|
||||
this.root.selection.selectedRange.to = lastSelectedCell
|
||||
}
|
||||
this.root.renderSheet()
|
||||
})
|
||||
this.element.addEventListener('mouseup', () => {
|
||||
this.isSelecting = false
|
||||
|
||||
console.log(this.root.selection)
|
||||
this.root.renderSheet()
|
||||
})
|
||||
this.element.addEventListener('dblclick', event => {
|
||||
event.preventDefault();
|
||||
const position = this.root.getCellByCoords(event.offsetX, event.offsetY)
|
||||
this.root.showEditor(position)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
private handleClick = (event: MouseEvent) => {
|
||||
if(event.button !== 0) return; // Left mouse button
|
||||
const {offsetX, offsetY} = event
|
||||
const clickedCell = this.root.getCellByCoords(offsetX, offsetY)
|
||||
this.isSelecting = true
|
||||
|
|
|
|||
|
|
@ -58,7 +58,6 @@ export class Sheet {
|
|||
const lastRowIdx = this.root.viewport.lastRow + 3
|
||||
const firstColIdx = this.root.viewport.firstCol
|
||||
|
||||
console.log()
|
||||
|
||||
let rowsCount = 0
|
||||
|
||||
|
|
@ -73,7 +72,6 @@ export class Sheet {
|
|||
rowsCount++;
|
||||
}
|
||||
|
||||
console.log(`Rendered ${rowsCount} rows!`)
|
||||
}
|
||||
|
||||
}
|
||||
18
src/main.ts
18
src/main.ts
|
|
@ -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 } from "./modules/cell";
|
||||
import { Cell, CellConstructorProps, Position } from "./modules/cell";
|
||||
import { Config, ViewProperties } from "./modules/config";
|
||||
import { Selection } from "./modules/selection";
|
||||
import { Styles } from "./modules/styles";
|
||||
|
|
@ -101,6 +101,22 @@ export class Spreadsheet {
|
|||
return this.sheet.getCellByCoords(x, y)
|
||||
}
|
||||
|
||||
getCell(position: Position): Cell {
|
||||
const {column, row} = position
|
||||
return this.data[row][column]
|
||||
}
|
||||
|
||||
changeCellValues(position: Position, values: Partial<Omit<CellConstructorProps, 'position'>>) {
|
||||
const {column, row} = position
|
||||
|
||||
this.data[row][column].changeValues(values)
|
||||
this.renderCell(row, column)
|
||||
}
|
||||
|
||||
showEditor(position: Position) {
|
||||
this.editor.show(position)
|
||||
}
|
||||
|
||||
renderSheet() {
|
||||
this.sheet.renderSheet()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,16 @@ export type CellConstructorProps = {
|
|||
position: Position
|
||||
}
|
||||
|
||||
export class CellStyles {
|
||||
fontSize: number = 16
|
||||
fontColor: string = 'black'
|
||||
background: string = 'white'
|
||||
borderColor: string = 'black'
|
||||
|
||||
selectedBackground = '#4287f5'
|
||||
selectedFontColor = '#ffffff'
|
||||
}
|
||||
|
||||
export class Position {
|
||||
row: number
|
||||
column: number
|
||||
|
|
@ -23,6 +33,8 @@ export class Cell {
|
|||
/** This refers to the values that were obtained by calculations, for example, after calculating the formula */
|
||||
resultValue: string
|
||||
position: Position
|
||||
style: CellStyles = new CellStyles()
|
||||
|
||||
constructor(props: CellConstructorProps) {
|
||||
this.value = props.value
|
||||
this.displayValue = props.displayValue
|
||||
|
|
@ -30,23 +42,40 @@ export class Cell {
|
|||
this.position = props.position
|
||||
}
|
||||
|
||||
changeValues(values: Partial<Omit<CellConstructorProps, 'position'>>) {
|
||||
Object.assign(this, values)
|
||||
}
|
||||
|
||||
private isCellInRange(root: Spreadsheet): boolean {
|
||||
const { column, row } = this.position
|
||||
const { selectedRange } = root.selection
|
||||
|
||||
if (!selectedRange) return false;
|
||||
|
||||
const isCellInRow = row >= Math.min(selectedRange.from.row, selectedRange.to.row) && row <= Math.max(selectedRange.to.row, selectedRange.from.row)
|
||||
const isCellInCol = column >= Math.min(selectedRange.from.column, selectedRange.to.column) && column <= Math.max(selectedRange.to.column, selectedRange.from.column)
|
||||
|
||||
return isCellInCol && isCellInRow
|
||||
}
|
||||
|
||||
render(root: Spreadsheet) {
|
||||
let {height, width, x, y} = new RenderBox(root.config, this.position)
|
||||
let { height, width, x, y } = new RenderBox(root.config, this.position)
|
||||
const { ctx } = root
|
||||
|
||||
const isCellSelected = (root.selection.selectedCell?.row === this.position.row && root.selection.selectedCell.column === this.position.column)
|
||||
const isCellInRange = this.isCellInRange(root)
|
||||
y -= root.viewport.top
|
||||
x -= root.viewport.left
|
||||
|
||||
ctx.clearRect(x, y, width, height)
|
||||
ctx.fillStyle = isCellSelected ? 'red' : 'white'
|
||||
ctx.fillStyle = isCellSelected || isCellInRange ? this.style.selectedBackground : this.style.background
|
||||
ctx.strokeStyle = 'black'
|
||||
ctx.fillRect(x, y, width - 1, height - 1)
|
||||
ctx.strokeRect(x, y, width, height)
|
||||
|
||||
ctx.fillStyle = 'black'
|
||||
ctx.fillStyle = isCellSelected || isCellInRange ? this.style.selectedFontColor : this.style.fontColor
|
||||
ctx.textAlign = 'left'
|
||||
ctx.font = `16px Arial`
|
||||
ctx.font = `${this.style.fontSize}px Arial`
|
||||
ctx.textBaseline = 'middle'
|
||||
ctx.fillText(this.displayValue, x + 2, y + height / 2, width)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
|
||||
|
||||
export class Styles {
|
||||
|
||||
}
|
||||
|
|
@ -51,8 +51,6 @@ export class Viewport {
|
|||
this.lastRow = this.getLastRow()
|
||||
this.firstCol = this.getFirstCol()
|
||||
this.lastCol = this.getLastCol()
|
||||
|
||||
console.log({ first: this.firstCol, last: this.lastCol })
|
||||
}
|
||||
|
||||
/** Get index of first row in viewport */
|
||||
|
|
|
|||
|
|
@ -21,4 +21,15 @@
|
|||
overflow: scroll;
|
||||
box-sizing: border-box;
|
||||
transform: translateZ(0);
|
||||
}
|
||||
|
||||
.editor {
|
||||
position: absolute;
|
||||
box-sizing: border-box;
|
||||
font-size: 16px;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
}
|
||||
|
||||
.hide {
|
||||
visibility: hidden;
|
||||
}
|
||||
Loading…
Reference in New Issue