@coffic/cosy-ui 0.8.20 → 0.8.22
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/dist/app.css +1 -1
- package/dist/src/assets/iconData.ts +10 -0
- package/dist/src/utils/i18n.ts +52 -50
- package/dist/src-astro/banner/Banner.astro +55 -3
- package/dist/src-astro/banner/index.ts +1 -52
- package/dist/src-astro/button/Button.astro +41 -2
- package/dist/src-astro/code-container/ButtonCodeToggle.astro +55 -0
- package/dist/src-astro/code-container/ButtonCopyCode.astro +74 -0
- package/dist/src-astro/code-container/CodeContainer.astro +14 -289
- package/dist/src-astro/code-container/CodePanel.astro +14 -0
- package/dist/src-astro/code-container/CodeToolbar.astro +100 -0
- package/dist/src-astro/code-container/Description.astro +17 -0
- package/dist/src-astro/code-container/Preview.astro +93 -0
- package/dist/src-astro/footer/Footer.astro +52 -20
- package/dist/src-astro/footer/FooterSection.astro +7 -9
- package/dist/src-astro/grid/index.ts +1 -9
- package/dist/src-astro/heading/index.ts +1 -9
- package/dist/src-astro/hero/Hero.astro +78 -9
- package/dist/src-astro/icons/AppStoreIcon.astro +37 -0
- package/dist/src-astro/icons/AstroIcon.astro +8 -1
- package/dist/src-astro/icons/CodeIcon.astro +22 -0
- package/dist/src-astro/icons/WebsiteIcon.astro +31 -0
- package/dist/src-astro/icons/index.ts +4 -2
- package/dist/src-astro/language-switcher/LanguageSwitcher.astro +6 -2
- package/dist/src-astro/link/Link.astro +50 -3
- package/dist/src-astro/nav-item/index.ts +1 -9
- package/dist/src-astro/products/ProductCard.astro +68 -32
- package/dist/src-astro/types/footer.ts +130 -125
- package/dist/src-vue/iPhone/iPhoneWindow.vue +2 -6
- package/dist/src-vue/utils/i18n.ts +52 -50
- package/package.json +1 -1
- package/dist/src-astro/banner/BannerAllAnimations.astro +0 -10
- package/dist/src-astro/banner/BannerBasic.astro +0 -5
- package/dist/src-astro/banner/BannerCustomStyle.astro +0 -8
- package/dist/src-astro/banner/BannerDanger.astro +0 -5
- package/dist/src-astro/banner/BannerFadeIn.astro +0 -5
- package/dist/src-astro/banner/BannerInfo.astro +0 -5
- package/dist/src-astro/banner/BannerPrimary.astro +0 -5
- package/dist/src-astro/banner/BannerSecondary.astro +0 -5
- package/dist/src-astro/banner/BannerSlideUp.astro +0 -5
- package/dist/src-astro/banner/BannerSuccess.astro +0 -5
- package/dist/src-astro/banner/BannerWarning.astro +0 -5
- package/dist/src-astro/grid/GridBasic.astro +0 -21
- package/dist/src-astro/heading/HeadingBasic.astro +0 -10
- package/dist/src-astro/nav-item/NavItemsBasic.astro +0 -30
@@ -224,4 +224,14 @@ 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
|
+
|
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
|
+
|
234
|
+
code: {
|
235
|
+
path: 'M8 6L2 12L8 18M16 6L22 12L16 18M10 16L14 8',
|
236
|
+
},
|
227
237
|
};
|
package/dist/src/utils/i18n.ts
CHANGED
@@ -9,56 +9,58 @@ type TextContent = Record<string, Record<string, string>>;
|
|
9
9
|
|
10
10
|
// 多语言文本内容
|
11
11
|
export const texts: Record<string, TextContent> = {
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
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
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
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
|
-
|
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
|
-
|
84
|
+
return (key: string): string => getText(langInfo, component, key);
|
83
85
|
}
|
@@ -56,7 +56,23 @@ interface Props {
|
|
56
56
|
| 'info'
|
57
57
|
| 'success'
|
58
58
|
| 'warning'
|
59
|
-
| 'error'
|
59
|
+
| 'error'
|
60
|
+
// 大自然灵感渐变
|
61
|
+
| 'gradient-sky'
|
62
|
+
| 'gradient-sunset'
|
63
|
+
| 'gradient-forest'
|
64
|
+
| 'gradient-ocean'
|
65
|
+
| 'gradient-mountain'
|
66
|
+
| 'gradient-flower'
|
67
|
+
// 水果灵感渐变
|
68
|
+
| 'gradient-watermelon'
|
69
|
+
| 'gradient-lemon'
|
70
|
+
| 'gradient-grape'
|
71
|
+
| 'gradient-blueberry'
|
72
|
+
| 'gradient-mango'
|
73
|
+
| 'gradient-kiwi'
|
74
|
+
| 'gradient-pitaya'
|
75
|
+
| 'gradient-banana';
|
60
76
|
|
61
77
|
/**
|
62
78
|
* 文本颜色,默认根据背景色自动设置
|
@@ -101,7 +117,43 @@ const getTextColorClass = () => {
|
|
101
117
|
: 'cosy:text-gray-800';
|
102
118
|
};
|
103
119
|
|
104
|
-
//
|
120
|
+
// 渐变色背景映射
|
121
|
+
const gradientBgClassMap = {
|
122
|
+
'gradient-sky': 'cosy:bg-gradient-to-r cosy:from-sky-400 cosy:to-indigo-500',
|
123
|
+
'gradient-watermelon':
|
124
|
+
'cosy:bg-gradient-to-r cosy:from-green-300 cosy:via-pink-400 cosy:to-red-500',
|
125
|
+
'gradient-lemon':
|
126
|
+
'cosy:bg-gradient-to-r cosy:from-yellow-200 cosy:via-yellow-400 cosy:to-yellow-600',
|
127
|
+
'gradient-grape':
|
128
|
+
'cosy:bg-gradient-to-r cosy:from-purple-400 cosy:via-indigo-500 cosy:to-purple-700',
|
129
|
+
'gradient-mango':
|
130
|
+
'cosy:bg-gradient-to-r cosy:from-yellow-300 cosy:via-orange-400 cosy:to-orange-600',
|
131
|
+
'gradient-forest':
|
132
|
+
'cosy:bg-gradient-to-r cosy:from-green-700 cosy:to-lime-300',
|
133
|
+
'gradient-ocean': 'cosy:bg-gradient-to-r cosy:from-cyan-400 cosy:to-blue-700',
|
134
|
+
'gradient-sunset':
|
135
|
+
'cosy:bg-gradient-to-r cosy:from-orange-400 cosy:via-pink-500 cosy:to-red-500',
|
136
|
+
'gradient-flower':
|
137
|
+
'cosy:bg-gradient-to-r cosy:from-pink-300 cosy:via-purple-400 cosy:to-fuchsia-500',
|
138
|
+
'gradient-pitaya':
|
139
|
+
'cosy:bg-gradient-to-r cosy:from-pink-200 cosy:via-fuchsia-400 cosy:to-lime-300',
|
140
|
+
'gradient-banana':
|
141
|
+
'cosy:bg-gradient-to-r cosy:from-yellow-100 cosy:via-yellow-300 cosy:to-yellow-500',
|
142
|
+
'gradient-blueberry':
|
143
|
+
'cosy:bg-gradient-to-r cosy:from-blue-400 cosy:via-blue-600 cosy:to-indigo-700',
|
144
|
+
'gradient-kiwi':
|
145
|
+
'cosy:bg-gradient-to-r cosy:from-lime-200 cosy:via-green-400 cosy:to-green-700',
|
146
|
+
};
|
147
|
+
|
148
|
+
const isGradient =
|
149
|
+
typeof bgColor === 'string' && bgColor.startsWith('gradient-');
|
150
|
+
let bgClass = '';
|
151
|
+
if (isGradient) {
|
152
|
+
bgClass =
|
153
|
+
gradientBgClassMap[bgColor as keyof typeof gradientBgClassMap] ?? '';
|
154
|
+
} else {
|
155
|
+
bgClass = `cosy:bg-${bgColor}`;
|
156
|
+
}
|
105
157
|
const bannerClasses = [
|
106
158
|
'cosy:w-full',
|
107
159
|
'cosy:py-8',
|
@@ -119,7 +171,7 @@ const bannerClasses = [
|
|
119
171
|
'cosy:shadow-md',
|
120
172
|
'cosy:hover:shadow-lg',
|
121
173
|
'cosy:hover:scale-[1.01]',
|
122
|
-
|
174
|
+
bgClass,
|
123
175
|
getTextColorClass(),
|
124
176
|
className,
|
125
177
|
].join(' ');
|
@@ -1,54 +1,3 @@
|
|
1
1
|
import Banner from './Banner.astro';
|
2
|
-
import BannerBasic from './BannerBasic.astro';
|
3
|
-
import BannerPrimary from './BannerPrimary.astro';
|
4
|
-
import BannerSecondary from './BannerSecondary.astro';
|
5
|
-
import BannerSuccess from './BannerSuccess.astro';
|
6
|
-
import BannerWarning from './BannerWarning.astro';
|
7
|
-
import BannerDanger from './BannerDanger.astro';
|
8
|
-
import BannerInfo from './BannerInfo.astro';
|
9
|
-
import BannerCustomStyle from './BannerCustomStyle.astro';
|
10
|
-
import BannerFadeIn from './BannerFadeIn.astro';
|
11
|
-
import BannerSlideUp from './BannerSlideUp.astro';
|
12
|
-
import BannerAllAnimations from './BannerAllAnimations.astro';
|
13
|
-
import BasicSourceCode from './BannerBasic.astro?raw';
|
14
|
-
import PrimarySourceCode from './BannerPrimary.astro?raw';
|
15
|
-
import SecondarySourceCode from './BannerSecondary.astro?raw';
|
16
|
-
import SuccessSourceCode from './BannerSuccess.astro?raw';
|
17
|
-
import WarningSourceCode from './BannerWarning.astro?raw';
|
18
|
-
import DangerSourceCode from './BannerDanger.astro?raw';
|
19
|
-
import InfoSourceCode from './BannerInfo.astro?raw';
|
20
|
-
import CustomStyleSourceCode from './BannerCustomStyle.astro?raw';
|
21
|
-
import FadeInSourceCode from './BannerFadeIn.astro?raw';
|
22
|
-
import SlideUpSourceCode from './BannerSlideUp.astro?raw';
|
23
|
-
import AllAnimationsSourceCode from './BannerAllAnimations.astro?raw';
|
24
|
-
import { extractSimpleExample } from '../../src/utils/component';
|
25
2
|
|
26
|
-
export {
|
27
|
-
Banner,
|
28
|
-
BannerBasic,
|
29
|
-
BannerPrimary,
|
30
|
-
BannerSecondary,
|
31
|
-
BannerSuccess,
|
32
|
-
BannerWarning,
|
33
|
-
BannerDanger,
|
34
|
-
BannerInfo,
|
35
|
-
BannerCustomStyle,
|
36
|
-
BannerFadeIn,
|
37
|
-
BannerSlideUp,
|
38
|
-
BannerAllAnimations,
|
39
|
-
};
|
40
|
-
|
41
|
-
// 导出示例源代码
|
42
|
-
export const BannerExampleCodes = {
|
43
|
-
Basic: extractSimpleExample(BasicSourceCode, 'Banner'),
|
44
|
-
Primary: extractSimpleExample(PrimarySourceCode, 'Banner'),
|
45
|
-
Secondary: extractSimpleExample(SecondarySourceCode, 'Banner'),
|
46
|
-
Success: extractSimpleExample(SuccessSourceCode, 'Banner'),
|
47
|
-
Warning: extractSimpleExample(WarningSourceCode, 'Banner'),
|
48
|
-
Danger: extractSimpleExample(DangerSourceCode, 'Banner'),
|
49
|
-
Info: extractSimpleExample(InfoSourceCode, 'Banner'),
|
50
|
-
CustomStyle: extractSimpleExample(CustomStyleSourceCode, 'Banner'),
|
51
|
-
FadeIn: extractSimpleExample(FadeInSourceCode, 'Banner'),
|
52
|
-
SlideUp: extractSimpleExample(SlideUpSourceCode, 'Banner'),
|
53
|
-
AllAnimations: extractSimpleExample(AllAnimationsSourceCode, 'Banner'),
|
54
|
-
};
|
3
|
+
export { Banner };
|
@@ -69,7 +69,20 @@ interface Props {
|
|
69
69
|
| 'ghost'
|
70
70
|
| 'link'
|
71
71
|
| 'outline'
|
72
|
-
| 'neutral'
|
72
|
+
| 'neutral'
|
73
|
+
| 'gradient-sky'
|
74
|
+
| 'gradient-watermelon'
|
75
|
+
| 'gradient-lemon'
|
76
|
+
| 'gradient-grape'
|
77
|
+
| 'gradient-mango'
|
78
|
+
| 'gradient-forest'
|
79
|
+
| 'gradient-ocean'
|
80
|
+
| 'gradient-sunset'
|
81
|
+
| 'gradient-flower'
|
82
|
+
| 'gradient-pitaya'
|
83
|
+
| 'gradient-banana'
|
84
|
+
| 'gradient-blueberry'
|
85
|
+
| 'gradient-kiwi';
|
73
86
|
size?: 'lg' | 'md' | 'sm' | 'xs';
|
74
87
|
shape?: 'circle' | 'square';
|
75
88
|
wide?: boolean;
|
@@ -81,7 +94,7 @@ interface Props {
|
|
81
94
|
onClick?: string;
|
82
95
|
formmethod?: string;
|
83
96
|
href?: string;
|
84
|
-
target?:
|
97
|
+
target?: '_self' | '_blank' | '_parent' | '_top';
|
85
98
|
[key: string]: any; // 允许任意自定义属性
|
86
99
|
}
|
87
100
|
|
@@ -119,6 +132,32 @@ const getButtonClasses = () => {
|
|
119
132
|
link: 'cosy:btn-link',
|
120
133
|
outline: 'cosy:btn-outline',
|
121
134
|
neutral: 'cosy:btn-neutral',
|
135
|
+
'gradient-sky':
|
136
|
+
'cosy:bg-gradient-to-r cosy:from-sky-400 cosy:to-indigo-500 cosy:text-white hover:cosy:from-sky-500 hover:cosy:to-indigo-600',
|
137
|
+
'gradient-watermelon':
|
138
|
+
'cosy:bg-gradient-to-r cosy:from-green-300 cosy:via-pink-400 cosy:to-red-500 cosy:text-white hover:cosy:from-green-400 hover:cosy:to-red-600',
|
139
|
+
'gradient-lemon':
|
140
|
+
'cosy:bg-gradient-to-r cosy:from-yellow-200 cosy:via-yellow-400 cosy:to-yellow-600 cosy:text-gray-900 hover:cosy:from-yellow-300 hover:cosy:to-yellow-700',
|
141
|
+
'gradient-grape':
|
142
|
+
'cosy:bg-gradient-to-r cosy:from-purple-400 cosy:via-indigo-500 cosy:to-purple-700 cosy:text-white hover:cosy:from-purple-500 hover:cosy:to-purple-800',
|
143
|
+
'gradient-mango':
|
144
|
+
'cosy:bg-gradient-to-r cosy:from-yellow-300 cosy:via-orange-400 cosy:to-orange-600 cosy:text-white hover:cosy:from-yellow-400 hover:cosy:to-orange-700',
|
145
|
+
'gradient-forest':
|
146
|
+
'cosy:bg-gradient-to-r cosy:from-green-700 cosy:to-lime-300 cosy:text-white hover:cosy:from-green-800 hover:cosy:to-lime-400',
|
147
|
+
'gradient-ocean':
|
148
|
+
'cosy:bg-gradient-to-r cosy:from-cyan-400 cosy:to-blue-700 cosy:text-white hover:cosy:from-cyan-500 hover:cosy:to-blue-800',
|
149
|
+
'gradient-sunset':
|
150
|
+
'cosy:bg-gradient-to-r cosy:from-orange-400 cosy:via-pink-500 cosy:to-red-500 cosy:text-white hover:cosy:from-orange-500 hover:cosy:to-red-600',
|
151
|
+
'gradient-flower':
|
152
|
+
'cosy:bg-gradient-to-r cosy:from-pink-300 cosy:via-purple-400 cosy:to-fuchsia-500 cosy:text-white hover:cosy:from-pink-400 hover:cosy:to-fuchsia-600',
|
153
|
+
'gradient-pitaya':
|
154
|
+
'cosy:bg-gradient-to-r cosy:from-pink-200 cosy:via-fuchsia-400 cosy:to-lime-300 cosy:text-white hover:cosy:from-pink-300 hover:cosy:to-lime-400',
|
155
|
+
'gradient-banana':
|
156
|
+
'cosy:bg-gradient-to-r cosy:from-yellow-100 cosy:via-yellow-300 cosy:to-yellow-500 cosy:text-gray-900 hover:cosy:from-yellow-200 hover:cosy:to-yellow-600',
|
157
|
+
'gradient-blueberry':
|
158
|
+
'cosy:bg-gradient-to-r cosy:from-blue-400 cosy:via-blue-600 cosy:to-indigo-700 cosy:text-white hover:cosy:from-blue-500 hover:cosy:to-indigo-800',
|
159
|
+
'gradient-kiwi':
|
160
|
+
'cosy:bg-gradient-to-r cosy:from-lime-200 cosy:via-green-400 cosy:to-green-700 cosy:text-white hover:cosy:from-lime-300 hover:cosy:to-green-800',
|
122
161
|
};
|
123
162
|
|
124
163
|
// Size classes
|
@@ -0,0 +1,55 @@
|
|
1
|
+
---
|
2
|
+
import { CodeIcon } from '../icons';
|
3
|
+
const { isCodeView = false } = Astro.props;
|
4
|
+
---
|
5
|
+
|
6
|
+
<button
|
7
|
+
role="switch"
|
8
|
+
class={`cosy:btn cosy:btn-ghost cosy:btn-sm ${isCodeView ? 'cosy:btn-primary' : ''}`}
|
9
|
+
aria-checked={isCodeView ? 'true' : 'false'}
|
10
|
+
aria-label="切换代码/预览"
|
11
|
+
data-toggle="code">
|
12
|
+
<span class="cosy:code-icon"><CodeIcon /></span>
|
13
|
+
</button>
|
14
|
+
|
15
|
+
<script>
|
16
|
+
function initializeCodeToggle() {
|
17
|
+
console.log('CodeContainer: 初始化代码/预览切换按钮');
|
18
|
+
const codeToggles = document.querySelectorAll('[data-toggle="code"]');
|
19
|
+
codeToggles.forEach((toggle) => {
|
20
|
+
toggle.addEventListener('click', () => {
|
21
|
+
const container = toggle.closest('[data-role="code-container"]');
|
22
|
+
if (!container) {
|
23
|
+
console.error('CodeContainer: 无法找到父容器');
|
24
|
+
return;
|
25
|
+
}
|
26
|
+
const isChecked = toggle.getAttribute('aria-checked') === 'true';
|
27
|
+
toggle.setAttribute('aria-checked', !isChecked ? 'true' : 'false');
|
28
|
+
toggle.classList.toggle('cosy:btn-primary', !isChecked);
|
29
|
+
toggle.classList.toggle('cosy:btn-ghost', isChecked);
|
30
|
+
const activeExample = container.querySelector(
|
31
|
+
'.cosy\\:example-container:not(.cosy\\:hidden)'
|
32
|
+
);
|
33
|
+
if (!activeExample) {
|
34
|
+
console.error('CodeContainer: 无法找到活动示例');
|
35
|
+
return;
|
36
|
+
}
|
37
|
+
activeExample
|
38
|
+
.querySelectorAll('.cosy\\:code-example-panel')
|
39
|
+
.forEach((panel) => {
|
40
|
+
if (panel.getAttribute('data-panel') === 'code') {
|
41
|
+
panel.classList.toggle('cosy:hidden', isChecked);
|
42
|
+
panel.classList.toggle('cosy:block', !isChecked);
|
43
|
+
} else {
|
44
|
+
panel.classList.toggle('cosy:hidden', !isChecked);
|
45
|
+
panel.classList.toggle('cosy:block', isChecked);
|
46
|
+
}
|
47
|
+
});
|
48
|
+
});
|
49
|
+
});
|
50
|
+
}
|
51
|
+
|
52
|
+
document.addEventListener('astro:page-load', () => {
|
53
|
+
initializeCodeToggle();
|
54
|
+
});
|
55
|
+
</script>
|
@@ -0,0 +1,74 @@
|
|
1
|
+
---
|
2
|
+
import { ClipboardIcon } from '../icons';
|
3
|
+
---
|
4
|
+
|
5
|
+
<button
|
6
|
+
class="cosy:gap-2 cosy:btn cosy:btn-ghost cosy:btn-sm"
|
7
|
+
aria-label="复制代码"
|
8
|
+
id="cosy-copy-btn"
|
9
|
+
type="button"
|
10
|
+
style="position: relative;">
|
11
|
+
<span class="cosy:copy-icon"><ClipboardIcon /></span>
|
12
|
+
<span
|
13
|
+
id="copy-toast"
|
14
|
+
style="
|
15
|
+
display: none;
|
16
|
+
position: absolute;
|
17
|
+
top: -2.5rem;
|
18
|
+
left: 50%;
|
19
|
+
transform: translateX(-50%);
|
20
|
+
background: #22c55e;
|
21
|
+
color: #fff;
|
22
|
+
padding: 0.25rem 0.75rem;
|
23
|
+
border-radius: 0.5rem;
|
24
|
+
font-size: 0.875rem;
|
25
|
+
white-space: nowrap;
|
26
|
+
z-index: 10;
|
27
|
+
box-shadow: 0 2px 8px rgba(0,0,0,0.08);
|
28
|
+
pointer-events: none;
|
29
|
+
transition: opacity 0.2s;
|
30
|
+
"
|
31
|
+
>复制成功</span
|
32
|
+
>
|
33
|
+
</button>
|
34
|
+
|
35
|
+
<script>
|
36
|
+
function initializeCopyCode() {
|
37
|
+
console.log('CodeContainer: 初始化复制代码按钮');
|
38
|
+
|
39
|
+
const copyButtons = document.querySelectorAll('[aria-label="复制代码"]');
|
40
|
+
copyButtons.forEach((button) => {
|
41
|
+
button.addEventListener('click', () => {
|
42
|
+
const container = button.closest('[data-role="code-container"]');
|
43
|
+
if (!container) return;
|
44
|
+
const activeExample = container.querySelector(
|
45
|
+
'.cosy\\:example-container:not(.cosy\\:hidden)'
|
46
|
+
);
|
47
|
+
if (!activeExample) return;
|
48
|
+
const codePanel = activeExample.querySelector('[data-panel="code"]');
|
49
|
+
if (!codePanel) return;
|
50
|
+
const codeElement = codePanel.querySelector('code');
|
51
|
+
if (!codeElement) return;
|
52
|
+
const code = codeElement.textContent || '';
|
53
|
+
navigator.clipboard.writeText(code).then(() => {
|
54
|
+
// 气泡提示
|
55
|
+
const toast = button.querySelector('#copy-toast');
|
56
|
+
if (toast && toast instanceof HTMLElement) {
|
57
|
+
toast.style.display = 'block';
|
58
|
+
toast.style.opacity = '1';
|
59
|
+
setTimeout(() => {
|
60
|
+
toast.style.opacity = '0';
|
61
|
+
setTimeout(() => {
|
62
|
+
toast.style.display = 'none';
|
63
|
+
}, 200);
|
64
|
+
}, 2000);
|
65
|
+
}
|
66
|
+
});
|
67
|
+
});
|
68
|
+
});
|
69
|
+
}
|
70
|
+
|
71
|
+
document.addEventListener('astro:page-load', () => {
|
72
|
+
initializeCopyCode();
|
73
|
+
});
|
74
|
+
</script>
|