@coffic/cosy-ui 1.0.11 → 1.0.13

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 (32) hide show
  1. package/dist/app.css +1 -1
  2. package/dist/index-astro.ts +1 -0
  3. package/dist/index-vue.ts +1 -0
  4. package/dist/src/assets/iconData.js +3 -0
  5. package/dist/src/assets/icons-data/arrowDownS.d.ts +2 -0
  6. package/dist/src/assets/icons-data/arrowDownS.js +3 -0
  7. package/dist/src/assets/icons-data/arrowUpS.d.ts +2 -0
  8. package/dist/src/assets/icons-data/arrowUpS.js +3 -0
  9. package/dist/src/assets/icons-data/function.d.ts +2 -0
  10. package/dist/src/assets/icons-data/function.js +3 -0
  11. package/dist/src/assets/icons-data/index.d.ts +3 -0
  12. package/dist/src/assets/icons-data/index.js +3 -0
  13. package/dist/src-astro/icons/ArrowDownSIcon.astro +28 -0
  14. package/dist/src-astro/icons/ArrowUpSIcon.astro +28 -0
  15. package/dist/src-astro/icons/FunctionIcon.astro +28 -0
  16. package/dist/src-astro/icons/index.ts +3 -0
  17. package/dist/src-astro/mac-window/MacWindow.astro +7 -34
  18. package/dist/src-astro/math-formula/MathFormula.astro +463 -0
  19. package/dist/src-astro/math-formula/index.ts +3 -0
  20. package/dist/src-astro/math-formula/props.ts +11 -0
  21. package/dist/src-astro/math-formula/types.ts +46 -0
  22. package/dist/src-astro/products/ProductCard.astro +12 -6
  23. package/dist/src-astro/products/ProductHero.astro +0 -3
  24. package/dist/src-astro/products/ProductHeroContent.astro +0 -3
  25. package/dist/src-astro/products/ProductHeroImage.astro +0 -3
  26. package/dist/src-astro/products/Products.astro +8 -3
  27. package/dist/src-vue/math-formula/MathFormula.vue +198 -0
  28. package/dist/src-vue/math-formula/index.ts +2 -0
  29. package/dist/src-vue/math-formula/types.ts +18 -0
  30. package/dist/src-vue/products/ProductCard.vue +14 -2
  31. package/package.json +1 -1
  32. /package/dist/{src-astro/products → src/styles}/product-card.css +0 -0
