@eternalheart/react-file-preview 1.5.1 → 1.5.2

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 (53) hide show
  1. package/lib/chunks/{index-Dta7iGov.mjs → index-37FMdXja.mjs} +2 -2
  2. package/lib/chunks/{index-Dta7iGov.mjs.map → index-37FMdXja.mjs.map} +1 -1
  3. package/lib/chunks/{index-BFh22D_W.mjs → index-7aRho9r4.mjs} +3 -3
  4. package/lib/chunks/{index-BFh22D_W.mjs.map → index-7aRho9r4.mjs.map} +1 -1
  5. package/lib/chunks/{index-CgFv7B_G.mjs → index-BXa7r4uK.mjs} +3 -3
  6. package/lib/chunks/{index-CgFv7B_G.mjs.map → index-BXa7r4uK.mjs.map} +1 -1
  7. package/lib/chunks/{index-COOUxB5e.mjs → index-BaSsmMZP.mjs} +2 -2
  8. package/lib/chunks/{index-COOUxB5e.mjs.map → index-BaSsmMZP.mjs.map} +1 -1
  9. package/lib/chunks/{index-fSw6Hl5e.mjs → index-Bn0NJNzq.mjs} +2 -2
  10. package/lib/chunks/{index-fSw6Hl5e.mjs.map → index-Bn0NJNzq.mjs.map} +1 -1
  11. package/lib/chunks/{index-fQGAUFAX.mjs → index-Btsr3v83.mjs} +2 -2
  12. package/lib/chunks/{index-fQGAUFAX.mjs.map → index-Btsr3v83.mjs.map} +1 -1
  13. package/lib/chunks/{index-Bw3Fh4b5.mjs → index-C2uu09Eb.mjs} +2 -2
  14. package/lib/chunks/{index-Bw3Fh4b5.mjs.map → index-C2uu09Eb.mjs.map} +1 -1
  15. package/lib/chunks/{index-vRLKumL8.mjs → index-C5o_T3Es.mjs} +18 -19
  16. package/lib/chunks/index-C5o_T3Es.mjs.map +1 -0
  17. package/lib/chunks/{index-Cn4ZyhGM.mjs → index-CMehLA91.mjs} +2 -2
  18. package/lib/chunks/{index-Cn4ZyhGM.mjs.map → index-CMehLA91.mjs.map} +1 -1
  19. package/lib/chunks/{index-jvNrkVkp.mjs → index-CTEgp9x8.mjs} +2 -2
  20. package/lib/chunks/{index-jvNrkVkp.mjs.map → index-CTEgp9x8.mjs.map} +1 -1
  21. package/lib/chunks/{index-DreA69iU.mjs → index-Cbp94jbP.mjs} +20 -20
  22. package/lib/chunks/{index-DreA69iU.mjs.map → index-Cbp94jbP.mjs.map} +1 -1
  23. package/lib/chunks/{index-CU1Lc3lV.mjs → index-CmK5E5Oa.mjs} +3 -3
  24. package/lib/chunks/{index-CU1Lc3lV.mjs.map → index-CmK5E5Oa.mjs.map} +1 -1
  25. package/lib/chunks/index-CyBXARuf.mjs +5215 -0
  26. package/lib/chunks/index-CyBXARuf.mjs.map +1 -0
  27. package/lib/chunks/{index-DVtPyN-s.mjs → index-DTNdG1bB.mjs} +3 -3
  28. package/lib/chunks/{index-DVtPyN-s.mjs.map → index-DTNdG1bB.mjs.map} +1 -1
  29. package/lib/chunks/{index-oVJyD-FV.mjs → index-DfzgQFfx.mjs} +2 -2
  30. package/lib/chunks/{index-oVJyD-FV.mjs.map → index-DfzgQFfx.mjs.map} +1 -1
  31. package/lib/chunks/{index-CEC_DHgr.mjs → index-DsIUJXpz.mjs} +8 -9
  32. package/lib/chunks/index-DsIUJXpz.mjs.map +1 -0
  33. package/lib/chunks/{index-DGNNEnWE.mjs → index-DxUP4apX.mjs} +2 -2
  34. package/lib/chunks/{index-DGNNEnWE.mjs.map → index-DxUP4apX.mjs.map} +1 -1
  35. package/lib/chunks/{index-BBYKNNLb.mjs → index-HRUhzosx.mjs} +2 -2
  36. package/lib/chunks/{index-BBYKNNLb.mjs.map → index-HRUhzosx.mjs.map} +1 -1
  37. package/lib/chunks/{index-BKXvtJh5.mjs → index-VnjkEX5p.mjs} +2 -2
  38. package/lib/chunks/{index-BKXvtJh5.mjs.map → index-VnjkEX5p.mjs.map} +1 -1
  39. package/lib/chunks/{index-DLk08ylq.mjs → index-qWLZuYn6.mjs} +2 -2
  40. package/lib/chunks/{index-DLk08ylq.mjs.map → index-qWLZuYn6.mjs.map} +1 -1
  41. package/lib/chunks/{useShikiHighlight-C6nJcETW.mjs → useShikiHighlight-BG7pCfB5.mjs} +2 -2
  42. package/lib/chunks/{useShikiHighlight-C6nJcETW.mjs.map → useShikiHighlight-BG7pCfB5.mjs.map} +1 -1
  43. package/lib/index.cjs +1 -1
  44. package/lib/index.cjs.map +1 -1
  45. package/lib/index.css +1 -1
  46. package/lib/index.mjs +1 -1
  47. package/lib/renderers/Csv/index.d.ts +0 -1
  48. package/lib/renderers/Csv/index.d.ts.map +1 -1
  49. package/lib/renderers/Xlsx/index.d.ts +0 -1
  50. package/lib/renderers/Xlsx/index.d.ts.map +1 -1
  51. package/package.json +1 -1
  52. package/lib/chunks/index-CEC_DHgr.mjs.map +0 -1
  53. package/lib/chunks/index-vRLKumL8.mjs.map +0 -1
