@stainless-api/docs 0.1.0-beta.7 → 0.1.0-beta.70

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 (120) hide show
  1. package/CHANGELOG.md +554 -0
  2. package/README.md +1 -1
  3. package/eslint-suppressions.json +52 -0
  4. package/locals.d.ts +17 -0
  5. package/package.json +51 -40
  6. package/plugin/assets/languages/csharp.svg +1 -0
  7. package/plugin/buildAlgoliaIndex.ts +32 -7
  8. package/plugin/cms/server.ts +130 -58
  9. package/plugin/cms/sidebar-builder.ts +7 -26
  10. package/plugin/cms/worker.ts +83 -5
  11. package/plugin/components/MethodDescription.tsx +54 -0
  12. package/plugin/components/SDKSelect.astro +7 -87
  13. package/plugin/components/SnippetCode.tsx +53 -8
  14. package/plugin/components/search/SearchAlgolia.astro +45 -28
  15. package/plugin/components/search/SearchIsland.tsx +38 -24
  16. package/plugin/create-playground.shim.tsx +3 -0
  17. package/plugin/generateAPIReferenceLink.ts +2 -2
  18. package/plugin/globalJs/ai-dropdown-options.ts +243 -0
  19. package/plugin/globalJs/code-snippets.ts +15 -8
  20. package/plugin/globalJs/copy.ts +81 -16
  21. package/plugin/globalJs/method-descriptions.ts +33 -0
  22. package/plugin/globalJs/navigation.ts +7 -4
  23. package/plugin/helpers/generateDocsRoutes.ts +27 -0
  24. package/plugin/index.ts +178 -35
  25. package/plugin/languages.ts +5 -2
  26. package/plugin/loadPluginConfig.ts +121 -32
  27. package/plugin/middlewareBuilder/stainlessMiddleware.d.ts +1 -1
  28. package/plugin/react/Routing.tsx +208 -129
  29. package/plugin/referencePlaceholderUtils.ts +1 -1
  30. package/plugin/replaceSidebarPlaceholderMiddleware.ts +5 -1
  31. package/plugin/routes/Docs.astro +62 -89
  32. package/plugin/routes/DocsStatic.astro +1 -1
  33. package/plugin/routes/Overview.astro +10 -16
  34. package/plugin/routes/markdown.ts +9 -8
  35. package/plugin/vendor/preview.worker.docs.js +19768 -17702
  36. package/plugin/vendor/templates/go.md +1 -1
  37. package/plugin/vendor/templates/python.md +1 -1
  38. package/resolveSrcFile.ts +10 -0
  39. package/scripts/vendor_deps.ts +5 -5
  40. package/shared/getProsePages.ts +42 -0
  41. package/shared/getSharedLogger.ts +15 -0
  42. package/shared/terminalUtils.ts +3 -0
  43. package/src/content.config.ts +9 -0
  44. package/stl-docs/components/AIDropdown.tsx +63 -0
  45. package/stl-docs/components/AiChatIsland.tsx +14 -0
  46. package/stl-docs/components/{content-panel/ContentBreadcrumbs.tsx → ContentBreadcrumbs.tsx} +10 -18
  47. package/stl-docs/components/Head.astro +16 -0
  48. package/stl-docs/components/Header.astro +6 -8
  49. package/stl-docs/components/PageFrame.astro +18 -0
  50. package/stl-docs/components/PageTitle.astro +82 -0
  51. package/stl-docs/components/TableOfContents.astro +34 -0
  52. package/stl-docs/components/ThemeProvider.astro +36 -0
  53. package/stl-docs/components/ThemeSelect.astro +84 -139
  54. package/stl-docs/components/content-panel/ContentPanel.astro +16 -25
  55. package/stl-docs/components/headers/SplashMobileMenuToggle.astro +17 -1
  56. package/stl-docs/components/headers/StackedHeader.astro +29 -24
  57. package/stl-docs/components/icons/chat-gpt.tsx +17 -0
  58. package/stl-docs/components/icons/claude.tsx +10 -0
  59. package/stl-docs/components/icons/cursor.tsx +10 -0
  60. package/stl-docs/components/icons/gemini.tsx +19 -0
  61. package/stl-docs/components/icons/markdown.tsx +10 -0
  62. package/stl-docs/components/index.ts +1 -0
  63. package/stl-docs/components/mintlify-compat/Accordion.astro +7 -5
  64. package/stl-docs/components/mintlify-compat/AccordionGroup.astro +7 -3
  65. package/stl-docs/components/mintlify-compat/Columns.astro +40 -42
  66. package/stl-docs/components/mintlify-compat/Frame.astro +16 -18
  67. package/stl-docs/components/mintlify-compat/callouts/Callout.astro +1 -1
  68. package/stl-docs/components/mintlify-compat/callouts/Check.astro +1 -1
  69. package/stl-docs/components/mintlify-compat/callouts/Danger.astro +1 -1
  70. package/stl-docs/components/mintlify-compat/callouts/Info.astro +1 -1
  71. package/stl-docs/components/mintlify-compat/callouts/Note.astro +1 -1
  72. package/stl-docs/components/mintlify-compat/callouts/Tip.astro +1 -1
  73. package/stl-docs/components/mintlify-compat/callouts/Warning.astro +1 -1
  74. package/stl-docs/components/mintlify-compat/card.css +33 -35
  75. package/stl-docs/components/mintlify-compat/index.ts +2 -4
  76. package/stl-docs/components/nav-tabs/NavDropdown.astro +31 -70
  77. package/stl-docs/components/nav-tabs/NavTabs.astro +78 -80
  78. package/stl-docs/components/nav-tabs/SecondaryNavTabs.astro +15 -8
  79. package/stl-docs/components/nav-tabs/buildNavLinks.ts +3 -2
  80. package/stl-docs/components/pagination/HomeLink.astro +10 -0
  81. package/stl-docs/components/pagination/Pagination.astro +175 -0
  82. package/stl-docs/components/pagination/PaginationLinkEmphasized.astro +22 -0
  83. package/stl-docs/components/pagination/PaginationLinkQuiet.astro +13 -0
  84. package/stl-docs/components/pagination/util.ts +71 -0
  85. package/stl-docs/components/scripts.ts +1 -0
  86. package/stl-docs/disableCalloutSyntax.ts +36 -0
  87. package/stl-docs/index.ts +141 -50
  88. package/stl-docs/loadStlDocsConfig.ts +45 -5
  89. package/stl-docs/proseMarkdown/proseMarkdownIntegration.ts +61 -0
  90. package/stl-docs/proseMarkdown/proseMarkdownMiddleware.ts +39 -0
  91. package/stl-docs/proseMarkdown/toMarkdown.ts +158 -0
  92. package/stl-docs/proseSearchIndexing.ts +450 -0
  93. package/stl-docs/tabsMiddleware.ts +11 -3
  94. package/styles/code.css +108 -140
  95. package/styles/fonts.css +32 -17
  96. package/styles/links.css +11 -48
  97. package/styles/method-descriptions.css +36 -0
  98. package/styles/overrides.css +48 -60
  99. package/styles/page.css +92 -52
  100. package/styles/sdk_select.css +9 -7
  101. package/styles/search.css +56 -69
  102. package/styles/sidebar.css +211 -131
  103. package/styles/{variables.css → sl-variables.css} +3 -2
  104. package/styles/stldocs-variables.css +6 -0
  105. package/styles/toc.css +41 -34
  106. package/theme.css +10 -10
  107. package/tsconfig.json +2 -5
  108. package/virtual-module.d.ts +26 -4
  109. package/components/variables.css +0 -135
  110. package/stl-docs/components/mintlify-compat/Step.astro +0 -58
  111. package/stl-docs/components/mintlify-compat/Steps.astro +0 -17
  112. /package/{plugin/assets → assets}/fonts/geist/OFL.txt +0 -0
  113. /package/{plugin/assets → assets}/fonts/geist/geist-italic-latin-ext.woff2 +0 -0
  114. /package/{plugin/assets → assets}/fonts/geist/geist-italic-latin.woff2 +0 -0
  115. /package/{plugin/assets → assets}/fonts/geist/geist-latin-ext.woff2 +0 -0
  116. /package/{plugin/assets → assets}/fonts/geist/geist-latin.woff2 +0 -0
  117. /package/{plugin/assets → assets}/fonts/geist/geist-mono-italic-latin-ext.woff2 +0 -0
  118. /package/{plugin/assets → assets}/fonts/geist/geist-mono-italic-latin.woff2 +0 -0
  119. /package/{plugin/assets → assets}/fonts/geist/geist-mono-latin-ext.woff2 +0 -0
  120. /package/{plugin/assets → assets}/fonts/geist/geist-mono-latin.woff2 +0 -0
