@turinhub/atomix-common-ui 0.4.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/README.md +20 -2
  2. package/dist/AuthPanel-CTKx618F.cjs +2 -0
  3. package/dist/AuthPanel-CTKx618F.cjs.map +1 -0
  4. package/dist/AuthPanel-Cn_WwmjX.js +703 -0
  5. package/dist/AuthPanel-Cn_WwmjX.js.map +1 -0
  6. package/dist/PDFSidebar-4DtXqqzN.cjs +2 -0
  7. package/dist/PDFSidebar-4DtXqqzN.cjs.map +1 -0
  8. package/dist/PDFSidebar-ClnrF4Br.js +239 -0
  9. package/dist/PDFSidebar-ClnrF4Br.js.map +1 -0
  10. package/dist/auth.cjs +2 -0
  11. package/dist/auth.cjs.map +1 -0
  12. package/dist/auth.d.ts +11 -0
  13. package/dist/auth.d.ts.map +1 -0
  14. package/dist/auth.js +9 -0
  15. package/dist/auth.js.map +1 -0
  16. package/dist/components/AuthLoginPanel.d.ts +55 -0
  17. package/dist/components/AuthLoginPanel.d.ts.map +1 -0
  18. package/dist/components/AuthPageShell.d.ts +11 -0
  19. package/dist/components/AuthPageShell.d.ts.map +1 -0
  20. package/dist/components/AuthPanel.d.ts +20 -0
  21. package/dist/components/AuthPanel.d.ts.map +1 -0
  22. package/dist/components/AuthRegisterPanel.d.ts +34 -0
  23. package/dist/components/AuthRegisterPanel.d.ts.map +1 -0
  24. package/dist/components/AuthVisualCarousel.d.ts +22 -0
  25. package/dist/components/AuthVisualCarousel.d.ts.map +1 -0
  26. package/dist/components/DataTable.d.ts +2 -2
  27. package/dist/components/DataTable.d.ts.map +1 -1
  28. package/dist/components/ImageReader.d.ts +44 -0
  29. package/dist/components/ImageReader.d.ts.map +1 -0
  30. package/dist/components/MarkdownReader.d.ts.map +1 -1
  31. package/dist/components/PDFReader.d.ts.map +1 -1
  32. package/dist/components/PDFSidebar.d.ts.map +1 -1
  33. package/dist/components/SimplePDFReader.d.ts.map +1 -1
  34. package/dist/components/TableHeader.d.ts.map +1 -1
  35. package/dist/components/TablePagination.d.ts +2 -1
  36. package/dist/components/TablePagination.d.ts.map +1 -1
  37. package/dist/components/VideoReader.d.ts +39 -0
  38. package/dist/components/VideoReader.d.ts.map +1 -0
  39. package/dist/components/media-utils.d.ts +9 -0
  40. package/dist/components/media-utils.d.ts.map +1 -0
  41. package/dist/components/ui/switch.d.ts +5 -0
  42. package/dist/components/ui/switch.d.ts.map +1 -0
  43. package/dist/data-table.cjs +1 -1
  44. package/dist/data-table.cjs.map +1 -1
  45. package/dist/data-table.js +83 -73
  46. package/dist/data-table.js.map +1 -1
  47. package/dist/file-upload.cjs +1 -1
  48. package/dist/file-upload.cjs.map +1 -1
  49. package/dist/file-upload.js +36 -36
  50. package/dist/file-upload.js.map +1 -1
  51. package/dist/image-reader.cjs +2 -0
  52. package/dist/image-reader.cjs.map +1 -0
  53. package/dist/image-reader.d.ts +3 -0
  54. package/dist/image-reader.d.ts.map +1 -0
  55. package/dist/image-reader.js +215 -0
  56. package/dist/image-reader.js.map +1 -0
  57. package/dist/index.cjs +1 -1
  58. package/dist/index.d.ts +10 -0
  59. package/dist/index.d.ts.map +1 -1
  60. package/dist/index.js +8 -2
  61. package/dist/index.js.map +1 -1
  62. package/dist/markdown-reader.cjs +1 -1
  63. package/dist/markdown-reader.cjs.map +1 -1
  64. package/dist/markdown-reader.js +28 -24
  65. package/dist/markdown-reader.js.map +1 -1
  66. package/dist/media-utils-5UPuocc1.js +23 -0
  67. package/dist/media-utils-5UPuocc1.js.map +1 -0
  68. package/dist/media-utils-X1dDYP9W.cjs +2 -0
  69. package/dist/media-utils-X1dDYP9W.cjs.map +1 -0
  70. package/dist/pdf-reader.cjs +1 -1
  71. package/dist/pdf-reader.cjs.map +1 -1
  72. package/dist/pdf-reader.js +170 -121
  73. package/dist/pdf-reader.js.map +1 -1
  74. package/dist/pdf-sidebar.cjs +1 -1
  75. package/dist/pdf-sidebar.js +1 -1
  76. package/dist/simple-pdf-reader.cjs +1 -1
  77. package/dist/simple-pdf-reader.cjs.map +1 -1
  78. package/dist/simple-pdf-reader.js +138 -105
  79. package/dist/simple-pdf-reader.js.map +1 -1
  80. package/dist/table-header.cjs +1 -1
  81. package/dist/table-header.cjs.map +1 -1
  82. package/dist/table-header.js +42 -34
  83. package/dist/table-header.js.map +1 -1
  84. package/dist/table-pagination.cjs +1 -1
  85. package/dist/table-pagination.cjs.map +1 -1
  86. package/dist/table-pagination.js +49 -43
  87. package/dist/table-pagination.js.map +1 -1
  88. package/dist/types/component-types.d.ts +2 -0
  89. package/dist/types/component-types.d.ts.map +1 -1
  90. package/dist/video-reader.cjs +2 -0
  91. package/dist/video-reader.cjs.map +1 -0
  92. package/dist/video-reader.d.ts +3 -0
  93. package/dist/video-reader.d.ts.map +1 -0
  94. package/dist/video-reader.js +158 -0
  95. package/dist/video-reader.js.map +1 -0
  96. package/package.json +32 -1
  97. package/dist/PDFSidebar-BBtucLK6.js +0 -232
  98. package/dist/PDFSidebar-BBtucLK6.js.map +0 -1
  99. package/dist/PDFSidebar-Di0D-yPS.cjs +0 -2
  100. package/dist/PDFSidebar-Di0D-yPS.cjs.map +0 -1
  101. package/dist/index-BiA_tnaq.cjs +0 -13
  102. package/dist/index-BiA_tnaq.cjs.map +0 -1
  103. package/dist/index-BypbGNpR.js +0 -18821
  104. package/dist/index-BypbGNpR.js.map +0 -1