@@ -0,0 +1,463 @@
1
+ ---
2
+ /**
3
+ * @component MathFormula
4
+ *
5
+ * @description
6
+ * MathFormula 公式展示组件用于在文档或页面中美观、统一地展示数学公式,支持标题、编号和说明。
7
+ *
8
+ * @usage
9
+ * 基本用法:
10
+ * ```astro
11
+ * <MathFormula title="换底公式" number="1" variant="gradient">
12
+ * $$\log_a c = \frac{\log_b c}{\log_b a}$$
13
+ * </MathFormula>
14
+ * ```
15
+ *
16
+ * 带说明和符号表:
17
+ * ```astro
18
+ * <MathFormula title="换底公式" number="1">
19
+ * $$\log_a c = \frac{\log_b c}{\log_b a}$$
20
+ * <div slot="desc">
21
+ * 这是对数函数的重要性质之一。
22
+ * </div>
23
+ * <div slot="symbols">
24
+ * | 符号 | 含义 |
25
+ * | :--- | :--- |
26
+ * | $\log_a$ | 以 a 为底的对数 |
27
+ * </div>
28
+ * </MathFormula>
29
+ * ```
30
+ *
31
+ * @props
32
+ * @prop {string} [title] - 公式标题,可选
33
+ * @prop {string|number} [number] - 公式编号,可选
34
+ * @prop {('default'|'gradient'|'glass'|'neon'|'card'|'spotlight')} [variant='gradient'] - 视觉风格
35
+ * @prop {boolean} [symbolsCollapsed=true] - 符号说明是否默认折叠
36
+ * @prop {string} [class] - 自定义 CSS 类名,用于覆盖默认样式
37
+ *
38
+ * @slots
39
+ * @slot default - 公式内容(支持 LaTeX)
40
+ * @slot desc - 说明文字(可选)
41
+ * @slot symbols - 符号说明(可折叠,默认折叠)
42
+ * @slot details - 详细说明(可折叠,默认折叠)
43
+ */
44
+
45
+ import { cn } from '../../src/class';
46
+ import { ArrowDownSIcon, ArrowUpSIcon, FunctionIcon, InfoIcon } from '../icons';
47
+ import type { IMathFormulaProps } from './props';
48
+
49
+ const props = Astro.props as IMathFormulaProps;
50
+
51
+ const {
52
+ title = '',
53
+ number = '',
54
+ variant = 'gradient',
55
+ symbolsCollapsed = true,
56
+ class: className = '',
57
+ } = props;
58
+
59
+ const hasHeader = title || number;
60
+ const showDesc = Astro.slots.has('desc');
61
+ const showSymbols = Astro.slots.has('symbols');
62
+ const showDetails = Astro.slots.has('details');
63
+
64
+ // 生成唯一 ID 用于多个实例
65
+ const componentId = `math-formula-${Math.random().toString(36).substring(2, 9)}`;
66
+
67
+ // 构建容器样式类
68
+ const baseClasses = cn()
69
+ .add('cosy:my-6')
70
+ .add('cosy:p-4')
71
+ .add('cosy:rounded-lg')
72
+ .add('cosy:relative')
73
+ .add('cosy:transition-all')
74
+ .add('cosy:duration-300')
75
+ .build();
76
+
77
+ // 变体样式映射
78
+ const variantClassMap: Record<string, string> = {
79
+ default:
80
+ 'cosy:bg-base-200/80 cosy:border-l-2 cosy:border-accent cosy:rounded-r-lg cosy:shadow cosy:hover:shadow-lg',
81
+ gradient:
82
+ 'cosy:bg-linear-to-br cosy:from-accent/10 cosy:via-base-200/80 cosy:to-primary/10 cosy:border cosy:border-accent/30 cosy:shadow-inner cosy:hover:border-accent/50 cosy:backdrop-blur-sm',
83
+ glass: 'cosy:bg-base-100/40 cosy:backdrop-blur-md cosy:border cosy:border-base-300/50 cosy:shadow-xl cosy:hover:bg-base-100/50',
84
+ neon: 'cosy:bg-base-200/50 cosy:border-2 cosy:border-accent cosy:shadow-[0_0_15px_rgba(var(--a),0.3)] cosy:hover:shadow-[0_0_25px_rgba(var(--a),0.5)] cosy:backdrop-blur-sm',
85
+ card: 'cosy:bg-base-100 cosy:border-2 cosy:border-l-8 cosy:border-accent cosy:shadow-lg cosy:hover:shadow-2xl cosy:hover:-translate-y-1',
86
+ spotlight:
87
+ 'cosy:bg-base-200/80 cosy:border cosy:border-accent/20 cosy:shadow-lg cosy:hover:shadow-xl cosy:overflow-hidden',
88
+ };
89
+
90
+ const containerClasses = cn()
91
+ .add(baseClasses)
92
+ .add(variantClassMap[variant] || variantClassMap.gradient)
93
+ .add(className)
94
+ .build();
95
+ ---
96
+
97
+ <div
98
+ class={`formula-container ${containerClasses}`}
99
+ data-formula-id={componentId}
100
+ data-variant={variant}>
101
+ <!-- Spotlight 效果的光斑(仅在 spotlight variant 时显示) -->
102
+ {
103
+ variant === 'spotlight' && (
104
+ <div class="spotlight-effect cosy:absolute cosy:inset-0 cosy:pointer-events-none" />
105
+ )
106
+ }
107
+
108
+ <!-- 右上角 info 图标 -->
109
+ <div class="cosy:absolute cosy:top-2 cosy:right-2 cosy:z-10">
110
+ <button
111
+ class="formula-info-btn cosy:w-5 cosy:h-5 cosy:text-accent cosy:hover:text-accent-focus cosy:hover:scale-110 cosy:transition-all cosy:duration-200"
112
+ title="什么是公式?"
113
+ type="button"
114
+ data-formula-id={componentId}>
115
+ <InfoIcon class="cosy:w-4 cosy:h-4" />
116
+ </button>
117
+ <!-- 提示框 -->
118
+ <div
119
+ class="formula-tooltip cosy:absolute cosy:top-6 cosy:right-0 cosy:w-64 cosy:p-3 cosy:bg-base-100 cosy:border cosy:border-base-300 cosy:rounded-lg cosy:shadow-xl cosy:z-20 cosy:text-sm cosy:animate-fade-in cosy:hidden"
120
+ data-formula-id={componentId}>
121
+ <div class="cosy:flex cosy:items-start cosy:gap-2">
122
+ <InfoIcon
123
+ class="cosy:w-4 cosy:h-4 cosy:text-accent cosy:mt-0.5 cosy:shrink-0"
124
+ />
125
+ <div class="cosy:text-base-content">
126
+ <p class="cosy:font-medium cosy:mb-1 not-prose">数学公式</p>
127
+ <p
128
+ class="cosy:text-xs cosy:leading-relaxed not-prose cosy:opacity-70">
129
+ 公式是数学中表达数量关系、结构规律的符号表达式,是解决数学问题的重要工具。重要结论公式应熟练掌握和灵活应用。
130
+ </p>
131
+ </div>
132
+ </div>
133
+ <!-- 小三角 -->
134
+ <div
135
+ class="cosy:absolute cosy:-top-1 cosy:right-3 cosy:w-2 cosy:h-2 cosy:bg-base-100 cosy:border-l cosy:border-t cosy:border-base-300 cosy:transform cosy:rotate-45">
136
+ </div>
137
+ </div>
138
+ </div>
139
+
140
+ {
141
+ hasHeader && (
142
+ <div
143
+ class={cn()
144
+ .flex()
145
+ .items('center')
146
+ .mb(2)
147
+ .relative()
148
+ .z(1)
149
+ .build()}>
150
+ <FunctionIcon
151
+ class={`cosy:text-accent cosy:mr-2 cosy:text-lg ${
152
+ variant === 'neon'
153
+ ? 'cosy:drop-shadow-[0_0_8px_rgba(var(--a),0.8)]'
154
+ : ''
155
+ }`}
156
+ />
157
+ {title && (
158
+ <span
159
+ class={`cosy:font-bold cosy:text-base-content ${
160
+ variant === 'neon'
161
+ ? 'cosy:drop-shadow-[0_0_4px_rgba(var(--a),0.3)]'
162
+ : ''
163
+ }`}>
164
+ {title}
165
+ </span>
166
+ )}
167
+ {number && (
168
+ <span
169
+ class={`cosy:ml-2 cosy:text-xs cosy:text-base-content/70 cosy:px-2 cosy:py-0.5 cosy:rounded-full ${
170
+ variant !== 'default'
171
+ ? 'cosy:bg-accent/20'
172
+ : 'cosy:bg-base-300'
173
+ }`}>
174
+ 公式{number}
175
+ </span>
176
+ )}
177
+ </div>
178
+ )
179
+ }
180
+
181
+ <div
182
+ class={cn()
183
+ .add('cosy:overflow-x-auto')
184
+ .text('lg')
185
+ .add('cosy:text-base-content', 'formula-block')
186
+ .relative()
187
+ .z(1)
188
+ .build()}>
189
+ <slot />
190
+ </div>
191
+
192
+ {
193
+ showDesc && (
194
+ <div
195
+ class={cn()
196
+ .mt(2)
197
+ .text('sm')
198
+ .add(
199
+ 'cosy:text-base-content/70',
200
+ 'cosy:border-t',
201
+ 'cosy:border-base-content/10'
202
+ )
203
+ .pt(2)
204
+ .relative()
205
+ .z(1)
206
+ .build()}>
207
+ <slot name="desc" />
208
+ </div>
209
+ )
210
+ }
211
+
212
+ <!-- 可折叠的符号说明 -->
213
+ {
214
+ showSymbols && (
215
+ <div
216
+ class={`cosy:mt-2 cosy:pt-3 cosy:border-t cosy:border-base-content/10 cosy:relative cosy:z-1 ${
217
+ variant === 'default'
218
+ ? 'cosy:border-t cosy:border-base-300'
219
+ : 'cosy:border-t cosy:border-accent/20'
220
+ }`}>
221
+ <details class="group" open={!symbolsCollapsed}>
222
+ <summary
223
+ class={`cosy:cursor-pointer cosy:text-sm cosy:font-medium cosy:flex cosy:items-center cosy:gap-1 cosy:transition-colors ${
224
+ variant === 'neon'
225
+ ? 'cosy:text-accent cosy:hover:text-accent cosy:drop-shadow-[0_0_4px_rgba(var(--a),0.5)]'
226
+ : 'cosy:text-accent cosy:hover:text-accent-focus'
227
+ }`}>
228
+ <InfoIcon class="cosy:w-4 cosy:h-4 group-open:cosy:rotate-180 cosy:transition-transform cosy:duration-200" />
229
+ 符号说明
230
+ </summary>
231
+ <div class="cosy:mt-2 cosy:text-sm cosy:text-base-content/70">
232
+ <slot name="symbols" />
233
+ </div>
234
+ </details>
235
+ </div>
236
+ )
237
+ }
238
+
239
+ <!-- 可折叠的详细说明 -->
240
+ {
241
+ showDetails && (
242
+ <div class="cosy:mt-2 cosy:border-t cosy:border-base-content/10 cosy:pt-2 cosy:relative cosy:z-1">
243
+ <div class="cosy:flex cosy:justify-end">
244
+ <button
245
+ class="formula-details-toggle cosy:flex cosy:items-center cosy:gap-2 cosy:text-sm cosy:font-medium cosy:text-accent cosy:hover:text-accent-focus cosy:transition-colors cosy:duration-200 group"
246
+ type="button"
247
+ data-formula-id={componentId}>
248
+ <ArrowDownSIcon class="cosy:w-4 cosy:h-4 cosy:transition-transform cosy:duration-200 formula-details-icon-down" />
249
+ <ArrowUpSIcon class="cosy:w-4 cosy:h-4 cosy:transition-transform cosy:duration-200 formula-details-icon-up cosy:hidden" />
250
+ </button>
251
+ </div>
252
+ <div
253
+ class="formula-details-content cosy:mt-2 cosy:text-sm cosy:text-base-content/80 cosy:animate-fade-in cosy:hidden"
254
+ data-formula-id={componentId}>
255
+ <slot name="details" />
256
+ </div>
257
+ </div>
258
+ )
259
+ }
260
+ </div>
261
+
262
+ <style>
263
+ .formula-block {
264
+ /* 让公式在小屏下可横向滚动 */
265
+ font-family: 'KaTeX_Main', 'Times New Roman', Times, serif;
266
+ word-break: break-word;
267
+ }
268
+
269
+ /* Spotlight 效果 */
270
+ .spotlight-effect {
271
+ background: radial-gradient(
272
+ circle at var(--mouse-x, 50%) var(--mouse-y, 50%),
273
+ rgba(var(--a), 0.15) 0%,
274
+ transparent 50%
275
+ );
276
+ opacity: 0;
277
+ transition: opacity 0.3s ease;
278
+ }
279
+
280
+ .formula-container:hover .spotlight-effect {
281
+ opacity: 1;
282
+ }
283
+
284
+ /* 淡入动画 */
285
+ @keyframes fade-in {
286
+ from {
287
+ opacity: 0;
288
+ transform: translateY(-10px);
289
+ }
290
+ to {
291
+ opacity: 1;
292
+ transform: translateY(0);
293
+ }
294
+ }
295
+
296
+ .animate-fade-in {
297
+ animation: fade-in 0.2s ease-out;
298
+ }
299
+
300
+ /* Neon 效果脉冲 */
301
+ @keyframes neon-pulse {
302
+ 0%,
303
+ 100% {
304
+ box-shadow: 0 0 15px rgba(var(--a), 0.3);
305
+ }
306
+ 50% {
307
+ box-shadow: 0 0 25px rgba(var(--a), 0.5);
308
+ }
309
+ }
310
+ </style>
311
+
312
+ <script is:inline define:vars={{ componentId }}>
313
+ // 全局点击外部处理函数(使用事件委托,避免重复绑定)
314
+ let globalClickHandler = null;
315
+
316
+ function setupGlobalClickHandler() {
317
+ if (globalClickHandler) return; // 已经设置过
318
+
319
+ globalClickHandler = (event) => {
320
+ const target = event.target;
321
+ // 检查是否点击在 tooltip 或按钮外部
322
+ const allTooltips = document.querySelectorAll(
323
+ '.formula-tooltip:not(.cosy\\:hidden)'
324
+ );
325
+ allTooltips.forEach((tooltip) => {
326
+ const formulaId = tooltip.getAttribute('data-formula-id');
327
+ if (!formulaId) return;
328
+
329
+ const button = document.querySelector(
330
+ `.formula-info-btn[data-formula-id="${formulaId}"]`
331
+ );
332
+ if (
333
+ button &&
334
+ !button.contains(target) &&
335
+ !tooltip.contains(target)
336
+ ) {
337
+ tooltip.classList.add('cosy:hidden');
338
+ }
339
+ });
340
+ };
341
+
342
+ document.addEventListener('click', globalClickHandler);
343
+ }
344
+
345
+ // 处理 tooltip 显示/隐藏
346
+ function initTooltip(formulaId) {
347
+ const button = document.querySelector(
348
+ `.formula-info-btn[data-formula-id="${formulaId}"]`
349
+ );
350
+ const tooltip = document.querySelector(
351
+ `.formula-tooltip[data-formula-id="${formulaId}"]`
352
+ );
353
+
354
+ if (!button || !tooltip) return;
355
+
356
+ // 检查是否已经初始化过
357
+ if (button.hasAttribute('data-tooltip-initialized')) return;
358
+
359
+ const toggleTooltip = () => {
360
+ const isVisible = !tooltip.classList.contains('cosy:hidden');
361
+ // 关闭所有其他 tooltip
362
+ document
363
+ .querySelectorAll('.formula-tooltip')
364
+ .forEach((t) => t.classList.add('cosy:hidden'));
365
+ if (!isVisible) {
366
+ tooltip.classList.remove('cosy:hidden');
367
+ }
368
+ };
369
+
370
+ button.addEventListener('click', toggleTooltip);
371
+ button.setAttribute('data-tooltip-initialized', 'true');
372
+ }
373
+
374
+ // 处理 details 折叠/展开
375
+ function initDetails(formulaId) {
376
+ const toggle = document.querySelector(
377
+ `.formula-details-toggle[data-formula-id="${formulaId}"]`
378
+ );
379
+ const content = document.querySelector(
380
+ `.formula-details-content[data-formula-id="${formulaId}"]`
381
+ );
382
+ const iconDown = toggle?.querySelector('.formula-details-icon-down');
383
+ const iconUp = toggle?.querySelector('.formula-details-icon-up');
384
+
385
+ if (!toggle || !content || !iconDown || !iconUp) return;
386
+
387
+ // 检查是否已经初始化过
388
+ if (toggle.hasAttribute('data-details-initialized')) return;
389
+
390
+ toggle.addEventListener('click', () => {
391
+ const isExpanded = !content.classList.contains('cosy:hidden');
392
+ if (isExpanded) {
393
+ content.classList.add('cosy:hidden');
394
+ // 切换图标:显示 down,隐藏 up
395
+ iconDown.classList.remove('cosy:hidden');
396
+ iconUp.classList.add('cosy:hidden');
397
+ } else {
398
+ content.classList.remove('cosy:hidden');
399
+ // 切换图标:隐藏 down,显示 up
400
+ iconDown.classList.add('cosy:hidden');
401
+ iconUp.classList.remove('cosy:hidden');
402
+ }
403
+ });
404
+
405
+ toggle.setAttribute('data-details-initialized', 'true');
406
+ }
407
+
408
+ // 处理 spotlight 鼠标跟踪效果
409
+ function initSpotlight(formulaId) {
410
+ const container = document.querySelector(
411
+ `.formula-container[data-formula-id="${formulaId}"][data-variant="spotlight"]`
412
+ );
413
+
414
+ if (!container) return;
415
+
416
+ // 检查是否已经初始化过
417
+ if (container.hasAttribute('data-spotlight-initialized')) return;
418
+
419
+ const handleMouseMove = (e) => {
420
+ const rect = container.getBoundingClientRect();
421
+ const x = ((e.clientX - rect.left) / rect.width) * 100;
422
+ const y = ((e.clientY - rect.top) / rect.height) * 100;
423
+ container.style.setProperty('--mouse-x', `${x}%`);
424
+ container.style.setProperty('--mouse-y', `${y}%`);
425
+ };
426
+
427
+ container.addEventListener('mousemove', handleMouseMove);
428
+ // 初始化位置
429
+ container.style.setProperty('--mouse-x', '50%');
430
+ container.style.setProperty('--mouse-y', '50%');
431
+ container.setAttribute('data-spotlight-initialized', 'true');
432
+ }
433
+
434
+ // 初始化所有 MathFormula 组件
435
+ function initAllFormulas() {
436
+ // 设置全局点击处理(只需要设置一次)
437
+ setupGlobalClickHandler();
438
+
439
+ const containers = document.querySelectorAll(
440
+ '.formula-container[data-formula-id]'
441
+ );
442
+
443
+ containers.forEach((container) => {
444
+ const formulaId = container.getAttribute('data-formula-id');
445
+ if (!formulaId) return;
446
+
447
+ initTooltip(formulaId);
448
+ initDetails(formulaId);
449
+ initSpotlight(formulaId);
450
+ });
451
+ }
452
+
453
+ // 首次加载时初始化
454
+ if (document.readyState === 'loading') {
455
+ document.addEventListener('DOMContentLoaded', initAllFormulas);
456
+ } else {
457
+ // 如果 DOM 已经加载完成,立即初始化
458
+ initAllFormulas();
459
+ }
460
+
461
+ // 客户端路由切换时重新初始化
462
+ document.addEventListener('astro:page-load', initAllFormulas);
463
+ </script>
@@ -0,0 +1,3 @@
1
+ export { default as MathFormula } from "./MathFormula.astro";
2
+ export type { IMathFormulaProps } from "./props";
3
+ export type { IMathFormulaPropsBase, MathFormulaVariant } from "./types";
@@ -0,0 +1,11 @@
1
+ import type { HTMLAttributes } from "astro/types";
2
+ import type { IMathFormulaPropsBase } from "./types";
3
+
4
+ /**
5
+ * MathFormula 组件的 Astro 版本属性接口(继承基础接口并扩展 Astro 特定属性)
6
+ */
7
+ export interface IMathFormulaProps
8
+ extends IMathFormulaPropsBase,
9
+ Omit<HTMLAttributes<"div">, keyof IMathFormulaPropsBase> {
10
+ // 继承基础属性和 HTML div 属性,但避免冲突
11
+ }
@@ -0,0 +1,46 @@
1
+ /**
2
+ * MathFormula 组件的类型定义
3
+ */
4
+
5
+ /**
6
+ * 视觉风格变体
7
+ */
8
+ export type MathFormulaVariant =
9
+ | "default"
10
+ | "gradient"
11
+ | "glass"
12
+ | "neon"
13
+ | "card"
14
+ | "spotlight";
15
+
16
+ /**
17
+ * MathFormula 组件的基础属性接口(与框架无关)
18
+ */
19
+ export interface IMathFormulaPropsBase {
20
+ /**
21
+ * 公式标题,可选
22
+ */
23
+ title?: string;
24
+
25
+ /**
26
+ * 公式编号,可选
27
+ */
28
+ number?: string | number;
29
+
30
+ /**
31
+ * 视觉风格,支持多种预设样式
32
+ * @default "gradient"
33
+ */
34
+ variant?: MathFormulaVariant;
35
+
36
+ /**
37
+ * 符号说明是否默认折叠
38
+ * @default true
39
+ */
40
+ symbolsCollapsed?: boolean;
41
+
42
+ /**
43
+ * 自定义 CSS 类名,用于覆盖默认样式
44
+ */
45
+ class?: string;
46
+ }
@@ -1,7 +1,4 @@
1
1
  ---