@@ -1,10 +1,11 @@
1
1
  import Worker from 'web-worker';
2
- import { Languages, type DocsLanguage } from '@stainless-api/docs-ui/src/routing';
3
- import type * as SDKJSON from '~/lib/json-spec-v2/types';
2
+ import { Languages, type DocsLanguage } from '@stainless-api/docs-ui/routing';
3
+ import type * as SDKJSON from '@stainless/sdk-json';
4
4
  import { fileURLToPath } from 'node:url';
5
5
  import { dirname, resolve } from 'node:path';
6
6
  import fs from 'fs/promises';
7
7
  import pathutils from 'path';
8
+ import type { VersionUserConfig } from '../loadPluginConfig';
8
9
 
9
10
  const __filename = fileURLToPath(import.meta.url);
10
11
  const __dirname = dirname(__filename);
@@ -12,7 +13,81 @@ const __dirname = dirname(__filename);
12
13
  const workerPath = resolve(__dirname, '..', 'vendor', 'preview.worker.docs.js');
13
14
 
14
15
  type OpenAPIDocument = Record<string, any>;
15
- type ParsedConfig = Record<string, any>;
16
+ export type ParsedConfig = {
17
+ docs:
18
+ | {
19
+ title?: string | undefined;
20
+ favicon?: string | undefined;
21
+ logo_icon?: string | undefined;
22
+ search?:
23
+ | {
24
+ algolia?:
25
+ | {
26
+ app_id: string;
27
+ index_name: string;
28
+ search_key: string;
29
+ }
30
+ | undefined;
31
+ }
32
+ | undefined;
33
+ description?: string | undefined;
34
+ languages?:
35
+ | ('node' | 'typescript' | 'python' | 'java' | 'kotlin' | 'go' | 'ruby' | 'terraform' | 'http')[]
36
+ | undefined;
37
+ snippets?:
38
+ | {
39
+ exclude_languages?: string[] | undefined;
40
+ }
41
+ | undefined;
42
+ show_security?: boolean | undefined;
43
+ show_readme?: boolean | undefined;
44
+ base_path?: string | undefined;
45
+ navigation?:
46
+ | {
47
+ menubar?:
48
+ | {
49
+ title: string;
50
+ icon?: string;
51
+ variant?: string;
52
+ href?: string | undefined;
53
+ page?: string | undefined;
54
+ }[]
55
+ | undefined;
56
+ sidebar?:
57
+ | {
58
+ title: string;
59
+ icon?: string;
60
+ variant?: string;
61
+ href?: string | undefined;
62
+ page?: string | undefined;
63
+ }[]
64
+ | undefined;
65
+ }
66
+ | undefined;
67
+ pages?: unknown;
68
+ resources?: unknown[] | undefined;
69
+ }
70
+ | undefined;
71
+ targets: Record<string, { skip?: boolean }>;
72
+ client_settings: {
73
+ opts: {
74
+ [x: string]: {
75
+ type: 'string' | 'number' | 'boolean' | 'null' | 'integer';
76
+ nullable: boolean;
77
+ description?: string | undefined;
78
+ example?: unknown;
79
+ default?: unknown;
80
+ read_env?: string | undefined;
81
+ auth?:
82
+ | {
83
+ security_scheme: string;
84
+ role?: 'value' | 'password' | 'username' | 'client_id' | 'client_secret' | undefined;
85
+ }
86
+ | undefined;
87
+ };
88
+ };
89
+ };
90
+ };
16
91
 
