├── stencil.config.js ├── .editorconfig ├── .gitignore ├── src ├── index.html ├── components │ └── wc-voice2text │ │ ├── wc-voice2text.css │ │ └── wc-voice2text.tsx └── components.d.ts ├── tsconfig.json ├── LICENSE ├── package.json └── README.md /stencil.config.js: -------------------------------------------------------------------------------- 1 | exports.config = { 2 | namespace: 'voice2text', 3 | bundles: [ 4 | { components: ['wc-voice2text'] } 5 | ], 6 | outputTargets: [ 7 | { type: 'www' }, 8 | { type: 'dist' } 9 | ] 10 | }; -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | charset = utf-8 7 | indent_style = space 8 | indent_size = 2 9 | end_of_line = lf 10 | insert_final_newline = true 11 | trim_trailing_whitespace = true 12 | 13 | [*.md] 14 | insert_final_newline = false 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | 3 | *~ 4 | *.sw[mnpcod] 5 | *.log 6 | *.lock 7 | *.tmp 8 | *.tmp.* 9 | log.txt 10 | *.sublime-project 11 | *.sublime-workspace 12 | 13 | .idea/ 14 | .stencil/ 15 | .vscode/ 16 | .sass-cache/ 17 | .versions/ 18 | www/ 19 | node_modules/ 20 | $RECYCLE.BIN/ 21 | 22 | .DS_Store 23 | Thumbs.db 24 | UserInterfaceState.xcuserstate 25 | .env 26 | -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Voice 2 Text 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowSyntheticDefaultImports": true, 4 | "allowUnreachableCode": false, 5 | "declaration": false, 6 | "experimentalDecorators": true, 7 | "lib": [ 8 | "dom", 9 | "es2015" 10 | ], 11 | "moduleResolution": "node", 12 | "module": "es2015", 13 | "target": "es2015", 14 | "noUnusedLocals": true, 15 | "noUnusedParameters": true, 16 | "jsx": "react", 17 | "jsxFactory": "h" 18 | }, 19 | "include": [ 20 | "src", 21 | "types/jsx.d.ts" 22 | ], 23 | "exclude": [ 24 | "node_modules" 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Fernando del olmo 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/components/wc-voice2text/wc-voice2text.css: -------------------------------------------------------------------------------- 1 | st-voice2text { 2 | position: relative; 3 | } 4 | .voice2text-start, .voice2text-stop { 5 | position: absolute; 6 | border: none; 7 | margin: 0; 8 | background: transparent; 9 | padding: 0; 10 | display: none; 11 | top: 0; 12 | right: 0; 13 | } 14 | .voice2text-enabled.voice2text-recording > .voice2text-stop { 15 | display: block; 16 | } 17 | .voice2text-enabled:not(.voice2text-recording) > .voice2text-start { 18 | display: block; 19 | } 20 | .voice2text-start { 21 | height: 24px; 22 | width: 24px; 23 | background: url("data:image/svg+xml; utf8,") no-repeat; 24 | } 25 | .voice2text-stop { 26 | height: 24px; 27 | width: 24px; 28 | background: url("data:image/svg+xml; utf8,") no-repeat; 29 | } 30 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "stencil-voice2text", 3 | "version": "1.0.0", 4 | "description": "Voice 2 text component built with Stencil", 5 | "main": "dist/voice2text.js", 6 | "types": "dist/types/components.d.ts", 7 | "collection": "dist/collection/collection-manifest.json", 8 | "files": [ 9 | "dist/" 10 | ], 11 | "browser": "dist/voice2text.js", 12 | "scripts": { 13 | "build": "stencil build", 14 | "dev": "sd concurrent \"stencil build --dev --watch\" \"stencil-dev-server\" ", 15 | "serve": "stencil-dev-server", 16 | "start": "npm run dev", 17 | "test": "jest --no-cache", 18 | "test.watch": "jest --watch --no-cache" 19 | }, 20 | "dependencies": { 21 | "@stencil/core": "0.11.4", 22 | "@types/webspeechapi": "0.0.28" 23 | }, 24 | "devDependencies": { 25 | "@stencil/dev-server": "0.0.17", 26 | "@stencil/utils": "0.0.4" 27 | }, 28 | "repository": { 29 | "type": "git", 30 | "url": "git+https://github.com/Fdom92/stencil-voice2text.git" 31 | }, 32 | "author": "Fernando del olmo martin", 33 | "license": "MIT", 34 | "bugs": { 35 | "url": "https://github.com/Fdom92/stencil-voice2text" 36 | }, 37 | "homepage": "https://github.com/Fdom92/stencil-voice2text", 38 | "jest": { 39 | "transform": { 40 | "^.+\\.(ts|tsx)$": "/node_modules/@stencil/core/testing/jest.preprocessor.js" 41 | }, 42 | "testRegex": "(/__tests__/.*|\\.(test|spec))\\.(tsx?|jsx?)$", 43 | "moduleFileExtensions": [ 44 | "ts", 45 | "tsx", 46 | "js", 47 | "json", 48 | "jsx" 49 | ] 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/components.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This is an autogenerated file created by the Stencil compiler. 3 | * It contains typing information for all components that exist in this project. 4 | */ 5 | /* tslint:disable */ 6 | 7 | import '@stencil/core'; 8 | 9 | 10 | 11 | 12 | declare global { 13 | interface HTMLElement { 14 | componentOnReady?: () => Promise; 15 | } 16 | 17 | interface HTMLStencilElement extends HTMLElement { 18 | componentOnReady(): Promise; 19 | 20 | forceUpdate(): void; 21 | } 22 | 23 | interface HTMLAttributes {} 24 | 25 | namespace StencilComponents { 26 | 27 | interface WcVoice2text { 28 | 'continuous': boolean; 29 | 'enabled': boolean; 30 | 'lang': string; 31 | } 32 | } 33 | 34 | 35 | interface HTMLWcVoice2textElement extends StencilComponents.WcVoice2text, HTMLStencilElement {} 36 | 37 | var HTMLWcVoice2textElement: { 38 | prototype: HTMLWcVoice2textElement; 39 | new (): HTMLWcVoice2textElement; 40 | }; 41 | 42 | 43 | namespace JSX { 44 | interface Element {} 45 | export interface IntrinsicElements { 46 | 'wc-voice2text': JSXElements.WcVoice2textAttributes; 47 | } 48 | } 49 | 50 | namespace JSXElements { 51 | 52 | export interface WcVoice2textAttributes extends HTMLAttributes { 53 | 'continuous'?: boolean; 54 | 'enabled'?: boolean; 55 | 'lang'?: string; 56 | } 57 | } 58 | 59 | interface HTMLElementTagNameMap { 60 | 'wc-voice2text': HTMLWcVoice2textElement 61 | } 62 | 63 | interface ElementTagNameMap { 64 | 'wc-voice2text': HTMLWcVoice2textElement; 65 | } 66 | } 67 | declare global { namespace JSX { interface StencilJSX {} } } 68 | 69 | export declare function defineCustomElements(window: any): void; -------------------------------------------------------------------------------- /src/components/wc-voice2text/wc-voice2text.tsx: -------------------------------------------------------------------------------- 1 | import { Component, State, Prop, Element } from '@stencil/core'; 2 | 3 | @Component({ 4 | tag: 'wc-voice2text', 5 | styleUrl: 'wc-voice2text.css' 6 | }) 7 | export class WCVoice2Text { 8 | 9 | @Element() element; 10 | 11 | @State() recording = false; 12 | @State() recognition: any = null; 13 | 14 | @Prop() enabled = true; 15 | @Prop() lang = 'en-US'; 16 | @Prop() continuous = false; 17 | 18 | input: HTMLInputElement; 19 | 20 | componentDidLoad() { 21 | if ('webkitSpeechRecognition' in window) { 22 | this.input = this.element.querySelector('input[type=text]'); 23 | this.recognition = new webkitSpeechRecognition(); 24 | this.recognition.continuous = this.continuous; 25 | this.recognition.interimResults = true; 26 | this.recognition.lang = this.lang; 27 | 28 | this.recognition.onerror = (err) => { 29 | console.error(err); 30 | this.recording = false; 31 | }; 32 | this.recognition.onresult = (event) => { 33 | this.input.value = event.results[0][0].transcript; 34 | }; 35 | } 36 | } 37 | 38 | start() { 39 | this.recording = true; 40 | this.recognition.start(); 41 | } 42 | 43 | stop() { 44 | this.recording = false; 45 | this.recognition.stop(); 46 | } 47 | 48 | hostData() { 49 | return { 50 | class: { 51 | 'voice2text-enabled': this.recognition !== null && this.enabled, 52 | 'voice2text-recording': this.recording 53 | } 54 | }; 55 | } 56 | 57 | render() { 58 | const dom = []; 59 | if (this.recognition) { 60 | dom.push( 61 | , 63 | 65 | ); 66 | } 67 | return dom; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Built With Stencil](https://img.shields.io/badge/-Built%20With%20Stencil-16161d.svg?logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDE5LjIuMSwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCA1MTIgNTEyIiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCA1MTIgNTEyOyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI%2BCjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI%2BCgkuc3Qwe2ZpbGw6I0ZGRkZGRjt9Cjwvc3R5bGU%2BCjxwYXRoIGNsYXNzPSJzdDAiIGQ9Ik00MjQuNywzNzMuOWMwLDM3LjYtNTUuMSw2OC42LTkyLjcsNjguNkgxODAuNGMtMzcuOSwwLTkyLjctMzAuNy05Mi43LTY4LjZ2LTMuNmgzMzYuOVYzNzMuOXoiLz4KPHBhdGggY2xhc3M9InN0MCIgZD0iTTQyNC43LDI5Mi4xSDE4MC40Yy0zNy42LDAtOTIuNy0zMS05Mi43LTY4LjZ2LTMuNkgzMzJjMzcuNiwwLDkyLjcsMzEsOTIuNyw2OC42VjI5Mi4xeiIvPgo8cGF0aCBjbGFzcz0ic3QwIiBkPSJNNDI0LjcsMTQxLjdIODcuN3YtMy42YzAtMzcuNiw1NC44LTY4LjYsOTIuNy02OC42SDMzMmMzNy45LDAsOTIuNywzMC43LDkyLjcsNjguNlYxNDEuN3oiLz4KPC9zdmc%2BCg%3D%3D&colorA=16161d&style=flat-square) 2 | 3 | # stencil-voice2text 4 | 5 | wc-voice2text is a web component built with [Stencil](https://stenciljs.com/) that allows you to use the [Web Speech API](https://developers.google.com/web/updates/2013/01/Voice-Driven-Web-Apps-Introduction-to-the-Web-Speech-API). 6 | 7 | ## Getting Started 8 | 9 | To try this component: 10 | 11 | ```bash 12 | git clone git@github.com:Fdom92/stencil-voice2text.git 13 | cd my-app 14 | git remote rm origin 15 | ``` 16 | 17 | and run: 18 | 19 | ```bash 20 | npm install 21 | npm start 22 | ``` 23 | 24 | ## Using this component 25 | 26 | ### Script tag 27 | 28 | - Put `` in the head of your index.html 29 | - Then you can use the element like this: 30 | ```html 31 | 32 | 33 | 34 | ``` 35 | 36 | ### Node Modules 37 | - Run `npm install stencil-voice2text --save` 38 | - Put a script tag similar to this `