@sanity/hierarchical-document-list 0.1.0 → 1.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.
Files changed (85) hide show
  1. package/.husky/commit-msg +4 -0
  2. package/.husky/pre-commit +4 -0
  3. package/.idea/hierarchical-document-list.iml +11 -0
  4. package/.idea/inspectionProfiles/Project_Default.xml +6 -0
  5. package/.idea/misc.xml +6 -0
  6. package/.idea/modules.xml +8 -0
  7. package/.idea/prettier.xml +7 -0
  8. package/.idea/vcs.xml +6 -0
  9. package/CHANGELOG.md +15 -0
  10. package/README.md +329 -224
  11. package/commitlint.config.js +3 -0
  12. package/lib/TreeDeskStructure.d.ts +8 -7
  13. package/lib/TreeDeskStructure.js +96 -71
  14. package/lib/TreeInputComponent.d.ts +19 -19
  15. package/lib/TreeInputComponent.js +50 -21
  16. package/lib/components/DeskWarning.d.ts +6 -6
  17. package/lib/components/DeskWarning.js +46 -25
  18. package/lib/components/DocumentInNode.d.ts +11 -11
  19. package/lib/components/DocumentInNode.js +81 -58
  20. package/lib/components/DocumentPreviewStatus.d.ts +7 -7
  21. package/lib/components/DocumentPreviewStatus.js +39 -35
  22. package/lib/components/NodeActions.d.ts +10 -10
  23. package/lib/components/NodeActions.js +61 -37
  24. package/lib/components/NodeContentRenderer.d.ts +8 -8
  25. package/lib/components/NodeContentRenderer.js +105 -81
  26. package/lib/components/PlaceholderDropzone.d.ts +9 -9
  27. package/lib/components/PlaceholderDropzone.js +30 -28
  28. package/lib/components/SuppressedDnDManager.d.ts +2 -0
  29. package/lib/components/SuppressedDnDManager.js +59 -0
  30. package/lib/components/TreeEditor.d.ts +12 -12
  31. package/lib/components/TreeEditor.js +74 -54
  32. package/lib/components/TreeEditorErrorBoundary.d.ts +16 -17
  33. package/lib/components/TreeEditorErrorBoundary.js +74 -69
  34. package/lib/components/TreeNodeRenderer.d.ts +3 -3
  35. package/lib/components/TreeNodeRenderer.js +59 -35
  36. package/lib/components/TreeNodeRendererScaffold.d.ts +4 -4
  37. package/lib/components/TreeNodeRendererScaffold.js +44 -42
  38. package/lib/createDeskHierarchy.d.ts +14 -14
  39. package/lib/createDeskHierarchy.js +84 -67
  40. package/lib/createHierarchicalSchemas.d.ts +98 -0
  41. package/lib/createHierarchicalSchemas.js +138 -0
  42. package/lib/{utils → hooks}/useAllItems.d.ts +7 -7
  43. package/lib/{utils → hooks}/useAllItems.js +119 -94
  44. package/lib/{utils → hooks}/useLocalTree.d.ts +17 -17
  45. package/lib/{utils → hooks}/useLocalTree.js +59 -37
  46. package/lib/{utils → hooks}/useTreeOperations.d.ts +9 -9
  47. package/lib/hooks/useTreeOperations.js +39 -0
  48. package/lib/{utils → hooks}/useTreeOperationsProvider.d.ts +14 -14
  49. package/lib/hooks/useTreeOperationsProvider.js +85 -0
  50. package/lib/index.d.ts +3 -3
  51. package/lib/index.js +12 -3
  52. package/lib/schemas/hierarchy.tree.d.ts +13 -23
  53. package/lib/schemas/hierarchy.tree.js +19 -31
  54. package/lib/types.d.ts +128 -0
  55. package/lib/types.js +2 -0
  56. package/lib/utils/flatDataToTree.d.ts +6 -6
  57. package/lib/utils/flatDataToTree.js +26 -23
  58. package/lib/utils/getAdjescentNodes.d.ts +12 -12
  59. package/lib/utils/getAdjescentNodes.js +19 -16
  60. package/lib/utils/getCommonTreeProps.d.ts +7 -7
  61. package/lib/utils/getCommonTreeProps.js +33 -27
  62. package/lib/utils/getTreeHeight.d.ts +3 -3
  63. package/lib/utils/getTreeHeight.js +11 -7
  64. package/lib/utils/gradientPatchAdapter.d.ts +4 -4
  65. package/lib/utils/gradientPatchAdapter.js +40 -35
  66. package/lib/utils/idUtils.d.ts +2 -2
  67. package/lib/utils/idUtils.js +13 -8
  68. package/lib/utils/injectNodeTypeInPatches.d.ts +12 -0
  69. package/lib/utils/injectNodeTypeInPatches.js +59 -0
  70. package/lib/utils/moveItemInArray.d.ts +5 -5
  71. package/lib/utils/moveItemInArray.js +26 -23
  72. package/lib/utils/throwError.d.ts +7 -0
  73. package/lib/utils/throwError.js +12 -0
  74. package/lib/utils/treeData.d.ts +18 -18
  75. package/lib/utils/treeData.js +118 -106
  76. package/lib/utils/treePatches.d.ts +15 -15
  77. package/lib/utils/treePatches.js +171 -141
  78. package/lint-staged.config.js +4 -0
  79. package/package.json +65 -56
  80. package/sanity.json +12 -12
  81. package/tsconfig.json +20 -20
  82. package/lib/createHierarchicalField.d.ts +0 -8
  83. package/lib/createHierarchicalField.js +0 -51
  84. package/lib/utils/useTreeOperations.js +0 -16
  85. package/lib/utils/useTreeOperationsProvider.js +0 -60
