@coffic/cosy-ui 0.3.69 → 0.4.5

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 (34) hide show
  1. package/dist/app.css +1 -1
  2. package/dist/components/base/Alert.astro +3 -3
  3. package/dist/components/containers/Container.astro +80 -4
  4. package/dist/components/containers/Main.astro +41 -54
  5. package/dist/components/data-display/Blog.astro +1 -0
  6. package/dist/components/data-display/ProductCard.astro +0 -2
  7. package/dist/components/data-display/Products.astro +0 -2
  8. package/dist/components/data-display/TeamMember.astro +0 -2
  9. package/dist/components/data-display/TeamMembers.astro +0 -2
  10. package/dist/components/display/Banner.astro +0 -1
  11. package/dist/components/display/Card.astro +0 -1
  12. package/dist/components/display/CodeBlock.astro +0 -1
  13. package/dist/components/display/CodeExample.astro +0 -1
  14. package/dist/components/display/Modal.astro +65 -67
  15. package/dist/components/layouts/AppLayout.astro +258 -0
  16. package/dist/components/layouts/BaseLayout.astro +46 -92
  17. package/dist/components/layouts/DashboardLayout.astro +615 -604
  18. package/dist/components/layouts/Footer.astro +141 -113
  19. package/dist/components/layouts/Header.astro +11 -292
  20. package/dist/components/layouts/Sidebar.astro +54 -31
  21. package/dist/components/layouts/SidebarNav.astro +1 -11
  22. package/dist/components/typography/Article.astro +8 -30
  23. package/dist/index.ts +7 -4
  24. package/dist/types/article.ts +22 -0
  25. package/dist/types/footer.ts +119 -22
  26. package/dist/types/header.ts +70 -0
  27. package/dist/types/layout.ts +71 -10
  28. package/dist/types/main.ts +69 -0
  29. package/dist/types/meta.ts +50 -0
  30. package/dist/types/sidebar.ts +38 -0
  31. package/package.json +2 -2
  32. package/dist/components/layouts/DefaultLayout.astro +0 -170
  33. package/dist/components/layouts/DocumentationLayout.astro +0 -624
  34. package/dist/components/layouts/LandingLayout.astro +0 -388
@@ -47,58 +47,12 @@
47
47
  * </Main>
