@designcrowd/fe-shared-lib 1.6.10-voiceText-1 → 1.6.10-voiceText-3

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 (42) hide show
  1. package/.claude/settings.local.json +4 -9
  2. package/.playwright-cli/{page-2026-04-13T02-23-08-374Z.yml → page-2026-04-15T02-26-54-483Z.yml} +2 -2
  3. package/.playwright-cli/page-2026-04-15T02-27-08-312Z.yml +0 -0
  4. package/.playwright-cli/page-2026-04-15T02-27-25-596Z.yml +0 -0
  5. package/.playwright-cli/page-2026-04-15T02-27-40-203Z.yml +0 -0
  6. package/.playwright-cli/page-2026-04-15T02-38-58-180Z.yml +0 -0
  7. package/.playwright-cli/page-2026-04-15T02-39-01-736Z.yml +26 -0
  8. package/.playwright-cli/page-2026-04-15T02-39-10-233Z.yml +26 -0
  9. package/.playwright-cli/page-2026-04-15T02-39-43-909Z.yml +26 -0
  10. package/.playwright-cli/page-2026-04-15T02-40-44-800Z.yml +0 -0
  11. package/.playwright-cli/page-2026-04-15T02-40-54-188Z.yml +26 -0
  12. package/.playwright-cli/page-2026-04-15T02-40-59-031Z.yml +26 -0
  13. package/.playwright-cli/page-2026-04-15T02-51-07-111Z.yml +0 -0
  14. package/.playwright-cli/page-2026-04-15T02-51-10-941Z.yml +26 -0
  15. package/.playwright-cli/page-2026-04-15T02-51-17-020Z.yml +26 -0
  16. package/.playwright-cli/page-2026-04-15T02-51-42-403Z.yml +2 -0
  17. package/.playwright-cli/page-2026-04-15T02-51-53-552Z.yml +26 -0
  18. package/.playwright-cli/page-2026-04-15T02-51-54-631Z.yml +26 -0
  19. package/.playwright-cli/page-2026-04-15T02-52-16-170Z.yml +26 -0
  20. package/.playwright-cli/page-2026-04-15T02-52-17-246Z.yml +26 -0
  21. package/.playwright-cli/page-2026-04-15T02-52-28-472Z.yml +26 -0
  22. package/.playwright-cli/page-2026-04-15T02-53-15-507Z.yml +0 -0
  23. package/.playwright-cli/page-2026-04-15T02-53-16-554Z.yml +26 -0
  24. package/.playwright-cli/page-2026-04-15T02-53-22-178Z.yml +26 -0
  25. package/.playwright-cli/page-2026-04-15T02-53-34-973Z.yml +26 -0
  26. package/docs/voice-to-text-discussion-attachments/Screenshot 2026-04-15 at 11.44.18/342/200/257am.png +0 -0
  27. package/docs/voice-to-text-discussion-attachments/image.png +0 -0
  28. package/docs/voice-to-text-discussion-attachments/image_1.png +0 -0
  29. package/docs/voice-to-text-discussion-attachments/image_2.png +0 -0
  30. package/docs/voice-to-text-discussion-attachments/image_3.png +0 -0
  31. package/docs/voice-to-text-discussion-attachments/image_4.png +0 -0
  32. package/docs/voice-to-text-discussion.md +330 -0
  33. package/package.json +1 -1
  34. package/public/css/tailwind-brandCrowd.css +8 -4
  35. package/public/css/tailwind-brandPage.css +8 -4
  36. package/public/css/tailwind-crazyDomains.css +8 -4
  37. package/public/css/tailwind-designCom.css +8 -4
  38. package/public/css/tailwind-designCrowd.css +8 -4
  39. package/src/atoms/components/VoiceToTextButton/VoiceToTextButton.stories.js +147 -10
  40. package/src/atoms/components/VoiceToTextButton/VoiceToTextButton.vue +31 -7
  41. package/src/useVoiceToText.js +1 -0
  42. package/.playwright-cli/page-2026-04-13T02-23-13-730Z.yml +0 -421
