kempo-ui 0.4.2 → 0.4.4

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.
Files changed (104) hide show
  1. package/.claude/skills/get-icon/SKILL.md +144 -0
  2. package/.claude/skills/highlight-code/SKILL.md +62 -0
  3. package/.claude/skills/new-component/SKILL.md +362 -0
  4. package/.github/skills/get-icon/SKILL.md +4 -4
  5. package/.github/skills/highlight-code/SKILL.md +51 -20
  6. package/.github/skills/new-component/SKILL.md +183 -152
  7. package/AGENTS.md +2 -2
  8. package/dist/components/Calendar.js +170 -0
  9. package/dist/components/SpeechToText.js +60 -0
  10. package/dist/components/TextToSpeech.js +56 -0
  11. package/dist/components/Time.js +37 -0
  12. package/docs/components/accordion.html +16 -0
  13. package/docs/components/aside.html +16 -0
  14. package/docs/components/calendar.html +720 -0
  15. package/docs/components/card.html +16 -0
  16. package/docs/components/code-editor.html +16 -0
  17. package/docs/components/color-picker.html +16 -0
  18. package/docs/components/combobox.html +16 -0
  19. package/docs/components/content-slider.html +16 -0
  20. package/docs/components/context.html +16 -0
  21. package/docs/components/dialog.html +16 -0
  22. package/docs/components/dropdown.html +16 -0
  23. package/docs/components/filter-list.html +16 -0
  24. package/docs/components/focus-capture.html +16 -0
  25. package/docs/components/html-editor.html +16 -0
  26. package/docs/components/hybrid-component.html +16 -0
  27. package/docs/components/icon.html +16 -0
  28. package/docs/components/import.html +16 -0
  29. package/docs/components/light-component.html +16 -0
  30. package/docs/components/nav-spacer.html +16 -0
  31. package/docs/components/nav.html +16 -0
  32. package/docs/components/photo-viewer.html +16 -0
  33. package/docs/components/progress.html +16 -0
  34. package/docs/components/resize.html +16 -0
  35. package/docs/components/shadow-component.html +16 -0
  36. package/docs/components/show-more.html +16 -0
  37. package/docs/components/slider.html +16 -0
  38. package/docs/components/sortable.html +16 -0
  39. package/docs/components/speech-to-text.html +717 -0
  40. package/docs/components/spinner.html +16 -0
  41. package/docs/components/split.html +16 -0
  42. package/docs/components/table.html +16 -0
  43. package/docs/components/tableControls.html +16 -0
  44. package/docs/components/tableCustomFields.html +16 -0
  45. package/docs/components/tableFetchRecords.html +16 -0
  46. package/docs/components/tableFieldSortHide.html +16 -0
  47. package/docs/components/tablePagination.html +16 -0
  48. package/docs/components/tablePlaceholder.html +16 -0
  49. package/docs/components/tableRecordEditing.html +16 -0
  50. package/docs/components/tableRecordFiltering.html +16 -0
  51. package/docs/components/tableRecordHiding.html +16 -0
  52. package/docs/components/tableRecordSearching.html +16 -0
  53. package/docs/components/tableRecordSelection.html +16 -0
  54. package/docs/components/tableRowControls.html +16 -0
  55. package/docs/components/tableServerSync.html +16 -0
  56. package/docs/components/tableSorting.html +16 -0
  57. package/docs/components/tabs.html +16 -0
  58. package/docs/components/tags.html +16 -0
  59. package/docs/components/text-to-speech.html +668 -0
  60. package/docs/components/theme-select.html +16 -0
  61. package/docs/components/theme-switcher.html +16 -0
  62. package/docs/components/time.html +670 -0
  63. package/docs/components/timestamp.html +16 -0
  64. package/docs/components/toast.html +16 -0
  65. package/docs/components/toggle.html +16 -0
  66. package/docs/components/tree.html +16 -0
  67. package/docs/icons/mic.svg +1 -0
  68. package/docs/icons/record_voice_over.svg +1 -0
  69. package/docs/icons/stop.svg +1 -0
  70. package/docs/index.html +40 -0
  71. package/docs/src/components/Calendar.js +170 -0
  72. package/docs/src/components/SpeechToText.js +60 -0
  73. package/docs/src/components/TextToSpeech.js +56 -0
  74. package/docs/src/components/Time.js +37 -0
  75. package/docs/utils/context.html +16 -0
  76. package/docs/utils/cookie.html +16 -0
  77. package/docs/utils/debounce.html +16 -0
  78. package/docs/utils/drag.html +16 -0
  79. package/docs/utils/elevation.html +16 -0
  80. package/docs/utils/formatTimestamp.html +16 -0
  81. package/docs/utils/object.html +16 -0
  82. package/docs/utils/propConverters.html +16 -0
  83. package/docs/utils/string.html +16 -0
  84. package/docs/utils/theme.html +16 -0
  85. package/docs/utils/toTitleCase.html +16 -0
  86. package/docs/utils/type.html +16 -0
  87. package/docs/utils/wait.html +16 -0
  88. package/docs-src/components/calendar.page.html +254 -0
  89. package/docs-src/components/speech-to-text.page.html +251 -0
  90. package/docs-src/components/text-to-speech.page.html +202 -0
  91. package/docs-src/components/time.page.html +204 -0
  92. package/docs-src/index.page.html +24 -0
  93. package/docs-src/nav.fragment.html +16 -0
  94. package/icons/mic.svg +1 -0
  95. package/icons/record_voice_over.svg +1 -0
  96. package/icons/stop.svg +1 -0
  97. package/llms.txt +4 -0
  98. package/package.json +1 -1
  99. package/src/components/Calendar.js +473 -0
  100. package/src/components/SpeechToText.js +252 -0
  101. package/src/components/TextToSpeech.js +194 -0
  102. package/src/components/Time.js +137 -0
  103. package/tests/components/SpeechToText.browser-test.js +530 -0
  104. package/tests/components/TextToSpeech.browser-test.js +432 -0