@@ -0,0 +1,215 @@
1
+ import { j as e } from "./jsx-runtime-B4hRZ52C.js";
2
+ import { ZoomOut as de, ZoomIn as ue, RotateCcw as xe, RotateCw as fe, ExternalLink as pe } from "lucide-react";
3
+ import { useState as m, useCallback as F, useMemo as ge, useEffect as je } from "react";
4
+ import { c as I } from "./utils-B6yFEsav.js";
5
+ import { i as he, g as be } from "./media-utils-5UPuocc1.js";
6
+ const ve = [
7
+ "jpg",
8
+ "jpeg",
9
+ "png",
10
+ "gif",
11
+ "webp",
12
+ "svg",
13
+ "bmp",
14
+ "avif",
15
+ "ico"
16
+ ], we = [
17
+ "image/jpeg",
18
+ "image/png",
19
+ "image/gif",
20
+ "image/webp",
21
+ "image/svg+xml",
22
+ "image/bmp",
23
+ "image/avif",
24
+ "image/x-icon",
25
+ "image/vnd.microsoft.icon"
26
+ ], Ne = (s) => s ? s instanceof Error ? s : new Error(s) : null, Ee = (s, d, a) => Math.min(Math.max(s, d), a);
27
+ function Oe({
28
+ src: s,
29
+ alt: d = "",
30
+ fileName: a,
31
+ mimeType: u,
32
+ components: G,
33
+ loading: S = !1,
34
+ error: Z,
35
+ className: M,
36
+ containerClassName: $,
37
+ imageClassName: T,
38
+ toolbarClassName: X,
39
+ loadingText: Y = "正在加载图片...",
40
+ errorText: y = "图片加载失败",
41
+ unsupportedText: q = "暂不支持该图片格式",
42
+ showToolbar: H = !0,
43
+ showOpenInNewTab: J = !0,
44
+ objectFit: K = "contain",
45
+ initialScale: Q = 1,
46
+ minScale: x = 0.25,
47
+ maxScale: f = 4,
48
+ scaleStep: _ = 0.25,
49
+ scale: p,
50
+ onScaleChange: l,
51
+ rotation: g,
52
+ onRotationChange: c,
53
+ allowUnsupportedFormat: V = !1,
54
+ supportedExtensions: W = ve,
55
+ supportedMimeTypes: C = we,
56
+ onLoad: j,
57
+ onError: h,
58
+ style: ee,
59
+ ...te
60
+ }) {
61
+ const { Card: k, CardContent: O, Button: P, Skeleton: b } = G || {}, [se, ne] = m(Q), [re, ie] = m(0), [ae, v] = m(!0), [oe, w] = m(null), i = p ?? se, N = g ?? re, r = Ne(Z) || oe, z = V || he({
62
+ src: s,
63
+ fileName: a,
64
+ mimeType: u,
65
+ supportedExtensions: W,
66
+ supportedMimeTypes: C
67
+ }), L = S || ae && !r, R = F(
68
+ (t) => {
69
+ const n = Ee(t, x, f);
70
+ p === void 0 && ne(n), l == null || l(n);
71
+ },
72
+ [p, f, x, l]
73
+ ), U = F(
74
+ (t) => {
75
+ const n = (t % 360 + 360) % 360;
76
+ g === void 0 && ie(n), c == null || c(n);
77
+ },
78
+ [g, c]
79
+ ), le = ge(() => {
80
+ const t = be(s, a);
81
+ return t ? t.toUpperCase() : u || "图片";
82
+ }, [a, u, s]);
83
+ je(() => {
84
+ v(!0), w(null);
85
+ }, [s]);
86
+ const o = (t, n, B, D) => {
87
+ const me = "inline-flex h-8 w-8 items-center justify-center rounded-md border border-input bg-background text-foreground shadow-sm transition-colors hover:bg-accent hover:text-accent-foreground disabled:pointer-events-none disabled:opacity-50";
88
+ return P ? /* @__PURE__ */ e.jsx(
89
+ P,
90
+ {
91
+ "aria-label": t,
92
+ className: "h-8 w-8",
93
+ disabled: D,
94
+ onClick: B,
95
+ size: "icon",
96
+ title: t,
97
+ type: "button",
98
+ variant: "outline",
99
+ children: n
100
+ }
101
+ ) : /* @__PURE__ */ e.jsx(
102
+ "button",
103
+ {
104
+ "aria-label": t,
105
+ className: me,
106
+ disabled: D,
107
+ onClick: B,
108
+ title: t,
109
+ type: "button",
110
+ children: n
111
+ }
112
+ );
113
+ }, ce = () => /* @__PURE__ */ e.jsx("div", { className: "w-full space-y-3 p-4", role: "status", "aria-live": "polite", children: b ? /* @__PURE__ */ e.jsxs(e.Fragment, { children: [
114
+ /* @__PURE__ */ e.jsx(b, { className: "h-4 w-32" }),
115
+ /* @__PURE__ */ e.jsx(b, { className: "h-80 w-full" })
116
+ ] }) : /* @__PURE__ */ e.jsx("p", { className: "text-sm text-muted-foreground", children: Y }) }), A = (t) => /* @__PURE__ */ e.jsxs("div", { className: "p-4 text-center text-sm text-destructive", role: "alert", children: [
117
+ /* @__PURE__ */ e.jsx("p", { className: "font-medium", children: t || y }),
118
+ r != null && r.message ? /* @__PURE__ */ e.jsx("p", { className: "mt-1 opacity-80", children: r.message }) : null
119
+ ] }), E = /* @__PURE__ */ e.jsxs(
120
+ "div",
121
+ {
122
+ className: I(
123
+ "flex h-full min-h-[360px] flex-col overflow-hidden rounded-md border bg-background",
124
+ $
125
+ ),
126
+ children: [
127
+ H ? /* @__PURE__ */ e.jsxs(
128
+ "div",
129
+ {
130
+ className: I(
131
+ "flex flex-wrap items-center justify-between gap-2 border-b px-3 py-2",
132
+ X
133
+ ),
134
+ children: [
135
+ /* @__PURE__ */ e.jsx("span", { className: "text-xs font-medium text-muted-foreground", children: le }),
136
+ /* @__PURE__ */ e.jsxs("div", { className: "flex items-center gap-1", children: [
137
+ o(
138
+ "缩小",
139
+ /* @__PURE__ */ e.jsx(de, { className: "h-4 w-4" }),
140
+ () => R(i - _),
141
+ i <= x
142
+ ),
143
+ /* @__PURE__ */ e.jsxs("span", { className: "min-w-14 text-center text-xs text-muted-foreground", children: [
144
+ Math.round(i * 100),
145
+ "%"
146
+ ] }),
147
+ o(
148
+ "放大",
149
+ /* @__PURE__ */ e.jsx(ue, { className: "h-4 w-4" }),
150
+ () => R(i + _),
151
+ i >= f
152
+ ),
153
+ o(
154
+ "向左旋转",
155
+ /* @__PURE__ */ e.jsx(xe, { className: "h-4 w-4" }),
156
+ () => U(N - 90)
157
+ ),
158
+ o(
159
+ "向右旋转",
160
+ /* @__PURE__ */ e.jsx(fe, { className: "h-4 w-4" }),
161
+ () => U(N + 90)
162
+ ),
163
+ J ? o(
164
+ "新窗口打开",
165
+ /* @__PURE__ */ e.jsx(pe, { className: "h-4 w-4" }),
166
+ () => window.open(s, "_blank", "noreferrer")
167
+ ) : null
168
+ ] })
169
+ ]
170
+ }
171
+ ) : null,
172
+ /* @__PURE__ */ e.jsxs("div", { className: "relative flex min-h-0 flex-1 items-center justify-center overflow-auto bg-muted/20 p-4", children: [
173
+ z ? r ? A() : null : A(q),
174
+ z && !r ? /* @__PURE__ */ e.jsxs(e.Fragment, { children: [
175
+ L ? ce() : null,
176
+ /* @__PURE__ */ e.jsx(
177
+ "img",
178
+ {
179
+ ...te,
180
+ alt: d,
181
+ className: I(
182
+ "max-h-full max-w-full transition-transform",
183
+ L ? "invisible absolute" : "visible",
184
+ T
185
+ ),
186
+ onError: () => {
187
+ const t = new Error(y);
188
+ v(!1), w(t), h == null || h(t);
189
+ },
190
+ onLoad: () => {
191
+ v(!1), w(null), j == null || j();
192
+ },
193
+ src: s,
194
+ decoding: "async",
195
+ style: {
196
+ objectFit: K,
197
+ transform: `scale(${i}) rotate(${N}deg)`,
198
+ transformOrigin: "center center",
199
+ ...ee
200
+ }
201
+ }
202
+ )
203
+ ] }) : null
204
+ ] })
205
+ ]
206
+ }
207
+ );
208
+ return k ? /* @__PURE__ */ e.jsx(k, { className: M, children: O ? /* @__PURE__ */ e.jsx(O, { children: E }) : E }) : /* @__PURE__ */ e.jsx("div", { className: M, children: E });
209
+ }
210
+ export {
211
+ Oe as ImageReader,
212
+ ve as SUPPORTED_IMAGE_EXTENSIONS,
213
+ we as SUPPORTED_IMAGE_MIME_TYPES
214
+ };
215
+ //# sourceMappingURL=image-reader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-reader.js","sources":["../src/components/ImageReader.tsx"],"sourcesContent":["import {\n ExternalLink as ExternalLinkIcon,\n RotateCcw as RotateCcwIcon,\n RotateCw as RotateCwIcon,\n ZoomIn as ZoomInIcon,\n ZoomOut as ZoomOutIcon,\n} from 'lucide-react';\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport type { HTMLAttributes, ImgHTMLAttributes, ReactNode } from 'react';\n\nimport { cn } from '../lib/utils';\nimport type {\n ButtonComponent,\n CardComponent,\n SkeletonComponent,\n UIComponent,\n} from '../types/component-types';\n\nimport { getMediaExtension, isSupportedMediaSource } from './media-utils';\n\nexport const SUPPORTED_IMAGE_EXTENSIONS = [\n 'jpg',\n 'jpeg',\n 'png',\n 'gif',\n 'webp',\n 'svg',\n 'bmp',\n 'avif',\n 'ico',\n] as const;\n\nexport const SUPPORTED_IMAGE_MIME_TYPES = [\n 'image/jpeg',\n 'image/png',\n 'image/gif',\n 'image/webp',\n 'image/svg+xml',\n 'image/bmp',\n 'image/avif',\n 'image/x-icon',\n 'image/vnd.microsoft.icon',\n] as const;\n\nexport interface ImageReaderUIComponents {\n Card?: CardComponent;\n CardContent?: UIComponent<HTMLAttributes<HTMLDivElement>>;\n Button?: ButtonComponent;\n Skeleton?: SkeletonComponent;\n}\n\nexport interface ImageReaderProps extends Omit<\n ImgHTMLAttributes<HTMLImageElement>,\n 'alt' | 'children' | 'className' | 'loading' | 'onError' | 'onLoad' | 'src'\n> {\n src: string;\n alt?: string;\n fileName?: string;\n mimeType?: string;\n components?: ImageReaderUIComponents;\n loading?: boolean;\n error?: Error | string | null;\n className?: string;\n containerClassName?: string;\n imageClassName?: string;\n toolbarClassName?: string;\n loadingText?: string;\n errorText?: string;\n unsupportedText?: string;\n showToolbar?: boolean;\n showOpenInNewTab?: boolean;\n objectFit?: 'contain' | 'cover' | 'fill' | 'none' | 'scale-down';\n initialScale?: number;\n minScale?: number;\n maxScale?: number;\n scaleStep?: number;\n scale?: number;\n onScaleChange?: (scale: number) => void;\n rotation?: number;\n onRotationChange?: (rotation: number) => void;\n allowUnsupportedFormat?: boolean;\n supportedExtensions?: readonly string[];\n supportedMimeTypes?: readonly string[];\n onLoad?: () => void;\n onError?: (error: Error) => void;\n}\n\nconst normalizeError = (error: Error | string | null | undefined) => {\n if (!error) return null;\n return error instanceof Error ? error : new Error(error);\n};\n\nconst clamp = (value: number, min: number, max: number) =>\n Math.min(Math.max(value, min), max);\n\nexport function ImageReader({\n src,\n alt = '',\n fileName,\n mimeType,\n components,\n loading = false,\n error,\n className,\n containerClassName,\n imageClassName,\n toolbarClassName,\n loadingText = '正在加载图片...',\n errorText = '图片加载失败',\n unsupportedText = '暂不支持该图片格式',\n showToolbar = true,\n showOpenInNewTab = true,\n objectFit = 'contain',\n initialScale = 1,\n minScale = 0.25,\n maxScale = 4,\n scaleStep = 0.25,\n scale: controlledScale,\n onScaleChange,\n rotation: controlledRotation,\n onRotationChange,\n allowUnsupportedFormat = false,\n supportedExtensions = SUPPORTED_IMAGE_EXTENSIONS,\n supportedMimeTypes = SUPPORTED_IMAGE_MIME_TYPES,\n onLoad,\n onError,\n style,\n ...imageProps\n}: ImageReaderProps) {\n const { Card, CardContent, Button, Skeleton } = components || {};\n const [internalScale, setInternalScale] = useState(initialScale);\n const [internalRotation, setInternalRotation] = useState(0);\n const [isImageLoading, setIsImageLoading] = useState(true);\n const [imageError, setImageError] = useState<Error | null>(null);\n\n const scale = controlledScale ?? internalScale;\n const rotation = controlledRotation ?? internalRotation;\n const displayedError = normalizeError(error) || imageError;\n const isSupported =\n allowUnsupportedFormat ||\n isSupportedMediaSource({\n src,\n fileName,\n mimeType,\n supportedExtensions,\n supportedMimeTypes,\n });\n const isLoading = loading || (isImageLoading && !displayedError);\n\n const setNextScale = useCallback(\n (nextScale: number) => {\n const clampedScale = clamp(nextScale, minScale, maxScale);\n if (controlledScale === undefined) {\n setInternalScale(clampedScale);\n }\n onScaleChange?.(clampedScale);\n },\n [controlledScale, maxScale, minScale, onScaleChange]\n );\n\n const setNextRotation = useCallback(\n (nextRotation: number) => {\n const normalizedRotation = ((nextRotation % 360) + 360) % 360;\n if (controlledRotation === undefined) {\n setInternalRotation(normalizedRotation);\n }\n onRotationChange?.(normalizedRotation);\n },\n [controlledRotation, onRotationChange]\n );\n\n const formatLabel = useMemo(() => {\n const extension = getMediaExtension(src, fileName);\n return extension ? extension.toUpperCase() : mimeType || '图片';\n }, [fileName, mimeType, src]);\n\n useEffect(() => {\n setIsImageLoading(true);\n setImageError(null);\n }, [src]);\n\n const renderButton = (\n label: string,\n icon: ReactNode,\n onClick: () => void,\n disabled?: boolean\n ) => {\n const buttonClassName =\n 'inline-flex h-8 w-8 items-center justify-center rounded-md border border-input bg-background text-foreground shadow-sm transition-colors hover:bg-accent hover:text-accent-foreground disabled:pointer-events-none disabled:opacity-50';\n\n if (Button) {\n return (\n <Button\n aria-label={label}\n className=\"h-8 w-8\"\n disabled={disabled}\n onClick={onClick}\n size=\"icon\"\n title={label}\n type=\"button\"\n variant=\"outline\"\n >\n {icon}\n </Button>\n );\n }\n\n return (\n <button\n aria-label={label}\n className={buttonClassName}\n disabled={disabled}\n onClick={onClick}\n title={label}\n type=\"button\"\n >\n {icon}\n </button>\n );\n };\n\n const renderLoading = () => (\n <div className=\"w-full space-y-3 p-4\" role=\"status\" aria-live=\"polite\">\n {Skeleton ? (\n <>\n <Skeleton className=\"h-4 w-32\" />\n <Skeleton className=\"h-80 w-full\" />\n </>\n ) : (\n <p className=\"text-sm text-muted-foreground\">{loadingText}</p>\n )}\n </div>\n );\n\n const renderError = (message?: string) => (\n <div className=\"p-4 text-center text-sm text-destructive\" role=\"alert\">\n <p className=\"font-medium\">{message || errorText}</p>\n {displayedError?.message ? (\n <p className=\"mt-1 opacity-80\">{displayedError.message}</p>\n ) : null}\n </div>\n );\n\n const body = (\n <div\n className={cn(\n 'flex h-full min-h-[360px] flex-col overflow-hidden rounded-md border bg-background',\n containerClassName\n )}\n >\n {showToolbar ? (\n <div\n className={cn(\n 'flex flex-wrap items-center justify-between gap-2 border-b px-3 py-2',\n toolbarClassName\n )}\n >\n <span className=\"text-xs font-medium text-muted-foreground\">\n {formatLabel}\n </span>\n <div className=\"flex items-center gap-1\">\n {renderButton(\n '缩小',\n <ZoomOutIcon className=\"h-4 w-4\" />,\n () => setNextScale(scale - scaleStep),\n scale <= minScale\n )}\n <span className=\"min-w-14 text-center text-xs text-muted-foreground\">\n {Math.round(scale * 100)}%\n </span>\n {renderButton(\n '放大',\n <ZoomInIcon className=\"h-4 w-4\" />,\n () => setNextScale(scale + scaleStep),\n scale >= maxScale\n )}\n {renderButton(\n '向左旋转',\n <RotateCcwIcon className=\"h-4 w-4\" />,\n () => setNextRotation(rotation - 90)\n )}\n {renderButton(\n '向右旋转',\n <RotateCwIcon className=\"h-4 w-4\" />,\n () => setNextRotation(rotation + 90)\n )}\n {showOpenInNewTab\n ? renderButton(\n '新窗口打开',\n <ExternalLinkIcon className=\"h-4 w-4\" />,\n () => window.open(src, '_blank', 'noreferrer')\n )\n : null}\n </div>\n </div>\n ) : null}\n <div className=\"relative flex min-h-0 flex-1 items-center justify-center overflow-auto bg-muted/20 p-4\">\n {!isSupported\n ? renderError(unsupportedText)\n : displayedError\n ? renderError()\n : null}\n {isSupported && !displayedError ? (\n <>\n {isLoading ? renderLoading() : null}\n <img\n {...imageProps}\n alt={alt}\n className={cn(\n 'max-h-full max-w-full transition-transform',\n isLoading ? 'invisible absolute' : 'visible',\n imageClassName\n )}\n onError={() => {\n const nextError = new Error(errorText);\n setIsImageLoading(false);\n setImageError(nextError);\n onError?.(nextError);\n }}\n onLoad={() => {\n setIsImageLoading(false);\n setImageError(null);\n onLoad?.();\n }}\n src={src}\n decoding=\"async\"\n style={{\n objectFit,\n transform: `scale(${scale}) rotate(${rotation}deg)`,\n transformOrigin: 'center center',\n ...style,\n }}\n />\n </>\n ) : null}\n </div>\n </div>\n );\n\n if (Card) {\n return (\n <Card className={className}>\n {CardContent ? <CardContent>{body}</CardContent> : body}\n </Card>\n );\n }\n\n return <div className={className}>{body}</div>;\n}\n"],"names":["SUPPORTED_IMAGE_EXTENSIONS","SUPPORTED_IMAGE_MIME_TYPES","normalizeError","error","clamp","value","min","max","ImageReader","src","alt","fileName","mimeType","components","loading","className","containerClassName","imageClassName","toolbarClassName","loadingText","errorText","unsupportedText","showToolbar","showOpenInNewTab","objectFit","initialScale","minScale","maxScale","scaleStep","controlledScale","onScaleChange","controlledRotation","onRotationChange","allowUnsupportedFormat","supportedExtensions","supportedMimeTypes","onLoad","onError","style","imageProps","Card","CardContent","Button","Skeleton","internalScale","setInternalScale","useState","internalRotation","setInternalRotation","isImageLoading","setIsImageLoading","imageError","setImageError","scale","rotation","displayedError","isSupported","isSupportedMediaSource","isLoading","setNextScale","useCallback","nextScale","clampedScale","setNextRotation","nextRotation","normalizedRotation","formatLabel","useMemo","extension","getMediaExtension","useEffect","renderButton","label","icon","onClick","disabled","buttonClassName","jsx","renderLoading","jsxs","Fragment","renderError","message","body","cn","ZoomOutIcon","ZoomInIcon","RotateCcwIcon","RotateCwIcon","ExternalLinkIcon","nextError"],"mappings":"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"}
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./utils-IjLH3w2e.cjs");exports.cn=e.cn;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("./utils-IjLH3w2e.cjs"),e=require("./AuthPanel-CTKx618F.cjs");exports.cn=t.cn;exports.AuthLoginPanel=e.AuthLoginPanel;exports.AuthPageShell=e.AuthPageShell;exports.AuthPanel=e.AuthPanel;exports.AuthRegisterPanel=e.AuthRegisterPanel;exports.AuthVisualCarousel=e.AuthVisualCarousel;
2
2
  //# sourceMappingURL=index.cjs.map
