@@ -27,12 +27,18 @@ function toggleSkill(dirName: string) {
2727 expandedSkills .value = new Set (expandedSkills .value )
2828}
2929
30- const requestUrl = useRequestURL ()
31- const baseUrl = computed (() => ` ${requestUrl .protocol }//${requestUrl .host } ` )
30+ type InstallMethod = ' skills-npm' | ' skills-cli'
31+ const selectedMethod = ref <InstallMethod >(' skills-npm' )
32+
33+ const baseUrl = computed (() =>
34+ typeof window !== ' undefined' ? window .location .origin : ' https://npmx.dev' ,
35+ )
3236
3337const installCommand = computed (() => {
3438 if (! props .skills .length ) return null
35- return ` npx skills add ${baseUrl .value }/${props .packageName } `
39+ return selectedMethod .value === ' skills-npm'
40+ ? ` npm i ${props .packageName } `
41+ : ` npx skills add ${baseUrl .value }/${props .packageName } `
3642})
3743
3844const { copied, copy } = useClipboard ({ copiedDuring: 2000 })
@@ -94,40 +100,96 @@ function handleKeydown(event: KeyboardEvent) {
94100 </button >
95101 </div >
96102
103+ <!-- Install header with tabs -->
104+ <div class =" flex flex-wrap items-center justify-between gap-2 mb-3" >
105+ <h3 class =" text-xs text-fg-subtle uppercase tracking-wider" >Install</h3 >
106+ <div
107+ class =" flex items-center gap-1 p-0.5 bg-bg-subtle border border-border-subtle rounded-md"
108+ role =" tablist"
109+ aria-label =" Installation method"
110+ >
111+ <button
112+ role =" tab"
113+ :aria-selected =" selectedMethod === 'skills-npm'"
114+ :tabindex =" selectedMethod === 'skills-npm' ? 0 : -1"
115+ type =" button"
116+ class =" px-2 py-1 font-mono text-xs rounded transition-colors duration-150 border border-solid focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-fg/50"
117+ :class ="
118+ selectedMethod === 'skills-npm'
119+ ? 'bg-bg border-border shadow-sm text-fg'
120+ : 'border-transparent text-fg-subtle hover:text-fg'
121+ "
122+ @click =" selectedMethod = 'skills-npm'"
123+ >
124+ skills-npm
125+ </button >
126+ <button
127+ role =" tab"
128+ :aria-selected =" selectedMethod === 'skills-cli'"
129+ :tabindex =" selectedMethod === 'skills-cli' ? 0 : -1"
130+ type =" button"
131+ class =" px-2 py-1 font-mono text-xs rounded transition-colors duration-150 border border-solid focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-fg/50"
132+ :class ="
133+ selectedMethod === 'skills-cli'
134+ ? 'bg-bg border-border shadow-sm text-fg'
135+ : 'border-transparent text-fg-subtle hover:text-fg'
136+ "
137+ @click =" selectedMethod = 'skills-cli'"
138+ >
139+ skills CLI
140+ </button >
141+ </div >
142+ </div >
143+
97144 <!-- Terminal-style install command -->
98145 <div
99146 v-if =" installCommand"
100147 class =" bg-bg-subtle border border-border rounded-lg overflow-hidden mb-5"
101148 >
102149 <div class =" flex gap-1.5 px-3 pt-2 sm:px-4 sm:pt-3" >
103- <span class =" size -2.5 rounded-full bg-fg-subtle/50 " />
104- <span class =" size -2.5 rounded-full bg-fg-subtle/50 " />
105- <span class =" size -2.5 rounded-full bg-fg-subtle/50 " />
150+ <span class =" w -2.5 h-2.5 rounded-full bg-fg-subtle" />
151+ <span class =" w -2.5 h-2.5 rounded-full bg-fg-subtle" />
152+ <span class =" w -2.5 h-2.5 rounded-full bg-fg-subtle" />
106153 </div >
107154 <div class =" px-3 pt-2 pb-3 sm:px-4 sm:pt-3 sm:pb-4 overflow-x-auto" >
108- <div class =" flex items-center gap-2" >
155+ <div class =" flex items-center gap-2 group/cmd " >
109156 <span class =" text-fg-subtle font-mono text-sm select-none shrink-0" >$</span >
110- <code class =" font-mono text-sm text-fg-muted whitespace-nowrap" >
111- npx skills add {{ baseUrl }}/{{ packageName }}
112- </code >
157+ <code v-if =" selectedMethod === 'skills-npm'" class =" font-mono text-sm"
158+ ><span class =" text-fg" >npm</span >
159+ <span class =" text-fg-muted" >i {{ packageName }}</span ></code
160+ >
161+ <code v-else class =" font-mono text-sm"
162+ ><span class =" text-fg" >npx</span >
163+ <span class =" text-fg-muted"
164+ >skills add {{ baseUrl }}/{{ packageName }}</span
165+ ></code
166+ >
113167 <button
114168 type =" button"
115- class =" p-1 .5 text-fg-muted rounded transition-colors duration-200 hover:text-fg hover:bg-bg-muted active:scale-95 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-fg/50 shrink-0 "
169+ 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/cmd: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"
116170 :aria-label =" $t('package.get_started.copy_command')"
117171 @click.stop =" copyCommand"
118172 >
119- <span
120- v-if =" copied"
121- class =" i-carbon:checkmark size-4 block"
122- aria-hidden =" true"
123- />
124- <span v-else class =" i-carbon:copy size-4 block" aria-hidden =" true" />
173+ <span aria-live =" polite" >{{
174+ copied ? $t('common.copied') : $t('common.copy')
175+ }}</span >
125176 </button >
126177 </div >
127178 </div >
179+
180+ <!-- Learn more link (skills-npm only) -->
181+ <a
182+ v-if =" selectedMethod === 'skills-npm'"
183+ href =" /skills-npm"
184+ class =" flex items-center gap-1.5 px-3 py-2 sm:px-4 text-xs text-fg-subtle hover:text-fg transition-colors border-t border-border"
185+ >
186+ <span class =" i-carbon:arrow-right w-3 h-3" />
187+ Learn more about skills-npm
188+ </a >
128189 </div >
129190
130- <!-- Skills list with expandable descriptions -->
191+ <!-- Skills list -->
192+ <h3 class =" text-xs text-fg-subtle uppercase tracking-wider mb-2" >Available Skills</h3 >
131193 <ul class =" space-y-0.5 list-none m-0 p-0" >
132194 <li v-for =" skill in skills" :key =" skill.dirName" >
133195 <button
@@ -137,14 +199,14 @@ function handleKeydown(event: KeyboardEvent) {
137199 @click =" toggleSkill(skill.dirName)"
138200 >
139201 <span
140- class =" i-carbon:chevron-right w-3.5 h-3.5 text-fg-subtle shrink-0 transition-transform duration-200"
202+ class =" i-carbon:chevron-right w-3 h-3 text-fg-subtle shrink-0 transition-transform duration-200"
141203 :class =" { 'rotate-90': expandedSkills.has(skill.dirName) }"
142204 aria-hidden =" true"
143205 />
144206 <span class =" font-mono text-sm text-fg-muted" >{{ skill.name }}</span >
145207 <span
146208 v-if =" skill.warnings?.length"
147- class =" i-carbon:warning size -3.5 text-amber-500 shrink-0"
209+ class =" i-carbon:warning w-3.5 h -3.5 text-amber-500 shrink-0"
148210 :title =" getWarningTooltip(skill)"
149211 />
150212 </button >
0 commit comments