@stainless-api/docs 0.1.0-beta.129 → 0.1.0-beta.130

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 (61) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/ambient.d.ts +6 -0
  3. package/eslint-suppressions.json +0 -5
  4. package/package.json +19 -15
  5. package/plugin/generateAPIReferenceLink.ts +0 -40
  6. package/plugin/index.ts +12 -0
  7. package/plugin/loadPluginConfig.ts +36 -5
  8. package/plugin/markdown/highlighter.ts +1 -1
  9. package/plugin/react/Routing.tsx +1 -85
  10. package/plugin/referencePlaceholderUtils.ts +1 -1
  11. package/plugin/routes/llms.ts +186 -0
  12. package/plugin/sidebar-utils/sidebar-builder.ts +2 -7
  13. package/plugin/specs/FileCache.ts +1 -1
  14. package/plugin/specs/index.ts +1 -6
  15. package/plugin/vendor/preview.worker.docs.js +9001 -8694
  16. package/shared/virtualModule.ts +1 -9
  17. package/stl-docs/chat/docs-chat-handler.ts +18 -0
  18. package/stl-docs/chat/hook.ts +215 -0
  19. package/stl-docs/chat/schemas.ts +70 -0
  20. package/stl-docs/chat/stainless-handler/index.ts +126 -0
  21. package/stl-docs/chat/stream-util.ts +16 -0
  22. package/stl-docs/chat/ui/AiChat.module.css +591 -0
  23. package/stl-docs/chat/ui/AiChat.tsx +188 -0
  24. package/stl-docs/chat/ui/Trigger.tsx +154 -0
  25. package/stl-docs/chat/ui/components/ChatControls.tsx +51 -0
  26. package/stl-docs/chat/ui/components/ChatEmpty.tsx +42 -0
  27. package/stl-docs/chat/ui/components/ChatLog.tsx +96 -0
  28. package/stl-docs/chat/ui/components/ChatMessage.tsx +47 -0
  29. package/stl-docs/chat/ui/components/CodeBlock.tsx +33 -0
  30. package/stl-docs/chat/ui/components/MessageFeedback.tsx +109 -0
  31. package/stl-docs/chat/ui/components/Table.tsx +15 -0
  32. package/stl-docs/chat/ui/components/ToolCall.tsx +34 -0
  33. package/stl-docs/chat/ui/components/hljs-github.css +81 -0
  34. package/stl-docs/chat/ui/scroll-manager.ts +86 -0
  35. package/stl-docs/chat/ui/types.ts +45 -0
  36. package/stl-docs/components/AiChatIsland.tsx +14 -12
  37. package/stl-docs/components/PageFrame.astro +7 -4
  38. package/stl-docs/components/headers/DefaultHeader.astro +2 -2
  39. package/stl-docs/components/headers/StackedHeader.astro +2 -2
  40. package/stl-docs/components/mintlify-compat/Accordion.astro +2 -2
  41. package/stl-docs/components/mintlify-compat/AccordionGroup.astro +0 -4
  42. package/stl-docs/components/mintlify-compat/Columns.astro +2 -2
  43. package/stl-docs/components/mintlify-compat/Frame.astro +2 -2
  44. package/stl-docs/components/mintlify-compat/Tab.astro +2 -2
  45. package/stl-docs/components/mintlify-compat/callouts/Callout.astro +2 -2
  46. package/stl-docs/components/mintlify-compat/callouts/Check.astro +0 -4
  47. package/stl-docs/components/mintlify-compat/callouts/Danger.astro +0 -4
  48. package/stl-docs/components/mintlify-compat/callouts/Info.astro +0 -4
  49. package/stl-docs/components/mintlify-compat/callouts/Note.astro +0 -4
  50. package/stl-docs/components/mintlify-compat/callouts/Tip.astro +0 -4
  51. package/stl-docs/components/mintlify-compat/callouts/Warning.astro +0 -4
  52. package/stl-docs/components/nav-tabs/NavDropdown.astro +1 -1
  53. package/stl-docs/components/pagination/PaginationLinkEmphasized.astro +2 -2
  54. package/stl-docs/components/pagination/PaginationLinkQuiet.astro +2 -2
  55. package/stl-docs/components/pagination/util.ts +3 -3
  56. package/stl-docs/disableCalloutSyntax.ts +1 -1
  57. package/stl-docs/index.ts +14 -28
  58. package/stl-docs/loadStlDocsConfig.ts +15 -4
  59. package/stl-docs/proseSearchIndexing.ts +2 -6
  60. package/virtual-module.d.ts +8 -17
  61. package/stl-docs/components/ClientRouterHead.astro +0 -41
