@@ -7,6 +7,7 @@ const props = defineProps<{
77 requestedVersion? : string | null
88 installVersionOverride? : string | null
99 jsrInfo? : JsrPackageInfo | null
10+ readmeHtml? : string | null
1011 typesPackageName? : string | null
1112 executableInfo? : { hasExecutable: boolean ; primaryCommand? : string } | null
1213 createPackageInfo? : { packageName: string } | null
@@ -30,6 +31,20 @@ function getInstallPartsForPM(pmId: PackageManagerId) {
3031 })
3132}
3233
34+ const devDependencySuggestion = computed (() =>
35+ getDevDependencySuggestion (props .packageName , props .readmeHtml ),
36+ )
37+
38+ function getDevInstallPartsForPM(pmId : PackageManagerId ) {
39+ return getInstallCommandParts ({
40+ packageName: props .packageName ,
41+ packageManager: pmId ,
42+ version: props .requestedVersion ,
43+ jsrInfo: props .jsrInfo ,
44+ dev: true ,
45+ })
46+ }
47+
3348// Generate run command parts for a specific package manager
3449function getRunPartsForPM(pmId : PackageManagerId , command ? : string ) {
3550 return getRunCommandParts ({
@@ -68,7 +83,7 @@ function getTypesInstallPartsForPM(pmId: PackageManagerId) {
6883 const pm = packageManagers .find (p => p .id === pmId )
6984 if (! pm ) return []
7085
71- const devFlag = pmId === ' bun ' ? ' -d ' : ' -D '
86+ const devFlag = getDevDependencyFlag ( pmId )
7287 const pkgSpec = pmId === ' deno' ? ` npm:${props .typesPackageName } ` : props .typesPackageName
7388
7489 return [pm .label , pm .action , devFlag , pkgSpec ]
@@ -95,6 +110,18 @@ const copyRunCommand = (command?: string) => copyRun(getFullRunCommand(command))
95110
96111const { copied : createCopied, copy : copyCreate } = useClipboard ({ copiedDuring: 2000 })
97112const copyCreateCommand = () => copyCreate (getFullCreateCommand ())
113+
114+ const { copied : devInstallCopied, copy : copyDevInstall } = useClipboard ({ copiedDuring: 2000 })
115+ const copyDevInstallCommand = () =>
116+ copyDevInstall (
117+ getInstallCommand ({
118+ packageName: props .packageName ,
119+ packageManager: selectedPM .value ,
120+ version: props .requestedVersion ,
121+ jsrInfo: props .jsrInfo ,
122+ dev: true ,
123+ }),
124+ )
98125 </script >
99126
100127<template >
@@ -133,6 +160,41 @@ const copyCreateCommand = () => copyCreate(getFullCreateCommand())
133160 </button >
134161 </div >
135162
163+ <!-- Suggested dev dependency install command -->
164+ <template v-if =" devDependencySuggestion .recommended " >
165+ <div class =" flex items-center gap-2 pt-1 select-none" >
166+ <span class =" text-fg-subtle font-mono text-sm"
167+ ># {{ $t('package.get_started.dev_dependency_hint') }}</span
168+ >
169+ </div >
170+ <div
171+ v-for =" pm in packageManagers"
172+ :key =" `install-dev-${pm.id}`"
173+ :data-pm-cmd =" pm.id"
174+ class =" flex items-center gap-2 group/devinstallcmd min-w-0"
175+ >
176+ <span class =" text-fg-subtle font-mono text-sm select-none shrink-0" >$</span >
177+ <code class =" font-mono text-sm min-w-0"
178+ ><span
179+ v-for =" (part, i) in getDevInstallPartsForPM(pm.id)"
180+ :key =" i"
181+ :class =" i === 0 ? 'text-fg' : 'text-fg-muted'"
182+ >{{ i > 0 ? ' ' : '' }}{{ part }}</span
183+ ></code
184+ >
185+ <button
186+ type =" button"
187+ class =" px-2 py-0.5 font-mono text-xs text-fg-muted bg-bg-subtle/80 border border-border rounded transition-colors duration-200 opacity-0 group-hover/devinstallcmd:opacity-100 hover:(text-fg border-border-hover) active:scale-95 focus-visible:opacity-100 focus-visible:outline-accent/70 select-none"
188+ :aria-label =" $t('package.get_started.copy_dev_command')"
189+ @click.stop =" copyDevInstallCommand"
190+ >
191+ <span aria-live =" polite" >{{
192+ devInstallCopied ? $t('common.copied') : $t('common.copy')
193+ }}</span >
194+ </button >
195+ </div >
196+ </template >
197+
136198 <!-- @types package install - render all PM variants when types package exists -->
137199 <template v-if =" typesPackageName && showTypesInInstall " >
138200 <div
0 commit comments