diff --git a/package-lock.json b/package-lock.json index 5d07fc752..5ee7d7459 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,6 +24,7 @@ "lottie-web": "^5.9.5", "notyf": "^3.9.0", "sweetalert2": "^11.6.13", + "tippy.js": "^6.3.7", "v8-compile-cache": "^2.3.0" }, "devDependencies": { @@ -3400,6 +3401,15 @@ "node": ">=14" } }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, "node_modules/@radix-ui/number": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.0.1.tgz", @@ -19446,6 +19456,14 @@ "node": ">=14.0.0" } }, + "node_modules/tippy.js": { + "version": "6.3.7", + "resolved": "https://registry.npmjs.org/tippy.js/-/tippy.js-6.3.7.tgz", + "integrity": "sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==", + "dependencies": { + "@popperjs/core": "^2.9.0" + } + }, "node_modules/tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", diff --git a/package.json b/package.json index dda8296a5..fb97e0b00 100644 --- a/package.json +++ b/package.json @@ -151,6 +151,7 @@ "lottie-web": "^5.9.5", "notyf": "^3.9.0", "sweetalert2": "^11.6.13", + "tippy.js": "^6.3.7", "v8-compile-cache": "^2.3.0" }, "devDependencies": { diff --git a/src/renderer/assets/css/demo.css b/src/renderer/assets/css/demo.css index 4d4eb688f..f959c0a4d 100755 --- a/src/renderer/assets/css/demo.css +++ b/src/renderer/assets/css/demo.css @@ -713,13 +713,6 @@ table.table-save-metadata { font-size: 14px; font-style: italic; } - -.info { - width: 18px; - height: 18px; - float: right; -} - .tooltipnew .tooltiptext { visibility: hidden; width: 400px; diff --git a/src/renderer/assets/css/global.css b/src/renderer/assets/css/global.css index bc675321f..936161b96 100755 --- a/src/renderer/assets/css/global.css +++ b/src/renderer/assets/css/global.css @@ -17,6 +17,15 @@ word-break: break-all; } +/* Tippy */ +.tippy-box[data-theme~="error"] { + background-color: hsl(0, 100%, 70%); +} + +.tippy-box[data-theme~="warning"] { + background-color: hsl(57, 100%, 70%); +} + /* Global ---------------------------- */ * { diff --git a/src/renderer/src/stories/Table.js b/src/renderer/src/stories/Table.js index 2707b2da2..eaa0f4948 100644 --- a/src/renderer/src/stories/Table.js +++ b/src/renderer/src/stories/Table.js @@ -6,6 +6,9 @@ import { errorHue, warningHue } from "./globals"; import { checkStatus } from "../validation"; import { emojiFontFamily } from "./globals"; +import tippy from "tippy.js"; +import "tippy.js/dist/tippy.css"; + const maxRows = 20; // Inject scoped stylesheet @@ -13,6 +16,7 @@ const styles = ` ${css} + .handsontable td[error] { background: hsl(${errorHue}, 100%, 90%) !important; } @@ -37,11 +41,8 @@ const styles = ` padding-left: 20px } - [title] .relative::after { - content: 'ℹ️'; - display: inline-block; + .relative .info { margin: 0px 5px; - text-align: center; font-size: 80%; font-family: ${emojiFontFamily} } @@ -283,7 +284,19 @@ export class Table extends LitElement { const onAfterGetHeader = function (index, TH) { const desc = entries[colHeaders[index]].description; - if (desc) TH.setAttribute("title", desc); + if (desc) { + const rel = TH.querySelector(".relative"); + let span = rel.querySelector(".info"); + if (!span) { + span = document.createElement("span"); + span.classList.add("info"); + span.innerText = "ℹ️"; + rel.append(span); + } + + if (span._tippy) span._tippy.destroy(); + tippy(span, { content: `${desc}` }); + } }; const data = this.#getData(); @@ -425,17 +438,20 @@ export class Table extends LitElement { if (cell) { let title = ""; + let theme = ""; if (warnings.length) { - cell.setAttribute("warning", ""); - title = warnings.map((o) => o.message).join("\n"); + (theme = "warning"), (title = warnings.map((o) => o.message).join("\n")); } else cell.removeAttribute("warning"); if (errors.length) { - cell.setAttribute("error", ""); - title = errors.map((o) => o.message).join("\n"); // Class switching handled automatically + (theme = "error"), (title = errors.map((o) => o.message).join("\n")); // Class switching handled automatically } else cell.removeAttribute("error"); - if (title) cell.title = title; + if (theme) cell.setAttribute(theme, ""); + + if (cell._tippy) cell._tippy.destroy(); + + if (title) tippy(cell, { content: title, theme }); } this.#checkStatus(); // Check status after every validation update diff --git a/src/renderer/src/stories/pages/Page.js b/src/renderer/src/stories/pages/Page.js index 08e49c592..50f962a65 100644 --- a/src/renderer/src/stories/pages/Page.js +++ b/src/renderer/src/stories/pages/Page.js @@ -58,7 +58,7 @@ export class Page extends LitElement { notify = (...args) => { const ref = notify(...args); this.#notifications.push(ref); - return ref + return ref; }; to = async (transition) => { diff --git a/src/renderer/src/stories/pages/settings/SettingsPage.js b/src/renderer/src/stories/pages/settings/SettingsPage.js index b824b1872..d610f96ac 100644 --- a/src/renderer/src/stories/pages/settings/SettingsPage.js +++ b/src/renderer/src/stories/pages/settings/SettingsPage.js @@ -37,7 +37,7 @@ export class SettingsPage extends Page { #openNotyf = (message, type) => { if (this.#notification) notyf.dismiss(this.#notification); - return (this.#notification = this.notify(message,type)); + return (this.#notification = this.notify(message, type)); }; beforeSave = () => { @@ -60,8 +60,7 @@ export class SettingsPage extends Page { const button = new Button({ label: "Save Changes", onClick: async () => { - if (!this.unsavedUpdates) - return this.#openNotyf("All changes were already saved", "success"); + if (!this.unsavedUpdates) return this.#openNotyf("All changes were already saved", "success"); this.save(); }, }); diff --git a/src/renderer/src/stories/pages/uploads/UploadsPage.js b/src/renderer/src/stories/pages/uploads/UploadsPage.js index 0c53b7b7b..6ddefb19c 100644 --- a/src/renderer/src/stories/pages/uploads/UploadsPage.js +++ b/src/renderer/src/stories/pages/uploads/UploadsPage.js @@ -48,11 +48,17 @@ export async function uploadToDandi(info, type = "project" in info ? "project" : }, { title: "Uploading to DANDI" } ).catch((e) => { - this.notify(e.message, 'error'); + this.notify(e.message, "error"); throw e; }); - if (result) this.notify(`${info.project ?? `${info[folderPathKey].length} filesystem entries`} successfully uploaded to Dandiset ${dandiset_id}`, "success"); + if (result) + this.notify( + `${ + info.project ?? `${info[folderPathKey].length} filesystem entries` + } successfully uploaded to Dandiset ${dandiset_id}`, + "success" + ); return result; }