@@ -0,0 +1,109 @@
1
+ import { CheckIcon, CopyIcon, ThumbsDownIcon, ThumbsUpIcon } from 'lucide-react';
2
+ import { motion } from 'motion/react';
3
+ import { startTransition, useCallback, useOptimistic, useState } from 'react';
4
+
5
+ import type { AssistantTextMessage } from '../types';
6
+
7
+ import { Button } from '@stainless-api/ui-primitives';
8
+ import clsx from 'clsx';
9
+ import styles from '../AiChat.module.css';
10
+
11
+ export default function MessageFeedbackButtons({
12
+ spanId,
13
+ messages,
14
+ rateMessage,
15
+ onCopyMessage,
16
+ }: {
17
+ spanId: string;
18
+ messages: AssistantTextMessage[];
19
+ rateMessage?: (spanId: string, rating: 'up' | 'down') => Promise<boolean>;
20
+ onCopyMessage?: (spanId: string) => void;
21
+ }) {
22
+ // Copy response as markdown
23
+ const [copied, setCopied] = useState(false);
24
+ const handleCopy = useCallback(() => {
25
+ onCopyMessage?.(spanId);
26
+ const combinedText = messages.map((msg) => msg.content).join('\n\n');
27
+ navigator.clipboard
28
+ .writeText(combinedText)
29
+ .then(() => {
30
+ setCopied(true);
31
+ setTimeout(() => setCopied(false), 2000);
32
+ })
33
+ .catch(() => {
34
+ setCopied(false);
35
+ });
36
+ }, [messages, spanId, onCopyMessage]);
37
+
38
+ // Provide message rating
39
+ const [rating, setRating] = useState<'up' | 'down' | null>(null);
40
+ const [optimisticRating, setOptimisticRating] = useOptimistic(
41
+ rating,
42
+ (current, newRating: NonNullable<typeof rating>) => newRating,
43
+ );
44
+ const handleRate = useCallback(
45
+ (newRating: 'up' | 'down') => {
46
+ if (!rateMessage) {
47
+ return;
48
+ }
49
+
50
+ startTransition(async () => {
51
+ setOptimisticRating(newRating);
52
+ const success = await rateMessage(spanId, newRating).catch(() => false);
53
+ if (success) setRating(newRating);
54
+ });
55
+ },
56
+ [spanId, setOptimisticRating, rateMessage],
57
+ );
58
+
59
+ return (
60
+ <motion.li
61
+ layout="position"
62
+ data-message-role="assistant"
63
+ className={clsx(styles['chat-message'], styles['feedback-buttons'])}
64
+ >
65
+ {rateMessage != null && (
66
+ <>
67
+ <Button
68
+ type="button"
69
+ variant="ghost"
70
+ size="sm"
71
+ onClick={() => handleRate('up')}
72
+ className={clsx(optimisticRating === 'up' && styles.active)}
73
+ aria-label="Thumbs up"
74
+ >
75
+ <Button.Icon icon={ThumbsUpIcon} size={15} />
76
+ </Button>
77
+
78
+ <Button
79
+ type="button"
80
+ variant="ghost"
81
+ size="sm"
82
+ onClick={() => handleRate('down')}
83
+ className={clsx(optimisticRating === 'down' && styles.active)}
84
+ aria-label="Thumbs down"
85
+ >
86
+ <Button.Icon icon={ThumbsDownIcon} size={15} />
87
+ </Button>
88
+ </>
89
+ )}
90
+
91
+ {messages.length > 0 && messages.some((msg) => msg.content.trim().length) && (
92
+ <Button
93
+ type="button"
94
+ variant="ghost"
95
+ size="sm"
96
+ onClick={handleCopy}
97
+ className={clsx(copied && styles.active)}
98
+ aria-label={copied ? 'Copied' : 'Copy response'}
99
+ >
100
+ <Button.Icon
101
+ // TODO: nicer cross-fade transition
102
+ icon={copied ? CheckIcon : CopyIcon}
103
+ size={15}
104
+ />
105
+ </Button>
106
+ )}
107
+ </motion.li>
108
+ );
109
+ }
@@ -0,0 +1,15 @@
1
+ import clsx from 'clsx';
2
+ import type { Components } from 'react-markdown';
3
+ import styles from '../AiChat.module.css';
4
+
5
+ export default {
6
+ table(props) {
7
+ const { children, ...rest } = props;
8
+
9
+ return (
10
+ <div className={clsx(styles['chat-table'])}>
11
+ <table {...rest}>{children}</table>
12
+ </div>
13
+ );
14
+ },
15
+ } satisfies Components;
@@ -0,0 +1,34 @@
1
+ import { motion } from 'motion/react';
2
+ import z from 'zod';
3
+
4
+ import type { AssistantToolCallMessage } from '../types';
5
+
6
+ import clsx from 'clsx';
7
+ import styles from '../AiChat.module.css';
8
+
9
+ export default function ToolCall({
10
+ message,
11
+ }: {
12
+ message: Pick<AssistantToolCallMessage, 'id' | 'toolName' | 'input'>;
13
+ }) {
14
+ // Render docs searches
15
+ if (message.toolName.endsWith('search_docs')) {
16
+ const parsed = z.object({ query: z.string() }).safeParse(message.input);
17
+ if (parsed.success) {
18
+ return (
19
+ <motion.li
20
+ layout="position"
21
+ data-message-role="assistant"
22
+ className={clsx(styles['chat-message'], styles['tool-use'])}
23
+ >
24
+ <p>
25
+ Fetching docs for <em>{parsed.data.query}</em>
26
+ </p>
27
+ </motion.li>
28
+ );
29
+ }
30
+ }
31
+
32
+ // No other tool renderers yet
33
+ return null;
34
+ }
@@ -0,0 +1,81 @@
1
+ .hljs-github {
2
+ /* color: light-dark(#24292e, #c9d1d9); */
3
+ /* background: light-dark(#ffffff, #0d1117); */
4
+
5
+ .hljs-doctag,
6
+ .hljs-keyword,
7
+ .hljs-meta .hljs-keyword,
8
+ .hljs-template-tag,
9
+ .hljs-template-variable,
10
+ .hljs-type,
11
+ .hljs-variable.language_ {
12
+ color: light-dark(#d73a49, #ff7b72);
13
+ }
14
+
15
+ .hljs-title,
16
+ .hljs-title.class_,
17
+ .hljs-title.class_.inherited__,
18
+ .hljs-title.function_ {
19
+ color: light-dark(#6f42c1, #d2a8ff);
20
+ }
21
+
22
+ .hljs-attr,
23
+ .hljs-attribute,
24
+ .hljs-literal,
25
+ .hljs-meta,
26
+ .hljs-number,
27
+ .hljs-operator,
28
+ .hljs-variable,
29
+ .hljs-selector-attr,
30
+ .hljs-selector-class,
31
+ .hljs-selector-id {
32
+ color: light-dark(#005cc5, #79c0ff);
33
+ }
34
+
35
+ .hljs-regexp,
36
+ .hljs-string,
37
+ .hljs-meta .hljs-string {
38
+ color: light-dark(#032f62, #a5d6ff);
39
+ }
40
+
41
+ .hljs-built_in,
42
+ .hljs-symbol {
43
+ color: light-dark(#e36209, #ffa657);
44
+ }
45
+
46
+ .hljs-comment,
47
+ .hljs-code,
48
+ .hljs-formula {
49
+ color: light-dark(#6a737d, #8b949e);
50
+ }
51
+
52
+ .hljs-name,
53
+ .hljs-quote,
54
+ .hljs-selector-tag,
55
+ .hljs-selector-pseudo {
56
+ color: light-dark(#22863a, #7ee787);
57
+ }
58
+
59
+ .hljs-subst {
60
+ color: light-dark(#24292e, #c9d1d9);
61
+ }
62
+
63
+ .hljs-section {
64
+ color: light-dark(#005cc5, #1f6feb);
65
+ font-weight: bold;
66
+ }
67
+
68
+ .hljs-bullet {
69
+ color: light-dark(#735c0f, #f2cc60);
70
+ }
71
+
72
+ .hljs-emphasis {
73
+ color: light-dark(#24292e, #c9d1d9);
74
+ font-style: italic;
75
+ }
76
+
77
+ .hljs-strong {
78
+ color: light-dark(#24292e, #c9d1d9);
79
+ font-weight: bold;
80
+ }
81
+ }
@@ -0,0 +1,86 @@
1
+ import React, { useEffect } from 'react';
2
+
3
+ const THRESHOLD_FROM_BOTTOM = 32; // px
4
+
5
+ /** Keep chat area scrolled to bottom */
6
+ export function useScrollToBottom(
7
+ scrollAreaRef: React.RefObject<HTMLDivElement | null>,
8
+ scrollContentsRef: React.RefObject<HTMLDivElement | null>,
9
+ watchValue: unknown,
10
+ ) {
11
+ /**
12
+ * Set `overflow` based on whether content is actually overflowing.
13
+ * - The reason this behavior is different than `overflow: auto` is that `overflow: auto` would
14
+ * show scrollbars while `motion` transitions are in flight applying scale correction to the
15
+ * children (i.e. while the chat area is animating to accommodate increased child height).
16
+ * - If we measure with `offsetHeight`/`clientHeight`, we only see the eventual “resting”
17
+ * dimensions (unaffected by transforms) so we know better whether a scrollbar should actually
18
+ * show, and avoid distracting flicker of scrollbars appearing & disappearing
19
+ */
20
+ useEffect(() => {
21
+ if (!scrollAreaRef.current || !scrollContentsRef.current) return;
22
+ const containerStyle = getComputedStyle(scrollAreaRef.current);
23
+ const scrollAreaHeight = scrollAreaRef.current.clientHeight;
24
+ const scrollContentsHeight = // scrollHeight is sometimes off; maybe because of scale correction?
25
+ scrollContentsRef.current.offsetHeight +
26
+ parseFloat(containerStyle.paddingTop) +
27
+ parseFloat(containerStyle.paddingBottom);
28
+ const canScroll = scrollContentsHeight > scrollAreaHeight + 1;
29
+ scrollAreaRef.current.style.overflowY = canScroll ? 'auto' : 'hidden';
30
+ }, [watchValue, scrollAreaRef, scrollContentsRef]);
31
+
32
+ /**
33
+ * Flip scroll direction based on user’s scroll position
34
+ * - By default, we need to keep the container scrolled all the way to the end during streaming,
35
+ * so that the user sees the new content that is appearing.
36
+ * - However, if the user scrolls upwards to read previous content, we shouldn’t scroll them
37
+ * back to the bottom while they’re trying to read content further up, even if more content is
38
+ * streaming.
39
+ *
40
+ * The smoothest way to accomplish this interaction is to flip the container’s scroll direction
41
+ * using flex-direction:
42
+ * - When the scroll position is near the bottom, scrolling should run in reverse direction—so
43
+ * that at a constant `0` scrollTop, the scroll stays at the end (no js-driven scrolling with
44
+ * distracting scrollbar flashing).
45
+ * - When the user scrolls upwards by a certain threshold, we flip scroll direction to normal,
46
+ * so that as scroll position holds constant, the still-streaming content below doesn’t push
47
+ * up the content the user is trying to read.
48
+ *
49
+ * When changing the flex direction, the meaning of `scrollTop` changes dramatically, so we need
50
+ * to manually adjust `scrollTop` to keep the scroll position visually seamless.
51
+ */
52
+ useEffect(() => {
53
+ if (!scrollAreaRef.current) return;
54
+ const ac = new AbortController();
55
+ scrollAreaRef.current.addEventListener(
56
+ 'scroll',
57
+ (e) => {
58
+ const scroller = e.currentTarget;
59
+ if (!(scroller instanceof HTMLElement)) return;
60
+ const appliedScrollDirection = scroller.classList.contains('scrolls-up') ? 'up' : 'down';
61
+ if (!appliedScrollDirection) return;
62
+ const { scrollHeight, clientHeight, scrollTop } = scroller;
63
+ // scrollTop is measured from the opposite edge depending on the appliedScrollDirection
64
+ // prettier-ignore
65
+ const distanceFromBottom = appliedScrollDirection === 'up'
66
+ ? -scrollTop
67
+ : scrollHeight - clientHeight - scrollTop;
68
+
69
+ // apply reverse scroll when the container is scrolled near the bottom, so that new content
70
+ // pushes old content up and the bottom edge stays constant.
71
+ if (appliedScrollDirection === 'down' && distanceFromBottom < THRESHOLD_FROM_BOTTOM) {
72
+ scroller.classList.add('scrolls-up');
73
+ scroller.scrollTop = -distanceFromBottom;
74
+ }
75
+ // flip to forward scroll when the user scrolls up from the bottom, so that new content
76
+ // doesn’t push up the content the user is trying to read.
77
+ if (appliedScrollDirection === 'up' && distanceFromBottom > THRESHOLD_FROM_BOTTOM) {
78
+ scroller.classList.remove('scrolls-up');
79
+ scroller.scrollTop = scrollHeight - clientHeight + scrollTop;
80
+ }
81
+ },
82
+ { capture: false, signal: ac.signal },
83
+ );
84
+ return () => ac.abort();
85
+ }, [scrollAreaRef]);
86
+ }
@@ -0,0 +1,45 @@
1
+ // Base
2
+ type BaseMessage = { id: string };
3
+ type BaseTextMessage = BaseMessage & { content: string };
4
+ // User
5
+ export type UserMessage = BaseTextMessage & { role: 'user' };
6
+ // Assistant
7
+ export type AssistantTextMessage = BaseMessage & {
8
+ role: 'assistant';
9
+ respondingTo: string;
10
+ messageType: 'text';
11
+ content: string;
12
+ isComplete: boolean;
13
+ };
14
+ export type AssistantToolCallMessage = BaseMessage & {
15
+ role: 'assistant';
16
+ respondingTo: string;
17
+ messageType: 'tool_use';
18
+ toolName: string;
19
+ input: Record<string, unknown> | undefined;
20
+ };
21
+ export type AssistantDoneMessage = BaseMessage & {
22
+ role: 'assistant';
23
+ respondingTo: string;
24
+ messageType: 'done';
25
+ spanId: string;
26
+ };
27
+ export type AssistantErrorMessage = BaseMessage & {
28
+ role: 'assistant';
29
+ respondingTo: string;
30
+ messageType: 'error';
31
+ errorMessage: string;
32
+ };
33
+
34
+ export type ChatMessage =
35
+ | UserMessage
36
+ | AssistantTextMessage
37
+ | AssistantToolCallMessage
38
+ | AssistantDoneMessage
39
+ | AssistantErrorMessage;
40
+
41
+ export type ExamplePrompt = {
42
+ longPrompt: string;
43
+ shortPrompt: string;
44
+ icon: React.ComponentType;
45
+ };
@@ -1,14 +1,16 @@
1
- import type { DocsLanguage } from '@stainless-api/docs-ui/routing';
2
- import AiChat, { STAINLESS_PROJECT } from 'virtual:stl-docs/components/AiChat.tsx';
1
+ // Conditionally load DocsChat only if it is enabled
2
+ // this way the virtual module imports aren’t evaluated and don’t cause errors when the feature is disabled
3
3
 
4
- export default function AiChatIsland({
5
- currentLanguage,
6
- siteTitle,
7
- }: {
8
- currentLanguage: DocsLanguage | undefined;
9
- siteTitle: string | undefined;
10
- }) {
11
- if (!AiChat) throw new Error('AiChatIsland was rendered but could not load AiChat component');
12
- if (!STAINLESS_PROJECT) return null;
13
- return <AiChat projectId={STAINLESS_PROJECT} language={currentLanguage} siteTitle={siteTitle} />;
4
+ // This conditional can’t be inlined into PageFrame because it breaks Astro’s static analysis of imports of client islands
5
+ const AiChat = __STLDOCS_ENABLE_AI_CHAT__ ? (await import('../chat/ui/AiChat')).default : null;
6
+
7
+ const STAINLESS_PROJECT = __STLDOCS_HAS_API_REFERENCE__
8
+ ? (await import('virtual:stl-starlight-virtual-module')).STAINLESS_PROJECT
9
+ : undefined;
10
+
11
+ export default function DocsChatLazy(
12
+ props: Omit<React.ComponentProps<NonNullable<typeof AiChat>>, 'stainlessProject'>,
13
+ ) {
14
+ if (!AiChat || !STAINLESS_PROJECT) return null;
15
+ return <AiChat {...props} stainlessProject={STAINLESS_PROJECT} />;
14
16
  }
@@ -2,15 +2,14 @@
2
2
  import Sidebar from 'virtual:starlight/components/Sidebar';
3
3
  import MobileMenuToggle from 'virtual:starlight/components/MobileMenuToggle';
4
4
 
5
- import AiChat from 'virtual:stl-docs/components/AiChat.tsx'; // conditionally resolves to null if ai chat module is not injected
6
- import AiChatIsland from './AiChatIsland.tsx'; // entrypoint for client island can’t be a virtual module
5
+ import AiChatIsland from './AiChatIsland.tsx'; // entrypoint for client island can’t be conditionally import()ed
6
+ import clsx from 'clsx';
7
7
 
8
8
  import starlightConfig from 'virtual:starlight/user-config';
9
9
  const locale = Astro.currentLocale ?? starlightConfig.defaultLocale.lang;
10
10
  const siteTitle = locale && starlightConfig.title[locale];
11
11
 
12
12
  const { hasSidebar } = Astro.locals.starlightRoute;
13
- import clsx from 'clsx';
14
13
  ---
15
14
 
16
15
  <div class="page">
@@ -30,5 +29,9 @@ import clsx from 'clsx';
30
29
 
31
30
  <slot />
32
31
 
33
- {!!AiChat && <AiChatIsland client:load currentLanguage={Astro.locals.language} siteTitle={siteTitle} />}
32
+ {
33
+ __STLDOCS_ENABLE_AI_CHAT__ && (
34
+ <AiChatIsland client:load currentLanguage={Astro.locals.language} siteTitle={siteTitle} />
35
+ )
36
+ }
34
37
  </div>
@@ -7,9 +7,9 @@ import NavLinks from '../nav-tabs/NavTabs.astro';
7
7
  import { TABS } from 'virtual:stl-docs-virtual-module';
8
8
  import ThemeSelect from 'virtual:starlight/components/ThemeSelect';
9
9
 
10
- interface Props {
10
+ type Props = {
11
11
  shouldRenderSearch?: boolean;
12
- }
12
+ };
13
13
 
14
14
  const { shouldRenderSearch } = Astro.props;
15
15
  ---
@@ -6,9 +6,9 @@ import HeaderLinks from './HeaderLinks.astro';
6
6
  import ThemeSelect from 'virtual:starlight/components/ThemeSelect';
7
7
  import SecondaryNavTabs from '../nav-tabs/SecondaryNavTabs.astro';
8
8
 
9
- interface Props {
9
+ type Props = {
10
10
  shouldRenderSearch?: boolean;
11
- }
11
+ };
12
12
 
13
13
  const { shouldRenderSearch } = Astro.props;
14
14
  ---
@@ -1,8 +1,8 @@
1
1
  ---
2
- export interface Props {
2
+ type Props = {
3
3
  title: string;
4
4
  children: astroHTML.JSX.Children;
5
- }
5
+ };
6
6
 
7
7
  const { title } = Astro.props;
8
8
 
@@ -1,9 +1,5 @@
1
1
  ---
2
2
  import { Accordion as StainlessAccordion } from '@stainless-api/ui-primitives';
3
-
4
- export interface Props {
5
- children: astroHTML.JSX.Children;
6
- }
7
3
  ---
8
4
 
9
5
  <StainlessAccordion.Group>
@@ -1,9 +1,9 @@
1
1
  ---
2
2
  import clsx from 'clsx';
3
3
 
4
- export interface Props {
4
+ type Props = {
5
5
  cols: number;
6
- }
6
+ };
7
7
 
8
8
  const { cols } = Astro.props;
9
9
  ---
@@ -1,7 +1,7 @@
1
1
  ---
2
- export interface Props {
2
+ type Props = {
3
3
  caption?: string;
4
- }
4
+ };
5
5
 
6
6
  const { caption } = Astro.props;
7
7
  ---
@@ -1,9 +1,9 @@
1
1
  ---
2
2
  import { TabItem } from '@astrojs/starlight/components';
3
3
 
4
- export interface Props {
4
+ type Props = {
5
5
  title: string;
6
- }
6
+ };
7
7
 
8
8
  const { title } = Astro.props;
9
9
  ---
@@ -1,10 +1,10 @@
1
1
  ---
2
2
  import { Callout as StainlessCallout, type CalloutVariant } from '@stainless-api/ui-primitives';
3
3
 
4
- export interface Props {
4
+ type Props = {
5
5
  variant?: CalloutVariant;
6
6
  children: astroHTML.JSX.Children;
7
- }
7
+ };
8
8
 
9
9
  const { variant } = Astro.props;
10
10
  ---
@@ -1,9 +1,5 @@
1
1
  ---
2
2
  import { Callout } from '@stainless-api/ui-primitives';
3
-
4
- export interface Props {
5
- children: astroHTML.JSX.Children;
6
- }
7
3
  ---
8
4
 
9
5
  <Callout variant="success">
@@ -1,9 +1,5 @@
1
1
  ---
2
2
  import { Callout } from '@stainless-api/ui-primitives';
3
-
4
- export interface Props {
5
- children: astroHTML.JSX.Children;
6
- }
7
3
  ---
8
4
 
9
5
  <Callout variant="danger">
@@ -1,9 +1,5 @@
1
1
  ---
2
2
  import { Callout } from '@stainless-api/ui-primitives';
3
-
4
- export interface Props {
5
- children: astroHTML.JSX.Children;
6
- }
7
3
  ---
8
4
 
9
5
  <Callout variant="info">
@@ -1,9 +1,5 @@
1
1
  ---
2
2
  import { Callout } from '@stainless-api/ui-primitives';
3
-
4
- export interface Props {
5
- children: astroHTML.JSX.Children;
6
- }
7
3
  ---
8
4
 
9
5
  <Callout variant="note">
@@ -1,9 +1,5 @@
1
1
  ---
2
2
  import { Callout } from '@stainless-api/ui-primitives';
3
-
4
- export interface Props {
5
- children: astroHTML.JSX.Children;
6
- }
7
3
  ---
8
4
 
9
5
  <Callout variant="tip">
@@ -1,9 +1,5 @@
1
1
  ---
2
2
  import { Callout } from '@stainless-api/ui-primitives';
3
-
4
- export interface Props {
5
- children: astroHTML.JSX.Children;
6
- }
7
3
  ---
8
4
 
9
5
  <Callout variant="warning">
@@ -4,7 +4,7 @@ import { Dropdown } from '@stainless-api/docs/components';
4
4
 
5
5
  import type { NavLink } from './buildNavLinks';
6
6
 
7
- export type Props = {
7
+ type Props = {
8
8
  links: NavLink[];
9
9
  currentItem: NavLink | null;
10
10
  };
@@ -1,10 +1,10 @@
1
1
  ---
2
2
  import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react';
3
3
  const { href, direction } = Astro.props;
4
- export interface Props {
4
+ type Props = {
5
5
  href: string;
6
6
  direction: 'prev' | 'next';
7
- }
7
+ };
8
8
  ---
9
9
 
10
10
  <a href={href} class="pagination-links__link pagination-links__link--emphasized">
@@ -1,8 +1,8 @@
1
1
  ---
2
2
  const { href } = Astro.props;
3
- export interface Props {
3
+ type Props = {
4
4
  href: string;
5
- }
5
+ };
6
6
  ---
7
7
 
8
8
  <a href={href} class="pagination-links__link pagination-links__button pagination-links__link--quiet">
@@ -2,10 +2,10 @@ import type { StarlightRouteData } from '@astrojs/starlight/route-data';
2
2
  import { getCollection } from 'astro:content';
3
3
 
4
4
  export type SidebarEntry = StarlightRouteData['sidebar'][number];
5
- export type SidebarLink = Extract<SidebarEntry, { type: 'link' }>;
6
- export type SidebarGroup = Extract<SidebarEntry, { type: 'group' }>;
5
+ type SidebarLink = Extract<SidebarEntry, { type: 'link' }>;
6
+ type SidebarGroup = Extract<SidebarEntry, { type: 'group' }>;
7
7
 
8
- export const flattenSidebar = (sidebar: SidebarEntry[]): SidebarLink[] =>
8
+ const flattenSidebar = (sidebar: SidebarEntry[]): SidebarLink[] =>
9
9
  sidebar.flatMap((e) => (e.type === 'group' ? flattenSidebar(e.entries) : e));
10
10
 
11
11
  function findParentOfSidebarEntry(sidebar: SidebarEntry[], targetEntry: SidebarEntry): SidebarGroup | null {
@@ -1,7 +1,7 @@
1
1
  import type { AstroIntegration } from 'astro';
2
2
  import type { StarlightPlugin } from '@astrojs/starlight/types';
3
3
 
4
- export const disableCalloutSyntaxAstroIntegration = {
4
+ const disableCalloutSyntaxAstroIntegration = {
5
5
  name: 'stl-starlight-remove-callout-syntax',
6
6
  hooks: {
7
7
  'astro:config:setup': ({ config: astroConfig }) => {