dictate-button 1.2.0 → 1.4.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
@@ -22,7 +22,7 @@ Developed for [dictate-button.io](https://dictate-button.io).
22
22
  - textarea
23
23
  - input[type="text"]
24
24
  - input[type="search"]
25
- - input
25
+ - input (without a type; defaults to text)
26
26
 
27
27
  ## Usage
28
28
 
@@ -35,6 +35,11 @@ Choose the auto-inject mode that best suits your needs:
35
35
  | Exclusive | Enables for text fields with the `data-dictate-button-on` attribute only. | `inject-exclusive.js` |
36
36
  | Inclusive | Enables for text fields without the `data-dictate-button-off` attribute. | `inject-inclusive.js` |
37
37
 
38
+ Both auto-inject modes:
39
+ - Automatically run on DOMContentLoaded (or immediately if the DOM is already loaded).
40
+ - Watch for DOM changes to apply the dictate button to newly added elements.
41
+ - Set the button’s language from `document.documentElement.lang` (if present). Long codes like `en-GB` are normalized to `en`.
42
+
38
43
  ### From CDN
39
44
 
40
45
  #### Option 1: Using the exclusive auto-inject script
@@ -46,11 +51,13 @@ In your HTML `<head>` tag, add the following script tags:
46
51
  <script type="module" crossorigin src="https://cdn.dictate-button.io/inject-exclusive.js"></script>
47
52
  ```
48
53
 
49
- Add the `data-dictate-button-on` attribute to any `textarea` or `input[type=text]` elements where you want the dictate button to appear:
54
+ Add the `data-dictate-button-on` attribute to any `textarea`, `input[type="text"]`, `input[type="search"]`, or `input` without a `type` attribute:
50
55
 
51
56
  ```html
52
57
  <textarea data-dictate-button-on></textarea>
53
58
  <input type="text" data-dictate-button-on />
59
+ <input type="search" data-dictate-button-on />
60
+ <input data-dictate-button-on />
54
61
  ```
55
62
 
56
63
  #### Option 2: Using the inclusive auto-inject script
@@ -62,13 +69,15 @@ In your HTML `<head>` tag, add the following script tags:
62
69
  <script type="module" crossorigin src="https://cdn.dictate-button.io/inject-inclusive.js"></script>
63
70
  ```
64
71
 
65
- All `textarea` and `input[type=text]` elements without the `data-dictate-button-off` attribute will be automatically enhanced with the dictate button by default.
72
+ All `textarea`, `input[type="text"]`, `input[type="search"]`, and `input` elements without a `type` attribute that lack `data-dictate-button-off` will be automatically enhanced by default.
66
73
 
67
74
  To disable that for a specific field, add the `data-dictate-button-off` attribute to it this way:
68
75
 
69
76
  ```html
70
77
  <textarea data-dictate-button-off></textarea>
71
78
  <input type="text" data-dictate-button-off />
79
+ <input type="search" data-dictate-button-off />
80
+ <input data-dictate-button-off />
72
81
  ```
73
82
 
74
83
  #### Option 3: Manual integration
@@ -102,6 +111,42 @@ import 'dictate-button/inject-inclusive'
102
111
 
103
112
  To choose between **exclusive** and **inclusive** auto-inject modes, see the [Auto-inject modes](#auto-inject-modes) section.
104
113
 
114
+ ### Advanced usage with library functions
115
+
116
+ If you need more control over when and how the dictate buttons are injected, you can use the library functions directly:
117
+
118
+ Tip: You can also import from subpaths (e.g., 'dictate-button/libs/injectDictateButton')
119
+ for smaller bundles, if your bundler resolves package subpath exports.
120
+
121
+ ```js
122
+ import { injectDictateButton, injectDictateButtonOnLoad } from 'dictate-button/libs'
123
+
124
+ // Inject dictate buttons immediately to matching elements
125
+ injectDictateButton(
126
+ 'textarea.custom-selector', // CSS selector for target elements
127
+ {
128
+ buttonSize: 30, // Button size in pixels (optional; default: 30)
129
+ verbose: false, // Log events to console (optional; default: false)
130
+ customApiEndpoint: 'https://api.example.com/transcribe' // Optional custom API endpoint
131
+ }
132
+ )
133
+
134
+ // Inject on DOM load with mutation observer to catch dynamically added elements
135
+ injectDictateButtonOnLoad(
136
+ 'input.custom-selector', // CSS selector for target elements
137
+ {
138
+ buttonSize: 30, // Button size in pixels (optional; default: 30)
139
+ watchDomChanges: true, // Watch for DOM changes (optional; default: false)
140
+ verbose: false, // Log events to console (optional; default: false)
141
+ customApiEndpoint: 'https://api.example.com/transcribe' // Optional custom API endpoint
142
+ }
143
+ )
144
+ ```
145
+
146
+ Note: the injector mirrors the target field’s display/margins into the wrapper,
147
+ sets wrapper width to 100% for block-level fields, and adds padding to avoid the button overlapping text.
148
+ The wrapper also has the `dictate-button-wrapper` class for easy styling.
149
+
105
150
  ## Events
106
151
 
107
152
  The dictate-button component emits the following events:
@@ -605,7 +605,7 @@ const Vt = `
605
605
  }
606
606
  `;
607
607
  var qt = /* @__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>'), Ht = /* @__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">'), Gt = /* @__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>'), Wt = /* @__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">'), Xt = /* @__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>');
608
- console.debug("dictate-button version:", "1.2.0");
608
+ console.debug("dictate-button version:", "1.4.0");
609
609
  const Jt = "https://api.dictate-button.io/transcribe", v = "dictate-button.io", H = -70, ot = -10, it = 0, Zt = 4, Qt = 0.25, Yt = 0.05;
610
610
  zt("dictate-button", {
611
611
  size: 30,
@@ -1 +1 @@
1
- export {}
1
+ export {};
@@ -1,68 +1,12 @@
1
- const b = [
1
+ import { injectDictateButtonOnLoad as t } from "./libs/injectDictateButtonOnLoad.js";
2
+ const a = 30, n = !0, e = !1, o = [
2
3
  "textarea[data-dictate-button-on]:not([data-dictate-button-enabled])",
3
4
  'input[type="text"][data-dictate-button-on]:not([data-dictate-button-enabled])',
4
5
  'input[type="search"][data-dictate-button-on]:not([data-dictate-button-enabled])',
5
6
  "input[data-dictate-button-on]:not([type]):not([data-dictate-button-enabled])"
6
7
  ].join(",");
7
- function g() {
8
- const t = document.querySelectorAll(b);
9
- for (const n of t) {
10
- const a = document.createElement("div");
11
- a.style.position = "relative", a.style.display = "inline-block", a.style.width = "auto", a.style.color = "inherit", n.parentNode.insertBefore(a, n), n.setAttribute("data-dictate-button-enabled", ""), a.appendChild(n), n.style.boxSizing = "border-box";
12
- const e = document.createElement("dictate-button");
13
- e.size = 30, e.style.position = "absolute", e.style.right = "0", e.style.top = T(a, n) + "px", e.style.margin = "10px";
14
- const s = document.documentElement.lang;
15
- s && s.length >= 2 && (e.language = s), e.addEventListener("recording:started", (o) => {
16
- console.log("recording:started", o);
17
- }), e.addEventListener("recording:stopped", (o) => {
18
- console.log("recording:stopped", o);
19
- }), e.addEventListener("recording:failed", (o) => {
20
- console.log("recording:failed", o), i(n);
21
- }), e.addEventListener("transcribing:started", (o) => {
22
- console.log("transcribing:started", o);
23
- }), e.addEventListener("transcribing:finished", (o) => {
24
- console.log("transcribing:finished", o);
25
- const c = o.detail;
26
- f(n, c);
27
- }), e.addEventListener("transcribing:failed", (o) => {
28
- console.log("transcribing:failed", o), i(n);
29
- }), a.appendChild(e);
30
- }
31
- }
32
- function T(t, n) {
33
- if (n.tagName.toLowerCase() === "textarea")
34
- return 0;
35
- const a = Math.round(
36
- t.clientHeight / 2 - 30 / 2 - 10
37
- );
38
- return Math.max(0, a);
39
- }
40
- function f(t, n) {
41
- const a = typeof n == "string" ? n.trim() : String(n ?? "").trim();
42
- if (a.length === 0)
43
- return;
44
- const e = t.selectionStart || 0, s = t.selectionEnd || 0, o = e > 0 ? t.value.charAt(e - 1) : "", d = o && !/\s/.test(o), c = s < t.value.length ? t.value.charAt(s) : "", p = c && !/\s/.test(c), r = (d ? " " : "") + a + (p ? " " : ""), l = e + r.length, u = typeof t.scrollTop == "number" ? t.scrollTop : null;
45
- if (typeof t.setRangeText == "function")
46
- t.setRangeText(r, e, s, "end");
47
- else {
48
- t.value = t.value.substring(0, e) + r + t.value.substring(s);
49
- try {
50
- t.selectionStart = l, t.selectionEnd = l;
51
- } catch {
52
- }
53
- }
54
- u !== null && (t.scrollTop = u), t.dispatchEvent(new Event("input", { bubbles: !0, composed: !0 })), i(t);
55
- }
56
- function i(t) {
57
- try {
58
- t.focus({ preventScroll: !0 });
59
- } catch {
60
- t.focus();
61
- }
62
- }
63
- document.addEventListener("DOMContentLoaded", () => {
64
- g(), new MutationObserver(g).observe(document.body, {
65
- childList: !0,
66
- subtree: !0
67
- });
8
+ t(o, {
9
+ buttonSize: a,
10
+ watchDomChanges: n,
11
+ verbose: e
68
12
  });
@@ -1 +1 @@
1
- export {}
1
+ export {};
@@ -1,68 +1,12 @@
1
- const b = [
1
+ import { injectDictateButtonOnLoad as t } from "./libs/injectDictateButtonOnLoad.js";
2
+ const a = 30, n = !0, o = !1, e = [
2
3
  "textarea:not([data-dictate-button-off]):not([data-dictate-button-enabled])",
3
4
  'input[type="text"]:not([data-dictate-button-off]):not([data-dictate-button-enabled])',
4
5
  'input[type="search"]:not([data-dictate-button-off]):not([data-dictate-button-enabled])',
5
6
  "input:not([type]):not([data-dictate-button-off]):not([data-dictate-button-enabled])"
6
7
  ].join(",");
7
- function g() {
8
- const t = document.querySelectorAll(b);
9
- for (const n of t) {
10
- const a = document.createElement("div");
11
- a.style.position = "relative", a.style.display = "inline-block", a.style.width = "auto", a.style.color = "inherit", n.parentNode.insertBefore(a, n), n.setAttribute("data-dictate-button-enabled", ""), a.appendChild(n), n.style.boxSizing = "border-box";
12
- const e = document.createElement("dictate-button");
13
- e.size = 30, e.style.position = "absolute", e.style.right = "0", e.style.top = f(a, n) + "px", e.style.margin = "10px";
14
- const s = document.documentElement.lang;
15
- s && s.length >= 2 && (e.language = s), e.addEventListener("recording:started", (o) => {
16
- console.log("recording:started", o);
17
- }), e.addEventListener("recording:stopped", (o) => {
18
- console.log("recording:stopped", o);
19
- }), e.addEventListener("recording:failed", (o) => {
20
- console.log("recording:failed", o), i(n);
21
- }), e.addEventListener("transcribing:started", (o) => {
22
- console.log("transcribing:started", o);
23
- }), e.addEventListener("transcribing:finished", (o) => {
24
- console.log("transcribing:finished", o);
25
- const c = o.detail;
26
- T(n, c);
27
- }), e.addEventListener("transcribing:failed", (o) => {
28
- console.log("transcribing:failed", o), i(n);
29
- }), a.appendChild(e);
30
- }
31
- }
32
- function f(t, n) {
33
- if (n.tagName.toLowerCase() === "textarea")
34
- return 0;
35
- const a = Math.round(
36
- t.clientHeight / 2 - 30 / 2 - 10
37
- );
38
- return Math.max(0, a);
39
- }
40
- function T(t, n) {
41
- const a = typeof n == "string" ? n.trim() : String(n ?? "").trim();
42
- if (a.length === 0)
43
- return;
44
- const e = t.selectionStart || 0, s = t.selectionEnd || 0, o = e > 0 ? t.value.charAt(e - 1) : "", d = o && !/\s/.test(o), c = s < t.value.length ? t.value.charAt(s) : "", p = c && !/\s/.test(c), r = (d ? " " : "") + a + (p ? " " : ""), l = e + r.length, u = typeof t.scrollTop == "number" ? t.scrollTop : null;
45
- if (typeof t.setRangeText == "function")
46
- t.setRangeText(r, e, s, "end");
47
- else {
48
- t.value = t.value.substring(0, e) + r + t.value.substring(s);
49
- try {
50
- t.selectionStart = l, t.selectionEnd = l;
51
- } catch {
52
- }
53
- }
54
- u !== null && (t.scrollTop = u), t.dispatchEvent(new Event("input", { bubbles: !0, composed: !0 })), i(t);
55
- }
56
- function i(t) {
57
- try {
58
- t.focus({ preventScroll: !0 });
59
- } catch {
60
- t.focus();
61
- }
62
- }
63
- document.addEventListener("DOMContentLoaded", () => {
64
- g(), new MutationObserver(g).observe(document.body, {
65
- childList: !0,
66
- subtree: !0
67
- });
8
+ t(e, {
9
+ buttonSize: a,
10
+ watchDomChanges: n,
11
+ verbose: o
68
12
  });
@@ -0,0 +1,2 @@
1
+ export { injectDictateButton } from './injectDictateButton';
2
+ export { injectDictateButtonOnLoad } from './injectDictateButtonOnLoad';
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Options for the dictate button injection.
3
+ */
4
+ export interface InjectDictateButtonOptions {
5
+ /** Size of the button in pixels; defaults to 30 */
6
+ buttonSize?: number;
7
+ /** Whether to log events to console */
8
+ verbose?: boolean;
9
+ /** Optional custom API endpoint */
10
+ customApiEndpoint?: string;
11
+ }
12
+ /**
13
+ * Inject the dictate-button component to text fields.
14
+ *
15
+ * Optionally log button events to the console (verbose mode).
16
+ *
17
+ * @param {string} textFieldSelector - CSS selector for text fields to enhance
18
+ * @param {InjectDictateButtonOptions} options - Configuration options
19
+ */
20
+ export declare function injectDictateButton(textFieldSelector: string, options?: InjectDictateButtonOptions): void;
@@ -0,0 +1,81 @@
1
+ function T(t, c = {}) {
2
+ const { buttonSize: i = 30, verbose: o = !1, customApiEndpoint: r } = c, d = document.querySelectorAll(t);
3
+ for (const n of d) {
4
+ if (n.hasAttribute("data-dictate-button-enabled")) continue;
5
+ const u = n.parentNode;
6
+ if (!n.isConnected || !u) {
7
+ o && console.debug("injectDictateButton: skipping detached field", n);
8
+ continue;
9
+ }
10
+ n.setAttribute("data-dictate-button-enabled", "");
11
+ const s = document.createElement("div");
12
+ s.style.position = "relative";
13
+ const l = getComputedStyle(n), g = l.display === "block";
14
+ s.style.display = g ? "block" : "inline-block", s.style.width = g ? "100%" : "auto", s.style.color = "inherit", s.classList.add("dictate-button-wrapper"), u.insertBefore(s, n), s.appendChild(n), s.style.margin = l.margin, n.style.margin = "0", n.style.boxSizing = "border-box";
15
+ const p = parseFloat(l.paddingRight || "0") || 4;
16
+ n.style.paddingRight = `${i + p * 2}px`;
17
+ const e = document.createElement("dictate-button");
18
+ e.size = i, e.style.position = "absolute", e.style.right = "0", e.style.top = m(
19
+ s,
20
+ n,
21
+ i
22
+ ), e.style.marginRight = e.style.marginLeft = `${p}px`, e.style.marginTop = "0", e.style.marginBottom = "0", r && (e.apiEndpoint = r), e.language = h(), e.addEventListener("recording:started", (a) => {
23
+ o && console.debug("recording:started", a);
24
+ }), e.addEventListener("recording:stopped", (a) => {
25
+ o && console.debug("recording:stopped", a);
26
+ }), e.addEventListener("recording:failed", (a) => {
27
+ o && console.debug("recording:failed", a), b(n);
28
+ }), e.addEventListener("transcribing:started", (a) => {
29
+ o && console.debug("transcribing:started", a);
30
+ }), e.addEventListener("transcribing:finished", (a) => {
31
+ o && console.debug("transcribing:finished", a);
32
+ const f = a.detail;
33
+ y(n, f);
34
+ }), e.addEventListener("transcribing:failed", (a) => {
35
+ o && console.debug("transcribing:failed", a), b(n);
36
+ }), s.appendChild(e);
37
+ }
38
+ }
39
+ function h() {
40
+ const t = document.documentElement.lang;
41
+ if (t && t.length >= 2)
42
+ try {
43
+ return (Intl?.Locale ? new Intl.Locale(t) : null)?.language ?? t.split(/[-_]/)[0].toLowerCase();
44
+ } catch {
45
+ return t.split(/[-_]/)[0].toLowerCase();
46
+ }
47
+ }
48
+ function m(t, c, i) {
49
+ if (c.tagName.toLowerCase() === "textarea") {
50
+ const r = getComputedStyle(c);
51
+ return `${parseFloat(r.paddingTop || "0") || 4}px`;
52
+ }
53
+ const o = Math.round(t.clientHeight / 2 - i / 2);
54
+ return `${Math.max(4, o)}px`;
55
+ }
56
+ function y(t, c) {
57
+ const i = typeof c == "string" ? c.trim() : String(c ?? "").trim();
58
+ if (i.length === 0)
59
+ return;
60
+ const o = t.selectionStart ?? 0, r = t.selectionEnd ?? 0, d = o > 0 ? t.value.charAt(o - 1) : "", n = d && !/\s/.test(d), u = r < t.value.length ? t.value.charAt(r) : "", s = u && !/\s/.test(u), l = (n ? " " : "") + i + (s ? " " : ""), g = o + l.length, p = typeof t.scrollTop == "number" ? t.scrollTop : null;
61
+ if (typeof t.setRangeText == "function")
62
+ t.setRangeText(l, o, r, "end");
63
+ else {
64
+ t.value = t.value.substring(0, o) + l + t.value.substring(r);
65
+ try {
66
+ t.selectionStart = g, t.selectionEnd = g;
67
+ } catch {
68
+ }
69
+ }
70
+ p !== null && (t.scrollTop = p), t.dispatchEvent(new Event("input", { bubbles: !0, composed: !0 })), b(t);
71
+ }
72
+ function b(t) {
73
+ try {
74
+ t.focus({ preventScroll: !0 });
75
+ } catch {
76
+ t.focus();
77
+ }
78
+ }
79
+ export {
80
+ T as injectDictateButton
81
+ };
@@ -0,0 +1,20 @@
1
+ import { InjectDictateButtonOptions } from './injectDictateButton';
2
+ /**
3
+ * Options for injecting the dictate button on load, extends the base options.
4
+ */
5
+ export interface InjectDictateButtonOnLoadOptions extends InjectDictateButtonOptions {
6
+ /** Whether to watch for DOM changes and re-inject the component */
7
+ watchDomChanges?: boolean;
8
+ }
9
+ /**
10
+ * Add a DOMContentLoaded event listener which injects the dictate-button component to text fields
11
+ * or run it immediately if DOM is already loaded.
12
+ *
13
+ * Optionally watch for DOM changes to re-inject the component.
14
+ *
15
+ * Optionally log button events to the console (verbose mode).
16
+ *
17
+ * @param {string} textFieldSelector - CSS selector for text fields to enhance
18
+ * @param {InjectDictateButtonOnLoadOptions} options - Configuration options
19
+ */
20
+ export declare function injectDictateButtonOnLoad(textFieldSelector: string, options?: InjectDictateButtonOnLoadOptions): void;
@@ -0,0 +1,12 @@
1
+ import { injectDictateButton as o } from "./injectDictateButton.js";
2
+ function u(t, e = {}) {
3
+ const { watchDomChanges: r = !1 } = e, n = () => {
4
+ o(t, e), r && document.body && new MutationObserver(() => {
5
+ o(t, e);
6
+ }).observe(document.body, { childList: !0, subtree: !0 });
7
+ };
8
+ document.readyState === "loading" ? document.addEventListener("DOMContentLoaded", n, { once: !0 }) : n();
9
+ }
10
+ export {
11
+ u as injectDictateButtonOnLoad
12
+ };
package/dist/libs.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export * from './libs/index'
2
+ export {}
package/dist/libs.js ADDED
@@ -0,0 +1,6 @@
1
+ import { injectDictateButton as e } from "./libs/injectDictateButton.js";
2
+ import { injectDictateButtonOnLoad as c } from "./libs/injectDictateButtonOnLoad.js";
3
+ export {
4
+ e as injectDictateButton,
5
+ c as injectDictateButtonOnLoad
6
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dictate-button",
3
- "version": "1.2.0",
3
+ "version": "1.4.0",
4
4
  "description": "Dictate Button (Web Component)",
5
5
  "keywords": [
6
6
  "custom-element",
@@ -25,6 +25,21 @@
25
25
  "import": "./dist/dictate-button.js",
26
26
  "default": "./dist/dictate-button.js"
27
27
  },
28
+ "./libs": {
29
+ "types": "./dist/libs/index.d.ts",
30
+ "import": "./dist/libs/index.js",
31
+ "default": "./dist/libs/index.js"
32
+ },
33
+ "./libs/injectDictateButton": {
34
+ "types": "./dist/libs/injectDictateButton.d.ts",
35
+ "import": "./dist/libs/injectDictateButton.js",
36
+ "default": "./dist/libs/injectDictateButton.js"
37
+ },
38
+ "./libs/injectDictateButtonOnLoad": {
39
+ "types": "./dist/libs/injectDictateButtonOnLoad.d.ts",
40
+ "import": "./dist/libs/injectDictateButtonOnLoad.js",
41
+ "default": "./dist/libs/injectDictateButtonOnLoad.js"
42
+ },
28
43
  "./inject-exclusive": {
29
44
  "types": "./dist/inject-exclusive.d.ts",
30
45
  "import": "./dist/inject-exclusive.js",
@@ -50,7 +65,7 @@
50
65
  "devDependencies": {
51
66
  "prettier": "^3.6.2",
52
67
  "typescript": "^5.9.2",
53
- "vite": "^7.1.3",
68
+ "vite": "^7.1.5",
54
69
  "vite-plugin-dts": "^4.5.4",
55
70
  "vite-plugin-solid": "^2.11.8",
56
71
  "vite-plugin-static-copy": "^3.1.2"