@coffic/cosy-ui 0.8.20 → 0.8.21

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.
@@ -224,4 +224,10 @@ export const iconData: Record<string, IconData> = {
224
224
  download: {
225
225
  path: 'M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M9 11l3 3m0 0l3-3m-3 3V4',
226
226
  },
227
- };
227
+
228
+ // App Store图标(苹果logo)
229
+ appstore: {
230
+ path: 'M12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2ZM12 4C7.58172 4 4 7.58172 4 12C4 16.4183 7.58172 20 12 20C16.4183 20 20 16.4183 20 12C20 7.58172 16.4183 4 12 4ZM8.82258 15.3427L8.03226 16.7137C7.80645 17.1089 7.30242 17.2419 6.90726 17.0161C6.5121 16.7903 6.37903 16.2863 6.60484 15.8911L7.19355 14.875C7.85484 14.6694 8.39516 14.8266 8.82258 15.3427ZM13.2097 8.66129L15.6331 12.8548H17.7742C18.2298 12.8548 18.5968 13.2218 18.5968 13.6774C18.5968 14.1331 18.2298 14.5 17.7742 14.5H16.5847L17.3871 15.8911C17.6129 16.2863 17.4798 16.7863 17.0847 17.0161C16.6895 17.2419 16.1895 17.1089 15.9597 16.7137L12.9194 11.4476C12.2298 10.2581 12.7218 9.06452 13.2097 8.66129ZM13.4879 5.61694C13.8831 5.84274 14.0161 6.34677 13.7903 6.74194L10.2621 12.8508H12.8145C13.6411 12.8508 14.1048 13.8226 13.746 14.496H6.26613C5.81048 14.496 5.44355 14.129 5.44355 13.6734C5.44355 13.2177 5.81048 12.8508 6.26613 12.8508H8.3629L11.0484 8.19758L10.2097 6.74194C9.98387 6.34677 10.1169 5.84677 10.5121 5.61694C10.9073 5.39113 11.4073 5.52419 11.6371 5.91935L11.996 6.55242L12.3629 5.91935C12.5887 5.52419 13.0927 5.39113 13.4879 5.61694Z',
231
+ viewBox: '0 0 24 24',
232
+ },
233
+ };
@@ -9,56 +9,58 @@ type TextContent = Record<string, Record<string, string>>;
9
9
 
10
10
  // 多语言文本内容