48
48
  * ```
49
49
  */
50
-
51
- import Container from './Container.astro';
52
-
53
- // 导入样式
54
50
  import '../../app.css';
51
+ import type { MainContentProps } from '../../index';
52
+ import Article from '../typography/Article.astro';
53
+ import TableOfContents from '../navigation/TableOfContents.astro';
55
54
 
56
- export interface Props {
57
- /**
58
- * 容器大小
59
- * @default "md"
60
- */
61
- size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'full';
62
-
63
- /**
64
- * 水平内边距(通过 Container 组件的 padding 属性设置)
65
- * @default "md"
66
- */
67
- padding?: 'none' | 'sm' | 'md' | 'lg' | 'xl';
68
-
69
- /**
70
- * 垂直内边距
71
- * @default "md"
72
- */
73
- verticalPadding?: 'none' | 'sm' | 'md' | 'lg' | 'xl' | string;
74
-
75
- /**
76
- * 是否居中显示内容
77
- * @default true
78
- */
79
- centered?: boolean;
80
-
81
- /**
82
- * 背景颜色
83
- * @default undefined
84
- */
85
- backgroundColor?: 'primary' | 'secondary' | 'tertiary' | 'light' | 'dark' | string;
86
-
87
- /**
88
- * HTML id 属性
89
- */
90
- id?: string;
91
-
92
- /**
93
- * 类名
94
- */
95
- class?: string;
96
-
97
- /**
98
- * 类名列表
99
- */
100
- 'class:list'?: any;
101
- }
55
+ export interface Props extends MainContentProps {}
102
56
 
103
57
  const {
104
58
  size = 'md',
@@ -106,19 +60,37 @@ const {
106
60
  verticalPadding = 'md',
107
61
  centered = true,
108
62
  backgroundColor,
63
+ layout = 'row',
64
+ isArticle = false,
109
65
  id,
66
+ showTableOfContents = false,
110
67
  class: className,
111
68
  'class:list': classList,
69
+ currentLocale,
112
70
  ...rest
113
71
  } = Astro.props;
114
72
 
73
+ // 新增获取布局类的函数
74
+ function getLayoutClasses(layout: string) {
75
+ if (layout === 'row') return 'cosy:flex cosy:flex-row';
76
+ if (layout === 'column') return 'cosy:flex cosy:flex-col';
77
+ return 'cosy:flex cosy:flex-col'; // 默认列布局
78
+ }
79
+
80
+ const layoutClass = getLayoutClasses(layout as string);
81
+
115
82
  // 获取垂直内边距的Tailwind类
116
83
  function getVerticalPaddingClasses(padding: string) {
117
84
  if (padding === 'none') return 'cosy:py-0';
85
+ if (padding === 'xs') return 'cosy:py-1';
118
86
  if (padding === 'sm') return 'cosy:py-2';
119
87
  if (padding === 'md') return 'cosy:py-4';
120
88
  if (padding === 'lg') return 'cosy:py-6';
121
89
  if (padding === 'xl') return 'cosy:py-8';
90
+ if (padding === '2xl') return 'cosy:py-10';
91
+ if (padding === '3xl') return 'cosy:py-12';
92
+ if (padding === '4xl') return 'cosy:py-16';
93
+ if (padding === '5xl') return 'cosy:py-20';
122
94
  return ''; // 对于自定义padding,使用内联样式
123
95
  }
124
96
 
@@ -153,10 +125,25 @@ const inlineStyle = customStyle.length > 0 ? customStyle.join(' ') : undefined;
153
125
 
154
126
  <main
155
127
  id={id}
156
- class:list={['cosy:w-full', verticalPaddingClass, bgColorClass, className, classList]}
128
+ class:list={[
129
+ 'cosy:w-full',
130
+ layoutClass,
131
+ verticalPaddingClass,
132
+ bgColorClass,
133
+ className,
134
+ classList,
135
+ ]}
157
136
  style={inlineStyle}
158
137
  {...rest}>
159
- <Container size={size} padding={padding} centered={centered}>
160
- <slot />
161
- </Container>
138
+ {
139
+ isArticle ? (
140
+ <Article>
141
+ <slot />
142
+ </Article>
143
+ ) : (
144
+ <slot />
145
+ )
146
+ }
147
+
148
+ {showTableOfContents && <TableOfContents lang={currentLocale} />}
162
149
  </main>
@@ -39,6 +39,7 @@
39
39
  * ```
40
40
  */
41
41
 
42
+ import '../../app.css';
42
43
  import { UserIcon, CalendarIcon } from '../../index';
43
44
 