package/dist/index.d.ts CHANGED
@@ -1,3 +1,13 @@
1
1
  export { cn } from './lib/utils';
2
+ export { AuthLoginPanel } from './components/AuthLoginPanel';
3
+ export type { AuthLoginMethod, AuthLoginPanelProps, AuthPasswordLoginPayload, AuthSmsCodeResult, AuthSmsLoginPayload, AuthSocialProvider, AuthUIComponents, AuthValidationResult, } from './components/AuthLoginPanel';
4
+ export { AuthRegisterPanel } from './components/AuthRegisterPanel';
5
+ export type { AuthRegisterPanelProps, AuthRegisterPayload, } from './components/AuthRegisterPanel';
6
+ export { AuthPageShell } from './components/AuthPageShell';
7
+ export type { AuthPageShellProps } from './components/AuthPageShell';
8
+ export { AuthVisualCarousel } from './components/AuthVisualCarousel';
9
+ export type { AuthVisualCarouselItem, AuthVisualCarouselProps, } from './components/AuthVisualCarousel';
10
+ export { AuthPanel } from './components/AuthPanel';
11
+ export type { AuthPanelMode, AuthPanelProps } from './components/AuthPanel';
2
12
  export type { UIComponent, ButtonComponent, InputComponent, CardComponent, TableComponent, TableRowComponent, TableCellComponent, SelectComponent, SelectTriggerComponent, SelectContentComponent, SelectItemComponent, SelectValueComponent, DialogComponent, DialogContentComponent, DialogHeaderComponent, DialogFooterComponent, DialogTitleComponent, DialogDescriptionComponent, LabelComponent, DropdownMenuComponent, DropdownMenuTriggerComponent, DropdownMenuContentComponent, DropdownMenuRadioGroupComponent, DropdownMenuRadioItemComponent, SkeletonComponent, TabsComponent, TabsListComponent, TabsTriggerComponent, TabsContentComponent, ScrollAreaComponent, } from './types/component-types';
3
13
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AAGjC,YAAY,EACV,WAAW,EACX,eAAe,EACf,cAAc,EACd,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EACf,sBAAsB,EACtB,sBAAsB,EACtB,mBAAmB,EACnB,oBAAoB,EACpB,eAAe,EACf,sBAAsB,EACtB,qBAAqB,EACrB,qBAAqB,EACrB,oBAAoB,EACpB,0BAA0B,EAC1B,cAAc,EACd,qBAAqB,EACrB,4BAA4B,EAC5B,4BAA4B,EAC5B,+BAA+B,EAC/B,8BAA8B,EAC9B,iBAAiB,EACjB,aAAa,EACb,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,yBAAyB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AAGjC,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,YAAY,EACV,eAAe,EACf,mBAAmB,EACnB,wBAAwB,EACxB,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACnE,YAAY,EACV,sBAAsB,EACtB,mBAAmB,GACpB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,YAAY,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AACrE,YAAY,EACV,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAG5E,YAAY,EACV,WAAW,EACX,eAAe,EACf,cAAc,EACd,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EACf,sBAAsB,EACtB,sBAAsB,EACtB,mBAAmB,EACnB,oBAAoB,EACpB,eAAe,EACf,sBAAsB,EACtB,qBAAqB,EACrB,qBAAqB,EACrB,oBAAoB,EACpB,0BAA0B,EAC1B,cAAc,EACd,qBAAqB,EACrB,4BAA4B,EAC5B,4BAA4B,EAC5B,+BAA+B,EAC/B,8BAA8B,EAC9B,iBAAiB,EACjB,aAAa,EACb,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,yBAAyB,CAAC"}
package/dist/index.js CHANGED
@@ -1,5 +1,11 @@
1
- import { c as r } from "./utils-B6yFEsav.js";
1
+ import { c as s } from "./utils-B6yFEsav.js";
2
+ import { A as l, a as u, b as h, c as o, d as r } from "./AuthPanel-Cn_WwmjX.js";
2
3
  export {
3
- r as cn
4
+ l as AuthLoginPanel,
5
+ u as AuthPageShell,
6
+ h as AuthPanel,
7
+ o as AuthRegisterPanel,
8
+ r as AuthVisualCarousel,
9
+ s as cn
4
10
  };
