@coffic/cosy-ui 0.9.44 → 0.9.45

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.
@@ -3,40 +3,46 @@
3
3
 
4
4
  // 确保 Astro 全局类型正确加载
5
5
  declare global {
6
- namespace astroHTML.JSX {
7
- interface IntrinsicElements {
8
- [elemName: string]: any;
6
+ namespace astroHTML.JSX {
7
+ interface IntrinsicElements {
8
+ [elemName: string]: any;
9
+ }
9
10
  }
10
- }
11
11
  }
12
12
 
13
13
  declare module '*.vue?raw' {
14
- const content: string;
15
- export default content;
14
+ const content: string;
15
+ export default content;
16
16
  }
17
17
 
18
18
  // 添加图片模块声明
19
19
  declare module '*.png' {
20
- const value: string;
21
- export default value;
20
+ const value: string;
21
+ export default value;
22
22
  }
23
23
 
24
24
  declare module '*.jpg' {
25
- const value: string;
26
- export default value;
25
+ const value: string;
26
+ export default value;
27
27
  }
28
28
 
29
29
  declare module '*.jpeg' {
30
- const value: string;
31
- export default value;
30
+ const value: string;
31
+ export default value;
32
32
  }
33
33
 
34
34
  declare module '*.svg' {
35
- const value: string;
36
- export default value;
35
+ const value: string;
36
+ export default value;
37
+ }
38
+
39
+ // 允许在 TS 中直接导入 .astro 组件
40
+ declare module '*.astro' {
41
+ const Component: any;
42
+ export default Component;
37
43
  }
38
44
 
39
45
  declare module '*.gif' {
40
- const value: string;
41
- export default value;
46
+ const value: string;
47
+ export default value;
42
48
  }
@@ -6,19 +6,18 @@
6
6
  * ```astro
7
7
  * <ImagesCircle
8
8
  * images={[
9
- * { src: 'image1.jpg', alt: '图片1' },
10
- * { src: 'image2.jpg', alt: '图片2' },
11
- * { src: 'image3.jpg', alt: '图片3' },
12
- * { src: 'image4.jpg', alt: '图片4' }
9
+ * 'image1.jpg',
10
+ * 'image2.jpg',
11
+ * 'image3.jpg',
12
+ * 'image4.jpg'
13
13
  * ]}
14
14
  * size="md"
15
- * style="apple"
16
15
  * />
17
16
  * ```
18
17
  * @props
19
18
  * @prop {BackgroundColor} [background] - 背景颜色
20
19
  * @prop {string} [class] - 自定义 CSS 类名
21
- * @prop {IImagesCircleItem[]} images - 图片数组,第一张为中心主图,其余环绕显示
20
+ * @prop {ImageSource[]} images - 图片源数组,可以是字符串URL或ImageMetadata对象,第一张为中心主图,其余环绕显示
22
21
  * @prop {string} [rounded='lg'] - 图片圆角,可选值:none、sm、md、lg、xl、2xl、3xl、full
23
22
  * @prop {string} [shadow='lg'] - 图片阴影,可选值:none、sm、md、lg、xl
24
23
  * @prop {string} [size='md'] - 组件大小,可选值:sm、md、lg、xl
@@ -154,7 +153,7 @@ const positions3D = get3DPositions(imageCount);
154
153
  style={`width: ${currentSize.container}px; height: ${currentSize.container}px; transform-style: preserve-3d;`}
155
154
  >
156
155
  <!-- 所有图片按3D位置排列 -->
157
- {images.map((image, index) => {
156
+ {images.map((imageSrc, index) => {
158
157
  const position = positions3D[index];
159
158
  if (!position) return null;
160
159
 
@@ -178,19 +177,14 @@ const positions3D = get3DPositions(imageCount);
178
177
  `}
179
178
  >
180
179
  <img
181
- src={image.src}
182
- alt={image.alt}
183
- width={image.width || imageSize}
184
- height={image.height || imageSize}
185
- loading={image.loading || 'lazy'}
180
+ src={typeof imageSrc === 'string' ? imageSrc : imageSrc.src}
181
+ alt={`图片 ${index + 1}`}
182
+ width={imageSize}
183
+ height={imageSize}
184
+ loading="lazy"
186
185
  class={`img-3d ${shadowClass} ${roundedClass}`}
187
186
  style={`width: ${imageSize}px; height: ${imageSize}px;`}
188
187
  />
189
- {image.caption && (
190
- <div class="image-caption">
191
- <p>{image.caption}</p>
192
- </div>
193
- )}
194
188
  </div>
195
189
  );
196
190
  })}
@@ -1,16 +1,8 @@
1
1
  import type { BackgroundColor } from '../../src/common/backgrounds';
2
-
3
- export interface IImagesCircleItem {
4
- src: string;
5
- alt: string;
6
- width?: number;
7
- height?: number;
8
- loading?: 'lazy' | 'eager';
9
- caption?: string;
10
- }
2
+ import type { ImageSource } from '../image/image';
11
3
 
12
4
  export interface IImagesCircleProps {
13
- images: IImagesCircleItem[];
5
+ images: ImageSource[];
14
6
  background?: BackgroundColor;
15
7
  class?: string;
16
8
  size?: 'sm' | 'md' | 'lg' | 'xl';
@@ -3,14 +3,14 @@
3
3
  * @component ProductHero
4
4
  *
5
5
  * @description
6
- * ProductHero 组件是 ProductHeroItem 的容器组件,用于展示多个产品的详细信息。
7
- * 采用苹果风格的大图展示设计,支持左右交替布局,提供优雅的产品展示体验。
8
- * 适用于产品展示页面、产品详情页等场景。
6
+ * ProductHero 组件用于展示单个产品的详细信息,采用苹果风格的大图展示设计。
7
+ * 支持左右交替布局、标签数组、价格显示和操作按钮。
8
+ * 适用于产品详情页、产品展示页面等场景。
9
9
  *
10
10
  * @design
11
11
  * 设计理念:
12
12
  * 1. 大图展示 - 突出产品图片,采用高质量大图展示
13
- * 2. 交替布局 - 自动左右交替布局,增加视觉层次
13
+ * 2. 交替布局 - 支持左右交替布局,增加视觉层次
14
14
  * 3. 信息层次 - 清晰的信息层次:标签、标题、描述、价格、按钮
15
15
  * 4. 苹果风格 - 采用苹果官网的简洁、优雅设计风格
16
16
  * 5. 响应式设计 - 在不同设备上都能良好展示
@@ -19,146 +19,176 @@
19
19
  * 基本用法:
20
20
  * ```astro
21
21
  * <ProductHero
22
- * products={[
23
- * {
24
- * name: "极简手机",
25
- * description: "纯净体验,回归本质",
26
- * image: "/images/products/phone.jpg",
27
- * price: "¥6,999",
28
- * isNew: true
29
- * },
30
- * {
31
- * name: "智能手表",
32
- * description: "健康生活,简约开始",
33
- * image: "/images/products/watch.jpg",
34
- * price: "¥2,999",
35
- * isNew: false
36
- * }
37
- * ]}
38
- * buyNowText="立即购买"
39
- * learnMoreText="了解更多"
22
+ * name="极简手机"
23
+ * description="纯净体验,回归本质"
24
+ * image="/images/products/phone.jpg"
25
+ * highlight="¥6,999"
26
+ * labels={["新品"]}
40
27
  * />
41
28
  * ```
42
29
  *
43
- * 自定义背景色:
30
+ * 右对齐布局:
44
31
  * ```astro
45
32
  * <ProductHero
46
- * products={products}
47
- * backgrounds={["gradient-sky", "primary/10"]}
48
- * buyNowText="立即购买"
49
- * learnMoreText="了解更多"
33
+ * name="智能手表"
34
+ * description="健康生活,简约开始"
35
+ * image="/images/products/watch.jpg"
36
+ * highlight="¥2,999"
37
+ * labels={["热卖", "直降 500"]}
38
+ * align="right"
50
39
  * />
51
40
  * ```
52
41
  *
53
- * 自定义按钮文本:
42
+ * 自定义背景色:
54
43
  * ```astro
55
44
  * <ProductHero
56
- * products={products}
57
- * buyNowText="立即购买"
58
- * learnMoreText="了解更多"
59
- * newLabelText="新品"
45
+ * name="无线耳机"
46
+ * description="纯净音质,无感佩戴"
47
+ * image="/images/products/earbuds.jpg"
48
+ * highlight="¥1,299"
49
+ * background="gradient-sky"
60
50
  * />
61
51
  * ```
52
+ *
53
+ * 自定义操作区(使用 actions 插槽):
54
+ * ```astro
55
+ * <ProductHero
56
+ * name="极简手机"
57
+ * description="纯净体验,回归本质"
58
+ * image="/images/products/phone.jpg"
59
+ * highlight="¥6,999">
60
+ * <div slot="actions" style="display:flex; gap:1rem;">
61
+ * <a href="#buy" class="btn btn-primary">立即购买</a>
62
+ * <a href="#learn" class="btn btn-outline">了解更多</a>
63
+ * </div>
64
+ * </ProductHero>
65
+ * ```
62
66
  */
63
67
 
64
- import { ProductHeroItem } from '../../index-astro';
68
+ import { Badge, Heading, Text, Image, Container } from '../../index-astro';
65
69
  import '../../style.ts';
66
- import type { Props as ProductHeroItemProps } from './ProductHeroItem.astro';
70
+ import type { ImageSource } from '../image/image.ts';
67
71
  import type { BackgroundColor } from '../../src/common/backgrounds';
68
72
 
69
- // 定义产品项类型
70
- type ProductItem = Omit<
71
- ProductHeroItemProps,
72
- | 'align'
73
- | 'background'
74
- | 'buyNowText'
75
- | 'learnMoreText'
76
- | 'newLabelText'
77
- | 'onBuyNow'
78
- | 'onLearnMore'
79
- | 'class'
80
- >;
81
-
73
+ // Props 按字母顺序(A-Z)
82
74
  export interface Props {
83
75
  /**
84
- * 产品数据数组
76
+ * 布局对齐方式
77
+ * - left: 左对齐(默认)
78
+ * - right: 右对齐
85
79
  */
86
- products: ProductItem[];
80
+ align?: 'left' | 'right';
87
81
  /**
88
- * 背景色类型数组
82
+ * 背景色类型
89
83
  * 使用预定义的背景色类型,如 'primary', 'base-200', 'gradient-sky' 等
90
- * 组件会循环使用这些背景色,如果只有一个背景色则所有产品项都使用该背景色
91
84
  */
92
- backgrounds?: BackgroundColor[];
85
+ background?: BackgroundColor;
93
86
  /**
94
- * 购买按钮文本
87
+ * 自定义类名
95
88
  */
96
- buyNowText?: string;
89
+ class?: string;
97
90
  /**
98
- * 了解更多按钮文本
91
+ * 产品描述
99
92
  */
100
- learnMoreText?: string;
93
+ description: string;
101
94
  /**
102
- * 新品标签文本
95
+ * 产品图片
103
96
  */
104
- newLabelText?: string;
97
+ image: ImageSource;
105
98
  /**
106
- * 购买按钮点击事件
99
+ * 标签文案列表。可传多个,如 ["限时优惠", "热销"]
107
100
  */
108
- onBuyNow?: (product: ProductItem, index: number) => void;
101
+ labels?: string[];
109
102
  /**
110
- * 了解更多按钮点击事件
103
+ * 产品名称
111
104
  */
112
- onLearnMore?: (product: ProductItem, index: number) => void;
105
+ name: string;
113
106
  /**
114
- * 自定义类名
107
+ * 高亮文案(价格、宣传语等)
115
108
  */
116
- class?: string;
109
+ highlight?: string;
117
110
  }
118
111
 
119
112
  const {
120
- products,
121
- backgrounds,
122
- buyNowText = '立即购买',
123
- learnMoreText = '了解更多',
124
- newLabelText = '新品',
125
- onBuyNow,
126
- onLearnMore,
113
+ name,
114
+ description,
115
+ image,
116
+ highlight,
117
+ labels = [],
118
+ align = 'left',
119
+ background,
127
120
  class: className = '',
128
121
  } = Astro.props;
129
122
 
130
- // 默认背景色数组,用于交替显示
131
- const defaultBackgrounds: BackgroundColor[] = ['base-200', 'base-100'];
123
+ // 根据对齐方式决定布局方向
124
+ const isRightAlign = align === 'right';
125
+ const gridDirection = isRightAlign ? 'direction: rtl;' : '';
126
+ const contentDirection = isRightAlign ? 'direction: ltr;' : '';
132
127
  ---
133
128
 
134
- <div class={className}>
135
- {
136
- products.map((product, index) => {
137
- // 计算当前产品的背景
138
- const availableBackgrounds =
139
- backgrounds && backgrounds.length > 0
140
- ? backgrounds
141
- : defaultBackgrounds;
142
- const currentBackground =
143
- availableBackgrounds[index % availableBackgrounds.length];
129
+ <Container
130
+ width="full"
131
+ background={background || 'base-100'}
132
+ padding="xl"
133
+ class={className}>
134
+ <Container width="xl">
135
+ <div
136
+ style={`display: grid; grid-template-columns: 1fr 1fr; gap: 4rem; align-items: center; ${gridDirection}`}>
137
+ <!-- 内容区域 -->
138
+ <div style={contentDirection}>
139
+ <!-- 标签列表 -->
140
+ {
141
+ labels && labels.length > 0 && (
142
+ <div class="cosy:flex cosy:flex-wrap cosy:gap-2 cosy:mb-4">
143
+ {labels.map((label) => (
144
+ <Badge variant="primary">{label}</Badge>
145
+ ))}
146
+ </div>
147
+ )
148
+ }
149
+
150
+ <!-- 产品标题 -->
151
+ <Heading level={2} size="4xl" class="cosy:mb-4 cosy:font-thin">
152
+ {name}
153
+ </Heading>
154
+
155
+ <!-- 产品描述 -->
156
+ <Text
157
+ size="xl"
158
+ class="cosy:text-base-content/70 cosy:mb-6 cosy:font-light">
159
+ {description}
160
+ </Text>
161
+
162
+ <!-- 高亮文案(价格/标语等) -->
163
+ {
164
+ highlight && (
165
+ <div style="display: flex; gap: 1rem; align-items: center; margin-bottom: 2rem;">
166
+ <Text size="2xl" class="cosy:font-thin">
167
+ {highlight}
168
+ </Text>
169
+ </div>
170
+ )
171
+ }
144
172
 
145
- // 计算布局对齐方式(左右交替)
146
- const align = index % 2 === 0 ? 'left' : 'right';
173
+ <!-- 自定义操作区插槽 -->
174
+ <div style="display: flex; gap: 1rem;">
175
+ <slot name="actions" />
176
+ </div>
177
+ </div>
147
178
 
148
- return (
149
- <ProductHeroItem
150
- {...product}
151
- align={align}
152
- background={currentBackground}
153
- buyNowText={buyNowText}
154
- learnMoreText={learnMoreText}
155
- newLabelText={newLabelText}
156
- onBuyNow={onBuyNow ? () => onBuyNow(product, index) : undefined}
157
- onLearnMore={
158
- onLearnMore ? () => onLearnMore(product, index) : undefined
159
- }
160
- />
161
- );
162
- })
163
- }
164
- </div>
179
+ <!-- 图片区域 -->
180
+ <div>
181
+ <div
182
+ style="width: 100%; height: auto; border-radius: 1rem; box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25); overflow: hidden;">
183
+ <Image
184
+ src={image}
185
+ alt={name}
186
+ width={800}
187
+ height={600}
188
+ class="cosy:w-full cosy:h-auto"
189
+ />
190
+ </div>
191
+ </div>
192
+ </div>
193
+ </Container>
194
+ </Container>
@@ -1,8 +1,5 @@
1
1
  export { default as Products } from './Products.astro';
2
2
  export { default as ProductCard } from './ProductCard.astro';
3
3
  export { default as ProductHero } from './ProductHero.astro';
4
- export { default as ProductHeroItem } from './ProductHeroItem.astro';
5
4
  export type { Props as ProductsProps } from './Products.astro';
6
5
  export type { Props as ProductCardProps } from './ProductCard.astro';
7
- export type { Props as ProductHeroProps } from './ProductHero.astro';
8
- export type { Props as ProductHeroItemProps } from './ProductHeroItem.astro';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coffic/cosy-ui",
3
- "version": "0.9.44",
3
+ "version": "0.9.45",
4
4
  "description": "An astro component library",
5
5
  "author": {
6
6
  "name": "nookery",
@@ -1,219 +0,0 @@
1
- ---
2
- /**
3
- * @component ProductHeroItem
4
- *
5
- * @description
6
- * ProductHeroItem 组件用于展示单个产品的详细信息,采用苹果风格的大图展示设计。
7
- * 支持左右交替布局、新品标签、价格显示和操作按钮。
8
- * 适用于产品详情页、产品展示页面等场景。
9
- *
10
- * @design
11
- * 设计理念:
12
- * 1. 大图展示 - 突出产品图片,采用高质量大图展示
13
- * 2. 交替布局 - 支持左右交替布局,增加视觉层次
14
- * 3. 信息层次 - 清晰的信息层次:标签、标题、描述、价格、按钮
15
- * 4. 苹果风格 - 采用苹果官网的简洁、优雅设计风格
16
- * 5. 响应式设计 - 在不同设备上都能良好展示
17
- *
18
- * @usage
19
- * 基本用法:
20
- * ```astro
21
- * <ProductHeroItem
22
- * name="极简手机"
23
- * description="纯净体验,回归本质"
24
- * image="/images/products/phone.jpg"
25
- * price="¥6,999"
26
- * isNew={true}
27
- * buyNowText="立即购买"
28
- * learnMoreText="了解更多"
29
- * />
30
- * ```
31
- *
32
- * 右对齐布局:
33
- * ```astro
34
- * <ProductHeroItem
35
- * name="智能手表"
36
- * description="健康生活,简约开始"
37
- * image="/images/products/watch.jpg"
38
- * price="¥2,999"
39
- * isNew={false}
40
- * align="right"
41
- * buyNowText="立即购买"
42
- * learnMoreText="了解更多"
43
- * />
44
- * ```
45
- *
46
- * 自定义背景色:
47
- * ```astro
48
- * <ProductHeroItem
49
- * name="无线耳机"
50
- * description="纯净音质,无感佩戴"
51
- * image="/images/products/earbuds.jpg"
52
- * price="¥1,299"
53
- * background="gradient-sky"
54
- * buyNowText="立即购买"
55
- * learnMoreText="了解更多"
56
- * />
57
- * ```
58
- */
59
-
60
- import {
61
- Badge,
62
- Button,
63
- Heading,
64
- Text,
65
- Image,
66
- Container,
67
- } from '../../index-astro';
68
- import '../../style.ts';
69
- import type { ImageSource } from '../image/image.ts';
70
- import type { BackgroundColor } from '../../src/common/backgrounds';
71
-
72
- export interface Props {
73
- /**
74
- * 产品名称
75
- */
76
- name: string;
77
- /**
78
- * 产品描述
79
- */
80
- description: string;
81
- /**
82
- * 产品图片
83
- */
84
- image: ImageSource;
85
- /**
86
- * 产品价格
87
- */
88
- price: string;
89
- /**
90
- * 是否为新品
91
- */
92
- isNew?: boolean;
93
- /**
94
- * 布局对齐方式
95
- * - left: 左对齐(默认)
96
- * - right: 右对齐
97
- */
98
- align?: 'left' | 'right';
99
- /**
100
- * 背景色类型
101
- * 使用预定义的背景色类型,如 'primary', 'base-200', 'gradient-sky' 等
102
- */
103
- background?: BackgroundColor;
104
- /**
105
- * 购买按钮文本
106
- */
107
- buyNowText?: string;
108
- /**
109
- * 了解更多按钮文本
110
- */
111
- learnMoreText?: string;
112
- /**
113
- * 新品标签文本
114
- */
115
- newLabelText?: string;
116
- /**
117
- * 购买按钮点击事件
118
- */
119
- onBuyNow?: () => void;
120
- /**
121
- * 了解更多按钮点击事件
122
- */
123
- onLearnMore?: () => void;
124
- /**
125
- * 自定义类名
126
- */
127
- class?: string;
128
- }
129
-
130
- const {
131
- name,
132
- description,
133
- image,
134
- price,
135
- isNew = false,
136
- align = 'left',
137
- background,
138
- buyNowText = '立即购买',
139
- learnMoreText = '了解更多',
140
- newLabelText = '新品',
141
- onBuyNow,
142
- onLearnMore,
143
- class: className = '',
144
- } = Astro.props;
145
-
146
- // 根据对齐方式决定布局方向
147
- const isRightAlign = align === 'right';
148
- const gridDirection = isRightAlign ? 'direction: rtl;' : '';
149
- const contentDirection = isRightAlign ? 'direction: ltr;' : '';
150
- ---
151
-
152
- <Container
153
- width="full"
154
- background={background || 'base-100'}
155
- padding="xl"
156
- class={className}>
157
- <Container width="xl">
158
- <div
159
- style={`display: grid; grid-template-columns: 1fr 1fr; gap: 4rem; align-items: center; ${gridDirection}`}>
160
- <!-- 内容区域 -->
161
- <div style={contentDirection}>
162
- <!-- 新品标签 -->
163
- {
164
- isNew && (
165
- <div style="margin-bottom: 1rem;">
166
- <Badge variant="primary" class="cosy:mb-4">
167
- {newLabelText}
168
- </Badge>
169
- </div>
170
- )
171
- }
172
-
173
- <!-- 产品标题 -->
174
- <Heading level={2} size="4xl" class="cosy:mb-4 cosy:font-thin">
175
- {name}
176
- </Heading>
177
-
178
- <!-- 产品描述 -->
179
- <Text
180
- size="xl"
181
- class="cosy:text-base-content/70 cosy:mb-6 cosy:font-light">
182
- {description}
183
- </Text>
184
-
185
- <!-- 价格 -->
186
- <div
187
- style="display: flex; gap: 1rem; align-items: center; margin-bottom: 2rem;">
188
- <Text size="2xl" class="cosy:font-thin">
189
- {price}
190
- </Text>
191
- </div>
192
-
193
- <!-- 操作按钮 -->
194
- <div style="display: flex; gap: 1rem;">
195
- <Button variant="primary" size="lg" onclick={onBuyNow}>
196
- {buyNowText}
197
- </Button>
198
- <Button variant="outline" size="lg" onclick={onLearnMore}>
199
- {learnMoreText}
200
- </Button>
201
- </div>
202
- </div>
203
-
204
- <!-- 图片区域 -->
205
- <div>
206
- <div
207
- style="width: 100%; height: auto; border-radius: 1rem; box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25); overflow: hidden;">
208
- <Image
209
- src={image}
210
- alt={name}
211
- width={800}
212
- height={600}
213
- class="cosy:w-full cosy:h-auto"
214
- />
215
- </div>
216
- </div>
217
- </div>
218
- </Container>
219
- </Container>