dishui 0.0.84 → 0.0.89
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/dist/components/Input/index.js +52 -62
- package/dist/components/Input/index.js.map +1 -1
- package/dist/components/LayoutSuite/index.d.ts +10 -0
- package/dist/components/LayoutSuite/index.js +27 -18
- package/dist/components/LayoutSuite/index.js.map +1 -1
- package/dist/components/Markdown/markdownComponents.js +1 -0
- package/dist/components/Markdown/markdownComponents.js.map +1 -1
- package/dist/components/Markdown/useMarkdownSource.js +46 -31
- package/dist/components/Markdown/useMarkdownSource.js.map +1 -1
- package/dist/components/Markdown/useMarkmapRenderer.js +44 -31
- package/dist/components/Markdown/useMarkmapRenderer.js.map +1 -1
- package/dist/components/Markdown/useMermaidRenderer.js +49 -31
- package/dist/components/Markdown/useMermaidRenderer.js.map +1 -1
- package/dist/components/ProtectedRoute/index.d.ts +2 -1
- package/dist/components/ProtectedRoute/index.js +16 -6
- package/dist/components/ProtectedRoute/index.js.map +1 -1
- package/dist/components/Select/index.d.ts +6 -0
- package/dist/components/Select/index.js +166 -136
- package/dist/components/Select/index.js.map +1 -1
- package/dist/components/Tabs/index.d.ts +12 -1
- package/dist/components/Tabs/index.js +42 -17
- package/dist/components/Tabs/index.js.map +1 -1
- package/dist/components/pro/ArticleContextMenu/index.js +7 -7
- package/dist/components/pro/CodeEditor/editors/CodeEditor.js +200 -189
- package/dist/components/pro/CodeEditor/editors/CodeEditor.js.map +1 -1
- package/dist/components/pro/CodeEditor/types.d.ts +3 -0
- package/dist/components/pro/DataTable/DataTable.d.ts +1 -1
- package/dist/components/pro/DataTable/DataTable.js +98 -240
- package/dist/components/pro/DataTable/DataTable.js.map +1 -1
- package/dist/components/pro/DataTable/components/TableBody.js +14 -16
- package/dist/components/pro/DataTable/components/TableBody.js.map +1 -1
- package/dist/components/pro/DataTable/components/TablePagination.d.ts +3 -9
- package/dist/components/pro/DataTable/components/TablePagination.js +29 -25
- package/dist/components/pro/DataTable/components/TablePagination.js.map +1 -1
- package/dist/components/pro/DataTable/tanstack-table.d.ts +2 -2
- package/dist/components/pro/DataTable/tanstack-table.js +29 -21
- package/dist/components/pro/DataTable/tanstack-table.js.map +1 -1
- package/dist/components/pro/DataTable/treeDataUtils.d.ts +2 -0
- package/dist/components/pro/DataTable/treeDataUtils.js +18 -19
- package/dist/components/pro/DataTable/treeDataUtils.js.map +1 -1
- package/dist/components/pro/DataTable/types.d.ts +24 -0
- package/dist/components/pro/DataTable/useDataTableModel.d.ts +16 -0
- package/dist/components/pro/DataTable/useDataTableModel.js +148 -0
- package/dist/components/pro/DataTable/useDataTableModel.js.map +1 -0
- package/dist/components/pro/FileExplorer/Breadcrumb.js +12 -12
- package/dist/components/pro/Flow/nodes/DataNodeView.js +87 -82
- package/dist/components/pro/Flow/nodes/DataNodeView.js.map +1 -1
- package/dist/components/pro/Flow/nodes/MediaContent.js +1 -1
- package/dist/components/pro/Flow/nodes/MediaContent.js.map +1 -1
- package/dist/components/pro/Flow/nodes/MediaOverlay.js +1 -1
- package/dist/components/pro/Flow/nodes/MediaOverlay.js.map +1 -1
- package/dist/components/pro/Flow/nodes/Model3DView.js +69 -63
- package/dist/components/pro/Flow/nodes/Model3DView.js.map +1 -1
- package/dist/components/pro/Flow/nodes/chartGeometryBudget.d.ts +14 -0
- package/dist/components/pro/Flow/nodes/chartGeometryBudget.js +76 -0
- package/dist/components/pro/Flow/nodes/chartGeometryBudget.js.map +1 -0
- package/dist/components/pro/Flow/nodes/demandRender.d.ts +11 -0
- package/dist/components/pro/Flow/nodes/demandRender.js +26 -0
- package/dist/components/pro/Flow/nodes/demandRender.js.map +1 -0
- package/dist/components/pro/RichTextEditor/SlashMenu.js +68 -58
- package/dist/components/pro/RichTextEditor/SlashMenu.js.map +1 -1
- package/dist/contexts/AppContext.d.ts +1 -0
- package/dist/contexts/AppContext.js +144 -145
- package/dist/contexts/AppContext.js.map +1 -1
- package/dist/contexts/authentication.d.ts +7 -0
- package/dist/contexts/authentication.js +22 -0
- package/dist/contexts/authentication.js.map +1 -0
- package/dist/dishui.css +1 -1
- package/dist/hooks/useControllableState.d.ts +6 -14
- package/dist/hooks/useControllableState.js +21 -15
- package/dist/hooks/useControllableState.js.map +1 -1
- package/dist/hooks/useTableColumns.d.ts +3 -3
- package/dist/hooks/useTableColumns.js +2 -2
- package/dist/hooks/useTableColumns.js.map +1 -1
- package/dist/hooks/useTableData.d.ts +11 -4
- package/dist/hooks/useTableData.js +44 -26
- package/dist/hooks/useTableData.js.map +1 -1
- package/dist/index-nostyled.d.ts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +97 -97
- package/dist/utils/i18n.js +1 -1
- package/dist/utils/i18n.js.map +1 -1
- package/dist/utils/routerBuilder.d.ts +7 -5
- package/dist/utils/routerBuilder.js +11 -15
- package/dist/utils/routerBuilder.js.map +1 -1
- package/dist/utils/safeStorage.d.ts +8 -0
- package/dist/utils/safeStorage.js +45 -0
- package/dist/utils/safeStorage.js.map +1 -0
- package/package.json +22 -5
|
@@ -3,41 +3,35 @@ import { useId as e, useRef as t, useState as n } from "react";
|
|
|
3
3
|
import { jsx as r, jsxs as i } from "react/jsx-runtime";
|
|
4
4
|
//#region src/components/Input/index.tsx
|
|
5
5
|
var a = ({ placeholder: a, value: o, onChange: s, type: c = "text", variant: l, size: u = "sm", disabled: d = !1, required: f = !1, label: p, labelPosition: m = "inline", leftSection: h, rightSection: g, pattern: _, className: v = "", validator: y = !1, validatorHint: b, validationRules: x = [], id: S, readOnly: C, ...w }) => {
|
|
6
|
-
let T = e(), E = S || T, [D, O] = n(!1), [k, A] = n(
|
|
6
|
+
let T = e(), E = S || T, [D, O] = n(!1), [k, A] = n(null), [j, M] = n(!1), [N, P] = n([]), F = t(null), I = c === "password" && D ? "text" : c, L = (e) => {
|
|
7
7
|
let t = e.target.value;
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}, 1e3);
|
|
13
|
-
}
|
|
14
|
-
y && L.current && B(t), s && s(e);
|
|
15
|
-
}, B = (e) => {
|
|
16
|
-
if (!L.current) return;
|
|
17
|
-
let t = L.current.checkValidity(), n = [];
|
|
8
|
+
y && F.current && R(t), s && s(e);
|
|
9
|
+
}, R = (e) => {
|
|
10
|
+
if (!F.current) return;
|
|
11
|
+
let t = F.current.checkValidity(), n = [];
|
|
18
12
|
x.length > 0 && x.forEach((t) => {
|
|
19
13
|
t.pattern.test(e) || n.push(t.message);
|
|
20
|
-
}),
|
|
21
|
-
},
|
|
14
|
+
}), P(n), A(t && n.length === 0);
|
|
15
|
+
}, z = () => {
|
|
22
16
|
O(!D);
|
|
23
|
-
},
|
|
24
|
-
y && !
|
|
25
|
-
},
|
|
26
|
-
|
|
27
|
-
},
|
|
28
|
-
y &&
|
|
29
|
-
let
|
|
17
|
+
}, B = () => {
|
|
18
|
+
y && !k && M(!0);
|
|
19
|
+
}, V = () => {
|
|
20
|
+
M(!1);
|
|
21
|
+
}, H = "";
|
|
22
|
+
y && k !== null && (H = k ? "input-success" : "input-error");
|
|
23
|
+
let U = {
|
|
30
24
|
...w,
|
|
31
25
|
id: E,
|
|
32
26
|
readOnly: C,
|
|
33
|
-
"aria-invalid": w["aria-invalid"] ?? (y &&
|
|
34
|
-
},
|
|
27
|
+
"aria-invalid": w["aria-invalid"] ?? (y && k === !1 ? !0 : void 0)
|
|
28
|
+
}, W = "input dishui-input", G = l && !H ? `input-${l}` : "", K = u ? `input-${u}` : "", q = y ? "validator" : "", J = c === "password" && /* @__PURE__ */ r("button", {
|
|
35
29
|
type: "button",
|
|
36
30
|
disabled: d,
|
|
37
31
|
"aria-label": D ? "Hide password" : "Show password",
|
|
38
32
|
"aria-pressed": D,
|
|
39
33
|
className: "cursor-pointer opacity-70 hover:opacity-100",
|
|
40
|
-
onClick:
|
|
34
|
+
onClick: z,
|
|
41
35
|
children: D ? /* @__PURE__ */ i("svg", {
|
|
42
36
|
xmlns: "http://www.w3.org/2000/svg",
|
|
43
37
|
className: "h-5 w-5",
|
|
@@ -64,11 +58,11 @@ var a = ({ placeholder: a, value: o, onChange: s, type: c = "text", variant: l,
|
|
|
64
58
|
r: "3"
|
|
65
59
|
})]
|
|
66
60
|
})
|
|
67
|
-
}),
|
|
61
|
+
}), Y = /* @__PURE__ */ r("div", {
|
|
68
62
|
className: "validation-tooltip",
|
|
69
|
-
children:
|
|
63
|
+
children: N.length > 0 ? /* @__PURE__ */ r("ul", {
|
|
70
64
|
className: "text-xs list-disc pl-4 py-1",
|
|
71
|
-
children:
|
|
65
|
+
children: N.map((e, t) => /* @__PURE__ */ r("li", { children: e }, t))
|
|
72
66
|
}) : b ? /* @__PURE__ */ r("p", {
|
|
73
67
|
className: "text-xs py-1",
|
|
74
68
|
children: b
|
|
@@ -76,8 +70,8 @@ var a = ({ placeholder: a, value: o, onChange: s, type: c = "text", variant: l,
|
|
|
76
70
|
});
|
|
77
71
|
return p || h || g || c === "password" ? p && m === "top" ? /* @__PURE__ */ i("div", {
|
|
78
72
|
className: `relative w-full ${v}`,
|
|
79
|
-
onMouseEnter:
|
|
80
|
-
onMouseLeave:
|
|
73
|
+
onMouseEnter: B,
|
|
74
|
+
onMouseLeave: V,
|
|
81
75
|
children: [
|
|
82
76
|
/* @__PURE__ */ r("label", {
|
|
83
77
|
htmlFor: E,
|
|
@@ -85,16 +79,16 @@ var a = ({ placeholder: a, value: o, onChange: s, type: c = "text", variant: l,
|
|
|
85
79
|
children: p
|
|
86
80
|
}),
|
|
87
81
|
/* @__PURE__ */ i("label", {
|
|
88
|
-
className: `${
|
|
82
|
+
className: `${W} ${G} ${K} ${q} ${H} w-full flex items-center gap-2`,
|
|
89
83
|
children: [
|
|
90
84
|
h && /* @__PURE__ */ r("span", { children: h }),
|
|
91
85
|
/* @__PURE__ */ r("input", {
|
|
92
|
-
...
|
|
93
|
-
ref:
|
|
94
|
-
type:
|
|
86
|
+
...U,
|
|
87
|
+
ref: F,
|
|
88
|
+
type: I,
|
|
95
89
|
placeholder: a,
|
|
96
90
|
value: o,
|
|
97
|
-
onChange:
|
|
91
|
+
onChange: L,
|
|
98
92
|
disabled: d,
|
|
99
93
|
required: f,
|
|
100
94
|
className: "grow",
|
|
@@ -106,7 +100,7 @@ var a = ({ placeholder: a, value: o, onChange: s, type: c = "text", variant: l,
|
|
|
106
100
|
"aria-label": D ? "Hide password" : "Show password",
|
|
107
101
|
"aria-pressed": D,
|
|
108
102
|
className: "cursor-pointer opacity-70 hover:opacity-100",
|
|
109
|
-
onClick:
|
|
103
|
+
onClick: z,
|
|
110
104
|
children: D ? /* @__PURE__ */ i("svg", {
|
|
111
105
|
xmlns: "http://www.w3.org/2000/svg",
|
|
112
106
|
className: "h-5 w-5",
|
|
@@ -136,77 +130,73 @@ var a = ({ placeholder: a, value: o, onChange: s, type: c = "text", variant: l,
|
|
|
136
130
|
}) : g ? /* @__PURE__ */ r("span", { children: g }) : null
|
|
137
131
|
]
|
|
138
132
|
}),
|
|
139
|
-
y && b && !
|
|
133
|
+
y && b && !j && /* @__PURE__ */ r("p", {
|
|
140
134
|
className: "validator-hint text-xs mt-1 opacity-70",
|
|
141
135
|
children: b
|
|
142
136
|
}),
|
|
143
|
-
|
|
137
|
+
j && y && !k && /* @__PURE__ */ r("div", {
|
|
144
138
|
className: "absolute z-10 mt-1 bg-base-200 border border-error rounded shadow-lg text-error px-3 py-1",
|
|
145
|
-
children:
|
|
139
|
+
children: Y
|
|
146
140
|
})
|
|
147
141
|
]
|
|
148
142
|
}) : /* @__PURE__ */ i("div", {
|
|
149
143
|
className: `relative w-full ${v}`,
|
|
150
|
-
onMouseEnter:
|
|
151
|
-
onMouseLeave:
|
|
144
|
+
onMouseEnter: B,
|
|
145
|
+
onMouseLeave: V,
|
|
152
146
|
children: [
|
|
153
147
|
/* @__PURE__ */ i("label", {
|
|
154
|
-
className: `${
|
|
148
|
+
className: `${W} ${G} ${K} ${q} ${H} w-full flex items-center gap-2`,
|
|
155
149
|
children: [
|
|
156
150
|
h && /* @__PURE__ */ r("span", { children: h }),
|
|
157
151
|
p && /* @__PURE__ */ r("span", { children: p }),
|
|
158
152
|
/* @__PURE__ */ r("input", {
|
|
159
|
-
...
|
|
160
|
-
ref:
|
|
161
|
-
type:
|
|
153
|
+
...U,
|
|
154
|
+
ref: F,
|
|
155
|
+
type: I,
|
|
162
156
|
placeholder: a,
|
|
163
157
|
value: o,
|
|
164
|
-
onChange:
|
|
158
|
+
onChange: L,
|
|
165
159
|
disabled: d,
|
|
166
160
|
required: f,
|
|
167
161
|
className: "grow",
|
|
168
162
|
pattern: _
|
|
169
163
|
}),
|
|
170
|
-
c === "password"
|
|
171
|
-
className: "password-recent absolute right-10 font-mono",
|
|
172
|
-
children: k
|
|
173
|
-
}),
|
|
174
|
-
c === "password" ? /* @__PURE__ */ r("span", { children: X }) : g ? /* @__PURE__ */ r("span", { children: g }) : null
|
|
164
|
+
c === "password" ? /* @__PURE__ */ r("span", { children: J }) : g ? /* @__PURE__ */ r("span", { children: g }) : null
|
|
175
165
|
]
|
|
176
166
|
}),
|
|
177
|
-
y && b && !
|
|
167
|
+
y && b && !j && /* @__PURE__ */ r("p", {
|
|
178
168
|
className: "validator-hint text-xs mt-1 opacity-70",
|
|
179
169
|
children: b
|
|
180
170
|
}),
|
|
181
|
-
|
|
171
|
+
j && y && !k && /* @__PURE__ */ r("div", {
|
|
182
172
|
className: "absolute z-10 mt-1 bg-base-200 border border-error rounded shadow-lg text-error px-3 py-1",
|
|
183
|
-
children:
|
|
173
|
+
children: Y
|
|
184
174
|
})
|
|
185
175
|
]
|
|
186
176
|
}) : /* @__PURE__ */ i("div", {
|
|
187
177
|
className: `relative w-full ${v}`,
|
|
188
|
-
onMouseEnter:
|
|
189
|
-
onMouseLeave:
|
|
178
|
+
onMouseEnter: B,
|
|
179
|
+
onMouseLeave: V,
|
|
190
180
|
children: [
|
|
191
181
|
/* @__PURE__ */ r("input", {
|
|
192
|
-
...
|
|
193
|
-
ref:
|
|
194
|
-
type:
|
|
182
|
+
...U,
|
|
183
|
+
ref: F,
|
|
184
|
+
type: I,
|
|
195
185
|
placeholder: a,
|
|
196
186
|
value: o,
|
|
197
|
-
onChange:
|
|
187
|
+
onChange: L,
|
|
198
188
|
disabled: d,
|
|
199
189
|
required: f,
|
|
200
|
-
className: `${
|
|
190
|
+
className: `${W} ${G} ${K} ${q} ${H} w-full`,
|
|
201
191
|
pattern: _
|
|
202
192
|
}),
|
|
203
|
-
y && b && !
|
|
193
|
+
y && b && !j && /* @__PURE__ */ r("p", {
|
|
204
194
|
className: "validator-hint text-xs mt-1 opacity-70",
|
|
205
195
|
children: b
|
|
206
196
|
}),
|
|
207
|
-
|
|
197
|
+
j && y && !k && /* @__PURE__ */ r("div", {
|
|
208
198
|
className: "absolute z-10 mt-1 bg-base-200 border border-error rounded shadow-lg text-error px-3 py-1",
|
|
209
|
-
children:
|
|
199
|
+
children: Y
|
|
210
200
|
})
|
|
211
201
|
]
|
|
212
202
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/Input/index.tsx"],"sourcesContent":["import React, { useState, useRef, useId } from 'react';\nimport './Input.css';\n\nexport type InputProps = Pick<React.InputHTMLAttributes<HTMLInputElement>, 'id' | 'name' | 'readOnly' | 'aria-label' | 'aria-labelledby' | 'aria-describedby' | 'aria-invalid'> & {\n placeholder?: string;\n value?: string;\n onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;\n type?: string;\n variant?: 'neutral' | 'primary' | 'secondary' | 'accent' | 'info' | 'success' | 'warning' | 'error' | 'ghost';\n size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';\n disabled?: boolean;\n required?: boolean;\n label?: string;\n labelPosition?: 'inline' | 'top';\n leftSection?: React.ReactNode;\n rightSection?: React.ReactNode;\n pattern?: string;\n className?: string;\n validator?: boolean;\n validatorHint?: string;\n validationRules?: {\n pattern: RegExp;\n message: string;\n }[];\n};\n\nconst Input = ({\n placeholder,\n value,\n onChange,\n type = 'text',\n variant,\n size = 'sm',\n disabled = false,\n required = false,\n label,\n labelPosition = 'inline',\n leftSection,\n rightSection,\n pattern,\n className = '',\n validator = false,\n validatorHint,\n validationRules = [],\n id,\n readOnly,\n ...inputAttributes\n}: InputProps) => {\n const generatedId = useId();\n const fieldId = id || generatedId;\n\n // 密码显示/隐藏状态\n const [showPassword, setShowPassword] = useState(false);\n // 追踪最近输入的字符\n const [recentInput, setRecentInput] = useState('');\n // 表单验证状态\n const [isValid, setIsValid] = useState<boolean | null>(null);\n // 显示验证提示\n const [showValidationHint, setShowValidationHint] = useState(false);\n // 验证失败的规则消息\n const [failedRules, setFailedRules] = useState<string[]>([]);\n \n // 输入框引用,用于焦点和验证\n const inputRef = useRef<HTMLInputElement>(null);\n \n // 确定实际使用的输入类型\n const actualType = type === 'password' && showPassword ? 'text' : type;\n \n // 处理输入变化,包括密码字符延迟遮罩和验证\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const newValue = e.target.value;\n \n // 处理密码输入的特殊效果\n if (type === 'password' && newValue.length > (value || '').length) {\n // 获取新输入的字符\n const newChar = newValue.slice((value || '').length);\n setRecentInput(newChar);\n \n // 设置定时器延迟清除最近输入的字符\n setTimeout(() => {\n setRecentInput('');\n }, 1000); // 1秒后隐藏\n }\n \n // 验证输入\n if (validator && inputRef.current) {\n validateInput(newValue);\n }\n \n // 调用原始的onChange处理函数\n if (onChange) {\n onChange(e);\n }\n };\n \n // 验证输入值\n const validateInput = (inputValue: string) => {\n if (!inputRef.current) return;\n \n // 使用HTML5自带的验证\n const isNativeValid = inputRef.current.checkValidity();\n \n // 检查自定义验证规则\n const failedMessages: string[] = [];\n \n if (validationRules.length > 0) {\n validationRules.forEach(rule => {\n if (!rule.pattern.test(inputValue)) {\n failedMessages.push(rule.message);\n }\n });\n }\n \n setFailedRules(failedMessages);\n setIsValid(isNativeValid && failedMessages.length === 0);\n };\n \n // 切换密码显示/隐藏\n const togglePasswordVisibility = () => {\n setShowPassword(!showPassword);\n };\n \n // 鼠标悬停事件处理\n const handleMouseEnter = () => {\n if (validator && !isValid) {\n setShowValidationHint(true);\n }\n };\n \n const handleMouseLeave = () => {\n setShowValidationHint(false);\n };\n \n // 验证状态相关的类名\n let validationStateClass = '';\n if (validator && isValid !== null) {\n validationStateClass = isValid ? 'input-success' : 'input-error';\n }\n \n const fieldAttributes = {\n ...inputAttributes,\n id: fieldId,\n readOnly,\n 'aria-invalid': inputAttributes['aria-invalid'] ?? (validator && isValid === false ? true : undefined),\n };\n const baseClass = 'input dishui-input';\n const variantClass = variant && !validationStateClass ? `input-${variant}` : '';\n const sizeClass = size ? `input-${size}` : '';\n const validatorClass = validator ? 'validator' : '';\n \n\n // 密码可见性切换按钮\n const passwordToggle = type === 'password' && (\n <button\n type=\"button\"\n disabled={disabled}\n aria-label={showPassword ? 'Hide password' : 'Show password'}\n aria-pressed={showPassword}\n className=\"cursor-pointer opacity-70 hover:opacity-100\"\n onClick={togglePasswordVisibility}\n >\n {showPassword ? (\n // 眼睛关闭图标\n <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-5 w-5\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94\" />\n <path d=\"M14.12 14.12a3 3 0 1 1-4.24-4.24\" />\n <path d=\"M1 1l22 22\" />\n <path d=\"M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19\" />\n </svg>\n ) : (\n // 眼睛打开图标\n <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-5 w-5\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z\" />\n <circle cx=\"12\" cy=\"12\" r=\"3\" />\n </svg>\n )}\n </button>\n );\n \n // 构建验证提示悬浮框\n const validationTooltip = (\n <div className=\"validation-tooltip\">\n {failedRules.length > 0 ? (\n <ul className=\"text-xs list-disc pl-4 py-1\">\n {failedRules.map((rule, index) => (\n <li key={index}>{rule}</li>\n ))}\n </ul>\n ) : validatorHint ? (\n <p className=\"text-xs py-1\">{validatorHint}</p>\n ) : null}\n </div>\n );\n\n // 如果有label,则使用label作为容器\n if (label || leftSection || rightSection || type === 'password') {\n // labelPosition === 'top': label above the input field\n if (label && labelPosition === 'top') {\n return (\n <div className={`relative w-full ${className}`} onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave}>\n <label htmlFor={fieldId} className=\"text-sm font-medium mb-1 block\">{label}</label>\n <label className={`${baseClass} ${variantClass} ${sizeClass} ${validatorClass} ${validationStateClass} w-full flex items-center gap-2`}>\n {leftSection && <span>{leftSection}</span>}\n <input\n {...fieldAttributes}\n ref={inputRef}\n type={actualType}\n placeholder={placeholder}\n value={value}\n onChange={handleInputChange}\n disabled={disabled}\n required={required}\n className=\"grow\"\n pattern={pattern}\n />\n {type === 'password' ? (\n <button type=\"button\" disabled={disabled} aria-label={showPassword ? 'Hide password' : 'Show password'} aria-pressed={showPassword} className=\"cursor-pointer opacity-70 hover:opacity-100\" onClick={togglePasswordVisibility}>\n {showPassword ? (\n <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-5 w-5\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94\" />\n <path d=\"M14.12 14.12a3 3 0 1 1-4.24-4.24\" />\n <path d=\"M1 1l22 22\" />\n <path d=\"M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19\" />\n </svg>\n ) : (\n <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-5 w-5\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z\" />\n <circle cx=\"12\" cy=\"12\" r=\"3\" />\n </svg>\n )}\n </button>\n ) : rightSection ? (\n <span>{rightSection}</span>\n ) : null}\n </label>\n {validator && validatorHint && !showValidationHint && (\n <p className=\"validator-hint text-xs mt-1 opacity-70\">{validatorHint}</p>\n )}\n {showValidationHint && validator && !isValid && (\n <div className=\"absolute z-10 mt-1 bg-base-200 border border-error rounded shadow-lg text-error px-3 py-1\">\n {validationTooltip}\n </div>\n )}\n </div>\n );\n }\n\n // Default: inline label\n return (\n <div className={`relative w-full ${className}`} onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave}>\n <label className={`${baseClass} ${variantClass} ${sizeClass} ${validatorClass} ${validationStateClass} w-full flex items-center gap-2`}>\n {leftSection && <span>{leftSection}</span>}\n {label && <span>{label}</span>}\n <input\n {...fieldAttributes}\n ref={inputRef}\n type={actualType}\n placeholder={placeholder}\n value={value}\n onChange={handleInputChange}\n disabled={disabled}\n required={required}\n className=\"grow\"\n pattern={pattern}\n />\n {/* 显示最近输入的字符,仅针对密码字段 */}\n {type === 'password' && recentInput && (\n <span className=\"password-recent absolute right-10 font-mono\">\n {recentInput}\n </span>\n )}\n {/* 加入密码切换按钮或其他右侧元素 */}\n {type === 'password' ? (\n <span>{passwordToggle}</span>\n ) : rightSection ? (\n <span>{rightSection}</span>\n ) : null}\n </label>\n {validator && validatorHint && !showValidationHint && (\n <p className=\"validator-hint text-xs mt-1 opacity-70\">{validatorHint}</p>\n )}\n {showValidationHint && validator && !isValid && (\n <div className=\"absolute z-10 mt-1 bg-base-200 border border-error rounded shadow-lg text-error px-3 py-1\">\n {validationTooltip}\n </div>\n )}\n </div>\n );\n }\n\n // 如果没有label,则直接返回input\n return (\n <div className={`relative w-full ${className}`} onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave}>\n <input\n {...fieldAttributes}\n ref={inputRef}\n type={actualType}\n placeholder={placeholder}\n value={value}\n onChange={handleInputChange}\n disabled={disabled}\n required={required}\n className={`${baseClass} ${variantClass} ${sizeClass} ${validatorClass} ${validationStateClass} w-full`}\n pattern={pattern}\n />\n {validator && validatorHint && !showValidationHint && (\n <p className=\"validator-hint text-xs mt-1 opacity-70\">{validatorHint}</p>\n )}\n {showValidationHint && validator && !isValid && (\n <div className=\"absolute z-10 mt-1 bg-base-200 border border-error rounded shadow-lg text-error px-3 py-1\">\n {validationTooltip}\n </div>\n )}\n </div>\n );\n};\n\nexport default Input; "],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/Input/index.tsx"],"sourcesContent":["import React, { useState, useRef, useId } from 'react';\nimport './Input.css';\n\nexport type InputProps = Pick<React.InputHTMLAttributes<HTMLInputElement>, 'id' | 'name' | 'readOnly' | 'aria-label' | 'aria-labelledby' | 'aria-describedby' | 'aria-invalid'> & {\n placeholder?: string;\n value?: string;\n onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;\n type?: string;\n variant?: 'neutral' | 'primary' | 'secondary' | 'accent' | 'info' | 'success' | 'warning' | 'error' | 'ghost';\n size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';\n disabled?: boolean;\n required?: boolean;\n label?: string;\n labelPosition?: 'inline' | 'top';\n leftSection?: React.ReactNode;\n rightSection?: React.ReactNode;\n pattern?: string;\n className?: string;\n validator?: boolean;\n validatorHint?: string;\n validationRules?: {\n pattern: RegExp;\n message: string;\n }[];\n};\n\nconst Input = ({\n placeholder,\n value,\n onChange,\n type = 'text',\n variant,\n size = 'sm',\n disabled = false,\n required = false,\n label,\n labelPosition = 'inline',\n leftSection,\n rightSection,\n pattern,\n className = '',\n validator = false,\n validatorHint,\n validationRules = [],\n id,\n readOnly,\n ...inputAttributes\n}: InputProps) => {\n const generatedId = useId();\n const fieldId = id || generatedId;\n\n // 密码显示/隐藏状态\n const [showPassword, setShowPassword] = useState(false);\n // 表单验证状态\n const [isValid, setIsValid] = useState<boolean | null>(null);\n // 显示验证提示\n const [showValidationHint, setShowValidationHint] = useState(false);\n // 验证失败的规则消息\n const [failedRules, setFailedRules] = useState<string[]>([]);\n \n // 输入框引用,用于焦点和验证\n const inputRef = useRef<HTMLInputElement>(null);\n \n // 确定实际使用的输入类型\n const actualType = type === 'password' && showPassword ? 'text' : type;\n \n // 处理输入变化和验证\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const newValue = e.target.value;\n \n // 验证输入\n if (validator && inputRef.current) {\n validateInput(newValue);\n }\n \n // 调用原始的onChange处理函数\n if (onChange) {\n onChange(e);\n }\n };\n \n // 验证输入值\n const validateInput = (inputValue: string) => {\n if (!inputRef.current) return;\n \n // 使用HTML5自带的验证\n const isNativeValid = inputRef.current.checkValidity();\n \n // 检查自定义验证规则\n const failedMessages: string[] = [];\n \n if (validationRules.length > 0) {\n validationRules.forEach(rule => {\n if (!rule.pattern.test(inputValue)) {\n failedMessages.push(rule.message);\n }\n });\n }\n \n setFailedRules(failedMessages);\n setIsValid(isNativeValid && failedMessages.length === 0);\n };\n \n // 切换密码显示/隐藏\n const togglePasswordVisibility = () => {\n setShowPassword(!showPassword);\n };\n \n // 鼠标悬停事件处理\n const handleMouseEnter = () => {\n if (validator && !isValid) {\n setShowValidationHint(true);\n }\n };\n \n const handleMouseLeave = () => {\n setShowValidationHint(false);\n };\n \n // 验证状态相关的类名\n let validationStateClass = '';\n if (validator && isValid !== null) {\n validationStateClass = isValid ? 'input-success' : 'input-error';\n }\n \n const fieldAttributes = {\n ...inputAttributes,\n id: fieldId,\n readOnly,\n 'aria-invalid': inputAttributes['aria-invalid'] ?? (validator && isValid === false ? true : undefined),\n };\n const baseClass = 'input dishui-input';\n const variantClass = variant && !validationStateClass ? `input-${variant}` : '';\n const sizeClass = size ? `input-${size}` : '';\n const validatorClass = validator ? 'validator' : '';\n \n\n // 密码可见性切换按钮\n const passwordToggle = type === 'password' && (\n <button\n type=\"button\"\n disabled={disabled}\n aria-label={showPassword ? 'Hide password' : 'Show password'}\n aria-pressed={showPassword}\n className=\"cursor-pointer opacity-70 hover:opacity-100\"\n onClick={togglePasswordVisibility}\n >\n {showPassword ? (\n // 眼睛关闭图标\n <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-5 w-5\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94\" />\n <path d=\"M14.12 14.12a3 3 0 1 1-4.24-4.24\" />\n <path d=\"M1 1l22 22\" />\n <path d=\"M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19\" />\n </svg>\n ) : (\n // 眼睛打开图标\n <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-5 w-5\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z\" />\n <circle cx=\"12\" cy=\"12\" r=\"3\" />\n </svg>\n )}\n </button>\n );\n \n // 构建验证提示悬浮框\n const validationTooltip = (\n <div className=\"validation-tooltip\">\n {failedRules.length > 0 ? (\n <ul className=\"text-xs list-disc pl-4 py-1\">\n {failedRules.map((rule, index) => (\n <li key={index}>{rule}</li>\n ))}\n </ul>\n ) : validatorHint ? (\n <p className=\"text-xs py-1\">{validatorHint}</p>\n ) : null}\n </div>\n );\n\n // 如果有label,则使用label作为容器\n if (label || leftSection || rightSection || type === 'password') {\n // labelPosition === 'top': label above the input field\n if (label && labelPosition === 'top') {\n return (\n <div className={`relative w-full ${className}`} onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave}>\n <label htmlFor={fieldId} className=\"text-sm font-medium mb-1 block\">{label}</label>\n <label className={`${baseClass} ${variantClass} ${sizeClass} ${validatorClass} ${validationStateClass} w-full flex items-center gap-2`}>\n {leftSection && <span>{leftSection}</span>}\n <input\n {...fieldAttributes}\n ref={inputRef}\n type={actualType}\n placeholder={placeholder}\n value={value}\n onChange={handleInputChange}\n disabled={disabled}\n required={required}\n className=\"grow\"\n pattern={pattern}\n />\n {type === 'password' ? (\n <button type=\"button\" disabled={disabled} aria-label={showPassword ? 'Hide password' : 'Show password'} aria-pressed={showPassword} className=\"cursor-pointer opacity-70 hover:opacity-100\" onClick={togglePasswordVisibility}>\n {showPassword ? (\n <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-5 w-5\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94\" />\n <path d=\"M14.12 14.12a3 3 0 1 1-4.24-4.24\" />\n <path d=\"M1 1l22 22\" />\n <path d=\"M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19\" />\n </svg>\n ) : (\n <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-5 w-5\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z\" />\n <circle cx=\"12\" cy=\"12\" r=\"3\" />\n </svg>\n )}\n </button>\n ) : rightSection ? (\n <span>{rightSection}</span>\n ) : null}\n </label>\n {validator && validatorHint && !showValidationHint && (\n <p className=\"validator-hint text-xs mt-1 opacity-70\">{validatorHint}</p>\n )}\n {showValidationHint && validator && !isValid && (\n <div className=\"absolute z-10 mt-1 bg-base-200 border border-error rounded shadow-lg text-error px-3 py-1\">\n {validationTooltip}\n </div>\n )}\n </div>\n );\n }\n\n // Default: inline label\n return (\n <div className={`relative w-full ${className}`} onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave}>\n <label className={`${baseClass} ${variantClass} ${sizeClass} ${validatorClass} ${validationStateClass} w-full flex items-center gap-2`}>\n {leftSection && <span>{leftSection}</span>}\n {label && <span>{label}</span>}\n <input\n {...fieldAttributes}\n ref={inputRef}\n type={actualType}\n placeholder={placeholder}\n value={value}\n onChange={handleInputChange}\n disabled={disabled}\n required={required}\n className=\"grow\"\n pattern={pattern}\n />\n {/* 加入密码切换按钮或其他右侧元素 */}\n {type === 'password' ? (\n <span>{passwordToggle}</span>\n ) : rightSection ? (\n <span>{rightSection}</span>\n ) : null}\n </label>\n {validator && validatorHint && !showValidationHint && (\n <p className=\"validator-hint text-xs mt-1 opacity-70\">{validatorHint}</p>\n )}\n {showValidationHint && validator && !isValid && (\n <div className=\"absolute z-10 mt-1 bg-base-200 border border-error rounded shadow-lg text-error px-3 py-1\">\n {validationTooltip}\n </div>\n )}\n </div>\n );\n }\n\n // 如果没有label,则直接返回input\n return (\n <div className={`relative w-full ${className}`} onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave}>\n <input\n {...fieldAttributes}\n ref={inputRef}\n type={actualType}\n placeholder={placeholder}\n value={value}\n onChange={handleInputChange}\n disabled={disabled}\n required={required}\n className={`${baseClass} ${variantClass} ${sizeClass} ${validatorClass} ${validationStateClass} w-full`}\n pattern={pattern}\n />\n {validator && validatorHint && !showValidationHint && (\n <p className=\"validator-hint text-xs mt-1 opacity-70\">{validatorHint}</p>\n )}\n {showValidationHint && validator && !isValid && (\n <div className=\"absolute z-10 mt-1 bg-base-200 border border-error rounded shadow-lg text-error px-3 py-1\">\n {validationTooltip}\n </div>\n )}\n </div>\n );\n};\n\nexport default Input; "],"mappings":"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"}
|
|
@@ -26,6 +26,13 @@ export type AdminSuiteProps = LayoutSuiteBaseProps & {
|
|
|
26
26
|
header: LayoutSuiteHeaderProps;
|
|
27
27
|
left: LayoutSuiteSidebarProps;
|
|
28
28
|
};
|
|
29
|
+
/** 邮件工作台:文件夹、邮件列表、邮件正文三栏。 */
|
|
30
|
+
export type MailSuiteProps = LayoutSuiteBaseProps & {
|
|
31
|
+
left: LayoutSuiteSidebarProps;
|
|
32
|
+
/** 第二栏为 Page.Left,承载邮件列表;open 控制收起/展开,resizable 启用调宽。
|
|
33
|
+
* children / main.children 承载选中的邮件正文。 */
|
|
34
|
+
list: PageAsideProps;
|
|
35
|
+
};
|
|
29
36
|
export type WikiSuiteProps = LayoutSuiteBaseProps & {
|
|
30
37
|
left?: LayoutSuiteSidebarProps;
|
|
31
38
|
right?: LayoutSuiteSidebarProps;
|
|
@@ -40,6 +47,8 @@ export type BlankSuiteProps = LayoutSuiteBaseProps & {
|
|
|
40
47
|
};
|
|
41
48
|
/** 后台:必填页头和内置导航侧栏。Sidebar 需置于 TanStack Router 上下文中。 */
|
|
42
49
|
export declare const AdminSuite: (props: AdminSuiteProps) => React.JSX.Element;
|
|
50
|
+
/** 邮件:全宽三栏;省略 header 或设置 header.open=false 可隐藏页头。 */
|
|
51
|
+
export declare const MailSuite: ({ className, ...props }: MailSuiteProps) => React.JSX.Element;
|
|
43
52
|
/** 文档:可选双侧导航与浮窗。 */
|
|
44
53
|
export declare const WikiSuite: (props: WikiSuiteProps) => React.JSX.Element;
|
|
45
54
|
/** 博客:必填页头,可选页脚。 */
|
|
@@ -48,6 +57,7 @@ export declare const BlogSuite: (props: BlogSuiteProps) => React.JSX.Element;
|
|
|
48
57
|
export declare const BlankSuite: (props: BlankSuiteProps) => React.JSX.Element;
|
|
49
58
|
export declare const LayoutSuite: {
|
|
50
59
|
AdminSuite: typeof AdminSuite;
|
|
60
|
+
MailSuite: typeof MailSuite;
|
|
51
61
|
WikiSuite: typeof WikiSuite;
|
|
52
62
|
BlogSuite: typeof BlogSuite;
|
|
53
63
|
BlankSuite: typeof BlankSuite;
|
|
@@ -59,43 +59,52 @@ var s = ({ side: r, panel: o, resizable: s = !1, language: c = "zh", isCollapsed
|
|
|
59
59
|
onWidthChange: p || u.onToggle && (o?.resizable ?? s) ? T : void 0
|
|
60
60
|
})
|
|
61
61
|
});
|
|
62
|
-
}, c = ({ header: n, left: r,
|
|
63
|
-
fullHeight:
|
|
64
|
-
...
|
|
65
|
-
className: e("dishui-layout-suite",
|
|
62
|
+
}, c = ({ header: n, left: r, list: i, right: c, footer: l, float: u, body: d, main: f, fullHeight: p = !1, children: m, className: h, ...g }) => /* @__PURE__ */ o(t, {
|
|
63
|
+
fullHeight: p,
|
|
64
|
+
...g,
|
|
65
|
+
className: e("dishui-layout-suite", h),
|
|
66
66
|
children: [
|
|
67
67
|
n && /* @__PURE__ */ a(t.Header, { ...n }),
|
|
68
68
|
/* @__PURE__ */ o(t.Body, {
|
|
69
69
|
gap: 0,
|
|
70
|
-
scroll:
|
|
71
|
-
...
|
|
70
|
+
scroll: p,
|
|
71
|
+
...d,
|
|
72
72
|
children: [
|
|
73
73
|
r && /* @__PURE__ */ a(s, {
|
|
74
74
|
side: "left",
|
|
75
75
|
...r
|
|
76
76
|
}),
|
|
77
|
+
i && /* @__PURE__ */ a(t.Left, {
|
|
78
|
+
width: 320,
|
|
79
|
+
scroll: !0,
|
|
80
|
+
...i
|
|
81
|
+
}),
|
|
77
82
|
/* @__PURE__ */ a(t.Main, {
|
|
78
|
-
scroll:
|
|
79
|
-
...
|
|
80
|
-
children:
|
|
83
|
+
scroll: p,
|
|
84
|
+
...f,
|
|
85
|
+
children: m === void 0 ? f?.children : m
|
|
81
86
|
}),
|
|
82
|
-
|
|
87
|
+
c && /* @__PURE__ */ a(s, {
|
|
83
88
|
side: "right",
|
|
84
|
-
...
|
|
89
|
+
...c
|
|
85
90
|
})
|
|
86
91
|
]
|
|
87
92
|
}),
|
|
88
|
-
|
|
89
|
-
|
|
93
|
+
l && /* @__PURE__ */ a(t.Footer, { ...l }),
|
|
94
|
+
u && /* @__PURE__ */ a(t.Float, { ...u })
|
|
90
95
|
]
|
|
91
|
-
}), l = (e) => /* @__PURE__ */ a(c, { ...e }), u = (
|
|
96
|
+
}), l = (e) => /* @__PURE__ */ a(c, { ...e }), u = ({ className: t, ...n }) => /* @__PURE__ */ a(c, {
|
|
97
|
+
...n,
|
|
98
|
+
className: e("dishui-mail-suite", t)
|
|
99
|
+
}), d = (e) => /* @__PURE__ */ a(c, { ...e }), f = (e) => /* @__PURE__ */ a(c, { ...e }), p = (e) => /* @__PURE__ */ a(c, { ...e }), m = {
|
|
92
100
|
AdminSuite: l,
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
101
|
+
MailSuite: u,
|
|
102
|
+
WikiSuite: d,
|
|
103
|
+
BlogSuite: f,
|
|
104
|
+
BlankSuite: p,
|
|
96
105
|
DashboardSuite: r
|
|
97
106
|
};
|
|
98
107
|
//#endregion
|
|
99
|
-
export { l as AdminSuite,
|
|
108
|
+
export { l as AdminSuite, p as BlankSuite, f as BlogSuite, r as DashboardSuite, m as LayoutSuite, m as default, u as MailSuite, d as WikiSuite };
|
|
100
109
|
|
|
101
110
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/LayoutSuite/index.tsx"],"sourcesContent":["import React, { useState } from 'react';\nimport Page, {\n type PageProps,\n type PageBodyProps,\n type PageMainProps,\n type PageAsideProps,\n type PagePanelProps,\n type PageFooterProps,\n type PageFloatProps,\n} from '../Page';\nimport type { PageHeaderProps } from '../PageHeader';\nimport Sidebar from '../../layouts/Sidebar';\nimport { cn } from '../../utils/cn';\nimport './style.css';\nimport { DashboardSuite } from './DashboardSuite';\nexport { DashboardSuite } from './DashboardSuite';\nexport type { DashboardSuiteProps } from './DashboardSuite';\n\n/** Sidebar 保持原有 API;panel 仅配置外层 Page.Left / Page.Right。 */\nexport type LayoutSuiteSidebarProps = Omit<React.ComponentProps<typeof Sidebar>, 'language' | 'isCollapsed' | 'side'> & {\n language?: 'zh' | 'en';\n isCollapsed?: boolean;\n /** 独立启用区域边缘调宽,不要求 onToggle 或 onWidthChange。 */\n resizable?: boolean;\n panel?: Omit<PageAsideProps, 'children'>;\n};\n\nexport type LayoutSuiteHeaderProps = PageHeaderProps & PagePanelProps;\n\nexport type LayoutSuiteBaseProps = PageProps & {\n /** 可选三段式页头;Admin / Blog 仍要求配置 header。 */\n header?: LayoutSuiteHeaderProps;\n footer?: PageFooterProps;\n /** body 不接收 children;主内容支持顶层 children 或 main.children。 */\n body?: Omit<PageBodyProps, 'children'>;\n main?: PageMainProps;\n};\n\nexport type AdminSuiteProps = LayoutSuiteBaseProps & {\n header: LayoutSuiteHeaderProps;\n left: LayoutSuiteSidebarProps;\n};\n\nexport type WikiSuiteProps = LayoutSuiteBaseProps & {\n left?: LayoutSuiteSidebarProps;\n right?: LayoutSuiteSidebarProps;\n float?: PageFloatProps;\n};\n\nexport type BlogSuiteProps = LayoutSuiteBaseProps & {\n header: LayoutSuiteHeaderProps;\n footer?: PageFooterProps;\n};\n\nexport type BlankSuiteProps = LayoutSuiteBaseProps & {\n float?: PageFloatProps;\n};\n\nconst SidebarPanel = ({\n side,\n panel,\n resizable = false,\n language = 'zh',\n isCollapsed = false,\n ...sidebar\n}: LayoutSuiteSidebarProps & { side: 'left' | 'right' }) => {\n const { initialWidth = 280, collapsedWidth = 64, onWidthChange } = sidebar;\n const requestedMin = panel?.minWidth ?? sidebar.minWidth ?? 160;\n const requestedMax = panel?.maxWidth ?? sidebar.maxWidth ?? 400;\n const minWidth = Number.isFinite(requestedMin) ? Math.max(0, requestedMin) : 160;\n const maxWidth = Math.max(minWidth, Number.isFinite(requestedMax) ? requestedMax : 400);\n const panelWidth = panel?.style?.width ?? panel?.width;\n const sourceWidth = panelWidth ?? initialWidth;\n const clamp = (width: number) => Math.max(minWidth, Math.min(Number.isFinite(width) ? width : 280, maxWidth));\n const [widthState, setWidthState] = useState(() => ({\n initialWidth, sourceWidth, minWidth, maxWidth,\n width: typeof sourceWidth === 'number' ? clamp(sourceWidth) : sourceWidth,\n }));\n\n // 与 Sidebar 的配置同步规则一致;折叠不重置用户拖动后的展开宽度。\n const configChanged = !Object.is(widthState.initialWidth, initialWidth)\n || !Object.is(widthState.sourceWidth, sourceWidth)\n || !Object.is(widthState.minWidth, minWidth) || !Object.is(widthState.maxWidth, maxWidth);\n const expandedWidth = configChanged\n ? (typeof sourceWidth === 'number' ? clamp(sourceWidth) : sourceWidth)\n : widthState.width;\n if (configChanged) {\n setWidthState({ initialWidth, sourceWidth, minWidth, maxWidth, width: expandedWidth });\n }\n\n const handleWidthChange = (width: number) => {\n const next = clamp(width);\n setWidthState({ initialWidth, sourceWidth, minWidth, maxWidth, width: next });\n onWidthChange?.(next);\n };\n const handlePanelWidthChange = (width: number) => {\n handleWidthChange(width);\n if (panel?.onWidthChange !== onWidthChange) panel?.onWidthChange?.(clamp(width));\n };\n const sidebarWidth = typeof expandedWidth === 'number' ? expandedWidth : clamp(initialWidth);\n const Aside = side === 'left' ? Page.Left : Page.Right;\n return (\n <Aside\n bordered={false}\n scroll={false}\n {...panel}\n width={isCollapsed ? collapsedWidth : expandedWidth}\n style={panel?.style ? { ...panel.style, width: undefined } : undefined}\n minWidth={minWidth}\n maxWidth={maxWidth}\n resizable={!isCollapsed && (panel?.resizable ?? resizable)}\n resizeVariant={sidebar.onToggle ? 'line' : panel?.resizeVariant}\n onWidthChange={handlePanelWidthChange}\n className={cn('dishui-layout-suite-sidebar',\n !isCollapsed && typeof expandedWidth === 'string' && 'dishui-layout-suite-sidebar-css-width', panel?.className)}\n >\n <Sidebar {...sidebar} side={side} language={language} isCollapsed={isCollapsed}\n initialWidth={sidebarWidth} minWidth={minWidth} maxWidth={maxWidth}\n onWidthChange={onWidthChange || (sidebar.onToggle && (panel?.resizable ?? resizable)) ? handlePanelWidthChange : undefined} />\n </Aside>\n );\n};\n\ntype SuiteFrameProps = LayoutSuiteBaseProps & {\n header?: LayoutSuiteHeaderProps;\n left?: LayoutSuiteSidebarProps;\n right?: LayoutSuiteSidebarProps;\n footer?: PageFooterProps;\n float?: PageFloatProps;\n};\n\nconst SuiteFrame = ({\n header,\n left,\n right,\n footer,\n float,\n body,\n main,\n fullHeight = false,\n children,\n className,\n ...page\n}: SuiteFrameProps) => (\n <Page fullHeight={fullHeight} {...page} className={cn('dishui-layout-suite', className)}>\n {header && <Page.Header {...header} />}\n <Page.Body gap={0} scroll={fullHeight} {...body}>\n {left && <SidebarPanel side=\"left\" {...left} />}\n <Page.Main scroll={fullHeight} {...main}>{children !== undefined ? children : main?.children}</Page.Main>\n {right && <SidebarPanel side=\"right\" {...right} />}\n </Page.Body>\n {footer && <Page.Footer {...footer} />}\n {float && <Page.Float {...float} />}\n </Page>\n);\n\n/** 后台:必填页头和内置导航侧栏。Sidebar 需置于 TanStack Router 上下文中。 */\nexport const AdminSuite = (props: AdminSuiteProps) => <SuiteFrame {...props} />;\n\n/** 文档:可选双侧导航与浮窗。 */\nexport const WikiSuite = (props: WikiSuiteProps) => <SuiteFrame {...props} />;\n\n/** 博客:必填页头,可选页脚。 */\nexport const BlogSuite = (props: BlogSuiteProps) => <SuiteFrame {...props} />;\n\n/** 空白页:主内容与可选浮窗。 */\nexport const BlankSuite = (props: BlankSuiteProps) => <SuiteFrame {...props} />;\n\nexport const LayoutSuite = { AdminSuite, WikiSuite, BlogSuite, BlankSuite, DashboardSuite };\n\nexport default LayoutSuite;\n"],"mappings":";;;;;;;;
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/LayoutSuite/index.tsx"],"sourcesContent":["import React, { useState } from 'react';\nimport Page, {\n type PageProps,\n type PageBodyProps,\n type PageMainProps,\n type PageAsideProps,\n type PagePanelProps,\n type PageFooterProps,\n type PageFloatProps,\n} from '../Page';\nimport type { PageHeaderProps } from '../PageHeader';\nimport Sidebar from '../../layouts/Sidebar';\nimport { cn } from '../../utils/cn';\nimport './style.css';\nimport { DashboardSuite } from './DashboardSuite';\nexport { DashboardSuite } from './DashboardSuite';\nexport type { DashboardSuiteProps } from './DashboardSuite';\n\n/** Sidebar 保持原有 API;panel 仅配置外层 Page.Left / Page.Right。 */\nexport type LayoutSuiteSidebarProps = Omit<React.ComponentProps<typeof Sidebar>, 'language' | 'isCollapsed' | 'side'> & {\n language?: 'zh' | 'en';\n isCollapsed?: boolean;\n /** 独立启用区域边缘调宽,不要求 onToggle 或 onWidthChange。 */\n resizable?: boolean;\n panel?: Omit<PageAsideProps, 'children'>;\n};\n\nexport type LayoutSuiteHeaderProps = PageHeaderProps & PagePanelProps;\n\nexport type LayoutSuiteBaseProps = PageProps & {\n /** 可选三段式页头;Admin / Blog 仍要求配置 header。 */\n header?: LayoutSuiteHeaderProps;\n footer?: PageFooterProps;\n /** body 不接收 children;主内容支持顶层 children 或 main.children。 */\n body?: Omit<PageBodyProps, 'children'>;\n main?: PageMainProps;\n};\n\nexport type AdminSuiteProps = LayoutSuiteBaseProps & {\n header: LayoutSuiteHeaderProps;\n left: LayoutSuiteSidebarProps;\n};\n\n/** 邮件工作台:文件夹、邮件列表、邮件正文三栏。 */\nexport type MailSuiteProps = LayoutSuiteBaseProps & {\n left: LayoutSuiteSidebarProps;\n /** 第二栏为 Page.Left,承载邮件列表;open 控制收起/展开,resizable 启用调宽。\n * children / main.children 承载选中的邮件正文。 */\n list: PageAsideProps;\n};\n\nexport type WikiSuiteProps = LayoutSuiteBaseProps & {\n left?: LayoutSuiteSidebarProps;\n right?: LayoutSuiteSidebarProps;\n float?: PageFloatProps;\n};\n\nexport type BlogSuiteProps = LayoutSuiteBaseProps & {\n header: LayoutSuiteHeaderProps;\n footer?: PageFooterProps;\n};\n\nexport type BlankSuiteProps = LayoutSuiteBaseProps & {\n float?: PageFloatProps;\n};\n\nconst SidebarPanel = ({\n side,\n panel,\n resizable = false,\n language = 'zh',\n isCollapsed = false,\n ...sidebar\n}: LayoutSuiteSidebarProps & { side: 'left' | 'right' }) => {\n const { initialWidth = 280, collapsedWidth = 64, onWidthChange } = sidebar;\n const requestedMin = panel?.minWidth ?? sidebar.minWidth ?? 160;\n const requestedMax = panel?.maxWidth ?? sidebar.maxWidth ?? 400;\n const minWidth = Number.isFinite(requestedMin) ? Math.max(0, requestedMin) : 160;\n const maxWidth = Math.max(minWidth, Number.isFinite(requestedMax) ? requestedMax : 400);\n const panelWidth = panel?.style?.width ?? panel?.width;\n const sourceWidth = panelWidth ?? initialWidth;\n const clamp = (width: number) => Math.max(minWidth, Math.min(Number.isFinite(width) ? width : 280, maxWidth));\n const [widthState, setWidthState] = useState(() => ({\n initialWidth, sourceWidth, minWidth, maxWidth,\n width: typeof sourceWidth === 'number' ? clamp(sourceWidth) : sourceWidth,\n }));\n\n // 与 Sidebar 的配置同步规则一致;折叠不重置用户拖动后的展开宽度。\n const configChanged = !Object.is(widthState.initialWidth, initialWidth)\n || !Object.is(widthState.sourceWidth, sourceWidth)\n || !Object.is(widthState.minWidth, minWidth) || !Object.is(widthState.maxWidth, maxWidth);\n const expandedWidth = configChanged\n ? (typeof sourceWidth === 'number' ? clamp(sourceWidth) : sourceWidth)\n : widthState.width;\n if (configChanged) {\n setWidthState({ initialWidth, sourceWidth, minWidth, maxWidth, width: expandedWidth });\n }\n\n const handleWidthChange = (width: number) => {\n const next = clamp(width);\n setWidthState({ initialWidth, sourceWidth, minWidth, maxWidth, width: next });\n onWidthChange?.(next);\n };\n const handlePanelWidthChange = (width: number) => {\n handleWidthChange(width);\n if (panel?.onWidthChange !== onWidthChange) panel?.onWidthChange?.(clamp(width));\n };\n const sidebarWidth = typeof expandedWidth === 'number' ? expandedWidth : clamp(initialWidth);\n const Aside = side === 'left' ? Page.Left : Page.Right;\n return (\n <Aside\n bordered={false}\n scroll={false}\n {...panel}\n width={isCollapsed ? collapsedWidth : expandedWidth}\n style={panel?.style ? { ...panel.style, width: undefined } : undefined}\n minWidth={minWidth}\n maxWidth={maxWidth}\n resizable={!isCollapsed && (panel?.resizable ?? resizable)}\n resizeVariant={sidebar.onToggle ? 'line' : panel?.resizeVariant}\n onWidthChange={handlePanelWidthChange}\n className={cn('dishui-layout-suite-sidebar',\n !isCollapsed && typeof expandedWidth === 'string' && 'dishui-layout-suite-sidebar-css-width', panel?.className)}\n >\n <Sidebar {...sidebar} side={side} language={language} isCollapsed={isCollapsed}\n initialWidth={sidebarWidth} minWidth={minWidth} maxWidth={maxWidth}\n onWidthChange={onWidthChange || (sidebar.onToggle && (panel?.resizable ?? resizable)) ? handlePanelWidthChange : undefined} />\n </Aside>\n );\n};\n\ntype SuiteFrameProps = LayoutSuiteBaseProps & {\n header?: LayoutSuiteHeaderProps;\n left?: LayoutSuiteSidebarProps;\n list?: PageAsideProps;\n right?: LayoutSuiteSidebarProps;\n footer?: PageFooterProps;\n float?: PageFloatProps;\n};\n\nconst SuiteFrame = ({\n header,\n left,\n list,\n right,\n footer,\n float,\n body,\n main,\n fullHeight = false,\n children,\n className,\n ...page\n}: SuiteFrameProps) => (\n <Page fullHeight={fullHeight} {...page} className={cn('dishui-layout-suite', className)}>\n {header && <Page.Header {...header} />}\n <Page.Body gap={0} scroll={fullHeight} {...body}>\n {left && <SidebarPanel side=\"left\" {...left} />}\n {list && <Page.Left width={320} scroll {...list} />}\n <Page.Main scroll={fullHeight} {...main}>{children !== undefined ? children : main?.children}</Page.Main>\n {right && <SidebarPanel side=\"right\" {...right} />}\n </Page.Body>\n {footer && <Page.Footer {...footer} />}\n {float && <Page.Float {...float} />}\n </Page>\n);\n\n/** 后台:必填页头和内置导航侧栏。Sidebar 需置于 TanStack Router 上下文中。 */\nexport const AdminSuite = (props: AdminSuiteProps) => <SuiteFrame {...props} />;\n\n/** 邮件:全宽三栏;省略 header 或设置 header.open=false 可隐藏页头。 */\nexport const MailSuite = ({ className, ...props }: MailSuiteProps) => (\n <SuiteFrame {...props} className={cn('dishui-mail-suite', className)} />\n);\n\n/** 文档:可选双侧导航与浮窗。 */\nexport const WikiSuite = (props: WikiSuiteProps) => <SuiteFrame {...props} />;\n\n/** 博客:必填页头,可选页脚。 */\nexport const BlogSuite = (props: BlogSuiteProps) => <SuiteFrame {...props} />;\n\n/** 空白页:主内容与可选浮窗。 */\nexport const BlankSuite = (props: BlankSuiteProps) => <SuiteFrame {...props} />;\n\nexport const LayoutSuite = { AdminSuite, MailSuite, WikiSuite, BlogSuite, BlankSuite, DashboardSuite };\n\nexport default LayoutSuite;\n"],"mappings":"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"}
|
|
@@ -70,6 +70,7 @@ function s(s) {
|
|
|
70
70
|
let h = f || "", g = /language-(\w+)/.exec(h), _ = m.inline, v = g ? g[1] : "", y = m.dataMeta || m["data-meta"] || "", b = t(y, h);
|
|
71
71
|
if (!_ && v === "mermaid" && c) return /* @__PURE__ */ n("div", {
|
|
72
72
|
className: "mermaid-diagram my-4",
|
|
73
|
+
"data-mermaid-content": String(p).replace(/\n$/, ""),
|
|
73
74
|
children: String(p).replace(/\n$/, "")
|
|
74
75
|
});
|
|
75
76
|
if (!_ && v === "markmap" && l) return /* @__PURE__ */ n("div", {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"markdownComponents.js","names":[],"sources":["../../../src/components/Markdown/markdownComponents.tsx"],"sourcesContent":["import React from 'react';\nimport { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';\nimport { parseCodeBlockMeta } from './parseCodeBlockMeta';\nimport { resolveMetaTheme } from './codeThemes';\n\nfunction highlightMarkdown(text: string) {\n const lines = text.split('\\n');\n return lines.map((line, index) => {\n if (/^#{1,6}\\s/.test(line)) {\n const match = line.match(/^(#{1,6})(\\s+.*)$/);\n if (match) {\n return (\n <div key={index}>\n <span style={{ color: '#569cd6' }}>{match[1]}</span>\n <span style={{ color: '#dcdcaa' }}>{match[2]}</span>\n </div>\n );\n }\n }\n\n if (/^(\\s*)([-*+]|\\d+\\.)\\s/.test(line)) {\n const match = line.match(/^(\\s*)([-*+]|\\d+\\.)(\\s+.*)$/);\n if (match) {\n return (\n <div key={index}>\n <span>{match[1]}</span>\n <span style={{ color: '#c586c0' }}>{match[2]}</span>\n <span>{match[3]}</span>\n </div>\n );\n }\n }\n\n if (line.startsWith('```')) {\n return (\n <div key={index}>\n <span style={{ color: '#4ec9b0' }}>{line}</span>\n </div>\n );\n }\n\n if (/^>\\s/.test(line)) {\n return (\n <div key={index}>\n <span style={{ color: '#608b4e' }}>{line}</span>\n </div>\n );\n }\n\n const processInlineStyles = (text: string) => {\n const parts: React.ReactNode[] = [];\n let lastIndex = 0;\n const regex = /(\\*\\*[^*]+\\*\\*|\\*[^*]+\\*|`[^`]+`|\\[([^\\]]+)\\]\\(([^)]+)\\))/g;\n let match;\n\n while ((match = regex.exec(text)) !== null) {\n if (match.index > lastIndex) {\n parts.push(text.substring(lastIndex, match.index));\n }\n const matched = match[1];\n if (matched.startsWith('**')) {\n parts.push(<span key={match.index} style={{ color: '#ce9178', fontWeight: 'bold' }}>{matched}</span>);\n } else if (matched.startsWith('*')) {\n parts.push(<span key={match.index} style={{ color: '#ce9178', fontStyle: 'italic' }}>{matched}</span>);\n } else if (matched.startsWith('`')) {\n parts.push(<span key={match.index} style={{ color: '#d16969' }}>{matched}</span>);\n } else if (matched.startsWith('[')) {\n parts.push(<span key={match.index} style={{ color: '#4ec9b0' }}>{matched}</span>);\n }\n lastIndex = regex.lastIndex;\n }\n\n if (lastIndex < text.length) {\n parts.push(text.substring(lastIndex));\n }\n\n return parts.length > 0 ? parts : text;\n };\n\n return (\n <div key={index}>\n {processInlineStyles(line)}\n </div>\n );\n }).filter(Boolean);\n}\n\nconst MONO_FONT = 'ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, Consolas, \"Liberation Mono\", monospace';\n\ninterface CreateMarkdownComponentsOpts {\n enableMermaid: boolean;\n enableMarkmap: boolean;\n showLineNumbers: boolean;\n codeStyle: any;\n}\n\nexport function createMarkdownComponents(opts: CreateMarkdownComponentsOpts) {\n const { enableMermaid, enableMarkmap, showLineNumbers, codeStyle } = opts;\n\n return {\n code({ node, className, children, ...props }: any) {\n const fullClassName = className || '';\n const match = /language-(\\w+)/.exec(fullClassName);\n const inline = props.inline;\n const language = match ? match[1] : '';\n\n const metaString = (props as any).dataMeta ||\n (props as any)['data-meta'] || '';\n\n const codeMeta = parseCodeBlockMeta(metaString, fullClassName);\n\n if (!inline && language === 'mermaid' && enableMermaid) {\n return (\n <div className=\"mermaid-diagram my-4\">\n {String(children).replace(/\\n$/, '')}\n </div>\n );\n }\n\n if (!inline && language === 'markmap' && enableMarkmap) {\n return (\n <div\n className=\"markmap-diagram my-4 border border-base-300 rounded-lg overflow-hidden\"\n data-markmap-content={String(children).replace(/\\n$/, '')}\n />\n );\n }\n\n if (!inline && match && language === 'markdown') {\n const code = String(children).replace(/\\n$/, '');\n return (\n <pre\n style={{\n fontFamily: MONO_FONT,\n fontSize: '0.875em',\n borderRadius: '0.5rem',\n padding: '1em',\n margin: 0,\n backgroundColor: 'rgb(30, 30, 30)',\n color: 'rgb(212, 212, 212)',\n overflow: 'auto',\n lineHeight: '1.5',\n }}\n >\n <code style={{ fontFamily: MONO_FONT }}>\n {highlightMarkdown(code)}\n </code>\n </pre>\n );\n }\n\n if (!inline && match) {\n const selectedStyle = resolveMetaTheme(codeMeta.theme, codeStyle);\n\n let shouldShowLineNumbers: boolean | undefined;\n let lineNumbersToShow: number[] | undefined;\n\n if (Array.isArray(codeMeta.showLineNumbers)) {\n shouldShowLineNumbers = true;\n lineNumbersToShow = codeMeta.showLineNumbers;\n } else if (codeMeta.showLineNumbers !== undefined) {\n shouldShowLineNumbers = codeMeta.showLineNumbers as boolean;\n } else {\n shouldShowLineNumbers = showLineNumbers;\n }\n\n const startingLineNumber = codeMeta.startLineNumber || 1;\n const wrapLines = (codeMeta.highlightLines && codeMeta.highlightLines.length > 0) ||\n (lineNumbersToShow && lineNumbersToShow.length > 0);\n\n const codeBlock = (\n <SyntaxHighlighter\n style={selectedStyle as any}\n language={language}\n PreTag=\"div\"\n showLineNumbers={shouldShowLineNumbers}\n startingLineNumber={startingLineNumber}\n customStyle={{\n fontFamily: MONO_FONT,\n fontSize: '0.875em',\n borderRadius: codeMeta.title ? '0 0 0.5rem 0.5rem' : '0.5rem',\n borderTop: codeMeta.title ? 'none' : undefined,\n padding: '1em',\n margin: 0,\n border: 'none',\n boxShadow: 'none',\n lineHeight: '1.5',\n }}\n codeTagProps={{\n style: { fontFamily: MONO_FONT }\n }}\n lineNumberStyle={(lineNumber: number) => {\n const baseStyle: React.CSSProperties = {\n minWidth: '3em',\n paddingRight: '1em',\n userSelect: 'none',\n border: 'none',\n };\n if (lineNumbersToShow) {\n if (lineNumbersToShow.includes(lineNumber)) {\n baseStyle.opacity = 0.5;\n } else {\n baseStyle.opacity = 0;\n baseStyle.visibility = 'hidden';\n }\n } else {\n baseStyle.opacity = 0.5;\n }\n return baseStyle;\n }}\n wrapLines={wrapLines}\n lineProps={(lineNumber: number) => {\n const style: React.CSSProperties = {\n display: 'block',\n border: 'none',\n boxShadow: 'none',\n outline: 'none',\n margin: 0,\n padding: 0,\n };\n if (codeMeta.highlightLines && codeMeta.highlightLines.includes(lineNumber)) {\n style.backgroundColor = 'rgba(255, 255, 0, 0.1)';\n style.display = 'block';\n style.width = '100%';\n }\n return { style };\n }}\n {...props}\n >\n {String(children).replace(/\\n$/, '')}\n </SyntaxHighlighter>\n );\n\n if (codeMeta.title) {\n return (\n <div className=\"my-4\">\n <div\n className=\"px-4 py-2 text-sm font-mono text-base-content bg-base-200 rounded-t-lg border-b border-base-300\"\n style={{ fontFamily: MONO_FONT }}\n >\n {codeMeta.title}\n </div>\n {codeBlock}\n </div>\n );\n }\n\n return codeBlock;\n }\n\n return (\n <code className={className} {...props}>\n {children}\n </code>\n );\n },\n\n table({ node, children, ...props }: any) {\n return (\n <div className=\"overflow-x-auto my-6\">\n <table className=\"table-auto border-collapse w-full\" {...props}>\n {children}\n </table>\n </div>\n );\n },\n thead({ node, children, ...props }: any) {\n return <thead className=\"bg-base-200\" {...props}>{children}</thead>;\n },\n tbody({ node, children, ...props }: any) {\n return <tbody {...props}>{children}</tbody>;\n },\n tr({ node, children, ...props }: any) {\n return <tr className=\"border-b border-base-300 hover:bg-base-100 transition-colors\" {...props}>{children}</tr>;\n },\n th({ node, children, ...props }: any) {\n return <th className=\"px-4 py-3 text-left font-semibold text-base-content border-b-2 border-base-300\" {...props}>{children}</th>;\n },\n td({ node, children, ...props }: any) {\n return <td className=\"px-4 py-3 text-base-content\" {...props}>{children}</td>;\n },\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"markdownComponents.js","names":[],"sources":["../../../src/components/Markdown/markdownComponents.tsx"],"sourcesContent":["import React from 'react';\nimport { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';\nimport { parseCodeBlockMeta } from './parseCodeBlockMeta';\nimport { resolveMetaTheme } from './codeThemes';\n\nfunction highlightMarkdown(text: string) {\n const lines = text.split('\\n');\n return lines.map((line, index) => {\n if (/^#{1,6}\\s/.test(line)) {\n const match = line.match(/^(#{1,6})(\\s+.*)$/);\n if (match) {\n return (\n <div key={index}>\n <span style={{ color: '#569cd6' }}>{match[1]}</span>\n <span style={{ color: '#dcdcaa' }}>{match[2]}</span>\n </div>\n );\n }\n }\n\n if (/^(\\s*)([-*+]|\\d+\\.)\\s/.test(line)) {\n const match = line.match(/^(\\s*)([-*+]|\\d+\\.)(\\s+.*)$/);\n if (match) {\n return (\n <div key={index}>\n <span>{match[1]}</span>\n <span style={{ color: '#c586c0' }}>{match[2]}</span>\n <span>{match[3]}</span>\n </div>\n );\n }\n }\n\n if (line.startsWith('```')) {\n return (\n <div key={index}>\n <span style={{ color: '#4ec9b0' }}>{line}</span>\n </div>\n );\n }\n\n if (/^>\\s/.test(line)) {\n return (\n <div key={index}>\n <span style={{ color: '#608b4e' }}>{line}</span>\n </div>\n );\n }\n\n const processInlineStyles = (text: string) => {\n const parts: React.ReactNode[] = [];\n let lastIndex = 0;\n const regex = /(\\*\\*[^*]+\\*\\*|\\*[^*]+\\*|`[^`]+`|\\[([^\\]]+)\\]\\(([^)]+)\\))/g;\n let match;\n\n while ((match = regex.exec(text)) !== null) {\n if (match.index > lastIndex) {\n parts.push(text.substring(lastIndex, match.index));\n }\n const matched = match[1];\n if (matched.startsWith('**')) {\n parts.push(<span key={match.index} style={{ color: '#ce9178', fontWeight: 'bold' }}>{matched}</span>);\n } else if (matched.startsWith('*')) {\n parts.push(<span key={match.index} style={{ color: '#ce9178', fontStyle: 'italic' }}>{matched}</span>);\n } else if (matched.startsWith('`')) {\n parts.push(<span key={match.index} style={{ color: '#d16969' }}>{matched}</span>);\n } else if (matched.startsWith('[')) {\n parts.push(<span key={match.index} style={{ color: '#4ec9b0' }}>{matched}</span>);\n }\n lastIndex = regex.lastIndex;\n }\n\n if (lastIndex < text.length) {\n parts.push(text.substring(lastIndex));\n }\n\n return parts.length > 0 ? parts : text;\n };\n\n return (\n <div key={index}>\n {processInlineStyles(line)}\n </div>\n );\n }).filter(Boolean);\n}\n\nconst MONO_FONT = 'ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, Consolas, \"Liberation Mono\", monospace';\n\ninterface CreateMarkdownComponentsOpts {\n enableMermaid: boolean;\n enableMarkmap: boolean;\n showLineNumbers: boolean;\n codeStyle: any;\n}\n\nexport function createMarkdownComponents(opts: CreateMarkdownComponentsOpts) {\n const { enableMermaid, enableMarkmap, showLineNumbers, codeStyle } = opts;\n\n return {\n code({ node, className, children, ...props }: any) {\n const fullClassName = className || '';\n const match = /language-(\\w+)/.exec(fullClassName);\n const inline = props.inline;\n const language = match ? match[1] : '';\n\n const metaString = (props as any).dataMeta ||\n (props as any)['data-meta'] || '';\n\n const codeMeta = parseCodeBlockMeta(metaString, fullClassName);\n\n if (!inline && language === 'mermaid' && enableMermaid) {\n return (\n <div\n className=\"mermaid-diagram my-4\"\n data-mermaid-content={String(children).replace(/\\n$/, '')}\n >\n {String(children).replace(/\\n$/, '')}\n </div>\n );\n }\n\n if (!inline && language === 'markmap' && enableMarkmap) {\n return (\n <div\n className=\"markmap-diagram my-4 border border-base-300 rounded-lg overflow-hidden\"\n data-markmap-content={String(children).replace(/\\n$/, '')}\n />\n );\n }\n\n if (!inline && match && language === 'markdown') {\n const code = String(children).replace(/\\n$/, '');\n return (\n <pre\n style={{\n fontFamily: MONO_FONT,\n fontSize: '0.875em',\n borderRadius: '0.5rem',\n padding: '1em',\n margin: 0,\n backgroundColor: 'rgb(30, 30, 30)',\n color: 'rgb(212, 212, 212)',\n overflow: 'auto',\n lineHeight: '1.5',\n }}\n >\n <code style={{ fontFamily: MONO_FONT }}>\n {highlightMarkdown(code)}\n </code>\n </pre>\n );\n }\n\n if (!inline && match) {\n const selectedStyle = resolveMetaTheme(codeMeta.theme, codeStyle);\n\n let shouldShowLineNumbers: boolean | undefined;\n let lineNumbersToShow: number[] | undefined;\n\n if (Array.isArray(codeMeta.showLineNumbers)) {\n shouldShowLineNumbers = true;\n lineNumbersToShow = codeMeta.showLineNumbers;\n } else if (codeMeta.showLineNumbers !== undefined) {\n shouldShowLineNumbers = codeMeta.showLineNumbers as boolean;\n } else {\n shouldShowLineNumbers = showLineNumbers;\n }\n\n const startingLineNumber = codeMeta.startLineNumber || 1;\n const wrapLines = (codeMeta.highlightLines && codeMeta.highlightLines.length > 0) ||\n (lineNumbersToShow && lineNumbersToShow.length > 0);\n\n const codeBlock = (\n <SyntaxHighlighter\n style={selectedStyle as any}\n language={language}\n PreTag=\"div\"\n showLineNumbers={shouldShowLineNumbers}\n startingLineNumber={startingLineNumber}\n customStyle={{\n fontFamily: MONO_FONT,\n fontSize: '0.875em',\n borderRadius: codeMeta.title ? '0 0 0.5rem 0.5rem' : '0.5rem',\n borderTop: codeMeta.title ? 'none' : undefined,\n padding: '1em',\n margin: 0,\n border: 'none',\n boxShadow: 'none',\n lineHeight: '1.5',\n }}\n codeTagProps={{\n style: { fontFamily: MONO_FONT }\n }}\n lineNumberStyle={(lineNumber: number) => {\n const baseStyle: React.CSSProperties = {\n minWidth: '3em',\n paddingRight: '1em',\n userSelect: 'none',\n border: 'none',\n };\n if (lineNumbersToShow) {\n if (lineNumbersToShow.includes(lineNumber)) {\n baseStyle.opacity = 0.5;\n } else {\n baseStyle.opacity = 0;\n baseStyle.visibility = 'hidden';\n }\n } else {\n baseStyle.opacity = 0.5;\n }\n return baseStyle;\n }}\n wrapLines={wrapLines}\n lineProps={(lineNumber: number) => {\n const style: React.CSSProperties = {\n display: 'block',\n border: 'none',\n boxShadow: 'none',\n outline: 'none',\n margin: 0,\n padding: 0,\n };\n if (codeMeta.highlightLines && codeMeta.highlightLines.includes(lineNumber)) {\n style.backgroundColor = 'rgba(255, 255, 0, 0.1)';\n style.display = 'block';\n style.width = '100%';\n }\n return { style };\n }}\n {...props}\n >\n {String(children).replace(/\\n$/, '')}\n </SyntaxHighlighter>\n );\n\n if (codeMeta.title) {\n return (\n <div className=\"my-4\">\n <div\n className=\"px-4 py-2 text-sm font-mono text-base-content bg-base-200 rounded-t-lg border-b border-base-300\"\n style={{ fontFamily: MONO_FONT }}\n >\n {codeMeta.title}\n </div>\n {codeBlock}\n </div>\n );\n }\n\n return codeBlock;\n }\n\n return (\n <code className={className} {...props}>\n {children}\n </code>\n );\n },\n\n table({ node, children, ...props }: any) {\n return (\n <div className=\"overflow-x-auto my-6\">\n <table className=\"table-auto border-collapse w-full\" {...props}>\n {children}\n </table>\n </div>\n );\n },\n thead({ node, children, ...props }: any) {\n return <thead className=\"bg-base-200\" {...props}>{children}</thead>;\n },\n tbody({ node, children, ...props }: any) {\n return <tbody {...props}>{children}</tbody>;\n },\n tr({ node, children, ...props }: any) {\n return <tr className=\"border-b border-base-300 hover:bg-base-100 transition-colors\" {...props}>{children}</tr>;\n },\n th({ node, children, ...props }: any) {\n return <th className=\"px-4 py-3 text-left font-semibold text-base-content border-b-2 border-base-300\" {...props}>{children}</th>;\n },\n td({ node, children, ...props }: any) {\n return <td className=\"px-4 py-3 text-base-content\" {...props}>{children}</td>;\n },\n };\n}\n"],"mappings":"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"}
|