voice-page-agent 2.7.2 → 2.7.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.
package/README.md CHANGED
@@ -51,7 +51,18 @@ Use this shape:
51
51
  commandMaxWindowMs: 22000, // max command listening window
52
52
  recognitionLang: "zh-CN", // SpeechRecognition language
53
53
  showAgentWhenWake: true, // auto-open panel when wake hit
54
- autoStart: false // start wake on init
54
+ autoStart: false, // start wake on init
55
+ buttonText: {
56
+ startText: "开始唤醒",
57
+ wakeOnText: "语音唤醒中",
58
+ openText: "打开助手",
59
+ },
60
+ buttonStyle: {
61
+ wakeButtonBackground: "linear-gradient(135deg, #22c1ff, #3366ff)",
62
+ wakeButtonTextColor: "#ffffff",
63
+ openButtonBackground: "linear-gradient(135deg, #ffa84a, #ff5f6d)",
64
+ openButtonTextColor: "#ffffff",
65
+ }
55
66
  }
56
67
  ```
57
68
 
@@ -72,6 +83,15 @@ app.use(VoicePageAgentPlugin, {
72
83
  },
73
84
  wakeWord: "布丁布丁",
74
85
  enableHomophoneMatch: true,
86
+ buttonText: {
87
+ startText: "开始语音",
88
+ wakeOnText: "语音进行中",
89
+ openText: "网页助手",
90
+ },
91
+ buttonStyle: {
92
+ wakeButtonBackground: "linear-gradient(135deg, #38bdf8, #2563eb)",
93
+ openButtonBackground: "linear-gradient(135deg, #f59e0b, #ef4444)",
94
+ },
75
95
  });
76
96
  app.mount("#app");
77
97
  ```
@@ -101,6 +121,15 @@ Vue.use(VoicePageAgentPlugin, {
101
121
  language: "zh-CN",
102
122
  },
103
123
  wakeWord: "布丁布丁",
124
+ buttonText: {
125
+ startText: "开始语音",
126
+ wakeOnText: "语音进行中",
127
+ openText: "网页助手",
128
+ },
129
+ buttonStyle: {
130
+ wakeButtonBackground: "linear-gradient(135deg, #38bdf8, #2563eb)",
131
+ openButtonBackground: "linear-gradient(135deg, #f59e0b, #ef4444)",
132
+ },
104
133
  });
105
134
  ```
106
135
 
@@ -120,6 +149,15 @@ Vue.use(VoicePageAgentPlugin, {
120
149
  language: "zh-CN",
121
150
  },
122
151
  wakeWord: "布丁布丁",
152
+ buttonText: {
153
+ startText: "开始语音",
154
+ wakeOnText: "语音进行中",
155
+ openText: "网页助手",
156
+ },
157
+ buttonStyle: {
158
+ wakeButtonBackground: "linear-gradient(135deg, #38bdf8, #2563eb)",
159
+ openButtonBackground: "linear-gradient(135deg, #f59e0b, #ef4444)",
160
+ },
123
161
  });
124
162
  ```
125
163
 
@@ -137,6 +175,25 @@ You can use `VoicePageAgentButton` globally after plugin install:
137
175
  <VoicePageAgentButton />
