@primer/doctocat-nextjs 0.0.0-20250619155353 → 0.0.0-20250620092520

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/CHANGELOG.md CHANGED
@@ -1,16 +1,18 @@
1
1
  # @primer/doctocat-nextjs
2
2
 
3
- ## 0.0.0-20250619155353
3
+ ## 0.0.0-20250620092520
4
4
 
5
5
  ### Patch Changes
6
6
 
7
7
  - Fake entry to force publishing
8
8
 
9
- ## 0.0.0-20250619155352
9
+ ## 0.0.0-20250620092519
10
10
 
11
11
  ### Patch Changes
12
12
 
13
- - [#43](https://github.com/primer/doctocat-nextjs/pull/43) [`1b15bdf`](https://github.com/primer/doctocat-nextjs/commit/1b15bdfcf4b54996f38d20f1da711def23c636bd) Thanks [@rezrah](https://github.com/rezrah)! - Fix lack of `basePath` support on index cards. `href` now prepends the `basePath`.
13
+ - [#43](https://github.com/primer/doctocat-nextjs/pull/43) [`c5542e9`](https://github.com/primer/doctocat-nextjs/commit/c5542e915dc0fbe6e054e8fde96f7136498b9cc7) Thanks [@rezrah](https://github.com/rezrah)! - Fix lack of `basePath` support on index cards. `href` now prepends the `basePath`.
14
+
15
+ - [`fea58bc`](https://github.com/primer/doctocat-nextjs/commit/fea58bc04c1cfb4897ef8f5921dbc9afd5b18dc8) Thanks [@rezrah](https://github.com/rezrah)! - Prepend basePath to paths in Doctocat UI, where it would previously not resolve correctly.
14
16
 
15
17
  ## 0.5.2
16
18
 
@@ -10,6 +10,7 @@ export type ConfigContextLink = {
10
10
  export type ConfigContextValue = {
11
11
  headerLinks: ConfigContextLink[]
12
12
  sidebarLinks: ConfigContextLink[]
13
+ basePath: string
13
14
  }
14
15
 
15
16
  export const ConfigContext = createContext<ConfigContextValue | null>(null)
@@ -1,38 +1,42 @@
1
1
  .Article {
2
2
  display: grid;
3
- grid-template-areas: 'main';
4
- grid-template-columns: 1fr;
5
3
  }
6
4
 
7
5
  .Article--withToc {
8
6
  gap: var(--base-size-48);
9
- grid-template-areas: 'main aside';
10
- grid-template-columns: 1fr 200px;
11
7
  }
12
8
 
13
9
  .main {
14
- grid-area: main;
15
- max-width: 100%;
16
- overflow-x: hidden;
10
+ order: 1;
17
11
  }
18
12
 
19
13
  .aside {
20
- grid-area: aside;
21
- position: relative;
14
+ order: 0;
22
15
  }
23
16
 
24
- @media screen and (max-width: 1023px) {
17
+ @media screen and (max-width: 48rem) {
25
18
  .Article--withToc {
26
- grid-template-areas:
27
- 'aside'
28
- 'main';
29
- grid-template-columns: 1fr;
19
+ display: flex; /* Prevents column overflow */
20
+ flex-direction: column;
21
+ }
22
+ }
23
+
24
+ @media screen and (min-width: 1023px) {
25
+ .main {
26
+ order: 0;
27
+ }
28
+
29
+ .aside {
30
+ order: 1;
31
+ }
32
+
33
+ .Article--withToc {
34
+ grid-template-columns: 1fr 200px;
30
35
  }
31
36
  }
32
37
 
33
38
  @media screen and (min-width: 2048px) {
34
39
  .Article--withToc {
35
- grid-template-areas: 'main';
36
40
  grid-template-columns: 1fr;
37
41
  }
38
42
  }
@@ -3,12 +3,14 @@ import React, {PropsWithChildren, useCallback, useState} from 'react'
3
3
  import clsx from 'clsx'
4
4
  import {LiveProvider, LiveEditor, LiveError, LivePreview} from 'react-live'
5
5
  import {useColorMode} from '../../context/color-modes/useColorMode'
6
+ import {useConfig} from '../../context/useConfig'
6
7
  import styles from './ReactCodeBlock.module.css'
7
8
  import {ActionBar, Button, ThemeProvider} from '@primer/react'
8
9
  import {CopyIcon, MoonIcon, SunIcon, UndoIcon} from '@primer/octicons-react'
9
10
  import {colorModes} from '../../context/color-modes/context'
10
11
 
11
12
  import {lightTheme, darkTheme} from './syntax-highlighting-themes'
13
+ import {codeTransformer} from './code-transformer'
12
14
 
13
15
  type ReactCodeBlockProps = {
14
16
  'data-language': string
@@ -18,10 +20,19 @@ type ReactCodeBlockProps = {
18
20
 
19
21
  export function ReactCodeBlock(props: ReactCodeBlockProps) {
20
22
  const {colorMode, setColorMode} = useColorMode()
23
+ const {basePath} = useConfig()
21
24
  const initialCode = getCodeFromChildren(props.children)
22
25
  const [code, setCode] = useState(initialCode)
23
26
  const shouldShowPreview = ['tsx', 'jsx'].includes(props['data-language'])
24
27
 
28
+ /**
29
+ * Transforms code to prepend basePath to img src attributes
30
+ */
31
+ const transformCodeWithBasePath = useCallback(
32
+ (sourceCode: string) => codeTransformer(sourceCode, basePath),
33
+ [basePath],
34
+ )
35
+
25
36
  const handleReset = useCallback(() => {
26
37
  setCode(initialCode)
27
38
  }, [initialCode, setCode])
@@ -34,7 +45,7 @@ export function ReactCodeBlock(props: ReactCodeBlockProps) {
34
45
 
35
46
  return (
36
47
  <>
37
- <LiveProvider code={code} scope={props.jsxScope} noInline={noInline}>
48
+ <LiveProvider transformCode={transformCodeWithBasePath} code={code} scope={props.jsxScope} noInline={noInline}>
38
49
  <div className={clsx(styles.CodeBlock, 'custom-component')}>
39
50
  {shouldShowPreview && (
40
51
  <div>
@@ -0,0 +1,20 @@
1
+ export const codeTransformer = (sourceCode: string, basePath: string): string => {
2
+ if (!basePath) return sourceCode
3
+
4
+ // to skip external URLs and other irrelevant paths
5
+ const shouldTransform = (src: string) => !src.startsWith('http') && !src.startsWith('//') && !src.startsWith(basePath)
6
+
7
+ // normalise for absolute (/path) and relative (path) values
8
+ const transformSrc = (src: string) => (src.startsWith('/') ? `${basePath}${src}` : `${basePath}/${src}`)
9
+
10
+ const transformElement =
11
+ (imgTag: string) =>
12
+ (match: string, before = '', src: string, after: string) => {
13
+ if (!shouldTransform(src)) return match
14
+ return `<${imgTag} ${before}src="${transformSrc(src)}"${after}`
15
+ }
16
+
17
+ return sourceCode
18
+ .replace(/<img\s+([^>]*\s+)?src=["']([^"']+)["']([^>]*>)/g, transformElement('img'))
19
+ .replace(/<Image\s+([^>]*\s+)?src=["']([^"']+)["']([^>]*)/g, transformElement('Image'))
20
+ }
@@ -92,7 +92,7 @@ export function IndexCards({route, folderData}: IndexCardsProps) {
92
92
  return (
93
93
  <Grid.Column span={{xsmall: 12, small: 12, medium: 12, large: 6, xlarge: 4}} key={item.frontMatter.title}>
94
94
  <Link legacyBehavior passHref href={item.route}>
95
- <Card href="#" hasBorder fullWidth>
95
+ <Card href="#" hasBorder>
96
96
  <Card.Image src={thumbnailUrl} alt="" aspectRatio="4:3" />
97
97
  <Card.Heading>{item.frontMatter.title}</Card.Heading>
98
98
  {item.frontMatter.description && <Card.Description>{item.frontMatter.description}</Card.Description>}
@@ -25,6 +25,7 @@ export default function Shell({children, headerLinks = [], sidebarLinks = [], ..
25
25
  value={{
26
26
  headerLinks,
27
27
  sidebarLinks,
28
+ basePath: process.env.NEXT_PUBLIC_DOCTOCAT_BASE_PATH || '',
28
29
  }}
29
30
  >
30
31
  <Theme {...rest}>{children}</Theme>
@@ -26,6 +26,7 @@
26
26
  display: flex;
27
27
  flex-direction: column;
28
28
  min-width: 280px;
29
+ right: 0;
29
30
  overflow: auto;
30
31
  padding: var(--base-size-40) var(--base-size-40) var(--base-size-40) 0;
31
32
  top: 65px;
package/css/global.css CHANGED
@@ -18,8 +18,7 @@ body {
18
18
  margin-block-start: 0 !important;
19
19
  }
20
20
 
21
- /* Pre styles are scoped to Nextra code blocks to prevent unintended styling of other code blocks (e.g., ReactCodeBlock previews). */
22
- .nextra-code pre {
21
+ pre {
23
22
  background-color: var(--brand-color-canvas-subtle);
24
23
  border-radius: var(--brand-borderRadius-large);
25
24
  padding-top: 1rem;
@@ -10,7 +10,7 @@ const withNextra = nextra({
10
10
  * Relies on `transpilePackages: ['@primer/doctocat-nextjs'],` being set in the next.config
11
11
  */
12
12
  function withDoctocat(config = {}) {
13
- return {
13
+ const finalConfig = {
14
14
  ...withNextra(),
15
15
  images: {
16
16
  unoptimized: true,
@@ -18,6 +18,13 @@ function withDoctocat(config = {}) {
18
18
 
19
19
  ...config,
20
20
  }
21
+
22
+ // Enables basePath in next.config.js to be used inside Doctocat
23
+ if (finalConfig.basePath) {
24
+ process.env.NEXT_PUBLIC_DOCTOCAT_BASE_PATH = finalConfig.basePath
25
+ }
26
+
27
+ return finalConfig
21
28
  }
22
29
 
23
30
  export default withDoctocat
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@primer/doctocat-nextjs",
3
- "version": "0.0.0-20250619155353",
3
+ "version": "0.0.0-20250620092520",
4
4
  "description": "A Next.js theme for building Primer documentation sites",
5
5
  "main": "index.js",
6
6
  "type": "module",