@driftime/sanity-plugin-handbook 0.2.0 → 0.3.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 (69) hide show
  1. package/README.md +133 -80
  2. package/dist/index.d.ts +203 -110
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +2790 -2064
  5. package/dist/index.js.map +1 -1
  6. package/package.json +36 -37
  7. package/dist/index.cjs +0 -2094
  8. package/dist/index.cjs.map +0 -1
  9. package/dist/index.d.cts +0 -143
  10. package/src/blocks/callout/block.tsx +0 -56
  11. package/src/blocks/callout/content.tsx +0 -41
  12. package/src/blocks/callout/preview.tsx +0 -15
  13. package/src/blocks/code/block.tsx +0 -18
  14. package/src/blocks/code/content.tsx +0 -18
  15. package/src/blocks/code/preview.tsx +0 -17
  16. package/src/blocks/horizontal-rule/block.tsx +0 -5
  17. package/src/blocks/horizontal-rule/content.tsx +0 -8
  18. package/src/blocks/horizontal-rule/preview.tsx +0 -5
  19. package/src/blocks/image/block.tsx +0 -23
  20. package/src/blocks/image/content.tsx +0 -31
  21. package/src/blocks/image/preview.tsx +0 -23
  22. package/src/blocks/video/block.tsx +0 -21
  23. package/src/blocks/video/content.tsx +0 -37
  24. package/src/blocks/video/preview.tsx +0 -21
  25. package/src/components/content-panel.tsx +0 -58
  26. package/src/components/decorators.tsx +0 -53
  27. package/src/components/document-types.tsx +0 -49
  28. package/src/components/field.tsx +0 -530
  29. package/src/components/guide-content.tsx +0 -117
  30. package/src/components/guides.tsx +0 -36
  31. package/src/components/pane-header.tsx +0 -26
  32. package/src/components/sidebar-group.tsx +0 -30
  33. package/src/components/sidebar-tab.tsx +0 -78
  34. package/src/contexts/handbook-context.tsx +0 -84
  35. package/src/getting-started/document-types.tsx +0 -104
  36. package/src/getting-started/how-to-use.tsx +0 -95
  37. package/src/getting-started/overview.tsx +0 -65
  38. package/src/hooks/use-container-width.ts +0 -41
  39. package/src/hooks/use-handbook-configuration.ts +0 -74
  40. package/src/hooks/use-is-handbook-editor.ts +0 -18
  41. package/src/icons/book-open-text.tsx +0 -22
  42. package/src/icons/book-text.tsx +0 -19
  43. package/src/icons/code.tsx +0 -18
  44. package/src/icons/image.tsx +0 -19
  45. package/src/icons/info.tsx +0 -19
  46. package/src/icons/layout-grid.tsx +0 -20
  47. package/src/icons/lightbulb.tsx +0 -19
  48. package/src/icons/list-plus.tsx +0 -21
  49. package/src/icons/message-circle-question-mark.tsx +0 -19
  50. package/src/icons/minus.tsx +0 -17
  51. package/src/icons/triangle-alert.tsx +0 -19
  52. package/src/icons/video.tsx +0 -18
  53. package/src/index.ts +0 -145
  54. package/src/layouts/content.tsx +0 -13
  55. package/src/layouts/sidebar.tsx +0 -15
  56. package/src/layouts/tool.tsx +0 -205
  57. package/src/lib/handbook-structure.ts +0 -47
  58. package/src/lib/icons.ts +0 -16
  59. package/src/lib/utils.ts +0 -69
  60. package/src/schemas/annotations/link.ts +0 -19
  61. package/src/schemas/blocks/callout.ts +0 -69
  62. package/src/schemas/blocks/code.ts +0 -46
  63. package/src/schemas/blocks/horizontal-rule.ts +0 -31
  64. package/src/schemas/blocks/image.ts +0 -40
  65. package/src/schemas/blocks/video.ts +0 -34
  66. package/src/schemas/guide-content.ts +0 -58
  67. package/src/schemas/types/guide.ts +0 -48
  68. package/src/schemas/types/handbook.ts +0 -86
  69. package/src/types.ts +0 -101
