|
| 1 | +<script setup lang="ts"> |
| 2 | +import type { JsrPackageInfo } from '#shared/types/jsr' |
| 3 | +import type { PackageManagerId } from '~/utils/install-command' |
| 4 | +
|
| 5 | +/** |
| 6 | + * A terminal-style execute command display for binary-only packages. |
| 7 | + * Renders all package manager variants with CSS-based visibility. |
| 8 | + */ |
| 9 | +
|
| 10 | +const props = defineProps<{ |
| 11 | + packageName: string |
| 12 | + jsrInfo?: JsrPackageInfo | null |
| 13 | + isCreatePackage?: boolean |
| 14 | +}>() |
| 15 | +
|
| 16 | +const selectedPM = useSelectedPackageManager() |
| 17 | +
|
| 18 | +// Generate execute command parts for a specific package manager |
| 19 | +function getExecutePartsForPM(pmId: PackageManagerId) { |
| 20 | + return getExecuteCommandParts({ |
| 21 | + packageName: props.packageName, |
| 22 | + packageManager: pmId, |
| 23 | + jsrInfo: props.jsrInfo, |
| 24 | + isBinaryOnly: true, |
| 25 | + isCreatePackage: props.isCreatePackage, |
| 26 | + }) |
| 27 | +} |
| 28 | +
|
| 29 | +// Full execute command for copying (uses current selected PM) |
| 30 | +function getFullExecuteCommand() { |
| 31 | + return getExecuteCommand({ |
| 32 | + packageName: props.packageName, |
| 33 | + packageManager: selectedPM.value, |
| 34 | + jsrInfo: props.jsrInfo, |
| 35 | + isBinaryOnly: true, |
| 36 | + isCreatePackage: props.isCreatePackage, |
| 37 | + }) |
| 38 | +} |
| 39 | +
|
| 40 | +// Copy handler |
| 41 | +const { copied: executeCopied, copy: copyExecute } = useClipboard({ copiedDuring: 2000 }) |
| 42 | +const copyExecuteCommand = () => copyExecute(getFullExecuteCommand()) |
| 43 | +</script> |
| 44 | + |
| 45 | +<template> |
| 46 | + <div class="relative group"> |
| 47 | + <!-- Terminal-style execute command --> |
| 48 | + <div class="bg-bg-subtle border border-border rounded-lg overflow-hidden"> |
| 49 | + <div class="flex gap-1.5 px-3 pt-2 sm:px-4 sm:pt-3"> |
| 50 | + <span class="w-2.5 h-2.5 rounded-full bg-fg-subtle" /> |
| 51 | + <span class="w-2.5 h-2.5 rounded-full bg-fg-subtle" /> |
| 52 | + <span class="w-2.5 h-2.5 rounded-full bg-fg-subtle" /> |
| 53 | + </div> |
| 54 | + <div class="px-3 pt-2 pb-3 sm:px-4 sm:pt-3 sm:pb-4 space-y-1"> |
| 55 | + <!-- Execute command - render all PM variants, CSS controls visibility --> |
| 56 | + <div |
| 57 | + v-for="pm in packageManagers" |
| 58 | + :key="`execute-${pm.id}`" |
| 59 | + :data-pm-cmd="pm.id" |
| 60 | + class="flex items-center gap-2 group/executecmd" |
| 61 | + > |
| 62 | + <span class="text-fg-subtle font-mono text-sm select-none">$</span> |
| 63 | + <code class="font-mono text-sm" |
| 64 | + ><span |
| 65 | + v-for="(part, i) in getExecutePartsForPM(pm.id)" |
| 66 | + :key="i" |
| 67 | + :class="i === 0 ? 'text-fg' : 'text-fg-muted'" |
| 68 | + >{{ i > 0 ? ' ' : '' }}{{ part }}</span |
| 69 | + ></code |
| 70 | + > |
| 71 | + <button |
| 72 | + type="button" |
| 73 | + 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/executecmd:opacity-100 hover:(text-fg border-border-hover) active:scale-95 focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-fg/50" |
| 74 | + :aria-label="$t('package.get_started.copy_command')" |
| 75 | + @click.stop="copyExecuteCommand" |
| 76 | + > |
| 77 | + {{ executeCopied ? $t('common.copied') : $t('common.copy') }} |
| 78 | + </button> |
| 79 | + </div> |
| 80 | + </div> |
| 81 | + </div> |
| 82 | + </div> |
| 83 | +</template> |
| 84 | + |
| 85 | +<style> |
| 86 | +/* Hide all variants by default when preference is set */ |
| 87 | +:root[data-pm] [data-pm-cmd] { |
| 88 | + display: none; |
| 89 | +} |
| 90 | +
|
| 91 | +/* Show only the matching package manager command */ |
| 92 | +:root[data-pm='npm'] [data-pm-cmd='npm'], |
| 93 | +:root[data-pm='pnpm'] [data-pm-cmd='pnpm'], |
| 94 | +:root[data-pm='yarn'] [data-pm-cmd='yarn'], |
| 95 | +:root[data-pm='bun'] [data-pm-cmd='bun'], |
| 96 | +:root[data-pm='deno'] [data-pm-cmd='deno'], |
| 97 | +:root[data-pm='vlt'] [data-pm-cmd='vlt'] { |
| 98 | + display: flex; |
| 99 | +} |
| 100 | +
|
| 101 | +/* Fallback: when no data-pm is set (SSR initial), show npm as default */ |
| 102 | +:root:not([data-pm]) [data-pm-cmd]:not([data-pm-cmd='npm']) { |
| 103 | + display: none; |
| 104 | +} |
| 105 | +</style> |
0 commit comments