sticky-file-tree 0.0.1 → 0.0.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 (2) hide show
  1. package/README.md +192 -0
  2. package/package.json +4 -4
package/README.md ADDED
@@ -0,0 +1,192 @@
1
+ # Sticky File Tree
2
+
3
+ A customizable File Tree component built specifically for the React 19 ecosystem. Featuring VS Code-style "Sticky Folding", intelligent sorting, and light/dark theme support.
4
+
5
+ ## Features
6
+
7
+ - 📂 **VS Code Style Sticky Headers:** Parent folders "stick" to the top while scrolling through their content.
8
+ - 🎨 **Dynamic Theming:** Color injection using CSS variables for instant theme switching.
9
+ - 🔡 **Auto-Sorting:** Intelligently sorts folders first, then files, both alphabetically.
10
+ - 🧩 **Component Slots:** Override any part of the tree (Icons, Labels) with your own React components.
11
+
12
+ ---
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ npm install sticky-file-tree
18
+
19
+ ```
20
+
21
+ ## Quick Start
22
+
23
+ ```tsx
24
+ import { useRef } from "react";
25
+ import { FileTree } from "sticky-file-tree";
26
+
27
+ const files = [
28
+ "src/components/Button.tsx",
29
+ "src/utils/format.ts",
30
+ "package.json",
31
+ "public/favicon.ico"
32
+ ];
33
+
34
+ function App() {
35
+ const ref = useRef<HTMLDivElement>(null);
36
+
37
+ return (
38
+ <div ref={ref} style={{ width: "320px", height: "640px" overflow: "auto" }}>
39
+ <FileTree
40
+ files={files}
41
+ scrollContainerRef={ref}
42
+ onFileSelect={(props) => console.log(props)}
43
+ />
44
+ </div>
45
+ );
46
+ }
47
+ ```
48
+
49
+ > **Note:** If you want to have the sticky behavior, you must pass the Ref of the parent scrollable element.
50
+
51
+ ---
52
+
53
+ ## Compatibility
54
+
55
+ **React 19+** This package is built exclusively for the React 19 ecosystem to leverage the latest performance optimizations. It does not support React 18 or older.
56
+
57
+ ---
58
+
59
+ ## Customization
60
+
61
+ ### The "Slot" Pattern
62
+
63
+ You can replace the default text or icons with your own components. This is useful for adding file-type specific icons (e.g., JS, TS, PDF).
64
+
65
+ ```tsx
66
+ <FileTree
67
+ fileOptions={{
68
+ icon: ({ name, selected }) => (
69
+ <span>{name.endsWith(".ts") ? "🟦" : "📄"}</span>
70
+ )
71
+ }}
72
+ />
73
+ ```
74
+
75
+ ### With a File Icon Library
76
+
77
+ You can also use a file/folder icon library to add file and folder specific icons.
78
+
79
+ ```tsx
80
+ import { useRef } from "react";
81
+ import { ArrowIcon, FileTree } from "sticky-file-tree";
82
+ import { FileIcon, FolderIcon } from "@react-symbols/icons/utils";
83
+
84
+ function App() {
85
+ const ref = useRef<HTMLDivElement>(null);
86
+
87
+ return (
88
+ <div ref={ref} style={{ width: "320px", height: "640px" overflow: "auto" }}>
89
+ <FileTree
90
+ files={files}
91
+ scrollContainerRef={ref}
92
+ fileOptions={{
93
+ icon: ({ name }) => (
94
+ <FileIcon
95
+ fileName={name}
96
+ style={{ width: "16px", height: "16px" }}
97
+ />
98
+ ),
99
+ depthOffset: ({ depth, depthDistance, gap }) => {
100
+ return depthDistance * (depth - 1) + gap + 16;
101
+ }
102
+ }}
103
+ folderOptions={{
104
+ icon: ({ name, open }) => (
105
+ <>
106
+ <ArrowIcon
107
+ style={{ rotate: open ? "90deg" : undefined }}
108
+ />
109
+ <FolderIcon
110
+ folderName={name}
111
+ style={{ width: "16px", height: "16px" }}
112
+ />
113
+ </>
114
+ )
115
+ }}
116
+ />
117
+ </div>
118
+ );
119
+ }
120
+ ```
121
+
122
+ > **Note:** By default, when using the custom file/folder elements, `Sticky File Tree` likely won't align the nodes as you want. For that, we can use `depthOffset` callback to provide the logic for the indentation.
123
+
124
+ ---
125
+
126
+ ## API Reference
127
+
128
+ ### 1. `FileTreeProps`
129
+
130
+ These are the primary props passed to the `<FileTree />` component.
131
+
132
+ | Prop | Type | Default | Description |
133
+ | -------------------- | ---------------------------------- | --------------------------------- | ----------------------------------------------------------------- |
134
+ | `files` | `string[]` | **Required** | Array of relative paths. Automatically parsed into a tree. |
135
+ | `onFileSelect` | `(props: CustomBaseProps) => void` | `undefined` | Callback returning the `path` and `name` of the clicked file. |
136
+ | `folding` | `boolean` | `true` | Enables VS Code-style sticky headers for folders. |
137
+ | `scrollContainerRef` | `RefObject<HTMLElement>` | `undefined` | **Required for folding.** Ref to the parent scrollable container. |
138
+ | `theme` | `"light" \| "dark"` | `"light"` | Sets the default color palette. |
139
+ | `depthDistance` | `number` | `16` | Horizontal indentation (px) per nesting level. |
140
+ | `paddingBottom` | `number` | `16` | Extra whitespace at the bottom of the tree. |
141
+ | `backgroundColor` | `string` | Light: `#ffffff`, Dark: `#161616` | Overrides the theme's base container background. |
142
+ | `nodeOptions` | `TreeNodeOptions` | See below | Global configuration for all rows (Files & Folders). |
143
+ | `fileOptions` | `TreeFileNodeOptions` | See below | Specific overrides for file (leaf) nodes. |
144
+ | `folderOptions` | `TreeFolderNodeOptions` | See below | Specific overrides for folder (branch) nodes. |
145
+
146
+ ---
147
+
148
+ ### 2. `nodeOptions`
149
+
150
+ Global settings applied to every node in the tree.
151
+
152
+ | Option | Type | Default | Description |
153
+ | -------------- | ------------------- | ----------------------------------------------------------- | ------------------------------------------------------ |
154
+ | `height` | `number` | `28` | Row height in pixels. |
155
+ | `gap` | `number` | `8` | Spacing between the icon and the text label. |
156
+ | `inlineOffset` | `number` | `{ left: 12, right: 4 }` | Horizontal padding inside the node row. |
157
+ | `depthOffset` | `(props) => number` | `({ depth, depthDistance }) => depthDistance * (depth - 1)` | Custom function to calculate indentation per level. |
158
+ | `colors` | `BaseColorsProps` | `Theme defaults` | Global color states (Default, Hover, Focus, Selected). |
159
+
160
+ ---
161
+
162
+ ### 3. `fileOptions`
163
+
164
+ Specific to files. Inherits options from `nodeOptions`.
165
+
166
+ | Option | Type | Description |
167
+ | ------ | ----------------------------- | -------------------------------------------------- |
168
+ | `icon` | `Component \| IconProps` | Custom file icon or props for the default icon. |
169
+ | `text` | `Component \| HTMLAttributes` | Custom label renderer or standard span attributes. |
170
+
171
+ ---
172
+
173
+ ### 4. `folderOptions`
174
+
175
+ Specific to folders. Inherits from `nodeOptions` (except `colors` which adds the `stuck` state).
176
+
177
+ | Option | Type | Description |
178
+ | --------------- | ----------------------------- | ------------------------------------------------------------------ |
179
+ | `icon` | `Component \| IconProps` | Custom folder icon (can change based on `open` state). |
180
+ | `text` | `Component \| HTMLAttributes` | Custom label renderer or standard span attributes. |
181
+ | `foldingShadow` | `string` | CSS box-shadow applied when a folder header is "stuck" at the top. |
182
+ | `colors.stuck` | `ColorProps` | Colors applied specifically when the folder is sticky/stuck. |
183
+
184
+ ---
185
+
186
+ ## Styling Hierarchy & Context
187
+
188
+ To keep your implementation clean, the `FileTree` uses a **cascading override system**. Understanding this is key to efficient styling:
189
+
190
+ 1. **Defaults:** The component looks at the `theme` prop ("light" or "dark").
191
+ 2. **Global Overrides:** Any value provided in `nodeOptions` replaces the theme default for _both_ files and folders.
192
+ 3. **Specific Overrides:** Values in `fileOptions` or `folderOptions` have the highest priority and override everything else.
package/package.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "name": "sticky-file-tree",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "description": "A customizable file tree component for React apps.",
5
- "homepage": "https://github.com/bhuvanpddahal/react-file-tree#readme",
5
+ "homepage": "https://github.com/bhuvanpddahal/sticky-file-tree#readme",
6
6
  "bugs": {
7
- "url": "https://github.com/bhuvanpddahal/react-file-tree/issues"
7
+ "url": "https://github.com/bhuvanpddahal/sticky-file-tree/issues"
8
8
  },
9
9
  "repository": {
10
10
  "type": "git",
11
- "url": "git+https://github.com/bhuvanpddahal/react-file-tree.git"
11
+ "url": "git+https://github.com/bhuvanpddahal/sticky-file-tree.git"
12
12
  },
13
13
  "license": "ISC",
14
14
  "author": "Bhuvan Dahal",