@exegia/corpora-ui 0.20.0 → 0.22.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/dist-lib/components/blocks/auth/auth-flow-atom.d.ts +77 -0
- package/dist-lib/components/blocks/auth/auth-session-atom.d.ts +28 -0
- package/dist-lib/components/blocks/auth/auth-state-type.d.ts +71 -0
- package/dist-lib/components/blocks/auth/auth-state.d.ts +9 -0
- package/dist-lib/components/blocks/auth/use-auth-state.d.ts +52 -0
- package/dist-lib/components/blocks/layout.d.ts +4 -1
- package/dist-lib/components/blocks/nav/sidebar/__tests__/ai-sidebar-atom.test.d.ts +1 -0
- package/dist-lib/components/blocks/nav/sidebar/ai-sidebar-atom.d.ts +217 -0
- package/dist-lib/components/blocks/nav/sidebar/index.d.ts +3 -1
- package/dist-lib/components/blocks/nav/sidebar/sidebar-context.d.ts +3 -0
- package/dist-lib/components/blocks/nav/sidebar/sidebar-row.d.ts +3 -1
- package/dist-lib/components/blocks/nav/sidebar/type.d.ts +109 -29
- package/dist-lib/components/blocks/nav/sidebar/use-ai-sidebar-state.d.ts +29 -0
- package/dist-lib/components/blocks/nav/sidebar/use-ai-sidebar.d.ts +6 -1
- package/dist-lib/components/blocks/nav/sidebar/utils.d.ts +1 -1
- package/dist-lib/components/blocks/profile/index.d.ts +7 -0
- package/dist-lib/components/blocks/profile/profile-card-atom.d.ts +68 -0
- package/dist-lib/components/blocks/profile/profile-card-block.d.ts +28 -39
- package/dist-lib/components/blocks/profile/type.d.ts +80 -0
- package/dist-lib/components/blocks/profile/use-profile-card-state.d.ts +24 -0
- package/dist-lib/components/blocks/profile/use-profile-card.d.ts +34 -0
- package/dist-lib/components/blocks/shell/__tests__/shell-fit-atom.test.d.ts +1 -0
- package/dist-lib/components/blocks/shell/__tests__/shell-metrics.test.d.ts +1 -0
- package/dist-lib/components/blocks/shell/animated-panel-provider.d.ts +1 -1
- package/dist-lib/components/blocks/shell/animated-panel.d.ts +1 -1
- package/dist-lib/components/blocks/shell/index.d.ts +4 -12
- package/dist-lib/components/blocks/shell/shell-fit-atom.d.ts +68 -0
- package/dist-lib/components/blocks/shell/shell-metrics.d.ts +54 -0
- package/dist-lib/components/blocks/shell/type.d.ts +115 -3
- package/dist-lib/components/blocks/shell/use-shell-fit-state.d.ts +25 -0
- package/dist-lib/components/blocks/shell/use-shell-fit.d.ts +14 -0
- package/dist-lib/components/blocks/shell/use-shell-panels.d.ts +12 -1
- package/dist-lib/components/blocks/shell/utils.d.ts +32 -0
- package/dist-lib/components/composed/__tests__/logo.test.d.ts +1 -0
- package/dist-lib/components/composed/logo.d.ts +34 -0
- package/dist-lib/components/composed/tree/__tests__/tree-atom.test.d.ts +1 -0
- package/dist-lib/components/composed/tree/constants.d.ts +4 -4
- package/dist-lib/components/composed/tree/index.d.ts +3 -1
- package/dist-lib/components/composed/tree/tree-atom.d.ts +160 -0
- package/dist-lib/components/composed/tree/tree-node.d.ts +6 -1
- package/dist-lib/components/composed/tree/type.d.ts +116 -18
- package/dist-lib/components/composed/tree/use-tree-dnd.d.ts +18 -7
- package/dist-lib/components/composed/tree/use-tree-state.d.ts +25 -0
- package/dist-lib/components/composed/tree/use-tree.d.ts +4 -0
- package/dist-lib/components/composed/user-avatar.d.ts +5 -28
- package/dist-lib/components/user-avatar/__tests__/user-avatar.test.d.ts +1 -0
- package/dist-lib/components/user-avatar/component.d.ts +1 -8
- package/dist-lib/components/user-avatar/index.d.ts +5 -0
- package/dist-lib/components/user-avatar/presence-badge.d.ts +16 -0
- package/dist-lib/components/user-avatar/type.d.ts +53 -0
- package/dist-lib/components/user-avatar/use-user-avatar-state.d.ts +26 -0
- package/dist-lib/components/user-avatar/use-user-avatar.d.ts +37 -0
- package/dist-lib/components/user-avatar/user-avatar-atom.d.ts +64 -0
- package/dist-lib/components/user-avatar/utils.d.ts +22 -0
- package/dist-lib/index.d.ts +6 -3
- package/dist-lib/index.js +3732 -2670
- package/dist-lib/index.js.map +1 -1
- package/dist-lib/state/exegia-provider.d.ts +51 -0
- package/dist-lib/state/index.d.ts +4 -0
- package/dist-lib/state/store.d.ts +17 -0
- package/package.json +15 -12
- package/src/components/blocks/auth/__tests__/auth-state-atom.test.tsx +247 -0
- package/src/components/blocks/auth/auth-flow-atom.ts +238 -0
- package/src/components/blocks/auth/auth-session-atom.ts +82 -0
- package/src/components/blocks/auth/auth-state-type.ts +97 -0
- package/src/components/blocks/auth/auth-state.ts +52 -0
- package/src/components/blocks/auth/use-auth-state.ts +127 -0
- package/src/components/blocks/layout.ts +30 -2
- package/src/components/blocks/nav/sidebar/__tests__/ai-sidebar-atom.test.tsx +325 -0
- package/src/components/blocks/nav/sidebar/ai-sidebar-atom.ts +698 -0
- package/src/components/blocks/nav/sidebar/ai-sidebar.tsx +48 -42
- package/src/components/blocks/nav/sidebar/index.ts +53 -1
- package/src/components/blocks/nav/sidebar/sidebar-context.ts +15 -0
- package/src/components/blocks/nav/sidebar/sidebar-row.tsx +119 -50
- package/src/components/blocks/nav/sidebar/type.ts +125 -30
- package/src/components/blocks/nav/sidebar/use-ai-sidebar-state.ts +123 -0
- package/src/components/blocks/nav/sidebar/use-ai-sidebar.ts +301 -248
- package/src/components/blocks/nav/sidebar/utils.ts +1 -1
- package/src/components/blocks/profile/__tests__/profile-card-block.test.tsx +194 -0
- package/src/components/blocks/profile/index.ts +28 -0
- package/src/components/blocks/profile/profile-card-atom.ts +247 -0
- package/src/components/blocks/profile/profile-card-block.tsx +153 -74
- package/src/components/blocks/profile/type.ts +95 -0
- package/src/components/blocks/profile/use-profile-card-state.ts +67 -0
- package/src/components/blocks/profile/use-profile-card.ts +126 -0
- package/src/components/blocks/shell/__tests__/shell-fit-atom.test.tsx +360 -0
- package/src/components/blocks/shell/__tests__/shell-layout.test.tsx +192 -3
- package/src/components/blocks/shell/__tests__/shell-metrics.test.ts +108 -0
- package/src/components/blocks/shell/animated-panel-inset.tsx +5 -1
- package/src/components/blocks/shell/animated-panel-provider.tsx +77 -11
- package/src/components/blocks/shell/animated-panel-trigger.tsx +4 -0
- package/src/components/blocks/shell/animated-panel.tsx +126 -29
- package/src/components/blocks/shell/index.ts +18 -13
- package/src/components/blocks/shell/shell-fit-atom.ts +243 -0
- package/src/components/blocks/shell/shell-layout.tsx +55 -53
- package/src/components/blocks/shell/shell-metrics.ts +79 -0
- package/src/components/blocks/shell/type.ts +130 -3
- package/src/components/blocks/shell/use-shell-fit-state.ts +49 -0
- package/src/components/blocks/shell/use-shell-fit.ts +135 -0
- package/src/components/blocks/shell/use-shell-panels.ts +57 -4
- package/src/components/blocks/shell/utils.ts +44 -4
- package/src/components/composed/__tests__/logo.test.tsx +60 -0
- package/src/components/composed/logo.tsx +159 -0
- package/src/components/composed/tree/CLAUDE.md +132 -0
- package/src/components/composed/tree/__tests__/tree-atom.test.tsx +217 -0
- package/src/components/composed/tree/__tests__/tree.test.tsx +162 -37
- package/src/components/composed/tree/__tests__/use-tree.test.tsx +2 -1
- package/src/components/composed/tree/constants.ts +4 -4
- package/src/components/composed/tree/index.ts +38 -0
- package/src/components/composed/tree/tree-atom.ts +590 -0
- package/src/components/composed/tree/tree-node.tsx +117 -78
- package/src/components/composed/tree/tree.tsx +24 -16
- package/src/components/composed/tree/type.ts +125 -15
- package/src/components/composed/tree/use-tree-dnd.ts +82 -51
- package/src/components/composed/tree/use-tree-state.ts +105 -0
- package/src/components/composed/tree/use-tree.ts +185 -184
- package/src/components/composed/user-avatar.tsx +11 -99
- package/src/components/user-avatar/__tests__/user-avatar.test.tsx +286 -0
- package/src/components/user-avatar/component.tsx +151 -22
- package/src/components/user-avatar/fallback.tsx +3 -1
- package/src/components/user-avatar/index.ts +19 -0
- package/src/components/user-avatar/presence-badge.tsx +56 -0
- package/src/components/user-avatar/type.ts +58 -0
- package/src/components/user-avatar/use-user-avatar-state.ts +60 -0
- package/src/components/user-avatar/use-user-avatar.ts +180 -0
- package/src/components/user-avatar/user-avatar-atom.ts +218 -0
- package/src/components/user-avatar/utils.ts +94 -0
- package/src/index.ts +35 -3
- package/src/state/exegia-provider.tsx +79 -0
- package/src/state/index.ts +4 -0
- package/src/state/store.ts +19 -0
- package/dist-lib/components/blocks/nav/sidebar-block.d.ts +0 -14
- package/dist-lib/components/blocks/nav/sidebar-nav-row.d.ts +0 -3
- package/dist-lib/components/blocks/nav/types.d.ts +0 -60
- package/dist-lib/components/blocks/nav/utils.d.ts +0 -1
- package/dist-lib/components/blocks/shell/animated-sidebar-content.d.ts +0 -2
- package/dist-lib/components/blocks/shell/animated-sidebar-footer.d.ts +0 -2
- package/dist-lib/components/blocks/shell/animated-sidebar-group-content.d.ts +0 -2
- package/dist-lib/components/blocks/shell/animated-sidebar-group-label.d.ts +0 -2
- package/dist-lib/components/blocks/shell/animated-sidebar-group.d.ts +0 -2
- package/dist-lib/components/blocks/shell/animated-sidebar-header.d.ts +0 -2
- package/dist-lib/components/blocks/shell/animated-sidebar-menu-button.d.ts +0 -3
- package/dist-lib/components/blocks/shell/animated-sidebar-menu-item.d.ts +0 -2
- package/dist-lib/components/blocks/shell/animated-sidebar-menu-sub-button.d.ts +0 -3
- package/dist-lib/components/blocks/shell/animated-sidebar-menu-sub-item.d.ts +0 -2
- package/dist-lib/components/blocks/shell/animated-sidebar-menu-sub.d.ts +0 -2
- package/dist-lib/components/blocks/shell/animated-sidebar-menu.d.ts +0 -2
- package/src/components/blocks/nav/__tests__/sidebar-block.test.tsx +0 -125
- package/src/components/blocks/nav/sidebar-block.tsx +0 -142
- package/src/components/blocks/nav/sidebar-nav-row.tsx +0 -78
- package/src/components/blocks/nav/types.ts +0 -65
- package/src/components/blocks/nav/utils.ts +0 -4
- package/src/components/blocks/shell/animated-sidebar-content.tsx +0 -19
- package/src/components/blocks/shell/animated-sidebar-footer.tsx +0 -19
- package/src/components/blocks/shell/animated-sidebar-group-content.tsx +0 -16
- package/src/components/blocks/shell/animated-sidebar-group-label.tsx +0 -29
- package/src/components/blocks/shell/animated-sidebar-group.tsx +0 -16
- package/src/components/blocks/shell/animated-sidebar-header.tsx +0 -16
- package/src/components/blocks/shell/animated-sidebar-menu-button.tsx +0 -151
- package/src/components/blocks/shell/animated-sidebar-menu-item.tsx +0 -20
- package/src/components/blocks/shell/animated-sidebar-menu-sub-button.tsx +0 -85
- package/src/components/blocks/shell/animated-sidebar-menu-sub-item.tsx +0 -19
- package/src/components/blocks/shell/animated-sidebar-menu-sub.tsx +0 -44
- package/src/components/blocks/shell/animated-sidebar-menu.tsx +0 -26
- /package/dist-lib/components/blocks/{nav/__tests__/sidebar-block.test.d.ts → auth/__tests__/auth-state-atom.test.d.ts} +0 -0
|
@@ -1,39 +1,62 @@
|
|
|
1
1
|
"use client"
|
|
2
2
|
|
|
3
3
|
import * as React from "react"
|
|
4
|
+
import { useAtomValue, useSetAtom, useStore } from "jotai"
|
|
4
5
|
|
|
6
|
+
import {
|
|
7
|
+
endTreeDragAtom,
|
|
8
|
+
moveTreeNodeAtom,
|
|
9
|
+
treeCanMoveAtom,
|
|
10
|
+
treeDraggedIdAtom,
|
|
11
|
+
treeDropTargetAtom,
|
|
12
|
+
treeItemsAtom,
|
|
13
|
+
} from "./tree-atom"
|
|
5
14
|
import type {
|
|
6
15
|
TreeDndContextValue,
|
|
16
|
+
TreeDndHandlers,
|
|
7
17
|
TreeDropPosition,
|
|
18
|
+
TreeInstanceId,
|
|
8
19
|
TreeNode,
|
|
9
|
-
UseTreeOptions,
|
|
10
20
|
} from "./type"
|
|
11
21
|
import { containsNode, findNode, locateNode } from "./utils"
|
|
12
22
|
|
|
13
|
-
/** How far into a folder row the pointer must sit (from either edge) to
|
|
14
|
-
*
|
|
23
|
+
/** How far into a folder row the pointer must sit (from either edge) to read
|
|
24
|
+
* as "inside" rather than "before"/"after". */
|
|
15
25
|
const EDGE_RATIO = 0.25
|
|
16
26
|
|
|
17
|
-
/**
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
27
|
+
/**
|
|
28
|
+
* The drag handlers for the `files` variant, stable for the life of the tree.
|
|
29
|
+
*
|
|
30
|
+
* Nothing here subscribes to drag state: items, the dragged id and the drop
|
|
31
|
+
* target are read out of the store when a handler runs. That is what lets
|
|
32
|
+
* every row share one handler object without re-rendering when a drag moves —
|
|
33
|
+
* and it keeps `useTree` from subscribing to data it also projects from
|
|
34
|
+
* props, which would loop on an inline `items` array.
|
|
35
|
+
*
|
|
36
|
+
* Inert unless the tree `canMove`. `dataTransfer` is set for interop but
|
|
37
|
+
* never read, so the flow also works where the store is unavailable (tests,
|
|
38
|
+
* some webviews).
|
|
39
|
+
*/
|
|
40
|
+
export function useTreeDndHandlers(treeId: TreeInstanceId): TreeDndHandlers {
|
|
41
|
+
const store = useStore()
|
|
42
|
+
const enabled = useAtomValue(treeCanMoveAtom(treeId))
|
|
43
|
+
const setDraggedId = useSetAtom(treeDraggedIdAtom(treeId))
|
|
44
|
+
const setDropTarget = useSetAtom(treeDropTargetAtom(treeId))
|
|
45
|
+
const move = useSetAtom(moveTreeNodeAtom(treeId))
|
|
46
|
+
const reset = useSetAtom(endTreeDragAtom(treeId))
|
|
32
47
|
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
48
|
+
const readItems = React.useCallback(
|
|
49
|
+
() => store.get(treeItemsAtom(treeId)),
|
|
50
|
+
[store, treeId]
|
|
51
|
+
)
|
|
52
|
+
const readDraggedId = React.useCallback(
|
|
53
|
+
() => store.get(treeDraggedIdAtom(treeId)),
|
|
54
|
+
[store, treeId]
|
|
55
|
+
)
|
|
56
|
+
const readDropTarget = React.useCallback(
|
|
57
|
+
() => store.get(treeDropTargetAtom(treeId)),
|
|
58
|
+
[store, treeId]
|
|
59
|
+
)
|
|
37
60
|
|
|
38
61
|
const onRowDragStart = React.useCallback(
|
|
39
62
|
(event: React.DragEvent, id: string) => {
|
|
@@ -45,14 +68,15 @@ export function useTreeDnd(
|
|
|
45
68
|
event.dataTransfer.setData("text/plain", id)
|
|
46
69
|
}
|
|
47
70
|
},
|
|
48
|
-
[enabled]
|
|
71
|
+
[enabled, setDraggedId]
|
|
49
72
|
)
|
|
50
73
|
|
|
51
74
|
const onRowDragOver = React.useCallback(
|
|
52
75
|
(event: React.DragEvent, node: TreeNode) => {
|
|
76
|
+
const draggedId = readDraggedId()
|
|
53
77
|
if (!enabled || draggedId === null) return
|
|
54
78
|
// A node never drops onto itself or into its own subtree.
|
|
55
|
-
if (containsNode(
|
|
79
|
+
if (containsNode(readItems(), draggedId, node.id)) return
|
|
56
80
|
event.preventDefault()
|
|
57
81
|
event.stopPropagation()
|
|
58
82
|
if (event.dataTransfer) event.dataTransfer.dropEffect = "move"
|
|
@@ -60,8 +84,8 @@ export function useTreeDnd(
|
|
|
60
84
|
const rect = event.currentTarget.getBoundingClientRect()
|
|
61
85
|
const ratio =
|
|
62
86
|
rect.height > 0 ? (event.clientY - rect.top) / rect.height : 0.5
|
|
63
|
-
// Any node carrying a children array is a folder — an empty one
|
|
64
|
-
//
|
|
87
|
+
// Any node carrying a children array is a folder — an empty one still
|
|
88
|
+
// accepts drops "inside".
|
|
65
89
|
const folder = node.children !== undefined
|
|
66
90
|
const position: TreeDropPosition = folder
|
|
67
91
|
? ratio < EDGE_RATIO
|
|
@@ -78,33 +102,38 @@ export function useTreeDnd(
|
|
|
78
102
|
: { id: node.id, position }
|
|
79
103
|
)
|
|
80
104
|
},
|
|
81
|
-
[enabled,
|
|
105
|
+
[enabled, readDraggedId, readItems, setDropTarget]
|
|
82
106
|
)
|
|
83
107
|
|
|
84
|
-
const onRowDragLeave = React.useCallback(
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
108
|
+
const onRowDragLeave = React.useCallback(
|
|
109
|
+
(event: React.DragEvent) => {
|
|
110
|
+
// Leaving for a child of the same row still counts as hovering it.
|
|
111
|
+
const next = event.relatedTarget as Node | null
|
|
112
|
+
if (next && event.currentTarget.contains(next)) return
|
|
113
|
+
setDropTarget(null)
|
|
114
|
+
},
|
|
115
|
+
[setDropTarget]
|
|
116
|
+
)
|
|
90
117
|
|
|
91
118
|
const onRowDrop = React.useCallback(
|
|
92
119
|
(event: React.DragEvent, node: TreeNode) => {
|
|
93
120
|
if (!enabled) return
|
|
94
121
|
event.preventDefault()
|
|
95
122
|
event.stopPropagation()
|
|
96
|
-
const
|
|
123
|
+
const draggedId = readDraggedId()
|
|
124
|
+
const target = readDropTarget()
|
|
97
125
|
if (draggedId === null || target === null || target.id !== node.id) {
|
|
98
126
|
reset()
|
|
99
127
|
return
|
|
100
128
|
}
|
|
129
|
+
const items = readItems()
|
|
101
130
|
|
|
102
131
|
if (target.position === "inside") {
|
|
103
|
-
// Append at the end of the folder, sized without the dragged node
|
|
104
|
-
//
|
|
132
|
+
// Append at the end of the folder, sized without the dragged node (it
|
|
133
|
+
// may already live there).
|
|
105
134
|
const children = node.children ?? []
|
|
106
135
|
const index = children.filter((child) => child.id !== draggedId).length
|
|
107
|
-
|
|
136
|
+
move(draggedId, node.id, index)
|
|
108
137
|
} else {
|
|
109
138
|
const location = locateNode(items, node.id)
|
|
110
139
|
if (location) {
|
|
@@ -115,34 +144,36 @@ export function useTreeDnd(
|
|
|
115
144
|
).filter((sibling) => sibling.id !== draggedId)
|
|
116
145
|
const at = siblings.findIndex((sibling) => sibling.id === node.id)
|
|
117
146
|
const index = target.position === "after" ? at + 1 : at
|
|
118
|
-
|
|
147
|
+
move(draggedId, location.parentId, index)
|
|
119
148
|
}
|
|
120
149
|
}
|
|
121
150
|
reset()
|
|
122
151
|
},
|
|
123
|
-
[enabled,
|
|
152
|
+
[enabled, move, readDraggedId, readDropTarget, readItems, reset]
|
|
124
153
|
)
|
|
125
154
|
|
|
126
155
|
return React.useMemo(
|
|
127
156
|
() => ({
|
|
128
157
|
enabled,
|
|
129
|
-
draggedId,
|
|
130
|
-
dropTarget,
|
|
131
158
|
onRowDragStart,
|
|
132
159
|
onRowDragOver,
|
|
133
160
|
onRowDragLeave,
|
|
134
161
|
onRowDrop,
|
|
135
162
|
onRowDragEnd: reset,
|
|
136
163
|
}),
|
|
137
|
-
[
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
164
|
+
[enabled, onRowDragStart, onRowDragOver, onRowDragLeave, onRowDrop, reset]
|
|
165
|
+
)
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/** The handlers plus live drag state, for `TreeController.dnd`. Rows take the
|
|
169
|
+
* handlers alone and read the state per node instead. */
|
|
170
|
+
export function useTreeDnd(treeId: TreeInstanceId): TreeDndContextValue {
|
|
171
|
+
const handlers = useTreeDndHandlers(treeId)
|
|
172
|
+
const draggedId = useAtomValue(treeDraggedIdAtom(treeId))
|
|
173
|
+
const dropTarget = useAtomValue(treeDropTargetAtom(treeId))
|
|
174
|
+
|
|
175
|
+
return React.useMemo(
|
|
176
|
+
() => ({ ...handlers, draggedId, dropTarget }),
|
|
177
|
+
[handlers, draggedId, dropTarget]
|
|
147
178
|
)
|
|
148
179
|
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import * as React from "react"
|
|
4
|
+
import { useAtomValue, useSetAtom } from "jotai"
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
cancelTreeRenameAtom,
|
|
8
|
+
collapseAllTreeNodesAtom,
|
|
9
|
+
collapseTreeNodeAtom,
|
|
10
|
+
expandAllTreeNodesAtom,
|
|
11
|
+
expandTreeNodeAtom,
|
|
12
|
+
moveTreeNodeAtom,
|
|
13
|
+
renameTreeNodeAtom,
|
|
14
|
+
resetTreeAtom,
|
|
15
|
+
revealTreeNodeAtom,
|
|
16
|
+
selectTreeNodeAtom,
|
|
17
|
+
setTreeCollapsedAtom,
|
|
18
|
+
setTreeItemsAtom,
|
|
19
|
+
startTreeRenameAtom,
|
|
20
|
+
toggleTreeCollapsedAtom,
|
|
21
|
+
toggleTreeNodeAtom,
|
|
22
|
+
treeStateAtom,
|
|
23
|
+
} from "./tree-atom"
|
|
24
|
+
import type { TreeActions, TreeInstanceId, TreeState } from "./type"
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Read the tree registered under `treeId` from anywhere below
|
|
28
|
+
* `ExegiaProvider` — no controller, no props, no provider of its own.
|
|
29
|
+
*
|
|
30
|
+
* ```tsx
|
|
31
|
+
* const { collapsed, activeId } = useTreeState("app-nav")
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* This returns the whole state object, so the caller re-renders on any
|
|
35
|
+
* change. A component that reads one field should subscribe to that field's
|
|
36
|
+
* atom instead: `useAtomValue(treeCollapsedAtom("app-nav"))`.
|
|
37
|
+
*/
|
|
38
|
+
export function useTreeState(treeId: TreeInstanceId): TreeState {
|
|
39
|
+
return useAtomValue(treeStateAtom(treeId))
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Drive the tree registered under `treeId` from anywhere. Writes only — the
|
|
44
|
+
* caller never re-renders when the tree changes, so this is what a command
|
|
45
|
+
* palette, a keyboard shortcut or a route guard should reach for.
|
|
46
|
+
*
|
|
47
|
+
* ```tsx
|
|
48
|
+
* const nav = useTreeActions("app-nav")
|
|
49
|
+
* <Button onClick={nav.collapseAll}>Collapse all</Button>
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
export function useTreeActions(treeId: TreeInstanceId): TreeActions {
|
|
53
|
+
const expand = useSetAtom(expandTreeNodeAtom(treeId))
|
|
54
|
+
const collapse = useSetAtom(collapseTreeNodeAtom(treeId))
|
|
55
|
+
const toggleExpanded = useSetAtom(toggleTreeNodeAtom(treeId))
|
|
56
|
+
const expandAll = useSetAtom(expandAllTreeNodesAtom(treeId))
|
|
57
|
+
const collapseAll = useSetAtom(collapseAllTreeNodesAtom(treeId))
|
|
58
|
+
const reveal = useSetAtom(revealTreeNodeAtom(treeId))
|
|
59
|
+
const setCollapsed = useSetAtom(setTreeCollapsedAtom(treeId))
|
|
60
|
+
const toggleCollapsed = useSetAtom(toggleTreeCollapsedAtom(treeId))
|
|
61
|
+
const select = useSetAtom(selectTreeNodeAtom(treeId))
|
|
62
|
+
const startRename = useSetAtom(startTreeRenameAtom(treeId))
|
|
63
|
+
const cancelRename = useSetAtom(cancelTreeRenameAtom(treeId))
|
|
64
|
+
const rename = useSetAtom(renameTreeNodeAtom(treeId))
|
|
65
|
+
const move = useSetAtom(moveTreeNodeAtom(treeId))
|
|
66
|
+
const setItems = useSetAtom(setTreeItemsAtom(treeId))
|
|
67
|
+
const reset = useSetAtom(resetTreeAtom(treeId))
|
|
68
|
+
|
|
69
|
+
return React.useMemo(
|
|
70
|
+
() => ({
|
|
71
|
+
expand,
|
|
72
|
+
collapse,
|
|
73
|
+
toggleExpanded,
|
|
74
|
+
expandAll,
|
|
75
|
+
collapseAll,
|
|
76
|
+
reveal,
|
|
77
|
+
setCollapsed,
|
|
78
|
+
toggleCollapsed,
|
|
79
|
+
select,
|
|
80
|
+
startRename,
|
|
81
|
+
cancelRename,
|
|
82
|
+
rename,
|
|
83
|
+
move,
|
|
84
|
+
setItems,
|
|
85
|
+
reset,
|
|
86
|
+
}),
|
|
87
|
+
[
|
|
88
|
+
expand,
|
|
89
|
+
collapse,
|
|
90
|
+
toggleExpanded,
|
|
91
|
+
expandAll,
|
|
92
|
+
collapseAll,
|
|
93
|
+
reveal,
|
|
94
|
+
setCollapsed,
|
|
95
|
+
toggleCollapsed,
|
|
96
|
+
select,
|
|
97
|
+
startRename,
|
|
98
|
+
cancelRename,
|
|
99
|
+
rename,
|
|
100
|
+
move,
|
|
101
|
+
setItems,
|
|
102
|
+
reset,
|
|
103
|
+
]
|
|
104
|
+
)
|
|
105
|
+
}
|