UNPKG

bionictoggle

Version:

Bionic toggle to enable/disable bionic reading in your blogs

80 lines (79 loc) 3.59 kB
import React, { useState } from "react"; import styles from "./BionicToggle.module.css"; function BionicToggle({ contentClassName }) { const [isToggled, setIsToggled] = useState(false); const [originalText, setOriginalText] = useState({}); // Components to be considered can be added here const componentNames = ["p", "span"]; const handleToggle = () => { const componentSelectors = componentNames .map((name) => `.${contentClassName} ${name}`) .join(", "); const textTags = document.querySelectorAll(componentSelectors); // Loop through each text tag and modify its text content textTags.forEach((el, i) => { // Toggle on - store the original text and update the tag content if (!isToggled) { const textNodes = el.childNodes; let originalText = ""; let boldText = ""; // Loop through each child node of the tag textNodes.forEach((node) => { // If the child node is a text node if (node.nodeType === Node.TEXT_NODE) { const text = node.textContent; boldText += boldWords(text).join(" "); originalText += text; } // If the child node is a p or span tag else if (node.nodeName === "P" || node.nodeName === "SPAN") { const text = node.textContent; const boldChildText = text ? boldWords(text).join(" ") : null; el.innerHTML = boldChildText; originalText += text; } }); // Update the original text and tag content if (el.nodeType === Node.TEXT_NODE) { if (boldText) el.textContent = boldText; setOriginalText((prevState) => (Object.assign(Object.assign({}, prevState), { [i]: originalText }))); } else if (el.nodeName === "P" || el.nodeName === "SPAN") { if (boldText) el.innerHTML = boldText; setOriginalText((prevState) => (Object.assign(Object.assign({}, prevState), { [i]: originalText }))); } } // Toggle off - retrieve the original text and update the tag content else { if (el.nodeType === Node.TEXT_NODE) { el.textContent = originalText[i]; } else if (el.nodeName === "P" || el.nodeName === "SPAN") { el.innerHTML = originalText[i]; } } }); // Toggle the isToggled state setIsToggled(!isToggled); }; const boldWords = (text) => { const first = "<strong>"; const last = "</strong>"; return text .split(" ") .map((x) => x.length === 1 ? first + x + last : first + x.slice(0, Math.round(x.length / 2)) + last + x.slice(Math.round(x.length / 2))); }; return (React.createElement("div", { className: "container" }, React.createElement("button", { className: isToggled ? styles.on : styles.off, onClick: handleToggle }, React.createElement("span", { className: styles.pin }, "B")))); } export default BionicToggle;