UNPKG

react-text-to-speech

Version:

An easy-to-use React.js library that leverages the Web Speech API to convert text to speech.

67 lines (64 loc) 3.88 kB
import { composeProps, idPrefix, highlightedTextIdSuffix, useSpeechInternal, hideElement, showElement } from './chunk-A4O2Q4ZN.js'; import { HiVolumeUp, HiVolumeOff, HiMiniStop } from './chunk-KE4WPWBB.js'; import { __objRest, __spreadValues } from './chunk-FZ4QVG4I.js'; import React, { useRef, useLayoutEffect } from 'react'; function HighlightedText(_a) { var _b = _a, { id, children } = _b, props = __objRest(_b, ["id", "children"]); const uniqueId = `${idPrefix}${id}`; return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", __spreadValues({}, composeProps(uniqueId, props))), /* @__PURE__ */ React.createElement("div", __spreadValues({}, composeProps(`${uniqueId}${highlightedTextIdSuffix}`, props)))); } function Speech(_a) { var _b = _a, { startBtn = /* @__PURE__ */ React.createElement(HiVolumeUp, null), pauseBtn = /* @__PURE__ */ React.createElement(HiVolumeOff, null), stopBtn = /* @__PURE__ */ React.createElement(HiMiniStop, null), useStopOverPause = false, enableConditionalHighlight = false, props = {}, children } = _b, hookProps = __objRest(_b, [ "startBtn", "pauseBtn", "stopBtn", "useStopOverPause", "enableConditionalHighlight", "props", "children" ]); const _a2 = useSpeechInternal(hookProps), { uniqueId, normalizedText, reactContent, Text, speechStatus } = _a2, childrenOptions = __objRest(_a2, ["uniqueId", "normalizedText", "reactContent", "Text", "speechStatus"]); const { isInQueue, start, pause, stop } = childrenOptions; const sourceRef = useRef(null); useLayoutEffect(() => { const containers = Array.from(document.getElementsByClassName(uniqueId)).filter((container) => container !== sourceRef.current); if (!containers.length) return; const sourceHTML = sourceRef.current.innerHTML; containers.forEach((container) => container.innerHTML = sourceHTML); if (!enableConditionalHighlight) return; const observer = new MutationObserver(() => { const observedContainers = Array.from(document.getElementsByClassName(uniqueId)); observedContainers.forEach((container) => { if (!container.innerHTML) container.innerHTML = sourceHTML; }); }); observer.observe(document.body, { childList: true, subtree: true }); return () => observer.disconnect(); }, [normalizedText, uniqueId]); useLayoutEffect(() => { const containers = Array.from(document.getElementsByClassName(uniqueId)).filter((container) => container !== sourceRef.current); if (!containers.length) return; const highlightedTextContainers = Array.from(document.getElementsByClassName(`${uniqueId}${highlightedTextIdSuffix}`)); if (hookProps.showOnlyHighlightedText) { const sourceHTML = sourceRef.current.innerHTML; containers.forEach(hideElement); highlightedTextContainers.forEach((container) => { container.innerHTML = sourceHTML; showElement(container); }); } else { highlightedTextContainers.forEach(hideElement); containers.forEach(showElement); } }, [reactContent, uniqueId]); return typeof children === "function" ? children(childrenOptions) : /* @__PURE__ */ React.createElement("div", __spreadValues({ style: { display: "flex", columnGap: "1rem" } }, props), !isInQueue ? /* @__PURE__ */ React.createElement("span", { role: "button", onClick: start }, startBtn) : useStopOverPause ? /* @__PURE__ */ React.createElement("span", { role: "button", onClick: stop }, stopBtn) : /* @__PURE__ */ React.createElement("span", { role: "button", onClick: pause }, pauseBtn), !useStopOverPause && stopBtn && /* @__PURE__ */ React.createElement("span", { role: "button", onClick: stop }, stopBtn), /* @__PURE__ */ React.createElement(Text, { ref: sourceRef, style: { display: "none" } })); } export { HighlightedText, Speech };