11
11
  export const texts: Record<string, TextContent> = {
12
- en: {
13
- tableOfContents: {
14
- title: 'Table of Contents',
15
- loading: 'Loading...',
12
+ en: {
13
+ tableOfContents: {
14
+ title: 'Table of Contents',
15
+ loading: 'Loading...',
16
+ },
17
+ footer: {
18
+ products: 'Products',
19
+ about: 'About',
20
+ aboutUs: 'About Us',
21
+ team: 'Our Team',
22
+ careers: 'Careers',
23
+ contactUs: 'Contact Us',
24
+ resources: 'Resources',
25
+ news: 'News',
26
+ blog: 'Blog',
27
+ faq: 'FAQ',
28
+ history: 'History',
29
+ techStack: 'Tech Stack',
30
+ legal: 'Legal',
31
+ terms: 'Terms of Service',
32
+ privacy: 'Privacy Policy',
33
+ slogan: 'Build a beautiful digital experience',
34
+ allRightsReserved: 'All Rights Reserved',
35
+ friendlyLinks: 'Friendly Links',
36
+ },
16
37
  },
17
- footer: {
18
- products: 'Products',
19
- about: 'About',
20
- aboutUs: 'About Us',
21
- team: 'Our Team',
22
- careers: 'Careers',
23
- contactUs: 'Contact Us',
24
- resources: 'Resources',
25
- news: 'News',
26
- blog: 'Blog',
27
- faq: 'FAQ',
28
- history: 'History',
29
- techStack: 'Tech Stack',
30
- legal: 'Legal',
31
- terms: 'Terms of Service',
32
- privacy: 'Privacy Policy',
33
- slogan: 'Build a beautiful digital experience',
34
- allRightsReserved: 'All Rights Reserved',
38
+ 'zh-cn': {
39
+ tableOfContents: {
40
+ title: '目录',
41
+ loading: '加载中...',
42
+ },
43
+ footer: {
44
+ products: '产品',
45
+ about: '关于',
46
+ aboutUs: '关于我们',
47
+ team: '团队介绍',
48
+ careers: '加入我们',
49
+ contactUs: '联系我们',
50
+ defaultSlogan: '优雅、高效的组件库',
51
+ resources: '资源',
52
+ news: '新闻动态',
53
+ blog: '技术博客',
54
+ faq: '常见问题',
55
+ history: '发展历程',
56
+ techStack: '技术栈',
57
+ legal: '法律',
58
+ terms: '服务条款',
59
+ privacy: '隐私政策',
60
+ allRightsReserved: '保留所有权利',
61
+ friendlyLinks: '友情链接',
62
+ },
35
63
  },
36
- },
37
- 'zh-cn': {
38
- tableOfContents: {
39
- title: '目录',
40
- loading: '加载中...',
41
- },
42
- footer: {
43
- products: '产品',
44
- about: '关于',
45
- aboutUs: '关于我们',
46
- team: '团队介绍',
47
- careers: '加入我们',
48
- contactUs: '联系我们',
49
- defaultSlogan: '优雅、高效的组件库',
50
- resources: '资源',
51
- news: '新闻动态',
52
- blog: '技术博客',
53
- faq: '常见问题',
54
- history: '发展历程',
55
- techStack: '技术栈',
56
- legal: '法律',
57
- terms: '服务条款',
58
- privacy: '隐私政策',
59
- allRightsReserved: '保留所有权利',
60
- },
61
- },
62
64
  };
63
65
 
64
66
  /**
@@ -69,7 +71,7 @@ export const texts: Record<string, TextContent> = {
69
71
  * @returns 对应的文本内容
70
72
  */
71
73
  export function getText(lang: string, component: string, key: string): string {
72
- return texts[lang]?.[component]?.[key] || texts['en'][component]?.[key] || '';
74
+ return texts[lang]?.[component]?.[key] || texts['en'][component]?.[key] || '';
73
75
  }
74
76
 
75
77
  /**
@@ -79,5 +81,5 @@ export function getText(lang: string, component: string, key: string): string {
79
81
  * @returns 文本获取函数
80
82
  */
81
83
  export function createTextGetter(langInfo: string, component: string) {
82
- return (key: string): string => getText(langInfo, component, key);
84
+ return (key: string): string => getText(langInfo, component, key);
83
85
  }
@@ -81,7 +81,7 @@ interface Props {
81
81
  onClick?: string;
82
82
  formmethod?: string;
83
83
  href?: string;
84
- target?: string;
84
+ target?: '_self' | '_blank' | '_parent' | '_top';
85
85
  [key: string]: any; // 允许任意自定义属性
86
86
  }
87
87
 
@@ -65,6 +65,22 @@
65
65
  * />
66
66
  * ```
67
67
  *
68
+ * 添加友情链接:
69
+ * ```astro
70
+ * <Footer
71
+ * siteName="我的网站"
72
+ * homeLink="/"
73
+ * slogan="简单而强大"
74
+ * company="我的公司"
75
+ * copyright="保留所有权利"
76
+ * inspirationalSlogan="构建美好的数字体验"
77
+ * friendlyLinks={[
78
+ * { name: "合作伙伴A", href: "https://partner-a.com" },
79
+ * { name: "合作伙伴B", href: "https://partner-b.com", external: true }
80
+ * ]}
81
+ * />
82
+ * ```
83
+ *
68
84
  * 完整示例:
69
85
  * ```astro
70
86
  * <Footer
@@ -79,6 +95,10 @@
79
95
  * { name: "产品A", href: "/products/a" },
80
96
  * { name: "产品B", href: "/products/b" }
81
97
  * ]}