138
176
  ```
139
177
 
178
+ The component injects a built-in gradient style (same visual direction across Vue2 / Vue2.7 / Vue3).
179
+
180
+ You can override by props:
181
+
182
+ - `startText`
183
+ - `wakeOnText`
184
+ - `openText`
185
+ - `wakeButtonBackground`
186
+ - `wakeButtonTextColor`
187
+ - `openButtonBackground`
188
+ - `openButtonTextColor`
189
+
190
+ You can also override these classes in your app:
191
+
192
+ - `.voice-page-agent-root`
193
+ - `.voice-page-agent-actions`
194
+ - `.voice-page-agent-btn`
195
+ - `.voice-page-agent-status`
196
+
140
197
  It renders:
141
198
  - wake button (only when mic permission is not granted)
142
199
  - open page-agent button
package/dist/index.cjs CHANGED
@@ -20240,9 +20240,139 @@ function createVoicePageAgent(options) {
20240
20240
  return new VoicePageAgentController(options);
20241
20241
  }
20242
20242
  var VOICE_PAGE_AGENT_KEY = "VOICE_PAGE_AGENT_INSTANCE";
20243
+ var VOICE_PAGE_AGENT_STYLE_ID = "voice-page-agent-style";
20244
+ var VOICE_PAGE_AGENT_STYLE_TEXT = `
20245
+ .voice-page-agent-root {
20246
+ --voice-page-agent-wake-bg: linear-gradient(135deg, #22c1ff, #3366ff);
20247
+ --voice-page-agent-wake-color: #ffffff;
20248
+ --voice-page-agent-open-bg: linear-gradient(135deg, #ffa84a, #ff5f6d);
20249
+ --voice-page-agent-open-color: #ffffff;
20250
+ --voice-page-agent-status-color: #e2e8f0;
20251
+ --voice-page-agent-surface-bg: linear-gradient(135deg, rgba(15, 23, 42, 0.92), rgba(30, 41, 59, 0.9));
20252
+ --voice-page-agent-surface-border: rgba(148, 163, 184, 0.3);
20253
+
20254
+ position: relative;
20255
+ display: flex;
20256
+ flex-direction: column;
20257
+ gap: 12px;
20258
+ margin-top: 12px;
20259
+ padding: 14px;
20260
+ border-radius: 16px;
20261
+ border: 1px solid var(--voice-page-agent-surface-border);
20262
+ background: var(--voice-page-agent-surface-bg);
20263
+ box-shadow:
20264
+ 0 16px 34px -26px rgba(15, 23, 42, 0.9),
20265
+ inset 0 1px 0 rgba(255, 255, 255, 0.12);
20266
+ overflow: hidden;
20267
+ }
20268
+
20269
+ .voice-page-agent-root::before {
20270
+ content: "";
20271
+ position: absolute;
20272
+ inset: -35% -10% auto;
20273
+ height: 58%;
20274
+ background: radial-gradient(ellipse at center, rgba(56, 189, 248, 0.2), rgba(56, 189, 248, 0));
20275
+ pointer-events: none;
20276
+ }
20277
+
20278
+ .voice-page-agent-actions {
20279
+ position: relative;
20280
+ z-index: 1;
20281
+ display: flex;
20282
+ flex-wrap: wrap;
20283
+ gap: 10px;
20284
+ }
20285
+
20286
+ .voice-page-agent-btn {
20287
+ border: 0;
20288
+ border-radius: 999px;
20289
+ padding: 9px 16px;
20290
+ font-size: 13px;
20291
+ line-height: 1.3;
20292
+ font-weight: 600;
20293
+ letter-spacing: 0.1px;
20294
+ cursor: pointer;
20295
+ box-shadow:
20296
+ 0 10px 20px -14px rgba(15, 23, 42, 1),
20297
+ inset 0 1px 0 rgba(255, 255, 255, 0.22);
20298
+ transition: transform 0.2s ease, filter 0.2s ease, box-shadow 0.2s ease;
20299
+ }
20300
+
20301
+ .voice-page-agent-btn--wake {
20302
+ background: var(--voice-page-agent-wake-bg);
20303
+ color: var(--voice-page-agent-wake-color);
20304
+ }
20305
+
20306
+ .voice-page-agent-btn--open {
20307
+ background: var(--voice-page-agent-open-bg);
20308
+ color: var(--voice-page-agent-open-color);
20309
+ }
20310
+
20311
+ .voice-page-agent-btn:hover {
20312
+ transform: translateY(-1px);
20313
+ filter: brightness(1.03);
20314
+ box-shadow:
20315
+ 0 14px 24px -14px rgba(15, 23, 42, 0.95),
20316
+ inset 0 1px 0 rgba(255, 255, 255, 0.24);
20317
+ }
20318
+
20319
+ .voice-page-agent-btn:active {
20320
+ transform: translateY(0);
20321
+ filter: brightness(0.98);
20322
+ }
20323
+
20324
+ .voice-page-agent-status {
20325
+ margin: 0;
20326
+ position: relative;
20327
+ z-index: 1;
20328
+ color: var(--voice-page-agent-status-color);
20329
+ font-size: 13px;
20330
+ line-height: 1.4;
20331
+ opacity: 0.95;
20332
+ }
20333
+ `;
20334
+ var DEFAULT_BUTTON_CONFIG = {
20335
+ startText: "\u5F00\u542F\u8BED\u97F3\u5524\u9192",
20336
+ wakeOnText: "\u8BED\u97F3\u5524\u9192\u4E2D",
20337
+ openText: "\u7F51\u9875\u52A9\u624B",
20338
+ wakeButtonBackground: "linear-gradient(135deg, #22c1ff, #3366ff)",
20339
+ wakeButtonTextColor: "#ffffff",
20340
+ openButtonBackground: "linear-gradient(135deg, #ffa84a, #ff5f6d)",
20341
+ openButtonTextColor: "#ffffff"
20342
+ };
20343
+ var globalButtonConfig = {
20344
+ ...DEFAULT_BUTTON_CONFIG
20345
+ };
20243
20346
  var defaultController = null;
20347
+ function ensureButtonStyles() {
20348
+ if (typeof document === "undefined") return;
20349
+ if (document.getElementById(VOICE_PAGE_AGENT_STYLE_ID)) return;
20350
+ const style = document.createElement("style");
20351
+ style.id = VOICE_PAGE_AGENT_STYLE_ID;
20352
+ style.textContent = VOICE_PAGE_AGENT_STYLE_TEXT;
20353
+ document.head.appendChild(style);
20354
+ }
20355
+ function resolveButtonConfig(options) {
20356
+ var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
20357
+ return {
20358
+ startText: (_b = (_a3 = options == null ? void 0 : options.buttonText) == null ? void 0 : _a3.startText) != null ? _b : DEFAULT_BUTTON_CONFIG.startText,
20359
+ wakeOnText: (_d = (_c = options == null ? void 0 : options.buttonText) == null ? void 0 : _c.wakeOnText) != null ? _d : DEFAULT_BUTTON_CONFIG.wakeOnText,
20360
+ openText: (_f = (_e = options == null ? void 0 : options.buttonText) == null ? void 0 : _e.openText) != null ? _f : DEFAULT_BUTTON_CONFIG.openText,
20361
+ wakeButtonBackground: (_h = (_g = options == null ? void 0 : options.buttonStyle) == null ? void 0 : _g.wakeButtonBackground) != null ? _h : DEFAULT_BUTTON_CONFIG.wakeButtonBackground,
20362
+ wakeButtonTextColor: (_j = (_i = options == null ? void 0 : options.buttonStyle) == null ? void 0 : _i.wakeButtonTextColor) != null ? _j : DEFAULT_BUTTON_CONFIG.wakeButtonTextColor,
20363
+ openButtonBackground: (_l = (_k = options == null ? void 0 : options.buttonStyle) == null ? void 0 : _k.openButtonBackground) != null ? _l : DEFAULT_BUTTON_CONFIG.openButtonBackground,
20364
+ openButtonTextColor: (_n = (_m = options == null ? void 0 : options.buttonStyle) == null ? void 0 : _m.openButtonTextColor) != null ? _n : DEFAULT_BUTTON_CONFIG.openButtonTextColor
20365
+ };
20366
+ }
20367
+ function applyGlobalButtonConfig(options) {
20368
+ globalButtonConfig = resolveButtonConfig({
20369
+ buttonText: options == null ? void 0 : options.buttonText,
20370
+ buttonStyle: options == null ? void 0 : options.buttonStyle
20371
+ });
20372
+ }
20244
20373
  function attachToApp(target, controller) {
20245
20374
  var _a3, _b, _c, _d, _e;
20375
+ ensureButtonStyles();
20246
20376
  const anyTarget = target;
20247
20377
  if ("config" in anyTarget && ((_a3 = anyTarget.config) == null ? void 0 : _a3.globalProperties)) {
20248
20378
  anyTarget.config.globalProperties.$voicePageAgent = controller;
@@ -20278,18 +20408,35 @@ var VoicePageAgentButton = vueDemi.defineComponent({
20278
20408
  },
20279
20409
  startText: {
20280
20410
  type: String,
20281
- default: "\u5F00\u542F\u8BED\u97F3\u5524\u9192"
20411
+ default: void 0
20282
20412
  },
20283
20413
  wakeOnText: {
20284
20414
  type: String,
20285
- default: "\u8BED\u97F3\u5524\u9192\u4E2D"
20415
+ default: void 0
20286
20416
  },
20287
20417
  openText: {
20288
20418
  type: String,
20289
- default: "\u7F51\u9875\u52A9\u624B"
20419
+ default: void 0
20420
+ },
20421
+ wakeButtonBackground: {
20422
+ type: String,
20423
+ default: void 0
20424
+ },
20425
+ wakeButtonTextColor: {
20426
+ type: String,
20427
+ default: void 0
20428
+ },
20429
+ openButtonBackground: {
20430
+ type: String,
20431
+ default: void 0
20432
+ },
20433
+ openButtonTextColor: {
20434
+ type: String,
20435
+ default: void 0
20290
20436
  }
20291
20437
  },
20292
20438
  setup(props) {
20439
+ ensureButtonStyles();
20293
20440
  const controller = useVoicePageAgent();
20294
20441
  const state = vueDemi.ref(controller.snapshot);
20295
20442
  let off = null;
@@ -20312,32 +20459,49 @@ var VoicePageAgentButton = vueDemi.defineComponent({
20312
20459
  const handleOpenClick = () => {
20313
20460
  void controller.openAgent();
20314
20461
  };
20315
- return () => vueDemi.h("div", { class: "voice-page-agent-root" }, [
20316
- vueDemi.h("div", { class: "voice-page-agent-actions" }, [
20317
- state.value.supported && !state.value.micPermissionGranted ? vueDemi.h(
20318
- "button",
20319
- {
20320
- type: "button",
20321
- class: "voice-page-agent-btn",
20322
- onClick: handleWakeClick
20323
- },
20324
- state.value.enabled ? props.wakeOnText : props.startText
20325
- ) : null,
20326
- vueDemi.h(
20327
- "button",
20328
- {
20329
- type: "button",
20330
- class: "voice-page-agent-btn",
20331
- onClick: handleOpenClick
20332
- },
20333
- props.openText
20334
- )
20335
- ]),
20336
- props.showStatus ? vueDemi.h("p", { class: "voice-page-agent-status" }, state.value.message) : null
20337
- ]);
20462
+ return () => {
20463
+ var _a3, _b, _c, _d, _e, _f, _g;
20464
+ const resolvedStartText = (_a3 = props.startText) != null ? _a3 : globalButtonConfig.startText;
20465
+ const resolvedWakeOnText = (_b = props.wakeOnText) != null ? _b : globalButtonConfig.wakeOnText;
20466
+ const resolvedOpenText = (_c = props.openText) != null ? _c : globalButtonConfig.openText;
20467
+ const resolvedWakeButtonBackground = (_d = props.wakeButtonBackground) != null ? _d : globalButtonConfig.wakeButtonBackground;
20468
+ const resolvedWakeButtonTextColor = (_e = props.wakeButtonTextColor) != null ? _e : globalButtonConfig.wakeButtonTextColor;
20469
+ const resolvedOpenButtonBackground = (_f = props.openButtonBackground) != null ? _f : globalButtonConfig.openButtonBackground;
20470
+ const resolvedOpenButtonTextColor = (_g = props.openButtonTextColor) != null ? _g : globalButtonConfig.openButtonTextColor;
20471
+ const rootStyle = {
20472
+ "--voice-page-agent-wake-bg": resolvedWakeButtonBackground,
20473
+ "--voice-page-agent-wake-color": resolvedWakeButtonTextColor,
20474
+ "--voice-page-agent-open-bg": resolvedOpenButtonBackground,
20475
+ "--voice-page-agent-open-color": resolvedOpenButtonTextColor
20476
+ };
20477
+ return vueDemi.h("div", { class: "voice-page-agent-root", style: rootStyle }, [
20478
+ vueDemi.h("div", { class: "voice-page-agent-actions" }, [
20479
+ state.value.supported && !state.value.micPermissionGranted ? vueDemi.h(
20480
+ "button",
20481
+ {
20482
+ type: "button",
20483
+ class: "voice-page-agent-btn voice-page-agent-btn--wake",
20484
+ onClick: handleWakeClick
20485
+ },
20486
+ state.value.enabled ? resolvedWakeOnText : resolvedStartText
20487
+ ) : null,
20488
+ vueDemi.h(
20489
+ "button",
20490
+ {
20491
+ type: "button",
20492
+ class: "voice-page-agent-btn voice-page-agent-btn--open",
20493
+ onClick: handleOpenClick
20494
+ },
20495
+ resolvedOpenText
20496
+ )
20497
+ ]),
20498
+ props.showStatus ? vueDemi.h("p", { class: "voice-page-agent-status" }, state.value.message) : null
20499
+ ]);
20500
+ };
20338
20501
  }
20339
20502
  });
20340
20503
  function createVoicePageAgentPlugin(options) {
20504
+ applyGlobalButtonConfig(options);
20341
20505
  const controller = createVoicePageAgent(options);
20342
20506
  defaultController = controller;
20343
20507
  return {
@@ -20352,6 +20516,7 @@ var VoicePageAgentVuePlugin = {
20352
20516
  if (!options) {
20353
20517
  throw new Error("voice-page-agent: install options is required.");
20354
20518
  }
20519
+ applyGlobalButtonConfig(options);
20355
20520
  const plugin = createVoicePageAgentPlugin(options);
20356
20521
  VoicePageAgentVuePlugin.controller = plugin.controller;
20357
20522
  attachToApp(app, plugin.controller);
package/dist/index.d.cts CHANGED
@@ -16,6 +16,17 @@ type RuntimePageAgent = {
16
16
  execute: (task: string) => Promise<unknown>;
17
17
  status?: "idle" | "running" | "completed" | "error" | string;
18
18
  };
19
+ type VoicePageAgentButtonTextOptions = {
20
+ startText?: string;
21
+ wakeOnText?: string;
22
+ openText?: string;
23
+ };
24
+ type VoicePageAgentButtonStyleOptions = {
25
+ wakeButtonBackground?: string;
26
+ wakeButtonTextColor?: string;
27
+ openButtonBackground?: string;
28
+ openButtonTextColor?: string;
29
+ };
19
30
  type VoicePageAgentOptions = {
20
31
  pageAgent: Record<string, unknown>;
21
32
  wakeWord?: string | string[];
@@ -27,6 +38,8 @@ type VoicePageAgentOptions = {
27
38
  recognitionLang?: string;
28
39
  showAgentWhenWake?: boolean;
29
40
  autoStart?: boolean;
41
+ buttonText?: VoicePageAgentButtonTextOptions;
42
+ buttonStyle?: VoicePageAgentButtonStyleOptions;
30
43
  };
31
44
  type ResolvedVoicePageAgentOptions = {
32
45
  pageAgent: Record<string, unknown>;
@@ -39,6 +52,8 @@ type ResolvedVoicePageAgentOptions = {
39
52
  recognitionLang: string;
40
53
  showAgentWhenWake: boolean;
41
54
  autoStart: boolean;
55
+ buttonText?: VoicePageAgentButtonTextOptions;
56
+ buttonStyle?: VoicePageAgentButtonStyleOptions;
42
57
  };
43
58
  type VoiceStateListener = (state: VoicePageAgentState) => void;
44
59
 
@@ -106,15 +121,31 @@ declare const VoicePageAgentButton: vue.DefineComponent<vue.ExtractPropTypes<{
106
121
  };
107
122
  startText: {
108
123
  type: StringConstructor;
109
- default: string;
124
+ default: undefined;
110
125
  };
111
126
  wakeOnText: {
112
127
  type: StringConstructor;
113
- default: string;
128
+ default: undefined;
114
129
  };
115
130
  openText: {
116
131
  type: StringConstructor;
117
- default: string;
132
+ default: undefined;
133
+ };
134
+ wakeButtonBackground: {
135
+ type: StringConstructor;
136
+ default: undefined;
137
+ };
138
+ wakeButtonTextColor: {
139
+ type: StringConstructor;
140
+ default: undefined;
141
+ };
142
+ openButtonBackground: {
143
+ type: StringConstructor;
144
+ default: undefined;
145
+ };
146
+ openButtonTextColor: {
147
+ type: StringConstructor;
148
+ default: undefined;
118
149
  };
119
150
  }>, () => vue.VNode<vue.RendererNode, vue.RendererElement, {
120
151
  [key: string]: any;
@@ -125,21 +156,41 @@ declare const VoicePageAgentButton: vue.DefineComponent<vue.ExtractPropTypes<{
125
156
  };
126
157
  startText: {
127
158
  type: StringConstructor;
128
- default: string;
159
+ default: undefined;
129
160
  };
130
161
  wakeOnText: {
131
162
  type: StringConstructor;
132
- default: string;
163
+ default: undefined;
133
164
  };
134
165
  openText: {
135
166
  type: StringConstructor;
136
- default: string;
167
+ default: undefined;
168
+ };
169
+ wakeButtonBackground: {
170
+ type: StringConstructor;
171
+ default: undefined;
172
+ };
173
+ wakeButtonTextColor: {
174
+ type: StringConstructor;
175
+ default: undefined;
176
+ };
177
+ openButtonBackground: {
178
+ type: StringConstructor;
179
+ default: undefined;
180
+ };
181
+ openButtonTextColor: {
182
+ type: StringConstructor;
183
+ default: undefined;
137
184
  };
138
185
  }>> & Readonly<{}>, {
139
186
  showStatus: boolean;
140
187
  startText: string;
141
188
  wakeOnText: string;
142
189
  openText: string;
190
+ wakeButtonBackground: string;
191
+ wakeButtonTextColor: string;
192
+ openButtonBackground: string;
193
+ openButtonTextColor: string;
143
194
  }, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
144
195
  type VoicePageAgentPlugin = {
145
196
  install: (app: unknown, options?: VoicePageAgentOptions) => void;
@@ -148,4 +199,4 @@ type VoicePageAgentPlugin = {
148
199
  declare function createVoicePageAgentPlugin(options: VoicePageAgentOptions): VoicePageAgentPlugin;
149
200
  declare const VoicePageAgentVuePlugin: VoicePageAgentPlugin;
150
201
 
151
- export { type ResolvedVoicePageAgentOptions, type RuntimePageAgent, VoicePageAgentButton, VoicePageAgentController, type VoicePageAgentOptions, VoicePageAgentVuePlugin as VoicePageAgentPlugin, type VoicePageAgentState, type VoiceStateListener, type VoiceStateStatus, createVoicePageAgent, createVoicePageAgentPlugin, VoicePageAgentVuePlugin as default, useVoicePageAgent };
202
+ export { type ResolvedVoicePageAgentOptions, type RuntimePageAgent, VoicePageAgentButton, type VoicePageAgentButtonStyleOptions, type VoicePageAgentButtonTextOptions, VoicePageAgentController, type VoicePageAgentOptions, VoicePageAgentVuePlugin as VoicePageAgentPlugin, type VoicePageAgentState, type VoiceStateListener, type VoiceStateStatus, createVoicePageAgent, createVoicePageAgentPlugin, VoicePageAgentVuePlugin as default, useVoicePageAgent };
package/dist/index.d.ts CHANGED
@@ -16,6 +16,17 @@ type RuntimePageAgent = {
16
16
  execute: (task: string) => Promise<unknown>;
17
17
  status?: "idle" | "running" | "completed" | "error" | string;
18
18
  };
19
+ type VoicePageAgentButtonTextOptions = {
20
+ startText?: string;
21
+ wakeOnText?: string;
22
+ openText?: string;
23
+ };
24
+ type VoicePageAgentButtonStyleOptions = {
25
+ wakeButtonBackground?: string;
26
+ wakeButtonTextColor?: string;
27
+ openButtonBackground?: string;
28
+ openButtonTextColor?: string;
29
+ };
19
30
  type VoicePageAgentOptions = {
20
31
  pageAgent: Record<string, unknown>;
21
32
  wakeWord?: string | string[];
@@ -27,6 +38,8 @@ type VoicePageAgentOptions = {
27
38
  recognitionLang?: string;
28
39
  showAgentWhenWake?: boolean;
29
40
  autoStart?: boolean;
41
+ buttonText?: VoicePageAgentButtonTextOptions;
42
+ buttonStyle?: VoicePageAgentButtonStyleOptions;
30
43
  };
31
44
  type ResolvedVoicePageAgentOptions = {
32
45
  pageAgent: Record<string, unknown>;
@@ -39,6 +52,8 @@ type ResolvedVoicePageAgentOptions = {
39
52
  recognitionLang: string;
40
53
  showAgentWhenWake: boolean;
41
54
  autoStart: boolean;
55
+ buttonText?: VoicePageAgentButtonTextOptions;
56
+ buttonStyle?: VoicePageAgentButtonStyleOptions;
42
57
  };
43
58
  type VoiceStateListener = (state: VoicePageAgentState) => void;
44
59
 
@@ -106,15 +121,31 @@ declare const VoicePageAgentButton: vue.DefineComponent<vue.ExtractPropTypes<{
106
121
  };
107
122
  startText: {
108
123
  type: StringConstructor;
109
- default: string;
124
+ default: undefined;
110
125
  };
111
126
  wakeOnText: {
112
127
  type: StringConstructor;
113
- default: string;
128
+ default: undefined;
114
129
  };
115
130
  openText: {
116
131
  type: StringConstructor;
117
- default: string;
132
+ default: undefined;
133
+ };
134
+ wakeButtonBackground: {
135
+ type: StringConstructor;
136
+ default: undefined;
137
+ };
138
+ wakeButtonTextColor: {
139
+ type: StringConstructor;
140
+ default: undefined;
141
+ };
142
+ openButtonBackground: {
143
+ type: StringConstructor;
144
+ default: undefined;
145
+ };
146
+ openButtonTextColor: {
147
+ type: StringConstructor;
148
+ default: undefined;
118
149
  };
119
150
  }>, () => vue.VNode<vue.RendererNode, vue.RendererElement, {
120
151
  [key: string]: any;
@@ -125,21 +156,41 @@ declare const VoicePageAgentButton: vue.DefineComponent<vue.ExtractPropTypes<{
125
156
  };
126
157
  startText: {
127
158
  type: StringConstructor;
128
- default: string;
159
+ default: undefined;
129
160
  };
130
161
  wakeOnText: {
131
162
  type: StringConstructor;
132
- default: string;
163
+ default: undefined;
133
164
  };
134
165
  openText: {
135
166
  type: StringConstructor;
136
- default: string;
167
+ default: undefined;
168
+ };
169
+ wakeButtonBackground: {
170
+ type: StringConstructor;
171
+ default: undefined;
172
+ };
173
+ wakeButtonTextColor: {
174
+ type: StringConstructor;
175
+ default: undefined;
176
+ };
177
+ openButtonBackground: {
178
+ type: StringConstructor;
179
+ default: undefined;
180
+ };
181
+ openButtonTextColor: {
182
+ type: StringConstructor;
183
+ default: undefined;
137
184
  };
138
185
  }>> & Readonly<{}>, {
139
186
  showStatus: boolean;
140
187
  startText: string;
141
188
  wakeOnText: string;
142
189
  openText: string;
190
+ wakeButtonBackground: string;
191
+ wakeButtonTextColor: string;
192
+ openButtonBackground: string;
193
+ openButtonTextColor: string;
143
194
  }, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
144
195
  type VoicePageAgentPlugin = {
145
196
  install: (app: unknown, options?: VoicePageAgentOptions) => void;
@@ -148,4 +199,4 @@ type VoicePageAgentPlugin = {
148
199
  declare function createVoicePageAgentPlugin(options: VoicePageAgentOptions): VoicePageAgentPlugin;
149
200
  declare const VoicePageAgentVuePlugin: VoicePageAgentPlugin;
150
201
 
151
- export { type ResolvedVoicePageAgentOptions, type RuntimePageAgent, VoicePageAgentButton, VoicePageAgentController, type VoicePageAgentOptions, VoicePageAgentVuePlugin as VoicePageAgentPlugin, type VoicePageAgentState, type VoiceStateListener, type VoiceStateStatus, createVoicePageAgent, createVoicePageAgentPlugin, VoicePageAgentVuePlugin as default, useVoicePageAgent };
202
+ export { type ResolvedVoicePageAgentOptions, type RuntimePageAgent, VoicePageAgentButton, type VoicePageAgentButtonStyleOptions, type VoicePageAgentButtonTextOptions, VoicePageAgentController, type VoicePageAgentOptions, VoicePageAgentVuePlugin as VoicePageAgentPlugin, type VoicePageAgentState, type VoiceStateListener, type VoiceStateStatus, createVoicePageAgent, createVoicePageAgentPlugin, VoicePageAgentVuePlugin as default, useVoicePageAgent };
package/dist/index.js CHANGED
@@ -475,9 +475,139 @@ function createVoicePageAgent(options) {
475
475
  return new VoicePageAgentController(options);
476
476
  }
477
477
  var VOICE_PAGE_AGENT_KEY = "VOICE_PAGE_AGENT_INSTANCE";
478
+ var VOICE_PAGE_AGENT_STYLE_ID = "voice-page-agent-style";
479
+ var VOICE_PAGE_AGENT_STYLE_TEXT = `
480
+ .voice-page-agent-root {
481
+ --voice-page-agent-wake-bg: linear-gradient(135deg, #22c1ff, #3366ff);
482
+ --voice-page-agent-wake-color: #ffffff;
483
+ --voice-page-agent-open-bg: linear-gradient(135deg, #ffa84a, #ff5f6d);
484
+ --voice-page-agent-open-color: #ffffff;
485
+ --voice-page-agent-status-color: #e2e8f0;
486
+ --voice-page-agent-surface-bg: linear-gradient(135deg, rgba(15, 23, 42, 0.92), rgba(30, 41, 59, 0.9));
487
+ --voice-page-agent-surface-border: rgba(148, 163, 184, 0.3);
488
+
489
+ position: relative;
490
+ display: flex;
491
+ flex-direction: column;
492
+ gap: 12px;
493
+ margin-top: 12px;
494
+ padding: 14px;
495
+ border-radius: 16px;
496
+ border: 1px solid var(--voice-page-agent-surface-border);
497
+ background: var(--voice-page-agent-surface-bg);
498
+ box-shadow:
499
+ 0 16px 34px -26px rgba(15, 23, 42, 0.9),
500
+ inset 0 1px 0 rgba(255, 255, 255, 0.12);
501
+ overflow: hidden;
502
+ }
503
+
504
+ .voice-page-agent-root::before {
505
+ content: "";
506
+ position: absolute;
507
+ inset: -35% -10% auto;
508
+ height: 58%;
509
+ background: radial-gradient(ellipse at center, rgba(56, 189, 248, 0.2), rgba(56, 189, 248, 0));
510
+ pointer-events: none;
511
+ }
512
+
513
+ .voice-page-agent-actions {
514
+ position: relative;
515
+ z-index: 1;
516
+ display: flex;
517
+ flex-wrap: wrap;
518
+ gap: 10px;
519
+ }
520
+
521
+ .voice-page-agent-btn {
522
+ border: 0;
523
+ border-radius: 999px;
524
+ padding: 9px 16px;
525
+ font-size: 13px;
526
+ line-height: 1.3;
527
+ font-weight: 600;
528
+ letter-spacing: 0.1px;
529
+ cursor: pointer;
530
+ box-shadow:
531
+ 0 10px 20px -14px rgba(15, 23, 42, 1),
532
+ inset 0 1px 0 rgba(255, 255, 255, 0.22);
533
+ transition: transform 0.2s ease, filter 0.2s ease, box-shadow 0.2s ease;
534
+ }
535
+
536
+ .voice-page-agent-btn--wake {
537
+ background: var(--voice-page-agent-wake-bg);
538
+ color: var(--voice-page-agent-wake-color);
539
+ }
540
+
541
+ .voice-page-agent-btn--open {
542
+ background: var(--voice-page-agent-open-bg);
543
+ color: var(--voice-page-agent-open-color);
544
+ }
545
+
546
+ .voice-page-agent-btn:hover {
547
+ transform: translateY(-1px);
548
+ filter: brightness(1.03);
549
+ box-shadow:
550
+ 0 14px 24px -14px rgba(15, 23, 42, 0.95),
551
+ inset 0 1px 0 rgba(255, 255, 255, 0.24);
552
+ }
553
+
554
+ .voice-page-agent-btn:active {
555
+ transform: translateY(0);
556
+ filter: brightness(0.98);
557
+ }
558
+
559
+ .voice-page-agent-status {
560
+ margin: 0;
561
+ position: relative;
562
+ z-index: 1;
563
+ color: var(--voice-page-agent-status-color);
564
+ font-size: 13px;
565
+ line-height: 1.4;
566
+ opacity: 0.95;
567
+ }
568
+ `;
569
+ var DEFAULT_BUTTON_CONFIG = {
570
+ startText: "\u5F00\u542F\u8BED\u97F3\u5524\u9192",
571
+ wakeOnText: "\u8BED\u97F3\u5524\u9192\u4E2D",
572
+ openText: "\u7F51\u9875\u52A9\u624B",
573
+ wakeButtonBackground: "linear-gradient(135deg, #22c1ff, #3366ff)",
574
+ wakeButtonTextColor: "#ffffff",
575
+ openButtonBackground: "linear-gradient(135deg, #ffa84a, #ff5f6d)",
576
+ openButtonTextColor: "#ffffff"
577
+ };
578
+ var globalButtonConfig = {
579
+ ...DEFAULT_BUTTON_CONFIG
580
+ };
478
581
  var defaultController = null;
582
+ function ensureButtonStyles() {
583
+ if (typeof document === "undefined") return;
584
+ if (document.getElementById(VOICE_PAGE_AGENT_STYLE_ID)) return;
585
+ const style = document.createElement("style");
586
+ style.id = VOICE_PAGE_AGENT_STYLE_ID;
587
+ style.textContent = VOICE_PAGE_AGENT_STYLE_TEXT;
588
+ document.head.appendChild(style);
589
+ }
590
+ function resolveButtonConfig(options) {
591
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
592
+ return {
593
+ startText: (_b = (_a = options == null ? void 0 : options.buttonText) == null ? void 0 : _a.startText) != null ? _b : DEFAULT_BUTTON_CONFIG.startText,
594
+ wakeOnText: (_d = (_c = options == null ? void 0 : options.buttonText) == null ? void 0 : _c.wakeOnText) != null ? _d : DEFAULT_BUTTON_CONFIG.wakeOnText,
595
+ openText: (_f = (_e = options == null ? void 0 : options.buttonText) == null ? void 0 : _e.openText) != null ? _f : DEFAULT_BUTTON_CONFIG.openText,
596
+ wakeButtonBackground: (_h = (_g = options == null ? void 0 : options.buttonStyle) == null ? void 0 : _g.wakeButtonBackground) != null ? _h : DEFAULT_BUTTON_CONFIG.wakeButtonBackground,
597
+ wakeButtonTextColor: (_j = (_i = options == null ? void 0 : options.buttonStyle) == null ? void 0 : _i.wakeButtonTextColor) != null ? _j : DEFAULT_BUTTON_CONFIG.wakeButtonTextColor,
598
+ openButtonBackground: (_l = (_k = options == null ? void 0 : options.buttonStyle) == null ? void 0 : _k.openButtonBackground) != null ? _l : DEFAULT_BUTTON_CONFIG.openButtonBackground,
599
+ openButtonTextColor: (_n = (_m = options == null ? void 0 : options.buttonStyle) == null ? void 0 : _m.openButtonTextColor) != null ? _n : DEFAULT_BUTTON_CONFIG.openButtonTextColor
600
+ };
601
+ }
602
+ function applyGlobalButtonConfig(options) {
603
+ globalButtonConfig = resolveButtonConfig({
604
+ buttonText: options == null ? void 0 : options.buttonText,
605
+ buttonStyle: options == null ? void 0 : options.buttonStyle
606
+ });
607
+ }
479
608
  function attachToApp(target, controller) {
480
609
  var _a, _b, _c, _d, _e;
610
+ ensureButtonStyles();
481
611
  const anyTarget = target;
482
612
  if ("config" in anyTarget && ((_a = anyTarget.config) == null ? void 0 : _a.globalProperties)) {
483
613
  anyTarget.config.globalProperties.$voicePageAgent = controller;
@@ -513,18 +643,35 @@ var VoicePageAgentButton = defineComponent({
513
643
  },
514
644
  startText: {
515
645
  type: String,
516
- default: "\u5F00\u542F\u8BED\u97F3\u5524\u9192"
646
+ default: void 0
517
647
  },
518
648
  wakeOnText: {
519
649
  type: String,
520
- default: "\u8BED\u97F3\u5524\u9192\u4E2D"
650
+ default: void 0
521
651
  },
522
652
  openText: {
523
653
  type: String,
524
- default: "\u7F51\u9875\u52A9\u624B"
654
+ default: void 0
655
+ },
656
+ wakeButtonBackground: {
657
+ type: String,
658
+ default: void 0
659
+ },
660
+ wakeButtonTextColor: {
661
+ type: String,
662
+ default: void 0
663
+ },
664
+ openButtonBackground: {
665
+ type: String,
666
+ default: void 0
667
+ },
668
+ openButtonTextColor: {
669
+ type: String,
670
+ default: void 0
525
671
  }
526
672
  },
527
673
  setup(props) {
674
+ ensureButtonStyles();
528
675
  const controller = useVoicePageAgent();
529
676
  const state = ref(controller.snapshot);
530
677
  let off = null;
@@ -547,32 +694,49 @@ var VoicePageAgentButton = defineComponent({
547
694
  const handleOpenClick = () => {
548
695
  void controller.openAgent();
549
696
  };
550
- return () => h("div", { class: "voice-page-agent-root" }, [
551
- h("div", { class: "voice-page-agent-actions" }, [
552
- state.value.supported && !state.value.micPermissionGranted ? h(
553
- "button",
554
- {
555
- type: "button",
556
- class: "voice-page-agent-btn",
557
- onClick: handleWakeClick
558
- },
559
- state.value.enabled ? props.wakeOnText : props.startText
560
- ) : null,
561
- h(
562
- "button",
563
- {
564
- type: "button",
565
- class: "voice-page-agent-btn",
566
- onClick: handleOpenClick
567
- },
568
- props.openText
569
- )
570
- ]),
571
- props.showStatus ? h("p", { class: "voice-page-agent-status" }, state.value.message) : null
572
- ]);
697
+ return () => {
698
+ var _a, _b, _c, _d, _e, _f, _g;
699
+ const resolvedStartText = (_a = props.startText) != null ? _a : globalButtonConfig.startText;
700
+ const resolvedWakeOnText = (_b = props.wakeOnText) != null ? _b : globalButtonConfig.wakeOnText;
701
+ const resolvedOpenText = (_c = props.openText) != null ? _c : globalButtonConfig.openText;
702
+ const resolvedWakeButtonBackground = (_d = props.wakeButtonBackground) != null ? _d : globalButtonConfig.wakeButtonBackground;
703
+ const resolvedWakeButtonTextColor = (_e = props.wakeButtonTextColor) != null ? _e : globalButtonConfig.wakeButtonTextColor;
704
+ const resolvedOpenButtonBackground = (_f = props.openButtonBackground) != null ? _f : globalButtonConfig.openButtonBackground;
705
+ const resolvedOpenButtonTextColor = (_g = props.openButtonTextColor) != null ? _g : globalButtonConfig.openButtonTextColor;
706
+ const rootStyle = {
707
+ "--voice-page-agent-wake-bg": resolvedWakeButtonBackground,
708
+ "--voice-page-agent-wake-color": resolvedWakeButtonTextColor,
709
+ "--voice-page-agent-open-bg": resolvedOpenButtonBackground,
710
+ "--voice-page-agent-open-color": resolvedOpenButtonTextColor
711
+ };
712
+ return h("div", { class: "voice-page-agent-root", style: rootStyle }, [
713
+ h("div", { class: "voice-page-agent-actions" }, [
714
+ state.value.supported && !state.value.micPermissionGranted ? h(
715
+ "button",
716
+ {
717
+ type: "button",
718
+ class: "voice-page-agent-btn voice-page-agent-btn--wake",
719
+ onClick: handleWakeClick
720
+ },
721
+ state.value.enabled ? resolvedWakeOnText : resolvedStartText
722
+ ) : null,
723
+ h(
724
+ "button",
725
+ {
726
+ type: "button",
727
+ class: "voice-page-agent-btn voice-page-agent-btn--open",
728
+ onClick: handleOpenClick
729
+ },
730
+ resolvedOpenText
731
+ )
732
+ ]),
733
+ props.showStatus ? h("p", { class: "voice-page-agent-status" }, state.value.message) : null
734
+ ]);
735
+ };
573
736
  }
574
737
  });
575
738
  function createVoicePageAgentPlugin(options) {
739
+ applyGlobalButtonConfig(options);
576
740
  const controller = createVoicePageAgent(options);
577
741
  defaultController = controller;
578
742
  return {
@@ -587,6 +751,7 @@ var VoicePageAgentVuePlugin = {
587
751
  if (!options) {
588
752
  throw new Error("voice-page-agent: install options is required.");
589
753
  }
754
+ applyGlobalButtonConfig(options);
590
755
  const plugin = createVoicePageAgentPlugin(options);
591
756
  VoicePageAgentVuePlugin.controller = plugin.controller;
592
757
  attachToApp(app, plugin.controller);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "voice-page-agent",
3
- "version": "2.7.2",
3
+ "version": "2.7.4",
4
4
  "description": "Voice wake plugin for page-agent with Vue2/Vue3 compatibility.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -49,5 +49,6 @@
49
49
  "@types/node": "^22.10.1",
50
50
  "tsup": "^8.4.0",
51
51
  "typescript": "^5.7.2"
52
- }
52
+ },
53
+ "packageManager": "pnpm@10.28.2+sha512.41872f037ad22f7348e3b1debbaf7e867cfd448f2726d9cf74c08f19507c31d2c8e7a11525b983febc2df640b5438dee6023ebb1f84ed43cc2d654d2bc326264"
53
54
  }