dictate-button 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,4 +1,5 @@
1
1
  # Dictate Button (Web Component)
2
+ ![NPM Version](https://img.shields.io/npm/v/dictate-button)
2
3
 
3
4
  A customizable web component that adds speech-to-text dictation capabilities to any text input or textarea field on your website.
4
5
 
@@ -8,7 +9,7 @@ Developed for [dictate-button.io](https://dictate-button.io).
8
9
 
9
10
  - Easy integration with any website
10
11
  - Compatible with any framework (or no framework)
11
- - Automatic injection into any textarea or text input with the `data-dictate-button-target` attribute
12
+ - Automatic injection into any textarea or text input with the `data-dictate-button-on` attribute (exclusive mode) or without the `data-dictate-button-off` attribute (inclusive mode)
12
13
  - Simple speech-to-text functionality with clean UI
13
14
  - Customizable size and API endpoint
14
15
  - Dark and light theme support
@@ -17,32 +18,59 @@ Developed for [dictate-button.io](https://dictate-button.io).
17
18
 
18
19
  ## Usage
19
20
 
21
+ ### Auto-inject modes
22
+
23
+ Choose the auto-inject mode that best suits your needs:
24
+
25
+ | Mode | Description | Scripts |
26
+ |---|---|---|
27
+ | Exclusive | Automatically injects the dictate button into any textarea or text input **with the `data-dictate-button-on` attribute**. | `inject-exclusive.es.js`, `inject-exclusive.cjs.js` |
28
+ | Inclusive | Automatically injects the dictate button into any textarea or text input **without the `data-dictate-button-off` attribute**. | `inject-inclusive.es.js`, `inject-inclusive.cjs.js` |
29
+
20
30
  ### From CDN
21
31
 
22
- #### Option 1: Using the auto-inject script
32
+ #### Option 1: Using the exclusive auto-inject script
23
33
 
24
- Include the inject script in your HTML:
34
+ In your HTML `<head>` tag, add the following script tags:
25
35
 
26
36
  ```html
27
37
  <script type="module" crossorigin src="https://cdn.dictate-button.io/dictate-button.es.js"></script>
28
- <script type="module" crossorigin src="https://cdn.dictate-button.io/inject.es.js"></script>
38
+ <script type="module" crossorigin src="https://cdn.dictate-button.io/inject-exclusive.es.js"></script>
29
39
  ```
30
40
 
31
- Add the `data-dictate-button-target` attribute to any textarea or text input where you want the dictate button to appear:
41
+ Add the `data-dictate-button-on` attribute to any `textarea` or `input[type=text]` elements where you want the dictate button to appear:
32
42
 
33
43
  ```html
34
- <textarea data-dictate-button-target></textarea>
35
- <input type="text" data-dictate-button-target />
44
+ <textarea data-dictate-button-on></textarea>
45
+ <input type="text" data-dictate-button-on />
36
46
  ```
37
47
 
38
- #### Option 2: Manual integration
48
+ #### Option 2: Using the inclusive auto-inject script
49
+
50
+ In your HTML `<head>` tag, add the following script tags:
51
+
52
+ ```html
53
+ <script type="module" crossorigin src="https://cdn.dictate-button.io/dictate-button.es.js"></script>
54
+ <script type="module" crossorigin src="https://cdn.dictate-button.io/inject-inclusive.es.js"></script>
55
+ ```
56
+
57
+ All `textarea` and `input[type=text]` elements without the `data-dictate-button-off` attribute will be automatically enhanced with the dictate button by default.
58
+
59
+ To disable that for a specific field, add the `data-dictate-button-off` attribute to it this way:
60
+
61
+ ```html
62
+ <textarea data-dictate-button-off></textarea>
63
+ <input type="text" data-dictate-button-off />
64
+ ```
65
+
66
+ #### Option 3: Manual integration
39
67
 
40
68
  Import the component and use it directly in your code:
41
69
 
42
70
  ```html
43
71
  <script type="module" crossorigin src="https://cdn.dictate-button.io/dictate-button.es.js"></script>
44
72
 
45
- <dictate-button size="24" api-endpoint="https://api.dictate-button.io/transcribe"></dictate-button>
73
+ <dictate-button size="24" api-endpoint="https://api.dictate-button.io/transcribe" language="en"></dictate-button>
46
74
  ```
47
75
 
48
76
  ### From NPM
@@ -58,9 +86,13 @@ import 'dictate-button'
58
86
  The auto-inject script:
59
87
 
60
88
  ```js
61
- import 'dictate-button/inject'
89
+ import 'dictate-button/inject-exclusive'
90
+ // or
91
+ import 'dictate-button/inject-inclusive'
62
92
  ```
63
93
 
94
+ To choose between **exclusive** and **inclusive** auto-inject modes, see the [Auto-inject modes](#auto-inject-modes) section.
95
+
64
96
  ## Events
65
97
 
66
98
  The dictate-button component emits the following events:
@@ -92,6 +124,7 @@ dictateButton.addEventListener('transcribing:finished', (event) => {
92
124
  |---------------|---------|-----------------------------------------|----------------------------------------|
93
125
  | size | number | 24 | Size of the button in pixels |
94
126
  | apiEndpoint | string | https://api.dictate-button.io/transcribe| API endpoint for transcription service |
127
+ | language | string | (not set) | Optional language code (e.g., 'en', 'fr', 'de') which may speed up the transcription. |
95
128
  | theme | string | (inherits from page) | 'light' or 'dark' |
96
129
  | class | string | | Custom CSS class |
97
130
 
@@ -118,11 +151,15 @@ dictate-button::part(icon) {
118
151
 
119
152
  ## API Endpoint
120
153
 
121
- By default, dictate-button uses the `https://api.dictate-button.io/transcribe` endpoint for speech-to-text conversion. You can specify your own endpoint by setting the `apiEndpoint` attribute.
154
+ By default, dictate-button uses the `https://api.dictate-button.io/transcribe` endpoint for speech-to-text conversion.
155
+ You can specify your own endpoint by setting the `apiEndpoint` attribute.
122
156
 
123
157
  The API expects:
124
158
  - POST request
125
- - Audio data as a Blob (audio/webm format)
159
+ - Multipart form data with the following fields:
160
+ - `audio`: Audio data as a Blob (audio/webm format)
161
+ - `origin`: The origin of the website (automatically added)
162
+ - `language`: Optional language code (if provided as an attribute)
126
163
  - Response should be JSON with a `text` property containing the transcribed text
127
164
 
128
165
  ## Browser Compatibility
package/dist/404.html CHANGED
@@ -4,14 +4,14 @@
4
4
  <head>
5
5
  <meta charset="UTF-8">
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
- <title>Dictate Button Web Component</title>
7
+ <title>Dictate Button CDN</title>
8
8
  </head>
9
9
 
10
10
  <body
11
11
  style="display: flex; flex-direction: column; justify-content: center; align-items: center; gap: 1rem; height: 100vh;">
12
- </body>
13
- <h1>404 - Not Found</h1>
14
- <p>Check the correct url on <a href="https://dictate-button.io">dictate-button.io</a></p>
12
+ <h1>404 - Not Found</h1>
13
+ <p>Check the correct url in the docs <a href="https://github.com/kkomelin/dictate-button">kkomelin/dictate-button</a>
14
+ </p>
15
15
  </body>
16
16
 
17
17
  </html>
@@ -1,4 +1,4 @@
1
- "use strict";const st=(t,e)=>t===e,T={equals:st};let rt=Q;const w=1,O=2,q={owned:null,cleanups:null,context:null,owner:null};var b=null;let R=null,it=null,f=null,p=null,_=null,M=0;function ot(t,e){const n=f,r=b,s=t.length===0,i=e===void 0?r:e,l=s?q:{owned:null,cleanups:null,context:i?i.context:null,owner:i},o=s?t:()=>t(()=>L(()=>E(l)));b=l,f=null;try{return A(o,!0)}finally{f=n,b=r}}function z(t,e){e=e?Object.assign({},T,e):T;const n={value:t,observers:null,observerSlots:null,comparator:e.equals||void 0},r=s=>(typeof s=="function"&&(s=s(n.value)),H(n,s));return[G.bind(n),r]}function P(t,e,n){const r=Z(t,e,!1,w);B(r)}function lt(t,e,n){n=n?Object.assign({},T,n):T;const r=Z(t,e,!0,0);return r.observers=null,r.observerSlots=null,r.comparator=n.equals||void 0,B(r),G.bind(r)}function L(t){if(f===null)return t();const e=f;f=null;try{return t()}finally{f=e}}function G(){if(this.sources&&this.state)if(this.state===w)B(this);else{const t=p;p=null,A(()=>j(this),!1),p=t}if(f){const t=this.observers?this.observers.length:0;f.sources?(f.sources.push(this),f.sourceSlots.push(t)):(f.sources=[this],f.sourceSlots=[t]),this.observers?(this.observers.push(f),this.observerSlots.push(f.sources.length-1)):(this.observers=[f],this.observerSlots=[f.sources.length-1])}return this.value}function H(t,e,n){let r=t.value;return(!t.comparator||!t.comparator(r,e))&&(t.value=e,t.observers&&t.observers.length&&A(()=>{for(let s=0;s<t.observers.length;s+=1){const i=t.observers[s],l=R&&R.running;l&&R.disposed.has(i),(l?!i.tState:!i.state)&&(i.pure?p.push(i):_.push(i),i.observers&&W(i)),l||(i.state=w)}if(p.length>1e6)throw p=[],new Error},!1)),e}function B(t){if(!t.fn)return;E(t);const e=M;ct(t,t.value,e)}function ct(t,e,n){let r;const s=b,i=f;f=b=t;try{r=t.fn(e)}catch(l){return t.pure&&(t.state=w,t.owned&&t.owned.forEach(E),t.owned=null),t.updatedAt=n+1,X(l)}finally{f=i,b=s}(!t.updatedAt||t.updatedAt<=n)&&(t.updatedAt!=null&&"observers"in t?H(t,r):t.value=r,t.updatedAt=n)}function Z(t,e,n,r=w,s){const i={fn:t,state:r,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:e,owner:b,context:b?b.context:null,pure:n};return b===null||b!==q&&(b.owned?b.owned.push(i):b.owned=[i]),i}function J(t){if(t.state===0)return;if(t.state===O)return j(t);if(t.suspense&&L(t.suspense.inFallback))return t.suspense.effects.push(t);const e=[t];for(;(t=t.owner)&&(!t.updatedAt||t.updatedAt<M);)t.state&&e.push(t);for(let n=e.length-1;n>=0;n--)if(t=e[n],t.state===w)B(t);else if(t.state===O){const r=p;p=null,A(()=>j(t,e[0]),!1),p=r}}function A(t,e){if(p)return t();let n=!1;e||(p=[]),_?n=!0:_=[],M++;try{const r=t();return at(n),r}catch(r){n||(_=null),p=null,X(r)}}function at(t){if(p&&(Q(p),p=null),t)return;const e=_;_=null,e.length&&A(()=>rt(e),!1)}function Q(t){for(let e=0;e<t.length;e++)J(t[e])}function j(t,e){t.state=0;for(let n=0;n<t.sources.length;n+=1){const r=t.sources[n];if(r.sources){const s=r.state;s===w?r!==e&&(!r.updatedAt||r.updatedAt<M)&&J(r):s===O&&j(r,e)}}}function W(t){for(let e=0;e<t.observers.length;e+=1){const n=t.observers[e];n.state||(n.state=O,n.pure?p.push(n):_.push(n),n.observers&&W(n))}}function E(t){let e;if(t.sources)for(;t.sources.length;){const n=t.sources.pop(),r=t.sourceSlots.pop(),s=n.observers;if(s&&s.length){const i=s.pop(),l=n.observerSlots.pop();r<s.length&&(i.sourceSlots[l]=r,s[r]=i,n.observerSlots[r]=l)}}if(t.tOwned){for(e=t.tOwned.length-1;e>=0;e--)E(t.tOwned[e]);delete t.tOwned}if(t.owned){for(e=t.owned.length-1;e>=0;e--)E(t.owned[e]);t.owned=null}if(t.cleanups){for(e=t.cleanups.length-1;e>=0;e--)t.cleanups[e]();t.cleanups=null}t.state=0}function ut(t){return t instanceof Error?t:new Error(typeof t=="string"?t:"Unknown error",{cause:t})}function X(t,e=b){throw ut(t)}function x(t,e){return L(()=>t(e||{}))}const $=t=>lt(()=>t());function ft(t,e,n){let r=n.length,s=e.length,i=r,l=0,o=0,c=e[s-1].nextSibling,a=null;for(;l<s||o<i;){if(e[l]===n[o]){l++,o++;continue}for(;e[s-1]===n[i-1];)s--,i--;if(s===l){const u=i<r?o?n[o-1].nextSibling:n[i-o]:c;for(;o<i;)t.insertBefore(n[o++],u)}else if(i===o)for(;l<s;)(!a||!a.has(e[l]))&&e[l].remove(),l++;else if(e[l]===n[i-1]&&n[o]===e[s-1]){const u=e[--s].nextSibling;t.insertBefore(n[o++],e[l++].nextSibling),t.insertBefore(n[--i],u),e[s]=n[i]}else{if(!a){a=new Map;let h=o;for(;h<i;)a.set(n[h],h++)}const u=a.get(e[l]);if(u!=null)if(o<u&&u<i){let h=l,y=1,g;for(;++h<s&&h<i&&!((g=a.get(e[h]))==null||g!==u+y);)y++;if(y>u-o){const d=e[l];for(;o<u;)t.insertBefore(n[o++],d)}else t.replaceChild(n[o++],e[l++])}else l++;else e[l++].remove()}}}const U="_$DX_DELEGATE";function m(t,e,n,r){let s;const i=()=>{const o=document.createElement("template");return o.innerHTML=t,o.content.firstChild},l=()=>(s||(s=i())).cloneNode(!0);return l.cloneNode=l,l}function dt(t,e=window.document){const n=e[U]||(e[U]=new Set);for(let r=0,s=t.length;r<s;r++){const i=t[r];n.has(i)||(n.add(i),e.addEventListener(i,pt))}}function Y(t,e,n){n==null?t.removeAttribute(e):t.setAttribute(e,n)}function ht(t,e,n){if(!e)return n?Y(t,"style"):e;const r=t.style;if(typeof e=="string")return r.cssText=e;typeof n=="string"&&(r.cssText=n=void 0),n||(n={}),e||(e={});let s,i;for(i in n)e[i]==null&&r.removeProperty(i),delete n[i];for(i in e)s=e[i],s!==n[i]&&(r.setProperty(i,s),n[i]=s);return n}function v(t,e,n,r){if(n!==void 0&&!r&&(r=[]),typeof e!="function")return N(t,e,r,n);P(s=>N(t,e(),s,n),r)}function pt(t){let e=t.target;const n=`$$${t.type}`,r=t.target,s=t.currentTarget,i=c=>Object.defineProperty(t,"target",{configurable:!0,value:c}),l=()=>{const c=e[n];if(c&&!e.disabled){const a=e[`${n}Data`];if(a!==void 0?c.call(e,a,t):c.call(e,t),t.cancelBubble)return}return e.host&&typeof e.host!="string"&&!e.host._$host&&e.contains(t.target)&&i(e.host),!0},o=()=>{for(;l()&&(e=e._$host||e.parentNode||e.host););};if(Object.defineProperty(t,"currentTarget",{configurable:!0,get(){return e||document}}),t.composedPath){const c=t.composedPath();i(c[0]);for(let a=0;a<c.length-2&&(e=c[a],!!l());a++){if(e._$host){e=e._$host,o();break}if(e.parentNode===s)break}}else o();i(r)}function N(t,e,n,r,s){for(;typeof n=="function";)n=n();if(e===n)return n;const i=typeof e,l=r!==void 0;if(t=l&&n[0]&&n[0].parentNode||t,i==="string"||i==="number"){if(i==="number"&&(e=e.toString(),e===n))return n;if(l){let o=n[0];o&&o.nodeType===3?o.data!==e&&(o.data=e):o=document.createTextNode(e),n=C(t,n,r,o)}else n!==""&&typeof n=="string"?n=t.firstChild.data=e:n=t.textContent=e}else if(e==null||i==="boolean")n=C(t,n,r);else{if(i==="function")return P(()=>{let o=e();for(;typeof o=="function";)o=o();n=N(t,o,n,r)}),()=>n;if(Array.isArray(e)){const o=[],c=n&&Array.isArray(n);if(F(o,e,n,s))return P(()=>n=N(t,o,n,r,!0)),()=>n;if(o.length===0){if(n=C(t,n,r),l)return n}else c?n.length===0?V(t,o,r):ft(t,n,o):(n&&C(t),V(t,o));n=o}else if(e.nodeType){if(Array.isArray(n)){if(l)return n=C(t,n,r,e);C(t,n,null,e)}else n==null||n===""||!t.firstChild?t.appendChild(e):t.replaceChild(e,t.firstChild);n=e}}return n}function F(t,e,n,r){let s=!1;for(let i=0,l=e.length;i<l;i++){let o=e[i],c=n&&n[t.length],a;if(!(o==null||o===!0||o===!1))if((a=typeof o)=="object"&&o.nodeType)t.push(o);else if(Array.isArray(o))s=F(t,o,c)||s;else if(a==="function")if(r){for(;typeof o=="function";)o=o();s=F(t,Array.isArray(o)?o:[o],Array.isArray(c)?c:[c])||s}else t.push(o),s=!0;else{const u=String(o);c&&c.nodeType===3&&c.data===u?t.push(c):t.push(document.createTextNode(u))}}return s}function V(t,e,n=null){for(let r=0,s=e.length;r<s;r++)t.insertBefore(e[r],n)}function C(t,e,n,r){if(n===void 0)return t.textContent="";const s=r||document.createTextNode("");if(e.length){let i=!1;for(let l=e.length-1;l>=0;l--){const o=e[l];if(s!==o){const c=o.parentNode===t;!i&&!l?c?t.replaceChild(s,o):t.insertBefore(s,n):c&&o.remove()}else i=!0}}else t.insertBefore(s,n);return[s]}function gt(t){return Object.keys(t).reduce((n,r)=>{const s=t[r];return n[r]=Object.assign({},s),et(s.value)&&!Ct(s.value)&&!Array.isArray(s.value)&&(n[r].value=Object.assign({},s.value)),Array.isArray(s.value)&&(n[r].value=s.value.slice(0)),n},{})}function bt(t){return t?Object.keys(t).reduce((n,r)=>{const s=t[r];return n[r]=et(s)&&"value"in s?s:{value:s},n[r].attribute||(n[r].attribute=wt(r)),n[r].parse="parse"in n[r]?n[r].parse:typeof n[r].value!="string",n},{}):{}}function yt(t){return Object.keys(t).reduce((n,r)=>(n[r]=t[r].value,n),{})}function _t(t,e){const n=gt(e);return Object.keys(e).forEach(s=>{const i=n[s],l=t.getAttribute(i.attribute),o=t[s];l!=null&&(i.value=i.parse?tt(l):l),o!=null&&(i.value=Array.isArray(o)?o.slice(0):o),i.reflect&&D(t,i.attribute,i.value,!!i.parse),Object.defineProperty(t,s,{get(){return i.value},set(c){const a=i.value;i.value=c,i.reflect&&D(this,i.attribute,i.value,!!i.parse);for(let u=0,h=this.__propertyChangedCallbacks.length;u<h;u++)this.__propertyChangedCallbacks[u](s,c,a)},enumerable:!0,configurable:!0})}),n}function tt(t){if(t)try{return JSON.parse(t)}catch{return t}}function D(t,e,n,r){if(n==null||n===!1)return t.removeAttribute(e);let s=r?JSON.stringify(n):n;t.__updating[e]=!0,s==="true"&&(s=""),t.setAttribute(e,s),Promise.resolve().then(()=>delete t.__updating[e])}function wt(t){return t.replace(/\.?([A-Z]+)/g,(e,n)=>"-"+n.toLowerCase()).replace("_","-").replace(/^-/,"")}function et(t){return t!=null&&(typeof t=="object"||typeof t=="function")}function Ct(t){return Object.prototype.toString.call(t)==="[object Function]"}function vt(t){return typeof t=="function"&&t.toString().indexOf("class")===0}let I;function St(t,e){const n=Object.keys(e);return class extends t{static get observedAttributes(){return n.map(s=>e[s].attribute)}constructor(){super(),this.__initialized=!1,this.__released=!1,this.__releaseCallbacks=[],this.__propertyChangedCallbacks=[],this.__updating={},this.props={}}connectedCallback(){if(this.__initialized)return;this.__releaseCallbacks=[],this.__propertyChangedCallbacks=[],this.__updating={},this.props=_t(this,e);const s=yt(this.props),i=this.Component,l=I;try{I=this,this.__initialized=!0,vt(i)?new i(s,{element:this}):i(s,{element:this})}finally{I=l}}async disconnectedCallback(){if(await Promise.resolve(),this.isConnected)return;this.__propertyChangedCallbacks.length=0;let s=null;for(;s=this.__releaseCallbacks.pop();)s(this);delete this.__initialized,this.__released=!0}attributeChangedCallback(s,i,l){if(this.__initialized&&!this.__updating[s]&&(s=this.lookupProp(s),s in e)){if(l==null&&!this[s])return;this[s]=e[s].parse?tt(l):l}}lookupProp(s){if(e)return n.find(i=>s===i||s===e[i].attribute)}get renderRoot(){return this.shadowRoot||this.attachShadow({mode:"open"})}addReleaseCallback(s){this.__releaseCallbacks.push(s)}addPropertyChangedCallback(s){this.__propertyChangedCallbacks.push(s)}}}function Et(t,e={},n={}){const{BaseElement:r=HTMLElement,extension:s,customElements:i=window.customElements}=n;return l=>{let o=i.get(t);return o?(o.prototype.Component=l,o):(o=St(r,bt(e)),o.prototype.Component=l,o.prototype.registeredTag=t,i.define(t,o,s),o)}}function At(t){const e=Object.keys(t),n={};for(let r=0;r<e.length;r++){const[s,i]=z(t[e[r]]);Object.defineProperty(n,e[r],{get:s,set(l){i(()=>l)}})}return n}function mt(t){if(t.assignedSlot&&t.assignedSlot._$owner)return t.assignedSlot._$owner;let e=t.parentNode;for(;e&&!e._$owner&&!(e.assignedSlot&&e.assignedSlot._$owner);)e=e.parentNode;return e&&e.assignedSlot?e.assignedSlot._$owner:t._$owner}function xt(t){return(e,n)=>{const{element:r}=n;return ot(s=>{const i=At(e);r.addPropertyChangedCallback((o,c)=>i[o]=c),r.addReleaseCallback(()=>{r.renderRoot.textContent="",s()});const l=t(i,n);return v(r.renderRoot,l)},mt(r))}}function $t(t,e,n){return arguments.length===2&&(n=e,e={}),Et(t,e)(xt(n))}const kt=`
1
+ "use strict";const rt=(t,e)=>t===e,O={equals:rt};let it=X;const C=1,P=2,G={owned:null,cleanups:null,context:null,owner:null};var g=null;let F=null,ot=null,u=null,p=null,w=null,M=0;function lt(t,e){const n=u,r=g,s=t.length===0,i=e===void 0?r:e,l=s?G:{owned:null,cleanups:null,context:i?i.context:null,owner:i},o=s?t:()=>t(()=>U(()=>A(l)));g=l,u=null;try{return m(o,!0)}finally{u=n,g=r}}function H(t,e){e=e?Object.assign({},O,e):O;const n={value:t,observers:null,observerSlots:null,comparator:e.equals||void 0},r=s=>(typeof s=="function"&&(s=s(n.value)),J(n,s));return[Z.bind(n),r]}function j(t,e,n){const r=Q(t,e,!1,C);R(r)}function ct(t,e,n){n=n?Object.assign({},O,n):O;const r=Q(t,e,!0,0);return r.observers=null,r.observerSlots=null,r.comparator=n.equals||void 0,R(r),Z.bind(r)}function U(t){if(u===null)return t();const e=u;u=null;try{return t()}finally{u=e}}function Z(){if(this.sources&&this.state)if(this.state===C)R(this);else{const t=p;p=null,m(()=>N(this),!1),p=t}if(u){const t=this.observers?this.observers.length:0;u.sources?(u.sources.push(this),u.sourceSlots.push(t)):(u.sources=[this],u.sourceSlots=[t]),this.observers?(this.observers.push(u),this.observerSlots.push(u.sources.length-1)):(this.observers=[u],this.observerSlots=[u.sources.length-1])}return this.value}function J(t,e,n){let r=t.value;return(!t.comparator||!t.comparator(r,e))&&(t.value=e,t.observers&&t.observers.length&&m(()=>{for(let s=0;s<t.observers.length;s+=1){const i=t.observers[s],l=F&&F.running;l&&F.disposed.has(i),(l?!i.tState:!i.state)&&(i.pure?p.push(i):w.push(i),i.observers&&Y(i)),l||(i.state=C)}if(p.length>1e6)throw p=[],new Error},!1)),e}function R(t){if(!t.fn)return;A(t);const e=M;at(t,t.value,e)}function at(t,e,n){let r;const s=g,i=u;u=g=t;try{r=t.fn(e)}catch(l){return t.pure&&(t.state=C,t.owned&&t.owned.forEach(A),t.owned=null),t.updatedAt=n+1,tt(l)}finally{u=i,g=s}(!t.updatedAt||t.updatedAt<=n)&&(t.updatedAt!=null&&"observers"in t?J(t,r):t.value=r,t.updatedAt=n)}function Q(t,e,n,r=C,s){const i={fn:t,state:r,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:e,owner:g,context:g?g.context:null,pure:n};return g===null||g!==G&&(g.owned?g.owned.push(i):g.owned=[i]),i}function W(t){if(t.state===0)return;if(t.state===P)return N(t);if(t.suspense&&U(t.suspense.inFallback))return t.suspense.effects.push(t);const e=[t];for(;(t=t.owner)&&(!t.updatedAt||t.updatedAt<M);)t.state&&e.push(t);for(let n=e.length-1;n>=0;n--)if(t=e[n],t.state===C)R(t);else if(t.state===P){const r=p;p=null,m(()=>N(t,e[0]),!1),p=r}}function m(t,e){if(p)return t();let n=!1;e||(p=[]),w?n=!0:w=[],M++;try{const r=t();return ut(n),r}catch(r){n||(w=null),p=null,tt(r)}}function ut(t){if(p&&(X(p),p=null),t)return;const e=w;w=null,e.length&&m(()=>it(e),!1)}function X(t){for(let e=0;e<t.length;e++)W(t[e])}function N(t,e){t.state=0;for(let n=0;n<t.sources.length;n+=1){const r=t.sources[n];if(r.sources){const s=r.state;s===C?r!==e&&(!r.updatedAt||r.updatedAt<M)&&W(r):s===P&&N(r,e)}}}function Y(t){for(let e=0;e<t.observers.length;e+=1){const n=t.observers[e];n.state||(n.state=P,n.pure?p.push(n):w.push(n),n.observers&&Y(n))}}function A(t){let e;if(t.sources)for(;t.sources.length;){const n=t.sources.pop(),r=t.sourceSlots.pop(),s=n.observers;if(s&&s.length){const i=s.pop(),l=n.observerSlots.pop();r<s.length&&(i.sourceSlots[l]=r,s[r]=i,n.observerSlots[r]=l)}}if(t.tOwned){for(e=t.tOwned.length-1;e>=0;e--)A(t.tOwned[e]);delete t.tOwned}if(t.owned){for(e=t.owned.length-1;e>=0;e--)A(t.owned[e]);t.owned=null}if(t.cleanups){for(e=t.cleanups.length-1;e>=0;e--)t.cleanups[e]();t.cleanups=null}t.state=0}function ft(t){return t instanceof Error?t:new Error(typeof t=="string"?t:"Unknown error",{cause:t})}function tt(t,e=g){throw ft(t)}function $(t,e){return U(()=>t(e||{}))}const k=t=>ct(()=>t());function dt(t,e,n){let r=n.length,s=e.length,i=r,l=0,o=0,c=e[s-1].nextSibling,a=null;for(;l<s||o<i;){if(e[l]===n[o]){l++,o++;continue}for(;e[s-1]===n[i-1];)s--,i--;if(s===l){const f=i<r?o?n[o-1].nextSibling:n[i-o]:c;for(;o<i;)t.insertBefore(n[o++],f)}else if(i===o)for(;l<s;)(!a||!a.has(e[l]))&&e[l].remove(),l++;else if(e[l]===n[i-1]&&n[o]===e[s-1]){const f=e[--s].nextSibling;t.insertBefore(n[o++],e[l++].nextSibling),t.insertBefore(n[--i],f),e[s]=n[i]}else{if(!a){a=new Map;let b=o;for(;b<i;)a.set(n[b],b++)}const f=a.get(e[l]);if(f!=null)if(o<f&&f<i){let b=l,y=1,_;for(;++b<s&&b<i&&!((_=a.get(e[b]))==null||_!==f+y);)y++;if(y>f-o){const d=e[l];for(;o<f;)t.insertBefore(n[o++],d)}else t.replaceChild(n[o++],e[l++])}else l++;else e[l++].remove()}}}const D="_$DX_DELEGATE";function x(t,e,n,r){let s;const i=()=>{const o=document.createElement("template");return o.innerHTML=t,o.content.firstChild},l=()=>(s||(s=i())).cloneNode(!0);return l.cloneNode=l,l}function ht(t,e=window.document){const n=e[D]||(e[D]=new Set);for(let r=0,s=t.length;r<s;r++){const i=t[r];n.has(i)||(n.add(i),e.addEventListener(i,gt))}}function et(t,e,n){n==null?t.removeAttribute(e):t.setAttribute(e,n)}function pt(t,e,n){if(!e)return n?et(t,"style"):e;const r=t.style;if(typeof e=="string")return r.cssText=e;typeof n=="string"&&(r.cssText=n=void 0),n||(n={}),e||(e={});let s,i;for(i in n)e[i]==null&&r.removeProperty(i),delete n[i];for(i in e)s=e[i],s!==n[i]&&(r.setProperty(i,s),n[i]=s);return n}function E(t,e,n,r){if(n!==void 0&&!r&&(r=[]),typeof e!="function")return B(t,e,r,n);j(s=>B(t,e(),s,n),r)}function gt(t){let e=t.target;const n=`$$${t.type}`,r=t.target,s=t.currentTarget,i=c=>Object.defineProperty(t,"target",{configurable:!0,value:c}),l=()=>{const c=e[n];if(c&&!e.disabled){const a=e[`${n}Data`];if(a!==void 0?c.call(e,a,t):c.call(e,t),t.cancelBubble)return}return e.host&&typeof e.host!="string"&&!e.host._$host&&e.contains(t.target)&&i(e.host),!0},o=()=>{for(;l()&&(e=e._$host||e.parentNode||e.host););};if(Object.defineProperty(t,"currentTarget",{configurable:!0,get(){return e||document}}),t.composedPath){const c=t.composedPath();i(c[0]);for(let a=0;a<c.length-2&&(e=c[a],!!l());a++){if(e._$host){e=e._$host,o();break}if(e.parentNode===s)break}}else o();i(r)}function B(t,e,n,r,s){for(;typeof n=="function";)n=n();if(e===n)return n;const i=typeof e,l=r!==void 0;if(t=l&&n[0]&&n[0].parentNode||t,i==="string"||i==="number"){if(i==="number"&&(e=e.toString(),e===n))return n;if(l){let o=n[0];o&&o.nodeType===3?o.data!==e&&(o.data=e):o=document.createTextNode(e),n=v(t,n,r,o)}else n!==""&&typeof n=="string"?n=t.firstChild.data=e:n=t.textContent=e}else if(e==null||i==="boolean")n=v(t,n,r);else{if(i==="function")return j(()=>{let o=e();for(;typeof o=="function";)o=o();n=B(t,o,n,r)}),()=>n;if(Array.isArray(e)){const o=[],c=n&&Array.isArray(n);if(K(o,e,n,s))return j(()=>n=B(t,o,n,r,!0)),()=>n;if(o.length===0){if(n=v(t,n,r),l)return n}else c?n.length===0?q(t,o,r):dt(t,n,o):(n&&v(t),q(t,o));n=o}else if(e.nodeType){if(Array.isArray(n)){if(l)return n=v(t,n,r,e);v(t,n,null,e)}else n==null||n===""||!t.firstChild?t.appendChild(e):t.replaceChild(e,t.firstChild);n=e}}return n}function K(t,e,n,r){let s=!1;for(let i=0,l=e.length;i<l;i++){let o=e[i],c=n&&n[t.length],a;if(!(o==null||o===!0||o===!1))if((a=typeof o)=="object"&&o.nodeType)t.push(o);else if(Array.isArray(o))s=K(t,o,c)||s;else if(a==="function")if(r){for(;typeof o=="function";)o=o();s=K(t,Array.isArray(o)?o:[o],Array.isArray(c)?c:[c])||s}else t.push(o),s=!0;else{const f=String(o);c&&c.nodeType===3&&c.data===f?t.push(c):t.push(document.createTextNode(f))}}return s}function q(t,e,n=null){for(let r=0,s=e.length;r<s;r++)t.insertBefore(e[r],n)}function v(t,e,n,r){if(n===void 0)return t.textContent="";const s=r||document.createTextNode("");if(e.length){let i=!1;for(let l=e.length-1;l>=0;l--){const o=e[l];if(s!==o){const c=o.parentNode===t;!i&&!l?c?t.replaceChild(s,o):t.insertBefore(s,n):c&&o.remove()}else i=!0}}else t.insertBefore(s,n);return[s]}function bt(t){return Object.keys(t).reduce((n,r)=>{const s=t[r];return n[r]=Object.assign({},s),st(s.value)&&!vt(s.value)&&!Array.isArray(s.value)&&(n[r].value=Object.assign({},s.value)),Array.isArray(s.value)&&(n[r].value=s.value.slice(0)),n},{})}function yt(t){return t?Object.keys(t).reduce((n,r)=>{const s=t[r];return n[r]=st(s)&&"value"in s?s:{value:s},n[r].attribute||(n[r].attribute=Ct(r)),n[r].parse="parse"in n[r]?n[r].parse:typeof n[r].value!="string",n},{}):{}}function _t(t){return Object.keys(t).reduce((n,r)=>(n[r]=t[r].value,n),{})}function wt(t,e){const n=bt(e);return Object.keys(e).forEach(s=>{const i=n[s],l=t.getAttribute(i.attribute),o=t[s];l!=null&&(i.value=i.parse?nt(l):l),o!=null&&(i.value=Array.isArray(o)?o.slice(0):o),i.reflect&&z(t,i.attribute,i.value,!!i.parse),Object.defineProperty(t,s,{get(){return i.value},set(c){const a=i.value;i.value=c,i.reflect&&z(this,i.attribute,i.value,!!i.parse);for(let f=0,b=this.__propertyChangedCallbacks.length;f<b;f++)this.__propertyChangedCallbacks[f](s,c,a)},enumerable:!0,configurable:!0})}),n}function nt(t){if(t)try{return JSON.parse(t)}catch{return t}}function z(t,e,n,r){if(n==null||n===!1)return t.removeAttribute(e);let s=r?JSON.stringify(n):n;t.__updating[e]=!0,s==="true"&&(s=""),t.setAttribute(e,s),Promise.resolve().then(()=>delete t.__updating[e])}function Ct(t){return t.replace(/\.?([A-Z]+)/g,(e,n)=>"-"+n.toLowerCase()).replace("_","-").replace(/^-/,"")}function st(t){return t!=null&&(typeof t=="object"||typeof t=="function")}function vt(t){return Object.prototype.toString.call(t)==="[object Function]"}function St(t){return typeof t=="function"&&t.toString().indexOf("class")===0}let L;function Et(t,e){const n=Object.keys(e);return class extends t{static get observedAttributes(){return n.map(s=>e[s].attribute)}constructor(){super(),this.__initialized=!1,this.__released=!1,this.__releaseCallbacks=[],this.__propertyChangedCallbacks=[],this.__updating={},this.props={}}connectedCallback(){if(this.__initialized)return;this.__releaseCallbacks=[],this.__propertyChangedCallbacks=[],this.__updating={},this.props=wt(this,e);const s=_t(this.props),i=this.Component,l=L;try{L=this,this.__initialized=!0,St(i)?new i(s,{element:this}):i(s,{element:this})}finally{L=l}}async disconnectedCallback(){if(await Promise.resolve(),this.isConnected)return;this.__propertyChangedCallbacks.length=0;let s=null;for(;s=this.__releaseCallbacks.pop();)s(this);delete this.__initialized,this.__released=!0}attributeChangedCallback(s,i,l){if(this.__initialized&&!this.__updating[s]&&(s=this.lookupProp(s),s in e)){if(l==null&&!this[s])return;this[s]=e[s].parse?nt(l):l}}lookupProp(s){if(e)return n.find(i=>s===i||s===e[i].attribute)}get renderRoot(){return this.shadowRoot||this.attachShadow({mode:"open"})}addReleaseCallback(s){this.__releaseCallbacks.push(s)}addPropertyChangedCallback(s){this.__propertyChangedCallbacks.push(s)}}}function At(t,e={},n={}){const{BaseElement:r=HTMLElement,extension:s,customElements:i=window.customElements}=n;return l=>{let o=i.get(t);return o?(o.prototype.Component=l,o):(o=Et(r,yt(e)),o.prototype.Component=l,o.prototype.registeredTag=t,i.define(t,o,s),o)}}function mt(t){const e=Object.keys(t),n={};for(let r=0;r<e.length;r++){const[s,i]=H(t[e[r]]);Object.defineProperty(n,e[r],{get:s,set(l){i(()=>l)}})}return n}function xt(t){if(t.assignedSlot&&t.assignedSlot._$owner)return t.assignedSlot._$owner;let e=t.parentNode;for(;e&&!e._$owner&&!(e.assignedSlot&&e.assignedSlot._$owner);)e=e.parentNode;return e&&e.assignedSlot?e.assignedSlot._$owner:t._$owner}function $t(t){return(e,n)=>{const{element:r}=n;return lt(s=>{const i=mt(e);r.addPropertyChangedCallback((o,c)=>i[o]=c),r.addReleaseCallback(()=>{r.renderRoot.textContent="",s()});const l=t(i,n);return E(r.renderRoot,l)},xt(r))}}function kt(t,e,n){return arguments.length===2&&(n=e,e={}),At(t,e)($t(n))}const Tt=`
2
2
  :host([theme="dark"]) {
3
3
  color-scheme: only dark;
4
4
  }
@@ -33,4 +33,4 @@
33
33
  0% { transform: rotate(0deg); }
34
34
  100% { transform: rotate(360deg); }
35
35
  }
36
- `;var Tt=m("<div part=container class=dictate-button__container><style></style><button part=button class=dictate-button__button>"),Ot=m('<svg part=icon class="dictate-button__icon dictate-button__icon--idle"fill=none viewBox="0 0 24 24"stroke-width=1.5 stroke=currentColor><path stroke-linecap=round stroke-linejoin=round d="M12 18.75a6 6 0 0 0 6-6v-1.5m-6 7.5a6 6 0 0 1-6-6v-1.5m6 7.5v3.75m-3.75 0h7.5M12 15.75a3 3 0 0 1-3-3V4.5a3 3 0 1 1 6 0v8.25a3 3 0 0 1-3 3Z">'),Pt=m('<svg part=icon class="dictate-button__icon dictate-button__icon--recording"viewBox="0 0 24 24"fill=currentColor><path fill-rule=evenodd d="M4.5 7.5a3 3 0 0 1 3-3h9a3 3 0 0 1 3 3v9a3 3 0 0 1-3 3h-9a3 3 0 0 1-3-3v-9Z"clip-rule=evenodd>'),jt=m('<svg part=icon class="dictate-button__icon dictate-button__icon--processing"fill=none viewBox="0 0 24 24"stroke-width=1.5 stroke=currentColor><path stroke-linecap=round stroke-linejoin=round d="M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0 3.181 3.183a8.25 8.25 0 0 0 13.803-3.7M4.031 9.865a8.25 8.25 0 0 1 13.803-3.7l3.181 3.182m0-4.991v4.99">'),Nt=m('<svg part=icon class="dictate-button__icon dictate-button__icon--error"fill=none viewBox="0 0 24 24"stroke-width=1.5 stroke=currentColor><path stroke-linecap=round stroke-linejoin=round d="M6 18 18 6M6 6l12 12">');console.debug("dictate-button version:","0.1.0");const Mt="https://api.dictate-button.io/transcribe",k="dictate-button.io";$t("dictate-button",{size:24,apiEndpoint:Mt},(t,{element:e})=>{const{size:n,apiEndpoint:r}=t;console.log("api",r);const[s,i]=z("idle");let l=null,o=[];const c=()=>{l&&l.state!=="inactive"&&l.stop(),o=[]};e.addEventListener("disconnected",c);const a=async()=>{if(c(),s()==="idle")try{const h=await navigator.mediaDevices.getUserMedia({audio:!0});l=new MediaRecorder(h,{mimeType:"audio/webm"}),o=[],l.ondataavailable=y=>{o.push(y.data)},l.onstop=async()=>{i("processing");const y=new Blob(o,{type:"audio/webm"});try{const g=await fetch(r,{method:"POST",body:y});if(!g.ok)throw new Error("Failed to transcribe audio");const d=await g.json();if(s()!=="processing")return;S(e,"transcribed",d.text),i("idle")}catch(g){console.error("Failed to transcribe audio:",g),S(e,"error","Failed to transcribe audio"),u()}},l.start(),S(e,"started","Started recording"),i("recording")}catch(h){console.error("Failed to start recording:",h),S(e,"error","Failed to start recording"),u()}else S(e,"stopped","Stopped recording"),i("idle")},u=()=>{i("error"),setTimeout(()=>i("idle"),2e3)};return(()=>{var h=Tt(),y=h.firstChild,g=y.nextSibling;return v(y,kt),g.$$click=a,v(g,(()=>{var d=$(()=>s()==="idle");return()=>d()&&x(Rt,{})})(),null),v(g,(()=>{var d=$(()=>s()==="recording");return()=>d()&&x(It,{})})(),null),v(g,(()=>{var d=$(()=>s()==="processing");return()=>d()&&x(Ft,{})})(),null),v(g,(()=>{var d=$(()=>s()==="error");return()=>d()&&x(Lt,{})})(),null),P(d=>{var nt=`width:${n}px;height:${n}px"`,K=Bt(s());return d.e=ht(g,nt,d.e),K!==d.t&&Y(g,"title",d.t=K),d},{e:void 0,t:void 0}),h})()});const Bt=t=>{switch(t){case"idle":return`Start dictation (${k})`;case"recording":return`Stop dictation (${k})`;case"processing":return`Stop processing (${k})`;case"error":return`Click to reset (${k})`}},S=(t,e,n)=>{t.dispatchEvent(new CustomEvent(e,{detail:n,bubbles:!0,composed:!0}))},Rt=()=>Ot(),It=()=>Pt(),Ft=()=>jt(),Lt=()=>Nt();dt(["click"]);
36
+ `;var Ot=x("<div part=container class=dictate-button__container><style></style><button part=button class=dictate-button__button>"),Pt=x('<svg part=icon class="dictate-button__icon dictate-button__icon--idle"fill=none viewBox="0 0 24 24"stroke-width=1.5 stroke=currentColor><path stroke-linecap=round stroke-linejoin=round d="M12 18.75a6 6 0 0 0 6-6v-1.5m-6 7.5a6 6 0 0 1-6-6v-1.5m6 7.5v3.75m-3.75 0h7.5M12 15.75a3 3 0 0 1-3-3V4.5a3 3 0 1 1 6 0v8.25a3 3 0 0 1-3 3Z">'),jt=x('<svg part=icon class="dictate-button__icon dictate-button__icon--recording"viewBox="0 0 24 24"fill=currentColor><path fill-rule=evenodd d="M4.5 7.5a3 3 0 0 1 3-3h9a3 3 0 0 1 3 3v9a3 3 0 0 1-3 3h-9a3 3 0 0 1-3-3v-9Z"clip-rule=evenodd>'),Nt=x('<svg part=icon class="dictate-button__icon dictate-button__icon--processing"fill=none viewBox="0 0 24 24"stroke-width=1.5 stroke=currentColor><path stroke-linecap=round stroke-linejoin=round d="M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0 3.181 3.183a8.25 8.25 0 0 0 13.803-3.7M4.031 9.865a8.25 8.25 0 0 1 13.803-3.7l3.181 3.182m0-4.991v4.99">'),Bt=x('<svg part=icon class="dictate-button__icon dictate-button__icon--error"fill=none viewBox="0 0 24 24"stroke-width=1.5 stroke=currentColor><path stroke-linecap=round stroke-linejoin=round d="M6 18 18 6M6 6l12 12">');console.debug("dictate-button version:","0.3.0");const Mt="https://api.dictate-button.io/transcribe",T="dictate-button.io";kt("dictate-button",{size:24,apiEndpoint:Mt,language:void 0},(t,{element:e})=>{const{size:n,apiEndpoint:r,language:s}=t;console.debug("api",r);const[i,l]=H("idle");let o=null,c=[];const a=()=>{o&&o.state!=="inactive"&&o.stop(),c=[]};e.addEventListener("disconnected",a);const f=async()=>{if(a(),i()==="idle")try{const y=await navigator.mediaDevices.getUserMedia({audio:!0});o=new MediaRecorder(y,{mimeType:"audio/webm"}),c=[],o.ondataavailable=_=>{c.push(_.data)},o.onstop=async()=>{l("processing"),S(e,"transcribing:started","Started transcribing");const _=new Blob(c,{type:"audio/webm"});try{const d=new FormData;d.append("audio",_,"recording.webm"),d.append("origin",window?.location?.origin),s&&d.append("language",s);const h=await fetch(r,{method:"POST",body:d});if(!h.ok)throw new Error("Failed to transcribe audio");const I=await h.json();if(i()!=="processing")return;S(e,"transcribing:finished",I.text),l("idle")}catch(d){console.error("Failed to transcribe audio:",d),S(e,"transcribing:failed","Failed to transcribe audio"),b()}},o.start(),S(e,"recording:started","Started recording"),l("recording")}catch(y){console.error("Failed to start recording:",y),S(e,"recording:failed","Failed to start recording"),b()}else S(e,"recording:stopped","Stopped recording"),l("idle")},b=()=>{l("error"),setTimeout(()=>l("idle"),2e3)};return(()=>{var y=Ot(),_=y.firstChild,d=_.nextSibling;return E(_,Tt),d.$$click=f,E(d,(()=>{var h=k(()=>i()==="idle");return()=>h()&&$(It,{})})(),null),E(d,(()=>{var h=k(()=>i()==="recording");return()=>h()&&$(Ft,{})})(),null),E(d,(()=>{var h=k(()=>i()==="processing");return()=>h()&&$(Lt,{})})(),null),E(d,(()=>{var h=k(()=>i()==="error");return()=>h()&&$(Kt,{})})(),null),j(h=>{var I=`width:${n}px;height:${n}px"`,V=Rt(i());return h.e=pt(d,I,h.e),V!==h.t&&et(d,"title",h.t=V),h},{e:void 0,t:void 0}),y})()});const Rt=t=>{switch(t){case"idle":return`Start dictation (${T})`;case"recording":return`Stop dictation (${T})`;case"processing":return`Stop processing (${T})`;case"error":return`Click to reset (${T})`}},S=(t,e,n)=>{t.dispatchEvent(new CustomEvent(e,{detail:n,bubbles:!0,composed:!0}))},It=()=>Pt(),Ft=()=>jt(),Lt=()=>Nt(),Kt=()=>Bt();ht(["click"]);
@@ -1,13 +1,14 @@
1
- export interface BtnDictateProps {
1
+ export interface DictateButtonProps {
2
2
  size?: number;
3
3
  apiEndpoint?: string;
4
+ language?: string;
4
5
  theme?: 'light' | 'dark';
5
6
  class?: string;
6
7
  }
7
8
  declare module 'solid-js' {
8
9
  namespace JSX {
9
10
  interface IntrinsicElements {
10
- 'dictate-button': BtnDictateProps;
11
+ 'dictate-button': Element & DictateButtonProps;
11
12
  }
12
13
  }
13
14
  }