Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"css.lint.unknownAtRules": "ignore",
"scss.lint.unknownAtRules": "ignore",
"less.lint.unknownAtRules": "ignore"
}
36 changes: 34 additions & 2 deletions docs/.vitepress/config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
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 {
Expand Down Expand Up @@ -45,7 +46,7 @@ const searchConfig =
}
: { provider: "local" as const };

export default defineConfig({
const config = defineConfig({
title: "Plane",
description: "Modern project management software",
cleanUrls: true,
Expand Down Expand Up @@ -192,14 +193,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",

Comment on lines 225 to 232
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

@voidzero-dev/vitepress-theme themeConfig.variant supported values list

💡 Result:

The supported values for themeConfig.variant in @voidzero-dev/vitepress-theme are strings corresponding to VoidZero projects, such as "viteplus", "vite", "vitest". Additional likely values based on project context include "rolldown" and "oxc", as the theme is designed for Vite+, Vite, Vitest, Rolldown, and Oxc. The variant controls branding colors and styling via CSS selectors like :root[data-variant="vite"]. Users import specific variants like '@voidzero-dev/vitepress-theme/src/vite' in the theme entry.

Citations:


Change variant: "voidzero" to a supported value.

The @voidzero-dev/vitepress-theme package only supports variants: "vite", "viteplus", "vitest", "rolldown", and "oxc". The variant "voidzero" is not recognized and will cause incorrect theme rendering or build failures. Use one of the supported variants that matches your target project.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/.vitepress/config.ts` around lines 225 - 232, The themeConfig currently
sets variant: "voidzero", which is unsupported by `@voidzero-dev/vitepress-theme`;
update the variant property inside themeConfig to one of the supported values
("vite", "viteplus", "vitest", "rolldown", or "oxc") that best matches your
project (e.g., change variant in themeConfig from "voidzero" to "vite" or
another supported option) so the theme renders and builds correctly.

outline: {
level: [2, 3],
Expand All @@ -224,6 +253,7 @@ export default defineConfig({
{
text: "Sign in",
link: "https://app.plane.so/sign-in",
noIcon: true,
},
],

Expand Down Expand Up @@ -684,3 +714,5 @@ export default defineConfig({
},
},
});

export default extendConfig(config);
16 changes: 16 additions & 0 deletions docs/.vitepress/theme/Layout.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<script setup lang="ts">
import { computed, useSlots } from "vue";
import VoidZeroTheme from "@voidzero-dev/vitepress-theme";

const BaseLayout = VoidZeroTheme.Layout;
const slots = useSlots();
const forwardSlotNames = computed(() => Object.keys(slots) as string[]);
</script>

<template>
<BaseLayout>
<template v-for="name in forwardSlotNames" :key="name" #[name]="data">
<slot :name="name" v-bind="data || {}" />
</template>
</BaseLayout>
</template>
41 changes: 31 additions & 10 deletions docs/.vitepress/theme/components/Card.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,27 @@
<!-- @format -->

<script setup>
import { computed } from "vue";
import * as LucideIcons from "lucide-vue-next";

const props = defineProps({
title: String,
icon: String,
/** Doc path or full URL */
href: String,
/** Alias for `href` (common in markdown) */
link: String,
/** When set, used instead of the default slot for body text */
description: String,
/** Bottom link label (shown with →). Home feature cards only. */
cta: String,
});

const hasDestination = computed(() => Boolean((props.link || props.href || "").toString().trim()));

const resolvedHref = computed(() => {
const h = (props.link || props.href || "").toString().trim();
return h;
});

// Custom SVG icons for brands
Expand Down Expand Up @@ -44,18 +60,23 @@ const IconComponent = computed(() => {
</script>

<template>
<a :href="href" class="card-link">
<div v-if="icon" class="card-icon">
<!-- Render custom SVG if available -->
<component
:is="hasDestination ? 'a' : 'div'"
:href="hasDestination ? resolvedHref : undefined"
class="card-link"
:class="{ 'card-link--with-cta': cta }"
>
<div v-if="icon" class="card-icon" aria-hidden="true">
<div v-if="customSvgIcons[icon]" v-html="customSvgIcons[icon]"></div>
<!-- Otherwise render Lucide icon -->
<component v-else :is="IconComponent" :size="24" />
<component v-else :is="IconComponent" :size="24" stroke-width="1.5" />
</div>
<h3 class="card-title">
{{ title }}
</h3>
<p class="card-description">
<h3 class="card-title">{{ title }}</h3>
<p v-if="description" class="card-description">
{{ description }}
</p>
<p v-else class="card-description">
<slot />
</p>
</a>
<span v-if="cta" class="card-cta">{{ cta }} →</span>
</component>
</template>
17 changes: 13 additions & 4 deletions docs/.vitepress/theme/components/CardGroup.vue
Original file line number Diff line number Diff line change
@@ -1,19 +1,28 @@
<script setup>
defineProps({
import { computed } from "vue";

const props = defineProps({
cols: {
type: [Number, String],
default: 2,
},
/** Alias for `cols` (e.g. `<CardGroup columns="3">`) */
columns: {
type: [Number, String],
default: undefined,
},
});

const columnCount = computed(() => props.columns ?? props.cols);
</script>

<template>
<div
class="card-group"
:class="{
'card-group-2': cols == 2,
'card-group-3': cols == 3,
'card-group-4': cols == 4,
'card-group-2': columnCount == 2,
'card-group-3': columnCount == 3,
'card-group-4': columnCount == 4,
}"
>
<slot />
Expand Down
Loading
Loading