UPDATE: Adds cell context menu

This commit is contained in:
Nicolás Hatcher
2025-01-21 18:37:18 +01:00
committed by Nicolás Hatcher Andrés
parent f96481feb8
commit 99125f1fea
8 changed files with 632 additions and 258 deletions

View File

@@ -8,12 +8,20 @@
- New document server (Thanks Dani!) - New document server (Thanks Dani!)
- New function FORMULATEXT - New function FORMULATEXT
- Name Manager ([#212](https://github.com/ironcalc/IronCalc/pull/212) [#220](https://github.com/ironcalc/IronCalc/pull/220)) - Name Manager ([#212](https://github.com/ironcalc/IronCalc/pull/212) [#220](https://github.com/ironcalc/IronCalc/pull/220))
- Add context menu. We can now insert rows and columns. Freeze and unfreeze rows and columns. Delete rows and columns [#271]
- Add nodejs bindings [#254]
- Add python bindings for all platforms
- Add is split into the product and widget
- Add Python documentation [#260]
### Fixed ### Fixed
- Fixed several issues with pasting content - Fixed several issues with pasting content
- Fixed several issues with borders - Fixed several issues with borders
- Fixed bug where columns and rows could be resized to negative width and height, respectively - Fixed bug where columns and rows could be resized to negative width and height, respectively
- Undo/redo when add/delete sheet now works [#270]
- Numerous small fixes
- Multiple fixes to the documentation
## [0.2.0] - 2024-11-06 (The HN release) ## [0.2.0] - 2024-11-06 (The HN release)

2
Cargo.lock generated
View File

@@ -1070,7 +1070,7 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]] [[package]]
name = "wasm" name = "wasm"
version = "0.3.0" version = "0.3.2"
dependencies = [ dependencies = [
"ironcalc_base", "ironcalc_base",
"serde", "serde",

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "wasm" name = "wasm"
version = "0.3.0" version = "0.3.2"
authors = ["Nicolas Hatcher <nicolas@theuniverse.today>"] authors = ["Nicolas Hatcher <nicolas@theuniverse.today>"]
description = "IronCalc Web bindings" description = "IronCalc Web bindings"
license = "MIT/Apache-2.0" license = "MIT/Apache-2.0"

View File

@@ -45,7 +45,7 @@
} }
}, },
"../../bindings/wasm/pkg": { "../../bindings/wasm/pkg": {
"version": "0.3.0", "version": "0.3.2",
"license": "MIT/Apache-2.0" "license": "MIT/Apache-2.0"
}, },
"node_modules/@adobe/css-tools": { "node_modules/@adobe/css-tools": {
@@ -1383,9 +1383,9 @@
} }
}, },
"node_modules/@rollup/rollup-android-arm-eabi": { "node_modules/@rollup/rollup-android-arm-eabi": {
"version": "4.34.2", "version": "4.34.6",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.2.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.6.tgz",
"integrity": "sha512-6Fyg9yQbwJR+ykVdT9sid1oc2ewejS6h4wzQltmJfSW53N60G/ah9pngXGANdy9/aaE/TcUFpWosdm7JXS1WTQ==", "integrity": "sha512-+GcCXtOQoWuC7hhX1P00LqjjIiS/iOouHXhMdiDSnq/1DGTox4SpUvO52Xm+div6+106r+TcvOeo/cxvyEyTgg==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@@ -1396,9 +1396,9 @@
] ]
}, },
"node_modules/@rollup/rollup-android-arm64": { "node_modules/@rollup/rollup-android-arm64": {
"version": "4.34.2", "version": "4.34.6",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.2.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.6.tgz",
"integrity": "sha512-K5GfWe+vtQ3kyEbihrimM38UgX57UqHp+oME7X/EX9Im6suwZfa7Hsr8AtzbJvukTpwMGs+4s29YMSO3rwWtsw==", "integrity": "sha512-E8+2qCIjciYUnCa1AiVF1BkRgqIGW9KzJeesQqVfyRITGQN+dFuoivO0hnro1DjT74wXLRZ7QF8MIbz+luGaJA==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -1409,9 +1409,9 @@
] ]
}, },
"node_modules/@rollup/rollup-darwin-arm64": { "node_modules/@rollup/rollup-darwin-arm64": {
"version": "4.34.2", "version": "4.34.6",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.2.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.6.tgz",
"integrity": "sha512-PSN58XG/V/tzqDb9kDGutUruycgylMlUE59f40ny6QIRNsTEIZsrNQTJKUN2keMMSmlzgunMFqyaGLmly39sug==", "integrity": "sha512-z9Ib+OzqN3DZEjX7PDQMHEhtF+t6Mi2z/ueChQPLS/qUMKY7Ybn5A2ggFoKRNRh1q1T03YTQfBTQCJZiepESAg==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -1422,9 +1422,9 @@
] ]
}, },
"node_modules/@rollup/rollup-darwin-x64": { "node_modules/@rollup/rollup-darwin-x64": {
"version": "4.34.2", "version": "4.34.6",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.2.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.6.tgz",
"integrity": "sha512-gQhK788rQJm9pzmXyfBB84VHViDERhAhzGafw+E5mUpnGKuxZGkMVDa3wgDFKT6ukLC5V7QTifzsUKdNVxp5qQ==", "integrity": "sha512-PShKVY4u0FDAR7jskyFIYVyHEPCPnIQY8s5OcXkdU8mz3Y7eXDJPdyM/ZWjkYdR2m0izD9HHWA8sGcXn+Qrsyg==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -1435,9 +1435,9 @@
] ]
}, },
"node_modules/@rollup/rollup-freebsd-arm64": { "node_modules/@rollup/rollup-freebsd-arm64": {
"version": "4.34.2", "version": "4.34.6",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.2.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.6.tgz",
"integrity": "sha512-eiaHgQwGPpxLC3+zTAcdKl4VsBl3r0AiJOd1Um/ArEzAjN/dbPK1nROHrVkdnoE6p7Svvn04w3f/jEZSTVHunA==", "integrity": "sha512-YSwyOqlDAdKqs0iKuqvRHLN4SrD2TiswfoLfvYXseKbL47ht1grQpq46MSiQAx6rQEN8o8URtpXARCpqabqxGQ==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -1448,9 +1448,9 @@
] ]
}, },
"node_modules/@rollup/rollup-freebsd-x64": { "node_modules/@rollup/rollup-freebsd-x64": {
"version": "4.34.2", "version": "4.34.6",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.2.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.6.tgz",
"integrity": "sha512-lhdiwQ+jf8pewYOTG4bag0Qd68Jn1v2gO1i0mTuiD+Qkt5vNfHVK/jrT7uVvycV8ZchlzXp5HDVmhpzjC6mh0g==", "integrity": "sha512-HEP4CgPAY1RxXwwL5sPFv6BBM3tVeLnshF03HMhJYCNc6kvSqBgTMmsEjb72RkZBAWIqiPUyF1JpEBv5XT9wKQ==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -1461,9 +1461,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-arm-gnueabihf": { "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
"version": "4.34.2", "version": "4.34.6",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.2.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.6.tgz",
"integrity": "sha512-lfqTpWjSvbgQP1vqGTXdv+/kxIznKXZlI109WkIFPbud41bjigjNmOAAKoazmRGx+k9e3rtIdbq2pQZPV1pMig==", "integrity": "sha512-88fSzjC5xeH9S2Vg3rPgXJULkHcLYMkh8faix8DX4h4TIAL65ekwuQMA/g2CXq8W+NJC43V6fUpYZNjaX3+IIg==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@@ -1474,9 +1474,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-arm-musleabihf": { "node_modules/@rollup/rollup-linux-arm-musleabihf": {
"version": "4.34.2", "version": "4.34.6",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.2.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.6.tgz",
"integrity": "sha512-RGjqULqIurqqv+NJTyuPgdZhka8ImMLB32YwUle2BPTDqDoXNgwFjdjQC59FbSk08z0IqlRJjrJ0AvDQ5W5lpw==", "integrity": "sha512-wM4ztnutBqYFyvNeR7Av+reWI/enK9tDOTKNF+6Kk2Q96k9bwhDDOlnCUNRPvromlVXo04riSliMBs/Z7RteEg==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@@ -1487,9 +1487,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-arm64-gnu": { "node_modules/@rollup/rollup-linux-arm64-gnu": {
"version": "4.34.2", "version": "4.34.6",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.2.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.6.tgz",
"integrity": "sha512-ZvkPiheyXtXlFqHpsdgscx+tZ7hoR59vOettvArinEspq5fxSDSgfF+L5wqqJ9R4t+n53nyn0sKxeXlik7AY9Q==", "integrity": "sha512-9RyprECbRa9zEjXLtvvshhw4CMrRa3K+0wcp3KME0zmBe1ILmvcVHnypZ/aIDXpRyfhSYSuN4EPdCCj5Du8FIA==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -1500,9 +1500,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-arm64-musl": { "node_modules/@rollup/rollup-linux-arm64-musl": {
"version": "4.34.2", "version": "4.34.6",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.2.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.6.tgz",
"integrity": "sha512-UlFk+E46TZEoxD9ufLKDBzfSG7Ki03fo6hsNRRRHF+KuvNZ5vd1RRVQm8YZlGsjcJG8R252XFK0xNPay+4WV7w==", "integrity": "sha512-qTmklhCTyaJSB05S+iSovfo++EwnIEZxHkzv5dep4qoszUMX5Ca4WM4zAVUMbfdviLgCSQOu5oU8YoGk1s6M9Q==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -1513,9 +1513,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-loongarch64-gnu": { "node_modules/@rollup/rollup-linux-loongarch64-gnu": {
"version": "4.34.2", "version": "4.34.6",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.2.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.6.tgz",
"integrity": "sha512-hJhfsD9ykx59jZuuoQgYT1GEcNNi3RCoEmbo5OGfG8RlHOiVS7iVNev9rhLKh7UBYq409f4uEw0cclTXx8nh8Q==", "integrity": "sha512-4Qmkaps9yqmpjY5pvpkfOerYgKNUGzQpFxV6rnS7c/JfYbDSU0y6WpbbredB5cCpLFGJEqYX40WUmxMkwhWCjw==",
"cpu": [ "cpu": [
"loong64" "loong64"
], ],
@@ -1526,9 +1526,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-powerpc64le-gnu": { "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
"version": "4.34.2", "version": "4.34.6",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.2.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.6.tgz",
"integrity": "sha512-g/O5IpgtrQqPegvqopvmdCF9vneLE7eqYfdPWW8yjPS8f63DNam3U4ARL1PNNB64XHZDHKpvO2Giftf43puB8Q==", "integrity": "sha512-Zsrtux3PuaxuBTX/zHdLaFmcofWGzaWW1scwLU3ZbW/X+hSsFbz9wDIp6XvnT7pzYRl9MezWqEqKy7ssmDEnuQ==",
"cpu": [ "cpu": [
"ppc64" "ppc64"
], ],
@@ -1539,9 +1539,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-riscv64-gnu": { "node_modules/@rollup/rollup-linux-riscv64-gnu": {
"version": "4.34.2", "version": "4.34.6",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.2.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.6.tgz",
"integrity": "sha512-bSQijDC96M6PuooOuXHpvXUYiIwsnDmqGU8+br2U7iPoykNi9JtMUpN7K6xml29e0evK0/g0D1qbAUzWZFHY5Q==", "integrity": "sha512-aK+Zp+CRM55iPrlyKiU3/zyhgzWBxLVrw2mwiQSYJRobCURb781+XstzvA8Gkjg/hbdQFuDw44aUOxVQFycrAg==",
"cpu": [ "cpu": [
"riscv64" "riscv64"
], ],
@@ -1552,9 +1552,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-s390x-gnu": { "node_modules/@rollup/rollup-linux-s390x-gnu": {
"version": "4.34.2", "version": "4.34.6",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.2.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.6.tgz",
"integrity": "sha512-49TtdeVAsdRuiUHXPrFVucaP4SivazetGUVH8CIxVsNsaPHV4PFkpLmH9LeqU/R4Nbgky9lzX5Xe1NrzLyraVA==", "integrity": "sha512-WoKLVrY9ogmaYPXwTH326+ErlCIgMmsoRSx6bO+l68YgJnlOXhygDYSZe/qbUJCSiCiZAQ+tKm88NcWuUXqOzw==",
"cpu": [ "cpu": [
"s390x" "s390x"
], ],
@@ -1565,9 +1565,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-x64-gnu": { "node_modules/@rollup/rollup-linux-x64-gnu": {
"version": "4.34.2", "version": "4.34.6",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.2.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.6.tgz",
"integrity": "sha512-j+jFdfOycLIQ7FWKka9Zd3qvsIyugg5LeZuHF6kFlXo6MSOc6R1w37YUVy8VpAKd81LMWGi5g9J25P09M0SSIw==", "integrity": "sha512-Sht4aFvmA4ToHd2vFzwMFaQCiYm2lDFho5rPcvPBT5pCdC+GwHG6CMch4GQfmWTQ1SwRKS0dhDYb54khSrjDWw==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -1578,9 +1578,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-x64-musl": { "node_modules/@rollup/rollup-linux-x64-musl": {
"version": "4.34.2", "version": "4.34.6",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.2.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.6.tgz",
"integrity": "sha512-aDPHyM/D2SpXfSNCVWCxyHmOqN9qb7SWkY1+vaXqMNMXslZYnwh9V/UCudl6psyG0v6Ukj7pXanIpfZwCOEMUg==", "integrity": "sha512-zmmpOQh8vXc2QITsnCiODCDGXFC8LMi64+/oPpPx5qz3pqv0s6x46ps4xoycfUiVZps5PFn1gksZzo4RGTKT+A==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -1591,9 +1591,9 @@
] ]
}, },
"node_modules/@rollup/rollup-win32-arm64-msvc": { "node_modules/@rollup/rollup-win32-arm64-msvc": {
"version": "4.34.2", "version": "4.34.6",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.2.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.6.tgz",
"integrity": "sha512-LQRkCyUBnAo7r8dbEdtNU08EKLCJMgAk2oP5H3R7BnUlKLqgR3dUjrLBVirmc1RK6U6qhtDw29Dimeer8d5hzQ==", "integrity": "sha512-3/q1qUsO/tLqGBaD4uXsB6coVGB3usxw3qyeVb59aArCgedSF66MPdgRStUd7vbZOsko/CgVaY5fo2vkvPLWiA==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -1604,9 +1604,9 @@
] ]
}, },
"node_modules/@rollup/rollup-win32-ia32-msvc": { "node_modules/@rollup/rollup-win32-ia32-msvc": {
"version": "4.34.2", "version": "4.34.6",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.2.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.6.tgz",
"integrity": "sha512-wt8OhpQUi6JuPFkm1wbVi1BByeag87LDFzeKSXzIdGcX4bMLqORTtKxLoCbV57BHYNSUSOKlSL4BYYUghainYA==", "integrity": "sha512-oLHxuyywc6efdKVTxvc0135zPrRdtYVjtVD5GUm55I3ODxhU/PwkQFD97z16Xzxa1Fz0AEe4W/2hzRtd+IfpOA==",
"cpu": [ "cpu": [
"ia32" "ia32"
], ],
@@ -1617,9 +1617,9 @@
] ]
}, },
"node_modules/@rollup/rollup-win32-x64-msvc": { "node_modules/@rollup/rollup-win32-x64-msvc": {
"version": "4.34.2", "version": "4.34.6",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.2.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.6.tgz",
"integrity": "sha512-rUrqINax0TvrPBXrFKg0YbQx18NpPN3NNrgmaao9xRNbTwek7lOXObhx8tQy8gelmQ/gLaGy1WptpU2eKJZImg==", "integrity": "sha512-0PVwmgzZ8+TZ9oGBmdZoQVXflbvuwzN/HRclujpl4N/q3i+y0lqLw8n1bXA8ru3sApDjlmONaNAuYr38y1Kr9w==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -3020,9 +3020,9 @@
} }
}, },
"node_modules/caniuse-lite": { "node_modules/caniuse-lite": {
"version": "1.0.30001697", "version": "1.0.30001698",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001697.tgz", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001698.tgz",
"integrity": "sha512-GwNPlWJin8E+d7Gxq96jxM6w0w+VFeyyXRsjU58emtkYqnbwHqXm5uT2uCmO0RQE9htWknOP4xtBlLmM/gWxvQ==", "integrity": "sha512-xJ3km2oiG/MbNU8G6zIq6XRZ6HtAOVXsbOrP/blGazi52kc5Yy7b6sDA5O+FbROzRrV7BSTllLHuNvmawYUJjw==",
"dev": true, "dev": true,
"funding": [ "funding": [
{ {
@@ -3295,9 +3295,9 @@
} }
}, },
"node_modules/electron-to-chromium": { "node_modules/electron-to-chromium": {
"version": "1.5.91", "version": "1.5.96",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.91.tgz", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.96.tgz",
"integrity": "sha512-sNSHHyq048PFmZY4S90ax61q+gLCs0X0YmcOII9wG9S2XwbVr+h4VW2wWhnbp/Eys3cCwTxVF292W3qPaxIapQ==", "integrity": "sha512-8AJUW6dh75Fm/ny8+kZKJzI1pgoE8bKLZlzDU2W1ENd+DXKJrx7I7l9hb8UWR4ojlnb5OlixMt00QWiYJoVw1w==",
"dev": true "dev": true
}, },
"node_modules/entities": { "node_modules/entities": {
@@ -4252,9 +4252,9 @@
} }
}, },
"node_modules/possible-typed-array-names": { "node_modules/possible-typed-array-names": {
"version": "1.0.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz",
"integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==",
"dev": true, "dev": true,
"engines": { "engines": {
"node": ">= 0.4" "node": ">= 0.4"
@@ -4550,9 +4550,9 @@
} }
}, },
"node_modules/rollup": { "node_modules/rollup": {
"version": "4.34.2", "version": "4.34.6",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.34.2.tgz", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.34.6.tgz",
"integrity": "sha512-sBDUoxZEaqLu9QeNalL8v3jw6WjPku4wfZGyTU7l7m1oC+rpRihXc/n/H+4148ZkGz5Xli8CHMns//fFGKvpIQ==", "integrity": "sha512-wc2cBWqJgkU3Iz5oztRkQbfVkbxoz5EhnCGOrnJvnLnQ7O0WhQUYyv18qQI79O8L7DdHrrlJNeCHd4VGpnaXKQ==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@types/estree": "1.0.6" "@types/estree": "1.0.6"
@@ -4565,25 +4565,25 @@
"npm": ">=8.0.0" "npm": ">=8.0.0"
}, },
"optionalDependencies": { "optionalDependencies": {
"@rollup/rollup-android-arm-eabi": "4.34.2", "@rollup/rollup-android-arm-eabi": "4.34.6",
"@rollup/rollup-android-arm64": "4.34.2", "@rollup/rollup-android-arm64": "4.34.6",
"@rollup/rollup-darwin-arm64": "4.34.2", "@rollup/rollup-darwin-arm64": "4.34.6",
"@rollup/rollup-darwin-x64": "4.34.2", "@rollup/rollup-darwin-x64": "4.34.6",
"@rollup/rollup-freebsd-arm64": "4.34.2", "@rollup/rollup-freebsd-arm64": "4.34.6",
"@rollup/rollup-freebsd-x64": "4.34.2", "@rollup/rollup-freebsd-x64": "4.34.6",
"@rollup/rollup-linux-arm-gnueabihf": "4.34.2", "@rollup/rollup-linux-arm-gnueabihf": "4.34.6",
"@rollup/rollup-linux-arm-musleabihf": "4.34.2", "@rollup/rollup-linux-arm-musleabihf": "4.34.6",
"@rollup/rollup-linux-arm64-gnu": "4.34.2", "@rollup/rollup-linux-arm64-gnu": "4.34.6",
"@rollup/rollup-linux-arm64-musl": "4.34.2", "@rollup/rollup-linux-arm64-musl": "4.34.6",
"@rollup/rollup-linux-loongarch64-gnu": "4.34.2", "@rollup/rollup-linux-loongarch64-gnu": "4.34.6",
"@rollup/rollup-linux-powerpc64le-gnu": "4.34.2", "@rollup/rollup-linux-powerpc64le-gnu": "4.34.6",
"@rollup/rollup-linux-riscv64-gnu": "4.34.2", "@rollup/rollup-linux-riscv64-gnu": "4.34.6",
"@rollup/rollup-linux-s390x-gnu": "4.34.2", "@rollup/rollup-linux-s390x-gnu": "4.34.6",
"@rollup/rollup-linux-x64-gnu": "4.34.2", "@rollup/rollup-linux-x64-gnu": "4.34.6",
"@rollup/rollup-linux-x64-musl": "4.34.2", "@rollup/rollup-linux-x64-musl": "4.34.6",
"@rollup/rollup-win32-arm64-msvc": "4.34.2", "@rollup/rollup-win32-arm64-msvc": "4.34.6",
"@rollup/rollup-win32-ia32-msvc": "4.34.2", "@rollup/rollup-win32-ia32-msvc": "4.34.6",
"@rollup/rollup-win32-x64-msvc": "4.34.2", "@rollup/rollup-win32-x64-msvc": "4.34.6",
"fsevents": "~2.3.2" "fsevents": "~2.3.2"
} }
}, },
@@ -5031,14 +5031,14 @@
"dev": true "dev": true
}, },
"node_modules/vite": { "node_modules/vite": {
"version": "6.0.11", "version": "6.1.0",
"resolved": "https://registry.npmjs.org/vite/-/vite-6.0.11.tgz", "resolved": "https://registry.npmjs.org/vite/-/vite-6.1.0.tgz",
"integrity": "sha512-4VL9mQPKoHy4+FE0NnRE/kbY51TOfaknxAjt3fJbGJxhIpBZiqVzlZDEesWWsuREXHwNdAoOFZ9MkPEVXczHwg==", "integrity": "sha512-RjjMipCKVoR4hVfPY6GQTgveinjNuyLw+qruksLDvA5ktI1150VmcMBKmQaEWJhg/j6Uaf6dNCNA0AfdzUb/hQ==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"esbuild": "^0.24.2", "esbuild": "^0.24.2",
"postcss": "^8.4.49", "postcss": "^8.5.1",
"rollup": "^4.23.0" "rollup": "^4.30.1"
}, },
"bin": { "bin": {
"vite": "bin/vite.js" "vite": "bin/vite.js"

View File

@@ -0,0 +1,286 @@
import { Menu, MenuItem, styled } from "@mui/material";
import {
BetweenHorizontalStart,
BetweenVerticalStart,
ChevronRight,
Snowflake,
Trash2,
} from "lucide-react";
import { useRef, useState } from "react";
import { useTranslation } from "react-i18next";
const red_color = "rgb(235, 12, 12)";
interface CellContextMenuProps {
open: boolean;
onClose: () => void;
anchorEl: HTMLDivElement | null;
onInsertRowAbove: () => void;
onInsertRowBelow: () => void;
onInsertColumnLeft: () => void;
onInsertColumnRight: () => void;
onFreezeColumns: () => void;
onFreezeRows: () => void;
onUnfreezeColumns: () => void;
onUnfreezeRows: () => void;
onDeleteRow: () => void;
onDeleteColumn: () => void;
row: number;
column: string;
}
const CellContextMenu = (properties: CellContextMenuProps) => {
const { t } = useTranslation();
const {
open,
onClose,
anchorEl,
onInsertRowAbove,
onInsertRowBelow,
onInsertColumnLeft,
onInsertColumnRight,
onFreezeColumns,
onFreezeRows,
onUnfreezeColumns,
onUnfreezeRows,
onDeleteRow,
onDeleteColumn,
row,
column,
} = properties;
const [freezeMenuOpen, setFreezeMenuOpen] = useState(false);
const freezeRef = useRef(null);
const [insertRowMenuOpen, setInsertRowMenuOpen] = useState(false);
const insertRowRef = useRef(null);
const [insertColumnMenuOpen, setInsertColumnMenuOpen] = useState(false);
const insertColumnRef = useRef(null);
return (
<>
<StyledMenu
open={open}
onClose={onClose}
anchorEl={anchorEl}
anchorOrigin={{
vertical: "top",
horizontal: "left",
}}
transformOrigin={{
vertical: "bottom",
horizontal: 6,
}}
>
<StyledMenuItem
ref={insertColumnRef}
onClick={() => setInsertColumnMenuOpen(true)}
>
<BetweenVerticalStartStyled />
<ItemNameStyled>{t("cell_context.insert_column")}</ItemNameStyled>
<ChevronRightStyled />
</StyledMenuItem>
<StyledMenuItem
ref={insertRowRef}
onClick={() => setInsertRowMenuOpen(true)}
>
<BetweenHorizontalStartStyled />
<ItemNameStyled>{t("cell_context.insert_row")}</ItemNameStyled>
<ChevronRightStyled />
</StyledMenuItem>
<MenuDivider />
<StyledMenuItem ref={freezeRef} onClick={() => setFreezeMenuOpen(true)}>
<StyledSnowflake />
<ItemNameStyled>{t("cell_context.freeze")}</ItemNameStyled>
<ChevronRightStyled />
</StyledMenuItem>
<MenuDivider />
<StyledMenuItem onClick={onDeleteRow}>
<StyledTrash />
<ItemNameStyled style={{ color: red_color }}>
{t("cell_context.delete_row", { row })}
</ItemNameStyled>
</StyledMenuItem>
<StyledMenuItem onClick={onDeleteColumn}>
<StyledTrash />
<ItemNameStyled style={{ color: red_color }}>
{t("cell_context.delete_column", { column })}
</ItemNameStyled>
</StyledMenuItem>
</StyledMenu>
<StyledMenu
open={insertRowMenuOpen}
onClose={() => setInsertRowMenuOpen(false)}
anchorEl={insertRowRef.current}
anchorOrigin={{
vertical: "top",
horizontal: "right",
}}
>
<StyledMenuItem
onClick={() => {
setInsertRowMenuOpen(false);
onInsertRowAbove();
}}
>
<ItemNameStyled>{t("cell_context.insert_row_above")}</ItemNameStyled>
</StyledMenuItem>
<StyledMenuItem
onClick={() => {
setInsertRowMenuOpen(false);
onInsertRowBelow();
}}
>
<ItemNameStyled>{t("cell_context.insert_row_below")}</ItemNameStyled>
</StyledMenuItem>
</StyledMenu>
<StyledMenu
open={insertColumnMenuOpen}
onClose={() => setInsertColumnMenuOpen(false)}
anchorEl={insertColumnRef.current}
anchorOrigin={{
vertical: "top",
horizontal: "right",
}}
>
<StyledMenuItem
onClick={() => {
setInsertColumnMenuOpen(false);
onInsertColumnLeft();
}}
>
<ItemNameStyled>
{t("cell_context.insert_column_before")}
</ItemNameStyled>
</StyledMenuItem>
<StyledMenuItem
onClick={() => {
setInsertColumnMenuOpen(false);
onInsertColumnRight();
}}
>
<ItemNameStyled>
{t("cell_context.insert_column_after")}
</ItemNameStyled>
</StyledMenuItem>
</StyledMenu>
<StyledMenu
open={freezeMenuOpen}
onClose={() => setFreezeMenuOpen(false)}
anchorEl={freezeRef.current}
anchorOrigin={{
vertical: "top",
horizontal: "right",
}}
>
<StyledMenuItem
onClick={() => {
onFreezeColumns();
setFreezeMenuOpen(false);
}}
>
<ItemNameStyled>
{t("cell_context.freeze_columns", { column })}
</ItemNameStyled>
</StyledMenuItem>
<StyledMenuItem
onClick={() => {
onFreezeRows();
setFreezeMenuOpen(false);
}}
>
<ItemNameStyled>
{t("cell_context.freeze_rows", { row })}
</ItemNameStyled>
</StyledMenuItem>
<StyledMenuItem
onClick={() => {
onUnfreezeColumns();
setFreezeMenuOpen(false);
}}
>
<ItemNameStyled>{t("cell_context.unfreeze_columns")}</ItemNameStyled>
</StyledMenuItem>
<StyledMenuItem
onClick={() => {
onUnfreezeRows();
setFreezeMenuOpen(false);
}}
>
<ItemNameStyled>{t("cell_context.unfreeze_rows")}</ItemNameStyled>
</StyledMenuItem>
</StyledMenu>
</>
);
};
const BetweenVerticalStartStyled = styled(BetweenVerticalStart)`
width: 16px;
height: 16px;
color: #333333;
padding-right: 10px;
`;
const BetweenHorizontalStartStyled = styled(BetweenHorizontalStart)`
width: 16px;
height: 16px;
color: #333333;
padding-right: 10px;
`;
const StyledSnowflake = styled(Snowflake)`
width: 16px;
height: 16px;
color: #333333;
padding-right: 10px;
`;
const StyledTrash = styled(Trash2)`
width: 16px;
height: 16px;
color: ${red_color};
padding-right: 10px;
`;
const StyledMenu = styled(Menu)({
"& .MuiPaper-root": {
borderRadius: 8,
padding: 4,
},
"& .MuiList-padding": {
padding: 0,
},
});
const StyledMenuItem = styled(MenuItem)`
display: flex;
justify-content: flex-start;
font-size: 14px;
width: calc(100% - 8px);
min-width: 172px;
margin: 0px 4px;
border-radius: 4px;
padding: 8px;
height: 32px;
`;
const MenuDivider = styled("div")`
width: 100%;
margin: auto;
margin-top: 4px;
margin-bottom: 4px;
border-top: 1px solid #eeeeee;
`;
const ItemNameStyled = styled("div")`
font-size: 12px;
color: #333;
flex-grow: 2;
`;
const ChevronRightStyled = styled(ChevronRight)`
width: 16px;
height: 16px;
`;
export default CellContextMenu;

View File

@@ -240,7 +240,6 @@ const usePointer = (options: PointerSettings): PointerEvents => {
onPointerMove, onPointerMove,
onPointerUp, onPointerUp,
onPointerHandleDown, onPointerHandleDown,
// onContextMenu,
}; };
}; };

