@coffic/cosy-ui 0.1.29 → 0.2.2

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 (84) hide show
  1. package/README.md +43 -22
  2. package/dist/app.css +1 -0
  3. package/dist/assets/logo-rounded.png +0 -0
  4. package/dist/assets/logo.png +0 -0
  5. package/dist/components/base/Alert.astro +186 -0
  6. package/dist/components/base/Button.astro +103 -0
  7. package/dist/components/base/Image.astro +291 -0
  8. package/dist/components/base/Link.astro +131 -0
  9. package/dist/components/containers/Container.astro +103 -0
  10. package/dist/components/containers/Main.astro +167 -0
  11. package/dist/components/containers/Section.astro +145 -0
  12. package/dist/components/containers/index.ts +3 -0
  13. package/dist/components/data-display/Blog.astro +195 -0
  14. package/dist/components/data-display/TeamMember.astro +135 -0
  15. package/dist/components/data-display/TeamMembers.astro +101 -0
  16. package/dist/components/display/Banner.astro +57 -0
  17. package/dist/components/display/Card.astro +135 -0
  18. package/dist/components/display/CodeBlock.astro +147 -0
  19. package/dist/components/display/CodeExample.astro +330 -0
  20. package/dist/components/display/Hero.astro +119 -0
  21. package/dist/components/display/Modal.astro +115 -0
  22. package/dist/components/icons/AlertTriangle.astro +35 -0
  23. package/dist/components/icons/CalendarIcon.astro +38 -0
  24. package/dist/components/icons/CheckCircle.astro +36 -0
  25. package/dist/components/icons/CheckIcon.astro +38 -0
  26. package/dist/components/icons/ClipboardIcon.astro +39 -0
  27. package/dist/components/icons/CloseIcon.astro +38 -0
  28. package/dist/components/icons/ErrorIcon.astro +35 -0
  29. package/dist/components/icons/GithubIcon.astro +31 -0
  30. package/dist/components/icons/InfoCircle.astro +37 -0
  31. package/dist/components/icons/InfoIcon.astro +38 -0
  32. package/dist/components/icons/LinkIcon.astro +39 -0
  33. package/dist/components/icons/LinkedinIcon.astro +31 -0
  34. package/dist/components/icons/MenuIcon.astro +41 -0
  35. package/dist/components/icons/SearchIcon.astro +40 -0
  36. package/dist/components/icons/SocialIcon.astro +100 -0
  37. package/dist/components/icons/SuccessIcon.astro +35 -0
  38. package/dist/components/icons/SunCloudyIcon.astro +45 -0
  39. package/dist/components/icons/TwitterIcon.astro +31 -0
  40. package/dist/components/icons/UserIcon.astro +35 -0
  41. package/dist/components/icons/WarningIcon.astro +38 -0
  42. package/dist/components/icons/XCircle.astro +37 -0
  43. package/dist/components/layouts/BaseLayout.astro +144 -0
  44. package/dist/components/layouts/DashboardLayout.astro +660 -0
  45. package/dist/components/layouts/DefaultLayout.astro +170 -0
  46. package/dist/components/layouts/DocumentationLayout.astro +469 -0
  47. package/dist/components/layouts/Flex.astro +138 -0
  48. package/dist/components/layouts/Footer.astro +284 -0
  49. package/dist/components/layouts/Grid.astro +182 -0
  50. package/dist/components/layouts/Header.astro +114 -0
  51. package/dist/components/layouts/LandingLayout.astro +388 -0
  52. package/dist/components/layouts/Stack.astro +149 -0
  53. package/dist/components/navigation/LanguageSwitcher.astro +81 -0
  54. package/dist/components/navigation/TableOfContents.astro +352 -0
  55. package/dist/components/navigation/ThemeSwitcher.astro +89 -0
  56. package/dist/components/typography/Article.astro +144 -0
  57. package/dist/components/typography/Heading.astro +205 -0
  58. package/dist/components/typography/Text.astro +187 -0
  59. package/dist/index.ts +70 -0
  60. package/dist/integration.ts +14 -0
  61. package/dist/style.ts +1 -0
  62. package/{src → dist}/types/footer.ts +1 -0
  63. package/dist/utils/theme.ts +55 -0
  64. package/package.json +67 -59
  65. package/index.ts +0 -18
  66. package/src/components/Alert.astro +0 -78
  67. package/src/components/Article.astro +0 -11
  68. package/src/components/Banner.astro +0 -49
  69. package/src/components/Blog.astro +0 -115
  70. package/src/components/Button.astro +0 -49
  71. package/src/components/Card.astro +0 -113
  72. package/src/components/CodeBlock.astro +0 -186
  73. package/src/components/Footer.astro +0 -148
  74. package/src/components/Header.astro +0 -305
  75. package/src/components/Hero.astro +0 -69
  76. package/src/components/Image.astro +0 -251
  77. package/src/components/Link.astro +0 -82
  78. package/src/components/Modal.astro +0 -67
  79. package/src/components/SocialIcon.astro +0 -36
  80. package/src/components/TeamMember.astro +0 -68
  81. package/src/components/TeamMembers.astro +0 -43
  82. package/src/env.d.ts +0 -0
  83. /package/{src/components → dist/components/base}/ThemeItem.astro +0 -0
  84. /package/{src → dist}/utils/social.ts +0 -0