5
11
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;"}
@@ -1,2 +1,2 @@
1
- "use strict";var U=Object.create;var P=Object.defineProperty;var H=Object.getOwnPropertyDescriptor;var L=Object.getOwnPropertyNames;var I=Object.getPrototypeOf,ee=Object.prototype.hasOwnProperty;var te=(e,o,i,_)=>{if(o&&typeof o=="object"||typeof o=="function")for(let d of L(o))!ee.call(e,d)&&d!==i&&P(e,d,{get:()=>o[d],enumerable:!(_=H(o,d))||_.enumerable});return e};var $=(e,o,i)=>(i=e!=null?U(I(e)):{},te(o||!e||!e.__esModule?P(i,"default",{value:e,enumerable:!0}):i,e));Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("./jsx-runtime-BB_1_6y_.cjs"),a=require("react"),re=require("./utils-IjLH3w2e.cjs"),ne=e=>e?e instanceof Error?e:new Error(e):null,se=e=>e instanceof Error?e:new Error("无法加载 Markdown 渲染依赖"),oe="markdown-reader-content max-w-none text-sm leading-7 text-slate-800 dark:text-slate-100 [&_h1]:mb-4 [&_h1]:mt-0 [&_h1]:text-3xl [&_h1]:font-semibold [&_h2]:mb-3 [&_h2]:mt-8 [&_h2]:text-2xl [&_h2]:font-semibold [&_h3]:mb-2 [&_h3]:mt-6 [&_h3]:text-xl [&_h3]:font-semibold [&_p]:my-4 [&_ul]:my-4 [&_ol]:my-4 [&_li]:my-1 [&_ul]:list-disc [&_ol]:list-decimal [&_ul]:pl-6 [&_ol]:pl-6 [&_blockquote]:my-4 [&_blockquote]:border-l-4 [&_blockquote]:border-slate-300 [&_blockquote]:pl-4 [&_blockquote]:text-slate-600 dark:[&_blockquote]:border-slate-700 dark:[&_blockquote]:text-slate-300 [&_a]:font-medium [&_a]:text-cyan-700 [&_a]:underline-offset-4 hover:[&_a]:underline dark:[&_a]:text-cyan-300 [&_table]:my-4 [&_table]:w-full [&_table]:border-collapse [&_th]:border [&_td]:border [&_th]:border-slate-200 [&_td]:border-slate-200 [&_th]:bg-slate-100 [&_th]:px-3 [&_th]:py-2 [&_td]:px-3 [&_td]:py-2 dark:[&_th]:border-slate-700 dark:[&_td]:border-slate-700 dark:[&_th]:bg-slate-800 [&_pre]:my-4 [&_pre]:overflow-x-auto [&_pre]:rounded-lg [&_pre]:bg-slate-950 [&_pre]:p-4 [&_pre]:text-slate-50 [&_code]:rounded [&_code]:bg-slate-100 [&_code]:px-1.5 [&_code]:py-0.5 [&_code]:text-sm dark:[&_code]:bg-slate-800 [&_pre_code]:bg-transparent [&_pre_code]:p-0 [&_img]:my-4 [&_img]:max-w-full [&_img]:rounded-lg [&_hr]:my-8 [&_hr]:border-slate-200 dark:[&_hr]:border-slate-800";function le({content:e,sourceUrl:o,components:i,loading:_=!1,error:d,className:k,contentClassName:z,loadingText:G="正在加载 Markdown 内容...",errorText:O="Markdown 加载失败",emptyText:A="暂无 Markdown 内容",allowImages:R=!0,openLinksInNewTab:j=!0,transformLinkHref:p,transformImageSrc:h,onLoadError:b}){const[w,B]=a.useState(null),[F,y]=a.useState(!0),[D,M]=a.useState(null),[J,v]=a.useState(""),[K,f]=a.useState(!1),[Q,E]=a.useState(null),c=a.useRef(b),{Card:C,CardContent:q,Skeleton:m}=i||{};a.useEffect(()=>{c.current=b},[b]),a.useEffect(()=>{let r=!0;return(async()=>{var s;y(!0),M(null);try{const[n,u]=await Promise.all([import("react-markdown"),import("remark-gfm")]);if(!r)return;B({ReactMarkdown:n.default,remarkGfm:u.default})}catch(n){if(!r)return;const u=se(n);M(u),(s=c.current)==null||s.call(c,u)}finally{r&&y(!1)}})(),()=>{r=!1}},[]),a.useEffect(()=>{if(e!==void 0||!o){v(""),f(!1),E(null);return}const r=new AbortController;return(async()=>{var s;f(!0),E(null);try{const n=await fetch(o,{signal:r.signal});if(!n.ok)throw new Error(`请求失败:${n.status}`);const u=await n.text();v(u)}catch(n){if(r.signal.aborted)return;const u=n instanceof Error?n:new Error("无法加载 Markdown 内容");E(u),(s=c.current)==null||s.call(c,u)}finally{r.signal.aborted||f(!1)}})(),()=>{r.abort()}},[e,o]);const N=e!==void 0?e:J,x=ne(d)||D||Q,S=_||F||K,V=!S&&!x&&N.trim().length===0,W=a.useMemo(()=>({a({href:r,children:l,...s}){const n=r?(p==null?void 0:p(r))??r:void 0;return t.jsxRuntimeExports.jsx("a",{...s,href:n,target:j?"_blank":s.target,rel:j?"noreferrer noopener":s.rel,children:l})},img({src:r,alt:l,...s}){if(!r)return null;const n=(h==null?void 0:h(r))??r;return R?t.jsxRuntimeExports.jsx("img",{...s,src:n,alt:l||"",loading:"lazy"}):t.jsxRuntimeExports.jsx("a",{href:n,target:"_blank",rel:"noreferrer noopener",children:l||n})},input({checked:r,type:l,...s}){return l!=="checkbox"?t.jsxRuntimeExports.jsx("input",{...s,type:l}):t.jsxRuntimeExports.jsx("input",{...s,type:"checkbox",checked:!!r,readOnly:!0,disabled:!0})}}),[R,j,h,p]),X=()=>t.jsxRuntimeExports.jsx("div",{className:"space-y-3 p-4",role:"status","aria-live":"polite",children:m?t.jsxRuntimeExports.jsxs(t.jsxRuntimeExports.Fragment,{children:[t.jsxRuntimeExports.jsx(m,{className:"h-5 w-2/3"}),t.jsxRuntimeExports.jsx(m,{className:"h-4 w-full"}),t.jsxRuntimeExports.jsx(m,{className:"h-4 w-5/6"}),t.jsxRuntimeExports.jsx(m,{className:"h-28 w-full"})]}):t.jsxRuntimeExports.jsx("p",{className:"text-sm text-muted-foreground",children:G})}),Y=()=>t.jsxRuntimeExports.jsxs("div",{className:"p-4 text-sm text-destructive",role:"alert",children:[t.jsxRuntimeExports.jsx("p",{className:"font-medium",children:O}),x!=null&&x.message?t.jsxRuntimeExports.jsx("p",{className:"mt-1 opacity-80",children:x.message}):null]}),Z=()=>t.jsxRuntimeExports.jsx("div",{className:"p-4 text-sm text-muted-foreground",children:A}),T=()=>{if(S)return X();if(x)return Y();if(V)return Z();if(!w)return null;const{ReactMarkdown:r,remarkGfm:l}=w;return t.jsxRuntimeExports.jsx(r,{remarkPlugins:[l],components:W,children:N})},g=t.jsxRuntimeExports.jsx("div",{className:re.cn(oe,z),children:T()});return C?t.jsxRuntimeExports.jsx(C,{className:k,children:q?t.jsxRuntimeExports.jsx(q,{children:g}):g}):t.jsxRuntimeExports.jsx("div",{className:k,children:g})}exports.MarkdownReader=le;
1
+ "use strict";var U=Object.create;var P=Object.defineProperty;var H=Object.getOwnPropertyDescriptor;var L=Object.getOwnPropertyNames;var I=Object.getPrototypeOf,ee=Object.prototype.hasOwnProperty;var te=(e,o,i,_)=>{if(o&&typeof o=="object"||typeof o=="function")for(let d of L(o))!ee.call(e,d)&&d!==i&&P(e,d,{get:()=>o[d],enumerable:!(_=H(o,d))||_.enumerable});return e};var $=(e,o,i)=>(i=e!=null?U(I(e)):{},te(o||!e||!e.__esModule?P(i,"default",{value:e,enumerable:!0}):i,e));Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("./jsx-runtime-BB_1_6y_.cjs"),a=require("react"),re=require("./utils-IjLH3w2e.cjs"),ne=e=>e?e instanceof Error?e:new Error(e):null,se=e=>e instanceof Error?e:new Error("无法加载 Markdown 渲染依赖"),oe="markdown-reader-content max-w-none text-sm leading-7 text-slate-800 dark:text-slate-100 [&_h1]:mb-4 [&_h1]:mt-0 [&_h1]:text-3xl [&_h1]:font-semibold [&_h2]:mb-3 [&_h2]:mt-8 [&_h2]:text-2xl [&_h2]:font-semibold [&_h3]:mb-2 [&_h3]:mt-6 [&_h3]:text-xl [&_h3]:font-semibold [&_p]:my-4 [&_ul]:my-4 [&_ol]:my-4 [&_li]:my-1 [&_ul]:list-disc [&_ol]:list-decimal [&_ul]:pl-6 [&_ol]:pl-6 [&_blockquote]:my-4 [&_blockquote]:border-l-4 [&_blockquote]:border-slate-300 [&_blockquote]:pl-4 [&_blockquote]:text-slate-600 dark:[&_blockquote]:border-slate-700 dark:[&_blockquote]:text-slate-300 [&_a]:font-medium [&_a]:text-cyan-700 [&_a]:underline-offset-4 hover:[&_a]:underline dark:[&_a]:text-cyan-300 [&_table]:my-4 [&_table]:w-full [&_table]:border-collapse [&_th]:border [&_td]:border [&_th]:border-slate-200 [&_td]:border-slate-200 [&_th]:bg-slate-100 [&_th]:px-3 [&_th]:py-2 [&_td]:px-3 [&_td]:py-2 dark:[&_th]:border-slate-700 dark:[&_td]:border-slate-700 dark:[&_th]:bg-slate-800 [&_pre]:my-4 [&_pre]:overflow-x-auto [&_pre]:rounded-lg [&_pre]:bg-slate-950 [&_pre]:p-4 [&_pre]:text-slate-50 [&_code]:rounded [&_code]:bg-slate-100 [&_code]:px-1.5 [&_code]:py-0.5 [&_code]:text-sm dark:[&_code]:bg-slate-800 [&_pre_code]:bg-transparent [&_pre_code]:p-0 [&_img]:my-4 [&_img]:max-w-full [&_img]:rounded-lg [&_hr]:my-8 [&_hr]:border-slate-200 dark:[&_hr]:border-slate-800";function le({content:e,sourceUrl:o,components:i,loading:_=!1,error:d,className:k,contentClassName:z,loadingText:G="正在加载 Markdown 内容...",errorText:O="Markdown 加载失败",emptyText:A="暂无 Markdown 内容",allowImages:R=!0,openLinksInNewTab:j=!0,transformLinkHref:p,transformImageSrc:h,onLoadError:b}){const[w,B]=a.useState(null),[F,y]=a.useState(!0),[D,M]=a.useState(null),[J,v]=a.useState(""),[K,f]=a.useState(!1),[Q,E]=a.useState(null),c=a.useRef(b),{Card:C,CardContent:q,Skeleton:m}=i||{};a.useEffect(()=>{c.current=b},[b]),a.useEffect(()=>{let r=!0;return(async()=>{var s;y(!0),M(null);try{const[n,u]=await Promise.all([import("react-markdown"),import("remark-gfm")]);if(!r)return;B({ReactMarkdown:n.default,remarkGfm:u.default})}catch(n){if(!r)return;const u=se(n);M(u),(s=c.current)==null||s.call(c,u)}finally{r&&y(!1)}})(),()=>{r=!1}},[]),a.useEffect(()=>{if(e!==void 0||!o){v(""),f(!1),E(null);return}const r=new AbortController;return(async()=>{var s;f(!0),E(null);try{const n=await fetch(o,{signal:r.signal});if(!n.ok)throw new Error(`请求失败:${n.status}`);const u=await n.text();v(u)}catch(n){if(r.signal.aborted)return;const u=n instanceof Error?n:new Error("无法加载 Markdown 内容");E(u),(s=c.current)==null||s.call(c,u)}finally{r.signal.aborted||f(!1)}})(),()=>{r.abort()}},[e,o]);const N=e!==void 0?e:J,x=ne(d)||D||Q,S=_||F||K,V=!S&&!x&&N.trim().length===0,W=a.useMemo(()=>({a({href:r,children:l,...s}){const n=r?(p==null?void 0:p(r))??r:void 0;return t.jsxRuntimeExports.jsx("a",{...s,href:n,target:j?"_blank":s.target,rel:j?"noreferrer noopener":s.rel,children:l})},img({src:r,alt:l,...s}){if(!r)return null;const n=(h==null?void 0:h(r))??r;return R?t.jsxRuntimeExports.jsx("span",{className:"block overflow-hidden rounded-lg bg-muted/20",children:t.jsxRuntimeExports.jsx("img",{...s,src:n,alt:l||"",loading:"lazy",decoding:"async"})}):t.jsxRuntimeExports.jsx("a",{href:n,target:"_blank",rel:"noreferrer noopener",children:l||n})},input({checked:r,type:l,...s}){return l!=="checkbox"?t.jsxRuntimeExports.jsx("input",{...s,type:l}):t.jsxRuntimeExports.jsx("input",{...s,type:"checkbox",checked:!!r,readOnly:!0,disabled:!0})}}),[R,j,h,p]),X=()=>t.jsxRuntimeExports.jsx("div",{className:"space-y-3 p-4",role:"status","aria-live":"polite",children:m?t.jsxRuntimeExports.jsxs(t.jsxRuntimeExports.Fragment,{children:[t.jsxRuntimeExports.jsx(m,{className:"h-5 w-2/3"}),t.jsxRuntimeExports.jsx(m,{className:"h-4 w-full"}),t.jsxRuntimeExports.jsx(m,{className:"h-4 w-5/6"}),t.jsxRuntimeExports.jsx(m,{className:"h-28 w-full"})]}):t.jsxRuntimeExports.jsx("p",{className:"text-sm text-muted-foreground",children:G})}),Y=()=>t.jsxRuntimeExports.jsxs("div",{className:"p-4 text-sm text-destructive",role:"alert",children:[t.jsxRuntimeExports.jsx("p",{className:"font-medium",children:O}),x!=null&&x.message?t.jsxRuntimeExports.jsx("p",{className:"mt-1 opacity-80",children:x.message}):null]}),Z=()=>t.jsxRuntimeExports.jsx("div",{className:"p-4 text-sm text-muted-foreground",children:A}),T=()=>{if(S)return X();if(x)return Y();if(V)return Z();if(!w)return null;const{ReactMarkdown:r,remarkGfm:l}=w;return t.jsxRuntimeExports.jsx(r,{remarkPlugins:[l],components:W,children:N})},g=t.jsxRuntimeExports.jsx("div",{className:re.cn(oe,z),children:T()});return C?t.jsxRuntimeExports.jsx(C,{className:k,children:q?t.jsxRuntimeExports.jsx(q,{children:g}):g}):t.jsxRuntimeExports.jsx("div",{className:k,children:g})}exports.MarkdownReader=le;
2
2
  //# sourceMappingURL=markdown-reader.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"markdown-reader.cjs","sources":["../src/components/MarkdownReader.tsx"],"sourcesContent":["import { useEffect, useMemo, useRef, useState } from 'react';\nimport type { ComponentType, HTMLAttributes } from 'react';\n\nimport { cn } from '../lib/utils';\nimport type {\n CardComponent,\n SkeletonComponent,\n UIComponent,\n} from '../types/component-types';\n\nexport interface MarkdownReaderUIComponents {\n Card?: CardComponent;\n CardContent?: UIComponent<HTMLAttributes<HTMLDivElement>>;\n Skeleton?: SkeletonComponent;\n}\n\nexport interface MarkdownReaderProps {\n content?: string;\n sourceUrl?: string;\n components?: MarkdownReaderUIComponents;\n loading?: boolean;\n error?: Error | string | null;\n className?: string;\n contentClassName?: string;\n loadingText?: string;\n errorText?: string;\n emptyText?: string;\n allowImages?: boolean;\n openLinksInNewTab?: boolean;\n transformLinkHref?: (href: string) => string | undefined;\n transformImageSrc?: (src: string) => string | undefined;\n onLoadError?: (error: Error) => void;\n}\n\ninterface MarkdownRuntime {\n ReactMarkdown: ComponentType<any>;\n remarkGfm: unknown;\n}\n\nconst normalizeError = (error: Error | string | null | undefined) => {\n if (!error) return null;\n return error instanceof Error ? error : new Error(error);\n};\n\nconst getMarkdownLoadError = (error: unknown) =>\n error instanceof Error\n ? error\n : new Error('无法加载 Markdown 渲染依赖');\n\nconst defaultContentClassName =\n 'markdown-reader-content max-w-none text-sm leading-7 text-slate-800 dark:text-slate-100 ' +\n '[&_h1]:mb-4 [&_h1]:mt-0 [&_h1]:text-3xl [&_h1]:font-semibold ' +\n '[&_h2]:mb-3 [&_h2]:mt-8 [&_h2]:text-2xl [&_h2]:font-semibold ' +\n '[&_h3]:mb-2 [&_h3]:mt-6 [&_h3]:text-xl [&_h3]:font-semibold ' +\n '[&_p]:my-4 [&_ul]:my-4 [&_ol]:my-4 [&_li]:my-1 [&_ul]:list-disc [&_ol]:list-decimal ' +\n '[&_ul]:pl-6 [&_ol]:pl-6 [&_blockquote]:my-4 [&_blockquote]:border-l-4 ' +\n '[&_blockquote]:border-slate-300 [&_blockquote]:pl-4 [&_blockquote]:text-slate-600 ' +\n 'dark:[&_blockquote]:border-slate-700 dark:[&_blockquote]:text-slate-300 ' +\n '[&_a]:font-medium [&_a]:text-cyan-700 [&_a]:underline-offset-4 hover:[&_a]:underline ' +\n 'dark:[&_a]:text-cyan-300 [&_table]:my-4 [&_table]:w-full [&_table]:border-collapse ' +\n '[&_th]:border [&_td]:border [&_th]:border-slate-200 [&_td]:border-slate-200 ' +\n '[&_th]:bg-slate-100 [&_th]:px-3 [&_th]:py-2 [&_td]:px-3 [&_td]:py-2 ' +\n 'dark:[&_th]:border-slate-700 dark:[&_td]:border-slate-700 dark:[&_th]:bg-slate-800 ' +\n '[&_pre]:my-4 [&_pre]:overflow-x-auto [&_pre]:rounded-lg [&_pre]:bg-slate-950 ' +\n '[&_pre]:p-4 [&_pre]:text-slate-50 [&_code]:rounded [&_code]:bg-slate-100 ' +\n '[&_code]:px-1.5 [&_code]:py-0.5 [&_code]:text-sm dark:[&_code]:bg-slate-800 ' +\n '[&_pre_code]:bg-transparent [&_pre_code]:p-0 [&_img]:my-4 [&_img]:max-w-full ' +\n '[&_img]:rounded-lg [&_hr]:my-8 [&_hr]:border-slate-200 dark:[&_hr]:border-slate-800';\n\nexport function MarkdownReader({\n content,\n sourceUrl,\n components,\n loading = false,\n error,\n className,\n contentClassName,\n loadingText = '正在加载 Markdown 内容...',\n errorText = 'Markdown 加载失败',\n emptyText = '暂无 Markdown 内容',\n allowImages = true,\n openLinksInNewTab = true,\n transformLinkHref,\n transformImageSrc,\n onLoadError,\n}: MarkdownReaderProps) {\n const [runtime, setRuntime] = useState<MarkdownRuntime | null>(null);\n const [runtimeLoading, setRuntimeLoading] = useState(true);\n const [runtimeError, setRuntimeError] = useState<Error | null>(null);\n const [remoteContent, setRemoteContent] = useState('');\n const [remoteLoading, setRemoteLoading] = useState(false);\n const [remoteError, setRemoteError] = useState<Error | null>(null);\n const onLoadErrorRef = useRef(onLoadError);\n\n const { Card, CardContent, Skeleton } = components || {};\n\n useEffect(() => {\n onLoadErrorRef.current = onLoadError;\n }, [onLoadError]);\n\n useEffect(() => {\n let isMounted = true;\n\n const loadRuntime = async () => {\n setRuntimeLoading(true);\n setRuntimeError(null);\n\n try {\n const [markdownModule, gfmModule] = await Promise.all([\n import('react-markdown'),\n import('remark-gfm'),\n ]);\n\n if (!isMounted) return;\n\n setRuntime({\n ReactMarkdown: markdownModule.default,\n remarkGfm: gfmModule.default,\n });\n } catch (err) {\n if (!isMounted) return;\n\n const nextError = getMarkdownLoadError(err);\n setRuntimeError(nextError);\n onLoadErrorRef.current?.(nextError);\n } finally {\n if (isMounted) {\n setRuntimeLoading(false);\n }\n }\n };\n\n loadRuntime();\n\n return () => {\n isMounted = false;\n };\n }, []);\n\n useEffect(() => {\n if (content !== undefined || !sourceUrl) {\n setRemoteContent('');\n setRemoteLoading(false);\n setRemoteError(null);\n return;\n }\n\n const controller = new AbortController();\n\n const loadContent = async () => {\n setRemoteLoading(true);\n setRemoteError(null);\n\n try {\n const response = await fetch(sourceUrl, {\n signal: controller.signal,\n });\n\n if (!response.ok) {\n throw new Error(`请求失败:${response.status}`);\n }\n\n const text = await response.text();\n setRemoteContent(text);\n } catch (err) {\n if (controller.signal.aborted) return;\n\n const nextError =\n err instanceof Error ? err : new Error('无法加载 Markdown 内容');\n setRemoteError(nextError);\n onLoadErrorRef.current?.(nextError);\n } finally {\n if (!controller.signal.aborted) {\n setRemoteLoading(false);\n }\n }\n };\n\n loadContent();\n\n return () => {\n controller.abort();\n };\n }, [content, sourceUrl]);\n\n const markdown = content !== undefined ? content : remoteContent;\n const displayedError = normalizeError(error) || runtimeError || remoteError;\n const isLoading = loading || runtimeLoading || remoteLoading;\n const isEmpty = !isLoading && !displayedError && markdown.trim().length === 0;\n\n const markdownComponents = useMemo(\n () => ({\n a({ href, children, ...props }: any) {\n const nextHref = href ? transformLinkHref?.(href) ?? href : undefined;\n\n return (\n <a\n {...props}\n href={nextHref}\n target={openLinksInNewTab ? '_blank' : props.target}\n rel={openLinksInNewTab ? 'noreferrer noopener' : props.rel}\n >\n {children}\n </a>\n );\n },\n img({ src, alt, ...props }: any) {\n if (!src) return null;\n\n const nextSrc = transformImageSrc?.(src) ?? src;\n\n if (!allowImages) {\n return (\n <a href={nextSrc} target=\"_blank\" rel=\"noreferrer noopener\">\n {alt || nextSrc}\n </a>\n );\n }\n\n return <img {...props} src={nextSrc} alt={alt || ''} loading=\"lazy\" />;\n },\n input({ checked, type, ...props }: any) {\n if (type !== 'checkbox') {\n return <input {...props} type={type} />;\n }\n\n return (\n <input\n {...props}\n type=\"checkbox\"\n checked={Boolean(checked)}\n readOnly\n disabled\n />\n );\n },\n }),\n [\n allowImages,\n openLinksInNewTab,\n transformImageSrc,\n transformLinkHref,\n ]\n );\n\n const renderLoading = () => (\n <div className=\"space-y-3 p-4\" role=\"status\" aria-live=\"polite\">\n {Skeleton ? (\n <>\n <Skeleton className=\"h-5 w-2/3\" />\n <Skeleton className=\"h-4 w-full\" />\n <Skeleton className=\"h-4 w-5/6\" />\n <Skeleton className=\"h-28 w-full\" />\n </>\n ) : (\n <p className=\"text-sm text-muted-foreground\">{loadingText}</p>\n )}\n </div>\n );\n\n const renderError = () => (\n <div className=\"p-4 text-sm text-destructive\" role=\"alert\">\n <p className=\"font-medium\">{errorText}</p>\n {displayedError?.message ? (\n <p className=\"mt-1 opacity-80\">{displayedError.message}</p>\n ) : null}\n </div>\n );\n\n const renderEmpty = () => (\n <div className=\"p-4 text-sm text-muted-foreground\">{emptyText}</div>\n );\n\n const renderContent = () => {\n if (isLoading) return renderLoading();\n if (displayedError) return renderError();\n if (isEmpty) return renderEmpty();\n if (!runtime) return null;\n\n const { ReactMarkdown, remarkGfm } = runtime;\n\n return (\n <ReactMarkdown\n remarkPlugins={[remarkGfm]}\n components={markdownComponents}\n >\n {markdown}\n </ReactMarkdown>\n );\n };\n\n const body = (\n <div className={cn(defaultContentClassName, contentClassName)}>\n {renderContent()}\n </div>\n );\n\n if (Card) {\n return (\n <Card className={className}>\n {CardContent ? <CardContent>{body}</CardContent> : body}\n </Card>\n );\n }\n\n return <div className={className}>{body}</div>;\n}\n"],"names":["normalizeError","error","getMarkdownLoadError","defaultContentClassName","MarkdownReader","content","sourceUrl","components","loading","className","contentClassName","loadingText","errorText","emptyText","allowImages","openLinksInNewTab","transformLinkHref","transformImageSrc","onLoadError","runtime","setRuntime","useState","runtimeLoading","setRuntimeLoading","runtimeError","setRuntimeError","remoteContent","setRemoteContent","remoteLoading","setRemoteLoading","remoteError","setRemoteError","onLoadErrorRef","useRef","Card","CardContent","Skeleton","useEffect","isMounted","markdownModule","gfmModule","err","nextError","_a","controller","response","text","markdown","displayedError","isLoading","isEmpty","markdownComponents","useMemo","href","children","props","nextHref","jsx","src","alt","nextSrc","checked","type","renderLoading","jsxs","Fragment","renderError","renderEmpty","renderContent","ReactMarkdown","remarkGfm","body","cn"],"mappings":"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"}