@@ -0,0 +1,251 @@
1
+ <page pageName="Speech To Text" title="Speech To Text - Components - Kempo Docs - A Web Components Solution">
2
+ <content>
3
+ <k-accordion persistent-id="toc" class="b r mb">
4
+ <k-accordion-header for-panel="toc-panel">Table of Contents</k-accordion-header>
5
+ <k-accordion-panel name="toc-panel">
6
+ <div class="m pl">
7
+ <h6>Examples</h6>
8
+ <a href="#basicUsage">Basic Usage</a><br />
9
+ <a href="#liveTranscript">Live Transcript</a><br />
10
+ <a href="#continuous">Continuous</a><br />
11
+ <a href="#language">Language</a><br />
12
+ <a href="#minConfidence">Min Confidence</a><br />
13
+ <a href="#timeout">Timeout</a><br />
14
+ <a href="#disabled">Disabled</a><br />
15
+
16
+ <h6 class="mt"><a href="#jsRef" class="no-link">JavaScript Reference</a></h6>
17
+ <a href="#constructor">Constructor</a><br />
18
+ <a href="#requirements">Requirements</a><br />
19
+ <a href="#properties">Properties</a><br />
20
+ <a href="#methods">Methods</a><br />
21
+ <a href="#cssVariables">CSS Variables</a><br />
22
+ <a href="#events">Events</a><br />
23
+ </div>
24
+ </k-accordion-panel>
25
+ </k-accordion>
26
+
27
+ <p>Wraps the browser's <a href="https://developer.mozilla.org/en-US/docs/Web/API/SpeechRecognition" target="_blank">Web Speech API</a> in a single microphone button. Click the button to start listening; the browser stops automatically when the user pauses (or click again to stop manually). Requires a secure context (HTTPS or <code>localhost</code>) and a Chromium-based browser at the time of writing.</p>
28
+
29
+ <h3 id="basicUsage"><a href="#basicUsage" class="no-link">Basic Usage</a></h3>
30
+ <p>The simplest setup &mdash; click the mic, speak, and the recognized text appears in the paragraph when you stop. The <code>end</code> event fires once with the full transcript.</p>
31
+ <div class="row -mx">
32
+ <div class="col m-span-12 px">
33
+ <k-card label="HTML">
34
+ <pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">k-speech-to-text</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;basicSpeech&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">k-speech-to-text</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;basicSpeechOutput&quot;</span>&gt;</span>(say something...)<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="language-javascript"><br> <span class="hljs-keyword">const</span> $stt = <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">getElementById</span>(<span class="hljs-string">&#x27;basicSpeech&#x27;</span>);<br> <span class="hljs-keyword">const</span> $out = <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">getElementById</span>(<span class="hljs-string">&#x27;basicSpeechOutput&#x27;</span>);<br> $stt.<span class="hljs-title function_">addEventListener</span>(<span class="hljs-string">&#x27;end&#x27;</span>, <span class="hljs-function">(<span class="hljs-params">e</span>) =&gt;</span> {<br> $out.<span class="hljs-property">textContent</span> = e.<span class="hljs-property">detail</span>.<span class="hljs-property">text</span> || <span class="hljs-string">&#x27;(nothing heard)&#x27;</span>;<br> });<br></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></code></pre>
35
+ </k-card>
36
+ </div>
37
+ <div class="col m-span-12 px">
38
+ <k-card label="Output">
39
+ <k-speech-to-text id="basicSpeech"></k-speech-to-text>
40
+ <p id="basicSpeechOutput" class="mt">(say something...)</p>
41
+ <script>
42
+ const $stt = document.getElementById('basicSpeech');
43
+ const $out = document.getElementById('basicSpeechOutput');
44
+ $stt.addEventListener('end', (e) => {
45
+ $out.textContent = e.detail.text || '(nothing heard)';
46
+ });
47
+ </script>
48
+ </k-card>
49
+ </div>
50
+ </div>
51
+
52
+ <h3 id="liveTranscript"><a href="#liveTranscript" class="no-link">Live Transcript</a></h3>
53
+ <p>Add the <code>interim</code> attribute and listen for the <code>result</code> event to update the paragraph as the user speaks. <code>detail.isFinal</code> indicates whether the chunk is finalized.</p>
54
+ <div class="row -mx">
55
+ <div class="col m-span-12 px">
56
+ <k-card label="HTML">
57
+ <pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">k-speech-to-text</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;liveSpeech&quot;</span> <span class="hljs-attr">interim</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">k-speech-to-text</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;liveSpeechOutput&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="language-javascript"><br> <span class="hljs-keyword">const</span> $stt = <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">getElementById</span>(<span class="hljs-string">&#x27;liveSpeech&#x27;</span>);<br> <span class="hljs-keyword">const</span> $out = <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">getElementById</span>(<span class="hljs-string">&#x27;liveSpeechOutput&#x27;</span>);<br> $stt.<span class="hljs-title function_">addEventListener</span>(<span class="hljs-string">&#x27;result&#x27;</span>, <span class="hljs-function">(<span class="hljs-params">e</span>) =&gt;</span> {<br> $out.<span class="hljs-property">textContent</span> = e.<span class="hljs-property">detail</span>.<span class="hljs-property">text</span>;<br> });<br></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></code></pre>
58
+ </k-card>
59
+ </div>
60
+ <div class="col m-span-12 px">
61
+ <k-card label="Output">
62
+ <k-speech-to-text id="liveSpeech" interim></k-speech-to-text>
63
+ <p id="liveSpeechOutput" class="mt">&nbsp;</p>
64
+ <script>
65
+ const $sttLive = document.getElementById('liveSpeech');
66
+ const $outLive = document.getElementById('liveSpeechOutput');
67
+ $sttLive.addEventListener('result', (e) => {
68
+ $outLive.textContent = e.detail.text;
69
+ });
70
+ </script>
71
+ </k-card>
72
+ </div>
73
+ </div>
74
+
75
+ <h3 id="continuous"><a href="#continuous" class="no-link">Continuous</a></h3>
76
+ <p>By default the recognizer stops automatically after a brief pause. Add <code>continuous</code> so it keeps listening until the user clicks the button a second time.</p>
77
+ <div class="row -mx">
78
+ <div class="col m-span-12 px">
79
+ <k-card label="HTML">
80
+ <pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">k-speech-to-text</span> <span class="hljs-attr">continuous</span> <span class="hljs-attr">interim</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;contSpeech&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">k-speech-to-text</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;contSpeechOutput&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></code></pre>
81
+ </k-card>
82
+ </div>
83
+ <div class="col m-span-12 px">
84
+ <k-card label="Output">
85
+ <k-speech-to-text id="contSpeech" continuous interim></k-speech-to-text>
86
+ <p id="contSpeechOutput" class="mt">&nbsp;</p>
87
+ <script>
88
+ const $sttCont = document.getElementById('contSpeech');
89
+ const $outCont = document.getElementById('contSpeechOutput');
90
+ $sttCont.addEventListener('result', (e) => {
91
+ $outCont.textContent = e.detail.text;
92
+ });
93
+ </script>
94
+ </k-card>
95
+ </div>
96
+ </div>
97
+
98
+ <h3 id="language"><a href="#language" class="no-link">Language</a></h3>
99
+ <p>Set the recognition <code>language</code> using a BCP&#x2011;47 tag (e.g. <code>"es-ES"</code>, <code>"fr-FR"</code>, <code>"de-DE"</code>). Defaults to <code>"en-US"</code>.</p>
100
+ <div class="row -mx">
101
+ <div class="col m-span-12 px">
102
+ <k-card label="HTML">
103
+ <pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">k-speech-to-text</span> <span class="hljs-attr">language</span>=<span class="hljs-string">&quot;es-ES&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">k-speech-to-text</span>&gt;</span></code></pre>
104
+ </k-card>
105
+ </div>
106
+ <div class="col m-span-12 px">
107
+ <k-card label="Output">
108
+ <k-speech-to-text language="es-ES"></k-speech-to-text>
109
+ </k-card>
110
+ </div>
111
+ </div>
112
+
113
+ <h3 id="minConfidence"><a href="#minConfidence" class="no-link">Min Confidence</a></h3>
114
+ <p>Set <code>min-confidence</code> to a number between <code>0</code> and <code>1</code> to drop low-confidence transcripts. Chrome's recognizer reports a confidence score on each finalized result; values below your threshold are skipped (they don't accumulate into <code>end.detail.text</code>). Interim chunks usually have <code>confidence === 0</code> in Chrome, so any positive threshold also filters those out &mdash; useful when you want to ignore background noise or ambient audio. Default is <code>0</code> (no filtering).</p>
115
+ <div class="row -mx">
116
+ <div class="col m-span-12 px">
117
+ <k-card label="HTML">
118
+ <pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">k-speech-to-text</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;confSpeech&quot;</span> <span class="hljs-attr">min-confidence</span>=<span class="hljs-string">&quot;0.7&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">k-speech-to-text</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;confSpeechOutput&quot;</span>&gt;</span>(only confident speech...)<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></code></pre>
119
+ </k-card>
120
+ </div>
121
+ <div class="col m-span-12 px">
122
+ <k-card label="Output">
123
+ <k-speech-to-text id="confSpeech" min-confidence="0.7"></k-speech-to-text>
124
+ <p id="confSpeechOutput" class="mt">(only confident speech...)</p>
125
+ <script>
126
+ const $sttConf = document.getElementById('confSpeech');
127
+ const $outConf = document.getElementById('confSpeechOutput');
128
+ $sttConf.addEventListener('end', (e) => {
129
+ $outConf.textContent = e.detail.text || '(no high-confidence speech detected)';
130
+ });
131
+ </script>
132
+ </k-card>
133
+ </div>
134
+ </div>
135
+
136
+ <h3 id="timeout"><a href="#timeout" class="no-link">Timeout</a></h3>
137
+ <p>Set <code>timeout</code> to the maximum number of seconds the component should listen before stopping itself. The recognition stops automatically and the <code>end</code> event fires with whatever transcript was captured. Default is <code>0</code> (no timeout &mdash; recognition runs until the user stops, or the browser auto-stops on a pause when <code>continuous</code> is unset).</p>
138
+ <div class="row -mx">
139
+ <div class="col m-span-12 px">
140
+ <k-card label="HTML">
141
+ <pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">k-speech-to-text</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;timeoutSpeech&quot;</span> <span class="hljs-attr">timeout</span>=<span class="hljs-string">&quot;5&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">k-speech-to-text</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;timeoutSpeechOutput&quot;</span>&gt;</span>(stops after 5 seconds...)<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></code></pre>
142
+ </k-card>
143
+ </div>
144
+ <div class="col m-span-12 px">
145
+ <k-card label="Output">
146
+ <k-speech-to-text id="timeoutSpeech" timeout="5" continuous interim></k-speech-to-text>
147
+ <p id="timeoutSpeechOutput" class="mt">(stops after 5 seconds...)</p>
148
+ <script>
149
+ const $sttTimeout = document.getElementById('timeoutSpeech');
150
+ const $outTimeout = document.getElementById('timeoutSpeechOutput');
151
+ $sttTimeout.addEventListener('result', (e) => {
152
+ $outTimeout.textContent = e.detail.text;
153
+ });
154
+ $sttTimeout.addEventListener('end', (e) => {
155
+ if(!e.detail.text) $outTimeout.textContent = '(no speech captured)';
156
+ });
157
+ </script>
158
+ </k-card>
159
+ </div>
160
+ </div>
161
+
162
+ <h3 id="disabled"><a href="#disabled" class="no-link">Disabled</a></h3>
163
+ <p>The <code>disabled</code> attribute prevents user interaction. The button also auto-disables when the browser doesn't support the Web Speech API.</p>
164
+ <div class="row -mx">
165
+ <div class="col m-span-12 px">
166
+ <k-card label="HTML">
167
+ <pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">k-speech-to-text</span> <span class="hljs-attr">disabled</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">k-speech-to-text</span>&gt;</span></code></pre>
168
+ </k-card>
169
+ </div>
170
+ <div class="col m-span-12 px">
171
+ <k-card label="Output">
172
+ <k-speech-to-text disabled></k-speech-to-text>
173
+ </k-card>
174
+ </div>
175
+ </div>
176
+
177
+ <h2 id="jsRef"><a href="#jsRef" class="no-link">JavaScript Reference</a></h2>
178
+
179
+ <h3 id="constructor"><a href="#constructor" class="no-link">Constructor</a></h3>
180
+ <h6>Extends <a href="./shadow-component.html">ShadowComponent</a></h6>
181
+ <h5><code>new SpeechToText()</code></h5>
182
+
183
+ <h3 id="requirements"><a href="#requirements" class="no-link">Requirements</a></h3>
184
+ <ul>
185
+ <li><a href="./shadow-component.html">ShadowComponent</a></li>
186
+ <li>A browser that supports <code>SpeechRecognition</code> (Chrome, Edge, Safari 14.1+, etc.) served over HTTPS or <code>localhost</code></li>
187
+ </ul>
188
+
189
+ <h3 id="properties"><a href="#properties" class="no-link">Properties</a></h3>
190
+ <h5><code>language<i>: String</i></code></h5>
191
+ <p>BCP&#x2011;47 language tag passed to the underlying <code>SpeechRecognition.lang</code> (e.g. <code>"en-US"</code>, <code>"es-ES"</code>). Default is <code>"en-US"</code>. Syncs to <code>language</code> attribute.</p>
192
+
193
+ <h5><code>continuous<i>: Boolean</i></code></h5>
194
+ <p>When <code>true</code>, recognition keeps listening past pauses until <code>stop()</code> is called. Default is <code>false</code>. Syncs to <code>continuous</code> attribute.</p>
195
+
196
+ <h5><code>interim<i>: Boolean</i></code></h5>
197
+ <p>When <code>true</code>, the recognizer emits unfinalized results as the user speaks (the <code>result</code> event fires for interim chunks too). Note that the underlying <code>SpeechRecognition.interimResults</code> is always <code>true</code> internally so the <code>end</code> event has a fallback transcript when the engine doesn't finalize; this attribute only controls public <code>result</code> dispatching. Default is <code>false</code>. Syncs to <code>interim</code> attribute.</p>
198
+
199
+ <h5><code>minConfidence<i>: Number</i></code></h5>
200
+ <p>A floor (<code>0</code>&ndash;<code>1</code>) on the confidence score Chrome reports for each result. Anything below the threshold is dropped. Useful for ignoring background noise: at <code>0.7</code> you'll only capture speech the engine is confident about. Default is <code>0</code> (accept everything). Syncs to <code>min-confidence</code> attribute.</p>
201
+
202
+ <h5><code>timeout<i>: Number</i></code></h5>
203
+ <p>Maximum recording duration in seconds. When non-zero, the component automatically calls <code>stop()</code> after this many seconds, firing the <code>end</code> event with the captured transcript. Default is <code>0</code> (no timeout). Syncs to <code>timeout</code> attribute.</p>
204
+
205
+ <h5><code>disabled<i>: Boolean</i></code></h5>
206
+ <p>When <code>true</code>, the button cannot be clicked. Syncs to <code>disabled</code> attribute.</p>
207
+
208
+ <h5><code>listening<i>: Boolean</i></code></h5>
209
+ <p>Read-only-ish state that reflects whether recognition is active. The button shows a pulsing red state while listening. Syncs to <code>listening</code> attribute.</p>
210
+
211
+ <h3 id="methods"><a href="#methods" class="no-link">Methods</a></h3>
212
+ <h5><code>start()<i>: void</i></code></h5>
213
+ <p>Begin listening. No-op if already listening, disabled, or unsupported.</p>
214
+
215
+ <h5><code>stop()<i>: void</i></code></h5>
216
+ <p>Stop listening and finalize the transcript.</p>
217
+
218
+ <h5><code>toggle()<i>: void</i></code></h5>
219
+ <p>Calls <code>start()</code> if idle, <code>stop()</code> if currently listening &mdash; the same behavior as clicking the button.</p>
220
+
221
+ <h3 id="cssVariables"><a href="#cssVariables" class="no-link">CSS Variables</a></h3>
222
+ <table class="b">
223
+ <thead><tr><th>Variable</th><th>Default</th><th>Description</th></tr></thead>
224
+ <tbody>
225
+ <tr><td><code>--btn_size</code></td><td><code>2.5rem</code></td><td>Diameter of the microphone button</td></tr>
226
+ <tr><td><code>--btn_bg</code></td><td><code>var(--c_bg)</code></td><td>Background of the idle button</td></tr>
227
+ <tr><td><code>--btn_bg__listening</code></td><td><code>var(--c_danger, #d32f2f)</code></td><td>Background while actively listening</td></tr>
228
+ <tr><td><code>--btn_tc__listening</code></td><td><code>white</code></td><td>Icon color while listening</td></tr>
229
+ </tbody>
230
+ </table>
231
+
232
+ <h3 id="events"><a href="#events" class="no-link">Events</a></h3>
233
+ <h5><code>start</code></h5>
234
+ <p>Fires when recognition begins.</p>
235
+
236
+ <h5><code>result</code></h5>
237
+ <p>Fires for each recognized chunk. <code>detail</code> contains <code>{ text: String, isFinal: Boolean }</code>. With <code>interim</code> enabled, this fires repeatedly as the user speaks.</p>
238
+
239
+ <h5><code>end</code></h5>
240
+ <p>Fires when recognition stops (auto pause, manual stop, or error). <code>detail</code> contains <code>{ text: String }</code> &mdash; the full final transcript.</p>
241
+
242
+ <h5><code>error</code></h5>
243
+ <p>Fires when the underlying <code>SpeechRecognition</code> reports an error. <code>detail</code> contains <code>{ error: String, message: String }</code>.</p>
244
+ </content>
245
+ <content location="scripts">
246
+ <script type="module" src="{{pathToRoot}}src/components/SpeechToText.js"></script>
247
+ <script type="module" src="{{pathToRoot}}src/components/Icon.js"></script>
248
+ <script type="module" src="{{pathToRoot}}src/components/Accordion.js"></script>
249
+ <script type="module" src="{{pathToRoot}}src/components/Card.js"></script>
250
+ </content>
251
+ </page>
@@ -0,0 +1,202 @@
1
+ <page pageName="Text To Speech" title="Text To Speech - Components - Kempo Docs - A Web Components Solution">
2
+ <content>
3
+ <k-accordion persistent-id="toc" class="b r mb">
4
+ <k-accordion-header for-panel="toc-panel">Table of Contents</k-accordion-header>
5
+ <k-accordion-panel name="toc-panel">
6
+ <div class="m pl">
7
+ <h6>Examples</h6>
8
+ <a href="#basicUsage">Basic Usage</a><br />
9
+ <a href="#slotted">Slotted Text</a><br />
10
+ <a href="#rate">Rate &amp; Pitch</a><br />
11
+ <a href="#language">Language</a><br />
12
+ <a href="#dynamic">Dynamic Text</a><br />
13
+ <a href="#disabled">Disabled</a><br />
14
+
15
+ <h6 class="mt"><a href="#jsRef" class="no-link">JavaScript Reference</a></h6>
16
+ <a href="#constructor">Constructor</a><br />
17
+ <a href="#requirements">Requirements</a><br />
18
+ <a href="#properties">Properties</a><br />
19
+ <a href="#methods">Methods</a><br />
20
+ <a href="#cssVariables">CSS Variables</a><br />
21
+ <a href="#events">Events</a><br />
22
+ </div>
23
+ </k-accordion-panel>
24
+ </k-accordion>
25
+
26
+ <p>Wraps the browser's <a href="https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesis" target="_blank">SpeechSynthesis API</a> in a single button. Click to speak; click again while speaking to stop. Works in all modern browsers (Chromium, Firefox, Safari).</p>
27
+
28
+ <h3 id="basicUsage"><a href="#basicUsage" class="no-link">Basic Usage</a></h3>
29
+ <p>The <code>text</code> attribute holds the phrase to read aloud.</p>
30
+ <div class="row -mx">
31
+ <div class="col m-span-12 px">
32
+ <k-card label="HTML">
33
+ <pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">k-text-to-speech</span> <span class="hljs-attr">text</span>=<span class="hljs-string">&quot;Hello, world!&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">k-text-to-speech</span>&gt;</span></code></pre>
34
+ </k-card>
35
+ </div>
36
+ <div class="col m-span-12 px">
37
+ <k-card label="Output">
38
+ <k-text-to-speech text="Hello, world!"></k-text-to-speech>
39
+ </k-card>
40
+ </div>
41
+ </div>
42
+
43
+ <h3 id="slotted"><a href="#slotted" class="no-link">Slotted Text</a></h3>
44
+ <p>If <code>text</code> is not set, the element's text content is spoken. Useful when the text is longer or already lives in the DOM.</p>
45
+ <div class="row -mx">
46
+ <div class="col m-span-12 px">
47
+ <k-card label="HTML">
48
+ <pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">k-text-to-speech</span>&gt;</span>The quick brown fox jumps over the lazy dog.<span class="hljs-tag">&lt;/<span class="hljs-name">k-text-to-speech</span>&gt;</span></code></pre>
49
+ </k-card>
50
+ </div>
51
+ <div class="col m-span-12 px">
52
+ <k-card label="Output">
53
+ <k-text-to-speech>The quick brown fox jumps over the lazy dog.</k-text-to-speech>
54
+ </k-card>
55
+ </div>
56
+ </div>
57
+
58
+ <h3 id="rate"><a href="#rate" class="no-link">Rate &amp; Pitch</a></h3>
59
+ <p>Tune playback with the <code>rate</code> (<code>0.1</code>&ndash;<code>10</code>, default <code>1</code>) and <code>pitch</code> (<code>0</code>&ndash;<code>2</code>, default <code>1</code>) attributes. <code>volume</code> (<code>0</code>&ndash;<code>1</code>, default <code>1</code>) is also available.</p>
60
+ <div class="row -mx">
61
+ <div class="col m-span-12 px">
62
+ <k-card label="HTML">
63
+ <pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">k-text-to-speech</span> <span class="hljs-attr">text</span>=<span class="hljs-string">&quot;Wow that is fast&quot;</span> <span class="hljs-attr">rate</span>=<span class="hljs-string">&quot;2&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">k-text-to-speech</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">k-text-to-speech</span> <span class="hljs-attr">text</span>=<span class="hljs-string">&quot;A bit higher pitch&quot;</span> <span class="hljs-attr">pitch</span>=<span class="hljs-string">&quot;1.6&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">k-text-to-speech</span>&gt;</span></code></pre>
64
+ </k-card>
65
+ </div>
66
+ <div class="col m-span-12 px">
67
+ <k-card label="Output">
68
+ <k-text-to-speech text="Wow that is fast" rate="2" class="mr"></k-text-to-speech>
69
+ <k-text-to-speech text="A bit higher pitch" pitch="1.6"></k-text-to-speech>
70
+ </k-card>
71
+ </div>
72
+ </div>
73
+
74
+ <h3 id="language"><a href="#language" class="no-link">Language</a></h3>
75
+ <p>Set <code>language</code> to a BCP&#x2011;47 tag to pick a localized voice (browser-dependent &mdash; the OS-installed voices determine availability).</p>
76
+ <div class="row -mx">
77
+ <div class="col m-span-12 px">
78
+ <k-card label="HTML">
79
+ <pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">k-text-to-speech</span> <span class="hljs-attr">text</span>=<span class="hljs-string">&quot;Bonjour le monde&quot;</span> <span class="hljs-attr">language</span>=<span class="hljs-string">&quot;fr-FR&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">k-text-to-speech</span>&gt;</span></code></pre>
80
+ </k-card>
81
+ </div>
82
+ <div class="col m-span-12 px">
83
+ <k-card label="Output">
84
+ <k-text-to-speech text="Bonjour le monde" language="fr-FR"></k-text-to-speech>
85
+ </k-card>
86
+ </div>
87
+ </div>
88
+
89
+ <h3 id="dynamic"><a href="#dynamic" class="no-link">Dynamic Text</a></h3>
90
+ <p>Set the <code>text</code> property at runtime to read whatever is in an input or other DOM source.</p>
91
+ <div class="row -mx">
92
+ <div class="col m-span-12 px">
93
+ <k-card label="HTML">
94
+ <pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">k-text-to-speech</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;ttsExample&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">k-text-to-speech</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;ttsInput&quot;</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;Type something then click the button&quot;</span> /&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="language-javascript"><br> <span class="hljs-keyword">const</span> $tts = <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">getElementById</span>(<span class="hljs-string">&#x27;ttsExample&#x27;</span>);<br> <span class="hljs-keyword">const</span> $input = <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">getElementById</span>(<span class="hljs-string">&#x27;ttsInput&#x27;</span>);<br> $input.<span class="hljs-title function_">addEventListener</span>(<span class="hljs-string">&#x27;input&#x27;</span>, <span class="hljs-function">() =&gt;</span> {<br> $tts.<span class="hljs-property">text</span> = $input.<span class="hljs-property">value</span>;<br> });<br> $tts.<span class="hljs-property">text</span> = $input.<span class="hljs-property">value</span>;<br></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></code></pre>
95
+ </k-card>
96
+ </div>
97
+ <div class="col m-span-12 px">
98
+ <k-card label="Output">
99
+ <k-text-to-speech id="ttsExample" class="mr"></k-text-to-speech>
100
+ <input id="ttsInput" type="text" value="Type something then click the button" />
101
+ <script>
102
+ const $tts = document.getElementById('ttsExample');
103
+ const $input = document.getElementById('ttsInput');
104
+ $input.addEventListener('input', () => {
105
+ $tts.text = $input.value;
106
+ });
107
+ $tts.text = $input.value;
108
+ </script>
109
+ </k-card>
110
+ </div>
111
+ </div>
112
+
113
+ <h3 id="disabled"><a href="#disabled" class="no-link">Disabled</a></h3>
114
+ <p>The <code>disabled</code> attribute prevents user interaction. The button also auto-disables when the browser doesn't support the SpeechSynthesis API.</p>
115
+ <div class="row -mx">
116
+ <div class="col m-span-12 px">
117
+ <k-card label="HTML">
118
+ <pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">k-text-to-speech</span> <span class="hljs-attr">disabled</span> <span class="hljs-attr">text</span>=<span class="hljs-string">&quot;You can't hear this&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">k-text-to-speech</span>&gt;</span></code></pre>
119
+ </k-card>
120
+ </div>
121
+ <div class="col m-span-12 px">
122
+ <k-card label="Output">
123
+ <k-text-to-speech disabled text="You can't hear this"></k-text-to-speech>
124
+ </k-card>
125
+ </div>
126
+ </div>
127
+
128
+ <h2 id="jsRef"><a href="#jsRef" class="no-link">JavaScript Reference</a></h2>
129
+
130
+ <h3 id="constructor"><a href="#constructor" class="no-link">Constructor</a></h3>
131
+ <h6>Extends <a href="./shadow-component.html">ShadowComponent</a></h6>
132
+ <h5><code>new TextToSpeech()</code></h5>
133
+
134
+ <h3 id="requirements"><a href="#requirements" class="no-link">Requirements</a></h3>
135
+ <ul>
136
+ <li><a href="./shadow-component.html">ShadowComponent</a></li>
137
+ <li>A browser with <code>window.speechSynthesis</code> (all major modern browsers)</li>
138
+ </ul>
139
+
140
+ <h3 id="properties"><a href="#properties" class="no-link">Properties</a></h3>
141
+ <h5><code>text<i>: String</i></code></h5>
142
+ <p>The text to speak. When empty, the element's slotted text content is used. Syncs to <code>text</code> attribute.</p>
143
+
144
+ <h5><code>voice<i>: String</i></code></h5>
145
+ <p>Optional voice name (matched against <code>speechSynthesis.getVoices()</code>). Falls back to the default voice for the language. Syncs to <code>voice</code> attribute.</p>
146
+
147
+ <h5><code>language<i>: String</i></code></h5>
148
+ <p>BCP&#x2011;47 language tag (e.g. <code>"en-US"</code>, <code>"fr-FR"</code>). Default is empty (browser default). Syncs to <code>language</code> attribute.</p>
149
+
150
+ <h5><code>rate<i>: Number</i></code></h5>
151
+ <p>Speech rate from <code>0.1</code> (slow) to <code>10</code> (fast). Default is <code>1</code>. Syncs to <code>rate</code> attribute.</p>
152
+
153
+ <h5><code>pitch<i>: Number</i></code></h5>
154
+ <p>Pitch from <code>0</code> to <code>2</code>. Default is <code>1</code>. Syncs to <code>pitch</code> attribute.</p>
155
+
156
+ <h5><code>volume<i>: Number</i></code></h5>
157
+ <p>Volume from <code>0</code> (silent) to <code>1</code> (loud). Default is <code>1</code>. Syncs to <code>volume</code> attribute.</p>
158
+
159
+ <h5><code>disabled<i>: Boolean</i></code></h5>
160
+ <p>When <code>true</code>, the button cannot be clicked. Syncs to <code>disabled</code> attribute.</p>
161
+
162
+ <h5><code>speaking<i>: Boolean</i></code></h5>
163
+ <p>Reflects whether the component is currently speaking. The button shows the stop icon and switches to the active color while <code>true</code>. Syncs to <code>speaking</code> attribute.</p>
164
+
165
+ <h3 id="methods"><a href="#methods" class="no-link">Methods</a></h3>
166
+ <h5><code>speak(textOverride?)<i>: void</i></code></h5>
167
+ <p>Begin speaking. If <code>textOverride</code> is supplied, it is spoken instead of <code>text</code>/slot content. Cancels any in-flight utterance first.</p>
168
+
169
+ <h5><code>stop()<i>: void</i></code></h5>
170
+ <p>Cancel any speech in progress.</p>
171
+
172
+ <h5><code>toggle()<i>: void</i></code></h5>
173
+ <p>Calls <code>stop()</code> if currently speaking, otherwise <code>speak()</code> &mdash; the same behavior as clicking the button.</p>
174
+
175
+ <h3 id="cssVariables"><a href="#cssVariables" class="no-link">CSS Variables</a></h3>
176
+ <table class="b">
177
+ <thead><tr><th>Variable</th><th>Default</th><th>Description</th></tr></thead>
178
+ <tbody>
179
+ <tr><td><code>--btn_size</code></td><td><code>2.5rem</code></td><td>Diameter of the button</td></tr>
180
+ <tr><td><code>--btn_bg</code></td><td><code>var(--c_bg)</code></td><td>Background of the idle button</td></tr>
181
+ <tr><td><code>--btn_bg__speaking</code></td><td><code>var(--c_primary)</code></td><td>Background while actively speaking</td></tr>
182
+ <tr><td><code>--btn_tc__speaking</code></td><td><code>white</code></td><td>Icon color while speaking</td></tr>
183
+ </tbody>
184
+ </table>
185
+
186
+ <h3 id="events"><a href="#events" class="no-link">Events</a></h3>
187
+ <h5><code>start</code></h5>
188
+ <p>Fires when speech begins.</p>
189
+
190
+ <h5><code>end</code></h5>
191
+ <p>Fires when speech finishes (naturally or via <code>stop()</code>).</p>
192
+
193
+ <h5><code>error</code></h5>
194
+ <p>Fires if the underlying <code>SpeechSynthesisUtterance</code> reports an error. <code>detail</code> contains <code>{ error: String }</code>.</p>
195
+ </content>
196
+ <content location="scripts">
197
+ <script type="module" src="{{pathToRoot}}src/components/TextToSpeech.js"></script>
198
+ <script type="module" src="{{pathToRoot}}src/components/Icon.js"></script>
199
+ <script type="module" src="{{pathToRoot}}src/components/Accordion.js"></script>
200
+ <script type="module" src="{{pathToRoot}}src/components/Card.js"></script>
201
+ </content>
202
+ </page>