@rxdrag/website-lib-core 0.0.119 → 0.0.121

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rxdrag/website-lib-core",
3
- "version": "0.0.119",
3
+ "version": "0.0.121",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./index.ts"
@@ -24,7 +24,7 @@
24
24
  "eslint": "^9.39.2",
25
25
  "typescript": "^5",
26
26
  "@rxdrag/eslint-config-custom": "0.2.13",
27
- "@rxdrag/tiptap-preview": "0.0.2",
27
+ "@rxdrag/tiptap-preview": "0.0.3",
28
28
  "@rxdrag/tsconfig": "0.2.1"
29
29
  },
30
30
  "dependencies": {
@@ -34,7 +34,7 @@
34
34
  "hls.js": "^1.6.13",
35
35
  "lodash-es": "^4.17.21",
36
36
  "@rxdrag/entify-lib": "0.0.24",
37
- "@rxdrag/rxcms-models": "0.3.97"
37
+ "@rxdrag/rxcms-models": "0.3.98"
38
38
  },
39
39
  "peerDependencies": {
40
40
  "astro": "^4.0.0 || ^5.0.0",
@@ -2,45 +2,50 @@
2
2
  export type ColorBackgroundConfig = {
3
3
  id?: string;
4
4
  type: "color";
5
- className?: string; // 颜色 ,模糊,图案等,如 "bg-blue-500", "bg-gradient-to-r from-blue-500 to-purple-600"
5
+ class?: string; // 颜色 ,模糊,图案等,如 "bg-blue-500", "bg-gradient-to-r from-blue-500 to-purple-600"
6
+ className?: string;//兼容旧的
6
7
  };
7
8
 
8
9
  export type BlurBackgroundConfig = {
9
10
  id?: string;
10
11
  type: "blur";
11
- className?: string; // 模糊,如 "backdrop-blur"
12
+ class?: string; // 模糊,如 "backdrop-blur"
13
+ className?: string;//兼容旧的
12
14
  };
13
15
 
14
16
  export type ImageBackgroundConfig = {
15
17
  id?: string;
16
18
  type: "image";
17
- className?: string; // 图片,如 "bg-cover bg-center bg-no-repeat"
18
- mediaRef?: string; // 图片ref
19
+ class?: string; // 图片,如 "bg-cover bg-center bg-no-repeat"
20
+ className?: string;//兼容旧的
21
+ //实际组件中还会传入ImageMetadata
19
22
  src?: string; // 图片源
20
23
  };
21
24
 
22
25
  export type SvgBackgroundConfig = {
23
26
  id?: string;
24
27
  type: "svg";
25
- className?: string; // 图案,如 "bg-dots-sm bg-gray-100"
28
+ class?: string; // 图案,如 "bg-dots-sm bg-gray-100"
29
+ className?: string;//兼容旧的
26
30
  code?: string; // SVG代码
27
31
  };
28
32
 
29
33
  export type VideoBackgroundConfig = {
30
34
  id?: string;
31
35
  type: "video";
32
- className?: string; // 视频,如 "bg-cover bg-center bg-no-repeat"
33
- mediaRef?: string; // 视频Ref
34
- posterRef?: string; // 视频封面Ref
35
- mediaSrc?: string; // 视频源
36
- posterSrc?: string; // 视频封面图源
36
+ class?: string; // 视频,如 "bg-cover bg-center bg-no-repeat"
37
+ className?: string;//兼容旧的
38
+ mediaRef?: string; // 视频源
39
+ //实际组件中还会传入ImageMetadata
40
+ poster?: string; // 视频封面图源
37
41
  };
38
42
 
39
43
  export type SplineBackgroundConfig = {
40
44
  id?: string;
41
45
  type: "spline";
42
- className?: string; // Spline,如 "bg-cover bg-center bg-no-repeat"
43
- mediaRef?: string; // Spline ID
46
+ class?: string; // Spline,如 "bg-cover bg-center bg-no-repeat"
47
+ className?: string;//兼容旧的
48
+ spline?: string; // Spline ID
44
49
  url?: string; // Spline 场景 URL
45
50
  };
46
51
 
@@ -55,7 +55,7 @@ export const DEFAULT_POST_THUMBNAIL_IMAGE_SIZE: ImageResize = {
55
55
  export type ImageProps = {
56
56
  alt?: string;
57
57
  className?: string;
58
- mediaRef?: string;
58
+ src?: string;
59
59
  //默认original
60
60
  fileField?: FileFieldType;
61
61
  resize?: ImageResize;
@@ -0,0 +1,160 @@
1
+ /**
2
+ * 站点排版(Typography)相关的 className 枚举。
3
+ *
4
+ * - 这些值对应 Tailwind/CSS 中的 class 名称(例如 `.text-h1`)。
5
+ * - 用 enum 的好处是:业务侧使用时避免手写字符串、避免拼写错误。
6
+ */
7
+ export enum TypographyClassName {
8
+ /**
9
+ * 一级标题(H1)
10
+ * - 使用场景:首页 Banner 主标题、内页页面标题
11
+ * - 样式:`@apply text-4xl sm:text-5xl lg:text-6xl xl:text-7xl font-semibold leading-tight;`
12
+ * - 文字颜色:品牌主色
13
+ * - 例:工业蓝 `#2E5AAC` / RGB(46, 90, 172)
14
+ * - Tailwind:`text-[#2E5AAC]`
15
+ */
16
+ textH1 = "text-h1",
17
+
18
+ /**
19
+ * 二级标题(H2)
20
+ * - 使用场景:板块标题(如“关于我们 / 产品分类 / 数字实力”)
21
+ * - 样式:`@apply text-3xl sm:text-4xl lg:text-5xl font-semibold leading-snug;`
22
+ * - 文字颜色:深灰色
23
+ * - 例:`#333333` / RGB(51, 51, 51)
24
+ * - Tailwind:`text-[#333333]`
25
+ */
26
+ textH2 = "text-h2",
27
+
28
+ /**
29
+ * 三级标题(H3)
30
+ * - 使用场景:子板块标题(如产品子类、优势小点)
31
+ * - 样式:`@apply text-2xl sm:text-3xl lg:text-4xl font-semibold leading-snug;`
32
+ * - 文字颜色:中深灰色
33
+ * - 例:`#444444` / RGB(68, 68, 68)
34
+ * - Tailwind:`text-[#444444]`
35
+ */
36
+ textH3 = "text-h3",
37
+
38
+ /**
39
+ * 四级标题(H4)
40
+ * - 使用场景:详情页小标题(如参数分类、案例亮点)
41
+ * - 样式:`@apply text-xl sm:text-2xl lg:text-3xl font-semibold leading-snug;`
42
+ * - 文字颜色:中灰色
43
+ * - 例:`#555555` / RGB(85, 85, 85)
44
+ * - Tailwind:`text-[#555555]`
45
+ */
46
+ textH4 = "text-h4",
47
+
48
+ /**
49
+ * H5
50
+ * - 使用场景:H5 标题
51
+ * - 样式:`@apply text-lg md:text-xl leading-snug;`
52
+ */
53
+ textH5 = "text-h5",
54
+
55
+ /**
56
+ * H6
57
+ * - 使用场景:H6 标题
58
+ * - 样式:`@apply text-base md:text-lg leading-relaxed;`
59
+ */
60
+ textH6 = "text-h6",
61
+
62
+
63
+ // 正文(Body)
64
+ // - 更符合网站惯例:用全局基准字体(body 或内容容器)统一控制正文样式,段落直接继承
65
+ // - 文字颜色:中灰色
66
+ // - 例:`#666666` / RGB(102, 102, 102)
67
+ // - Tailwind:`text-[#666666]`
68
+ // textBody = "text-body",
69
+
70
+ /**
71
+ * 辅助说明(Caption)
72
+ * - 使用场景:图片标注、参数备注、表单提示
73
+ * - 样式:`@apply text-xs md:text-sm leading-snug;` + `color: var(--foreground-secondary);`
74
+ * - 文字颜色:浅灰色
75
+ * - 例:`#888888` / RGB(136, 136, 136)
76
+ * - Tailwind:`text-[#888888]`
77
+ */
78
+ textCaption = "text-caption",
79
+
80
+ /**
81
+ * 强调文本(Strong)
82
+ * - 使用场景:核心数据、优势关键词(适配“数字实力”板块)
83
+ * - 样式:`@apply text-lg md:text-xl font-semibold leading-snug;`
84
+ * - 文字颜色:建议使用深灰色或继承当前容器标题色(以保证强调对比)
85
+ * - 深灰示例:`#333333` / RGB(51, 51, 51)
86
+ * - Tailwind:`text-[#333333]`
87
+ */
88
+ textStrong = "text-strong",
89
+
90
+ /**
91
+ * 链接文本(Link)
92
+ * - 使用场景:导航栏、按钮文字、详情跳转
93
+ * - 样式:`@apply text-sm md:text-base font-medium leading-snug;`
94
+ * - 文字颜色:品牌主色(同 H1)或深灰色 `#333333`
95
+ * - 常规:品牌主色 `#2E5AAC` / RGB(46, 90, 172)
96
+ * - Hover:主色加深 `#1E4A9C`
97
+ * - Tailwind:`text-[#2E5AAC] hover:text-[#1E4A9C]`
98
+ */
99
+ textLink = "text-link",
100
+ }
101
+
102
+ /**
103
+ * 颜色规范补充(非 Typography class):
104
+ * - 表单必填提示 / 订单须知:低饱和警示色
105
+ * - 例:`#E67E22` / RGB(230, 126, 34)
106
+ * - Tailwind:`text-[#E67E22]`
107
+ */
108
+
109
+ /**
110
+ * 下拉/单选等 UI 控件的可选项顺序。
111
+ *
112
+ * 说明:不要依赖 `Object.values(TypographyClassName)` 做 UI 列表
113
+ * - 顺序不一定符合展示需求
114
+ * - 后续插入/调整可能导致 UI 顺序变化
115
+ */
116
+ export const typographyClassNameList: TypographyClassName[] = [
117
+ TypographyClassName.textCaption,
118
+ TypographyClassName.textStrong,
119
+ TypographyClassName.textLink,
120
+ TypographyClassName.textH1,
121
+ TypographyClassName.textH2,
122
+ TypographyClassName.textH3,
123
+ TypographyClassName.textH4,
124
+ TypographyClassName.textH5,
125
+ TypographyClassName.textH6,
126
+ ];
127
+
128
+ /**
129
+ * 面向 UI 展示的短 label(用于下拉选项文案)。
130
+ *
131
+ * 约束:尽量短,避免下拉太宽。
132
+ */
133
+ export const typographyClassNameLabels: Record<TypographyClassName, string> = {
134
+ [TypographyClassName.textH1]: "一级标题",
135
+ [TypographyClassName.textH2]: "二级标题",
136
+ [TypographyClassName.textH3]: "三级标题",
137
+ [TypographyClassName.textH4]: "四级标题",
138
+ [TypographyClassName.textH5]: "五级标题",
139
+ [TypographyClassName.textH6]: "六级标题",
140
+ [TypographyClassName.textCaption]: "说明",
141
+ [TypographyClassName.textStrong]: "强调",
142
+ [TypographyClassName.textLink]: "链接",
143
+ };
144
+
145
+ /**
146
+ * Heading 组件 level(1-6) 与 Typography class 的映射。
147
+ *
148
+ * 说明:只定义 1-4(H1~H4)的排版规范;H5/H6 暂时回退到较小正文规格。
149
+ */
150
+ export const headingLevelToTypographyClassName: Record<
151
+ 1 | 2 | 3 | 4 | 5 | 6,
152
+ TypographyClassName
153
+ > = {
154
+ 1: TypographyClassName.textH1,
155
+ 2: TypographyClassName.textH2,
156
+ 3: TypographyClassName.textH3,
157
+ 4: TypographyClassName.textH4,
158
+ 5: TypographyClassName.textH5,
159
+ 6: TypographyClassName.textH6,
160
+ };
@@ -15,6 +15,8 @@ import {
15
15
  queryPosts,
16
16
  queryProductCategories,
17
17
  queryProducts,
18
+ queryTagCategories,
19
+ queryTags,
18
20
  queryUserPosts,
19
21
  fulltextSearch,
20
22
  queryOneEntity,
@@ -268,6 +270,14 @@ export class Entify implements IEntify {
268
270
  return await queryOnePostCategoryBySlug(slug, this.envVariables);
269
271
  }
270
272
 
273
+ public async getTagCategories() {
274
+ return await queryTagCategories(this.envVariables);
275
+ }
276
+
277
+ public async getTags(categoryId?: string) {
278
+ return await queryTags(this.envVariables, categoryId);
279
+ }
280
+
271
281
  public async getProducts(
272
282
  conditions: ListConditions,
273
283
  imageSize: ImageSize | undefined,
@@ -5,6 +5,8 @@ import {
5
5
  TPostCategory,
6
6
  TProduct,
7
7
  TProductCategory,
8
+ TTag,
9
+ TTagCategory,
8
10
  TUser,
9
11
  } from "./view-model";
10
12
  import {
@@ -123,6 +125,10 @@ export interface IEntify {
123
125
 
124
126
  getPostCategoryBySlug(slug: string): Promise<TPostCategory | undefined>;
125
127
 
128
+ getTagCategories(): Promise<TTagCategory[] | undefined>;
129
+
130
+ getTags(categoryId?: string): Promise<TTag[] | undefined>;
131
+
126
132
  getProducts(
127
133
  conditions: ListConditions,
128
134
  imageSize: ImageSize | undefined,
@@ -19,6 +19,8 @@ export * from "./queryOneProductCategoryBySlug";
19
19
  export * from "./queryOneUser";
20
20
  export * from "./queryPostCategories";
21
21
  export * from "./queryPosts";
22
+ export * from "./queryTagCategories";
23
+ export * from "./queryTags";
22
24
  export * from "./queryProductCategories";
23
25
  export * from "./queryProducts";
24
26
  export * from "./queryProductsInMenu";
@@ -0,0 +1,58 @@
1
+ import {
2
+ TagCategory,
3
+ TagCategoryBoolExp,
4
+ TagCategoryOrderBy,
5
+ TagCategoryDistinctExp,
6
+ TagCategoryFields,
7
+ TagCategoryQueryOptions,
8
+ TagQueryOptions,
9
+ TagFields,
10
+ } from "@rxdrag/rxcms-models";
11
+ import { queryEntityList } from "./queryEntityList";
12
+ import { ListResult } from "@rxdrag/entify-lib";
13
+ import { EnvVariables } from "../types";
14
+ import { TTagCategory } from "../view-model";
15
+ import { listToTree } from "./listToTree";
16
+
17
+ export async function queryTagCategories(envVariables: EnvVariables) {
18
+ const result = await queryEntityList<
19
+ TagCategory,
20
+ TagCategoryBoolExp,
21
+ TagCategoryOrderBy,
22
+ TagCategoryDistinctExp
23
+ >(
24
+ new TagCategoryQueryOptions(
25
+ [
26
+ TagCategoryFields.id,
27
+ TagCategoryFields.name,
28
+ ],
29
+ {
30
+ where: {
31
+ lang: {
32
+ abbr: {
33
+ _eq: envVariables.language,
34
+ },
35
+ },
36
+ },
37
+ orderBy: [{ [TagCategoryFields.name]: "asc" }],
38
+ }
39
+ )
40
+ .parent()
41
+ .tags(
42
+ new TagQueryOptions(
43
+ [TagFields.id, TagFields.name, TagFields.color],
44
+ {
45
+ orderBy: [{ [TagFields.createdAt]: "desc" }],
46
+ }
47
+ )
48
+ ),
49
+ envVariables
50
+ );
51
+ const typedResult = result as ListResult<TTagCategory> | undefined;
52
+
53
+ if (!typedResult) {
54
+ return undefined;
55
+ }
56
+
57
+ return listToTree(typedResult.items || []);
58
+ }
@@ -0,0 +1,57 @@
1
+ import {
2
+ Tag,
3
+ TagBoolExp,
4
+ TagOrderBy,
5
+ TagDistinctExp,
6
+ TagFields,
7
+ TagQueryOptions,
8
+ TagAssciations,
9
+ } from "@rxdrag/rxcms-models";
10
+ import { queryEntityList } from "./queryEntityList";
11
+ import { ListResult } from "@rxdrag/entify-lib";
12
+ import { EnvVariables } from "../types";
13
+ import { TTag } from "../view-model";
14
+
15
+ export async function queryTags(envVariables: EnvVariables, categoryId?: string) {
16
+ const whereCondition: TagBoolExp = {
17
+ lang: {
18
+ abbr: {
19
+ _eq: envVariables.language,
20
+ },
21
+ },
22
+ };
23
+
24
+ if (categoryId) {
25
+ whereCondition[TagAssciations.category] = {
26
+ id: { _eq: categoryId },
27
+ };
28
+ }
29
+
30
+ const result = await queryEntityList<
31
+ Tag,
32
+ TagBoolExp,
33
+ TagOrderBy,
34
+ TagDistinctExp
35
+ >(
36
+ new TagQueryOptions(
37
+ [
38
+ TagFields.id,
39
+ TagFields.name,
40
+ TagFields.color,
41
+ ],
42
+ {
43
+ where: whereCondition,
44
+ orderBy: [{ [TagFields.name]: "asc" }],
45
+ }
46
+ ).category(),
47
+ envVariables
48
+ );
49
+
50
+ const typedResult = result as ListResult<TTag> | undefined;
51
+
52
+ if (!typedResult) {
53
+ return undefined;
54
+ }
55
+
56
+ return typedResult.items;
57
+ }
@@ -50,6 +50,21 @@ export type TPostCategory = {
50
50
  posts?: TPost[];
51
51
  };
52
52
 
53
+ export type TTagCategory = {
54
+ id?: string | null;
55
+ name?: string;
56
+ children?: TTagCategory[];
57
+ parent?: TTagCategory;
58
+ tags?: TTag[];
59
+ };
60
+
61
+ export type TTag = {
62
+ id?: string | null;
63
+ name?: string;
64
+ color?: string;
65
+ category?: TTagCategory;
66
+ };
67
+
53
68
  export type TUser = {
54
69
  id?: string | null;
55
70
  name?: string;
@@ -113,6 +128,8 @@ export const entityMaps: Record<string, string> = {
113
128
  Product: "TProduct",
114
129
  Post: "TPost",
115
130
  PostCategory: "TPostCategory",
131
+ TagCategory: "TTagCategory",
132
+ Tag: "TTag",
116
133
  User: "TUser",
117
134
  WebsiteSettings: "TWebsiteSettings",
118
135
  };
package/src/index.ts CHANGED
@@ -4,3 +4,5 @@ export * from "./entify";
4
4
  export * from "./react";
5
5
  export * from "./robots";
6
6
  export * from "./lib";
7
+ export * from "./design-tokens";
8
+
@@ -2,25 +2,19 @@ import {
2
2
  Icon as IconifyIcon,
3
3
  IconProps as IconifyIconProps,
4
4
  } from "@iconify/react";
5
+ import type { IconifyIcon as IconifyIconData } from "@iconify/react";
5
6
  import { forwardRef } from "react";
6
- import { svgToIconify } from "./svgToIconify";
7
-
8
- export { svgToIconify };
9
7
 
10
8
  export type IconProps = Omit<IconifyIconProps, "icon"> & {
11
- icon?: string;
12
- svg?: string;
9
+ icon?: string | IconifyIconData;
13
10
  };
14
11
 
15
12
  export const Icon = forwardRef<SVGSVGElement, IconProps>((props, ref) => {
16
- const { icon, svg, ...rest } = props;
17
-
18
- const iconObj = svg ? svgToIconify(svg) : undefined;
19
- const finalIcon = icon || iconObj;
13
+ const { icon, ...rest } = props;
20
14
 
21
- if (!finalIcon) {
15
+ if (!icon) {
22
16
  return null;
23
17
  }
24
18
 
25
- return <IconifyIcon ref={ref} {...rest} icon={finalIcon} />;
26
- });
19
+ return <IconifyIcon ref={ref} {...rest} icon={icon} />;
20
+ });
@@ -1,59 +0,0 @@
1
- import { IconifyIcon } from "@iconify/react";
2
-
3
- export function svgToIconify(svgString: string): IconifyIcon | null {
4
- if (typeof window === 'undefined') return null;
5
-
6
- try {
7
- const parser = new DOMParser();
8
- const doc = parser.parseFromString(svgString, "image/svg+xml");
9
- const svg = doc.querySelector("svg");
10
-
11
- if (!svg) {
12
- console.error("Invalid SVG string");
13
- return null;
14
- }
15
-
16
- const viewBox = svg.getAttribute("viewBox");
17
- let width = svg.getAttribute("width");
18
- let height = svg.getAttribute("height");
19
-
20
- // 如果没有显式宽高,尝试从 viewBox 解析
21
- if (viewBox && (!width || !height)) {
22
- const parts = viewBox.split(/\s+/).map(parseFloat);
23
- if (parts.length === 4) {
24
- if (!width) width = parts[2].toString();
25
- if (!height) height = parts[3].toString();
26
- }
27
- }
28
-
29
- // 提取关键属性并包裹在 <g> 中,以保留 SVG 根节点的样式
30
- const attributesToPreserve = [
31
- "fill",
32
- "stroke",
33
- "stroke-width",
34
- "stroke-linecap",
35
- "stroke-linejoin"
36
- ];
37
-
38
- const gAttributes = attributesToPreserve
39
- .map(attr => {
40
- const value = svg.getAttribute(attr);
41
- return value ? `${attr}="${value}"` : "";
42
- })
43
- .filter(Boolean)
44
- .join(" ");
45
-
46
- const body = gAttributes
47
- ? `<g ${gAttributes}>${svg.innerHTML}</g>`
48
- : svg.innerHTML;
49
-
50
- return {
51
- body,
52
- width: width ? parseFloat(width) : undefined,
53
- height: height ? parseFloat(height) : undefined,
54
- };
55
- } catch (e) {
56
- console.error("Error parsing SVG:", e);
57
- return null;
58
- }
59
- }