package/dist/index.d.cts DELETED
@@ -1,143 +0,0 @@
1
- import type { ComponentType } from "react";
2
- import type { CurrentUser } from "sanity";
3
- import type { DocumentDefinition } from "sanity";
4
- import { ListItemBuilder } from "sanity/structure";
5
- import { PluginOptions } from "sanity";
6
- import type { PortableTextBlock } from "sanity";
7
- import type { PortableTextObject } from "sanity";
8
- import type { SanityDocument } from "sanity";
9
- import type { SchemaTypeDefinition } from "sanity";
10
- import type { StructureBuilder } from "sanity/structure";
11
-
12
- /** @public */
13
- export declare interface HandbookBlockDefinition {
14
- /** Sanity schema type definition for the custom block. */
15
- schema: SchemaTypeDefinition;
16
- /** React component for rendering the block in the Handbook viewer. */
17
- component: ComponentType<{
18
- value: PortableTextObject;
19
- }>;
20
- }
21
-
22
- /** @public */
23
- export declare interface HandbookConfig {
24
- /** Title shown in the Studio tool navigation. */
25
- title?: string;
26
- /** Heading displayed at the top of the sidebar. */
27
- sidebarTitle?: string;
28
- /** Document type groups defining the hierarchy. */
29
- groups?: HandbookStructureGroup[];
30
- /** Custom Portable Text block definitions for guide content. */
31
- blocks?: HandbookBlockDefinition[];
32
- /** Email addresses permitted to edit handbook documents. */
33
- editors?: string[];
34
- /** Fallback message shown when a field has no description. */
35
- undocumentedFieldMessage?: string;
36
- }
37
-
38
- /** @public */
39
- export declare interface HandbookGuideGroup {
40
- /** Unique key assigned by Sanity for this array item. */
41
- _key: string;
42
- /** Display title for this group in the sidebar. */
43
- title: string;
44
- /** Ordered array of guide references. */
45
- guides: SanityHandbookGuide[];
46
- }
47
-
48
- /** @public */
49
- export declare interface HandbookMetadata {
50
- /** Display title override for the field or document. */
51
- title?: string;
52
- /** Description shown beneath the field or document heading. */
53
- description?: string;
54
- /** Illustrative example value for the field. */
55
- example?: string;
56
- /** Helpful tip displayed as a popover hint. */
57
- tip?: string;
58
- /** Informational note displayed as a popover hint. */
59
- info?: string;
60
- /** Warning displayed as a popover hint. */
61
- caution?: string;
62
- }
63
-
64
- /**
65
- * Creates a Handbook tool for Sanity Studio, providing auto-generated documentation
66
- * for document types and Portable Text guides within the Studio interface.
67
- *
68
- * @public
69
- * @param config - Optional plugin configuration.
70
- * @returns Sanity plugin definition.
71
- */
72
- export declare function handbookPlugin(config?: HandbookConfig): PluginOptions;
73
-
74
- /**
75
- * Creates Structure tool items for handbook documents.
76
- * Returns an empty array if the current user is not in the editors list
77
- * configured via handbookPlugin.
78
- *
79
- * @public
80
- * @param structureBuilder - The Sanity Structure builder instance.
81
- * @param context - The Structure context containing the current user.
82
- * @returns An array of list items for the handbook singleton and guides list.
83
- */
84
- export declare function handbookStructure(
85
- structureBuilder: StructureBuilder,
86
- context: {
87
- currentUser: CurrentUser | null;
88
- },
89
- ): ListItemBuilder[];
90
-
91
- /** @public */
92
- export declare interface HandbookStructureGroup {
93
- /** Display title for the document type group. */
94
- title: string;
95
- /** Brief description of the group's purpose. */
96
- description?: string;
97
- /** Document definitions belonging to this group. */
98
- documents: DocumentDefinition[];
99
- }
100
-
101
- /** @public */
102
- export declare interface SanityHandbook extends SanityDocument {
103
- /** Document type identifier. */
104
- _type: "handbook.handbook";
105
- /** Ordered array of groups, each containing a title and guide references. */
106
- groups: HandbookGuideGroup[];
107
- }
108
-
109
- /** @public */
110
- export declare interface SanityHandbookGuide extends SanityDocument {
111
- /** Document type identifier. */
112
- _type: "handbook.guide";
113
- /** Unique key assigned by Sanity for this array item. */
114
- _key: string;
115
- /** Display title for this guide. */
116
- title: string;
117
- /** Brief description shown beneath the guide heading. */
118
- description?: string;
119
- /** Portable Text content of the guide. */
120
- content: PortableTextBlock[];
121
- }
122
-
123
- /**
124
- * Checks whether the current user is permitted to edit handbook content.
125
- * Returns true if no editors list is provided (unrestricted) or if the
126
- * current user's email is in the list.
127
- *
128
- * @public
129
- * @param editors - Optional list of permitted email addresses.
130
- * @returns Whether the current user can edit handbook documents.
131
- */
132
- export declare function useIsHandbookEditor(editors?: string[]): boolean;
133
-
134
- export {};
135
-
136
- declare module "@sanity/types" {
137
- interface FieldDefinitionBase {
138
- handbook?: HandbookMetadata;
139
- }
140
- interface DocumentDefinition {
141
- handbook?: HandbookMetadata;
142
- }
143
- }
@@ -1,56 +0,0 @@
1
- import { PortableText } from "@portabletext/react";
2
- import type { PortableTextBlock } from "@portabletext/react";
3
- import type { ReactNode } from "react";
4
-
5
- import type { CalloutVariant } from "./content";
6
- import { CalloutContent } from "./content";
7
-
8
- interface HandbookCalloutValue {
9
- /** Document type identifier. */
10
- _type: "handbook.callout";
11
- /** Visual style and intent of the callout. */
12
- variant: CalloutVariant;
13
- /** Portable Text content displayed inside the callout. */
14
- body: PortableTextBlock[];
15
- }
16
-
17
- export function CalloutBlock({ value }: { value: HandbookCalloutValue }) {
18
- return (
19
- <div style={{ marginBlock: "2rem" }}>
20
- <CalloutContent variant={value.variant}>
21
- <PortableText
22
- value={value.body}
23
- components={{
24
- block: { normal: ({ children }) => <>{children}</> },
25
- marks: {
26
- strong: ({ children }) => <strong>{children}</strong>,
27
- em: ({ children }) => <em>{children}</em>,
28
- code: ({ children }) => (
29
- <code
30
- style={{
31
- padding: "0.125rem 0.25rem",
32
- fontSize: "0.875em",
33
- backgroundColor: "var(--card-code-bg-color)",
34
- borderRadius: "0.125rem",
35
- }}
36
- >
37
- {children}
38
- </code>
39
- ),
40
- link: ({ children, value: mark }: { children: ReactNode; value?: { href?: string } }) => (
41
- <a
42
- href={mark?.href}
43
- target="_blank"
44
- rel="noopener noreferrer"
45
- style={{ color: "var(--card-fg-color)" }}
46
- >
47
- {children}
48
- </a>
49
- ),
50
- },
51
- }}
52
- />
53
- </CalloutContent>
54
- </div>
55
- );
56
- }
@@ -1,41 +0,0 @@
1
- import { Card, Flex, Text } from "@sanity/ui";
2
- import type { ReactNode } from "react";
3
-
4
- import { InfoIcon } from "../../icons/info";
5
- import { LightbulbIcon } from "../../icons/lightbulb";
6
- import { TriangleAlertIcon } from "../../icons/triangle-alert";
7
- import { defaultIconProps } from "../../lib/icons";
8
-
9
- export type CalloutVariant = "tip" | "info" | "warning";
10
-
11
- interface CalloutContentProps {
12
- /** Visual style variant determining the icon and tone. */
13
- variant: CalloutVariant;
14
- /** Content displayed inside the callout. */
15
- children: ReactNode;
16
- }
17
-
18
- /** Icon and tone mapping for each callout variant. */
19
- export const variantConfig = {
20
- tip: { icon: LightbulbIcon, tone: "positive" },
21
- info: { icon: InfoIcon, tone: "primary" },
22
- warning: { icon: TriangleAlertIcon, tone: "caution" },
23
- } as const;
24
-
25
- export function CalloutContent({ variant, children }: CalloutContentProps) {
26
- const config = variantConfig[variant];
27
- const Icon = config.icon;
28
-
29
- return (
30
- <Card padding={4} radius={2} tone={config.tone}>
31
- <Flex align="flex-start" gap={3}>
32
- <div style={{ flexShrink: 0, marginTop: "-2px", fontSize: "16px", color: "var(--card-icon-color)" }}>
33
- <Icon {...defaultIconProps} />
34
- </div>
35
- <Text size={1} style={{ color: "var(--card-icon-color)" }}>
36
- {children}
37
- </Text>
38
- </Flex>
39
- </Card>
40
- );
41
- }
@@ -1,15 +0,0 @@
1
- import type { PreviewProps } from "sanity";
2
-
3
- import type { CalloutVariant } from "./content";
4
- import { CalloutContent } from "./content";
5
-
6
- interface CalloutPreviewProps extends PreviewProps {
7
- /** Visual style variant for the callout. */
8
- variant?: CalloutVariant;
9
- /** Plain text content extracted from the callout body. */
10
- text?: string;
11
- }
12
-
13
- export function CalloutPreview({ variant, text }: CalloutPreviewProps) {
14
- return <CalloutContent variant={variant ?? "tip"}>{text}</CalloutContent>;
15
- }
@@ -1,18 +0,0 @@
1
- import { CodeContent } from "./content";
2
-
3
- interface HandbookCodeValue {
4
- /** Document type identifier. */
5
- _type: "handbook.code";
6
- /** Source code to display. */
7
- code: string;
8
- /** Programming language for syntax highlighting. */
9
- language?: string;
10
- }
11
-
12
- export function CodeBlock({ value }: { value: HandbookCodeValue }) {
13
- return (
14
- <div style={{ marginBlock: "1.5rem" }}>
15
- <CodeContent code={value.code} language={value.language} />
16
- </div>
17
- );
18
- }
@@ -1,18 +0,0 @@
1
- import { Card, Code } from "@sanity/ui";
2
-
3
- interface CodeContentProps {
4
- /** Source code to display. */
5
- code: string;
6
- /** Programming language for syntax highlighting. */
7
- language?: string;
8
- }
9
-
10
- export function CodeContent({ code, language }: CodeContentProps) {
11
- return (
12
- <Card padding={4} radius={2} tone="transparent" style={{ overflowX: "auto" }}>
13
- <Code size={1} language={language}>
14
- {code}
15
- </Code>
16
- </Card>
17
- );
18
- }
@@ -1,17 +0,0 @@
1
- import type { PreviewProps } from "sanity";
2
-
3
- import { isDefined } from "../../lib/utils";
4
- import { CodeContent } from "./content";
5
-
6
- interface CodePreviewProps extends PreviewProps {
7
- /** Source code to display. */
8
- code?: string;
9
- /** Programming language for syntax highlighting. */
10
- language?: string;
11
- }
12
-
13
- export function CodePreview({ code, language }: CodePreviewProps) {
14
- if (!isDefined(code)) return null;
15
-
16
- return <CodeContent code={code} language={language} />;
17
- }
@@ -1,5 +0,0 @@
1
- import { HorizontalRuleContent } from "./content";
2
-
3
- export function HorizontalRuleBlock() {
4
- return <HorizontalRuleContent marginBlock="2.5rem" />;
5
- }
@@ -1,8 +0,0 @@
1
- interface HorizontalRuleContentProps {
2
- /** Vertical spacing above and below the rule. */
3
- marginBlock?: string;
4
- }
5
-
6
- export function HorizontalRuleContent({ marginBlock = "0" }: HorizontalRuleContentProps) {
7
- return <hr style={{ marginBlock, border: "none", borderTop: "1px solid var(--card-border-color)" }} />;
8
- }
@@ -1,5 +0,0 @@
1
- import { HorizontalRuleContent } from "./content";
2
-
3
- export function HorizontalRulePreview() {
4
- return <HorizontalRuleContent marginBlock="0.5rem" />;
5
- }
@@ -1,23 +0,0 @@
1
- import { isDefined } from "../../lib/utils";
2
- import { ImageContent } from "./content";
3
-
4
- interface HandbookImageValue {
5
- /** Document type identifier. */
6
- _type: "handbook.image";
7
- /** Resolved image asset containing the URL. */
8
- asset?: { url?: string };
9
- /** Text displayed beneath the image. */
10
- caption?: string;
11
- /** Alternative text for screen readers. */
12
- alt?: string;
13
- }
14
-
15
- export function ImageBlock({ value }: { value: HandbookImageValue }) {
16
- if (!isDefined(value.asset?.url)) return null;
17
-
18
- return (
19
- <div style={{ marginBlock: "1.5rem" }}>
20
- <ImageContent url={value.asset.url} alt={value.alt} caption={value.caption} />
21
- </div>
22
- );
23
- }
@@ -1,31 +0,0 @@
1
- import { Text } from "@sanity/ui";
2
-
3
- import { isDefined } from "../../lib/utils";
4
-
5
- interface ImageContentProps {
6
- /** Image source URL. */
7
- url: string;
8
- /** Alternative text for screen readers. */
9
- alt?: string;
10
- /** Text displayed beneath the image. */
11
- caption?: string;
12
- }
13
-
14
- export function ImageContent({ url, alt, caption }: ImageContentProps) {
15
- return (
16
- <>
17
- <img
18
- src={url}
19
- alt={alt ?? ""}
20
- style={{ display: "block", maxWidth: "100%", borderRadius: "0.25rem", overflow: "hidden" }}
21
- />
22
- {isDefined(caption) && (
23
- <div style={{ marginBlockStart: "0.75rem" }}>
24
- <Text size={1} muted style={{ fontStyle: "italic" }}>
25
- {caption}
26
- </Text>
27
- </div>
28
- )}
29
- </>
30
- );
31
- }
@@ -1,23 +0,0 @@
1
- import type { PreviewProps } from "sanity";
2
-
3
- import { isDefined } from "../../lib/utils";
4
- import { ImageContent } from "./content";
5
-
6
- interface ImagePreviewProps extends PreviewProps {
7
- /** Resolved image URL from the asset. */
8
- url?: string;
9
- /** Alternative text for screen readers. */
10
- alt?: string;
11
- /** Text displayed beneath the image. */
12
- caption?: string;
13
- }
14
-
15
- export function ImagePreview({ url, alt, caption }: ImagePreviewProps) {
16
- if (!isDefined(url)) return null;
17
-
18
- return (
19
- <div style={{ padding: "0.5rem" }}>
20
- <ImageContent url={url} alt={alt} caption={caption} />
21
- </div>
22
- );
23
- }
@@ -1,21 +0,0 @@
1
- import { isDefined } from "../../lib/utils";
2
- import { VideoContent } from "./content";
3
-
4
- interface HandbookVideoValue {
5
- /** Document type identifier. */
6
- _type: "handbook.video";
7
- /** Resolved video asset containing the URL. */
8
- asset?: { url?: string };
9
- /** Text displayed beneath the video. */
10
- caption?: string;
11
- }
12
-
13
- export function VideoBlock({ value }: { value: HandbookVideoValue }) {
14
- if (!isDefined(value.asset?.url)) return null;
15
-
16
- return (
17
- <div style={{ marginBlock: "1.5rem" }}>
18
- <VideoContent url={value.asset.url} caption={value.caption} />
19
- </div>
20
- );
21
- }
@@ -1,37 +0,0 @@
1
- import { Text } from "@sanity/ui";
2
-
3
- import { isDefined } from "../../lib/utils";
4
-
5
- interface VideoContentProps {
6
- /** Video source URL. */
7
- url: string;
8
- /** Text displayed beneath the video. */
9
- caption?: string;
10
- }
11
-
12
- export function VideoContent({ url, caption }: VideoContentProps) {
13
- return (
14
- <>
15
- <video
16
- src={url}
17
- controls
18
- style={{
19
- display: "block",
20
- maxWidth: "100%",
21
- borderRadius: "0.25rem",
22
- overflow: "hidden",
23
- WebkitTransform: "translateZ(0)",
24
- }}
25
- >
26
- <track kind="captions" label={caption ?? "Video"} />
27
- </video>
28
- {isDefined(caption) && (
29
- <div style={{ marginBlockStart: "0.75rem" }}>
30
- <Text size={1} muted style={{ fontStyle: "italic" }}>
31
- {caption}
32
- </Text>
33
- </div>
34
- )}
35
- </>
36
- );
37
- }
@@ -1,21 +0,0 @@
1
- import type { PreviewProps } from "sanity";
2
-
3
- import { isDefined } from "../../lib/utils";
4
- import { VideoContent } from "./content";
5
-
6
- interface VideoPreviewProps extends PreviewProps {
7
- /** Resolved video URL from the asset. */
8
- url?: string;
9
- /** Text displayed beneath the video. */
10
- caption?: string;
11
- }
12
-
13
- export function VideoPreview({ url, caption }: VideoPreviewProps) {
14
- if (!isDefined(url)) return null;
15
-
16
- return (
17
- <div style={{ padding: "0.5rem" }}>
18
- <VideoContent url={url} caption={caption} />
19
- </div>
20
- );
21
- }
@@ -1,58 +0,0 @@
1
- import { Box, Heading, Stack, Text } from "@sanity/ui";
2
- import type { ReactNode } from "react";
3
-
4
- import { useHandbookContext } from "../contexts/handbook-context";
5
- import { isDefined } from "../lib/utils";
6
- import { PaneHeader } from "./pane-header";
7
-
8
- interface ContentPanelProps {
9
- /** Unique identifier linking this panel to its sidebar tab. */
10
- id: string;
11
- /** Heading displayed at the top of the panel. */
12
- title: string;
13
- /** Optional description shown beneath the heading. */
14
- description?: string;
15
- /** Panel body content. */
16
- children: ReactNode;
17
- }
18
-
19
- export function ContentPanel({ id, title, description, children }: ContentPanelProps) {
20
- const { activeTab } = useHandbookContext();
21
-
22
- if (activeTab !== id) return null;
23
-
24
- return (
25
- <div
26
- id={`panel-${id}`}
27
- aria-labelledby={id}
28
- role="tabpanel"
29
- style={{ display: "flex", flexDirection: "column", height: "100%" }}
30
- >
31
- <PaneHeader title={title} />
32
- <div style={{ flex: 1, overflowY: "auto" }}>
33
- <Box
34
- style={{
35
- maxWidth: "640px",
36
- boxSizing: "border-box",
37
- marginInline: "auto",
38
- paddingInline: "20px",
39
- paddingBlockStart: "32px",
40
- paddingBlockEnd: "220px",
41
- }}
42
- >
43
- <Stack marginBottom={6} space={5}>
44
- <Heading as="h2" size={4}>
45
- {title}
46
- </Heading>
47
- {isDefined(description) && (
48
- <Text size={1} muted>
49
- {description}
50
- </Text>
51
- )}
52
- </Stack>
53
- {children}
54
- </Box>
55
- </div>
56
- </div>
57
- );
58
- }
@@ -1,53 +0,0 @@
1
- import type { ReactNode } from "react";
2
-
3
- interface DecoratorProps {
4
- /** Text content wrapped by the decorator. */
5
- children: ReactNode;
6
- }
7
-
8
- export function ParagraphDecorator({ children }: DecoratorProps) {
9
- return <span style={{ fontSize: "0.8125rem" }}>{children}</span>;
10
- }
11
-
12
- export function HeadingDecorator({ children }: DecoratorProps) {
13
- return <span style={{ fontSize: "0.8125rem", fontWeight: "500" }}>{children}</span>;
14
- }
15
-
16
- export function BlockquoteDecorator({ children }: DecoratorProps) {
17
- return (
18
- <div
19
- style={{
20
- paddingLeft: "0.75em",
21
- fontSize: "0.8125rem",
22
- fontStyle: "italic",
23
- borderLeft: "2px solid var(--card-border-color)",
24
- }}
25
- >
26
- {children}
27
- </div>
28
- );
29
- }
30
-
31
- export function BulletListDecorator({ children }: DecoratorProps) {
32
- return <div style={{ marginTop: "-0.25em", fontSize: "0.8125rem" }}>{children}</div>;
33
- }
34
-
35
- export function NumberListDecorator({ children }: DecoratorProps) {
36
- return <div style={{ marginTop: "-0.25em", fontSize: "0.8125rem" }}>{children}</div>;
37
- }
38
-
39
- export function InlineCodeDecorator({ children }: DecoratorProps) {
40
- return (
41
- <code
42
- style={{
43
- padding: "0.125rem 0.25rem",
44
- fontSize: "0.8125rem",
45
- color: "var(--card-muted-fg-color)",
46
- backgroundColor: "var(--card-code-bg-color)",
47
- borderRadius: "0.125rem",
48
- }}
49
- >
50
- {children}
51
- </code>
52
- );
53
- }
@@ -1,49 +0,0 @@
1
- import { useHandbookContext } from "../contexts/handbook-context";
2
- import { convertCase } from "../lib/utils";
3
- import { ContentPanel } from "./content-panel";
4
- import { Field } from "./field";
5
- import { SidebarGroup } from "./sidebar-group";
6
- import { SidebarTab } from "./sidebar-tab";
7
-
8
- export function DocumentTypesTabs() {
9
- const { groups } = useHandbookContext();
10
-
11
- return groups.map((group) => {
12
- const { title, documents } = group;
13
-
14
- return (
15
- <SidebarGroup key={title} heading={title}>
16
- {documents.map((document) => {
17
- const effectiveTitle = document.handbook?.title ?? document.title ?? convertCase(document.name, "title");
18
- const icon = typeof document.icon === "function" ? document.icon : undefined;
19
-
20
- return <SidebarTab key={document.name} id={document.name} label={effectiveTitle} icon={icon} />;
21
- })}
22
- </SidebarGroup>
23
- );
24
- });
25
- }
26
-
27
- export function DocumentTypesPanels() {
28
- const { groups } = useHandbookContext();
29
-
30
- return groups.map((group) => {
31
- const { documents } = group;
32
-
33
- return documents.map((document) => {
34
- const effectiveTitle = document.handbook?.title ?? document.title ?? convertCase(document.name, "title");
35
- const effectiveDescription =
36
- document.handbook?.description ?? (typeof document.description === "string" ? document.description : undefined);
37
-
38
- return (
39
- <ContentPanel key={document.name} id={document.name} title={effectiveTitle} description={effectiveDescription}>
40
- <div style={{ display: "flex", flexDirection: "column", gap: "3.25rem" }}>
41
- {document.fields.map((field) => (
42
- <Field key={field.name} field={field} />
43
- ))}
44
- </div>
45
- </ContentPanel>
46
- );
47
- });
48
- });
49
- }