From b1c22f243fd3197fab2b66ead2b61e0dd1e1f98c Mon Sep 17 00:00:00 2001 From: Chris Mills Date: Wed, 19 Nov 2025 17:43:40 +0000 Subject: [PATCH] Add interest invoker examples to dom-examples --- README.md | 3 +- interest-invokers/index.html | 41 +++++++ .../popover-examples/chris-mills.jpg | Bin 0 -> 11114 bytes interest-invokers/popover-examples/index.html | 40 +++++++ interest-invokers/popover-examples/index.js | 35 ++++++ interest-invokers/popover-examples/styles.css | 96 ++++++++++++++++ interest-invokers/stock-moving/index.html | 60 ++++++++++ interest-invokers/stock-moving/index.js | 102 +++++++++++++++++ interest-invokers/stock-moving/styles.css | 58 ++++++++++ interest-invokers/style-preview/index.html | 23 ++++ interest-invokers/style-preview/index.js | 31 ++++++ interest-invokers/style-preview/styles.css | 105 ++++++++++++++++++ 12 files changed, 593 insertions(+), 1 deletion(-) create mode 100644 interest-invokers/index.html create mode 100644 interest-invokers/popover-examples/chris-mills.jpg create mode 100644 interest-invokers/popover-examples/index.html create mode 100644 interest-invokers/popover-examples/index.js create mode 100644 interest-invokers/popover-examples/styles.css create mode 100644 interest-invokers/stock-moving/index.html create mode 100644 interest-invokers/stock-moving/index.js create mode 100644 interest-invokers/stock-moving/styles.css create mode 100644 interest-invokers/style-preview/index.html create mode 100644 interest-invokers/style-preview/index.js create mode 100644 interest-invokers/style-preview/styles.css diff --git a/README.md b/README.md index a754e909..471d5bbf 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,8 @@ Do not specify supported browsers and their versions in code comments or prose, - The "insert-adjacent" directory contains basic demos for [insertAdjacentElement](https://mdn.github.io/dom-examples/insert-adjacent/insertAdjacentElement.html) and [insertAdjacentText](https://mdn.github.io/dom-examples/insert-adjacent/insertAdjacentText.html). +- The "interest-invokers" directory is for [interest invoker](https://developer.mozilla.org/docs/Web/API/Popover_API/Interest_invokers) examples. Go to the [Interest invoker examples index](https://mdn.github.io/dom-examples/interest-invokers/) to see what's available. + - The "launch-handler" directory contains a demo for the [Launch Handler API](https://developer.mozilla.org/en-US/docs/Web/API/Launch_Handler_API). [View the demo live](https://mdn.github.io/dom-examples/launch-handler/). This example was originally published on Glitch by [Thomas Steiner](https://front-end.social/@tomayac@toot.cafe). - The "local-font-access" directory contains a demo for the [Local Font Access API](https://developer.mozilla.org/en-US/docs/Web/API/Local_Font_Access_API). [View the demo live](https://mdn.github.io/dom-examples/local-font-access/). @@ -123,7 +125,6 @@ Do not specify supported browsers and their versions in code comments or prose, - Another example of view transitions in a [simple multiple-page app](https://mdn.github.io/dom-examples/view-transitions/mpa-homepage/) - [The `match-element` value](https://mdn.github.io/dom-examples/view-transitions/match-element/) for the `view-transition-name` property - - The "web-share" directory contains a basic demo to show usage of the [Web Share API](https://developer.mozilla.org/docs/Web/API/Navigator/share). [View the demo live](https://mdn.github.io/dom-examples/web-share/). - The "web-workers" directory contains several demos that show how [Web Workers](https://developer.mozilla.org/docs/Web/API/Web_Workers_API) operate. For example, view the live [simple web worker demo](https://mdn.github.io/dom-examples/web-workers/simple-web-worker/). diff --git a/interest-invokers/index.html b/interest-invokers/index.html new file mode 100644 index 00000000..81817ef8 --- /dev/null +++ b/interest-invokers/index.html @@ -0,0 +1,41 @@ + + + + + Interest invoker examples + + +

MDN interest invoker examples

+ +

+ This set of examples demonstrates usage of + Interest invokers. +

+ + + + diff --git a/interest-invokers/popover-examples/chris-mills.jpg b/interest-invokers/popover-examples/chris-mills.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0f9fdf37750a7abc6365f919b663ba0b5933fe95 GIT binary patch literal 11114 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 Zy$!D`CIf!ty{bh7r&;d;dx7MM{{y*X9<%@e literal 0 HcmV?d00001 diff --git a/interest-invokers/popover-examples/index.html b/interest-invokers/popover-examples/index.html new file mode 100644 index 00000000..516e59c2 --- /dev/null +++ b/interest-invokers/popover-examples/index.html @@ -0,0 +1,40 @@ + + + + + interestfor example + + + + + +

+ I think + @chrisdavidmills + should know about this. +

+ +
+
+ chris mills +
+

Chris Mills

+

+ Independent tech writer and web technology tinkerer, working on MDN + on behalf of Google and Mozilla. A11y and open standards advocate. + Heavy metal drummer. +

+

🌍 Greenfield, UK

+
+
+
+ +

+ +
+

This button does absolutely nothing.

+
+ + diff --git a/interest-invokers/popover-examples/index.js b/interest-invokers/popover-examples/index.js new file mode 100644 index 00000000..7b68d093 --- /dev/null +++ b/interest-invokers/popover-examples/index.js @@ -0,0 +1,35 @@ +const interestLink = document.querySelector("[interestfor='user-info']"); +const interestButton = document.querySelector("[interestfor='button-tooltip']"); +const userInfo = document.getElementById("user-info"); +const buttonTooltip = document.getElementById("button-tooltip"); + +// Feature detection + +const supported = + HTMLButtonElement.prototype.hasOwnProperty("interestForElement"); +if (!supported) { + document.querySelector("html").classList.add("no-interest-invokers"); +} + +// interestForElement example + +console.log(interestLink.interestForElement); +console.log(interestButton.interestForElement); + +// Event examples + +userInfo.addEventListener("interest", reportInterest); +buttonTooltip.addEventListener("interest", reportInterest); +userInfo.addEventListener("loseinterest", reportInterest); +buttonTooltip.addEventListener("loseinterest", reportInterest); + +function reportInterest(e) { + let action; + if (e.type === "interest") { + action = "Interest gained"; + } else { + action = "Interest lost"; + } + + console.log(`${action} on ${e.source.tagName}`); +} diff --git a/interest-invokers/popover-examples/styles.css b/interest-invokers/popover-examples/styles.css new file mode 100644 index 00000000..43c35790 --- /dev/null +++ b/interest-invokers/popover-examples/styles.css @@ -0,0 +1,96 @@ +html { + font-family: sans-serif; +} + +* { + box-sizing: border-box; +} + +/* Browser support banner */ + +.no-interest-invokers body::before { + content: "Your browser doesn't support interest invokers."; + background-color: wheat; + display: block; + padding: 10px 0; + width: 100%; + text-align: center; +} + +/* Link interestfor styles */ + +a[interestfor] { + interest-delay: 1s 2s; +} + +/* Shared styles across popovers */ + +#user-info, +#button-tooltip { + border: 1px solid lightgray; + border-radius: 5px; + padding: 0 10px; + margin: 5px; + background-color: white; + font-size: 0.8rem; +} + +#user-info { + position-area: bottom right; +} + +#user-info .wrapper { + display: flex; + align-items: center; + gap: 20px; + width: 480px; + font-size: 0.8rem; +} + +#user-info img { + margin: 10px 0; + border: 1px solid lightgray; + border-radius: 5px; +} + +/* button interestfor styles */ + +button[interestfor="button-tooltip"] { + border: 1px solid transparent; + padding: 5px 10px; + border-radius: 5px; + color: white; + background-color: rgb(200 0 0); +} + +/* Applies styles to the interest invoker, but only when the user is showing interest */ +button:interest-source { + background-color: rgb(255 0 0); +} + +button[interestfor="button-tooltip"]:active { + color: rgb(255 0 0); + border: 1px solid rgb(255 0 0); + background-color: white; +} + +#button-tooltip { + position-area: right; +} + +/* animation for interest targets */ + +[popover]:interest-target { + opacity: 1; +} + +[popover] { + opacity: 0; + transition: all 0.7s allow-discrete; +} + +@starting-style { + [popover]:interest-target { + opacity: 0; + } +} diff --git a/interest-invokers/stock-moving/index.html b/interest-invokers/stock-moving/index.html new file mode 100644 index 00000000..65d73679 --- /dev/null +++ b/interest-invokers/stock-moving/index.html @@ -0,0 +1,60 @@ + + + + + interestfor stock moving example + + + + + +

interestfor stock moving example

+
+

+
+

Stock to keep

+
+ + + + + +
+
+
+

Stock to sell

+
+
+
+ + diff --git a/interest-invokers/stock-moving/index.js b/interest-invokers/stock-moving/index.js new file mode 100644 index 00000000..c3251abc --- /dev/null +++ b/interest-invokers/stock-moving/index.js @@ -0,0 +1,102 @@ +// Feature detection + +const supported = + HTMLButtonElement.prototype.hasOwnProperty("interestForElement"); +if (!supported) { + document.querySelector("html").classList.add("no-interest-invokers"); +} + +// Variable and handler definition + +const interestBtns = document.querySelectorAll("button"); +const btnTooltip = document.getElementById("button-tooltip"); +const keepList = document.querySelector(".keep"); +const sellList = document.querySelector(".sell"); + +let interval; +let stockToMove = 0; + +btnTooltip.addEventListener("interest", incrementStock); +btnTooltip.addEventListener("loseinterest", resetStock); +interestBtns.forEach((btn) => btn.addEventListener("click", moveStock)); + +// Increment the amount of stock to move when interest is shown +function incrementStock(e) { + const sourceElem = e.source; + stockToMove = 0; + + function updateStockCount() { + // Only increment stockToMove if it is smaler than the entire available stock + let stock = Number(sourceElem.getAttribute("data-stock")); + if (stockToMove < stock) { + stockToMove++; + btnTooltip.textContent = `Stock to move: ${stockToMove}`; + } + } + + // Immediately increment stock to move, and then do it repeated every 250ms + updateStockCount(); + interval = setInterval(updateStockCount, 250); +} + +// Reset the amount of stock to move when interest is lost +function resetStock(e) { + // Clear the interval and the tooltip's text content, ready for next time + clearInterval(interval); + btnTooltip.textContent = ""; +} + +// Move the stock when the button is actually clicked +function moveStock(e) { + // Determine which list we are moving the stock item to + let targetList; + if (e.target.parentNode === keepList) { + targetList = sellList; + } else { + targetList = keepList; + } + + // number of items and product to move + const newStock = stockToMove; + const newProduct = e.target.getAttribute("data-product"); + + // Determine whether a stack of that item already + // exists at the place to move the item to + const targetProductsList = Array.from(targetList.children); + const existingNewProduct = targetProductsList.find( + (element) => element.getAttribute("data-product") === newProduct + ); + + // If so, just add the items to the existing stack + if (existingNewProduct) { + const totalStock = + Number(existingNewProduct.getAttribute("data-stock")) + newStock; + existingNewProduct.setAttribute("data-stock", totalStock); + existingNewProduct.textContent = `${newProduct} (${totalStock})`; + } else { + // If not, create a new stack and append it to the list + const newBtn = document.createElement("button"); + newBtn.setAttribute("interestFor", "button-tooltip"); + newBtn.setAttribute("data-stock", newStock); + newBtn.setAttribute("data-product", newProduct); + newBtn.textContent = `${newProduct} (${newStock})`; + newBtn.addEventListener("click", moveStock); + targetList.appendChild(newBtn); + } + + // Update the stack the stock was moved FROM to show the remaining items + const oldStock = Number(e.target.getAttribute("data-stock")) - stockToMove; + e.target.setAttribute("data-stock", oldStock); + e.target.textContent = `${newProduct} (${oldStock})`; + + // Unfocus the button interest was being shown in. If you don't do this, you get weird behavior + // when it was focused via the keyboard — the interestfor target element starts incrementing again + // immediately, and if the stack goes to 0 and disappears (see next block), the focus shifts to the + // body and you get the interestfor target appearing at the top of the viewport! + e.target.blur(); + + // If the stack the stock was moved from has no remaining items, remove it from the DOM + if (e.target.getAttribute("data-stock") === "0") { + e.target.remove(); + } +} diff --git a/interest-invokers/stock-moving/styles.css b/interest-invokers/stock-moving/styles.css new file mode 100644 index 00000000..e9f4a4b2 --- /dev/null +++ b/interest-invokers/stock-moving/styles.css @@ -0,0 +1,58 @@ +html { + font-family: sans-serif; +} + +* { + box-sizing: border-box; +} + +/* Browser support banner */ + +.no-interest-invokers body::before { + content: "Your browser doesn't support interest invokers."; + background-color: wheat; + display: block; + padding: 10px 0; + width: 100%; + text-align: center; +} + +/* Layout styles */ + +.wrapper { + max-width: 640px; + margin: 0 auto; + display: flex; +} + +.wrapper section { + flex: 1; +} + +/* interestfor styles */ + +h1, +h2 { + text-align: center; +} + +button[interestfor] { + display: block; + padding: 10px; + border-radius: 5px; + border: 1px solid lightgray; + width: 50%; + margin: 10px auto; + /* Needs to be set on the interest invoker element (with interestfor set on it), not the popover */ + interest-delay: 1s 0s; +} + +#button-tooltip { + border: 1px solid lightgray; + border-radius: 5px; + padding: 10px; + margin: 1px; + background-color: white; + font-size: 0.8rem; + position-area: bottom; +} diff --git a/interest-invokers/style-preview/index.html b/interest-invokers/style-preview/index.html new file mode 100644 index 00000000..f02a11d8 --- /dev/null +++ b/interest-invokers/style-preview/index.html @@ -0,0 +1,23 @@ + + + + + interestfor without popover + + + + + +
+ + + + + +
+
+

Style preview panel

+

This is kinda fun, no?

+
+ + diff --git a/interest-invokers/style-preview/index.js b/interest-invokers/style-preview/index.js new file mode 100644 index 00000000..3d39f846 --- /dev/null +++ b/interest-invokers/style-preview/index.js @@ -0,0 +1,31 @@ +const stylePanel = document.getElementById("style-panel"); +const buttons = document.querySelectorAll("button"); + +let prevStyle = "black-white"; + +// Feature detection + +const supported = + HTMLButtonElement.prototype.hasOwnProperty("interestForElement"); +if (!supported) { + document.querySelector("html").classList.add("no-interest-invokers"); +} + +// Event examples + +stylePanel.addEventListener("interest", sampleStyle); +stylePanel.addEventListener("loseinterest", revertStyle); +buttons.forEach((button) => button.addEventListener("click", setStyle)); + +function sampleStyle(e) { + e.target.className = e.source.className; +} + +function revertStyle(e) { + e.target.className = prevStyle; +} + +function setStyle(e) { + stylePanel.className = e.target.className; + prevStyle = e.target.className; +} diff --git a/interest-invokers/style-preview/styles.css b/interest-invokers/style-preview/styles.css new file mode 100644 index 00000000..4e0f1a2c --- /dev/null +++ b/interest-invokers/style-preview/styles.css @@ -0,0 +1,105 @@ +html { + font-family: sans-serif; +} + +* { + box-sizing: border-box; +} + +/* Browser support banner */ + +.no-interest-invokers body::before { + content: "Your browser doesn't support interest invokers."; + background-color: wheat; + display: block; + padding: 10px 0; + width: 100%; + text-align: center; +} + +/* General styles */ + +body { + width: 640px; + margin: 0 auto; +} + +body > div { + display: flex; + gap: 5px; + margin-top: 20px; +} + +button { + flex: 1; + padding: 5px; + border-radius: 3px; +} + +#style-panel { + padding: 20px; + border-radius: 30px; + margin-top: 20px; + border-width: 10px; + corner-shape: scoop; +} + +h2 { + margin-top: 0; + text-align: center; + letter-spacing: 5px; +} + +p { + margin-bottom: 0; + text-align: center; + font-weight: bold; + letter-spacing: 3px; +} + +/* Color classes */ + +.black-white { + color: black; + background-color: white; + border: 2px solid black; +} + +.bubblegum { + color: #fff8f0; + background-color: #ef476f; + border: 2px solid #fff8f0; + box-shadow: 0 0 2px #ef476f; +} + +.purple-haze { + color: #8a1c7c; + background-color: #f0bcd4; + border: 2px solid #8a1c7c; +} + +.blaze { + color: #f2e94e; + background-color: #7e6b8f; + border: 2px solid #f2e94e; +} + +.mint-brown { + color: #41463d; + background-color: #1cfeba; + border: 2px solid #41463d; +} + +/* Applies styles to the interest invoker, but only when the user is showing interest */ + +button:interest-source { + background-color: black; + color: white; + border: 2px solid black; +} + +/* animation for style panel */ + +#style-panel { + transition: all 0.7s; +}