From 0ba565b82158bbe41fe8bda52fb1655e4e4fa6a1 Mon Sep 17 00:00:00 2001 From: Manvel Saroyan Date: Thu, 28 Mar 2024 18:02:32 -0300 Subject: [PATCH] No issue - combine the alert and info tooltips (#70) * No issue - combine the alert and info tooltips * publish packages * updated colors for alerted table * updated tests --- package.json | 2 +- src/cba-list/cba-list.js | 107 ++++++++++------------ src/cba-list/shadow.css | 57 +++++++++--- src/cba-table/shadow.css | 5 + src/cba-tooltip/shadow.css | 2 +- tests/puppeteer/classes/CbaList.js | 2 +- tests/puppeteer/tests/cba-list-tooltip.js | 12 ++- tests/smoke/cba-list/index.html | 8 +- tests/smoke/cba-list/smoke.js | 21 +++-- 9 files changed, 126 insertions(+), 90 deletions(-) diff --git a/package.json b/package.json index 2180f50..5b33cfe 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cba-components", - "version": "1.2.4", + "version": "1.2.6", "description": "This is a repository where the components for the Chromium Browser Automation project might live.", "main": "index.js", "bin": { diff --git a/src/cba-list/cba-list.js b/src/cba-list/cba-list.js index aa7cddb..4a347a3 100644 --- a/src/cba-list/cba-list.js +++ b/src/cba-list/cba-list.js @@ -5,9 +5,11 @@ import ConstructableCSS from '../ConstructableCSS'; const constructableCSS = new ConstructableCSS(shadowCSS); /** - * @typedef {object} Alert - alert object. - * @property {string} [text] - alert text. - * @property {"error"} [type] - alert type. + * @typedef {object} Info - information tooltip. + * @property {string} [description] - tooltip text. + * @property {"error" | "info"} [type] - tooltip type. + * @property {string} [link] - tooltip link. + * @property {string} [linkText] - tooltip link text. */ /** @@ -16,7 +18,7 @@ const constructableCSS = new ConstructableCSS(shadowCSS); * @property {string} text - Text to be displayed. * @property {boolean} selected - Is the item selected. * @property {boolean} editable - Is the item editable. - * @property {Alert} alert - highlight row. + * @property {Info} [info] - information tooltip. */ /** @@ -27,7 +29,7 @@ const constructableCSS = new ConstructableCSS(shadowCSS); * @property {ListSubItem["selected"]} selected - Is the item selected. * @property {ListSubItem["editable"]} editable - Is the item editable. * @property {ListSubItem[]} subItems - Sub items of the item. - * @property {Alert} [alert] - highlight row. + * @property {Info} [info] - information tooltip. */ const infoIcon = html` @@ -530,61 +532,49 @@ export class List extends HTMLElement this.subheading.textContent = this.getAttribute("subheading"); } - /** - * Get tooltip text from the item - * @param {object} item row item object - * @param {string} tooltip "tooltip" attribute value - */ - _getText(item, tooltip) - { - if (!tooltip || !item) - { - return ""; - } - if (tooltip.includes(".")) - { - return tooltip.split(".").reduce((acc, prop) => acc[prop] || "" , item); - } - else if (tooltip.includes("$")) - { - return tooltip.split("$").reduce((acc, prop, index, {length}) => - { - if (index -1 === length) - return acc[parseInt(prop, 10)] || ""; - else - return acc[prop] || ""; - }, item); - } - return item[tooltip] || ""; - } - showTooltip({target}) { const itemId = target.closest("li").dataset.id; const item = this.getItem(itemId); - const infoText = this._getText(item, this.tooltipText); - if (infoText) + if (item.info) { + const isFirstRender = !this.tooltip.querySelector("p"); // On first tooltip render when cba-list is placed inside of flexbox the // tooltip location is calculated wrongly, recalculation fixes that. - if (!this.tooltip.querySelector("p")) - this._renderTooltip(target, item); - this._renderTooltip(target, item); + this._renderTooltip(target, item.info); + if (isFirstRender) + { + setTimeout(() => this._renderTooltip(target, item.info), 50); + } } } + /** + * @param {HTMLElement} infoElem info icon wrapper + * @param {Info} item row item object + */ _renderTooltip(infoElem, item) { - const infoText = this._getText(item, this.tooltipText); - const infoLink = this._getText(item, this.tooltipLink); - const infoLinkText = this._getText(item, this.tooltipLinkText) || - this.tooltipLinkTextDefault; - const subitems = infoLink ? html`${infoLinkText}` : ""; + const infoText = item.description || ""; + const subitems = item.link ? html`${item.linkText || "Learn more"}` : ""; render(html`

${infoText}

${subitems}`, this.tooltip); const infoRect = infoElem.getBoundingClientRect(); + const offsetTop = (infoRect.top + infoRect.height / 2) - this.getBoundingClientRect().top - 2; const tooltipRect = this.tooltip.getBoundingClientRect(); - this.style.setProperty("--tooltip-offset-y", `${infoRect.top}px`); - this.style.setProperty("--tooltip-offset-x", `${tooltipRect.width}px`); + const placementX = infoRect.x - tooltipRect.width < 0 ? "right" : "left"; + this.tooltip.dataset.direction = placementX; + + if (placementX === "right") + { + const offsetX = infoRect.x + 5; + this.style.setProperty("--tooltip-offset-x", `${offsetX}px`); + } + else + { + const offsetX = infoRect.width + 5; + this.style.setProperty("--tooltip-offset-x", `${offsetX}px`); + } + this.style.setProperty("--tooltip-offset-y", `${offsetTop}px`); this.tooltip.classList.add("visible"); } @@ -608,22 +598,21 @@ export class List extends HTMLElement const classes = ["row"]; if (selected) classes.push("highlight"); - let alertTmpl = ""; - if (item.alert) - { - alertTmpl = html`${infoIcon}`; - } - const row = html`
${text}${alertTmpl}
`; - const infoText = this._getText(item, this.tooltipText); - if (infoText) + const row = html`${text}`; + if (item.info) { - const tooltip = html``; - return html`${tooltip}${row}`; - } - else - { - return row; + const infoTypeClassname = item.info.type === "error" ? "alert" : "default"; + const tooltip = html`${infoIcon}`; + if (item.info.type === "error") + { + return html`
${tooltip}${row}
`; + } + else + { + return html`
${tooltip}${row}
`; + } } + return html`
${row}
`; } const createList = (item) => { diff --git a/src/cba-list/shadow.css b/src/cba-list/shadow.css index fca1686..9cb8369 100644 --- a/src/cba-list/shadow.css +++ b/src/cba-list/shadow.css @@ -118,11 +118,8 @@ ul li .row { display: flex; + flex: 1; align-items: center; - border: solid 1px var(--color-border); - border-top-width: 0; - border-left-width: 0; - border-right-width: 0; font-weight: 300; padding-left: 5px; } @@ -143,7 +140,7 @@ li .row:not(.highlight):hover cursor: pointer; } -li .alert +li .info { position: absolute; right: 5px; @@ -151,11 +148,25 @@ li .alert cursor: pointer; } -li .alert svg g +.rowWrapper +{ + display: flex; + border: solid 1px var(--color-border); + border-top-width: 0; + border-left-width: 0; + border-right-width: 0; +} + +li .info.alert svg g { fill: rgb(255, 131, 131); } +li .info.default svg g +{ + fill: #999; +} + ul li { position: relative; @@ -257,7 +268,7 @@ li > button.collapsed { --arrow-adjust-x: calc(0px - var(--tooltip-arrow-size) / 2 - var(--tooltip-border-size)); --arrow-adjust-y: calc(var(--arrow-adjust-x) + var(--tooltip-arrow-size)); - --tooltip-adjust-x: calc((var(--tooltip-offset-x) * -1) - var(--tooltip-arrow-size)); + --tooltip-adjust-x: calc(var(--tooltip-offset-x) + var(--tooltip-arrow-size)); --tooltip-adjust-y: calc(var(--tooltip-offset-y) - var(--tooltip-arrow-size)); border: var(--tooltip-border-size) solid var(--tooltip-border-color); @@ -266,12 +277,11 @@ li > button.collapsed padding: 10px; position: absolute; max-width: var(--tooltip-max-width); + width: 100%; visibility: visible; opacity: 1; transition: visibility 0.3s, opacity 0.3s linear; font-size: 1em; - top: var(--tooltip-adjust-y); - left: var(--tooltip-adjust-x); z-index: 21; } @@ -286,10 +296,35 @@ li > button.collapsed background-color: var(--tooltip-color-background); border: var(--tooltip-border-size) solid var(--tooltip-border-color); transform: rotate(45deg); - top: var(--arrow-adjust-y); - right: var(--arrow-adjust-x); +} + +#tooltip:not([data-direction="right"]) +{ + top: var(--tooltip-adjust-y); + right: var(--tooltip-adjust-x); +} + +#tooltip:not([data-direction="right"])::before +{ border-bottom-color: transparent; border-left-color: transparent; + top: var(--arrow-adjust-y); + right: var(--arrow-adjust-x); +} + +#tooltip[data-direction="right"] +{ + top: var(--tooltip-adjust-y); + left: var(--tooltip-adjust-x); +} + +#tooltip[data-direction="right"]:before +{ + top: var(--arrow-adjust-y); + bottom: var(--arrow-adjust-y); + left: var(--arrow-adjust-x); + border-right-color: transparent; + border-top-color: transparent; } #tooltip:not(.visible):not(:hover) diff --git a/src/cba-table/shadow.css b/src/cba-table/shadow.css index 2384aec..e476381 100644 --- a/src/cba-table/shadow.css +++ b/src/cba-table/shadow.css @@ -120,6 +120,11 @@ tbody tr.alert outline: none; } +tbody tr.alert +{ + background-color: var(--color-alert); +} + tbody tr { outline: none; diff --git a/src/cba-tooltip/shadow.css b/src/cba-tooltip/shadow.css index da03465..0a94eb2 100644 --- a/src/cba-tooltip/shadow.css +++ b/src/cba-tooltip/shadow.css @@ -57,7 +57,7 @@ visibility: visible; opacity: 1; transition: visibility 0.3s, opacity 0.3s linear; - z-index: 1; + z-index: 21; } :host(:not(:hover)) #tooltip, diff --git a/tests/puppeteer/classes/CbaList.js b/tests/puppeteer/classes/CbaList.js index 0c2918a..d377e10 100644 --- a/tests/puppeteer/classes/CbaList.js +++ b/tests/puppeteer/classes/CbaList.js @@ -44,7 +44,7 @@ class CbaList extends Common async getRowInfoHandle(id) { const rowHandel = await this.getRowHandle(id); - return rowHandel.$(".hasInfo"); + return rowHandel.$(".info"); } async getTooltipAttribute(attribute) { diff --git a/tests/puppeteer/tests/cba-list-tooltip.js b/tests/puppeteer/tests/cba-list-tooltip.js index e9d23dc..231c129 100644 --- a/tests/puppeteer/tests/cba-list-tooltip.js +++ b/tests/puppeteer/tests/cba-list-tooltip.js @@ -35,8 +35,9 @@ it("cba-list rows with matching data of tooltip-text and tooltip-link attribute id: tooltipRowId, data: "Info", text: "List3", - tooltip: { - text: tooltipText, + info: { + description: "Tooltip text", + type: "info", link: tooltipLink, linkText: tooltipLinkText } @@ -45,9 +46,10 @@ it("cba-list rows with matching data of tooltip-text and tooltip-link attribute id: tooltipNoLinkTextRowId, data: "Info", text: "List4", - tooltip: { - text: tooltipText, - link: tooltipLink + info: { + description: "Tooltip text", + type: "info", + link: tooltipLink, } }, ]; diff --git a/tests/smoke/cba-list/index.html b/tests/smoke/cba-list/index.html index fb2c2d3..174fa3c 100644 --- a/tests/smoke/cba-list/index.html +++ b/tests/smoke/cba-list/index.html @@ -19,8 +19,9 @@ { display: flex; flex-direction: column; - width: 350px; + width: 200px; height: 300px; + margin-bottom: 100px; font-family: Verdana, Arial, sans-serif; } cba-list @@ -31,6 +32,7 @@ #sortable { height: 100%; + --tooltip-icon: url("info.svg#default"); } #subItemList { @@ -54,8 +56,8 @@

cba-list


-
- +
+
diff --git a/tests/smoke/cba-list/smoke.js b/tests/smoke/cba-list/smoke.js index 94e1651..4b2a0ba 100644 --- a/tests/smoke/cba-list/smoke.js +++ b/tests/smoke/cba-list/smoke.js @@ -4,8 +4,8 @@ const items = [ id: "row1", data: "Info", text: "List1", - alert: { - text: "Topmost element Alert text", + info: { + description: "Topmost element Alert text", type: "error" } }, @@ -23,8 +23,8 @@ const items = [ id: "subrow2", data: "Info", text: "Sub List2", - alert: { - text: "Subitem Alert text", + info: { + description: "Subitem Alert text", type: "error" } }, @@ -51,7 +51,7 @@ for (let i = 4; i < 20; i++) if (i === 10) { item.alert = { - text: "Middle Alert text", + description: "Middle Alert text", type: "error" } } @@ -61,8 +61,8 @@ items.push({ id: "row20", data: "Info", text: "List20", - alert: { - text: "Bottom Alert text", + info: { + description: "Bottom Alert text", type: "error" } }); @@ -71,10 +71,13 @@ cbaList.items = items; const cbaSortableList = document.querySelector("#sortable"); cbaSortableList.items = [ { - text: "A longer List1 to test wrap" + text: "A longer", }, { - text: "List3" + text: "List3", + info: { + description: "Info description to be visible when hovered over the icon." + }, }, { text: "List2"