diff --git a/.github/workflows/site.yml b/.github/workflows/site.yml
new file mode 100644
index 00000000..aa6b55de
--- /dev/null
+++ b/.github/workflows/site.yml
@@ -0,0 +1,47 @@
+name: Site
+
+on:
+ workflow_dispatch:
+ push:
+ branches:
+ - master
+ - next
+ paths:
+ - ".github/workflows/site.yml"
+ - "apps/site/**"
+ - "docs/**"
+ - "packages/**"
+ - "package-lock.json"
+ - "package.json"
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v5
+
+ - name: Setup Node
+ uses: actions/setup-node@v5
+ with:
+ node-version: 22
+ cache: npm
+
+ - name: Install dependencies
+ run: npm ci --ignore-scripts
+
+ - name: Install Pro docs package
+ env:
+ CHART_KIT_PRO_NPM_TOKEN: ${{ secrets.CHART_KIT_PRO_NPM_TOKEN }}
+ run: |
+ if [ -n "$CHART_KIT_PRO_NPM_TOKEN" ]; then
+ npm config set //registry.npmjs.org/:_authToken "$CHART_KIT_PRO_NPM_TOKEN"
+ npm install --no-save --package-lock=false --ignore-scripts @chart-kit/pro
+ echo "CHART_KIT_PRO_DOCS=true" >> "$GITHUB_ENV"
+ else
+ echo "CHART_KIT_PRO_NPM_TOKEN is not set; building with local Pro docs stubs."
+ fi
+
+ - name: Build site
+ run: npm run site:build
diff --git a/apps/site/astro.config.mjs b/apps/site/astro.config.mjs
index cce9601a..1c265300 100644
--- a/apps/site/astro.config.mjs
+++ b/apps/site/astro.config.mjs
@@ -8,6 +8,7 @@ import { chartKitMarkdownPatches } from "./src/lib/starlight-markdown-patches.mj
import tailwindcss from "@tailwindcss/vite";
const repositoryUrl = "https://github.com/indiespirit/react-native-chart-kit";
+const docsSlug = (slug) => `docs/react-native/${slug}`;
const packageSource = (packagePath) =>
fileURLToPath(new URL(`../../packages/${packagePath}`, import.meta.url));
const nodeModuleSource = (packagePath) =>
@@ -24,6 +25,15 @@ const expoVectorIconsStub = localSource(
const svgTransformParserStub = localSource(
"./src/previews/svgTransformParserStub.ts"
);
+const useRealProCharts = process.env.CHART_KIT_PRO_DOCS === "true";
+const chartKitProAliases = useRealProCharts
+ ? []
+ : [
+ {
+ find: /^@chart-kit\/pro$/,
+ replacement: localSource("./src/previews/proStub.tsx")
+ }
+ ];
const chartKitPreviewWebAliases = () => ({
name: "chart-kit-preview-web-aliases",
@@ -77,32 +87,45 @@ export default defineConfig({
sidebar: [
{
label: "Start",
- items: [{ slug: "docs/getting-started/installation" }]
+ items: [
+ { slug: docsSlug("getting-started/installation") },
+ { slug: docsSlug("getting-started/contributing") }
+ ]
},
{
label: "Charts",
items: [
- { slug: "docs/charts/line-and-area" },
- { slug: "docs/charts/bar" },
- { slug: "docs/charts/pie-and-donut" },
- { slug: "docs/charts/progress" },
- { slug: "docs/charts/contribution-heatmap" }
+ { slug: docsSlug("charts/line") },
+ { slug: docsSlug("charts/area") },
+ { slug: docsSlug("charts/bar") },
+ { slug: docsSlug("charts/pie") },
+ { slug: docsSlug("charts/donut") },
+ { slug: docsSlug("charts/progress") },
+ { slug: docsSlug("charts/contribution-heatmap") }
+ ]
+ },
+ {
+ label: "Pro Charts",
+ items: [
+ { slug: docsSlug("charts/candlebar") },
+ { slug: docsSlug("charts/radar") },
+ { slug: docsSlug("charts/combo") }
]
},
{
label: "Guides",
items: [
- { slug: "docs/charts/themes" },
- { slug: "docs/charts/accessibility" },
- { slug: "docs/troubleshooting" },
- { slug: "docs/recipes" }
+ { slug: docsSlug("charts/themes") },
+ { slug: docsSlug("charts/accessibility") },
+ { slug: docsSlug("troubleshooting") },
+ { slug: docsSlug("recipes") }
]
},
{
label: "Migration",
items: [
- { slug: "docs/migration/from-v1" },
- { slug: "docs/migration/prop-mapping" }
+ { slug: docsSlug("migration/from-v1") },
+ { slug: docsSlug("migration/prop-mapping") }
]
}
],
@@ -119,6 +142,7 @@ export default defineConfig({
"react-native",
"react-native-chart-kit",
"react-native-chart-kit/v2",
+ "@chart-kit/pro",
"react-native-gesture-handler",
"react-native-svg"
]
@@ -141,6 +165,7 @@ export default defineConfig({
find: /^@chart-kit\/svg-renderer$/,
replacement: packageSource("svg-renderer/src/index.ts")
},
+ ...chartKitProAliases,
{
find: /^react-native$/,
replacement: reactNativeWebStub
diff --git a/apps/site/package.json b/apps/site/package.json
index dc13ef3c..bb6ed3f9 100644
--- a/apps/site/package.json
+++ b/apps/site/package.json
@@ -22,6 +22,7 @@
"dependencies": {
"@tailwindcss/vite": "^4.3.0",
"lucide-astro": "^0.556.0",
+ "react-live": "^4.1.8",
"tailwindcss": "^4.3.0"
}
}
diff --git a/apps/site/src/chart-theme-controls.ts b/apps/site/src/chart-theme-controls.ts
new file mode 100644
index 00000000..d24ed01d
--- /dev/null
+++ b/apps/site/src/chart-theme-controls.ts
@@ -0,0 +1,218 @@
+import {
+ applyChartThemePreset,
+ chartThemeOptions,
+ getCurrentChartThemePreset,
+ isChartThemePreset
+} from "./previews/chartTheme";
+
+type ColorTheme = "dark" | "light";
+
+const controlSelector = "[data-chart-theme-control]";
+const docsThemeToggleSelector = "[data-docs-theme-toggle]";
+const selectSelector = "[data-chart-theme-select]";
+const starlightThemeStorageKey = "starlight-theme";
+const themeColor = {
+ dark: "#06070a",
+ light: "#f7f8fb"
+};
+
+const isColorTheme = (value: string | null): value is ColorTheme =>
+ value === "dark" || value === "light";
+
+const getCurrentColorTheme = (): ColorTheme => {
+ try {
+ const stored = localStorage.getItem(starlightThemeStorageKey);
+
+ if (isColorTheme(stored)) {
+ return stored;
+ }
+ } catch {
+ // Storage can be blocked in restricted browser contexts.
+ }
+
+ return document.documentElement.dataset.theme === "light" ? "light" : "dark";
+};
+
+const syncStarlightThemeSelects = (theme: ColorTheme) => {
+ document
+ .querySelectorAll
${escapeHtml(
+ code
+ )}