@@ -0,0 +1,145 @@
1
+ ---
2
+ /**
3
+ * Section组件
4
+ *
5
+ * 一个用于页面内容区块的组件,支持不同的内边距、背景和间距
6
+ *
7
+ * @example
8
+ * ```astro
9
+ * <Section>
10
+ * <h2>默认区块</h2>
11
+ * <p>内容将被包裹在一个合适的区块中</p>
12
+ * </Section>
13
+ *
14
+ * <Section padding="lg" background="gray" centered={true}>
15
+ * <h2>自定义区块</h2>
16
+ * <p>大内边距,灰色背景,内容居中</p>
17
+ * </Section>
18
+ * ```
19
+ */
20
+
21
+ import type { HTMLAttributes } from 'astro/types';
22
+ import Container from './Container.astro';
23
+
24
+ interface Props extends HTMLAttributes<'section'> {
25
+ /**
26
+ * 内边距大小
27
+ * @default "md"
28
+ */
29
+ padding?: 'none' | 'sm' | 'md' | 'lg' | 'xl';
30
+
31
+ /**
32
+ * 背景颜色
33
+ * @default "transparent"
34
+ */
35
+ background?: 'transparent' | 'white' | 'gray' | 'primary' | 'secondary' | 'dark';
36
+
37
+ /**
38
+ * 是否使用容器包裹内容
39
+ * @default true
40
+ */
41
+ container?: boolean;
42
+
43
+ /**
44
+ * 容器尺寸,仅当container为true时有效
45
+ * @default "md"
46
+ */
47
+ containerSize?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'full';
48
+
49
+ /**
50
+ * 内容是否居中
51
+ * @default false
52
+ */
53
+ centered?: boolean;
54
+
55
+ /**
56
+ * 自定义类名
57
+ */
58
+ class?: string;
59
+
60
+ /**
61
+ * 类名列表
62
+ */
63
+ 'class:list'?: any;
64
+
65
+ /**
66
+ * 自定义ID
67
+ */
68
+ id?: string;
69
+
70
+ /**
71
+ * 自定义内联样式
72
+ */
73
+ style?: string;
74
+ }
75
+
76
+ const {
77
+ padding = 'md',
78
+ background = 'transparent',
79
+ container = true,
80
+ containerSize = 'md',
81
+ centered = false,
82
+ class: className = '',
83
+ 'class:list': classList,
84
+ id,
85
+ style,
86
+ ...rest
87
+ } = Astro.props;
88
+
89
+ // 内边距映射
90
+ const paddingClasses = {
91
+ 'none': 'py-0',
92
+ 'sm': 'py-6',
93
+ 'md': 'py-12',
94
+ 'lg': 'py-16',
95
+ 'xl': 'py-24'
96
+ };
97
+
98
+ // 背景颜色映射
99
+ const backgroundClasses = {
100
+ 'transparent': 'bg-transparent',
101
+ 'white': 'bg-white',
102
+ 'gray': 'bg-gray-100',
103
+ 'primary': 'bg-blue-50',
104
+ 'secondary': 'bg-gray-50',
105
+ 'dark': 'bg-gray-900 text-white'
106
+ };
107
+
108
+ // 构建最终类名
109
+ const sectionClasses = [
110
+ paddingClasses[padding as keyof typeof paddingClasses],
111
+ backgroundClasses[background as keyof typeof backgroundClasses],
112
+ className
113
+ ].join(' ');
114
+
115
+ // 内容类名
116
+ const contentClasses = centered ? 'text-center' : '';
117
+ ---
118
+
119
+ <section id={id} class:list={[sectionClasses, classList]} style={style} {...rest}>
120
+ {container ? (
121
+ <Container size={containerSize} class={contentClasses}>
122
+ <slot />
123
+ </Container>
124
+ ) : (
125
+ <div class={contentClasses}>
126
+ <slot />
127
+ </div>
128
+ )}
129
+ </section>
130
+
131
+ <style>
132
+ /* 背景颜色 */
133
+ .bg-transparent { background-color: transparent; }
134
+ .bg-white { background-color: #ffffff; }
135
+ .bg-gray-50 { background-color: #f9fafb; }
136
+ .bg-gray-100 { background-color: #f3f4f6; }
137
+ .bg-blue-50 { background-color: #eff6ff; }
138
+ .bg-gray-900 { background-color: #111827; }
139
+
140
+ /* 文字颜色 */
141
+ .text-white { color: #ffffff; }
142
+
143
+ /* 文本对齐 */
144
+ .text-center { text-align: center; }
145
+ </style>
@@ -0,0 +1,3 @@
1
+ export { default as Container } from './Container.astro';
2
+ export { default as Section } from './Section.astro';
3
+ export { default as Main } from './Main.astro';
@@ -0,0 +1,195 @@
1
+ ---
2
+ import { UserIcon, CalendarIcon } from '../../index';
3
+
4
+ interface Props {
5
+ title: string;
6
+ subtitle?: string;
7
+ author?: string;
8
+ date?: Date;
9
+ cover?: {
10
+ src: string;
11
+ alt?: string;
12
+ };
13
+ tags?: string[];
14
+ }
15
+
16
+ const {
17
+ title,
18
+ subtitle,
19
+ author,
20
+ date,
21
+ cover,
22
+ tags = [],
23
+ } = Astro.props;
24
+
25
+ // 格式化日期
26
+ const formatDate = (date?: Date) => {
27
+ if (!date) return '';
28
+ return new Intl.DateTimeFormat('zh-CN', {
29
+ year: 'numeric',
30
+ month: 'long',
31
+ day: 'numeric'
32
+ }).format(date);
33
+ };
34
+ ---
35
+
36
+ <article class="article">
37
+ <header class="article-header">
38
+ {cover && (
39
+ <div class="cover-container">
40
+ <img
41
+ src={cover.src}
42
+ alt={cover.alt || title}
43
+ class="cover-image"
44
+ />
45
+ </div>
46
+ )}
47
+
48
+ <div class="header-content">
49
+ <h1 class="article-title">{title}</h1>
50
+ {subtitle && (
51
+ <p class="article-subtitle">{subtitle}</p>
52
+ )}
53
+
54
+ <div class="article-meta">
55
+ {author && (
56
+ <div class="meta-item">
57
+ <UserIcon size="16px" />
58
+ <span>{author}</span>
59
+ </div>
60
+ )}
61
+
62
+ {date && (
63
+ <div class="meta-item">
64
+ <CalendarIcon size="16px" />
65
+ <time datetime={date.toISOString()}>{formatDate(date)}</time>
66
+ </div>
67
+ )}
68
+ </div>
69
+
70
+ {tags.length > 0 && (
71
+ <div class="article-tags">
72
+ {tags.map((tag: string) => (
73
+ <span class="tag">{tag}</span>
74
+ ))}
75
+ </div>
76
+ )}
77
+ </div>
78
+ </header>
79
+
80
+ <div class="article-content">
81
+ <slot />
82
+ </div>
83
+ </article>
84
+
85
+ <style>
86
+ /* 基础样式 */
87
+ .article {
88
+ container-type: inline-size;
89
+ }
90
+
91
+ /* 文章头部 */
92
+ .article-header {
93
+ margin-bottom: 2rem;
94
+ }
95
+
96
+ /* 封面图片 */
97
+ .cover-container {
98
+ position: relative;
99
+ width: 100%;
100
+ height: 300px;
101
+ margin-bottom: 1.5rem;
102
+ border-radius: 0.5rem;
103
+ overflow: hidden;
104
+ }
105
+
106
+ .cover-image {
107
+ width: 100%;
108
+ height: 100%;
109
+ object-fit: cover;
110
+ }
111
+
112
+ /* 标题和副标题 */
113
+ .header-content {
114
+ display: flex;
115
+ flex-direction: column;
116
+ gap: 1rem;
117
+ }
118
+
119
+ .article-title {
120
+ font-size: 2.25rem;
121
+ font-weight: 700;
122
+ line-height: 1.2;
123
+ letter-spacing: -0.025em;
124
+ }
125
+
126
+ .article-subtitle {
127
+ font-size: 1.25rem;
128
+ color: var(--text-secondary, rgba(0, 0, 0, 0.7));
129
+ }
130
+
131
+ /* 元数据 */
132
+ .article-meta {
133
+ display: flex;
134
+ flex-wrap: wrap;
135
+ align-items: center;
136
+ gap: 1rem;
137
+ font-size: 0.875rem;
138
+ color: var(--text-secondary, rgba(0, 0, 0, 0.6));
139
+ }
140
+
141
+ .meta-item {
142
+ display: flex;
143
+ align-items: center;
144
+ gap: 0.5rem;
145
+ }
146
+
147
+ /* 标签 */
148
+ .article-tags {
149
+ display: flex;
150
+ flex-wrap: wrap;
151
+ gap: 0.5rem;
152
+ }
153
+
154
+ .tag {
155
+ display: inline-block;
156
+ padding: 0.25rem 0.75rem;
157
+ border: 1px solid var(--border-color, #e2e8f0);
158
+ border-radius: 9999px;
159
+ font-size: 0.75rem;
160
+ line-height: 1.5;
161
+ }
162
+
163
+ /* 文章内容 */
164
+ .article-content {
165
+ max-width: none;
166
+ font-size: 1.125rem;
167
+ line-height: 1.75;
168
+ }
169
+
170
+ /* 响应式调整 */
171
+ @media (min-width: 768px) {
172
+ .article-title {
173
+ font-size: 3rem;
174
+ }
175
+
176
+ .cover-container {
177
+ height: 400px;
178
+ }
179
+ }
180
+
181
+ /* 暗色主题适配 */
182
+ @media (prefers-color-scheme: dark) {
183
+ .article-subtitle {
184
+ color: var(--text-secondary, rgba(255, 255, 255, 0.7));
185
+ }
186
+
187
+ .article-meta {
188
+ color: var(--text-secondary, rgba(255, 255, 255, 0.6));
189
+ }
190
+
191
+ .tag {
192
+ border-color: var(--border-color, #2d3748);
193
+ }
194
+ }
195
+ </style>
@@ -0,0 +1,135 @@
1
+ ---
2
+ /**
3
+ * @component TeamMember
4
+ *
5
+ * @description
6
+ * TeamMember 组件用于展示单个团队成员的信息,包括姓名、职位、头像、简介和社交媒体链接。
7
+ * 组件采用卡片式设计,支持悬停效果,并可以链接到成员的社交媒体账号。
8
+ *
9
+ * @design
10
+ * 设计理念:
11
+ * 1. 个人展示 - 突出展示团队成员的个人信息和形象
12
+ * 2. 社交连接 - 提供社交媒体链接,方便与团队成员建立联系
13
+ * 3. 视觉一致性 - 使用卡片组件确保与整体设计风格一致
14
+ * 4. 交互反馈 - 悬停时提供视觉反馈,增强用户体验
15
+ *
16
+ * @usage
17
+ * 基本用法:
18
+ * ```astro
19
+ * <TeamMember
20
+ * name="张三"
21
+ * role="前端开发工程师"
22
+ * avatar="/images/avatars/zhangsan.jpg"
23
+ * bio="拥有5年前端开发经验,专注于React和Vue生态系统。"
24
+ * />
25
+ * ```
26
+ *
27
+ * 包含社交媒体链接:
28
+ * ```astro
29
+ * <TeamMember
30
+ * name="李四"
31
+ * role="UI设计师"
32
+ * avatar="/images/avatars/lisi.jpg"
33
+ * bio="专注于用户体验和界面设计,热爱创造直观易用的产品。"
34
+ * socialLinks={[
35
+ * { platform: 'github', url: 'https://github.com/lisi' },
36
+ * { platform: 'twitter', url: 'https://twitter.com/lisi' },
37
+ * { platform: 'linkedin', url: 'https://linkedin.com/in/lisi' }
38
+ * ]}
39
+ * />
40
+ * ```
41
+ */
42
+
43
+ import Link from '../base/Link.astro';
44
+ import SocialIcon from '../icons/SocialIcon.astro';
45
+ import Image from '../base/Image.astro';
46
+
47
+ // 导入样式
48
+ import '../../app.css';
49
+
50
+ interface SocialLink {
51
+ /**
52
+ * 社交媒体平台
53
+ */
54
+ platform: 'github' | 'twitter' | 'linkedin' | 'website' | 'email';
55
+ /**
56
+ * 社交媒体链接URL
57
+ */
58
+ url: string;
59
+ }
60
+
61
+ // 自定义图片元数据接口,替代 astro 的 ImageMetadata
62
+ interface CustomImageMetadata {
63
+ src: string;
64
+ width: number;
65
+ height: number;
66
+ format: string;
67
+ }
68
+
69
+ export interface Props {
70
+ /**
71
+ * 团队成员姓名
72
+ */
73
+ name: string;
74
+ /**
75
+ * 团队成员职位
76
+ */
77
+ role: string;
78
+ /**
79
+ * 团队成员头像
80
+ */
81
+ avatar: CustomImageMetadata | string;
82
+ /**
83
+ * 团队成员简介
84
+ */
85
+ bio: string;
86
+ /**
87
+ * 社交媒体链接
88
+ */
89
+ socialLinks?: SocialLink[];
90
+ /**
91
+ * 自定义类名
92
+ */
93
+ class?: string;
94
+ }
95
+
96
+ const { name, role, avatar, bio, socialLinks, class: className = '' } = Astro.props;
97
+ ---
98
+
99
+ <div class:list={['team-member-card', className]}>
100
+ <figure class="team-member-avatar-container">
101
+ <Image
102
+ src={avatar}
103
+ alt={`${name}'s avatar`}
104
+ width={192}
105
+ height={192}
106
+ rounded="xl"
107
+ transition="fade"
108
+ hover="brightness"
109
+ class="team-member-avatar"
110
+ />
111
+ </figure>
112
+ <div class="team-member-content">
113
+ <h2 class="team-member-name">{name}</h2>
114
+ <p class="team-member-role">{role}</p>
115
+ <p class="team-member-bio">{bio}</p>
116
+
117
+ {
118
+ socialLinks && socialLinks.length > 0 && (
119
+ <div class="team-member-social">
120
+ {socialLinks.map((link: SocialLink) => (
121
+ <Link
122
+ href={link.url}
123
+ external
124
+ variant="ghost"
125
+ class="team-member-social-link"
126
+ aria-label={`Visit ${name}'s ${link.platform} profile`}>
127
+ <SocialIcon platform={link.platform} class="team-member-social-icon" />
128
+ </Link>
129
+ ))}
130
+ </div>
131
+ )
132
+ }
133
+ </div>
134
+ </div>
135
+
@@ -0,0 +1,101 @@
1
+ ---
2
+ /**
3
+ * @component TeamMembers
4
+ *
5
+ * @description
6
+ * TeamMembers 组件用于展示团队成员列表,以网格布局呈现多个 TeamMember 组件。
7
+ * 支持响应式布局,可以根据屏幕大小自动调整列数。
8
+ *
9
+ * @design
10
+ * 设计理念:
11
+ * 1. 一致性展示 - 以统一的卡片形式展示团队成员信息
12
+ * 2. 响应式布局 - 在不同屏幕尺寸下自动调整列数
13
+ * 3. 灵活配置 - 支持自定义列数和样式
14
+ *
15
+ * @usage
16
+ * 基本用法:
17
+ * ```astro
18
+ * <TeamMembers members={teamData} />
19
+ * ```
20
+ *
21
+ * 自定义列数:
22
+ * ```astro
23
+ * <TeamMembers members={teamData} columns={2} />
24
+ * ```
25
+ *
26
+ * 添加自定义类名:
27
+ * ```astro
28
+ * <TeamMembers members={teamData} class="mt-8" />
29
+ * ```
30
+ */
31
+
32
+ import TeamMember from './TeamMember.astro';
33
+
34
+ // 导入样式
35
+ import '../../app.css';
36
+
37
+ // 自定义图片元数据接口
38
+ interface ImageMetadata {
39
+ src: string;
40
+ width: number;
41
+ height: number;
42
+ format: string;
43
+ }
44
+
45
+ interface SocialLink {
46
+ platform: 'github' | 'twitter' | 'linkedin' | 'website' | 'email';
47
+ url: string;
48
+ }
49
+
50
+ interface TeamMemberData {
51
+ name: string;
52
+ role: string;
53
+ avatar: ImageMetadata | string;
54
+ bio: string;
55
+ socialLinks?: SocialLink[];
56
+ }
57
+
58
+ interface Props {
59
+ /**
60
+ * 团队成员数据数组
61
+ */
62
+ members: TeamMemberData[];
63
+ /**
64
+ * 网格列数
65
+ * @default 3
66
+ */
67
+ columns?: 2 | 3 | 4;
68
+ /**
69
+ * 自定义类名
70
+ */
71
+ class?: string;
72
+ }
73
+
74
+ const {
75
+ members,
76
+ columns = 3,
77
+ class: className = ''
78
+ } = Astro.props;
79
+
80
+ // 使用类型断言确保 columns 是有效的键
81
+ const columnsValue = columns as 2 | 3 | 4;
82
+
83
+ // 根据列数生成对应的类名
84
+ const getGridClasses = (cols: 2 | 3 | 4) => {
85
+ const baseClass = 'team-members-cols-1';
86
+ const mdClass = 'team-members-cols-md-2';
87
+ const lgClass = cols === 4 ? 'team-members-cols-lg-4' : 'team-members-cols-lg-3';
88
+
89
+ return [baseClass, mdClass, lgClass];
90
+ };
91
+ ---
92
+
93
+ <div class:list={["team-members-container", className]}>
94
+ <div class:list={["team-members-grid", ...getGridClasses(columnsValue)]}>
95
+ {members.map((member: TeamMemberData, index: number) => (
96
+ <div class="team-members-animate">
97
+ <TeamMember {...member} />
98
+ </div>
99
+ ))}
100
+ </div>
101
+ </div>
@@ -0,0 +1,57 @@
1
+ ---
2
+ /**
3
+ * @component Banner
4
+ *
5
+ * @description
6
+ * Banner 组件用于在页面中展示醒目的横幅信息,通常用于展示重要的标语、公告或营销信息。
7
+ * 组件设计简洁大方,具有平滑的动画效果,能够吸引用户注意力。
8
+ *
9
+ * @design
10
+ * 设计理念:
11
+ * 1. 视觉冲击力 - 使用大号字体和醒目的背景,确保信息能够被用户注意到
12
+ * 2. 简洁明了 - 简单的布局和充足的留白,让信息更容易被理解
13
+ * 3. 动态效果 - 使用淡入和上滑动画,增强用户体验
14
+ * 4. 响应式设计 - 在不同屏幕尺寸下保持良好的可读性
15
+ *
16
+ * 视觉特点:
17
+ * - 圆角设计:柔和的视觉效果
18
+ * - 悬停效果:轻微放大和阴影增强,提供交互反馈
19
+ * - 动画效果:淡入和上滑动画,增强视觉吸引力
20
+ * - 模糊背景:半透明背景配合模糊效果,现代感强
21
+ *
22
+ * @usage
23
+ * 基本用法:
24
+ * ```astro
25
+ * <Banner>欢迎使用我们的服务</Banner>
26
+ * ```
27
+ *
28
+ * 在页脚中使用:
29
+ * ```astro
30
+ * <footer>
31
+ * <Banner>构建美好的数字体验</Banner>
32
+ * </footer>
33
+ * ```
34
+ *
35
+ * @slots
36
+ * @slot default - Banner 中显示的文本内容
37
+ *
38
+ * @accessibility
39
+ * - 使用适当的字体大小和行高,确保文本可读性
40
+ * - 动画遵循 prefers-reduced-motion 媒体查询,尊重用户的动画偏好设置
41
+ */
42
+
43
+ // 导入样式
44
+ import '../../app.css';
45
+ ---
46
+
47
+ <div class="banner-container">
48
+ <div class="banner">
49
+ <div class="banner-content">
50
+ <div class="banner-text">
51
+ <p class="banner-message">
52
+ <slot />
53
+ </p>
54
+ </div>
55
+ </div>
56
+ </div>
57
+ </div>