@coffic/cosy-ui 0.3.12 → 0.3.33
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/README.md +25 -25
- package/dist/app.css +1 -1
- package/dist/components/base/Alert.astro +45 -140
- package/dist/components/base/Button.astro +61 -13
- package/dist/components/base/Image.astro +55 -16
- package/dist/components/base/Link.astro +14 -0
- package/dist/components/containers/Container.astro +35 -2
- package/dist/components/containers/Section.astro +23 -30
- package/dist/components/display/Modal.astro +14 -7
- package/dist/components/icons/MenuIcon.astro +5 -8
- package/dist/components/layouts/DocumentationLayout.astro +425 -359
- package/dist/components/layouts/Footer.astro +31 -77
- package/dist/components/layouts/Header.astro +17 -27
- package/dist/components/layouts/NavSection.astro +32 -0
- package/dist/components/layouts/Sidebar.astro +69 -92
- package/dist/components/layouts/SidebarNav.astro +122 -0
- package/dist/components/navigation/TableOfContents.astro +18 -50
- package/dist/index.ts +2 -0
- package/dist/types/layout.ts +10 -0
- package/package.json +2 -5
- package/dist/components/containers/index.ts +0 -3
@@ -62,6 +62,7 @@ interface Props {
|
|
62
62
|
type?: 'button' | 'submit' | 'reset';
|
63
63
|
class?: string;
|
64
64
|
onClick?: string;
|
65
|
+
formmethod?: string;
|
65
66
|
}
|
66
67
|
|
67
68
|
const {
|
@@ -75,27 +76,74 @@ const {
|
|
75
76
|
type = 'button',
|
76
77
|
class: className,
|
77
78
|
onClick,
|
79
|
+
formmethod,
|
78
80
|
} = Astro.props;
|
81
|
+
|
82
|
+
// 计算按钮的类名
|
83
|
+
const getButtonClasses = () => {
|
84
|
+
const classes = ['cosy:btn'];
|
85
|
+
|
86
|
+
// Variant classes
|
87
|
+
const variantClasses = {
|
88
|
+
primary: 'cosy:btn-primary',
|
89
|
+
secondary: 'cosy:btn-secondary',
|
90
|
+
accent: 'cosy:btn-accent',
|
91
|
+
info: 'cosy:btn-info',
|
92
|
+
success: 'cosy:btn-success',
|
93
|
+
warning: 'cosy:btn-warning',
|
94
|
+
error: 'cosy:btn-error',
|
95
|
+
ghost: 'cosy:btn-ghost',
|
96
|
+
link: 'cosy:btn-link',
|
97
|
+
outline: 'cosy:btn-outline',
|
98
|
+
neutral: 'cosy:btn-neutral'
|
99
|
+
};
|
100
|
+
|
101
|
+
// Size classes
|
102
|
+
const sizeClasses = {
|
103
|
+
lg: 'cosy:btn-lg',
|
104
|
+
md: 'cosy:btn-md',
|
105
|
+
sm: 'cosy:btn-sm',
|
106
|
+
xs: 'cosy:btn-xs'
|
107
|
+
};
|
108
|
+
|
109
|
+
// Shape classes
|
110
|
+
const shapeClasses = {
|
111
|
+
circle: 'cosy:btn-circle',
|
112
|
+
square: 'cosy:btn-square'
|
113
|
+
};
|
114
|
+
|
115
|
+
if (variantClasses[variant]) {
|
116
|
+
classes.push(variantClasses[variant]);
|
117
|
+
}
|
118
|
+
|
119
|
+
if (sizeClasses[size]) {
|
120
|
+
classes.push(sizeClasses[size]);
|
121
|
+
}
|
122
|
+
|
123
|
+
if (shape && shapeClasses[shape]) {
|
124
|
+
classes.push(shapeClasses[shape]);
|
125
|
+
}
|
126
|
+
|
127
|
+
if (wide) classes.push('cosy:btn-wide');
|
128
|
+
if (block) classes.push('cosy:btn-block');
|
129
|
+
if (loading) classes.push('cosy:loading');
|
130
|
+
if (className) classes.push(className);
|
131
|
+
|
132
|
+
return classes;
|
133
|
+
};
|
134
|
+
|
135
|
+
const buttonClasses = getButtonClasses();
|
79
136
|
---
|
80
137
|
|
81
138
|
<button
|
82
|
-
type={type}
|
83
|
-
class:list={
|
84
|
-
'button',
|
85
|
-
`button-${variant}`,
|
86
|
-
`button-${size}`,
|
87
|
-
shape && `button-${shape}`,
|
88
|
-
wide && 'button-wide',
|
89
|
-
block && 'button-block',
|
90
|
-
loading && 'button-loading',
|
91
|
-
className
|
92
|
-
]}
|
139
|
+
type={formmethod === 'dialog' ? 'submit' : type}
|
140
|
+
class:list={buttonClasses}
|
93
141
|
disabled={disabled}
|
94
142
|
onclick={onClick}
|
143
|
+
formmethod={formmethod}
|
95
144
|
data-variant={variant}
|
96
145
|
>
|
97
|
-
|
98
|
-
<span class="button-content">
|
146
|
+
<span class="cosy:flex cosy:items-center cosy:gap-2">
|
99
147
|
<slot name="icon-left" />
|
100
148
|
<slot />
|
101
149
|
<slot name="icon-right" />
|
@@ -157,33 +157,72 @@ const isRemoteImage = typeof src === 'string' && (src.startsWith('http') || src.
|
|
157
157
|
// 获取图片源
|
158
158
|
const imgSrc = typeof src === 'string' ? src : src.src;
|
159
159
|
|
160
|
+
// 对象映射定义所有可能的类名
|
161
|
+
const objectFitClasses = {
|
162
|
+
'contain': 'object-contain',
|
163
|
+
'cover': 'object-cover',
|
164
|
+
'fill': 'object-fill',
|
165
|
+
'none': 'object-none',
|
166
|
+
'scale-down': 'object-scale-down'
|
167
|
+
};
|
168
|
+
|
169
|
+
const roundedClasses = {
|
170
|
+
'none': '',
|
171
|
+
'sm': 'rounded-sm',
|
172
|
+
'md': 'rounded-md',
|
173
|
+
'lg': 'rounded-lg',
|
174
|
+
'xl': 'rounded-xl',
|
175
|
+
'2xl': 'rounded-2xl',
|
176
|
+
'3xl': 'rounded-3xl',
|
177
|
+
'full': 'rounded-full'
|
178
|
+
};
|
179
|
+
|
180
|
+
const shadowClasses = {
|
181
|
+
'none': '',
|
182
|
+
'sm': 'shadow-sm',
|
183
|
+
'md': 'shadow-md',
|
184
|
+
'lg': 'shadow-lg',
|
185
|
+
'xl': 'shadow-xl',
|
186
|
+
'2xl': 'shadow-2xl'
|
187
|
+
};
|
188
|
+
|
189
|
+
const hoverClasses = {
|
190
|
+
'none': '',
|
191
|
+
'scale': 'hover:scale-110',
|
192
|
+
'brightness': 'hover:brightness-110',
|
193
|
+
'blur': 'hover:blur-sm'
|
194
|
+
};
|
195
|
+
|
196
|
+
const transitionClasses = {
|
197
|
+
'none': '',
|
198
|
+
'fade': 'transition-opacity duration-300',
|
199
|
+
'slide': 'transition-transform duration-300',
|
200
|
+
'zoom': 'transition-all duration-300'
|
201
|
+
};
|
202
|
+
|
160
203
|
// 构建图片类名
|
161
204
|
const imgClasses = [
|
162
|
-
// DaisyUI 和 Tailwind 类
|
163
205
|
'object-center',
|
164
|
-
objectFit
|
165
|
-
rounded
|
166
|
-
shadow
|
167
|
-
hover
|
168
|
-
|
169
|
-
hover === 'blur' ? 'hover:blur-sm' : '',
|
170
|
-
transition !== 'none' ? 'transition-all duration-300' : '',
|
206
|
+
objectFitClasses[objectFit] || objectFitClasses['cover'],
|
207
|
+
roundedClasses[rounded],
|
208
|
+
shadowClasses[shadow],
|
209
|
+
hoverClasses[hover],
|
210
|
+
transitionClasses[transition],
|
171
211
|
className
|
172
212
|
].filter(Boolean).join(' ');
|
173
213
|
|
174
214
|
// 构建占位图类名
|
175
215
|
const placeholderClasses = [
|
176
216
|
'absolute inset-0',
|
177
|
-
rounded
|
178
|
-
loadingIndicator === 'skeleton' ? 'animate-pulse bg-base-300' : ''
|
179
|
-
loadingIndicator === 'pulse' ? 'animate-pulse bg-base-300' : '',
|
217
|
+
roundedClasses[rounded],
|
218
|
+
loadingIndicator === 'skeleton' || loadingIndicator === 'pulse' ? 'animate-pulse bg-base-300' : ''
|
180
219
|
].filter(Boolean).join(' ');
|
181
220
|
|
182
221
|
// 构建错误占位图类名
|
183
222
|
const errorClasses = [
|
184
223
|
'absolute inset-0 flex items-center justify-center',
|
185
|
-
rounded
|
186
|
-
'bg-error bg-opacity-10'
|
224
|
+
roundedClasses[rounded],
|
225
|
+
'bg-error bg-opacity-10'
|
187
226
|
].filter(Boolean).join(' ');
|
188
227
|
---
|
189
228
|
|
@@ -204,12 +243,12 @@ const errorClasses = [
|
|
204
243
|
<div class={placeholderClasses} data-placeholder>
|
205
244
|
{/* 远程图片加载指示器 */}
|
206
245
|
{isRemoteImage && loadingIndicator === 'spinner' && (
|
207
|
-
<div class="
|
246
|
+
<div class="absolute inset-0 m-auto text-primary loading loading-spinner loading-lg" />
|
208
247
|
)}
|
209
248
|
|
210
249
|
{isRemoteImage && loadingIndicator === 'progress' && (
|
211
|
-
<div class="
|
212
|
-
<progress class="progress progress-primary
|
250
|
+
<div class="right-0 bottom-0 left-0 absolute">
|
251
|
+
<progress class="w-full progress progress-primary" />
|
213
252
|
</div>
|
214
253
|
)}
|
215
254
|
</div>
|
@@ -76,6 +76,8 @@ interface Props extends HTMLAttributes<'a'> {
|
|
76
76
|
variant?: LinkVariant;
|
77
77
|
animation?: LinkAnimation;
|
78
78
|
size?: LinkSize;
|
79
|
+
debug?: boolean;
|
80
|
+
centerText?: boolean;
|
79
81
|
}
|
80
82
|
|
81
83
|
const {
|
@@ -87,6 +89,8 @@ const {
|
|
87
89
|
size = 'md',
|
88
90
|
class: className = '',
|
89
91
|
'class:list': classList,
|
92
|
+
debug = false,
|
93
|
+
centerText = false,
|
90
94
|
...rest
|
91
95
|
} = Astro.props;
|
92
96
|
|
@@ -119,6 +123,16 @@ const classes = [
|
|
119
123
|
// 自定义类名
|
120
124
|
className
|
121
125
|
];
|
126
|
+
|
127
|
+
// 文本居中样式
|
128
|
+
if (centerText) {
|
129
|
+
classes.push('cosy:justify-center cosy:text-center');
|
130
|
+
}
|
131
|
+
|
132
|
+
// 调试样式
|
133
|
+
if (debug) {
|
134
|
+
classes.push('cosy:border cosy:border-dashed cosy:border-red-500');
|
135
|
+
}
|
122
136
|
---
|
123
137
|
|
124
138
|
<a
|
@@ -41,6 +41,13 @@
|
|
41
41
|
* <p>不居中的容器,靠左对齐</p>
|
42
42
|
* </Container>
|
43
43
|
* ```
|
44
|
+
*
|
45
|
+
* 带边框的容器:
|
46
|
+
* ```astro
|
47
|
+
* <Container border>
|
48
|
+
* <p>带有边框的容器</p>
|
49
|
+
* </Container>
|
50
|
+
* ```
|
44
51
|
*/
|
45
52
|
|
46
53
|
import type { HTMLAttributes } from 'astro/types';
|
@@ -66,6 +73,12 @@ interface Props extends HTMLAttributes<'div'> {
|
|
66
73
|
* @default true
|
67
74
|
*/
|
68
75
|
centered?: boolean;
|
76
|
+
|
77
|
+
/**
|
78
|
+
* 是否显示边框
|
79
|
+
* @default false
|
80
|
+
*/
|
81
|
+
border?: boolean;
|
69
82
|
|
70
83
|
/**
|
71
84
|
* 自定义类名
|
@@ -82,17 +95,37 @@ const {
|
|
82
95
|
size = 'md',
|
83
96
|
padding = 'md',
|
84
97
|
centered = true,
|
98
|
+
border = false,
|
85
99
|
class: className = '',
|
86
100
|
'class:list': classList,
|
87
101
|
...rest
|
88
102
|
} = Astro.props;
|
89
103
|
|
104
|
+
// 静态类名映射
|
105
|
+
const sizeClasses = {
|
106
|
+
'xs': 'container-xs',
|
107
|
+
'sm': 'container-sm',
|
108
|
+
'md': 'container-md',
|
109
|
+
'lg': 'container-lg',
|
110
|
+
'xl': 'container-xl',
|
111
|
+
'full': 'container-full'
|
112
|
+
} as const;
|
113
|
+
|
114
|
+
const paddingClasses = {
|
115
|
+
'none': 'container-padding-none',
|
116
|
+
'sm': 'container-padding-sm',
|
117
|
+
'md': 'container-padding-md',
|
118
|
+
'lg': 'container-padding-lg',
|
119
|
+
'xl': 'container-padding-xl'
|
120
|
+
} as const;
|
121
|
+
|
90
122
|
// 构建CSS类名
|
91
123
|
const containerClasses = [
|
92
124
|
'container',
|
93
|
-
|
94
|
-
|
125
|
+
sizeClasses[size],
|
126
|
+
paddingClasses[padding],
|
95
127
|
centered ? 'container-centered' : '',
|
128
|
+
border ? 'cosy:border cosy:rounded-lg' : '',
|
96
129
|
className
|
97
130
|
];
|
98
131
|
---
|
@@ -11,15 +11,16 @@
|
|
11
11
|
* <p>内容将被包裹在一个合适的区块中</p>
|
12
12
|
* </Section>
|
13
13
|
*
|
14
|
-
* <Section padding="lg" background="gray" centered={true}>
|
14
|
+
* <Section padding="lg" background="gray" centered={true} border={true}>
|
15
15
|
* <h2>自定义区块</h2>
|
16
|
-
* <p
|
16
|
+
* <p>大内边距,灰色背景,内容居中,带边框</p>
|
17
17
|
* </Section>
|
18
18
|
* ```
|
19
19
|
*/
|
20
20
|
|
21
21
|
import type { HTMLAttributes } from 'astro/types';
|
22
22
|
import Container from './Container.astro';
|
23
|
+
import "../../app.css"
|
23
24
|
|
24
25
|
interface Props extends HTMLAttributes<'section'> {
|
25
26
|
/**
|
@@ -51,6 +52,12 @@ interface Props extends HTMLAttributes<'section'> {
|
|
51
52
|
* @default false
|
52
53
|
*/
|
53
54
|
centered?: boolean;
|
55
|
+
|
56
|
+
/**
|
57
|
+
* 是否显示边框
|
58
|
+
* @default false
|
59
|
+
*/
|
60
|
+
border?: boolean;
|
54
61
|
|
55
62
|
/**
|
56
63
|
* 自定义类名
|
@@ -79,6 +86,7 @@ const {
|
|
79
86
|
container = true,
|
80
87
|
containerSize = 'md',
|
81
88
|
centered = false,
|
89
|
+
border = false,
|
82
90
|
class: className = '',
|
83
91
|
'class:list': classList,
|
84
92
|
id,
|
@@ -88,32 +96,33 @@ const {
|
|
88
96
|
|
89
97
|
// 内边距映射
|
90
98
|
const paddingClasses = {
|
91
|
-
'none': 'py-0',
|
92
|
-
'sm': 'py-6',
|
93
|
-
'md': 'py-12',
|
94
|
-
'lg': 'py-16',
|
95
|
-
'xl': 'py-24'
|
99
|
+
'none': 'cosy:py-0',
|
100
|
+
'sm': 'cosy:py-6',
|
101
|
+
'md': 'cosy:py-12',
|
102
|
+
'lg': 'cosy:py-16',
|
103
|
+
'xl': 'cosy:py-24'
|
96
104
|
};
|
97
105
|
|
98
106
|
// 背景颜色映射
|
99
107
|
const backgroundClasses = {
|
100
|
-
'transparent': 'bg-transparent',
|
101
|
-
'white': 'bg-
|
102
|
-
'gray': 'bg-
|
103
|
-
'primary': 'bg-
|
104
|
-
'secondary': 'bg-
|
105
|
-
'dark': 'bg-
|
108
|
+
'transparent': 'cosy:bg-transparent',
|
109
|
+
'white': 'cosy:bg-base-100',
|
110
|
+
'gray': 'cosy:bg-base-200',
|
111
|
+
'primary': 'cosy:bg-primary/10',
|
112
|
+
'secondary': 'cosy:bg-secondary/10',
|
113
|
+
'dark': 'cosy:bg-neutral cosy:text-neutral-content'
|
106
114
|
};
|
107
115
|
|
108
116
|
// 构建最终类名
|
109
117
|
const sectionClasses = [
|
110
118
|
paddingClasses[padding as keyof typeof paddingClasses],
|
111
119
|
backgroundClasses[background as keyof typeof backgroundClasses],
|
120
|
+
border ? 'cosy:border cosy:rounded-lg' : '',
|
112
121
|
className
|
113
122
|
].join(' ');
|
114
123
|
|
115
124
|
// 内容类名
|
116
|
-
const contentClasses = centered ? 'text-center' : '';
|
125
|
+
const contentClasses = centered ? 'cosy:text-center' : '';
|
117
126
|
---
|
118
127
|
|
119
128
|
<section id={id} class:list={[sectionClasses, classList]} style={style} {...rest}>
|
@@ -127,19 +136,3 @@ const contentClasses = centered ? 'text-center' : '';
|
|
127
136
|
</div>
|
128
137
|
)}
|
129
138
|
</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>
|
@@ -46,6 +46,7 @@
|
|
46
46
|
|
47
47
|
// 导入样式
|
48
48
|
import '../../app.css';
|
49
|
+
import Button from '../base/Button.astro';
|
49
50
|
|
50
51
|
interface Props {
|
51
52
|
/**
|
@@ -75,26 +76,32 @@ const {
|
|
75
76
|
} = Astro.props;
|
76
77
|
---
|
77
78
|
|
78
|
-
<dialog id={id} class="modal">
|
79
|
-
<div class:list={["modal-box", className]}>
|
79
|
+
<dialog id={id} class="cosy:modal">
|
80
|
+
<div class:list={["cosy:modal-box", className]}>
|
80
81
|
{showCloseButton && (
|
81
82
|
<form method="dialog">
|
82
|
-
<
|
83
|
+
<Button
|
84
|
+
variant="ghost"
|
85
|
+
size="sm"
|
86
|
+
shape="circle"
|
87
|
+
formmethod="dialog"
|
88
|
+
class="cosy:modal-close-button"
|
89
|
+
>✕</Button>
|
83
90
|
</form>
|
84
91
|
)}
|
85
92
|
|
86
|
-
{title && <h3 class="modal-title">{title}</h3>}
|
93
|
+
{title && <h3 class="cosy:modal-title">{title}</h3>}
|
87
94
|
|
88
|
-
<div class="modal-content">
|
95
|
+
<div class="cosy:modal-content">
|
89
96
|
<slot />
|
90
97
|
</div>
|
91
98
|
|
92
|
-
<div class="modal-action">
|
99
|
+
<div class="cosy:modal-action">
|
93
100
|
<slot name="actions" />
|
94
101
|
</div>
|
95
102
|
</div>
|
96
103
|
|
97
|
-
<form method="dialog" class="modal-backdrop">
|
104
|
+
<form method="dialog" class="cosy:modal-backdrop">
|
98
105
|
<button>关闭</button>
|
99
106
|
</form>
|
100
107
|
</dialog>
|
@@ -1,4 +1,7 @@
|
|
1
1
|
---
|
2
|
+
/**
|
3
|
+
* 菜单图标组件
|
4
|
+
*/
|
2
5
|
interface Props {
|
3
6
|
/**
|
4
7
|
* 图标的大小
|
@@ -14,13 +17,9 @@ interface Props {
|
|
14
17
|
* 自定义类名
|
15
18
|
*/
|
16
19
|
class?: string;
|
17
|
-
/**
|
18
|
-
* 插槽名称
|
19
|
-
*/
|
20
|
-
slot?: string;
|
21
20
|
}
|
22
21
|
|
23
|
-
const { size = '24px', color = 'currentColor', class: className = ''
|
22
|
+
const { size = '24px', color = 'currentColor', class: className = '' } = Astro.props;
|
24
23
|
---
|
25
24
|
|
26
25
|
<svg
|
@@ -35,7 +34,5 @@ const { size = '24px', color = 'currentColor', class: className = '', slot } = A
|
|
35
34
|
stroke-linejoin="round"
|
36
35
|
class={className}
|
37
36
|
>
|
38
|
-
<
|
39
|
-
<line x1="3" y1="6" x2="21" y2="6" />
|
40
|
-
<line x1="3" y1="18" x2="21" y2="18" />
|
37
|
+
<path d="M4 6h16M4 12h16M4 18h16" />
|
41
38
|
</svg>
|