@@ -4,7 +4,7 @@ import styles from './Packages.module.css'
44import { parsePackageInput , generatePackageBadges , getInstallCommands , type PackageManager } from '../utils/packageBadge'
55import PackageSearchDropdown from '../components/PackageSearchDropdown'
66
7- type CopyTarget = 'version' | 'downloads' | 'downloadsMonthly' | 'downloadsRecent' | 'combined' | 'commands'
7+ type CopyTarget = 'version' | 'versionPrerelease' | ' downloads' | 'downloadsMonthly' | 'downloadsRecent' | 'combined' | 'commands' | `command-${ number } `
88type InputMode = 'manual' | 'search'
99type Registry = 'npm' | 'pypi' | 'nuget' | 'rubygems' | 'crates' | 'maven'
1010
@@ -215,30 +215,61 @@ function Packages() {
215215 if ( ! badgeData ) return
216216
217217 let markdown = ''
218- switch ( target ) {
219- case 'version' :
220- markdown = badgeData . version . markdown
221- break
222- case 'downloads' :
223- markdown = badgeData . downloads ?. markdown ?? ''
224- break
225- case 'downloadsMonthly' :
226- markdown = badgeData . downloadsMonthly ?. markdown ?? ''
227- break
228- case 'downloadsRecent' :
229- markdown = badgeData . downloadsRecent ?. markdown ?? ''
230- break
231- case 'combined' : {
232- const parts = [ badgeData . version . markdown ]
233- if ( badgeData . downloads ) parts . push ( badgeData . downloads . markdown )
234- if ( badgeData . downloadsMonthly ) parts . push ( badgeData . downloadsMonthly . markdown )
235- if ( badgeData . downloadsRecent ) parts . push ( badgeData . downloadsRecent . markdown )
236- markdown = parts . join ( '\n' )
237- break
218+
219+ // Handle individual command copying
220+ if ( target . startsWith ( 'command-' ) ) {
221+ const commandIndex = parseInt ( target . split ( '-' ) [ 1 ] , 10 )
222+ const cmd = commands [ commandIndex ] || ''
223+ // Remove the comment line (e.g., "# .NET CLI\n") from the command
224+ const lines = cmd . split ( '\n' )
225+ markdown = lines [ 0 ] . startsWith ( '#' )
226+ ? lines . slice ( 1 ) . join ( '\n' ) . trim ( )
227+ : cmd . trim ( )
228+ } else {
229+ switch ( target ) {
230+ case 'version' :
231+ markdown = badgeData . version . markdown
232+ break
233+ case 'versionPrerelease' :
234+ markdown = badgeData . versionPrerelease ?. markdown ?? ''
235+ break
236+ case 'downloads' :
237+ markdown = badgeData . downloads ?. markdown ?? ''
238+ break
239+ case 'downloadsMonthly' :
240+ markdown = badgeData . downloadsMonthly ?. markdown ?? ''
241+ break
242+ case 'downloadsRecent' :
243+ markdown = badgeData . downloadsRecent ?. markdown ?? ''
244+ break
245+ case 'combined' : {
246+ const parts = [ badgeData . version . markdown ]
247+ if ( badgeData . versionPrerelease ) parts . push ( badgeData . versionPrerelease . markdown )
248+ if ( badgeData . downloads ) parts . push ( badgeData . downloads . markdown )
249+ if ( badgeData . downloadsMonthly ) parts . push ( badgeData . downloadsMonthly . markdown )
250+ if ( badgeData . downloadsRecent ) parts . push ( badgeData . downloadsRecent . markdown )
251+ markdown = parts . join ( '\n' )
252+ break
253+ }
254+ case 'commands' :
255+ markdown = commands . map ( cmd => {
256+ // Format each command with proper markdown headings and code blocks
257+ const lines = cmd . split ( '\n' )
258+ const titleLine = lines [ 0 ]
259+ const title = titleLine . startsWith ( '#' )
260+ ? titleLine . replace ( / ^ # \s * / , '' ) . trim ( )
261+ : null
262+ const codeContent = titleLine . startsWith ( '#' )
263+ ? lines . slice ( 1 ) . join ( '\n' ) . trim ( )
264+ : cmd . trim ( )
265+
266+ if ( title ) {
267+ return `### ${ title } \n\`\`\`bash\n${ codeContent } \n\`\`\``
268+ }
269+ return `\`\`\`bash\n${ codeContent } \n\`\`\``
270+ } ) . join ( '\n\n' )
271+ break
238272 }
239- case 'commands' :
240- markdown = commands . join ( '\n\n' )
241- break
242273 }
243274
244275 if ( markdown ) {
@@ -403,6 +434,11 @@ function Packages() {
403434 < a href = { badgeData . packageUrl } target = "_blank" rel = "noopener noreferrer" >
404435 < img src = { badgeData . version . imageUrl } alt = "Version badge" />
405436 </ a >
437+ { badgeData . versionPrerelease && (
438+ < a href = { badgeData . packageUrl } target = "_blank" rel = "noopener noreferrer" >
439+ < img src = { badgeData . versionPrerelease . imageUrl } alt = "Prerelease version badge" />
440+ </ a >
441+ ) }
406442 { badgeData . downloads && (
407443 < a href = { badgeData . packageUrl } target = "_blank" rel = "noopener noreferrer" >
408444 < img src = { badgeData . downloads . imageUrl } alt = "Downloads badge" />
@@ -437,6 +473,18 @@ function Packages() {
437473 < pre > < code > { badgeData . version . markdown } </ code > </ pre >
438474 </ article >
439475
476+ { badgeData . versionPrerelease && (
477+ < article className = "markdown-card" >
478+ < header className = "output-header" >
479+ < h3 > Prerelease Version</ h3 >
480+ < button type = "button" className = "copy-btn" onClick = { ( ) => handleCopy ( 'versionPrerelease' ) } >
481+ { copiedTarget === 'versionPrerelease' ? '✅ Copied!' : '📋 Copy' }
482+ </ button >
483+ </ header >
484+ < pre > < code > { badgeData . versionPrerelease . markdown } </ code > </ pre >
485+ </ article >
486+ ) }
487+
440488 { badgeData . downloads && (
441489 < article className = "markdown-card" >
442490 < header className = "output-header" >
@@ -484,6 +532,7 @@ function Packages() {
484532 </ header >
485533 < pre > < code > { [
486534 badgeData . version . markdown ,
535+ badgeData . versionPrerelease ?. markdown ,
487536 badgeData . downloads ?. markdown ,
488537 badgeData . downloadsMonthly ?. markdown ,
489538 badgeData . downloadsRecent ?. markdown
@@ -493,16 +542,70 @@ function Packages() {
493542
494543 { commands . length > 0 && (
495544 < div className = { `${ styles . installationSection } installation-section` } >
496- < header className = "output-header" >
497- < h3 > Installation Commands</ h3 >
498- < button type = "button" className = "copy-btn" onClick = { ( ) => handleCopy ( 'commands' ) } >
499- { copiedTarget === 'commands' ? '✅ Copied!' : '📋 Copy' }
500- </ button >
501- </ header >
502- < div className = "command-blocks" >
503- { commands . map ( ( cmd , index ) => (
504- < pre key = { index } > < code > { cmd } </ code > </ pre >
505- ) ) }
545+ < h2 > Installation Commands</ h2 >
546+ < p className = "section-description" >
547+ Choose your preferred installation method:
548+ </ p >
549+
550+ < div className = { `${ styles . combinedCommands } combined-commands` } >
551+ < article className = "markdown-card" >
552+ < header className = "output-header" >
553+ < h3 > Combined README Format</ h3 >
554+ < button
555+ type = "button"
556+ className = "copy-btn"
557+ onClick = { ( ) => handleCopy ( 'commands' ) }
558+ >
559+ { copiedTarget === 'commands' ? '✅ Copied!' : '📋 Copy All' }
560+ </ button >
561+ </ header >
562+ < pre > < code > { commands . map ( cmd => {
563+ // Format each command with proper markdown
564+ const lines = cmd . split ( '\n' )
565+ const titleLine = lines [ 0 ]
566+ const title = titleLine . startsWith ( '#' )
567+ ? titleLine . replace ( / ^ # \s * / , '' ) . trim ( )
568+ : null
569+ const codeContent = titleLine . startsWith ( '#' )
570+ ? lines . slice ( 1 ) . join ( '\n' ) . trim ( )
571+ : cmd . trim ( )
572+
573+ if ( title ) {
574+ return `### ${ title } \n\`\`\`bash\n${ codeContent } \n\`\`\``
575+ }
576+ return `\`\`\`bash\n${ codeContent } \n\`\`\``
577+ } ) . join ( '\n\n' ) } </ code > </ pre >
578+ </ article >
579+ </ div >
580+
581+ < div className = { styles . commandGrid } >
582+ { commands . map ( ( cmd , index ) => {
583+ // Extract the title from the comment (e.g., "# .NET CLI" -> ".NET CLI")
584+ const lines = cmd . split ( '\n' )
585+ const titleLine = lines [ 0 ]
586+ const title = titleLine . startsWith ( '#' )
587+ ? titleLine . replace ( / ^ # \s * / , '' ) . trim ( )
588+ : `Option ${ index + 1 } `
589+ const codeContent = titleLine . startsWith ( '#' )
590+ ? lines . slice ( 1 ) . join ( '\n' ) . trim ( )
591+ : cmd . trim ( )
592+
593+ return (
594+ < article key = { index } className = { `${ styles . commandCard } markdown-card` } >
595+ < header className = "output-header" >
596+ < h3 > { title } </ h3 >
597+ < button
598+ type = "button"
599+ className = "copy-btn"
600+ onClick = { ( ) => handleCopy ( `command-${ index } ` as CopyTarget ) }
601+ >
602+ { copiedTarget === `command-${ index } ` ? '✅ Copied!' : '📋 Copy' }
603+ </ button >
604+ </ header >
605+ < pre > < code > { codeContent } </ code > </ pre >
606+ </ article >
607+ )
608+ } ) }
506609 </ div >
507610 </ div >
508611 ) }
0 commit comments