jamdesk 1.1.207 → 1.1.208

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jamdesk",
3
- "version": "1.1.207",
3
+ "version": "1.1.208",
4
4
  "description": "CLI for Jamdesk — build, preview, and deploy documentation sites from MDX. Dev server with hot reload, 50+ components, OpenAPI support, AI search, and Mintlify migration",
5
5
  "keywords": [
6
6
  "jamdesk",
@@ -1,4 +1,12 @@
1
- 'use client';
1
+ // Deliberately NOT 'use client'. CodeGroup reads its children as elements, so
2
+ // it must see them BEFORE React Server Components renders them. As a client
3
+ // component it received what MdxPreBlock (a server component) had already
4
+ // turned each fence into: a bare <pre> for an untitled fence, but a whole
5
+ // titled CodePanel for a titled one. Nothing below recognises the latter, so
6
+ // in production every titled fence fell out of the tab strip. Run on the
7
+ // server, it gets the raw MdxPreBlock elements, the same shape its tests
8
+ // build. The browser half lives in CodePanel, which stays a client component.
9
+ // Pinned by the directive test in __tests__/components/CodeGroup.test.tsx.
2
10
 
3
11
  import { ReactNode, ReactElement, Children, Fragment, cloneElement, isValidElement, memo } from 'react';
4
12
  import { CodePanel, CodePanelTab } from '../ui/CodePanel';
@@ -161,8 +169,10 @@ const CODE_FENCE_MARKER = 'jdCodeFenceMarker';
161
169
  * the child is not a fence at all.
162
170
  *
163
171
  * Two layers have to be peeled, and the pre-fix filter (`child.type ===
164
- * 'pre'`) saw through neither, which is why no <CodeGroup> in production
165
- * ever rendered a tab strip:
172
+ * 'pre'`) saw through neither, so no <CodeGroup> rendered a tab strip
173
+ * outside RSC (the editor preview, tests). Under RSC it only ever caught
174
+ * untitled fences, as host <pre> elements; see the note at the top of the
175
+ * file:
166
176
  *
167
177
  * 1. Compiled MDX hands each fence over wrapped in a single-child
168
178
  * Fragment, not as the fence element directly.
@@ -194,6 +204,21 @@ function unwrapCodeFence(child: ReactNode): ReactElement | null {
194
204
  return null;
195
205
  }
196
206
 
207
+ /**
208
+ * Whether MdxPreBlock will render this fence as its own captioned panel.
209
+ * Mirrors MdxPreBlock's `if (!dataTitle)` branch exactly, and only for the
210
+ * marked MdxPreBlock element: a hand-built host <pre> never takes that
211
+ * branch, whatever attributes it carries.
212
+ */
213
+ function isTitledMdxFence(block: ReactElement): boolean {
214
+ const { type } = block;
215
+ return (
216
+ typeof type === 'function' &&
217
+ (type as unknown as Record<string, unknown>)[CODE_FENCE_MARKER] === true &&
218
+ Boolean((block.props as PreProps)['data-title'])
219
+ );
220
+ }
221
+
197
222
  /**
198
223
  * Children that are neither code fences nor the blank text nodes MDX emits
199
224
  * between block children. These are rendered after the panel so a
@@ -237,6 +262,17 @@ export const CodeGroup = memo(function CodeGroup({ children }: CodeGroupProps) {
237
262
  return <div>{children}</div>;
238
263
  }
239
264
 
265
+ // A lone titled fence keeps the caption-only panel production has always
266
+ // shown for it, through the same fallback as above. While CodeGroup was a
267
+ // client component it never recognised a titled fence, so this is the only
268
+ // rendering such a group has ever had; tabbing it would add a one-tab
269
+ // language strip under the caption on every page that wraps a single
270
+ // titled fence in <CodeGroup>. Fence titles become tab labels only where
271
+ // there is more than one fence to switch between.
272
+ if (codeBlocks.length === 1 && isTitledMdxFence(codeBlocks[0])) {
273
+ return <div>{children}</div>;
274
+ }
275
+
240
276
  const extras = allChildren.filter(isRenderableExtra);
241
277
 
242
278
  // Extract title from first code block (only shown for single blocks)