@particle-academy/fancy-code 0.5.1 → 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.
@@ -0,0 +1,78 @@
1
+ # FileViewer
2
+
3
+ A unified file viewer. Detects whether a file is **text** or **media** and
4
+ renders the right surface:
5
+
6
+ - **text** → a read-only `CodeEditor` with syntax highlighting picked from the
7
+ filename.
8
+ - **media** (image / video / audio / PDF) → react-fancy's [`<MediaViewer>`](https://github.com/Particle-Academy/react-fancy/blob/main/docs/MediaViewer.md),
9
+ always read-only.
10
+
11
+ This solves the "open an image in a code editor and get binary rendered as
12
+ text" problem for apps that show arbitrary files from a tree (e.g. an IDE
13
+ editor panel built on `CodeEditor` + `TreeNav`).
14
+
15
+ ## Import
16
+
17
+ ```tsx
18
+ import { FileViewer } from "@particle-academy/fancy-code";
19
+ ```
20
+
21
+ > **Peer requirement:** the media path uses `<MediaViewer>` from
22
+ > `@particle-academy/react-fancy` **>= 4.9**.
23
+
24
+ ## Usage
25
+
26
+ ```tsx
27
+ // text → CodeEditor (read-only, language from the filename)
28
+ <FileViewer filename="app.tsx" value={source} />
29
+
30
+ // media → <MediaViewer> (give it the file URL via `src`, and a height)
31
+ <FileViewer filename="diagram.png" src={url} style={{ height: 360 }} />
32
+
33
+ // editable text
34
+ <FileViewer filename="notes.md" value={md} onChange={setMd} readOnly={false} />
35
+ ```
36
+
37
+ ## Props
38
+
39
+ | Prop | Type | Default | Description |
40
+ |------|------|---------|-------------|
41
+ | filename | `string` | — | File name / path — drives detection + language, used as label/alt |
42
+ | mime | `string` | — | MIME type — preferred over `filename` for detection |
43
+ | src | `string` | — | Source URL for **media** files (`http(s):` / `data:` / `blob:`) |
44
+ | value | `string` | `""` | Text content for **text** files |
45
+ | onChange | `(value: string) => void` | — | Text change handler (ignored when `readOnly`) |
46
+ | readOnly | `boolean` | `true` | Read-only. Media is always read-only |
47
+ | theme | `string` | `"auto"` | Editor theme for text (`light` / `dark` / `auto` / registered) |
48
+ | fileKind | `FileKind` | — | Force the kind, bypassing detection |
49
+ | lineNumbers | `boolean` | `true` | Line numbers in the text editor |
50
+ | wordWrap | `boolean` | `false` | Wrap long lines in the text editor |
51
+ | minHeight / maxHeight | `number` | — | Editor height bounds (px) |
52
+ | mediaProps | `Partial<MediaViewerProps>` | — | Extra props forwarded to `<MediaViewer>` |
53
+ | className | `string` | — | Classes for the wrapper |
54
+ | style | `CSSProperties` | — | Styles for the wrapper (e.g. a height for media) |
55
+
56
+ The wrapper carries stable handles: `data-fancy-file-viewer`, `data-kind`
57
+ (`"text"` / `"media"`), and `data-media-kind` for media.
58
+
59
+ ## `resolveFileKind` / `languageFromFilename`
60
+
61
+ The detection logic is exported so you can branch your own chrome (tabs, save
62
+ buttons, download actions) the same way `FileViewer` does internally.
63
+
64
+ ```ts
65
+ import { resolveFileKind, languageFromFilename } from "@particle-academy/fancy-code";
66
+
67
+ resolveFileKind({ filename: "logo.png" }); // { kind: "media", mediaKind: "image" }
68
+ resolveFileKind({ filename: "app.tsx" }); // { kind: "text", language: "typescript" }
69
+ resolveFileKind({ mime: "application/pdf" }); // { kind: "media", mediaKind: "pdf" }
70
+
71
+ languageFromFilename("server.go"); // "go"
72
+ languageFromFilename("data.unknown"); // "plaintext"
73
+ ```
74
+
75
+ `FileKind` is `{ kind: "text"; language: string } | { kind: "media"; mediaKind: MediaKind }`.
76
+ MIME wins over the filename when both are given. Text files with no known
77
+ extension resolve to the `"plaintext"` language (no highlighting). SVG resolves
78
+ to a media **image**, not text.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@particle-academy/fancy-code",
3
- "version": "0.5.1",
3
+ "version": "0.6.0",
4
4
  "description": "Lightweight embedded code editor with syntax highlighting and extensible language/theme registries",
5
5
  "repository": {
6
6
  "type": "git",
@@ -39,12 +39,12 @@
39
39
  "prepublishOnly": "tsup"
40
40
  },
41
41
  "peerDependencies": {
42
- "@particle-academy/react-fancy": ">=2",
42
+ "@particle-academy/react-fancy": ">=4.9.0",
43
43
  "react": "^18.0.0 || ^19.0.0",
44
44
  "react-dom": "^18.0.0 || ^19.0.0"
45
45
  },
46
46
  "devDependencies": {
47
- "@particle-academy/react-fancy": "^4.0.0",
47
+ "@particle-academy/react-fancy": "^4.9.0",
48
48
  "@types/react": "^19.0.0",
49
49
  "@types/react-dom": "^19.0.0",
50
50
  "react": "^19.0.0",