Skip to content

Commit 54bc232

Browse files
committed
useCharts
2 parents e0e8fdb + 1dbf2c2 commit 54bc232

64 files changed

Lines changed: 1571 additions & 444 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.lighthouserc.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
},
1717
"assert": {
1818
"assertions": {
19-
"categories:accessibility": ["warn", { "minScore": 0.9 }]
19+
"categories:accessibility": ["warn", { "minScore": 1 }]
2020
}
2121
},
2222
"upload": {

.oxlintrc.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
"no-console": "warn",
1111
"no-await-in-loop": "off",
1212
"unicorn/no-array-sort": "off",
13-
"no-restricted-globals": "error"
13+
"no-restricted-globals": "error",
14+
"typescript/consistent-type-imports": "error"
1415
},
1516
"ignorePatterns": [
1617
".output/**",

README.md

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,18 @@ The aim of [npmx.dev](https://npmx.dev) is to provide a better browser for the n
1818
- **URL compatible** – Replace `npmjs.com` with `xnpmjs.com` or `npmx.dev` in any URL and it just works.
1919
- **Simplicity** – No noise, cluttered display, or confusing UI. If in doubt: choose simplicity.
2020

21+
## Shortcuts
22+
23+
> [!IMPORTANT]
24+
> We're keeping the website, repository, and our discord community low-profile until the browser is polished enough. We'll do a formal announcement at that point. Please avoid sharing the website or the invite link to discord on social media directly. The repo is public, so people who care about the project can easily find it and join us. Anyone who wants to help is more than welcome to [join the community](https://chat.npm.dev). If you know others who would be interested, please invite them too!
25+
26+
- [chat.npmx.dev](https://chat.npmx.dev) - Discord Server
27+
- [social.npmx.dev](https://social.npmx.dev) - Bluesky Profile
28+
- [repo.npmx.dev](https://repo.npmx.dev) - GitHub Repository
29+
- [issues.npmx.dev](https://issues.npmx.dev) - GitHub Issues
30+
- [coc.npmx.dev](https://coc.npmx.dev) - Code of Conduct
31+
- [contributing.npmx.dev](https://contributing.npmx.dev) - Contributing Guide
32+
2133
## Features
2234

2335
### Package browsing
@@ -29,15 +41,18 @@ The aim of [npmx.dev](https://npmx.dev) is to provide a better browser for the n
2941
- **Provenance indicators** – verified build badges for packages with npm provenance
3042
- **Multi-provider repository support** – stars/forks from GitHub, GitLab, Bitbucket, Codeberg, Gitee, and Sourcehut
3143
- **JSR availability** – see if scoped packages are also available on JSR
32-
- **Package badges** – module format (ESM/CJS/dual), TypeScript types, and engine constraints
44+
- **Package badges** – module format (ESM/CJS/dual), TypeScript types (with `@types/*` links), and engine constraints
3345
- **Outdated dependency indicators** – visual cues showing which dependencies are behind
3446
- **Vulnerability warnings** – security advisories from the OSV database
3547
- **Download statistics** – weekly download counts with sparkline charts
36-
- **Install size** – total install size including dependencies
48+
- **Install size** – total install size (including transitive dependencies)
3749
- **Playground links** – quick access to StackBlitz, CodeSandbox, and other demo environments from READMEs
3850
- **Infinite search** – auto-load additional search pages as you scroll
39-
- **Keyboard navigation** – press `/` to focus search, arrow keys to navigate results, Enter to select
51+
- **Keyboard navigation** – press `/` to focus search, `.` to open code viewer, arrow keys to navigate results
52+
- **Deprecation notices** – clear warnings for deprecated packages and versions
53+
- **Version range resolution** – dependency ranges (e.g., `^1.0.0`) resolve to actual installed versions
4054
- **Claim new packages** – register new package names directly from search results (via local connector)
55+
- **Clickable version tags** – navigate directly to any version from the versions list
4156

4257
### User & org pages
4358

@@ -65,10 +80,12 @@ The aim of [npmx.dev](https://npmx.dev) is to provide a better browser for the n
6580
| Install size calculation |||
6681
| JSR cross-reference |||
6782
| Vulnerability warnings |||
83+
| Deprecation notices |||
6884
| Download charts |||
6985
| Playground links |||
7086
| Keyboard navigation |||
7187
| Multi-provider repo support |||
88+
| Version range resolution |||
7289
| Dependents list || 🚧 |
7390
| Package admin (access/owners) || 🚧 |
7491
| Org/team management || 🚧 |
@@ -105,12 +122,13 @@ npmx.dev supports npm permalinks – just replace `npmjs.com` with `npmx.dev
105122

106123
npmx.dev also supports shorter, cleaner URLs:
107124

108-
| Pattern | Example |
109-
| -------------- | -------------------------------------------------- |
110-
| `/<package>` | [`/nuxt`](https://npmx.dev/nuxt) |
111-
| `/@scope/name` | [`/@nuxt/kit`](https://npmx.dev/@nuxt/kit) |
112-
| `/@org` | [`/@nuxt`](https://npmx.dev/@nuxt) |
113-
| `/~username` | [`/~sindresorhus`](https://npmx.dev/~sindresorhus) |
125+
| Pattern | Example |
126+
| ------------------ | -------------------------------------------------- |
127+
| `/<package>` | [`/nuxt`](https://npmx.dev/nuxt) |
128+
| `/<pkg>@<version>` | [`/vue@3.4.0`](https://npmx.dev/vue@3.4.0) |
129+
| `/@scope/name` | [`/@nuxt/kit`](https://npmx.dev/@nuxt/kit) |
130+
| `/@org` | [`/@nuxt`](https://npmx.dev/@nuxt) |
131+
| `/~username` | [`/~sindresorhus`](https://npmx.dev/~sindresorhus) |
114132

115133
## Tech stack
116134

@@ -122,7 +140,7 @@ npmx.dev also supports shorter, cleaner URLs:
122140

123141
## Contributing
124142

125-
I'd welcome contributions &ndash; please do feel free to poke around and improve things. See [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines on how to get up and running!
143+
We welcome contributions &ndash; please do feel free to poke around and improve things. See [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines on how to get up and running!
126144

127145
## Related projects
128146

@@ -132,7 +150,7 @@ I'd welcome contributions &ndash; please do feel free to poke around and improve
132150
- [npm-alt](https://npm.willow.sh/) &ndash; An alternative npm package browser
133151
- [npkg.lorypelli.dev](https://npkg.lorypelli.dev/) &ndash; An alternative frontend to npm made with as little client-side JavaScript as possible
134152

135-
If you're building something cool, let me know! 🙏
153+
If you're building something cool, let us know! 🙏
136154

137155
## License
138156

app/app.vue

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,10 @@ button {
195195
margin-top: 2rem;
196196
margin-bottom: 1rem;
197197
line-height: 1.3;
198+
199+
a {
200+
text-decoration: none;
201+
}
198202
}
199203
200204
/* Visual styling based on original README heading level */

app/components/AppFooter.vue

Lines changed: 24 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
<script setup lang="ts">
2-
const isMounted = ref(false)
3-
const isVisible = ref(false)
4-
const isScrollable = ref(true)
5-
const lastScrollY = ref(0)
6-
const footerRef = ref<HTMLElement>()
2+
const isMounted = shallowRef(false)
3+
const isVisible = shallowRef(false)
4+
const isScrollable = shallowRef(true)
5+
const lastScrollY = shallowRef(0)
6+
const footerRef = useTemplateRef('footerRef')
77
88
// Check if CSS scroll-state container queries are supported
99
// Once this becomes baseline, we can remove the JS scroll handling entirely
10-
const supportsScrollStateQueries = ref(false)
10+
const supportsScrollStateQueries = useSupported(() => {
11+
return isMounted.value && CSS.supports('container-type', 'scroll-state')
12+
})
1113
1214
function checkScrollable() {
1315
return document.documentElement.scrollHeight > window.innerHeight
@@ -48,26 +50,17 @@ function onResize() {
4850
updateFooterPadding()
4951
}
5052
51-
onMounted(() => {
52-
// Feature detect CSS scroll-state container queries (Chrome 133+)
53-
// @see https://developer.mozilla.org/en-US/docs/Web/CSS/@container#scroll-state_container_descriptors
54-
supportsScrollStateQueries.value = CSS.supports('container-type', 'scroll-state')
53+
useEventListener('scroll', onScroll, { passive: true })
54+
useEventListener('resize', onResize, { passive: true })
5555
56+
onMounted(() => {
5657
nextTick(() => {
5758
lastScrollY.value = window.scrollY
5859
isScrollable.value = checkScrollable()
5960
updateFooterPadding()
6061
// Only apply dynamic classes after mount to avoid hydration mismatch
6162
isMounted.value = true
6263
})
63-
64-
window.addEventListener('scroll', onScroll, { passive: true })
65-
window.addEventListener('resize', onResize, { passive: true })
66-
})
67-
68-
onUnmounted(() => {
69-
window.removeEventListener('scroll', onScroll)
70-
window.removeEventListener('resize', onResize)
7164
})
7265
</script>
7366

@@ -83,9 +76,9 @@ onUnmounted(() => {
8376
: // JS-controlled: fixed position, hidden by default, transition only after mount
8477
isScrollable
8578
? [
86-
'fixed bottom-0 left-0 right-0 z-40 translate-y-full',
79+
'fixed bottom-0 left-0 right-0 z-40',
8780
isMounted && 'transition-transform duration-300 ease-out',
88-
isVisible && 'translate-y-0',
81+
isVisible ? 'translate-y-0' : 'translate-y-full',
8982
]
9083
: 'mt-auto',
9184
]"
@@ -97,19 +90,25 @@ onUnmounted(() => {
9790
<p class="text-xs text-fg-muted m-0 sm:hidden">not affiliated with npm, Inc.</p>
9891
<div class="flex items-center gap-4 sm:gap-6">
9992
<a
100-
href="https://github.com/npmx-dev/npmx.dev"
93+
href="https://repo.npmx.dev"
10194
rel="noopener noreferrer"
102-
class="link-subtle font-mono text-xs min-h-11 min-w-11 flex items-center"
95+
class="link-subtle font-mono text-xs min-h-11 min-w- flex items-center"
10396
>
10497
source
10598
</a>
106-
<span class="text-border">|</span>
10799
<a
108-
href="https://roe.dev"
100+
href="https://social.npmx.dev"
101+
rel="noopener noreferrer"
102+
class="link-subtle font-mono text-xs min-h-11 min-w-11 flex items-center"
103+
>
104+
social
105+
</a>
106+
<a
107+
href="https://chat.npmx.dev"
109108
rel="noopener noreferrer"
110109
class="link-subtle font-mono text-xs min-h-11 min-w-11 flex items-center"
111110
>
112-
@danielroe
111+
chat
113112
</a>
114113
</div>
115114
</div>

app/components/AppHeader.vue

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,15 @@ withDefaults(
3030
<NuxtLink
3131
to="/search"
3232
class="link-subtle font-mono text-sm inline-flex items-center gap-2"
33+
aria-keyshortcuts="/"
3334
>
3435
search
3536
<kbd
3637
class="hidden sm:inline-flex items-center justify-center w-5 h-5 text-xs bg-bg-muted border border-border rounded"
37-
>/</kbd
38+
aria-hidden="true"
3839
>
40+
/
41+
</kbd>
3942
</NuxtLink>
4043
</li>
4144
<li v-if="showConnector" class="flex">

app/components/AppTooltip.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ const props = defineProps<{
66
position?: 'top' | 'bottom' | 'left' | 'right'
77
}>()
88
9-
const isVisible = ref(false)
9+
const isVisible = shallowRef(false)
1010
const tooltipId = useId()
1111
1212
const positionClasses: Record<string, string> = {

app/components/ClaimPackageModal.vue

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@ const {
1919
} = useConnector()
2020
2121
// Fetch name availability when modal opens
22-
const checkResult = ref<CheckNameResult | null>(null)
22+
const checkResult = shallowRef<CheckNameResult | null>(null)
2323
24-
const isChecking = ref(false)
25-
const isPublishing = ref(false)
26-
const publishError = ref<string | null>(null)
27-
const publishSuccess = ref(false)
24+
const isChecking = shallowRef(false)
25+
const isPublishing = shallowRef(false)
26+
const publishError = shallowRef<string | null>(null)
27+
const publishSuccess = shallowRef(false)
2828
2929
async function checkAvailability() {
3030
isChecking.value = true
@@ -125,7 +125,7 @@ const previewPackageJson = computed(() => {
125125
}
126126
})
127127
128-
const connectorModalOpen = ref(false)
128+
const connectorModalOpen = shallowRef(false)
129129
</script>
130130

131131
<template>

app/components/CodeMobileTreeDrawer.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ defineProps<{
77
baseUrl: string
88
}>()
99
10-
const isOpen = ref(false)
10+
const isOpen = shallowRef(false)
1111
1212
// Close drawer on navigation
1313
const route = useRoute()

app/components/CodeViewer.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const emit = defineEmits<{
99
lineClick: [lineNum: number, event: MouseEvent]
1010
}>()
1111
12-
const codeRef = ref<HTMLElement>()
12+
const codeRef = useTemplateRef('codeRef')
1313
1414
// Generate line numbers array
1515
const lineNumbers = computed(() => {

0 commit comments

Comments
 (0)