From 176f47fd16907aecfaefdd0404d19ea0eb60f174 Mon Sep 17 00:00:00 2001 From: vran Date: Tue, 16 Jan 2024 18:52:03 +0800 Subject: [PATCH] feat: new color picker in cell style (#48) --- package-lock.json | 560 +++++++++++++++++++++++++ package.json | 1 + src/render/calendarGraphRender.ts | 3 +- src/render/gitStyleTrackGraphRender.ts | 3 +- src/render/graphRender.ts | 17 +- src/render/monthTrackGraphRender.ts | 3 +- src/util/utils.ts | 4 +- src/view/form/CellRuleFormItem.tsx | 116 +++-- styles.css | 18 +- 9 files changed, 681 insertions(+), 44 deletions(-) diff --git a/package-lock.json b/package-lock.json index bd80ab3..5c061ad 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "license": "MIT", "dependencies": { "@floating-ui/react": "^0.26.4", + "@uiw/react-color": "^2.0.6", "luxon": "^3.4.4", "react": "^18.2.0", "react-dom": "^18.2.0" @@ -39,6 +40,18 @@ "node": ">=0.10.0" } }, + "node_modules/@babel/runtime": { + "version": "7.23.8", + "resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.23.8.tgz", + "integrity": "sha512-Y7KbAP984rn1VGMbGqKmBLio9V7y5Je9GvU4rQPCPinCyNfUcToxIXl06d59URp/F3LwinvODxab5N/G6qggkw==", + "peer": true, + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@codemirror/language": { "version": "6.9.2", "resolved": "git+ssh://git@github.com/lishid/cm-language.git#cc6a2cc30288db6be3f879ddf0e3ef64f14ed6ab", @@ -844,6 +857,319 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@uiw/color-convert": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/@uiw/color-convert/-/color-convert-2.0.6.tgz", + "integrity": "sha512-LDu9r8geEjUgGzsuTkUu6rV5SCqR9r2liVYQxH42tZ5NkFx87Oswz/lpwthCoulhgjSWA+QEjjE3XB8Z9ove1g==", + "peerDependencies": { + "@babel/runtime": ">=7.19.0" + } + }, + "node_modules/@uiw/react-color": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/@uiw/react-color/-/react-color-2.0.6.tgz", + "integrity": "sha512-0QdRfGFgIUtIMnoUzopVApORPXP8kvUqmk9iWJFF+VcKVyrNCTc8x05HLi/8HwPeawS/tQk4LdeGiwasba8/MA==", + "dependencies": { + "@uiw/color-convert": "2.0.6", + "@uiw/react-color-alpha": "2.0.6", + "@uiw/react-color-block": "2.0.6", + "@uiw/react-color-chrome": "2.0.6", + "@uiw/react-color-circle": "2.0.6", + "@uiw/react-color-colorful": "2.0.6", + "@uiw/react-color-compact": "2.0.6", + "@uiw/react-color-editable-input": "2.0.6", + "@uiw/react-color-editable-input-hsla": "2.0.6", + "@uiw/react-color-editable-input-rgba": "2.0.6", + "@uiw/react-color-github": "2.0.6", + "@uiw/react-color-hue": "2.0.6", + "@uiw/react-color-material": "2.0.6", + "@uiw/react-color-saturation": "2.0.6", + "@uiw/react-color-shade-slider": "2.0.6", + "@uiw/react-color-sketch": "2.0.6", + "@uiw/react-color-slider": "2.0.6", + "@uiw/react-color-swatch": "2.0.6", + "@uiw/react-color-wheel": "2.0.6" + }, + "peerDependencies": { + "@babel/runtime": ">=7.19.0", + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/@uiw/react-color-alpha": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/@uiw/react-color-alpha/-/react-color-alpha-2.0.6.tgz", + "integrity": "sha512-EWV54kU6cWT+cpq6QTqJwtSgh3Hjdu/1umVrEC7v6vp3abHgKpmLBMznybY6zoeIh6+TnLnNLoyc8M+Jm0Aj7g==", + "dependencies": { + "@uiw/color-convert": "2.0.6", + "@uiw/react-drag-event-interactive": "2.0.6" + }, + "peerDependencies": { + "@babel/runtime": ">=7.19.0", + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/@uiw/react-color-block": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/@uiw/react-color-block/-/react-color-block-2.0.6.tgz", + "integrity": "sha512-GV3c7OCElnNq+BwdOD4HfbL3gGQlc1d4kod9XlzjaR6oMlWZ5PMEXeirf8Pn0c7xPUV+ltwAbgCmLkwaSxwTew==", + "dependencies": { + "@uiw/color-convert": "2.0.6", + "@uiw/react-color-editable-input": "2.0.6", + "@uiw/react-color-swatch": "2.0.6" + }, + "peerDependencies": { + "@babel/runtime": ">=7.19.0", + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/@uiw/react-color-chrome": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/@uiw/react-color-chrome/-/react-color-chrome-2.0.6.tgz", + "integrity": "sha512-lcT9/r+IjYSCHJf6EH1Gb4XAlJUIkDy/1XJe7SYYmySig55daIs0LjenTw9U8mWQlqgGfMItGp9RFEQy9aJelQ==", + "dependencies": { + "@uiw/color-convert": "2.0.6", + "@uiw/react-color-alpha": "2.0.6", + "@uiw/react-color-editable-input": "2.0.6", + "@uiw/react-color-editable-input-hsla": "2.0.6", + "@uiw/react-color-editable-input-rgba": "2.0.6", + "@uiw/react-color-github": "2.0.6", + "@uiw/react-color-hue": "2.0.6", + "@uiw/react-color-saturation": "2.0.6" + }, + "peerDependencies": { + "@babel/runtime": ">=7.19.0", + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/@uiw/react-color-circle": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/@uiw/react-color-circle/-/react-color-circle-2.0.6.tgz", + "integrity": "sha512-jCwzlKXC0YVQPP6zhogYjFifNxS8J6VBx2ADKv8t50We0lc3gcicrT2Db/EAC0WGp8yigp/J+4OD5BROiST2rw==", + "dependencies": { + "@uiw/color-convert": "2.0.6", + "@uiw/react-color-swatch": "2.0.6" + }, + "peerDependencies": { + "@babel/runtime": ">=7.19.0", + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/@uiw/react-color-colorful": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/@uiw/react-color-colorful/-/react-color-colorful-2.0.6.tgz", + "integrity": "sha512-ZCUFeuviRJcJiu1MB1n1MbouzmrUMYYgLcWU3ZvGQOT0NkJ3PgCRJrKR/9p6X3zkDBfQ4QCUG88c9X7XiEb+SQ==", + "dependencies": { + "@uiw/color-convert": "2.0.6", + "@uiw/react-color-alpha": "2.0.6", + "@uiw/react-color-hue": "2.0.6", + "@uiw/react-color-saturation": "2.0.6" + }, + "peerDependencies": { + "@babel/runtime": ">=7.19.0", + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/@uiw/react-color-compact": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/@uiw/react-color-compact/-/react-color-compact-2.0.6.tgz", + "integrity": "sha512-NB3vDw6aNDzKFH4z9lnSMwd4QCc2SmAwAhglns38CwhoD75iwciMsv9iNLMiW7CCZhuJtWpIiSR36Vb9eIRm8Q==", + "dependencies": { + "@uiw/color-convert": "2.0.6", + "@uiw/react-color-editable-input": "2.0.6", + "@uiw/react-color-editable-input-rgba": "2.0.6", + "@uiw/react-color-swatch": "2.0.6" + }, + "peerDependencies": { + "@babel/runtime": ">=7.19.0", + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/@uiw/react-color-editable-input": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/@uiw/react-color-editable-input/-/react-color-editable-input-2.0.6.tgz", + "integrity": "sha512-m2aGFZU0nOtP6XYRaa4mRKv7654tG4YYnGtYXMkR32j4eCOAUEpAmMYbKtSFiB+vUPQKyA3tcEoKNa6alNp0vw==", + "peerDependencies": { + "@babel/runtime": ">=7.19.0", + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/@uiw/react-color-editable-input-hsla": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/@uiw/react-color-editable-input-hsla/-/react-color-editable-input-hsla-2.0.6.tgz", + "integrity": "sha512-ME3WcgP5piU8BED6pcSTe0LryIecr0GGLWTw2p9rfZgUlAaUIfdDHOTCXTCzxh9EWEQcclBlCotj1Nckcsjplg==", + "dependencies": { + "@uiw/color-convert": "2.0.6", + "@uiw/react-color-editable-input-rgba": "2.0.6" + }, + "peerDependencies": { + "@babel/runtime": ">=7.19.0", + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/@uiw/react-color-editable-input-rgba": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/@uiw/react-color-editable-input-rgba/-/react-color-editable-input-rgba-2.0.6.tgz", + "integrity": "sha512-EcEcjHkiQX8Ecuv6nYK2DWmR5oSp5d3VMifZovNCr8Q41C2p08AeFA16CgPnmlsWlghRYqe5ekY6bkwdIC5Q2Q==", + "dependencies": { + "@uiw/color-convert": "2.0.6", + "@uiw/react-color-editable-input": "2.0.6" + }, + "peerDependencies": { + "@babel/runtime": ">=7.19.0", + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/@uiw/react-color-github": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/@uiw/react-color-github/-/react-color-github-2.0.6.tgz", + "integrity": "sha512-oDLRId+r+YEMr9vCDBzAZbrCW3qNGcgtzhWEgCupMZfIpglTMwR2iJmWQjylq66kXhwuBqLJe5r+uvXljqo4VA==", + "dependencies": { + "@uiw/color-convert": "2.0.6", + "@uiw/react-color-swatch": "2.0.6" + }, + "peerDependencies": { + "@babel/runtime": ">=7.19.0", + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/@uiw/react-color-hue": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/@uiw/react-color-hue/-/react-color-hue-2.0.6.tgz", + "integrity": "sha512-ytn3yH2SDM761IwoyXPBLKFSGpGxBHKopE3bgyw/5nuDq12J/oFy2uOLjBNAUy0qfZC2FARt6yCYqQcON9aChQ==", + "dependencies": { + "@uiw/color-convert": "2.0.6", + "@uiw/react-color-alpha": "2.0.6" + }, + "peerDependencies": { + "@babel/runtime": ">=7.19.0", + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/@uiw/react-color-material": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/@uiw/react-color-material/-/react-color-material-2.0.6.tgz", + "integrity": "sha512-HylgLq4bArp8NFx/Ub78/Rt28+xnqhk72hK5sjd5PJyoD+1wuca+Hi1JhnRKCb4X4jNytMRol2Ny5Up/YTyiAg==", + "dependencies": { + "@uiw/color-convert": "2.0.6", + "@uiw/react-color-editable-input": "2.0.6", + "@uiw/react-color-editable-input-rgba": "2.0.6" + }, + "peerDependencies": { + "@babel/runtime": ">=7.19.0", + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/@uiw/react-color-saturation": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/@uiw/react-color-saturation/-/react-color-saturation-2.0.6.tgz", + "integrity": "sha512-wnM1GlxKjvFuEHhSOA/rxho2lqZyywcwscTPzgAxg59hrQ6ddUdDaiAWJiujJ+mkmGqf4xO6llAvf9epJC3AZg==", + "dependencies": { + "@uiw/color-convert": "2.0.6", + "@uiw/react-drag-event-interactive": "2.0.6" + }, + "peerDependencies": { + "@babel/runtime": ">=7.19.0", + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/@uiw/react-color-shade-slider": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/@uiw/react-color-shade-slider/-/react-color-shade-slider-2.0.6.tgz", + "integrity": "sha512-N9BmJ4HoeYiHKvOXWRNp9if4o+gNN4VK7/OPo4IjWiyZUKqskYIi0qqvlafIQix1SmZPa8C4Ip9e4dPq80qrFQ==", + "dependencies": { + "@uiw/color-convert": "2.0.6", + "@uiw/react-color-alpha": "2.0.6" + }, + "peerDependencies": { + "@babel/runtime": ">=7.19.0", + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/@uiw/react-color-sketch": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/@uiw/react-color-sketch/-/react-color-sketch-2.0.6.tgz", + "integrity": "sha512-tSN/R0JsvLJMuIN3nptfuYhkD7brY9BH6nJOPLaydPCLzj5jMftIcTyqY5H/bDMd8ZNwlU71TCLkPS4CNdHJSQ==", + "dependencies": { + "@uiw/color-convert": "2.0.6", + "@uiw/react-color-alpha": "2.0.6", + "@uiw/react-color-editable-input": "2.0.6", + "@uiw/react-color-editable-input-rgba": "2.0.6", + "@uiw/react-color-hue": "2.0.6", + "@uiw/react-color-saturation": "2.0.6", + "@uiw/react-color-swatch": "2.0.6" + }, + "peerDependencies": { + "@babel/runtime": ">=7.19.0", + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/@uiw/react-color-slider": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/@uiw/react-color-slider/-/react-color-slider-2.0.6.tgz", + "integrity": "sha512-cImrIBaqU04RmzJxkwS4QQATtF5OD2jj+wJCsPkRhcT1Zc+WD4JSe3CXgliVsyXQux4DHbND6NcCJjXyj5W3ig==", + "dependencies": { + "@uiw/color-convert": "2.0.6", + "@uiw/react-color-alpha": "2.0.6" + }, + "peerDependencies": { + "@babel/runtime": ">=7.19.0", + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/@uiw/react-color-swatch": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/@uiw/react-color-swatch/-/react-color-swatch-2.0.6.tgz", + "integrity": "sha512-fDS5oo25tJEW+Xzm8ZM+0t6WjTE7poOQhxbw9ePxVdlcg12SGIvOCiY0kQrox3QjCAgyjTx33poYNEa3uO6BAg==", + "dependencies": { + "@uiw/color-convert": "2.0.6" + }, + "peerDependencies": { + "@babel/runtime": ">=7.19.0", + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/@uiw/react-color-wheel": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/@uiw/react-color-wheel/-/react-color-wheel-2.0.6.tgz", + "integrity": "sha512-7EfZ3db+NUd+2AQ7Nm7lsXmmVXCD65cZFhpTQuM3PIF8VgzwVTumXKBV2WyfCdo+alQowvN8DQCxdcmmjIozFg==", + "dependencies": { + "@uiw/color-convert": "2.0.6", + "@uiw/react-drag-event-interactive": "2.0.6" + }, + "peerDependencies": { + "@babel/runtime": ">=7.19.0", + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/@uiw/react-drag-event-interactive": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/@uiw/react-drag-event-interactive/-/react-drag-event-interactive-2.0.6.tgz", + "integrity": "sha512-LO3Q5x7NMAiIiZMwd6Yulpim+bYafs8ZYOhp+uOgY3Isvbke/me2Ix62qM+gQimEQjOYuH/9GZx5aC+uOcYo2w==", + "peerDependencies": { + "@babel/runtime": ">=7.19.0", + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, "node_modules/@ungap/structured-clone": { "version": "1.2.0", "resolved": "https://registry.npmmirror.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", @@ -2107,6 +2433,12 @@ "react": "^18.2.0" } }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "peer": true + }, "node_modules/regexpp": { "version": "3.2.0", "resolved": "https://registry.npmmirror.com/regexpp/-/regexpp-3.2.0.tgz", @@ -2415,6 +2747,15 @@ "dev": true, "peer": true }, + "@babel/runtime": { + "version": "7.23.8", + "resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.23.8.tgz", + "integrity": "sha512-Y7KbAP984rn1VGMbGqKmBLio9V7y5Je9GvU4rQPCPinCyNfUcToxIXl06d59URp/F3LwinvODxab5N/G6qggkw==", + "peer": true, + "requires": { + "regenerator-runtime": "^0.14.0" + } + }, "@codemirror/language": { "version": "git+ssh://git@github.com/lishid/cm-language.git#cc6a2cc30288db6be3f879ddf0e3ef64f14ed6ab", "dev": true, @@ -2926,6 +3267,219 @@ "eslint-visitor-keys": "^3.3.0" } }, + "@uiw/color-convert": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/@uiw/color-convert/-/color-convert-2.0.6.tgz", + "integrity": "sha512-LDu9r8geEjUgGzsuTkUu6rV5SCqR9r2liVYQxH42tZ5NkFx87Oswz/lpwthCoulhgjSWA+QEjjE3XB8Z9ove1g==", + "requires": {} + }, + "@uiw/react-color": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/@uiw/react-color/-/react-color-2.0.6.tgz", + "integrity": "sha512-0QdRfGFgIUtIMnoUzopVApORPXP8kvUqmk9iWJFF+VcKVyrNCTc8x05HLi/8HwPeawS/tQk4LdeGiwasba8/MA==", + "requires": { + "@uiw/color-convert": "2.0.6", + "@uiw/react-color-alpha": "2.0.6", + "@uiw/react-color-block": "2.0.6", + "@uiw/react-color-chrome": "2.0.6", + "@uiw/react-color-circle": "2.0.6", + "@uiw/react-color-colorful": "2.0.6", + "@uiw/react-color-compact": "2.0.6", + "@uiw/react-color-editable-input": "2.0.6", + "@uiw/react-color-editable-input-hsla": "2.0.6", + "@uiw/react-color-editable-input-rgba": "2.0.6", + "@uiw/react-color-github": "2.0.6", + "@uiw/react-color-hue": "2.0.6", + "@uiw/react-color-material": "2.0.6", + "@uiw/react-color-saturation": "2.0.6", + "@uiw/react-color-shade-slider": "2.0.6", + "@uiw/react-color-sketch": "2.0.6", + "@uiw/react-color-slider": "2.0.6", + "@uiw/react-color-swatch": "2.0.6", + "@uiw/react-color-wheel": "2.0.6" + } + }, + "@uiw/react-color-alpha": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/@uiw/react-color-alpha/-/react-color-alpha-2.0.6.tgz", + "integrity": "sha512-EWV54kU6cWT+cpq6QTqJwtSgh3Hjdu/1umVrEC7v6vp3abHgKpmLBMznybY6zoeIh6+TnLnNLoyc8M+Jm0Aj7g==", + "requires": { + "@uiw/color-convert": "2.0.6", + "@uiw/react-drag-event-interactive": "2.0.6" + } + }, + "@uiw/react-color-block": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/@uiw/react-color-block/-/react-color-block-2.0.6.tgz", + "integrity": "sha512-GV3c7OCElnNq+BwdOD4HfbL3gGQlc1d4kod9XlzjaR6oMlWZ5PMEXeirf8Pn0c7xPUV+ltwAbgCmLkwaSxwTew==", + "requires": { + "@uiw/color-convert": "2.0.6", + "@uiw/react-color-editable-input": "2.0.6", + "@uiw/react-color-swatch": "2.0.6" + } + }, + "@uiw/react-color-chrome": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/@uiw/react-color-chrome/-/react-color-chrome-2.0.6.tgz", + "integrity": "sha512-lcT9/r+IjYSCHJf6EH1Gb4XAlJUIkDy/1XJe7SYYmySig55daIs0LjenTw9U8mWQlqgGfMItGp9RFEQy9aJelQ==", + "requires": { + "@uiw/color-convert": "2.0.6", + "@uiw/react-color-alpha": "2.0.6", + "@uiw/react-color-editable-input": "2.0.6", + "@uiw/react-color-editable-input-hsla": "2.0.6", + "@uiw/react-color-editable-input-rgba": "2.0.6", + "@uiw/react-color-github": "2.0.6", + "@uiw/react-color-hue": "2.0.6", + "@uiw/react-color-saturation": "2.0.6" + } + }, + "@uiw/react-color-circle": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/@uiw/react-color-circle/-/react-color-circle-2.0.6.tgz", + "integrity": "sha512-jCwzlKXC0YVQPP6zhogYjFifNxS8J6VBx2ADKv8t50We0lc3gcicrT2Db/EAC0WGp8yigp/J+4OD5BROiST2rw==", + "requires": { + "@uiw/color-convert": "2.0.6", + "@uiw/react-color-swatch": "2.0.6" + } + }, + "@uiw/react-color-colorful": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/@uiw/react-color-colorful/-/react-color-colorful-2.0.6.tgz", + "integrity": "sha512-ZCUFeuviRJcJiu1MB1n1MbouzmrUMYYgLcWU3ZvGQOT0NkJ3PgCRJrKR/9p6X3zkDBfQ4QCUG88c9X7XiEb+SQ==", + "requires": { + "@uiw/color-convert": "2.0.6", + "@uiw/react-color-alpha": "2.0.6", + "@uiw/react-color-hue": "2.0.6", + "@uiw/react-color-saturation": "2.0.6" + } + }, + "@uiw/react-color-compact": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/@uiw/react-color-compact/-/react-color-compact-2.0.6.tgz", + "integrity": "sha512-NB3vDw6aNDzKFH4z9lnSMwd4QCc2SmAwAhglns38CwhoD75iwciMsv9iNLMiW7CCZhuJtWpIiSR36Vb9eIRm8Q==", + "requires": { + "@uiw/color-convert": "2.0.6", + "@uiw/react-color-editable-input": "2.0.6", + "@uiw/react-color-editable-input-rgba": "2.0.6", + "@uiw/react-color-swatch": "2.0.6" + } + }, + "@uiw/react-color-editable-input": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/@uiw/react-color-editable-input/-/react-color-editable-input-2.0.6.tgz", + "integrity": "sha512-m2aGFZU0nOtP6XYRaa4mRKv7654tG4YYnGtYXMkR32j4eCOAUEpAmMYbKtSFiB+vUPQKyA3tcEoKNa6alNp0vw==", + "requires": {} + }, + "@uiw/react-color-editable-input-hsla": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/@uiw/react-color-editable-input-hsla/-/react-color-editable-input-hsla-2.0.6.tgz", + "integrity": "sha512-ME3WcgP5piU8BED6pcSTe0LryIecr0GGLWTw2p9rfZgUlAaUIfdDHOTCXTCzxh9EWEQcclBlCotj1Nckcsjplg==", + "requires": { + "@uiw/color-convert": "2.0.6", + "@uiw/react-color-editable-input-rgba": "2.0.6" + } + }, + "@uiw/react-color-editable-input-rgba": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/@uiw/react-color-editable-input-rgba/-/react-color-editable-input-rgba-2.0.6.tgz", + "integrity": "sha512-EcEcjHkiQX8Ecuv6nYK2DWmR5oSp5d3VMifZovNCr8Q41C2p08AeFA16CgPnmlsWlghRYqe5ekY6bkwdIC5Q2Q==", + "requires": { + "@uiw/color-convert": "2.0.6", + "@uiw/react-color-editable-input": "2.0.6" + } + }, + "@uiw/react-color-github": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/@uiw/react-color-github/-/react-color-github-2.0.6.tgz", + "integrity": "sha512-oDLRId+r+YEMr9vCDBzAZbrCW3qNGcgtzhWEgCupMZfIpglTMwR2iJmWQjylq66kXhwuBqLJe5r+uvXljqo4VA==", + "requires": { + "@uiw/color-convert": "2.0.6", + "@uiw/react-color-swatch": "2.0.6" + } + }, + "@uiw/react-color-hue": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/@uiw/react-color-hue/-/react-color-hue-2.0.6.tgz", + "integrity": "sha512-ytn3yH2SDM761IwoyXPBLKFSGpGxBHKopE3bgyw/5nuDq12J/oFy2uOLjBNAUy0qfZC2FARt6yCYqQcON9aChQ==", + "requires": { + "@uiw/color-convert": "2.0.6", + "@uiw/react-color-alpha": "2.0.6" + } + }, + "@uiw/react-color-material": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/@uiw/react-color-material/-/react-color-material-2.0.6.tgz", + "integrity": "sha512-HylgLq4bArp8NFx/Ub78/Rt28+xnqhk72hK5sjd5PJyoD+1wuca+Hi1JhnRKCb4X4jNytMRol2Ny5Up/YTyiAg==", + "requires": { + "@uiw/color-convert": "2.0.6", + "@uiw/react-color-editable-input": "2.0.6", + "@uiw/react-color-editable-input-rgba": "2.0.6" + } + }, + "@uiw/react-color-saturation": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/@uiw/react-color-saturation/-/react-color-saturation-2.0.6.tgz", + "integrity": "sha512-wnM1GlxKjvFuEHhSOA/rxho2lqZyywcwscTPzgAxg59hrQ6ddUdDaiAWJiujJ+mkmGqf4xO6llAvf9epJC3AZg==", + "requires": { + "@uiw/color-convert": "2.0.6", + "@uiw/react-drag-event-interactive": "2.0.6" + } + }, + "@uiw/react-color-shade-slider": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/@uiw/react-color-shade-slider/-/react-color-shade-slider-2.0.6.tgz", + "integrity": "sha512-N9BmJ4HoeYiHKvOXWRNp9if4o+gNN4VK7/OPo4IjWiyZUKqskYIi0qqvlafIQix1SmZPa8C4Ip9e4dPq80qrFQ==", + "requires": { + "@uiw/color-convert": "2.0.6", + "@uiw/react-color-alpha": "2.0.6" + } + }, + "@uiw/react-color-sketch": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/@uiw/react-color-sketch/-/react-color-sketch-2.0.6.tgz", + "integrity": "sha512-tSN/R0JsvLJMuIN3nptfuYhkD7brY9BH6nJOPLaydPCLzj5jMftIcTyqY5H/bDMd8ZNwlU71TCLkPS4CNdHJSQ==", + "requires": { + "@uiw/color-convert": "2.0.6", + "@uiw/react-color-alpha": "2.0.6", + "@uiw/react-color-editable-input": "2.0.6", + "@uiw/react-color-editable-input-rgba": "2.0.6", + "@uiw/react-color-hue": "2.0.6", + "@uiw/react-color-saturation": "2.0.6", + "@uiw/react-color-swatch": "2.0.6" + } + }, + "@uiw/react-color-slider": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/@uiw/react-color-slider/-/react-color-slider-2.0.6.tgz", + "integrity": "sha512-cImrIBaqU04RmzJxkwS4QQATtF5OD2jj+wJCsPkRhcT1Zc+WD4JSe3CXgliVsyXQux4DHbND6NcCJjXyj5W3ig==", + "requires": { + "@uiw/color-convert": "2.0.6", + "@uiw/react-color-alpha": "2.0.6" + } + }, + "@uiw/react-color-swatch": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/@uiw/react-color-swatch/-/react-color-swatch-2.0.6.tgz", + "integrity": "sha512-fDS5oo25tJEW+Xzm8ZM+0t6WjTE7poOQhxbw9ePxVdlcg12SGIvOCiY0kQrox3QjCAgyjTx33poYNEa3uO6BAg==", + "requires": { + "@uiw/color-convert": "2.0.6" + } + }, + "@uiw/react-color-wheel": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/@uiw/react-color-wheel/-/react-color-wheel-2.0.6.tgz", + "integrity": "sha512-7EfZ3db+NUd+2AQ7Nm7lsXmmVXCD65cZFhpTQuM3PIF8VgzwVTumXKBV2WyfCdo+alQowvN8DQCxdcmmjIozFg==", + "requires": { + "@uiw/color-convert": "2.0.6", + "@uiw/react-drag-event-interactive": "2.0.6" + } + }, + "@uiw/react-drag-event-interactive": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/@uiw/react-drag-event-interactive/-/react-drag-event-interactive-2.0.6.tgz", + "integrity": "sha512-LO3Q5x7NMAiIiZMwd6Yulpim+bYafs8ZYOhp+uOgY3Isvbke/me2Ix62qM+gQimEQjOYuH/9GZx5aC+uOcYo2w==", + "requires": {} + }, "@ungap/structured-clone": { "version": "1.2.0", "resolved": "https://registry.npmmirror.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", @@ -3963,6 +4517,12 @@ "scheduler": "^0.23.0" } }, + "regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "peer": true + }, "regexpp": { "version": "3.2.0", "resolved": "https://registry.npmmirror.com/regexpp/-/regexpp-3.2.0.tgz", diff --git a/package.json b/package.json index b3022f1..a84226c 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ }, "dependencies": { "@floating-ui/react": "^0.26.4", + "@uiw/react-color": "^2.0.6", "luxon": "^3.4.4", "react": "^18.2.0", "react-dom": "^18.2.0" diff --git a/src/render/calendarGraphRender.ts b/src/render/calendarGraphRender.ts index 32c29b5..2e15591 100644 --- a/src/render/calendarGraphRender.ts +++ b/src/render/calendarGraphRender.ts @@ -179,11 +179,12 @@ export class CalendarGraphRender extends BaseGraphRender { } else if (item.value == 0) { cellEl.className = "cell empty"; this.applyCellGlobalStyle(cellEl, graphConfig); + this.applyCellStyleRule(cellEl, item, cellRules); this.bindCellAttribute(cellEl, item); } else { cellEl.className = "cell"; this.applyCellGlobalStyle(cellEl, graphConfig); - this.applyCellStyleRule(cellEl, item, cellRules); + this.applyCellStyleRule(cellEl, item, cellRules, () => cellRules[0]); this.bindCellAttribute(cellEl, item); this.bindCellClickEvent(cellEl, item, graphConfig, activityContainer); this.bindCellTips(cellEl, item); diff --git a/src/render/gitStyleTrackGraphRender.ts b/src/render/gitStyleTrackGraphRender.ts index c5343a8..a242629 100644 --- a/src/render/gitStyleTrackGraphRender.ts +++ b/src/render/gitStyleTrackGraphRender.ts @@ -117,6 +117,7 @@ export class GitStyleTrackGraphRender extends BaseGraphRender { if (contributionItem.date != "$HOLE$") { cellEl.className = "cell empty"; this.applyCellGlobalStyle(cellEl, graphConfig); + this.applyCellStyleRule(cellEl, contributionItem, cellRules); this.bindCellAttribute(cellEl, contributionItem); } else { cellEl.className = "cell"; @@ -124,7 +125,7 @@ export class GitStyleTrackGraphRender extends BaseGraphRender { } else { cellEl.className = "cell"; this.applyCellGlobalStyle(cellEl, graphConfig); - this.applyCellStyleRule(cellEl, contributionItem, cellRules); + this.applyCellStyleRule(cellEl, contributionItem, cellRules, () => cellRules[0]); this.bindCellAttribute(cellEl, contributionItem); this.bindCellClickEvent(cellEl, contributionItem, graphConfig, activityContainer); this.bindCellTips(cellEl, contributionItem); diff --git a/src/render/graphRender.ts b/src/render/graphRender.ts index 5978bcb..19431b1 100644 --- a/src/render/graphRender.ts +++ b/src/render/graphRender.ts @@ -219,14 +219,25 @@ export abstract class BaseGraphRender implements GraphRender { applyCellStyleRule( cellEl: HTMLElement, contributionItem: ContributionCellData, - cellRules: CellStyleRule[] + cellRules: CellStyleRule[], + defaultCellStyleRule?: () => CellStyleRule ) { const cellStyleRule = matchCellStyleRule( contributionItem.value, cellRules ); - cellEl.style.backgroundColor = cellStyleRule.color; - cellEl.innerText = cellStyleRule.text || ""; + if (cellStyleRule != null) { + cellEl.style.backgroundColor = cellStyleRule.color; + cellEl.innerText = cellStyleRule.text || ""; + return; + } + + if (defaultCellStyleRule) { + const defaultRule = defaultCellStyleRule(); + cellEl.style.backgroundColor = defaultRule.color; + cellEl.innerText = defaultRule.text || ""; + } + } bindCellAttribute( diff --git a/src/render/monthTrackGraphRender.ts b/src/render/monthTrackGraphRender.ts index 5149323..ae33df1 100644 --- a/src/render/monthTrackGraphRender.ts +++ b/src/render/monthTrackGraphRender.ts @@ -128,11 +128,12 @@ export class MonthTrackGraphRender extends BaseGraphRender { monthDataRowEl?.appendChild(cellEl); if (contributionItem.value == 0) { cellEl.className = "cell empty"; + this.applyCellStyleRule(cellEl, contributionItem, cellRules); this.bindCellAttribute(cellEl, contributionItem); } else { cellEl.className = "cell"; - this.applyCellStyleRule(cellEl, contributionItem, cellRules); + this.applyCellStyleRule(cellEl, contributionItem, cellRules, () => cellRules[0]); this.bindCellAttribute(cellEl, contributionItem); this.bindCellClickEvent(cellEl, contributionItem, graphConfig, activityContainer); this.bindCellTips(cellEl, contributionItem); diff --git a/src/util/utils.ts b/src/util/utils.ts index b215154..d0f4607 100644 --- a/src/util/utils.ts +++ b/src/util/utils.ts @@ -19,13 +19,13 @@ export function mapBy( return map; } -export function matchCellStyleRule(value: number, rules: CellStyleRule[]): CellStyleRule { +export function matchCellStyleRule(value: number, rules: CellStyleRule[]): CellStyleRule | null { for (let i = 0; i < rules.length; i++) { if (value >= rules[i].min && value < rules[i].max) { return rules[i]; } } - return rules[0]; + return null; } export function parseNumberOption(str: string): number | null { diff --git a/src/view/form/CellRuleFormItem.tsx b/src/view/form/CellRuleFormItem.tsx index 834ae96..b7b0a45 100644 --- a/src/view/form/CellRuleFormItem.tsx +++ b/src/view/form/CellRuleFormItem.tsx @@ -1,3 +1,15 @@ +import { + useFloating, + offset, + flip, + shift, + inline, + autoUpdate, + useDismiss, + useRole, + useInteractions, +} from "@floating-ui/react"; +import { Chrome, ColorResult } from "@uiw/react-color"; import { useState } from "react"; import { CellStyleRule } from "src/types"; @@ -7,53 +19,87 @@ export function CellRuleItem(props: { onRemove: (id: string) => void; }): JSX.Element { const [rule, setRule] = useState(props.rule); + const [showColorPicker, setShowColorPicker] = useState(false); const changeRule = (name: string, value: any) => { const newRule = { ...rule, [name]: value }; setRule(newRule); props.onChange(newRule); }; + const { refs, floatingStyles, context } = useFloating({ + open: showColorPicker, + onOpenChange: (open) => setShowColorPicker(open), + middleware: [offset(6), flip(), shift(), inline()], + whileElementsMounted: autoUpdate, + }); + + const dismiss = useDismiss(context); + const { getFloatingProps } = useInteractions([dismiss]); + return (
-
- - changeRule("min", e.target.value)} - /> - - contributions - - changeRule("max", e.target.value)} - /> - = - + + changeRule("min", e.target.value)} + /> + + contributions + + changeRule("max", e.target.value)} + /> + = + {/* changeRule("color", e.target.value)} - /> - changeRule("text", e.target.value)} - /> + /> */} + setShowColorPicker(!showColorPicker)} + > + {showColorPicker ? ( +
+ { + changeRule("color", color.hexa); + }} + /> +
+ ) : null} + changeRule("text", e.target.value)} + />
); diff --git a/styles.css b/styles.css index 6df4b97..c42f9c8 100644 --- a/styles.css +++ b/styles.css @@ -252,7 +252,9 @@ flex-grow: 1; cursor: pointer; position: relative; - text-align: center; + display: flex; + justify-content: center; + align-items: center; } .contribution-graph .cell:hover { @@ -267,6 +269,20 @@ background: rgba(71, 71, 71, 0.6); } +.color-indicator { + height: 18px; + width: 18px; + border-radius: 50%; + border-width: 1px; + border-color: var(--background-modifier-border); + border-style: solid; +} + +.color-indicator:hover { + border-color: var(--interactive-accent); + opacity: 0.6; +} + /* default cell rule indicator */ .contribution-graph .cell-rule-indicator-container { position: relative;