1
+ {"version":3,"file":"markdown-reader.cjs","sources":["../src/components/MarkdownReader.tsx"],"sourcesContent":["import { useEffect, useMemo, useRef, useState } from 'react';\nimport type { ComponentType, HTMLAttributes } from 'react';\n\nimport { cn } from '../lib/utils';\nimport type {\n CardComponent,\n SkeletonComponent,\n UIComponent,\n} from '../types/component-types';\n\nexport interface MarkdownReaderUIComponents {\n Card?: CardComponent;\n CardContent?: UIComponent<HTMLAttributes<HTMLDivElement>>;\n Skeleton?: SkeletonComponent;\n}\n\nexport interface MarkdownReaderProps {\n content?: string;\n sourceUrl?: string;\n components?: MarkdownReaderUIComponents;\n loading?: boolean;\n error?: Error | string | null;\n className?: string;\n contentClassName?: string;\n loadingText?: string;\n errorText?: string;\n emptyText?: string;\n allowImages?: boolean;\n openLinksInNewTab?: boolean;\n transformLinkHref?: (href: string) => string | undefined;\n transformImageSrc?: (src: string) => string | undefined;\n onLoadError?: (error: Error) => void;\n}\n\ninterface MarkdownRuntime {\n ReactMarkdown: ComponentType<any>;\n remarkGfm: unknown;\n}\n\nconst normalizeError = (error: Error | string | null | undefined) => {\n if (!error) return null;\n return error instanceof Error ? error : new Error(error);\n};\n\nconst getMarkdownLoadError = (error: unknown) =>\n error instanceof Error ? error : new Error('无法加载 Markdown 渲染依赖');\n\nconst defaultContentClassName =\n 'markdown-reader-content max-w-none text-sm leading-7 text-slate-800 dark:text-slate-100 ' +\n '[&_h1]:mb-4 [&_h1]:mt-0 [&_h1]:text-3xl [&_h1]:font-semibold ' +\n '[&_h2]:mb-3 [&_h2]:mt-8 [&_h2]:text-2xl [&_h2]:font-semibold ' +\n '[&_h3]:mb-2 [&_h3]:mt-6 [&_h3]:text-xl [&_h3]:font-semibold ' +\n '[&_p]:my-4 [&_ul]:my-4 [&_ol]:my-4 [&_li]:my-1 [&_ul]:list-disc [&_ol]:list-decimal ' +\n '[&_ul]:pl-6 [&_ol]:pl-6 [&_blockquote]:my-4 [&_blockquote]:border-l-4 ' +\n '[&_blockquote]:border-slate-300 [&_blockquote]:pl-4 [&_blockquote]:text-slate-600 ' +\n 'dark:[&_blockquote]:border-slate-700 dark:[&_blockquote]:text-slate-300 ' +\n '[&_a]:font-medium [&_a]:text-cyan-700 [&_a]:underline-offset-4 hover:[&_a]:underline ' +\n 'dark:[&_a]:text-cyan-300 [&_table]:my-4 [&_table]:w-full [&_table]:border-collapse ' +\n '[&_th]:border [&_td]:border [&_th]:border-slate-200 [&_td]:border-slate-200 ' +\n '[&_th]:bg-slate-100 [&_th]:px-3 [&_th]:py-2 [&_td]:px-3 [&_td]:py-2 ' +\n 'dark:[&_th]:border-slate-700 dark:[&_td]:border-slate-700 dark:[&_th]:bg-slate-800 ' +\n '[&_pre]:my-4 [&_pre]:overflow-x-auto [&_pre]:rounded-lg [&_pre]:bg-slate-950 ' +\n '[&_pre]:p-4 [&_pre]:text-slate-50 [&_code]:rounded [&_code]:bg-slate-100 ' +\n '[&_code]:px-1.5 [&_code]:py-0.5 [&_code]:text-sm dark:[&_code]:bg-slate-800 ' +\n '[&_pre_code]:bg-transparent [&_pre_code]:p-0 [&_img]:my-4 [&_img]:max-w-full ' +\n '[&_img]:rounded-lg [&_hr]:my-8 [&_hr]:border-slate-200 dark:[&_hr]:border-slate-800';\n\nexport function MarkdownReader({\n content,\n sourceUrl,\n components,\n loading = false,\n error,\n className,\n contentClassName,\n loadingText = '正在加载 Markdown 内容...',\n errorText = 'Markdown 加载失败',\n emptyText = '暂无 Markdown 内容',\n allowImages = true,\n openLinksInNewTab = true,\n transformLinkHref,\n transformImageSrc,\n onLoadError,\n}: MarkdownReaderProps) {\n const [runtime, setRuntime] = useState<MarkdownRuntime | null>(null);\n const [runtimeLoading, setRuntimeLoading] = useState(true);\n const [runtimeError, setRuntimeError] = useState<Error | null>(null);\n const [remoteContent, setRemoteContent] = useState('');\n const [remoteLoading, setRemoteLoading] = useState(false);\n const [remoteError, setRemoteError] = useState<Error | null>(null);\n const onLoadErrorRef = useRef(onLoadError);\n\n const { Card, CardContent, Skeleton } = components || {};\n\n useEffect(() => {\n onLoadErrorRef.current = onLoadError;\n }, [onLoadError]);\n\n useEffect(() => {\n let isMounted = true;\n\n const loadRuntime = async () => {\n setRuntimeLoading(true);\n setRuntimeError(null);\n\n try {\n const [markdownModule, gfmModule] = await Promise.all([\n import('react-markdown'),\n import('remark-gfm'),\n ]);\n\n if (!isMounted) return;\n\n setRuntime({\n ReactMarkdown: markdownModule.default,\n remarkGfm: gfmModule.default,\n });\n } catch (err) {\n if (!isMounted) return;\n\n const nextError = getMarkdownLoadError(err);\n setRuntimeError(nextError);\n onLoadErrorRef.current?.(nextError);\n } finally {\n if (isMounted) {\n setRuntimeLoading(false);\n }\n }\n };\n\n loadRuntime();\n\n return () => {\n isMounted = false;\n };\n }, []);\n\n useEffect(() => {\n if (content !== undefined || !sourceUrl) {\n setRemoteContent('');\n setRemoteLoading(false);\n setRemoteError(null);\n return;\n }\n\n const controller = new AbortController();\n\n const loadContent = async () => {\n setRemoteLoading(true);\n setRemoteError(null);\n\n try {\n const response = await fetch(sourceUrl, {\n signal: controller.signal,\n });\n\n if (!response.ok) {\n throw new Error(`请求失败:${response.status}`);\n }\n\n const text = await response.text();\n setRemoteContent(text);\n } catch (err) {\n if (controller.signal.aborted) return;\n\n const nextError =\n err instanceof Error ? err : new Error('无法加载 Markdown 内容');\n setRemoteError(nextError);\n onLoadErrorRef.current?.(nextError);\n } finally {\n if (!controller.signal.aborted) {\n setRemoteLoading(false);\n }\n }\n };\n\n loadContent();\n\n return () => {\n controller.abort();\n };\n }, [content, sourceUrl]);\n\n const markdown = content !== undefined ? content : remoteContent;\n const displayedError = normalizeError(error) || runtimeError || remoteError;\n const isLoading = loading || runtimeLoading || remoteLoading;\n const isEmpty = !isLoading && !displayedError && markdown.trim().length === 0;\n\n const markdownComponents = useMemo(\n () => ({\n a({ href, children, ...props }: any) {\n const nextHref = href ? (transformLinkHref?.(href) ?? href) : undefined;\n\n return (\n <a\n {...props}\n href={nextHref}\n target={openLinksInNewTab ? '_blank' : props.target}\n rel={openLinksInNewTab ? 'noreferrer noopener' : props.rel}\n >\n {children}\n </a>\n );\n },\n img({ src, alt, ...props }: any) {\n if (!src) return null;\n\n const nextSrc = transformImageSrc?.(src) ?? src;\n\n if (!allowImages) {\n return (\n <a href={nextSrc} target=\"_blank\" rel=\"noreferrer noopener\">\n {alt || nextSrc}\n </a>\n );\n }\n\n return (\n <span className=\"block overflow-hidden rounded-lg bg-muted/20\">\n <img\n {...props}\n src={nextSrc}\n alt={alt || ''}\n loading=\"lazy\"\n decoding=\"async\"\n />\n </span>\n );\n },\n input({ checked, type, ...props }: any) {\n if (type !== 'checkbox') {\n return <input {...props} type={type} />;\n }\n\n return (\n <input\n {...props}\n type=\"checkbox\"\n checked={Boolean(checked)}\n readOnly\n disabled\n />\n );\n },\n }),\n [allowImages, openLinksInNewTab, transformImageSrc, transformLinkHref]\n );\n\n const renderLoading = () => (\n <div className=\"space-y-3 p-4\" role=\"status\" aria-live=\"polite\">\n {Skeleton ? (\n <>\n <Skeleton className=\"h-5 w-2/3\" />\n <Skeleton className=\"h-4 w-full\" />\n <Skeleton className=\"h-4 w-5/6\" />\n <Skeleton className=\"h-28 w-full\" />\n </>\n ) : (\n <p className=\"text-sm text-muted-foreground\">{loadingText}</p>\n )}\n </div>\n );\n\n const renderError = () => (\n <div className=\"p-4 text-sm text-destructive\" role=\"alert\">\n <p className=\"font-medium\">{errorText}</p>\n {displayedError?.message ? (\n <p className=\"mt-1 opacity-80\">{displayedError.message}</p>\n ) : null}\n </div>\n );\n\n const renderEmpty = () => (\n <div className=\"p-4 text-sm text-muted-foreground\">{emptyText}</div>\n );\n\n const renderContent = () => {\n if (isLoading) return renderLoading();\n if (displayedError) return renderError();\n if (isEmpty) return renderEmpty();\n if (!runtime) return null;\n\n const { ReactMarkdown, remarkGfm } = runtime;\n\n return (\n <ReactMarkdown\n remarkPlugins={[remarkGfm]}\n components={markdownComponents}\n >\n {markdown}\n </ReactMarkdown>\n );\n };\n\n const body = (\n <div className={cn(defaultContentClassName, contentClassName)}>\n {renderContent()}\n </div>\n );\n\n if (Card) {\n return (\n <Card className={className}>\n {CardContent ? <CardContent>{body}</CardContent> : body}\n </Card>\n );\n }\n\n return <div className={className}>{body}</div>;\n}\n"],"names":["normalizeError","error","getMarkdownLoadError","defaultContentClassName","MarkdownReader","content","sourceUrl","components","loading","className","contentClassName","loadingText","errorText","emptyText","allowImages","openLinksInNewTab","transformLinkHref","transformImageSrc","onLoadError","runtime","setRuntime","useState","runtimeLoading","setRuntimeLoading","runtimeError","setRuntimeError","remoteContent","setRemoteContent","remoteLoading","setRemoteLoading","remoteError","setRemoteError","onLoadErrorRef","useRef","Card","CardContent","Skeleton","useEffect","isMounted","markdownModule","gfmModule","err","nextError","_a","controller","response","text","markdown","displayedError","isLoading","isEmpty","markdownComponents","useMemo","href","children","props","nextHref","jsx","src","alt","nextSrc","checked","type","renderLoading","jsxs","Fragment","renderError","renderEmpty","renderContent","ReactMarkdown","remarkGfm","body","cn"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { j as e } from "./jsx-runtime-B4hRZ52C.js";
2
- import { useState as i, useRef as T, useEffect as k, useMemo as U } from "react";
2
+ import { useState as c, useRef as T, useEffect as g, useMemo as U } from "react";
3
3
  import { c as H } from "./utils-B6yFEsav.js";
4
4
  const L = (o) => o ? o instanceof Error ? o : new Error(o) : null, I = (o) => o instanceof Error ? o : new Error("无法加载 Markdown 渲染依赖"), ee = "markdown-reader-content max-w-none text-sm leading-7 text-slate-800 dark:text-slate-100 [&_h1]:mb-4 [&_h1]:mt-0 [&_h1]:text-3xl [&_h1]:font-semibold [&_h2]:mb-3 [&_h2]:mt-8 [&_h2]:text-2xl [&_h2]:font-semibold [&_h3]:mb-2 [&_h3]:mt-6 [&_h3]:text-xl [&_h3]:font-semibold [&_p]:my-4 [&_ul]:my-4 [&_ol]:my-4 [&_li]:my-1 [&_ul]:list-disc [&_ol]:list-decimal [&_ul]:pl-6 [&_ol]:pl-6 [&_blockquote]:my-4 [&_blockquote]:border-l-4 [&_blockquote]:border-slate-300 [&_blockquote]:pl-4 [&_blockquote]:text-slate-600 dark:[&_blockquote]:border-slate-700 dark:[&_blockquote]:text-slate-300 [&_a]:font-medium [&_a]:text-cyan-700 [&_a]:underline-offset-4 hover:[&_a]:underline dark:[&_a]:text-cyan-300 [&_table]:my-4 [&_table]:w-full [&_table]:border-collapse [&_th]:border [&_td]:border [&_th]:border-slate-200 [&_td]:border-slate-200 [&_th]:bg-slate-100 [&_th]:px-3 [&_th]:py-2 [&_td]:px-3 [&_td]:py-2 dark:[&_th]:border-slate-700 dark:[&_td]:border-slate-700 dark:[&_th]:bg-slate-800 [&_pre]:my-4 [&_pre]:overflow-x-auto [&_pre]:rounded-lg [&_pre]:bg-slate-950 [&_pre]:p-4 [&_pre]:text-slate-50 [&_code]:rounded [&_code]:bg-slate-100 [&_code]:px-1.5 [&_code]:py-0.5 [&_code]:text-sm dark:[&_code]:bg-slate-800 [&_pre_code]:bg-transparent [&_pre_code]:p-0 [&_img]:my-4 [&_img]:max-w-full [&_img]:rounded-lg [&_hr]:my-8 [&_hr]:border-slate-200 dark:[&_hr]:border-slate-800";
5
5
  function oe({
@@ -8,7 +8,7 @@ function oe({
8
8
  components: q,
9
9
  loading: z = !1,
10
10
  error: G,
11
- className: g,
11
+ className: k,
12
12
  contentClassName: P,
13
13
  loadingText: A = "正在加载 Markdown 内容...",
14
14
  errorText: B = "Markdown 加载失败",
@@ -19,10 +19,10 @@ function oe({
19
19
  transformImageSrc: m,
20
20
  onLoadError: h
21
21
  }) {
22
- const [y, O] = i(null), [$, j] = i(!0), [D, E] = i(null), [J, M] = i(""), [K, b] = i(!1), [Q, f] = i(null), a = T(h), { Card: v, CardContent: C, Skeleton: c } = q || {};
23
- k(() => {
22
+ const [y, O] = c(null), [$, j] = c(!0), [D, E] = c(null), [J, v] = c(""), [K, b] = c(!1), [Q, f] = c(null), a = T(h), { Card: M, CardContent: C, Skeleton: i } = q || {};
23
+ g(() => {
24
24
  a.current = h;
25
- }, [h]), k(() => {
25
+ }, [h]), g(() => {
26
26
  let t = !0;
27
27
  return (async () => {
28
28
  var n;
@@ -47,9 +47,9 @@ function oe({
47
47
  })(), () => {
48
48
  t = !1;
49
49
  };
50
- }, []), k(() => {
50
+ }, []), g(() => {
51
51
  if (o !== void 0 || !_) {
52
- M(""), b(!1), f(null);
52
+ v(""), b(!1), f(null);
53
53
  return;
54
54
  }
55
55
  const t = new AbortController();
@@ -63,7 +63,7 @@ function oe({
63
63
  if (!r.ok)
64
64
  throw new Error(`请求失败:${r.status}`);
65
65
  const s = await r.text();
66
- M(s);
66
+ v(s);
67
67
  } catch (r) {
68
68
  if (t.signal.aborted) return;
69
69
  const s = r instanceof Error ? r : new Error("无法加载 Markdown 内容");
@@ -75,7 +75,7 @@ function oe({
75
75
  t.abort();
76
76
  };
77
77
  }, [o, _]);
78
- const R = o !== void 0 ? o : J, d = L(G) || D || Q, N = z || $ || K, V = !N && !d && R.trim().length === 0, W = U(
78
+ const N = o !== void 0 ? o : J, d = L(G) || D || Q, R = z || $ || K, V = !R && !d && N.trim().length === 0, W = U(
79
79
  () => ({
80
80
  a({ href: t, children: l, ...n }) {
81
81
  const r = t ? (u == null ? void 0 : u(t)) ?? t : void 0;
@@ -93,7 +93,16 @@ function oe({
93
93
  img({ src: t, alt: l, ...n }) {
94
94
  if (!t) return null;
95
95
  const r = (m == null ? void 0 : m(t)) ?? t;
96
- return w ? /* @__PURE__ */ e.jsx("img", { ...n, src: r, alt: l || "", loading: "lazy" }) : /* @__PURE__ */ e.jsx("a", { href: r, target: "_blank", rel: "noreferrer noopener", children: l || r });
96
+ return w ? /* @__PURE__ */ e.jsx("span", { className: "block overflow-hidden rounded-lg bg-muted/20", children: /* @__PURE__ */ e.jsx(
97
+ "img",
98
+ {
99
+ ...n,
100
+ src: r,
101
+ alt: l || "",
102
+ loading: "lazy",
103
+ decoding: "async"
104
+ }
105
+ ) }) : /* @__PURE__ */ e.jsx("a", { href: r, target: "_blank", rel: "noreferrer noopener", children: l || r });
97
106
  },
98
107
  input({ checked: t, type: l, ...n }) {
99
108
  return l !== "checkbox" ? /* @__PURE__ */ e.jsx("input", { ...n, type: l }) : /* @__PURE__ */ e.jsx(
@@ -108,22 +117,17 @@ function oe({
108
117
  );
109
118
  }
110
119
  }),
111
- [
112
- w,
113
- x,
114
- m,
115
- u
116
- ]
117
- ), X = () => /* @__PURE__ */ e.jsx("div", { className: "space-y-3 p-4", role: "status", "aria-live": "polite", children: c ? /* @__PURE__ */ e.jsxs(e.Fragment, { children: [
118
- /* @__PURE__ */ e.jsx(c, { className: "h-5 w-2/3" }),
119
- /* @__PURE__ */ e.jsx(c, { className: "h-4 w-full" }),
120
- /* @__PURE__ */ e.jsx(c, { className: "h-4 w-5/6" }),
121
- /* @__PURE__ */ e.jsx(c, { className: "h-28 w-full" })
120
+ [w, x, m, u]
121
+ ), X = () => /* @__PURE__ */ e.jsx("div", { className: "space-y-3 p-4", role: "status", "aria-live": "polite", children: i ? /* @__PURE__ */ e.jsxs(e.Fragment, { children: [
122
+ /* @__PURE__ */ e.jsx(i, { className: "h-5 w-2/3" }),
123
+ /* @__PURE__ */ e.jsx(i, { className: "h-4 w-full" }),
124
+ /* @__PURE__ */ e.jsx(i, { className: "h-4 w-5/6" }),
125
+ /* @__PURE__ */ e.jsx(i, { className: "h-28 w-full" })
122
126
  ] }) : /* @__PURE__ */ e.jsx("p", { className: "text-sm text-muted-foreground", children: A }) }), Y = () => /* @__PURE__ */ e.jsxs("div", { className: "p-4 text-sm text-destructive", role: "alert", children: [
123
127
  /* @__PURE__ */ e.jsx("p", { className: "font-medium", children: B }),
124
128
  d != null && d.message ? /* @__PURE__ */ e.jsx("p", { className: "mt-1 opacity-80", children: d.message }) : null
125
129
  ] }), Z = () => /* @__PURE__ */ e.jsx("div", { className: "p-4 text-sm text-muted-foreground", children: F }), S = () => {
126
- if (N) return X();
130
+ if (R) return X();
127
131
  if (d) return Y();
128
132
  if (V) return Z();
129
133
  if (!y) return null;
@@ -133,11 +137,11 @@ function oe({
133
137
  {
134
138
  remarkPlugins: [l],
135
139
  components: W,
136
- children: R
140
+ children: N
137
141
  }
138
142
  );
139
143
  }, p = /* @__PURE__ */ e.jsx("div", { className: H(ee, P), children: S() });
140
- return v ? /* @__PURE__ */ e.jsx(v, { className: g, children: C ? /* @__PURE__ */ e.jsx(C, { children: p }) : p }) : /* @__PURE__ */ e.jsx("div", { className: g, children: p });
144
+ return M ? /* @__PURE__ */ e.jsx(M, { className: k, children: C ? /* @__PURE__ */ e.jsx(C, { children: p }) : p }) : /* @__PURE__ */ e.jsx("div", { className: k, children: p });
141
145
  }
142
146
  export {
143
147
  oe as MarkdownReader
@@ -1 +1 @@
1
- {"version":3,"file":"markdown-reader.js","sources":["../src/components/MarkdownReader.tsx"],"sourcesContent":["import { useEffect, useMemo, useRef, useState } from 'react';\nimport type { ComponentType, HTMLAttributes } from 'react';\n\nimport { cn } from '../lib/utils';\nimport type {\n CardComponent,\n SkeletonComponent,\n UIComponent,\n} from '../types/component-types';\n\nexport interface MarkdownReaderUIComponents {\n Card?: CardComponent;\n CardContent?: UIComponent<HTMLAttributes<HTMLDivElement>>;\n Skeleton?: SkeletonComponent;\n}\n\nexport interface MarkdownReaderProps {\n content?: string;\n sourceUrl?: string;\n components?: MarkdownReaderUIComponents;\n loading?: boolean;\n error?: Error | string | null;\n className?: string;\n contentClassName?: string;\n loadingText?: string;\n errorText?: string;\n emptyText?: string;\n allowImages?: boolean;\n openLinksInNewTab?: boolean;\n transformLinkHref?: (href: string) => string | undefined;\n transformImageSrc?: (src: string) => string | undefined;\n onLoadError?: (error: Error) => void;\n}\n\ninterface MarkdownRuntime {\n ReactMarkdown: ComponentType<any>;\n remarkGfm: unknown;\n}\n\nconst normalizeError = (error: Error | string | null | undefined) => {\n if (!error) return null;\n return error instanceof Error ? error : new Error(error);\n};\n\nconst getMarkdownLoadError = (error: unknown) =>\n error instanceof Error\n ? error\n : new Error('无法加载 Markdown 渲染依赖');\n\nconst defaultContentClassName =\n 'markdown-reader-content max-w-none text-sm leading-7 text-slate-800 dark:text-slate-100 ' +\n '[&_h1]:mb-4 [&_h1]:mt-0 [&_h1]:text-3xl [&_h1]:font-semibold ' +\n '[&_h2]:mb-3 [&_h2]:mt-8 [&_h2]:text-2xl [&_h2]:font-semibold ' +\n '[&_h3]:mb-2 [&_h3]:mt-6 [&_h3]:text-xl [&_h3]:font-semibold ' +\n '[&_p]:my-4 [&_ul]:my-4 [&_ol]:my-4 [&_li]:my-1 [&_ul]:list-disc [&_ol]:list-decimal ' +\n '[&_ul]:pl-6 [&_ol]:pl-6 [&_blockquote]:my-4 [&_blockquote]:border-l-4 ' +\n '[&_blockquote]:border-slate-300 [&_blockquote]:pl-4 [&_blockquote]:text-slate-600 ' +\n 'dark:[&_blockquote]:border-slate-700 dark:[&_blockquote]:text-slate-300 ' +\n '[&_a]:font-medium [&_a]:text-cyan-700 [&_a]:underline-offset-4 hover:[&_a]:underline ' +\n 'dark:[&_a]:text-cyan-300 [&_table]:my-4 [&_table]:w-full [&_table]:border-collapse ' +\n '[&_th]:border [&_td]:border [&_th]:border-slate-200 [&_td]:border-slate-200 ' +\n '[&_th]:bg-slate-100 [&_th]:px-3 [&_th]:py-2 [&_td]:px-3 [&_td]:py-2 ' +\n 'dark:[&_th]:border-slate-700 dark:[&_td]:border-slate-700 dark:[&_th]:bg-slate-800 ' +\n '[&_pre]:my-4 [&_pre]:overflow-x-auto [&_pre]:rounded-lg [&_pre]:bg-slate-950 ' +\n '[&_pre]:p-4 [&_pre]:text-slate-50 [&_code]:rounded [&_code]:bg-slate-100 ' +\n '[&_code]:px-1.5 [&_code]:py-0.5 [&_code]:text-sm dark:[&_code]:bg-slate-800 ' +\n '[&_pre_code]:bg-transparent [&_pre_code]:p-0 [&_img]:my-4 [&_img]:max-w-full ' +\n '[&_img]:rounded-lg [&_hr]:my-8 [&_hr]:border-slate-200 dark:[&_hr]:border-slate-800';\n\nexport function MarkdownReader({\n content,\n sourceUrl,\n components,\n loading = false,\n error,\n className,\n contentClassName,\n loadingText = '正在加载 Markdown 内容...',\n errorText = 'Markdown 加载失败',\n emptyText = '暂无 Markdown 内容',\n allowImages = true,\n openLinksInNewTab = true,\n transformLinkHref,\n transformImageSrc,\n onLoadError,\n}: MarkdownReaderProps) {\n const [runtime, setRuntime] = useState<MarkdownRuntime | null>(null);\n const [runtimeLoading, setRuntimeLoading] = useState(true);\n const [runtimeError, setRuntimeError] = useState<Error | null>(null);\n const [remoteContent, setRemoteContent] = useState('');\n const [remoteLoading, setRemoteLoading] = useState(false);\n const [remoteError, setRemoteError] = useState<Error | null>(null);\n const onLoadErrorRef = useRef(onLoadError);\n\n const { Card, CardContent, Skeleton } = components || {};\n\n useEffect(() => {\n onLoadErrorRef.current = onLoadError;\n }, [onLoadError]);\n\n useEffect(() => {\n let isMounted = true;\n\n const loadRuntime = async () => {\n setRuntimeLoading(true);\n setRuntimeError(null);\n\n try {\n const [markdownModule, gfmModule] = await Promise.all([\n import('react-markdown'),\n import('remark-gfm'),\n ]);\n\n if (!isMounted) return;\n\n setRuntime({\n ReactMarkdown: markdownModule.default,\n remarkGfm: gfmModule.default,\n });\n } catch (err) {\n if (!isMounted) return;\n\n const nextError = getMarkdownLoadError(err);\n setRuntimeError(nextError);\n onLoadErrorRef.current?.(nextError);\n } finally {\n if (isMounted) {\n setRuntimeLoading(false);\n }\n }\n };\n\n loadRuntime();\n\n return () => {\n isMounted = false;\n };\n }, []);\n\n useEffect(() => {\n if (content !== undefined || !sourceUrl) {\n setRemoteContent('');\n setRemoteLoading(false);\n setRemoteError(null);\n return;\n }\n\n const controller = new AbortController();\n\n const loadContent = async () => {\n setRemoteLoading(true);\n setRemoteError(null);\n\n try {\n const response = await fetch(sourceUrl, {\n signal: controller.signal,\n });\n\n if (!response.ok) {\n throw new Error(`请求失败:${response.status}`);\n }\n\n const text = await response.text();\n setRemoteContent(text);\n } catch (err) {\n if (controller.signal.aborted) return;\n\n const nextError =\n err instanceof Error ? err : new Error('无法加载 Markdown 内容');\n setRemoteError(nextError);\n onLoadErrorRef.current?.(nextError);\n } finally {\n if (!controller.signal.aborted) {\n setRemoteLoading(false);\n }\n }\n };\n\n loadContent();\n\n return () => {\n controller.abort();\n };\n }, [content, sourceUrl]);\n\n const markdown = content !== undefined ? content : remoteContent;\n const displayedError = normalizeError(error) || runtimeError || remoteError;\n const isLoading = loading || runtimeLoading || remoteLoading;\n const isEmpty = !isLoading && !displayedError && markdown.trim().length === 0;\n\n const markdownComponents = useMemo(\n () => ({\n a({ href, children, ...props }: any) {\n const nextHref = href ? transformLinkHref?.(href) ?? href : undefined;\n\n return (\n <a\n {...props}\n href={nextHref}\n target={openLinksInNewTab ? '_blank' : props.target}\n rel={openLinksInNewTab ? 'noreferrer noopener' : props.rel}\n >\n {children}\n </a>\n );\n },\n img({ src, alt, ...props }: any) {\n if (!src) return null;\n\n const nextSrc = transformImageSrc?.(src) ?? src;\n\n if (!allowImages) {\n return (\n <a href={nextSrc} target=\"_blank\" rel=\"noreferrer noopener\">\n {alt || nextSrc}\n </a>\n );\n }\n\n return <img {...props} src={nextSrc} alt={alt || ''} loading=\"lazy\" />;\n },\n input({ checked, type, ...props }: any) {\n if (type !== 'checkbox') {\n return <input {...props} type={type} />;\n }\n\n return (\n <input\n {...props}\n type=\"checkbox\"\n checked={Boolean(checked)}\n readOnly\n disabled\n />\n );\n },\n }),\n [\n allowImages,\n openLinksInNewTab,\n transformImageSrc,\n transformLinkHref,\n ]\n );\n\n const renderLoading = () => (\n <div className=\"space-y-3 p-4\" role=\"status\" aria-live=\"polite\">\n {Skeleton ? (\n <>\n <Skeleton className=\"h-5 w-2/3\" />\n <Skeleton className=\"h-4 w-full\" />\n <Skeleton className=\"h-4 w-5/6\" />\n <Skeleton className=\"h-28 w-full\" />\n </>\n ) : (\n <p className=\"text-sm text-muted-foreground\">{loadingText}</p>\n )}\n </div>\n );\n\n const renderError = () => (\n <div className=\"p-4 text-sm text-destructive\" role=\"alert\">\n <p className=\"font-medium\">{errorText}</p>\n {displayedError?.message ? (\n <p className=\"mt-1 opacity-80\">{displayedError.message}</p>\n ) : null}\n </div>\n );\n\n const renderEmpty = () => (\n <div className=\"p-4 text-sm text-muted-foreground\">{emptyText}</div>\n );\n\n const renderContent = () => {\n if (isLoading) return renderLoading();\n if (displayedError) return renderError();\n if (isEmpty) return renderEmpty();\n if (!runtime) return null;\n\n const { ReactMarkdown, remarkGfm } = runtime;\n\n return (\n <ReactMarkdown\n remarkPlugins={[remarkGfm]}\n components={markdownComponents}\n >\n {markdown}\n </ReactMarkdown>\n );\n };\n\n const body = (\n <div className={cn(defaultContentClassName, contentClassName)}>\n {renderContent()}\n </div>\n );\n\n if (Card) {\n return (\n <Card className={className}>\n {CardContent ? <CardContent>{body}</CardContent> : body}\n </Card>\n );\n }\n\n return <div className={className}>{body}</div>;\n}\n"],"names":["normalizeError","error","getMarkdownLoadError","defaultContentClassName","MarkdownReader","content","sourceUrl","components","loading","className","contentClassName","loadingText","errorText","emptyText","allowImages","openLinksInNewTab","transformLinkHref","transformImageSrc","onLoadError","runtime","setRuntime","useState","runtimeLoading","setRuntimeLoading","runtimeError","setRuntimeError","remoteContent","setRemoteContent","remoteLoading","setRemoteLoading","remoteError","setRemoteError","onLoadErrorRef","useRef","Card","CardContent","Skeleton","useEffect","isMounted","markdownModule","gfmModule","err","nextError","_a","controller","response","text","markdown","displayedError","isLoading","isEmpty","markdownComponents","useMemo","href","children","props","nextHref","jsx","src","alt","nextSrc","checked","type","renderLoading","jsxs","Fragment","renderError","renderEmpty","renderContent","ReactMarkdown","remarkGfm","body","cn"],"mappings":"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"}
1
+ {"version":3,"file":"markdown-reader.js","sources":["../src/components/MarkdownReader.tsx"],"sourcesContent":["import { useEffect, useMemo, useRef, useState } from 'react';\nimport type { ComponentType, HTMLAttributes } from 'react';\n\nimport { cn } from '../lib/utils';\nimport type {\n CardComponent,\n SkeletonComponent,\n UIComponent,\n} from '../types/component-types';\n\nexport interface MarkdownReaderUIComponents {\n Card?: CardComponent;\n CardContent?: UIComponent<HTMLAttributes<HTMLDivElement>>;\n Skeleton?: SkeletonComponent;\n}\n\nexport interface MarkdownReaderProps {\n content?: string;\n sourceUrl?: string;\n components?: MarkdownReaderUIComponents;\n loading?: boolean;\n error?: Error | string | null;\n className?: string;\n contentClassName?: string;\n loadingText?: string;\n errorText?: string;\n emptyText?: string;\n allowImages?: boolean;\n openLinksInNewTab?: boolean;\n transformLinkHref?: (href: string) => string | undefined;\n transformImageSrc?: (src: string) => string | undefined;\n onLoadError?: (error: Error) => void;\n}\n\ninterface MarkdownRuntime {\n ReactMarkdown: ComponentType<any>;\n remarkGfm: unknown;\n}\n\nconst normalizeError = (error: Error | string | null | undefined) => {\n if (!error) return null;\n return error instanceof Error ? error : new Error(error);\n};\n\nconst getMarkdownLoadError = (error: unknown) =>\n error instanceof Error ? error : new Error('无法加载 Markdown 渲染依赖');\n\nconst defaultContentClassName =\n 'markdown-reader-content max-w-none text-sm leading-7 text-slate-800 dark:text-slate-100 ' +\n '[&_h1]:mb-4 [&_h1]:mt-0 [&_h1]:text-3xl [&_h1]:font-semibold ' +\n '[&_h2]:mb-3 [&_h2]:mt-8 [&_h2]:text-2xl [&_h2]:font-semibold ' +\n '[&_h3]:mb-2 [&_h3]:mt-6 [&_h3]:text-xl [&_h3]:font-semibold ' +\n '[&_p]:my-4 [&_ul]:my-4 [&_ol]:my-4 [&_li]:my-1 [&_ul]:list-disc [&_ol]:list-decimal ' +\n '[&_ul]:pl-6 [&_ol]:pl-6 [&_blockquote]:my-4 [&_blockquote]:border-l-4 ' +\n '[&_blockquote]:border-slate-300 [&_blockquote]:pl-4 [&_blockquote]:text-slate-600 ' +\n 'dark:[&_blockquote]:border-slate-700 dark:[&_blockquote]:text-slate-300 ' +\n '[&_a]:font-medium [&_a]:text-cyan-700 [&_a]:underline-offset-4 hover:[&_a]:underline ' +\n 'dark:[&_a]:text-cyan-300 [&_table]:my-4 [&_table]:w-full [&_table]:border-collapse ' +\n '[&_th]:border [&_td]:border [&_th]:border-slate-200 [&_td]:border-slate-200 ' +\n '[&_th]:bg-slate-100 [&_th]:px-3 [&_th]:py-2 [&_td]:px-3 [&_td]:py-2 ' +\n 'dark:[&_th]:border-slate-700 dark:[&_td]:border-slate-700 dark:[&_th]:bg-slate-800 ' +\n '[&_pre]:my-4 [&_pre]:overflow-x-auto [&_pre]:rounded-lg [&_pre]:bg-slate-950 ' +\n '[&_pre]:p-4 [&_pre]:text-slate-50 [&_code]:rounded [&_code]:bg-slate-100 ' +\n '[&_code]:px-1.5 [&_code]:py-0.5 [&_code]:text-sm dark:[&_code]:bg-slate-800 ' +\n '[&_pre_code]:bg-transparent [&_pre_code]:p-0 [&_img]:my-4 [&_img]:max-w-full ' +\n '[&_img]:rounded-lg [&_hr]:my-8 [&_hr]:border-slate-200 dark:[&_hr]:border-slate-800';\n\nexport function MarkdownReader({\n content,\n sourceUrl,\n components,\n loading = false,\n error,\n className,\n contentClassName,\n loadingText = '正在加载 Markdown 内容...',\n errorText = 'Markdown 加载失败',\n emptyText = '暂无 Markdown 内容',\n allowImages = true,\n openLinksInNewTab = true,\n transformLinkHref,\n transformImageSrc,\n onLoadError,\n}: MarkdownReaderProps) {\n const [runtime, setRuntime] = useState<MarkdownRuntime | null>(null);\n const [runtimeLoading, setRuntimeLoading] = useState(true);\n const [runtimeError, setRuntimeError] = useState<Error | null>(null);\n const [remoteContent, setRemoteContent] = useState('');\n const [remoteLoading, setRemoteLoading] = useState(false);\n const [remoteError, setRemoteError] = useState<Error | null>(null);\n const onLoadErrorRef = useRef(onLoadError);\n\n const { Card, CardContent, Skeleton } = components || {};\n\n useEffect(() => {\n onLoadErrorRef.current = onLoadError;\n }, [onLoadError]);\n\n useEffect(() => {\n let isMounted = true;\n\n const loadRuntime = async () => {\n setRuntimeLoading(true);\n setRuntimeError(null);\n\n try {\n const [markdownModule, gfmModule] = await Promise.all([\n import('react-markdown'),\n import('remark-gfm'),\n ]);\n\n if (!isMounted) return;\n\n setRuntime({\n ReactMarkdown: markdownModule.default,\n remarkGfm: gfmModule.default,\n });\n } catch (err) {\n if (!isMounted) return;\n\n const nextError = getMarkdownLoadError(err);\n setRuntimeError(nextError);\n onLoadErrorRef.current?.(nextError);\n } finally {\n if (isMounted) {\n setRuntimeLoading(false);\n }\n }\n };\n\n loadRuntime();\n\n return () => {\n isMounted = false;\n };\n }, []);\n\n useEffect(() => {\n if (content !== undefined || !sourceUrl) {\n setRemoteContent('');\n setRemoteLoading(false);\n setRemoteError(null);\n return;\n }\n\n const controller = new AbortController();\n\n const loadContent = async () => {\n setRemoteLoading(true);\n setRemoteError(null);\n\n try {\n const response = await fetch(sourceUrl, {\n signal: controller.signal,\n });\n\n if (!response.ok) {\n throw new Error(`请求失败:${response.status}`);\n }\n\n const text = await response.text();\n setRemoteContent(text);\n } catch (err) {\n if (controller.signal.aborted) return;\n\n const nextError =\n err instanceof Error ? err : new Error('无法加载 Markdown 内容');\n setRemoteError(nextError);\n onLoadErrorRef.current?.(nextError);\n } finally {\n if (!controller.signal.aborted) {\n setRemoteLoading(false);\n }\n }\n };\n\n loadContent();\n\n return () => {\n controller.abort();\n };\n }, [content, sourceUrl]);\n\n const markdown = content !== undefined ? content : remoteContent;\n const displayedError = normalizeError(error) || runtimeError || remoteError;\n const isLoading = loading || runtimeLoading || remoteLoading;\n const isEmpty = !isLoading && !displayedError && markdown.trim().length === 0;\n\n const markdownComponents = useMemo(\n () => ({\n a({ href, children, ...props }: any) {\n const nextHref = href ? (transformLinkHref?.(href) ?? href) : undefined;\n\n return (\n <a\n {...props}\n href={nextHref}\n target={openLinksInNewTab ? '_blank' : props.target}\n rel={openLinksInNewTab ? 'noreferrer noopener' : props.rel}\n >\n {children}\n </a>\n );\n },\n img({ src, alt, ...props }: any) {\n if (!src) return null;\n\n const nextSrc = transformImageSrc?.(src) ?? src;\n\n if (!allowImages) {\n return (\n <a href={nextSrc} target=\"_blank\" rel=\"noreferrer noopener\">\n {alt || nextSrc}\n </a>\n );\n }\n\n return (\n <span className=\"block overflow-hidden rounded-lg bg-muted/20\">\n <img\n {...props}\n src={nextSrc}\n alt={alt || ''}\n loading=\"lazy\"\n decoding=\"async\"\n />\n </span>\n );\n },\n input({ checked, type, ...props }: any) {\n if (type !== 'checkbox') {\n return <input {...props} type={type} />;\n }\n\n return (\n <input\n {...props}\n type=\"checkbox\"\n checked={Boolean(checked)}\n readOnly\n disabled\n />\n );\n },\n }),\n [allowImages, openLinksInNewTab, transformImageSrc, transformLinkHref]\n );\n\n const renderLoading = () => (\n <div className=\"space-y-3 p-4\" role=\"status\" aria-live=\"polite\">\n {Skeleton ? (\n <>\n <Skeleton className=\"h-5 w-2/3\" />\n <Skeleton className=\"h-4 w-full\" />\n <Skeleton className=\"h-4 w-5/6\" />\n <Skeleton className=\"h-28 w-full\" />\n </>\n ) : (\n <p className=\"text-sm text-muted-foreground\">{loadingText}</p>\n )}\n </div>\n );\n\n const renderError = () => (\n <div className=\"p-4 text-sm text-destructive\" role=\"alert\">\n <p className=\"font-medium\">{errorText}</p>\n {displayedError?.message ? (\n <p className=\"mt-1 opacity-80\">{displayedError.message}</p>\n ) : null}\n </div>\n );\n\n const renderEmpty = () => (\n <div className=\"p-4 text-sm text-muted-foreground\">{emptyText}</div>\n );\n\n const renderContent = () => {\n if (isLoading) return renderLoading();\n if (displayedError) return renderError();\n if (isEmpty) return renderEmpty();\n if (!runtime) return null;\n\n const { ReactMarkdown, remarkGfm } = runtime;\n\n return (\n <ReactMarkdown\n remarkPlugins={[remarkGfm]}\n components={markdownComponents}\n >\n {markdown}\n </ReactMarkdown>\n );\n };\n\n const body = (\n <div className={cn(defaultContentClassName, contentClassName)}>\n {renderContent()}\n </div>\n );\n\n if (Card) {\n return (\n <Card className={className}>\n {CardContent ? <CardContent>{body}</CardContent> : body}\n </Card>\n );\n }\n\n return <div className={className}>{body}</div>;\n}\n"],"names":["normalizeError","error","getMarkdownLoadError","defaultContentClassName","MarkdownReader","content","sourceUrl","components","loading","className","contentClassName","loadingText","errorText","emptyText","allowImages","openLinksInNewTab","transformLinkHref","transformImageSrc","onLoadError","runtime","setRuntime","useState","runtimeLoading","setRuntimeLoading","runtimeError","setRuntimeError","remoteContent","setRemoteContent","remoteLoading","setRemoteLoading","remoteError","setRemoteError","onLoadErrorRef","useRef","Card","CardContent","Skeleton","useEffect","isMounted","markdownModule","gfmModule","err","nextError","_a","controller","response","text","markdown","displayedError","isLoading","isEmpty","markdownComponents","useMemo","href","children","props","nextHref","jsx","src","alt","nextSrc","checked","type","renderLoading","jsxs","Fragment","renderError","renderEmpty","renderContent","ReactMarkdown","remarkGfm","body","cn"],"mappings":"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"}