44
45
  interface Props {
@@ -69,8 +69,6 @@
69
69
  import Link from '../base/Link.astro';
70
70
  import Image from '../base/Image.astro';
71
71
  import SocialIcon from '../icons/SocialIcon.astro';
72
-
73
- // 导入样式
74
72
  import '../../app.css';
75
73
 
76
74
  // 自定义图片元数据接口,替代 astro 的 ImageMetadata
@@ -64,8 +64,6 @@
64
64
 
65
65
  import ProductCard from './ProductCard.astro';
66
66
  import '../../app.css';
67
-
68
- // 导入ProductCard的类型定义
69
67
  import type { Props as ProductCardProps } from './ProductCard.astro';
70
68
 
71
69
  // 定义产品项类型
@@ -43,8 +43,6 @@
43
43
  import Link from '../base/Link.astro';
44
44
  import SocialIcon from '../icons/SocialIcon.astro';
45
45
  import Image from '../base/Image.astro';
46
-
47
- // 导入样式
48
46
  import '../../app.css';
49
47
 
50
48
  interface SocialLink {
@@ -30,8 +30,6 @@
30
30
  */
31
31
 
32
32
  import TeamMember from './TeamMember.astro';
33
-
34
- // 导入样式
35
33
  import '../../app.css';
36
34
 
37
35
  // 自定义图片元数据接口
@@ -40,7 +40,6 @@
40
40
  * - 动画遵循 prefers-reduced-motion 媒体查询,尊重用户的动画偏好设置
41
41
  */
42
42
 
43
- // 导入样式
44
43
  import '../../app.css';
45
44
 
46
45
  interface Props {
@@ -68,7 +68,6 @@
68
68
  * - 动画遵循 prefers-reduced-motion 媒体查询,尊重用户的动画偏好设置
69
69
  */
70
70
 
71
- // 导入样式
72
71
  import '../../app.css';
73
72
 
74
73
  interface Props {
@@ -47,7 +47,6 @@
47
47
  * - 代码使用等宽字体,确保对齐和可读性
48
48
  */
49
49
 
50
- // 导入样式
51
50
  import '../../app.css';
52
51
 
53
52
  interface Props {
@@ -27,7 +27,6 @@
27
27
  * @slot default - 组件的实际渲染内容
28
28
  */
29
29
 
30
- // 导入图标
31
30
  import { ClipboardIcon, CheckIcon } from '../../index';
32
31
  import '../../app.css';
33
32
 
@@ -1,18 +1,18 @@
1
1
  ---
2
2
  /**
3
3
  * @component Modal
4
- *
4
+ *
5
5
  * @description
6
6
  * Modal 组件是一个模态对话框,用于在不离开当前页面的情况下显示内容、通知或请求用户输入。
7
7
  * 它会覆盖在页面内容上方,并提供一个聚焦的交互环境。
8
- *
8
+ *
9
9
  * @design
10
10
  * 设计理念:
11
11
  * 1. 聚焦交互 - 通过遮罩层和动画效果引导用户注意力
12
12
  * 2. 灵活布局 - 支持标题、内容和操作按钮的灵活组合
13
13
  * 3. 可访问性 - 支持键盘导航和屏幕阅读器
14
14
  * 4. 响应式设计 - 在不同屏幕尺寸下保持良好的用户体验
15
- *
15
+ *
16
16
  * @usage
17
17
  * 基本用法:
18
18
  * ```astro
@@ -20,11 +20,11 @@
20
20
  * <p>这是一个模态对话框的内容。</p>
21
21
  * <button slot="actions" data-modal-target="my-modal">关闭</button>
22
22
  * </Modal>
23
- *
23
+ *
24
24
  * <!-- 触发按钮 -->
25
25
  * <button data-modal-target="my-modal">打开模态框</button>
26
26
  * ```
27
- *
27
+ *
28
28
  * 自定义操作按钮:
29
29
  * ```astro
30
30
  * <Modal id="confirm-modal" title="确认操作">
@@ -35,7 +35,7 @@
35
35
  * </div>
36
36
  * </Modal>
37
37
  * ```
38
- *
38
+ *
39
39
  * 不带标题的模态框:
40
40
  * ```astro
41
41
  * <Modal id="image-modal">
@@ -44,79 +44,77 @@
44
44
  * ```
45
45
  */
46
46
 
47
- // 导入样式
48
47
  import '../../app.css';
49
48
  import Button from '../base/Button.astro';
50
49
 
51
50
  interface Props {
52
- /**
53
- * Modal 的唯一标识符
54
- */
55
- id: string;
56
- /**
57
- * 模态框的标题
58
- */
59
- title?: string;
60
- /**
61
- * 是否显示关闭按钮
62
- * @default true
63
- */
64
- showCloseButton?: boolean;
65
- /**
66
- * 自定义类名
67
- */
68
- class?: string;
51
+ /**
52
+ * Modal 的唯一标识符
53
+ */
54
+ id: string;
55
+ /**
56
+ * 模态框的标题
57
+ */
58
+ title?: string;
59
+ /**
60
+ * 是否显示关闭按钮
61
+ * @default true
62
+ */
63
+ showCloseButton?: boolean;
64
+ /**
65
+ * 自定义类名
66
+ */
67
+ class?: string;
69
68
  }
70
69
 
71
- const {
72
- id,
73
- title,
74
- showCloseButton = true,
75
- class: className = '',
76
- } = Astro.props;
70
+ const { id, title, showCloseButton = true, class: className = '' } = Astro.props;
77
71
  ---
78
72
 
79
73
  <dialog id={id} class="cosy:modal">
80
- <div class:list={["cosy:modal-box", className]}>
81
- {showCloseButton && (
82
- <form method="dialog">
83
- <Button
84
- variant="ghost"
85
- size="sm"
86
- shape="circle"
87
- formmethod="dialog"
88
- class="cosy:modal-close-button"
89
- >✕</Button>
90
- </form>
91
- )}
92
-
93
- {title && <h3 class="cosy:modal-title">{title}</h3>}
94
-
95
- <div class="cosy:modal-content">
96
- <slot />
97
- </div>
74
+ <div class:list={['cosy:modal-box', className]}>
75
+ {
76
+ showCloseButton && (
77
+ <form method="dialog">
78
+ <Button
79
+ variant="ghost"
80
+ size="sm"
81
+ shape="circle"
82
+ formmethod="dialog"
83
+ class="cosy:modal-close-button">
84
+
85
+ </Button>
86
+ </form>
87
+ )
88
+ }
98
89
 
99
- <div class="cosy:modal-action">
100
- <slot name="actions" />
101
- </div>
102
- </div>
90
+ {title && <h3 class="cosy:modal-title">{title}</h3>}
103
91
 
104
- <form method="dialog" class="cosy:modal-backdrop">
105
- <button>关闭</button>
106
- </form>
92
+ <div class="cosy:modal-content">
93
+ <slot />
94
+ </div>
95
+
96
+ <div class="cosy:modal-action">
97
+ <slot name="actions" />
98
+ </div>
99
+ </div>
100
+
101
+ <form method="dialog" class="cosy:modal-backdrop">
102
+ <button>关闭</button>
103
+ </form>
107
104
  </dialog>
108
105
 
109
106
  <script define:vars={{ id }}>
110
- // 为了方便使用,我们提供一些辅助方法
111
- document.addEventListener('DOMContentLoaded', () => {
112
- const modal = document.getElementById(id);
113
- if (!modal) return;
107
+ // 为了方便使用,我们提供一些辅助方法
108
+ document.addEventListener('DOMContentLoaded', () => {
109
+ const modal = document.getElementById(id);
110
+ if (!modal) return;
111
+
112
+ // 为所有触发这个模态框的按钮添加点击事件
113
+ document.querySelectorAll(`[data-modal-target="${id}"]`).forEach((trigger) => {
114
+ trigger.addEventListener('click', () => {
115
+ modal.showModal();
116
+ });
117
+ });
118
+ });
119
+ </script>
114
120
 
115
- // 为所有触发这个模态框的按钮添加点击事件
116
- document.querySelectorAll(`[data-modal-target="${id}"]`).forEach(trigger => {
117
- trigger.addEventListener('click', () => {
118
- modal.showModal();
119
- });
120
- });
121
- });
122
- </script>
@@ -0,0 +1,258 @@
1
+ ---
2
+ /**
3
+ * AppLayout组件
4
+ *
5
+ * 适用于页面布局,包含侧边栏导航和目录
6
+ *
7
+ * 布局效果:
8
+ *
9
+ * 移动端:
10
+ * ```
11
+ * +------------------+
12
+ * | Header |
13
+ * +------------------+
14
+ * | Sidebar (1 line) |
15
+ * +------------------+
16
+ * | |
17
+ * | Main Content |
18
+ * | |
19
+ * | |
20
+ * +------------------+
21
+ * | Footer |
22
+ * +------------------+
23
+ * ```
24
+ *
25
+ * 桌面端:
26
+ * ```
27
+ * +------------------+
28
+ * | Header |
29
+ * +--------+---------+
30
+ * | | |
31
+ * |Sidebar | Content |
32
+ * | | |
33
+ * | | |
34
+ * +--------+---------+
35
+ * | Footer |
36
+ * +------------------+
37
+ * ```
38
+ *
39
+ * @param {Object} sidebarConfig - 侧边栏配置
40
+ * @param {boolean} [showHeader=true] - 是否显示头部
41
+ * @param {boolean} [showFooter=true] - 是否显示页脚
42
+ * @param {boolean} [showSidebar=true] - 是否显示侧边栏
43
+ * @param {string} [className] - 自定义类名
44
+ * @param {Array} [classList] - 自定义类名列表
45
+ * @param {boolean} [debug=true] - 是否启用调试模式
46
+ * @param {Object} mainContentConfig - 主内容区域配置
47
+ * @param {Object} footerConfig - 页脚配置
48
+ * @param {Object} headerConfig - 头部配置
49
+ * @param {Object} metaConfig - 元数据配置
50
+ * @param {Object} rest - 其他属性
51
+ *
52
+ * @example
53
+ * ```astro
54
+ * ---
55
+ * import AppLayout from '../layouts/AppLayout.astro';
56
+ *
57
+ * const sidebarItems = [
58
+ * { title: "入门", items: [
59
+ * { href: "/docs/getting-started", text: "快速开始" },
60
+ * { href: "/docs/installation", text: "安装" }
61
+ * ]},
62
+ * { title: "组件", items: [
63
+ * { href: "/docs/components/button", text: "Button 按钮" },
64
+ * { href: "/docs/components/card", text: "Card 卡片" }
65
+ * ]}
66
+ * ];
67
+ * ---
68
+ *
69
+ * <AppLayout
70
+ * metaConfig={{
71
+ * title: "文档标题",
72
+ * description: "文档描述"
73
+ * }}
74
+ * sidebarConfig={{
75
+ * sidebarItems: sidebarItems
76
+ * }}
77
+ * >
78
+ * <h1>文档内容</h1>
79
+ * <p>这是文档的主要内容</p>
80
+ * </AppLayout>
81
+ * ```
82
+ *
83
+ * 自定义页脚示例:
84
+ * ```astro
85
+ * <AppLayout
86
+ * metaConfig={{
87
+ * title: "文档标题",
88
+ * description: "文档描述"
89
+ * }}
90
+ * sidebarConfig={{
91
+ * sidebarItems: sidebarItems
92
+ * }}
93
+ * footerConfig={{
94
+ * slogan: "简单而强大的组件库",
95
+ * inspirationalSlogan: "让开发更加愉悦",
96
+ * socialLinks: [
97
+ * "https://github.com/myorg/myrepo",
98
+ * "https://twitter.com/myorg"
99
+ * ],
100
+ * products: [
101
+ * { name: "组件库", href: "/components" },
102
+ * { name: "模板", href: "/templates" }
103
+ * ]
104
+ * }}
105
+ * >
106
+ * <h1>文档内容</h1>
107
+ * <p>这是文档的主要内容</p>
108
+ * </AppLayout>
109
+ * ```
110
+ *
111
+ * 组件支持多种页脚相关的配置参数,可以通过以 `footer` 为前缀的属性来自定义页脚的内容和链接。
112
+ * 所有这些参数都是可选的,组件会为常用参数提供默认值。
113
+ *
114
+ * 全宽内容区域示例:
115
+ * ```astro
116
+ * <AppLayout
117
+ * metaConfig={{
118
+ * title: "文档标题",
119
+ * description: "文档描述"
120
+ * }}
121
+ * sidebarConfig={{
122
+ * sidebarItems: sidebarItems
123
+ * }}
124
+ * mainContentConfig={{
125
+ * fullWidth: true
126
+ * }}
127
+ * >
128
+ * <!-- 全宽Hero部分,无需容器限制 -->
129
+ * <div class="cosy:bg-primary cosy:p-10 cosy:text-white cosy:text-center">
130
+ * <h1 class="cosy:text-3xl">全宽Hero部分</h1>
131
+ * <p class="cosy:mt-4">没有容器限制,宽度可以100%占满</p>
132
+ * </div>
133
+ *
134
+ * <!-- 自定义容器部分 -->
135
+ * <div class="cosy:mx-auto cosy:p-6 cosy:container">
136
+ * <p>在全宽模式下,您可以自行控制内容的容器和间距</p>
137
+ * <p>这使得创建全宽背景的同时,保持内容在合适的宽度内</p>
138
+ * </div>
139
+ *
140
+ * <!-- 另一个全宽部分 -->
141
+ * <div class="cosy:bg-accent cosy:mt-8 cosy:p-10">
142
+ * <div class="cosy:mx-auto cosy:container">
143
+ * <h2 class="cosy:text-2xl">灵活的布局</h2>
144
+ * <p>您可以自由组合全宽区域和容器限制区域</p>
145
+ * </div>
146
+ * </div>
147
+ * </AppLayout>
148
+ * ```
149
+ *
150
+ * 调试模式示例:
151
+ * ```astro
152
+ * <AppLayout
153
+ * metaConfig={{
154
+ * title: "文档标题",
155
+ * description: "文档描述"
156
+ * }}
157
+ * sidebarConfig={{
158
+ * sidebarItems: sidebarItems
159
+ * }}
160
+ * debug={true}
161
+ * >
162
+ * <h1>文档内容</h1>
163
+ * <p>这是文档的主要内容</p>
164
+ * </AppLayout>
165
+ * ```
166
+ */
167
+
168
+ import '../../app.css';
169
+ import BaseLayout from './BaseLayout.astro';
170
+ import Footer from './Footer.astro';
171
+ import Main from '../containers/Main.astro';
172
+ import Header from './Header.astro';
173
+ import Sidebar from './Sidebar.astro';
174
+ import { ClientRouter } from 'astro:transitions';
175
+ import type { AppLayoutProps } from '../../index';
176
+ import Container from '../containers/Container.astro';
177
+
178
+ interface Props extends AppLayoutProps {}
179
+
180
+ const {
181
+ sidebarConfig,
182
+ showHeader = true,
183
+ showFooter = true,
184
+ showSidebar = true,
185
+ class: className,
186
+ 'class:list': classList,
187
+ debug = true,
188
+ mainContentConfig,
189
+ footerConfig,
190
+ headerConfig,
191
+ metaConfig,
192
+ ...rest
193
+ }: Props = Astro.props;
194
+ ---
195
+
196
+ <BaseLayout
197
+ title={metaConfig.title}
198
+ description={metaConfig.description}
199
+ keywords={metaConfig.keywords}
200
+ author={metaConfig.author}
201
+ robots={metaConfig.robots}
202
+ head={metaConfig.head}
203
+ debug={debug}
204
+ {...rest}>
205
+ {
206
+ showHeader && (
207
+ <Header
208
+ logo={headerConfig.logo}
209
+ logoHref={headerConfig.logoHref}
210
+ navItems={headerConfig.navItems}
211
+ languages={headerConfig.languages}
212
+ currentLocale={headerConfig.currentLocale}
213
+ sticky={headerConfig.sticky}
214
+ basePath={headerConfig.basePath}
215
+ showSidebarToggle={headerConfig.showSidebarToggle}
216
+ defaultSidebarOpen={headerConfig.defaultSidebarOpen}
217
+ height={headerConfig.height}
218
+ transition:persist
219
+ />
220
+ )
221
+ }
222
+
223
+ <Container flex="row" gap="md" size="full" padding="none">
224
+ <!-- 侧边栏容器 -->
225
+ {showSidebar && <Sidebar {...sidebarConfig} />}
226
+
227
+ <!-- 主内容区域 -->
228
+ <Main {...mainContentConfig}>
229
+ <slot />
230
+ <ClientRouter />
231
+ </Main>
232
+ </Container>
233
+
234
+ <!-- Footer -->
235
+ {
236
+ showFooter && (
237
+ <Container size="full" padding="none">
238
+ <Footer {...footerConfig} />
239
+ </Container>
240
+ )
241
+ }
242
+
243
+ <script>
244
+ // Handle sidebar toggle
245
+ const sidebarToggle = document.getElementById('sidebar-toggle');
246
+ const sidebar = document.getElementById('sidebar-mobile');
247
+ const sidebarOverlay = document.getElementById('sidebar-overlay');
248
+
249
+ function toggleSidebar() {
250
+ sidebar?.classList.toggle('cosy:hidden');
251
+ sidebarOverlay?.classList.toggle('cosy:hidden');
252
+ document.body.classList.toggle('cosy:overflow-hidden');
253
+ }
254
+
255
+ sidebarToggle?.addEventListener('click', toggleSidebar);
256
+ sidebarOverlay?.addEventListener('click', toggleSidebar);
257
+ </script>
258
+ </BaseLayout>