This is an automated email from the ASF dual-hosted git repository. chaokunyang pushed a commit to branch refine_website in repository https://gitbox.apache.org/repos/asf/fory-site.git
commit 035b7442cf9662c0ccab6875b76f0c884369b477 Author: chaokunyang <[email protected]> AuthorDate: Sat May 30 22:52:30 2026 +0800 Redesign homepage first pass --- docs/start/install.md | 16 +- docusaurus.config.ts | 12 +- .../current/start/install.md | 16 +- .../version-1.0.0/start/install.md | 16 +- src/components/home/HomepageLanding.module.css | 742 ++++++++++++++++++++ src/components/home/HomepageLanding.tsx | 775 +++++++++++++++++++++ src/css/custom.css | 87 ++- src/pages/index.tsx | 51 +- versioned_docs/version-1.0.0/start/install.md | 16 +- 9 files changed, 1616 insertions(+), 115 deletions(-) diff --git a/docs/start/install.md b/docs/start/install.md index 68b2720c2b..9888849b21 100644 --- a/docs/start/install.md +++ b/docs/start/install.md @@ -112,26 +112,18 @@ Or use `cargo add`: cargo add [email protected] ``` -## JavaScript +## JavaScript / TypeScript -The JavaScript packages are not published to npm yet. - -Install and build them from source for now: +Install the published JavaScript package from npm: ```bash -git clone https://github.com/apache/fory.git -cd fory/javascript -npm install -npm run build +npm install @apache-fory/core ``` -After building from source, use `@apache-fory/core` and optionally `@apache-fory/hps` in your project or workspace setup. - Optional native acceleration requires Node.js 20+: ```bash -cd packages/hps -npm run build +npm install @apache-fory/hps ``` ## Dart diff --git a/docusaurus.config.ts b/docusaurus.config.ts index cb420ac5c4..111d6f6349 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -135,32 +135,32 @@ const config: Config = { { type: 'docSidebar', sidebarId: 'docsSidebar', - position: 'right', + position: 'left', label: 'Docs', }, { type: 'docSidebar', sidebarId: 'specificationSidebar', - position: 'right', + position: 'left', label: 'Specification', }, { type: 'docSidebar', sidebarId: 'communitySidebar', - position: 'right', + position: 'left', label: 'Community', }, { to: '/user', label: 'Users', - position: "right", + position: "left", }, { - position: 'right', + position: 'left', to: '/download', label: 'Download', }, - { to: '/blog', label: 'Blog', position: 'right' }, + { to: '/blog', label: 'Blog', position: 'left' }, { type: 'dropdown', label: 'ASF', diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/install.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/install.md index 6737454dfd..8c5da2d260 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/install.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/install.md @@ -112,26 +112,18 @@ fory = "1.0.0" cargo add [email protected] ``` -## JavaScript +## JavaScript / TypeScript -JavaScript 包尚未发布到 npm。 - -目前请先从源码安装并构建: +从 npm 安装已发布的 JavaScript 包: ```bash -git clone https://github.com/apache/fory.git -cd fory/javascript -npm install -npm run build +npm install @apache-fory/core ``` -完成源码构建后,再在你的项目或 workspace 配置中使用 `@apache-fory/core`,并按需启用 `@apache-fory/hps`。 - 可选的原生加速需要 Node.js 20+: ```bash -cd packages/hps -npm run build +npm install @apache-fory/hps ``` ## Dart diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.0.0/start/install.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.0.0/start/install.md index 6737454dfd..8c5da2d260 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.0.0/start/install.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.0.0/start/install.md @@ -112,26 +112,18 @@ fory = "1.0.0" cargo add [email protected] ``` -## JavaScript +## JavaScript / TypeScript -JavaScript 包尚未发布到 npm。 - -目前请先从源码安装并构建: +从 npm 安装已发布的 JavaScript 包: ```bash -git clone https://github.com/apache/fory.git -cd fory/javascript -npm install -npm run build +npm install @apache-fory/core ``` -完成源码构建后,再在你的项目或 workspace 配置中使用 `@apache-fory/core`,并按需启用 `@apache-fory/hps`。 - 可选的原生加速需要 Node.js 20+: ```bash -cd packages/hps -npm run build +npm install @apache-fory/hps ``` ## Dart diff --git a/src/components/home/HomepageLanding.module.css b/src/components/home/HomepageLanding.module.css new file mode 100644 index 0000000000..c3a43801dd --- /dev/null +++ b/src/components/home/HomepageLanding.module.css @@ -0,0 +1,742 @@ +.homepage { + background: var(--ifm-background-color); + color: var(--ifm-font-color-base); + --fory-border: #e4e8f0; + --fory-card-shadow: 0 18px 50px rgba(31, 41, 55, 0.1); + --fory-code-bg: #f7f9fc; + --fory-muted: #667085; + --fory-soft-band: #f7f9fc; + --fory-surface: #ffffff; +} + +.hero { + align-items: stretch; + background: + linear-gradient(90deg, rgba(255, 112, 1, 0.055), transparent 32%), + linear-gradient(180deg, var(--ifm-background-color), #f9fafb); + display: grid; + gap: 2rem; + grid-template-columns: minmax(0, 1fr) minmax(420px, 0.9fr); + min-height: 720px; + padding: 4rem max(2rem, calc((100vw - 1180px) / 2)) 4rem; +} + +.heroContent { + align-self: center; + max-width: 680px; +} + +.eyebrow, +.sectionHeader span, +.performanceCopy span { + color: var(--ifm-color-primary); + display: inline-block; + font-size: 0.78rem; + font-weight: 800; + letter-spacing: 0; + margin-bottom: 0.8rem; + text-transform: uppercase; +} + +.hero h1, +.sectionHeader h2, +.performanceCopy h2, +.ecosystem h2 { + font-size: 3.65rem; + line-height: 1.02; + margin: 0; +} + +.heroSubtitle { + color: var(--ifm-color-emphasis-800); + font-size: 1.2rem; + line-height: 1.72; + margin: 1.35rem 0 0; + max-width: 650px; +} + +.heroActions { + display: flex; + flex-wrap: wrap; + gap: 0.75rem; + margin-top: 2rem; +} + +.primaryButton, +.secondaryButton, +.ghostButton { + align-items: center; + border-radius: 8px; + display: inline-flex; + font-weight: 700; + justify-content: center; + min-height: 44px; + padding: 0.7rem 1rem; + text-decoration: none; + transition: border-color 160ms ease, background 160ms ease, color 160ms ease, transform 160ms ease; +} + +.primaryButton:hover, +.secondaryButton:hover, +.ghostButton:hover { + text-decoration: none; + transform: translateY(-1px); +} + +.primaryButton { + background: var(--ifm-color-primary); + border: 1px solid var(--ifm-color-primary); + color: #fff; +} + +.primaryButton:hover { + background: var(--ifm-color-primary-dark); + color: #fff; +} + +.secondaryButton { + background: var(--ifm-background-surface-color); + border: 1px solid var(--ifm-color-emphasis-300); + color: var(--ifm-font-color-base); +} + +.secondaryButton:hover { + border-color: var(--ifm-color-primary); + color: var(--ifm-color-primary); +} + +.ghostButton { + background: transparent; + border: 1px solid transparent; + color: var(--ifm-color-emphasis-800); +} + +.ghostButton:hover { + background: var(--ifm-color-emphasis-100); + color: var(--ifm-font-color-base); +} + +.trustList { + display: grid; + gap: 0.75rem; + grid-template-columns: repeat(4, minmax(0, 1fr)); + margin: 2.25rem 0 0; +} + +.trustList div { + border-left: 2px solid var(--ifm-color-primary); + padding-left: 0.85rem; +} + +.trustList dt { + color: var(--ifm-font-color-base); + font-size: 0.86rem; + font-weight: 800; +} + +.trustList dd { + color: var(--ifm-color-emphasis-700); + font-size: 0.82rem; + margin: 0.25rem 0 0; +} + +.heroVisual { + align-self: center; + background: var(--fory-surface); + border: 1px solid var(--fory-border); + border-radius: 8px; + box-shadow: var(--fory-card-shadow); + color: var(--ifm-font-color-base); + overflow: hidden; +} + +.panelHeader { + align-items: flex-start; + border-bottom: 1px solid var(--fory-border); + display: flex; + gap: 1rem; + justify-content: space-between; + padding: 1.1rem; +} + +.panelHeader strong, +.runtimeTitleRow span { + display: block; + font-size: 1rem; +} + +.panelHeader span { + color: var(--fory-muted); + display: block; + font-size: 0.86rem; + line-height: 1.5; + margin-top: 0.25rem; +} + +.panelBadge { + background: #ecfdf5; + border: 1px solid #a7f3d0; + border-radius: 999px; + color: #047857 !important; + flex: 0 0 auto; + font-size: 0.76rem !important; + font-weight: 800; + margin-top: 0 !important; + padding: 0.28rem 0.58rem; +} + +.flowGrid { + display: grid; + gap: 0.75rem; + grid-template-columns: 1fr 28px 1fr 28px 1fr; + padding: 1.1rem; +} + +.flowNode { + background: var(--fory-code-bg); + border: 1px solid var(--fory-border); + border-radius: 8px; + min-width: 0; + padding: 0.85rem; +} + +.flowNode span { + color: #0e7490; + display: block; + font-size: 0.72rem; + font-weight: 900; + margin-bottom: 0.45rem; +} + +.flowNode strong { + display: block; + font-size: 0.86rem; +} + +.flowNode code { + background: transparent; + color: #6941c6; + display: block; + font-size: 0.72rem; + line-height: 1.4; + margin-top: 0.45rem; + overflow-wrap: anywhere; + padding: 0; +} + +.flowLine { + align-self: center; + background: var(--ifm-color-primary); + height: 2px; + opacity: 0.75; +} + +.heroCode { + border-top: 1px solid var(--fory-border); + min-width: 0; +} + +.heroCode :global(.theme-code-block) { + background: var(--fory-code-bg); + border-radius: 0; + box-shadow: none; + margin: 0; +} + +.heroCode :global(pre.prism-code) { + background: var(--fory-code-bg) !important; + font-size: 0.85rem; + line-height: 1.6; + padding: 1.1rem; +} + +.quickStart, +.capabilities, +.useCases { + padding: 5rem max(2rem, calc((100vw - 1180px) / 2)); +} + +.sectionHeader { + margin: 0 auto 2rem; + max-width: 760px; + text-align: center; +} + +.sectionHeader h2, +.performanceCopy h2, +.ecosystem h2 { + font-size: 2.35rem; + line-height: 1.12; +} + +.sectionHeader p, +.performanceCopy p, +.ecosystem p { + color: var(--ifm-color-emphasis-800); + font-size: 1.04rem; + line-height: 1.7; + margin: 1rem 0 0; +} + +.runtimeShell { + background: var(--ifm-background-surface-color); + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 8px; + box-shadow: 0 16px 40px rgba(31, 41, 55, 0.07); + overflow: hidden; +} + +.runtimeTabs { + background: var(--fory-soft-band); + border-bottom: 1px solid var(--ifm-color-emphasis-200); + display: flex; + gap: 0.5rem; + overflow-x: auto; + padding: 0.75rem; +} + +.runtimeTab, +.runtimeTabActive { + border: 1px solid transparent; + border-radius: 999px; + cursor: pointer; + flex: 0 0 auto; + font-weight: 800; + min-height: 36px; + padding: 0.45rem 0.8rem; + transition: background 150ms ease, border-color 150ms ease, color 150ms ease; +} + +.runtimeTab { + background: var(--ifm-background-color); + color: var(--ifm-color-emphasis-800); +} + +.runtimeTab:hover { + border-color: var(--ifm-color-primary); + color: var(--ifm-color-primary); +} + +.runtimeTabActive { + background: rgba(255, 112, 1, 0.11); + border-color: rgba(255, 112, 1, 0.35); + color: var(--ifm-color-primary-dark); +} + +.runtimeDetail { + display: grid; + gap: 0; + grid-template-columns: minmax(300px, 0.72fr) minmax(0, 1fr); +} + +.runtimeSummary { + border-right: 1px solid var(--ifm-color-emphasis-200); + padding: 1.4rem; +} + +.runtimeTitleRow { + align-items: center; + display: flex; + gap: 1rem; + justify-content: space-between; +} + +.runtimeTitleRow span { + font-size: 1.45rem; + font-weight: 900; +} + +.runtimeTitleRow a { + color: var(--ifm-color-primary); + flex: 0 0 auto; + font-weight: 800; +} + +.runtimeSummary p { + color: var(--ifm-color-emphasis-800); + line-height: 1.65; + margin: 0.9rem 0 1.25rem; +} + +.installBlock, +.codeBlock { + min-width: 0; +} + +.blockLabel { + color: var(--ifm-color-emphasis-700); + font-size: 0.76rem; + font-weight: 900; + margin-bottom: 0.55rem; + text-transform: uppercase; +} + +.installBlock :global(.theme-code-block), +.codeBlock :global(.theme-code-block) { + background: var(--fory-code-bg); + border: 1px solid var(--fory-border); + border-radius: 8px; + box-shadow: none; + margin: 0; +} + +.installBlock :global(pre.prism-code), +.codeBlock :global(pre.prism-code) { + background: var(--fory-code-bg) !important; + color: #111827; + font-size: 0.84rem; + line-height: 1.58; + padding: 1rem; +} + +.codeBlock { + padding: 1.4rem; +} + +.capabilities { + background: var(--fory-soft-band); +} + +.capabilityGrid { + display: grid; + gap: 1rem; + grid-template-columns: repeat(3, minmax(0, 1fr)); +} + +.capabilityCard { + background: var(--ifm-background-surface-color); + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 8px; + color: inherit; + min-height: 220px; + padding: 1.25rem; + text-decoration: none; + transition: border-color 160ms ease, transform 160ms ease, box-shadow 160ms ease; +} + +.capabilityCard:hover { + border-color: var(--ifm-color-primary); + box-shadow: 0 12px 35px rgba(16, 24, 39, 0.08); + color: inherit; + text-decoration: none; + transform: translateY(-2px); +} + +.capabilityCard > span { + background: rgba(20, 184, 166, 0.12); + border: 1px solid rgba(20, 184, 166, 0.28); + border-radius: 999px; + color: #0f766e; + display: inline-flex; + font-size: 0.72rem; + font-weight: 900; + padding: 0.25rem 0.55rem; +} + +.capabilityCard h3 { + font-size: 1.18rem; + margin: 1rem 0 0.65rem; +} + +.capabilityCard p { + color: var(--ifm-color-emphasis-800); + line-height: 1.65; + margin: 0; +} + +.performance { + align-items: center; + display: grid; + gap: 2rem; + grid-template-columns: minmax(0, 0.8fr) minmax(420px, 1fr); + padding: 5rem max(2rem, calc((100vw - 1180px) / 2)); +} + +.performanceCopy { + max-width: 560px; +} + +.performanceCopy .secondaryButton { + margin-top: 1.4rem; +} + +.performanceCards { + display: grid; + gap: 1rem; + grid-template-columns: repeat(3, minmax(0, 1fr)); +} + +.performanceCard { + background: var(--ifm-background-surface-color); + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 8px; + padding: 1.2rem; +} + +.performanceCard strong { + color: var(--ifm-color-primary); + display: block; + font-size: 2.2rem; + line-height: 1; +} + +.performanceCard span { + color: var(--ifm-font-color-base); + display: block; + font-weight: 900; + margin-top: 0.5rem; +} + +.performanceCard p { + color: var(--ifm-color-emphasis-800); + font-size: 0.9rem; + line-height: 1.55; + margin: 0.65rem 0 0; +} + +.useCaseGrid { + display: grid; + gap: 1rem; + grid-template-columns: repeat(3, minmax(0, 1fr)); +} + +.useCaseCard { + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 8px; + padding: 1.25rem; +} + +.useCaseCard h3 { + font-size: 1.14rem; + margin: 0 0 0.65rem; +} + +.useCaseCard p { + color: var(--ifm-color-emphasis-800); + line-height: 1.65; + margin: 0; +} + +.ecosystem { + background: var(--ifm-background-color); + border-top: 1px solid var(--fory-border); + color: var(--ifm-font-color-base); + padding: 5rem max(2rem, calc((100vw - 1180px) / 2)); +} + +.ecosystemHeader { + max-width: 760px; +} + +.ecosystem p { + color: var(--ifm-color-emphasis-800); + max-width: 680px; +} + +.adoptionGrid { + display: grid; + gap: 1rem; + grid-template-columns: repeat(3, minmax(0, 1fr)); + margin-top: 2rem; +} + +.adoptionCard { + background: #ffffff; + border: 1px solid var(--fory-border); + border-top: 3px solid rgba(255, 112, 1, 0.55); + border-radius: 8px; + color: var(--ifm-font-color-base); + min-height: 220px; + padding: 1.25rem; + text-decoration: none; + transition: border-color 160ms ease, box-shadow 160ms ease, transform 160ms ease; +} + +.adoptionCard:hover { + border-color: var(--ifm-color-primary); + color: var(--ifm-color-primary); + box-shadow: 0 14px 36px rgba(31, 41, 55, 0.08); + text-decoration: none; + transform: translateY(-2px); +} + +.adoptionCard span { + color: var(--ifm-color-primary); + display: block; + font-size: 0.76rem; + font-weight: 900; + margin-bottom: 1rem; +} + +.adoptionCard h3 { + color: var(--ifm-font-color-base); + font-size: 1.18rem; + margin: 0 0 0.65rem; +} + +.adoptionCard p { + color: var(--ifm-color-emphasis-800); + line-height: 1.65; + margin: 0; +} + +.adoptionCard strong { + color: var(--ifm-color-primary); + display: inline-block; + font-size: 0.88rem; + margin-top: 1rem; +} + +[data-theme="dark"] .hero { + background: + linear-gradient(90deg, rgba(255, 112, 1, 0.12), transparent 34%), + linear-gradient(180deg, #10141d, var(--ifm-background-color)); +} + +[data-theme="dark"] .homepage { + --fory-border: #283244; + --fory-card-shadow: none; + --fory-code-bg: #151d2b; + --fory-muted: #aeb8c8; + --fory-soft-band: #111827; + --fory-surface: #172033; +} + +[data-theme="dark"] .runtimeShell, +[data-theme="dark"] .capabilityCard, +[data-theme="dark"] .performanceCard, +[data-theme="dark"] .useCaseCard, +[data-theme="dark"] .adoptionCard { + box-shadow: none; +} + +[data-theme="dark"] .runtimeTabActive { + background: rgba(255, 112, 1, 0.18); + color: #ffb27a; +} + +[data-theme="dark"] .capabilityCard > span { + color: #99f6e4; +} + +[data-theme="dark"] .panelBadge { + background: rgba(20, 184, 166, 0.14); + border-color: rgba(20, 184, 166, 0.34); + color: #99f6e4 !important; +} + +[data-theme="dark"] .ecosystem { + background: var(--ifm-background-color); + border-top-color: var(--fory-border); +} + +[data-theme="dark"] .adoptionCard { + background: #172033; +} + +@media (max-width: 1100px) { + .hero, + .performance { + grid-template-columns: 1fr; + } + + .hero { + min-height: auto; + } + + .heroVisual { + max-width: 760px; + } + + .performanceCopy { + max-width: none; + } +} + +@media (max-width: 996px) { + .hero, + .quickStart, + .capabilities, + .performance, + .useCases, + .ecosystem { + padding-left: 1rem; + padding-right: 1rem; + } + + .hero { + padding-top: 3.5rem; + } + + .hero h1 { + font-size: 2.55rem; + } + + .sectionHeader h2, + .performanceCopy h2, + .ecosystem h2 { + font-size: 2rem; + } + + .trustList, + .capabilityGrid, + .performanceCards, + .useCaseGrid, + .adoptionGrid { + grid-template-columns: 1fr; + } + + .runtimeDetail { + grid-template-columns: 1fr; + } + + .runtimeSummary { + border-bottom: 1px solid var(--ifm-color-emphasis-200); + border-right: 0; + } + + .flowGrid { + grid-template-columns: 1fr; + } + + .flowLine { + height: 18px; + justify-self: center; + width: 2px; + } +} + +@media (max-width: 560px) { + .hero h1 { + font-size: 2.18rem; + } + + .heroSubtitle, + .sectionHeader p, + .performanceCopy p, + .ecosystem p { + font-size: 0.98rem; + } + + .heroActions { + align-items: stretch; + flex-direction: column; + } + + .primaryButton, + .secondaryButton, + .ghostButton { + width: 100%; + } + + .runtimeTitleRow { + align-items: flex-start; + flex-direction: column; + } + + .installBlock :global(pre.prism-code), + .codeBlock :global(pre.prism-code), + .heroCode :global(pre.prism-code) { + font-size: 0.78rem; + } +} diff --git a/src/components/home/HomepageLanding.tsx b/src/components/home/HomepageLanding.tsx new file mode 100644 index 0000000000..6af4c2acb8 --- /dev/null +++ b/src/components/home/HomepageLanding.tsx @@ -0,0 +1,775 @@ +import React, { useMemo, useState } from "react"; +import Link from "@docusaurus/Link"; +import useDocusaurusContext from "@docusaurus/useDocusaurusContext"; +import CodeBlock from "@theme/CodeBlock"; +import styles from "./HomepageLanding.module.css"; + +type RuntimeId = + | "java" + | "python" + | "rust" + | "go" + | "cpp" + | "javascript" + | "csharp" + | "swift" + | "dart" + | "scala" + | "kotlin" + | "xlang"; + +type RuntimeExample = { + id: RuntimeId; + label: string; + install: string; + installLanguage: string; + codeLanguage: string; + code: string; + guide: string; + summary: string; +}; + +type Copy = { + heroEyebrow: string; + heroTitle: string; + heroSubtitle: string; + heroPrimary: string; + heroSecondary: string; + heroGithub: string; + heroVersion: string; + heroRuntimes: string; + heroBenchmarks: string; + heroApache: string; + heroPanelTitle: string; + heroPanelSubtitle: string; + heroFlowSource: string; + heroFlowWire: string; + heroFlowTarget: string; + quickEyebrow: string; + quickTitle: string; + quickSubtitle: string; + installLabel: string; + codeLabel: string; + guideLabel: string; + capabilitiesEyebrow: string; + capabilitiesTitle: string; + capabilitiesSubtitle: string; + performanceEyebrow: string; + performanceTitle: string; + performanceSubtitle: string; + benchmarkCta: string; + useCasesEyebrow: string; + useCasesTitle: string; + useCasesSubtitle: string; + ecosystemTitle: string; + ecosystemSubtitle: string; +}; + +const copies: Record<"en" | "zh", Copy> = { + en: { + heroEyebrow: "Apache Fory 1.0", + heroTitle: "Fast object serialization across languages.", + heroSubtitle: + "Fory serializes native domain objects, preserves object graphs, and gives teams a compact cross-language wire format with Schema IDL when contracts need to be explicit.", + heroPrimary: "Get Started", + heroSecondary: "View Docs", + heroGithub: "GitHub", + heroVersion: "1.0.0 release", + heroRuntimes: "12 runtime entries", + heroBenchmarks: "Benchmarks by language", + heroApache: "Apache project", + heroPanelTitle: "Native objects in, portable bytes out", + heroPanelSubtitle: + "Use xlang mode for payloads that cross runtime boundaries, or native mode for same-runtime hot paths.", + heroFlowSource: "Java object", + heroFlowWire: "Fory payload", + heroFlowTarget: "Python object", + quickEyebrow: "Quick start", + quickTitle: "Choose a runtime and copy a current example.", + quickSubtitle: + "The homepage examples are intentionally short. Each one links to the full guide for configuration, schema evolution, references, and production notes.", + installLabel: "Install", + codeLabel: "Serialize / deserialize", + guideLabel: "Open guide", + capabilitiesEyebrow: "Core capabilities", + capabilitiesTitle: "Built for language boundaries, object graphs, and hot paths.", + capabilitiesSubtitle: + "Fory combines a portable wire format with runtime-specific optimization and object-graph semantics that ordinary IDL-first serializers often flatten away.", + performanceEyebrow: "Performance", + performanceTitle: "Keep hot paths compact, typed, and fast.", + performanceSubtitle: + "Homepage numbers stay high level; the full charts, raw notes, and reproduction details remain in the benchmark documentation.", + benchmarkCta: "View full benchmark charts", + useCasesEyebrow: "Use cases", + useCasesTitle: "Built for language boundaries and data-heavy systems.", + useCasesSubtitle: + "Use Fory where object graphs, schema evolution, and high-throughput binary data need to coexist.", + ecosystemTitle: "Choose the adoption path that matches your system.", + ecosystemSubtitle: + "Move from a single runtime to shared schemas and measured performance without changing the object model.", + }, + zh: { + heroEyebrow: "Apache Fory 1.0", + heroTitle: "面向多语言系统的高性能对象序列化。", + heroSubtitle: + "Fory 直接序列化原生领域对象,保留对象图语义,并提供紧凑的跨语言线格式;当团队需要显式契约时,也可以使用 Schema IDL。", + heroPrimary: "开始使用", + heroSecondary: "查看文档", + heroGithub: "GitHub", + heroVersion: "1.0.0 版本", + heroRuntimes: "12 个运行时入口", + heroBenchmarks: "多语言性能测试", + heroApache: "Apache 项目", + heroPanelTitle: "原生对象输入,可移植字节输出", + heroPanelSubtitle: + "跨运行时载荷使用 xlang 模式;同一运行时的热点路径可以选择 native 模式。", + heroFlowSource: "Java 对象", + heroFlowWire: "Fory 载荷", + heroFlowTarget: "Python 对象", + quickEyebrow: "快速开始", + quickTitle: "选择运行时,复制当前可用示例。", + quickSubtitle: + "首页示例刻意保持精简。每个示例都会链接到完整指南,覆盖配置、Schema 演进、引用和生产使用注意事项。", + installLabel: "安装", + codeLabel: "序列化 / 反序列化", + guideLabel: "打开指南", + capabilitiesEyebrow: "核心能力", + capabilitiesTitle: "面向语言边界、对象图和热点路径而设计。", + capabilitiesSubtitle: + "Fory 将可移植线格式、运行时定制优化和对象图语义结合起来,避免传统 IDL 优先序列化器常见的语义压平。", + performanceEyebrow: "性能", + performanceTitle: "让热点路径保持紧凑、类型化和高速。", + performanceSubtitle: + "首页只保留高层性能入口;完整图表、原始说明和复现细节仍保留在 Benchmark 文档中。", + benchmarkCta: "查看完整性能图表", + useCasesEyebrow: "使用场景", + useCasesTitle: "为语言边界和数据密集型系统而设计。", + useCasesSubtitle: + "当对象图、Schema 演进和高吞吐二进制数据需要共存时,Fory 可以作为统一的序列化层。", + ecosystemTitle: "选择适合当前系统的采用路径。", + ecosystemSubtitle: + "从单一运行时开始,再逐步走向共享 Schema 和可复现性能验证,而不改变领域对象模型。", + }, +}; + +const runtimeExamples: RuntimeExample[] = [ + { + id: "java", + label: "Java", + installLanguage: "xml", + install: `<dependency> + <groupId>org.apache.fory</groupId> + <artifactId>fory-core</artifactId> + <version>1.0.0</version> +</dependency>`, + codeLanguage: "java", + guide: "/docs/guide/java/", + summary: "JVM runtime with xlang and native modes, JIT serializers, and object graph support.", + code: `import org.apache.fory.Fory; + +public record Person(String name, int age) {} + +Fory fory = Fory.builder() + .withXlang(true) + .build(); +fory.register(Person.class, "example", "Person"); + +byte[] bytes = fory.serialize(new Person("Alice", 30)); +Person out = (Person) fory.deserialize(bytes);`, + }, + { + id: "python", + label: "Python", + installLanguage: "bash", + install: `pip install pyfory==1.0.0`, + codeLanguage: "python", + guide: "/docs/guide/python/", + summary: "Python dataclasses, native Python object graphs, and xlang payloads.", + code: `from dataclasses import dataclass +import pyfory + +@dataclass +class Person: + name: str + age: pyfory.Int32 + +fory = pyfory.Fory(xlang=True) +fory.register(Person, typename="example.Person") + +data = fory.serialize(Person("Alice", 30)) +out = fory.deserialize(data)`, + }, + { + id: "rust", + label: "Rust", + installLanguage: "bash", + install: `cargo add [email protected]`, + codeLanguage: "rust", + guide: "/docs/guide/rust/", + summary: "Typed Rust structs with derive-based registration and xlang support.", + code: `use fory::{Error, Fory, ForyObject}; + +#[derive(ForyObject, Debug, PartialEq)] +struct Person { + name: String, + age: i32, +} + +fn main() -> Result<(), Error> { + let mut fory = Fory::builder().xlang(true).build(); + fory.register_by_name::<Person>("example", "Person")?; + + let bytes = fory.serialize(&Person { name: "Alice".into(), age: 30 })?; + let out: Person = fory.deserialize(&bytes)?; + Ok(()) +}`, + }, + { + id: "go", + label: "Go", + installLanguage: "bash", + install: `go get github.com/apache/fory/go/[email protected]`, + codeLanguage: "go", + guide: "/docs/guide/go/", + summary: "Go structs, native mode, xlang mode, and explicit registration.", + code: `type Person struct { + Name string + Age int32 +} + +f := fory.New(fory.WithXlang(true)) +_ = f.RegisterStruct(Person{}, 1) + +payload, _ := f.Serialize(&Person{Name: "Alice", Age: 30}) +var out Person +_ = f.Deserialize(payload, &out)`, + }, + { + id: "cpp", + label: "C++", + installLanguage: "cmake", + install: `FetchContent_Declare( + fory + GIT_REPOSITORY https://github.com/apache/fory.git + GIT_TAG v1.0.0 + SOURCE_SUBDIR cpp +)`, + codeLanguage: "cpp", + guide: "/docs/guide/cpp/", + summary: "Modern C++17 serialization with compile-time type safety and xlang mode.", + code: `struct Person { + std::string name; + int32_t age; + + bool operator==(const Person& other) const { + return name == other.name && age == other.age; + } +}; +FORY_STRUCT(Person, name, age); + +auto fory = Fory::builder().xlang(true).build(); +fory.register_struct<Person>(1); + +auto bytes = fory.serialize(Person{"Alice", 30}).value(); +auto out = fory.deserialize<Person>(bytes).value();`, + }, + { + id: "javascript", + label: "JavaScript", + installLanguage: "bash", + install: `npm install @apache-fory/core`, + codeLanguage: "typescript", + guide: "/docs/guide/javascript/", + summary: "JavaScript and TypeScript xlang payloads for Node.js and browsers.", + code: `import Fory, { Type } from "@apache-fory/core"; + +const personType = Type.struct( + { typeName: "example.Person" }, + { name: Type.string(), age: Type.int32() }, +); + +const fory = new Fory(); +const { serialize, deserialize } = fory.register(personType); + +const payload = serialize({ name: "Alice", age: 30 }); +const out = deserialize(payload);`, + }, + { + id: "csharp", + label: "C#", + installLanguage: "bash", + install: `dotnet add package Apache.Fory --version 1.0.0`, + codeLanguage: "csharp", + guide: "/docs/guide/csharp/", + summary: ".NET runtime with source-generated serializers and xlang compatibility.", + code: `using Apache.Fory; + +[ForyStruct] +public sealed class Person +{ + public string Name { get; set; } = ""; + public int Age { get; set; } +} + +Fory fory = Fory.Builder().Build(); +fory.Register<Person>(1); + +byte[] payload = fory.Serialize(new Person { Name = "Alice", Age = 30 }); +Person out = fory.Deserialize<Person>(payload);`, + }, + { + id: "swift", + label: "Swift", + installLanguage: "swift", + install: `.package(url: "https://github.com/apache/fory.git", exact: "1.0.0")`, + codeLanguage: "swift", + guide: "/docs/guide/swift/", + summary: "Swift value types with macro-based registration and strong type safety.", + code: `import Fory + +@ForyStruct +struct Person: Equatable { + var name: String = "" + var age: Int32 = 0 +} + +let fory = Fory() +fory.register(Person.self, id: 1) + +let payload = try fory.serialize(Person(name: "Alice", age: 30)) +let out: Person = try fory.deserialize(payload)`, + }, + { + id: "dart", + label: "Dart", + installLanguage: "yaml", + install: `dependencies: + fory: ^1.0.0 + +dev_dependencies: + build_runner: ^2.4.13`, + codeLanguage: "dart", + guide: "/docs/guide/dart/", + summary: "Generated Dart serializers for VM, Flutter, and web xlang payloads.", + code: `@ForyStruct() +class Person { + Person(); + String name = ""; + + @ForyField(type: Int32Type()) + int age = 0; +} + +final fory = Fory(); +PersonForyModule.register(fory, Person, namespace: "example", typeName: "Person"); + +final payload = fory.serialize(Person()..name = "Alice"..age = 30); +final out = fory.deserialize<Person>(payload);`, + }, + { + id: "scala", + label: "Scala", + installLanguage: "sbt", + install: `libraryDependencies += "org.apache.fory" %% "fory-scala" % "1.0.0"`, + codeLanguage: "scala", + guide: "/docs/guide/scala/", + summary: "Scala case classes and collections on top of optimized JVM serialization.", + code: `import org.apache.fory.scala.ForyScala + +case class Person(name: String, age: Int) + +val fory = ForyScala.builder() + .withXlang(true) + .build() +fory.register(classOf[Person]) + +val payload = fory.serialize(Person("Alice", 30)) +val out = fory.deserialize(payload).asInstanceOf[Person]`, + }, + { + id: "kotlin", + label: "Kotlin", + installLanguage: "kotlin", + install: `implementation("org.apache.fory:fory-kotlin:1.0.0")`, + codeLanguage: "kotlin", + guide: "/docs/guide/kotlin/", + summary: "Kotlin data classes, Android support, and JVM xlang/native modes.", + code: `import org.apache.fory.kotlin.ForyKotlin + +data class Person(val name: String, val age: Int) + +val fory = ForyKotlin.builder() + .withXlang(true) + .requireClassRegistration(true) + .buildThreadSafeFory() +fory.register(Person::class.java) + +val payload = fory.serialize(Person("Alice", 30)) +val out = fory.deserialize(payload) as Person`, + }, + { + id: "xlang", + label: "Schema IDL", + installLanguage: "fory", + install: `foryc example.fdl --lang rust --output ./generated`, + codeLanguage: "protobuf", + guide: "/docs/guide/xlang/", + summary: "Define a stable schema once and generate a native Rust model.", + code: `package example; + +message Person { + string name = 1; + int32 age = 2; + optional string email = 3; +} + +// This follows the Fory IDL Quick Start schema.`, + }, +]; + +const capabilities = [ + { + title: "Cross-language wire format", + zhTitle: "跨语言线格式", + label: "XLANG", + description: + "Use one compact binary payload across supported runtimes when services cross language boundaries.", + zhDescription: "跨服务语言边界时,用同一套紧凑二进制载荷连接不同运行时。", + link: "/docs/guide/xlang/", + }, + { + title: "Object graph semantics", + zhTitle: "对象图语义", + label: "GRAPH", + description: + "Preserve shared references, circular references, and polymorphic runtime types instead of flattening them away.", + zhDescription: "保留共享引用、循环引用和多态运行时类型,而不是把对象图语义压平。", + link: "/docs/introduction/overview/", + }, + { + title: "Schema IDL and compiler", + zhTitle: "Schema IDL 与编译器", + label: "IDL", + description: + "Define stable contracts once and generate idiomatic domain objects for each target language.", + zhDescription: "一次定义稳定契约,为不同语言生成符合习惯的领域对象。", + link: "/docs/compiler/", + }, + { + title: "Row format and zero-copy", + zhTitle: "Row format 与零拷贝", + label: "ROW", + description: + "Read fields, arrays, and nested values without rebuilding whole objects for analytics and partial-read paths.", + zhDescription: "无需重建完整对象即可读取字段、数组和嵌套值,适合分析和部分读取路径。", + link: "/docs/specification/row_format_spec", + }, + { + title: "Optimized runtimes", + zhTitle: "运行时优化", + label: "JIT", + description: + "Combine Java JIT serializers with generated or static serializers in other runtimes.", + zhDescription: "结合 Java JIT 序列化器,以及其他运行时的生成式或静态序列化器。", + link: "/docs/guide/java/", + }, + { + title: "Multi-runtime ecosystem", + zhTitle: "多运行时生态", + label: "12X", + description: + "Work from Java, Python, Rust, Go, C++, JavaScript, C#, Swift, Dart, Scala, Kotlin, and cross-language guides.", + zhDescription: "覆盖 Java、Python、Rust、Go、C++、JavaScript、C#、Swift、Dart、Scala、Kotlin 和跨语言指南。", + link: "/docs/start/usage", + }, +]; + +const performanceCards = [ + { + value: "9", + label: "benchmark reports", + zhLabel: "份性能报告", + text: "Java, Python, Rust, C++, Go, C#, Swift, JavaScript, and Dart have dedicated benchmark pages.", + zhText: "Java、Python、Rust、C++、Go、C#、Swift、JavaScript 和 Dart 均有独立性能报告。", + }, + { + value: "2", + label: "wire modes", + zhLabel: "种线格式模式", + text: "Use xlang for portable payloads and native mode for same-runtime object surfaces.", + zhText: "xlang 用于可移植载荷,native mode 用于同一运行时的原生对象面。", + }, + { + value: "1", + label: "object model", + zhLabel: "套对象模型", + text: "Keep domain objects central while choosing schema, row format, or runtime-specific paths as needed.", + zhText: "以领域对象为中心,并按需选择 Schema、Row format 或运行时定制路径。", + }, +]; + +const useCases = [ + { + title: "Cross-language service payloads", + zhTitle: "跨语言服务载荷", + text: "Share objects between JVM, Python, Rust, Go, JavaScript, .NET, Swift, and Dart services.", + zhText: "在 JVM、Python、Rust、Go、JavaScript、.NET、Swift、Dart 服务之间共享对象。", + }, + { + title: "Cache and state snapshots", + zhTitle: "缓存与状态快照", + text: "Serialize rich object graphs without losing reference structure.", + zhText: "序列化复杂对象图,同时保留引用结构。", + }, + { + title: "Data pipelines and partial reads", + zhTitle: "数据管道与部分读取", + text: "Use row format when pipelines need zero-copy access to selected fields.", + zhText: "当管道只需要读取部分字段时,使用 Row format 获得零拷贝访问。", + }, +]; + +const adoptionPaths = [ + { + label: "01", + title: "Start with one runtime", + zhTitle: "从单一运行时开始", + text: "Install the package for your language and serialize native domain objects first.", + zhText: "安装当前语言的运行时包,先序列化原生领域对象。", + cta: "Install guide", + zhCta: "安装指南", + link: "/docs/start/install", + }, + { + label: "02", + title: "Standardize with Schema IDL", + zhTitle: "用 Schema IDL 标准化", + text: "Define shared contracts when teams need stable models across services and languages.", + zhText: "当团队需要跨服务、跨语言稳定模型时,用 Schema IDL 定义共享契约。", + cta: "Compiler docs", + zhCta: "编译器文档", + link: "/docs/compiler/", + }, + { + label: "03", + title: "Validate performance", + zhTitle: "验证性能表现", + text: "Use the benchmark notes and charts to compare runtime behavior before rollout.", + zhText: "上线前通过 Benchmark 说明和图表比较不同运行时表现。", + cta: "Benchmarks", + zhCta: "性能测试", + link: "/docs/introduction/benchmark", + }, +]; + +function langKey(locale?: string): "en" | "zh" { + return locale === "zh-CN" ? "zh" : "en"; +} + +function HomepageLanding(): JSX.Element { + const { + i18n: { currentLocale }, + } = useDocusaurusContext(); + const copy = copies[langKey(currentLocale)]; + const isZh = langKey(currentLocale) === "zh"; + const [selectedRuntime, setSelectedRuntime] = useState<RuntimeId>("java"); + + const selected = useMemo( + () => runtimeExamples.find((item) => item.id === selectedRuntime) ?? runtimeExamples[0], + [selectedRuntime], + ); + + return ( + <main className={styles.homepage}> + <section className={styles.hero}> + <div className={styles.heroContent}> + <div className={styles.eyebrow}>{copy.heroEyebrow}</div> + <h1>{copy.heroTitle}</h1> + <p className={styles.heroSubtitle}>{copy.heroSubtitle}</p> + <div className={styles.heroActions}> + <Link className={styles.primaryButton} to="/docs/start/install"> + {copy.heroPrimary} + </Link> + <Link className={styles.secondaryButton} to="/docs/introduction/overview"> + {copy.heroSecondary} + </Link> + <Link className={styles.ghostButton} to="https://github.com/apache/fory"> + {copy.heroGithub} + </Link> + </div> + <dl className={styles.trustList}> + <div> + <dt>{copy.heroVersion}</dt> + <dd>2026-05-21</dd> + </div> + <div> + <dt>{copy.heroRuntimes}</dt> + <dd>Java to Dart</dd> + </div> + <div> + <dt>{copy.heroBenchmarks}</dt> + <dd>9 reports</dd> + </div> + <div> + <dt>{copy.heroApache}</dt> + <dd>ASF</dd> + </div> + </dl> + </div> + + <div className={styles.heroVisual} aria-label={copy.heroPanelTitle}> + <div className={styles.panelHeader}> + <div> + <strong>{copy.heroPanelTitle}</strong> + <span>{copy.heroPanelSubtitle}</span> + </div> + <span className={styles.panelBadge}>xlang=true</span> + </div> + <div className={styles.flowGrid}> + <div className={styles.flowNode}> + <span>01</span> + <strong>{copy.heroFlowSource}</strong> + <code>Person("Alice", 30)</code> + </div> + <div className={styles.flowLine} /> + <div className={styles.flowNode}> + <span>02</span> + <strong>{copy.heroFlowWire}</strong> + <code>compact bytes</code> + </div> + <div className={styles.flowLine} /> + <div className={styles.flowNode}> + <span>03</span> + <strong>{copy.heroFlowTarget}</strong> + <code>Person(name="Alice")</code> + </div> + </div> + <div className={styles.heroCode}> + <CodeBlock language="java">{`Fory fory = Fory.builder().withXlang(true).build(); +fory.register(Person.class, "example", "Person"); + +byte[] bytes = fory.serialize(new Person("Alice", 30)); +Person out = (Person) fory.deserialize(bytes);`}</CodeBlock> + </div> + </div> + </section> + + <section className={styles.quickStart}> + <div className={styles.sectionHeader}> + <span>{copy.quickEyebrow}</span> + <h2>{copy.quickTitle}</h2> + <p>{copy.quickSubtitle}</p> + </div> + + <div className={styles.runtimeShell}> + <div className={styles.runtimeTabs} role="tablist" aria-label="Runtime examples"> + {runtimeExamples.map((runtime) => ( + <button + aria-selected={runtime.id === selectedRuntime} + className={runtime.id === selectedRuntime ? styles.runtimeTabActive : styles.runtimeTab} + key={runtime.id} + onClick={() => setSelectedRuntime(runtime.id)} + role="tab" + type="button" + > + {runtime.label} + </button> + ))} + </div> + + <div className={styles.runtimeDetail}> + <div className={styles.runtimeSummary}> + <div className={styles.runtimeTitleRow}> + <span>{selected.label}</span> + <Link to={selected.guide}>{copy.guideLabel}</Link> + </div> + <p>{selected.summary}</p> + <div className={styles.installBlock}> + <div className={styles.blockLabel}>{copy.installLabel}</div> + <CodeBlock language={selected.installLanguage}>{selected.install}</CodeBlock> + </div> + </div> + + <div className={styles.codeBlock}> + <div className={styles.blockLabel}>{copy.codeLabel}</div> + <CodeBlock language={selected.codeLanguage}>{selected.code}</CodeBlock> + </div> + </div> + </div> + </section> + + <section className={styles.capabilities}> + <div className={styles.sectionHeader}> + <span>{copy.capabilitiesEyebrow}</span> + <h2>{copy.capabilitiesTitle}</h2> + <p>{copy.capabilitiesSubtitle}</p> + </div> + <div className={styles.capabilityGrid}> + {capabilities.map((item) => ( + <Link className={styles.capabilityCard} key={item.title} to={item.link}> + <span>{item.label}</span> + <h3>{isZh ? item.zhTitle : item.title}</h3> + <p>{isZh ? item.zhDescription : item.description}</p> + </Link> + ))} + </div> + </section> + + <section className={styles.performance}> + <div className={styles.performanceCopy}> + <span>{copy.performanceEyebrow}</span> + <h2>{copy.performanceTitle}</h2> + <p>{copy.performanceSubtitle}</p> + <Link className={styles.secondaryButton} to="/docs/introduction/benchmark"> + {copy.benchmarkCta} + </Link> + </div> + <div className={styles.performanceCards}> + {performanceCards.map((item) => ( + <div className={styles.performanceCard} key={item.label}> + <strong>{item.value}</strong> + <span>{isZh ? item.zhLabel : item.label}</span> + <p>{isZh ? item.zhText : item.text}</p> + </div> + ))} + </div> + </section> + + <section className={styles.useCases}> + <div className={styles.sectionHeader}> + <span>{copy.useCasesEyebrow}</span> + <h2>{copy.useCasesTitle}</h2> + <p>{copy.useCasesSubtitle}</p> + </div> + <div className={styles.useCaseGrid}> + {useCases.map((item) => ( + <article className={styles.useCaseCard} key={item.title}> + <h3>{isZh ? item.zhTitle : item.title}</h3> + <p>{isZh ? item.zhText : item.text}</p> + </article> + ))} + </div> + </section> + + <section className={styles.ecosystem}> + <div className={styles.ecosystemHeader}> + <span className={styles.eyebrow}>{isZh ? "采用路径" : "Adoption paths"}</span> + <h2>{copy.ecosystemTitle}</h2> + <p>{copy.ecosystemSubtitle}</p> + </div> + <div className={styles.adoptionGrid}> + {adoptionPaths.map((item) => ( + <Link className={styles.adoptionCard} key={item.title} to={item.link}> + <span>{item.label}</span> + <h3>{isZh ? item.zhTitle : item.title}</h3> + <p>{isZh ? item.zhText : item.text}</p> + <strong>{isZh ? item.zhCta : item.cta}</strong> + </Link> + ))} + </div> + </section> + </main> + ); +} + +export default HomepageLanding; diff --git a/src/css/custom.css b/src/css/custom.css index f9cd9fa6b5..1bd8049e7c 100644 --- a/src/css/custom.css +++ b/src/css/custom.css @@ -29,33 +29,73 @@ --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3); } -.navbar__logo { - height: 2.25rem; -} - @media (min-width: 997px) { .navbar { - padding-left: calc( - var(--fory-doc-sidebar-inset) + - var(--ifm-menu-link-padding-horizontal) - ); + padding-left: 2rem; + padding-right: 2rem; + } + + .navbar__inner { + margin-left: auto; + margin-right: auto; + max-width: 1180px; + } + + .navbar__brand { + margin-right: 1.25rem; } } +.navbar { + --ifm-navbar-link-color: #4b5563; + --ifm-navbar-link-hover-color: #f26322; + box-shadow: 0 1px 0 rgba(15, 23, 42, .06); +} + +.navbar__logo { + height: 1.75rem; +} + .navbar__item { - font-size: .95rem; + font-size: .9375rem; + font-weight: 600; margin-right: 0; } .navbar__link { - font-size: .95rem; - padding-left: .55rem; - padding-right: .55rem; + color: var(--ifm-navbar-link-color); + font-size: .9375rem; + padding-left: .5rem; + padding-right: .5rem; +} + +.navbar__link:hover, +.navbar__link--active { + color: var(--ifm-navbar-link-hover-color); +} + +.navbar__search-input { + background-color: #f5f7fa; + border: 1px solid #edf0f5; + color: #475569; + font-size: .9375rem; + height: 2rem; +} + +.navbar__search-input::placeholder { + color: #9aa4b2; +} + +.navbar .clean-btn { + color: #5f6875; } +.navbar .clean-btn:hover { + color: var(--ifm-navbar-link-hover-color); +} .header-github-link:hover { - opacity: 0.6; + opacity: 1; } .header-github-link::before { @@ -65,6 +105,7 @@ display: flex; background: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.52 [...] no-repeat; + opacity: .7; } [data-theme='dark'] .header-github-link::before { @@ -72,6 +113,26 @@ no-repeat; } +[data-theme='dark'] .navbar { + --ifm-navbar-link-color: #c8d0dc; + --ifm-navbar-link-hover-color: #ff9a4f; + box-shadow: 0 1px 0 rgba(255, 255, 255, .08); +} + +[data-theme='dark'] .navbar__search-input { + background-color: rgba(255, 255, 255, .07); + border-color: rgba(255, 255, 255, .1); + color: #d7dee9; +} + +[data-theme='dark'] .navbar__search-input::placeholder { + color: #8e99a8; +} + +[data-theme='dark'] .navbar .clean-btn { + color: #c8d0dc; +} + .footer__copyright { font-size: .7em; } diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 9af67f8801..fc049d8dd5 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -1,42 +1,11 @@ -import React, { useEffect } from "react"; +import React from "react"; import Layout from "@theme/Layout"; import useDocusaurusContext from "@docusaurus/useDocusaurusContext"; -import useIsBrowser from "@docusaurus/useIsBrowser"; import { translate } from "@docusaurus/Translate"; -import HomepageHeader from "./home/components/HomepageHeader"; -import HomepageFeatures from "./home/components/HomepageFeatures"; -import HomePageLanguageCard from "./home/components/HomePageLanguageCard"; -import HomepageCodeDisplay from "./home/components/HomepageCodeDisplay"; -import HomepageFoot from "./home/components/HomepageFoot"; -import useAOS from "../hooks/useAOS"; +import HomepageLanding from "../components/home/HomepageLanding"; export default function App() { - const isBrowser = useIsBrowser(); const { siteConfig } = useDocusaurusContext(); - const pathname = isBrowser && window.location.pathname; - - const handleNavClass = () => { - if (isBrowser) { - try { - const nav = document.getElementsByTagName("nav")[0]; - if (!nav) return; - const classList = nav.classList; - if (pathname === "/" || pathname === "/zh-CN/") { - classList.add("index-nav"); - } else { - classList.remove("index-nav"); - } - } catch (error) { - console.error("处理导航栏类名时出错:", error); - } - } - }; - - useEffect(() => { - handleNavClass(); - }, [isBrowser, pathname]); - - useAOS(); const metaDescription = translate({ id: "homepage.metaDescription", @@ -46,21 +15,7 @@ export default function App() { return ( <Layout title={`${siteConfig.title}`} description={metaDescription}> - <main> - <HomepageHeader /> - <div data-aos="fade-up" data-aos-delay="10"> - <HomepageFeatures /> - </div> - <div data-aos="fade-up" data-aos-delay="10"> - <HomePageLanguageCard /> - </div> - <div data-aos="fade-up" data-aos-delay="10"> - <HomepageCodeDisplay /> - </div> - <div data-aos="fade-up" data-aos-delay="10"> - <HomepageFoot /> - </div> - </main> + <HomepageLanding /> </Layout> ); } diff --git a/versioned_docs/version-1.0.0/start/install.md b/versioned_docs/version-1.0.0/start/install.md index 68b2720c2b..9888849b21 100644 --- a/versioned_docs/version-1.0.0/start/install.md +++ b/versioned_docs/version-1.0.0/start/install.md @@ -112,26 +112,18 @@ Or use `cargo add`: cargo add [email protected] ``` -## JavaScript +## JavaScript / TypeScript -The JavaScript packages are not published to npm yet. - -Install and build them from source for now: +Install the published JavaScript package from npm: ```bash -git clone https://github.com/apache/fory.git -cd fory/javascript -npm install -npm run build +npm install @apache-fory/core ``` -After building from source, use `@apache-fory/core` and optionally `@apache-fory/hps` in your project or workspace setup. - Optional native acceleration requires Node.js 20+: ```bash -cd packages/hps -npm run build +npm install @apache-fory/hps ``` ## Dart --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