@@ -0,0 +1,4 @@
1
+ #!/bin/sh
2
+ . "$(dirname "$0")/_/husky.sh"
3
+
4
+ npx --no -- commitlint --edit ""
@@ -0,0 +1,4 @@
1
+ #!/bin/sh
2
+ . "$(dirname "$0")/_/husky.sh"
3
+
4
+ npx lint-staged
@@ -0,0 +1,11 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <module type="JAVA_MODULE" version="4">
3
+ <component name="NewModuleRootManager" inherit-compiler-output="true">
4
+ <exclude-output />
5
+ <content url="file://$MODULE_DIR$">
6
+ <excludeFolder url="file://$MODULE_DIR$/lib" />
7
+ </content>
8
+ <orderEntry type="inheritedJdk" />
9
+ <orderEntry type="sourceFolder" forTests="false" />
10
+ </component>
11
+ </module>
@@ -0,0 +1,6 @@
1
+ <component name="InspectionProjectProfileManager">
2
+ <profile version="1.0">
3
+ <option name="myName" value="Project Default" />
4
+ <inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
5
+ </profile>
6
+ </component>
package/.idea/misc.xml ADDED
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="ProjectRootManager">
4
+ <output url="file://$PROJECT_DIR$/out" />
5
+ </component>
6
+ </project>
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="ProjectModuleManager">
4
+ <modules>
5
+ <module fileurl="file://$PROJECT_DIR$/.idea/hierarchical-document-list.iml" filepath="$PROJECT_DIR$/.idea/hierarchical-document-list.iml" />
6
+ </modules>
7
+ </component>
8
+ </project>
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="PrettierConfiguration">
4
+ <option name="myRunOnSave" value="true" />
5
+ <option name="myRunOnReformat" value="true" />
6
+ </component>
7
+ </project>
package/.idea/vcs.xml ADDED
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="VcsDirectoryMappings">
4
+ <mapping directory="" vcs="Git" />
5
+ </component>
6
+ </project>
package/CHANGELOG.md ADDED
@@ -0,0 +1,15 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
+
5
+ ## [1.1.0](https://github.com/sanity-io/hierarchical-document-list/compare/v1.0.0...v1.1.0) (2022-03-18)
6
+
7
+
8
+ ### Features
9
+
10
+ * types are now correctly bundled ([50ecd09](https://github.com/sanity-io/hierarchical-document-list/commit/50ecd0974af5bf09f17ee2e73d64e8db74701e42))
11
+
12
+
13
+ ### Bug Fixes
14
+
15
+ * multiple createDeskHierarchy in a studio now works correctly ([7283c4c](https://github.com/sanity-io/hierarchical-document-list/commit/7283c4c56dad3a845eff93ae112c9b43238cf612))
package/README.md CHANGED
@@ -1,224 +1,329 @@
1
- # sanity-plugin-hierarchical-document-list
2
-
3
- Plugin for editing hierarchical references in the [Sanity studio](https://www.sanity.io/docs/sanity-studio).
4
-
5
- ![Screenshot of the plugin](/screenshot-1.jpg)
6
-
7
- ⚠️ **Compatibility:** This plugin requires Sanity Studio [version 2.25.0](https://github.com/sanity-io/sanity/releases/tag/v2.25.0) or higher.
8
-
9
- If you're looking for a way to order documents on a flat list, refer to [@sanity/orderable-document-list](https://github.com/sanity-io/orderable-document-list).
10
-
11
- ## Getting started
12
-
13
- ```bash
14
- # From the root of your sanity project
15
- sanity install @sanity/hierarchical-document-list
16
- ```
17
-
18
- With the plugin installed, you'll add the following to your Desk Structure:
19
-
20
- 💡 _If you don't have a custom desk structure, refer to the [Structure Builder docs](https://www.sanity.io/docs/overview-structure-builder) to learn how to do so._
21
-
22
- ```js
23
- // deskStructure.js
24
- import S from '@sanity/desk-tool/structure-builder'
25
- import {createDeskHierarchy} from '@sanity/hierarchical-document-list'
26
-
27
- export default () => {
28
- return S.list()
29
- .title('Content')
30
- .items([
31
- ...S.documentTypeListItems(), // or whatever other structure you have
32
- createDeskHierarchy({
33
- title: 'Main table of contents',
34
-
35
- // The hierarchy will be stored in this document ID 👇
36
- documentId: 'main-table-of-contents',
37
-
38
- // Document types editors should be able to include in the hierarchy
39
- referenceTo: ['site.page', 'site.post', 'docs.article', 'social.youtubeVideo'],
40
-
41
- // ❓ Optional: provide filters and/or parameters for narrowing which documents can be added
42
- referenceOptions: {
43
- filter: 'status in $acceptedStatuses',
44
- filterParams: {
45
- acceptedStatuses: ['published', 'approved']
46
- }
47
- }
48
- })
49
- ])
50
- }
51
- ```
52
-
53
- ## How it works
54
-
55
- The hierarchical data is stored in the document specified by the `documentId` of your choosing. As compared to storing `parent` fields in each individual document in the hierarchy, this makes it easier to implement different hierarchies for the same content according to the context, and also simplifies querying the full structure - as you'll see in [Querying data](#querying-data) below.
56
-
57
- Keep in mind that **this document is live-edited**, meaning it has no draft and every change by editors will directly affect its published version.
58
-
59
- Instead of manually adding items one-by-one, the plugin will create a [GROQ](https://www.sanity.io/docs/overview-groq) query that matches all documents with a `_type` in `referenceTo`, that also match the optional `referenceOptions.filter`. From these documents, editors are able to drag, nest and re-order them at will from the "Items not added" list.
60
-
61
- If a document in the tree doesn't match the filters set, it'll still exist in the tree. This can happen if the document has a new, unfitting value, the configuration changed or it was deleted. Although the tree will still be publishable, editors will get a warning and won't be able to drag these entries around.
62
-
63
- ## Querying data
64
-
65
- The plugin stores flat arrays which represent your hierarchical data through `parent` keys. Here's an example of one top-level item with one child:
66
-
67
- ```json
68
- [
69
- {
70
- "_key": "741b9edde2ba",
71
- "_type": "hierarchy.node",
72
- "value": {
73
- "reference": {
74
- "_ref": "75c47994-e6bb-487a-b8c9-b283f2436031",
75
- "_type": "reference",
76
- "_weak": true // This plugin includes weak references by default
77
- },
78
- "docType": "docs.article"
79
- }
80
- // no `parent`, this item is top-level
81
- },
82
- {
83
- "_key": "f92eaeec96f7",
84
- "_type": "hierarchy.node",
85
- "value": {
86
- "reference": {
87
- "_ref": "7ad60a02-5d6e-47d8-92e2-6724cc130058",
88
- "_type": "reference",
89
- "_weak": true
90
- },
91
- "docType": "site.post"
92
- },
93
- // The `parent` property points to the _key of the parent node where this one is nested
94
- "parent": "741b9edde2ba"
95
- }
96
- ]
97
- ```
98
-
99
- 📌 If using GraphQL, refer to [Usage with GraphQL](#usage-with-graphql).
100
-
101
- From the the above, we know how to expand referenced documents in GROQ:
102
-
103
- ```groq
104
- *[_id == "main-table-of-contents"][0]{
105
- tree[] {
106
- // Make sure you include each item's _key and parent
107
- _key,
108
- parent,
109
-
110
- // "Expand" the reference to the node
111
- value {
112
- reference->{
113
- // Get whatever property you need from your documents
114
- title,
115
- slug,
116
- }
117
- }
118
- }
119
- }
120
- ```
121
-
122
- The query above will then need to be converted from flat data to a tree. Refer to [Using the data](#using-the-data).
123
-
124
- <!-- ### Other query scenarios
125
-
126
- Find a given document in a hierarchy and get its parent - useful for rendering breadcrumbs:
127
-
128
- ```groq
129
- // Works starting from Content Lake V2021-03-25
130
- *[_id == "main-table-of-contents"][0]{
131
- // From the tree, get the 1st node that references a given document _id
132
- tree[node._ref == "my-book-section"][0] {
133
- _key,
134
- "section": node.reference->{
135
- title,
136
- },
137
- // Then, from the tree get the element matching the `parent` _key of the found node
138
- "parentChapter": ^.tree[_key == ^.parent][0]{
139
- _key,
140
- "chapter": node.reference->{
141
- title,
142
- contributors,
143
- }
144
- },
145
- }
146
- }
147
- ```
148
-
149
- ---- -->
150
-
151
- ## Using the data
152
-
153
- From the flat data queried, you'll need to convert it to a nested tree with `flatDataToTree`:
154
-
155
- ```js
156
- import {flatDataToTree} from '@sanity/hierarchical-document-list'
157
-
158
- const hierarchyDocument = await client.fetch(`*[_id == "book-v3-review-a"][0]{
159
- tree[] {
160
- // Make sure you include each item's _key and parent
161
- _key,
162
- parent,
163
- value {
164
- reference->{
165
- title,
166
- slug,
167
- content,
168
- }
169
- }
170
- }
171
- }`)
172
- const tree = flatDataToTree(data.tree)
173
- ```
174
-
175
- After the transformation above, nodes with nested entries will include a `children` array. This data structure is recursive.
176
-
177
- ## Usage with GraphQL
178
-
179
- By default, this plugin will create and update documents of `_type: hierarchy.tree`, with a `tree` field holding the hierarchical data. When deploying a [GraphQL Sanity endpoint](https://www.sanity.io/docs/graphql), however, you'll need an explicit document type in your schema so that you get the proper types for querying.
180
-
181
- To add this document type, create a new document schema similar to the following:
182
-
183
- ```js
184
- import {createHierarchicalField} from '@sanity/hierarchical-document-list'
185
-
186
- export default {
187
- name: 'myCustomHierarchicalType',
188
- title: 'Custom document type for holding hierarchical data',
189
- type: 'document',
190
- liveEdit: true, // 👉 Important: set liveEdit to `true` to ensure the UI works properly
191
- fields: [
192
- createHierarchicalField({
193
- name: 'customTreeDataKey', // key for the tree field in the document
194
- title: 'Custom tree',
195
- options: {
196
- referenceTo: ['category']
197
- }
198
- })
199
- ]
200
- }
201
- ```
202
-
203
- Then, in your desk structure where you added the hierarchical document(s), include the right `documentType` and `fieldKeyInDocument` properties:
204
-
205
- ```js
206
- createDeskHierarchy({
207
- // Include whatever values you defined in your schema in the step above
208
- documentType: 'myCustomHierarchicalType', // the name of your document type
209
- fieldKeyInDocument: 'customTreeDataKey' // the name of the hierarchical field
210
- // ...
211
- })
212
- ```
213
-
214
- ---
215
-
216
- 📌 **Note:** you can also use the method above to add hierarchies inside the schema of documents and objects, which would be editable outside the desk structure.
217
-
218
- We're considering adapting this input to support any type of nest-able data, not only references. Until then, avoid `createHierarchicalField` for fields in nested schemas as, in these contexts, it lacks the necessary affordances for a good editing experience.
219
-
220
- ---
221
-
222
- ## License
223
-
224
- MIT-licensed. See LICENSE.
1
+ # sanity-plugin-hierarchical-document-list
2
+
3
+ Plugin for visually organizing documents as hierarchies in the [Sanity studio](https://www.sanity.io/docs/sanity-studio). Applications include:
4
+
5
+ - Tables of content - such as a book's sections and chapters
6
+ - Navigational structure & menus - a website mega-menu with multiple levels, for example
7
+ - Taxonomy inheritance - "_Carbs_ is a parent of _Legumes_ which is a parent of _Beans_"
8
+
9
+ ![Screenshot of the plugin](/screenshot-1.jpg)
10
+
11
+ ⚠️ **Compatibility:** This plugin requires Sanity Studio [version 2.25.0](https://github.com/sanity-io/sanity/releases/tag/v2.25.0) or higher.
12
+
13
+ If you're looking for a way to order documents on a flat list, refer to [@sanity/orderable-document-list](https://github.com/sanity-io/orderable-document-list).
14
+
15
+ ## Getting started
16
+
17
+ ```bash
18
+ # From the root of your sanity project
19
+ sanity install @sanity/hierarchical-document-list
20
+ ```
21
+
22
+ Once you've installed the plugin the next step is to add one or more hierarchy documents to your Structure Builder.
23
+
24
+ 💡 _To learn about custom desk structures, refer to the [Structure Builder docs](https://www.sanity.io/docs/overview-structure-builder)._
25
+
26
+ ```js
27
+ // deskStructure.js
28
+ import S from '@sanity/desk-tool/structure-builder'
29
+ import {createDeskHierarchy} from '@sanity/hierarchical-document-list'
30
+
31
+ export default () => {
32
+ return S.list()
33
+ .title('Content')
34
+ .items([
35
+ ...S.documentTypeListItems(), // or whatever other structure you have
36
+ createDeskHierarchy({
37
+ title: 'Main table of contents',
38
+
39
+ // The hierarchy will be stored in this document ID 👇
40
+ documentId: 'main-table-of-contents',
41
+
42
+ // Document types editors should be able to include in the hierarchy
43
+ referenceTo: ['site.page', 'site.post', 'docs.article', 'social.youtubeVideo'],
44
+
45
+ // ❓ Optional: provide filters and/or parameters for narrowing which documents can be added
46
+ referenceOptions: {
47
+ filter: 'status in $acceptedStatuses',
48
+ filterParams: {
49
+ acceptedStatuses: ['published', 'approved']
50
+ }
51
+ },
52
+
53
+ // Optional: limit the depth of your hierarachies
54
+ maxDept: 3
55
+ })
56
+ ])
57
+ }
58
+ ```
59
+
60
+ ## How it works
61
+
62
+ The hierarchical data is stored in a centralized document with the `documentId` of your choosing. As compared to storing parent/child relationships in each individual document in the hierarchy, this makes it easier to implement different hierarchies for the same content according to the context.
63
+
64
+ This approach also simplifies querying the full structure - as you'll see in [querying data](#querying-data) below.
65
+
66
+ Keep in mind that this specified **document is live-edited**, meaning it has no draft and every change by editors will directly affect its published version.
67
+
68
+ Instead of requiring editors to manually add items one-by-one, the plugin will create a [GROQ](https://www.sanity.io/docs/overview-groq) query that matches all documents with a `_type` in the `referenceTo` option you specify, that also match the optional `referenceOptions.filter`. From these documents, editors are able to drag, nest and re-order them at will from the "Add more items" list.
69
+
70
+ If a document in the tree doesn't match the filters set, it'll keep existing in the data. This can happen if the document has a new, unfitting value, the configuration changed or it was deleted. Although the tree will still be publishable, editors will get a warning and won't be able to drag these faulty entries around.
71
+
72
+ ## Querying data
73
+
74
+ The plugin stores flat arrays which represent your hierarchical data through `parent` keys. Here's an example of one top-level item with one child:
75
+
76
+ ```json
77
+ [
78
+ {
79
+ "_key": "741b9edde2ba",
80
+ "_type": "hierarchy.node",
81
+ "value": {
82
+ "reference": {
83
+ "_ref": "75c47994-e6bb-487a-b8c9-b283f2436031",
84
+ "_type": "reference",
85
+ "_weak": true // This plugin includes weak references by default
86
+ },
87
+ "docType": "docs.article"
88
+ }
89
+ // no `parent`, this item is top-level
90
+ },
91
+ {
92
+ "_key": "f92eaeec96f7",
93
+ "_type": "hierarchy.node",
94
+ "value": {
95
+ "reference": {
96
+ "_ref": "7ad60a02-5d6e-47d8-92e2-6724cc130058",
97
+ "_type": "reference",
98
+ "_weak": true
99
+ },
100
+ "docType": "site.post"
101
+ },
102
+ // The `parent` property points to the _key of the parent node where this one is nested
103
+ "parent": "741b9edde2ba"
104
+ }
105
+ ]
106
+ ```
107
+
108
+ 📌 If using GraphQL, refer to [Usage with GraphQL](#usage-with-graphql).
109
+
110
+ From the the above, we know how to expand referenced documents in GROQ:
111
+
112
+ ```groq
113
+ *[_id == "main-table-of-contents"][0]{
114
+ tree[] {
115
+ // Make sure you include each item's _key and parent
116
+ _key,
117
+ parent,
118
+
119
+ // "Expand" the reference to the node
120
+ value {
121
+ reference->{
122
+ // Get whatever property you need from your documents
123
+ title,
124
+ slug,
125
+ }
126
+ }
127
+ }
128
+ }
129
+ ```
130
+
131
+ The query above will then need to be converted from flat data to a tree. Refer to [Using the data](#using-the-data).
132
+
133
+ <!-- ### Other query scenarios
134
+
135
+ Find a given document in a hierarchy and get its parent - useful for rendering breadcrumbs:
136
+
137
+ ```groq
138
+ // Works starting from Content Lake V2021-03-25
139
+ *[_id == "main-table-of-contents"][0]{
140
+ // From the tree, get the 1st node that references a given document _id
141
+ tree[node._ref == "my-book-section"][0] {
142
+ _key,
143
+ "section": node.reference->{
144
+ title,
145
+ },
146
+ // Then, from the tree get the element matching the `parent` _key of the found node
147
+ "parentChapter": ^.tree[_key == ^.parent][0]{
148
+ _key,
149
+ "chapter": node.reference->{
150
+ title,
151
+ contributors,
152
+ }
153
+ },
154
+ }
155
+ }
156
+ ```
157
+
158
+ ---- -->
159
+
160
+ ## Using the data
161
+
162
+ From the flat data queried, you'll need to convert it to a nested tree with `flatDataToTree`:
163
+
164
+ ```js
165
+ import {flatDataToTree} from '@sanity/hierarchical-document-list'
166
+
167
+ const hierarchyDocument = await client.fetch(`*[_id == "book-v3-review-a"][0]{
168
+ tree[] {
169
+ // Make sure you include each item's _key and parent
170
+ _key,
171
+ parent,
172
+ value {
173
+ reference->{
174
+ title,
175
+ slug,
176
+ content,
177
+ }
178
+ }
179
+ }
180
+ }`)
181
+ const tree = flatDataToTree(data.tree)
182
+
183
+ /* Results in a recursively nested structure. Using the example data above:
184
+ {
185
+ "_key": "741b9edde2ba",
186
+ "_type": "hierarchy.node",
187
+ "value": {
188
+ "reference": {
189
+ "_ref": "75c47994-e6bb-487a-b8c9-b283f2436031",
190
+ "_type": "reference",
191
+ "_weak": true
192
+ },
193
+ "docType": "docs.article"
194
+ },
195
+ "parent": null,
196
+ "children": [
197
+ {
198
+ "_key": "f92eaeec96f7",
199
+ "_type": "hierarchy.node",
200
+ "value": {
201
+ "reference": {
202
+ "_ref": "7ad60a02-5d6e-47d8-92e2-6724cc130058",
203
+ "_type": "reference",
204
+ "_weak": true
205
+ },
206
+ "docType": "site.post"
207
+ },
208
+ "parent": "741b9edde2ba"
209
+ }
210
+ ]
211
+ }
212
+ */
213
+ ```
214
+
215
+ After the transformation above, nodes with nested entries will include a `children` array. This data structure is recursive.
216
+
217
+ ## Usage with GraphQL
218
+
219
+ By default, this plugin will create and update documents of `_type: hierarchy.tree`, with a `tree` field holding the hierarchical data. When deploying a [GraphQL Sanity endpoint](https://www.sanity.io/docs/graphql), however, you'll need an explicit document type in your schema so that you get the proper types for querying.
220
+
221
+ To add this document type, create a set of schemas with the `createHierarchicalSchemas`:
222
+
223
+ ```js
224
+ // hierarchicalSchemas.js
225
+ import {createHierarchicalSchemas} from '@sanity/hierarchical-document-list'
226
+
227
+ export const hierarchicalOptions = {
228
+ // choose the document type name that suits you best
229
+ documentType: 'myCustomHierarchicalType',
230
+
231
+ // key for the tree field in the document - "tree" by default
232
+ fieldKeyInDocument: 'customTreeDataKey',
233
+
234
+ // Document types editors should be able to include in the hierarchy
235
+ referenceTo: ['site.page', 'site.post', 'docs.article', 'social.youtubeVideo'],
236
+
237
+ // ❓ Optional: provide filters and/or parameters for narrowing which documents can be added
238
+ referenceOptions: {
239
+ filter: 'status in $acceptedStatuses',
240
+ filterParams: {
241
+ acceptedStatuses: ['published', 'approved']
242
+ }
243
+ },
244
+
245
+ // ❓ Optional: limit the depth of your hierarachies
246
+ maxDept: 3
247
+ }
248
+
249
+ export default createHierarchicalSchemas(hierarchicalOptions)
250
+ ```
251
+
252
+ And add these schemas to your studio:
253
+
254
+ ```js
255
+ import createSchema from 'part:@sanity/base/schema-creator'
256
+ import schemaTypes from 'all:part:@sanity/base/schema-type'
257
+ import hierarchicalSchemas from './hierarchicalSchemas'
258
+
259
+ export default createSchema({
260
+ name: 'default',
261
+ types: schemaTypes.concat([
262
+ // ...Other schemas
263
+ ...hierarchicalSchemas // add all items in the array of hierarchical schemas
264
+ ])
265
+ })
266
+ ```
267
+
268
+ Then, in your desk structure where you added the hierarchical document(s), include the right `documentType` and `fieldKeyInDocument` properties:
269
+
270
+ ```js
271
+ createDeskHierarchy({
272
+ // Include whatever values you defined in your schema in the step above
273
+ documentType: 'myCustomHierarchicalType', // the name of your document type
274
+ fieldKeyInDocument: 'customTreeDataKey' // the name of the hierarchical field
275
+ // ...
276
+ })
277
+
278
+ // Ideally, use the same configuration object you defined in your schemas:
279
+ import {hierarchicalOptions} from './hierarchicalSchemas'
280
+
281
+ createDeskHierarchy({
282
+ ...hierarchicalOptions
283
+ // ...
284
+ })
285
+ ```
286
+
287
+ ---
288
+
289
+ 📌 **Note:** you can also use the method above to add hierarchies inside the schema of documents and objects, which would be editable outside the desk structure.
290
+
291
+ We're considering adapting this input to support any type of nest-able data, not only references. Until then, avoid using the generated schemas in nested schemas as, in these contexts, it lacks the necessary affordances for a good editing experience.
292
+
293
+ ---
294
+
295
+ ## License
296
+
297
+ MIT-licensed. See LICENSE.
298
+
299
+ ## Developing
300
+
301
+ If you want to test a dev-build of this plugin in the studio there is a bit of a workaround.
302
+ npm/yarn link does not integrate correctly with StructureBuilder and schema part registration in
303
+ the Studio.
304
+
305
+ The most consistent workflow is:
306
+
307
+ 1.Install [yalc](https://github.com/wclr/yalc)
308
+ 2. Run `npm run build && yalc publish` in this repo
309
+ 3. In Sanity Studio:
310
+ 1. Run `yalc link @sanity/hierarchical-document-list`
311
+ 2. Run `yarn install` (installs the dependencies for the plugin)
312
+ 3. Ensure `"@sanity/hierarchical-document-list"` is present in `sanity.json` plugins array.
313
+ 4. Configure the plugin for structure as documented above
314
+
315
+ Rerun steps 2. and 3.1 after making edits to the plugin (or automate it).
316
+
317
+ ### Publishing
318
+
319
+ Test publish command safely:
320
+ * `yalc publish`
321
+
322
+ To go live with a new version, run:
323
+ * `npm run release`
324
+ * runs [standard-version](https://www.npmjs.com/package/standard-version) which will bump version according to semver, commit and tag
325
+ * feel free to inspect the results in package.json and git log before continuing
326
+ * `npm publish`
327
+ * Will clean, lint and build before finally publishing to npm.
328
+ * After publishing, you should push with tags:
329
+ * `git push --follow-tags`
@@ -0,0 +1,3 @@
1
+ module.exports = {
2
+ extends: ['@commitlint/config-conventional'],
3
+ }