98
+ * friendlyLinks={[
99
+ * { name: "合作伙伴A", href: "https://partner-a.com" },
100
+ * { name: "合作伙伴B", href: "https://partner-b.com", external: true }
101
+ * ]}
82
102
  * socialLinks={[
83
103
  * "https://github.com/myusername",
84
104
  * "https://twitter.com/myusername"
@@ -121,6 +141,7 @@
121
141
  * @prop {string} [icp] - ICP备案号(中国网站需要)
122
142
  * @prop {Object} [logo] - 网站Logo对象,包含src和alt属性
123
143
  * @prop {Array<Object>} [products=[]] - 产品链接数组,每个对象包含name、href和可选的external属性
144
+ * @prop {Array<Object>} [friendlyLinks=[]] - 友情链接数组,每个对象包含name、href和可选的external属性
124
145
  * @prop {string} [aboutLink] - "关于我们"页面链接
125
146
  * @prop {string} [contactLink] - "联系我们"页面链接
126
147
  * @prop {string} [termsLink] - "服务条款"页面链接
@@ -165,6 +186,7 @@ const {
165
186
  icp,
166
187
  logo,
167
188
  products = [],
189
+ friendlyLinks = [],
168
190
  aboutLink,
169
191
  contactLink,
170
192
  termsLink,
@@ -272,6 +294,13 @@ const debugClasses = debug
272
294
  )
273
295
  }
274
296
 
297
+ {/* 友情链接导航 */}
298
+ {
299
+ friendlyLinks.length > 0 && (
300
+ <FooterSection title={t('friendlyLinks')} links={friendlyLinks} />
301
+ )
302
+ }
303
+
275
304
  {/* 关于导航 */}
276
305
  {
277
306
  (aboutLink || contactLink || teamLink || careersLink) && (
@@ -157,6 +157,7 @@ import { Button } from '../../index-astro';
157
157
  interface Link {
158
158
  text: string;
159
159
  href: string;
160
+ target?: '_self' | '_blank' | '_parent' | '_top';
160
161
  variant:
161
162
  | 'primary'
162
163
  | 'secondary'
@@ -368,7 +369,11 @@ const contentOrder = {
368
369
  <div class={linksContainerClasses}>
369
370
  {
370
371
  links.map((link: Link) => (
371
- <Button href={link.href} variant={link.variant} size="lg">
372
+ <Button
373
+ href={link.href}
374
+ target={link.target}
375
+ variant={link.variant}
376
+ size="lg">
372
377
  {link.text}
373
378
  </Button>
374
379
  ))
@@ -0,0 +1,37 @@
1
+ ---
2
+ import AstroIcon from './AstroIcon.astro';
3
+
4
+ /**
5
+ * App Store图标组件
6
+ */
7
+ interface Props {
8
+ /**
9
+ * 图标的大小
10
+ * @default "24px"
11
+ */
12
+ size?: string;
13
+ /**
14
+ * 图标的颜色
15
+ * @default "currentColor"
16
+ */
17
+ color?: string;
18
+ /**
19
+ * 自定义类名
20
+ */
21
+ class?: string;
22
+ }
23
+
24
+ const {
25
+ size = '24px',
26
+ color = 'currentColor',
27
+ class: className = '',
28
+ } = Astro.props;
29
+ ---
30
+
31
+ <AstroIcon
32
+ name="appstore"
33
+ strokeWidth="0.5"
34
+ size={size}
35
+ fill={true}
36
+ class={className}
37
+ />
@@ -19,6 +19,12 @@ interface Props {
19
19
  */
20
20
  stroke?: string;
21
21
 
22
+ /**
23
+ * 描边宽度
24
+ * @default "2"
25
+ */
26
+ strokeWidth?: string;
27
+
22
28
  /**
23
29
  * 自定义类名
24
30
  */
@@ -35,6 +41,7 @@ const {
35
41
  name,
36
42
  size = '24px',
37
43
  stroke = 'currentColor',
44
+ strokeWidth = '2',
38
45
  class: className = '',
39
46
  fill = false,
40
47
  } = Astro.props;
@@ -51,7 +58,7 @@ const viewBox = icon?.viewBox || '0 0 24 24';
51
58
  viewBox={viewBox}
52
59
  fill={fill ? 'currentColor' : 'none'}
53
60
  stroke={stroke}
54
- stroke-width="2"
61
+ stroke-width={strokeWidth}
55
62
  stroke-linecap="round"
56
63
  stroke-linejoin="round"
57
64
  class={className}>
@@ -0,0 +1,31 @@
1
+ ---
2
+ import AstroIcon from './AstroIcon.astro';
3
+
4
+ /**
5
+ * 网站图标组件
6
+ */
7
+ interface Props {
8
+ /**
9
+ * 图标的大小
10
+ * @default "24px"
11
+ */
12
+ size?: string;
13
+ /**
14
+ * 图标的颜色
15
+ * @default "currentColor"
16
+ */
17
+ color?: string;
18
+ /**
19
+ * 自定义类名
20
+ */
21
+ class?: string;
22
+ }
23
+
24
+ const {
25
+ size = '24px',
26
+ color = 'currentColor',
27
+ class: className = '',
28
+ } = Astro.props;
29
+ ---
30
+
31
+ <AstroIcon name="website" size={size} stroke={color} class={className} />
@@ -44,4 +44,5 @@ export { default as SecurityIcon } from './SecurityIcon.astro';
44
44
  export { default as UploadIcon } from './UploadIcon.astro';
45
45
  export { default as DownloadIcon } from './DownloadIcon.astro';
46
46
  export { default as LogOut } from './LogOut.astro';
47
-
47
+ export { default as AppStoreIcon } from './AppStoreIcon.astro';
48
+ export { default as WebsiteIcon } from './WebsiteIcon.astro';
@@ -1,11 +1,3 @@
1
1
  import NavItems from './NavItems.astro';
2
- import NavItemsBasic from './NavItemsBasic.astro';
3
- import BasicSourceCode from './NavItemsBasic.astro?raw';
4
- import { extractSimpleExample } from '../../src/utils/component';
5
2
 
6
- export { NavItems, NavItemsBasic };
7
-
8
- // 导出示例源代码
9
- export const NavItemsExampleCodes = {
10
- Basic: extractSimpleExample(BasicSourceCode, 'NavItems'),
11
- };
3
+ export { NavItems };
@@ -64,9 +64,32 @@
64
64
  * />
65
65
  * </div>
66
66
  * ```
67
+ *
68
+ * 自定义阴影样式:
69
+ * ```astro
70
+ * <ProductCard
71
+ * shadow="lg"
72
+ * name="突出显示的产品"
73
+ * image="/images/products/product1.jpg"
74
+ * description="使用大阴影突出显示的产品"
75
+ * />
76
+ *
77
+ * <ProductCard
78
+ * shadow="none"
79
+ * name="简洁风格产品"
80
+ * image="/images/products/product2.jpg"
81
+ * description="无阴影的简洁风格"
82
+ * />
83
+ * ```
67
84
  */
68
85
 
69
- import { SocialIcon, Image, Link } from '../../index-astro';
86
+ import {
87
+ SocialIcon,
88
+ Image,
89
+ Button,
90
+ LinkIcon,
91
+ AppStoreIcon,
92
+ } from '../../index-astro';
70
93
  import '../../style.ts';
71
94
  import type { ImageSource } from '../types/image.ts';
72
95
 
@@ -138,6 +161,15 @@ export interface Props {
138
161
  * 自定义类名
139
162
  */
140
163
  class?: string;
164
+ /**
165
+ * 卡片阴影样式
166
+ * - none: 无阴影
167
+ * - sm: 小阴影
168
+ * - md: 中等阴影(默认)
169
+ * - lg: 大阴影
170
+ * - xl: 超大阴影
171
+ */
172
+ shadow?: 'none' | 'sm' | 'md' | 'lg' | 'xl';
141
173
  }
142
174
 
143
175
  const {
@@ -155,6 +187,7 @@ const {
155
187
  equalHeight = false,
156
188
  descriptionLines,
157
189
  class: className = '',
190
+ shadow = 'md',
158
191
  } = Astro.props;
159
192
 
160
193
  // 尺寸样式映射
@@ -238,6 +271,15 @@ const sizeStyles = {
238
271
 
239
272
  const currentSize = sizeStyles[size];
240
273
 
274
+ // 阴影样式映射
275
+ const shadowStyles = {
276
+ none: 'cosy:shadow-none',
277
+ sm: 'cosy:shadow-sm cosy:hover:shadow-md',
278
+ md: 'cosy:shadow-md cosy:hover:shadow-lg',
279
+ lg: 'cosy:shadow-lg cosy:hover:shadow-xl',
280
+ xl: 'cosy:shadow-xl cosy:hover:shadow-2xl',
281
+ };
282
+
241
283
  // 描述文本的行数限制
242
284
  const descriptionClass = descriptionLines
243
285
  ? `cosy:line-clamp-${descriptionLines}`
@@ -279,7 +321,8 @@ const buttonsContainerClass =
279
321
 
280
322
  <div
281
323
  class:list={[
282
- 'cosy:card cosy:bg-base-100 cosy:shadow-md cosy:hover:shadow-lg cosy:transition-shadow cosy:duration-300',
324
+ 'cosy:card cosy:bg-base-100 cosy:transition-shadow cosy:duration-300',
325
+ shadowStyles[shadow],
283
326
  currentSize.card,
284
327
  equalHeight && currentSize.cardHeight,
285
328
  'cosy:flex cosy:flex-col',
@@ -319,54 +362,47 @@ const buttonsContainerClass =
319
362
  <div class={buttonsContainerClass}>
320
363
  {
321
364
  productUrl && (
322
- <Link
365
+ <Button
323
366
  href={productUrl}
324
- external
367
+ target="_blank"
325
368
  variant="primary"
326
- class:list={[
327
- 'cosy:btn cosy:bg-[#4468e3] cosy:hover:bg-[#3857cc] cosy:border-0',
328
- 'cosy:text-white cosy:font-bold cosy:shadow-sm',
329
- buttonLayoutClass,
330
- currentSize.buttons,
331
- ]}
369
+ class:list={[buttonLayoutClass, currentSize.buttons]}
332
370
  aria-label={`Visit ${name}'s website`}>
371
+ <span slot="icon-left">
372
+ <LinkIcon size="22px" />
373
+ </span>
333
374
  {primaryButtonText}
334
- </Link>
375
+ </Button>
335
376
  )
336
377
  }
337
378
  {
338
379
  appStoreUrl && (
339
- <Link
380
+ <Button
340
381
  href={appStoreUrl}
341
- external
382
+ target="_blank"
342
383
  variant="secondary"
343
- class:list={[
344
- 'cosy:btn cosy:bg-[#161616] cosy:hover:bg-black cosy:border-0',
345
- 'cosy:text-white cosy:font-bold cosy:shadow-sm',
346
- buttonLayoutClass,
347
- currentSize.buttons,
348
- ]}
384
+ class:list={[buttonLayoutClass, currentSize.buttons]}
349
385
  aria-label={`Download ${name} on App Store`}>
386
+ <span slot="icon-left">
387
+ <AppStoreIcon size="22px" />
388
+ </span>
350
389
  {secondaryButtonText}
351
- </Link>
390
+ </Button>
352
391
  )
353
392
  }
354
393
  {
355
394
  githubUrl && (
356
- <Link
395
+ <Button
357
396
  href={githubUrl}
358
- external
359
- variant="ghost"
360
- class:list={[
361
- 'cosy:btn cosy:bg-[#f0f0f0] cosy:hover:bg-[#e0e0e0] cosy:border-0',
362
- 'cosy:text-[#24292f] cosy:font-bold cosy:shadow-sm',
363
- buttonLayoutClass,
364
- currentSize.buttons,
365
- ]}
397
+ target="_blank"
398
+ variant="info"
399
+ class:list={[buttonLayoutClass, currentSize.buttons]}
366
400
  aria-label={`View ${name}'s GitHub repository`}>
367
- <SocialIcon platform="github" size="18px" />
368
- <span class="cosy:inline-block">{githubButtonText}</span>
369
- </Link>
401
+ <span slot="icon-left">
402
+ <SocialIcon platform="github" size="22px" />
403
+ </span>
404
+ {githubButtonText}
405
+ </Button>
370
406
  )
371
407
  }
372
408
  </div>