bough 0.1.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.
- package/README.md +219 -0
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.mjs +673 -0
- package/dist/index.mjs.map +1 -0
- package/dist/styles.css +1 -0
- package/dist/vite.svg +1 -0
- package/package.json +85 -0
package/README.md
ADDED
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
# Bough
|
|
2
|
+
|
|
3
|
+
A flexible, accessible tree primitives library for React. Build file explorers, navigation menus, and complex hierarchical data displays.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Simple or Full Control** – Use `Tree.Recursive` for quick setup, or primitives for complete customization.
|
|
8
|
+
- **WAI-ARIA Compliant** – Keyboard navigation and screen reader support built-in.
|
|
9
|
+
- **Data Utilities** – Built-in functions for searching, filtering, and flattening tree data.
|
|
10
|
+
- **TypeScript Ready** – Full type definitions with generic support for custom node data.
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm install bough
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Quick Start
|
|
19
|
+
|
|
20
|
+
Use `Tree.Recursive` for the simplest setup – it handles all the recursive rendering for you:
|
|
21
|
+
|
|
22
|
+
```tsx
|
|
23
|
+
import { Tree, type TreeNode } from 'bough';
|
|
24
|
+
import 'bough/styles.css'; // Optional default styles
|
|
25
|
+
|
|
26
|
+
const nodes: TreeNode[] = [
|
|
27
|
+
{
|
|
28
|
+
id: "docs",
|
|
29
|
+
name: "Documents",
|
|
30
|
+
children: [
|
|
31
|
+
{ id: "report", name: "Report.pdf" },
|
|
32
|
+
]
|
|
33
|
+
},
|
|
34
|
+
{ id: "downloads", name: "Downloads" },
|
|
35
|
+
];
|
|
36
|
+
|
|
37
|
+
function App() {
|
|
38
|
+
return (
|
|
39
|
+
<div className="tree"> {/* CSS variable scope */}
|
|
40
|
+
<Tree.Root aria-label="Files" defaultExpandedIds={["docs"]} className="tree__root">
|
|
41
|
+
<Tree.Recursive
|
|
42
|
+
nodes={nodes}
|
|
43
|
+
renderContent={({ name }) => <span>{name}</span>}
|
|
44
|
+
/>
|
|
45
|
+
</Tree.Root>
|
|
46
|
+
</div>
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
That's it! Keyboard navigation, ARIA attributes, expand/collapse animations, and default styling all work automatically.
|
|
52
|
+
|
|
53
|
+
For unstyled/headless usage, set `styled={false}`:
|
|
54
|
+
|
|
55
|
+
```tsx
|
|
56
|
+
<Tree.Recursive nodes={nodes} styled={false} renderContent={...} />
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Custom Node Data
|
|
60
|
+
|
|
61
|
+
Attach custom data to nodes and render them however you want:
|
|
62
|
+
|
|
63
|
+
```tsx
|
|
64
|
+
interface FileData {
|
|
65
|
+
type: "folder" | "file";
|
|
66
|
+
size?: number;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const nodes: TreeNode<FileData>[] = [
|
|
70
|
+
{
|
|
71
|
+
id: "src",
|
|
72
|
+
name: "src",
|
|
73
|
+
data: { type: "folder" },
|
|
74
|
+
children: [
|
|
75
|
+
{ id: "index", name: "index.ts", data: { type: "file", size: 1024 } },
|
|
76
|
+
],
|
|
77
|
+
},
|
|
78
|
+
];
|
|
79
|
+
|
|
80
|
+
function FileRow({ name, data }: TreeNode<FileData>) {
|
|
81
|
+
return (
|
|
82
|
+
<>
|
|
83
|
+
{data?.type === "folder" ? "📁" : "📄"}
|
|
84
|
+
<span>{name}</span>
|
|
85
|
+
{data?.size && <span className="text-gray-400 ml-2">{data.size} bytes</span>}
|
|
86
|
+
</>
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
<Tree.Root aria-label="Files">
|
|
91
|
+
<Tree.Recursive nodes={nodes} renderContent={FileRow} />
|
|
92
|
+
</Tree.Root>
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Full Control with Primitives
|
|
96
|
+
|
|
97
|
+
For complete control over the DOM structure, use the primitives directly:
|
|
98
|
+
|
|
99
|
+
```tsx
|
|
100
|
+
function TreeItem({ node, level, index, total, parentId = null }) {
|
|
101
|
+
const hasChildren = node.children?.length > 0;
|
|
102
|
+
|
|
103
|
+
return (
|
|
104
|
+
<Tree.Item node={node} level={level} posinset={index + 1} setsize={total} parentId={parentId}>
|
|
105
|
+
{({ isExpanded, isSelected, isFocused, nodeId }) => (
|
|
106
|
+
<>
|
|
107
|
+
<Tree.ItemContent className={isSelected ? "bg-blue-100" : ""}>
|
|
108
|
+
<Tree.Chevron />
|
|
109
|
+
<span>{node.name}</span>
|
|
110
|
+
</Tree.ItemContent>
|
|
111
|
+
{hasChildren && (
|
|
112
|
+
<Tree.Group className="ml-6">
|
|
113
|
+
{node.children.map((child, i) => (
|
|
114
|
+
<TreeItem
|
|
115
|
+
key={child.id}
|
|
116
|
+
node={child}
|
|
117
|
+
level={level + 1}
|
|
118
|
+
index={i}
|
|
119
|
+
total={node.children.length}
|
|
120
|
+
parentId={nodeId}
|
|
121
|
+
/>
|
|
122
|
+
))}
|
|
123
|
+
</Tree.Group>
|
|
124
|
+
)}
|
|
125
|
+
</>
|
|
126
|
+
)}
|
|
127
|
+
</Tree.Item>
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## Primitives Reference
|
|
133
|
+
|
|
134
|
+
| Component | Purpose |
|
|
135
|
+
|-----------|---------|
|
|
136
|
+
| `Tree.Root` | Container that manages state and keyboard navigation |
|
|
137
|
+
| `Tree.Recursive` | Handles recursive rendering (the easy path) |
|
|
138
|
+
| `Tree.Item` | Individual tree node with ARIA attributes |
|
|
139
|
+
| `Tree.ItemContent` | Clickable content area (handles selection/expansion) |
|
|
140
|
+
| `Tree.Chevron` | Expand/collapse indicator |
|
|
141
|
+
| `Tree.Group` | Container for child nodes |
|
|
142
|
+
|
|
143
|
+
## Data Utilities
|
|
144
|
+
|
|
145
|
+
```tsx
|
|
146
|
+
import { flattenTree, searchTree, filterTree, buildTree } from 'bough';
|
|
147
|
+
|
|
148
|
+
// Convert nested tree to flat array
|
|
149
|
+
const flat = flattenTree(nodes);
|
|
150
|
+
|
|
151
|
+
// Search for nodes (preserves ancestry)
|
|
152
|
+
const results = searchTree(nodes, "report");
|
|
153
|
+
|
|
154
|
+
// Filter nodes by predicate
|
|
155
|
+
const filtered = filterTree(nodes, n => n.data?.type === "folder");
|
|
156
|
+
|
|
157
|
+
// Build tree from flat database records
|
|
158
|
+
const tree = buildTree(records, {
|
|
159
|
+
getId: r => r.id,
|
|
160
|
+
getParentId: r => r.parentId,
|
|
161
|
+
getName: r => r.title,
|
|
162
|
+
});
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Controlled State
|
|
166
|
+
|
|
167
|
+
```tsx
|
|
168
|
+
function ControlledTree() {
|
|
169
|
+
const [expandedIds, setExpandedIds] = useState<string[]>(["root"]);
|
|
170
|
+
|
|
171
|
+
return (
|
|
172
|
+
<Tree.Root
|
|
173
|
+
aria-label="Controlled tree"
|
|
174
|
+
expandedIds={expandedIds}
|
|
175
|
+
onExpandedIdsChange={setExpandedIds}
|
|
176
|
+
onSelect={(node) => console.log("Selected:", node.name)}
|
|
177
|
+
>
|
|
178
|
+
<Tree.Recursive nodes={nodes} renderContent={...} />
|
|
179
|
+
</Tree.Root>
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
## Styling
|
|
185
|
+
|
|
186
|
+
`Tree.Recursive` applies default CSS classes (`tree__row`, `tree__chevron`, `tree__children`) that work with the included stylesheet. Customize using CSS variables:
|
|
187
|
+
|
|
188
|
+
```css
|
|
189
|
+
.tree {
|
|
190
|
+
--tree-hover-bg: rgba(0, 0, 0, 0.05);
|
|
191
|
+
--tree-selected-bg: rgba(59, 130, 246, 0.1);
|
|
192
|
+
--tree-focus-ring: #3b82f6;
|
|
193
|
+
--tree-indent: 1.5rem;
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
Or add additional classes:
|
|
198
|
+
|
|
199
|
+
```tsx
|
|
200
|
+
<Tree.Recursive
|
|
201
|
+
nodes={nodes}
|
|
202
|
+
renderContent={({ name }) => <span>{name}</span>}
|
|
203
|
+
rowClassName="my-custom-row"
|
|
204
|
+
groupClassName="my-custom-group"
|
|
205
|
+
/>
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
For fully custom styling, use `styled={false}` and apply your own classes.
|
|
209
|
+
|
|
210
|
+
## Development
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
npm install
|
|
214
|
+
npm run dev
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
## License
|
|
218
|
+
|
|
219
|
+
MIT
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const I=require("react/jsx-runtime"),l=require("react");function se({defaultExpandedIds:n=[],expandedIds:o,onExpandedIdsChange:c,selectedId:d,onSelect:f,onExpandChange:t}={}){const[e,h]=l.useState(null),[r,a]=l.useState(null),[m,x]=l.useState(()=>new Set(n)),g=o!==void 0,T=g?o:m,w=d??r,C=l.useRef(new Map),[$,S]=l.useState(null),F=l.useRef([]),p=l.useRef(null),j=l.useRef(""),P=l.useRef(),R=l.useCallback(s=>{if(g){const u=s(T);c==null||c(u)}else x(s)},[g,T,c]),W=l.useCallback((s,u,i)=>{C.current.set(s,{node:u,parentId:i}),i===null&&S(b=>b??s)},[]),q=l.useCallback(s=>{C.current.delete(s)},[]),Q=l.useCallback(s=>{var u;return((u=C.current.get(s))==null?void 0:u.parentId)??null},[]),U=l.useCallback(s=>{var u;return((u=C.current.get(s))==null?void 0:u.node)??null},[]),A=l.useCallback(s=>T.has(s),[T]),J=l.useCallback(s=>w===s,[w]),X=l.useCallback(s=>e===s,[e]),D=l.useCallback((s,u)=>{R(i=>{const b=new Set(i),v=!b.has(s);return v?b.add(s):b.delete(s),t==null||t(u,v),b})},[R,t]),Y=l.useCallback(s=>{R(u=>{if(u.has(s))return u;const i=new Set(u);i.add(s);const b=C.current.get(s);return b&&(t==null||t(b.node,!0)),i})},[R,t]),Z=l.useCallback(s=>{R(u=>{if(!u.has(s))return u;const i=new Set(u);i.delete(s);const b=C.current.get(s);return b&&(t==null||t(b.node,!1)),i})},[R,t]),ee=l.useCallback(()=>{R(()=>{const s=new Set;return C.current.forEach((u,i)=>{u.node.children&&u.node.children.length>0&&s.add(i)}),s})},[R]),te=l.useCallback(()=>{R(()=>new Set)},[R]),B=l.useCallback((s,u)=>{a(s),f==null||f(u)},[f]),L=l.useCallback(()=>{if(!p.current)return[];const s=p.current.querySelectorAll('[role="treeitem"]'),u=[];return s.forEach(i=>{const b=i.getAttribute("data-node-id");b&&!i.closest('[role="group"][aria-hidden="true"]')&&u.push(b)}),F.current=u,u},[]),_=l.useCallback(s=>{var i;h(s);const u=(i=p.current)==null?void 0:i.querySelector(`[data-node-id="${s}"]`);u instanceof HTMLElement&&u.focus()},[]),y=l.useCallback((s,u)=>{var E,re;const i=L();if(i.length===0)return;let b=u??e;!b&&document.activeElement&&(b=(re=(E=document.activeElement).getAttribute)==null?void 0:re.call(E,"data-node-id"));let v;const N=b?i.indexOf(b):-1;switch(s){case"next":v=N<i.length-1?N+1:N;break;case"prev":v=N>0?N-1:0;break;case"first":v=0;break;case"last":v=i.length-1;break}const k=i[v];k&&_(k)},[e,L,_]),ne=l.useCallback(s=>{P.current&&clearTimeout(P.current),j.current+=s.toLowerCase(),P.current=setTimeout(()=>{j.current=""},500);const u=L(),i=e?u.indexOf(e):-1;for(let b=0;b<u.length;b++){const v=(i+1+b)%u.length,N=u[v],k=C.current.get(N);if(k!=null&&k.node.name.toLowerCase().startsWith(j.current)){_(N);break}}},[e,L,_]),he=l.useCallback(s=>{var b,v,N;const{key:u}=s;if(!((b=p.current)!=null&&b.contains(document.activeElement)))return;let i=e;if(!i&&document.activeElement){const k=(N=(v=document.activeElement).getAttribute)==null?void 0:N.call(v,"data-node-id");k&&(i=k,h(k))}switch(u){case"ArrowDown":s.preventDefault(),y("next",i);break;case"ArrowUp":s.preventDefault(),y("prev",i);break;case"ArrowRight":{if(s.preventDefault(),!i)break;const k=C.current.get(i);if(!k)break;k.node.children&&k.node.children.length>0&&(A(i)?y("next",i):D(i,k.node));break}case"ArrowLeft":{if(s.preventDefault(),!i)break;const k=C.current.get(i);if(!k)break;k.node.children&&k.node.children.length>0&&A(i)?D(i,k.node):k.parentId&&_(k.parentId);break}case"Home":s.preventDefault(),y("first",i);break;case"End":s.preventDefault(),y("last",i);break;case"Enter":case" ":{if(s.preventDefault(),!i)break;const k=C.current.get(i);k&&B(i,k.node);break}default:u.length===1&&!s.ctrlKey&&!s.altKey&&!s.metaKey&&ne(u);break}},[e,A,D,y,_,B,ne]),me=l.useMemo(()=>({focusedId:e,selectedId:w,expandedIds:T,firstNodeId:$,setFocusedId:h,selectNode:B,toggleExpanded:D,expand:Y,collapse:Z,expandAll:ee,collapseAll:te,isExpanded:A,isSelected:J,isFocused:X,registerNode:W,unregisterNode:q,getParentId:Q,getNode:U}),[e,w,T,$,B,D,Y,Z,ee,te,A,J,X,W,q,Q,U]),be=l.useCallback((s={})=>({role:"tree",...s}),[]);return{state:me,getRootProps:be,handleKeyDown:he,treeRef:p}}function ce({node:n,level:o,posinset:c,setsize:d,parentId:f},t){const e=n.id??`${f??"root"}-${o}-${c}-${n.name}`,h=`tree-group-${e}`,r=!!(n.children&&n.children.length>0),a=r&&t.isExpanded(e),m=t.isSelected(e),x=t.isFocused(e),g=t.focusedId===null&&f===null&&c===1,T=x||g?0:-1;l.useEffect(()=>(t.registerNode(e,n,f),()=>t.unregisterNode(e)),[e,n,f,t]);const w=l.useCallback(()=>{r&&t.toggleExpanded(e,n)},[r,e,n,t]),C=l.useCallback(()=>{t.selectNode(e,n)},[e,n,t]),$=l.useCallback((p={})=>({role:"treeitem","aria-expanded":r?a:void 0,"aria-selected":m,"aria-level":o,"aria-setsize":d,"aria-posinset":c,"aria-owns":r?h:void 0,"data-node-id":e,"data-expanded":r?a:void 0,"data-selected":m||void 0,"data-focused":x||void 0,tabIndex:T,onFocus:j=>{var P;j.stopPropagation(),t.setFocusedId(e),(P=p.onFocus)==null||P.call(p,j)},...p}),[r,a,m,x,o,d,c,h,e,T,t]),S=l.useCallback((p={})=>({onClick:j=>{var P;j.stopPropagation(),r&&w(),C(),(P=p.onClick)==null||P.call(p,j)},...p}),[r,w,C]),F=l.useCallback((p={})=>({id:h,role:"group","aria-hidden":!a,"data-state":a?"open":"closed",...p}),[h,a]);return l.useMemo(()=>({nodeId:e,isExpanded:a,isSelected:m,isFocused:x,isFirstFocusable:g,hasChildren:r,tabIndex:T,getItemProps:$,getContentProps:S,getGroupProps:F,toggle:w,select:C}),[e,a,m,x,g,r,T,$,S,F,w,C])}const K=l.createContext(null);function oe(){const n=l.useContext(K);if(!n)throw new Error("useTreeContext must be used within a Tree.Root component");return n}const V=l.createContext(null);function M(){const n=l.useContext(V);if(!n)throw new Error("useTreeItemContext must be used within a Tree.Item component");return n}function ie({children:n,className:o,style:c,"aria-label":d,"aria-labelledby":f,...t}){const{state:e,getRootProps:h,handleKeyDown:r,treeRef:a}=se(t),m=l.useMemo(()=>({state:e,treeRef:a}),[e,a]);return I.jsx(K.Provider,{value:m,children:I.jsx("div",{ref:a,...h(),"aria-label":d,"aria-labelledby":f,className:o,style:c,onKeyDown:r,children:n})})}function G({node:n,level:o,posinset:c,setsize:d,parentId:f,children:t,className:e,style:h}){const{state:r}=oe(),a=ce({node:n,level:o,posinset:c,setsize:d,parentId:f},r),m=typeof t=="function"?t(a):t;return I.jsx(V.Provider,{value:a,children:I.jsx("div",{...a.getItemProps(),className:e,style:h,children:m})})}const z=l.forwardRef(function({children:o,className:c,style:d,onClick:f,...t},e){const r=M().getContentProps(),a=f??r.onClick;return I.jsx("div",{ref:e,...t,className:c,style:d,onClick:a,children:o})});function ge({open:n}){return I.jsx("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",style:{width:"0.75rem",height:"0.75rem",flexShrink:0,transition:"transform 200ms",transform:n?"rotate(180deg)":"rotate(0deg)"},children:I.jsx("polyline",{points:"18 15 12 9 6 15"})})}function O({children:n,className:o,style:c,openClassName:d,closedClassName:f}){const{isExpanded:t,hasChildren:e}=M();if(!e)return I.jsx("span",{style:{width:"0.75rem",height:"0.75rem",flexShrink:0,...c},className:o,"aria-hidden":"true"});const r=[o,t?d:f].filter(Boolean).join(" ")||void 0;return n?I.jsx("span",{className:r,style:c,"aria-hidden":"true",children:n}):I.jsx("span",{className:r,style:c,children:I.jsx(ge,{open:t})})}function H({children:n,className:o,style:c}){const d=M(),f=d.getGroupProps();return d.hasChildren?I.jsx("div",{...f,className:o,style:c,children:n}):null}function le({nodes:n,level:o=1,parentId:c=null,renderItem:d}){return I.jsx(I.Fragment,{children:n.map((f,t)=>d({node:f,level:o,posinset:t+1,setsize:n.length,parentId:c}))})}function ae({nodes:n,renderContent:o,styled:c=!0,rowClassName:d,groupClassName:f,chevronClassName:t}){return I.jsx(I.Fragment,{children:n.map((e,h)=>I.jsx(ue,{node:e,level:1,posinset:h+1,setsize:n.length,parentId:null,NodeContent:o,styled:c,rowClassName:d,groupClassName:f,chevronClassName:t},e.id??`${e.name}-${h}`))})}function ue({node:n,level:o,posinset:c,setsize:d,parentId:f,NodeContent:t,styled:e,rowClassName:h,groupClassName:r,chevronClassName:a}){const m=!!(n.children&&n.children.length>0);return I.jsx(G,{node:n,level:o,posinset:c,setsize:d,parentId:f,children:({isExpanded:x,isSelected:g,isFocused:T,nodeId:w})=>{const C=e?["tree__row",g&&"tree__row--selected",T&&"tree__row--focused",h].filter(Boolean).join(" "):h,$=e?["tree__children",x&&"tree__children--open",r].filter(Boolean).join(" "):r,S=e?["tree__chevron",a].filter(Boolean).join(" "):a,F=e?"tree__chevron--open":void 0;return I.jsxs(I.Fragment,{children:[I.jsxs(z,{className:C,children:[I.jsx(O,{className:S,openClassName:F}),I.jsx(t,{...n})]}),m&&I.jsx(H,{className:$,children:I.jsx("div",{className:e?"tree__children-inner":void 0,children:n.children.map((p,j)=>I.jsx(ue,{node:p,level:o+1,posinset:j+1,setsize:n.children.length,parentId:w,NodeContent:t,styled:e,rowClassName:h,groupClassName:r,chevronClassName:a},p.id??`${p.name}-${j}`))})})]})}})}const Ie={Root:ie,Item:G,ItemContent:z,Chevron:O,Group:H,Nodes:le,Recursive:ae};function ke(n,o={}){const{startLevel:c=1,filter:d,includeCollapsedChildren:f=!0,expandedIds:t}=o,e=[];function h(r,a,m){const x=d?r.filter(d):r;x.forEach((g,T)=>{const w=g.id??`${m??"root"}-${a}-${T+1}-${g.name}`,C=!!(g.children&&g.children.length>0),$={...g,nodeId:w,level:a,posinset:T+1,setsize:x.length,parentId:m,hasChildren:C};e.push($),C&&g.children&&(f||t&&t.has(w))&&h(g.children,a+1,w)})}return h(n,c,null),e}function Ce(n,o){const{getId:c,getParentId:d,transform:f}=o,t=new Map,e=[];n.forEach(r=>{const a=c(r),m={...f(r),children:[]};t.set(a,m)}),n.forEach(r=>{const a=c(r),m=d(r),x=t.get(a);if(m===null)e.push(x);else{const g=t.get(m);g?(g.children=g.children||[],g.children.push(x)):e.push(x)}});function h(r){r.forEach(a=>{a.children&&a.children.length===0?delete a.children:a.children&&h(a.children)})}return h(e),e}function de(n,o,c={}){const{keepAncestors:d=!0,keepDescendants:f=!1}=c;function t(e){const h=[];return e.forEach(r=>{const a=o(r);let m=[];r.children&&r.children.length>0&&(a&&f?m=r.children:m=t(r.children)),a?h.push({...r,children:m.length>0?m:void 0}):d&&m.length>0&&h.push({...r,children:m})}),h}return t(n)}function pe(n,o,c={}){const{ignoreCase:d=!0,searchFields:f=[],minLength:t=1}=c;if(!o||o.length<t)return n;const e=d?o.toLowerCase():o;return de(n,r=>{if((d?r.name.toLowerCase():r.name).includes(e))return!0;if(r.data&&f.length>0){const m=r.data;return f.some(x=>{const g=m[x];return typeof g=="string"?(d?g.toLowerCase():g).includes(e):!1})}return!1},{keepAncestors:!0,keepDescendants:!1})}function fe(n,o){for(const c of n){if(c.id===o)return c;if(c.children){const d=fe(c.children,o);if(d)return d}}return null}function xe(n,o){function c(d,f){for(const t of d){const e=t.id??t.name,h=[...f,e];if(e===o)return h;if(t.children){const r=c(t.children,h);if(r)return r}}return null}return c(n,[])??[]}function Te(n){const o=[];function c(d,f,t){d.forEach((e,h)=>{const r=e.id??`${f??"root"}-${t}-${h+1}-${e.name}`;o.push(r),e.children&&c(e.children,r,t+1)})}return c(n,null,1),o}function we(n){const o=[];function c(d,f,t){d.forEach((e,h)=>{const r=e.id??`${f??"root"}-${t}-${h+1}-${e.name}`;e.children&&e.children.length>0&&(o.push(r),c(e.children,r,t+1))})}return c(n,null,1),o}function ve(...n){return n.filter(Boolean).join(" ")}exports.Tree=Ie;exports.TreeChevron=O;exports.TreeContext=K;exports.TreeGroup=H;exports.TreeItem=G;exports.TreeItemContent=z;exports.TreeItemContext=V;exports.TreeNodes=le;exports.TreeRecursive=ae;exports.TreeRoot=ie;exports.buildTree=Ce;exports.cn=ve;exports.filterTree=de;exports.findNodeById=fe;exports.flattenTree=ke;exports.getAllNodeIds=Te;exports.getExpandableNodeIds=we;exports.getNodePath=xe;exports.searchTree=pe;exports.useTree=se;exports.useTreeContext=oe;exports.useTreeItem=ce;exports.useTreeItemContext=M;
|
|
2
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/lib/primitives/useTree.ts","../src/lib/primitives/useTreeItem.ts","../src/lib/primitives/context.ts","../src/lib/primitives/Tree.tsx","../src/lib/primitives/utils.ts","../src/lib/utils/cn.ts"],"sourcesContent":["import { useCallback, useMemo, useRef, useState } from \"react\";\nimport type {\n TreeNode,\n TreeState,\n UseTreeProps,\n UseTreeReturn,\n} from \"./types\";\n\ninterface NodeInfo<T = unknown> {\n node: TreeNode<T>;\n parentId: string | null;\n}\n\n/**\n * Headless hook for managing tree state.\n * Handles focus, selection, expansion, and keyboard navigation.\n * \n * @example\n * ```tsx\n * const { state, getRootProps, handleKeyDown, treeRef } = useTree({\n * onSelect: (node) => console.log('Selected:', node),\n * defaultExpandedIds: ['node-1'],\n * });\n * \n * return (\n * <div {...getRootProps()} ref={treeRef} onKeyDown={handleKeyDown}>\n * {nodes.map(node => <TreeItem key={node.id} node={node} />)}\n * </div>\n * );\n * ```\n */\nexport function useTree<T = unknown>({\n defaultExpandedIds = [],\n expandedIds: controlledExpandedIds,\n onExpandedIdsChange,\n selectedId: controlledSelectedId,\n onSelect,\n onExpandChange,\n}: UseTreeProps<T> = {}): UseTreeReturn<T> {\n // Internal state\n const [focusedId, setFocusedId] = useState<string | null>(null);\n const [internalSelectedId, setInternalSelectedId] = useState<string | null>(null);\n const [internalExpandedIds, setInternalExpandedIds] = useState<Set<string>>(\n () => new Set(defaultExpandedIds)\n );\n\n // Determine if we're controlled or uncontrolled\n const isExpandedControlled = controlledExpandedIds !== undefined;\n const expandedIds = isExpandedControlled ? controlledExpandedIds : internalExpandedIds;\n const selectedId = controlledSelectedId ?? internalSelectedId;\n\n // Node registry for navigation\n const nodeRegistry = useRef<Map<string, NodeInfo<T>>>(new Map());\n const [firstNodeId, setFirstNodeId] = useState<string | null>(null);\n const visibleNodeIdsRef = useRef<string[]>([]);\n const treeRef = useRef<HTMLDivElement>(null);\n\n // Type-ahead state\n const typeaheadBuffer = useRef<string>(\"\");\n const typeaheadTimeout = useRef<ReturnType<typeof setTimeout>>();\n\n // Update expanded IDs (internal or via callback)\n const updateExpandedIds = useCallback((updater: (prev: Set<string>) => Set<string>) => {\n if (isExpandedControlled) {\n const newIds = updater(expandedIds);\n onExpandedIdsChange?.(newIds);\n } else {\n setInternalExpandedIds(updater);\n }\n }, [isExpandedControlled, expandedIds, onExpandedIdsChange]);\n\n // Register a node\n const registerNode = useCallback((nodeId: string, node: TreeNode<T>, parentId: string | null) => {\n nodeRegistry.current.set(nodeId, { node, parentId });\n if (parentId === null) {\n setFirstNodeId((current) => current ?? nodeId);\n }\n }, []);\n\n // Unregister a node\n const unregisterNode = useCallback((nodeId: string) => {\n nodeRegistry.current.delete(nodeId);\n }, []);\n\n // Get parent node ID\n const getParentId = useCallback((nodeId: string): string | null => {\n return nodeRegistry.current.get(nodeId)?.parentId ?? null;\n }, []);\n\n // Get node info\n const getNode = useCallback((nodeId: string): TreeNode<T> | null => {\n return nodeRegistry.current.get(nodeId)?.node ?? null;\n }, []);\n\n // Check if a node is expanded\n const isExpanded = useCallback((nodeId: string): boolean => {\n return expandedIds.has(nodeId);\n }, [expandedIds]);\n\n // Check if a node is selected\n const isSelected = useCallback((nodeId: string): boolean => {\n return selectedId === nodeId;\n }, [selectedId]);\n\n // Check if a node is focused\n const isFocused = useCallback((nodeId: string): boolean => {\n return focusedId === nodeId;\n }, [focusedId]);\n\n // Toggle expansion\n const toggleExpanded = useCallback((nodeId: string, node: TreeNode<T>) => {\n updateExpandedIds((prev) => {\n const next = new Set(prev);\n const willBeExpanded = !next.has(nodeId);\n if (willBeExpanded) {\n next.add(nodeId);\n } else {\n next.delete(nodeId);\n }\n onExpandChange?.(node, willBeExpanded);\n return next;\n });\n }, [updateExpandedIds, onExpandChange]);\n\n // Expand a node\n const expand = useCallback((nodeId: string) => {\n updateExpandedIds((prev) => {\n if (prev.has(nodeId)) return prev;\n const next = new Set(prev);\n next.add(nodeId);\n const nodeInfo = nodeRegistry.current.get(nodeId);\n if (nodeInfo) {\n onExpandChange?.(nodeInfo.node, true);\n }\n return next;\n });\n }, [updateExpandedIds, onExpandChange]);\n\n // Collapse a node\n const collapse = useCallback((nodeId: string) => {\n updateExpandedIds((prev) => {\n if (!prev.has(nodeId)) return prev;\n const next = new Set(prev);\n next.delete(nodeId);\n const nodeInfo = nodeRegistry.current.get(nodeId);\n if (nodeInfo) {\n onExpandChange?.(nodeInfo.node, false);\n }\n return next;\n });\n }, [updateExpandedIds, onExpandChange]);\n\n // Expand all nodes\n const expandAll = useCallback(() => {\n updateExpandedIds(() => {\n const allIds = new Set<string>();\n nodeRegistry.current.forEach((info, nodeId) => {\n if (info.node.children && info.node.children.length > 0) {\n allIds.add(nodeId);\n }\n });\n return allIds;\n });\n }, [updateExpandedIds]);\n\n // Collapse all nodes\n const collapseAll = useCallback(() => {\n updateExpandedIds(() => new Set());\n }, [updateExpandedIds]);\n\n // Select a node\n const selectNode = useCallback((nodeId: string, node: TreeNode<T>) => {\n setInternalSelectedId(nodeId);\n onSelect?.(node);\n }, [onSelect]);\n\n // Get visible node IDs from DOM\n const getVisibleNodeIds = useCallback((): string[] => {\n if (!treeRef.current) return [];\n const treeitems = treeRef.current.querySelectorAll('[role=\"treeitem\"]');\n const ids: string[] = [];\n treeitems.forEach((item) => {\n const id = item.getAttribute(\"data-node-id\");\n if (id) {\n const isVisible = !item.closest('[role=\"group\"][aria-hidden=\"true\"]');\n if (isVisible) {\n ids.push(id);\n }\n }\n });\n visibleNodeIdsRef.current = ids;\n return ids;\n }, []);\n\n // Focus a specific node\n const focusNode = useCallback((nodeId: string) => {\n setFocusedId(nodeId);\n const element = treeRef.current?.querySelector(`[data-node-id=\"${nodeId}\"]`);\n if (element instanceof HTMLElement) {\n element.focus();\n }\n }, []);\n\n // Navigate to node\n const navigateToNode = useCallback((direction: \"next\" | \"prev\" | \"first\" | \"last\", currentId?: string | null) => {\n const visibleIds = getVisibleNodeIds();\n if (visibleIds.length === 0) return;\n\n let effectiveFocusedId = currentId ?? focusedId;\n if (!effectiveFocusedId && document.activeElement) {\n effectiveFocusedId = (document.activeElement as HTMLElement).getAttribute?.(\"data-node-id\");\n }\n\n let targetIndex: number;\n const currentIndex = effectiveFocusedId ? visibleIds.indexOf(effectiveFocusedId) : -1;\n\n switch (direction) {\n case \"next\":\n targetIndex = currentIndex < visibleIds.length - 1 ? currentIndex + 1 : currentIndex;\n break;\n case \"prev\":\n targetIndex = currentIndex > 0 ? currentIndex - 1 : 0;\n break;\n case \"first\":\n targetIndex = 0;\n break;\n case \"last\":\n targetIndex = visibleIds.length - 1;\n break;\n }\n\n const targetId = visibleIds[targetIndex];\n if (targetId) {\n focusNode(targetId);\n }\n }, [focusedId, getVisibleNodeIds, focusNode]);\n\n // Handle type-ahead search\n const handleTypeahead = useCallback((char: string) => {\n if (typeaheadTimeout.current) {\n clearTimeout(typeaheadTimeout.current);\n }\n\n typeaheadBuffer.current += char.toLowerCase();\n\n typeaheadTimeout.current = setTimeout(() => {\n typeaheadBuffer.current = \"\";\n }, 500);\n\n const visibleIds = getVisibleNodeIds();\n const currentIndex = focusedId ? visibleIds.indexOf(focusedId) : -1;\n\n for (let i = 0; i < visibleIds.length; i++) {\n const searchIndex = (currentIndex + 1 + i) % visibleIds.length;\n const nodeId = visibleIds[searchIndex];\n const nodeInfo = nodeRegistry.current.get(nodeId);\n if (nodeInfo?.node.name.toLowerCase().startsWith(typeaheadBuffer.current)) {\n focusNode(nodeId);\n break;\n }\n }\n }, [focusedId, getVisibleNodeIds, focusNode]);\n\n // Keyboard handler\n const handleKeyDown = useCallback((event: React.KeyboardEvent) => {\n const { key } = event;\n\n if (!treeRef.current?.contains(document.activeElement)) {\n return;\n }\n\n let currentFocusedId = focusedId;\n if (!currentFocusedId && document.activeElement) {\n const nodeId = (document.activeElement as HTMLElement).getAttribute?.(\"data-node-id\");\n if (nodeId) {\n currentFocusedId = nodeId;\n setFocusedId(nodeId);\n }\n }\n\n switch (key) {\n case \"ArrowDown\":\n event.preventDefault();\n navigateToNode(\"next\", currentFocusedId);\n break;\n\n case \"ArrowUp\":\n event.preventDefault();\n navigateToNode(\"prev\", currentFocusedId);\n break;\n\n case \"ArrowRight\": {\n event.preventDefault();\n if (!currentFocusedId) break;\n const nodeInfo = nodeRegistry.current.get(currentFocusedId);\n if (!nodeInfo) break;\n\n const hasChildren = nodeInfo.node.children && nodeInfo.node.children.length > 0;\n if (hasChildren) {\n if (isExpanded(currentFocusedId)) {\n navigateToNode(\"next\", currentFocusedId);\n } else {\n toggleExpanded(currentFocusedId, nodeInfo.node);\n }\n }\n break;\n }\n\n case \"ArrowLeft\": {\n event.preventDefault();\n if (!currentFocusedId) break;\n const nodeInfo = nodeRegistry.current.get(currentFocusedId);\n if (!nodeInfo) break;\n\n const hasChildren = nodeInfo.node.children && nodeInfo.node.children.length > 0;\n if (hasChildren && isExpanded(currentFocusedId)) {\n toggleExpanded(currentFocusedId, nodeInfo.node);\n } else if (nodeInfo.parentId) {\n focusNode(nodeInfo.parentId);\n }\n break;\n }\n\n case \"Home\":\n event.preventDefault();\n navigateToNode(\"first\", currentFocusedId);\n break;\n\n case \"End\":\n event.preventDefault();\n navigateToNode(\"last\", currentFocusedId);\n break;\n\n case \"Enter\":\n case \" \": {\n event.preventDefault();\n if (!currentFocusedId) break;\n const nodeInfo = nodeRegistry.current.get(currentFocusedId);\n if (nodeInfo) {\n selectNode(currentFocusedId, nodeInfo.node);\n }\n break;\n }\n\n default:\n if (key.length === 1 && !event.ctrlKey && !event.altKey && !event.metaKey) {\n handleTypeahead(key);\n }\n break;\n }\n }, [focusedId, isExpanded, toggleExpanded, navigateToNode, focusNode, selectNode, handleTypeahead]);\n\n // Build state object\n const state = useMemo<TreeState<T>>(() => ({\n focusedId,\n selectedId,\n expandedIds,\n firstNodeId,\n setFocusedId,\n selectNode,\n toggleExpanded,\n expand,\n collapse,\n expandAll,\n collapseAll,\n isExpanded,\n isSelected,\n isFocused,\n registerNode,\n unregisterNode,\n getParentId,\n getNode,\n }), [\n focusedId,\n selectedId,\n expandedIds,\n firstNodeId,\n selectNode,\n toggleExpanded,\n expand,\n collapse,\n expandAll,\n collapseAll,\n isExpanded,\n isSelected,\n isFocused,\n registerNode,\n unregisterNode,\n getParentId,\n getNode,\n ]);\n\n // Get props for root element\n const getRootProps = useCallback((props: Record<string, unknown> = {}) => ({\n role: \"tree\",\n ...props,\n }), []);\n\n return {\n state,\n getRootProps,\n handleKeyDown,\n treeRef,\n };\n}\n\nexport default useTree;\n\n","import { useCallback, useEffect, useMemo } from \"react\";\nimport type { TreeNode, TreeState, UseTreeItemProps, UseTreeItemReturn } from \"./types\";\n\n/**\n * Headless hook for managing individual tree item state and behavior.\n * Handles registration, ARIA props, and interaction handlers.\n * \n * @example\n * ```tsx\n * function MyTreeItem({ node, level, posinset, setsize, parentId }) {\n * const {\n * isExpanded,\n * isSelected,\n * isFocused,\n * hasChildren,\n * getItemProps,\n * getContentProps,\n * getGroupProps,\n * toggle,\n * select,\n * } = useTreeItem({ node, level, posinset, setsize, parentId }, treeState);\n * \n * return (\n * <div {...getItemProps()}>\n * <div {...getContentProps()}>\n * {hasChildren && <ChevronIcon open={isExpanded} />}\n * {node.name}\n * </div>\n * {hasChildren && (\n * <div {...getGroupProps()}>\n * {node.children?.map(...)}\n * </div>\n * )}\n * </div>\n * );\n * }\n * ```\n */\nexport function useTreeItem<T = unknown>(\n { node, level, posinset, setsize, parentId }: UseTreeItemProps<T>,\n state: TreeState<T>\n): UseTreeItemReturn {\n // Generate stable node ID\n const nodeId = node.id ?? `${parentId ?? \"root\"}-${level}-${posinset}-${node.name}`;\n const groupId = `tree-group-${nodeId}`;\n\n const hasChildren = Boolean(node.children && node.children.length > 0);\n const isExpanded = hasChildren && state.isExpanded(nodeId);\n const isSelected = state.isSelected(nodeId);\n const isFocused = state.isFocused(nodeId);\n const isFirstFocusable = state.focusedId === null && parentId === null && posinset === 1;\n const tabIndex = isFocused || isFirstFocusable ? 0 : -1;\n\n // Register/unregister node\n useEffect(() => {\n state.registerNode(nodeId, node as TreeNode<T>, parentId);\n return () => state.unregisterNode(nodeId);\n }, [nodeId, node, parentId, state]);\n\n // Toggle expansion\n const toggle = useCallback(() => {\n if (hasChildren) {\n state.toggleExpanded(nodeId, node as TreeNode<T>);\n }\n }, [hasChildren, nodeId, node, state]);\n\n // Select this item\n const select = useCallback(() => {\n state.selectNode(nodeId, node as TreeNode<T>);\n }, [nodeId, node, state]);\n\n // Get props for the item wrapper element\n const getItemProps = useCallback((props: Record<string, unknown> = {}) => ({\n role: \"treeitem\",\n \"aria-expanded\": hasChildren ? isExpanded : undefined,\n \"aria-selected\": isSelected,\n \"aria-level\": level,\n \"aria-setsize\": setsize,\n \"aria-posinset\": posinset,\n \"aria-owns\": hasChildren ? groupId : undefined,\n \"data-node-id\": nodeId,\n \"data-expanded\": hasChildren ? isExpanded : undefined,\n \"data-selected\": isSelected || undefined,\n \"data-focused\": isFocused || undefined,\n tabIndex,\n onFocus: (event: React.FocusEvent) => {\n event.stopPropagation();\n state.setFocusedId(nodeId);\n (props.onFocus as ((e: React.FocusEvent) => void) | undefined)?.(event);\n },\n ...props,\n }), [hasChildren, isExpanded, isSelected, isFocused, level, setsize, posinset, groupId, nodeId, tabIndex, state]);\n\n // Get props for the content/trigger element\n const getContentProps = useCallback((props: Record<string, unknown> = {}) => ({\n onClick: (event: React.MouseEvent) => {\n event.stopPropagation();\n if (hasChildren) {\n toggle();\n }\n select();\n (props.onClick as ((e: React.MouseEvent) => void) | undefined)?.(event);\n },\n ...props,\n }), [hasChildren, toggle, select]);\n\n // Get props for the group/children container\n const getGroupProps = useCallback((props: Record<string, unknown> = {}) => ({\n id: groupId,\n role: \"group\",\n \"aria-hidden\": !isExpanded,\n \"data-state\": isExpanded ? \"open\" : \"closed\",\n ...props,\n }), [groupId, isExpanded]);\n\n return useMemo(() => ({\n nodeId,\n isExpanded,\n isSelected,\n isFocused,\n isFirstFocusable,\n hasChildren,\n tabIndex,\n getItemProps,\n getContentProps,\n getGroupProps,\n toggle,\n select,\n }), [\n nodeId,\n isExpanded,\n isSelected,\n isFocused,\n isFirstFocusable,\n hasChildren,\n tabIndex,\n getItemProps,\n getContentProps,\n getGroupProps,\n toggle,\n select,\n ]);\n}\n\nexport default useTreeItem;\n\n","import { createContext, useContext } from \"react\";\nimport type { TreeContextValue, UseTreeItemReturn } from \"./types\";\n\n/**\n * Context for sharing tree state across nested components.\n */\nexport const TreeContext = createContext<TreeContextValue | null>(null);\n\n/**\n * Hook to access tree context.\n * Must be used within a Tree.Root component.\n */\nexport function useTreeContext<T = unknown>(): TreeContextValue<T> {\n const context = useContext(TreeContext);\n if (!context) {\n throw new Error(\"useTreeContext must be used within a Tree.Root component\");\n }\n return context as TreeContextValue<T>;\n}\n\n/**\n * Context for sharing tree item state within an item.\n */\nexport const TreeItemContext = createContext<UseTreeItemReturn | null>(null);\n\n/**\n * Hook to access tree item context.\n * Must be used within a Tree.Item component.\n */\nexport function useTreeItemContext(): UseTreeItemReturn {\n const context = useContext(TreeItemContext);\n if (!context) {\n throw new Error(\"useTreeItemContext must be used within a Tree.Item component\");\n }\n return context;\n}\n\n","import React, { forwardRef, useMemo } from \"react\";\nimport type {\n TreeNode,\n TreeRootProps,\n TreeItemProps,\n TreeItemContentProps,\n TreeChevronProps,\n TreeGroupProps,\n TreeContextValue,\n UseTreeProps,\n} from \"./types\";\nimport { useTree } from \"./useTree\";\nimport { useTreeItem } from \"./useTreeItem\";\nimport { TreeContext, TreeItemContext, useTreeContext, useTreeItemContext } from \"./context\";\n\n/**\n * Tree.Root - The root container for a tree.\n * Provides context and keyboard navigation for all nested items.\n * \n * @example\n * ```tsx\n * <Tree.Root aria-label=\"File explorer\">\n * {nodes.map(node => (\n * <Tree.Item key={node.id} node={node} level={1} posinset={idx + 1} setsize={nodes.length} parentId={null}>\n * ...\n * </Tree.Item>\n * ))}\n * </Tree.Root>\n * ```\n */\nfunction TreeRoot<T = unknown>({\n children,\n className,\n style,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledby,\n ...props\n}: TreeRootProps & UseTreeProps<T>) {\n const { state, getRootProps, handleKeyDown, treeRef } = useTree<T>(props);\n\n const contextValue = useMemo(() => ({ state, treeRef }), [state, treeRef]);\n\n return (\n <TreeContext.Provider value={contextValue as TreeContextValue}>\n <div\n ref={treeRef as React.RefObject<HTMLDivElement>}\n {...getRootProps()}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledby}\n className={className}\n style={style}\n onKeyDown={handleKeyDown}\n >\n {children}\n </div>\n </TreeContext.Provider>\n );\n}\n\n/**\n * Tree.Item - A single item in the tree.\n * Handles ARIA attributes and registration with the tree.\n * \n * @example\n * ```tsx\n * <Tree.Item node={node} level={1} posinset={1} setsize={3} parentId={null}>\n * {({ isExpanded, isSelected, hasChildren }) => (\n * <>\n * <Tree.ItemContent>\n * {hasChildren && <Tree.Chevron />}\n * <span>{node.name}</span>\n * </Tree.ItemContent>\n * {hasChildren && (\n * <Tree.Group>\n * {node.children.map(...)}\n * </Tree.Group>\n * )}\n * </>\n * )}\n * </Tree.Item>\n * ```\n */\nfunction TreeItem<T = unknown>({\n node,\n level,\n posinset,\n setsize,\n parentId,\n children,\n className,\n style,\n}: TreeItemProps<T>) {\n const { state } = useTreeContext<T>();\n const itemState = useTreeItem({ node, level, posinset, setsize, parentId }, state);\n\n const content = typeof children === \"function\" ? children(itemState) : children;\n\n return (\n <TreeItemContext.Provider value={itemState}>\n <div\n {...itemState.getItemProps()}\n className={className}\n style={style}\n >\n {content}\n </div>\n </TreeItemContext.Provider>\n );\n}\n\n/**\n * Tree.ItemContent - The clickable content area of a tree item.\n * Handles click events for selection and expansion.\n * \n * @example\n * ```tsx\n * <Tree.ItemContent className=\"flex items-center gap-2\">\n * <Tree.Chevron />\n * <span>{node.name}</span>\n * </Tree.ItemContent>\n * ```\n */\nconst TreeItemContent = forwardRef<HTMLDivElement, TreeItemContentProps>(\n function TreeItemContent({ children, className, style, onClick, ...props }, ref) {\n const itemState = useTreeItemContext();\n const contentProps = itemState.getContentProps();\n\n const handleClick = onClick ?? contentProps.onClick;\n\n return (\n <div\n ref={ref}\n {...props}\n className={className}\n style={style}\n onClick={handleClick as React.MouseEventHandler<HTMLDivElement>}\n >\n {children}\n </div>\n );\n }\n);\n\n/**\n * Default chevron SVG icon\n */\nfunction DefaultChevron({ open }: { open: boolean }) {\n return (\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n style={{\n width: \"0.75rem\",\n height: \"0.75rem\",\n flexShrink: 0,\n transition: \"transform 200ms\",\n transform: open ? \"rotate(180deg)\" : \"rotate(0deg)\",\n }}\n >\n <polyline points=\"18 15 12 9 6 15\" />\n </svg>\n );\n}\n\n/**\n * Tree.Chevron - Expand/collapse indicator for tree items.\n * Only renders if the item has children.\n * \n * @example\n * ```tsx\n * // Default chevron\n * <Tree.Chevron />\n * \n * // Custom chevron\n * <Tree.Chevron>\n * {isExpanded ? <MinusIcon /> : <PlusIcon />}\n * </Tree.Chevron>\n * ```\n */\nfunction TreeChevron({\n children,\n className,\n style,\n openClassName,\n closedClassName,\n}: TreeChevronProps) {\n const { isExpanded, hasChildren } = useTreeItemContext();\n\n if (!hasChildren) {\n // Return a spacer to maintain alignment\n return (\n <span\n style={{ width: \"0.75rem\", height: \"0.75rem\", flexShrink: 0, ...style }}\n className={className}\n aria-hidden=\"true\"\n />\n );\n }\n\n const stateClassName = isExpanded ? openClassName : closedClassName;\n const combinedClassName = [className, stateClassName].filter(Boolean).join(\" \") || undefined;\n\n if (children) {\n return (\n <span className={combinedClassName} style={style} aria-hidden=\"true\">\n {children}\n </span>\n );\n }\n\n return (\n <span className={combinedClassName} style={style}>\n <DefaultChevron open={isExpanded} />\n </span>\n );\n}\n\n/**\n * Tree.Group - Container for child items.\n * Handles visibility based on expansion state.\n * \n * @example\n * ```tsx\n * <Tree.Group className=\"ml-4\">\n * {node.children.map((child, idx) => (\n * <Tree.Item key={child.id} node={child} level={level + 1} ... />\n * ))}\n * </Tree.Group>\n * ```\n */\nfunction TreeGroup({ children, className, style }: TreeGroupProps) {\n const itemState = useTreeItemContext();\n const groupProps = itemState.getGroupProps();\n\n if (!itemState.hasChildren) {\n return null;\n }\n\n return (\n <div\n {...groupProps}\n className={className}\n style={style}\n >\n {children}\n </div>\n );\n}\n\n/**\n * Utility component to recursively render tree nodes.\n * Optional helper for common use cases.\n */\ninterface TreeNodesProps<T = unknown> {\n nodes: TreeNode<T>[];\n level?: number;\n parentId?: string | null;\n renderItem: (props: {\n node: TreeNode<T>;\n level: number;\n posinset: number;\n setsize: number;\n parentId: string | null;\n }) => React.ReactNode;\n}\n\nfunction TreeNodes<T = unknown>({\n nodes,\n level = 1,\n parentId = null,\n renderItem,\n}: TreeNodesProps<T>) {\n return (\n <>\n {nodes.map((node, index) => \n renderItem({\n node,\n level,\n posinset: index + 1,\n setsize: nodes.length,\n parentId,\n })\n )}\n </>\n );\n}\n\n/**\n * Props for Tree.Recursive component\n */\ninterface TreeRecursiveProps<T = unknown> {\n /** Array of root-level nodes */\n nodes: TreeNode<T>[];\n /** Component to render each node's content */\n renderContent: React.ComponentType<TreeNode<T>>;\n /** \n * Whether to apply default CSS classes (tree__row, tree__chevron, etc.)\n * Set to false to go fully unstyled. Defaults to true.\n */\n styled?: boolean;\n /** Additional class name for each row (appended to defaults if styled=true) */\n rowClassName?: string;\n /** Additional class name for the children container */\n groupClassName?: string;\n /** Additional class name for the chevron */\n chevronClassName?: string;\n}\n\n/**\n * Tree.Recursive - Handles recursive rendering of tree nodes.\n * \n * This is a convenience component that handles all the recursive complexity\n * while still giving you control over how each node's content is rendered.\n * \n * By default, applies the library's CSS classes (tree__row, tree__chevron, etc.)\n * Set styled={false} to render without any default classes.\n * \n * @example\n * ```tsx\n * // Simple usage - default styles applied\n * <Tree.Root aria-label=\"Files\" className=\"tree__root\">\n * <Tree.Recursive\n * nodes={nodes}\n * renderContent={({ name }) => <span>{name}</span>}\n * />\n * </Tree.Root>\n * ```\n * \n * @example\n * ```tsx\n * // Unstyled (for custom styling)\n * <Tree.Root aria-label=\"Files\">\n * <Tree.Recursive\n * nodes={nodes}\n * styled={false}\n * renderContent={({ name }) => <span>{name}</span>}\n * />\n * </Tree.Root>\n * ```\n */\nfunction TreeRecursive<T = unknown>({\n nodes,\n renderContent: NodeContent,\n styled = true,\n rowClassName,\n groupClassName,\n chevronClassName,\n}: TreeRecursiveProps<T>) {\n return (\n <>\n {nodes.map((node, index) => (\n <TreeRecursiveItem<T>\n key={node.id ?? `${node.name}-${index}`}\n node={node}\n level={1}\n posinset={index + 1}\n setsize={nodes.length}\n parentId={null}\n NodeContent={NodeContent}\n styled={styled}\n rowClassName={rowClassName}\n groupClassName={groupClassName}\n chevronClassName={chevronClassName}\n />\n ))}\n </>\n );\n}\n\ninterface TreeRecursiveItemProps<T = unknown> {\n node: TreeNode<T>;\n level: number;\n posinset: number;\n setsize: number;\n parentId: string | null;\n NodeContent: React.ComponentType<TreeNode<T>>;\n styled: boolean;\n rowClassName?: string;\n groupClassName?: string;\n chevronClassName?: string;\n}\n\nfunction TreeRecursiveItem<T = unknown>({\n node,\n level,\n posinset,\n setsize,\n parentId,\n NodeContent,\n styled,\n rowClassName,\n groupClassName,\n chevronClassName,\n}: TreeRecursiveItemProps<T>) {\n const hasChildren = Boolean(node.children && node.children.length > 0);\n\n return (\n <TreeItem<T>\n node={node}\n level={level}\n posinset={posinset}\n setsize={setsize}\n parentId={parentId}\n >\n {({ isExpanded, isSelected, isFocused, nodeId }) => {\n // Build class names with defaults when styled=true\n const rowClasses = styled\n ? [\n \"tree__row\",\n isSelected && \"tree__row--selected\",\n isFocused && \"tree__row--focused\",\n rowClassName,\n ].filter(Boolean).join(\" \")\n : rowClassName;\n\n const groupClasses = styled\n ? [\n \"tree__children\",\n isExpanded && \"tree__children--open\",\n groupClassName,\n ].filter(Boolean).join(\" \")\n : groupClassName;\n\n const chevronClasses = styled\n ? [\"tree__chevron\", chevronClassName].filter(Boolean).join(\" \")\n : chevronClassName;\n\n const chevronOpenClass = styled ? \"tree__chevron--open\" : undefined;\n\n return (\n <>\n <TreeItemContent className={rowClasses}>\n <TreeChevron \n className={chevronClasses} \n openClassName={chevronOpenClass} \n />\n <NodeContent {...node} />\n </TreeItemContent>\n {hasChildren && (\n <TreeGroup className={groupClasses}>\n <div className={styled ? \"tree__children-inner\" : undefined}>\n {node.children!.map((childNode, index) => (\n <TreeRecursiveItem<T>\n key={childNode.id ?? `${childNode.name}-${index}`}\n node={childNode as TreeNode<T>}\n level={level + 1}\n posinset={index + 1}\n setsize={node.children!.length}\n parentId={nodeId}\n NodeContent={NodeContent}\n styled={styled}\n rowClassName={rowClassName}\n groupClassName={groupClassName}\n chevronClassName={chevronClassName}\n />\n ))}\n </div>\n </TreeGroup>\n )}\n </>\n );\n }}\n </TreeItem>\n );\n}\n\n/**\n * Tree compound component for building accessible trees.\n * \n * @example\n * ```tsx\n * import { Tree } from 'your-library/primitives';\n * \n * function FileTree({ files }) {\n * return (\n * <Tree.Root aria-label=\"Files\">\n * {files.map((file, idx) => (\n * <Tree.Item key={file.id} node={file} level={1} posinset={idx + 1} setsize={files.length} parentId={null}>\n * {({ isExpanded, hasChildren }) => (\n * <>\n * <Tree.ItemContent className=\"flex items-center gap-2 p-1 hover:bg-gray-100 rounded\">\n * <Tree.Chevron />\n * <span>{file.name}</span>\n * </Tree.ItemContent>\n * {hasChildren && (\n * <Tree.Group className=\"ml-4\">\n * {file.children.map((child, cidx) => (\n * <Tree.Item key={child.id} ... />\n * ))}\n * </Tree.Group>\n * )}\n * </>\n * )}\n * </Tree.Item>\n * ))}\n * </Tree.Root>\n * );\n * }\n * ```\n */\n/**\n * Tree compound component for building accessible trees.\n * \n * @example\n * ```tsx\n * // Simple usage with Tree.Recursive (handles recursion for you)\n * <Tree.Root aria-label=\"Files\">\n * <Tree.Recursive\n * nodes={nodes}\n * renderContent={({ name }) => <span>{name}</span>}\n * />\n * </Tree.Root>\n * ```\n * \n * @example\n * ```tsx\n * // Full control with primitives\n * <Tree.Root aria-label=\"Files\">\n * {nodes.map((node, idx) => (\n * <Tree.Item key={node.id} node={node} level={1} posinset={idx + 1} setsize={nodes.length} parentId={null}>\n * {({ isExpanded, hasChildren }) => (\n * <>\n * <Tree.ItemContent>\n * <Tree.Chevron />\n * <span>{node.name}</span>\n * </Tree.ItemContent>\n * {hasChildren && (\n * <Tree.Group>\n * {node.children.map(...)}\n * </Tree.Group>\n * )}\n * </>\n * )}\n * </Tree.Item>\n * ))}\n * </Tree.Root>\n * ```\n */\nexport const Tree = {\n Root: TreeRoot,\n Item: TreeItem,\n ItemContent: TreeItemContent,\n Chevron: TreeChevron,\n Group: TreeGroup,\n Nodes: TreeNodes,\n Recursive: TreeRecursive,\n};\n\n// Named exports for individual components\nexport {\n TreeRoot,\n TreeItem,\n TreeItemContent,\n TreeChevron,\n TreeGroup,\n TreeNodes,\n TreeRecursive,\n};\n\nexport default Tree;\n\n","import type { TreeNode, TreeNodeInternal } from \"./types\";\n\n/**\n * Options for flattening a tree\n */\nexport interface FlattenTreeOptions {\n /** Starting level (default: 1) */\n startLevel?: number;\n /** Filter function to exclude nodes */\n filter?: (node: TreeNode) => boolean;\n /** Whether to include collapsed nodes' children (default: true) */\n includeCollapsedChildren?: boolean;\n /** Set of expanded node IDs (used when includeCollapsedChildren is false) */\n expandedIds?: Set<string>;\n}\n\n/**\n * Flattens a tree structure into a flat array with computed properties.\n * Useful for virtualized rendering or when you need positional information.\n * \n * @example\n * ```tsx\n * const nodes = [{ name: 'Root', children: [{ name: 'Child' }] }];\n * const flat = flattenTree(nodes);\n * // Returns array with level, posinset, setsize for each node\n * ```\n */\nexport function flattenTree<T = unknown>(\n nodes: TreeNode<T>[],\n options: FlattenTreeOptions = {}\n): TreeNodeInternal<T>[] {\n const {\n startLevel = 1,\n filter,\n includeCollapsedChildren = true,\n expandedIds,\n } = options;\n\n const result: TreeNodeInternal<T>[] = [];\n\n function processNodes(\n items: TreeNode<T>[],\n level: number,\n parentId: string | null\n ) {\n const filteredItems = filter ? items.filter(filter) : items;\n\n filteredItems.forEach((node, index) => {\n const nodeId = node.id ?? `${parentId ?? \"root\"}-${level}-${index + 1}-${node.name}`;\n const hasChildren = Boolean(node.children && node.children.length > 0);\n \n const internalNode: TreeNodeInternal<T> = {\n ...node,\n nodeId,\n level,\n posinset: index + 1,\n setsize: filteredItems.length,\n parentId,\n hasChildren,\n };\n\n result.push(internalNode);\n\n // Process children if they exist and should be included\n if (hasChildren && node.children) {\n const shouldIncludeChildren = includeCollapsedChildren || \n (expandedIds && expandedIds.has(nodeId));\n \n if (shouldIncludeChildren) {\n processNodes(node.children as TreeNode<T>[], level + 1, nodeId);\n }\n }\n });\n }\n\n processNodes(nodes, startLevel, null);\n return result;\n}\n\n/**\n * Options for building a tree from flat data\n */\nexport interface BuildTreeOptions<T, R> {\n /** Function to get the parent ID from a record */\n getParentId: (record: R) => string | null;\n /** Function to get the ID from a record */\n getId: (record: R) => string;\n /** Function to transform a record into a TreeNode */\n transform: (record: R) => Omit<TreeNode<T>, \"children\">;\n}\n\n/**\n * Builds a tree structure from flat data.\n * Useful when working with database records that have parent references.\n * \n * @example\n * ```tsx\n * const records = [\n * { id: '1', name: 'Root', parentId: null },\n * { id: '2', name: 'Child', parentId: '1' },\n * ];\n * \n * const tree = buildTree(records, {\n * getId: r => r.id,\n * getParentId: r => r.parentId,\n * transform: r => ({ id: r.id, name: r.name }),\n * });\n * ```\n */\nexport function buildTree<T, R>(\n records: R[],\n options: BuildTreeOptions<T, R>\n): TreeNode<T>[] {\n const { getId, getParentId, transform } = options;\n \n // Build lookup map and identify roots\n const nodeMap = new Map<string, TreeNode<T>>();\n const roots: TreeNode<T>[] = [];\n\n // First pass: create all nodes\n records.forEach((record) => {\n const id = getId(record);\n const node: TreeNode<T> = {\n ...transform(record),\n children: [],\n };\n nodeMap.set(id, node);\n });\n\n // Second pass: build tree structure\n records.forEach((record) => {\n const id = getId(record);\n const parentId = getParentId(record);\n const node = nodeMap.get(id)!;\n\n if (parentId === null) {\n roots.push(node);\n } else {\n const parent = nodeMap.get(parentId);\n if (parent) {\n parent.children = parent.children || [];\n parent.children.push(node);\n } else {\n // Orphan node - treat as root\n roots.push(node);\n }\n }\n });\n\n // Clean up empty children arrays\n function cleanChildren(nodes: TreeNode<T>[]) {\n nodes.forEach((node) => {\n if (node.children && node.children.length === 0) {\n delete node.children;\n } else if (node.children) {\n cleanChildren(node.children);\n }\n });\n }\n\n cleanChildren(roots);\n return roots;\n}\n\n/**\n * Options for filtering a tree\n */\nexport interface FilterTreeOptions<T> {\n /** Keep ancestors of matching nodes (default: true) */\n keepAncestors?: boolean;\n /** Keep descendants of matching nodes (default: false) */\n keepDescendants?: boolean;\n}\n\n/**\n * Filters a tree structure, optionally keeping ancestors/descendants.\n * \n * @example\n * ```tsx\n * const filtered = filterTree(nodes, \n * node => node.name.includes('search'),\n * { keepAncestors: true }\n * );\n * ```\n */\nexport function filterTree<T = unknown>(\n nodes: TreeNode<T>[],\n predicate: (node: TreeNode<T>) => boolean,\n options: FilterTreeOptions<T> = {}\n): TreeNode<T>[] {\n const { keepAncestors = true, keepDescendants = false } = options;\n\n function filterNodes(items: TreeNode<T>[]): TreeNode<T>[] {\n const result: TreeNode<T>[] = [];\n\n items.forEach((node) => {\n const matches = predicate(node);\n let filteredChildren: TreeNode<T>[] = [];\n\n if (node.children && node.children.length > 0) {\n if (matches && keepDescendants) {\n // Keep all descendants as-is\n filteredChildren = node.children;\n } else {\n // Recursively filter children\n filteredChildren = filterNodes(node.children);\n }\n }\n\n if (matches) {\n // Node matches - include it\n result.push({\n ...node,\n children: filteredChildren.length > 0 ? filteredChildren : undefined,\n });\n } else if (keepAncestors && filteredChildren.length > 0) {\n // Node doesn't match but has matching descendants\n result.push({\n ...node,\n children: filteredChildren,\n });\n }\n });\n\n return result;\n }\n\n return filterNodes(nodes);\n}\n\n/**\n * Options for searching a tree\n */\nexport interface SearchTreeOptions {\n /** Case-insensitive search (default: true) */\n ignoreCase?: boolean;\n /** Search in additional fields (default: only name) */\n searchFields?: string[];\n /** Minimum characters to trigger search (default: 1) */\n minLength?: number;\n}\n\n/**\n * Searches a tree for nodes matching a query string.\n * Returns a filtered tree with ancestors preserved.\n * \n * @example\n * ```tsx\n * const results = searchTree(nodes, 'component', { ignoreCase: true });\n * ```\n */\nexport function searchTree<T = unknown>(\n nodes: TreeNode<T>[],\n query: string,\n options: SearchTreeOptions = {}\n): TreeNode<T>[] {\n const { ignoreCase = true, searchFields = [], minLength = 1 } = options;\n\n if (!query || query.length < minLength) {\n return nodes;\n }\n\n const searchQuery = ignoreCase ? query.toLowerCase() : query;\n\n const matches = (node: TreeNode<T>): boolean => {\n const name = ignoreCase ? node.name.toLowerCase() : node.name;\n if (name.includes(searchQuery)) {\n return true;\n }\n\n // Check additional fields in data\n if (node.data && searchFields.length > 0) {\n const data = node.data as Record<string, unknown>;\n return searchFields.some((field) => {\n const value = data[field];\n if (typeof value === \"string\") {\n const fieldValue = ignoreCase ? value.toLowerCase() : value;\n return fieldValue.includes(searchQuery);\n }\n return false;\n });\n }\n\n return false;\n };\n\n return filterTree(nodes, matches, { keepAncestors: true, keepDescendants: false });\n}\n\n/**\n * Finds a node by ID in a tree structure.\n */\nexport function findNodeById<T = unknown>(\n nodes: TreeNode<T>[],\n id: string\n): TreeNode<T> | null {\n for (const node of nodes) {\n if (node.id === id) {\n return node;\n }\n if (node.children) {\n const found = findNodeById(node.children, id);\n if (found) {\n return found;\n }\n }\n }\n return null;\n}\n\n/**\n * Gets the path from root to a node by ID.\n * Returns array of node IDs from root to target.\n */\nexport function getNodePath<T = unknown>(\n nodes: TreeNode<T>[],\n targetId: string\n): string[] {\n function findPath(items: TreeNode<T>[], path: string[]): string[] | null {\n for (const node of items) {\n const nodeId = node.id ?? node.name;\n const currentPath = [...path, nodeId];\n \n if (nodeId === targetId) {\n return currentPath;\n }\n \n if (node.children) {\n const found = findPath(node.children, currentPath);\n if (found) {\n return found;\n }\n }\n }\n return null;\n }\n\n return findPath(nodes, []) ?? [];\n}\n\n/**\n * Gets all node IDs in a tree (for expand all functionality).\n */\nexport function getAllNodeIds<T = unknown>(nodes: TreeNode<T>[]): string[] {\n const ids: string[] = [];\n\n function collectIds(items: TreeNode<T>[], parentId: string | null, level: number) {\n items.forEach((node, index) => {\n const nodeId = node.id ?? `${parentId ?? \"root\"}-${level}-${index + 1}-${node.name}`;\n ids.push(nodeId);\n if (node.children) {\n collectIds(node.children, nodeId, level + 1);\n }\n });\n }\n\n collectIds(nodes, null, 1);\n return ids;\n}\n\n/**\n * Gets all expandable node IDs (nodes with children).\n */\nexport function getExpandableNodeIds<T = unknown>(nodes: TreeNode<T>[]): string[] {\n const ids: string[] = [];\n\n function collectIds(items: TreeNode<T>[], parentId: string | null, level: number) {\n items.forEach((node, index) => {\n const nodeId = node.id ?? `${parentId ?? \"root\"}-${level}-${index + 1}-${node.name}`;\n if (node.children && node.children.length > 0) {\n ids.push(nodeId);\n collectIds(node.children, nodeId, level + 1);\n }\n });\n }\n\n collectIds(nodes, null, 1);\n return ids;\n}\n\n","/**\n * Utility function to combine CSS class names.\n * Filters out falsy values and joins the rest with spaces.\n */\nexport function cn(\n ...inputs: (string | undefined | null | false)[]\n): string {\n return inputs.filter(Boolean).join(\" \");\n}\n\n"],"names":["useTree","defaultExpandedIds","controlledExpandedIds","onExpandedIdsChange","controlledSelectedId","onSelect","onExpandChange","focusedId","setFocusedId","useState","internalSelectedId","setInternalSelectedId","internalExpandedIds","setInternalExpandedIds","isExpandedControlled","expandedIds","selectedId","nodeRegistry","useRef","firstNodeId","setFirstNodeId","visibleNodeIdsRef","treeRef","typeaheadBuffer","typeaheadTimeout","updateExpandedIds","useCallback","updater","newIds","registerNode","nodeId","node","parentId","current","unregisterNode","getParentId","_a","getNode","isExpanded","isSelected","isFocused","toggleExpanded","prev","next","willBeExpanded","expand","nodeInfo","collapse","expandAll","allIds","info","collapseAll","selectNode","getVisibleNodeIds","treeitems","ids","item","id","focusNode","element","navigateToNode","direction","currentId","visibleIds","effectiveFocusedId","_b","targetIndex","currentIndex","targetId","handleTypeahead","char","i","searchIndex","handleKeyDown","event","key","currentFocusedId","_c","state","useMemo","getRootProps","props","useTreeItem","level","posinset","setsize","groupId","hasChildren","isFirstFocusable","tabIndex","useEffect","toggle","select","getItemProps","getContentProps","getGroupProps","TreeContext","createContext","useTreeContext","context","useContext","TreeItemContext","useTreeItemContext","TreeRoot","children","className","style","ariaLabel","ariaLabelledby","contextValue","jsx","TreeItem","itemState","content","TreeItemContent","forwardRef","onClick","ref","contentProps","handleClick","DefaultChevron","open","TreeChevron","openClassName","closedClassName","combinedClassName","TreeGroup","groupProps","TreeNodes","nodes","renderItem","index","TreeRecursive","NodeContent","styled","rowClassName","groupClassName","chevronClassName","Fragment","TreeRecursiveItem","rowClasses","groupClasses","chevronClasses","chevronOpenClass","jsxs","childNode","Tree","flattenTree","options","startLevel","filter","includeCollapsedChildren","result","processNodes","items","filteredItems","internalNode","buildTree","records","getId","transform","nodeMap","roots","record","parent","cleanChildren","filterTree","predicate","keepAncestors","keepDescendants","filterNodes","matches","filteredChildren","searchTree","query","ignoreCase","searchFields","minLength","searchQuery","data","field","value","findNodeById","found","getNodePath","findPath","path","currentPath","getAllNodeIds","collectIds","getExpandableNodeIds","cn","inputs"],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {}
|