2
-
3
-
4
-
5
2
  /**
6
3
  * @component ProductCard
7
4
  *
@@ -104,7 +101,6 @@ import {
104
101
  LinkIcon,
105
102
  SocialIcon,
106
103
  } from '../../index-astro';
107
- import './product-card.css';
108
104
  import {
109
105
  type BackgroundColor,
110
106
  getBackgroundClass,
@@ -159,6 +155,12 @@ export interface Props {
159
155
  * GitHub按钮文本
160
156
  */
161
157
  githubButtonText?: string;
158
+ /**
159
+ * 语言设置,影响默认按钮文本
160
+ * - zh-cn: 中文默认(访问官网)
161
+ * - en: 英文默认(Visit Website)
162
+ */
163
+ lang?: string;
162
164
  /**
163
165
  * 按钮布局方向
164
166
  * - row: 水平布局(默认)
@@ -207,7 +209,7 @@ const {
207
209
  productUrl,
208
210
  githubUrl,
209
211
  size = 'md',
210
- primaryButtonText = '访问官网',
212
+ primaryButtonText,
211
213
  secondaryButtonText = 'App Store',
212
214
  githubButtonText = 'GitHub',
213
215
  buttonLayout = 'row',
@@ -217,8 +219,12 @@ const {
217
219
  shadow = 'md',
218
220
  background,
219
221
  muted = false,
222
+ lang,
220
223
  } = Astro.props;
221
224
 
225
+ const effectivePrimaryButtonText =
226
+ primaryButtonText ?? (lang === 'en' ? 'Visit Website' : '访问官网');
227
+
222
228
  // 尺寸样式映射
223
229
  const sizeStyles = {
224
230
  xs: {
@@ -405,7 +411,7 @@ const buttonsContainerClass =
405
411
  <span slot="icon-left">
406
412
  <LinkIcon size="22px" />
407
413
  </span>
408
- {primaryButtonText}
414
+ {effectivePrimaryButtonText}
409
415
  </Button>
410
416
  )
411
417
  }
@@ -1,7 +1,4 @@
1
1
  ---
2
-
3
-
4
-
5
2
  /**
6
3
  * @component ProductHero
7
4
  *
@@ -1,7 +1,4 @@
1
1
  ---
2
-
3
-
4
-
5
2
  import { Badge, Heading, Text } from '../../index-astro';
6
3
 
7
4
  export interface Props {
@@ -1,7 +1,4 @@
1
1
  ---
2
-
3
-
4
-
5
2
  import { Image } from '../../index-astro';
6
3
  import type { ImageSource } from '../image/types';
7
4
 
@@ -1,7 +1,4 @@
1
1
  ---
2
-
3
-
4
-
5
2
  /**
6
3
  * @component Products
7
4
  *
@@ -167,6 +164,12 @@ export interface Props {
167
164
  * 控制网格布局中所有卡片是否居中显示
168
165
  */
169
166
  centerItems?: boolean;
167
+ /**
168
+ * 语言设置,传递给 ProductCard 用于默认按钮文本
169
+ * - zh-cn: 中文(访问官网)
170
+ * - en: 英文(Visit Website)
171
+ */
172
+ lang?: string;
170
173
  /**
171
174
  * 自定义类名
172
175
  */
@@ -184,6 +187,7 @@ const {
184
187
  showBorder = false,
185
188
  margin = 'md',
186
189
  centerItems = true,
190
+ lang,
187
191
  class: className = '',
188
192
  } = Astro.props;
189
193
 
@@ -258,6 +262,7 @@ const containerClasses = [
258
262
  size={cardSize}
259
263
  equalHeight={equalHeight}
260
264
  descriptionLines={descriptionLines}
265
+ lang={lang ?? product.lang}
261
266
  />
262
267
  ))
263
268
  }