@lamberl-lee/file-preview 0.2.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 (263) hide show
  1. package/COPYING +674 -0
  2. package/LICENSE +165 -0
  3. package/README.md +165 -0
  4. package/dist/AudioPreview.d.ts +9 -0
  5. package/dist/AudioPreview.js +29 -0
  6. package/dist/AudioPreview.js.map +1 -0
  7. package/dist/CodePreview.d.ts +10 -0
  8. package/dist/CodePreview.js +121 -0
  9. package/dist/CodePreview.js.map +1 -0
  10. package/dist/CsvPreview.d.ts +9 -0
  11. package/dist/CsvPreview.js +117 -0
  12. package/dist/CsvPreview.js.map +1 -0
  13. package/dist/DocxPreview.d.ts +11 -0
  14. package/dist/DocxPreview.js +89 -0
  15. package/dist/DocxPreview.js.map +1 -0
  16. package/dist/EpubPreview.d.ts +9 -0
  17. package/dist/EpubPreview.js +693 -0
  18. package/dist/EpubPreview.js.map +1 -0
  19. package/dist/HtmlPreview.d.ts +9 -0
  20. package/dist/HtmlPreview.js +60 -0
  21. package/dist/HtmlPreview.js.map +1 -0
  22. package/dist/ImagePreview.d.ts +9 -0
  23. package/dist/ImagePreview.js +44 -0
  24. package/dist/ImagePreview.js.map +1 -0
  25. package/dist/LargeFileGate.d.ts +12 -0
  26. package/dist/LargeFileGate.js +88 -0
  27. package/dist/LargeFileGate.js.map +1 -0
  28. package/dist/MarkdownPreview.d.ts +8 -0
  29. package/dist/MarkdownPreview.js +140 -0
  30. package/dist/MarkdownPreview.js.map +1 -0
  31. package/dist/PdfPreview.d.ts +11 -0
  32. package/dist/PdfPreview.js +206 -0
  33. package/dist/PdfPreview.js.map +1 -0
  34. package/dist/PlainTextLargePreview.d.ts +9 -0
  35. package/dist/PlainTextLargePreview.js +62 -0
  36. package/dist/PlainTextLargePreview.js.map +1 -0
  37. package/dist/PluginPreviewRenderer.d.ts +13 -0
  38. package/dist/PluginPreviewRenderer.js +89 -0
  39. package/dist/PluginPreviewRenderer.js.map +1 -0
  40. package/dist/PptxPreview.d.ts +16 -0
  41. package/dist/PptxPreview.js +376 -0
  42. package/dist/PptxPreview.js.map +1 -0
  43. package/dist/PreviewErrorBoundary.d.ts +29 -0
  44. package/dist/PreviewErrorBoundary.js +53 -0
  45. package/dist/PreviewErrorBoundary.js.map +1 -0
  46. package/dist/PreviewFallback.d.ts +18 -0
  47. package/dist/PreviewFallback.js +143 -0
  48. package/dist/PreviewFallback.js.map +1 -0
  49. package/dist/PreviewLoading.d.ts +8 -0
  50. package/dist/PreviewLoading.js +14 -0
  51. package/dist/PreviewLoading.js.map +1 -0
  52. package/dist/RtfPreview.d.ts +10 -0
  53. package/dist/RtfPreview.js +240 -0
  54. package/dist/RtfPreview.js.map +1 -0
  55. package/dist/ShikiSourceView.d.ts +11 -0
  56. package/dist/ShikiSourceView.js +112 -0
  57. package/dist/ShikiSourceView.js.map +1 -0
  58. package/dist/SvgPreview.d.ts +9 -0
  59. package/dist/SvgPreview.js +89 -0
  60. package/dist/SvgPreview.js.map +1 -0
  61. package/dist/TextPreview.d.ts +9 -0
  62. package/dist/TextPreview.js +9 -0
  63. package/dist/TextPreview.js.map +1 -0
  64. package/dist/VideoPreview.d.ts +9 -0
  65. package/dist/VideoPreview.js +18 -0
  66. package/dist/VideoPreview.js.map +1 -0
  67. package/dist/XlsxPreview.d.ts +12 -0
  68. package/dist/XlsxPreview.js +856 -0
  69. package/dist/XlsxPreview.js.map +1 -0
  70. package/dist/ZipPreview.d.ts +9 -0
  71. package/dist/ZipPreview.js +153 -0
  72. package/dist/ZipPreview.js.map +1 -0
  73. package/dist/core/binary.d.ts +10 -0
  74. package/dist/core/binary.js +27 -0
  75. package/dist/core/binary.js.map +1 -0
  76. package/dist/core/config.d.ts +17 -0
  77. package/dist/core/config.js +19 -0
  78. package/dist/core/config.js.map +1 -0
  79. package/dist/core/download.d.ts +5 -0
  80. package/dist/core/download.js +20 -0
  81. package/dist/core/download.js.map +1 -0
  82. package/dist/core/i18n.d.ts +101 -0
  83. package/dist/core/i18n.js +200 -0
  84. package/dist/core/i18n.js.map +1 -0
  85. package/dist/core/plugin.d.ts +38 -0
  86. package/dist/core/plugin.js +46 -0
  87. package/dist/core/plugin.js.map +1 -0
  88. package/dist/core/registry.d.ts +13 -0
  89. package/dist/core/registry.js +33 -0
  90. package/dist/core/registry.js.map +1 -0
  91. package/dist/core/source.d.ts +14 -0
  92. package/dist/core/source.js +131 -0
  93. package/dist/core/source.js.map +1 -0
  94. package/dist/core/types.d.ts +88 -0
  95. package/dist/core/types.js +27 -0
  96. package/dist/core/types.js.map +1 -0
  97. package/dist/hooks/useObjectUrlFromSource.d.ts +9 -0
  98. package/dist/hooks/useObjectUrlFromSource.js +50 -0
  99. package/dist/hooks/useObjectUrlFromSource.js.map +1 -0
  100. package/dist/hooks/useSourceBase64.d.ts +10 -0
  101. package/dist/hooks/useSourceBase64.js +32 -0
  102. package/dist/hooks/useSourceBase64.js.map +1 -0
  103. package/dist/hooks/useSourceText.d.ts +10 -0
  104. package/dist/hooks/useSourceText.js +32 -0
  105. package/dist/hooks/useSourceText.js.map +1 -0
  106. package/dist/icons.d.ts +44 -0
  107. package/dist/icons.js +248 -0
  108. package/dist/icons.js.map +1 -0
  109. package/dist/index.d.ts +36 -0
  110. package/dist/index.js +147 -0
  111. package/dist/index.js.map +1 -0
  112. package/dist/limits.d.ts +26 -0
  113. package/dist/limits.js +45 -0
  114. package/dist/limits.js.map +1 -0
  115. package/dist/performance-limits.d.ts +27 -0
  116. package/dist/performance-limits.js +54 -0
  117. package/dist/performance-limits.js.map +1 -0
  118. package/dist/plugins/audio-plugin.d.ts +7 -0
  119. package/dist/plugins/audio-plugin.js +11 -0
  120. package/dist/plugins/audio-plugin.js.map +1 -0
  121. package/dist/plugins/builtin-plugins.d.ts +9 -0
  122. package/dist/plugins/builtin-plugins.js +43 -0
  123. package/dist/plugins/builtin-plugins.js.map +1 -0
  124. package/dist/plugins/csv-plugin.d.ts +7 -0
  125. package/dist/plugins/csv-plugin.js +11 -0
  126. package/dist/plugins/csv-plugin.js.map +1 -0
  127. package/dist/plugins/docx-plugin.d.ts +7 -0
  128. package/dist/plugins/docx-plugin.js +15 -0
  129. package/dist/plugins/docx-plugin.js.map +1 -0
  130. package/dist/plugins/epub-plugin.d.ts +7 -0
  131. package/dist/plugins/epub-plugin.js +15 -0
  132. package/dist/plugins/epub-plugin.js.map +1 -0
  133. package/dist/plugins/html-plugin.d.ts +7 -0
  134. package/dist/plugins/html-plugin.js +11 -0
  135. package/dist/plugins/html-plugin.js.map +1 -0
  136. package/dist/plugins/image-plugin.d.ts +7 -0
  137. package/dist/plugins/image-plugin.js +11 -0
  138. package/dist/plugins/image-plugin.js.map +1 -0
  139. package/dist/plugins/markdown-plugin.d.ts +7 -0
  140. package/dist/plugins/markdown-plugin.js +11 -0
  141. package/dist/plugins/markdown-plugin.js.map +1 -0
  142. package/dist/plugins/pdf-plugin.d.ts +7 -0
  143. package/dist/plugins/pdf-plugin.js +15 -0
  144. package/dist/plugins/pdf-plugin.js.map +1 -0
  145. package/dist/plugins/pptx-plugin.d.ts +7 -0
  146. package/dist/plugins/pptx-plugin.js +15 -0
  147. package/dist/plugins/pptx-plugin.js.map +1 -0
  148. package/dist/plugins/rtf-plugin.d.ts +7 -0
  149. package/dist/plugins/rtf-plugin.js +15 -0
  150. package/dist/plugins/rtf-plugin.js.map +1 -0
  151. package/dist/plugins/source-code-plugin.d.ts +7 -0
  152. package/dist/plugins/source-code-plugin.js +11 -0
  153. package/dist/plugins/source-code-plugin.js.map +1 -0
  154. package/dist/plugins/svg-plugin.d.ts +7 -0
  155. package/dist/plugins/svg-plugin.js +11 -0
  156. package/dist/plugins/svg-plugin.js.map +1 -0
  157. package/dist/plugins/text-plugin.d.ts +7 -0
  158. package/dist/plugins/text-plugin.js +11 -0
  159. package/dist/plugins/text-plugin.js.map +1 -0
  160. package/dist/plugins/video-plugin.d.ts +7 -0
  161. package/dist/plugins/video-plugin.js +11 -0
  162. package/dist/plugins/video-plugin.js.map +1 -0
  163. package/dist/plugins/xlsx-plugin.d.ts +7 -0
  164. package/dist/plugins/xlsx-plugin.js +15 -0
  165. package/dist/plugins/xlsx-plugin.js.map +1 -0
  166. package/dist/plugins/zip-plugin.d.ts +7 -0
  167. package/dist/plugins/zip-plugin.js +15 -0
  168. package/dist/plugins/zip-plugin.js.map +1 -0
  169. package/dist/preview-adapters/AudioPreviewAdapter.d.ts +8 -0
  170. package/dist/preview-adapters/AudioPreviewAdapter.js +31 -0
  171. package/dist/preview-adapters/AudioPreviewAdapter.js.map +1 -0
  172. package/dist/preview-adapters/CsvPreviewAdapter.d.ts +8 -0
  173. package/dist/preview-adapters/CsvPreviewAdapter.js +28 -0
  174. package/dist/preview-adapters/CsvPreviewAdapter.js.map +1 -0
  175. package/dist/preview-adapters/DocxPreviewAdapter.d.ts +8 -0
  176. package/dist/preview-adapters/DocxPreviewAdapter.js +16 -0
  177. package/dist/preview-adapters/DocxPreviewAdapter.js.map +1 -0
  178. package/dist/preview-adapters/EpubPreviewAdapter.d.ts +8 -0
  179. package/dist/preview-adapters/EpubPreviewAdapter.js +28 -0
  180. package/dist/preview-adapters/EpubPreviewAdapter.js.map +1 -0
  181. package/dist/preview-adapters/HtmlPreviewAdapter.d.ts +8 -0
  182. package/dist/preview-adapters/HtmlPreviewAdapter.js +28 -0
  183. package/dist/preview-adapters/HtmlPreviewAdapter.js.map +1 -0
  184. package/dist/preview-adapters/ImagePreviewAdapter.d.ts +8 -0
  185. package/dist/preview-adapters/ImagePreviewAdapter.js +31 -0
  186. package/dist/preview-adapters/ImagePreviewAdapter.js.map +1 -0
  187. package/dist/preview-adapters/MarkdownPreviewAdapter.d.ts +8 -0
  188. package/dist/preview-adapters/MarkdownPreviewAdapter.js +28 -0
  189. package/dist/preview-adapters/MarkdownPreviewAdapter.js.map +1 -0
  190. package/dist/preview-adapters/PdfPreviewAdapter.d.ts +8 -0
  191. package/dist/preview-adapters/PdfPreviewAdapter.js +16 -0
  192. package/dist/preview-adapters/PdfPreviewAdapter.js.map +1 -0
  193. package/dist/preview-adapters/PptxPreviewAdapter.d.ts +8 -0
  194. package/dist/preview-adapters/PptxPreviewAdapter.js +16 -0
  195. package/dist/preview-adapters/PptxPreviewAdapter.js.map +1 -0
  196. package/dist/preview-adapters/RtfPreviewAdapter.d.ts +8 -0
  197. package/dist/preview-adapters/RtfPreviewAdapter.js +54 -0
  198. package/dist/preview-adapters/RtfPreviewAdapter.js.map +1 -0
  199. package/dist/preview-adapters/SourceCodePreviewAdapter.d.ts +8 -0
  200. package/dist/preview-adapters/SourceCodePreviewAdapter.js +35 -0
  201. package/dist/preview-adapters/SourceCodePreviewAdapter.js.map +1 -0
  202. package/dist/preview-adapters/SvgPreviewAdapter.d.ts +8 -0
  203. package/dist/preview-adapters/SvgPreviewAdapter.js +28 -0
  204. package/dist/preview-adapters/SvgPreviewAdapter.js.map +1 -0
  205. package/dist/preview-adapters/TextPreviewAdapter.d.ts +8 -0
  206. package/dist/preview-adapters/TextPreviewAdapter.js +28 -0
  207. package/dist/preview-adapters/TextPreviewAdapter.js.map +1 -0
  208. package/dist/preview-adapters/UnsupportedPluginPreview.d.ts +11 -0
  209. package/dist/preview-adapters/UnsupportedPluginPreview.js +34 -0
  210. package/dist/preview-adapters/UnsupportedPluginPreview.js.map +1 -0
  211. package/dist/preview-adapters/VideoPreviewAdapter.d.ts +8 -0
  212. package/dist/preview-adapters/VideoPreviewAdapter.js +31 -0
  213. package/dist/preview-adapters/VideoPreviewAdapter.js.map +1 -0
  214. package/dist/preview-adapters/XlsxPreviewAdapter.d.ts +8 -0
  215. package/dist/preview-adapters/XlsxPreviewAdapter.js +17 -0
  216. package/dist/preview-adapters/XlsxPreviewAdapter.js.map +1 -0
  217. package/dist/preview-adapters/ZipPreviewAdapter.d.ts +8 -0
  218. package/dist/preview-adapters/ZipPreviewAdapter.js +28 -0
  219. package/dist/preview-adapters/ZipPreviewAdapter.js.map +1 -0
  220. package/dist/remote-url.d.ts +20 -0
  221. package/dist/remote-url.js +478 -0
  222. package/dist/remote-url.js.map +1 -0
  223. package/dist/rtf/load-rtfjs.d.ts +42 -0
  224. package/dist/rtf/load-rtfjs.js +71 -0
  225. package/dist/rtf/load-rtfjs.js.map +1 -0
  226. package/dist/rtf/normalize-codepage.d.ts +33 -0
  227. package/dist/rtf/normalize-codepage.js +88 -0
  228. package/dist/rtf/normalize-codepage.js.map +1 -0
  229. package/dist/shiki.d.ts +35 -0
  230. package/dist/shiki.js +128 -0
  231. package/dist/shiki.js.map +1 -0
  232. package/dist/styles/AudioPreview.css +35 -0
  233. package/dist/styles/CsvPreview.css +106 -0
  234. package/dist/styles/DocxPreview.css +93 -0
  235. package/dist/styles/EpubPreview.css +509 -0
  236. package/dist/styles/HtmlPreview.css +15 -0
  237. package/dist/styles/ImagePreview.css +45 -0
  238. package/dist/styles/LargeFileGate.css +55 -0
  239. package/dist/styles/MarkdownPreview.css +291 -0
  240. package/dist/styles/PdfPreview.css +68 -0
  241. package/dist/styles/PlainTextLargePreview.css +85 -0
  242. package/dist/styles/PluginDebugBar.css +30 -0
  243. package/dist/styles/PptxPreview.css +207 -0
  244. package/dist/styles/PreviewFallback.css +88 -0
  245. package/dist/styles/PreviewLoading.css +13 -0
  246. package/dist/styles/RtfPreview.css +99 -0
  247. package/dist/styles/ShikiSourceView.css +159 -0
  248. package/dist/styles/SvgPreview.css +99 -0
  249. package/dist/styles/VideoPreview.css +19 -0
  250. package/dist/styles/ViewModeBar.css +38 -0
  251. package/dist/styles/XlsxPreview.css +361 -0
  252. package/dist/styles/ZipPreview.css +86 -0
  253. package/dist/styles/base.css +238 -0
  254. package/dist/styles/index.css +39 -0
  255. package/dist/support-status.d.ts +19 -0
  256. package/dist/support-status.js +174 -0
  257. package/dist/support-status.js.map +1 -0
  258. package/dist/utils.d.ts +17 -0
  259. package/dist/utils.js +205 -0
  260. package/dist/utils.js.map +1 -0
  261. package/package.json +125 -0
  262. package/scripts/copy-pdf-worker.mjs +31 -0
  263. package/scripts/copy-rtfjs-bundles.mjs +49 -0