View File

@@ -1,6 +1,7 @@
import type { Model } from "@ironcalc/wasm"; import { type Model, columnNameFromNumber } from "@ironcalc/wasm";
import { styled } from "@mui/material/styles"; import { styled } from "@mui/material/styles";
import { useEffect, useLayoutEffect, useRef, useState } from "react"; import { useEffect, useLayoutEffect, useRef, useState } from "react";
import CellContextMenu from "./CellContextMenu";
import { import {
COLUMN_WIDTH_SCALE, COLUMN_WIDTH_SCALE,
ROW_HEIGH_SCALE, ROW_HEIGH_SCALE,
@@ -52,6 +53,8 @@ function Worksheet(props: {
const columnHeaders = useRef<HTMLDivElement>(null); const columnHeaders = useRef<HTMLDivElement>(null);
const worksheetCanvas = useRef<WorksheetCanvas | null>(null); const worksheetCanvas = useRef<WorksheetCanvas | null>(null);
const [contextMenuOpen, setContextMenuOpen] = useState(false);
const ignoreScrollEventRef = useRef(false); const ignoreScrollEventRef = useRef(false);
const { model, workbookState, refresh } = props; const { model, workbookState, refresh } = props;
@@ -147,13 +150,8 @@ function Worksheet(props: {
worksheetCanvas.current = canvas; worksheetCanvas.current = canvas;
}); });
const { const { onPointerMove, onPointerDown, onPointerHandleDown, onPointerUp } =
onPointerMove, usePointer({
onPointerDown,
onPointerHandleDown,
onPointerUp,
// onContextMenu,
} = usePointer({
model, model,
workbookState, workbookState,
refresh, refresh,
@@ -283,7 +281,13 @@ function Worksheet(props: {
const width = Math.abs(range[3] - range[1]) + 1; const width = Math.abs(range[3] - range[1]) + 1;
const columnStart = Math.min(range[1], range[3]); const columnStart = Math.min(range[1], range[3]);
const area = { sheet, row: rowStart, column: columnStart, width, height }; const area = {
sheet,
row: rowStart,
column: columnStart,
width,
height,
};
switch (extendedArea.type) { switch (extendedArea.type) {
case AreaType.rowsDown: case AreaType.rowsDown:
@@ -340,6 +344,11 @@ function Worksheet(props: {
onPointerDown={onPointerDown} onPointerDown={onPointerDown}
onPointerMove={onPointerMove} onPointerMove={onPointerMove}
onPointerUp={onPointerUp} onPointerUp={onPointerUp}
onContextMenu={(event) => {
event.preventDefault();
event.stopPropagation();
setContextMenuOpen(true);
}}
onDoubleClick={(event) => { onDoubleClick={(event) => {
// Starts editing cell // Starts editing cell
const { sheet, row, column } = model.getSelectedView(); const { sheet, row, column } = model.getSelectedView();
@@ -392,6 +401,63 @@ function Worksheet(props: {
<RowResizeGuide ref={rowResizeGuide} /> <RowResizeGuide ref={rowResizeGuide} />
<ColumnHeaders ref={columnHeaders} /> <ColumnHeaders ref={columnHeaders} />
</SheetContainer> </SheetContainer>
<CellContextMenu
open={contextMenuOpen}
onClose={() => setContextMenuOpen(false)}
anchorEl={cellOutline.current}
onInsertRowAbove={(): void => {
const view = model.getSelectedView();
model.insertRow(view.sheet, view.row);
setContextMenuOpen(false);
}}
onInsertRowBelow={(): void => {
const view = model.getSelectedView();
model.insertRow(view.sheet, view.row + 1);
setContextMenuOpen(false);
}}
onInsertColumnLeft={(): void => {
const view = model.getSelectedView();
model.insertColumn(view.sheet, view.column);
setContextMenuOpen(false);
}}
onInsertColumnRight={(): void => {
const view = model.getSelectedView();
model.insertColumn(view.sheet, view.column + 1);
setContextMenuOpen(false);
}}
onFreezeColumns={(): void => {
const view = model.getSelectedView();
model.setFrozenColumnsCount(view.sheet, view.column);
setContextMenuOpen(false);
}}
onFreezeRows={(): void => {
const view = model.getSelectedView();
model.setFrozenRowsCount(view.sheet, view.row);
setContextMenuOpen(false);
}}
onUnfreezeColumns={(): void => {
const sheet = model.getSelectedSheet();
model.setFrozenColumnsCount(sheet, 0);
setContextMenuOpen(false);
}}
onUnfreezeRows={(): void => {
const sheet = model.getSelectedSheet();
model.setFrozenRowsCount(sheet, 0);
setContextMenuOpen(false);
}}
onDeleteRow={(): void => {
const view = model.getSelectedView();
model.deleteRow(view.sheet, view.row);
setContextMenuOpen(false);
}}
onDeleteColumn={(): void => {
const view = model.getSelectedView();
model.deleteColumn(view.sheet, view.column);
setContextMenuOpen(false);
}}
row={model.getSelectedView().row}
column={columnNameFromNumber(model.getSelectedView().column)}
/>
</Wrapper> </Wrapper>
); );
} }

View File

@@ -100,5 +100,20 @@
"edit": "Edit Range", "edit": "Edit Range",
"apply": "Apply changes", "apply": "Apply changes",
"discard": "Discard changes" "discard": "Discard changes"
},
"cell_context": {
"insert_row_above": "Insert 1 row above",
"insert_row_below": "Insert 1 row below",
"insert_column_before": "Insert 1 column left",
"insert_column_after": "Insert 1 column right",
"freeze_columns": "Freeze up to column '{{column}}'",
"freeze_rows": "Freeze up to row '{{row}}'",
"unfreeze_rows": "Unfreeze rows",
"unfreeze_columns": "Unfreeze columns",
"delete_row": "Delete row '{{row}}'",
"delete_column": "Delete column '{{column}}'",
"freeze": "Freeze",
"insert_row": "Insert row",
"insert_column": "Insert column"
} }
} }