New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

react-text-to-speech

Package Overview
Dependencies
Maintainers
1
Versions
121
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-text-to-speech - npm Package Compare versions

Comparing version 0.6.8 to 0.7.0

12

dist/icons.js
import React from "react";
export function HiVolumeUp(props) {
return React.createElement("span", Object.assign({}, props),
return (React.createElement("span", Object.assign({}, props),
React.createElement("svg", { viewBox: "0 0 20 20", fill: "currentColor", "aria-hidden": true, width: "1.25rem", height: "1.25rem" },
React.createElement("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M9.383 3.076A1 1 0 0110 4v12a1 1 0 01-1.707.707L4.586 13H2a1 1 0 01-1-1V8a1 1 0 011-1h2.586l3.707-3.707a1 1 0 011.09-.217zM14.657 2.929a1 1 0 011.414 0A9.972 9.972 0 0119 10a9.972 9.972 0 01-2.929 7.071 1 1 0 01-1.414-1.414A7.971 7.971 0 0017 10c0-2.21-.894-4.208-2.343-5.657a1 1 0 010-1.414zm-2.829 2.828a1 1 0 011.415 0A5.983 5.983 0 0115 10a5.984 5.984 0 01-1.757 4.243 1 1 0 01-1.415-1.415A3.984 3.984 0 0013 10a3.983 3.983 0 00-1.172-2.828 1 1 0 010-1.415z" })));
React.createElement("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M9.383 3.076A1 1 0 0110 4v12a1 1 0 01-1.707.707L4.586 13H2a1 1 0 01-1-1V8a1 1 0 011-1h2.586l3.707-3.707a1 1 0 011.09-.217zM14.657 2.929a1 1 0 011.414 0A9.972 9.972 0 0119 10a9.972 9.972 0 01-2.929 7.071 1 1 0 01-1.414-1.414A7.971 7.971 0 0017 10c0-2.21-.894-4.208-2.343-5.657a1 1 0 010-1.414zm-2.829 2.828a1 1 0 011.415 0A5.983 5.983 0 0115 10a5.984 5.984 0 01-1.757 4.243 1 1 0 01-1.415-1.415A3.984 3.984 0 0013 10a3.983 3.983 0 00-1.172-2.828 1 1 0 010-1.415z" }))));
}
export function HiVolumeOff(props) {
return React.createElement("span", Object.assign({}, props),
return (React.createElement("span", Object.assign({}, props),
React.createElement("svg", { viewBox: "0 0 20 20", fill: "currentColor", "aria-hidden": true, width: "1.25rem", height: "1.25rem" },
React.createElement("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M9.383 3.076A1 1 0 0110 4v12a1 1 0 01-1.707.707L4.586 13H2a1 1 0 01-1-1V8a1 1 0 011-1h2.586l3.707-3.707a1 1 0 011.09-.217zM12.293 7.293a1 1 0 011.414 0L15 8.586l1.293-1.293a1 1 0 111.414 1.414L16.414 10l1.293 1.293a1 1 0 01-1.414 1.414L15 11.414l-1.293 1.293a1 1 0 01-1.414-1.414L13.586 10l-1.293-1.293a1 1 0 010-1.414z" })));
React.createElement("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M9.383 3.076A1 1 0 0110 4v12a1 1 0 01-1.707.707L4.586 13H2a1 1 0 01-1-1V8a1 1 0 011-1h2.586l3.707-3.707a1 1 0 011.09-.217zM12.293 7.293a1 1 0 011.414 0L15 8.586l1.293-1.293a1 1 0 111.414 1.414L16.414 10l1.293 1.293a1 1 0 01-1.414 1.414L15 11.414l-1.293 1.293a1 1 0 01-1.414-1.414L13.586 10l-1.293-1.293a1 1 0 010-1.414z" }))));
}
export function HiMiniStop(props) {
return React.createElement("span", Object.assign({}, props),
return (React.createElement("span", Object.assign({}, props),
React.createElement("svg", { viewBox: "0 0 20 20", fill: "currentColor", "aria-hidden": true, width: "1.25rem", height: "1.25rem" },
React.createElement("path", { d: "M5.25 3A2.25 2.25 0 003 5.25v9.5A2.25 2.25 0 005.25 17h9.5A2.25 2.25 0 0017 14.75v-9.5A2.25 2.25 0 0014.75 3h-9.5z" })));
React.createElement("path", { d: "M5.25 3A2.25 2.25 0 003 5.25v9.5A2.25 2.25 0 005.25 17h9.5A2.25 2.25 0 0017 14.75v-9.5A2.25 2.25 0 0014.75 3h-9.5z" }))));
}

@@ -1,4 +0,4 @@

