jamdesk 1.1.85 → 1.1.87

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.85",
3
+ "version": "1.1.87",
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,6 +1,6 @@
1
1
  'use client';
2
2
 
3
- import { ReactNode, Children, cloneElement, isValidElement, memo } from 'react';
3
+ import { ReactNode, Children, Fragment, cloneElement, isValidElement, memo } from 'react';
4
4
  import { getIconClass } from '@/lib/icon-utils';
5
5
  import { useStepSlug } from './StepSlugContext';
6
6
 
@@ -25,11 +25,25 @@ interface StepProps {
25
25
  function isStepComponent(child: unknown): boolean {
26
26
  if (!isValidElement(child)) return false;
27
27
  const type = child.type as { displayName?: string; name?: string };
28
- return (
28
+ if (
29
29
  type === Step ||
30
30
  type?.displayName === 'Step' ||
31
31
  type?.name === 'Step'
32
- );
32
+ ) {
33
+ return true;
34
+ }
35
+
36
+ const childProps = child.props as Record<string, unknown> | null;
37
+ if (childProps && Object.prototype.hasOwnProperty.call(childProps, 'title')) {
38
+ return true;
39
+ }
40
+
41
+ if (child.type === Fragment) return false;
42
+
43
+ // In the RSC + MDX path, nested client components can arrive as opaque
44
+ // client references instead of the local `Step` function. Direct custom
45
+ // elements inside <Steps> are Step-compatible; DOM nodes like <p> are not.
46
+ return typeof child.type !== 'string';
33
47
  }
34
48
 
35
49
  export const Steps = memo(function Steps({ children, titleSize = 'p' }: StepsProps) {
@@ -39,7 +53,7 @@ export const Steps = memo(function Steps({ children, titleSize = 'p' }: StepsPro
39
53
 
40
54
  let stepIndex = 0;
41
55
  return (
42
- <div className="relative my-8 space-y-0 not-prose">
56
+ <div className="relative my-8 space-y-0 not-prose" style={{ paddingInlineStart: 16 }}>
43
57
  {childrenArray.map((child) => {
44
58
  if (isStepComponent(child)) {
45
59
  const childProps = (child as any).props as StepProps;
@@ -29,9 +29,16 @@ function getItemOffset(depth: number): number {
29
29
  return 36;
30
30
  }
31
31
 
32
+ const TOC_STEP_INDICATOR_INSET = 30;
33
+ const TOC_STEP_INDICATOR_SIZE = 14;
34
+ const TOC_STEP_LABEL_GAP = 8;
35
+
32
36
  /** Horizontal position of the vertical line based on heading depth */
33
- function getLineOffset(depth: number): number {
34
- return depth >= 3 ? 10 : 0;
37
+ function getLineOffset(item: TocItem): number {
38
+ if (typeof item.stepNumber === 'number') {
39
+ return TOC_STEP_INDICATOR_INSET + TOC_STEP_INDICATOR_SIZE / 2;
40
+ }
41
+ return item.level >= 3 ? 10 : 0;
35
42
  }
36
43
 
37
44
  function getLinkClass(level: number, isActive: boolean): string {
@@ -199,7 +206,7 @@ export function TableOfContents({ content, className = '' }: TableOfContentsProp
199
206
  const heading = headings.find(item => item.id === href.slice(1));
200
207
  if (!heading) continue;
201
208
 
202
- const offset = getLineOffset(heading.level) + 0.5;
209
+ const offset = getLineOffset(heading) + 0.5;
203
210
  const elTop = getOffsetRelativeTo(element, container);
204
211
  items.push({ offset, top: elTop, bottom: elTop + element.clientHeight });
205
212
  }
@@ -567,12 +574,13 @@ export function TableOfContents({ content, className = '' }: TableOfContentsProp
567
574
  }
568
575
  };
569
576
 
570
- // 30px leaves room for the absolute-positioned 14px step circle
571
- // (insetInlineStart: 1) + a gap. Non-step H3s use the same value
572
- // so mixed step/non-step groups align visually.
573
- const startOffset = heading.level === 3
574
- ? 30
575
- : getItemOffset(heading.level);
577
+ // Step entries sit under their parent heading: number aligned with
578
+ // H3 text, label after the 14px circle plus an 8px gap.
579
+ const startOffset = hasStepNumber
580
+ ? TOC_STEP_INDICATOR_INSET + TOC_STEP_INDICATOR_SIZE + TOC_STEP_LABEL_GAP
581
+ : heading.level === 3
582
+ ? 30
583
+ : getItemOffset(heading.level);
576
584
 
577
585
  return (
578
586
  <a
@@ -592,11 +600,11 @@ export function TableOfContents({ content, className = '' }: TableOfContentsProp
592
600
  aria-hidden="true"
593
601
  className="absolute flex items-center justify-center rounded-full text-[9px] font-medium"
594
602
  style={{
595
- insetInlineStart: 3,
603
+ insetInlineStart: TOC_STEP_INDICATOR_INSET,
596
604
  top: '50%',
597
605
  transform: 'translateY(-50%)',
598
- width: 14,
599
- height: 14,
606
+ width: TOC_STEP_INDICATOR_SIZE,
607
+ height: TOC_STEP_INDICATOR_SIZE,
600
608
  backgroundColor: isActive
601
609
  ? 'var(--color-primary)'
602
610
  : 'var(--color-bg-primary)',