Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 23 additions & 2 deletions src/components/CopyPageDropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
DropdownContent,
DropdownItem,
} from './Dropdown'
import {
getPackageManager,
PACKAGE_MANAGERS,

Check warning on line 15 in src/components/CopyPageDropdown.tsx

View workflow job for this annotation

GitHub Actions / PR

'PACKAGE_MANAGERS' is defined but never used. Allowed unused vars must match /(^_)|(^__+$)|(^e$)|(^error$)/u
} from '~/utils/markdown/installCommand'

// Markdown icon component matching the screenshot
function MarkdownIcon({ className }: { className?: string }) {
Expand Down Expand Up @@ -92,23 +96,40 @@
branch?: string
/** File path in the repo (e.g., 'src/blog/my-post.md'). Required if repo is provided. */
filePath?: string
/** Current framework for filtering markdown content (appended as ?framework= query param) */
currentFramework?: string
}

export function CopyPageDropdown({
repo,
branch,
filePath,
currentFramework,
}: CopyPageDropdownProps = {}) {
const [open, setOpen] = React.useState(false)
const [copied, setCopied] = React.useState(false)
const { notify } = useToast()

// Determine if we should fetch from GitHub or use the page URL
const useGitHub = repo && branch && filePath
const useGitHub = repo === 'tanstack/tanstack.com'
const gitHubUrl = useGitHub
? `https://raw.githubusercontent.com/${repo}/${branch}/${filePath}`
: null
const pageMarkdownUrl = `${typeof window !== 'undefined' ? window.location.origin : ''}${typeof window !== 'undefined' ? window.location.pathname.replace(/\/$/, '') : ''}.md`
const pageMarkdownUrl = (() => {
const base = `${typeof window !== 'undefined' ? window.location.origin : ''}${typeof window !== 'undefined' ? window.location.pathname.replace(/\/$/, '') : ''}.md`
const params = new URLSearchParams()
if (currentFramework) {
params.set('framework', currentFramework)
}
// Read package manager from localStorage (same key as PackageManagerTabs)
if (typeof localStorage !== 'undefined') {
const pm = localStorage.getItem('packageManager')
const validPm = getPackageManager(pm)
params.set('pm', validPm)
}
const queryString = params.toString()
return queryString ? `${base}?${queryString}` : base
})()

const handleCopyPage = async () => {
const urlToFetch = gitHubUrl || pageMarkdownUrl
Expand Down
1 change: 1 addition & 0 deletions src/components/Doc.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ export function Doc({
libraryId={libraryId}
libraryVersion={libraryVersion}
pagePath={pagePath}
currentFramework={currentFramework}
titleBarActions={
setIsFullWidth ? (
<button
Expand Down
10 changes: 9 additions & 1 deletion src/components/markdown/MarkdownContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ type MarkdownContentProps = {
libraryId?: string
libraryVersion?: string
pagePath?: string
/** Current framework for filtering markdown content */
currentFramework?: string
}

export function MarkdownContent({
Expand All @@ -41,6 +43,7 @@ export function MarkdownContent({
libraryId,
libraryVersion,
pagePath,
currentFramework,
}: MarkdownContentProps) {
const renderMarkdownContent = () => {
const markdownElement = htmlMarkup ? (
Expand Down Expand Up @@ -70,7 +73,12 @@ export function MarkdownContent({
<div className="flex flex-wrap items-center justify-between gap-2">
<DocTitle>{title}</DocTitle>
<div className="flex items-center gap-2 shrink-0">
<CopyPageDropdown repo={repo} branch={branch} filePath={filePath} />
<CopyPageDropdown
repo={repo}
branch={branch}
filePath={filePath}
currentFramework={currentFramework}
/>
{titleBarActions}
</div>
</div>
Expand Down
127 changes: 6 additions & 121 deletions src/components/markdown/PackageManagerTabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,12 @@ import { create } from 'zustand'
import { Tabs, type TabDefinition } from './Tabs'
import { CodeBlock } from './CodeBlock'
import type { Framework } from '~/libraries/types'

type PackageManager = 'bun' | 'npm' | 'pnpm' | 'yarn'
type InstallMode =
| 'install'
| 'dev-install'
| 'local-install'
| 'create'
| 'custom'
import {
getInstallCommand,
PACKAGE_MANAGERS,
type PackageManager,
type InstallMode,
} from '~/utils/markdown/installCommand'

// Use zustand for cross-component synchronization
// This ensures all PackageManagerTabs instances on the page stay in sync
Expand All @@ -36,119 +34,6 @@ type PackageManagerTabsProps = {
frameworks: Framework[]
}

const PACKAGE_MANAGERS: PackageManager[] = ['npm', 'pnpm', 'yarn', 'bun']

function getInstallCommand(
packageManager: PackageManager,
packageGroups: string[][],
mode: InstallMode,
): string[] {
const commands: string[] = []

if (mode === 'custom') {
for (const packages of packageGroups) {
const pkgStr = packages.join(' ')
switch (packageManager) {
case 'npm':
commands.push(`npm ${pkgStr}`)
break
case 'pnpm':
commands.push(`pnpm ${pkgStr}`)
break
case 'yarn':
commands.push(`yarn ${pkgStr}`)
break
case 'bun':
commands.push(`bun ${pkgStr}`)
break
}
}
}

if (mode === 'create') {
for (const packages of packageGroups) {
const pkgStr = packages.join(' ')
switch (packageManager) {
case 'npm':
commands.push(`npm create ${pkgStr}`)
break
case 'pnpm':
commands.push(`pnpm create ${pkgStr}`)
break
case 'yarn':
commands.push(`yarn create ${pkgStr}`)
break
case 'bun':
commands.push(`bun create ${pkgStr}`)
break
}
}
}

if (mode === 'local-install') {
// Each group becomes one command line
for (const packages of packageGroups) {
const pkgStr = packages.join(' ')
switch (packageManager) {
case 'npm':
commands.push(`npx ${pkgStr}`)
break
case 'pnpm':
commands.push(`pnpx ${pkgStr}`)
break
case 'yarn':
commands.push(`yarn dlx ${pkgStr}`)
break
case 'bun':
commands.push(`bunx ${pkgStr}`)
break
}
}
return commands
}

if (mode === 'dev-install') {
for (const packages of packageGroups) {
const pkgStr = packages.join(' ')
switch (packageManager) {
case 'npm':
commands.push(`npm i -D ${pkgStr}`)
break
case 'pnpm':
commands.push(`pnpm add -D ${pkgStr}`)
break
case 'yarn':
commands.push(`yarn add -D ${pkgStr}`)
break
case 'bun':
commands.push(`bun add -d ${pkgStr}`)
break
}
}
return commands
}

// install mode
for (const packages of packageGroups) {
const pkgStr = packages.join(' ')
switch (packageManager) {
case 'npm':
commands.push(`npm i ${pkgStr}`)
break
case 'pnpm':
commands.push(`pnpm add ${pkgStr}`)
break
case 'yarn':
commands.push(`yarn add ${pkgStr}`)
break
case 'bun':
commands.push(`bun add ${pkgStr}`)
break
}
}
return commands
}

export function PackageManagerTabs({
packagesByFramework,
mode,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { findLibrary, getBranch } from '~/libraries'
import { loadDocs } from '~/utils/docs'
import { notFound, createFileRoute } from '@tanstack/react-router'
import { filterFrameworkContent } from '~/utils/markdown/filterFrameworkContent'
import { getPackageManager } from '~/utils/markdown/installCommand'

export const Route = createFileRoute(
'/$libraryId/$version/docs/framework/$framework/{$}.md',
Expand All @@ -19,7 +21,9 @@ export const Route = createFileRoute(
_splat: string
}
}) => {
const _url = new URL(request.url)
const url = new URL(request.url)
const pm = getPackageManager(url.searchParams.get('pm'))
const keepMarkers = url.searchParams.get('keep_markers') === 'true'

const { libraryId, version, framework, _splat: docsPath } = params
const library = findLibrary(libraryId)
Expand All @@ -36,7 +40,14 @@ export const Route = createFileRoute(
docsPath: `${root}/framework/${framework}/${docsPath}`,
})

const markdownContent = `# ${doc.title}\n${doc.content}`
// Filter framework-specific content using framework from URL path
const filteredContent = filterFrameworkContent(doc.content, {
framework,
packageManager: pm,
keepMarkers,
})

const markdownContent = `# ${doc.title}\n${filteredContent}`
const filename = (docsPath || 'file').split('/').join('-')

return new Response(markdownContent, {
Expand Down
18 changes: 16 additions & 2 deletions src/routes/$libraryId/$version.docs.{$}[.]md.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { createFileRoute } from '@tanstack/react-router'
import { getBranch, getLibrary, type LibraryId } from '~/libraries'
import { loadDocs } from '~/utils/docs'
import { filterFrameworkContent } from '~/utils/markdown/filterFrameworkContent'
import { getPackageManager } from '~/utils/markdown/installCommand'

export const Route = createFileRoute('/$libraryId/$version/docs/{$}.md')({
server: {
Expand All @@ -12,7 +14,10 @@ export const Route = createFileRoute('/$libraryId/$version/docs/{$}.md')({
request: Request
params: { libraryId: string; version: string; _splat: string }
}) => {
const _url = new URL(request.url)
const url = new URL(request.url)
const framework = url.searchParams.get('framework')
const pm = getPackageManager(url.searchParams.get('pm'))
const keepMarkers = url.searchParams.get('keep_markers') === 'true'

const { libraryId, version, _splat: docsPath } = params
const library = getLibrary(libraryId as LibraryId)
Expand All @@ -24,7 +29,16 @@ export const Route = createFileRoute('/$libraryId/$version/docs/{$}.md')({
docsPath: `${root}/${docsPath}`,
})

const markdownContent = `# ${doc.title}\n${doc.content}`
// Filter framework-specific content only if framework is explicitly specified
const filteredContent = framework
? filterFrameworkContent(doc.content, {
framework,
packageManager: pm,
keepMarkers,
})
: doc.content

const markdownContent = `# ${doc.title}\n${filteredContent}`
const filename = (docsPath || 'file').split('/').join('-')

return new Response(markdownContent, {
Expand Down
Loading