@@ -0,0 +1,88 @@
1
+ .fv-fallback {
2
+ display: flex;
3
+ height: 100%;
4
+ min-height: 320px;
5
+ align-items: center;
6
+ justify-content: center;
7
+ padding: 1.5rem;
8
+ }
9
+ .fv-fallback__inner {
10
+ max-width: 32rem;
11
+ text-align: center;
12
+ display: flex;
13
+ flex-direction: column;
14
+ gap: 1rem;
15
+ }
16
+ .fv-fallback__icon-wrap {
17
+ margin: 0 auto;
18
+ display: flex;
19
+ height: 3rem;
20
+ width: 3rem;
21
+ align-items: center;
22
+ justify-content: center;
23
+ border-radius: 9999px;
24
+ background: var(--fv-muted);
25
+ color: var(--fv-muted-foreground);
26
+ }
27
+ .fv-fallback__title {
28
+ font-size: var(--fv-font-size-lg);
29
+ font-weight: 600;
30
+ }
31
+ .fv-fallback__desc {
32
+ font-size: var(--fv-font-size-sm);
33
+ color: var(--fv-muted-foreground);
34
+ }
35
+ .fv-fallback__meta {
36
+ font-size: var(--fv-font-size-xs);
37
+ color: var(--fv-muted-foreground);
38
+ }
39
+ .fv-fallback__actions {
40
+ display: flex;
41
+ justify-content: center;
42
+ gap: 0.5rem;
43
+ }
44
+ .fv-fallback__details {
45
+ margin-top: 0.5rem;
46
+ width: 100%;
47
+ max-width: 24rem;
48
+ }
49
+ .fv-fallback__details-toggle {
50
+ font-size: 10px;
51
+ color: var(--fv-muted-foreground);
52
+ background: none;
53
+ border: none;
54
+ cursor: pointer;
55
+ text-decoration: underline;
56
+ padding: 0;
57
+ }
58
+ .fv-fallback__details-toggle:hover {
59
+ color: var(--fv-primary);
60
+ }
61
+ .fv-fallback__details-pre {
62
+ position: relative;
63
+ margin-top: 0.25rem;
64
+ border-radius: var(--fv-radius);
65
+ background: var(--fv-muted);
66
+ padding: 0.5rem;
67
+ font-size: 10px;
68
+ text-align: left;
69
+ overflow: auto;
70
+ max-height: 8rem;
71
+ white-space: pre-wrap;
72
+ word-break: break-all;
73
+ font-family: var(--fv-font-mono);
74
+ }
75
+ .fv-fallback__details-copy {
76
+ position: absolute;
77
+ top: 0.375rem;
78
+ right: 0.375rem;
79
+ padding: 0.25rem;
80
+ border-radius: var(--fv-radius);
81
+ border: none;
82
+ background: none;
83
+ color: var(--fv-muted-foreground);
84
+ cursor: pointer;
85
+ }
86
+ .fv-fallback__details-copy:hover {
87
+ background: color-mix(in srgb, var(--fv-muted-foreground) 20%, transparent);
88
+ }
@@ -0,0 +1,13 @@
1
+ .fv-loading {
2
+ display: flex;
3
+ flex-direction: column;
4
+ align-items: center;
5
+ justify-content: center;
6
+ height: 100%;
7
+ min-height: 300px;
8
+ gap: 0.75rem;
9
+ }
10
+ .fv-loading__label {
11
+ font-size: var(--fv-font-size-xs);
12
+ color: var(--fv-muted-foreground);
13
+ }
@@ -0,0 +1,99 @@
1
+ .fv-rtf {
2
+ display: flex;
3
+ flex-direction: column;
4
+ height: 100%;
5
+ }
6
+ .fv-rtf__topbar {
7
+ display: flex;
8
+ align-items: center;
9
+ justify-content: space-between;
10
+ border-bottom: 1px solid var(--fv-border);
11
+ background: color-mix(in srgb, var(--fv-muted) 20%, transparent);
12
+ padding: 0.375rem 0.75rem;
13
+ flex-shrink: 0;
14
+ }
15
+ .fv-rtf__topbar-left {
16
+ display: flex;
17
+ align-items: center;
18
+ gap: 0.5rem;
19
+ }
20
+ .fv-rtf__filename {
21
+ font-size: var(--fv-font-size-xs);
22
+ color: var(--fv-muted-foreground);
23
+ max-width: 200px;
24
+ overflow: hidden;
25
+ text-overflow: ellipsis;
26
+ white-space: nowrap;
27
+ }
28
+ .fv-rtf__filetype {
29
+ font-size: 10px;
30
+ color: color-mix(in srgb, var(--fv-muted-foreground) 60%, transparent);
31
+ }
32
+ .fv-rtf__content {
33
+ flex: 1;
34
+ min-height: 0;
35
+ }
36
+ .fv-rtf__loading {
37
+ display: flex;
38
+ align-items: center;
39
+ justify-content: center;
40
+ height: 100%;
41
+ font-size: var(--fv-font-size-sm);
42
+ color: var(--fv-muted-foreground);
43
+ }
44
+ .fv-rtf__iframe {
45
+ width: 100%;
46
+ height: 100%;
47
+ border: 0;
48
+ }
49
+ .fv-rtf-text-fallback {
50
+ overflow: auto;
51
+ height: 100%;
52
+ padding: 1.5rem;
53
+ }
54
+ .fv-rtf-text-fallback__inner {
55
+ max-width: 48rem;
56
+ margin: 0 auto;
57
+ }
58
+ .fv-rtf-text-fallback__warn {
59
+ margin-bottom: 1rem;
60
+ border-radius: var(--fv-radius);
61
+ border: 1px solid #fde68a;
62
+ background: #fffbeb;
63
+ padding: 0.75rem;
64
+ }
65
+ [data-fv-theme="dark"] .fv-rtf-text-fallback__warn {
66
+ border-color: rgba(180, 83, 9, 0.3);
67
+ background: rgba(180, 83, 9, 0.15);
68
+ }
69
+ .fv-rtf-text-fallback__warn-header {
70
+ display: flex;
71
+ align-items: center;
72
+ gap: 0.5rem;
73
+ color: #b45309;
74
+ }
75
+ [data-fv-theme="dark"] .fv-rtf-text-fallback__warn-header {
76
+ color: #fbbf24;
77
+ }
78
+ .fv-rtf-text-fallback__warn-text {
79
+ font-size: var(--fv-font-size-xs);
80
+ font-weight: 500;
81
+ }
82
+ .fv-rtf-text-fallback__paper {
83
+ background: var(--fv-primary-foreground, #fff);
84
+ border-radius: var(--fv-radius);
85
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
86
+ border: 1px solid var(--fv-border);
87
+ padding: 1.5rem;
88
+ display: flex;
89
+ flex-direction: column;
90
+ gap: 0.75rem;
91
+ }
92
+ .fv-rtf-text-fallback__p {
93
+ font-size: var(--fv-font-size-sm);
94
+ line-height: 1.625;
95
+ color: #374151;
96
+ }
97
+ [data-fv-theme="dark"] .fv-rtf-text-fallback__p {
98
+ color: #d1d5db;
99
+ }
@@ -0,0 +1,159 @@
1
+ /* ── Shiki Source View ── */
2
+
3
+ .fv-source {
4
+ display: flex;
5
+ flex-direction: column;
6
+ height: 100%;
7
+ }
8
+ .fv-source__toolbar {
9
+ display: flex;
10
+ align-items: center;
11
+ justify-content: space-between;
12
+ padding: 0.5rem 1rem;
13
+ border-bottom: 1px solid var(--fv-border);
14
+ background: color-mix(in srgb, var(--fv-muted) 30%, transparent);
15
+ }
16
+ .fv-source__toolbar-left {
17
+ display: flex;
18
+ align-items: center;
19
+ gap: 0.5rem;
20
+ }
21
+ .fv-source__toolbar-right {
22
+ display: flex;
23
+ align-items: center;
24
+ gap: 0.25rem;
25
+ }
26
+ .fv-source__lang-badge {
27
+ font-size: var(--fv-font-size-xs);
28
+ font-family: var(--fv-font-mono);
29
+ padding: 0.125rem 0.5rem;
30
+ border-radius: var(--fv-radius);
31
+ background: color-mix(in srgb, var(--fv-primary) 10%, transparent);
32
+ color: var(--fv-primary);
33
+ }
34
+ .fv-source__line-count {
35
+ font-size: var(--fv-font-size-xs);
36
+ color: var(--fv-muted-foreground);
37
+ }
38
+ .fv-source__btn-active {
39
+ background: color-mix(in srgb, var(--fv-primary) 10%, transparent);
40
+ color: var(--fv-primary);
41
+ }
42
+ .fv-source__content {
43
+ flex: 1;
44
+ overflow: auto;
45
+ }
46
+ .fv-source__loading {
47
+ display: flex;
48
+ align-items: center;
49
+ justify-content: center;
50
+ padding: 5rem 0;
51
+ }
52
+ .fv-source__loading-inner {
53
+ display: flex;
54
+ flex-direction: column;
55
+ align-items: center;
56
+ gap: 0.75rem;
57
+ }
58
+ .fv-source__loading-label {
59
+ font-size: var(--fv-font-size-xs);
60
+ color: var(--fv-muted-foreground);
61
+ }
62
+
63
+ /* ── Shiki wrapper ── */
64
+ .fv-shiki-wrapper pre {
65
+ margin: 0 !important;
66
+ padding: 1rem 1.5rem !important;
67
+ font-size: 0.8125rem !important;
68
+ line-height: 1.7 !important;
69
+ font-family: var(--fv-font-mono) !important;
70
+ overflow-x: auto;
71
+ tab-size: 2;
72
+ }
73
+ .fv-shiki-wrap pre { white-space: pre-wrap !important; word-break: break-word !important; }
74
+ .fv-shiki-wrap .line { white-space: pre-wrap; word-break: break-word; }
75
+ .fv-shiki-nowrap pre { white-space: pre !important; }
76
+ .fv-shiki-nowrap .line { white-space: pre; }
77
+
78
+ /* ── Line numbers ── */
79
+ .fv-shiki-wrapper .line {
80
+ min-height: 1.7em;
81
+ padding-left: 3.5em;
82
+ position: relative;
83
+ display: inline-block;
84
+ width: 100%;
85
+ }
86
+ .fv-shiki-wrapper .line::before {
87
+ content: attr(data-line);
88
+ position: absolute;
89
+ left: 0;
90
+ width: 2.5em;
91
+ text-align: right;
92
+ opacity: 0.3;
93
+ user-select: none;
94
+ font-variant-numeric: tabular-nums;
95
+ }
96
+
97
+ /* ── Dual theme switching ── */
98
+ .fv-shiki-wrapper .shiki {
99
+ background-color: var(--shiki-light-bg, #fff) !important;
100
+ color: var(--shiki-light, #24292e) !important;
101
+ }
102
+ .fv-shiki-wrapper .shiki span {
103
+ color: var(--shiki-light) !important;
104
+ background-color: var(--shiki-light-bg, transparent) !important;
105
+ }
106
+ .dark .fv-shiki-wrapper .shiki,
107
+ html.dark .fv-shiki-wrapper .shiki,
108
+ [data-fv-theme="dark"] .fv-shiki-wrapper .shiki {
109
+ background-color: var(--shiki-dark-bg, #24292e) !important;
110
+ color: var(--shiki-dark, #e1e4e8) !important;
111
+ }
112
+ .dark .fv-shiki-wrapper .shiki span,
113
+ html.dark .fv-shiki-wrapper .shiki span,
114
+ [data-fv-theme="dark"] .fv-shiki-wrapper .shiki span {
115
+ color: var(--shiki-dark) !important;
116
+ background-color: var(--shiki-dark-bg, transparent) !important;
117
+ }
118
+ @media (prefers-color-scheme: dark) {
119
+ :root:not(:has(.light)) .fv-shiki-wrapper .shiki {
120
+ background-color: var(--shiki-dark-bg, #24292e) !important;
121
+ color: var(--shiki-dark, #e1e4e8) !important;
122
+ }
123
+ :root:not(:has(.light)) .fv-shiki-wrapper .shiki span {
124
+ color: var(--shiki-dark) !important;
125
+ background-color: var(--shiki-dark-bg, transparent) !important;
126
+ }
127
+ }
128
+
129
+ /* ── Plain text fallback ── */
130
+ .fv-shiki-plaintext pre {
131
+ margin: 0;
132
+ padding: 1rem 1.5rem;
133
+ font-size: 0.8125rem;
134
+ line-height: 1.7;
135
+ font-family: var(--fv-font-mono);
136
+ background-color: var(--fv-code-bg);
137
+ color: var(--fv-code-fg);
138
+ white-space: pre-wrap;
139
+ word-break: break-word;
140
+ }
141
+ .fv-shiki-plaintext .line {
142
+ display: flex;
143
+ min-height: 1.7em;
144
+ }
145
+ .fv-shiki-plaintext .linenumber {
146
+ display: inline-block;
147
+ width: 2.5em;
148
+ text-align: right;
149
+ padding-right: 1em;
150
+ opacity: 0.3;
151
+ user-select: none;
152
+ flex-shrink: 0;
153
+ font-variant-numeric: tabular-nums;
154
+ }
155
+ .fv-shiki-plaintext .linecontent {
156
+ flex: 1;
157
+ white-space: pre-wrap;
158
+ word-break: break-word;
159
+ }
@@ -0,0 +1,99 @@
1
+ .fv-svg {
2
+ display: flex;
3
+ flex-direction: column;
4
+ height: 100%;
5
+ }
6
+ .fv-svg__mode-bar {
7
+ display: flex;
8
+ align-items: center;
9
+ border-bottom: 1px solid var(--fv-border);
10
+ background: color-mix(in srgb, var(--fv-muted) 20%, transparent);
11
+ }
12
+ .fv-svg__mode-group {
13
+ display: flex;
14
+ align-items: center;
15
+ padding: 0.25rem 0.5rem;
16
+ gap: 0.125rem;
17
+ }
18
+ .fv-svg__mode-btn {
19
+ display: inline-flex;
20
+ align-items: center;
21
+ gap: 0.375rem;
22
+ padding: 0.375rem 0.75rem;
23
+ font-size: var(--fv-font-size-xs);
24
+ font-weight: 500;
25
+ border-radius: var(--fv-radius);
26
+ border: 1px solid transparent;
27
+ background: none;
28
+ color: var(--fv-muted-foreground);
29
+ cursor: pointer;
30
+ transition: background 0.15s, color 0.15s;
31
+ }
32
+ .fv-svg__mode-btn:hover {
33
+ color: var(--fv-primary);
34
+ background: color-mix(in srgb, var(--fv-muted) 50%, transparent);
35
+ }
36
+ .fv-svg__mode-btn--active {
37
+ background: var(--fv-primary);
38
+ color: var(--fv-primary-foreground);
39
+ border-color: var(--fv-border);
40
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
41
+ }
42
+ .fv-svg__content {
43
+ flex: 1;
44
+ min-height: 0;
45
+ display: flex;
46
+ }
47
+ .fv-svg__panel {
48
+ display: flex;
49
+ flex-direction: column;
50
+ height: 100%;
51
+ width: 100%;
52
+ }
53
+ .fv-svg__panel--split {
54
+ width: 50%;
55
+ border-right: 1px solid var(--fv-border);
56
+ }
57
+ .fv-svg__panel--split-source {
58
+ width: 50%;
59
+ }
60
+ .fv-svg__toolbar {
61
+ display: flex;
62
+ align-items: center;
63
+ justify-content: center;
64
+ gap: 0.5rem;
65
+ padding: 0.5rem;
66
+ border-bottom: 1px solid var(--fv-border);
67
+ background: color-mix(in srgb, var(--fv-muted) 30%, transparent);
68
+ }
69
+ .fv-svg__zoom-label {
70
+ font-size: var(--fv-font-size-xs);
71
+ font-family: var(--fv-font-mono);
72
+ min-width: 3rem;
73
+ text-align: center;
74
+ }
75
+ .fv-svg__reset-btn {
76
+ padding: 0.25rem 0.5rem;
77
+ border-radius: var(--fv-radius);
78
+ font-size: var(--fv-font-size-xs);
79
+ background: none;
80
+ border: none;
81
+ cursor: pointer;
82
+ color: var(--fv-primary);
83
+ }
84
+ .fv-svg__reset-btn:hover {
85
+ background: var(--fv-muted);
86
+ }
87
+ .fv-svg__canvas {
88
+ flex: 1;
89
+ display: flex;
90
+ align-items: center;
91
+ justify-content: center;
92
+ padding: 1.5rem;
93
+ overflow: auto;
94
+ background: repeating-conic-gradient(rgba(128, 128, 128, 0.125) 0% 25%, transparent 0% 50%) 0 0 / 20px 20px;
95
+ }
96
+ .fv-svg__img {
97
+ max-width: 100%;
98
+ transition: transform 0.2s;
99
+ }
@@ -0,0 +1,19 @@
1
+ .fv-video {
2
+ display: flex;
3
+ align-items: center;
4
+ justify-content: center;
5
+ height: 100%;
6
+ min-height: 400px;
7
+ padding: 1.5rem;
8
+ background: color-mix(in srgb, #000 5%, transparent);
9
+ border-radius: var(--fv-radius);
10
+ }
11
+ [data-fv-theme="dark"] .fv-video {
12
+ background: color-mix(in srgb, #000 20%, transparent);
13
+ }
14
+ .fv-video__player {
15
+ max-width: 100%;
16
+ max-height: 70vh;
17
+ border-radius: var(--fv-radius);
18
+ box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
19
+ }
@@ -0,0 +1,38 @@
1
+ /* Shared view-mode-toggle bar — used by Markdown, Html, Rtf, Svg */
2
+
3
+ .fv-view-mode-bar {
4
+ display: flex;
5
+ align-items: center;
6
+ border-bottom: 1px solid var(--fv-border);
7
+ background: color-mix(in srgb, var(--fv-muted) 20%, transparent);
8
+ }
9
+ .fv-view-mode-group {
10
+ display: flex;
11
+ align-items: center;
12
+ padding: 0.25rem 0.5rem;
13
+ gap: 0.125rem;
14
+ }
15
+ .fv-view-mode-btn {
16
+ display: inline-flex;
17
+ align-items: center;
18
+ gap: 0.375rem;
19
+ padding: 0.375rem 0.75rem;
20
+ font-size: var(--fv-font-size-xs);
21
+ font-weight: 500;
22
+ border-radius: var(--fv-radius);
23
+ border: 1px solid transparent;
24
+ background: none;
25
+ color: var(--fv-muted-foreground);
26
+ cursor: pointer;
27
+ transition: background 0.15s, color 0.15s;
28
+ }
29
+ .fv-view-mode-btn:hover {
30
+ color: var(--fv-primary);
31
+ background: color-mix(in srgb, var(--fv-muted) 50%, transparent);
32
+ }
33
+ .fv-view-mode-btn--active {
34
+ background: var(--fv-primary-foreground, #fff);
35
+ color: var(--fv-primary);
36
+ border-color: var(--fv-border);
37
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
38
+ }