17
92
  function runJob({ type, signal, data }: { type: string; signal?: AbortSignal; data: any }) {
18
93
  const stainlessWorker = new Worker(workerPath, {
@@ -22,6 +97,7 @@ function runJob({ type, signal, data }: { type: string; signal?: AbortSignal; da
22
97
 
23
98
  return new Promise<any>((resolve, reject) => {
24
99
  stainlessWorker.addEventListener('error', (e) => {
100
+ e.preventDefault();
25
101
  reject(e);
26
102
  });
27
103
 
@@ -85,10 +161,12 @@ export async function createSDKJSON({
85
161
  oas,
86
162
  config,
87
163
  languages,
164
+ version,
88
165
  }: {
89
166
  oas: OpenAPIDocument;
90
167
  config: ParsedConfig;
91
168
  languages: DocsLanguage[];
169
+ version: VersionUserConfig;
92
170
  }) {
93
171
  const templatePath = resolve(__dirname, '../vendor/templates');
94
172
  const readmeLoader = await Promise.all(
@@ -98,7 +176,7 @@ export async function createSDKJSON({
98
176
  try {
99
177
  const content = await fs.readFile(mdfile);
100
178
  return [language, content.toString()];
101
- } catch (err) {
179
+ } catch {
102
180
  return [language, null];
103
181
  }
104
182
  }),
@@ -113,7 +191,7 @@ export async function createSDKJSON({
113
191
  config,
114
192
  languages,
115
193
  transform: false,
116
- projectName: '',
194
+ projectName: version.stainlessProject,
117
195
  readmeTemplates,
118
196
  },
119
197
  });
@@ -0,0 +1,54 @@
1
+ import { MethodDescriptionProps } from '@stainless-api/docs-ui/components';
2
+ import { useComponents } from '@stainless-api/docs-ui/contexts/use-components';
3
+ import style from '@stainless-api/docs-ui/style';
4
+ import { Button } from '@stainless-api/ui-primitives';
5
+
6
+ function shouldCollapseDescription(description: string) {
7
+ const MIN_CHARS = 400;
8
+ const MIN_LINES = 6;
9
+
10
+ const lineCount = description.split('\n').length;
11
+
12
+ if (description.length >= MIN_CHARS) return true;
13
+ if (lineCount >= MIN_LINES) return true;
14
+
15
+ // Markdown structure often means longer content
16
+ if (/#\s/.test(description)) return true; // has headings
17
+ if (/```/.test(description)) return true; // has code blocks
18
+ if (/^\s*[-*]\s+/m.test(description)) return true; // has lists
19
+
20
+ return false;
21
+ }
22
+
23
+ export function MethodDescription({ description }: MethodDescriptionProps) {
24
+ const { Markdown } = useComponents();
25
+
26
+ if (description) {
27
+ // Attempt to determine if we should make the description collapsible initially
28
+ // or not. If we get this right, there will be no FOUC.
29
+ const collapsible = shouldCollapseDescription(description);
30
+
31
+ return (
32
+ <div className="stl-method-description">
33
+ <div
34
+ className={style.MethodDescription}
35
+ data-stldocs-property-group="method-description"
36
+ data-collapsed={collapsible ? 'true' : 'false'}
37
+ >
38
+ <Markdown content={description} />
39
+ </div>
40
+ <div className="stl-method-description-overflow-wrapper">
41
+ <Button
42
+ type="button"
43
+ data-method-description-toggle
44
+ size="sm"
45
+ variant="ghost"
46
+ hidden={!collapsible}
47
+ >
48
+ Show more
49
+ </Button>
50
+ </div>
51
+ </div>
52
+ );
53
+ }
54
+ }
@@ -1,6 +1,6 @@
1
1
  ---
2
- import type { DocsLanguage } from '@stainless-api/docs-ui/src/routing';
3
- import { parseRoute } from '@stainless-api/docs-ui/src/routing';
2
+ import type { DocsLanguage } from '@stainless-api/docs-ui/routing';
3
+ import { parseRoute } from '@stainless-api/docs-ui/routing';
4
4
  import { cmsClient } from '../cms/client';
5
5
  import { BASE_PATH, DEFAULT_LANGUAGE, EXCLUDE_LANGUAGES } from 'virtual:stl-starlight-virtual-module';
6
6
  import { Languages } from '../languages';
@@ -53,100 +53,20 @@ const readmeSlug = language === 'http' ? BASE_PATH : `${BASE_PATH}/${language}`;
53
53
  )
54
54
  }
55
55
 
56
- <style>
57
- @layer starlight.core {
58
- label {
59
- --sl-label-icon-size: 16px;
60
- --sl-caret-size: 1.25rem;
61
- --sl-inline-padding: 0.5rem;
62
- position: relative;
63
- display: flex;
64
- align-items: center;
65
- gap: 0.25rem;
66
- color: var(--sl-color-gray-1);
67
- }
68
-
69
- label:hover {
70
- color: var(--sl-color-gray-2);
71
- }
72
-
73
- .icon {
74
- position: absolute;
75
- top: 50%;
76
- transform: translateY(-50%);
77
- pointer-events: none;
78
- width: 16px;
79
- }
80
-
81
- select {
82
- padding-block: 0.3rem;
83
- padding-inline: calc(var(--sl-label-icon-size) + var(--sl-inline-padding) + 0.5rem)
84
- calc(var(--sl-caret-size) + var(--sl-inline-padding) + 0.25rem);
85
- margin-inline: calc(var(--sl-inline-padding) * -1);
86
- width: calc(var(--sl-select-width) + var(--sl-inline-padding) * 2);
87
- text-overflow: ellipsis;
88
- color: inherit;
89
- cursor: pointer;
90
- appearance: none;
91
- font-weight: 600;
92
- text-transform: capitalize;
93
- }
94
-
95
- select:active {
96
- font-weight: inherit;
97
- /* font-family: sans-serif;
98
- font-weight: 400; */
99
- }
100
-
101
- option {
102
- background-color: var(--sl-color-bg-nav);
103
- color: var(--sl-color-gray-1);
104
- }
105
-
106
- @media (min-width: 50rem) {
107
- select {
108
- font-size: var(--sl-text-sm);
109
- }
110
- }
111
- }
112
-
113
- @layer starlight.components {
114
- .label-icon {
115
- font-size: var(--sl-label-icon-size);
116
- inset-inline-start: 0;
117
- }
118
-
119
- .caret {
120
- font-size: var(--sl-caret-size);
121
- inset-inline-end: 0;
122
- }
123
- }
124
-
125
- .custom-select-wrapper {
126
- --sl-inline-padding: 0.5rem;
127
- position: relative;
128
- display: inline-block;
129
- /* These match the padding on the sidebar menu */
130
- padding-left: var(--sl-inline-padding);
131
- padding-right: var(--sl-inline-padding);
132
-
133
- .icon.http path {
134
- fill: var(--sl-color-text);
135
- }
136
- }
137
- </style>
138
56
  <script>
139
57
  import { navigate } from 'astro:transitions/client';
140
58
  import { updateSelectedLanguage } from '../languages';
141
- import { initDropdown } from '@stainless-api/docs-ui/src/components/scripts/dropdown';
59
+ import { initDropdown } from '@stainless-api/docs/components/scripts';
142
60
  import { BASE_PATH } from 'virtual:stl-starlight-virtual-module';
143
61
  import { getPageLoadEvent } from '../helpers/getPageLoadEvent';
144
62
 
145
63
  document.addEventListener(getPageLoadEvent(), () => {
64
+ const sdkSelect = document.getElementById('sidebar-sdk-select');
65
+ if (!sdkSelect) return;
146
66
  initDropdown({
147
- dropdownId: 'sidebar-sdk-select',
67
+ root: sdkSelect,
148
68
  onSelect: (value) => {
149
- const originalLanguage = document.getElementById('sidebar-sdk-select')?.dataset.currentValue;
69
+ const originalLanguage = sdkSelect.dataset.currentValue;
150
70
  navigate(updateSelectedLanguage(BASE_PATH, originalLanguage, value));
151
71
  },
152
72
  });
@@ -2,12 +2,38 @@ import type {
2
2
  SnippetCodeProps,
3
3
  SnippetContainerProps,
4
4
  SnippetRequestContainerProps,
5
- } from '@stainless-api/docs-ui/src/components';
6
- import { useHighlight, useLanguage } from '@stainless-api/docs-ui/src/contexts';
7
- import style from '@stainless-api/docs-ui/src/style';
5
+ } from '@stainless-api/docs-ui/components';
6
+ import { useHighlight, useLanguage } from '@stainless-api/docs-ui/contexts';
7
+ import style from '@stainless-api/docs-ui/style';
8
8
  import * as cheerio from 'cheerio/slim';
9
- import { EXPERIMENTAL_COLLAPSIBLE_SNIPPETS } from 'virtual:stl-starlight-virtual-module';
9
+ import {
10
+ EXPERIMENTAL_COLLAPSIBLE_SNIPPETS,
11
+ EXPERIMENTAL_PLAYGROUNDS,
12
+ } from 'virtual:stl-starlight-virtual-module';
10
13
  import clsx from 'clsx';
14
+ import { Button } from '@stainless-api/ui-primitives';
15
+ import { CopyIcon } from 'lucide-react';
16
+
17
+ function PlaygroundIcon() {
18
+ return (
19
+ <svg
20
+ xmlns="http://www.w3.org/2000/svg"
21
+ width={16}
22
+ height={16}
23
+ viewBox="0 0 24 24"
24
+ fill="none"
25
+ stroke="currentColor"
26
+ strokeWidth={2}
27
+ strokeLinecap="round"
28
+ strokeLinejoin="round"
29
+ className={'lucide ' + style.Icon}
30
+ aria-hidden="true"
31
+ >
32
+ <path d="m 1,2 h 1 a 4,4 0 0 1 4,4 v 1 m 5,15 H 10 A 4,4 0 0 1 6,18 V 6 a 4,4 0 0 1 4,-4 h 1 M 1,22 H 2 A 4,4 0 0 0 6,18 V 17 M 14.029059,8.147837 A 1.2853426,1.2853426 0 0 1 15.978924,7.0437277 L 22.40178,10.8959 a 1.2853426,1.2853426 0 0 1 0,2.208219 l -6.422856,3.852172 a 1.2853426,1.2853426 0 0 1 -1.949865,-1.105395 z" />
33
+ </svg>
34
+ );
35
+ }
36
+
11
37
  /*
12
38
  * This may be replaced by additional data from the sdk.
13
39
  * Without information from the sdk, we use simple heuristics per language.
@@ -53,7 +79,7 @@ function wrapFirstNSpaces($line: cheerio.Cheerio<any>, n: number) {
53
79
  const m = inner.match(new RegExp(`^( {1,${n}})`));
54
80
  if (!m) return;
55
81
 
56
- const lead = m[1];
82
+ const lead = m[1]!;
57
83
  $firstSpan.html(`<span class="leading-ws">${lead}</span>${inner.slice(lead.length)}`);
58
84
  }
59
85
 
@@ -130,12 +156,14 @@ export function SnippetRequestContainer({ children, signature }: SnippetRequestC
130
156
  <div className="stl-snippet-request-container">
131
157
  {children}
132
158
  {signature && isCollapsible && (
133
- <button
134
- className={clsx(style.Button, style.ButtonSecondary, 'stl-snippet-expand-button')}
159
+ <Button
160
+ className={'stl-snippet-expand-button'}
135
161
  id="stl-snippet-expand-button"
162
+ size="sm"
163
+ variant="outline"
136
164
  >
137
165
  Show more
138
- </button>
166
+ </Button>
139
167
  )}
140
168
  </div>
141
169
  );
@@ -181,6 +209,23 @@ export function CondensibleSnippetCode({
181
209
  );
182
210
  }
183
211
 
212
+ export function SnippetButtons({ content }: { content: string }) {
213
+ void content;
214
+ const language = useLanguage();
215
+ return (
216
+ <>
217
+ <Button variant="outline" data-stldocs-snippet-copy>
218
+ <CopyIcon size={16} className={style.Icon} />
219
+ </Button>
220
+ {EXPERIMENTAL_PLAYGROUNDS &&
221
+ (language === 'python' || language === 'typescript' || language === 'http') && (
222
+ <Button data-stldocs-snippet-play variant="muted" border title="Play">
223
+ <PlaygroundIcon />
224
+ </Button>
225
+ )}
226
+ </>
227
+ );
228
+ }
184
229
  export function SnippetCode({ content, signature, language: forcedLanguage }: SnippetCodeProps) {
185
230
  const lang = useLanguage();
186
231
  const language = forcedLanguage || lang;
@@ -1,23 +1,25 @@
1
1
  ---
2
- import { Icon } from '@astrojs/starlight/components';
3
2
  import { DocsSearch } from './SearchIsland';
4
- import { SEARCH } from 'virtual:stl-starlight-virtual-module';
3
+ import { Button } from '@stainless-api/ui-primitives';
4
+ import { SearchIcon, XIcon } from 'lucide-react';
5
5
  ---
6
6
 
7
7
  <site-search>
8
- <button
9
- popovertarget="stldocs-search"
8
+ <Button
9
+ popoverTarget="stldocs-search"
10
10
  data-open-modal
11
11
  aria-label={Astro.locals.t('search.label')}
12
12
  aria-keyshortcuts="Control+K"
13
- class="stldocs-button stldocs-button-secondary"
13
+ variant="outline"
14
+ className="stl-algolia-search"
14
15
  >
15
- <Icon name="magnifier" />
16
+ <SearchIcon className="icon-search" size={14} />
17
+ <XIcon className="icon-close" size={14} />
16
18
  <span class="sl-hidden md:sl-block" aria-hidden="true">{Astro.locals.t('search.label')}</span>
17
19
  <kbd class="sl-hidden md:sl-flex" style="display: none;">
18
20
  <kbd>{Astro.locals.t('search.ctrlKey')}</kbd><kbd>K</kbd>
19
21
  </kbd>
20
- </button>
22
+ </Button>
21
23
 
22
24
  <DocsSearch
23
25
  client:only="react"
@@ -31,27 +33,6 @@ import { SEARCH } from 'virtual:stl-starlight-virtual-module';
31
33
  />
32
34
  </site-search>
33
35
 
34
- {
35
- SEARCH?.enableAISearch === true && (
36
- <button id="chat-button" popovertarget="stldocs-chat" data-open-modal>
37
- <Icon name="comment" />
38
- </button>
39
- )
40
- }
41
-
42
- <style>
43
- #chat-button {
44
- background: var(--sl-color-bg-ui);
45
- border: 1px solid var(--sl-color-hairline);
46
- height: 2.25rem;
47
- width: 2.25rem;
48
-
49
- &:hover {
50
- border: 1px solid rgb(64, 64, 64);
51
- }
52
- }
53
- </style>
54
-
55
36
  <script is:inline>
56
37
  function setupShortcut() {
57
38
  const openBtn = document.querySelector('button[data-open-modal]');
@@ -78,3 +59,39 @@ import { SEARCH } from 'virtual:stl-starlight-virtual-module';
78
59
  }
79
60
  });
80
61
  </script>
62
+
63
+ <style is:inline>
64
+ .default-tabs-container .stl-algolia-search {
65
+ max-width: unset;
66
+ width: unset;
67
+ flex-grow: 1;
68
+ }
69
+ .stl-algolia-search {
70
+ padding: 0;
71
+ }
72
+ @media (min-width: 50rem) {
73
+ .stl-algolia-search {
74
+ padding: 8px 10px;
75
+ }
76
+ }
77
+
78
+ .stl-algolia-search {
79
+ .icon-search {
80
+ display: inline;
81
+ }
82
+
83
+ .icon-close {
84
+ display: none;
85
+ }
86
+ }
87
+
88
+ site-search:has(#stldocs-search[data-stldocs-modal-open='true']) .stl-algolia-search {
89
+ .icon-search {
90
+ display: none;
91
+ }
92
+
93
+ .icon-close {
94
+ display: inline;
95
+ }
96
+ }
97
+ </style>
@@ -1,19 +1,20 @@
1
1
  import * as React from 'react';
2
- import { BASE_PATH, SEARCH } from 'virtual:stl-starlight-virtual-module';
3
- import { parseRoute, generateRoute } from '@stainless-api/docs-ui/src/routing';
4
- import { SearchModal } from '@stainless-api/docs-ui/src/search/index';
5
- import { ChatModal } from '@stainless-api/docs-ui/src/components/chat';
2
+ import { BASE_PATH, HIGHLIGHT_THEMES } from 'virtual:stl-starlight-virtual-module';
3
+ import { parseRoute, generateRoute } from '@stainless-api/docs-ui/routing';
4
+ import { SearchModal } from '@stainless-api/docs-search';
6
5
  import * as Markdoc from '@markdoc/markdoc';
7
6
  import { createHighlighter } from 'shiki';
8
7
  import type { BundledLanguage, BundledTheme, HighlighterGeneric } from 'shiki';
9
8
 
10
9
  import {
11
10
  DocsProvider,
11
+ type MarkdownContext,
12
12
  MarkdownProvider,
13
13
  NavigationProvider,
14
- SearchProvider,
15
- } from '@stainless-api/docs-ui/src/contexts';
16
- import type { SearchSettings } from '@stainless-api/docs-ui/src/search/types';
14
+ } from '@stainless-api/docs-ui/contexts';
15
+ import { ComponentProvider } from '@stainless-api/docs-ui/contexts/component';
16
+ import { SearchProvider } from '@stainless-api/docs-search/context';
17
+ import type { SearchSettings } from '@stainless-api/docs-search/types';
17
18
 
18
19
  let $$highlighter: HighlighterGeneric<BundledLanguage, BundledTheme> | null = null;
19
20
  async function getHighlighter() {
@@ -27,7 +28,7 @@ async function getHighlighter() {
27
28
  return $$highlighter;
28
29
  }
29
30
 
30
- async function createMarkdownRenderer() {
31
+ async function createMarkdownRenderer(): Promise<MarkdownContext> {
31
32
  const highlighter = await getHighlighter();
32
33
  const markdocConfig: Markdoc.Config = {
33
34
  nodes: {
@@ -37,7 +38,10 @@ async function createMarkdownRenderer() {
37
38
  transform(node, config) {
38
39
  const attributes = node.transformAttributes(config);
39
40
  const lang = node.attributes.language === 'node' ? 'typescript' : node.attributes.language;
40
- const code = highlighter.codeToTokens(node.attributes.content, { lang, theme: 'github-dark' });
41
+ const code = highlighter.codeToTokens(node.attributes.content, {
42
+ lang,
43
+ theme: 'github-dark',
44
+ });
41
45
 
42
46
  return new Markdoc.Tag(
43
47
  'pre',
@@ -66,16 +70,25 @@ async function createMarkdownRenderer() {
66
70
  },
67
71
  };
68
72
 
69
- return (content: string) => {
70
- const ast = Markdoc.parse(content);
71
- const transformed = Markdoc.transform(ast, markdocConfig);
72
- return Markdoc.renderers.html(transformed);
73
+ return {
74
+ render: (content: string) => {
75
+ const ast = Markdoc.parse(content);
76
+ const transformed = Markdoc.transform(ast, markdocConfig);
77
+ return Markdoc.renderers.html(transformed);
78
+ },
79
+ highlight: (content: string, language: string) => {
80
+ return highlighter.codeToHtml(content, {
81
+ lang: language ?? 'javascript',
82
+ themes: HIGHLIGHT_THEMES || {},
83
+ });
84
+ },
73
85
  };
74
86
  }
75
87
 
76
88
  export function DocsSearch({ settings, currentPath }: { settings: SearchSettings; currentPath: string }) {
77
- const renderMarkdown = React.use(createMarkdownRenderer());
89
+ const markdownRenderer = React.use(createMarkdownRenderer());
78
90
  const { stainlessPath, language } = parseRoute(BASE_PATH, currentPath);
91
+ // eslint-disable-next-line turbo/no-undeclared-env-vars
79
92
  const pageFind = import.meta.env.DEV ? undefined : '/pagefind/pagefind.js';
80
93
 
81
94
  function handleSelect(path: string) {
@@ -85,16 +98,17 @@ export function DocsSearch({ settings, currentPath }: { settings: SearchSettings
85
98
 
86
99
  return (
87
100
  <DocsProvider spec={null} language={language}>
88
- <NavigationProvider basePath="/" selectedPath={stainlessPath}>
89
- <MarkdownProvider render={renderMarkdown}>
90
- <SearchProvider onSelect={handleSelect} pageFind={pageFind} settings={settings}>
91
- <div className="stldocs-root">
92
- <SearchModal id="stldocs-search" />
93
- {SEARCH?.enableAISearch === true && <ChatModal id="stldocs-chat" />}
94
- </div>
95
- </SearchProvider>
96
- </MarkdownProvider>
97
- </NavigationProvider>
101
+ <ComponentProvider>
102
+ <NavigationProvider basePath="/" selectedPath={stainlessPath}>
103
+ <MarkdownProvider {...markdownRenderer}>
104
+ <SearchProvider onSelect={handleSelect} pageFind={pageFind} settings={settings}>
105
+ <div className="stldocs-root">
106
+ <SearchModal id="stldocs-search" />
107
+ </div>
108
+ </SearchProvider>
109
+ </MarkdownProvider>
110
+ </NavigationProvider>
111
+ </ComponentProvider>
98
112
  </DocsProvider>
99
113
  );
100
114
  }
@@ -0,0 +1,3 @@
1
+ export function createPlayground(): () => Promise<void> {
2
+ return () => Promise.resolve();
3
+ }
@@ -1,8 +1,8 @@
1
1
  // This is probably temporary, but it fills in functionality needed for Mintlify imports
2
2
 
3
3
  import type { StarlightRouteData } from '@astrojs/starlight/route-data';
4
- import type * as SDKJSON from '~/lib/json-spec-v2/types';
5
- import { walkTree } from '@stainless-api/docs-ui/src/routing';
4
+ import type * as SDKJSON from '@stainless/sdk-json';
5
+ import { walkTree } from '@stainless-api/docs-ui/routing';
6
6
 
7
7
  const INTERNAL_REFERENCE_ENTRY_MARKER = 'STL_STARLIGHT_API_REFERENCE_METHOD_LINK_PLACEHOLDER';
8
8