@@ -27,6 +27,7 @@ export const PromptInputDemo = () => ({
27
27
  class="tw-flex-1 tw-bg-transparent tw-border-none tw-text-white tw-placeholder-grayscale-500 focus:tw-outline-none tw-text-base"
28
28
  />
29
29
  <VoiceToTextButton
30
+ variant="dark"
30
31
  size="md"
31
32
  @on-transcript="transcript = $event"
32
33
  @on-interim-transcript="transcript = $event"
@@ -54,52 +55,188 @@ export const PromptInputDemo = () => ({
54
55
  });
55
56
 
56
57
  PromptInputDemo.story = {
57
- name: 'Prompt Input (Dark Theme)',
58
+ name: 'Dark - Prompt Input',
58
59
  };
59
60
 
60
- export const PromptVariantStates = () => ({
61
+ export const DarkVariantStates = () => ({
61
62
  components: { VoiceToTextButton },
62
63
  template: `
63
64
  <div class="tw-p-8" style="background: #1a1a2e;">
64
- <h3 class="tw-text-white tw-text-lg tw-font-semibold tw-mb-6">Prompt Variant - All States</h3>
65
+ <h3 class="tw-text-white tw-text-lg tw-font-semibold tw-mb-6">Dark Variant - All States</h3>
65
66
 
66
67
  <div class="tw-flex tw-gap-8 tw-items-start">
67
68
  <div class="tw-text-center">
68
69
  <div class="tw-mb-2 tw-p-4 tw-bg-grayscale-800 tw-rounded-lg tw-inline-block">
69
- <VoiceToTextButton size="sm" />
70
+ <VoiceToTextButton variant="dark" size="sm" />
70
71
  </div>
71
72
  <p class="tw-text-grayscale-400 tw-text-xs">Small</p>
72
73
  </div>
73
74
 
74
75
  <div class="tw-text-center">
75
76
  <div class="tw-mb-2 tw-p-4 tw-bg-grayscale-800 tw-rounded-lg tw-inline-block">
76
- <VoiceToTextButton size="md" />
77
+ <VoiceToTextButton variant="dark" size="md" />
77
78
  </div>
78
79
  <p class="tw-text-grayscale-400 tw-text-xs">Medium (default)</p>
79
80
  </div>
80
81
 
81
82
  <div class="tw-text-center">
82
83
  <div class="tw-mb-2 tw-p-4 tw-bg-grayscale-800 tw-rounded-lg tw-inline-block">
83
- <VoiceToTextButton size="lg" />
84
+ <VoiceToTextButton variant="dark" size="lg" />
84
85
  </div>
85
86
  <p class="tw-text-grayscale-400 tw-text-xs">Large</p>
86
87
  </div>
87
88
 
88
89
  <div class="tw-text-center">
89
90
  <div class="tw-mb-2 tw-p-4 tw-bg-grayscale-800 tw-rounded-lg tw-inline-block">
90
- <VoiceToTextButton :disabled="true" />
91
+ <VoiceToTextButton variant="dark" :disabled="true" />
91
92
  </div>
92
93
  <p class="tw-text-grayscale-400 tw-text-xs">Disabled</p>
93
94
  </div>
94
95
  </div>
95
96
 
96
97
  <p class="tw-text-grayscale-500 tw-text-sm tw-mt-6">
97
- Click any button to see the recording state with red ring animation
98
+ Click any button to see the recording state with grey circle indicator
98
99
  </p>
99
100
  </div>
100
101
  `,
101
102
  });
102
103
 
103
- PromptVariantStates.story = {
104
- name: 'Prompt Variant States',
104
+ DarkVariantStates.story = {
105
+ name: 'Dark - Variant States',
106
+ };
107
+
108
+ export const LightInputDemo = () => ({
109
+ components: { VoiceToTextButton },
110
+ data() {
111
+ return {
112
+ transcript: '',
113
+ isListening: false,
114
+ error: null,
115
+ };
116
+ },
117
+ template: `
118
+ <div class="tw-min-h-[400px] tw-p-8 tw-flex tw-flex-col tw-items-center tw-justify-center tw-bg-white">
119
+ <h1 class="tw-text-grayscale-800 tw-text-3xl tw-font-bold tw-mb-2 tw-text-center">Search</h1>
120
+ <p class="tw-text-grayscale-600 tw-mb-8 tw-text-center">Find what you're looking for</p>
121
+
122
+ <div class="tw-w-full tw-max-w-xl tw-bg-grayscale-100 tw-rounded-full tw-px-6 tw-py-3 tw-flex tw-items-center tw-gap-3 tw-border tw-border-grayscale-300">
123
+ <input
124
+ v-model="transcript"
125
+ type="text"
126
+ placeholder="Type to search..."
127
+ class="tw-flex-1 tw-bg-transparent tw-border-none tw-text-grayscale-800 tw-placeholder-grayscale-500 focus:tw-outline-none tw-text-base"
128
+ />
129
+ <VoiceToTextButton
130
+ variant="light"
131
+ size="md"
132
+ @on-transcript="transcript = $event"
133
+ @on-interim-transcript="transcript = $event"
134
+ @on-start="isListening = true; error = null"
135
+ @on-stop="isListening = false"
136
+ @on-error="error = $event"
137
+ />
138
+ </div>
139
+
140
+ <div class="tw-mt-4 tw-text-sm tw-h-6">
141
+ <p v-if="isListening" class="tw-text-error-500 tw-font-medium">
142
+ Recording... speak now
143
+ </p>
144
+ <p v-else-if="error" class="tw-text-error-400">
145
+ {{ error }}
146
+ </p>
147
+ </div>
148
+ </div>
149
+ `,
150
+ });
151
+
152
+ LightInputDemo.story = {
153
+ name: 'Light - Search Input',
154
+ };
155
+
156
+ export const LightVariantStates = () => ({
157
+ components: { VoiceToTextButton },
158
+ template: `
159
+ <div class="tw-p-8 tw-bg-white">
160
+ <h3 class="tw-text-grayscale-800 tw-text-lg tw-font-semibold tw-mb-6">Light Variant - All States</h3>
161
+
162
+ <div class="tw-flex tw-gap-8 tw-items-start">
163
+ <div class="tw-text-center">
164
+ <div class="tw-mb-2 tw-p-4 tw-bg-grayscale-100 tw-rounded-lg tw-inline-block">
165
+ <VoiceToTextButton variant="light" size="sm" />
166
+ </div>
167
+ <p class="tw-text-grayscale-600 tw-text-xs">Small</p>
168
+ </div>
169
+
170
+ <div class="tw-text-center">
171
+ <div class="tw-mb-2 tw-p-4 tw-bg-grayscale-100 tw-rounded-lg tw-inline-block">
172
+ <VoiceToTextButton variant="light" size="md" />
173
+ </div>
174
+ <p class="tw-text-grayscale-600 tw-text-xs">Medium (default)</p>
175
+ </div>
176
+
177
+ <div class="tw-text-center">
178
+ <div class="tw-mb-2 tw-p-4 tw-bg-grayscale-100 tw-rounded-lg tw-inline-block">
179
+ <VoiceToTextButton variant="light" size="lg" />
180
+ </div>
181
+ <p class="tw-text-grayscale-600 tw-text-xs">Large</p>
182
+ </div>
183
+
184
+ <div class="tw-text-center">
185
+ <div class="tw-mb-2 tw-p-4 tw-bg-grayscale-100 tw-rounded-lg tw-inline-block">
186
+ <VoiceToTextButton variant="light" :disabled="true" />
187
+ </div>
188
+ <p class="tw-text-grayscale-600 tw-text-xs">Disabled</p>
189
+ </div>
190
+ </div>
191
+
192
+ <p class="tw-text-grayscale-500 tw-text-sm tw-mt-6">
193
+ Click any button to see the recording state with grey circle indicator
194
+ </p>
195
+ </div>
196
+ `,
197
+ });
198
+
199
+ LightVariantStates.story = {
200
+ name: 'Light - Variant States',
201
+ };
202
+
203
+ export const SideBySide = () => ({
204
+ components: { VoiceToTextButton },
205
+ template: `
206
+ <div class="tw-flex tw-min-h-[300px]">
207
+ <div class="tw-flex-1 tw-p-8 tw-flex tw-flex-col tw-items-center tw-justify-center" style="background: #1a1a2e;">
208
+ <h3 class="tw-text-white tw-text-lg tw-font-semibold tw-mb-6">Dark Variant</h3>
209
+ <div class="tw-flex tw-gap-4 tw-items-center">
210
+ <div class="tw-p-3 tw-bg-grayscale-800 tw-rounded-lg">
211
+ <VoiceToTextButton variant="dark" size="sm" />
212
+ </div>
213
+ <div class="tw-p-3 tw-bg-grayscale-800 tw-rounded-lg">
214
+ <VoiceToTextButton variant="dark" size="md" />
215
+ </div>
216
+ <div class="tw-p-3 tw-bg-grayscale-800 tw-rounded-lg">
217
+ <VoiceToTextButton variant="dark" size="lg" />
218
+ </div>
219
+ </div>
220
+ </div>
221
+
222
+ <div class="tw-flex-1 tw-p-8 tw-flex tw-flex-col tw-items-center tw-justify-center tw-bg-white">
223
+ <h3 class="tw-text-grayscale-800 tw-text-lg tw-font-semibold tw-mb-6">Light Variant</h3>
224
+ <div class="tw-flex tw-gap-4 tw-items-center">
225
+ <div class="tw-p-3 tw-bg-grayscale-100 tw-rounded-lg">
226
+ <VoiceToTextButton variant="light" size="sm" />
227
+ </div>
228
+ <div class="tw-p-3 tw-bg-grayscale-100 tw-rounded-lg">
229
+ <VoiceToTextButton variant="light" size="md" />
230
+ </div>
231
+ <div class="tw-p-3 tw-bg-grayscale-100 tw-rounded-lg">
232
+ <VoiceToTextButton variant="light" size="lg" />
233
+ </div>
234
+ </div>
235
+ </div>
236
+ </div>
237
+ `,
238
+ });
239
+
240
+ SideBySide.story = {
241
+ name: 'Side by Side Comparison',
105
242
  };
@@ -5,18 +5,21 @@
5
5
  :disabled="disabled"
6
6
  :aria-label="isListening ? 'Stop voice input' : 'Start voice input'"
7
7
  data-test="voice-to-text-button"
8
- class="voice-prompt-button tw-rounded-full tw-border-2 tw-bg-transparent tw-flex tw-items-center tw-justify-center tw-transition-all tw-duration-200 tw-cursor-pointer focus:tw-outline-none focus:tw-ring-2 focus:tw-ring-offset-2 focus:tw-ring-primary-500"
8
+ class="voice-prompt-button tw-rounded-full tw-border-0 tw-flex tw-items-center tw-justify-center tw-transition-all tw-duration-200 tw-cursor-pointer focus:tw-outline-none focus-visible:tw-ring-2 focus-visible:tw-ring-offset-2 focus-visible:tw-ring-primary-500"
9
9
  :class="[
10
10
  sizeClasses,
11
- isListening ? 'voice-prompt-listening tw-border-error-500' : 'tw-border-grayscale-400 hover:tw-border-grayscale-300',
11
+ variantClasses.button,
12
+ isListening ? 'voice-prompt-listening' : '',
12
13
  disabled ? 'tw-opacity-50 tw-cursor-not-allowed' : '',
13
14
  ]"
15
+ :style="isListening ? { '--voice-bg': variantClasses.recordingBg } : {}"
14
16
  @click="toggle"
15
17
  >
16
18
  <Icon
17
19
  name="microphone"
18
20
  :size="iconSize"
19
- :class="isListening ? 'tw-text-error-500' : 'tw-text-grayscale-400'"
21
+ :class="variantClasses.icon"
22
+ aria-hidden="true"
20
23
  />
21
24
  </button>
22
25
  </template>
@@ -40,6 +43,11 @@ const props = defineProps({
40
43
  default: 'md',
41
44
  validator: (value) => ['sm', 'md', 'lg'].includes(value),
42
45
  },
46
+ variant: {
47
+ type: String,
48
+ default: 'dark',
49
+ validator: (value) => ['light', 'dark'].includes(value),
50
+ },
43
51
  });
44
52
 
45
53
  const sizeClasses = computed(() => {
@@ -66,6 +74,21 @@ const { isSupported, isListening, transcript, isFinal, error, toggle, setLang }
66
74
  lang: props.lang,
67
75
  });
68
76
 
77
+ const variantClasses = computed(() => {
78
+ if (props.variant === 'light') {
79
+ return {
80
+ button: isListening.value ? '' : 'tw-bg-transparent hover:tw-bg-grayscale-200',
81
+ icon: isListening.value ? 'tw-text-grayscale-700' : 'tw-text-grayscale-600',
82
+ recordingBg: '#EDEDED',
83
+ };
84
+ }
85
+ return {
86
+ button: isListening.value ? '' : 'tw-bg-transparent hover:tw-bg-grayscale-700',
87
+ icon: isListening.value ? 'tw-text-white' : 'tw-text-grayscale-400',
88
+ recordingBg: '#606060',
89
+ };
90
+ });
91
+
69
92
  // Keep recognition language in sync with prop
70
93
  watch(toRef(props, 'lang'), setLang);
71
94
 
@@ -106,16 +129,17 @@ watch(error, (newError) => {
106
129
  }
107
130
 
108
131
  .voice-prompt-listening {
109
- animation: voice-ring-pulse 1.5s ease-in-out infinite;
132
+ background-color: var(--voice-bg);
133
+ animation: voice-bg-pulse 2s ease-in-out infinite;
110
134
  }
111
135
 
112
- @keyframes voice-ring-pulse {
136
+ @keyframes voice-bg-pulse {
113
137
  0%,
114
138
  100% {
115
- box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.4);
139
+ opacity: 1;
116
140
  }
117
141
  50% {
118
- box-shadow: 0 0 0 6px rgba(239, 68, 68, 0);
142
+ opacity: 0.5;
119
143
  }
120
144
  }
121
145
  </style>
@@ -134,6 +134,7 @@ export function useVoiceToText(options = {}) {
134
134
  const stop = () => {
135
135
  if (!recognition || !isListening.value) return;
136
136
 
137
+ isListening.value = false;
137
138
  try {
138
139
  recognition.stop();
139
140
  } catch (e) {