@@ -1,7 +1,7 @@
1
1
  import { jsx as e, jsxs as R } from "react/jsx-runtime";
2
2
  import { forwardRef as S, useState as s, useEffect as m, useRef as j, useCallback as i, useImperativeHandle as P, Fragment as $ } from "react";
3
- import { u as z, a as A, y as F, z as I } from "./index-DreA69iU.mjs";
4
- import { u as L } from "./useShikiHighlight-C6nJcETW.mjs";
3
+ import { u as z, a as A, y as F, z as I } from "./index-Cbp94jbP.mjs";
4
+ import { u as L } from "./useShikiHighlight-BG7pCfB5.mjs";
5
5
  import { R as D } from "./RendererError-D5i8eSpN.mjs";
6
6
  import { WrapText as G, Code as M, Eye as q } from "lucide-react";
7
7
  const V = S(({
@@ -117,4 +117,4 @@ const V = S(({
117
117
  export {
118
118
  V as TextRenderer
119
119
  };
120
- //# sourceMappingURL=index-CU1Lc3lV.mjs.map
120
+ //# sourceMappingURL=index-CmK5E5Oa.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index-CU1Lc3lV.mjs","sources":["../../src/renderers/Text/index.tsx"],"sourcesContent":["import { useState, useEffect, Fragment, forwardRef, useCallback, useImperativeHandle, useRef } from 'react';\nimport { fetchTextUtf8, getLanguageFromFileName } from '@eternalheart/file-preview-core';\nimport { useTranslator } from '../../i18n/LocaleContext';\nimport { useFetcher } from '../../RequestContext';\nimport { useShikiHighlight } from '../../hooks/useShikiHighlight';\nimport { RendererError } from '../RendererError';\nimport { WrapText, Code, Eye } from 'lucide-react';\nimport type { RendererHandle } from '../base.types';\nimport type { ToolbarGroup } from '../toolbar.types';\n\ninterface TextRendererProps {\n url: string;\n fileName: string;\n}\n\nexport const TextRenderer = forwardRef<RendererHandle, TextRendererProps>(({\n url,\n fileName,\n}, ref) => {\n const t = useTranslator();\n const fetcher = useFetcher();\n\n // 内部状态管理\n const [content, setContent] = useState<string>('');\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [wordWrap, setWordWrap] = useState(true);\n const [htmlPreview, setHtmlPreview] = useState(false);\n\n const language = getLanguageFromFileName(fileName);\n const { lineHtmls } = useShikiHighlight(\n language !== 'text' ? content : '',\n language,\n );\n\n useEffect(() => {\n const controller = new AbortController();\n const loadText = async () => {\n try {\n setLoading(true);\n setError(null);\n const text = await fetchTextUtf8(url, { fetcher, signal: controller.signal });\n setContent(text);\n } catch (err: any) {\n if (err.name === 'AbortError') return;\n setError(t('text.load_failed'));\n console.error(err);\n } finally {\n setLoading(false);\n }\n };\n\n loadText();\n return () => controller.abort();\n }, [url]);\n\n // 事件发射器:用于通知主组件工具栏状态变化\n const listenersRef = useRef<Set<() => void>>(new Set());\n const notifyToolbarChange = useCallback(() => {\n listenersRef.current.forEach(listener => listener());\n }, []);\n\n // 监听影响工具栏的状态变化\n useEffect(() => {\n notifyToolbarChange();\n }, [wordWrap, notifyToolbarChange]);\n\n useEffect(() => {\n notifyToolbarChange();\n }, [htmlPreview, notifyToolbarChange]);\n\n // 切换操作\n const toggleWordWrap = useCallback(() => {\n setWordWrap(prev => !prev);\n }, []);\n\n const toggleHtmlPreview = useCallback(() => {\n setHtmlPreview(prev => !prev);\n }, []);\n\n // 工具栏配置\n const getToolbarGroups = useCallback((): ToolbarGroup[] => {\n const groups: ToolbarGroup[] = [\n {\n items: [\n {\n type: 'button',\n icon: <WrapText className=\"rfp-w-4 rfp-h-4\" />,\n tooltip: wordWrap ? t('toolbar.wrap_off') : t('toolbar.wrap_on'),\n action: toggleWordWrap,\n active: wordWrap,\n },\n ],\n },\n ];\n\n // HTML 文件显示预览按钮\n if (language === 'html') {\n groups.push({\n items: [\n {\n type: 'button',\n icon: htmlPreview\n ? <Code className=\"rfp-w-4 rfp-h-4\" />\n : <Eye className=\"rfp-w-4 rfp-h-4\" />,\n tooltip: htmlPreview ? t('toolbar.source') : t('toolbar.preview'),\n action: toggleHtmlPreview,\n active: htmlPreview,\n },\n ],\n });\n }\n\n return groups;\n }, [wordWrap, htmlPreview, language, t, toggleWordWrap, toggleHtmlPreview]);\n\n // 暴露接口给父组件\n useImperativeHandle(ref, () => ({\n getToolbarGroups,\n onToolbarChange: (listener: () => void) => {\n listenersRef.current.add(listener);\n return () => listenersRef.current.delete(listener);\n },\n }), [getToolbarGroups]);\n\n if (loading) {\n return (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full\">\n <div className=\"rfp-w-12 rfp-h-12 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin\" />\n </div>\n );\n }\n\n if (error) {\n return <RendererError message={error} />;\n }\n\n // HTML 预览模式\n if (htmlPreview && (language === 'html')) {\n return (\n <div className=\"rfp-w-full rfp-h-full rfp-bg-surface-toolbar\">\n <iframe\n srcDoc={content}\n sandbox=\"allow-same-origin\"\n className=\"rfp-w-full rfp-h-full rfp-border-0\"\n title={fileName}\n />\n </div>\n );\n }\n\n // 纯文本或高亮未就绪:fallback 到普通 pre\n if (language === 'text' || lineHtmls.length === 0) {\n return (\n <div className=\"rfp-w-full rfp-h-full rfp-overflow-auto rfp-bg-code-bg\">\n <pre\n className={`rfp-py-6 rfp-px-4 rfp-text-fg-primary rfp-font-mono rfp-text-sm ${\n wordWrap ? 'rfp-whitespace-pre-wrap rfp-break-words' : 'rfp-whitespace-pre'\n }`}\n >\n {content}\n </pre>\n </div>\n );\n }\n\n // 双列布局:左 gutter(行号),右 code(shiki 高亮)\n const lines = content.split('\\n');\n return (\n <div className=\"rfp-w-full rfp-h-full rfp-overflow-auto rfp-bg-code-bg\">\n <div\n className={`rfp-code-block with-line-numbers ${wordWrap ? '' : 'no-wrap'} rfp-w-full`}\n style={{ gridTemplateRows: `repeat(${lines.length}, auto) minmax(1.5rem, 1fr)` }}\n >\n {lines.map((_, i) => (\n <Fragment key={i}>\n <span className=\"rfp-code-gutter\">{i + 1}</span>\n <span\n className=\"rfp-code-line\"\n dangerouslySetInnerHTML={{ __html: lineHtmls[i] ?? '' }}\n />\n </Fragment>\n ))}\n {/* 占位行:撑满剩余高度,让 gutter border 延伸到底部 */}\n <span className=\"rfp-code-gutter-filler\" />\n <span className=\"rfp-code-line-filler\" />\n </div>\n </div>\n );\n});\n"],"names":["TextRenderer","forwardRef","url","fileName","ref","useTranslator","fetcher","useFetcher","content","setContent","useState","loading","setLoading","error","setError","wordWrap","setWordWrap","htmlPreview","setHtmlPreview","language","getLanguageFromFileName","lineHtmls","useShikiHighlight","useEffect","controller","text","fetchTextUtf8","err","listenersRef","useRef","notifyToolbarChange","useCallback","listener","toggleWordWrap","prev","toggleHtmlPreview","getToolbarGroups","groups","jsx","WrapText","Code","Eye","useImperativeHandle","RendererError","lines","jsxs","_","i","Fragment"],"mappings":"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"}
1
+ {"version":3,"file":"index-CmK5E5Oa.mjs","sources":["../../src/renderers/Text/index.tsx"],"sourcesContent":["import { useState, useEffect, Fragment, forwardRef, useCallback, useImperativeHandle, useRef } from 'react';\nimport { fetchTextUtf8, getLanguageFromFileName } from '@eternalheart/file-preview-core';\nimport { useTranslator } from '../../i18n/LocaleContext';\nimport { useFetcher } from '../../RequestContext';\nimport { useShikiHighlight } from '../../hooks/useShikiHighlight';\nimport { RendererError } from '../RendererError';\nimport { WrapText, Code, Eye } from 'lucide-react';\nimport type { RendererHandle } from '../base.types';\nimport type { ToolbarGroup } from '../toolbar.types';\n\ninterface TextRendererProps {\n url: string;\n fileName: string;\n}\n\nexport const TextRenderer = forwardRef<RendererHandle, TextRendererProps>(({\n url,\n fileName,\n}, ref) => {\n const t = useTranslator();\n const fetcher = useFetcher();\n\n // 内部状态管理\n const [content, setContent] = useState<string>('');\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [wordWrap, setWordWrap] = useState(true);\n const [htmlPreview, setHtmlPreview] = useState(false);\n\n const language = getLanguageFromFileName(fileName);\n const { lineHtmls } = useShikiHighlight(\n language !== 'text' ? content : '',\n language,\n );\n\n useEffect(() => {\n const controller = new AbortController();\n const loadText = async () => {\n try {\n setLoading(true);\n setError(null);\n const text = await fetchTextUtf8(url, { fetcher, signal: controller.signal });\n setContent(text);\n } catch (err: any) {\n if (err.name === 'AbortError') return;\n setError(t('text.load_failed'));\n console.error(err);\n } finally {\n setLoading(false);\n }\n };\n\n loadText();\n return () => controller.abort();\n }, [url]);\n\n // 事件发射器:用于通知主组件工具栏状态变化\n const listenersRef = useRef<Set<() => void>>(new Set());\n const notifyToolbarChange = useCallback(() => {\n listenersRef.current.forEach(listener => listener());\n }, []);\n\n // 监听影响工具栏的状态变化\n useEffect(() => {\n notifyToolbarChange();\n }, [wordWrap, notifyToolbarChange]);\n\n useEffect(() => {\n notifyToolbarChange();\n }, [htmlPreview, notifyToolbarChange]);\n\n // 切换操作\n const toggleWordWrap = useCallback(() => {\n setWordWrap(prev => !prev);\n }, []);\n\n const toggleHtmlPreview = useCallback(() => {\n setHtmlPreview(prev => !prev);\n }, []);\n\n // 工具栏配置\n const getToolbarGroups = useCallback((): ToolbarGroup[] => {\n const groups: ToolbarGroup[] = [\n {\n items: [\n {\n type: 'button',\n icon: <WrapText className=\"rfp-w-4 rfp-h-4\" />,\n tooltip: wordWrap ? t('toolbar.wrap_off') : t('toolbar.wrap_on'),\n action: toggleWordWrap,\n active: wordWrap,\n },\n ],\n },\n ];\n\n // HTML 文件显示预览按钮\n if (language === 'html') {\n groups.push({\n items: [\n {\n type: 'button',\n icon: htmlPreview\n ? <Code className=\"rfp-w-4 rfp-h-4\" />\n : <Eye className=\"rfp-w-4 rfp-h-4\" />,\n tooltip: htmlPreview ? t('toolbar.source') : t('toolbar.preview'),\n action: toggleHtmlPreview,\n active: htmlPreview,\n },\n ],\n });\n }\n\n return groups;\n }, [wordWrap, htmlPreview, language, t, toggleWordWrap, toggleHtmlPreview]);\n\n // 暴露接口给父组件\n useImperativeHandle(ref, () => ({\n getToolbarGroups,\n onToolbarChange: (listener: () => void) => {\n listenersRef.current.add(listener);\n return () => listenersRef.current.delete(listener);\n },\n }), [getToolbarGroups]);\n\n if (loading) {\n return (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full\">\n <div className=\"rfp-w-12 rfp-h-12 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin\" />\n </div>\n );\n }\n\n if (error) {\n return <RendererError message={error} />;\n }\n\n // HTML 预览模式\n if (htmlPreview && (language === 'html')) {\n return (\n <div className=\"rfp-w-full rfp-h-full rfp-bg-surface-toolbar\">\n <iframe\n srcDoc={content}\n sandbox=\"allow-same-origin\"\n className=\"rfp-w-full rfp-h-full rfp-border-0\"\n title={fileName}\n />\n </div>\n );\n }\n\n // 纯文本或高亮未就绪:fallback 到普通 pre\n if (language === 'text' || lineHtmls.length === 0) {\n return (\n <div className=\"rfp-w-full rfp-h-full rfp-overflow-auto rfp-bg-code-bg\">\n <pre\n className={`rfp-py-6 rfp-px-4 rfp-text-fg-primary rfp-font-mono rfp-text-sm ${\n wordWrap ? 'rfp-whitespace-pre-wrap rfp-break-words' : 'rfp-whitespace-pre'\n }`}\n >\n {content}\n </pre>\n </div>\n );\n }\n\n // 双列布局:左 gutter(行号),右 code(shiki 高亮)\n const lines = content.split('\\n');\n return (\n <div className=\"rfp-w-full rfp-h-full rfp-overflow-auto rfp-bg-code-bg\">\n <div\n className={`rfp-code-block with-line-numbers ${wordWrap ? '' : 'no-wrap'} rfp-w-full`}\n style={{ gridTemplateRows: `repeat(${lines.length}, auto) minmax(1.5rem, 1fr)` }}\n >\n {lines.map((_, i) => (\n <Fragment key={i}>\n <span className=\"rfp-code-gutter\">{i + 1}</span>\n <span\n className=\"rfp-code-line\"\n dangerouslySetInnerHTML={{ __html: lineHtmls[i] ?? '' }}\n />\n </Fragment>\n ))}\n {/* 占位行:撑满剩余高度,让 gutter border 延伸到底部 */}\n <span className=\"rfp-code-gutter-filler\" />\n <span className=\"rfp-code-line-filler\" />\n </div>\n </div>\n );\n});\n"],"names":["TextRenderer","forwardRef","url","fileName","ref","useTranslator","fetcher","useFetcher","content","setContent","useState","loading","setLoading","error","setError","wordWrap","setWordWrap","htmlPreview","setHtmlPreview","language","getLanguageFromFileName","lineHtmls","useShikiHighlight","useEffect","controller","text","fetchTextUtf8","err","listenersRef","useRef","notifyToolbarChange","useCallback","listener","toggleWordWrap","prev","toggleHtmlPreview","getToolbarGroups","groups","jsx","WrapText","Code","Eye","useImperativeHandle","RendererError","lines","jsxs","_","i","Fragment"],"mappings":"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"}