@driftime/sanity-plugin-handbook 0.4.0 → 0.4.1
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 +18 -16
- package/dist/index.d.ts +68 -75
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +180 -186
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -11,21 +11,18 @@ import { ChevronRightIcon } from "@sanity/icons/ChevronRight";
|
|
|
11
11
|
import { Popover } from "@sanity/ui/popover";
|
|
12
12
|
import { PortableText } from "@portabletext/react";
|
|
13
13
|
import { Code } from "@sanity/ui/code";
|
|
14
|
-
/**
|
|
15
|
-
* Properties the plugin's own icons are drawn with. Icons taken from `@sanity/icons` are left alone,
|
|
16
|
-
* since they already carry the sizing and stroke the rest of the Studio uses.
|
|
17
|
-
*/
|
|
14
|
+
/** Default props for the plugin's own icons. Icons from `@sanity/icons` already match the Studio. */
|
|
18
15
|
const defaultIconProps = {
|
|
19
16
|
width: "1em",
|
|
20
17
|
height: "1em",
|
|
21
18
|
strokeWidth: 1.5
|
|
22
19
|
};
|
|
23
20
|
/**
|
|
24
|
-
*
|
|
21
|
+
* Wraps an SVG icon component for use in the Studio.
|
|
25
22
|
*
|
|
26
|
-
* @param icon - The icon
|
|
27
|
-
* @param props -
|
|
28
|
-
* @returns
|
|
23
|
+
* @param icon - The icon to wrap.
|
|
24
|
+
* @param props - Props that override the Studio icon defaults.
|
|
25
|
+
* @returns An icon component.
|
|
29
26
|
*/
|
|
30
27
|
function createSanityIcon(icon, props) {
|
|
31
28
|
let Icon = icon;
|
|
@@ -37,38 +34,45 @@ function createSanityIcon(icon, props) {
|
|
|
37
34
|
}
|
|
38
35
|
return SanityIcon;
|
|
39
36
|
}
|
|
40
|
-
/** Whether
|
|
37
|
+
/** Whether this is a development build, the only kind in which the plugin logs. */
|
|
41
38
|
const isDevelopment = process.env.NODE_ENV === "development", prefixStyle = "color: #2276fc";
|
|
42
39
|
/**
|
|
43
|
-
* Creates
|
|
44
|
-
*
|
|
45
|
-
* Studio's own messages are; a terminal ignores the styling and prints it plain.
|
|
40
|
+
* Creates a logger that prefixes messages with the plugin's name and only logs in development builds.
|
|
41
|
+
* Browser consoles show the prefix in blue.
|
|
46
42
|
*
|
|
47
|
-
* @param name -
|
|
48
|
-
* @returns Functions that
|
|
43
|
+
* @param name - The package name to prefix messages with.
|
|
44
|
+
* @returns Functions that log progress, a warning, or an error, or format a message to throw.
|
|
49
45
|
*/
|
|
50
46
|
function createLogger(name) {
|
|
51
47
|
let prefix = `[${name}]`;
|
|
52
48
|
/**
|
|
53
|
-
*
|
|
49
|
+
* Prefixes a message with the package name.
|
|
54
50
|
*
|
|
55
|
-
* @param message - The message
|
|
56
|
-
* @returns The message
|
|
51
|
+
* @param message - The message.
|
|
52
|
+
* @returns The prefixed message.
|
|
57
53
|
*/
|
|
58
54
|
function format(message) {
|
|
59
55
|
return `${prefix} ${message}`;
|
|
60
56
|
}
|
|
61
57
|
return {
|
|
62
58
|
/**
|
|
63
|
-
*
|
|
59
|
+
* Logs progress worth seeing, such as what a build step did, in development builds only.
|
|
60
|
+
*
|
|
61
|
+
* @param message - What happened.
|
|
62
|
+
*/
|
|
63
|
+
info(message) {
|
|
64
|
+
isDevelopment && console.info(`%c${prefix}%c ${message}`, prefixStyle, "");
|
|
65
|
+
},
|
|
66
|
+
/**
|
|
67
|
+
* Logs a warning about something the plugin recovered from, in development builds only.
|
|
64
68
|
*
|
|
65
|
-
* @param message - What
|
|
69
|
+
* @param message - What happened and what to do about it.
|
|
66
70
|
*/
|
|
67
71
|
warn(message) {
|
|
68
72
|
isDevelopment && console.warn(`%c${prefix}%c ${message}`, prefixStyle, "");
|
|
69
73
|
},
|
|
70
74
|
/**
|
|
71
|
-
*
|
|
75
|
+
* Logs an error the plugin couldn't recover from, in development builds only.
|
|
72
76
|
*
|
|
73
77
|
* @param message - What went wrong and what to do about it.
|
|
74
78
|
*/
|
|
@@ -78,7 +82,7 @@ function createLogger(name) {
|
|
|
78
82
|
format
|
|
79
83
|
};
|
|
80
84
|
}
|
|
81
|
-
/**
|
|
85
|
+
/** Package name, used as the prefix on every logged message. */
|
|
82
86
|
const pluginName = "@driftime/sanity-plugin-handbook", logger = createLogger(pluginName), guideTypeName = "handbook.guide", handbookTypeName = "handbook.handbook", imageTypeName = "handbook.image", videoTypeName = "handbook.video", codeTypeName = "handbook.code", calloutTypeName = "handbook.callout", horizontalRuleTypeName = "handbook.horizontalRule", singletonTypes = /* @__PURE__ */ new Set([handbookTypeName]), documentTypes = /* @__PURE__ */ new Set([handbookTypeName, guideTypeName]);
|
|
83
87
|
function BookTextIcon(props) {
|
|
84
88
|
let $ = c(5), t0, t1, t2;
|
|
@@ -103,12 +107,11 @@ function BookTextIcon(props) {
|
|
|
103
107
|
}), $[3] = props, $[4] = t3), t3;
|
|
104
108
|
}
|
|
105
109
|
/**
|
|
106
|
-
* Checks whether a value is
|
|
107
|
-
*
|
|
108
|
-
* built from a class counts as present on existence alone. Not intended for boolean flags.
|
|
110
|
+
* Checks whether a value is present. `false`, blank strings, and empty plain objects count as absent,
|
|
111
|
+
* as does an array with no present elements.
|
|
109
112
|
*
|
|
110
113
|
* @param value - The value to check.
|
|
111
|
-
* @returns True if the value is
|
|
114
|
+
* @returns True if the value is present.
|
|
112
115
|
*/
|
|
113
116
|
function isDefined(value) {
|
|
114
117
|
if (value == null || value === !1) return !1;
|
|
@@ -121,10 +124,10 @@ function isDefined(value) {
|
|
|
121
124
|
return !0;
|
|
122
125
|
}
|
|
123
126
|
/**
|
|
124
|
-
* Converts a string
|
|
127
|
+
* Converts a string to another case.
|
|
125
128
|
*
|
|
126
129
|
* @param value - The string to convert.
|
|
127
|
-
* @param format - The
|
|
130
|
+
* @param format - The case to convert to.
|
|
128
131
|
* @returns The converted string.
|
|
129
132
|
*/
|
|
130
133
|
function convertCase(value, format) {
|
|
@@ -140,21 +143,20 @@ function convertCase(value, format) {
|
|
|
140
143
|
}
|
|
141
144
|
}
|
|
142
145
|
/**
|
|
143
|
-
* Checks whether a value
|
|
146
|
+
* Checks whether a value is an object whose keys can be read.
|
|
144
147
|
*
|
|
145
148
|
* @param value - The value to check.
|
|
146
|
-
* @returns True if the value
|
|
149
|
+
* @returns True if the value is an object.
|
|
147
150
|
*/
|
|
148
151
|
function isRecord(value) {
|
|
149
152
|
return typeof value == "object" && !!value;
|
|
150
153
|
}
|
|
151
154
|
/**
|
|
152
|
-
* Reads a
|
|
153
|
-
* inside a shape it does not otherwise know.
|
|
155
|
+
* Reads a nested value by following a path of keys.
|
|
154
156
|
*
|
|
155
157
|
* @param value - The object to read from.
|
|
156
|
-
* @param path -
|
|
157
|
-
* @returns The value
|
|
158
|
+
* @param path - The keys to follow.
|
|
159
|
+
* @returns The value, or undefined when the path doesn't exist.
|
|
158
160
|
*/
|
|
159
161
|
function readPath(value, path) {
|
|
160
162
|
let current = value;
|
|
@@ -164,7 +166,7 @@ function readPath(value, path) {
|
|
|
164
166
|
}
|
|
165
167
|
return current;
|
|
166
168
|
}
|
|
167
|
-
/** Share of the
|
|
169
|
+
/** Share of the space the content pane takes relative to the sidebar. */
|
|
168
170
|
const contentSpacing = {
|
|
169
171
|
section: 48,
|
|
170
172
|
paragraph: 16,
|
|
@@ -183,26 +185,25 @@ const contentSpacing = {
|
|
|
183
185
|
`} }
|
|
184
186
|
}`;
|
|
185
187
|
/**
|
|
186
|
-
*
|
|
187
|
-
* instead of being told it at every call site.
|
|
188
|
+
* Defines a GROQ query typed with its result, so fetches infer the result type.
|
|
188
189
|
*
|
|
189
|
-
* @param query - The GROQ query
|
|
190
|
-
* @returns The query, typed
|
|
190
|
+
* @param query - The GROQ query.
|
|
191
|
+
* @returns The query, typed with its result.
|
|
191
192
|
*/
|
|
192
193
|
function defineTypedQuery(query) {
|
|
193
194
|
return query;
|
|
194
195
|
}
|
|
195
196
|
/**
|
|
196
|
-
* Runs a
|
|
197
|
+
* Runs a typed query, returning undefined instead of null when nothing matches.
|
|
197
198
|
*
|
|
198
|
-
* @param client - The Sanity client
|
|
199
|
-
* @param query - The
|
|
200
|
-
* @returns The result, or undefined when
|
|
199
|
+
* @param client - The Sanity client.
|
|
200
|
+
* @param query - The typed query.
|
|
201
|
+
* @returns The result, or undefined when nothing matches.
|
|
201
202
|
*/
|
|
202
203
|
async function fetchQuery(client, query) {
|
|
203
204
|
return await client.fetch(query) ?? void 0;
|
|
204
205
|
}
|
|
205
|
-
/**
|
|
206
|
+
/** Handbook document with its guide references expanded. */
|
|
206
207
|
const handbookQuery = defineTypedQuery(`
|
|
207
208
|
*[_type == "${handbookTypeName}"][0] {
|
|
208
209
|
...,
|
|
@@ -216,10 +217,9 @@ const handbookQuery = defineTypedQuery(`
|
|
|
216
217
|
}
|
|
217
218
|
`), handbookDocumentsQuery = defineTypedQuery(`*[_type == "${handbookTypeName}" || _type == "${guideTypeName}"]`);
|
|
218
219
|
/**
|
|
219
|
-
* Fetches the Handbook
|
|
220
|
-
* whenever one of the documents it draws on changes.
|
|
220
|
+
* Fetches the Handbook document with its guides expanded, refetching when any Handbook document changes.
|
|
221
221
|
*
|
|
222
|
-
* @returns The Handbook and
|
|
222
|
+
* @returns The Handbook document, and whether it's still loading.
|
|
223
223
|
*/
|
|
224
224
|
function useHandbookDocument() {
|
|
225
225
|
let $ = c(7), t0;
|
|
@@ -245,10 +245,10 @@ function useHandbookDocument() {
|
|
|
245
245
|
}
|
|
246
246
|
const HandbookContext = createContext(void 0);
|
|
247
247
|
/**
|
|
248
|
-
*
|
|
248
|
+
* Reads the Handbook context.
|
|
249
249
|
*
|
|
250
|
-
* @returns The
|
|
251
|
-
* @throws
|
|
250
|
+
* @returns The plugin configuration and the shared pane state.
|
|
251
|
+
* @throws When used outside the provider.
|
|
252
252
|
*/
|
|
253
253
|
function useHandbookContext() {
|
|
254
254
|
let handbookContext = useContext(HandbookContext);
|
|
@@ -256,10 +256,10 @@ function useHandbookContext() {
|
|
|
256
256
|
return handbookContext;
|
|
257
257
|
}
|
|
258
258
|
/**
|
|
259
|
-
* Provides the
|
|
260
|
-
*
|
|
259
|
+
* Provides the plugin configuration, the Handbook document, and the tab state shared by the sidebar and
|
|
260
|
+
* content panes.
|
|
261
261
|
*
|
|
262
|
-
* @returns The provider
|
|
262
|
+
* @returns The provider.
|
|
263
263
|
*/
|
|
264
264
|
function HandbookProvider(t0) {
|
|
265
265
|
let $ = c(12), { sidebarTitle, roles, blocks, undocumentedFieldMessage, children } = t0, [activeTab, setActiveTab] = useState(void 0), [sidebarExpanded, setSidebarExpanded] = useState(!0), { handbook, loading } = useHandbookDocument(), t1;
|
|
@@ -571,7 +571,7 @@ function TriangleAlertIcon(props) {
|
|
|
571
571
|
]
|
|
572
572
|
}), $[3] = props, $[4] = t3), t3;
|
|
573
573
|
}
|
|
574
|
-
/** Hint kinds
|
|
574
|
+
/** Hint kinds, in display order. */
|
|
575
575
|
const hintKinds = [
|
|
576
576
|
{
|
|
577
577
|
name: "tip",
|
|
@@ -626,10 +626,9 @@ function FieldHints(t0) {
|
|
|
626
626
|
}), $[16] = T0, $[17] = t1, $[18] = t2, $[19] = t3, $[20] = t4, $[21] = t5) : t5 = $[21], t5;
|
|
627
627
|
}
|
|
628
628
|
/**
|
|
629
|
-
*
|
|
630
|
-
* title and falling back to a title-cased name.
|
|
629
|
+
* Works out a schema type's label: its Handbook title, then its schema title, then its name in title case.
|
|
631
630
|
*
|
|
632
|
-
* @param type - The schema type or field
|
|
631
|
+
* @param type - The schema type or field.
|
|
633
632
|
* @returns The label.
|
|
634
633
|
*/
|
|
635
634
|
function resolveTitle(type) {
|
|
@@ -637,28 +636,27 @@ function resolveTitle(type) {
|
|
|
637
636
|
return handbook?.title ?? title ?? convertCase(name, "title");
|
|
638
637
|
}
|
|
639
638
|
/**
|
|
640
|
-
*
|
|
641
|
-
*
|
|
639
|
+
* Works out a schema type's description, preferring its Handbook description and ignoring non-string
|
|
640
|
+
* schema descriptions.
|
|
642
641
|
*
|
|
643
|
-
* @param type - The schema type or field
|
|
644
|
-
* @returns The description, or undefined when
|
|
642
|
+
* @param type - The schema type or field.
|
|
643
|
+
* @returns The description, or undefined when there isn't one.
|
|
645
644
|
*/
|
|
646
645
|
function resolveDescription(type) {
|
|
647
646
|
let { description, handbook } = type;
|
|
648
647
|
return handbook?.description ?? (typeof description == "string" ? description : void 0);
|
|
649
648
|
}
|
|
650
649
|
/**
|
|
651
|
-
*
|
|
652
|
-
*
|
|
653
|
-
* built-in ones rather than at its own library's default size.
|
|
650
|
+
* Gets a schema type's icon as a component, redrawn at the plugin's icon size to match the built-in icons.
|
|
651
|
+
* String icons are ignored.
|
|
654
652
|
*
|
|
655
|
-
* @param type - The schema type
|
|
656
|
-
* @returns The icon component, or undefined when
|
|
653
|
+
* @param type - The schema type.
|
|
654
|
+
* @returns The icon component, or undefined when there isn't one.
|
|
657
655
|
*/
|
|
658
656
|
function resolveIcon(type) {
|
|
659
657
|
return typeof type.icon == "function" ? createSanityIcon(type.icon) : void 0;
|
|
660
658
|
}
|
|
661
|
-
/**
|
|
659
|
+
/** Types whose subfields aren't shown. */
|
|
662
660
|
const opaqueTypes = /* @__PURE__ */ new Set([
|
|
663
661
|
"block",
|
|
664
662
|
"boolean",
|
|
@@ -697,7 +695,7 @@ const opaqueTypes = /* @__PURE__ */ new Set([
|
|
|
697
695
|
slug: /* @__PURE__ */ new Set(["current", "source"])
|
|
698
696
|
};
|
|
699
697
|
/**
|
|
700
|
-
* Checks whether a value is a compiled schema field with a
|
|
698
|
+
* Checks whether a value is a compiled schema field with a type object.
|
|
701
699
|
*
|
|
702
700
|
* @param value - The value to check.
|
|
703
701
|
* @returns True if the value is a compiled field.
|
|
@@ -706,49 +704,49 @@ function isCompiledField(value) {
|
|
|
706
704
|
return !isRecord(value) || !("name" in value) || !("type" in value) ? !1 : isRecord(value.type);
|
|
707
705
|
}
|
|
708
706
|
/**
|
|
709
|
-
* Checks whether a value has a `fields` array
|
|
707
|
+
* Checks whether a value has a `fields` array.
|
|
710
708
|
*
|
|
711
709
|
* @param value - The value to check.
|
|
712
|
-
* @returns True if the value
|
|
710
|
+
* @returns True if the value has a `fields` array.
|
|
713
711
|
*/
|
|
714
712
|
function hasFieldsArray(value) {
|
|
715
713
|
return isRecord(value) && Array.isArray(value.fields);
|
|
716
714
|
}
|
|
717
715
|
/**
|
|
718
|
-
* Checks whether a value has an `of` array
|
|
716
|
+
* Checks whether a value has an `of` array.
|
|
719
717
|
*
|
|
720
718
|
* @param value - The value to check.
|
|
721
|
-
* @returns True if the value
|
|
719
|
+
* @returns True if the value has an `of` array.
|
|
722
720
|
*/
|
|
723
721
|
function hasOfArray(value) {
|
|
724
722
|
return isRecord(value) && Array.isArray(value.of);
|
|
725
723
|
}
|
|
726
724
|
/**
|
|
727
|
-
*
|
|
725
|
+
* Reads the type name a value declares.
|
|
728
726
|
*
|
|
729
|
-
* @param value - The value
|
|
730
|
-
* @returns The type name, or undefined when
|
|
727
|
+
* @param value - The value.
|
|
728
|
+
* @returns The type name, or undefined when there isn't one.
|
|
731
729
|
*/
|
|
732
730
|
function getTypeName(value) {
|
|
733
731
|
let typeName = readPath(value, ["type"]);
|
|
734
732
|
return typeof typeName == "string" ? typeName : void 0;
|
|
735
733
|
}
|
|
736
734
|
/**
|
|
737
|
-
*
|
|
735
|
+
* Reads the parent type name from a compiled schema type.
|
|
738
736
|
*
|
|
739
|
-
* @param resolvedType - The compiled schema type
|
|
740
|
-
* @returns The parent type name, or undefined when
|
|
737
|
+
* @param resolvedType - The compiled schema type.
|
|
738
|
+
* @returns The parent type name, or undefined when there isn't one.
|
|
741
739
|
*/
|
|
742
740
|
function getParentTypeName(resolvedType) {
|
|
743
741
|
let parentName = readPath(resolvedType, ["type", "name"]);
|
|
744
742
|
return isDefined(parentName) ? String(parentName) : void 0;
|
|
745
743
|
}
|
|
746
744
|
/**
|
|
747
|
-
*
|
|
748
|
-
*
|
|
745
|
+
* Converts a compiled schema field into the shape the Handbook renders. Types already seen are tracked,
|
|
746
|
+
* so a type that refers to itself doesn't recurse forever.
|
|
749
747
|
*
|
|
750
|
-
* @param field - A compiled
|
|
751
|
-
* @param visited - Type names already seen
|
|
748
|
+
* @param field - A compiled field or a plain field definition.
|
|
749
|
+
* @param visited - Type names already seen.
|
|
752
750
|
* @returns The normalised field.
|
|
753
751
|
*/
|
|
754
752
|
function normalizeField(field, visited = /* @__PURE__ */ new Set()) {
|
|
@@ -769,12 +767,11 @@ function normalizeField(field, visited = /* @__PURE__ */ new Set()) {
|
|
|
769
767
|
return field;
|
|
770
768
|
}
|
|
771
769
|
/**
|
|
772
|
-
*
|
|
773
|
-
* base type contributes of its own accord.
|
|
770
|
+
* Lists the fields a custom type adds to an opaque base type, leaving out the base type's own.
|
|
774
771
|
*
|
|
775
772
|
* @param resolvedType - The compiled or normalised schema type.
|
|
776
|
-
* @param parentName - The opaque base type name.
|
|
777
|
-
* @returns The custom fields, or undefined when
|
|
773
|
+
* @param parentName - The opaque base type's name.
|
|
774
|
+
* @returns The custom fields, or undefined when there are none.
|
|
778
775
|
*/
|
|
779
776
|
function resolveCustomFields(resolvedType, parentName) {
|
|
780
777
|
if (!hasFieldsArray(resolvedType)) return;
|
|
@@ -782,32 +779,31 @@ function resolveCustomFields(resolvedType, parentName) {
|
|
|
782
779
|
return isDefined(customFields) ? customFields : void 0;
|
|
783
780
|
}
|
|
784
781
|
/**
|
|
785
|
-
* Normalises a list of raw
|
|
782
|
+
* Normalises a list of raw fields.
|
|
786
783
|
*
|
|
787
|
-
* @param items -
|
|
788
|
-
* @returns The normalised fields, or undefined when
|
|
784
|
+
* @param items - The raw fields.
|
|
785
|
+
* @returns The normalised fields, or undefined when there are none.
|
|
789
786
|
*/
|
|
790
787
|
function resolveNormalizedFields(items) {
|
|
791
788
|
let normalized = items.map((item) => normalizeField(item));
|
|
792
789
|
return isDefined(normalized) ? normalized : void 0;
|
|
793
790
|
}
|
|
794
791
|
/**
|
|
795
|
-
* Normalises array members
|
|
792
|
+
* Normalises array members, leaving out opaque types.
|
|
796
793
|
*
|
|
797
|
-
* @param members -
|
|
798
|
-
* @returns The normalised
|
|
794
|
+
* @param members - The raw array members.
|
|
795
|
+
* @returns The normalised members, or undefined when there are none.
|
|
799
796
|
*/
|
|
800
797
|
function resolveNormalizedMembers(members) {
|
|
801
798
|
let normalized = members.map((member) => normalizeField(member)).filter((member) => !opaqueTypes.has(member.type));
|
|
802
799
|
return isDefined(normalized) ? normalized : void 0;
|
|
803
800
|
}
|
|
804
801
|
/**
|
|
805
|
-
*
|
|
806
|
-
* carries nothing but a type name of its own.
|
|
802
|
+
* Works out a value's parent type name, looking it up in the schema when the value only names its type.
|
|
807
803
|
*
|
|
808
|
-
* @param value - The value
|
|
809
|
-
* @param schema - The Sanity schema
|
|
810
|
-
* @returns The parent type name, or undefined when
|
|
804
|
+
* @param value - The value.
|
|
805
|
+
* @param schema - The Sanity schema.
|
|
806
|
+
* @returns The parent type name, or undefined when there isn't one.
|
|
811
807
|
*/
|
|
812
808
|
function resolveParentName(value, schema) {
|
|
813
809
|
let direct = getParentTypeName(value);
|
|
@@ -818,12 +814,12 @@ function resolveParentName(value, schema) {
|
|
|
818
814
|
return isDefined(resolvedType) ? getParentTypeName(resolvedType) : void 0;
|
|
819
815
|
}
|
|
820
816
|
/**
|
|
821
|
-
*
|
|
822
|
-
*
|
|
817
|
+
* Works out the fields a value shows, whether it holds them directly, has array members that do, or
|
|
818
|
+
* names a type that does.
|
|
823
819
|
*
|
|
824
|
-
* @param value - The value
|
|
825
|
-
* @param schema - The Sanity schema
|
|
826
|
-
* @returns The
|
|
820
|
+
* @param value - The value.
|
|
821
|
+
* @param schema - The Sanity schema.
|
|
822
|
+
* @returns The fields, or undefined when there are none.
|
|
827
823
|
*/
|
|
828
824
|
function resolveFields(value, schema) {
|
|
829
825
|
if (hasFieldsArray(value)) {
|
|
@@ -846,11 +842,11 @@ function resolveFields(value, schema) {
|
|
|
846
842
|
}
|
|
847
843
|
}
|
|
848
844
|
/**
|
|
849
|
-
*
|
|
845
|
+
* Works out a field's visible subfields by looking through the schema.
|
|
850
846
|
*
|
|
851
|
-
* @param field - The
|
|
852
|
-
* @param schema - The Sanity schema
|
|
853
|
-
* @returns The
|
|
847
|
+
* @param field - The field.
|
|
848
|
+
* @param schema - The Sanity schema.
|
|
849
|
+
* @returns The subfields, or undefined when there are none.
|
|
854
850
|
*/
|
|
855
851
|
function getSubfields(field, schema) {
|
|
856
852
|
if (opaqueTypes.has(field.type)) return;
|
|
@@ -861,7 +857,7 @@ function getSubfields(field, schema) {
|
|
|
861
857
|
let parentName = getParentTypeName(resolvedType);
|
|
862
858
|
return isDefined(parentName) && opaqueTypes.has(parentName) ? resolveCustomFields(resolvedType, parentName) : resolveFields(resolvedType, schema);
|
|
863
859
|
}
|
|
864
|
-
/** Shared empty
|
|
860
|
+
/** Shared empty set, so the default prop keeps the same reference between renders. */
|
|
865
861
|
const noAncestors = /* @__PURE__ */ new Set();
|
|
866
862
|
function DocumentedField(t0) {
|
|
867
863
|
let $ = c(59), field, props, t1;
|
|
@@ -1014,10 +1010,10 @@ function DocumentedField(t0) {
|
|
|
1014
1010
|
return t6;
|
|
1015
1011
|
}
|
|
1016
1012
|
/**
|
|
1017
|
-
* Builds a section for each
|
|
1013
|
+
* Builds a sidebar section for each document role.
|
|
1018
1014
|
*
|
|
1019
|
-
* @param roles -
|
|
1020
|
-
* @returns One section per role,
|
|
1015
|
+
* @param roles - The configured document roles.
|
|
1016
|
+
* @returns One section per role, with an entry per document type.
|
|
1021
1017
|
*/
|
|
1022
1018
|
function documentTypesSections(roles) {
|
|
1023
1019
|
return roles.map(({ title, documents }) => ({
|
|
@@ -1193,11 +1189,11 @@ function DocumentTypesOverview() {
|
|
|
1193
1189
|
children: t1
|
|
1194
1190
|
}), $[8] = t1, $[9] = t2), t2;
|
|
1195
1191
|
}
|
|
1196
|
-
/** What each hint kind
|
|
1192
|
+
/** What each hint kind means, shown next to its icon as a key. */
|
|
1197
1193
|
const hintDescriptions = {
|
|
1198
|
-
tip: "
|
|
1199
|
-
info: "
|
|
1200
|
-
caution: "
|
|
1194
|
+
tip: "Tips and suggested practices for people editing content.",
|
|
1195
|
+
info: "More detail about how and where the field is used.",
|
|
1196
|
+
caution: "Warnings about restrictions or problems the field can cause."
|
|
1201
1197
|
};
|
|
1202
1198
|
function HowToUse() {
|
|
1203
1199
|
let $ = c(8), t0;
|
|
@@ -1220,7 +1216,7 @@ function HowToUse() {
|
|
|
1220
1216
|
}), /* @__PURE__ */ jsx(Text, {
|
|
1221
1217
|
size: 1,
|
|
1222
1218
|
muted: !0,
|
|
1223
|
-
children: "The sidebar lists everything the Handbook
|
|
1219
|
+
children: "The sidebar lists everything in the Handbook: these introductory pages first, then the document types you can create, grouped by their role on the site, and then any guides your team has written. Select an entry to open it here."
|
|
1224
1220
|
})]
|
|
1225
1221
|
}), $[1] = t1) : t1 = $[1];
|
|
1226
1222
|
let t2;
|
|
@@ -1237,7 +1233,7 @@ function HowToUse() {
|
|
|
1237
1233
|
}), /* @__PURE__ */ jsx(Text, {
|
|
1238
1234
|
size: 1,
|
|
1239
1235
|
muted: !0,
|
|
1240
|
-
children: "Selecting a document type lists its fields, each
|
|
1236
|
+
children: "Selecting a document type lists its fields, with each field’s name, the kind of value it holds, and what it’s for. This documentation is generated from the content model, so it always matches what you see in the editor."
|
|
1241
1237
|
})]
|
|
1242
1238
|
}), $[2] = t2) : t2 = $[2];
|
|
1243
1239
|
let t3, t4;
|
|
@@ -1252,7 +1248,7 @@ function HowToUse() {
|
|
|
1252
1248
|
}), t4 = /* @__PURE__ */ jsx(Text, {
|
|
1253
1249
|
size: 1,
|
|
1254
1250
|
muted: !0,
|
|
1255
|
-
children: "Icons
|
|
1251
|
+
children: "Icons next to a field’s name hold extra guidance that would make its description too long. Hover over or click an icon to read it, and use the key below to see what each icon means."
|
|
1256
1252
|
}), $[3] = t3, $[4] = t4) : (t3 = $[3], t4 = $[4]);
|
|
1257
1253
|
let t5;
|
|
1258
1254
|
$[5] === Symbol.for("react.memo_cache_sentinel") ? (t5 = /* @__PURE__ */ jsxs(Stack, {
|
|
@@ -1281,7 +1277,7 @@ function HowToUse() {
|
|
|
1281
1277
|
}), /* @__PURE__ */ jsx(Text, {
|
|
1282
1278
|
size: 1,
|
|
1283
1279
|
muted: !0,
|
|
1284
|
-
children: "Some fields
|
|
1280
|
+
children: "Some fields contain subfields, such as a content block with a heading and body text. A button below the description shows how many there are and expands to list them, each documented like any other field."
|
|
1285
1281
|
})]
|
|
1286
1282
|
}), $[6] = t6) : t6 = $[6];
|
|
1287
1283
|
let t7;
|
|
@@ -1305,7 +1301,7 @@ function HowToUse() {
|
|
|
1305
1301
|
}), /* @__PURE__ */ jsx(Text, {
|
|
1306
1302
|
size: 1,
|
|
1307
1303
|
muted: !0,
|
|
1308
|
-
children: "
|
|
1304
|
+
children: "Below the document types, you may find guides written by your team rather than generated from the content model. They cover things a field description can’t, such as house style, editorial process, and how everything fits together."
|
|
1309
1305
|
})]
|
|
1310
1306
|
})
|
|
1311
1307
|
]
|
|
@@ -1332,9 +1328,9 @@ function _temp$3(t0) {
|
|
|
1332
1328
|
}, name);
|
|
1333
1329
|
}
|
|
1334
1330
|
/**
|
|
1335
|
-
* Builds the section
|
|
1331
|
+
* Builds the section for the plugin's introductory pages.
|
|
1336
1332
|
*
|
|
1337
|
-
* @returns
|
|
1333
|
+
* @returns One section listing the built-in pages.
|
|
1338
1334
|
*/
|
|
1339
1335
|
function gettingStartedSections() {
|
|
1340
1336
|
return [{
|
|
@@ -1342,19 +1338,19 @@ function gettingStartedSections() {
|
|
|
1342
1338
|
entries: [{
|
|
1343
1339
|
id: "how-to-use-this-handbook",
|
|
1344
1340
|
title: "How to use the Handbook",
|
|
1345
|
-
description: "
|
|
1341
|
+
description: "How to find your way around the Handbook, read the documentation for each field, and understand its examples, hints, and subfields.",
|
|
1346
1342
|
icon: createSanityIcon(BookTextIcon),
|
|
1347
1343
|
render: () => /* @__PURE__ */ jsx(HowToUse, {})
|
|
1348
1344
|
}, {
|
|
1349
1345
|
id: "document-types",
|
|
1350
1346
|
title: "Document Types",
|
|
1351
|
-
description: "
|
|
1347
|
+
description: "A list of every document type, grouped by role. Select a document type to see its fields, descriptions, and examples.",
|
|
1352
1348
|
icon: createSanityIcon(LayoutGridIcon),
|
|
1353
1349
|
render: () => /* @__PURE__ */ jsx(DocumentTypesOverview, {})
|
|
1354
1350
|
}]
|
|
1355
1351
|
}];
|
|
1356
1352
|
}
|
|
1357
|
-
/**
|
|
1353
|
+
/** Icon and tone for each callout variant. */
|
|
1358
1354
|
const presentation = {
|
|
1359
1355
|
tip: {
|
|
1360
1356
|
icon: LightbulbIcon,
|
|
@@ -1442,7 +1438,7 @@ function PortableLink(t0) {
|
|
|
1442
1438
|
children
|
|
1443
1439
|
}), $[6] = children, $[7] = props, $[8] = t1, $[9] = t2) : t2 = $[9], t2;
|
|
1444
1440
|
}
|
|
1445
|
-
/** Overrides for
|
|
1441
|
+
/** Overrides for callout text, which uses the card's own text style and doesn't wrap paragraphs. */
|
|
1446
1442
|
const components$1 = {
|
|
1447
1443
|
block: { normal: ({ children }) => /* @__PURE__ */ jsx(Fragment, { children }) },
|
|
1448
1444
|
marks: {
|
|
@@ -1720,18 +1716,17 @@ function PortableParagraph(props) {
|
|
|
1720
1716
|
}), $[0] = props, $[1] = t0), t0;
|
|
1721
1717
|
}
|
|
1722
1718
|
/**
|
|
1723
|
-
*
|
|
1719
|
+
* Works out the vertical space around a list, which is smaller for nested lists.
|
|
1724
1720
|
*
|
|
1725
|
-
* @param level - Nesting depth
|
|
1726
|
-
* @returns The
|
|
1721
|
+
* @param level - Nesting depth, starting at 1.
|
|
1722
|
+
* @returns The space in pixels.
|
|
1727
1723
|
*/
|
|
1728
1724
|
function listSpacing(level) {
|
|
1729
1725
|
return level > 1 ? contentSpacing.nestedList : contentSpacing.list;
|
|
1730
1726
|
}
|
|
1731
1727
|
/**
|
|
1732
|
-
*
|
|
1733
|
-
*
|
|
1734
|
-
* as the surrounding text.
|
|
1728
|
+
* Components for each block style, mark, and embedded type in a guide. Marks and list items not listed
|
|
1729
|
+
* here are left to the library's defaults on purpose.
|
|
1735
1730
|
*/
|
|
1736
1731
|
const components = {
|
|
1737
1732
|
block: {
|
|
@@ -1777,10 +1772,10 @@ const components = {
|
|
|
1777
1772
|
}
|
|
1778
1773
|
};
|
|
1779
1774
|
/**
|
|
1780
|
-
*
|
|
1781
|
-
*
|
|
1775
|
+
* Wraps a block component for Portable Text, passing only the block's value. Otherwise the library's
|
|
1776
|
+
* other props would reach the DOM.
|
|
1782
1777
|
*
|
|
1783
|
-
* @param Component -
|
|
1778
|
+
* @param Component - The block component.
|
|
1784
1779
|
* @returns A component Portable Text can render the type with.
|
|
1785
1780
|
*/
|
|
1786
1781
|
function blockRenderer(Component) {
|
|
@@ -1855,10 +1850,10 @@ function BookOpenTextIcon(props) {
|
|
|
1855
1850
|
}), $[6] = props, $[7] = t6), t6;
|
|
1856
1851
|
}
|
|
1857
1852
|
/**
|
|
1858
|
-
* Builds a section for each guide group
|
|
1853
|
+
* Builds a sidebar section for each guide group.
|
|
1859
1854
|
*
|
|
1860
|
-
* @param handbook - Handbook
|
|
1861
|
-
* @returns One section per group,
|
|
1855
|
+
* @param handbook - The Handbook document.
|
|
1856
|
+
* @returns One section per group, with an entry per guide.
|
|
1862
1857
|
*/
|
|
1863
1858
|
function guidesSections(handbook) {
|
|
1864
1859
|
return handbook.groups.map(({ title, guides }) => ({
|
|
@@ -1873,9 +1868,9 @@ function guidesSections(handbook) {
|
|
|
1873
1868
|
}));
|
|
1874
1869
|
}
|
|
1875
1870
|
/**
|
|
1876
|
-
*
|
|
1871
|
+
* Lists every page in the Handbook, in sidebar order.
|
|
1877
1872
|
*
|
|
1878
|
-
* @returns
|
|
1873
|
+
* @returns The built-in pages, the configured document roles, and the guide groups, as sections.
|
|
1879
1874
|
*/
|
|
1880
1875
|
function useSections() {
|
|
1881
1876
|
let $ = c(4), { roles, handbook, loading } = useHandbookContext(), t0;
|
|
@@ -2094,23 +2089,23 @@ function HandbookTool(t0) {
|
|
|
2094
2089
|
children: t7
|
|
2095
2090
|
}), $[7] = options, $[8] = t7, $[9] = t8) : t8 = $[9], t8;
|
|
2096
2091
|
}
|
|
2097
|
-
/** Editors the plugin
|
|
2092
|
+
/** Editors from the plugin configuration, so the structure helper doesn't need them passed again. */
|
|
2098
2093
|
let configuredEditors;
|
|
2099
2094
|
/**
|
|
2100
|
-
*
|
|
2101
|
-
*
|
|
2095
|
+
* Stores the editors from the plugin configuration. A Studio with several workspaces keeps only the last
|
|
2096
|
+
* workspace's list, so pass the list explicitly there.
|
|
2102
2097
|
*
|
|
2103
|
-
* @param editors - Email addresses
|
|
2098
|
+
* @param editors - Email addresses of the editors.
|
|
2104
2099
|
*/
|
|
2105
2100
|
function setConfiguredEditors(editors) {
|
|
2106
2101
|
configuredEditors = editors;
|
|
2107
2102
|
}
|
|
2108
2103
|
/**
|
|
2109
|
-
* Checks whether an email address
|
|
2104
|
+
* Checks whether an email address belongs to an editor. Without an editors list, everyone is an editor.
|
|
2110
2105
|
*
|
|
2111
|
-
* @param editors - Email addresses
|
|
2106
|
+
* @param editors - Email addresses of the editors, defaulting to the configured list.
|
|
2112
2107
|
* @param email - The email address to check.
|
|
2113
|
-
* @returns Whether the
|
|
2108
|
+
* @returns Whether the address belongs to an editor.
|
|
2114
2109
|
*/
|
|
2115
2110
|
function isPermittedEditor(editors, email) {
|
|
2116
2111
|
let permitted = editors ?? configuredEditors;
|
|
@@ -2208,7 +2203,7 @@ const linkAnnotation = defineArrayMember({
|
|
|
2208
2203
|
name: "href",
|
|
2209
2204
|
type: "url",
|
|
2210
2205
|
title: "URL",
|
|
2211
|
-
description: "Web address
|
|
2206
|
+
description: "Web address to link to. Use http, https, mailto, or tel.",
|
|
2212
2207
|
validation: (rule) => rule.uri({ scheme: [
|
|
2213
2208
|
"http",
|
|
2214
2209
|
"https",
|
|
@@ -2220,7 +2215,7 @@ const linkAnnotation = defineArrayMember({
|
|
|
2220
2215
|
name: calloutTypeName,
|
|
2221
2216
|
type: "object",
|
|
2222
2217
|
title: "Callout",
|
|
2223
|
-
description: "Highlighted
|
|
2218
|
+
description: "Highlighted tip, note, or warning.",
|
|
2224
2219
|
icon: createSanityIcon(MessageCircleIcon),
|
|
2225
2220
|
components: { preview: CalloutPreview },
|
|
2226
2221
|
preview: {
|
|
@@ -2240,7 +2235,7 @@ const linkAnnotation = defineArrayMember({
|
|
|
2240
2235
|
fields: [defineField({
|
|
2241
2236
|
name: "variant",
|
|
2242
2237
|
type: "string",
|
|
2243
|
-
description: "
|
|
2238
|
+
description: "Kind of callout, which sets its icon and color.",
|
|
2244
2239
|
initialValue: "tip",
|
|
2245
2240
|
validation: (rule) => rule.required(),
|
|
2246
2241
|
options: {
|
|
@@ -2264,7 +2259,7 @@ const linkAnnotation = defineArrayMember({
|
|
|
2264
2259
|
}), defineField({
|
|
2265
2260
|
name: "body",
|
|
2266
2261
|
type: "array",
|
|
2267
|
-
description: "
|
|
2262
|
+
description: "Text inside the callout, with inline formatting and links.",
|
|
2268
2263
|
of: [defineArrayMember({
|
|
2269
2264
|
name: "block",
|
|
2270
2265
|
type: "block",
|
|
@@ -2330,7 +2325,7 @@ const codeType = defineType({
|
|
|
2330
2325
|
name: codeTypeName,
|
|
2331
2326
|
type: "object",
|
|
2332
2327
|
title: "Code",
|
|
2333
|
-
description: "
|
|
2328
|
+
description: "Code block with syntax highlighting.",
|
|
2334
2329
|
icon: createSanityIcon(CodeIcon),
|
|
2335
2330
|
components: { preview: CodePreview },
|
|
2336
2331
|
preview: { select: {
|
|
@@ -2340,11 +2335,11 @@ const codeType = defineType({
|
|
|
2340
2335
|
fields: [defineField({
|
|
2341
2336
|
name: "code",
|
|
2342
2337
|
type: "text",
|
|
2343
|
-
description: "
|
|
2338
|
+
description: "Code to display."
|
|
2344
2339
|
}), defineField({
|
|
2345
2340
|
name: "language",
|
|
2346
2341
|
type: "string",
|
|
2347
|
-
description: "
|
|
2342
|
+
description: "Language used for syntax highlighting.",
|
|
2348
2343
|
options: { list: [
|
|
2349
2344
|
{
|
|
2350
2345
|
title: "CSS",
|
|
@@ -2415,7 +2410,7 @@ const horizontalRuleType = defineType({
|
|
|
2415
2410
|
name: horizontalRuleTypeName,
|
|
2416
2411
|
type: "object",
|
|
2417
2412
|
title: "Horizontal Rule",
|
|
2418
|
-
description: "
|
|
2413
|
+
description: "Divider between sections.",
|
|
2419
2414
|
icon: createSanityIcon(SeparatorHorizontalIcon),
|
|
2420
2415
|
components: { preview: HorizontalRulePreview },
|
|
2421
2416
|
preview: { prepare() {
|
|
@@ -2424,7 +2419,7 @@ const horizontalRuleType = defineType({
|
|
|
2424
2419
|
fields: [defineField({
|
|
2425
2420
|
name: "style",
|
|
2426
2421
|
type: "string",
|
|
2427
|
-
description: "
|
|
2422
|
+
description: "Unused placeholder field.",
|
|
2428
2423
|
hidden: !0
|
|
2429
2424
|
})]
|
|
2430
2425
|
});
|
|
@@ -2491,19 +2486,19 @@ const imageType = defineType({
|
|
|
2491
2486
|
name: "asset",
|
|
2492
2487
|
type: "image",
|
|
2493
2488
|
title: "Image",
|
|
2494
|
-
description: "
|
|
2489
|
+
description: "Image to show.",
|
|
2495
2490
|
options: { hotspot: !0 }
|
|
2496
2491
|
}),
|
|
2497
2492
|
defineField({
|
|
2498
2493
|
name: "caption",
|
|
2499
2494
|
type: "string",
|
|
2500
|
-
description: "
|
|
2495
|
+
description: "Text shown below the image, such as a credit."
|
|
2501
2496
|
}),
|
|
2502
2497
|
defineField({
|
|
2503
2498
|
name: "alt",
|
|
2504
2499
|
type: "string",
|
|
2505
2500
|
title: "Alternative Text",
|
|
2506
|
-
description: "
|
|
2501
|
+
description: "Description of the image for people who can't see it. Don't repeat the caption."
|
|
2507
2502
|
})
|
|
2508
2503
|
]
|
|
2509
2504
|
});
|
|
@@ -2567,12 +2562,12 @@ const videoType = defineType({
|
|
|
2567
2562
|
name: "asset",
|
|
2568
2563
|
type: "file",
|
|
2569
2564
|
title: "Video",
|
|
2570
|
-
description: "
|
|
2565
|
+
description: "Video to show.",
|
|
2571
2566
|
options: { accept: "video/*" }
|
|
2572
2567
|
}), defineField({
|
|
2573
2568
|
name: "caption",
|
|
2574
2569
|
type: "string",
|
|
2575
|
-
description: "
|
|
2570
|
+
description: "Text shown below the video, such as a credit."
|
|
2576
2571
|
})]
|
|
2577
2572
|
});
|
|
2578
2573
|
function ListItemStyle(t0) {
|
|
@@ -2586,11 +2581,10 @@ function ListItemStyle(t0) {
|
|
|
2586
2581
|
}), $[1] = children, $[2] = t2), t2;
|
|
2587
2582
|
}
|
|
2588
2583
|
/**
|
|
2589
|
-
* Creates the
|
|
2590
|
-
* any a consumer registered.
|
|
2584
|
+
* Creates the guide content field, offering the built-in blocks and any custom ones.
|
|
2591
2585
|
*
|
|
2592
|
-
* @param customBlocks - Custom
|
|
2593
|
-
* @returns
|
|
2586
|
+
* @param customBlocks - Custom blocks added by the site.
|
|
2587
|
+
* @returns The content field.
|
|
2594
2588
|
*/
|
|
2595
2589
|
function createGuideContentField(customBlocks = []) {
|
|
2596
2590
|
return defineField({
|
|
@@ -2678,18 +2672,17 @@ function createGuideContentField(customBlocks = []) {
|
|
|
2678
2672
|
});
|
|
2679
2673
|
}
|
|
2680
2674
|
/**
|
|
2681
|
-
* Creates the document type a
|
|
2682
|
-
* built-in blocks alongside any a consumer registered.
|
|
2675
|
+
* Creates the guide document type, with a content field offering the built-in blocks and any custom ones.
|
|
2683
2676
|
*
|
|
2684
|
-
* @param customBlocks - Custom
|
|
2685
|
-
* @returns
|
|
2677
|
+
* @param customBlocks - Custom blocks added by the site.
|
|
2678
|
+
* @returns The guide document type.
|
|
2686
2679
|
*/
|
|
2687
2680
|
function createGuideType(customBlocks = []) {
|
|
2688
2681
|
return defineType({
|
|
2689
2682
|
name: guideTypeName,
|
|
2690
2683
|
type: "document",
|
|
2691
2684
|
title: "Handbook Guide",
|
|
2692
|
-
description: "Handbook page
|
|
2685
|
+
description: "Handbook page written in rich text.",
|
|
2693
2686
|
icon: createSanityIcon(BookOpenTextIcon),
|
|
2694
2687
|
preview: {
|
|
2695
2688
|
select: {
|
|
@@ -2708,13 +2701,13 @@ function createGuideType(customBlocks = []) {
|
|
|
2708
2701
|
defineField({
|
|
2709
2702
|
name: "title",
|
|
2710
2703
|
type: "string",
|
|
2711
|
-
description: "
|
|
2704
|
+
description: "Title shown in the Handbook sidebar and as the guide heading.",
|
|
2712
2705
|
validation: (rule) => rule.required()
|
|
2713
2706
|
}),
|
|
2714
2707
|
defineField({
|
|
2715
2708
|
name: "description",
|
|
2716
2709
|
type: "string",
|
|
2717
|
-
description: "Short introduction
|
|
2710
|
+
description: "Short introduction shown below the heading."
|
|
2718
2711
|
}),
|
|
2719
2712
|
createGuideContentField(customBlocks)
|
|
2720
2713
|
]
|
|
@@ -2748,7 +2741,7 @@ const handbookType = defineType({
|
|
|
2748
2741
|
name: handbookTypeName,
|
|
2749
2742
|
type: "document",
|
|
2750
2743
|
title: "Handbook",
|
|
2751
|
-
description: "
|
|
2744
|
+
description: "Groups of guides shown in the Handbook sidebar, in order.",
|
|
2752
2745
|
icon: createSanityIcon(BookTextIcon),
|
|
2753
2746
|
preview: { prepare() {
|
|
2754
2747
|
return { title: "Handbook" };
|
|
@@ -2756,21 +2749,21 @@ const handbookType = defineType({
|
|
|
2756
2749
|
fields: [defineField({
|
|
2757
2750
|
name: "groups",
|
|
2758
2751
|
type: "array",
|
|
2759
|
-
description: "
|
|
2752
|
+
description: "Groups of guides shown in the Handbook sidebar, in order. Each group has a title and a list of guides, also in order.",
|
|
2760
2753
|
of: [defineArrayMember({
|
|
2761
2754
|
name: "group",
|
|
2762
2755
|
type: "object",
|
|
2763
|
-
description: "
|
|
2756
|
+
description: "Sidebar section holding a list of guides.",
|
|
2764
2757
|
icon: createSanityIcon(ListPlusIcon),
|
|
2765
2758
|
fields: [defineField({
|
|
2766
2759
|
name: "title",
|
|
2767
2760
|
type: "string",
|
|
2768
|
-
description: "Heading
|
|
2761
|
+
description: "Heading shown above the group in the sidebar.",
|
|
2769
2762
|
validation: (rule) => rule.required()
|
|
2770
2763
|
}), defineField({
|
|
2771
2764
|
name: "guides",
|
|
2772
2765
|
type: "array",
|
|
2773
|
-
description: "
|
|
2766
|
+
description: "Guides in the group, in order. Drag to reorder.",
|
|
2774
2767
|
of: [defineArrayMember({
|
|
2775
2768
|
name: "guide",
|
|
2776
2769
|
type: "reference",
|
|
@@ -2808,7 +2801,7 @@ const handbookType = defineType({
|
|
|
2808
2801
|
sidebarTitle: sidebarTitle ?? "Handbook",
|
|
2809
2802
|
roles,
|
|
2810
2803
|
blocks: blocks ?? [],
|
|
2811
|
-
undocumentedFieldMessage: undocumentedFieldMessage ?? "This field
|
|
2804
|
+
undocumentedFieldMessage: undocumentedFieldMessage ?? "This field isn't documented yet. Ask your development team for guidance."
|
|
2812
2805
|
}, guideType = createGuideType(resolved.blocks);
|
|
2813
2806
|
return {
|
|
2814
2807
|
name: pluginName,
|
|
@@ -2844,25 +2837,26 @@ const handbookType = defineType({
|
|
|
2844
2837
|
};
|
|
2845
2838
|
});
|
|
2846
2839
|
/**
|
|
2847
|
-
* Creates
|
|
2848
|
-
* not permitted to edit them.
|
|
2840
|
+
* Creates Structure tool items for the Handbook documents, or none when the current user can't edit them.
|
|
2849
2841
|
*
|
|
2850
|
-
* @param structureBuilder - The
|
|
2851
|
-
* @param context - The
|
|
2852
|
-
* @param editors - Email addresses
|
|
2853
|
-
* @returns
|
|
2842
|
+
* @param structureBuilder - The structure builder.
|
|
2843
|
+
* @param context - The structure context, with the current user.
|
|
2844
|
+
* @param editors - Email addresses of the editors, defaulting to the configured list.
|
|
2845
|
+
* @returns List items for the Handbook document and the guides list, oldest guide first.
|
|
2854
2846
|
* @public
|
|
2855
2847
|
*/
|
|
2856
2848
|
function handbookStructure(structureBuilder, context, editors) {
|
|
2857
2849
|
if (!isPermittedEditor(editors, context.currentUser?.email)) return [];
|
|
2858
2850
|
let { listItem, document, documentTypeList } = structureBuilder;
|
|
2859
|
-
return [listItem().title("Handbook").icon(createSanityIcon(BookTextIcon)).child(document().id(handbookTypeName).schemaType(handbookTypeName).title("Handbook")), listItem().title("Handbook Guides").icon(createSanityIcon(BookOpenTextIcon)).child(documentTypeList(guideTypeName).title("Handbook Guides")
|
|
2851
|
+
return [listItem().title("Handbook").icon(createSanityIcon(BookTextIcon)).child(document().id(handbookTypeName).schemaType(handbookTypeName).title("Handbook")), listItem().title("Handbook Guides").icon(createSanityIcon(BookOpenTextIcon)).child(documentTypeList(guideTypeName).title("Handbook Guides").defaultOrdering([{
|
|
2852
|
+
field: "_createdAt",
|
|
2853
|
+
direction: "asc"
|
|
2854
|
+
}]))];
|
|
2860
2855
|
}
|
|
2861
2856
|
/**
|
|
2862
|
-
* Checks whether the current user
|
|
2863
|
-
* unrestricted access.
|
|
2857
|
+
* Checks whether the current user can edit Handbook documents. Without an editors list, everyone can.
|
|
2864
2858
|
*
|
|
2865
|
-
* @param editors - Email addresses
|
|
2859
|
+
* @param editors - Email addresses of the editors, defaulting to the configured list.
|
|
2866
2860
|
* @returns Whether the current user can edit Handbook documents.
|
|
2867
2861
|
* @public
|
|
2868
2862
|
*/
|