diff --git a/apps/dashboard/src/App.css b/apps/dashboard/src/App.css index d29bf54..c855304 100644 --- a/apps/dashboard/src/App.css +++ b/apps/dashboard/src/App.css @@ -323,6 +323,68 @@ border-bottom: 2px solid #e2e8f0; } +/* NPM Downloads List */ +.npm-downloads-list-container { + margin: 0 auto 2rem auto; + border-radius: 0.5rem; + border: 1px solid #e2e8f0; + background: white; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + max-width: 500px; + width: fit-content; +} + +.npm-downloads-list { + list-style: none; + padding: 0; + margin: 0; +} + +.npm-download-item { + display: flex; + align-items: center; + justify-content: space-between; + padding: 0.5rem 1rem; + border-bottom: 1px solid #e2e8f0; + transition: all 0.2s ease; + cursor: pointer; + gap: 0.75rem; + min-width: fit-content; +} + +.npm-download-item:hover { + background: #f8fafc; +} + +.npm-download-item:focus { + outline: 2px solid #3b82f6; + outline-offset: -2px; + background: #f8fafc; +} + +.npm-download-item:last-child { + border-bottom: none; +} + +.npm-download-item .package-name { + font-family: 'Consolas', 'Monaco', 'Courier New', monospace; + font-size: 0.875rem; + font-weight: 500; + color: #374151; + background: #f1f5f9; + padding: 0.25rem 0.5rem; + border-radius: 0.25rem; + border: 1px solid #cbd5e1; + min-width: fit-content; + white-space: nowrap; +} + +.npm-download-item .download-badge { + height: auto; + max-height: 20px; + flex-shrink: 0; +} + /* Responsive Design */ @media (max-width: 768px) { .page-nav { @@ -347,6 +409,27 @@ grid-template-columns: 1fr; } + .npm-downloads-list-container { + margin-bottom: 1rem; + } + + .npm-download-item { + padding: 0.75rem; + flex-direction: column; + align-items: flex-start; + gap: 0.5rem; + } + + .npm-download-item .package-name { + font-size: 0.875rem; + padding: 0.375rem 0.5rem; + } + + .npm-download-item .download-badge { + max-width: 100%; + height: auto; + } + .library-charts-grid { padding: 0 1rem; gap: 1rem; diff --git a/apps/dashboard/src/App.tsx b/apps/dashboard/src/App.tsx index 4d6c1dd..bfb704b 100644 --- a/apps/dashboard/src/App.tsx +++ b/apps/dashboard/src/App.tsx @@ -2,6 +2,7 @@ import { BrowserRouter, Route, Routes } from 'react-router-dom'; import './App.css'; import Layout from './components/Layout'; import MinificationBenchmarksPage from './pages/MinificationBenchmarksPage'; +import NpmDownloadsPage from './pages/NpmDownloadsPage'; import RolldownStatsPage from './pages/RolldownStatsPage'; function App() { @@ -11,6 +12,7 @@ function App() { }> } /> } /> + } /> diff --git a/apps/dashboard/src/NpmDownloads.tsx b/apps/dashboard/src/NpmDownloads.tsx new file mode 100644 index 0000000..60a487e --- /dev/null +++ b/apps/dashboard/src/NpmDownloads.tsx @@ -0,0 +1,84 @@ +interface NpmDownloadsProps {} + +// List of npm packages to display download counts for +const packages = [ + 'vite', + 'rolldown-vite', + 'rolldown', + 'tsdown', + 'oxlint', + 'oxc-parser', + 'oxc-transform', + 'oxc-minify', + 'oxc-resolver' +]; + +function NpmDownloads({}: NpmDownloadsProps) { + const handleCardClick = (packageName: string) => { + const npmUrl = `https://www.npmjs.com/package/${packageName}`; + window.open(npmUrl, '_blank', 'noopener,noreferrer'); + }; + + return ( + <> +
+
+

NPM Weekly Downloads

+ +
+
    + {packages.map((packageName) => ( +
  • handleCardClick(packageName)} + role="button" + tabIndex={0} + onKeyDown={(e) => { + if (e.key === 'Enter' || e.key === ' ') { + e.preventDefault(); + handleCardClick(packageName); + } + }} + > + {packageName} + {`Weekly +
  • + ))} +
+
+
+ +
+
+

Total Packages

+

{packages.length}

+ NPM Packages +
+
+

Registry

+

NPM

+ Public Registry +
+
+

Update Frequency

+

Weekly

+ Auto Updated +
+
+

Data Source

+

Shields.io

+ Live Data +
+
+
+ + ); +} + +export default NpmDownloads; \ No newline at end of file diff --git a/apps/dashboard/src/components/Layout.tsx b/apps/dashboard/src/components/Layout.tsx index 0f2edd9..b4a8581 100644 --- a/apps/dashboard/src/components/Layout.tsx +++ b/apps/dashboard/src/components/Layout.tsx @@ -1,4 +1,4 @@ -import { BarChart3, Package, Zap } from 'lucide-react'; +import { BarChart3, Download, Package, Zap } from 'lucide-react'; import { Link, Outlet, useLocation } from 'react-router-dom'; function Layout() { @@ -30,6 +30,13 @@ function Layout() { Minification Benchmarks + + + NPM Downloads + {/* Render the current route's component */} diff --git a/apps/dashboard/src/pages/NpmDownloadsPage.tsx b/apps/dashboard/src/pages/NpmDownloadsPage.tsx new file mode 100644 index 0000000..816752a --- /dev/null +++ b/apps/dashboard/src/pages/NpmDownloadsPage.tsx @@ -0,0 +1,24 @@ +import { BarChart3 } from 'lucide-react'; +import NpmDownloads from '../NpmDownloads'; + +function NpmDownloadsPage() { + return ( +
+
+
+
+ +

NPM Downloads

+
+

+ Weekly download statistics for key packages +

+
+
+ + +
+ ); +} + +export default NpmDownloadsPage; \ No newline at end of file