From 50db2b2a39c7f957a2d348f79fdc2b98c483e293 Mon Sep 17 00:00:00 2001 From: Eric Date: Thu, 29 Oct 2026 14:21:16 +0100 Subject: [PATCH] feat(docs): add navbar sponsor button, more sponsor stats and tier links - Replace the Sponsor nav text link with a dedicated heart button in the navbar, shown icon-only at tablet widths where the menu is crowded - Show weekly npm downloads across all Lucide packages and the all-time Open Collective sponsor count in the sponsor page hero - Add tierLinks.ts for direct Open Collective and GitHub Sponsors tier checkout links, falling back to the general pages while empty Co-Authored-By: Claude Opus 5.5 --- docs/.vitepress/config.ts | 1 - .../sponsor/SponsorAmountPicker.vue | 16 ++-- .../theme/components/sponsor/SponsorHero.vue | 33 +++++-- .../components/sponsor/SponsorStats.data.ts | 56 ++++++++++- .../components/sponsor/SponsorTierCard.vue | 13 +-- .../theme/components/sponsor/sponsors.ts | 3 + .../theme/components/sponsor/tierLinks.ts | 33 +++++++ .../theme/components/sponsor/tiers.ts | 12 +++ docs/.vitepress/theme/index.ts | 2 + .../theme/layouts/NavBarSponsorButton.vue | 95 +++++++++++++++++++ docs/scripts/writeSponsorsData.mts | 16 +++- 11 files changed, 245 insertions(+), 35 deletions(-) create mode 100644 docs/.vitepress/theme/components/sponsor/tierLinks.ts create mode 100644 docs/.vitepress/theme/layouts/NavBarSponsorButton.vue diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts index fd61f358e..46068963d 100644 --- a/docs/.vitepress/config.ts +++ b/docs/.vitepress/config.ts @@ -118,7 +118,6 @@ export default defineConfig({ }, { text: 'Packages', link: '/packages' }, { text: 'Showcase', link: '/showcase' }, - { text: 'Sponsor', link: '/sponsor' }, { text: 'Merch', link: 'https://merch.lucide.dev/' }, ], sidebar, diff --git a/docs/.vitepress/theme/components/sponsor/SponsorAmountPicker.vue b/docs/.vitepress/theme/components/sponsor/SponsorAmountPicker.vue index dd1f73d76..ef140c791 100644 --- a/docs/.vitepress/theme/components/sponsor/SponsorAmountPicker.vue +++ b/docs/.vitepress/theme/components/sponsor/SponsorAmountPicker.vue @@ -5,14 +5,7 @@ import Icon from '@lucide/vue/src/Icon'; import { check } from '../../../data/iconNodes'; import SponsorSection from './SponsorSection.vue'; import SponsorSectionHeader from './SponsorSectionHeader.vue'; -import { - GITHUB_SPONSORS_URL, - OPEN_COLLECTIVE_URL, - TIERS, - formatEuro, - getPreviousTier, - getTierForAmount, -} from './tiers'; +import { TIERS, formatEuro, getPreviousTier, getTierForAmount, getTierLinks } from './tiers'; type Frequency = 'monthly' | 'once'; @@ -36,6 +29,9 @@ const total = computed(() => { const tier = computed(() => (isMonthly.value ? getTierForAmount(total.value) : null)); +// Only a monthly preset matches a tier's checkout, other amounts go to the general pages. +const links = computed(() => getTierLinks(customAmount.value === '' ? tier.value?.id : undefined)); + const amountText = computed(() => formatEuro(total.value)); const summary = computed(() => { @@ -159,11 +155,11 @@ function pickAmount(value: number) {
diff --git a/docs/.vitepress/theme/components/sponsor/SponsorHero.vue b/docs/.vitepress/theme/components/sponsor/SponsorHero.vue index 681524ee2..557124dd9 100644 --- a/docs/.vitepress/theme/components/sponsor/SponsorHero.vue +++ b/docs/.vitepress/theme/components/sponsor/SponsorHero.vue @@ -2,18 +2,32 @@ import VPButton from 'vitepress/dist/client/theme-default/components/VPButton.vue'; import SponsorSection from './SponsorSection.vue'; import { data } from './SponsorStats.data'; -import { sponsors } from './sponsors'; +import { allTimeSponsorCount } from './sponsors'; + +/** Rounds down to a short "120M+" / "25k+" figure. */ +function formatCompact(value: number) { + if (value >= 1_000_000) return `${Math.floor(value / 1_000_000)}M+`; + if (value >= 1_000) return `${Math.floor(value / 1_000)}k+`; + return value.toLocaleString('en-US'); +} const stats = [ - ...(data.stars != null - ? [{ value: `${Math.floor(data.stars / 1000)}k+`, label: 'GitHub stars' }] - : []), + { value: data.weeklyDownloads, label: 'Weekly downloads', format: formatCompact }, + { value: data.stars, label: 'GitHub stars', format: formatCompact }, { - value: `${(Math.floor(data.iconsCount / 100) * 100).toLocaleString('en-US')}+`, + value: data.iconsCount, label: 'Icons', + format: (value: number) => `${(Math.floor(value / 100) * 100).toLocaleString('en-US')}+`, }, - { value: sponsors.length.toLocaleString('en-US'), label: 'Sponsors' }, -]; + { + value: allTimeSponsorCount, + label: 'All-time sponsors', + format: (value: number) => value.toLocaleString('en-US'), + }, +] + // Stats the build couldn't fetch are left out. + .filter((stat): stat is typeof stat & { value: number } => stat.value != null) + .map(({ value, label, format }) => ({ value: format(value), label }));