@voidzero-dev/vitepress-theme 2.0.1 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -33
- package/package.json +5 -26
- package/src/assets/clients/clickup.svg +5 -0
- package/src/assets/clients/stripe.svg +3 -0
- package/src/{vitepress/components → components}/oss/Footer.vue +4 -21
- package/src/{vitepress/components → components}/oss/Header.vue +82 -180
- package/src/{vitepress/components → components}/oss/Sponsors.vue +3 -3
- package/src/components/oss/TopBanner.vue +111 -0
- package/src/{vitepress/components → components}/oss/TrustedBy.vue +1 -1
- package/src/{vitepress/components → components}/vite/Community.vue +3 -3
- package/src/components/vite/FeatureGrid1.vue +63 -0
- package/src/{vitepress/components/vite/FeatureGrid.vue → components/vite/FeatureGrid2.vue} +12 -11
- package/src/{vitepress/components → components}/vite/Hero.vue +9 -18
- package/src/{vitepress/components → components}/vitepress-default/VPDocOutlineItem.vue +2 -2
- package/src/{vitepress/components → components}/vitepress-default/VPFlyout.vue +1 -1
- package/src/{vitepress/components → components}/vitepress-default/VPMenuLink.vue +1 -1
- package/src/{vitepress/components → components}/vitepress-default/VPNavBarMenuLink.vue +1 -1
- package/src/{vitepress/components → components}/vitepress-default/VPSidebarItem.vue +1 -1
- package/src/{vitepress/components → components}/vitepress-default/VPSocialLink.vue +1 -2
- package/src/fonts/APK-Protocol-Semi-Bold.woff2 +0 -0
- package/src/fonts/inter-italic-cyrillic-ext.woff2 +0 -0
- package/src/fonts/inter-italic-cyrillic.woff2 +0 -0
- package/src/fonts/inter-italic-greek-ext.woff2 +0 -0
- package/src/fonts/inter-italic-greek.woff2 +0 -0
- package/src/fonts/inter-italic-latin-ext.woff2 +0 -0
- package/src/fonts/inter-italic-latin.woff2 +0 -0
- package/src/fonts/inter-italic-vietnamese.woff2 +0 -0
- package/src/fonts/inter-roman-cyrillic-ext.woff2 +0 -0
- package/src/fonts/inter-roman-cyrillic.woff2 +0 -0
- package/src/fonts/inter-roman-greek-ext.woff2 +0 -0
- package/src/fonts/inter-roman-greek.woff2 +0 -0
- package/src/fonts/inter-roman-latin-ext.woff2 +0 -0
- package/src/fonts/inter-roman-latin.woff2 +0 -0
- package/src/fonts/inter-roman-vietnamese.woff2 +0 -0
- package/src/index.ts +103 -2
- package/src/{vitepress/layouts → layouts}/VPLayout.vue +2 -17
- package/src/styles/tokens.css +321 -0
- package/src/{vitepress/styles → styles}/vitepress-default/vars.css +1 -1
- package/src/{vitepress/types → types}/theme-config.ts +2 -0
- package/src/types/theme-context.ts +33 -0
- package/src/vitepress/assets/clients/beehiiv.svg +0 -30
- package/src/vitepress/assets/clients/excalidraw.svg +0 -82
- package/src/vitepress/assets/clients/get-your-guide.svg +0 -1
- package/src/vitepress/assets/clients/posthog.svg +0 -1
- package/src/vitepress/assets/clients/ramp.svg +0 -1
- package/src/vitepress/assets/clients/shopee.svg +0 -55
- package/src/vitepress/components/oss/TopBanner.vue +0 -150
- package/src/vitepress/components/vite/FeaturePanel1.vue +0 -41
- package/src/vitepress/components/vite/FeaturePanel2.vue +0 -37
- package/src/vitepress/components/vite/FeaturePanel3.vue +0 -43
- package/src/vitepress/components/vite/FeaturePanel4.vue +0 -46
- package/src/vitepress/components/voidzero/Footer.vue +0 -65
- package/src/vitepress/components/voidzero/Header.vue +0 -560
- package/src/vitepress/components/voidzero/Megamenu.vue +0 -190
- package/src/vitepress/components/voidzero/about/CareerCTA.vue +0 -56
- package/src/vitepress/components/voidzero/about/Hero.vue +0 -206
- package/src/vitepress/components/voidzero/about/Investors.vue +0 -112
- package/src/vitepress/components/voidzero/about/TeamGrid.vue +0 -161
- package/src/vitepress/components/voidzero/about/TeamSectionHeading.vue +0 -13
- package/src/vitepress/components/voidzero/blog/BlogArchive.vue +0 -223
- package/src/vitepress/components/voidzero/blog/BlogSingleContent.vue +0 -364
- package/src/vitepress/components/voidzero/blog/BlogSingleHero.vue +0 -113
- package/src/vitepress/components/voidzero/blog/BlogSingleRelated.vue +0 -92
- package/src/vitepress/components/voidzero/blog/FeaturedArticles.vue +0 -146
- package/src/vitepress/components/voidzero/blog/types.ts +0 -56
- package/src/vitepress/components/voidzero/home/CaseStudySlider.vue +0 -235
- package/src/vitepress/components/voidzero/home/CustomersSectionHeading.vue +0 -5
- package/src/vitepress/components/voidzero/home/GitHubStats.vue +0 -27
- package/src/vitepress/components/voidzero/home/Hero.vue +0 -69
- package/src/vitepress/components/voidzero/home/Investors.vue +0 -30
- package/src/vitepress/components/voidzero/home/NewsletterCTA.vue +0 -23
- package/src/vitepress/components/voidzero/home/OpenSourceSectionHeading.vue +0 -6
- package/src/vitepress/components/voidzero/home/OpenSourceSectionProjects.vue +0 -419
- package/src/vitepress/components/voidzero/home/Resources.vue +0 -144
- package/src/vitepress/components/voidzero/home/Statistics.vue +0 -507
- package/src/vitepress/components/voidzero/home/StatisticsSectionHeading.vue +0 -5
- package/src/vitepress/components/voidzero/home/TeamCTA.vue +0 -17
- package/src/vitepress/components/voidzero/home/TrustedBy.vue +0 -248
- package/src/vitepress/components/voidzero/home/VitePlusSectionFeatures.vue +0 -55
- package/src/vitepress/components/voidzero/home/VitePlusSectionHeading.vue +0 -17
- package/src/vitepress/fonts/KHTeka-Medium.woff2 +0 -0
- package/src/vitepress/fonts/KHTeka-Regular.woff2 +0 -0
- package/src/vitepress/index.ts +0 -269
- package/src/vitepress/layouts/OSSProjectLayout.vue +0 -28
- package/src/vitepress/styles/tokens.css +0 -137
- /package/src/{vitepress/assets → assets}/checkmark.svg +0 -0
- /package/src/{vitepress/assets → assets}/clients/airbnb.svg +0 -0
- /package/src/{vitepress/assets → assets}/clients/bolt.svg +0 -0
- /package/src/{vitepress/assets → assets}/clients/cloudflare.svg +0 -0
- /package/src/{vitepress/assets → assets}/clients/framer.svg +0 -0
- /package/src/{vitepress/assets → assets}/clients/hugging-face.svg +0 -0
- /package/src/{vitepress/assets → assets}/clients/linear.svg +0 -0
- /package/src/{vitepress/assets → assets}/clients/mercedes.svg +0 -0
- /package/src/{vitepress/assets → assets}/clients/openai.svg +0 -0
- /package/src/{vitepress/assets → assets}/clients/paramount.svg +0 -0
- /package/src/{vitepress/assets → assets}/clients/plaid.svg +0 -0
- /package/src/{vitepress/assets → assets}/clients/shopify.svg +0 -0
- /package/src/{vitepress/assets → assets}/cta-background.jpg +0 -0
- /package/src/{vitepress/assets → assets}/icons/oxc-dark.svg +0 -0
- /package/src/{vitepress/assets → assets}/icons/oxc-light.svg +0 -0
- /package/src/{vitepress/assets → assets}/icons/oxc-mono.svg +0 -0
- /package/src/{vitepress/assets → assets}/icons/rolldown-dark.svg +0 -0
- /package/src/{vitepress/assets → assets}/icons/rolldown-light.svg +0 -0
- /package/src/{vitepress/assets → assets}/icons/rolldown-mono.svg +0 -0
- /package/src/{vitepress/assets → assets}/icons/vite-dark.svg +0 -0
- /package/src/{vitepress/assets → assets}/icons/vite-light.svg +0 -0
- /package/src/{vitepress/assets → assets}/icons/vite-mono.svg +0 -0
- /package/src/{vitepress/assets → assets}/icons/viteplus-dark.svg +0 -0
- /package/src/{vitepress/assets → assets}/icons/viteplus-light.svg +0 -0
- /package/src/{vitepress/assets → assets}/icons/viteplus-mono.svg +0 -0
- /package/src/{vitepress/assets → assets}/icons/vitest-dark.svg +0 -0
- /package/src/{vitepress/assets → assets}/icons/vitest-light.svg +0 -0
- /package/src/{vitepress/assets → assets}/icons/vitest-mono.svg +0 -0
- /package/src/{vitepress/assets → assets}/logos/oxc-dark.svg +0 -0
- /package/src/{vitepress/assets → assets}/logos/oxc-light.svg +0 -0
- /package/src/{vitepress/assets → assets}/logos/rolldown-dark.svg +0 -0
- /package/src/{vitepress/assets → assets}/logos/rolldown-light.svg +0 -0
- /package/src/{vitepress/assets → assets}/logos/vite-dark.svg +0 -0
- /package/src/{vitepress/assets → assets}/logos/vite-light.svg +0 -0
- /package/src/{vitepress/assets → assets}/logos/viteplus-dark.svg +0 -0
- /package/src/{vitepress/assets → assets}/logos/viteplus-light.svg +0 -0
- /package/src/{vitepress/assets → assets}/logos/vitest-dark.svg +0 -0
- /package/src/{vitepress/assets → assets}/logos/vitest-light.svg +0 -0
- /package/src/{vitepress/assets → assets}/logos/voidzero-dark.svg +0 -0
- /package/src/{vitepress/assets → assets}/logos/voidzero-light.svg +0 -0
- /package/src/{vitepress/assets → assets}/oxc/animations/560_x_260_minifier.riv +0 -0
- /package/src/{vitepress/assets → assets}/oxc/animations/640_x_630_oxc masthead_.riv +0 -0
- /package/src/{vitepress/assets → assets}/oxc/footer-background.jpg +0 -0
- /package/src/{vitepress/assets → assets}/oxc/oxc-feature-background.jpg +0 -0
- /package/src/{vitepress/assets → assets}/oxc/oxc-formatter-terminal.png +0 -0
- /package/src/{vitepress/assets → assets}/oxc/oxc-linter-terminal.png +0 -0
- /package/src/{vitepress/assets → assets}/oxc/oxc-resolver-terminal.png +0 -0
- /package/src/{vitepress/assets → assets}/oxc/oxc-transformer-terminal.png +0 -0
- /package/src/{vitepress/assets → assets}/oxc/primary-button-background.jpg +0 -0
- /package/src/{vitepress/assets → assets}/primary-button-background.jpg +0 -0
- /package/src/{vitepress/assets → assets}/rolldown/animations/640_x_300_design_for_vite.riv +0 -0
- /package/src/{vitepress/assets → assets}/rolldown/animations/640_x_300_esbuild.riv +0 -0
- /package/src/{vitepress/assets → assets}/rolldown/animations/640_x_520_rolldown_masthead.riv +0 -0
- /package/src/{vitepress/assets → assets}/rolldown/footer-background.jpg +0 -0
- /package/src/{vitepress/assets → assets}/rolldown/hero-background.jpg +0 -0
- /package/src/{vitepress/assets → assets}/rolldown/hero-terminal.svg +0 -0
- /package/src/{vitepress/assets → assets}/rolldown/primary-button-background.jpg +0 -0
- /package/src/{vitepress/assets → assets}/rolldown/rolldown-esbuild-parity.png +0 -0
- /package/src/{vitepress/assets → assets}/rolldown/rolldown-rollup-background.jpg +0 -0
- /package/src/{vitepress/assets → assets}/rolldown/rolldown-rollup.png +0 -0
- /package/src/{vitepress/assets → assets}/rolldown/rolldown-thumbnail.png +0 -0
- /package/src/{vitepress/assets → assets}/social/bluesky-light.svg +0 -0
- /package/src/{vitepress/assets → assets}/social/bluesky.svg +0 -0
- /package/src/{vitepress/assets → assets}/social/discord-light.svg +0 -0
- /package/src/{vitepress/assets → assets}/social/discord.svg +0 -0
- /package/src/{vitepress/assets → assets}/social/github-light.svg +0 -0
- /package/src/{vitepress/assets → assets}/social/github.svg +0 -0
- /package/src/{vitepress/assets → assets}/social/twitter-light.svg +0 -0
- /package/src/{vitepress/assets → assets}/social/twitter.svg +0 -0
- /package/src/{vitepress/assets → assets}/terminal-background.jpg +0 -0
- /package/src/{vitepress/assets → assets}/vite/animations/563_x_420_rich_features.riv +0 -0
- /package/src/{vitepress/assets → assets}/vite/animations/640_x_300_flexible_plugin.riv +0 -0
- /package/src/{vitepress/assets → assets}/vite/animations/641_x_629_vite_masthead.riv +0 -0
- /package/src/{vitepress/assets → assets}/vite/footer-background.jpg +0 -0
- /package/src/{vitepress/assets → assets}/vite/primary-button-background.jpg +0 -0
- /package/src/{vitepress/assets → assets}/vite/vite-by-voidzero.png +0 -0
- /package/src/{vitepress/assets → assets}/vite/vite-ci.svg +0 -0
- /package/src/{vitepress/assets → assets}/vite/vite-featurepanel-1-background.jpg +0 -0
- /package/src/{vitepress/assets → assets}/vite/vite-featurepanel-1-terminal.svg +0 -0
- /package/src/{vitepress/assets → assets}/vite/vite-featurepanel-2-terminal.png +0 -0
- /package/src/{vitepress/assets → assets}/vite/vite-featurepanel-4-background.jpg +0 -0
- /package/src/{vitepress/assets → assets}/vite/vite-featurepanel-4-terminal.svg +0 -0
- /package/src/{vitepress/assets → assets}/vite/vite-frameworks-mobile.png +0 -0
- /package/src/{vitepress/assets → assets}/vite/vite-frameworks.png +0 -0
- /package/src/{vitepress/assets → assets}/vite/vite-ssr-support.png +0 -0
- /package/src/{vitepress/assets → assets}/vite/vite-typed-api.svg +0 -0
- /package/src/{vitepress/assets → assets}/viteplus/logo.svg +0 -0
- /package/src/{vitepress/assets → assets}/vitest/animations/640_x_300_esm.riv +0 -0
- /package/src/{vitepress/assets → assets}/vitest/animations/640_x_560_vitest_masthead.riv +0 -0
- /package/src/{vitepress/assets → assets}/vitest/animations/650_x_300_vite_powered.riv +0 -0
- /package/src/{vitepress/assets → assets}/vitest/footer-background.jpg +0 -0
- /package/src/{vitepress/assets → assets}/vitest/hero-background.jpg +0 -0
- /package/src/{vitepress/assets → assets}/vitest/hero-terminal.svg +0 -0
- /package/src/{vitepress/assets → assets}/vitest/primary-button-background.jpg +0 -0
- /package/src/{vitepress/assets → assets}/vitest/vitest-jest-compatible.png +0 -0
- /package/src/{vitepress/assets → assets}/vitest/vitest-watcher-background.jpg +0 -0
- /package/src/{vitepress/assets → assets}/vitest/vitest-watcher.png +0 -0
- /package/src/{vitepress/assets → assets}/voidzero/animations/1280_x_552_homepage.riv +0 -0
- /package/src/{vitepress/assets → assets}/voidzero/animations/343_x_148_homepage_mobile.riv +0 -0
- /package/src/{vitepress/assets → assets}/voidzero/animations/480_x_480_build_tool_for_web.riv +0 -0
- /package/src/{vitepress/assets → assets}/voidzero/animations/480_x_480_fastest_javascript_bundler.riv +0 -0
- /package/src/{vitepress/assets → assets}/voidzero/animations/480_x_480_language_toolchain.riv +0 -0
- /package/src/{vitepress/assets → assets}/voidzero/animations/480_x_480_next_generation_runner.riv +0 -0
- /package/src/{vitepress/assets → assets}/voidzero/animations/about-mobile.riv +0 -0
- /package/src/{vitepress/assets → assets}/voidzero/animations/about.riv +0 -0
- /package/src/{vitepress/assets → assets}/voidzero/backgrounds/casestudies.jpg +0 -0
- /package/src/{vitepress/assets → assets}/voidzero/backgrounds/oxc.jpg +0 -0
- /package/src/{vitepress/assets → assets}/voidzero/backgrounds/rolldown.jpg +0 -0
- /package/src/{vitepress/assets → assets}/voidzero/backgrounds/vite.jpg +0 -0
- /package/src/{vitepress/assets → assets}/voidzero/backgrounds/vitest.jpg +0 -0
- /package/src/{vitepress/assets → assets}/voidzero/career-illustration.jpg +0 -0
- /package/src/{vitepress/assets → assets}/voidzero/footer-logo.svg +0 -0
- /package/src/{vitepress/assets → assets}/voidzero/footer.jpg +0 -0
- /package/src/{vitepress/assets → assets}/voidzero/investors/accel.svg +0 -0
- /package/src/{vitepress/assets → assets}/voidzero/investors/amplify.svg +0 -0
- /package/src/{vitepress/assets → assets}/voidzero/investors/peakxv.png +0 -0
- /package/src/{vitepress/assets → assets}/voidzero/investors/resend.svg +0 -0
- /package/src/{vitepress/assets → assets}/voidzero/investors/sentry.svg +0 -0
- /package/src/{vitepress/assets → assets}/voidzero/investors/sunflower.png +0 -0
- /package/src/{vitepress/assets → assets}/voidzero/logo-light.svg +0 -0
- /package/src/{vitepress/assets → assets}/voidzero/logo.svg +0 -0
- /package/src/{vitepress/assets → assets}/voidzero/signature.svg +0 -0
- /package/src/{vitepress/assets → assets}/voidzero/terminals/rolldown.svg +0 -0
- /package/src/{vitepress/assets → assets}/voidzero/terminals/vite.svg +0 -0
- /package/src/{vitepress/assets → assets}/voidzero/terminals/vitest.svg +0 -0
- /package/src/{vitepress/assets → assets}/voidzero/vite-plus-chip.png +0 -0
- /package/src/{vitepress/components → components}/oss/CTAShaderBackground.vue +0 -0
- /package/src/{vitepress/components → components}/oss/HeadingSection.vue +0 -0
- /package/src/{vitepress/components → components}/oxc/FeatureLinter.vue +0 -0
- /package/src/{vitepress/components → components}/oxc/FeatureMinifierFormatter.vue +0 -0
- /package/src/{vitepress/components → components}/oxc/FeatureParser.vue +0 -0
- /package/src/{vitepress/components → components}/oxc/FeatureResolver.vue +0 -0
- /package/src/{vitepress/components → components}/oxc/FeatureToolbar.vue +0 -0
- /package/src/{vitepress/components → components}/oxc/FeatureTransformer.vue +0 -0
- /package/src/{vitepress/components → components}/oxc/Hero.vue +0 -0
- /package/src/{vitepress/components → components}/rolldown/FeatureGrid.vue +0 -0
- /package/src/{vitepress/components → components}/rolldown/Hero.vue +0 -0
- /package/src/{vitepress/components → components}/shared/CodeGroup.vue +0 -0
- /package/src/{vitepress/components → components}/shared/Eyebrow.vue +0 -0
- /package/src/{vitepress/components → components}/shared/LogoGrid.vue +0 -0
- /package/src/{vitepress/components → components}/shared/NewsletterForm.vue +0 -0
- /package/src/{vitepress/components → components}/shared/PerformanceBar.vue +0 -0
- /package/src/{vitepress/components → components}/shared/RiveAnimation.vue +0 -0
- /package/src/{vitepress/components → components}/shared/ShaderBackground.vue +0 -0
- /package/src/{vitepress/components → components}/shared/Spacer.vue +0 -0
- /package/src/{vitepress/components → components}/shared/Terminal.vue +0 -0
- /package/src/{vitepress/components → components}/shared/icons/VZIconBluesky.vue +0 -0
- /package/src/{vitepress/components → components}/shared/icons/VZIconGitHub.vue +0 -0
- /package/src/{vitepress/components → components}/shared/icons/VZIconLogo.vue +0 -0
- /package/src/{vitepress/components → components}/shared/icons/VZIconTwitter.vue +0 -0
- /package/src/{vitepress/components → components}/shared/terminal-animations/TerminalAnimation1.vue +0 -0
- /package/src/{vitepress/components → components}/shared/terminal-animations/TerminalAnimation2.vue +0 -0
- /package/src/{vitepress/components → components}/shared/terminal-animations/TerminalAnimation3.vue +0 -0
- /package/src/{vitepress/components → components}/shared/terminal-animations/TerminalAnimation4.vue +0 -0
- /package/src/{vitepress/components → components}/shared/terminal-animations/TerminalAnimation5.vue +0 -0
- /package/src/{vitepress/components → components}/shared/terminal-animations/TerminalAnimation6.vue +0 -0
- /package/src/{vitepress/components → components}/vite/Frameworks.vue +0 -0
- /package/src/{vitepress/components → components}/viteplus/Header.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/Layout.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/NotFound.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPAlgoliaSearchBox.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPBackdrop.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPBadge.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPButton.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPCarbonAds.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPContent.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPDoc.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPDocAside.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPDocAsideCarbonAds.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPDocAsideOutline.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPDocAsideSponsors.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPDocFooter.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPDocFooterLastUpdated.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPFeature.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPFeatures.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPFooter.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPHero.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPHome.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPHomeContent.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPHomeFeatures.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPHomeHero.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPHomeSponsors.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPImage.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPLink.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPLocalNav.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPLocalNavOutlineDropdown.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPLocalSearchBox.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPMenu.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPMenuGroup.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPNav.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPNavBar.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPNavBarAppearance.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPNavBarExtra.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPNavBarHamburger.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPNavBarMenu.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPNavBarMenuGroup.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPNavBarSearch.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPNavBarSearchButton.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPNavBarSocialLinks.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPNavBarTitle.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPNavBarTranslations.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPNavScreen.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPNavScreenAppearance.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPNavScreenMenu.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPNavScreenMenuGroup.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPNavScreenMenuGroupLink.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPNavScreenMenuGroupSection.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPNavScreenMenuLink.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPNavScreenSocialLinks.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPNavScreenTranslations.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPPage.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPSearchError.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPSidebar.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPSidebarGroup.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPSkipLink.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPSocialLinks.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPSponsors.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPSponsorsGrid.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPSwitch.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPSwitchAppearance.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPTeamMembers.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPTeamMembersItem.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPTeamPage.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPTeamPageSection.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/VPTeamPageTitle.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/icons/VPIconAlignJustify.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/icons/VPIconAlignLeft.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/icons/VPIconAlignRight.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/icons/VPIconArrowLeft.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/icons/VPIconArrowRight.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/icons/VPIconChevronDown.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/icons/VPIconChevronLeft.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/icons/VPIconChevronRight.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/icons/VPIconChevronUp.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/icons/VPIconEdit.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/icons/VPIconHeart.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/icons/VPIconLanguages.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/icons/VPIconMinus.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/icons/VPIconMinusSquare.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/icons/VPIconMoon.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/icons/VPIconMoreHorizontal.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/icons/VPIconPlus.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/icons/VPIconPlusSquare.vue +0 -0
- /package/src/{vitepress/components → components}/vitepress-default/icons/VPIconSun.vue +0 -0
- /package/src/{vitepress/components → components}/vitest/FeatureGrid.vue +0 -0
- /package/src/{vitepress/components → components}/vitest/Hero.vue +0 -0
- /package/src/{vitepress/components → components}/vitest/Intro.vue +0 -0
- /package/src/{vitepress/composables → composables}/vitepress-default/aside.ts +0 -0
- /package/src/{vitepress/composables → composables}/vitepress-default/data.ts +0 -0
- /package/src/{vitepress/composables → composables}/vitepress-default/edit-link.ts +0 -0
- /package/src/{vitepress/composables → composables}/vitepress-default/flyout.ts +0 -0
- /package/src/{vitepress/composables → composables}/vitepress-default/langs.ts +0 -0
- /package/src/{vitepress/composables → composables}/vitepress-default/layout.ts +0 -0
- /package/src/{vitepress/composables → composables}/vitepress-default/nav.ts +0 -0
- /package/src/{vitepress/composables → composables}/vitepress-default/outline.ts +0 -0
- /package/src/{vitepress/composables → composables}/vitepress-default/prev-next.ts +0 -0
- /package/src/{vitepress/composables → composables}/vitepress-default/sidebar.ts +0 -0
- /package/src/{vitepress/composables → composables}/vitepress-default/sponsor-grid.ts +0 -0
- /package/src/{vitepress/env.d.ts → env.d.ts} +0 -0
- /package/src/{vitepress/fonts → fonts}/APK-Protocol-Medium.woff2 +0 -0
- /package/src/{vitepress/fonts → fonts}/KHTekaMono-Medium.woff2 +0 -0
- /package/src/{vitepress/fonts → fonts}/KHTekaMono-Regular.woff2 +0 -0
- /package/src/{vitepress/styles → styles}/base.css +0 -0
- /package/src/{vitepress/styles → styles}/docs.css +0 -0
- /package/src/{vitepress/styles → styles}/index.css +0 -0
- /package/src/{vitepress/styles → styles}/marketing.css +0 -0
- /package/src/{vitepress/styles → styles}/vitepress-default/base-scoped.css +0 -0
- /package/src/{vitepress/styles → styles}/vitepress-default/base.css +0 -0
- /package/src/{vitepress/styles → styles}/vitepress-default/components/custom-block.css +0 -0
- /package/src/{vitepress/styles → styles}/vitepress-default/components/vp-code-group.css +0 -0
- /package/src/{vitepress/styles → styles}/vitepress-default/components/vp-code.css +0 -0
- /package/src/{vitepress/styles → styles}/vitepress-default/components/vp-doc.css +0 -0
- /package/src/{vitepress/styles → styles}/vitepress-default/components/vp-sponsor.css +0 -0
- /package/src/{vitepress/styles → styles}/vitepress-default/fonts.css +0 -0
- /package/src/{vitepress/styles → styles}/vitepress-default/icons.css +0 -0
- /package/src/{vitepress/styles → styles}/vitepress-default/index-scoped.css +0 -0
- /package/src/{vitepress/styles → styles}/vitepress-default/index.css +0 -0
- /package/src/{vitepress/styles → styles}/vitepress-default/utils.css +0 -0
- /package/src/{vitepress/support → support}/vitepress-default/app-utils.ts +0 -0
- /package/src/{vitepress/support → support}/vitepress-default/docsearch-loader.ts +0 -0
- /package/src/{vitepress/support → support}/vitepress-default/lru.ts +0 -0
- /package/src/{vitepress/support → support}/vitepress-default/search-config.ts +0 -0
- /package/src/{vitepress/support → support}/vitepress-default/shared-utils.ts +0 -0
- /package/src/{vitepress/support → support}/vitepress-default/sidebar.ts +0 -0
- /package/src/{vitepress/support → support}/vitepress-default/translation.ts +0 -0
- /package/src/{vitepress/support → support}/vitepress-default/utils.ts +0 -0
- /package/src/{vitepress/types → types}/docsearch.d.ts +0 -0
- /package/src/{vitepress/types → types}/local-search.d.ts +0 -0
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
import githubIcon from '@assets/social/github.svg'
|
|
3
|
-
import twitterIcon from '@assets/social/twitter.svg'
|
|
4
|
-
import blueskyIcon from '@assets/social/bluesky.svg'
|
|
5
|
-
import discordIcon from '@assets/social/discord.svg'
|
|
6
|
-
|
|
7
|
-
interface Member {
|
|
8
|
-
avatar: string
|
|
9
|
-
name: string
|
|
10
|
-
title: string
|
|
11
|
-
desc?: string
|
|
12
|
-
handle: string
|
|
13
|
-
links: Array<{ icon: 'github' | 'x' | 'bluesky' | 'discord', link: string }>
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const props = defineProps<{
|
|
17
|
-
members: Member[]
|
|
18
|
-
}>()
|
|
19
|
-
|
|
20
|
-
const iconMap = {
|
|
21
|
-
github: githubIcon,
|
|
22
|
-
x: twitterIcon,
|
|
23
|
-
bluesky: blueskyIcon,
|
|
24
|
-
discord: discordIcon,
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// Helper to determine which borders a card needs based on its position
|
|
28
|
-
const getBorderClasses = (index: number) => {
|
|
29
|
-
const classes: string[] = []
|
|
30
|
-
const position = index + 1 // 1-based
|
|
31
|
-
const total = props.members.length
|
|
32
|
-
|
|
33
|
-
// RIGHT BORDERS: remove from last item in each row per breakpoint
|
|
34
|
-
// Mobile (1 col): no right borders
|
|
35
|
-
classes.push('border-r-0')
|
|
36
|
-
|
|
37
|
-
// SM (2 cols): border-r on odd items (1st, 3rd, 5th...)
|
|
38
|
-
if (position % 2 !== 0) classes.push('sm:border-r')
|
|
39
|
-
|
|
40
|
-
// LG (3 cols): border-r on all except every 3rd (3rd, 6th, 9th...)
|
|
41
|
-
if (position % 3 !== 0) classes.push('lg:border-r')
|
|
42
|
-
else classes.push('lg:border-r-0')
|
|
43
|
-
|
|
44
|
-
// XL (4 cols): border-r on all except every 4th (4th, 8th, 12th...)
|
|
45
|
-
if (position % 4 !== 0) classes.push('xl:border-r')
|
|
46
|
-
else classes.push('xl:border-r-0')
|
|
47
|
-
|
|
48
|
-
// TOP BORDERS: remove from first row per breakpoint
|
|
49
|
-
// Mobile (1 col): top border on all except 1st
|
|
50
|
-
if (position > 1) classes.push('border-t')
|
|
51
|
-
|
|
52
|
-
// SM (2 cols): top border on all except 1st row (positions 1-2)
|
|
53
|
-
if (position > 2) classes.push('sm:border-t')
|
|
54
|
-
else classes.push('sm:border-t-0')
|
|
55
|
-
|
|
56
|
-
// LG (3 cols): top border on all except 1st row (positions 1-3)
|
|
57
|
-
if (position > 3) classes.push('lg:border-t')
|
|
58
|
-
else classes.push('lg:border-t-0')
|
|
59
|
-
|
|
60
|
-
// XL (4 cols): top border on all except 1st row (positions 1-4)
|
|
61
|
-
if (position > 4) classes.push('xl:border-t')
|
|
62
|
-
else classes.push('xl:border-t-0')
|
|
63
|
-
|
|
64
|
-
// BOTTOM BORDERS: remove from last row per breakpoint
|
|
65
|
-
// Mobile (1 col): bottom border on all except last
|
|
66
|
-
if (position < total) classes.push('border-b')
|
|
67
|
-
|
|
68
|
-
// SM (2 cols): bottom border on all except last row
|
|
69
|
-
const lastRowStartSm = Math.ceil(total / 2) * 2 - 1 // Start of last row in 2-col
|
|
70
|
-
if (position <= total - 2 || position < lastRowStartSm) classes.push('sm:border-b')
|
|
71
|
-
else classes.push('sm:border-b-0')
|
|
72
|
-
|
|
73
|
-
// LG (3 cols): bottom border on all except last row
|
|
74
|
-
const lastRowStartLg = Math.ceil(total / 3) * 3 - 2
|
|
75
|
-
if (position <= total - 3 || position < lastRowStartLg) classes.push('lg:border-b')
|
|
76
|
-
else classes.push('lg:border-b-0')
|
|
77
|
-
|
|
78
|
-
// XL (4 cols): bottom border on all except last row
|
|
79
|
-
const lastRowStartXl = Math.ceil(total / 4) * 4 - 3
|
|
80
|
-
if (position <= total - 4 || position < lastRowStartXl) classes.push('xl:border-b')
|
|
81
|
-
else classes.push('xl:border-b-0')
|
|
82
|
-
|
|
83
|
-
return classes.join(' ')
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
const formatDescription = (desc: string): string => {
|
|
87
|
-
// Format as line comments: "Creator of Vue.js & Vite" -> "// Creator of\n// Vue.js & Vite"
|
|
88
|
-
const words = desc.split(' ')
|
|
89
|
-
const lines: string[] = []
|
|
90
|
-
let currentLine = ''
|
|
91
|
-
|
|
92
|
-
// Group words into lines (roughly 2-3 words per line for readability)
|
|
93
|
-
words.forEach((word, i) => {
|
|
94
|
-
if (i % 3 === 0 && i > 0) {
|
|
95
|
-
lines.push(currentLine.trim())
|
|
96
|
-
currentLine = word
|
|
97
|
-
} else {
|
|
98
|
-
currentLine += (currentLine ? ' ' : '') + word
|
|
99
|
-
}
|
|
100
|
-
})
|
|
101
|
-
if (currentLine) lines.push(currentLine.trim())
|
|
102
|
-
|
|
103
|
-
// Build comment format
|
|
104
|
-
return lines.map(line => `// ${line}`).join('\n')
|
|
105
|
-
}
|
|
106
|
-
</script>
|
|
107
|
-
|
|
108
|
-
<template>
|
|
109
|
-
<section id="team" class="wrapper wrapper--ticks border-t">
|
|
110
|
-
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-y-10">
|
|
111
|
-
<div
|
|
112
|
-
v-for="(member, index) in members"
|
|
113
|
-
:key="index"
|
|
114
|
-
class="border-stroke flex flex-col"
|
|
115
|
-
:class="getBorderClasses(index)"
|
|
116
|
-
>
|
|
117
|
-
<!-- Card content -->
|
|
118
|
-
<div class="flex flex-col gap-5 pt-4 md:pt-8 pb-4 flex-1">
|
|
119
|
-
<!-- Header: Avatar + Name/Title -->
|
|
120
|
-
<div class="px-8 flex gap-6">
|
|
121
|
-
<div class="w-14 h-14 rounded-[10px] bg-violet-600/20 overflow-hidden flex-shrink-0">
|
|
122
|
-
<img :src="member.avatar" :alt="member.name" class="w-full h-full object-cover" />
|
|
123
|
-
</div>
|
|
124
|
-
<div class="flex flex-col gap-0.5 flex-1 min-w-0">
|
|
125
|
-
<h5 class="text-primary md:text-lg font-medium truncate">{{ member.name }}</h5>
|
|
126
|
-
<p class="text-nickel text-base">{{ member.title }}</p>
|
|
127
|
-
</div>
|
|
128
|
-
</div>
|
|
129
|
-
|
|
130
|
-
<!-- Description (comment format) -->
|
|
131
|
-
<div class="px-8 hidden md:block min-h-[3rem]">
|
|
132
|
-
<pre v-if="member.desc" class="font-mono text-grey text-xs uppercase whitespace-pre-wrap leading-tight">{{ formatDescription(member.desc) }}</pre>
|
|
133
|
-
</div>
|
|
134
|
-
</div>
|
|
135
|
-
|
|
136
|
-
<!-- Footer: Social links + Handle -->
|
|
137
|
-
<div class="px-6 py-4 border-t border-stroke flex justify-between items-center">
|
|
138
|
-
<!-- Social icons -->
|
|
139
|
-
<div class="flex items-center gap-3">
|
|
140
|
-
<template v-for="(link, linkIndex) in member.links" :key="linkIndex">
|
|
141
|
-
<a
|
|
142
|
-
v-if="iconMap[link.icon]"
|
|
143
|
-
:href="link.link"
|
|
144
|
-
target="_blank"
|
|
145
|
-
rel="noopener noreferrer"
|
|
146
|
-
class="text-nickel hover:text-white transition-colors"
|
|
147
|
-
>
|
|
148
|
-
<img :src="iconMap[link.icon]" :alt="link.icon" class="size-5" />
|
|
149
|
-
</a>
|
|
150
|
-
</template>
|
|
151
|
-
</div>
|
|
152
|
-
|
|
153
|
-
<!-- Handle badge -->
|
|
154
|
-
<div class="bg-beige rounded-md px-3 pb-0.5">
|
|
155
|
-
<span class="text-nickel text-xs font-mono uppercase font-medium">{{ member.handle }}</span>
|
|
156
|
-
</div>
|
|
157
|
-
</div>
|
|
158
|
-
</div>
|
|
159
|
-
</div>
|
|
160
|
-
</section>
|
|
161
|
-
</template>
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div class="wrapper border-t flex flex-col justify-start items-center py-10 md:py-30">
|
|
3
|
-
<div class="w-full sm:w-2xl flex flex-col justify-start items-center gap-5 px-5 sm:px-0">
|
|
4
|
-
<h2 class="text-center text-primary text-balance">
|
|
5
|
-
Meet the team
|
|
6
|
-
</h2>
|
|
7
|
-
<p class="self-stretch text-center text-balance text-grey">Including creators and core contributors to some of the
|
|
8
|
-
most widely adopted open-source projects.</p>
|
|
9
|
-
</div>
|
|
10
|
-
</div>
|
|
11
|
-
</template>
|
|
12
|
-
<script setup lang="ts">
|
|
13
|
-
</script>
|
|
@@ -1,223 +0,0 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
import {ref, computed, watch} from 'vue'
|
|
3
|
-
import {type Post, formatDateShort} from './types'
|
|
4
|
-
import {
|
|
5
|
-
PaginationRoot,
|
|
6
|
-
PaginationList,
|
|
7
|
-
PaginationListItem,
|
|
8
|
-
PaginationEllipsis,
|
|
9
|
-
PaginationPrev,
|
|
10
|
-
PaginationNext
|
|
11
|
-
} from 'reka-ui'
|
|
12
|
-
|
|
13
|
-
interface Props {
|
|
14
|
-
posts: Post[]
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const props = defineProps<Props>()
|
|
18
|
-
|
|
19
|
-
const ITEMS_PER_PAGE = 10
|
|
20
|
-
|
|
21
|
-
// State
|
|
22
|
-
const currentPage = ref(1)
|
|
23
|
-
const searchQuery = ref('')
|
|
24
|
-
const selectedCategory = ref('all')
|
|
25
|
-
|
|
26
|
-
// Extract unique categories from posts
|
|
27
|
-
const allCategories = computed(() => {
|
|
28
|
-
const categories = new Set<string>()
|
|
29
|
-
props.posts.forEach(post => {
|
|
30
|
-
if (post.category) {
|
|
31
|
-
categories.add(post.category)
|
|
32
|
-
}
|
|
33
|
-
})
|
|
34
|
-
return ['All', ...Array.from(categories).sort()]
|
|
35
|
-
})
|
|
36
|
-
|
|
37
|
-
// Filter posts by search query and category
|
|
38
|
-
const filteredPosts = computed(() => {
|
|
39
|
-
let result = props.posts
|
|
40
|
-
|
|
41
|
-
// Filter by category
|
|
42
|
-
if (selectedCategory.value !== 'all') {
|
|
43
|
-
result = result.filter(post =>
|
|
44
|
-
post.category.toLowerCase() === selectedCategory.value.toLowerCase()
|
|
45
|
-
)
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// Filter by search query
|
|
49
|
-
if (searchQuery.value.trim()) {
|
|
50
|
-
const query = searchQuery.value.toLowerCase().trim()
|
|
51
|
-
result = result.filter(post =>
|
|
52
|
-
post.title.toLowerCase().includes(query)
|
|
53
|
-
)
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
return result
|
|
57
|
-
})
|
|
58
|
-
|
|
59
|
-
// Get paginated posts for current page
|
|
60
|
-
const paginatedPosts = computed(() => {
|
|
61
|
-
const start = (currentPage.value - 1) * ITEMS_PER_PAGE
|
|
62
|
-
const end = start + ITEMS_PER_PAGE
|
|
63
|
-
return filteredPosts.value.slice(start, end)
|
|
64
|
-
})
|
|
65
|
-
|
|
66
|
-
// Total items for pagination
|
|
67
|
-
const totalItems = computed(() => filteredPosts.value.length)
|
|
68
|
-
|
|
69
|
-
// Reset pagination when filters change
|
|
70
|
-
watch([searchQuery, selectedCategory], () => {
|
|
71
|
-
currentPage.value = 1
|
|
72
|
-
})
|
|
73
|
-
|
|
74
|
-
// Category selection handler
|
|
75
|
-
function selectCategory(category: string, event: MouseEvent) {
|
|
76
|
-
selectedCategory.value = category.toLowerCase() === 'all' ? 'all' : category
|
|
77
|
-
// Blur button to prevent focus state from interfering with outline
|
|
78
|
-
;(event.target as HTMLButtonElement)?.blur()
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// Check if category is active
|
|
82
|
-
function isCategoryActive(category: string): boolean {
|
|
83
|
-
if (category.toLowerCase() === 'all') {
|
|
84
|
-
return selectedCategory.value === 'all'
|
|
85
|
-
}
|
|
86
|
-
return selectedCategory.value.toLowerCase() === category.toLowerCase()
|
|
87
|
-
}
|
|
88
|
-
</script>
|
|
89
|
-
|
|
90
|
-
<template>
|
|
91
|
-
<section class="wrapper wrapper--ticks border-t">
|
|
92
|
-
<!-- Header Row -->
|
|
93
|
-
<div class="px-6 md:px-20 pt-30 pb-10 flex flex-col gap-6">
|
|
94
|
-
<!-- Title -->
|
|
95
|
-
<h2 class="text-3xl md:text-4xl font-heading font-medium text-primary">All articles</h2>
|
|
96
|
-
|
|
97
|
-
<!-- Filters Row -->
|
|
98
|
-
<div class="flex flex-col md:flex-row md:items-center md:justify-between gap-4 md:gap-6">
|
|
99
|
-
<!-- Category Filters -->
|
|
100
|
-
<div class="flex flex-wrap items-center gap-2 md:gap-3">
|
|
101
|
-
<span class="text-grey text-xs font-medium font-mono uppercase tracking-wide mr-2">// Categories</span>
|
|
102
|
-
<button
|
|
103
|
-
v-for="category in allCategories"
|
|
104
|
-
:key="category"
|
|
105
|
-
type="button"
|
|
106
|
-
:data-active="isCategoryActive(category)"
|
|
107
|
-
class="px-3 py-1.5 rounded text-sm font-medium outline outline-1 transition-colors cursor-pointer bg-white text-primary outline-stroke data-[active=true]:outline-ruby data-[active=false]:hover:bg-beige focus:outline-1 capitalize"
|
|
108
|
-
@click="selectCategory(category, $event)"
|
|
109
|
-
>
|
|
110
|
-
{{ category }}
|
|
111
|
-
</button>
|
|
112
|
-
</div>
|
|
113
|
-
|
|
114
|
-
<!-- Search Input -->
|
|
115
|
-
<div class="flex items-center gap-2 outline outline-1 outline-stroke rounded-lg px-3 py-2 w-full md:w-64">
|
|
116
|
-
<svg class="size-5 text-grey shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
117
|
-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
118
|
-
d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"/>
|
|
119
|
-
</svg>
|
|
120
|
-
<input
|
|
121
|
-
v-model="searchQuery"
|
|
122
|
-
type="text"
|
|
123
|
-
placeholder="Search..."
|
|
124
|
-
class="bg-transparent text-primary placeholder-grey text-sm outline-none w-full"
|
|
125
|
-
/>
|
|
126
|
-
</div>
|
|
127
|
-
</div>
|
|
128
|
-
</div>
|
|
129
|
-
|
|
130
|
-
<!-- Full-width border -->
|
|
131
|
-
<div class="border-t border-stroke relative tick-left tick-right"></div>
|
|
132
|
-
|
|
133
|
-
<!-- Articles List -->
|
|
134
|
-
<div class="mx-6 md:mx-20 border-l border-r border-stroke flex flex-col gap-5" :class="{ 'pb-6 md:pb-20': totalItems <= ITEMS_PER_PAGE }">
|
|
135
|
-
<a
|
|
136
|
-
v-for="post in paginatedPosts"
|
|
137
|
-
:key="post.url"
|
|
138
|
-
:href="post.url"
|
|
139
|
-
class="flex flex-col md:flex-row hover:bg-beige transition-colors border-t border-b border-stroke first:border-t-0 last:border-b-0"
|
|
140
|
-
>
|
|
141
|
-
<!-- Cover Image -->
|
|
142
|
-
<div class="w-full md:w-[350px] bg-nickel overflow-hidden shrink-0">
|
|
143
|
-
<img
|
|
144
|
-
v-if="post.cover"
|
|
145
|
-
:src="post.cover"
|
|
146
|
-
:alt="post.title"
|
|
147
|
-
class="w-full object-cover"
|
|
148
|
-
/>
|
|
149
|
-
</div>
|
|
150
|
-
|
|
151
|
-
<!-- Content -->
|
|
152
|
-
<div class="flex flex-col md:flex-row md:items-center md:justify-between grow gap-4 md:gap-6 p-6 md:py-0 md:pr-10">
|
|
153
|
-
<div class="flex flex-col gap-2">
|
|
154
|
-
<span class="text-grey text-xs font-medium font-mono uppercase tracking-wide">// {{ post.category }}</span>
|
|
155
|
-
<h4 class="text-xl text-primary font-normal leading-snug text-pretty">
|
|
156
|
-
{{ post.title }}
|
|
157
|
-
</h4>
|
|
158
|
-
</div>
|
|
159
|
-
<span class="text-grey text-xs font-medium font-mono uppercase tracking-wide whitespace-nowrap">
|
|
160
|
-
{{ formatDateShort(post.date.string) }}
|
|
161
|
-
</span>
|
|
162
|
-
</div>
|
|
163
|
-
</a>
|
|
164
|
-
|
|
165
|
-
<!-- Empty State -->
|
|
166
|
-
<div v-if="paginatedPosts.length === 0" class="p-10 text-center">
|
|
167
|
-
<p class="text-grey text-base">No articles found matching your criteria.</p>
|
|
168
|
-
</div>
|
|
169
|
-
</div>
|
|
170
|
-
|
|
171
|
-
<!-- Pagination -->
|
|
172
|
-
<div v-if="totalItems > ITEMS_PER_PAGE" class="border-t border-stroke p-6 md:p-10 flex justify-center">
|
|
173
|
-
<PaginationRoot
|
|
174
|
-
v-model:page="currentPage"
|
|
175
|
-
:total="totalItems"
|
|
176
|
-
:items-per-page="ITEMS_PER_PAGE"
|
|
177
|
-
:sibling-count="1"
|
|
178
|
-
:show-edges="true"
|
|
179
|
-
>
|
|
180
|
-
<PaginationList v-slot="{ items }" class="flex items-center gap-1">
|
|
181
|
-
<PaginationPrev class="size-10 flex items-center justify-center text-grey hover:text-primary transition-colors cursor-pointer disabled:opacity-30 disabled:cursor-not-allowed">
|
|
182
|
-
<svg class="size-4" viewBox="0 0 24 24" fill="currentColor">
|
|
183
|
-
<path
|
|
184
|
-
d="M19,11H7.4l5.3-5.3c0.4-0.4,0.4-1,0-1.4s-1-0.4-1.4,0l-7,7c-0.1,0.1-0.2,0.2-0.2,0.3c-0.1,0.2-0.1,0.5,0,0.8c0.1,0.1,0.1,0.2,0.2,0.3l7,7c0.2,0.2,0.5,0.3,0.7,0.3s0.5-0.1,0.7-0.3c0.4-0.4,0.4-1,0-1.4L7.4,13H19c0.6,0,1-0.4,1-1S19.6,11,19,11z"/>
|
|
185
|
-
</svg>
|
|
186
|
-
</PaginationPrev>
|
|
187
|
-
|
|
188
|
-
<template v-for="(page, index) in items" :key="index">
|
|
189
|
-
<PaginationListItem
|
|
190
|
-
v-if="page.type === 'page'"
|
|
191
|
-
:value="page.value"
|
|
192
|
-
class="pagination-item size-10 flex items-center justify-center text-sm font-mono text-grey hover:text-primary transition-colors cursor-pointer"
|
|
193
|
-
>
|
|
194
|
-
{{ page.value }}
|
|
195
|
-
</PaginationListItem>
|
|
196
|
-
<PaginationEllipsis
|
|
197
|
-
v-else
|
|
198
|
-
:index="index"
|
|
199
|
-
class="size-10 flex items-center justify-center text-sm font-mono text-grey"
|
|
200
|
-
>
|
|
201
|
-
…
|
|
202
|
-
</PaginationEllipsis>
|
|
203
|
-
</template>
|
|
204
|
-
|
|
205
|
-
<PaginationNext class="size-10 flex items-center justify-center text-grey hover:text-primary transition-colors cursor-pointer disabled:opacity-30 disabled:cursor-not-allowed">
|
|
206
|
-
<svg class="size-4" viewBox="0 0 24 24" fill="currentColor">
|
|
207
|
-
<path
|
|
208
|
-
d="M19.9,12.4c0.1-0.2,0.1-0.5,0-0.8c-0.1-0.1-0.1-0.2-0.2-0.3l-7-7c-0.4-0.4-1-0.4-1.4,0s-0.4,1,0,1.4l5.3,5.3H5c-0.6,0-1,0.4-1,1s0.4,1,1,1h11.6l-5.3,5.3c-0.4,0.4-0.4,1,0,1.4c0.2,0.2,0.5,0.3,0.7,0.3s0.5-0.1,0.7-0.3l7-7C19.8,12.6,19.9,12.5,19.9,12.4z"/>
|
|
209
|
-
</svg>
|
|
210
|
-
</PaginationNext>
|
|
211
|
-
</PaginationList>
|
|
212
|
-
</PaginationRoot>
|
|
213
|
-
</div>
|
|
214
|
-
</section>
|
|
215
|
-
</template>
|
|
216
|
-
|
|
217
|
-
<style scoped>
|
|
218
|
-
/* Pagination active state - needs scoped style for data attribute selector */
|
|
219
|
-
.pagination-item[data-selected="true"] {
|
|
220
|
-
outline: 1px solid var(--color-stroke);
|
|
221
|
-
color: var(--color-primary);
|
|
222
|
-
}
|
|
223
|
-
</style>
|