dictate-button 1.8.0 → 1.9.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 +13 -15
- package/dist/dictate-button.js +37 -37
- package/dist/dictate-button.test.d.ts +0 -0
- package/dist/inject-exclusive.d.ts +0 -1
- package/dist/inject-exclusive.js +1 -0
- package/dist/inject-inclusive.d.ts +0 -1
- package/dist/inject-inclusive.js +1 -0
- package/package.json +15 -7
package/README.md
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
# Dictate Button
|
|
1
|
+
# Dictate Button
|
|
2
2
|

|
|
3
|
+
[](https://github.com/dictate-button/dictate-button/actions/workflows/test.yml)
|
|
3
4
|
|
|
4
5
|
A customizable web component that adds speech-to-text dictation capabilities to any text input, textarea field, or contenteditable element on your website.
|
|
5
6
|
|
|
@@ -46,10 +47,9 @@ Both auto-inject modes:
|
|
|
46
47
|
|
|
47
48
|
#### Option 1: Using the exclusive auto-inject script
|
|
48
49
|
|
|
49
|
-
In your HTML `<head>` tag, add the following script
|
|
50
|
+
In your HTML `<head>` tag, add the following script tag:
|
|
50
51
|
|
|
51
52
|
```html
|
|
52
|
-
<script type="module" crossorigin src="https://cdn.dictate-button.io/dictate-button.js"></script>
|
|
53
53
|
<script type="module" crossorigin src="https://cdn.dictate-button.io/inject-exclusive.js"></script>
|
|
54
54
|
```
|
|
55
55
|
|
|
@@ -65,10 +65,9 @@ Add the `data-dictate-button-on` attribute to any `textarea`, `input[type="text"
|
|
|
65
65
|
|
|
66
66
|
#### Option 2: Using the inclusive auto-inject script
|
|
67
67
|
|
|
68
|
-
In your HTML `<head>` tag, add the following script
|
|
68
|
+
In your HTML `<head>` tag, add the following script tag:
|
|
69
69
|
|
|
70
70
|
```html
|
|
71
|
-
<script type="module" crossorigin src="https://cdn.dictate-button.io/dictate-button.js"></script>
|
|
72
71
|
<script type="module" crossorigin src="https://cdn.dictate-button.io/inject-inclusive.js"></script>
|
|
73
72
|
```
|
|
74
73
|
|
|
@@ -96,15 +95,7 @@ Import the component and use it directly in your code:
|
|
|
96
95
|
|
|
97
96
|
### From NPM
|
|
98
97
|
|
|
99
|
-
Import once for your app
|
|
100
|
-
|
|
101
|
-
The button component:
|
|
102
|
-
|
|
103
|
-
```js
|
|
104
|
-
import 'dictate-button'
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
The auto-inject script:
|
|
98
|
+
Import once for your app:
|
|
108
99
|
|
|
109
100
|
```js
|
|
110
101
|
// For selected text fields (with data-dictate-button-on attribute):
|
|
@@ -123,6 +114,7 @@ Tip: You can also import from subpaths (e.g., 'dictate-button/libs/injectDictate
|
|
|
123
114
|
for smaller bundles, if your bundler resolves package subpath exports.
|
|
124
115
|
|
|
125
116
|
```js
|
|
117
|
+
import 'dictate-button' // Required when using library functions directly
|
|
126
118
|
import { injectDictateButton, injectDictateButtonOnLoad } from 'dictate-button/libs'
|
|
127
119
|
|
|
128
120
|
// Inject dictate buttons immediately to matching elements
|
|
@@ -162,6 +154,12 @@ The dictate-button component emits the following events:
|
|
|
162
154
|
- `transcribing:finished`: Fired when transcribing is complete. The event detail contains the transcribed text.
|
|
163
155
|
- `transcribing:failed`: Fired when an error occurs during transcribing.
|
|
164
156
|
|
|
157
|
+
The ideal scenario is when user first starts recording (`recording:started`), then stops recording (`recording:stopped`), then the recorded audio is sent to the server for processing (`transcribing:started`), and finally the transcribed text is received (`transcribing:finished`).
|
|
158
|
+
|
|
159
|
+
> recording:started -> recording:stopped -> transcribing:started -> transcribing:finished
|
|
160
|
+
|
|
161
|
+
In case of an error in recording or transcribing, the `recording:failed` or `transcribing:failed` event is fired, respectively.
|
|
162
|
+
|
|
165
163
|
Example event handling:
|
|
166
164
|
|
|
167
165
|
```javascript
|
|
@@ -215,7 +213,7 @@ You can specify your own endpoint by setting the `apiEndpoint` attribute.
|
|
|
215
213
|
The API expects:
|
|
216
214
|
- POST request
|
|
217
215
|
- Multipart form data with the following fields:
|
|
218
|
-
- `audio`: Audio data as a
|
|
216
|
+
- `audio`: Audio data as a File (audio/webm format)
|
|
219
217
|
- `origin`: The origin of the website (automatically added)
|
|
220
218
|
- `language`: Optional language code (if provided as an attribute)
|
|
221
219
|
- Response should be JSON with a `text` property containing the transcribed text
|
package/dist/dictate-button.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const St = (t, n) => t === n,
|
|
1
|
+
const St = (t, n) => t === n, I = {
|
|
2
2
|
equals: St
|
|
3
3
|
};
|
|
4
4
|
let pt = _t;
|
|
@@ -16,7 +16,7 @@ function At(t, n) {
|
|
|
16
16
|
cleanups: null,
|
|
17
17
|
context: i ? i.context : null,
|
|
18
18
|
owner: i
|
|
19
|
-
}, s = r ? t : () => t(() => V(() =>
|
|
19
|
+
}, s = r ? t : () => t(() => V(() => L(l)));
|
|
20
20
|
b = l, g = null;
|
|
21
21
|
try {
|
|
22
22
|
return M(s, !0);
|
|
@@ -25,7 +25,7 @@ function At(t, n) {
|
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
27
|
function gt(t, n) {
|
|
28
|
-
n = n ? Object.assign({},
|
|
28
|
+
n = n ? Object.assign({}, I, n) : I;
|
|
29
29
|
const e = {
|
|
30
30
|
value: t,
|
|
31
31
|
observers: null,
|
|
@@ -36,17 +36,17 @@ function gt(t, n) {
|
|
|
36
36
|
}
|
|
37
37
|
function D(t, n, e) {
|
|
38
38
|
const o = Z(t, n, !1, x);
|
|
39
|
-
|
|
39
|
+
$(o);
|
|
40
40
|
}
|
|
41
41
|
function kt(t, n, e) {
|
|
42
42
|
pt = Mt;
|
|
43
43
|
const o = Z(t, n, !1, x);
|
|
44
|
-
o.user = !0, E ? E.push(o) :
|
|
44
|
+
o.user = !0, E ? E.push(o) : $(o);
|
|
45
45
|
}
|
|
46
46
|
function Tt(t, n, e) {
|
|
47
|
-
e = e ? Object.assign({},
|
|
47
|
+
e = e ? Object.assign({}, I, e) : I;
|
|
48
48
|
const o = Z(t, n, !0, 0);
|
|
49
|
-
return o.observers = null, o.observerSlots = null, o.comparator = e.equals || void 0,
|
|
49
|
+
return o.observers = null, o.observerSlots = null, o.comparator = e.equals || void 0, $(o), bt.bind(o);
|
|
50
50
|
}
|
|
51
51
|
function V(t) {
|
|
52
52
|
if (g === null) return t();
|
|
@@ -63,7 +63,7 @@ function Pt(t) {
|
|
|
63
63
|
}
|
|
64
64
|
function bt() {
|
|
65
65
|
if (this.sources && this.state)
|
|
66
|
-
if (this.state === x)
|
|
66
|
+
if (this.state === x) $(this);
|
|
67
67
|
else {
|
|
68
68
|
const t = w;
|
|
69
69
|
w = null, M(() => K(this), !1), w = t;
|
|
@@ -85,20 +85,20 @@ function yt(t, n, e) {
|
|
|
85
85
|
throw w = [], new Error();
|
|
86
86
|
}, !1)), n;
|
|
87
87
|
}
|
|
88
|
-
function
|
|
88
|
+
function $(t) {
|
|
89
89
|
if (!t.fn) return;
|
|
90
|
-
|
|
90
|
+
L(t);
|
|
91
91
|
const n = z;
|
|
92
|
-
|
|
92
|
+
Lt(t, t.value, n);
|
|
93
93
|
}
|
|
94
|
-
function
|
|
94
|
+
function Lt(t, n, e) {
|
|
95
95
|
let o;
|
|
96
96
|
const r = b, i = g;
|
|
97
97
|
g = b = t;
|
|
98
98
|
try {
|
|
99
99
|
o = t.fn(n);
|
|
100
100
|
} catch (l) {
|
|
101
|
-
return t.pure && (t.state = x, t.owned && t.owned.forEach(
|
|
101
|
+
return t.pure && (t.state = x, t.owned && t.owned.forEach(L), t.owned = null), t.updatedAt = e + 1, vt(l);
|
|
102
102
|
} finally {
|
|
103
103
|
g = i, b = r;
|
|
104
104
|
}
|
|
@@ -129,7 +129,7 @@ function F(t) {
|
|
|
129
129
|
t.state && n.push(t);
|
|
130
130
|
for (let e = n.length - 1; e >= 0; e--)
|
|
131
131
|
if (t = n[e], t.state === x)
|
|
132
|
-
|
|
132
|
+
$(t);
|
|
133
133
|
else if (t.state === N) {
|
|
134
134
|
const o = w;
|
|
135
135
|
w = null, M(() => K(t, n[0]), !1), w = o;
|
|
@@ -141,12 +141,12 @@ function M(t, n) {
|
|
|
141
141
|
n || (w = []), E ? e = !0 : E = [], z++;
|
|
142
142
|
try {
|
|
143
143
|
const o = t();
|
|
144
|
-
return
|
|
144
|
+
return $t(e), o;
|
|
145
145
|
} catch (o) {
|
|
146
146
|
e || (E = null), w = null, vt(o);
|
|
147
147
|
}
|
|
148
148
|
}
|
|
149
|
-
function
|
|
149
|
+
function $t(t) {
|
|
150
150
|
if (w && (_t(w), w = null), t) return;
|
|
151
151
|
const n = E;
|
|
152
152
|
E = null, n.length && M(() => pt(n), !1);
|
|
@@ -178,7 +178,7 @@ function wt(t) {
|
|
|
178
178
|
e.state || (e.state = N, e.pure ? w.push(e) : E.push(e), e.observers && wt(e));
|
|
179
179
|
}
|
|
180
180
|
}
|
|
181
|
-
function
|
|
181
|
+
function L(t) {
|
|
182
182
|
let n;
|
|
183
183
|
if (t.sources)
|
|
184
184
|
for (; t.sources.length; ) {
|
|
@@ -189,11 +189,11 @@ function $(t) {
|
|
|
189
189
|
}
|
|
190
190
|
}
|
|
191
191
|
if (t.tOwned) {
|
|
192
|
-
for (n = t.tOwned.length - 1; n >= 0; n--)
|
|
192
|
+
for (n = t.tOwned.length - 1; n >= 0; n--) L(t.tOwned[n]);
|
|
193
193
|
delete t.tOwned;
|
|
194
194
|
}
|
|
195
195
|
if (t.owned) {
|
|
196
|
-
for (n = t.owned.length - 1; n >= 0; n--)
|
|
196
|
+
for (n = t.owned.length - 1; n >= 0; n--) L(t.owned[n]);
|
|
197
197
|
t.owned = null;
|
|
198
198
|
}
|
|
199
199
|
if (t.cleanups) {
|
|
@@ -210,10 +210,10 @@ function Ot(t) {
|
|
|
210
210
|
function vt(t, n = b) {
|
|
211
211
|
throw Ot(t);
|
|
212
212
|
}
|
|
213
|
-
function
|
|
213
|
+
function j(t, n) {
|
|
214
214
|
return V(() => t(n || {}));
|
|
215
215
|
}
|
|
216
|
-
const
|
|
216
|
+
const B = (t) => Tt(() => t());
|
|
217
217
|
function Rt(t, n, e) {
|
|
218
218
|
let o = e.length, r = n.length, i = o, l = 0, s = 0, a = n[r - 1].nextSibling, d = null;
|
|
219
219
|
for (; l < r || s < i; ) {
|
|
@@ -264,7 +264,7 @@ function O(t, n, e, o) {
|
|
|
264
264
|
function P(t, n, e) {
|
|
265
265
|
e == null ? t.removeAttribute(n) : t.setAttribute(n, e);
|
|
266
266
|
}
|
|
267
|
-
function
|
|
267
|
+
function jt(t, n, e) {
|
|
268
268
|
if (!n) return e ? P(t, "style") : n;
|
|
269
269
|
const o = t.style;
|
|
270
270
|
if (typeof n == "string") return o.cssText = n;
|
|
@@ -276,7 +276,7 @@ function Bt(t, n, e) {
|
|
|
276
276
|
r = n[i], r !== e[i] && (o.setProperty(i, r), e[i] = r);
|
|
277
277
|
return e;
|
|
278
278
|
}
|
|
279
|
-
function
|
|
279
|
+
function Bt(t, n, e) {
|
|
280
280
|
return V(() => t(n, e));
|
|
281
281
|
}
|
|
282
282
|
function A(t, n, e, o) {
|
|
@@ -361,7 +361,7 @@ function k(t, n, e, o) {
|
|
|
361
361
|
} else t.insertBefore(r, e);
|
|
362
362
|
return [r];
|
|
363
363
|
}
|
|
364
|
-
function
|
|
364
|
+
function It(t) {
|
|
365
365
|
return Object.keys(t).reduce((e, o) => {
|
|
366
366
|
const r = t[o];
|
|
367
367
|
return e[o] = Object.assign({}, r), mt(r.value) && !Ut(r.value) && !Array.isArray(r.value) && (e[o].value = Object.assign({}, r.value)), Array.isArray(r.value) && (e[o].value = r.value.slice(0)), e;
|
|
@@ -379,7 +379,7 @@ function Dt(t) {
|
|
|
379
379
|
return Object.keys(t).reduce((e, o) => (e[o] = t[o].value, e), {});
|
|
380
380
|
}
|
|
381
381
|
function Ft(t, n) {
|
|
382
|
-
const e =
|
|
382
|
+
const e = It(n);
|
|
383
383
|
return Object.keys(n).forEach((r) => {
|
|
384
384
|
const i = e[r], l = t.getAttribute(i.attribute), s = t[r];
|
|
385
385
|
l != null && (i.value = i.parse ? Ct(l) : l), s != null && (i.value = Array.isArray(s) ? s.slice(0) : s), i.reflect && ct(t, i.attribute, i.value, !!i.parse), Object.defineProperty(t, r, {
|
|
@@ -584,9 +584,9 @@ const Xt = `
|
|
|
584
584
|
}
|
|
585
585
|
`;
|
|
586
586
|
var Zt = /* @__PURE__ */ O('<div part=container class=dictate-button__container><style></style><div aria-live=polite class=dictate-button__status-announcer style="position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;border-width:0"></div><button part=button class=dictate-button__button>'), Qt = /* @__PURE__ */ O('<svg part=icon class="dictate-button__icon dictate-button__icon--idle"fill=none viewBox="0 0 24 24"stroke-width=1.5 stroke=currentColor role=img aria-hidden=true><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">'), Yt = /* @__PURE__ */ O('<svg part=icon class="dictate-button__icon dictate-button__icon--recording"viewBox="0 0 24 24"fill=currentColor role=img aria-hidden=true><circle cx=12 cy=12 r=10>'), te = /* @__PURE__ */ O('<svg part=icon class="dictate-button__icon dictate-button__icon--processing"viewBox="0 0 24 24"fill=none stroke=currentColor stroke-width=1.5 stroke-linecap=round stroke-linejoin=round role=img aria-hidden=true><path d="M12 2v4"></path><path d="m16.2 7.8 2.9-2.9"></path><path d="M18 12h4"></path><path d="m16.2 16.2 2.9 2.9"></path><path d="M12 18v4"></path><path d="m4.9 19.1 2.9-2.9"></path><path d="M2 12h4"></path><path d="m4.9 4.9 2.9 2.9">'), ee = /* @__PURE__ */ O('<svg part=icon class="dictate-button__icon dictate-button__icon--error"viewBox="0 0 24 24"fill=none stroke=currentColor stroke-width=4 stroke-linecap=round stroke-linejoin=round role=img aria-hidden=true><line x1=12 x2=12 y1=4 y2=14></line><line x1=12 x2=12.01 y1=20 y2=20>');
|
|
587
|
-
console.debug("dictate-button version:", "1.
|
|
587
|
+
console.debug("dictate-button version:", "1.9.0");
|
|
588
588
|
const ne = "https://api.dictate-button.io/transcribe", S = "dictate-button.io", J = -70, ut = -10, dt = 0, re = 4, oe = 0.25, ie = 0.05;
|
|
589
|
-
Jt("dictate-button", {
|
|
589
|
+
customElements.get("dictate-button") ? console.debug("dictate-button: We don't require importing the dictate-button component separately anymore, so you may remove the script tag which imports https://cdn.dictate-button.io/dictate-button.js from the HTML head.") : Jt("dictate-button", {
|
|
590
590
|
size: 30,
|
|
591
591
|
apiEndpoint: ne,
|
|
592
592
|
language: void 0
|
|
@@ -679,21 +679,21 @@ Jt("dictate-button", {
|
|
|
679
679
|
var f = Zt(), _ = f.firstChild, v = _.nextSibling, u = v.nextSibling;
|
|
680
680
|
A(_, Xt), A(v, () => ft(e()));
|
|
681
681
|
var m = R;
|
|
682
|
-
return typeof m == "function" ?
|
|
683
|
-
var h =
|
|
684
|
-
return () => h() &&
|
|
682
|
+
return typeof m == "function" ? Bt(m, u) : R = u, A(u, (() => {
|
|
683
|
+
var h = B(() => e() === "idle");
|
|
684
|
+
return () => h() && j(le, {});
|
|
685
685
|
})(), null), A(u, (() => {
|
|
686
|
-
var h =
|
|
687
|
-
return () => h() &&
|
|
686
|
+
var h = B(() => e() === "recording");
|
|
687
|
+
return () => h() && j(ae, {});
|
|
688
688
|
})(), null), A(u, (() => {
|
|
689
|
-
var h =
|
|
690
|
-
return () => h() &&
|
|
689
|
+
var h = B(() => e() === "processing");
|
|
690
|
+
return () => h() && j(ce, {});
|
|
691
691
|
})(), null), A(u, (() => {
|
|
692
|
-
var h =
|
|
693
|
-
return () => h() &&
|
|
692
|
+
var h = B(() => e() === "error");
|
|
693
|
+
return () => h() && j(ue, {});
|
|
694
694
|
})(), null), D((h) => {
|
|
695
695
|
var H = `width:${t.size}px;height:${t.size}px"`, ot = se(e()), it = ft(e()), st = e() === "recording", lt = e() === "processing";
|
|
696
|
-
return h.e =
|
|
696
|
+
return h.e = jt(u, H, h.e), ot !== h.t && P(u, "title", h.t = ot), it !== h.a && P(u, "aria-label", h.a = it), st !== h.o && P(u, "aria-pressed", h.o = st), lt !== h.i && P(u, "aria-busy", h.i = lt), h;
|
|
697
697
|
}, {
|
|
698
698
|
e: void 0,
|
|
699
699
|
t: void 0,
|
|
File without changes
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/dist/inject-exclusive.js
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/dist/inject-inclusive.js
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dictate-button",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.9.0",
|
|
4
|
+
"description": "Customizable Web Component that adds speech-to-text dictation capabilities to text fields",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"custom-element",
|
|
7
7
|
"dictate",
|
|
@@ -60,15 +60,20 @@
|
|
|
60
60
|
},
|
|
61
61
|
"dependencies": {
|
|
62
62
|
"solid-element": "^1.9.1",
|
|
63
|
-
"solid-js": "^1.9.
|
|
63
|
+
"solid-js": "^1.9.10"
|
|
64
64
|
},
|
|
65
65
|
"devDependencies": {
|
|
66
|
+
"@solidjs/testing-library": "^0.8.10",
|
|
67
|
+
"@testing-library/user-event": "^14.6.1",
|
|
68
|
+
"@vitest/ui": "^4.0.10",
|
|
69
|
+
"jsdom": "^27.2.0",
|
|
66
70
|
"prettier": "^3.6.2",
|
|
67
71
|
"typescript": "^5.9.3",
|
|
68
|
-
"vite": "^7.
|
|
72
|
+
"vite": "^7.2.2",
|
|
69
73
|
"vite-plugin-dts": "^4.5.4",
|
|
70
|
-
"vite-plugin-solid": "^2.11.
|
|
71
|
-
"vite-plugin-static-copy": "^3.1.4"
|
|
74
|
+
"vite-plugin-solid": "^2.11.10",
|
|
75
|
+
"vite-plugin-static-copy": "^3.1.4",
|
|
76
|
+
"vitest": "^4.0.10"
|
|
72
77
|
},
|
|
73
78
|
"homepage": "https://github.com/dictate-button/dictate-button",
|
|
74
79
|
"repository": {
|
|
@@ -81,6 +86,9 @@
|
|
|
81
86
|
"scripts": {
|
|
82
87
|
"build": "vite build",
|
|
83
88
|
"format": "prettier --write './src/**/*.{js,jsx,ts,tsx}'",
|
|
84
|
-
"deploy": "firebase deploy"
|
|
89
|
+
"deploy": "firebase deploy",
|
|
90
|
+
"test": "vitest run",
|
|
91
|
+
"test:watch": "vitest",
|
|
92
|
+
"test:ui": "vitest --ui"
|
|
85
93
|
}
|
|
86
94
|
}
|