import React, { DetailedHTMLProps, HTMLAttributes, ReactNode } from 'react';
import React, { DetailedHTMLProps, HTMLAttributes, ReactNode } from "react";
export type Button = JSX.Element | string | null;
export type SpeechStatus = 'started' | 'paused' | 'stopped';
export type SpeechStatus = "started" | "paused" | "stopped";
export type ChildrenOptions = {

@@ -18,2 +18,3 @@ speechStatus?: SpeechStatus;

lang?: string;
voiceURI?: string | string[];
startBtn?: Button;

@@ -27,3 +28,3 @@ pauseBtn?: Button;

};
export type { IconProps } from './icons.js';
export default function Speech({ text, pitch, rate, volume, lang, startBtn, pauseBtn, stopBtn, useStopOverPause, onError, children, props }: SpeechProps): string | number | boolean | React.JSX.Element | Iterable<React.ReactNode> | null | undefined;
export type { IconProps } from "./icons.js";
export default function Speech({ text, pitch, rate, volume, lang, voiceURI, startBtn, pauseBtn, stopBtn, useStopOverPause, onError, children, props, }: SpeechProps): string | number | boolean | React.JSX.Element | Iterable<React.ReactNode> | null | undefined;

@@ -1,8 +0,8 @@

import React, { useEffect, useState } from 'react';
import { HiMiniStop, HiVolumeOff, HiVolumeUp } from './icons.js';
export default function Speech({ text, pitch = 1, rate = 1, volume = 1, lang = '', startBtn = React.createElement(HiVolumeUp, null), pauseBtn = React.createElement(HiVolumeOff, null), stopBtn = React.createElement(HiMiniStop, null), useStopOverPause, onError = () => alert('Browser not supported! Try some other browser.'), children, props = {} }) {
const [speechStatus, setSpeechStatus] = useState('stopped');
import React, { useEffect, useState } from "react";
import { HiMiniStop, HiVolumeOff, HiVolumeUp } from "./icons.js";
export default function Speech({ text, pitch = 1, rate = 1, volume = 1, lang, voiceURI, startBtn = React.createElement(HiVolumeUp, null), pauseBtn = React.createElement(HiVolumeOff, null), stopBtn = React.createElement(HiMiniStop, null), useStopOverPause, onError = () => alert("Browser not supported! Try some other browser."), children, props = {}, }) {
const [speechStatus, setSpeechStatus] = useState("stopped");
const [useStop, setUseStop] = useState();
const pause = () => { var _a; return speechStatus !== 'paused' && ((_a = window.speechSynthesis) === null || _a === void 0 ? void 0 : _a.pause()); };
const stop = () => { var _a; return speechStatus !== 'stopped' && ((_a = window.speechSynthesis) === null || _a === void 0 ? void 0 : _a.cancel()); };
const pause = () => { var _a; return speechStatus !== "paused" && ((_a = window.speechSynthesis) === null || _a === void 0 ? void 0 : _a.pause()); };
const stop = () => { var _a; return speechStatus !== "stopped" && ((_a = window.speechSynthesis) === null || _a === void 0 ? void 0 : _a.cancel()); };
function start() {

@@ -12,14 +12,21 @@ const synth = window.speechSynthesis;

return onError();
setSpeechStatus('started');
if (speechStatus === 'paused')
setSpeechStatus("started");
if (speechStatus === "paused")
return synth.resume();
if (synth.speaking)
synth.cancel();
const utterance = new window.SpeechSynthesisUtterance(text === null || text === void 0 ? void 0 : text.replace(/\s/g, ' '));
const utterance = new window.SpeechSynthesisUtterance(text === null || text === void 0 ? void 0 : text.replace(/\s/g, " "));
utterance.pitch = pitch;
utterance.rate = rate;
utterance.volume = volume;
utterance.lang = lang;
if (lang)
utterance.lang = lang;
if (voiceURI) {
if (!Array.isArray(voiceURI))
voiceURI = [voiceURI];
const voices = synth.getVoices();
utterance.voice = voiceURI.flatMap((uri) => voices.find((voice) => voice.voiceURI === uri) || [])[0] || null;
}
function setStopped() {
setSpeechStatus('stopped');
setSpeechStatus("stopped");
utterance.onpause = null;

@@ -31,3 +38,3 @@ utterance.onend = null;

}
utterance.onpause = () => setSpeechStatus('paused');
utterance.onpause = () => setSpeechStatus("paused");
utterance.onend = setStopped;

@@ -37,10 +44,2 @@ utterance.onerror = setStopped;

}
function speech() {
if (speechStatus !== 'started')
start();
else if (useStop === false)
pause();
else
stop();
}
useEffect(() => {

@@ -51,5 +50,5 @@ var _a, _b;

}, []);
return typeof children === 'function' ? children({ speechStatus, start, pause, stop }) : React.createElement("div", Object.assign({ style: { display: 'flex', columnGap: '1rem' } }, props),
React.createElement("span", { role: 'button', onClick: speech }, speechStatus !== 'started' ? startBtn : useStop === false ? pauseBtn : stopBtn),
useStop === false && stopBtn && React.createElement("span", { role: 'button', onClick: stop }, stopBtn));
return typeof children === "function" ? (children({ speechStatus, start, pause, stop })) : (React.createElement("div", Object.assign({ style: { display: "flex", columnGap: "1rem" } }, props),
speechStatus !== "started" ? (React.createElement("span", { role: "button", onClick: start }, startBtn)) : useStop === false ? (React.createElement("span", { role: "button", onClick: pause }, pauseBtn)) : (React.createElement("span", { role: "button", onClick: stop }, stopBtn)),
useStop === false && stopBtn && (React.createElement("span", { role: "button", onClick: stop }, stopBtn))));
}
{
"name": "react-text-to-speech",
"version": "0.6.8",
"version": "0.7.0",
"description": "An easy to use react component for the Web Speech API.",

@@ -34,3 +34,3 @@ "type": "module",

"devDependencies": {
"@types/react": "^18.2.48"
"@types/react": "^18.2.52"
},

@@ -37,0 +37,0 @@ "scripts": {

# react-text-to-speech
An easy to use react component for the [Web Speech API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Speech_API).
It is as easy as to import a React component!
## Features
- Text-to-speech

@@ -11,4 +14,7 @@ - Easy to use

- Fully Customizable. See [usage with FaC](#full-customization)
## Installation
To install react-text-to-speech
```bash

@@ -27,95 +33,131 @@ # with npm:

```
## Usage
When you use the `<Speech>` component of `react-text-to-speech`, initially the user will see the `startBtn` and when the user clicks on it, the speech instance will start and the user will see the `pauseBtn` which can be used to pause the speech instance. The user will also see the `stopBtn` which can be used to stop the speech instance at any moment.
#### Basic Usage
```jsx
import React from 'react'
import Speech from 'react-text-to-speech'
import React from "react";
import Speech from "react-text-to-speech";
export default function App() {
return <Speech text='This library is awesome!' />
return <Speech text="This library is awesome!" />;
}
```
#### Advanced Usage
This is the use case where `react-text-to-speech` outshines the other text-to-speech libraries.
Let's assume that you fetch news from any News API and the API returns 3 news in response as shown below. Now if the user clicks on `startBtn` of #1 news (assuming # as id) and then clicks on `startBtn` on #2 news before the speech instance of #1 news ends, then `react-text-to-speech` will not just stop the #1 news speech instance and start the #2 news speech instance, but will also convert the `pauseBtn` of #1 news to `startBtn`, thus avoiding any confusion.
```jsx
import React from 'react'
import Speech from 'react-text-to-speech'
import React from "react";
import Speech from "react-text-to-speech";
export default function App() {
// 'news' holds response from some News API
const news = [
{ id: '1', title: 'First random title', desc: 'First random description' },
{ id: '2', title: 'Second random title', desc: 'Second random description' },
{ id: '3', title: 'Third random title', desc: 'Third random description' },
]
// 'news' holds response from some News API
const news = [
{ id: "1", title: "First random title", desc: "First random description" },
{ id: "2", title: "Second random title", desc: "Second random description" },
{ id: "3", title: "Third random title", desc: "Third random description" },
];
return <>
{news.map(({ id, title, desc }) => <div key={id}>
<h4>{title}</h4>
<div>{desc}</div>
<Speech text={`${title}. ${desc}`} />
</div>)}
return (
<>
{news.map(({ id, title, desc }) => (
<div key={id}>
<h4>{title}</h4>
<div>{desc}</div>
<Speech text={`${title}. ${desc}`} />
</div>
))}
</>
);
}
```
#### Partial Customization
Use props provided by `<Speech>` component to customize it.
```jsx
import React from 'react';
import Speech from 'react-text-to-speech';
import React from "react";
import Speech from "react-text-to-speech";
export default function App() {
const startBtn = <button className='my-start-btn'>Start Speech</button>
const pauseBtn = <button className='my-pause-btn'>Pause Speech</button>
const stopBtn = <button className='my-stop-btn'>Stop Speech</button>
const startBtn = <button className="my-start-btn">Start Speech</button>;
const pauseBtn = <button className="my-pause-btn">Pause Speech</button>;
const stopBtn = <button className="my-stop-btn">Stop Speech</button>;
return <Speech
text='This is a partially customized speech component.'
pitch={1.5}
rate={2}
volume={0.5}
startBtn={startBtn}
pauseBtn={pauseBtn}
stopBtn={stopBtn}
props={{ title: 'React Text-To-Speech Component' }}
onError={() => console.error('Browser not supported!')}
return (
<Speech
text="This is a partially customized speech component."
pitch={1.5}
rate={2}
volume={0.5}
voiceURI="Microsoft Heera - English (India)"
startBtn={startBtn}
pauseBtn={pauseBtn}
stopBtn={stopBtn}
props={{ title: "React Text-To-Speech Component" }}
onError={() => console.error("Browser not supported!")}
/>
);
}
```
#### Full Customization
#### Full Customization
Use Function as Children(FaC) to fully customize the `<Speech>` component.
```jsx
import React from 'react'
import Speech from 'react-text-to-speech'
import React from "react";
import Speech from "react-text-to-speech";
export default function App() {
return <Speech
text='This is a fully customized speech component.'
pitch={1.5}
rate={2}
volume={0.5}
onError={() => console.error('Browser not supported!')}
return (
<Speech
text="This is a fully customized speech component."
pitch={1.5}
rate={2}
volume={0.5}
voiceURI="Microsoft Heera - English (India)"
onError={() => console.error("Browser not supported!")}
>
{({ speechStatus, start, pause, stop }) => (
<YourCustomComponent>
{speechStatus !== 'started' && <button className='my-start-btn' onClick={start}>Start Speech</button>}
{speechStatus === 'started' && <button className='my-pause-btn' onClick={pause}>Pause Speech</button>}
<button className='my-stop-btn' onClick={stop}>Stop Speech</button>
</YourCustomComponent>
)}
{({ speechStatus, start, pause, stop }) => (
<YourCustomComponent>
{speechStatus !== "started" && (
<button className="my-start-btn" onClick={start}>
Start Speech
</button>
)}
{speechStatus === "started" && (
<button className="my-pause-btn" onClick={pause}>
Pause Speech
</button>
)}
<button className="my-stop-btn" onClick={stop}>
Stop Speech
</button>
</YourCustomComponent>
)}
</Speech>
);
}
```
## Speech Component API Reference
Here is the full API for the `<Speech>` component, these properties can be set on an instance of Speech:
| Parameter | Type | Required | Default | Description |
| - | - | - | - | - |
| `text` | `String` | Yes | - | It contains the text to be spoken when `startBtn` is clicked. |
| `pitch` | `Number (0 to 2)` | No | 1 | The pitch at which the utterance will be spoken. |
| `rate` | `Number (0.1 to 10)` | No | 1 | The speed at which the utterance will be spoken. |
| `volume` | `Number (0 to 1)` | No | 1 | The volume at which the utterance will be spoken. |
| `lang` | `String` | No | - | The language in which the utterance will be spoken. |
| `text` | `string` | Yes | - | It contains the text to be spoken when `startBtn` is clicked. |
| `pitch` | `number (0 to 2)` | No | 1 | The pitch at which the utterance will be spoken. |
| `rate` | `number (0.1 to 10)` | No | 1 | The speed at which the utterance will be spoken. |
| `volume` | `number (0 to 1)` | No | 1 | The volume at which the utterance will be spoken. |
| `lang` | `string` | No | - | The language in which the utterance will be spoken. |
| `voiceURI` | `string \| string[]` | No | - | The voice using which the utterance will be spoken. If provided an array, further voices will be used as fallback if initial voices are not found. See possible values [here](https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesis/getVoices). |
| `startBtn` | [`Button`](#button) | No | `<HiVolumeUp />` | Button to start the speech instance. |

@@ -128,15 +170,31 @@ | `pauseBtn` | [`Button`](#button) | No | `<HiVolumeOff />` | Button to pause the speech instance. |

| `children` | [`Children`](#children) | No | - | See [usage with FaC](#full-customization) |
### Types
#### Button
```typescript
type Button = JSX.Element | string | null
type Button = JSX.Element | string | null;
```
#### Children
```typescript
import { ReactNode } from 'react';
type SpeechStatus = 'started' | 'paused' | 'stopped'
type ChildrenOptions = { speechStatus?: SpeechStatus, start?: Function, pause?: Function, stop?: Function }
type Children = (childrenOptions: ChildrenOptions) => ReactNode
import { ReactNode } from "react";
type SpeechStatus = "started" | "paused" | "stopped";
type ChildrenOptions = {
speechStatus?: SpeechStatus;
start?: Function;
pause?: Function;
stop?: Function;
};
type Children = (childrenOptions: ChildrenOptions) => ReactNode;
```
## Author
[Sahil Aggarwal](https://www.github.com/SahilAggarwal2004)
[Sahil Aggarwal](https://www.github.com/SahilAggarwal2004)
### Contributors
- [Akshay Srivastava](https://github.com/akshaypx)
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc