diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..1540bfb --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "css.lint.unknownAtRules": "ignore", + "scss.lint.unknownAtRules": "ignore", + "less.lint.unknownAtRules": "ignore" +} diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts index 406f7c1..025be9e 100644 --- a/docs/.vitepress/config.ts +++ b/docs/.vitepress/config.ts @@ -1,6 +1,15 @@ -import { copyFileSync, mkdirSync, readFileSync, readdirSync, statSync } from "fs"; +/** @format */ + +import { + copyFileSync, + mkdirSync, + readFileSync, + readdirSync, + statSync, +} from "fs"; import { dirname, join, relative, resolve } from "path"; import { defineConfig, type HeadConfig } from "vitepress"; +import { extendConfig } from "@voidzero-dev/vitepress-theme/config"; import { tabsMarkdownPlugin } from "vitepress-plugin-tabs"; function loadEnvVar(key: string): string | undefined { @@ -21,8 +30,9 @@ const algoliaAppId = loadEnvVar("VITE_ALGOLIA_APP_ID"); const algoliaApiKey = loadEnvVar("VITE_ALGOLIA_API_KEY"); const algoliaIndexName = loadEnvVar("VITE_ALGOLIA_INDEX_NAME"); -const posthogHead: HeadConfig[] = posthogKey - ? [ +const posthogHead: HeadConfig[] = + posthogKey ? + [ [ "script", {}, @@ -33,19 +43,19 @@ const posthogHead: HeadConfig[] = posthogKey : []; const searchConfig = - algoliaAppId && algoliaApiKey && algoliaIndexName - ? { - provider: "algolia" as const, - options: { - appId: algoliaAppId, - apiKey: algoliaApiKey, - indexName: algoliaIndexName, - insights: true, - }, - } - : { provider: "local" as const }; + algoliaAppId && algoliaApiKey && algoliaIndexName ? + { + provider: "algolia" as const, + options: { + appId: algoliaAppId, + apiKey: algoliaApiKey, + indexName: algoliaIndexName, + insights: true, + }, + } + : { provider: "local" as const }; -export default defineConfig({ +const config = defineConfig({ title: "Plane", description: "Modern project management software", cleanUrls: true, @@ -57,7 +67,12 @@ export default defineConfig({ function walk(dir: string): void { for (const entry of readdirSync(dir)) { - if (entry === ".vitepress" || entry === "public" || entry === "node_modules") continue; + if ( + entry === ".vitepress" || + entry === "public" || + entry === "node_modules" + ) + continue; const abs = join(dir, entry); const stat = statSync(abs); if (stat.isDirectory()) { @@ -102,13 +117,6 @@ export default defineConfig({ crossorigin: "anonymous", }, ], - [ - "link", - { - rel: "stylesheet", - href: "https://fonts.googleapis.com/css2?family=Instrument+Sans:ital,wght@0,400..700;1,400..700&family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&family=National+Park:wght@200..800&family=Noto+Sans:ital,wght@0,100..900;1,100..900&family=Nunito+Sans:ital,opsz,wght@0,6..12,200..1000;1,6..12,200..1000&family=PT+Sans:ital,wght@0,400;0,700;1,400;1,700&family=Raleway:ital,wght@0,100..900;1,100..900&family=Roboto:ital,wght@0,100..900;1,100..900&family=Work+Sans:ital,wght@0,100..900;1,100..900&display=swap", - }, - ], [ "script", { @@ -192,14 +200,42 @@ export default defineConfig({ "project management, issue tracking, sprint management, agile, scrum, create projects, track sprints", }, ], + /** + * SSG inlines OSSHeader with data-theme from server isDark. Tailwind `dark:…` + * keys off [data-theme*="dark"] on that wrapper, so the bar can stay dark + * until Vue hydrates. The built-in "check-dark-mode" also only add()s + * html.dark. Run in setTimeout(0) so it executes after that script, then + * clear stale data-theme as soon as the bar exists. + */ + [ + "script", + {}, + `!function(){setTimeout(function(){ +var k="vitepress-theme-appearance"; +var p=localStorage.getItem(k)||"dark"; +var m=matchMedia("(prefers-color-scheme: dark)").matches; +var d=!p||p==="auto"?m:p==="dark"; +document.documentElement.classList.toggle("dark",d); +function bar(n){ +var h=document.querySelector(".docs-layout header"); +if(h&&h.parentElement){ +var w=h.parentElement; +if(d)w.setAttribute("data-theme","dark");else w.removeAttribute("data-theme"); +return; +} +if(n<200&&document.readyState==="loading")requestAnimationFrame(function(){bar(n+1)}); +}bar(0); +},0);}();`, + ], ], themeConfig: { + variant: "voidzero", logo: { light: "https://media.docs.plane.so/logo/new-logo-white.png", dark: "https://media.docs.plane.so/logo/new-logo-dark.png", }, - siteTitle: "", + siteTitle: "Plane", outline: { level: [2, 3], @@ -209,21 +245,25 @@ export default defineConfig({ search: searchConfig, socialLinks: [ - { icon: "github", link: "https://github.com/makeplane/plane" }, { icon: { - svg: '', + svg: '', }, link: "https://forum.plane.so", }, + { icon: "github", link: "https://github.com/makeplane/plane" }, { icon: "twitter", link: "https://twitter.com/planepowers" }, - { icon: "linkedin", link: "https://www.linkedin.com/company/planepowers/" }, + { + icon: "linkedin", + link: "https://www.linkedin.com/company/planepowers/", + }, ], nav: [ { text: "Sign in", link: "https://app.plane.so/sign-in", + noIcon: true, }, ], @@ -302,7 +342,10 @@ export default defineConfig({ text: "Search workspace", link: "/workspaces-and-users/search-workspace", }, - { text: "Personalize homepage", link: "/core-concepts/account/overview" }, + { + text: "Personalize homepage", + link: "/core-concepts/account/overview", + }, { text: "Power K", link: "/core-concepts/power-k" }, { text: "Customize navigation", @@ -377,7 +420,10 @@ export default defineConfig({ text: "Projects", collapsed: true, items: [ - { text: "Manage projects", link: "/core-concepts/projects/overview" }, + { + text: "Manage projects", + link: "/core-concepts/projects/overview", + }, { text: "Manage members", link: "/core-concepts/projects/manage-project-members", @@ -410,7 +456,10 @@ export default defineConfig({ text: "Work Items", collapsed: true, items: [ - { text: "Manage work items", link: "/core-concepts/issues/overview" }, + { + text: "Manage work items", + link: "/core-concepts/issues/overview", + }, { text: "Work item properties", link: "/core-concepts/issues/properties", @@ -498,7 +547,10 @@ export default defineConfig({ text: "Pages", collapsed: true, items: [ - { text: "Manage project pages", link: "/core-concepts/pages/overview" }, + { + text: "Manage project pages", + link: "/core-concepts/pages/overview", + }, { text: "Editor blocks", link: "/core-concepts/pages/editor-blocks", @@ -520,7 +572,10 @@ export default defineConfig({ text: "Time Tracking", link: "/core-concepts/issues/time-tracking", }, - { text: "Workflows and Approvals", link: "/workflows-and-approvals/workflows" }, + { + text: "Workflows and Approvals", + link: "/workflows-and-approvals/workflows", + }, { text: "Custom Relations", link: "/work-items/custom-relations" }, { text: "Automations", @@ -554,8 +609,14 @@ export default defineConfig({ text: "Page Inline Comments", link: "/core-concepts/pages/inline-comments", }, - { text: "Subscribers", link: "/communication-and-collaboration/subscribers" }, - { text: "Notifications", link: "/communication-and-collaboration/notifications" }, + { + text: "Subscribers", + link: "/communication-and-collaboration/subscribers", + }, + { + text: "Notifications", + link: "/communication-and-collaboration/notifications", + }, { text: "Inbox", link: "/communication-and-collaboration/inbox" }, ], }, @@ -697,3 +758,5 @@ export default defineConfig({ }, }, }); + +export default extendConfig(config); diff --git a/docs/.vitepress/theme/Layout.vue b/docs/.vitepress/theme/Layout.vue new file mode 100644 index 0000000..b34b700 --- /dev/null +++ b/docs/.vitepress/theme/Layout.vue @@ -0,0 +1,16 @@ + + + diff --git a/docs/.vitepress/theme/components/Card.vue b/docs/.vitepress/theme/components/Card.vue index 6aa2329..2e95257 100644 --- a/docs/.vitepress/theme/components/Card.vue +++ b/docs/.vitepress/theme/components/Card.vue @@ -1,3 +1,5 @@ + + + + + + diff --git a/docs/.vitepress/theme/components/CardGroup.vue b/docs/.vitepress/theme/components/CardGroup.vue index 260208e..335095f 100644 --- a/docs/.vitepress/theme/components/CardGroup.vue +++ b/docs/.vitepress/theme/components/CardGroup.vue @@ -1,19 +1,28 @@