@sanity/hierarchical-document-list 2.1.3 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +30 -28
  3. package/dist/index.d.ts +170 -195
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +835 -6031
  6. package/dist/index.js.map +1 -1
  7. package/package.json +38 -77
  8. package/dist/index.d.mts +0 -240
  9. package/dist/index.mjs +0 -6433
  10. package/dist/index.mjs.map +0 -1
  11. package/sanity.json +0 -8
  12. package/src/TreeDeskStructure.tsx +0 -80
  13. package/src/TreeInputComponent.tsx +0 -41
  14. package/src/components/DeskWarning.tsx +0 -40
  15. package/src/components/DocumentInNode.tsx +0 -133
  16. package/src/components/DocumentPreviewStatus.tsx +0 -70
  17. package/src/components/NodeActions.tsx +0 -85
  18. package/src/components/NodeContentRenderer.tsx +0 -141
  19. package/src/components/PlaceholderDropzone.tsx +0 -45
  20. package/src/components/TreeEditor.tsx +0 -184
  21. package/src/components/TreeEditorErrorBoundary.tsx +0 -14
  22. package/src/components/TreeNodeRenderer.tsx +0 -37
  23. package/src/components/TreeNodeRendererScaffold.tsx +0 -193
  24. package/src/createDeskHierarchy.tsx +0 -110
  25. package/src/createHierarchicalSchemas.tsx +0 -151
  26. package/src/hooks/useAllItems.ts +0 -119
  27. package/src/hooks/useLocalTree.ts +0 -40
  28. package/src/hooks/useTreeOperations.ts +0 -25
  29. package/src/hooks/useTreeOperationsProvider.ts +0 -86
  30. package/src/index.ts +0 -25
  31. package/src/schemas/hierarchy.tree.ts +0 -19
  32. package/src/types.ts +0 -148
  33. package/src/utils/flatDataToTree.ts +0 -20
  34. package/src/utils/getAdjescentNodes.ts +0 -30
  35. package/src/utils/getCommonTreeProps.tsx +0 -28
  36. package/src/utils/getTreeHeight.ts +0 -8
  37. package/src/utils/gradientPatchAdapter.ts +0 -43
  38. package/src/utils/idUtils.ts +0 -7
  39. package/src/utils/injectNodeTypeInPatches.ts +0 -60
  40. package/src/utils/moveItemInArray.ts +0 -26
  41. package/src/utils/throwError.ts +0 -9
  42. package/src/utils/treeData.tsx +0 -119
  43. package/src/utils/treePatches.ts +0 -171
  44. package/v2-incompatible.js +0 -11
