Skip to content
Closed
Show file tree
Hide file tree
Changes from 2 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
6 changes: 3 additions & 3 deletions app/app.vue
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,9 @@ if (import.meta.client) {
<template>
<div class="min-h-screen flex flex-col bg-bg text-fg">
<NuxtPwaAssets />
<LinkBase to="#main-content" variant="button-primary" class="skip-link">{{
$t('common.skip_link')
}}</LinkBase>
<LinkBase to="#main-content" type="button" class="skip-link" size="sm">
{{ $t('common.skip_link') }}
</LinkBase>

<AppHeader :show-logo="!isHomepage" />

Expand Down
13 changes: 7 additions & 6 deletions app/components/AppFooter.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ const showModal = () => modalRef.value?.showModal?.()
</div>
<!-- Desktop: Show all links. Mobile: Links are in MobileMenu -->
<div class="hidden sm:flex items-center gap-6 min-h-11 text-xs">
<LinkBase :to="{ name: 'about' }">
<LinkBase :to="{ name: 'about' }" size="xs">
{{ $t('footer.about') }}
</LinkBase>
<LinkBase :to="{ name: 'privacy' }">
<LinkBase :to="{ name: 'privacy' }" size="xs">
{{ $t('privacy_policy.title') }}
</LinkBase>
<button
Expand All @@ -32,6 +32,7 @@ const showModal = () => modalRef.value?.showModal?.()
{{ $t('footer.keyboard_shortcuts') }}
</button>

<!-- Keyboard Shortcuts Modal -->
<Modal
ref="modalRef"
:modalTitle="$t('footer.keyboard_shortcuts')"
Expand Down Expand Up @@ -89,16 +90,16 @@ const showModal = () => modalRef.value?.showModal?.()
</li>
</ul>
</Modal>
<LinkBase to="https://docs.npmx.dev">
<LinkBase to="https://docs.npmx.dev" size="xs">
{{ $t('footer.docs') }}
</LinkBase>
<LinkBase to="https://repo.npmx.dev">
<LinkBase to="https://repo.npmx.dev" size="xs">
{{ $t('footer.source') }}
</LinkBase>
<LinkBase to="https://social.npmx.dev">
<LinkBase to="https://social.npmx.dev" size="xs">
{{ $t('footer.social') }}
</LinkBase>
<LinkBase to="https://chat.npmx.dev">
<LinkBase to="https://chat.npmx.dev" size="xs">
{{ $t('footer.chat') }}
</LinkBase>
</div>
Expand Down
3 changes: 2 additions & 1 deletion app/components/AppHeader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -257,9 +257,10 @@ onKeyStroke(
v-for="link in desktopLinks"
:key="link.name"
class="border-none"
variant="button-secondary"
type="button"
:to="link.to"
:aria-keyshortcuts="link.keyshortcut"
size="sm"
>
{{ link.label }}
</LinkBase>
Expand Down
3 changes: 2 additions & 1 deletion app/components/BuildEnvironment.vue
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,15 @@ const buildTime = computed(() => new Date(buildInfo.value.time))
<LinkBase
v-if="buildInfo.env === 'release'"
:to="`https://github.com/npmx-dev/npmx.dev/tag/v${buildInfo.version}`"
size="sm"
>
v{{ buildInfo.version }}
</LinkBase>
<span v-else class="tracking-wider">{{ buildInfo.env }}</span>

<template v-if="buildInfo.commit && buildInfo.branch !== 'release'">
<span>&middot;</span>
<LinkBase :to="`https://github.com/npmx-dev/npmx.dev/commit/${buildInfo.commit}`">
<LinkBase :to="`https://github.com/npmx-dev/npmx.dev/commit/${buildInfo.commit}`" size="xs">
{{ buildInfo.shortCommit }}
</LinkBase>
</template>
Expand Down
5 changes: 3 additions & 2 deletions app/components/Code/FileTree.vue
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,12 @@ watch(
<!-- File -->
<template v-else>
<LinkBase
variant="button-secondary"
type="button"
:to="getFileRoute(node.path)"
:aria-current="currentPath === node.path"
class="w-full justify-start! rounded-none! border-none!"
block
:inline="false"
size="sm"
:style="{ paddingLeft: `${depth * 12 + 32}px` }"
:classicon="getFileIcon(node.name)"
>
Expand Down
2 changes: 1 addition & 1 deletion app/components/CollapsibleSection.vue
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ useHead({
/>
</button>

<LinkBase :to="`#${id}`">
<LinkBase :to="`#${id}`" size="xs">
{{ title }}
</LinkBase>
</component>
Expand Down
11 changes: 6 additions & 5 deletions app/components/Compare/ComparisonGrid.vue
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,9 @@ function getReplacementTooltip(col: ComparisonGridColumn): string {
<span class="inline-flex items-center gap-1.5 truncate">
<LinkBase
:to="packageRoute(col.name, col.version)"
class="text-sm truncate"
block
class="truncate"
:inline="false"
size="sm"
:title="col.version ? `${col.name}@${col.version}` : col.name"
>
{{ col.name }}<template v-if="col.version">@{{ col.version }}</template>
Expand Down Expand Up @@ -80,9 +81,9 @@ function getReplacementTooltip(col: ComparisonGridColumn): string {
<p class="text-xs text-fg-muted">
<i18n-t keypath="compare.no_dependency.tooltip_description" tag="span">
<template #link>
<LinkBase to="https://e18e.dev/docs/replacements/">{{
$t('compare.no_dependency.e18e_community')
}}</LinkBase>
<LinkBase to="https://e18e.dev/docs/replacements/" size="xs">
{{ $t('compare.no_dependency.e18e_community') }}
</LinkBase>
</template>
</i18n-t>
</p>
Expand Down
2 changes: 1 addition & 1 deletion app/components/Compare/ReplacementSuggestion.vue
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ const docUrl = computed(() => {
</ButtonBase>

<!-- Info link -->
<LinkBase v-else-if="docUrl" :to="docUrl" variant="button-secondary" size="small">
<LinkBase v-else-if="docUrl" :to="docUrl" type="button" size="xs">
{{ $t('package.replacement.learn_more') }}
</LinkBase>
</div>
Expand Down
94 changes: 56 additions & 38 deletions app/components/Link/Base.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,11 @@ const props = withDefaults(
/** Disabled links will be displayed as plain text */
disabled?: boolean
/**
* `type` should never be used, because this will always be a link.
* */
type?: never
variant?: 'button-primary' | 'button-secondary' | 'link'
size?: 'small' | 'medium'
block?: boolean
* Controls whether the link is styled as text or as a button.
*/
type?: 'button' | 'link'
size?: 'xs' | 'sm' | 'md' | 'lg'
inline?: boolean

ariaKeyshortcuts?: string

Expand All @@ -37,7 +36,7 @@ const props = withDefaults(
noUnderline?: boolean
} & NuxtLinkProps
>(),
{ variant: 'link', size: 'medium' },
{ type: 'link', size: 'md', inline: true },
)

const isLinkExternal = computed(
Expand All @@ -50,47 +49,66 @@ const isLinkAnchor = computed(
() => !!props.to && typeof props.to === 'string' && props.to.startsWith('#'),
)

/** size is only applicable for button like links */
const isLink = computed(() => props.variant === 'link')
const isButton = computed(() => !isLink.value)
const isButtonSmall = computed(() => props.size === 'small' && !isLink.value)
const isButtonMedium = computed(() => props.size === 'medium' && !isLink.value)
const isLink = computed(() => props.type === 'link')
const isButton = computed(() => props.type === 'button')
const sizeClass = computed(() => {
if (isButton.value) {
switch (props.size) {
case 'xs':
return 'text-xs px-2 py-0.5'
case 'sm':
return 'text-sm px-4 py-2'
case 'md':
return 'text-base px-5 py-2.5'
case 'lg':
return 'text-lg px-6 py-3'
}
}

switch (props.size) {
case 'xs':
return 'text-xs'
case 'sm':
return 'text-sm'
case 'md':
return 'text-base'
case 'lg':
return 'text-lg'
}
})
Comment on lines +54 to +78
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Setting a class like this doesn't work, because Uno won't pick these up. It only works "by accident", because these classes are all used somewhere else. Try setting bg-indigo-300 here and it wouldn't be applied.

This needs to be inlined into the components class prop.

</script>

<template>
<span
v-if="disabled"
:class="{
'flex': block,
'inline-flex': !block,
'opacity-50 gap-x-1 items-center justify-center font-mono border border-transparent rounded-md':
isButton,
'text-sm px-4 py-2': isButtonMedium,
'text-xs px-2 py-0.5': isButtonSmall,
'text-bg bg-fg': variant === 'button-primary',
'bg-transparent text-fg': variant === 'button-secondary',
}"
:class="[
inline ? 'inline-flex' : 'flex',
sizeClass,
{
'opacity-50 gap-x-1 items-center justify-center font-mono border border-transparent rounded-md':
isButton,
'bg-transparent text-fg': isButton,
},
]"
><slot
/></span>
<NuxtLink
v-else
class="group/link gap-x-1 items-center"
:class="{
'flex': block,
'inline-flex': !block,
'underline-offset-[0.2rem] underline decoration-1 decoration-fg/30':
!isLinkAnchor && isLink && !noUnderline,
'justify-start font-mono text-fg hover:(decoration-accent text-accent) focus-visible:(decoration-accent text-accent) transition-colors duration-200':
isLink,
'justify-center font-mono border border-border rounded-md transition-all duration-200':
isButton,
'text-sm px-4 py-2': isButtonMedium,
'text-xs px-2 py-0.5': isButtonSmall,
'bg-transparent text-fg hover:(bg-fg/10 text-accent) focus-visible:(bg-fg/10 text-accent) aria-[current=true]:(bg-fg/10 text-accent border-fg/20 hover:enabled:(bg-fg/20 text-fg/50))':
variant === 'button-secondary',
'text-bg bg-fg hover:(bg-fg/50 text-accent) focus-visible:(bg-fg/50) aria-current:(bg-fg text-bg border-fg hover:enabled:(text-bg/50))':
variant === 'button-primary',
}"
:class="[
inline ? 'inline-flex' : 'flex',
sizeClass,
{
'underline-offset-[0.2rem] underline decoration-1 decoration-fg/30':
!isLinkAnchor && isLink && !noUnderline,
'justify-start font-mono text-fg hover:(decoration-accent text-accent) focus-visible:(decoration-accent text-accent) transition-colors duration-200':
isLink,
'justify-center font-mono border border-border rounded-md transition-all duration-200':
isButton,
'bg-transparent text-fg hover:(bg-fg/10 text-accent) focus-visible:(bg-fg/10 text-accent) aria-[current=true]:(bg-fg/10 text-accent border-fg/20 hover:enabled:(bg-fg/20 text-fg/50))':
isButton,
},
]"
:to="to"
:aria-keyshortcuts="ariaKeyshortcuts"
:target="isLinkExternal ? '_blank' : undefined"
Expand Down
23 changes: 18 additions & 5 deletions app/components/Package/Dependencies.vue
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ const numberFormatter = useNumberFormatter()
:key="dep"
class="flex items-center justify-between py-1 text-sm gap-2"
>
<LinkBase :to="packageRoute(dep)" class="block truncate" dir="ltr">
<LinkBase :to="packageRoute(dep)" :inline="false" class="truncate" dir="ltr" size="sm">
{{ dep }}
</LinkBase>
<span class="flex items-center gap-1 max-w-[40%]" dir="ltr">
Expand All @@ -111,6 +111,7 @@ const numberFormatter = useNumberFormatter()
:class="SEVERITY_TEXT_COLORS[getHighestSeverity(getVulnerableDepInfo(dep)!.counts)]"
:title="`${getVulnerableDepInfo(dep)!.counts.total} vulnerabilities`"
classicon="i-carbon:security"
size="sm"
>
<span class="sr-only">{{ $t('package.dependencies.view_vulnerabilities') }}</span>
</LinkBase>
Expand All @@ -120,6 +121,7 @@ const numberFormatter = useNumberFormatter()
class="shrink-0 text-purple-500"
:title="getDeprecatedDepInfo(dep)!.message"
classicon="i-carbon:warning-hex"
size="sm"
>
<span class="sr-only">{{ $t('package.deprecated.label') }}</span>
</LinkBase>
Expand All @@ -128,6 +130,7 @@ const numberFormatter = useNumberFormatter()
class="block truncate"
:class="getVersionClass(outdatedDeps[dep])"
:title="outdatedDeps[dep] ? getOutdatedTooltip(outdatedDeps[dep], $t) : version"
size="sm"
>
{{ version }}
</LinkBase>
Expand Down Expand Up @@ -178,7 +181,13 @@ const numberFormatter = useNumberFormatter()
class="flex items-center justify-between py-1 text-sm gap-1 min-w-0"
>
<div class="flex items-center gap-1 min-w-0 flex-1">
<LinkBase :to="packageRoute(peer.name)" class="block truncate" dir="ltr">
<LinkBase
:to="packageRoute(peer.name)"
:inline="false"
class="truncate"
dir="ltr"
size="sm"
>
{{ peer.name }}
</LinkBase>
<TagStatic v-if="peer.optional" :title="$t('package.dependencies.optional')">
Expand All @@ -187,9 +196,11 @@ const numberFormatter = useNumberFormatter()
</div>
<LinkBase
:to="packageRoute(peer.name, peer.version)"
class="block truncate max-w-[40%]"
:inline="false"
class="truncate max-w-[40%]"
:title="peer.version"
dir="ltr"
size="sm"
>
{{ peer.version }}
</LinkBase>
Expand Down Expand Up @@ -239,14 +250,16 @@ const numberFormatter = useNumberFormatter()
:key="dep"
class="flex items-center justify-between py-1 text-sm gap-2"
>
<LinkBase :to="packageRoute(dep)" class="block truncate" dir="ltr">
<LinkBase :to="packageRoute(dep)" :inline="false" class="truncate" dir="ltr" size="sm">
{{ dep }}
</LinkBase>
<LinkBase
:to="packageRoute(dep, version)"
class="block truncate"
:inline="false"
class="truncate"
:title="version"
dir="ltr"
size="sm"
>
{{ version }}
</LinkBase>
Expand Down
8 changes: 4 additions & 4 deletions app/components/Package/InstallScripts.vue
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,10 @@ const isExpanded = shallowRef(false)
>
<template v-if="installScripts.content?.[scriptName] && scriptParts[scriptName]">
<template v-if="scriptParts[scriptName].prefix">
{{ scriptParts[scriptName].prefix
}}<LinkBase :to="scriptParts[scriptName].link">{{
scriptParts[scriptName].filePath
}}</LinkBase>
{{ scriptParts[scriptName].prefix }}
<LinkBase :to="scriptParts[scriptName].link" text="sm">
{{ scriptParts[scriptName].filePath }}
</LinkBase>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Likely typo: text="sm" should be size="sm".

Based on the PR objectives and all other LinkBase usages in this PR (which use size="xs" or size="sm"), this appears to be a typo. The text prop doesn't align with the documented LinkBase API changes.

🔧 Proposed fix
              {{ scriptParts[scriptName].prefix }}
-              <LinkBase :to="scriptParts[scriptName].link" text="sm">
+              <LinkBase :to="scriptParts[scriptName].link" size="sm">
                {{ scriptParts[scriptName].filePath }}
              </LinkBase>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<LinkBase :to="scriptParts[scriptName].link" text="sm">
{{ scriptParts[scriptName].filePath }}
</LinkBase>
<LinkBase :to="scriptParts[scriptName].link" size="sm">
{{ scriptParts[scriptName].filePath }}
</LinkBase>

</template>
<LinkBase v-else :to="scriptParts[scriptName].link">
{{ installScripts.content[scriptName] }}
Expand Down
4 changes: 2 additions & 2 deletions app/components/Package/Keywords.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ defineProps<{
<ul class="flex flex-wrap gap-1.5 list-none m-0 p-1">
<li v-for="keyword in keywords.slice(0, 15)" :key="keyword">
<LinkBase
variant="button-secondary"
size="small"
type="button"
size="xs"
:to="{ name: 'search', query: { q: `keywords:${keyword}` } }"
>
{{ keyword }}
Expand Down
4 changes: 2 additions & 2 deletions app/components/Package/MetricsBadges.vue
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ const typesHref = computed(() => {
<TooltipApp :text="typesTooltip">
<LinkBase
v-if="typesHref"
variant="button-secondary"
size="small"
type="button"
size="xs"
:to="typesHref"
classicon="i-carbon-checkmark"
>
Expand Down
Loading
Loading