@@ -1,9 +0,0 @@
1
- const ERROR_MESSAGES = {
2
- invalidDocumentId: 'Please add a documentId to your tree',
3
- invalidDocumentType: 'Please add a valid documentType to createHierarchicalSchemas',
4
- invalidReferenceTo: "Missing valid 'referenceTo' value",
5
- }
6
-
7
- export default function throwError(message: keyof typeof ERROR_MESSAGES, extraContext = ''): void {
8
- throw new Error(`[hierarchical input] ${ERROR_MESSAGES[message]} ${extraContext}`)
9
- }
@@ -1,119 +0,0 @@
1
- import {TreeItem} from '@nosferatu500/react-sortable-tree'
2
- import {randomKey} from '@sanity/util/content'
3
- import {SanityDocument} from 'sanity'
4
- import DocumentInNode from '../components/DocumentInNode'
5
- import NodeActions from '../components/NodeActions'
6
- import {
7
- AllItems,
8
- DocumentPair,
9
- EnhancedTreeItem,
10
- LocalTreeItem,
11
- NodeProps,
12
- StoredTreeItem,
13
- VisibilityMap
14
- } from '../types'
15
- import flatDataToTree from './flatDataToTree'
16
- import {INTERNAL_NODE_TYPE, INTERNAL_NODE_VALUE_TYPE} from './injectNodeTypeInPatches'
17
-
18
- export const dataToEditorTree = ({
19
- tree,
20
- allItems,
21
- visibilityMap
22
- }: {
23
- tree: StoredTreeItem[]
24
- allItems: AllItems
25
- visibilityMap: VisibilityMap
26
- }): LocalTreeItem[] => {
27
- const itemsWithTitle = tree
28
- .filter((item) => item?.value?.reference?._ref)
29
- .map((item) => {
30
- const refId = item.value?.reference?._ref
31
- const docPair = refId ? allItems[refId] : undefined
32
- const draftDoc = docPair?.draft
33
- const publishedDoc = docPair?.published
34
-
35
- const enhancedItem: LocalTreeItem = {
36
- ...item,
37
- expanded: visibilityMap[item._key] !== false,
38
- draftId: draftDoc?._id,
39
- publishedId: publishedDoc?._id,
40
- draftUpdatedAt: draftDoc?._updatedAt,
41
- publishedUpdatedAt: publishedDoc?._updatedAt
42
- }
43
-
44
- return {
45
- ...enhancedItem,
46
- title: (nodeProps: NodeProps) => (
47
- <DocumentInNode item={enhancedItem} action={<NodeActions nodeProps={nodeProps} />} />
48
- ),
49
- children: []
50
- }
51
- })
52
- return flatDataToTree(itemsWithTitle)
53
- }
54
-
55
- const documentPairToNode = (doc?: DocumentPair): EnhancedTreeItem | undefined => {
56
- if (!doc?.published?._id) {
57
- return undefined
58
- }
59
-
60
- return {
61
- _key: randomKey(12),
62
- _type: INTERNAL_NODE_TYPE,
63
- draftId: doc.draft?._id,
64
- draftUpdatedAt: doc.draft?._updatedAt,
65
- publishedId: doc.published._id,
66
- publishedUpdatedAt: doc.published?._updatedAt,
67
- value: {
68
- _type: INTERNAL_NODE_VALUE_TYPE,
69
- reference: {
70
- _ref: doc.published._id,
71
- _type: 'reference',
72
- _weak: true
73
- },
74
- docType: doc.published._type
75
- }
76
- }
77
- }
78
-
79
- export const flatTree = (tree: TreeItem[]): TreeItem[] => {
80
- return tree.reduce((flattened, item) => {
81
- const {children, ...node} = item
82
- return [...flattened, node, ...(Array.isArray(children) ? flatTree(children) : [])]
83
- }, [] as TreeItem[])
84
- }
85
-
86
- export interface FetchData {
87
- mainTree?: LocalTreeItem[]
88
- allItems?: SanityDocument[]
89
- }
90
-
91
- export const getUnaddedItems = (data: {
92
- allItems: AllItems
93
- tree: StoredTreeItem[]
94
- }): EnhancedTreeItem[] => {
95
- if (!data.tree) {
96
- return Object.entries(data.allItems)
97
- .map((value) => documentPairToNode(value[1]))
98
- .filter(Boolean) as EnhancedTreeItem[]
99
- }
100
-
101
- return Object.entries(data.allItems)
102
- .filter(
103
- ([publishedId]) =>
104
- publishedId &&
105
- // unadded items shouldn't be in the tree
106
- !data.tree.some((treeItem) => treeItem?.value?.reference?._ref === publishedId)
107
- )
108
- .map(([, documentPair]) => documentPairToNode(documentPair))
109
- .filter(Boolean) as EnhancedTreeItem[]
110
- }
111
-
112
- export function normalizeNodeForStorage(item: LocalTreeItem): StoredTreeItem {
113
- return {
114
- _key: item._key,
115
- _type: item._type || INTERNAL_NODE_TYPE,
116
- value: item.value,
117
- parent: item.parent
118
- }
119
- }
@@ -1,171 +0,0 @@
1
- import {
2
- FlatDataItem,
3
- FullTree,
4
- getFlatDataFromTree,
5
- NodeData,
6
- TreeItem
7
- } from '@nosferatu500/react-sortable-tree'
8
- import {randomKey} from '@sanity/util/content'
9
- import * as Patch from 'sanity'
10
- import {LocalTreeItem, NodeProps} from '../types'
11
- import getAdjescentNodes from './getAdjescentNodes'
12
- import moveItemInArray from './moveItemInArray'
13
- import {normalizeNodeForStorage} from './treeData'
14
-
15
- export type HandleMovedNodeData = Omit<
16
- NodeData & FullTree & any,
17
- 'prevPath' | 'prevTreeIndex' | 'path' | 'treeIndex' | 'node'
18
- > & {node: LocalTreeItem}
19
-
20
- export type HandleMovedNode = (moveData: HandleMovedNodeData) => void
21
-
22
- export function getAddItemPatch(item: LocalTreeItem): unknown[] {
23
- const normalizedNode = normalizeNodeForStorage(item)
24
-
25
- return [
26
- // Add the node to the end of the tree
27
- Patch.insert([normalizedNode], 'after', [-1])
28
- ]
29
- }
30
-
31
- export function getDuplicateItemPatch(nodeProps: NodeProps): unknown[] {
32
- const newItem = {
33
- ...nodeProps.node,
34
- _key: randomKey(12)
35
- }
36
- const normalizedNode = normalizeNodeForStorage(newItem)
37
-
38
- return [
39
- // Add duplicated node before the existing one
40
- Patch.insert([normalizedNode], 'before', [{_key: nodeProps.node._key}])
41
- ]
42
- }
43
-
44
- export function getRemoveItemPatch({node}: Pick<NodeProps, 'node'>): unknown[] {
45
- const keyPath = {_key: node._key}
46
- const children = getChildrenPaths(node)
47
-
48
- return [
49
- // 1. Unset the removed node
50
- Patch.unset([keyPath]),
51
-
52
- // 2. Unset its children
53
- ...children.map((path) => Patch.unset([{_key: path}]))
54
- ]
55
- }
56
-
57
- export function getMovedNodePatch(data: HandleMovedNodeData): unknown[] {
58
- const {nextParentNode} = data
59
- const keyPath = {_key: data.node._key}
60
-
61
- // === REMOVING NODE FROM TREE ===
62
- // `nextPath` will be null if the item is removed from tree
63
- if (!Array.isArray(data.nextPath)) {
64
- return getRemoveItemPatch({node: data.node})
65
- }
66
-
67
- const nextFlatTree = getFlatDataFromTree({
68
- treeData: data.treeData,
69
- getNodeKey: (t) => t.node._key
70
- })
71
- const normalizedNode = normalizeNodeForStorage(data.node)
72
-
73
- const {leadingNode, followingNode} = getAdjescentNodes({
74
- flatTree: nextFlatTree,
75
- node: data.node,
76
- treeIndex: data.nextTreeIndex
77
- })
78
-
79
- return [
80
- // 1. Unset the moved node
81
- // (will be ignored by Content Lake on new nodes with _key not yet in tree)
82
- Patch.unset([keyPath]),
83
-
84
- // 2. SIBLING-BASED PLACEMENT
85
- // If we were to place solely based on nextTreeIndex, concurrent changes from other editors could put the new node in an unexpected position.
86
- // Let's instead anchor it to the _key of the sibling coming before or after it.
87
- leadingNode?.node?._key
88
- ? // After the sibling before it
89
- Patch.insert([normalizedNode], 'after', [{_key: leadingNode.node._key}])
90
- : // Or before the sibling right after it, in case there's no leading sibling node
91
- // prettier-ignore
92
- Patch.insert([normalizedNode], 'before', [followingNode?.node?._key ? {_key: followingNode.node._key} : data.nextTreeIndex]),
93
-
94
- // 3. Patch the new node with its new `parent`
95
- nextParentNode
96
- ? // If it has a parent node, set that parent's _key
97
- Patch.set(nextParentNode._key, [keyPath, 'parent'])
98
- : // Else remove the parent key entirely
99
- Patch.unset([keyPath, 'parent'])
100
- ]
101
- }
102
-
103
- function getChildrenPaths(node: TreeItem): string[] {
104
- if (!Array.isArray(node.children)) {
105
- return []
106
- }
107
-
108
- return node.children
109
- .reduce(
110
- (keyPaths, child) => [...keyPaths, child._key, ...getChildrenPaths(child)],
111
- [] as string[]
112
- )
113
- .filter(Boolean)
114
- }
115
-
116
- export function getMoveItemPatch({
117
- nodeProps: {node, treeIndex},
118
- localTree,
119
- direction = 'up'
120
- }: {
121
- nodeProps: any
122
- localTree: TreeItem[]
123
- direction: 'up' | 'down'
124
- }): unknown[] {
125
- const keyPath = {_key: node._key}
126
-
127
- const nextTreeIndex = treeIndex + (direction === 'up' ? -1 : 1)
128
-
129
- const flatTree = getFlatDataFromTree({
130
- treeData: localTree,
131
- getNodeKey: (t) => t.node._key
132
- })
133
- const nextFlatTree = moveItemInArray<FlatDataItem>({
134
- array: flatTree,
135
- fromIndex: treeIndex,
136
- toIndex: nextTreeIndex
137
- })
138
- const {leadingNode, followingNode} = getAdjescentNodes({
139
- flatTree: nextFlatTree,
140
- node,
141
- treeIndex: nextTreeIndex
142
- })
143
-
144
- const normalizedNode = normalizeNodeForStorage(node)
145
-
146
- // When moving up, look at following node to figure out what is the next parent.
147
- const nodeToInheritParent = direction === 'up' ? followingNode : leadingNode
148
- const nextParentNode = nodeToInheritParent?.parentNode
149
-
150
- return [
151
- // 1. Unset the moved node
152
- // (will be ignored by Content Lake on new nodes with _key not yet in tree)
153
- Patch.unset([keyPath]),
154
-
155
- // 2. SIBLING-BASED PLACEMENT
156
- leadingNode?.node?._key
157
- ? // After the sibling before it
158
- Patch.insert([normalizedNode], 'after', [{_key: leadingNode.node._key}])
159
- : // Or before the sibling right after it, in case there's no leading sibling node
160
- Patch.insert([normalizedNode], 'before', [
161
- followingNode?.node?._key ? {_key: followingNode.node._key} : nextTreeIndex
162
- ]),
163
-
164
- // 3. Patch the new node with its new `parent`
165
- nextParentNode
166
- ? // If it has a parent node, set that parent's _key
167
- Patch.set(nextParentNode._key, [keyPath, 'parent'])
168
- : // Else remove the parent key entirely
169
- Patch.unset([keyPath, 'parent'])
170
- ]
171
- }
@@ -1,11 +0,0 @@
1
- const {showIncompatiblePluginDialog} = require('@sanity/incompatible-plugin')
2
- const {name, version, sanityExchangeUrl} = require('./package.json')
3
-
4
- export default showIncompatiblePluginDialog({
5
- name: name,
6
- versions: {
7
- v3: version,
8
- v2: undefined,
9
- },
10
- sanityExchangeUrl,
11
- })